Skip to content

Persisted desktop Browser tab steals keyboard focus when returning to a thread #3958

Description

@matthiasvongrundherr

Summary

A normal persisted desktop Browser tab in the right side panel steals native keyboard focus when the operator returns to its owning thread. Typing intended for the chat composer is then delivered to the embedded webpage instead.

This is dangerous with keyboard-heavy applications such as Trello: ordinary dictated text is interpreted as shortcuts and can move or modify cards before the operator notices that the browser owns focus.

This does not require Browser Automation, a controller lease, or background CDP activity.

Versions and environment

  • bb 0.43.3
  • Packaged macOS desktop app
  • Desktop Browser tab in a thread side panel
  • Reproduced with Trello as the embedded page

Steps to reproduce

  1. Open thread A in the bb desktop app.
  2. Open a Browser tab in thread A's right side panel and navigate to a page that reacts to keyboard shortcuts, for example Trello.
  3. Leave the Browser tab active in the persisted side panel.
  4. Navigate to another bb thread.
  5. Return to thread A by selecting it in the sidebar.
  6. Immediately type, expecting the thread composer to receive the text.

Expected

Returning to a thread focuses the chat composer, or at minimum leaves the embedded browser unfocused until the operator explicitly clicks inside the browser page.

A restored side-panel Browser tab may remain visible, but visibility restoration must not transfer the native keyboard target.

Actual

The embedded Browser tab receives the keystrokes. On Trello, typed characters are interpreted as keyboard shortcuts and can move or mutate cards.

Root cause evidence

The packaged 0.43.3 renderer asset BrowserTabDeck-BGMPuTrp.js contains both focus paths from BrowserTabContent:

  1. When the native view becomes visible, the visibility coordinator is called with { focus: canHandleBrowserCommands }. In the focused thread pane this routes through setVisible(...), whose desktop manager focuses a newly shown WebContentsView.
  2. A separate effect calls desktopBrowser.focus(tabId) whenever the browser view is visible and the pane can handle browser commands.

The current source retains the same behavior in apps/app/src/components/secondary-panel/BrowserTabContent.tsx:

visibilityCoordinator.show(tabId, syncBounds, { focus: canHandleBrowserCommands })

followed by an effect that calls desktopBrowser?.focus?.(tabId) when isViewVisible && canHandleBrowserCommands.

The existing test even codifies the automatic focus call as “restores native focus to the logical pane”. Pane command eligibility is therefore being treated as browser autofocus intent, although returning to a thread is not an explicit browser-focus action.

Suggested fix

  • Restore persisted Browser tabs with setVisibleWithoutFocus.
  • Do not call desktopBrowser.focus(tabId) merely because the containing thread pane is focused.
  • Transfer native focus only after an explicit browser interaction, such as clicking inside the page or choosing Take over.
  • Add a regression test that mounts a focused thread with a persisted active Browser tab and proves the browser API's focus method is not called. Preserve the existing test that a real native page-focus event updates logical pane focus.

Related issues

AGENT GENERATED

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions