Deep Dive: Arc Browser & AeroSpace Focus Conflict Leading to Workspace Flashback Bug on macOS
As a long-time Linux power user accustomed to tiling window managers, I adopted AeroSpace on macOS for its efficiency and i3-like workflow. I initially paired it with the Arc browser (Chromium-based) due to its features like Workspaces for tab management. However, I encountered a severe bug that forced me to switch browsers: a persistent workspace “flashback” loop when Arc was active.
This post details my investigation into this bug, revealing a complex interaction between Arc’s behavior, macOS window management (WindowServer), and AeroSpace’s unique virtual workspace implementation. The core issue stems from Arc’s frequent background calls to the makeKeyAndOrderFront:
API, which fundamentally clashes with how AeroSpace manages window visibility using the Accessibility API. Switching to a Firefox-based browser (Zen) ultimately resolved the problem.
The Problem: Frustrating Workspace Snapback
When using AeroSpace, attempting to switch from a workspace containing an active Arc window (let’s call it Workspace W) to another workspace (Workspace T) resulted in this disruptive behavior:
- The screen briefly flickered, showing Workspace T.
- Almost instantly (within milliseconds), the view snapped back to Workspace W.
- Repeatedly pressing the workspace switch shortcut slowly only reproduced the flashback.
- Only by rapidly mashing the shortcut keys could I sometimes “break through” and land on Workspace T.
This completely undermined the fluid workflow that tiling window managers aim to provide.
Uncovering the Root Cause: API Conflicts
My debugging process led me through several stages:
Initial Checks and Community Clues
I first ruled out interference from potential floating windows misidentified by AeroSpace. Then, searching AeroSpace’s GitHub issues revealed #289, describing a similar loop with Google Chrome. This pointed towards the underlying Chromium framework. Expanding the search to yabai
(another macOS tiling WM) issues #1662 and #2269 confirmed similar focus-stealing problems with Arc, often suggesting it was an issue within Arc itself.
The Key Difference: AeroSpace’s Virtual Workspaces
Common advice in yabai
threads involves tweaking macOS Mission Control settings like “Displays have separate Spaces” or “When switching to an application, switch to a Space…”. However, these are irrelevant for AeroSpace due to its core design:
- No Native Spaces: AeroSpace avoids macOS native Spaces to bypass performance issues and API limitations (especially without disabling System Integrity Protection - SIP).
- Accessibility API Based: It keeps all managed windows physically on the user’s first real macOS Desktop.
- Hide/Show Mechanism: Workspace switching is simulated. AeroSpace uses the Accessibility API to hide windows not belonging to the target workspace (effectively moving them off-screen via
kAXPositionAttribute
) and show windows that do belong. Functions likehideInCorner
andunhideFromCorner
handle this.
Good monitor arrangement in AeroSpace, showing all windows hidden in the corners.
Since all windows reside on Desktop 1, macOS settings related to switching between native Spaces have no effect on AeroSpace’s behavior.
Pinpointing the Culprit: makeKeyAndOrderFront:
The decisive clue came from observing that even using the native macOS Cmd+Tab
switcher to focus Arc (when it was on a different native Space) would forcibly pull the user to Arc’s Space, even with the relevant Mission Control setting disabled. This strongly indicated Arc actively forces itself to the foreground.
Further research identified the macOS AppKit method -[NSWindow makeKeyAndOrderFront:]
as the likely cause. This method does two critical things:
makeKeyWindow
: Designates the window as the “Key Window,” the one receiving keyboard events. macOS WindowServer enforces a rule: the Key Window’s Space (or Desktop) must be the active, visible one. If the Key Window is on an inactive Space/Desktop, WindowServer automatically switches the view.orderFront:
: Brings the window to the front of its level and makes it visible, overriding any “hiding” attempts (like AeroSpace moving it off-screen).
The problem is that Arc (and its underlying Chromium framework, as well as many Electron apps) calls makeKeyAndOrderFront:
frequently in the background for various reasons:
- Tab content updates (page load, title change).
- Browser UI interactions (Little Arc, command bar updates, notifications).
- Extension activity.
Arc’s rich UI likely triggers this more often than vanilla Chrome.
The Conflict Explained: A Vicious Cycle
Here’s how the flashback loop occurs:
- Switch Workspace (W → T): User triggers AeroSpace switch. AeroSpace hides Arc (on W) and shows windows on T using Accessibility API. All windows remain on Desktop 1.
- Arc Calls API: Almost simultaneously, Arc performs a background action triggering
makeKeyAndOrderFront:
. - Arc Becomes Visible & Key:
orderFront:
makes the Arc window visible again.makeKeyWindow
designates it as the Key Window. - WindowServer Intervenes: WindowServer sees the Key Window (Arc) is now visible on Desktop 1 and forces Desktop 1 to be the active view, pulling the user back from the intended Workspace T.
- AeroSpace Reacts: AeroSpace detects Arc unexpectedly becoming visible and focused. It interprets this as an intent to be on Workspace W and attempts to synchronize its state, solidifying the user’s view back on W.
This cycle of AeroSpace hides → Arc calls API → WindowServer forces focus → AeroSpace syncs back creates the rapid flashback.
A Broader Issue: This isn’t exclusive to Arc. Any Chromium (Chrome, Edge) or Electron (VS Code, Slack) app exhibiting frequent background makeKeyAndOrderFront:
calls can potentially conflict with AeroSpace’s virtual workspace model. Arc’s specific UI behavior just seems to trigger it more noticeably. I’ve reported this finding in an AeroSpace discussion: #1375.
The Solution: Change the Browser Engine
Understanding the root cause—the incompatibility between AeroSpace’s Accessibility API approach and Chromium’s makeKeyAndOrderFront:
usage—pointed to a clear solution: use a browser built on a different engine.
I switched to Zen browser, an open-source project offering an Arc-like experience but built on Firefox’s Gecko engine.
Immediately after switching to Zen, the workspace flashback problem completely disappeared. AeroSpace workspace switching became perfectly smooth, confirming the issue lies within the behavior of the Chromium/Electron framework’s interaction with macOS window management APIs when combined with AeroSpace’s specific implementation.
Conclusion
The workspace flashback bug when using Arc with AeroSpace is a complex interaction between application behavior (makeKeyAndOrderFront:
calls), OS window management rules (WindowServer enforcing Key Window visibility), and the window manager’s specific design (AeroSpace’s virtual workspaces via Accessibility API). By identifying the conflicting API call pattern inherent in Chromium/Electron apps as the root cause, the most effective solution was to switch to a browser using a different engine (Firefox/Gecko), which immediately resolved the issue.