mirror of
https://github.com/LGUG2Z/komorebi.git
synced 2026-03-18 07:23:57 +01:00
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<Option<Rect>>
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
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -52,6 +52,8 @@ pub enum SocketMessage {
|
||||
Stop,
|
||||
TogglePause,
|
||||
Retile,
|
||||
QuickSave,
|
||||
QuickLoad,
|
||||
FocusMonitorNumber(usize),
|
||||
FocusWorkspaceNumber(usize),
|
||||
ContainerPadding(usize, usize, i32),
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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<Option<Rect>> = serde_json::from_reader(file)?;
|
||||
|
||||
workspace.set_resize_dimensions(resize);
|
||||
self.update_focused_workspace(false)?;
|
||||
}
|
||||
};
|
||||
|
||||
tracing::info!("processed");
|
||||
|
||||
@@ -48,7 +48,7 @@ pub struct Workspace {
|
||||
#[serde(skip_serializing)]
|
||||
#[getset(get = "pub", set = "pub")]
|
||||
latest_layout: Vec<Rect>,
|
||||
#[getset(get = "pub", get_mut = "pub")]
|
||||
#[getset(get = "pub", get_mut = "pub", set = "pub")]
|
||||
resize_dimensions: Vec<Option<Rect>>,
|
||||
#[getset(get = "pub", set = "pub")]
|
||||
tile: bool,
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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(())
|
||||
|
||||
Reference in New Issue
Block a user