Skip to content

fix(desktop): macOS swipe Back/Forward moves the focused Browser tab - #33321

Open
juliusmarminge wants to merge 8 commits into
mainfrom
fix/issue-33307
Open

juliusmarminge wants to merge 8 commits into
mainfrom
fix/issue-33307

Conversation

@juliusmarminge

@juliusmarminge juliusmarminge commented Nov 9, 2026 •

Copy link
Copy Markdown
Member

Problem

On macOS, mouse drivers such as Logi Options+ send thumb Back/Forward as a window swipe gesture, not as mouse buttons 4/5. The desktop app's swipe handler always moved the app's own history. When the user clicked into the right-panel Browser tab and pressed Back, the app went back to the previous thread or route and the Browser tab stayed where it was. A three-finger trackpad swipe takes the same path.

Reproduced on main 2b65ffb641 with a unit test of the handler (a real macOS swipe cannot be produced on Linux). A Browser tab guest that holds keyboard focus is attached to the window, then the test swipes left and right. The app history moved back once and forward once ([1, 1]), and the Browser tab did not move ([0, 0]).

Change

  • The swipe handler in apps/desktop/src/window/DesktopWindow.ts now looks for a webview guest of this window that holds keyboard focus. If it finds one, the swipe moves that guest's history and leaves the app history alone. Otherwise the app history moves as before.
  • "Holds keyboard focus" is the rule the Browser tab already uses for shortcut forwarding (isFocused() && focusedFrame !== null). Every guest of a focused window reports isFocused(), so focusedFrame decides, and it goes null once focus returns to the app. The helper moves to module scope in apps/desktop/src/preview/Manager.ts so both callers share it.

Scope and approval

Fixes #33307

Triaged via the automated issue flow. Mouse buttons 3/4 over Browser tab content are a separate path, covered by https://git.cafe/pingdotgg/t3code/pulls/33276.

Verification

Checked on head e303ce0cb0 (main 934c7f8d8e merged in).

  • vp test run apps/desktop/src/window/DesktopWindow.test.ts: 27/27 pass. The swipe test DesktopWindow > maps macOS horizontal swipes to the focused Browser tab or the app history fails on main with:
    AssertionError: swipe back/forward should navigate the focused Browser tab, not the app router:
    expected { app: [ 2, 2 ], browserTab: [ 0, 0 ] } to deeply equal { app: [ 1, 1 ], browserTab: [ 1, 1 ] }
    
    It also covers the case with no Browser tab, up/down swipes, and the return to app history once the Browser tab's focusedFrame clears, where canGoBack/canGoForward still apply. With the focus check replaced by true, the last assertion fails (browserTab: [2, 2], expected [1, 1]).
  • The focus rule was checked in real Electron 44.10.1 on Linux (Xvfb): a host page with two <webview> guests, driven by sendInputEvent clicks. Every guest reported isFocused(). Only the clicked guest had a non-null focusedFrame. It went back to null after any of these: a click on a host input, a click on the empty host body, focusing the host from script, hiding the webview, or blur().
  • vp run check:changed on e303ce0cb0: pass (format, lint, knip, typecheck of 2 packages, tests in 2 files).
  • Independent review round on e303ce0cb0: no code defects found by either reviewer.
  • No render path changes. The proof matrix lists Linux recordings of the existing callers of the moved holdsKeyboardFocus helper (guest editing shortcuts, forwarded app shortcuts such as Ctrl+L and F6, several guests and focus returning to the app, agent key input into an unfocused guest, native popup editing). These are not captured yet.
  • cannot-verify macos: the BrowserWindow swipe event exists only on macOS. Real Logi Options+ or trackpad gestures, and macOS Chromium clearing a guest's focusedFrame after focus returns to the app, were not exercised on a Mac. The acceptance sequence there: click into the Browser tab, swipe back and forward (the Browser tab moves, the thread stays); click the composer, swipe again (the app history moves).

AI-assisted; verified with the tests and tools listed above.

juliusmarminge and others added 4 commits November 9, 2026 11:04
…ser tab

These tests reproduce #33307: when a Browser-tab preview guest of the window
holds keyboard focus, a macOS swipe (how Logi Options+ delivers mouse
Back/Forward) should navigate that guest's history, but the handler always
navigates the app's own webContents history.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Mouse drivers such as Logi Options+ deliver thumb Back/Forward as a
BrowserWindow swipe, and the handler always navigated the app's own
history even while the user was in the Browser tab. The swipe now goes to
the window's preview guest that holds keyboard focus, using the preview
manager's existing focus rule, and falls back to the app history otherwise.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… loses focus

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@github-actions github-actions Bot added vouch:trusted Author is trusted by repo permissions or the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Nov 9, 2026
macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Nov 9, 2026
@macroscopeapp

macroscopeapp Bot commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 6540c62

Macroscope's review found this PR approvable — macOS Back/Forward swipes now navigate the focused Browser tab, with app history retained as the fallback. The change reuses existing focus detection and remains limited to user-triggered navigation in the current window.

Notes:

  • No code objects were reviewed. Approvability was decided on eligibility alone.

No code changes detected at 47d0ae3. Prior analysis still applies.

You can add or adjust custom eligibility rules. Learn more.

… test

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

coderabbitai Bot commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

Explain Change →

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • Resume reviews
  • Trigger review

No actionable comments were generated in the recent review.

Walkthrough

On macOS, swipe navigation uses a live guest’s history when the guest is hosted by the main window and holds keyboard focus. Otherwise, it uses the main window history. A shared focus helper supports this check and shortcut handling.

Changes: Focused Guest Swipe Navigation

Layer / File(s) Summary
Shared keyboard-focus check
apps/desktop/src/preview/Manager.ts
The exported holdsKeyboardFocus helper checks that web contents are focused and have a focused frame. Existing shortcut handling uses the helper.
Swipe history routing
apps/desktop/src/window/DesktopWindow.ts, apps/desktop/src/window/DesktopWindow.test.ts
The macOS swipe handler selects a live, focused guest hosted by the main window when one exists; otherwise, it uses the main window history. Tests cover guest and app history navigation.

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix · Severity of issue fixed: Medium

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant DesktopWindow
  participant MainWindowContents
  participant GuestWebContents
  participant NavigationHistory
  User->>DesktopWindow: trigger macOS swipe
  DesktopWindow->>MainWindowContents: getAllWebContents
  MainWindowContents-->>DesktopWindow: web contents
  DesktopWindow->>GuestWebContents: check host and keyboard focus
  alt focused guest found
    DesktopWindow->>NavigationHistory: navigate guest history
  else no focused guest
    DesktopWindow->>NavigationHistory: navigate main window history
  end
Loading

Possibly related issues

Possibly related PRs

  • pingdotgg/t3code#25188: This PR adds guarded back and forward navigation to the macOS swipe handler that this change updates.

Suggested reviewers: maria-rcks, only21mil, shivamhwp

Merge Risk: Minimal · up to 47d0a

Swipe Back and Forward are routed to the focused Browser tab, with app history as the fallback. No actionable merge blocker was identified; macOS gesture behavior remains unverified on a Mac.

Pre-merge checks: Passed 4

Check name Status Explanation
Title check Passed The title clearly and concisely identifies the macOS swipe navigation fix for the focused Browser tab.
Description check Passed The description covers Problem, Change, Scope and approval, and Verification with detailed reproduction, implementation, and test results. It does not include a maintainer approval comment, and if an …
Linked Issues check Passed [#33307] requires swipe Back/Forward to navigate the focused Browser guest and to use app history when no guest qualifies. DesktopWindow.ts routes horizontal swipes to a live guest when `holdsKeyboa…
Out of Scope Changes check Passed The reported changes in DesktopWindow.ts, Manager.ts, and DesktopWindow.test.ts implement or test [#33307]. The summaries identify no unrelated changes. Mouse buttons 3/4 are a separate path and…
Full details: Description check

Explanation

The description covers Problem, Change, Scope and approval, and Verification with detailed reproduction, implementation, and test results. It does not include a maintainer approval comment, and if an agent was used, it does not name the model and harness as the template requests.

Full details: Linked Issues check

Explanation

[#33307] requires swipe Back/Forward to navigate the focused Browser guest and to use app history when no guest qualifies. DesktopWindow.ts routes horizontal swipes to a live guest when holdsKeyboardFocus is true and otherwise uses app history. Manager.ts shares the focus check, and DesktopWindow.test.ts covers guest routing, fallback, and unavailable history. The reported macOS gesture test remains unverified on macOS, but the available evidence supports the coding requirements.

Full details: Out of Scope Changes check

Explanation

The reported changes in DesktopWindow.ts, Manager.ts, and DesktopWindow.test.ts implement or test [#33307]. The summaries identify no unrelated changes. Mouse buttons 3/4 are a separate path and are not part of the reported changes.

Finishing Touches

Generate docstrings

  • Commit to this branch
  • Create a new PR
Generate unit tests (beta)

  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Recent review info

Run configuration

Commits

Reviewing files that changed from the base of the PR and between e303ce0 and 47d0ae3.

Files selected for processing: 2

  • apps/desktop/src/window/DesktopWindow.test.ts
  • apps/desktop/src/window/DesktopWindow.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 3 remain after this review.

@macroscopeapp
macroscopeapp Bot dismissed their stale review November 9, 2026 11:26

Dismissing prior approval to re-evaluate 6540c62

@juliusmarminge juliusmarminge added the bugfix Fix PR opened by an issue lead; enters the PR loop label Nov 9, 2026
@juliusmarminge juliusmarminge added pr:gate-failed A land gate failed pr:in-progress A lead is working on this PR and removed pr:gate-failed A land gate failed labels Nov 9, 2026
@juliusmarminge juliusmarminge added pr:gate-failed A land gate failed pr:in-progress A lead is working on this PR and removed pr:in-progress A lead is working on this PR pr:gate-failed A land gate failed labels Nov 10, 2026
@juliusmarminge juliusmarminge added pr:gate-failed A land gate failed and removed pr:in-progress A lead is working on this PR labels Nov 10, 2026

Copy link
Copy Markdown
Member Author

The automated pipeline stopped on this pull request and will not merge it:

the proof has no capture anyone can open:

  • Permanent environment blocker: the reproduction requires macOS and Logitech Options+ native swipe delivery. The assigned environment is Linux, and moving to another machine was prohibited.
  • Base failure, focused Browser tab Back/Forward navigation on head, thread preservation, and composer-focus app navigation were not observed. Both boolean fields are false because neither outcome was established.
  • No real-app builds or recordings were produced. Platform overrides or synthetic Electron swipe emissions would not establish the requested native-input reproduction.
  • Initial git fetch failed with: error: RPC failed; HTTP 503 curl 22 The requested URL returned error: 503; fatal: expected 'acknowledgments'. Both requested commits were already available locally, and their merge-base was resolved.

It stays open for a person to finish or close.

This branch has not been deployed

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

Labels

bugfix Fix PR opened by an issue lead; enters the PR loop pr:gate-failed A land gate failed size:S 10-29 changed lines (additions + deletions). vouch:trusted Author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Mouse Back/Forward sent as macOS swipe gestures always navigates the main app, never the focused browser panel

1 participant