Add consume-or-expel-window-left/right commands

This commit is contained in:
Dennis Ranke
2024-02-03 20:25:08 +01:00
committed by Ivan Molodetskikh
parent 6bb83757ee
commit 3a23417e98
6 changed files with 114 additions and 0 deletions
+2
View File
@@ -459,6 +459,8 @@ pub enum Action {
MoveWindowUp,
MoveWindowDownOrToWorkspaceDown,
MoveWindowUpOrToWorkspaceUp,
ConsumeOrExpelWindowLeft,
ConsumeOrExpelWindowRight,
ConsumeWindowIntoColumn,
ExpelWindowFromColumn,
CenterColumn,
+4
View File
@@ -322,6 +322,10 @@ binds {
Mod+Comma { consume-window-into-column; }
Mod+Period { expel-window-from-column; }
// There are also commands that consume or expel a single window to the side.
// Mod+BracketLeft { consume-or-expel-window-left; }
// Mod+BracketRight { consume-or-expel-window-right; }
Mod+R { switch-preset-column-width; }
Mod+F { maximize-column; }
Mod+Shift+F { fullscreen-window; }
+10
View File
@@ -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
+22
View File
@@ -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 {
+8
View File
@@ -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();
}
+68
View File
@@ -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 {