Skip to content

fix(desktop): route mouse thumb buttons to the in-app browser#4459

Open
akosbalogh wants to merge 1 commit into
pingdotgg:mainfrom
akosbalogh:fix/preview-mouse-thumb-navigation
Open

fix(desktop): route mouse thumb buttons to the in-app browser#4459
akosbalogh wants to merge 1 commit into
pingdotgg:mainfrom
akosbalogh:fix/preview-mouse-thumb-navigation

Conversation

@akosbalogh

@akosbalogh akosbalogh commented Jul 24, 2026

Copy link
Copy Markdown

What changed

Mouse thumb (side) buttons — back = button 3, forward = button 4 — now navigate the in-app browser's history when the pointer is over the preview <webview>, instead of navigating the host T3 Code app (threads/agents view).

Why

The preview is an Electron <webview> whose WebContents is driven by PreviewManager. When the pointer merely hovers the guest page (the guest isn't focused), Chromium routes thumb-button history navigation to the focused WebContents — the host app renderer — so pressing back/forward over the browser sent the app router back instead of the browser. This was intermittent ("sometimes") because it depended on which surface held focus.

How

  • PickPreload.ts (runs inside every preview guest): capture-phase listeners for the thumb buttons preventDefault() + stopImmediatePropagation() on mousedown/mouseup/auxclick to suppress Chromium's default navigation, and forward an explicit { direction } over a new MOUSE_NAVIGATE_CHANNEL IPC. Guarded by event.isTrusted so automation-injected events are unaffected.
  • Manager.ts: attachListeners registers a mouseNavigate handler that drives that tab's history via the existing wc.navigationHistory.goBack()/goForward() (guarded by canGoBack()/canGoForward()), mirroring the existing UI back/forward path. Registered/torn down alongside the existing HUMAN_INPUT_CHANNEL listener.
  • GuestProtocol.ts: new MOUSE_NAVIGATE_CHANNEL constant.

Suppression in the guest is unconditional, so the host app never navigates while the cursor is over the browser — even when the browser has no back history.

Testing

  • New unit test in Manager.test.ts asserting the IPC handler drives goBack/goForward, ignores unknown payloads, and does nothing when history is exhausted.
  • apps/desktop typecheck, lint, format, and full Manager.test.ts suite (20 tests) pass locally.
  • Manual (desktop): open the right-sidebar in-app browser, hover the site, press the mouse back/forward thumb buttons → the browser navigates its own history; the host app view no longer navigates.

🤖 Generated with Claude Code


Note

Low Risk
Scoped to desktop preview input handling with guards on payload and history; no auth or data changes.

Overview
Mouse back/forward thumb buttons over the preview webview now move that tab’s browser history instead of the host app router when the guest isn’t focused.

In PickPreload.ts, capture-phase listeners on thumb buttons (button 3/4) call preventDefault / stopImmediatePropagation and send { direction: "back" | "forward" } on new preview:mouse-navigate IPC (trusted events only). PreviewManager registers a mouseNavigate handler alongside human-input listeners that calls navigationHistory.goBack() / goForward() when history allows. Manager.test.ts covers valid directions, bad payloads, and exhausted back history.

Reviewed by Cursor Bugbot for commit d04de2b. Bugbot is set up for automated code reviews on this repo. Configure here.

Note

Route mouse thumb buttons to the in-app browser for back/forward navigation

  • The guest preload (PickPreload.ts) intercepts mousedown, auxclick, and mouseup events for mouse buttons 3 (back) and 4 (forward), suppresses Chromium's default focus-dependent navigation, and emits a preview:mouse-navigate IPC message with a direction payload.
  • PreviewManager.ts handles the IPC message by calling wc.navigationHistory.goBack() or goForward() only when canGoBack()/canGoForward() returns true; invalid payloads are ignored.
  • Behavioral Change: thumb-button navigation is now always handled via IPC rather than Chromium's built-in behavior, which previously depended on the webview having focus.

Macroscope summarized d04de2b.

When the pointer hovers the preview <webview> without focusing it,
Chromium routes back/forward thumb-button navigation to the focused
host renderer, so the app router navigated instead of the browser.

Intercept the thumb buttons (button 3 = back, 4 = forward) in the guest
preload, suppress Chromium's default, and forward an explicit navigate
request to PreviewManager so the buttons always drive the hovered
browser's history and never the host app.

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

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 523f4069-e3b9-46d3-af2a-c807812a5099

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Jul 24, 2026
@macroscopeapp

macroscopeapp Bot commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved

This is a targeted bug fix for mouse thumb button navigation in the in-app browser. The changes follow existing patterns in the codebase, include comprehensive tests, and are self-contained within the preview system without touching sensitive areas.

You can customize Macroscope's approvability policy. Learn more.

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

Labels

size:M 30-99 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant