diff --git a/Cargo.lock b/Cargo.lock
index a74e19cc..c889f847 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1452,9 +1452,9 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows"
-version = "0.20.0"
+version = "0.20.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0a0b63f34b1cf0fcb7a2e387189936a7c9822123ef124a95da2b8a0b493bc69d"
+checksum = "d7524f6f9074f6326a1c167cd3dc2ed4e6916648a1a55116d029620af9b65fb1"
dependencies = [
"const-sha1",
"windows_gen",
@@ -1463,9 +1463,9 @@ dependencies = [
[[package]]
name = "windows_gen"
-version = "0.20.0"
+version = "0.20.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7213e17fead412ec608804cbe190988db6f40b2a946ef58dd67fd9cdf39da144"
+checksum = "4be44a189bde96fc0e0cdd5b152b2d21c635c0c94c7d256aab4425477b2a2f37"
dependencies = [
"windows_quote",
"windows_reader",
@@ -1473,9 +1473,9 @@ dependencies = [
[[package]]
name = "windows_macros"
-version = "0.20.0"
+version = "0.20.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "661a56e1edb9f9d466a9cb59c392edfad0d273b66bb20b1f5f4aea6db5ad35d6"
+checksum = "cc1d78ce8a43d45b8da282383a2cb2ffcd5587cc3a9c341125d3181d2b701ede"
dependencies = [
"syn",
"windows_gen",
@@ -1485,15 +1485,15 @@ dependencies = [
[[package]]
name = "windows_quote"
-version = "0.20.0"
+version = "0.20.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6d16ae0ecb5b0a365ff465ca9b9780e70986f951b4e06a95f87ac54a421d3767"
+checksum = "51fa2185b18a6164a3fa3ea2b6c92ebc1b60f532ae5a85c57408ba6a5a064913"
[[package]]
name = "windows_reader"
-version = "0.20.0"
+version = "0.20.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c75040b326c26dda15a9c18970a7a15bf503dc22597d55dd559df16435f4a550"
+checksum = "3daa5bd758f2f8f20cd93a79aedca20759779f43785fc77b08a4e8e1e5876bbb"
[[package]]
name = "winput"
diff --git a/README.md b/README.md
index 401075ff..005696cb 100644
--- a/README.md
+++ b/README.md
@@ -184,6 +184,26 @@ passing it as an argument to the `--implementation` flag:
komorebic.exe toggle-focus-follows-mouse --implementation komorebi
```
+#### Saving and Loading Resized Layouts
+
+If you create a BSP layout through various resize adjustments that you want to be able to restore easily in the future,
+it is possible to "quicksave" that layout to the system's temporary folder and load it later in the same session, or
+alternatively, you may save it to a specific file to be loaded again at any point in the future.
+
+```powershell
+komorebic.exe quick-save # saves the focused workspace to $Env:TEMP\komorebi.quicksave.json
+komorebic.exe quick-load # loads $Env:TEMP\komorebi.quicksave.json on the focused workspace
+
+komorebic.exe save ~/layouts/primary.json # saves the focused workspace to $Env:USERPROFILE\layouts\primary.json
+komorebic.exe load ~/layouts/secondary.json # loads $Env:USERPROFILE\layouts\secondary.json on the focused workspace
+```
+
+These layouts can be applied to arbitrary collections of windows on any workspace, as they only track the layout
+dimensions and are not coupled to the applications that were running at the time of saving.
+
+When layouts that expect more or less windows than the number currently on the focused workspace are loaded, `komorebi`
+will automatically reconcile the difference.
+
## Configuration with `komorebic`
As previously mentioned, this project does not handle anything related to keybindings and shortcuts directly. I
@@ -198,10 +218,12 @@ 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)
+quick-save Quicksave the current resize layout dimensions
+quick-load Load the last quicksaved resize layout dimensions
+save Save the current resize layout dimensions to a file
+load Load the resize layout dimensions from a file
focus Change focus to the window in the specified direction
move Move the focused window in the specified direction
stack Stack the focused window in the specified direction
@@ -275,6 +297,7 @@ used [is available here](komorebi.sample.with.lib.ahk).
- [x] Resize window container in direction
- [ ] Resize child window containers by split ratio
- [x] Quicksave and quickload layouts with resize dimensions
+- [x] Save and load layouts with resize dimensions to/from specific files
- [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 dbe001df..32968226 100644
--- a/komorebi-core/src/lib.rs
+++ b/komorebi-core/src/lib.rs
@@ -1,6 +1,7 @@
#![warn(clippy::all, clippy::nursery, clippy::pedantic)]
#![allow(clippy::missing_errors_doc)]
+use std::path::PathBuf;
use std::str::FromStr;
use clap::ArgEnum;
@@ -54,6 +55,8 @@ pub enum SocketMessage {
Retile,
QuickSave,
QuickLoad,
+ Save(PathBuf),
+ Load(PathBuf),
FocusMonitorNumber(usize),
FocusWorkspaceNumber(usize),
ContainerPadding(usize, usize, i32),
diff --git a/komorebi/src/process_command.rs b/komorebi/src/process_command.rs
index 6f1f4ad6..8df7d627 100644
--- a/komorebi/src/process_command.rs
+++ b/komorebi/src/process_command.rs
@@ -359,6 +359,29 @@ impl WindowManager {
let resize: Vec