aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/input.rs10
-rw-r--r--src/layout/mod.rs22
-rw-r--r--src/layout/monitor.rs8
-rw-r--r--src/layout/workspace.rs68
4 files changed, 108 insertions, 0 deletions
diff --git a/src/input.rs b/src/input.rs
index f06f6142..0371e933 100644
--- a/src/input.rs
+++ b/src/input.rs
@@ -407,6 +407,16 @@ impl State {
// FIXME: granular
self.niri.queue_redraw_all();
}
+ Action::ConsumeOrExpelWindowLeft => {
+ self.niri.layout.consume_or_expel_window_left();
+ // FIXME: granular
+ self.niri.queue_redraw_all();
+ }
+ Action::ConsumeOrExpelWindowRight => {
+ self.niri.layout.consume_or_expel_window_right();
+ // FIXME: granular
+ self.niri.queue_redraw_all();
+ }
Action::FocusColumnLeft => {
self.niri.layout.focus_left();
// FIXME: granular
diff --git a/src/layout/mod.rs b/src/layout/mod.rs
index 111562cd..9ae89f03 100644
--- a/src/layout/mod.rs
+++ b/src/layout/mod.rs
@@ -898,6 +898,20 @@ impl<W: LayoutElement> Layout<W> {
monitor.move_up_or_to_workspace_up();
}
+ pub fn consume_or_expel_window_left(&mut self) {
+ let Some(monitor) = self.active_monitor() else {
+ return;
+ };
+ monitor.consume_or_expel_window_left();
+ }
+
+ pub fn consume_or_expel_window_right(&mut self) {
+ let Some(monitor) = self.active_monitor() else {
+ return;
+ };
+ monitor.consume_or_expel_window_right();
+ }
+
pub fn focus_left(&mut self) {
let Some(monitor) = self.active_monitor() else {
return;
@@ -1780,6 +1794,8 @@ mod tests {
MoveWindowUp,
MoveWindowDownOrToWorkspaceDown,
MoveWindowUpOrToWorkspaceUp,
+ ConsumeOrExpelWindowLeft,
+ ConsumeOrExpelWindowRight,
ConsumeWindowIntoColumn,
ExpelWindowFromColumn,
CenterColumn,
@@ -1906,6 +1922,8 @@ mod tests {
Op::MoveWindowUp => layout.move_up(),
Op::MoveWindowDownOrToWorkspaceDown => layout.move_down_or_to_workspace_down(),
Op::MoveWindowUpOrToWorkspaceUp => layout.move_up_or_to_workspace_up(),
+ Op::ConsumeOrExpelWindowLeft => layout.consume_or_expel_window_left(),
+ Op::ConsumeOrExpelWindowRight => layout.consume_or_expel_window_right(),
Op::ConsumeWindowIntoColumn => layout.consume_into_column(),
Op::ExpelWindowFromColumn => layout.expel_from_column(),
Op::CenterColumn => layout.center_column(),
@@ -2072,6 +2090,8 @@ mod tests {
Op::MoveWindowDownOrToWorkspaceDown,
Op::MoveWindowUp,
Op::MoveWindowUpOrToWorkspaceUp,
+ Op::ConsumeOrExpelWindowLeft,
+ Op::ConsumeOrExpelWindowRight,
Op::MoveWorkspaceToOutput(1),
];
@@ -2203,6 +2223,8 @@ mod tests {
Op::MoveWindowDownOrToWorkspaceDown,
Op::MoveWindowUp,
Op::MoveWindowUpOrToWorkspaceUp,
+ Op::ConsumeOrExpelWindowLeft,
+ Op::ConsumeOrExpelWindowRight,
];
for third in every_op {
diff --git a/src/layout/monitor.rs b/src/layout/monitor.rs
index f63b0c75..cd6d1eba 100644
--- a/src/layout/monitor.rs
+++ b/src/layout/monitor.rs
@@ -215,6 +215,14 @@ impl<W: LayoutElement> Monitor<W> {
}
}
+ pub fn consume_or_expel_window_left(&mut self) {
+ self.active_workspace().consume_or_expel_window_left();
+ }
+
+ pub fn consume_or_expel_window_right(&mut self) {
+ self.active_workspace().consume_or_expel_window_right();
+ }
+
pub fn focus_left(&mut self) {
self.active_workspace().focus_left();
}
diff --git a/src/layout/workspace.rs b/src/layout/workspace.rs
index fbae0064..4eb8c347 100644
--- a/src/layout/workspace.rs
+++ b/src/layout/workspace.rs
@@ -866,6 +866,70 @@ impl<W: LayoutElement> Workspace<W> {
self.columns[self.active_column_idx].move_up();
}
+ pub fn consume_or_expel_window_left(&mut self) {
+ if self.columns.is_empty() {
+ return;
+ }
+
+ let source_column = &self.columns[self.active_column_idx];
+ if source_column.tiles.len() == 1 {
+ if self.active_column_idx == 0 {
+ return;
+ }
+
+ // Move into adjacent column.
+ let target_column_idx = self.active_column_idx - 1;
+ let window = self.remove_window_by_idx(self.active_column_idx, 0);
+ self.enter_output_for_window(&window);
+
+ let target_column = &mut self.columns[target_column_idx];
+ target_column.add_window(window);
+ target_column.focus_last();
+ self.activate_column(target_column_idx);
+ } else {
+ // Move out of column.
+ let width = source_column.width;
+ let is_full_width = source_column.is_full_width;
+ let window =
+ self.remove_window_by_idx(self.active_column_idx, source_column.active_tile_idx);
+
+ self.add_window(window, true, width, is_full_width);
+ // Window was added to the right of current column, so move the new column left.
+ self.move_left();
+ }
+ }
+
+ pub fn consume_or_expel_window_right(&mut self) {
+ if self.columns.is_empty() {
+ return;
+ }
+
+ let source_column = &self.columns[self.active_column_idx];
+ if source_column.tiles.len() == 1 {
+ if self.active_column_idx + 1 == self.columns.len() {
+ return;
+ }
+
+ // Move into adjacent column.
+ let target_column_idx = self.active_column_idx;
+ let window = self.remove_window_by_idx(self.active_column_idx, 0);
+ self.enter_output_for_window(&window);
+
+ let target_column = &mut self.columns[target_column_idx];
+ target_column.add_window(window);
+ target_column.focus_last();
+ self.activate_column(target_column_idx);
+ } else {
+ // Move out of column.
+ let width = source_column.width;
+ let is_full_width = source_column.is_full_width;
+ let window =
+ self.remove_window_by_idx(self.active_column_idx, source_column.active_tile_idx);
+
+ self.add_window(window, true, width, is_full_width);
+ }
+ }
+
pub fn consume_into_column(&mut self) {
if self.columns.len() < 2 {
return;
@@ -1414,6 +1478,10 @@ impl<W: LayoutElement> Column<W> {
self.active_tile_idx = min(self.active_tile_idx + 1, self.tiles.len() - 1);
}
+ fn focus_last(&mut self) {
+ self.active_tile_idx = self.tiles.len() - 1;
+ }
+
fn move_up(&mut self) {
let new_idx = self.active_tile_idx.saturating_sub(1);
if self.active_tile_idx == new_idx {