Add option to disable auto-raise for focus-follows-cursor - #2535
Closed
perpetualbits wants to merge 3 commits into
Closed
Add option to disable auto-raise for focus-follows-cursor#2535perpetualbits wants to merge 3 commits into
perpetualbits wants to merge 3 commits into
Conversation
This was referenced Jul 8, 2026
Member
|
The PR template is required. |
Assisted-by: Claude Code (Anthropic) Signed-off-by: Roland Nagtegaal <perpetualbits@gmail.com>
Assisted-by: Claude Code (Anthropic) Signed-off-by: Roland Nagtegaal <perpetualbits@gmail.com>
Add a Raise intent enum threaded through Shell::set_focus and a single persisted no-raise window mark on Shell. update_active() skips raising the marked window, so focus-follows-cursor can move focus without lifting the window (sloppy focus) when focus_follows_cursor_raise is false. Explicit focus (click, keyboard, activation) passes Raise::Yes and still raises. Assisted-by: Claude Code (Anthropic) Signed-off-by: Roland Nagtegaal <perpetualbits@gmail.com>
perpetualbits
force-pushed
the
focus-follows-cursor-no-raise
branch
from
July 10, 2026 08:20
f2a3bdb to
3ce0f61
Compare
5 tasks
Author
|
Superseded by #2612. While addressing the checklist request I re-tested this change on real hardware Closing this in favour of #2612 to keep review in one place. Thanks! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Addresses #863.
AI assistance disclosure
This change was developed with AI assistance (Claude Code); the commits carry an
Assisted-by:trailer. Per your policy I want to be upfront about it rather thanhide it. The design decisions here are mine and I understand the change in full:
the intent-enum approach, the reason a persisted mark is needed (see
Implementation), and the trade-offs in the scope note are all things I can defend
in review. It was validated by me on real hardware (see Testing). I'm happy to
walk through any part of it or make changes on request.
Summary
Adds a new compositor config option,
focus_follows_cursor_raise(defaulttrue,preserving current behaviour), that decouples raising from focusing when focus
follows the cursor.
With
focus_follows_cursorenabled andfocus_follows_cursor_raiseset tofalse, moving the pointer over a floating window gives it keyboard focuswithout raising it to the front ("sloppy focus"). Explicit focus — a click, a
keyboard focus action, or an application activating itself — still raises the
window as before.
Motivation
Today focus and raising are coupled: any focus change runs
update_active(),which raises the focused floating window. With focus-follows-cursor that means a
window jumps to the front merely because the pointer crossed it. This option lets
the two behaviours be chosen independently, which is the long-standing "focus
follows mouse, no auto-raise" model many users prefer.
Implementation
focus_follows_cursor_raiseincosmic-comp-config(defaulttrue),with live reload wired into the existing config watcher.
Raise { Yes, No }intent enum threaded throughShell::set_focus. Anamed enum is used rather than a second
boolnext to the existingupdate_cursorargument, so call sites stay self-documenting and the compilerenforces completeness — a missed call site cannot build. Every explicit-focus
call site passes
Raise::Yes; only the focus-follows-cursor timer passes theconfigured choice.
no_raise_windowmark onShell. This is needed because focus isreconciled periodically:
update_active()is re-run and would re-raise thefocused floating window on the next pass, so suppressing the raise once is not
enough. Instead the hovered window is recorded and
update_active()skipsraising it every time it runs, under the same write lock that runs
update_active()so the two never disagree. The mark is set on passive focuswith raising disabled and cleared on any explicit focus.
Testing
cargo buildandcargo fmt --checkare clean.focus_follows_cursor_raise = true) is covered by a unit test incosmic-comp-config.focus_follows_cursoron andfocus_follows_cursor_raiseoff, hovering apartly-covered floating window focuses it without raising it, and clicking still
raises it. Toggling
focus_follows_cursor_raiseat runtime switches thebehaviour immediately (live reload).
Note: focus-follows-cursor only triggers under the KMS backend, since the
follow-cursor logic lives in the relative-motion (
PointerMotion) handler; thenested
winit/x11backends deliver absolute motion, so this must be exercised ona real session rather than nested.
Note on scope
The no-raise mark is a single value on
Shellrather than per-seat. In the commonsingle-seat case this is exact. In a multi-seat setup, one seat's explicit focus
clears another seat's hover mark, so the other seat's hovered window can be
re-raised on the next reconciliation. This keeps the change small; happy to make
it per-seat if preferred.