From f95fa068f34d8ae105fd15f985ba4a4ad59a6d0e Mon Sep 17 00:00:00 2001 From: Ashley Wulber Date: Tue, 28 Dec 2021 11:08:02 -0500 Subject: [PATCH] refactor and cleanup launcher --- Cargo.toml | 4 +- examples/dock/main.rs | 6 +- examples/launcher/application_object/imp.rs | 189 ++------------------ examples/launcher/application_object/mod.rs | 65 +------ examples/launcher/application_row/mod.rs | 54 ++---- examples/launcher/main.rs | 9 +- examples/launcher/utils.rs | 3 + examples/launcher/window/mod.rs | 2 +- 8 files changed, 45 insertions(+), 287 deletions(-) create mode 100644 examples/launcher/utils.rs diff --git a/Cargo.toml b/Cargo.toml index 74eb54d..805e8c9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,9 +12,9 @@ x11 = { version = "2", features = ["xlib"] } # examples/launcher #pop-launcher = "1.0.3" -pop-launcher = { git = "https://github.com/pop-os/launcher" } +pop-launcher = { git = "https://github.com/wash2/launcher.git" } serde_json = "1.0.72" -pop-launcher-service = { git = "https://github.com/pop-os/launcher" } +pop-launcher-service = { git = "https://github.com/wash2/launcher.git" } postage = "0.4.1" futures = "0.3.17" glib = "0.14.8" diff --git a/examples/dock/main.rs b/examples/dock/main.rs index 964ba98..e511148 100644 --- a/examples/dock/main.rs +++ b/examples/dock/main.rs @@ -1,9 +1,10 @@ -#![feature(iter_zip)] mod dock_item; mod dock_object; mod utils; mod window; +use self::dock_object::DockObject; +use self::window::Window; use crate::utils::BoxedWindowList; use futures::executor::block_on; use gdk4::Display; @@ -25,9 +26,6 @@ use x11rb::rust_connection::RustConnection; use zbus::Connection; use zvariant_derive::Type; -use self::dock_object::DockObject; -use self::window::Window; - const DEST: &str = "com.System76.PopShell"; const PATH: &str = "/com/System76/PopShell"; const NUM_LAUNCHER_ITEMS: u8 = 10; diff --git a/examples/launcher/application_object/imp.rs b/examples/launcher/application_object/imp.rs index 5048d2f..aec0454 100644 --- a/examples/launcher/application_object/imp.rs +++ b/examples/launcher/application_object/imp.rs @@ -1,4 +1,5 @@ -use glib::{FromVariant, ParamFlags, ParamSpec, ToVariant, Value, Variant, VariantTy}; +use crate::utils::BoxedSearchResult; +use glib::{ParamFlags, ParamSpec, Value}; use gtk4::glib; use gtk4::prelude::*; use gtk4::subclass::prelude::*; @@ -7,12 +8,10 @@ use once_cell::sync::Lazy; use std::cell::RefCell; use std::rc::Rc; -use super::ApplicationData; - // Object holding the state #[derive(Default)] pub struct ApplicationObject { - data: Rc>, + data: Rc>, } // The central trait for subclassing a GObject @@ -27,150 +26,26 @@ impl ObjectSubclass for ApplicationObject { impl ObjectImpl for ApplicationObject { fn properties() -> &'static [ParamSpec] { static PROPERTIES: Lazy> = Lazy::new(|| { - vec![ - ParamSpec::new_uint( - // Name - "id", - // Nickname - "id", - // Short description - "ID of application in launcher search result", - 0, - u32::MAX, - // Default value - 0, - // The property can be read and written to - ParamFlags::READWRITE, - ), - ParamSpec::new_string( - // Name - "name", - // Nickname - "name", - // Short description - "Name of application in launcher search result", - // Default value - Some(""), - // The property can be read and written to - ParamFlags::READWRITE, - ), - ParamSpec::new_string( - // Name - "description", - // Nickname - "description", - // Short description - "Description of application in launcher search result", - // Default value - Some(""), - // The property can be read and written to - ParamFlags::READWRITE, - ), - ParamSpec::new_variant( - // Name - "icon", - // Nickname - "icon", - // Short description - "Icon of application in launcher search result", - VariantTy::new("(is)").expect("Oops invalid string for VariantTy tuple."), - // Default value - None, - // The property can be read and written to - ParamFlags::READWRITE, - ), - ParamSpec::new_variant( - // Name - "categoryicon", - // Nickname - "categoryicon", - // Short description - "Category icon of application in launcher search result", - VariantTy::new("(is)").expect("Oops invalid string for VariantTy tuple."), - // Default value - None, - // The property can be read and written to - ParamFlags::READWRITE, - ), - ParamSpec::new_variant( - // Name - "window", - // Nickname - "window", - // Short description - "Window of application in launcher search result", - // type (tuple of two uint32) - VariantTy::new("(uu)").expect("Oops invalid string for VariantTy tuple."), - // Default value - None, - // The property can be read and written to - ParamFlags::READWRITE, - ), - ] + vec![ParamSpec::new_boxed( + // Name + "data", + // Nickname + "data", + // Short description + "data", + BoxedSearchResult::static_type(), + // The property can be read and written to + ParamFlags::READWRITE, + )] }); PROPERTIES.as_ref() } fn set_property(&self, _obj: &Self::Type, _id: usize, value: &Value, pspec: &ParamSpec) { match pspec.name() { - "id" => { - let id = value.get().expect("The value needs to be of type `u32`."); - self.data.borrow_mut().0.id = id; - } - "name" => { - let name = value - .get() - .expect("The value needs to be of type `String`."); - self.data.borrow_mut().0.name = name; - } - "description" => { - let description = value - .get() - .expect("The description needs to be of type `String`"); - self.data.borrow_mut().0.description = description; - } - "icon" => { - let icon = <(i32, String)>::from_variant( - &value - .get::() - .expect("The icon needs to be a Variant"), - ) - .expect("The icon variant needs to be an (i32, String)"); - self.data.borrow_mut().0.icon = match icon { - (i_type, name) if i_type == pop_launcher::IconSource::Name as i32 => { - Some(pop_launcher::IconSource::Name(name.into())) - } - (i_type, name) if i_type == pop_launcher::IconSource::Mime as i32 => { - Some(pop_launcher::IconSource::Mime(name.into())) - } - (i_type, name) => { - println!("Failed to set icon. {} {}", i_type, name); - None - } - }; - } - "categoryicon" => { - let icon = <(i32, String)>::from_variant( - &value - .get::() - .expect("The icon needs to be a Variant"), - ) - .expect("The icon variant needs to be an Option<(i32, String)>"); - self.data.borrow_mut().0.category_icon = match icon { - (i_type, name) if i_type == pop_launcher::IconSource::Name as i32 => { - Some(pop_launcher::IconSource::Name(name.into())) - } - (i_type, name) if i_type == pop_launcher::IconSource::Mime as i32 => { - Some(pop_launcher::IconSource::Mime(name.into())) - } - (i_type, name) => { - println!("Failed to set icon. {} {}", i_type, name); - None - } - }; - } - "window" => { - unimplemented!() + "data" => { + let data = value.get().expect("Value needs to be BoxedSearchResult"); + self.data.replace(data); } _ => unimplemented!(), } @@ -178,35 +53,7 @@ impl ObjectImpl for ApplicationObject { fn property(&self, _obj: &Self::Type, _id: usize, pspec: &ParamSpec) -> Value { match pspec.name() { - "id" => self.data.borrow().0.id.to_value(), - "name" => self.data.borrow().0.name.to_value(), - "description" => self.data.borrow().0.description.to_value(), - "icon" => match &self.data.borrow().0.icon { - Some(pop_launcher::IconSource::Name(icon_name)) => { - (pop_launcher::IconSource::Name as i32, icon_name.to_string()) - .to_variant() - .to_value() - } - Some(pop_launcher::IconSource::Mime(icon_name)) => { - (pop_launcher::IconSource::Mime as i32, icon_name.to_string()) - .to_variant() - .to_value() - } - _ => None::.to_value(), - }, - "categoryicon" => match &self.data.borrow().0.category_icon { - Some(pop_launcher::IconSource::Name(icon_name)) => { - (pop_launcher::IconSource::Name as i32, icon_name.to_string()) - .to_variant() - .to_value() - } - Some(pop_launcher::IconSource::Mime(icon_name)) => { - (pop_launcher::IconSource::Mime as i32, icon_name.to_string()) - .to_variant() - .to_value() - } - _ => None::.to_value(), - }, + "data" => self.data.borrow().to_value(), _ => unimplemented!(), } } diff --git a/examples/launcher/application_object/mod.rs b/examples/launcher/application_object/mod.rs index 1ce0337..6d659a7 100644 --- a/examples/launcher/application_object/mod.rs +++ b/examples/launcher/application_object/mod.rs @@ -1,72 +1,13 @@ mod imp; - +use crate::utils::BoxedSearchResult; use gdk4::glib::Object; -use glib::ObjectExt; -use glib::ToVariant; -use gtk4::glib; glib::wrapper! { pub struct ApplicationObject(ObjectSubclass); } impl ApplicationObject { - pub fn new(application_search_result: &pop_launcher::SearchResult) -> Self { - let self_: Self = Object::new(&[ - ("id", &application_search_result.id), - ("name", &application_search_result.name), - ("description", &application_search_result.description), - ]) - .expect("Failed to create `ApplicationObject`."); - if let Some(icon) = &application_search_result.icon { - if let Err(e) = self_.set_property( - "icon", - match icon { - pop_launcher::IconSource::Name(name) => { - (pop_launcher::IconSource::Name as i32, name.to_string()).to_variant() - } - pop_launcher::IconSource::Mime(name) => { - (pop_launcher::IconSource::Mime as i32, name.to_string()).to_variant() - } - }, - ) { - println!("failed to set icon property"); - dbg!(e); - }; - } - if let Some(icon) = &application_search_result.category_icon { - if let Err(e) = self_.set_property( - "categoryicon", - match icon { - pop_launcher::IconSource::Name(name) => { - (pop_launcher::IconSource::Name as i32, name.to_string()).to_variant() - } - pop_launcher::IconSource::Mime(name) => { - (pop_launcher::IconSource::Mime as i32, name.to_string()).to_variant() - } - }, - ) { - println!("failed to set category icon property"); - dbg!(e); - }; - } - - self_ - } -} - -// Object holding the state -pub struct ApplicationData(pop_launcher::SearchResult); - -impl Default for ApplicationData { - fn default() -> Self { - let default_application = pop_launcher::SearchResult { - id: 0, - name: String::default(), - description: String::default(), - icon: None, - category_icon: None, - window: None, - }; - Self(default_application) + pub fn new(search_result: &BoxedSearchResult) -> Self { + Object::new(&[("data", search_result)]).expect("Failed to create Application Object") } } diff --git a/examples/launcher/application_row/mod.rs b/examples/launcher/application_row/mod.rs index 08d09eb..26e9799 100644 --- a/examples/launcher/application_row/mod.rs +++ b/examples/launcher/application_row/mod.rs @@ -1,6 +1,5 @@ use crate::icon_source; -use glib::FromVariant; -use glib::Variant; +use crate::BoxedSearchResult; use gtk4 as gtk; mod imp; @@ -25,49 +24,16 @@ impl ApplicationRow { glib::Object::new(&[]).expect("Failed to create ApplicationRow") } - pub fn set_app_info(&self, app_obj: ApplicationObject) { + pub fn set_search_result(&self, search_obj: ApplicationObject) { let self_ = imp::ApplicationRow::from_instance(self); - - if let Ok(name) = app_obj.property("name") { - self_.name.set_text( - &name - .get::() - .expect("Property name needs to be a String."), - ); - } - if let Ok(desc) = app_obj.property("description") { - self_.description.set_text( - &desc - .get::() - .expect("Property description needs to be a String."), - ); - } - if let Ok(icon) = app_obj.property("icon") { - if let Ok(icon) = icon.get::() { - let icon = match <(i32, String)>::from_variant(&icon) { - Some((i_type, name)) if i_type == pop_launcher::IconSource::Name as i32 => { - Some(pop_launcher::IconSource::Name(name.into())) - } - Some((i_type, name)) if i_type == pop_launcher::IconSource::Mime as i32 => { - Some(pop_launcher::IconSource::Mime(name.into())) - } - _ => None, - }; - icon_source(&self_.image, &icon); - } - } - if let Ok(icon) = app_obj.property("categoryicon") { - if let Ok(icon) = icon.get::() { - let icon = match <(i32, String)>::from_variant(&icon) { - Some((i_type, name)) if i_type == pop_launcher::IconSource::Name as i32 => { - Some(pop_launcher::IconSource::Name(name.into())) - } - Some((i_type, name)) if i_type == pop_launcher::IconSource::Mime as i32 => { - Some(pop_launcher::IconSource::Mime(name.into())) - } - _ => None, - }; - icon_source(&self_.categoryimage, &icon); + if let Ok(search_result) = search_obj.property("data") { + if let Ok(search_result) = search_result.get::() { + if let Some(search_result) = search_result.0 { + self_.name.set_text(&search_result.name); + self_.description.set_text(&search_result.description); + icon_source(&self_.image, &search_result.icon); + icon_source(&self_.categoryimage, &search_result.category_icon); + } } } } diff --git a/examples/launcher/main.rs b/examples/launcher/main.rs index 03c54c5..bb2ab99 100644 --- a/examples/launcher/main.rs +++ b/examples/launcher/main.rs @@ -1,8 +1,11 @@ mod application_object; mod application_row; +mod utils; mod window; + use self::application_object::ApplicationObject; use self::window::Window; +use crate::utils::BoxedSearchResult; use gdk4::Display; use gio::DesktopAppInfo; use gtk::gio; @@ -121,9 +124,9 @@ fn main() { let model_len = model.n_items(); dbg!(&results); let new_results: Vec = results - [0..std::cmp::min(results.len(), NUM_LAUNCHER_ITEMS.into())] - .iter() - .map(|result| ApplicationObject::new(result).upcast()) + // [0..std::cmp::min(results.len(), NUM_LAUNCHER_ITEMS.into())] + .into_iter() + .map(|result| ApplicationObject::new(&BoxedSearchResult(Some(result))).upcast()) .collect(); model.splice(0, model_len, &new_results[..]); } else if let pop_launcher::Response::DesktopEntry { diff --git a/examples/launcher/utils.rs b/examples/launcher/utils.rs new file mode 100644 index 0000000..2be7481 --- /dev/null +++ b/examples/launcher/utils.rs @@ -0,0 +1,3 @@ +#[derive(Clone, Debug, Default, glib::GBoxed)] +#[gboxed(type_name = "BoxedSearchResult")] +pub struct BoxedSearchResult(pub Option); diff --git a/examples/launcher/window/mod.rs b/examples/launcher/window/mod.rs index 36c8db3..e3f98d2 100644 --- a/examples/launcher/window/mod.rs +++ b/examples/launcher/window/mod.rs @@ -240,7 +240,7 @@ impl Window { row.set_shortcut(list_item.position() + 1); } - row.set_app_info(application_object); + row.set_search_result(application_object); }); // Set the factory of the list view let imp = imp::Window::from_instance(self);