Skip to content

feat(web): add a setting to disable history swipe navigation - #28370

Open
chomamateusz wants to merge 2 commits into
pingdotgg:mainfrom
chomamateusz:feat/history-swipe-setting
Open

chomamateusz wants to merge 2 commits into
pingdotgg:mainfrom
chomamateusz:feat/history-swipe-setting

Conversation

@chomamateusz

Copy link
Copy Markdown

Problem

On macOS desktop, a Logitech MX Master's horizontal thumb wheel can navigate thread history accidentally, including when horizontal scrolling reaches the edge of wide content. Electron 44's input events carry no trackpad-vs-wheel provenance, so the existing gesture cannot currently be restricted to trackpads.

Change

Add “Swipe to go back and forward” in desktop Settings > General > Navigation, with Settings search, a per-setting reset, and restore-defaults support. The client preference defaults to enabled. Turning it off unmounts the gesture handler and indicator immediately, including during a swipe; turning it on works without reloading. Mouse back/forward buttons and keyboard navigation retain their existing behavior.

Scope and approval

CONTRIBUTING.md states: “A focused configuration option for an established capability may also be eligible without prior feature approval.” This option controls the existing desktop history-swipe capability. The default is unchanged, and the scope adds no workflow or broader navigation behavior. This follows the configuration route; it does not claim explicit maintainer approval or guaranteed acceptance.

The change is limited to the client setting contract, desktop renderer Settings/search/reset integration, its mount gate, and focused tests. Hosted/local web and native mobile do not expose the desktop gesture. The gesture is not documented in user guides, so no documentation change is needed.

Verification

  • Failing first on origin/main at 15fe283, with only regression tests added: both disabled swipe directions still invoked history navigation once; three schema cases failed because the field was absent (5 failures, 28 existing tests passed).
  • With the change: 59 tests passed across settings contracts, AppSidebarLayout browser behavior, the existing swipe helper, and Settings search. Covers disabled back/forward navigation, removal of the indicator during an active swipe, and re-enabling without a reload.
  • Command: vp test run packages/contracts/src/settings.test.ts apps/web/src/components/AppSidebarLayout.browser.test.tsx apps/web/src/components/HistorySwipeNavigation.test.ts apps/web/src/components/settings/settingsSearch.test.ts.
  • vp run check:changed: passed (exit 0): format, lint, both knip passes, typecheck of 35 affected packages/dependents, 64 tests across six files, and four changed-source React Compiler cases.
  • Upstream HistorySwipeNavigation.tsx was unchanged since 305a90d; this change only adds an indicator test ID there. PR fix(web): horizontal scrolling inside diff and file panes no longer switches threads #28091 addresses shadow-root scrollers, a separate case.
  • Manual check in a desktop build carrying this change (recording below).

Evidence

Settings > General > Navigation, enabled and disabled:

setting-on setting-off

Recording: 0–10 s the setting is on and horizontal swipes move between threads; at 12 s it is turned off; 15–24 s the same swipes leave the thread in place.

swipe-demo.mp4

Model: gpt-6.1-sol via Codex CLI, orchestrated by Claude Code.

Horizontal mouse wheels can accidentally navigate desktop thread history.
Electron input events do not distinguish a trackpad swipe from a mouse wheel.

Add a default-enabled client setting with desktop Settings search and reset
support. Unmount the gesture handler when disabled, and cover disabling,
mid-swipe cleanup, and re-enabling with focused regression tests.

Model: gpt-6.1-sol via Codex CLI, orchestrated by Claude Code.
@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 Oct 31, 2026
@macroscopeapp

macroscopeapp Bot commented Oct 31, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at db2a71b

Macroscope's review found this PR approvable — Adds a desktop setting to disable swipe history navigation while keeping it enabled by default. The change is reversible and removes gesture listeners when disabled.

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

@coderabbitai

coderabbitai Bot commented Oct 31, 2026 •

Copy link
Copy Markdown
Contributor

Explain Change →

No actionable comments were generated in the recent review.

Walkthrough

The change adds a client setting for desktop history swipe navigation. It defaults to enabled, appears in Electron General settings, and controls whether AppSidebarLayout renders the navigation component.

Changes: History Swipe Navigation

Layer / File(s) Summary
Client setting contract
packages/contracts/src/settings.ts, packages/contracts/src/settings.test.ts
ClientSettingsSchema defaults historySwipeNavigation to true. ClientSettingsPatch accepts an optional boolean. Tests cover omitted and explicit values.
Settings controls and search
apps/web/src/components/settings/SettingsPanels.tsx, apps/web/src/components/settings/settingsSearch.ts, apps/web/src/components/settings/settingsSearch.test.ts
The Electron General settings panel exposes the setting and a reset action. Restore tracking and restoring defaults include it. Desktop settings search indexes the setting.
Sidebar navigation gating
apps/web/src/components/AppSidebarLayout.tsx, apps/web/src/components/HistorySwipeNavigation.tsx, apps/web/src/components/AppSidebarLayout.browser.test.tsx
AppSidebarLayout renders HistorySwipeNavigation only in Electron when the setting is enabled. Browser tests cover disabled and enabled behavior in both directions. The indicator has a test ID.

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

Change: Feature

Possibly related issues

  • pingdotgg/t3code issue 32955 — The issue reports horizontal mouse-wheel input triggering desktop thread-history swipes and identifies an opt-out setting as a possible fix. This change adds that setting and gates the swipe component on its value.

Possibly related PRs

  • pingdotgg/t3code#27430 — Adds the desktop history-swipe gesture that this change gates with a setting.
  • pingdotgg/t3code#31728 — Adds the same setting and related settings, restore, search, and contract support.
  • pingdotgg/t3code#29766 — Changes when HistorySwipeNavigation invokes history navigation; this change gates that handler and tests disabled behavior.

Suggested reviewers: juliusmarminge

Merge Risk: Minimal · up to 18909

The swipe setting appears ready to merge after normal checks; no actionable issue is identified.

Pre-merge checks: Passed 4

Check name Status Explanation
Title check Passed The title clearly summarizes the main change: adding a setting to disable history swipe navigation.
Description check Passed The description includes the required Problem, Change, Scope and approval, and Verification sections. It explains the issue and behavior, defines the scope and approval rationale, reports focused test…
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Full details: Description check

Explanation

The description includes the required Problem, Change, Scope and approval, and Verification sections. It explains the issue and behavior, defines the scope and approval rationale, reports focused test results, and provides screenshots and a recording for the UI change.

Finishing Touches

Generate unit tests (beta)

  • 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 db2a71b and 18909a5.

Files selected for processing: 7

  • apps/web/src/components/AppSidebarLayout.tsx
  • apps/web/src/components/HistorySwipeNavigation.tsx
  • apps/web/src/components/settings/SettingsPanels.tsx
  • apps/web/src/components/settings/settingsSearch.test.ts
  • apps/web/src/components/settings/settingsSearch.ts
  • packages/contracts/src/settings.test.ts
  • packages/contracts/src/settings.ts

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

@maria-rcks

maria-rcks commented Nov 1, 2026 •

Copy link
Copy Markdown
Collaborator

Note

Written by claude-opus-5-5 on behalf of Maria

Takeover update

merged current main into the branch at 18909a592b (merge commit, no rebase). one conflict in AppSidebarLayout.tsx: main added a showSidebar prop, the pr gates HistorySwipeNavigation on the setting. both kept. no other source changes; no required changes or actionable bot findings.

  • blacksmith: vp run check:changed passed (format, lint, knip, typecheck of 37 packages, 7 test files, react compiler). AppSidebarLayout.browser.test.tsx, settingsSearch.test.ts and contracts settings.test.ts pass.
  • the electron client was not re-driven after the merge. the evidence below is from db2a71b.

Earlier verification (gpt-6.1-sol)

Verified in a real dev environment

verified as-is at db2a71b12f7d5a389f60aa0fc05f1ff56c72de54 on this linux vm. no source changes.

  • reproduced on github/main at 8b74a69019e3 first: horizontal wheel input navigates between threads, with no setting to disable it.
  • used real dev servers, chrome through repository playwright, and the actual electron 44 desktop client built from each revision. created a real git project and two threads through the app. codex gpt-6.1-sol completed both main turns and another turn through the pr's web client. no mocks or seeded conversations.
  • in desktop settings, the control defaults on. switching off blocks both directions and removes the indicator. re-enabling restores both directions without reload. disabling during a swipe removes its indicator. the disabled preference survives reload.
  • keyboard and toolbar back/forward still work while swipes are disabled. settings search for "horizontal wheel", per-setting reset, and restore device defaults work. chrome correctly hides the desktop-only control.
  • blacksmith: desktop build and vp run check:changed 15fe2832727893cbdd2214383f9f971474849695 passed, including 35-package typechecking, 64 tests across six files, and four react compiler cases. all 31 reported ci checks pass.

after disabling, the real-client checks reported:

disabled back swipe keeps beta true
disabled swipe has no indicator true
keyboard back still works while disabled true
disabled forward swipe keeps alpha true
keyboard forward still works while disabled true
toolbar back still works while disabled true
toolbar forward still works while disabled true
re-enabled back swipe works without reload true
re-enabled forward swipe works without reload true

before, main settings with matching project data and viewport:

main general settings without a swipe control

pr, enabled:

pr general settings with swipe navigation enabled

pr, disabled:

pr general settings with swipe navigation disabled

main: horizontal wheel input moves beta to alpha and back.

main desktop wheel navigation between real codex threads

pr: disabled swipes leave the thread unchanged; keyboard and toolbar navigation still work; enabling restores swipe navigation. these animations contain the full recordings. the original mp4s were inspected and played through in t3, including seeking.

pr disabling swipes, preserving other navigation, and re-enabling

Not verified

macos hardware input from a physical trackpad or logitech mx master, mouse thumb buttons, windows desktop, native ios/android, and relay/tunnel connections were not exercised on this linux vm. the wheel checks used trusted chromium input through the real electron renderer and gesture ipc, so they do not prove macos hardware event provenance.

@iliyasone

Copy link
Copy Markdown

Note

🤖 Claude Opus 5.5 responding on behalf of Ilias

I'm a huge +1 on this PR. I use an Apple Magic Trackpad, and I couldn't understand what was happening: while I was scrolling, my threads kept suddenly switching from one to another.

@vdmkotai

vdmkotai commented Nov 3, 2026

Copy link
Copy Markdown
Contributor

need this urgently

@mrpunkin

mrpunkin commented Nov 4, 2026

Copy link
Copy Markdown

I keep running into issues using shift+scroll to horizontally scroll diffs but end up over scrolling and moving forward/back in navigation history. It's incredibly obnoxious. Would this proposed setting fix that since over scrolls are considered swipes?

@andrewkelden

Copy link
Copy Markdown

+1. Same on macOS desktop with an MX Master 3S: horizontally scrolling a wide Markdown table with the thumb wheel, once the table hits its edge the swipe indicator appears and the app jumps to another thread. It is easy to miss and confusing. It also happens with the trackpad in the same situation, so a setting to turn the gesture off would help both cases.

@swiftyspiffy

Copy link
Copy Markdown

Same issue on Zorin OS 18.1 (Ubuntu-based), Wayland, T3 Code 0.1.7, with an MX Master 4. Horizontal thumb-wheel scrolling switches threads. Would appreciate this toggle.

@chomamateusz-agent

Copy link
Copy Markdown

🤖 Update on behalf of Mateusz (PR author): how this PR relates to the swipe fixes opened since.

This switch is the per-user escape hatch the platform check cannot provide: mouse users on macOS can turn the gesture off without taking it away from trackpad users. If #32963 lands first, I'll rebase and show the switch only where the gesture exists. #31728 proposes the same switch; happy to close this one in favour of whichever you prefer.

No code change in this update.

…tting

# Conflicts:
#	apps/web/src/components/AppSidebarLayout.tsx
@chomamateusz

Copy link
Copy Markdown
Author

macos hardware input from a physical trackpad or logitech mx master, mouse thumb buttons, windows desktop, native ios/android, and relay/tunnel connections were not exercised on this linux vm.

Adding the hardware side that the verification above could not cover (it ran on a Linux VM with synthetic wheel input).

I have used this change daily since 31 October in desktop builds on a MacBook Pro on macOS 26.6 with a Logitech MX Master and the built-in trackpad:

  • Switch on (the default): a two-finger trackpad swipe goes back and forward as on main. The MX Master's thumb wheel triggers the same navigation, which is the misfire that made me open this PR.
  • Switch off: neither the thumb wheel nor a trackpad swipe changes the thread. Keyboard and toolbar back/forward still work.
  • The choice has survived every restart and app update since.

On #32963: it leaves macOS unchanged, so this case stays open there. If it lands first, I'll rebase this PR and show the switch only where the gesture exists.

@alex-delia alex-delia left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Really agree with adding this as a toggleable feature. I think the suggested changes here just make the wording a little simpler and fit in with the rest of the settings a little better. Would love to see this merged!

: []),
...(settings.confirmQuit !== DEFAULT_UNIFIED_SETTINGS.confirmQuit ? ["Quit shortcut"] : []),
...(settings.historySwipeNavigation !== DEFAULT_UNIFIED_SETTINGS.historySwipeNavigation
? ["Swipe to go back and forward"]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggested change
? ["Swipe to go back and forward"]
? ["Swipe to navigate"]

},
{
id: "history-swipe-navigation",
title: "Swipe to go back and forward",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggested change
title: "Swipe to go back and forward",
title: "Swipe to navigate",

<SettingsSection id="navigation" title="Navigation">
<SettingsRow
{...searchableSetting("history-swipe-navigation")}
description="Two-finger horizontal swipes move through your thread history. Turn off if a mouse with a horizontal wheel switches threads by accident."

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggested change
description="Two-finger horizontal swipes move through your thread history. Turn off if a mouse with a horizontal wheel switches threads by accident."
description="Swipe horizontally with two fingers on a trackpad to go back or forward."

id: "history-swipe-navigation",
title: "Swipe to go back and forward",
to: "/settings/general",
searchTerms: ["two-finger horizontal trackpad gesture mouse wheel thread history navigation"],

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Suggested change
searchTerms: ["two-finger horizontal trackpad gesture mouse wheel thread history navigation"],
searchTerms: ["two-finger horizontal trackpad gesture mouse wheel back forward thread history navigation"],

@kelchm

kelchm commented Nov 10, 2026

Copy link
Copy Markdown

Tested locally at 18909a592b on macOS, with a trackpad and an MX Master 3.

  • Switch on: two-finger swipes and the thumb wheel navigate as before.
  • Switch off: neither trackpad swipes nor the MX Master thumb wheel navigate anymore.
  • ⌘[ / ⌘] and the back/forward buttons still work with it off.
  • Turning it back on takes effect right away, no reload needed.

+1 to getting this merged -- accidental navigation happens to me multiple time per day.

@NikhilGaddam

Copy link
Copy Markdown

Note

Written by Claude Opus 5.5 on behalf of Nikhil

@maria-rcks @juliusmarminge thanks for keeping this one and closing my duplicate (#34481). +1 to merge: it is clean against main, and kelchm and chomamateusz have confirmed it on macOS with a trackpad and an MX Master.

Two small refinements from #34481 that Julius mentioned. Neither needs to block this PR; I can open them as a follow-up after it merges, or you can take them here:

  • Since fix(web): mouse tilt wheel no longer switches threads on Windows and Linux desktop #32963 the gesture runs only on macOS, so on Windows and Linux desktop the switch does nothing. Show the row only when isElectron && isMacPlatform(navigator.platform), and mark its search item macOnly: true.
  • One line in docs/user/keybindings.md, after navigation.back / navigation.forward: "In the desktop app on macOS, a two-finger trackpad swipe does the same. Turn it off in Settings."

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

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.