Skip to content

fix(web): capture digit shortcuts as numbers instead of shifted symbols - #10174

Closed
Invictine wants to merge 1 commit into
pingdotgg:mainfrom
Invictine:fix/keybinding-digit-symbols
Closed

Invictine wants to merge 1 commit into
pingdotgg:mainfrom
Invictine:fix/keybinding-digit-symbols

Conversation

@Invictine

@Invictine Invictine commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

When recording a shortcut in Settings > Keyboard Shortcuts that includes Shift (e.g. Mod+Shift+1 or Shift+6), keybindingFromKeyboardEvent previously evaluated event.key directly. On standard keyboard layouts with Shift held down, this produced the shifted symbol (such as ! or ^) instead of the digit number, saving non-canonical bindings like shift+^ or mod+shift+!.

While legacy shift+^ bindings continued to match at runtime because resolveEventKeys matches event.key, storing shifted symbols produces non-canonical, ugly shortcut strings that diverge from standard keybinding conventions.

Changes

  • Shared code canonicalization (apps/web/src/keybindings.ts): Exported canonicalKeyFromEventCode, which derives canonical key tokens directly from the existing EVENT_CODE_KEY_ALIASES mapping (Digit0..Digit9 -> 0..9, BracketLeft -> [, BracketRight -> ]). This keeps a single source of truth for physical key aliasing between runtime dispatch and settings capture.
  • Settings capture (KeybindingsSettings.logic.ts): normalizeShortcutKeyToken now reuses canonicalKeyFromEventCode(event.code) before falling back to normalized layout keys. Numpad keys are not in the alias map, so NumLock-off keypad navigation (e.g. End) preserves navigation behavior and is never hijacked as a digit.
  • Backwards compatibility & Runtime tests (keybindings.test.ts):
    • Verified canonicalKeyFromEventCode mapping across digits, brackets, and non-aliased keys.
    • Added test verifying shifted keydown events (key: !, code: Digit1) resolve to canonical digit commands (modelPicker.jump.1).
    • Added test verifying shifted digit shortcuts (key: ^, code: Digit6) resolve to shift+6 bindings.
    • Added test verifying legacy stored shifted symbol bindings (shift+^) remain backwards-compatible and continue to fire via event.key.
    • Added test verifying NumLock-off navigation (key: End, code: Numpad1) does not trigger digit shortcuts.

Visual Comparison

Before After
Before After

Validation

Ran test suite:

  • vp test apps/web/src/components/settings/KeybindingsSettings.logic.test.ts apps/web/src/keybindings.test.ts (all 65 tests pass).
  • vp check --fix (formatting compliant).

Note

Fix keybinding digit shortcuts to capture numbers via event.code instead of shifted symbols

  • Adds canonicalKeyFromEventCode in keybindings.ts to map physical keyboard event codes (digits, brackets, numpad) to canonical key tokens
  • Updates normalizeShortcutKeyToken and keybindingFromKeyboardEvent in KeybindingsSettings.logic.ts to prefer the physical code over event.key, so shifted digits like ! or @ are stored as 1 and 2
  • Unmapped codes fall back to existing event.key normalization; modifier ordering and platform handling are unchanged
  • Behavioral Change: legacy keybindings stored with shifted symbols (e.g. !) remain resolvable, but newly captured digit shortcuts will now record numeric tokens instead

Macroscope summarized f58bf2e.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:S 10-29 changed lines (additions + deletions). labels Sep 5, 2026
Comment thread apps/web/src/components/settings/KeybindingsSettings.logic.ts Outdated
Comment thread apps/web/src/keybindings.ts Outdated
@macroscopeapp

macroscopeapp Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at f58bf2e

Macroscope's review found this PR approvable — This is a small, well-tested keyboard-shortcut recording fix that normalizes shifted digits and brackets without changing schemas, defaults, or unrelated runtime paths. The implementation also preserves logical keypad navigation when NumLock is off.

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

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 84529ecf99

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +306 to +308
const digitMatch = code?.match(/^(?:Digit|Numpad)(\d)$/);
if (digitMatch?.[1]) {
return digitMatch[1];

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve navigation keys when Num Lock is off

When Num Lock is disabled, browsers report keypad keys with logical values such as End or PageDown while their physical codes remain Numpad1 or Numpad3. This unconditional rewrite therefore records Ctrl+keypad-1 as mod+1 instead of mod+end; combined with the new runtime numpad aliases, the same keystroke can execute the global thread.jump.1 binding rather than its navigation action. Gate numpad normalization on the logical key or Num Lock state instead of matching the physical code alone.

Useful? React with 👍 / 👎.

@cursor

cursor Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Sep 5, 2026
@macroscopeapp
macroscopeapp Bot dismissed their stale review September 5, 2026 17:27

Dismissing prior approval to re-evaluate 4e668b5

macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Sep 5, 2026
@macroscopeapp
macroscopeapp Bot dismissed their stale review September 5, 2026 17:35

Dismissing prior approval to re-evaluate 867c724

macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Sep 5, 2026
@Invictine
Invictine force-pushed the fix/keybinding-digit-symbols branch from 867c724 to f58bf2e Compare September 6, 2026 08:14
@macroscopeapp
macroscopeapp Bot dismissed their stale review September 6, 2026 08:15

Dismissing prior approval to re-evaluate f58bf2e

@Invictine

Copy link
Copy Markdown
Contributor Author

Closing this PR as this behavior was addressed upstream in PR #8103 (commit 299404a75), merged on September 8, 2026 and released in v0.0.41-nightly.20260908.1377.

Upstream resolved this via:

  • Adding EVENT_CODE_SHORTCUT_KEYS and shortcutKeyFromEvent(event) in apps/web/src/keybindings.ts, mapping physical event.code values (Digit0..Digit9, brackets, symbols) to their base characters.
  • Updating keybindingFromKeyboardEvent(event) in apps/web/src/components/settings/KeybindingsSettings.logic.ts to evaluate normalizeShortcutKeyToken(shortcutKeyFromEvent(event)).

Thank you!

@Invictine Invictine closed this Sep 15, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:S 10-29 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