wip: toplevels

This commit is contained in:
Ashley Wulber 2022-07-19 15:19:05 -04:00
parent 8a855cb3d5
commit e7f9e95440
No known key found for this signature in database
GPG key ID: 5216D4F46A90A820
3 changed files with 64 additions and 37 deletions

View file

@ -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)
})); }));

View file

@ -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,
} }

View file

@ -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 => {