diff --git a/Cargo.lock b/Cargo.lock index 544a5ac..1c4e70a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1392,6 +1392,16 @@ dependencies = [ "memoffset", ] +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + [[package]] name = "num-conv" version = "0.1.0" @@ -1483,6 +1493,12 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + [[package]] name = "parking" version = "2.2.0" @@ -1618,6 +1634,7 @@ dependencies = [ "pop-launcher-toolkit", "tokio", "tracing", + "tracing-journald", "tracing-subscriber", ] @@ -2524,6 +2541,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" dependencies = [ "once_cell", + "valuable", +] + +[[package]] +name = "tracing-journald" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba316a74e8fc3c3896a850dba2375928a9fa171b085ecddfc7c054d39970f3fd" +dependencies = [ + "libc", + "tracing-core", + "tracing-subscriber", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", ] [[package]] @@ -2534,12 +2574,15 @@ checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" dependencies = [ "chrono", "matchers", + "nu-ansi-term", "once_cell", "regex", "sharded-slab", + "smallvec", "thread_local", "tracing", "tracing-core", + "tracing-log", ] [[package]] @@ -2624,6 +2667,12 @@ version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" +[[package]] +name = "valuable" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" + [[package]] name = "version_check" version = "0.9.4" diff --git a/bin/Cargo.toml b/bin/Cargo.toml index 1e1fd31..115dbca 100644 --- a/bin/Cargo.toml +++ b/bin/Cargo.toml @@ -11,6 +11,7 @@ publish = false pop-launcher-toolkit = { path = "../toolkit" } tracing.workspace = true tracing-subscriber = { version = "0.3.18", default-features = false, features = ["std", "fmt", "env-filter", "chrono"] } +tracing-journald = "0.3.0" dirs.workspace = true mimalloc = "0.1.39" diff --git a/bin/src/main.rs b/bin/src/main.rs index cb7bdc9..c6a2412 100644 --- a/bin/src/main.rs +++ b/bin/src/main.rs @@ -5,8 +5,6 @@ use pop_launcher_toolkit::plugins; use pop_launcher_toolkit::service; use mimalloc::MiMalloc; -use tracing_subscriber::layer::SubscriberExt; -use tracing_subscriber::EnvFilter; #[global_allocator] static GLOBAL: MiMalloc = MiMalloc; @@ -41,7 +39,7 @@ async fn main() { // todo: support journald once this issue is resolved: https://github.com/tokio-rs/tracing/issues/2348 fn init_logging(cmd: &str) { - use tracing_subscriber::{fmt, Registry}; + use tracing_subscriber::{fmt, layer::SubscriberExt, util::SubscriberInitExt, EnvFilter}; let logdir = match dirs::state_dir() { Some(dir) => dir.join("pop-launcher/"), @@ -59,7 +57,7 @@ fn init_logging(cmd: &str) { if let Ok(file) = logfile { if let Ok(meta) = file.metadata() { - if meta.len() > 1000 { + if meta.len() > 10000 { let _ = file.set_len(0); } } @@ -68,13 +66,18 @@ fn init_logging(cmd: &str) { .or_else(|_| EnvFilter::try_new("warn")) .unwrap(); - let fmt_layer = fmt::layer() - .with_target(false) - .with_timer(fmt::time::ChronoLocal::new("%T".into())) - .with_writer(file); + let fmt_layer = fmt::layer().with_target(false).with_writer(file); - let subscriber = Registry::default().with(filter_layer).with(fmt_layer); - - tracing::subscriber::set_global_default(subscriber).expect("Failed to set subscriber"); + if let Ok(journal_layer) = tracing_journald::layer() { + tracing_subscriber::registry() + .with(journal_layer) + .with(filter_layer) + .init(); + } else { + tracing_subscriber::registry() + .with(fmt_layer) + .with(filter_layer) + .init(); + } } } diff --git a/plugins/src/cosmic_toplevel/mod.rs b/plugins/src/cosmic_toplevel/mod.rs index 56cc04f..e872f63 100644 --- a/plugins/src/cosmic_toplevel/mod.rs +++ b/plugins/src/cosmic_toplevel/mod.rs @@ -1,10 +1,12 @@ mod toplevel_handler; +use cctk::cosmic_protocols::toplevel_info::v1::client::zcosmic_toplevel_handle_v1::State; use cctk::wayland_client::Proxy; use cctk::{cosmic_protocols, sctk::reexports::calloop, toplevel_info::ToplevelInfo}; use cosmic_protocols::toplevel_info::v1::client::zcosmic_toplevel_handle_v1::ZcosmicToplevelHandleV1; use fde::DesktopEntry; use freedesktop_desktop_entry as fde; +use tracing::{debug, info}; use crate::desktop_entries::utils::get_description; use crate::send; @@ -18,12 +20,13 @@ use pop_launcher::{ Request, }; use std::borrow::Cow; +use std::collections::VecDeque; use tokio::io::{AsyncWrite, AsyncWriteExt}; use self::toplevel_handler::{toplevel_handler, ToplevelAction, ToplevelEvent}; pub async fn main() { - tracing::info!("starting cosmic-toplevel"); + info!("starting cosmic-toplevel"); let mut tx = async_stdout(); @@ -67,20 +70,37 @@ pub async fn main() { Either::Right((Some(event), second_to_next_request)) => { next_event = toplevel_rx.next(); next_request = second_to_next_request; + match event { ToplevelEvent::Add(handle, info) => { - tracing::info!("{}", &info.app_id); + tracing::info!("add {}", &info.app_id); app.toplevels.retain(|t| t.0 != handle); - app.toplevels.push((handle, info)); + app.toplevels.push_front((handle, info)); } ToplevelEvent::Remove(handle) => { - app.toplevels.retain(|t| t.0 != handle); - // ignore requests for this id until after the next search - app.ids_to_ignore.push(handle.id().protocol_id()); + if let Some(pos) = app.toplevels.iter().position(|t| t.0 == handle) { + app.toplevels.remove(pos); + // ignore requests for this id until after the next search + app.ids_to_ignore.push(handle.id().protocol_id()); + } else { + tracing::warn!("ToplevelEvent::Remove, no toplevel found"); + } } ToplevelEvent::Update(handle, info) => { - if let Some(t) = app.toplevels.iter_mut().find(|t| t.0 == handle) { - t.1 = info; + debug!("Update {}", &info.app_id); + debug!("Update {:?}", &info.state); + + if let Some(pos) = app.toplevels.iter().position(|t| t.0 == handle) { + if info.state.contains(&State::Activated) { + tracing::warn!("Update {:?}: push front", &info.app_id); + app.toplevels.remove(pos); + app.toplevels.push_front((handle, info)); + } else { + app.toplevels[pos].1 = info; + } + } else { + tracing::warn!("ToplevelEvent::Update, no toplevel found"); + app.toplevels.push_front((handle, info)); } } } @@ -94,7 +114,8 @@ struct App { locales: Vec, desktop_entries: Vec>, ids_to_ignore: Vec, - toplevels: Vec<(ZcosmicToplevelHandleV1, ToplevelInfo)>, + // XXX: use LinkedList? + toplevels: VecDeque<(ZcosmicToplevelHandleV1, ToplevelInfo)>, calloop_tx: calloop::channel::Sender, tx: W, } @@ -118,7 +139,7 @@ impl App { locales, desktop_entries, ids_to_ignore: Vec::new(), - toplevels: Vec::new(), + toplevels: VecDeque::new(), calloop_tx, tx, }, diff --git a/plugins/src/cosmic_toplevel/plugin.ron b/plugins/src/cosmic_toplevel/plugin.ron index 7b9dd13..217fdc4 100644 --- a/plugins/src/cosmic_toplevel/plugin.ron +++ b/plugins/src/cosmic_toplevel/plugin.ron @@ -4,4 +4,5 @@ query: (persistent: true, priority: High), bin: (path: "cosmic-toplevel"), icon: Name("focus-windows-symbolic"), + long_lived: true, ) \ No newline at end of file diff --git a/plugins/src/desktop_entries/mod.rs b/plugins/src/desktop_entries/mod.rs index bbd8293..c25b300 100644 --- a/plugins/src/desktop_entries/mod.rs +++ b/plugins/src/desktop_entries/mod.rs @@ -9,11 +9,13 @@ use futures::StreamExt; use pop_launcher::*; use std::borrow::Cow; use tokio::io::AsyncWrite; +use tracing::info; use utils::get_description; pub(crate) mod utils; pub async fn main() { + info!("starting desktop entries"); let mut app = App::new(async_stdout()); app.reload().await; diff --git a/service/src/lib.rs b/service/src/lib.rs index 88ceaf5..b3491d8 100644 --- a/service/src/lib.rs +++ b/service/src/lib.rs @@ -201,6 +201,15 @@ impl + Unpin> Service { break; } + Request::Close => { + for (_key, plugin) in self.plugins.iter_mut() { + if !plugin.config.long_lived { + let tx = plugin.sender_exec(); + _ = tx.send_async(Request::Exit).await; + plugin.sender_drop(); + } + } + } } } @@ -465,6 +474,8 @@ impl + Unpin> Service { } } } else { + self.no_sort = query.is_empty(); + for plugin_id in query_queue { if let Some(plugin) = self.plugins.get_mut(plugin_id) { if plugin diff --git a/service/src/plugins/config.rs b/service/src/plugins/config.rs index 5be55e4..cd2d465 100644 --- a/service/src/plugins/config.rs +++ b/service/src/plugins/config.rs @@ -30,6 +30,9 @@ pub struct PluginConfig { #[serde(default)] pub history: bool, + + #[serde(default)] + pub long_lived: bool, } #[derive(Debug, Default, Deserialize, Clone)] diff --git a/service/src/plugins/help.rs b/service/src/plugins/help.rs index 2abff6e..1dbf1bc 100644 --- a/service/src/plugins/help.rs +++ b/service/src/plugins/help.rs @@ -24,6 +24,7 @@ pub const CONFIG: PluginConfig = PluginConfig { }, icon: Some(IconSource::Name(Cow::Borrowed("system-help-symbolic"))), history: false, + long_lived: false, }; pub struct HelpPlugin { pub id: usize, diff --git a/service/src/plugins/mod.rs b/service/src/plugins/mod.rs index c41ead5..24c1078 100644 --- a/service/src/plugins/mod.rs +++ b/service/src/plugins/mod.rs @@ -60,6 +60,9 @@ where self.exit(); break; } + Request::Close => { + self.exit(); + } } } diff --git a/src/lib.rs b/src/lib.rs index e626e9d..c63fb70 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -137,6 +137,9 @@ pub enum Request { Context(Indice), /// Request to end the service. Exit, + /// The frontend was closed and the service should release resources + /// and prepare for the next query + Close, /// Requests to cancel any active searches. Interrupt, /// Request to close the selected item. diff --git a/toolkit/src/plugin_trait.rs b/toolkit/src/plugin_trait.rs index cb5f4db..edaa2f6 100644 --- a/toolkit/src/plugin_trait.rs +++ b/toolkit/src/plugin_trait.rs @@ -89,6 +89,10 @@ where self.exit(); break; } + Request::Close => { + self.exit(); + break; + } }, Err(why) => tracing::error!("Malformed json request: {why}"), }