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
- Open thread A in the bb desktop app.
- Open a Browser tab in thread A's right side panel and navigate to a page that reacts to keyboard shortcuts, for example Trello.
- Leave the Browser tab active in the persisted side panel.
- Navigate to another bb thread.
- Return to thread A by selecting it in the sidebar.
- 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:
- 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.
- 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
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
Steps to reproduce
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.jscontains both focus paths fromBrowserTabContent:{ focus: canHandleBrowserCommands }. In the focused thread pane this routes throughsetVisible(...), whose desktop manager focuses a newly shown WebContentsView.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)whenisViewVisible && 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
setVisibleWithoutFocus.desktopBrowser.focus(tabId)merely because the containing thread pane is focused.focusmethod is not called. Preserve the existing test that a real native page-focus event updates logical pane focus.Related issues