aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--niri-config/src/lib.rs7
-rw-r--r--niri-ipc/src/lib.rs8
-rw-r--r--src/input/mod.rs10
-rw-r--r--src/layout/mod.rs31
-rw-r--r--src/layout/scrolling.rs21
-rw-r--r--src/layout/workspace.rs10
6 files changed, 87 insertions, 0 deletions
diff --git a/niri-config/src/lib.rs b/niri-config/src/lib.rs
index 20440d79..e7de610c 100644
--- a/niri-config/src/lib.rs
+++ b/niri-config/src/lib.rs
@@ -1273,6 +1273,9 @@ pub enum Action {
#[knuffel(skip)]
ResetWindowHeightById(u64),
SwitchPresetColumnWidth,
+ SwitchPresetWindowWidth,
+ #[knuffel(skip)]
+ SwitchPresetWindowWidthById(u64),
SwitchPresetWindowHeight,
#[knuffel(skip)]
SwitchPresetWindowHeightById(u64),
@@ -1424,6 +1427,10 @@ impl From<niri_ipc::Action> for Action {
niri_ipc::Action::ResetWindowHeight { id: None } => Self::ResetWindowHeight,
niri_ipc::Action::ResetWindowHeight { id: Some(id) } => Self::ResetWindowHeightById(id),
niri_ipc::Action::SwitchPresetColumnWidth {} => Self::SwitchPresetColumnWidth,
+ niri_ipc::Action::SwitchPresetWindowWidth { id: None } => Self::SwitchPresetWindowWidth,
+ niri_ipc::Action::SwitchPresetWindowWidth { id: Some(id) } => {
+ Self::SwitchPresetWindowWidthById(id)
+ }
niri_ipc::Action::SwitchPresetWindowHeight { id: None } => {
Self::SwitchPresetWindowHeight
}
diff --git a/niri-ipc/src/lib.rs b/niri-ipc/src/lib.rs
index 1f09e912..a53ac8ab 100644
--- a/niri-ipc/src/lib.rs
+++ b/niri-ipc/src/lib.rs
@@ -420,6 +420,14 @@ pub enum Action {
},
/// Switch between preset column widths.
SwitchPresetColumnWidth {},
+ /// Switch between preset window widths.
+ SwitchPresetWindowWidth {
+ /// Id of the window whose width to switch.
+ ///
+ /// If `None`, uses the focused window.
+ #[cfg_attr(feature = "clap", arg(long))]
+ id: Option<u64>,
+ },
/// Switch between preset window heights.
SwitchPresetWindowHeight {
/// Id of the window whose height to switch.
diff --git a/src/input/mod.rs b/src/input/mod.rs
index 98bbbb8e..8ce00712 100644
--- a/src/input/mod.rs
+++ b/src/input/mod.rs
@@ -1112,6 +1112,16 @@ impl State {
Action::SwitchPresetColumnWidth => {
self.niri.layout.toggle_width();
}
+ Action::SwitchPresetWindowWidth => {
+ self.niri.layout.toggle_window_width(None);
+ }
+ Action::SwitchPresetWindowWidthById(id) => {
+ 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.toggle_window_width(Some(&window));
+ }
+ }
Action::SwitchPresetWindowHeight => {
self.niri.layout.toggle_window_height(None);
}
diff --git a/src/layout/mod.rs b/src/layout/mod.rs
index 97d3d1e1..081a5f35 100644
--- a/src/layout/mod.rs
+++ b/src/layout/mod.rs
@@ -2607,6 +2607,29 @@ impl<W: LayoutElement> Layout<W> {
monitor.toggle_width();
}
+ pub fn toggle_window_width(&mut self, window: Option<&W::Id>) {
+ 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.toggle_window_width(window);
+ }
+
pub fn toggle_window_height(&mut self, window: Option<&W::Id>) {
if let Some(InteractiveMoveState::Moving(move_)) = &mut self.interactive_move {
if window.is_none() || window == Some(move_.tile.window().id()) {
@@ -4474,6 +4497,10 @@ mod tests {
},
MoveColumnToOutput(#[proptest(strategy = "1..=5usize")] usize),
SwitchPresetColumnWidth,
+ SwitchPresetWindowWidth {
+ #[proptest(strategy = "proptest::option::of(1..=5usize)")]
+ id: Option<usize>,
+ },
SwitchPresetWindowHeight {
#[proptest(strategy = "proptest::option::of(1..=5usize)")]
id: Option<usize>,
@@ -5009,6 +5036,10 @@ mod tests {
Op::MoveWorkspaceDown => layout.move_workspace_down(),
Op::MoveWorkspaceUp => layout.move_workspace_up(),
Op::SwitchPresetColumnWidth => layout.toggle_width(),
+ Op::SwitchPresetWindowWidth { id } => {
+ let id = id.filter(|id| layout.has_window(id));
+ layout.toggle_window_width(id.as_ref());
+ }
Op::SwitchPresetWindowHeight { id } => {
let id = id.filter(|id| layout.has_window(id));
layout.toggle_window_height(id.as_ref());
diff --git a/src/layout/scrolling.rs b/src/layout/scrolling.rs
index 10101cca..bdafdb71 100644
--- a/src/layout/scrolling.rs
+++ b/src/layout/scrolling.rs
@@ -2116,6 +2116,27 @@ impl<W: LayoutElement> ScrollingSpace<W> {
cancel_resize_for_column(&mut self.interactive_resize, col);
}
+ pub fn toggle_window_width(&mut self, window: Option<&W::Id>) {
+ if self.columns.is_empty() {
+ return;
+ }
+
+ let col = if let Some(window) = window {
+ self.columns
+ .iter_mut()
+ .find(|col| col.contains(window))
+ .unwrap()
+ } else {
+ &mut self.columns[self.active_column_idx]
+ };
+
+ // FIXME: when we fix preset fixed width to be per-window, this should also be made
+ // window-specific to resolve the correct window width.
+ col.toggle_width();
+
+ cancel_resize_for_column(&mut self.interactive_resize, col);
+ }
+
pub fn toggle_window_height(&mut self, window: Option<&W::Id>) {
if self.columns.is_empty() {
return;
diff --git a/src/layout/workspace.rs b/src/layout/workspace.rs
index c77fb44f..113b6df0 100644
--- a/src/layout/workspace.rs
+++ b/src/layout/workspace.rs
@@ -1041,6 +1041,16 @@ impl<W: LayoutElement> Workspace<W> {
self.scrolling.reset_window_height(window);
}
+ pub fn toggle_window_width(&mut self, window: Option<&W::Id>) {
+ if window.map_or(self.floating_is_active.get(), |id| {
+ self.floating.has_window(id)
+ }) {
+ self.floating.toggle_window_width(window);
+ } else {
+ self.scrolling.toggle_window_width(window);
+ }
+ }
+
pub fn toggle_window_height(&mut self, window: Option<&W::Id>) {
if window.map_or(self.floating_is_active.get(), |id| {
self.floating.has_window(id)