From 4d7ccc551972dbce76151a5d94757ee9dc262435 Mon Sep 17 00:00:00 2001 From: LGUG2Z Date: Wed, 3 Nov 2021 10:04:48 -0700 Subject: [PATCH] feat(wm): allow resize-axis for custom primary col This commit allows the resize-axis cmd on Axis::Horizontal to operate on the Primary column of a CustomLayout. Note that this will only operate on a CustomLayout that has met the window count threshold to enable the tertiary column. If it has not, the layout will render as DefaultLayout::Columns, which does not support the resize-axis cmd. --- Cargo.lock | 12 +++ README.md | 2 +- komorebi-core/src/custom_layout.rs | 15 ++++ komorebi/src/process_command.rs | 126 +++++++++++++++++------------ komorebi/src/workspace.rs | 2 +- komorebic/Cargo.toml | 2 +- komorebic/src/main.rs | 2 +- 7 files changed, 104 insertions(+), 57 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4e8ee340..c62cc44c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -96,6 +96,7 @@ dependencies = [ "os_str_bytes", "strsim", "termcolor", + "terminal_size", "textwrap", "unicase", ] @@ -1197,12 +1198,23 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "terminal_size" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df" +dependencies = [ + "libc", + "winapi 0.3.9", +] + [[package]] name = "textwrap" version = "0.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80" dependencies = [ + "terminal_size", "unicode-width", ] diff --git a/README.md b/README.md index 56829639..e06b3e72 100644 --- a/README.md +++ b/README.md @@ -299,7 +299,7 @@ cycle-focus Change focus to the window in the specified cycle cycle-move Move the focused window in the specified cycle direction stack Stack the focused window in the specified direction resize-edge Resize the focused window in the specified direction -resize-axis Resize the focused window along the specified axis +resize-axis Resize the focused window or primary column along the specified axis unstack Unstack the focused window cycle-stack Cycle the focused stack in the specified cycle direction move-to-monitor Move the focused window to the specified monitor diff --git a/komorebi-core/src/custom_layout.rs b/komorebi-core/src/custom_layout.rs index 08cc5393..1d620ca9 100644 --- a/komorebi-core/src/custom_layout.rs +++ b/komorebi-core/src/custom_layout.rs @@ -2,6 +2,7 @@ use std::collections::HashMap; use std::fs::File; use std::io::BufReader; use std::ops::Deref; +use std::ops::DerefMut; use std::path::PathBuf; use color_eyre::eyre::anyhow; @@ -22,6 +23,12 @@ impl Deref for CustomLayout { } } +impl DerefMut for CustomLayout { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + impl CustomLayout { pub fn from_path_buf(path: PathBuf) -> Result { let invalid_filetype = anyhow!("custom layouts must be json or yaml files"); @@ -75,6 +82,14 @@ impl CustomLayout { None } + pub fn set_primary_width_percentage(&mut self, percentage: usize) { + for column in self.iter_mut() { + if let Column::Primary(Option::Some(ColumnWidth::WidthPercentage(current))) = column { + *current = percentage; + } + } + } + #[must_use] pub fn is_valid(&self) -> bool { // A valid layout must have at least one column diff --git a/komorebi/src/process_command.rs b/komorebi/src/process_command.rs index 7bdcd726..8616f4ab 100644 --- a/komorebi/src/process_command.rs +++ b/komorebi/src/process_command.rs @@ -17,8 +17,10 @@ use uds_windows::UnixStream; use komorebi_core::Axis; use komorebi_core::FocusFollowsMouseImplementation; +use komorebi_core::Layout; use komorebi_core::OperationDirection; use komorebi_core::Rect; +use komorebi_core::Sizing; use komorebi_core::SocketMessage; use komorebi_core::StateQuery; @@ -266,62 +268,80 @@ impl WindowManager { self.resize_window(direction, sizing, self.resize_delta, true)?; } SocketMessage::ResizeWindowAxis(axis, sizing) => { - match axis { - Axis::Horizontal => { - self.resize_window( - OperationDirection::Left, - sizing, - self.resize_delta, - false, - )?; - self.resize_window( - OperationDirection::Right, - sizing, - self.resize_delta, - false, - )?; - } - Axis::Vertical => { - self.resize_window( - OperationDirection::Up, - sizing, - self.resize_delta, - false, - )?; - self.resize_window( - OperationDirection::Down, - sizing, - self.resize_delta, - false, - )?; + // If the user has a custom layout, allow for the resizing of the primary column + // with this signal + if let Layout::Custom(ref mut custom) = self.focused_workspace_mut()?.layout_mut() { + if matches!(axis, Axis::Horizontal) { + let percentage = custom + .primary_width_percentage() + .unwrap_or_else(|| 100 / custom.len()); + + match sizing { + Sizing::Increase => custom.set_primary_width_percentage(percentage + 5), + Sizing::Decrease => custom.set_primary_width_percentage(percentage - 5), + } } - Axis::HorizontalAndVertical => { - self.resize_window( - OperationDirection::Left, - sizing, - self.resize_delta, - false, - )?; - self.resize_window( - OperationDirection::Right, - sizing, - self.resize_delta, - false, - )?; - self.resize_window( - OperationDirection::Up, - sizing, - self.resize_delta, - false, - )?; - self.resize_window( - OperationDirection::Down, - sizing, - self.resize_delta, - false, - )?; + // Otherwise proceed with the resizing logic for individual window containers in the + // assumed BSP layout + } else { + match axis { + Axis::Horizontal => { + self.resize_window( + OperationDirection::Left, + sizing, + self.resize_delta, + false, + )?; + self.resize_window( + OperationDirection::Right, + sizing, + self.resize_delta, + false, + )?; + } + Axis::Vertical => { + self.resize_window( + OperationDirection::Up, + sizing, + self.resize_delta, + false, + )?; + self.resize_window( + OperationDirection::Down, + sizing, + self.resize_delta, + false, + )?; + } + Axis::HorizontalAndVertical => { + self.resize_window( + OperationDirection::Left, + sizing, + self.resize_delta, + false, + )?; + self.resize_window( + OperationDirection::Right, + sizing, + self.resize_delta, + false, + )?; + self.resize_window( + OperationDirection::Up, + sizing, + self.resize_delta, + false, + )?; + self.resize_window( + OperationDirection::Down, + sizing, + self.resize_delta, + false, + )?; + } } } + self.update_focused_workspace(false)?; } SocketMessage::FocusFollowsMouse(mut implementation, enable) => { diff --git a/komorebi/src/workspace.rs b/komorebi/src/workspace.rs index 31661a98..a52adb02 100644 --- a/komorebi/src/workspace.rs +++ b/komorebi/src/workspace.rs @@ -38,7 +38,7 @@ pub struct Workspace { maximized_window_restore_idx: Option, #[getset(get = "pub", get_mut = "pub")] floating_windows: Vec, - #[getset(get = "pub", set = "pub")] + #[getset(get = "pub", get_mut = "pub", set = "pub")] layout: Layout, #[getset(get_copy = "pub", set = "pub")] layout_flip: Option, diff --git a/komorebic/Cargo.toml b/komorebic/Cargo.toml index 1f16914c..014be1ee 100644 --- a/komorebic/Cargo.toml +++ b/komorebic/Cargo.toml @@ -14,7 +14,7 @@ edition = "2021" derive-ahk = { path = "../derive-ahk" } komorebi-core = { path = "../komorebi-core" } -clap = "3.0.0-beta.5" +clap = { version = "3.0.0-beta.5", features = ["wrap_help"] } color-eyre = "0.5" dirs = "4" fs-tail = "0.1" diff --git a/komorebic/src/main.rs b/komorebic/src/main.rs index 756ef75f..dac39b7a 100644 --- a/komorebic/src/main.rs +++ b/komorebic/src/main.rs @@ -400,7 +400,7 @@ enum SubCommand { #[clap(setting = AppSettings::ArgRequiredElseHelp)] #[clap(alias = "resize")] ResizeEdge(Resize), - /// Resize the focused window along the specified axis + /// Resize the focused window or primary column along the specified axis #[clap(setting = AppSettings::ArgRequiredElseHelp)] ResizeAxis(ResizeAxis), /// Unstack the focused window