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();
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<String, BoxedWindowList>, 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)
}));

View file

@ -13,8 +13,8 @@ pub const PATH: &str = "/com/System76/PopShell";
#[derive(Debug)]
pub enum AppListEvent {
WindowList(Vec<Toplevel>),
Activate((u32, u32)),
Close((u32, u32)),
Add(Toplevel),
Remove(Toplevel),
Favorite((String, bool)),
Refresh,
}

View file

@ -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<ZcosmicToplevelInfoV1, ()> 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<ZcosmicToplevelManagerV1, ()> for State {
_: &Connection,
_: &QueueHandle<Self>,
) {
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<ZcosmicToplevelHandleV1, ()> for State {
_: &Connection,
_: &QueueHandle<Self>,
) {
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<ZcosmicWorkspaceHandleV1, ()> 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 => {