From 80bcb51f7508c08b6e7bcae4cf4aa35ac3db61cc Mon Sep 17 00:00:00 2001 From: LGUG2Z Date: Tue, 21 Sep 2021 17:12:16 -0700 Subject: [PATCH] feat(wm): add quicksaving/loading of sizes/layouts This commit adds two new komorebic commands to quicksave and quickload BSP layouts with custom resize dimensions. The quicksave file is stored at ${Env:TEMP}/komorebi.quicksave.json, and is a Vec> serialized to JSON. If a user tries to quickload without a quicksave file being present, an error will be logged. At this point there is only one quicksave file which will always be overwritten whenever the quicksave command is called. Both commands will only operate on the focused workspace of the focused monitor. This means that you can quicksave a layout on one workspace, and then quickload it onto multiple other workspaces (individually) on the same or other monitors. If the number of elements in the deserialized Vec is greater than the number of containers on a workspace, the Vec will be truncated when Workspace.update is run, and similarly if the number of elements is less than the number of containers on a workspace, the Vec will be extended by the difference using None values. resolve #39 --- README.md | 3 +++ komorebi-core/src/lib.rs | 2 ++ komorebi.sample.with.lib.ahk | 8 ++++++++ komorebi/src/process_command.rs | 36 +++++++++++++++++++++++++++++++++ komorebi/src/workspace.rs | 2 +- komorebic.lib.sample.ahk | 8 ++++++++ komorebic/src/main.rs | 10 +++++++++ 7 files changed, 68 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 8fa652b7..401075ff 100644 --- a/README.md +++ b/README.md @@ -198,6 +198,8 @@ each command. start Start komorebi.exe as a background process stop Stop the komorebi.exe process and restore all hidden windows state Show a JSON representation of the current window manager state +quick-save Quicksave the current resize layout dimensions +quick-load Load the last quicksaved resize layout dimensions query Query the current window manager state log Tail komorebi.exe's process logs (cancel with Ctrl-C) focus Change focus to the window in the specified direction @@ -272,6 +274,7 @@ used [is available here](komorebi.sample.with.lib.ahk). - [x] Mouse follows focused container - [x] Resize window container in direction - [ ] Resize child window containers by split ratio +- [x] Quicksave and quickload layouts with resize dimensions - [x] Mouse drag to swap window container position - [x] Mouse drag to resize window container - [x] Configurable workspace and container gaps diff --git a/komorebi-core/src/lib.rs b/komorebi-core/src/lib.rs index f34dbeca..dbe001df 100644 --- a/komorebi-core/src/lib.rs +++ b/komorebi-core/src/lib.rs @@ -52,6 +52,8 @@ pub enum SocketMessage { Stop, TogglePause, Retile, + QuickSave, + QuickLoad, FocusMonitorNumber(usize), FocusWorkspaceNumber(usize), ContainerPadding(usize, usize, i32), diff --git a/komorebi.sample.with.lib.ahk b/komorebi.sample.with.lib.ahk index d580d117..89c39350 100644 --- a/komorebi.sample.with.lib.ahk +++ b/komorebi.sample.with.lib.ahk @@ -40,16 +40,24 @@ FloatRule("exe", "Wally.exe") FloatRule("exe", "wincompose.exe") FloatRule("exe", "1Password.exe") FloatRule("exe", "Wox.exe") +FloatRule("exe", "ddm.exe") +FloatRule("class", "Chrome_RenderWidgetHostHWND") ; GOG Electron invisible overlay +FloatRule("class", "CEFCLIENT") ; Identify Minimize-to-Tray Applications IdentifyTrayApplication("exe", "Discord.exe") IdentifyTrayApplication("exe", "Spotify.exe") +IdentifyTrayApplication("exe", "GalaxyClient.exe") ; Identify Electron applications with overflowing borders IdentifyBorderOverflow("exe", "Discord.exe") IdentifyBorderOverflow("exe", "Spotify.exe") +IdentifyBorderOverflow("exe", "GalaxyClient.exe") IdentifyBorderOverflow("class", "ZPFTEWndClass") +; Identify applications to be forcibly managed +ManageRule("exe", "GalaxyClient.exe") + ; Change the focused window, Alt + Vim direction keys !h:: Focus("left") diff --git a/komorebi/src/process_command.rs b/komorebi/src/process_command.rs index 9e34704a..6f1f4ad6 100644 --- a/komorebi/src/process_command.rs +++ b/komorebi/src/process_command.rs @@ -1,3 +1,5 @@ +use std::fs::File; +use std::fs::OpenOptions; use std::io::BufRead; use std::io::BufReader; use std::io::Write; @@ -12,6 +14,7 @@ use parking_lot::Mutex; use uds_windows::UnixStream; use komorebi_core::FocusFollowsMouseImplementation; +use komorebi_core::Rect; use komorebi_core::SocketMessage; use komorebi_core::StateQuery; @@ -326,6 +329,39 @@ impl WindowManager { self.invisible_borders = rect; self.retile_all()?; } + SocketMessage::QuickSave => { + let workspace = self.focused_workspace()?; + let resize = workspace.resize_dimensions(); + + let mut quicksave_json = std::env::temp_dir(); + quicksave_json.push("komorebi.quicksave.json"); + + let file = OpenOptions::new() + .write(true) + .truncate(true) + .create(true) + .open(quicksave_json)?; + + serde_json::to_writer_pretty(&file, &resize)?; + } + SocketMessage::QuickLoad => { + let workspace = self.focused_workspace_mut()?; + + let mut quicksave_json = std::env::temp_dir(); + quicksave_json.push("komorebi.quicksave.json"); + + let file = File::open(&quicksave_json).map_err(|_| { + anyhow!( + "no quicksave found at {}", + quicksave_json.display().to_string() + ) + })?; + + let resize: Vec> = serde_json::from_reader(file)?; + + workspace.set_resize_dimensions(resize); + self.update_focused_workspace(false)?; + } }; tracing::info!("processed"); diff --git a/komorebi/src/workspace.rs b/komorebi/src/workspace.rs index c91b4820..f4c6a2f1 100644 --- a/komorebi/src/workspace.rs +++ b/komorebi/src/workspace.rs @@ -48,7 +48,7 @@ pub struct Workspace { #[serde(skip_serializing)] #[getset(get = "pub", set = "pub")] latest_layout: Vec, - #[getset(get = "pub", get_mut = "pub")] + #[getset(get = "pub", get_mut = "pub", set = "pub")] resize_dimensions: Vec>, #[getset(get = "pub", set = "pub")] tile: bool, diff --git a/komorebic.lib.sample.ahk b/komorebic.lib.sample.ahk index 55f9dab5..f7f0ea42 100644 --- a/komorebic.lib.sample.ahk +++ b/komorebic.lib.sample.ahk @@ -12,6 +12,14 @@ State() { Run, komorebic.exe state, , Hide } +QuickSave() { + Run, komorebic.exe quick-save, , Hide +} + +QuickLoad() { + Run, komorebic.exe quick-load, , Hide +} + Query(state_query) { Run, komorebic.exe query %state_query%, , Hide } diff --git a/komorebic/src/main.rs b/komorebic/src/main.rs index 365c32d1..658270c6 100644 --- a/komorebic/src/main.rs +++ b/komorebic/src/main.rs @@ -283,6 +283,10 @@ enum SubCommand { Stop, /// Show a JSON representation of the current window manager state State, + /// Quicksave the current resize layout dimensions + QuickSave, + /// Load the last quicksaved resize layout dimensions + QuickLoad, /// Query the current window manager state #[clap(setting = AppSettings::ArgRequiredElseHelp)] Query(Query), @@ -767,6 +771,12 @@ fn main() -> Result<()> { SubCommand::Unmanage => { send_message(&*SocketMessage::UnmanageFocusedWindow.as_bytes()?)?; } + SubCommand::QuickSave => { + send_message(&*SocketMessage::QuickSave.as_bytes()?)?; + } + SubCommand::QuickLoad => { + send_message(&*SocketMessage::QuickLoad.as_bytes()?)?; + } } Ok(())