This commit is contained in:
Filipe Paniguel 2024-06-21 16:31:37 +00:00 committed by GitHub
commit 0944f6f24f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 134 additions and 0 deletions

View File

@ -954,6 +954,8 @@ pub enum Action {
FocusWindowUpOrColumnRight,
FocusWindowOrWorkspaceDown,
FocusWindowOrWorkspaceUp,
FocusWindowOrMonitorLeft,
FocusWindowOrMonitorRight,
MoveColumnLeft,
MoveColumnRight,
MoveColumnToFirst,
@ -1030,6 +1032,8 @@ impl From<niri_ipc::Action> for Action {
niri_ipc::Action::FocusWindowUpOrColumnRight => Self::FocusWindowUpOrColumnRight,
niri_ipc::Action::FocusWindowOrWorkspaceDown => Self::FocusWindowOrWorkspaceDown,
niri_ipc::Action::FocusWindowOrWorkspaceUp => Self::FocusWindowOrWorkspaceUp,
niri_ipc::Action::FocusWindowOrMonitorLeft => Self::FocusWindowOrMonitorLeft,
niri_ipc::Action::FocusWindowOrMonitorRight => Self::FocusWindowOrMonitorRight,
niri_ipc::Action::MoveColumnLeft => Self::MoveColumnLeft,
niri_ipc::Action::MoveColumnRight => Self::MoveColumnRight,
niri_ipc::Action::MoveColumnToFirst => Self::MoveColumnToFirst,

View File

@ -136,6 +136,10 @@ pub enum Action {
FocusWindowOrWorkspaceDown,
/// Focus the window or the workspace above.
FocusWindowOrWorkspaceUp,
/// Focus the window or the monitor to the left.
FocusWindowOrMonitorLeft,
/// Focus the window or the monitor to the right.
FocusWindowOrMonitorRight,
/// Move the focused column to the left.
MoveColumnLeft,
/// Move the focused column to the right.

View File

@ -644,6 +644,40 @@ impl State {
// FIXME: granular
self.niri.queue_redraw_all();
}
Action::FocusWindowOrMonitorLeft => {
if let Some(output) = self.niri.output_left() {
if self.niri.layout.should_focus_window_left() {
self.maybe_warp_cursor_to_focus();
} else if self.niri.layout.should_focus_monitor_left(&output)
&& !self.maybe_warp_cursor_to_focus_centered()
{
self.move_cursor_to_output(&output);
}
} else {
self.niri.layout.focus_left();
self.maybe_warp_cursor_to_focus();
}
// FIXME: granular
self.niri.queue_redraw_all();
}
Action::FocusWindowOrMonitorRight => {
if let Some(output) = self.niri.output_right() {
if self.niri.layout.should_focus_window_right() {
self.maybe_warp_cursor_to_focus();
} else if self.niri.layout.should_focus_monitor_right(&output)
&& !self.maybe_warp_cursor_to_focus_centered()
{
self.move_cursor_to_output(&output);
}
} else {
self.niri.layout.focus_right();
self.maybe_warp_cursor_to_focus();
}
// FIXME: granular
self.niri.queue_redraw_all();
}
Action::MoveWindowToWorkspaceDown => {
self.niri.layout.move_to_workspace_down();
self.maybe_warp_cursor_to_focus();

View File

@ -1320,6 +1320,76 @@ impl<W: LayoutElement> Layout<W> {
monitor.focus_window_or_workspace_up();
}
pub fn should_focus_window_left(&mut self) -> bool {
let Some(monitor) = self.active_monitor() else {
return false;
};
let workspace = monitor.active_workspace();
let curr_idx = workspace.active_column_idx;
if !workspace.columns.is_empty() && curr_idx != 0 {
monitor.focus_left();
return true;
}
false
}
pub fn should_focus_monitor_left(&mut self, output: &Output) -> bool {
let Some(monitor) = self.active_monitor() else {
return false;
};
let workspace = monitor.active_workspace();
let curr_idx = workspace.active_column_idx;
if workspace.columns.is_empty() || curr_idx == 0 {
self.focus_output(output);
return true;
}
false
}
pub fn should_focus_window_right(&mut self) -> bool {
let Some(monitor) = self.active_monitor() else {
return false;
};
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 true;
}
false
}
pub fn should_focus_monitor_right(&mut self, output: &Output) -> bool {
let Some(monitor) = self.active_monitor() else {
return false;
};
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 {
self.focus_output(output);
return true;
}
false
}
pub fn move_to_workspace_up(&mut self) {
let Some(monitor) = self.active_monitor() else {
return;
@ -2705,6 +2775,8 @@ mod tests {
FocusWindowUpOrColumnRight,
FocusWindowOrWorkspaceDown,
FocusWindowOrWorkspaceUp,
FocusWindowOrMonitorLeft(#[proptest(strategy = "0..=2u8")] u8), // no idea
FocusWindowOrMonitorRight(#[proptest(strategy = "0..=2u8")] u8), // no idea
MoveColumnLeft,
MoveColumnRight,
MoveColumnToFirst,
@ -3030,6 +3102,22 @@ mod tests {
Op::FocusWindowUpOrColumnRight => layout.focus_up_or_right(),
Op::FocusWindowOrWorkspaceDown => layout.focus_window_or_workspace_down(),
Op::FocusWindowOrWorkspaceUp => layout.focus_window_or_workspace_up(),
Op::FocusWindowOrMonitorLeft(id) => {
let name = format!("output{id}");
let Some(output) = layout.outputs().find(|o| o.name() == name).cloned() else {
return;
};
layout.focus_output(&output);
}
Op::FocusWindowOrMonitorRight(id) => {
let name = format!("output{id}");
let Some(output) = layout.outputs().find(|o| o.name() == name).cloned() else {
return;
};
layout.focus_output(&output);
}
Op::MoveColumnLeft => layout.move_left(),
Op::MoveColumnRight => layout.move_right(),
Op::MoveColumnToFirst => layout.move_column_to_first(),
@ -3250,6 +3338,8 @@ mod tests {
Op::FocusColumnRight,
Op::FocusColumnRightOrFirst,
Op::FocusColumnLeftOrLast,
Op::FocusWindowOrMonitorLeft(0),
Op::FocusWindowOrMonitorRight(1),
Op::FocusWindowUp,
Op::FocusWindowUpOrColumnLeft,
Op::FocusWindowUpOrColumnRight,
@ -3342,6 +3432,8 @@ mod tests {
bbox: Rectangle::from_loc_and_size((0, 0), (100, 200)),
min_max_size: Default::default(),
},
Op::FocusWindowOrMonitorLeft(0),
Op::FocusWindowOrMonitorRight(1),
Op::MoveWindowToOutput(2),
Op::FocusOutput(1),
Op::Communicate(1),