Skip to content

Commit f089d3e

Browse files
alex-ds13LGUG2Z
authored andcommitted
feat(wm): allow stopping without restoring windows
This commit creates a new `SocketMessage` called `StopIgnoreRestore` which makes komorebi stop without calling `window.restore()` on all windows. This way every maximized window will stay maximized once you start komorebi again and it is able to use the previous `State`. If it fails to restore the previous state you might have to call `komorebic restore-windows` in case you had hidden windows, for example when when using the `window_hiding_behaviour` as `Hide`, or you can simply unminimize them if you were using `Cloak` or `Minimize`.
1 parent 5dbf0f1 commit f089d3e

File tree

5 files changed

+59
-38
lines changed

5 files changed

+59
-38
lines changed

komorebi/src/core/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ pub enum SocketMessage {
105105
NewWorkspace,
106106
ToggleTiling,
107107
Stop,
108+
StopIgnoreRestore,
108109
TogglePause,
109110
Retile,
110111
RetileWithResizeDimensions,

komorebi/src/main.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -307,7 +307,7 @@ fn main() -> Result<()> {
307307

308308
ANIMATION_ENABLED_PER_ANIMATION.lock().clear();
309309
ANIMATION_ENABLED_GLOBAL.store(false, Ordering::SeqCst);
310-
wm.lock().restore_all_windows()?;
310+
wm.lock().restore_all_windows(false)?;
311311
AnimationEngine::wait_for_all_animations();
312312

313313
if WindowsApi::focus_follows_mouse()? {

komorebi/src/process_command.rs

+5-34
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
use std::collections::HashMap;
2-
use std::env::temp_dir;
32
use std::fs::File;
43
use std::fs::OpenOptions;
54
use std::io::BufRead;
65
use std::io::BufReader;
76
use std::io::Read;
8-
use std::net::Shutdown;
97
use std::net::TcpListener;
108
use std::net::TcpStream;
119
use std::num::NonZeroUsize;
@@ -23,7 +21,6 @@ use schemars::gen::SchemaSettings;
2321
use schemars::schema_for;
2422
use uds_windows::UnixStream;
2523

26-
use crate::animation::AnimationEngine;
2724
use crate::animation::ANIMATION_DURATION_PER_ANIMATION;
2825
use crate::animation::ANIMATION_ENABLED_PER_ANIMATION;
2926
use crate::animation::ANIMATION_STYLE_PER_ANIMATION;
@@ -913,36 +910,10 @@ impl WindowManager {
913910
}
914911
}
915912
SocketMessage::Stop => {
916-
tracing::info!(
917-
"received stop command, restoring all hidden windows and terminating process"
918-
);
919-
920-
let state = &window_manager::State::from(&*self);
921-
std::fs::write(
922-
temp_dir().join("komorebi.state.json"),
923-
serde_json::to_string_pretty(&state)?,
924-
)?;
925-
926-
ANIMATION_ENABLED_PER_ANIMATION.lock().clear();
927-
ANIMATION_ENABLED_GLOBAL.store(false, Ordering::SeqCst);
928-
self.restore_all_windows()?;
929-
AnimationEngine::wait_for_all_animations();
930-
931-
if WindowsApi::focus_follows_mouse()? {
932-
WindowsApi::disable_focus_follows_mouse()?;
933-
}
934-
935-
let sockets = SUBSCRIPTION_SOCKETS.lock();
936-
for path in (*sockets).values() {
937-
if let Ok(stream) = UnixStream::connect(path) {
938-
stream.shutdown(Shutdown::Both)?;
939-
}
940-
}
941-
942-
let socket = DATA_DIR.join("komorebi.sock");
943-
let _ = std::fs::remove_file(socket);
944-
945-
std::process::exit(0)
913+
self.stop(false)?;
914+
}
915+
SocketMessage::StopIgnoreRestore => {
916+
self.stop(true)?;
946917
}
947918
SocketMessage::MonitorIndexPreference(index_preference, left, top, right, bottom) => {
948919
let mut monitor_index_preferences = MONITOR_INDEX_PREFERENCES.lock();
@@ -1257,7 +1228,7 @@ impl WindowManager {
12571228
// Pause so that restored windows come to the foreground from all workspaces
12581229
self.is_paused = true;
12591230
// Bring all windows to the foreground
1260-
self.restore_all_windows()?;
1231+
self.restore_all_windows(false)?;
12611232

12621233
// Create a new wm from the config path
12631234
let mut wm = StaticConfig::preload(

komorebi/src/window_manager.rs

+44-2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use std::collections::HashSet;
33
use std::collections::VecDeque;
44
use std::env::temp_dir;
55
use std::io::ErrorKind;
6+
use std::net::Shutdown;
67
use std::num::NonZeroUsize;
78
use std::path::Path;
89
use std::path::PathBuf;
@@ -21,7 +22,11 @@ use schemars::JsonSchema;
2122
use serde::Deserialize;
2223
use serde::Serialize;
2324
use uds_windows::UnixListener;
25+
use uds_windows::UnixStream;
2426

27+
use crate::animation::AnimationEngine;
28+
use crate::animation::ANIMATION_ENABLED_GLOBAL;
29+
use crate::animation::ANIMATION_ENABLED_PER_ANIMATION;
2530
use crate::core::config_generation::MatchingRule;
2631
use crate::core::custom_layout::CustomLayout;
2732
use crate::core::Arrangement;
@@ -85,6 +90,7 @@ use crate::NO_TITLEBAR;
8590
use crate::OBJECT_NAME_CHANGE_ON_LAUNCH;
8691
use crate::REGEX_IDENTIFIERS;
8792
use crate::REMOVE_TITLEBARS;
93+
use crate::SUBSCRIPTION_SOCKETS;
8894
use crate::TRANSPARENCY_BLACKLIST;
8995
use crate::TRAY_AND_MULTI_WINDOW_IDENTIFIERS;
9096
use crate::WORKSPACE_MATCHING_RULES;
@@ -1386,7 +1392,41 @@ impl WindowManager {
13861392
}
13871393

13881394
#[tracing::instrument(skip(self))]
1389-
pub fn restore_all_windows(&mut self) -> Result<()> {
1395+
pub fn stop(&mut self, ignore_restore: bool) -> Result<()> {
1396+
tracing::info!(
1397+
"received stop command, restoring all hidden windows and terminating process"
1398+
);
1399+
1400+
let state = &State::from(&*self);
1401+
std::fs::write(
1402+
temp_dir().join("komorebi.state.json"),
1403+
serde_json::to_string_pretty(&state)?,
1404+
)?;
1405+
1406+
ANIMATION_ENABLED_PER_ANIMATION.lock().clear();
1407+
ANIMATION_ENABLED_GLOBAL.store(false, Ordering::SeqCst);
1408+
self.restore_all_windows(ignore_restore)?;
1409+
AnimationEngine::wait_for_all_animations();
1410+
1411+
if WindowsApi::focus_follows_mouse()? {
1412+
WindowsApi::disable_focus_follows_mouse()?;
1413+
}
1414+
1415+
let sockets = SUBSCRIPTION_SOCKETS.lock();
1416+
for path in (*sockets).values() {
1417+
if let Ok(stream) = UnixStream::connect(path) {
1418+
stream.shutdown(Shutdown::Both)?;
1419+
}
1420+
}
1421+
1422+
let socket = DATA_DIR.join("komorebi.sock");
1423+
let _ = std::fs::remove_file(socket);
1424+
1425+
std::process::exit(0)
1426+
}
1427+
1428+
#[tracing::instrument(skip(self))]
1429+
pub fn restore_all_windows(&mut self, ignore_restore: bool) -> Result<()> {
13901430
tracing::info!("restoring all hidden windows");
13911431

13921432
let no_titlebar = NO_TITLEBAR.lock();
@@ -1417,7 +1457,9 @@ impl WindowManager {
14171457
window.remove_accent()?;
14181458
}
14191459

1420-
window.restore();
1460+
if !ignore_restore {
1461+
window.restore();
1462+
}
14211463
}
14221464
}
14231465
}

komorebic/src/main.rs

+8-1
Original file line numberDiff line numberDiff line change
@@ -801,6 +801,9 @@ struct Stop {
801801
/// Stop masir if it is running as a background process
802802
#[clap(long)]
803803
masir: bool,
804+
/// Do not restore windows after stopping komorebi
805+
#[clap(long, hide = true)]
806+
ignore_restore: bool,
804807
}
805808

806809
#[derive(Parser)]
@@ -2300,7 +2303,11 @@ if (Get-Command Get-CimInstance -ErrorAction SilentlyContinue) {
23002303
}
23012304
}
23022305

2303-
send_message(&SocketMessage::Stop)?;
2306+
if arg.ignore_restore {
2307+
send_message(&SocketMessage::StopIgnoreRestore)?;
2308+
} else {
2309+
send_message(&SocketMessage::Stop)?;
2310+
}
23042311
let mut system = sysinfo::System::new_all();
23052312
system.refresh_processes(ProcessesToUpdate::All);
23062313

0 commit comments

Comments
 (0)