diff --git a/crates/eww/src/app.rs b/crates/eww/src/app.rs index 4900ddd..2e9aad9 100644 --- a/crates/eww/src/app.rs +++ b/crates/eww/src/app.rs @@ -332,7 +332,8 @@ impl App { let mut eww_window = initialize_window(monitor_geometry, root_widget, window_def, window_scope)?; eww_window.gtk_window.style_context().add_class(&window_name.to_string()); - // initialize script var handlers for variables that where not used before opening this window. + // initialize script var handlers for variables. As starting a scriptvar with the script_var_handler is idempodent, + // we can just start script vars that are already running without causing issues // TODO maybe this could be handled by having a track_newly_used_variables function in the scope tree? for used_var in self.scope_graph.borrow().variables_used_in_self_or_subscopes_of(eww_window.scope_index) { if let Ok(script_var) = self.eww_config.get_script_var(&used_var) { @@ -348,9 +349,8 @@ impl App { // Generally, this should get disconnected before the gtk window gets destroyed. // It serves as a fallback for when the window is closed manually. let (response_sender, _) = daemon_response::create_pair(); - if let Err(err) = app_evt_sender - .send(DaemonCommand::CloseWindows { windows: vec![window_name.clone()], sender: response_sender }) - { + let command = DaemonCommand::CloseWindows { windows: vec![window_name.clone()], sender: response_sender }; + if let Err(err) = app_evt_sender.send(command) { log::error!("Error sending close window command to daemon after gtk window destroy event: {}", err); } } diff --git a/crates/eww/src/script_var_handler.rs b/crates/eww/src/script_var_handler.rs index b78f4a8..3bc7541 100644 --- a/crates/eww/src/script_var_handler.rs +++ b/crates/eww/src/script_var_handler.rs @@ -61,6 +61,8 @@ pub struct ScriptVarHandlerHandle { impl ScriptVarHandlerHandle { /// Add a new script-var that should be executed. + /// This is idempodent, meaning that running a definition that already has a script_var attached which is running + /// won't do anything. pub fn add(&self, script_var: ScriptVarDefinition) { crate::print_result_err!( "while forwarding instruction to script-var handler", @@ -204,8 +206,16 @@ impl ListenVarHandler { Ok(handler) } + /// Start a listen-var. Starting a variable that is already running will not do anything. async fn start(&mut self, var: ListenScriptVar) { log::debug!("starting listen-var {}", &var.name); + + // Make sure the same listenvar is never started twice, + // as that would cause eww to not clean up the older listenvar on window close. + if self.listen_process_handles.contains_key(&var.name) { + return; + } + let cancellation_token = CancellationToken::new(); self.listen_process_handles.insert(var.name.clone(), cancellation_token.clone()); @@ -264,7 +274,7 @@ async fn terminate_handle(mut child: tokio::process::Child) { if let Some(id) = child.id() { let _ = signal::killpg(Pid::from_raw(id as i32), signal::SIGTERM); tokio::select! { - _ = child.wait() => {}, + _ = child.wait() => { }, _ = tokio::time::sleep(std::time::Duration::from_secs(10)) => { let _ = child.kill().await; }