aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFilipe Paniguel <paniguel.lpnh@gmail.com>2024-06-28 11:44:24 -0300
committerGitHub <noreply@github.com>2024-06-28 07:44:24 -0700
commitbdf9894020f184643ac98fbbc74402689edfe3f4 (patch)
tree1829fac0d2d224e161c6faa78db3f3163dcd3836
parentd180e60e0584e0c43682d7aca612c366f881dd85 (diff)
downloadniri-bdf9894020f184643ac98fbbc74402689edfe3f4.tar.gz
niri-bdf9894020f184643ac98fbbc74402689edfe3f4.tar.bz2
niri-bdf9894020f184643ac98fbbc74402689edfe3f4.zip
feat: add `focus-column-or-monitor-left`, `focus-column-or-monitor-right` (#456)
* feat: add support for focus-window-or-monitor * addresses output without window case * refactor: reduce verbosity * update this.. * refactor: rename `maybe_focus_window` functions * refactor: flip focus_window_or_output return logic * Update src/layout/mod.rs Co-authored-by: Ivan Molodetskikh <yalterz@gmail.com> * refactor: rename to Column * move blocks next to other Column variables --------- Co-authored-by: Ivan Molodetskikh <yalterz@gmail.com>
-rw-r--r--niri-config/src/lib.rs4
-rw-r--r--niri-ipc/src/lib.rs4
-rw-r--r--src/input/mod.rs34
-rw-r--r--src/layout/mod.rs53
4 files changed, 95 insertions, 0 deletions
diff --git a/niri-config/src/lib.rs b/niri-config/src/lib.rs
index b766072b..f1bd0afe 100644
--- a/niri-config/src/lib.rs
+++ b/niri-config/src/lib.rs
@@ -946,6 +946,8 @@ pub enum Action {
FocusColumnLast,
FocusColumnRightOrFirst,
FocusColumnLeftOrLast,
+ FocusColumnOrMonitorLeft,
+ FocusColumnOrMonitorRight,
FocusWindowDown,
FocusWindowUp,
FocusWindowDownOrColumnLeft,
@@ -1022,6 +1024,8 @@ impl From<niri_ipc::Action> for Action {
niri_ipc::Action::FocusColumnLast => Self::FocusColumnLast,
niri_ipc::Action::FocusColumnRightOrFirst => Self::FocusColumnRightOrFirst,
niri_ipc::Action::FocusColumnLeftOrLast => Self::FocusColumnLeftOrLast,
+ niri_ipc::Action::FocusColumnOrMonitorLeft => Self::FocusColumnOrMonitorLeft,
+ niri_ipc::Action::FocusColumnOrMonitorRight => Self::FocusColumnOrMonitorRight,
niri_ipc::Action::FocusWindowDown => Self::FocusWindowDown,
niri_ipc::Action::FocusWindowUp => Self::FocusWindowUp,
niri_ipc::Action::FocusWindowDownOrColumnLeft => Self::FocusWindowDownOrColumnLeft,
diff --git a/niri-ipc/src/lib.rs b/niri-ipc/src/lib.rs
index 72e050e4..4db883e5 100644
--- a/niri-ipc/src/lib.rs
+++ b/niri-ipc/src/lib.rs
@@ -120,6 +120,10 @@ pub enum Action {
FocusColumnRightOrFirst,
/// Focus the next column to the left, looping if at start.
FocusColumnLeftOrLast,
+ /// Focus the column or the monitor to the left.
+ FocusColumnOrMonitorLeft,
+ /// Focus the column or the monitor to the right.
+ FocusColumnOrMonitorRight,
/// Focus the window below.
FocusWindowDown,
/// Focus the window above.
diff --git a/src/input/mod.rs b/src/input/mod.rs
index 59a4b436..5e775b03 100644
--- a/src/input/mod.rs
+++ b/src/input/mod.rs
@@ -596,6 +596,40 @@ impl State {
// FIXME: granular
self.niri.queue_redraw_all();
}
+ Action::FocusColumnOrMonitorLeft => {
+ if let Some(output) = self.niri.output_left() {
+ if self.niri.layout.focus_column_left_or_output(&output)
+ && !self.maybe_warp_cursor_to_focus_centered()
+ {
+ self.move_cursor_to_output(&output);
+ } else {
+ self.maybe_warp_cursor_to_focus();
+ }
+ } else {
+ self.niri.layout.focus_left();
+ self.maybe_warp_cursor_to_focus();
+ }
+
+ // FIXME: granular
+ self.niri.queue_redraw_all();
+ }
+ Action::FocusColumnOrMonitorRight => {
+ if let Some(output) = self.niri.output_right() {
+ if self.niri.layout.focus_column_right_or_output(&output)
+ && !self.maybe_warp_cursor_to_focus_centered()
+ {
+ self.move_cursor_to_output(&output);
+ } else {
+ self.maybe_warp_cursor_to_focus();
+ }
+ } else {
+ self.niri.layout.focus_right();
+ self.maybe_warp_cursor_to_focus();
+ }
+
+ // FIXME: granular
+ self.niri.queue_redraw_all();
+ }
Action::FocusWindowDown => {
self.niri.layout.focus_down();
self.maybe_warp_cursor_to_focus();
diff --git a/src/layout/mod.rs b/src/layout/mod.rs
index b74ef729..8fabba6a 100644
--- a/src/layout/mod.rs
+++ b/src/layout/mod.rs
@@ -1264,6 +1264,37 @@ impl<W: LayoutElement> Layout<W> {
monitor.focus_column_left_or_last();
}
+ pub fn focus_column_left_or_output(&mut self, output: &Output) -> bool {
+ if let Some(monitor) = self.active_monitor() {
+ let workspace = monitor.active_workspace();
+ let curr_idx = workspace.active_column_idx;
+
+ if !workspace.columns.is_empty() && curr_idx != 0 {
+ monitor.focus_left();
+ return false;
+ }
+ }
+
+ self.focus_output(output);
+ true
+ }
+
+ pub fn focus_column_right_or_output(&mut self, output: &Output) -> bool {
+ if let Some(monitor) = self.active_monitor() {
+ let workspace = monitor.active_workspace();
+ let curr_idx = workspace.active_column_idx;
+ let columns = &workspace.columns;
+
+ if !workspace.columns.is_empty() && curr_idx != columns.len() - 1 {
+ monitor.focus_right();
+ return false;
+ }
+ }
+
+ self.focus_output(output);
+ true
+ }
+
pub fn focus_down(&mut self) {
let Some(monitor) = self.active_monitor() else {
return;
@@ -2697,6 +2728,8 @@ mod tests {
FocusColumnLast,
FocusColumnRightOrFirst,
FocusColumnLeftOrLast,
+ FocusColumnOrMonitorLeft(#[proptest(strategy = "1..=2u8")] u8),
+ FocusColumnOrMonitorRight(#[proptest(strategy = "1..=2u8")] u8),
FocusWindowDown,
FocusWindowUp,
FocusWindowDownOrColumnLeft,
@@ -3022,6 +3055,22 @@ mod tests {
Op::FocusColumnLast => layout.focus_column_last(),
Op::FocusColumnRightOrFirst => layout.focus_column_right_or_first(),
Op::FocusColumnLeftOrLast => layout.focus_column_left_or_last(),
+ Op::FocusColumnOrMonitorLeft(id) => {
+ let name = format!("output{id}");
+ let Some(output) = layout.outputs().find(|o| o.name() == name).cloned() else {
+ return;
+ };
+
+ layout.focus_column_left_or_output(&output);
+ }
+ Op::FocusColumnOrMonitorRight(id) => {
+ let name = format!("output{id}");
+ let Some(output) = layout.outputs().find(|o| o.name() == name).cloned() else {
+ return;
+ };
+
+ layout.focus_column_right_or_output(&output);
+ }
Op::FocusWindowDown => layout.focus_down(),
Op::FocusWindowUp => layout.focus_up(),
Op::FocusWindowDownOrColumnLeft => layout.focus_down_or_left(),
@@ -3250,6 +3299,8 @@ mod tests {
Op::FocusColumnRight,
Op::FocusColumnRightOrFirst,
Op::FocusColumnLeftOrLast,
+ Op::FocusColumnOrMonitorLeft(0),
+ Op::FocusColumnOrMonitorRight(1),
Op::FocusWindowUp,
Op::FocusWindowUpOrColumnLeft,
Op::FocusWindowUpOrColumnRight,
@@ -3425,6 +3476,8 @@ mod tests {
Op::FocusColumnRight,
Op::FocusColumnRightOrFirst,
Op::FocusColumnLeftOrLast,
+ Op::FocusColumnOrMonitorLeft(0),
+ Op::FocusColumnOrMonitorRight(1),
Op::FocusWindowUp,
Op::FocusWindowUpOrColumnLeft,
Op::FocusWindowUpOrColumnRight,