Fix bug: focus can land on a different window of the same app - #2213
Open
dmellok wants to merge 1 commit into
Open
Fix bug: focus can land on a different window of the same app#2213dmellok wants to merge 1 commit into
dmellok wants to merge 1 commit into
Conversation
nativeFocus could skip the per-window AX raise and call nsApp.activate() alone, on the evidence that the last window AeroSpace observed as focused already matched the requested one. That evidence doesn't hold: activate() focuses whichever window macOS currently holds as the app's main one, while the observation records only what AeroSpace last saw. The two drift apart on their own - a background window taking a link, an app reordering its own windows - so 'focus' on one window of a multi-window app could activate another. The shortcut now requires the app to have exactly one window, where activate() can only mean that window. It still covers the case it was added for: apps slow to answer AX requests, which are overwhelmingly single-window. lastNativeFocusedWindowId goes with it - the shortcut was its only reader. That leaves a race in the general path. The AX raise says which window should be main, and activating the app makes macOS restore whichever window it still holds as main; when macOS wins, focus lands on a sibling window - observed landing on a window parked off-screen on an inactive workspace, which then pulled the focused workspace along with it. The result is checked instead: 150ms after asking, look at the app's focused window and ask once more if it isn't the one requested. The retry is bounded to one attempt, and is skipped when the app is no longer frontmost so that focus moving to another app is left alone. Only reachable when 'Displays have separate Spaces' is off or there is a single monitor, which is why it doesn't reproduce for everyone. Only keyboard-driven focus is affected: a mouse click focuses natively and never enters this path. Measured with two Safari windows, focusing another app between attempts: 1 failure in 8 before, 0 in 24 after. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
dmellok
force-pushed
the
fix-focus-wrong-window
branch
from
August 7, 2026 02:15
b77da48 to
02528c2
Compare
Author
|
Force-pushed a fix for the CI failure. Periphery caught two things:
All five jobs pass now. |
vitorebatista
added a commit
to vitorebatista/AeroSpace-edge
that referenced
this pull request
Aug 27, 2026
…te sync state Sync state moves to upstream main @ c548c7f / 59 open PRs, reviewed 2026-08-27. Adds the newly ported upstream PRs (2244, 2232, 2211, 2228, 2225) to the already-backported list, and records this cycle's skips: focus-follows-mouse PRs (nikitabobko#2238/nikitabobko#2245, feature absent in the fork), nikitabobko#2220 (duplicate of the already-ported nikitabobko#2024), nikitabobko#2213 (deletes lastNativeFocusedWindowId, which fork PR #59 depends on), nikitabobko#2206 (competing implementation of nikitabobko#2225), and six deferred feature PRs. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WBcwRe3CktWZGGcHJHP4ds
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.
The bug
focuson one window of a multi-window app can focus a different window of that app. I hit it constantly with two Safari windows; it also pulled the focused workspace along when the window macOS picked was one AeroSpace had parked off-screen on an inactive workspace.Conditions, which is why it doesn't reproduce for everyone:
Displays have separate Spacesoff, or a single monitorCause
MacApp.nativeFocushas a fast path that skips the per-window AX raise and callsnsApp.activate()alone:activate()focuses whichever window macOS currently holds as the app's main one.lastNativeFocusedWindowIdrecords what AeroSpace last observed, and the app's main window drifts from that on its own — a background window taking a link, an app reordering its own windows — so the condition isn't evidence that the requested window is the oneactivate()will bring.The general path has a residual race too: the AX raise says which window should be main, and activating the app makes macOS restore whichever window it holds as main.
The fix
Two parts:
windowsCount == 1, whereactivate()can only mean the requested window. It still covers the case it was added for (apps slow to answer AX requests, which are overwhelmingly single-window).Measurements
Two Safari windows, focusing a different app between each attempt:
swift testpasses (382 tests).Happy to split this into two commits, drop the retry and keep only the fast-path fix, or move the discussion to Discussions first if you'd prefer that — just say which.