Skip to content

Add focus-follows-mouse feature#1993

Open
Dadams2 wants to merge 1 commit intonikitabobko:mainfrom
Dadams2:v3-focus-follows-mouse
Open

Add focus-follows-mouse feature#1993
Dadams2 wants to merge 1 commit intonikitabobko:mainfrom
Dadams2:v3-focus-follows-mouse

Conversation

@Dadams2
Copy link

@Dadams2 Dadams2 commented Mar 7, 2026

My third attempt at closing: #12

The following cases are handled with CGWindowListCopyWindowInfo
- tiled over floating
- floating over tiled
- multiple overlapping floating

CGWindowListCopyWindowInfo is a public CoreGraphics API already used in windowLevelCache.swift so hopefully it is ok to use in this context.

The following edge cases are also considered:
- Focus changes are suppressed while the left mouse button is held (drag operations).
- The handler is a no-op when AeroSpace is disabled (RunSessionGuard check).
- No feedback loop occurs with mouse-follows-focus because move-mouse monitor-lazy-center is a no-op when the cursor is already inside the target,

    Closes nikitabobko#12

    Implement the inverse of the existing mouse-follows-focus feature:
    hovering the cursor over a window automatically focuses it. This is
    a commonly requested feature from users of i3/Sway/Yabai.

    The feature is controlled by a new boolean config option
    `focus-follows-mouse` (default: false). When enabled, a global
    NSEvent monitor for .mouseMoved events resolves which window is
    under the cursor and focuses it via runLightSession.

    Window resolution uses CGWindowListCopyWindowInfo, which returns
    the proper stacking order as determined by macOS.

    The first AeroSpace-managed window whose kCGWindowBounds contains
    the cursor is the target. This should handle the following z-order
    scenarios:
        - tiled over floating
        - floating over tiled
        - multiple overlapping floating

    CGWindowListCopyWindowInfo is a public CoreGraphics API already
    used in windowLevelCache.swift.

    The following edge cases are also considered:
        - Focus changes are suppressed while the left mouse button is
          held (drag operations).
        - The handler is a no-op when AeroSpace is
          disabled (RunSessionGuard check).
        - No feedback loop occurs with mouse-follows-focus
          because move-mouse monitor-lazy-center is a no-op when
          the cursor is already inside the target,

    The monitor is installed at startup (GlobalObserver.initObserver)
    and reinstalled on config reload (ReloadConfigCommand) so toggling
    the option should effect immediately without restarting.
@jgengo
Copy link

jgengo commented Mar 9, 2026

I would love seeing this merged. I've been working with Omarchy, which provides this functionality out of the box, and I felt a bit disconnected when returning to my MacBook. 🩵 Thanks for the PR!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants