diff --git a/examples/dock/dock_object/imp.rs b/examples/dock/dock_object/imp.rs index e3e10f3..cfa6e56 100644 --- a/examples/dock/dock_object/imp.rs +++ b/examples/dock/dock_object/imp.rs @@ -13,9 +13,9 @@ use crate::utils::BoxedWindowList; // Object holding the state #[derive(Default)] pub struct DockObject { - appinfo: RefCell>, - active: RefCell, - saved: Cell, + pub(super) appinfo: RefCell>, + pub(super) active: RefCell, + pub(super) saved: Cell, pub(super) popover: Cell, } diff --git a/examples/dock/dock_object/mod.rs b/examples/dock/dock_object/mod.rs index 52cd2e5..3a3bf30 100644 --- a/examples/dock/dock_object/mod.rs +++ b/examples/dock/dock_object/mod.rs @@ -1,6 +1,7 @@ use std::path::Path; use gdk4::glib::Object; +use gdk4::prelude::FileExt; use gdk4::subclass::prelude::ObjectSubclassExt; use gio::DesktopAppInfo; use gtk4::glib; @@ -36,6 +37,22 @@ impl DockObject { None } + pub fn get_name(&self) -> Option { + let imp = imp::DockObject::from_instance(&self); + if let Some(app_info) = imp.appinfo.borrow().as_ref() { + app_info + .filename() + .map(|name| name.to_string_lossy().into()) + } else { + None + } + } + + pub fn set_saved(&self, is_saved: bool) { + let imp = imp::DockObject::from_instance(&self); + imp.saved.replace(is_saved); + } + pub fn from_search_results(results: BoxedWindowList) -> Self { let appinfo = if let Some(first) = results.0.iter().next() { xdg::BaseDirectories::new() diff --git a/examples/dock/dock_popover/mod.rs b/examples/dock/dock_popover/mod.rs index 6233ed1..df680c1 100644 --- a/examples/dock/dock_popover/mod.rs +++ b/examples/dock/dock_popover/mod.rs @@ -245,7 +245,15 @@ impl DockPopover { let self_ = self.clone(); favorite_item.connect_clicked(glib::clone!(@weak dock_object => move |_| { - println!("TODO handling favorite"); + let saved = dock_object.property("saved").expect("DockObject must have saved property").get::().expect("Failed to convert value to bool"); + + glib::MainContext::default().spawn_local(async move { + if let Some(tx) = TX.get() { + if let Some(name) = dock_object.get_name() { + let _ = tx.send(Event::Favorite((name.into(), !saved))).await; + } + } + }); self_.emit_hide(); })); diff --git a/examples/dock/main.rs b/examples/dock/main.rs index bccdee9..a1fdbd3 100644 --- a/examples/dock/main.rs +++ b/examples/dock/main.rs @@ -42,6 +42,7 @@ pub enum Event { WindowList(Vec), Activate((u32, u32)), Close((u32, u32)), + Favorite((String, bool)), RefreshFromCache, } @@ -143,6 +144,47 @@ fn main() { .await .expect("Failed to close selected window"); } + Event::Favorite((name, should_favorite)) => { + dbg!(&name); + dbg!(should_favorite); + let saved_app_model = window.model(DockListType::Saved); + let active_app_model = window.model(DockListType::Active); + if should_favorite { + let mut cur: u32 = 0; + let mut index: Option = None; + while let Some(item) = active_app_model.item(cur) { + if let Ok(cur_dock_object) = item.downcast::() { + if cur_dock_object.get_name() == Some(name.clone()) { + cur_dock_object.set_saved(true); + index = Some(cur); + } + } + cur += 1; + } + if let Some(index) = index { + let object = active_app_model.item(index).unwrap(); + active_app_model.remove(index); + saved_app_model.append(&object); + } + } else { + let mut cur: u32 = 0; + let mut index: Option = None; + while let Some(item) = saved_app_model.item(cur) { + if let Ok(cur_dock_object) = item.downcast::() { + if cur_dock_object.get_name() == Some(name.clone()) { + cur_dock_object.set_saved(false); + index = Some(cur); + } + } + cur += 1; + } + if let Some(index) = index { + let object = saved_app_model.item(index).unwrap(); + saved_app_model.remove(index); + active_app_model.append(&object); + } + } + } Event::RefreshFromCache => { // println!("refreshing model from cache"); let cached_results = cached_results.as_ref();