diff --git a/examples/dock/main.rs b/examples/dock/main.rs index 22b3e0c9..ae57d6a0 100644 --- a/examples/dock/main.rs +++ b/examples/dock/main.rs @@ -1,44 +1,4 @@ -use futures_util::stream::StreamExt; - -use zbus::{dbus_proxy, Connection, Result}; -use zvariant::ObjectPath; - -#[dbus_proxy( - default_service = "org.freedesktop.GeoClue2", - interface = "org.freedesktop.GeoClue2.Manager", - default_path = "/org/freedesktop/GeoClue2/Manager" -)] -trait Manager { - #[dbus_proxy(object = "Client")] - fn get_client(&self); -} - -#[dbus_proxy( - default_service = "org.freedesktop.GeoClue2", - interface = "org.freedesktop.GeoClue2.Client" -)] -trait Client { - fn start(&self) -> Result<()>; - fn stop(&self) -> Result<()>; - - #[dbus_proxy(property)] - fn set_desktop_id(&mut self, id: &str) -> Result<()>; - - #[dbus_proxy(signal)] - fn location_updated(&self, old: ObjectPath<'_>, new: ObjectPath<'_>) -> Result<()>; -} - -#[dbus_proxy( - default_service = "org.freedesktop.GeoClue2", - interface = "org.freedesktop.GeoClue2.Location" -)] -trait Location { - #[dbus_proxy(property)] - fn latitude(&self) -> Result; - #[dbus_proxy(property)] - fn longitude(&self) -> Result; -} - +#![feature(iter_zip)] mod dock_item; mod dock_object; mod utils; @@ -46,6 +6,7 @@ mod window; use crate::utils::BoxedSearchResults; use async_io::Timer; +use futures::StreamExt; use gdk4::Display; use gio::DesktopAppInfo; use gtk::gio; @@ -56,6 +17,7 @@ use gtk4 as gtk; use gtk4::CssProvider; use gtk4::StyleContext; use once_cell::sync::OnceCell; +use pop_launcher::SearchResult; use pop_launcher_service::IpcClient; use postage::mpsc::Sender; use postage::prelude::*; @@ -74,7 +36,6 @@ pub enum Event { Response(pop_launcher::Response), Search(String), Activate(u32), - Loc(f64, f64), } fn spawn_launcher(tx: Sender) -> IpcClient { @@ -92,37 +53,12 @@ fn spawn_launcher(tx: Sender) -> IpcClient { // TODO listen for signal indicating change from dock service... let mut sender = tx.clone(); glib::MainContext::default().spawn_local(async move { - // loop { - let _ = sender.send(Event::Search(String::new())).await; - Timer::after(Duration::from_secs(1)).await; - // } - }); - - let mut sender = tx.clone(); - glib::MainContext::default().spawn_local(async move { - let conn = Connection::system().await.unwrap(); - let manager = ManagerProxy::new(&conn).await.unwrap(); - let mut client = manager.get_client().await.unwrap(); - - client.set_desktop_id("org.freedesktop.zbus").await.unwrap(); - let mut location_updated_stream = client.receive_location_updated().await.unwrap(); - - client.start().await.unwrap(); - while let Some(signal) = location_updated_stream.next().await { - let args = signal.args().unwrap(); - - let location = LocationProxy::builder(&conn) - .path(args.new()) - .unwrap() - .build() - .await - .unwrap(); - let lat = location.latitude().await.unwrap(); - let long = location.longitude().await.unwrap(); - println!("Latitude: {}\nLongitude: {}", lat, long,); - let _ = sender.send(Event::Loc(lat, long)).await; + loop { + let _ = sender.send(Event::Search(String::new())).await; + Timer::after(Duration::from_secs(1)).await; } }); + launcher } @@ -179,13 +115,11 @@ fn main() { let window = Window::new(app); window.show(); + let cached_results: Vec = vec![]; glib::MainContext::default().spawn_local(async move { + futures::pin_mut!(cached_results); while let Some(event) = rx.recv().await { match event { - Event::Loc(lat, long) => { - dbg!(lat); - dbg!(long); - } Event::Search(search) => { let _ = launcher.send(pop_launcher::Request::Search(search)).await; } @@ -193,7 +127,19 @@ fn main() { let _ = launcher.send(pop_launcher::Request::Activate(index)).await; } Event::Response(event) => { - if let pop_launcher::Response::Update(results) = event { + if let pop_launcher::Response::Update(mut results) = event { + // sort to make comparison with cache easier + let mut cached_results = cached_results.as_mut(); + results.sort_by(|a, b| a.name.cmp(&b.name)); + // check if cache equals the new polled results + // skip if equal + if cached_results.len() == results.len() && results.iter().zip(cached_results.iter()).fold(0, |acc, z: (&SearchResult, &SearchResult)| { + let (a, b) = z; + if a.name == b.name {acc + 1} else {acc} + }) == cached_results.len() { + continue // skip this update + } + println!("updating active apps"); let model = window.active_app_model(); let model_len = model.n_items(); @@ -210,6 +156,7 @@ fn main() { .map(|v| DockObject::from_search_results(v).upcast()) .collect(); model.splice(0, model_len, &new_results[..]); + cached_results.splice(.., results); } else if let pop_launcher::Response::DesktopEntry { path,