diff --git a/applets/cosmic-app-list/src/main.rs b/applets/cosmic-app-list/src/main.rs index beb5d0dd..1f7e78cd 100644 --- a/applets/cosmic-app-list/src/main.rs +++ b/applets/cosmic-app-list/src/main.rs @@ -78,19 +78,7 @@ fn main() { TX.set(tx.clone()).unwrap(); rx.attach(None, glib::clone!(@weak window => @default-return glib::prelude::Continue(true), move |event| { - 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"); - } + let should_apply_changes = match event { AppListEvent::Favorite((name, should_favorite)) => { let saved_app_model = apps_container.model(DockListType::Saved); let active_app_model = apps_container.model(DockListType::Active); @@ -130,6 +118,7 @@ fn main() { } } let _ = tx.send(AppListEvent::Refresh); + false } AppListEvent::Refresh => { // println!("refreshing model from cache"); @@ -194,13 +183,28 @@ fn main() { .map(|v| DockObject::from_search_results(v).upcast()) .collect(); 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 - cached_results = results.clone(); - + cached_results.push(top_level); + true + } + }; + if should_apply_changes { + dbg!(&cached_results); // build active app stacks for each app - let stack_active = results.iter().fold( + let stack_active = cached_results.iter().fold( BTreeMap::new(), |mut acc: BTreeMap, elem| { if let Some(v) = acc.get_mut(&elem.name) { @@ -230,15 +234,15 @@ fn main() { if let Some((i, _s)) = stack_active .iter() .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); let active = stack_active.remove(i); dock_obj.set_property("active", active.to_value()); saved_app_model.items_changed(saved_i, 0, 0); - } else if results + } else if cached_results .iter() - .any(|s| s.name == cur_app_info.name()) + .any(|s| s.app_id == cur_app_info.name()) { dock_obj.set_property( "active", @@ -257,8 +261,7 @@ fn main() { .into_iter() .map(|v| DockObject::from_search_results(v).upcast()) .collect(); - active_app_model.splice(0, model_len, &new_results[..]); - } + active_app_model.splice(0, model_len, &new_results[..]); } glib::prelude::Continue(true) })); diff --git a/applets/cosmic-app-list/src/utils.rs b/applets/cosmic-app-list/src/utils.rs index 0a3d0e8a..7a6268c8 100644 --- a/applets/cosmic-app-list/src/utils.rs +++ b/applets/cosmic-app-list/src/utils.rs @@ -13,8 +13,8 @@ pub const PATH: &str = "/com/System76/PopShell"; #[derive(Debug)] pub enum AppListEvent { WindowList(Vec), - Activate((u32, u32)), - Close((u32, u32)), + Add(Toplevel), + Remove(Toplevel), Favorite((String, bool)), Refresh, } diff --git a/applets/cosmic-app-list/src/wayland.rs b/applets/cosmic-app-list/src/wayland.rs index a12524a2..4e57a752 100644 --- a/applets/cosmic-app-list/src/wayland.rs +++ b/applets/cosmic-app-list/src/wayland.rs @@ -2,7 +2,6 @@ use crate::{ wayland_source::WaylandSource, config::TopLevelFilter, TX, utils::AppListEvent, }; use cosmic_panel_config::CosmicPanelConfig; -use gtk4::glib; use std::{ env, os::unix::net::UnixStream, path::PathBuf,time::Duration, }; @@ -249,19 +248,15 @@ impl Dispatch for State { state.toplevels.push(Toplevel { name: "".into(), app_id: "".into(), toplevel_handle: toplevel, states: vec![], output: None, workspace: None }); }, zcosmic_toplevel_info_v1::Event::Finished => { - dbg!(&state.toplevels); - 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())); + todo!() }, _ => {}, } } + + event_created_child!(State, ZcosmicWorkspaceManagerV1, [ + 0 => (ZcosmicToplevelHandleV1, ()) + ]); } @@ -274,7 +269,6 @@ impl Dispatch for State { _: &Connection, _: &QueueHandle, ) { - dbg!(&event); match event { zcosmic_toplevel_manager_v1::Event::Capabilities { .. } => { // TODO capabilities affect what is shown to user in applet @@ -293,14 +287,42 @@ impl Dispatch for State { _: &Connection, _: &QueueHandle, ) { - dbg!(&event); match event { zcosmic_toplevel_handle_v1::Event::Closed => { if let Some(i) = state.toplevels.iter().position(|t| &t.toplevel_handle == p) { 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 } => { if let Some(i) = state.toplevels.iter_mut().find(|t| &t.toplevel_handle == p) { i.name = title; @@ -477,6 +499,8 @@ impl Dispatch for State { }) { // 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(); + // TODO if workspace active status changes while configured to only show active workspace, clear the list + } } zcosmic_workspace_handle_v1::Event::Remove => {