Repository navigation
Keyboard shortcuts: one remappable keymap, page conflicts, keys in every window (keys lane: KS) - #23
Merged
Merged
Conversation
…-16) Electron gives a web contents the keyboard whenever its page commits a navigation (focusOnNavigation). That held for a tab hidden behind another and for one that never had the keyboard, so a slow page finishing its load took the keys from the open command bar, from a sidebar field being typed in, or from the page in front (keys typed after it went to the page that loaded). Every web contents Orbit makes now turns it off: tab pages, pages a tab or Peek opens with window.open, and Orbit's own views (uiWebPreferences). Orbit already gives a page the keyboard itself when the user selects, opens or clicks it. keys.spec.ts types where the keyboard is while a slow page commits; the three tests fail with focusOnNavigation on and pass with it off. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…istence (KS-01, KS-18) Every action's bindings now come from one keymap: the defaults in src/shared/actions.ts with the user's changes from settings.shortcuts on top. The key router, the macOS menu bar (rebuilt after a remap), the command bar's action rows and the tooltips read it live, so a remap reaches every hint without a restart. - keys.bind / keys.unbind / keys.reset / keys.resetAll: replace a binding or add one (up to 5 per action), take one off (the command bar and menus still run the action), reset to the defaults. A binding needs a modifier except F1-F12; keys the system keeps are refused; a key another action has is reported as a conflict until the caller asks to clear or swap it; fixed actions (Settings, the recent-tab switcher) keep theirs. - Bindings that type or edit text (Shift+letter, the caret keys) act only outside text fields, like Cmd+Left already did; a Ctrl+Alt press that typed an AltGr character acts only outside text fields; plain keys belong to an input method while it composes. - settings.shortcuts and settings.shortcutPriority are cleaned on load. - keys.record lets Settings -> Shortcuts record a binding in main. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…w and F6 (KS-03, KS-05) - Every default binding is checked against the spec's shortcut tables on macOS, Windows and Linux (unit test), with no key bound twice and each one a binding Orbit accepts. - Close Window is an action: Cmd+Shift+W / Ctrl+Shift+W closes the window, or the Mini Window, Settings or onboarding window that has focus; the macOS File menu item runs it. - F6 moves the keyboard between the sidebar and the page. - F12 opens DevTools on macOS too; F1 opens Help on Windows and Linux. - The macOS menu shows bindings that edit text without registering them, so a text field keeps them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…on prefers websites (KS-02, KS-16) - before-input-event leaves the press of an action that prefers websites to a tab's page; an isolated-world watcher reports whether the page called preventDefault. Left alone, the action runs; used, a toast offers the action and a second press within a second runs it. Held-key repeats stay the page's. - Cmd+S / Ctrl+S (Toggle Sidebar) prefers websites everywhere; Ctrl+Shift+C (Copy URL) on Windows and Linux (NV-17). Settings' per-action priority wins. - In a page text field, Cmd+[ / Cmd+] (Alt+Left / Alt+Right) go to the page first and go back or forward only when the page leaves them alone (KS-16). - The macOS menu runs a let-through key's action once. - e2e: fixture pages that use and ignore the keys, priority set to Orbit, Copy URL, the text-field rule, and Cmd+Z undoing typing in a field. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ab switcher; tab, window, split and overlay keys checked (KS-02, KS-05, KS-06, KS-09, KS-19) - KS-02: Electron runs no isolated-world script in a page while its main frame loads, so a loading page can't say what it did with a key press. Orbit now takes the keys at once then (pageCanAnswer), and every answer it waits for has a 1 s limit. Before, ⌘S on a page that was on its way did nothing. - KS-06 / TB-05: W with ⌃ held while switching to a recent tab closes the highlighted tab; the next tab in the switcher takes the highlight. - KS-05: Rename Tab, Archive Tab and Move Tab to Space… are assignable actions with no default keys. - Main side of Settings → Shortcuts (ST-08): keys.setOptions (Go to Tab options) and keys.systemClashes (macOS Mission Control and GNOME workspace keys), with unit tests for the parsers. - e2e tests for KS-05, KS-06, KS-09 and KS-19 from a page; feature status for KS-02, KS-05, KS-06, KS-09, KS-19 and TB-05. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…riorities and Go to Tab options (ST-08) Settings gets a Shortcuts section, added through the section registry. It lists every action main has registered, grouped, with a search by name, search words or keys. Click a key and press the new one: the router records it (keys.record), so Orbit's own keys run nothing while Settings listens. Esc cancels, Backspace removes the binding, + adds another (up to five). A key another action has opens a dialog offering Swap (when replacing) or Remove from the other action. Right-click an action for Reset to Default, Remove Shortcut and Prefer Websites / Prefer Orbit (KS-02). Reset All asks first. Also on the page: the Go to Tab options (Include Favorites, the last or ninth item on ⌘9), and keys the system keeps marked on their rows (KS-03). keys.available names the registered actions; settings.shortcuts opens the section from the command bar (KS-12). The right-click menu closes when the list under it moves, not on a late scroll event from a scroll made just before it opened. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tcuts sheet (KS-18, OB-12) KS-18: the tab menu, a multi-selection's menu, the page menu and a split pane's menu show an item's key when the item does what the key does, read from the live keymap each time the menu opens. Items that only look alike get no hint (Copy Page URL copies the raw address; the Markdown copy key copies one link). OB-12: Help → Keyboard Shortcuts (macOS Help menu, the command bar everywhere, assignable) opens a sheet over the window with the essential keys as they are now, grouped Everyday, Navigation, Spaces and Split View. Esc, the close button, a click outside, Close Tab's keys or asking again close it; its link opens Settings → Shortcuts. From Settings or a Mini Window it opens over the browser window behind. Tests: menu hints, the sheet's content and the macOS menu template (KS-15 roles, live keys, Help → Keyboard Shortcuts) as unit tests; two e2e tests in keys.spec. Status: KS-01, KS-18, OB-12, OB-13 built, KS-12 partial. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
docs/feature-status.json: SB-11 keeps the keys lane's KS-02 note, SB-12 takes chrome's native-menu note; FEATURES.md regenerated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-20, KS-10) - A private window has no Spaces, pinned tabs, Favorites or folders: the actions that need them (⌘D, ⌃1–9 / Alt+1–9, ⌘⌥← / ⌘⌥→, ⌘⇧K Clear, every Space action) do nothing there, from a key, a menu or the command bar, and a toast says "Not available in a private window". Before, ⌘⇧K archived every private tab. Tab keys still work. - Mini Window: ⌘L now moves the keyboard into the address field, so what is typed next lands there (it stayed with the page). Help → Keyboard Shortcuts from a Mini Window opens over the browser window (it was swallowed). Both are small edits in src/main/miniwindow/index.ts. - Tests: private-window keys, Mini Window keys (⌘S, ⌃2, zoom, ⌘R, ⌘⌥O, ⌘L, the sheet, ⌘W) and full screen with the sidebar hidden (⌘1–9, ⌘⌥↑/↓). - The browser window an action from Settings or a Mini Window acts in is shared (keys/browser-window.ts) for the sheet and Open File. - Status: KS-10 yes, KS-20 partial (Mini Window ⌘F, the blank window and extension keys are not built). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…n Windows and Linux (KS-12, KS-15) - Open File… (macOS File menu, the command bar): the files chosen open in new tabs of the window, the last one selected. ⌘O / Ctrl+O are Open Peek as Tab's keys; where no Peek or Mini Window is open, the key router runs Open File on them instead (BORROWED_KEYS, keys/open-file.ts). The menu shows the key without registering it, and Settings → Shortcuts says it under Open File…, which can get keys of its own. From a Mini Window or Settings the files open in the browser window behind, which comes forward. - windows.ts: one line asks keyRouter.actionIn for the action before it runs. miniwindow/index.ts: file.open passes through like help.shortcuts. - `fixed` can be 'other' (Windows and Linux only), read through isFixed: F1 for Help can't be changed or taken there; on macOS Help has no keys and can be given some. - Tests: ⌘O with no Peek (two files, cancel), Open File from a Mini Window, the Settings note and the locked F1, menu and keymap unit tests. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: 13f39aa3-5f72-4b20-a014-7d9254b5e007) |
Conflicts:
- LibraryButton.tsx: downloads' button (recent files on hover, right-click) with the
title from useShortcutLabel('app.library'); the static TITLE and its imports go.
- OverlayApp.tsx: both imports (downloads flyout and the shortcut sheet), in Biome's order.
- feature-status.json: SB-09 from main (the recent-files popover is built); SB-11 keeps
the KS-02 note. FEATURES.md regenerated.
attachShortcuts keeps its order (record, switcher, actionIn, has, leaveToPage, run); the
run line now passes repeat from main.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ading page goes to the page first; D60 priorities (PR #23 review) - M1: main mirrors where the keyboard is in each tab's page (src/main/keys/page-focus.ts). The main frame, and the frame inside it that has the keyboard (contents.focusedFrame), say where focus is as it moves. So ⌘[ / Alt+← outside text fields goes back at once, in a frame too, and a press in a frame is judged by that frame's fields and handlers. - M2: Esc in a Mini Window's address field gives the keyboard back to its page (mini.focusPage). - M3: a private window's sidebar has no Clear button. - D59: the page preload sends one bit after a trusted Esc in a tab's main frame: whether the page used it. While the tab loads, main waits for it 250 ms at most and stops the load only if the page left Esc alone (src/main/keys/escape.ts). - D60: ⌘S prefers Orbit on macOS (Ctrl+S prefers websites on Windows and Linux); a page's answer is waited for 250 ms at most, no answer counting as left alone; ⌃` steps back in the recent-tab switcher on every platform, only while it is up; macOS Settings refuses ⌃ with a lone letter. - F4: ⌘Y / Ctrl+H and the Library's keys from a Mini Window act in the browser window behind it. - F5: View Archive in a private window shows the "Not available" hint. - F6: on macOS the menu takes ⌘O itself while no Orbit window is shown; it is built again as windows show, hide, minimize, restore and close. - KS-13: DevTools rows in the default-keymap table, and remap tests. KS-17: e2e for ⌘-click / middle-click on Forward and a double-click on the empty sidebar. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…2, KS-13, KS-16, KS-17, KS-19, KS-20, SB-11, TB-05, ST-08 and NV-04 notes; regenerate FEATURES.md Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: 4766449b-dcdc-4085-b1a0-3a0a36f75e0a) |
Conflicts: SidebarItems.tsx and src/shared/actions.ts each keep both sides' import lines; FEATURES.md regenerated with scripts/features.mjs. docs/feature-status.json merged on its own and matches both sides leaf by leaf. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: a8ba8ecf-74b2-4b88-8c40-78b7613077e7) |
siyabendoezdemir
added a commit
that referenced
this pull request
Oct 11, 2026
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
siyabendoezdemir
added a commit
that referenced
this pull request
Oct 11, 2026
…to lane/feel Conflicts, both sides kept: - OverlayApp.tsx, PeekLayer.tsx, SidebarItems.tsx: import lines only (keys' ShortcutSheet, useKeymap and useShortcutLabel beside the motion imports). - feature-status.json: keys' KS-09 and the lane's FL-15; FEATURES.md regenerated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The keys lane makes every Orbit action one keymap that people can change. It sets whether a key goes to the web page or to Orbit first, and which keys work in each kind of window. It's built from
lanes/keys.mdand the spec's KS rows, on top of chrome's action registry, withmain(PR #18) merged in.What it builds
Review
reviews/lane-keys.md) approved it with 3 must-fixes:8688b76..d742522) merged downloads (PR Downloads and DevTools (downloads lane: DL, DT) #20) and fixed all three, each with a test that fails without it. It also:reviews/lane-keys-fixcheck.md).main(75ffb3a, after import, PR Import: other browsers, bookmarks files, pasted links, history (IM) #22):SidebarItems.tsxandsrc/shared/actions.tskeep both sides' import lines, andFEATURES.mdis regenerated.docs/feature-status.jsonmerged without conflicts and matches both sides leaf by leaf.src/main/commandbar/sources.tskeeps both lanes' changes.Merge gate (D42), run locally on Linux on
75ffb3anpm run build,npm run typecheck,npm run lintand./node_modules/.bin/vitest runall exit 0. Unit: 850 passed of 850, in 83 files.xvfb-run -a -s "-screen 0 1440x900x24" ./node_modules/.bin/playwright test --workers 1 --retries 0ran 589 tests in 27.8 min: 585 passed, 4 skipped, 0 failed, and it exited 0.test.fail()) counts as passed.75ffb3aitself, withmain(fbb9103) in it.🤖 Generated with Claude Code
Note
High Risk
Centralizes all keyboard input through new main-process routing and injected page scripts; incorrect precedence or focus handling would affect every window, overlay, and web page interaction.
Overview
Adds the keys lane: a unified, per-device remappable keymap wired through main-process routing, Settings → Shortcuts, and live hints in menus, the command bar, and the new Help → Keyboard Shortcuts sheet.
Routing behavior is documented and implemented in
src/main/keys/:keyRouterruns before actions (recording in Settings, recent-tab switcher keys, Open File vs Peek/Mini Window), then decides Orbit vs page first (KS-02) using isolated-world page watchers and a focus mirror so Back/Forward and Ctrl+S / Copy URL can defer to sites with toast + second-press fallback. Esc while loading consultsorbit-page:escapebefore stopping navigation (D59).KEEP_KEYBOARDdisables focus-on-navigation so background loads don’t steal focus from the command bar or sidebar (KS-16).Integration touches include registering
registerKeysbefore other features,keys.*commands and persistence normalization, macOS menu rebuild on remap, private-window action blocking with toasts, and command-bar action shortcut cache invalidation on keymap version changes. Feature checklist and architecture docs are updated to reflect the new KS/ST/OB coverage.Reviewed by Cursor Bugbot for commit 75ffb3a. Bugbot is set up for automated code reviews on this repo. Configure here.