Add focus-column (by index) action

This commit is contained in:
Duncan Overbruck
2025-03-13 03:05:55 +01:00
committed by Ivan Molodetskikh
parent b4922086ce
commit a5d58d670b
7 changed files with 41 additions and 0 deletions
+2
View File
@@ -1486,6 +1486,7 @@ pub enum Action {
FocusColumnLast, FocusColumnLast,
FocusColumnRightOrFirst, FocusColumnRightOrFirst,
FocusColumnLeftOrLast, FocusColumnLeftOrLast,
FocusColumn(#[knuffel(argument)] usize),
FocusWindowOrMonitorUp, FocusWindowOrMonitorUp,
FocusWindowOrMonitorDown, FocusWindowOrMonitorDown,
FocusColumnOrMonitorLeft, FocusColumnOrMonitorLeft,
@@ -1682,6 +1683,7 @@ impl From<niri_ipc::Action> for Action {
niri_ipc::Action::FocusColumnLast {} => Self::FocusColumnLast, niri_ipc::Action::FocusColumnLast {} => Self::FocusColumnLast,
niri_ipc::Action::FocusColumnRightOrFirst {} => Self::FocusColumnRightOrFirst, niri_ipc::Action::FocusColumnRightOrFirst {} => Self::FocusColumnRightOrFirst,
niri_ipc::Action::FocusColumnLeftOrLast {} => Self::FocusColumnLeftOrLast, niri_ipc::Action::FocusColumnLeftOrLast {} => Self::FocusColumnLeftOrLast,
niri_ipc::Action::FocusColumn { index } => Self::FocusColumn(index),
niri_ipc::Action::FocusWindowOrMonitorUp {} => Self::FocusWindowOrMonitorUp, niri_ipc::Action::FocusWindowOrMonitorUp {} => Self::FocusWindowOrMonitorUp,
niri_ipc::Action::FocusWindowOrMonitorDown {} => Self::FocusWindowOrMonitorDown, niri_ipc::Action::FocusWindowOrMonitorDown {} => Self::FocusWindowOrMonitorDown,
niri_ipc::Action::FocusColumnOrMonitorLeft {} => Self::FocusColumnOrMonitorLeft, niri_ipc::Action::FocusColumnOrMonitorLeft {} => Self::FocusColumnOrMonitorLeft,
+8
View File
@@ -249,6 +249,14 @@ pub enum Action {
FocusColumnRightOrFirst {}, FocusColumnRightOrFirst {},
/// Focus the next column to the left, looping if at start. /// Focus the next column to the left, looping if at start.
FocusColumnLeftOrLast {}, FocusColumnLeftOrLast {},
/// Focus a column by index.
FocusColumn {
/// Index of the column to focus.
///
/// The index starts from 1 for the first column.
#[cfg_attr(feature = "clap", arg())]
index: usize,
},
/// Focus the window or the monitor above. /// Focus the window or the monitor above.
FocusWindowOrMonitorUp {}, FocusWindowOrMonitorUp {},
/// Focus the window or the monitor below. /// Focus the window or the monitor below.
+7
View File
@@ -882,6 +882,13 @@ impl State {
// FIXME: granular // FIXME: granular
self.niri.queue_redraw_all(); self.niri.queue_redraw_all();
} }
Action::FocusColumn(index) => {
self.niri.layout.focus_column(index);
self.maybe_warp_cursor_to_focus();
self.niri.layer_shell_on_demand_focus = None;
// FIXME: granular
self.niri.queue_redraw_all();
}
Action::FocusWindowOrMonitorUp => { Action::FocusWindowOrMonitorUp => {
if let Some(output) = self.niri.output_up() { if let Some(output) = self.niri.output_up() {
if self.niri.layout.focus_window_up_or_output(&output) if self.niri.layout.focus_window_up_or_output(&output)
+7
View File
@@ -1946,6 +1946,13 @@ impl<W: LayoutElement> Layout<W> {
workspace.focus_column_left_or_last(); workspace.focus_column_left_or_last();
} }
pub fn focus_column(&mut self, index: usize) {
let Some(workspace) = self.active_workspace_mut() else {
return;
};
workspace.focus_column(index);
}
pub fn focus_window_up_or_output(&mut self, output: &Output) -> bool { pub fn focus_window_up_or_output(&mut self, output: &Output) -> bool {
if let Some(workspace) = self.active_workspace_mut() { if let Some(workspace) = self.active_workspace_mut() {
if workspace.focus_up() { if workspace.focus_up() {
+8
View File
@@ -1491,6 +1491,14 @@ impl<W: LayoutElement> ScrollingSpace<W> {
self.activate_column(self.columns.len() - 1); self.activate_column(self.columns.len() - 1);
} }
pub fn focus_column(&mut self, index: usize) {
if self.columns.is_empty() {
return;
}
self.activate_column(index.saturating_sub(1).min(self.columns.len() - 1));
}
pub fn focus_window_in_column(&mut self, index: u8) { pub fn focus_window_in_column(&mut self, index: u8) {
if self.columns.is_empty() { if self.columns.is_empty() {
return; return;
+2
View File
@@ -374,6 +374,7 @@ enum Op {
FocusColumnLast, FocusColumnLast,
FocusColumnRightOrFirst, FocusColumnRightOrFirst,
FocusColumnLeftOrLast, FocusColumnLeftOrLast,
FocusColumn(#[proptest(strategy = "1..=5usize")] usize),
FocusWindowOrMonitorUp(#[proptest(strategy = "1..=2u8")] u8), FocusWindowOrMonitorUp(#[proptest(strategy = "1..=2u8")] u8),
FocusWindowOrMonitorDown(#[proptest(strategy = "1..=2u8")] u8), FocusWindowOrMonitorDown(#[proptest(strategy = "1..=2u8")] u8),
FocusColumnOrMonitorLeft(#[proptest(strategy = "1..=2u8")] u8), FocusColumnOrMonitorLeft(#[proptest(strategy = "1..=2u8")] u8),
@@ -907,6 +908,7 @@ impl Op {
Op::FocusColumnLast => layout.focus_column_last(), Op::FocusColumnLast => layout.focus_column_last(),
Op::FocusColumnRightOrFirst => layout.focus_column_right_or_first(), Op::FocusColumnRightOrFirst => layout.focus_column_right_or_first(),
Op::FocusColumnLeftOrLast => layout.focus_column_left_or_last(), Op::FocusColumnLeftOrLast => layout.focus_column_left_or_last(),
Op::FocusColumn(index) => layout.focus_column(index),
Op::FocusWindowOrMonitorUp(id) => { Op::FocusWindowOrMonitorUp(id) => {
let name = format!("output{id}"); let name = format!("output{id}");
let Some(output) = layout.outputs().find(|o| o.name() == name).cloned() else { let Some(output) = layout.outputs().find(|o| o.name() == name).cloned() else {
+7
View File
@@ -850,6 +850,13 @@ impl<W: LayoutElement> Workspace<W> {
} }
} }
pub fn focus_column(&mut self, index: usize) {
if self.floating_is_active.get() {
self.focus_tiling();
}
self.scrolling.focus_column(index);
}
pub fn focus_window_in_column(&mut self, index: u8) { pub fn focus_window_in_column(&mut self, index: u8) {
if self.floating_is_active.get() { if self.floating_is_active.get() {
return; return;