wip: toplevels
This commit is contained in:
parent
8a855cb3d5
commit
e7f9e95440
3 changed files with 64 additions and 37 deletions
|
|
@ -78,19 +78,7 @@ fn main() {
|
||||||
TX.set(tx.clone()).unwrap();
|
TX.set(tx.clone()).unwrap();
|
||||||
|
|
||||||
rx.attach(None, glib::clone!(@weak window => @default-return glib::prelude::Continue(true), move |event| {
|
rx.attach(None, glib::clone!(@weak window => @default-return glib::prelude::Continue(true), move |event| {
|
||||||
match event {
|
let should_apply_changes = match event {
|
||||||
AppListEvent::Activate(_) => {
|
|
||||||
// let _activate_window = zbus_conn
|
|
||||||
// .call_method(Some(DEST), PATH, Some(DEST), "WindowFocus", &((e,)))
|
|
||||||
// .await
|
|
||||||
// .expect("Failed to focus selected window");
|
|
||||||
}
|
|
||||||
AppListEvent::Close(_) => {
|
|
||||||
// let _activate_window = zbus_conn
|
|
||||||
// .call_method(Some(DEST), PATH, Some(DEST), "WindowQuit", &((e,)))
|
|
||||||
// .await
|
|
||||||
// .expect("Failed to close selected window");
|
|
||||||
}
|
|
||||||
AppListEvent::Favorite((name, should_favorite)) => {
|
AppListEvent::Favorite((name, should_favorite)) => {
|
||||||
let saved_app_model = apps_container.model(DockListType::Saved);
|
let saved_app_model = apps_container.model(DockListType::Saved);
|
||||||
let active_app_model = apps_container.model(DockListType::Active);
|
let active_app_model = apps_container.model(DockListType::Active);
|
||||||
|
|
@ -130,6 +118,7 @@ fn main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let _ = tx.send(AppListEvent::Refresh);
|
let _ = tx.send(AppListEvent::Refresh);
|
||||||
|
false
|
||||||
}
|
}
|
||||||
AppListEvent::Refresh => {
|
AppListEvent::Refresh => {
|
||||||
// println!("refreshing model from cache");
|
// println!("refreshing model from cache");
|
||||||
|
|
@ -194,13 +183,28 @@ fn main() {
|
||||||
.map(|v| DockObject::from_search_results(v).upcast())
|
.map(|v| DockObject::from_search_results(v).upcast())
|
||||||
.collect();
|
.collect();
|
||||||
active_app_model.splice(0, model_len, &new_results[..]);
|
active_app_model.splice(0, model_len, &new_results[..]);
|
||||||
|
true
|
||||||
}
|
}
|
||||||
AppListEvent::WindowList(results) => {
|
AppListEvent::WindowList(toplevels) => {
|
||||||
|
cached_results = toplevels;
|
||||||
|
true
|
||||||
|
}
|
||||||
|
AppListEvent::Remove(top_level) => {
|
||||||
|
if let Some(i) = cached_results.iter().position(|t| t.toplevel_handle == top_level.toplevel_handle) {
|
||||||
|
cached_results.swap_remove(i);
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
AppListEvent::Add(top_level) => {
|
||||||
// sort to make comparison with cache easier
|
// sort to make comparison with cache easier
|
||||||
cached_results = results.clone();
|
cached_results.push(top_level);
|
||||||
|
true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if should_apply_changes {
|
||||||
|
dbg!(&cached_results);
|
||||||
// build active app stacks for each app
|
// build active app stacks for each app
|
||||||
let stack_active = results.iter().fold(
|
let stack_active = cached_results.iter().fold(
|
||||||
BTreeMap::new(),
|
BTreeMap::new(),
|
||||||
|mut acc: BTreeMap<String, BoxedWindowList>, elem| {
|
|mut acc: BTreeMap<String, BoxedWindowList>, elem| {
|
||||||
if let Some(v) = acc.get_mut(&elem.name) {
|
if let Some(v) = acc.get_mut(&elem.name) {
|
||||||
|
|
@ -230,15 +234,15 @@ fn main() {
|
||||||
if let Some((i, _s)) = stack_active
|
if let Some((i, _s)) = stack_active
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.find(|(_i, s)| s.0[0].name == cur_app_info.name())
|
.find(|(_i, s)| s.0[0].app_id == cur_app_info.name())
|
||||||
{
|
{
|
||||||
// println!("found active saved app {} at {}", s.0[0].name, i);
|
// println!("found active saved app {} at {}", s.0[0].name, i);
|
||||||
let active = stack_active.remove(i);
|
let active = stack_active.remove(i);
|
||||||
dock_obj.set_property("active", active.to_value());
|
dock_obj.set_property("active", active.to_value());
|
||||||
saved_app_model.items_changed(saved_i, 0, 0);
|
saved_app_model.items_changed(saved_i, 0, 0);
|
||||||
} else if results
|
} else if cached_results
|
||||||
.iter()
|
.iter()
|
||||||
.any(|s| s.name == cur_app_info.name())
|
.any(|s| s.app_id == cur_app_info.name())
|
||||||
{
|
{
|
||||||
dock_obj.set_property(
|
dock_obj.set_property(
|
||||||
"active",
|
"active",
|
||||||
|
|
@ -257,8 +261,7 @@ fn main() {
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|v| DockObject::from_search_results(v).upcast())
|
.map(|v| DockObject::from_search_results(v).upcast())
|
||||||
.collect();
|
.collect();
|
||||||
active_app_model.splice(0, model_len, &new_results[..]);
|
active_app_model.splice(0, model_len, &new_results[..]);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
glib::prelude::Continue(true)
|
glib::prelude::Continue(true)
|
||||||
}));
|
}));
|
||||||
|
|
|
||||||
|
|
@ -13,8 +13,8 @@ pub const PATH: &str = "/com/System76/PopShell";
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum AppListEvent {
|
pub enum AppListEvent {
|
||||||
WindowList(Vec<Toplevel>),
|
WindowList(Vec<Toplevel>),
|
||||||
Activate((u32, u32)),
|
Add(Toplevel),
|
||||||
Close((u32, u32)),
|
Remove(Toplevel),
|
||||||
Favorite((String, bool)),
|
Favorite((String, bool)),
|
||||||
Refresh,
|
Refresh,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ use crate::{
|
||||||
wayland_source::WaylandSource, config::TopLevelFilter, TX, utils::AppListEvent,
|
wayland_source::WaylandSource, config::TopLevelFilter, TX, utils::AppListEvent,
|
||||||
};
|
};
|
||||||
use cosmic_panel_config::CosmicPanelConfig;
|
use cosmic_panel_config::CosmicPanelConfig;
|
||||||
use gtk4::glib;
|
|
||||||
use std::{
|
use std::{
|
||||||
env, os::unix::net::UnixStream, path::PathBuf,time::Duration,
|
env, os::unix::net::UnixStream, path::PathBuf,time::Duration,
|
||||||
};
|
};
|
||||||
|
|
@ -249,19 +248,15 @@ impl Dispatch<ZcosmicToplevelInfoV1, ()> for State {
|
||||||
state.toplevels.push(Toplevel { name: "".into(), app_id: "".into(), toplevel_handle: toplevel, states: vec![], output: None, workspace: None });
|
state.toplevels.push(Toplevel { name: "".into(), app_id: "".into(), toplevel_handle: toplevel, states: vec![], output: None, workspace: None });
|
||||||
},
|
},
|
||||||
zcosmic_toplevel_info_v1::Event::Finished => {
|
zcosmic_toplevel_info_v1::Event::Finished => {
|
||||||
dbg!(&state.toplevels);
|
todo!()
|
||||||
let tx = TX.get().unwrap().clone();
|
|
||||||
|
|
||||||
let _ = tx.send(AppListEvent::WindowList(state.toplevels.iter().filter(|t| {
|
|
||||||
match state.config.filter_top_levels {
|
|
||||||
Some(TopLevelFilter::ActiveWorkspace) => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}).cloned().collect()));
|
|
||||||
},
|
},
|
||||||
_ => {},
|
_ => {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
event_created_child!(State, ZcosmicWorkspaceManagerV1, [
|
||||||
|
0 => (ZcosmicToplevelHandleV1, ())
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -274,7 +269,6 @@ impl Dispatch<ZcosmicToplevelManagerV1, ()> for State {
|
||||||
_: &Connection,
|
_: &Connection,
|
||||||
_: &QueueHandle<Self>,
|
_: &QueueHandle<Self>,
|
||||||
) {
|
) {
|
||||||
dbg!(&event);
|
|
||||||
match event {
|
match event {
|
||||||
zcosmic_toplevel_manager_v1::Event::Capabilities { .. } => {
|
zcosmic_toplevel_manager_v1::Event::Capabilities { .. } => {
|
||||||
// TODO capabilities affect what is shown to user in applet
|
// TODO capabilities affect what is shown to user in applet
|
||||||
|
|
@ -293,14 +287,42 @@ impl Dispatch<ZcosmicToplevelHandleV1, ()> for State {
|
||||||
_: &Connection,
|
_: &Connection,
|
||||||
_: &QueueHandle<Self>,
|
_: &QueueHandle<Self>,
|
||||||
) {
|
) {
|
||||||
dbg!(&event);
|
|
||||||
match event {
|
match event {
|
||||||
zcosmic_toplevel_handle_v1::Event::Closed => {
|
zcosmic_toplevel_handle_v1::Event::Closed => {
|
||||||
if let Some(i) = state.toplevels.iter().position(|t| &t.toplevel_handle == p) {
|
if let Some(i) = state.toplevels.iter().position(|t| &t.toplevel_handle == p) {
|
||||||
state.toplevels.remove(i);
|
state.toplevels.remove(i);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
zcosmic_toplevel_handle_v1::Event::Done => {},
|
zcosmic_toplevel_handle_v1::Event::Done => {
|
||||||
|
let to_send = match state.config.filter_top_levels {
|
||||||
|
Some(TopLevelFilter::ActiveWorkspace) => {
|
||||||
|
state.toplevels.iter_mut().find(|t| {
|
||||||
|
if &t.toplevel_handle == p {
|
||||||
|
state
|
||||||
|
.workspace_groups
|
||||||
|
.iter()
|
||||||
|
.find(|g| {
|
||||||
|
g.workspaces
|
||||||
|
.iter()
|
||||||
|
.find(|w| w.states.contains(&zcosmic_workspace_handle_v1::State::Active) && Some(&w.workspace_handle) == t.workspace.as_ref()).is_some()
|
||||||
|
}).is_some()
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
Some(TopLevelFilter::ConfiguredOutput) =>
|
||||||
|
state.toplevels.iter_mut().find(|t| &t.toplevel_handle == p && state.expected_output == t.output),
|
||||||
|
_ => state.toplevels.iter_mut().find(|t| &t.toplevel_handle == p),
|
||||||
|
};
|
||||||
|
|
||||||
|
if let Some(toplevel) = to_send.cloned() {
|
||||||
|
let tx = TX.get().unwrap().clone();
|
||||||
|
|
||||||
|
let _ = tx.send(AppListEvent::Add(toplevel));
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
zcosmic_toplevel_handle_v1::Event::Title { title } => {
|
zcosmic_toplevel_handle_v1::Event::Title { title } => {
|
||||||
if let Some(i) = state.toplevels.iter_mut().find(|t| &t.toplevel_handle == p) {
|
if let Some(i) = state.toplevels.iter_mut().find(|t| &t.toplevel_handle == p) {
|
||||||
i.name = title;
|
i.name = title;
|
||||||
|
|
@ -477,6 +499,8 @@ impl Dispatch<ZcosmicWorkspaceHandleV1, ()> for State {
|
||||||
}) {
|
}) {
|
||||||
// wayland is host byte order
|
// wayland is host byte order
|
||||||
w.states = workspace_state.chunks(4).map(|chunk| zcosmic_workspace_handle_v1::State::try_from(u32::from_ne_bytes(chunk.try_into().unwrap())).unwrap()).collect();
|
w.states = workspace_state.chunks(4).map(|chunk| zcosmic_workspace_handle_v1::State::try_from(u32::from_ne_bytes(chunk.try_into().unwrap())).unwrap()).collect();
|
||||||
|
// TODO if workspace active status changes while configured to only show active workspace, clear the list
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
zcosmic_workspace_handle_v1::Event::Remove => {
|
zcosmic_workspace_handle_v1::Event::Remove => {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue