Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add option to not move cursor when focussing a window via ipc #1094

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 40 additions & 13 deletions niri-config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1434,7 +1434,10 @@ pub enum Action {
#[knuffel(skip)]
FullscreenWindowById(u64),
#[knuffel(skip)]
FocusWindow(u64),
FocusWindow {
id: u64,
no_mouse_warp: bool,
},
FocusWindowInColumn(#[knuffel(argument)] u8),
FocusWindowPrevious,
FocusColumnLeft,
Expand Down Expand Up @@ -1485,9 +1488,9 @@ pub enum Action {
CenterWindow,
#[knuffel(skip)]
CenterWindowById(u64),
FocusWorkspaceDown,
FocusWorkspaceUp,
FocusWorkspace(#[knuffel(argument)] WorkspaceReference),
FocusWorkspaceDown(FocusWorkspaceArgument),
FocusWorkspaceUp(FocusWorkspaceArgument),
FocusWorkspace(FocusWorkspaceWithReference),
FocusWorkspacePrevious,
MoveWindowToWorkspaceDown,
MoveWindowToWorkspaceUp,
Expand Down Expand Up @@ -1596,6 +1599,20 @@ pub enum Action {
ToggleWindowRuleOpacityById(u64),
}

#[derive(knuffel::Decode, Debug, Clone, PartialEq)]
pub struct FocusWorkspaceArgument {
#[knuffel(argument, default)]
pub no_mouse_warp: bool,
}

#[derive(knuffel::Decode, Debug, Clone, PartialEq)]
pub struct FocusWorkspaceWithReference {
#[knuffel(argument)]
pub reference: WorkspaceReference,
#[knuffel(argument, default)]
pub no_mouse_warp: bool,
}

impl From<niri_ipc::Action> for Action {
fn from(value: niri_ipc::Action) -> Self {
match value {
Expand All @@ -1620,7 +1637,9 @@ impl From<niri_ipc::Action> for Action {
niri_ipc::Action::CloseWindow { id: Some(id) } => Self::CloseWindowById(id),
niri_ipc::Action::FullscreenWindow { id: None } => Self::FullscreenWindow,
niri_ipc::Action::FullscreenWindow { id: Some(id) } => Self::FullscreenWindowById(id),
niri_ipc::Action::FocusWindow { id } => Self::FocusWindow(id),
niri_ipc::Action::FocusWindow { id, no_mouse_warp } => {
Self::FocusWindow { id, no_mouse_warp }
}
niri_ipc::Action::FocusWindowInColumn { index } => Self::FocusWindowInColumn(index),
niri_ipc::Action::FocusWindowPrevious {} => Self::FocusWindowPrevious,
niri_ipc::Action::FocusColumnLeft {} => Self::FocusColumnLeft,
Expand Down Expand Up @@ -1682,11 +1701,19 @@ impl From<niri_ipc::Action> for Action {
niri_ipc::Action::CenterColumn {} => Self::CenterColumn,
niri_ipc::Action::CenterWindow { id: None } => Self::CenterWindow,
niri_ipc::Action::CenterWindow { id: Some(id) } => Self::CenterWindowById(id),
niri_ipc::Action::FocusWorkspaceDown {} => Self::FocusWorkspaceDown,
niri_ipc::Action::FocusWorkspaceUp {} => Self::FocusWorkspaceUp,
niri_ipc::Action::FocusWorkspace { reference } => {
Self::FocusWorkspace(WorkspaceReference::from(reference))
niri_ipc::Action::FocusWorkspaceDown { no_mouse_warp } => {
Self::FocusWorkspaceDown(FocusWorkspaceArgument { no_mouse_warp })
}
niri_ipc::Action::FocusWorkspaceUp { no_mouse_warp } => {
Self::FocusWorkspaceUp(FocusWorkspaceArgument { no_mouse_warp })
}
niri_ipc::Action::FocusWorkspace {
reference,
no_mouse_warp,
} => Self::FocusWorkspace(FocusWorkspaceWithReference {
reference: WorkspaceReference::from(reference),
no_mouse_warp,
}),
niri_ipc::Action::FocusWorkspacePrevious {} => Self::FocusWorkspacePrevious,
niri_ipc::Action::MoveWindowToWorkspaceDown {} => Self::MoveWindowToWorkspaceDown,
niri_ipc::Action::MoveWindowToWorkspaceUp {} => Self::MoveWindowToWorkspaceUp,
Expand Down Expand Up @@ -4149,7 +4176,7 @@ mod tests {
trigger: Trigger::Keysym(Keysym::_1),
modifiers: Modifiers::COMPOSITOR,
},
action: Action::FocusWorkspace(WorkspaceReference::Index(1)),
action: Action::FocusWorkspace( FocusWorkspaceWithReference{reference: WorkspaceReference::Index(1), no_mouse_warp: false}),
repeat: true,
cooldown: None,
allow_when_locked: false,
Expand All @@ -4161,9 +4188,9 @@ mod tests {
trigger: Trigger::Keysym(Keysym::_1),
modifiers: Modifiers::COMPOSITOR | Modifiers::SHIFT,
},
action: Action::FocusWorkspace(WorkspaceReference::Name(
action: Action::FocusWorkspace(FocusWorkspaceWithReference{reference: WorkspaceReference::Name(
"workspace-1".to_string(),
)),
), no_mouse_warp: false}),
repeat: true,
cooldown: None,
allow_when_locked: false,
Expand All @@ -4187,7 +4214,7 @@ mod tests {
trigger: Trigger::WheelScrollDown,
modifiers: Modifiers::COMPOSITOR,
},
action: Action::FocusWorkspaceDown,
action: Action::FocusWorkspaceDown(FocusWorkspaceArgument{no_mouse_warp: false}),
repeat: true,
cooldown: Some(Duration::from_millis(150)),
allow_when_locked: false,
Expand Down
18 changes: 16 additions & 2 deletions niri-ipc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,9 @@ pub enum Action {
/// Id of the window to focus.
#[cfg_attr(feature = "clap", arg(long))]
id: u64,
/// Disable moving the cursor to the newly focused window or output.
#[cfg_attr(feature = "clap", arg(long))]
no_mouse_warp: bool,
},
/// Focus a window in the focused column by index.
FocusWindowInColumn {
Expand Down Expand Up @@ -344,14 +347,25 @@ pub enum Action {
id: Option<u64>,
},
/// Focus the workspace below.
FocusWorkspaceDown {},
FocusWorkspaceDown {
/// Disable moving the cursor to the newly focused window or output.
#[cfg_attr(feature = "clap", arg(long))]
no_mouse_warp: bool,
},
/// Focus the workspace above.
FocusWorkspaceUp {},
FocusWorkspaceUp {
/// Disable moving the cursor to the newly focused window or output.
#[cfg_attr(feature = "clap", arg(long))]
no_mouse_warp: bool,
},
/// Focus a workspace by reference (index or name).
FocusWorkspace {
/// Reference (index or name) of the workspace to focus.
#[cfg_attr(feature = "clap", arg())]
reference: WorkspaceReferenceArg,
/// Disable moving the cursor to the newly focused window or output.
#[cfg_attr(feature = "clap", arg(long))]
no_mouse_warp: bool,
},
/// Focus the previous workspace.
FocusWorkspacePrevious {},
Expand Down
31 changes: 22 additions & 9 deletions src/input/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -679,11 +679,15 @@ impl State {
self.niri.queue_redraw_all();
}
}
Action::FocusWindow(id) => {
Action::FocusWindow { id, no_mouse_warp } => {
let window = self.niri.layout.windows().find(|(_, m)| m.id().get() == id);
let window = window.map(|(_, m)| m.window.clone());
if let Some(window) = window {
self.focus_window(&window);
if !no_mouse_warp {
self.focus_window(&window);
return;
}
self.focus_window_without_moving_cursor(&window);
}
}
Action::FocusWindowInColumn(index) => {
Expand Down Expand Up @@ -1149,21 +1153,28 @@ impl State {
self.niri.queue_redraw_all();
}
}
Action::FocusWorkspaceDown => {
Action::FocusWorkspaceDown(niri_config::FocusWorkspaceArgument { no_mouse_warp }) => {
self.niri.layout.switch_workspace_down();
self.maybe_warp_cursor_to_focus();
if !no_mouse_warp {
self.maybe_warp_cursor_to_focus();
}
self.niri.layer_shell_on_demand_focus = None;
// FIXME: granular
self.niri.queue_redraw_all();
}
Action::FocusWorkspaceUp => {
Action::FocusWorkspaceUp(niri_config::FocusWorkspaceArgument { no_mouse_warp }) => {
self.niri.layout.switch_workspace_up();
self.maybe_warp_cursor_to_focus();
if !no_mouse_warp {
self.maybe_warp_cursor_to_focus();
}
self.niri.layer_shell_on_demand_focus = None;
// FIXME: granular
self.niri.queue_redraw_all();
}
Action::FocusWorkspace(reference) => {
Action::FocusWorkspace(niri_config::FocusWorkspaceWithReference {
reference,
no_mouse_warp,
}) => {
if let Some((mut output, index)) =
self.niri.find_output_and_workspace_index(reference)
{
Expand All @@ -1176,7 +1187,7 @@ impl State {
if let Some(output) = output {
self.niri.layout.focus_output(&output);
self.niri.layout.switch_workspace(index);
if !self.maybe_warp_cursor_to_focus_centered() {
if !no_mouse_warp && !self.maybe_warp_cursor_to_focus_centered() {
self.move_cursor_to_output(&output);
}
} else {
Expand All @@ -1186,7 +1197,9 @@ impl State {
} else {
self.niri.layout.switch_workspace(index);
}
self.maybe_warp_cursor_to_focus();
if !no_mouse_warp {
self.maybe_warp_cursor_to_focus();
}
}
self.niri.layer_shell_on_demand_focus = None;

Expand Down
7 changes: 7 additions & 0 deletions src/niri.rs
Original file line number Diff line number Diff line change
Expand Up @@ -775,6 +775,13 @@ impl State {
self.niri.queue_redraw_all();
}

/// Focus a specific window without moving the cursor.
pub fn focus_window_without_moving_cursor(&mut self, window: &Window) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe instead a bool argument to focus_window()?

Copy link
Author

@prog-r-amer prog-r-amer Feb 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sure, I just thought maybe there's more and more arguments coming and it's better to just duplicate since I didn't know what to do with the maybe warp cursor. I guess not moving cursor should override warp to focus but I wasnt sure.

self.niri.layout.activate_window(window);
// FIXME: granular
self.niri.queue_redraw_all();
}

pub fn maybe_warp_cursor_to_focus(&mut self) -> bool {
if !self.niri.config.borrow().input.warp_mouse_to_focus {
return false;
Expand Down
12 changes: 8 additions & 4 deletions src/ui/hotkey_overlay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,8 +210,12 @@ fn render(
&Action::FocusColumnRight,
&Action::MoveColumnLeft,
&Action::MoveColumnRight,
&Action::FocusWorkspaceDown,
&Action::FocusWorkspaceUp,
&Action::FocusWorkspaceDown(niri_config::FocusWorkspaceArgument {
no_mouse_warp: false,
}),
&Action::FocusWorkspaceUp(niri_config::FocusWorkspaceArgument {
no_mouse_warp: false,
}),
]);

// Prefer move-column-to-workspace-down, but fall back to move-window-to-workspace-down.
Expand Down Expand Up @@ -422,8 +426,8 @@ fn action_name(action: &Action) -> String {
Action::FocusColumnRight => String::from("Focus Column to the Right"),
Action::MoveColumnLeft => String::from("Move Column Left"),
Action::MoveColumnRight => String::from("Move Column Right"),
Action::FocusWorkspaceDown => String::from("Switch Workspace Down"),
Action::FocusWorkspaceUp => String::from("Switch Workspace Up"),
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::MoveWindowToWorkspaceDown => String::from("Move Window to Workspace Down"),
Expand Down