Skip to content

fix(macos): stop stealing OS focus when opening/switching tabs - #519

Closed
daniel771277 wants to merge 1 commit into
browser-use:mainfrom
daniel771277:fix/macos-focus-steal
Closed

fix(macos): stop stealing OS focus when opening/switching tabs#519
daniel771277 wants to merge 1 commit into
browser-use:mainfrom
daniel771277:fix/macos-focus-steal

Conversation

@daniel771277

@daniel771277 daniel771277 commented Jul 14, 2026

Copy link
Copy Markdown

Problem

On macOS, driving a headful Chrome with browser-harness repeatedly yanks the user's focus (and Space) over to the browser window. It happens on essentially every task, because it fires on tab creation.

Two CDP calls are responsible:

  1. Target.activateTarget — raises the browser window, which on macOS activates the app. switch_tab() called it on every switch, and new_tab() calls switch_tab(), so every tab creation stole focus.
  2. Target.createTarget in the foreground (the default) — when the browser has zero windows, it has to open a new one, and macOS raises + activates that window.

Fix

  • new_tab() creates targets with background=True.
  • switch_tab(target, activate=False) no longer activates unless the caller explicitly asks. Activation is only needed when a human has to look at the tab (e.g. logging in), not for automation.

Screenshots, coordinate clicks and key input all work on a non-selected tab — they go through the CDP session, not the OS window — so nothing is lost.

Verification (macOS 15, Chrome 150)

Tracked the frontmost app (System Events) across each individual CDP call:

call frontmost after
Target.createTarget (background=True) unchanged
Target.attachToTarget unchanged
Target.activateTarget Google Chrome ← the thief

End-to-end in the worst case (browser with zero windows open): new_tabwait_for_loadclick_at_xytype_text no longer brings Chrome forward, and the click registered, the typed text landed in the input, and Page.captureScreenshot returned the correct content of the non-selected tab in 0.2s.

🤖 Generated with Claude Code


Summary by cubic

Stop macOS from stealing focus when creating or switching tabs in headful Chrome. switch_tab() no longer activates the window by default, and new_tab() creates background targets so Chrome stays in the background.

  • Bug Fixes
    • new_tab() and daemon attach_first_page() call Target.createTarget with background=True to avoid activating Chrome when no windows exist.
    • switch_tab(target, activate=False) only calls Target.activateTarget when explicitly requested, keeping automation in the background while clicks, typing, and screenshots still work.

Written for commit e529bc1. Summary will update on new commits.

Review in cubic

@browser-harness-review

Copy link
Copy Markdown

✅ Skill review passed

Reviewed 1 file(s) — no findings.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No issues found across 3 files

Re-trigger cubic

On macOS, driving a headful Chrome repeatedly yanks the user's focus (and
Space) over to the browser. It fires on tab creation, so it happens on
essentially every task. Two CDP calls are responsible:

- Target.activateTarget raises the browser window, which activates the app.
  switch_tab() called it on every switch, and new_tab() calls switch_tab(),
  so every tab creation stole focus.
- Target.createTarget in the foreground (the default) has to open a new
  window when the browser has zero windows, and macOS raises + activates it.

Fix: new_tab() creates targets with background=True, and switch_tab() no
longer activates unless the caller asks (activate=True) — only needed when a
human has to look at the tab (e.g. login). Screenshots, coordinate clicks and
key input all work on a non-selected tab, since they go through the CDP
session rather than the OS window.

Verified on macOS 15 / Chrome 150 by tracking the frontmost app's pid across
each CDP call: createTarget(background=True) and attachToTarget leave it
alone, activateTarget was the thief. End-to-end with zero windows open,
new_tab -> click_at_xy -> type_text no longer brings Chrome forward, and the
click, the typed text and captureScreenshot all work on the non-selected tab.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@daniel771277

Copy link
Copy Markdown
Author

Closing this — handling the fix downstream instead. Thanks!

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.

1 participant