aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/input/mod.rs34
-rw-r--r--src/layout/mod.rs35
-rw-r--r--src/layout/monitor.rs12
-rw-r--r--src/layout/tests.rs113
-rw-r--r--src/ui/hotkey_overlay.rs24
5 files changed, 147 insertions, 71 deletions
diff --git a/src/input/mod.rs b/src/input/mod.rs
index b5213351..05880073 100644
--- a/src/input/mod.rs
+++ b/src/input/mod.rs
@@ -1230,19 +1230,19 @@ impl State {
}
}
}
- Action::MoveColumnToWorkspaceDown => {
- self.niri.layout.move_column_to_workspace_down();
+ Action::MoveColumnToWorkspaceDown(focus) => {
+ self.niri.layout.move_column_to_workspace_down(focus);
self.maybe_warp_cursor_to_focus();
// FIXME: granular
self.niri.queue_redraw_all();
}
- Action::MoveColumnToWorkspaceUp => {
- self.niri.layout.move_column_to_workspace_up();
+ Action::MoveColumnToWorkspaceUp(focus) => {
+ self.niri.layout.move_column_to_workspace_up(focus);
self.maybe_warp_cursor_to_focus();
// FIXME: granular
self.niri.queue_redraw_all();
}
- Action::MoveColumnToWorkspace(reference) => {
+ Action::MoveColumnToWorkspace(reference, focus) => {
if let Some((mut output, index)) =
self.niri.find_output_and_workspace_index(reference)
{
@@ -1255,13 +1255,15 @@ impl State {
if let Some(output) = output {
self.niri
.layout
- .move_column_to_workspace_on_output(&output, index);
- if !self.maybe_warp_cursor_to_focus_centered() {
+ .move_column_to_output(&output, Some(index), focus);
+ if focus && !self.maybe_warp_cursor_to_focus_centered() {
self.move_cursor_to_output(&output);
}
} else {
- self.niri.layout.move_column_to_workspace(index);
- self.maybe_warp_cursor_to_focus();
+ self.niri.layout.move_column_to_workspace(index, focus);
+ if focus {
+ self.maybe_warp_cursor_to_focus();
+ }
}
// FIXME: granular
@@ -1639,7 +1641,7 @@ impl State {
}
Action::MoveColumnToMonitorLeft => {
if let Some(output) = self.niri.output_left() {
- self.niri.layout.move_column_to_output(&output);
+ self.niri.layout.move_column_to_output(&output, None, true);
self.niri.layout.focus_output(&output);
if !self.maybe_warp_cursor_to_focus_centered() {
self.move_cursor_to_output(&output);
@@ -1648,7 +1650,7 @@ impl State {
}
Action::MoveColumnToMonitorRight => {
if let Some(output) = self.niri.output_right() {
- self.niri.layout.move_column_to_output(&output);
+ self.niri.layout.move_column_to_output(&output, None, true);
self.niri.layout.focus_output(&output);
if !self.maybe_warp_cursor_to_focus_centered() {
self.move_cursor_to_output(&output);
@@ -1657,7 +1659,7 @@ impl State {
}
Action::MoveColumnToMonitorDown => {
if let Some(output) = self.niri.output_down() {
- self.niri.layout.move_column_to_output(&output);
+ self.niri.layout.move_column_to_output(&output, None, true);
self.niri.layout.focus_output(&output);
if !self.maybe_warp_cursor_to_focus_centered() {
self.move_cursor_to_output(&output);
@@ -1666,7 +1668,7 @@ impl State {
}
Action::MoveColumnToMonitorUp => {
if let Some(output) = self.niri.output_up() {
- self.niri.layout.move_column_to_output(&output);
+ self.niri.layout.move_column_to_output(&output, None, true);
self.niri.layout.focus_output(&output);
if !self.maybe_warp_cursor_to_focus_centered() {
self.move_cursor_to_output(&output);
@@ -1675,7 +1677,7 @@ impl State {
}
Action::MoveColumnToMonitorPrevious => {
if let Some(output) = self.niri.output_previous() {
- self.niri.layout.move_column_to_output(&output);
+ self.niri.layout.move_column_to_output(&output, None, true);
self.niri.layout.focus_output(&output);
if !self.maybe_warp_cursor_to_focus_centered() {
self.move_cursor_to_output(&output);
@@ -1684,7 +1686,7 @@ impl State {
}
Action::MoveColumnToMonitorNext => {
if let Some(output) = self.niri.output_next() {
- self.niri.layout.move_column_to_output(&output);
+ self.niri.layout.move_column_to_output(&output, None, true);
self.niri.layout.focus_output(&output);
if !self.maybe_warp_cursor_to_focus_centered() {
self.move_cursor_to_output(&output);
@@ -1693,7 +1695,7 @@ impl State {
}
Action::MoveColumnToMonitor(output) => {
if let Some(output) = self.niri.output_by_name_match(&output).cloned() {
- self.niri.layout.move_column_to_output(&output);
+ self.niri.layout.move_column_to_output(&output, None, true);
self.niri.layout.focus_output(&output);
if !self.maybe_warp_cursor_to_focus_centered() {
self.move_cursor_to_output(&output);
diff --git a/src/layout/mod.rs b/src/layout/mod.rs
index 1906acd0..d42f05a5 100644
--- a/src/layout/mod.rs
+++ b/src/layout/mod.rs
@@ -1888,7 +1888,7 @@ impl<W: LayoutElement> Layout<W> {
}
}
- self.move_column_to_output(output);
+ self.move_column_to_output(output, None, true);
true
}
@@ -1899,7 +1899,7 @@ impl<W: LayoutElement> Layout<W> {
}
}
- self.move_column_to_output(output);
+ self.move_column_to_output(output, None, true);
true
}
@@ -2213,31 +2213,25 @@ impl<W: LayoutElement> Layout<W> {
monitor.move_to_workspace(window, idx, activate);
}
- pub fn move_column_to_workspace_up(&mut self) {
+ pub fn move_column_to_workspace_up(&mut self, activate: bool) {
let Some(monitor) = self.active_monitor() else {
return;
};
- monitor.move_column_to_workspace_up();
+ monitor.move_column_to_workspace_up(activate);
}
- pub fn move_column_to_workspace_down(&mut self) {
+ pub fn move_column_to_workspace_down(&mut self, activate: bool) {
let Some(monitor) = self.active_monitor() else {
return;
};
- monitor.move_column_to_workspace_down();
+ monitor.move_column_to_workspace_down(activate);
}
- pub fn move_column_to_workspace(&mut self, idx: usize) {
+ pub fn move_column_to_workspace(&mut self, idx: usize, activate: bool) {
let Some(monitor) = self.active_monitor() else {
return;
};
- monitor.move_column_to_workspace(idx);
- }
-
- pub fn move_column_to_workspace_on_output(&mut self, output: &Output, idx: usize) {
- self.move_column_to_output(output);
- self.focus_output(output);
- self.move_column_to_workspace(idx);
+ monitor.move_column_to_workspace(idx, activate);
}
pub fn switch_workspace_up(&mut self) {
@@ -3559,7 +3553,12 @@ impl<W: LayoutElement> Layout<W> {
}
}
- pub fn move_column_to_output(&mut self, output: &Output) {
+ pub fn move_column_to_output(
+ &mut self,
+ output: &Output,
+ target_ws_idx: Option<usize>,
+ activate: bool,
+ ) {
if let MonitorSet::Normal {
monitors,
active_monitor_idx,
@@ -3583,8 +3582,10 @@ impl<W: LayoutElement> Layout<W> {
return;
};
- let workspace_idx = monitors[new_idx].active_workspace_idx;
- self.add_column_by_idx(new_idx, workspace_idx, column, true);
+ let workspace_idx = target_ws_idx
+ .unwrap_or(monitors[new_idx].active_workspace_idx)
+ .min(monitors[new_idx].workspaces.len() - 1);
+ self.add_column_by_idx(new_idx, workspace_idx, column, activate);
}
}
diff --git a/src/layout/monitor.rs b/src/layout/monitor.rs
index ad91f874..6c2a906a 100644
--- a/src/layout/monitor.rs
+++ b/src/layout/monitor.rs
@@ -738,7 +738,7 @@ impl<W: LayoutElement> Monitor<W> {
}
}
- pub fn move_column_to_workspace_up(&mut self) {
+ pub fn move_column_to_workspace_up(&mut self, activate: bool) {
let source_workspace_idx = self.active_workspace_idx;
let new_idx = source_workspace_idx.saturating_sub(1);
@@ -756,10 +756,10 @@ impl<W: LayoutElement> Monitor<W> {
return;
};
- self.add_column(new_idx, column, true);
+ self.add_column(new_idx, column, activate);
}
- pub fn move_column_to_workspace_down(&mut self) {
+ pub fn move_column_to_workspace_down(&mut self, activate: bool) {
let source_workspace_idx = self.active_workspace_idx;
let new_idx = min(source_workspace_idx + 1, self.workspaces.len() - 1);
@@ -777,10 +777,10 @@ impl<W: LayoutElement> Monitor<W> {
return;
};
- self.add_column(new_idx, column, true);
+ self.add_column(new_idx, column, activate);
}
- pub fn move_column_to_workspace(&mut self, idx: usize) {
+ pub fn move_column_to_workspace(&mut self, idx: usize, activate: bool) {
let source_workspace_idx = self.active_workspace_idx;
let new_idx = min(idx, self.workspaces.len() - 1);
@@ -798,7 +798,7 @@ impl<W: LayoutElement> Monitor<W> {
return;
};
- self.add_column(new_idx, column, true);
+ self.add_column(new_idx, column, activate);
}
pub fn switch_workspace_up(&mut self) {
diff --git a/src/layout/tests.rs b/src/layout/tests.rs
index 349f95d7..4ac5aaf7 100644
--- a/src/layout/tests.rs
+++ b/src/layout/tests.rs
@@ -473,9 +473,9 @@ enum Op {
#[proptest(strategy = "0..=4usize")]
workspace_idx: usize,
},
- MoveColumnToWorkspaceDown,
- MoveColumnToWorkspaceUp,
- MoveColumnToWorkspace(#[proptest(strategy = "0..=4usize")] usize),
+ MoveColumnToWorkspaceDown(bool),
+ MoveColumnToWorkspaceUp(bool),
+ MoveColumnToWorkspace(#[proptest(strategy = "0..=4usize")] usize, bool),
MoveWorkspaceDown,
MoveWorkspaceUp,
MoveWorkspaceToIndex {
@@ -508,7 +508,13 @@ enum Op {
#[proptest(strategy = "proptest::option::of(0..=4usize)")]
target_ws_idx: Option<usize>,
},
- MoveColumnToOutput(#[proptest(strategy = "1..=5usize")] usize),
+ MoveColumnToOutput {
+ #[proptest(strategy = "1..=5usize")]
+ output_id: usize,
+ #[proptest(strategy = "proptest::option::of(0..=4usize)")]
+ target_ws_idx: Option<usize>,
+ activate: bool,
+ },
SwitchPresetColumnWidth,
SwitchPresetWindowWidth {
#[proptest(strategy = "proptest::option::of(1..=5usize)")]
@@ -1074,9 +1080,9 @@ impl Op {
let window_id = window_id.filter(|id| layout.has_window(id));
layout.move_to_workspace(window_id.as_ref(), workspace_idx, ActivateWindow::Smart);
}
- Op::MoveColumnToWorkspaceDown => layout.move_column_to_workspace_down(),
- Op::MoveColumnToWorkspaceUp => layout.move_column_to_workspace_up(),
- Op::MoveColumnToWorkspace(idx) => layout.move_column_to_workspace(idx),
+ Op::MoveColumnToWorkspaceDown(focus) => layout.move_column_to_workspace_down(focus),
+ Op::MoveColumnToWorkspaceUp(focus) => layout.move_column_to_workspace_up(focus),
+ Op::MoveColumnToWorkspace(idx, focus) => layout.move_column_to_workspace(idx, focus),
Op::MoveWindowToOutput {
window_id,
output_id: id,
@@ -1097,13 +1103,17 @@ impl Op {
ActivateWindow::Smart,
);
}
- Op::MoveColumnToOutput(id) => {
+ Op::MoveColumnToOutput {
+ output_id: id,
+ target_ws_idx,
+ activate,
+ } => {
let name = format!("output{id}");
let Some(output) = layout.outputs().find(|o| o.name() == name).cloned() else {
return;
};
- layout.move_column_to_output(&output);
+ layout.move_column_to_output(&output, target_ws_idx, activate);
}
Op::MoveWorkspaceDown => layout.move_workspace_down(),
Op::MoveWorkspaceUp => layout.move_workspace_up(),
@@ -1560,10 +1570,10 @@ fn operations_dont_panic() {
window_id: None,
workspace_idx: 2,
},
- Op::MoveColumnToWorkspaceDown,
- Op::MoveColumnToWorkspaceUp,
- Op::MoveColumnToWorkspace(1),
- Op::MoveColumnToWorkspace(2),
+ Op::MoveColumnToWorkspaceDown(true),
+ Op::MoveColumnToWorkspaceUp(true),
+ Op::MoveColumnToWorkspace(1, true),
+ Op::MoveColumnToWorkspace(2, true),
Op::MoveWindowDown,
Op::MoveWindowDownOrToWorkspaceDown,
Op::MoveWindowUp,
@@ -1735,11 +1745,11 @@ fn operations_from_starting_state_dont_panic() {
window_id: None,
workspace_idx: 3,
},
- Op::MoveColumnToWorkspaceDown,
- Op::MoveColumnToWorkspaceUp,
- Op::MoveColumnToWorkspace(1),
- Op::MoveColumnToWorkspace(2),
- Op::MoveColumnToWorkspace(3),
+ Op::MoveColumnToWorkspaceDown(true),
+ Op::MoveColumnToWorkspaceUp(true),
+ Op::MoveColumnToWorkspace(1, true),
+ Op::MoveColumnToWorkspace(2, true),
+ Op::MoveColumnToWorkspace(3, true),
Op::MoveWindowDown,
Op::MoveWindowDownOrToWorkspaceDown,
Op::MoveWindowUp,
@@ -2058,8 +2068,8 @@ fn workspace_transfer_during_switch_gets_cleaned_up() {
},
Op::RemoveOutput(1),
Op::AddOutput(2),
- Op::MoveColumnToWorkspaceDown,
- Op::MoveColumnToWorkspaceDown,
+ Op::MoveColumnToWorkspaceDown(true),
+ Op::MoveColumnToWorkspaceDown(true),
Op::AddOutput(1),
];
@@ -3355,6 +3365,69 @@ fn interactive_resize_on_pending_unfullscreen_column() {
}
#[test]
+fn move_column_to_workspace_unfocused_with_multiple_monitors() {
+ let ops = [
+ Op::AddOutput(1),
+ Op::SetWorkspaceName {
+ new_ws_name: 101,
+ ws_name: None,
+ },
+ Op::AddWindow {
+ params: TestWindowParams::new(1),
+ },
+ Op::FocusWorkspaceDown,
+ Op::SetWorkspaceName {
+ new_ws_name: 102,
+ ws_name: None,
+ },
+ Op::AddWindow {
+ params: TestWindowParams::new(2),
+ },
+ Op::AddOutput(2),
+ Op::FocusOutput(2),
+ Op::SetWorkspaceName {
+ new_ws_name: 201,
+ ws_name: None,
+ },
+ Op::AddWindow {
+ params: TestWindowParams::new(3),
+ },
+ Op::AddWindow {
+ params: TestWindowParams::new(4),
+ },
+ Op::MoveColumnToOutput {
+ output_id: 1,
+ target_ws_idx: Some(0),
+ activate: false,
+ },
+ Op::FocusOutput(1),
+ ];
+
+ let layout = check_ops(&ops);
+
+ assert_eq!(layout.active_workspace().unwrap().name().unwrap(), "ws102");
+
+ for (mon, win) in layout.windows() {
+ let mon = mon.unwrap();
+ let ws = mon
+ .workspaces
+ .iter()
+ .find(|w| w.has_window(win.id()))
+ .unwrap();
+
+ assert_eq!(
+ ws.name().unwrap(),
+ match win.id() {
+ 1 | 4 => "ws101",
+ 2 => "ws102",
+ 3 => "ws201",
+ _ => unreachable!(),
+ }
+ );
+ }
+}
+
+#[test]
fn interactive_move_unfullscreen_to_floating_stops_dnd_scroll() {
let ops = [
Op::AddOutput(3),
diff --git a/src/ui/hotkey_overlay.rs b/src/ui/hotkey_overlay.rs
index 660d569b..1430a9d6 100644
--- a/src/ui/hotkey_overlay.rs
+++ b/src/ui/hotkey_overlay.rs
@@ -211,33 +211,33 @@ fn render(
]);
// Prefer move-column-to-workspace-down, but fall back to move-window-to-workspace-down.
- if binds
+ if let Some(bind) = binds
.iter()
- .any(|bind| bind.action == Action::MoveColumnToWorkspaceDown)
+ .find(|bind| matches!(bind.action, Action::MoveColumnToWorkspaceDown(_)))
{
- actions.push(&Action::MoveColumnToWorkspaceDown);
+ actions.push(&bind.action);
} else if binds
.iter()
- .any(|bind| bind.action == Action::MoveWindowToWorkspaceDown)
+ .any(|bind| matches!(bind.action, Action::MoveWindowToWorkspaceDown))
{
actions.push(&Action::MoveWindowToWorkspaceDown);
} else {
- actions.push(&Action::MoveColumnToWorkspaceDown);
+ actions.push(&Action::MoveColumnToWorkspaceDown(true));
}
// Same for -up.
- if binds
+ if let Some(bind) = binds
.iter()
- .any(|bind| bind.action == Action::MoveColumnToWorkspaceUp)
+ .find(|bind| matches!(bind.action, Action::MoveColumnToWorkspaceUp(_)))
{
- actions.push(&Action::MoveColumnToWorkspaceUp);
+ actions.push(&bind.action);
} else if binds
.iter()
- .any(|bind| bind.action == Action::MoveWindowToWorkspaceUp)
+ .any(|bind| matches!(bind.action, Action::MoveWindowToWorkspaceUp))
{
actions.push(&Action::MoveWindowToWorkspaceUp);
} else {
- actions.push(&Action::MoveColumnToWorkspaceUp);
+ actions.push(&Action::MoveColumnToWorkspaceUp(true));
}
actions.extend(&[
@@ -424,8 +424,8 @@ fn action_name(action: &Action) -> String {
Action::MoveColumnRight => String::from("Move Column Right"),
Action::FocusWorkspaceDown => String::from("Switch Workspace Down"),
Action::FocusWorkspaceUp => String::from("Switch Workspace Up"),
- Action::MoveColumnToWorkspaceDown => String::from("Move Column to Workspace Down"),
- Action::MoveColumnToWorkspaceUp => String::from("Move Column to Workspace Up"),
+ Action::MoveColumnToWorkspaceDown(_) => String::from("Move Column to Workspace Down"),
+ Action::MoveColumnToWorkspaceUp(_) => String::from("Move Column to Workspace Up"),
Action::MoveWindowToWorkspaceDown => String::from("Move Window to Workspace Down"),
Action::MoveWindowToWorkspaceUp => String::from("Move Window to Workspace Up"),
Action::SwitchPresetColumnWidth => String::from("Switch Preset Column Widths"),