diff options
| author | Ivan Molodetskikh <yalterz@gmail.com> | 2024-12-28 10:12:50 +0300 |
|---|---|---|
| committer | Ivan Molodetskikh <yalterz@gmail.com> | 2024-12-30 20:12:37 +0300 |
| commit | 8b0cb0bb57112bd15bc7ac04e6952d857dadcbca (patch) | |
| tree | c0a9cd138e768e7596d8cd324be65024fbb35756 | |
| parent | a24a6e4e3c441389fd7731320f47e61e567e237f (diff) | |
| download | niri-8b0cb0bb57112bd15bc7ac04e6952d857dadcbca.tar.gz niri-8b0cb0bb57112bd15bc7ac04e6952d857dadcbca.tar.bz2 niri-8b0cb0bb57112bd15bc7ac04e6952d857dadcbca.zip | |
Add set-window-width action
| -rw-r--r-- | niri-config/src/lib.rs | 11 | ||||
| -rw-r--r-- | niri-ipc/src/lib.rs | 16 | ||||
| -rw-r--r-- | src/input/mod.rs | 10 | ||||
| -rw-r--r-- | src/layout/mod.rs | 33 | ||||
| -rw-r--r-- | src/layout/scrolling.rs | 19 | ||||
| -rw-r--r-- | src/layout/workspace.rs | 12 |
6 files changed, 97 insertions, 4 deletions
diff --git a/niri-config/src/lib.rs b/niri-config/src/lib.rs index 2437fe66..069bb015 100644 --- a/niri-config/src/lib.rs +++ b/niri-config/src/lib.rs @@ -1241,6 +1241,12 @@ pub enum Action { MoveColumnToMonitorRight, MoveColumnToMonitorDown, MoveColumnToMonitorUp, + SetWindowWidth(#[knuffel(argument, str)] SizeChange), + #[knuffel(skip)] + SetWindowWidthById { + id: u64, + change: SizeChange, + }, SetWindowHeight(#[knuffel(argument, str)] SizeChange), #[knuffel(skip)] SetWindowHeightById { @@ -1373,6 +1379,11 @@ impl From<niri_ipc::Action> for Action { niri_ipc::Action::MoveColumnToMonitorRight {} => Self::MoveColumnToMonitorRight, niri_ipc::Action::MoveColumnToMonitorDown {} => Self::MoveColumnToMonitorDown, niri_ipc::Action::MoveColumnToMonitorUp {} => Self::MoveColumnToMonitorUp, + niri_ipc::Action::SetWindowWidth { id: None, change } => Self::SetWindowWidth(change), + niri_ipc::Action::SetWindowWidth { + id: Some(id), + change, + } => Self::SetWindowWidthById { id, change }, niri_ipc::Action::SetWindowHeight { id: None, change } => Self::SetWindowHeight(change), niri_ipc::Action::SetWindowHeight { id: Some(id), diff --git a/niri-ipc/src/lib.rs b/niri-ipc/src/lib.rs index 6bbc00f2..bf66d3a8 100644 --- a/niri-ipc/src/lib.rs +++ b/niri-ipc/src/lib.rs @@ -362,6 +362,22 @@ pub enum Action { MoveColumnToMonitorDown {}, /// Move the focused column to the monitor above. MoveColumnToMonitorUp {}, + /// Change the width of a window. + #[cfg_attr( + feature = "clap", + clap(about = "Change the width of the focused window") + )] + SetWindowWidth { + /// Id of the window whose width to set. + /// + /// If `None`, uses the focused window. + #[cfg_attr(feature = "clap", arg(long))] + id: Option<u64>, + + /// How to change the width. + #[cfg_attr(feature = "clap", arg())] + change: SizeChange, + }, /// Change the height of a window. #[cfg_attr( feature = "clap", diff --git a/src/input/mod.rs b/src/input/mod.rs index 4e264b06..6e116d9e 100644 --- a/src/input/mod.rs +++ b/src/input/mod.rs @@ -1237,6 +1237,16 @@ impl State { Action::SetColumnWidth(change) => { self.niri.layout.set_column_width(change); } + Action::SetWindowWidth(change) => { + self.niri.layout.set_window_width(None, change); + } + Action::SetWindowWidthById { id, change } => { + let window = self.niri.layout.windows().find(|(_, m)| m.id().get() == id); + let window = window.map(|(_, m)| m.window.clone()); + if let Some(window) = window { + self.niri.layout.set_window_width(Some(&window), change); + } + } Action::SetWindowHeight(change) => { self.niri.layout.set_window_height(None, change); } diff --git a/src/layout/mod.rs b/src/layout/mod.rs index 2b12c7bb..acdf1301 100644 --- a/src/layout/mod.rs +++ b/src/layout/mod.rs @@ -2592,6 +2592,29 @@ impl<W: LayoutElement> Layout<W> { monitor.set_column_width(change); } + pub fn set_window_width(&mut self, window: Option<&W::Id>, change: SizeChange) { + if let Some(InteractiveMoveState::Moving(move_)) = &mut self.interactive_move { + if window.is_none() || window == Some(move_.tile.window().id()) { + return; + } + } + + let workspace = if let Some(window) = window { + Some( + self.workspaces_mut() + .find(|ws| ws.has_window(window)) + .unwrap(), + ) + } else { + self.active_workspace_mut() + }; + + let Some(workspace) = workspace else { + return; + }; + workspace.set_window_width(window, change); + } + pub fn set_window_height(&mut self, window: Option<&W::Id>, change: SizeChange) { if let Some(InteractiveMoveState::Moving(move_)) = &mut self.interactive_move { if window.is_none() || window == Some(move_.tile.window().id()) { @@ -4319,6 +4342,12 @@ mod tests { }, MaximizeColumn, SetColumnWidth(#[proptest(strategy = "arbitrary_size_change()")] SizeChange), + SetWindowWidth { + #[proptest(strategy = "proptest::option::of(1..=5usize)")] + id: Option<usize>, + #[proptest(strategy = "arbitrary_size_change()")] + change: SizeChange, + }, SetWindowHeight { #[proptest(strategy = "proptest::option::of(1..=5usize)")] id: Option<usize>, @@ -4829,6 +4858,10 @@ mod tests { } Op::MaximizeColumn => layout.toggle_full_width(), Op::SetColumnWidth(change) => layout.set_column_width(change), + Op::SetWindowWidth { id, change } => { + let id = id.filter(|id| layout.has_window(id)); + layout.set_window_width(id.as_ref(), change); + } Op::SetWindowHeight { id, change } => { let id = id.filter(|id| layout.has_window(id)); layout.set_window_height(id.as_ref(), change); diff --git a/src/layout/scrolling.rs b/src/layout/scrolling.rs index 5d1b8234..c0de770a 100644 --- a/src/layout/scrolling.rs +++ b/src/layout/scrolling.rs @@ -1996,13 +1996,26 @@ impl<W: LayoutElement> ScrollingSpace<W> { cancel_resize_for_column(&mut self.interactive_resize, col); } - pub fn set_column_width(&mut self, change: SizeChange) { + pub fn set_window_width(&mut self, window: Option<&W::Id>, change: SizeChange) { if self.columns.is_empty() { return; } - let col = &mut self.columns[self.active_column_idx]; - col.set_column_width(change, None, true); + let (col, tile_idx) = if let Some(window) = window { + self.columns + .iter_mut() + .find_map(|col| { + col.tiles + .iter() + .position(|tile| tile.window().id() == window) + .map(|tile_idx| (col, Some(tile_idx))) + }) + .unwrap() + } else { + (&mut self.columns[self.active_column_idx], None) + }; + + col.set_column_width(change, tile_idx, true); cancel_resize_for_column(&mut self.interactive_resize, col); } diff --git a/src/layout/workspace.rs b/src/layout/workspace.rs index 92900ff3..cd1a6261 100644 --- a/src/layout/workspace.rs +++ b/src/layout/workspace.rs @@ -998,7 +998,17 @@ impl<W: LayoutElement> Workspace<W> { if self.floating_is_active.get() { self.floating.set_window_width(None, change, true); } else { - self.scrolling.set_column_width(change); + self.scrolling.set_window_width(None, change); + } + } + + pub fn set_window_width(&mut self, window: Option<&W::Id>, change: SizeChange) { + if window.map_or(self.floating_is_active.get(), |id| { + self.floating.has_window(id) + }) { + self.floating.set_window_width(window, change, true); + } else { + self.scrolling.set_window_width(window, change); } } |
