Add focus argument to move-window-to-workspace (#1332)

* layout: add focus flag to move-window-to-workspace

* lib: update comment

* misc: minor dup refactor

* input: format code

* layout: minor nit

* layout: update comment

* input: remove unnecessary conditionals

* misc: replace boolean

* tests: fix the failing one

* layout: change to smart

* ipc: Option<bool> -> bool

* lib: format code

* Rewrite focus doc comment

---------

Co-authored-by: Ivan Molodetskikh <yalterz@gmail.com>
This commit is contained in:
nyx
2025-03-29 02:40:08 -04:00
committed by GitHub
parent 7cfecf4b1b
commit 0db48e2f1b
6 changed files with 58 additions and 19 deletions
+9 -2
View File
@@ -1592,11 +1592,15 @@ pub enum Action {
FocusWorkspacePrevious, FocusWorkspacePrevious,
MoveWindowToWorkspaceDown, MoveWindowToWorkspaceDown,
MoveWindowToWorkspaceUp, MoveWindowToWorkspaceUp,
MoveWindowToWorkspace(#[knuffel(argument)] WorkspaceReference), MoveWindowToWorkspace(
#[knuffel(argument)] WorkspaceReference,
#[knuffel(property(name = "focus"), default = true)] bool,
),
#[knuffel(skip)] #[knuffel(skip)]
MoveWindowToWorkspaceById { MoveWindowToWorkspaceById {
window_id: u64, window_id: u64,
reference: WorkspaceReference, reference: WorkspaceReference,
focus: bool,
}, },
MoveColumnToWorkspaceDown, MoveColumnToWorkspaceDown,
MoveColumnToWorkspaceUp, MoveColumnToWorkspaceUp,
@@ -1817,13 +1821,16 @@ impl From<niri_ipc::Action> for Action {
niri_ipc::Action::MoveWindowToWorkspace { niri_ipc::Action::MoveWindowToWorkspace {
window_id: None, window_id: None,
reference, reference,
} => Self::MoveWindowToWorkspace(WorkspaceReference::from(reference)), focus,
} => Self::MoveWindowToWorkspace(WorkspaceReference::from(reference), focus),
niri_ipc::Action::MoveWindowToWorkspace { niri_ipc::Action::MoveWindowToWorkspace {
window_id: Some(window_id), window_id: Some(window_id),
reference, reference,
focus,
} => Self::MoveWindowToWorkspaceById { } => Self::MoveWindowToWorkspaceById {
window_id, window_id,
reference: WorkspaceReference::from(reference), reference: WorkspaceReference::from(reference),
focus,
}, },
niri_ipc::Action::MoveColumnToWorkspaceDown {} => Self::MoveColumnToWorkspaceDown, niri_ipc::Action::MoveColumnToWorkspaceDown {} => Self::MoveColumnToWorkspaceDown,
niri_ipc::Action::MoveColumnToWorkspaceUp {} => Self::MoveColumnToWorkspaceUp, niri_ipc::Action::MoveColumnToWorkspaceUp {} => Self::MoveColumnToWorkspaceUp,
+8
View File
@@ -426,6 +426,14 @@ pub enum Action {
/// Reference (index or name) of the workspace to move the window to. /// Reference (index or name) of the workspace to move the window to.
#[cfg_attr(feature = "clap", arg())] #[cfg_attr(feature = "clap", arg())]
reference: WorkspaceReferenceArg, reference: WorkspaceReferenceArg,
/// Whether the focus should follow the moved window.
///
/// If `true` (the default) and the window to move is focused, the focus will follow the
/// window to the new workspace. If `false`, the focus will remain on the original
/// workspace.
#[cfg_attr(feature = "clap", arg(long, action = clap::ArgAction::Set, default_value_t = true))]
focus: bool,
}, },
/// Move the focused column to the workspace below. /// Move the focused column to the workspace below.
MoveColumnToWorkspaceDown {}, MoveColumnToWorkspaceDown {},
+17 -4
View File
@@ -40,7 +40,7 @@ use self::move_grab::MoveGrab;
use self::resize_grab::ResizeGrab; use self::resize_grab::ResizeGrab;
use self::spatial_movement_grab::SpatialMovementGrab; use self::spatial_movement_grab::SpatialMovementGrab;
use crate::layout::scrolling::ScrollDirection; use crate::layout::scrolling::ScrollDirection;
use crate::layout::LayoutElement as _; use crate::layout::{ActivateWindow, LayoutElement as _};
use crate::niri::{CastTarget, State}; use crate::niri::{CastTarget, State};
use crate::ui::screenshot_ui::ScreenshotUi; use crate::ui::screenshot_ui::ScreenshotUi;
use crate::utils::spawning::spawn; use crate::utils::spawning::spawn;
@@ -1072,7 +1072,7 @@ impl State {
// FIXME: granular // FIXME: granular
self.niri.queue_redraw_all(); self.niri.queue_redraw_all();
} }
Action::MoveWindowToWorkspace(reference) => { Action::MoveWindowToWorkspace(reference, focus) => {
if let Some((mut output, index)) = if let Some((mut output, index)) =
self.niri.find_output_and_workspace_index(reference) self.niri.find_output_and_workspace_index(reference)
{ {
@@ -1091,7 +1091,12 @@ impl State {
self.move_cursor_to_output(&output); self.move_cursor_to_output(&output);
} }
} else { } else {
self.niri.layout.move_to_workspace(None, index); let activate = if focus {
ActivateWindow::Smart
} else {
ActivateWindow::No
};
self.niri.layout.move_to_workspace(None, index, activate);
self.maybe_warp_cursor_to_focus(); self.maybe_warp_cursor_to_focus();
} }
@@ -1102,6 +1107,7 @@ impl State {
Action::MoveWindowToWorkspaceById { Action::MoveWindowToWorkspaceById {
window_id: id, window_id: id,
reference, reference,
focus,
} => { } => {
let window = self.niri.layout.windows().find(|(_, m)| m.id().get() == id); let window = self.niri.layout.windows().find(|(_, m)| m.id().get() == id);
let window = window.map(|(_, m)| m.window.clone()); let window = window.map(|(_, m)| m.window.clone());
@@ -1130,7 +1136,14 @@ impl State {
} }
} }
} else { } else {
self.niri.layout.move_to_workspace(Some(&window), index); let activate = if focus {
ActivateWindow::Smart
} else {
ActivateWindow::No
};
self.niri
.layout
.move_to_workspace(Some(&window), index, activate);
// If we focused the target window. // If we focused the target window.
let new_focus = self.niri.layout.focus(); let new_focus = self.niri.layout.focus();
+7 -2
View File
@@ -2120,7 +2120,12 @@ impl<W: LayoutElement> Layout<W> {
monitor.move_to_workspace_down(); monitor.move_to_workspace_down();
} }
pub fn move_to_workspace(&mut self, window: Option<&W::Id>, idx: usize) { pub fn move_to_workspace(
&mut self,
window: Option<&W::Id>,
idx: usize,
activate: ActivateWindow,
) {
if let Some(InteractiveMoveState::Moving(move_)) = &mut self.interactive_move { if let Some(InteractiveMoveState::Moving(move_)) = &mut self.interactive_move {
if window.is_none() || window == Some(move_.tile.window().id()) { if window.is_none() || window == Some(move_.tile.window().id()) {
return; return;
@@ -2143,7 +2148,7 @@ impl<W: LayoutElement> Layout<W> {
}; };
monitor monitor
}; };
monitor.move_to_workspace(window, idx); 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) {
+16 -10
View File
@@ -474,7 +474,12 @@ impl<W: LayoutElement> Monitor<W> {
); );
} }
pub fn move_to_workspace(&mut self, window: Option<&W::Id>, idx: usize) { pub fn move_to_workspace(
&mut self,
window: Option<&W::Id>,
idx: usize,
activate: ActivateWindow,
) {
let source_workspace_idx = if let Some(window) = window { let source_workspace_idx = if let Some(window) = window {
self.workspaces self.workspaces
.iter() .iter()
@@ -490,14 +495,11 @@ impl<W: LayoutElement> Monitor<W> {
} }
let new_id = self.workspaces[new_idx].id(); let new_id = self.workspaces[new_idx].id();
let activate = window.map_or(true, |win| { let activate = activate.map_smart(|| {
self.active_window().map(|win| win.id()) == Some(win) window.map_or(true, |win| {
self.active_window().map(|win| win.id()) == Some(win)
})
}); });
let activate = if activate {
ActivateWindow::Yes
} else {
ActivateWindow::No
};
let workspace = &mut self.workspaces[source_workspace_idx]; let workspace = &mut self.workspaces[source_workspace_idx];
let transaction = Transaction::new(); let transaction = Transaction::new();
@@ -515,7 +517,11 @@ impl<W: LayoutElement> Monitor<W> {
id: new_id, id: new_id,
column_idx: None, column_idx: None,
}, },
activate, if activate {
ActivateWindow::Yes
} else {
ActivateWindow::No
},
removed.width, removed.width,
removed.is_full_width, removed.is_full_width,
removed.is_floating, removed.is_floating,
@@ -578,7 +584,7 @@ impl<W: LayoutElement> Monitor<W> {
let workspace = &mut self.workspaces[source_workspace_idx]; let workspace = &mut self.workspaces[source_workspace_idx];
if workspace.floating_is_active() { if workspace.floating_is_active() {
self.move_to_workspace(None, idx); self.move_to_workspace(None, idx, ActivateWindow::Smart);
return; return;
} }
+1 -1
View File
@@ -1063,7 +1063,7 @@ impl Op {
workspace_idx, workspace_idx,
} => { } => {
let window_id = window_id.filter(|id| layout.has_window(id)); let window_id = window_id.filter(|id| layout.has_window(id));
layout.move_to_workspace(window_id.as_ref(), workspace_idx); layout.move_to_workspace(window_id.as_ref(), workspace_idx, ActivateWindow::Smart);
} }
Op::MoveColumnToWorkspaceDown => layout.move_column_to_workspace_down(), Op::MoveColumnToWorkspaceDown => layout.move_column_to_workspace_down(),
Op::MoveColumnToWorkspaceUp => layout.move_column_to_workspace_up(), Op::MoveColumnToWorkspaceUp => layout.move_column_to_workspace_up(),