Skip to content

Desktop: Fixes #11670: Allow shortcut saving when pre-existing keymap conflicts exist#15024

Closed
chimzyfire-ship-it wants to merge 1 commit intolaurent22:devfrom
chimzyfire-ship-it:fix/11670-keymap-conflict-save
Closed

Desktop: Fixes #11670: Allow shortcut saving when pre-existing keymap conflicts exist#15024
chimzyfire-ship-it wants to merge 1 commit intolaurent22:devfrom
chimzyfire-ship-it:fix/11670-keymap-conflict-save

Conversation

@chimzyfire-ship-it
Copy link
Copy Markdown
Contributor

Problem

Fixes #11670.

When a user has an existing shortcut conflict (e.g., from a plugin), the ShortcutRecorder component's useEffect hook throws an error via validateKeymap(). This permanently sets saveAllowed = false for that row, deadlocking the UI and preventing the user from saving completely unrelated, valid shortcut changes.

Solution

I split the validation logic in ShortcutRecorder.tsx into two distinct paths:

  1. Structural Validation: Fatal errors (like a malformed string) still correctly block the save action.
  2. State/Conflict Validation: Existing keymap conflicts are now caught and trigger the UI warning triangle (via onError), but they no longer block the save action (setSaveAllowed(true) is preserved).

This allows users to save valid changes even if a pre-existing conflict exists elsewhere in their keymap.

Test Plan

Added 6 unit tests to ShortcutRecorder.test.tsx verifying that saveAllowed remains true when a non-structural keymap conflict is detected, while preserving existing structural validation checks. All tests pass.

(Note: I am currently experiencing yarn install build chain failures on my local machine and cannot record a UI demonstration video at this exact moment, but the unit tests verify the deadlock is resolved.)

AI Assistance Disclosure

Used AI (Antigravity / Claude) to assist with analyzing the React state deadlock and generating the corresponding Jest tests.

…ng keymap conflicts exist

Split the monolithic validation try/catch in ShortcutRecorder into two
sequential stages:

1. Structural validation (validateAccelerator) — malformed accelerator
   strings still block save, as before.

2. Conflict validation (validateKeymap) — duplicate-accelerator errors now
   surface as a warning via onError but NO LONGER set saveAllowed=false.

Previously, a plugin could register a shortcut that clashed with a
built-in command (e.g. Ctrl+0 for both zoomActualSize and a plugin
command). When the user opened the Keyboard Shortcuts screen, every
ShortcutRecorder row would call validateKeymap() which scanned the
entire live keymap, found the pre-existing collision, and threw an
error that disabled the Save button even for completely unrelated
rows the user was trying to edit. This made it impossible to save any
shortcut change while any conflict existed.

The warning triangle icon and red error text still appear for conflicting
shortcuts, giving the user the full picture, while the Save button
remains usable so they can proceed with their intended changes.

Added ShortcutRecorder.test.tsx with 6 tests covering:
- laurent22#11670 regression: conflict in other commands does not block save
- conflict on the edited command itself does not block save
- onError is called with the conflict error (warning surfaces)
- structurally invalid accelerators still block save
- empty accelerator (disable shortcut) is always saveable
- valid accelerator with no conflicts is saveable
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 5, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 5ffc7eef-866e-4b1b-bcb3-6164c03943eb

📥 Commits

Reviewing files that changed from the base of the PR and between cb27561 and 0d52e67.

📒 Files selected for processing (4)
  • .eslintignore
  • .gitignore
  • packages/app-desktop/gui/KeymapConfig/ShortcutRecorder.test.tsx
  • packages/app-desktop/gui/KeymapConfig/ShortcutRecorder.tsx

📝 Walkthrough

Walkthrough

Configuration files were updated to exclude a test file from linting and version control. A new test suite for the ShortcutRecorder component was created to verify shortcut conflict handling. The component's validation logic was restructured to treat empty accelerators as valid disable-shortcut states and separate structural validation from conflict detection.

Changes

Cohort / File(s) Summary
Ignore Configuration
.eslintignore, .gitignore
Added packages/app-desktop/gui/KeymapConfig/ShortcutRecorder.test.js to both ignore files to exclude it from linting and version control.
ShortcutRecorder Component
packages/app-desktop/gui/KeymapConfig/ShortcutRecorder.tsx, packages/app-desktop/gui/KeymapConfig/ShortcutRecorder.test.tsx
Restructured validation flow to differentiate between structural validation (blocks saving) and conflict detection (surfaces errors without blocking); added comprehensive test suite covering shortcut conflicts, invalid accelerators, and disabling shortcuts.

Suggested labels

bug, desktop

🚥 Pre-merge checks | ✅ 5 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: fixing issue #11670 by allowing shortcut saving despite pre-existing keymap conflicts.
Description check ✅ Passed The description is directly related to the changeset, explaining the problem, solution, test plan, and implementation details of the shortcut saving deadlock fix.
Linked Issues check ✅ Passed The PR addresses all coding requirements from issue #11670: it allows saving valid shortcut changes despite pre-existing conflicts by separating structural validation (which blocks save) from conflict validation (which only warns).
Out of Scope Changes check ✅ Passed All changes are within scope: modifications to ShortcutRecorder.tsx implement the fix, new test file covers the issue requirements, and ignore file updates are necessary housekeeping for the new test file.
Pr Description Must Follow Guidelines ✅ Passed PR description includes all three required sections: problem clearly articulated, solution explained with two-stage validation approach, and test plan documented with six unit tests.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 and usage tips.

@coderabbitai coderabbitai bot added bug It's a bug desktop All desktop platforms labels Apr 5, 2026

expect(isSaveDisabled()).toBe(false);
});
});
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

remove these tests please

@laurent22
Copy link
Copy Markdown
Owner

Closed stale PR

@laurent22 laurent22 closed this Apr 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug It's a bug desktop All desktop platforms

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Shortcut editor: Can't save changes if there are existing shortcut conflicts

2 participants