diff --git a/komorebi/src/core/mod.rs b/komorebi/src/core/mod.rs index d4e14966..4d733fd4 100644 --- a/komorebi/src/core/mod.rs +++ b/komorebi/src/core/mod.rs @@ -105,6 +105,7 @@ pub enum SocketMessage { NewWorkspace, ToggleTiling, Stop, + StopIgnoreRestore, TogglePause, Retile, RetileWithResizeDimensions, diff --git a/komorebi/src/main.rs b/komorebi/src/main.rs index a2a64262..20af3242 100644 --- a/komorebi/src/main.rs +++ b/komorebi/src/main.rs @@ -307,7 +307,7 @@ fn main() -> Result<()> { ANIMATION_ENABLED_PER_ANIMATION.lock().clear(); ANIMATION_ENABLED_GLOBAL.store(false, Ordering::SeqCst); - wm.lock().restore_all_windows()?; + wm.lock().restore_all_windows(false)?; AnimationEngine::wait_for_all_animations(); if WindowsApi::focus_follows_mouse()? { diff --git a/komorebi/src/process_command.rs b/komorebi/src/process_command.rs index da5b89b5..a1a19531 100644 --- a/komorebi/src/process_command.rs +++ b/komorebi/src/process_command.rs @@ -1,11 +1,9 @@ use std::collections::HashMap; -use std::env::temp_dir; use std::fs::File; use std::fs::OpenOptions; use std::io::BufRead; use std::io::BufReader; use std::io::Read; -use std::net::Shutdown; use std::net::TcpListener; use std::net::TcpStream; use std::num::NonZeroUsize; @@ -23,7 +21,6 @@ use schemars::gen::SchemaSettings; use schemars::schema_for; use uds_windows::UnixStream; -use crate::animation::AnimationEngine; use crate::animation::ANIMATION_DURATION_PER_ANIMATION; use crate::animation::ANIMATION_ENABLED_PER_ANIMATION; use crate::animation::ANIMATION_STYLE_PER_ANIMATION; @@ -913,36 +910,10 @@ impl WindowManager { } } SocketMessage::Stop => { - tracing::info!( - "received stop command, restoring all hidden windows and terminating process" - ); - - let state = &window_manager::State::from(&*self); - std::fs::write( - temp_dir().join("komorebi.state.json"), - serde_json::to_string_pretty(&state)?, - )?; - - ANIMATION_ENABLED_PER_ANIMATION.lock().clear(); - ANIMATION_ENABLED_GLOBAL.store(false, Ordering::SeqCst); - self.restore_all_windows()?; - AnimationEngine::wait_for_all_animations(); - - if WindowsApi::focus_follows_mouse()? { - WindowsApi::disable_focus_follows_mouse()?; - } - - let sockets = SUBSCRIPTION_SOCKETS.lock(); - for path in (*sockets).values() { - if let Ok(stream) = UnixStream::connect(path) { - stream.shutdown(Shutdown::Both)?; - } - } - - let socket = DATA_DIR.join("komorebi.sock"); - let _ = std::fs::remove_file(socket); - - std::process::exit(0) + self.stop(false)?; + } + SocketMessage::StopIgnoreRestore => { + self.stop(true)?; } SocketMessage::MonitorIndexPreference(index_preference, left, top, right, bottom) => { let mut monitor_index_preferences = MONITOR_INDEX_PREFERENCES.lock(); @@ -1257,7 +1228,7 @@ impl WindowManager { // Pause so that restored windows come to the foreground from all workspaces self.is_paused = true; // Bring all windows to the foreground - self.restore_all_windows()?; + self.restore_all_windows(false)?; // Create a new wm from the config path let mut wm = StaticConfig::preload( diff --git a/komorebi/src/window_manager.rs b/komorebi/src/window_manager.rs index 75da084d..95446733 100644 --- a/komorebi/src/window_manager.rs +++ b/komorebi/src/window_manager.rs @@ -3,6 +3,7 @@ use std::collections::HashSet; use std::collections::VecDeque; use std::env::temp_dir; use std::io::ErrorKind; +use std::net::Shutdown; use std::num::NonZeroUsize; use std::path::Path; use std::path::PathBuf; @@ -21,7 +22,11 @@ use schemars::JsonSchema; use serde::Deserialize; use serde::Serialize; use uds_windows::UnixListener; +use uds_windows::UnixStream; +use crate::animation::AnimationEngine; +use crate::animation::ANIMATION_ENABLED_GLOBAL; +use crate::animation::ANIMATION_ENABLED_PER_ANIMATION; use crate::core::config_generation::MatchingRule; use crate::core::custom_layout::CustomLayout; use crate::core::Arrangement; @@ -85,6 +90,7 @@ use crate::NO_TITLEBAR; use crate::OBJECT_NAME_CHANGE_ON_LAUNCH; use crate::REGEX_IDENTIFIERS; use crate::REMOVE_TITLEBARS; +use crate::SUBSCRIPTION_SOCKETS; use crate::TRANSPARENCY_BLACKLIST; use crate::TRAY_AND_MULTI_WINDOW_IDENTIFIERS; use crate::WORKSPACE_MATCHING_RULES; @@ -1386,7 +1392,41 @@ impl WindowManager { } #[tracing::instrument(skip(self))] - pub fn restore_all_windows(&mut self) -> Result<()> { + pub fn stop(&mut self, ignore_restore: bool) -> Result<()> { + tracing::info!( + "received stop command, restoring all hidden windows and terminating process" + ); + + let state = &State::from(&*self); + std::fs::write( + temp_dir().join("komorebi.state.json"), + serde_json::to_string_pretty(&state)?, + )?; + + ANIMATION_ENABLED_PER_ANIMATION.lock().clear(); + ANIMATION_ENABLED_GLOBAL.store(false, Ordering::SeqCst); + self.restore_all_windows(ignore_restore)?; + AnimationEngine::wait_for_all_animations(); + + if WindowsApi::focus_follows_mouse()? { + WindowsApi::disable_focus_follows_mouse()?; + } + + let sockets = SUBSCRIPTION_SOCKETS.lock(); + for path in (*sockets).values() { + if let Ok(stream) = UnixStream::connect(path) { + stream.shutdown(Shutdown::Both)?; + } + } + + let socket = DATA_DIR.join("komorebi.sock"); + let _ = std::fs::remove_file(socket); + + std::process::exit(0) + } + + #[tracing::instrument(skip(self))] + pub fn restore_all_windows(&mut self, ignore_restore: bool) -> Result<()> { tracing::info!("restoring all hidden windows"); let no_titlebar = NO_TITLEBAR.lock(); @@ -1417,7 +1457,9 @@ impl WindowManager { window.remove_accent()?; } - window.restore(); + if !ignore_restore { + window.restore(); + } } } } diff --git a/komorebic/src/main.rs b/komorebic/src/main.rs index 309204a5..acbde19c 100644 --- a/komorebic/src/main.rs +++ b/komorebic/src/main.rs @@ -801,6 +801,9 @@ struct Stop { /// Stop masir if it is running as a background process #[clap(long)] masir: bool, + /// Do not restore windows after stopping komorebi + #[clap(long, hide = true)] + ignore_restore: bool, } #[derive(Parser)] @@ -2300,7 +2303,11 @@ if (Get-Command Get-CimInstance -ErrorAction SilentlyContinue) { } } - send_message(&SocketMessage::Stop)?; + if arg.ignore_restore { + send_message(&SocketMessage::StopIgnoreRestore)?; + } else { + send_message(&SocketMessage::Stop)?; + } let mut system = sysinfo::System::new_all(); system.refresh_processes(ProcessesToUpdate::All);