mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-04-29 07:27:03 +02:00
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`.
This commit is contained in:
@@ -105,6 +105,7 @@ pub enum SocketMessage {
|
|||||||
NewWorkspace,
|
NewWorkspace,
|
||||||
ToggleTiling,
|
ToggleTiling,
|
||||||
Stop,
|
Stop,
|
||||||
|
StopIgnoreRestore,
|
||||||
TogglePause,
|
TogglePause,
|
||||||
Retile,
|
Retile,
|
||||||
RetileWithResizeDimensions,
|
RetileWithResizeDimensions,
|
||||||
|
|||||||
@@ -307,7 +307,7 @@ fn main() -> Result<()> {
|
|||||||
|
|
||||||
ANIMATION_ENABLED_PER_ANIMATION.lock().clear();
|
ANIMATION_ENABLED_PER_ANIMATION.lock().clear();
|
||||||
ANIMATION_ENABLED_GLOBAL.store(false, Ordering::SeqCst);
|
ANIMATION_ENABLED_GLOBAL.store(false, Ordering::SeqCst);
|
||||||
wm.lock().restore_all_windows()?;
|
wm.lock().restore_all_windows(false)?;
|
||||||
AnimationEngine::wait_for_all_animations();
|
AnimationEngine::wait_for_all_animations();
|
||||||
|
|
||||||
if WindowsApi::focus_follows_mouse()? {
|
if WindowsApi::focus_follows_mouse()? {
|
||||||
|
|||||||
@@ -1,11 +1,9 @@
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::env::temp_dir;
|
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::fs::OpenOptions;
|
use std::fs::OpenOptions;
|
||||||
use std::io::BufRead;
|
use std::io::BufRead;
|
||||||
use std::io::BufReader;
|
use std::io::BufReader;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
use std::net::Shutdown;
|
|
||||||
use std::net::TcpListener;
|
use std::net::TcpListener;
|
||||||
use std::net::TcpStream;
|
use std::net::TcpStream;
|
||||||
use std::num::NonZeroUsize;
|
use std::num::NonZeroUsize;
|
||||||
@@ -23,7 +21,6 @@ use schemars::gen::SchemaSettings;
|
|||||||
use schemars::schema_for;
|
use schemars::schema_for;
|
||||||
use uds_windows::UnixStream;
|
use uds_windows::UnixStream;
|
||||||
|
|
||||||
use crate::animation::AnimationEngine;
|
|
||||||
use crate::animation::ANIMATION_DURATION_PER_ANIMATION;
|
use crate::animation::ANIMATION_DURATION_PER_ANIMATION;
|
||||||
use crate::animation::ANIMATION_ENABLED_PER_ANIMATION;
|
use crate::animation::ANIMATION_ENABLED_PER_ANIMATION;
|
||||||
use crate::animation::ANIMATION_STYLE_PER_ANIMATION;
|
use crate::animation::ANIMATION_STYLE_PER_ANIMATION;
|
||||||
@@ -913,36 +910,10 @@ impl WindowManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
SocketMessage::Stop => {
|
SocketMessage::Stop => {
|
||||||
tracing::info!(
|
self.stop(false)?;
|
||||||
"received stop command, restoring all hidden windows and terminating process"
|
}
|
||||||
);
|
SocketMessage::StopIgnoreRestore => {
|
||||||
|
self.stop(true)?;
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
SocketMessage::MonitorIndexPreference(index_preference, left, top, right, bottom) => {
|
SocketMessage::MonitorIndexPreference(index_preference, left, top, right, bottom) => {
|
||||||
let mut monitor_index_preferences = MONITOR_INDEX_PREFERENCES.lock();
|
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
|
// Pause so that restored windows come to the foreground from all workspaces
|
||||||
self.is_paused = true;
|
self.is_paused = true;
|
||||||
// Bring all windows to the foreground
|
// Bring all windows to the foreground
|
||||||
self.restore_all_windows()?;
|
self.restore_all_windows(false)?;
|
||||||
|
|
||||||
// Create a new wm from the config path
|
// Create a new wm from the config path
|
||||||
let mut wm = StaticConfig::preload(
|
let mut wm = StaticConfig::preload(
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ use std::collections::HashSet;
|
|||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::env::temp_dir;
|
use std::env::temp_dir;
|
||||||
use std::io::ErrorKind;
|
use std::io::ErrorKind;
|
||||||
|
use std::net::Shutdown;
|
||||||
use std::num::NonZeroUsize;
|
use std::num::NonZeroUsize;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
@@ -21,7 +22,11 @@ use schemars::JsonSchema;
|
|||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use uds_windows::UnixListener;
|
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::config_generation::MatchingRule;
|
||||||
use crate::core::custom_layout::CustomLayout;
|
use crate::core::custom_layout::CustomLayout;
|
||||||
use crate::core::Arrangement;
|
use crate::core::Arrangement;
|
||||||
@@ -85,6 +90,7 @@ use crate::NO_TITLEBAR;
|
|||||||
use crate::OBJECT_NAME_CHANGE_ON_LAUNCH;
|
use crate::OBJECT_NAME_CHANGE_ON_LAUNCH;
|
||||||
use crate::REGEX_IDENTIFIERS;
|
use crate::REGEX_IDENTIFIERS;
|
||||||
use crate::REMOVE_TITLEBARS;
|
use crate::REMOVE_TITLEBARS;
|
||||||
|
use crate::SUBSCRIPTION_SOCKETS;
|
||||||
use crate::TRANSPARENCY_BLACKLIST;
|
use crate::TRANSPARENCY_BLACKLIST;
|
||||||
use crate::TRAY_AND_MULTI_WINDOW_IDENTIFIERS;
|
use crate::TRAY_AND_MULTI_WINDOW_IDENTIFIERS;
|
||||||
use crate::WORKSPACE_MATCHING_RULES;
|
use crate::WORKSPACE_MATCHING_RULES;
|
||||||
@@ -1386,7 +1392,41 @@ impl WindowManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip(self))]
|
#[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");
|
tracing::info!("restoring all hidden windows");
|
||||||
|
|
||||||
let no_titlebar = NO_TITLEBAR.lock();
|
let no_titlebar = NO_TITLEBAR.lock();
|
||||||
@@ -1417,7 +1457,9 @@ impl WindowManager {
|
|||||||
window.remove_accent()?;
|
window.remove_accent()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.restore();
|
if !ignore_restore {
|
||||||
|
window.restore();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -801,6 +801,9 @@ struct Stop {
|
|||||||
/// Stop masir if it is running as a background process
|
/// Stop masir if it is running as a background process
|
||||||
#[clap(long)]
|
#[clap(long)]
|
||||||
masir: bool,
|
masir: bool,
|
||||||
|
/// Do not restore windows after stopping komorebi
|
||||||
|
#[clap(long, hide = true)]
|
||||||
|
ignore_restore: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Parser)]
|
#[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();
|
let mut system = sysinfo::System::new_all();
|
||||||
system.refresh_processes(ProcessesToUpdate::All);
|
system.refresh_processes(ProcessesToUpdate::All);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user