Skip to content

Fix Control key not being recorded when setting keyboard shortcuts on macOS - #16643

Merged
Siedlerchr merged 4 commits into
JabRef:mainfrom
krishna01989:issue-16604
Aug 25, 2026
Merged

Fix Control key not being recorded when setting keyboard shortcuts on macOS#16643
Siedlerchr merged 4 commits into
JabRef:mainfrom
krishna01989:issue-16604

Conversation

@krishna01989

@krishna01989 krishna01989 commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Summary

The keybinding preferences UI checked isShortcutDown(), isShiftDown(), and isAltDown() when capturing a new shortcut, but never isControlDown(). On macOS, Control is a separate modifier from Shortcut (Cmd), so pressing Control plus any key was silently ignored and no binding was recorded.

Windows/Linux are unaffected since Control is already their Shortcut key, so isControlDown() and isShortcutDown() fire together there; the fix is guarded to only add the extra Control handling on macOS to avoid duplicating the modifier.

jabref-contrib-policy:4.2:reviewed​:ok

Steps to test

  1. On macOS, launch JabRef and press ⌘, (Command+Comma) to open Preferences, then select "Keyboard shortcuts" from the left menu.
  2. Expand any category, select a shortcut entry, click its field, then press Control together with any letter key (e.g. Control+A).
  3. Confirm the shortcut field now shows the recorded binding (e.g. ^A) — before this fix, nothing was recorded when Control was pressed.
    NOTE: Some Control+Command combinations are reserved by macOS itself (e.g. Control+Command+D triggers the system dictionary lookup) and won't reach the app at all — this is expected OS behavior, not a bug in this fix.

Related issues and pull requests

Closes #16604

AI usage

AIL0

Checklist

  • I own the copyright of the code submitted and I license it under the MIT license
  • If AI tools were used, I disclosed them in the "AI usage" section and reviewed, understood, and take full ownership of all AI-generated code
  • I manually tested my changes in running JabRef (always required)
  • I added JUnit tests for changes (if applicable)
  • I added screenshots in the PR description (if change is visible to the user)
Screenshot 2026-08-21 at 21 48 17
  • I described the change in CHANGELOG.md in a way that can be understood by the average user (if change is visible to the user)
  • I checked the user documentation for up to dateness and submitted a pull request to our user documentation repository

@github-actions

Copy link
Copy Markdown
Contributor

Hey @krishna01989! 👋

Thank you for contributing to JabRef!

We have automated checks in place, based on which you will soon get feedback if any of them are failing. We also use Qodo for review assistance. It will update your pull request description with a review help and offer suggestions to improve the pull request.

After all automated checks pass, a maintainer will also review your contribution. Once that happens, you can go through their comments in the "Files changed" tab and act on them, or reply to the conversation if you have further inputs. You can read about the whole pull request process in our contribution guide.

Please ensure that your pull request is in line with our AI Usage Policy and make necessary disclosures.

@qodo-free-for-open-source-projects

Copy link
Copy Markdown
Contributor

PR Summary by Qodo

Record Control modifier when capturing keyboard shortcuts on macOS

🐞 Bug fix 🧪 Tests 📝 Documentation 🕐 20-40 Minutes

Grey Divider

AI Description

• Capture Ctrl as a modifier when recording new shortcuts on macOS
• Guard Ctrl handling to avoid duplicating modifiers on Windows/Linux
• Add regression tests and document the fix in the changelog
Diagram

graph TD
A["Preferences: Keyboard shortcuts UI"] --> B["KeyBindingViewModel"] --> C["KeyBindingRepository"]
B --> D["OS (macOS check)"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Inject a platform/modifier mapper (instead of static OS.OS_X)
  • ➕ Makes platform-specific modifier behavior unit-testable on any CI runner
  • ➕ Avoids tests that must be skipped/disabled due to OS constraints
  • ➕ Centralizes modifier normalization logic for future platform quirks
  • ➖ Slightly more refactoring (constructor params / DI) for a small bug fix
  • ➖ Requires touching additional call sites to pass the mapper/provider
2. Always include evt.isControlDown() without OS gating
  • ➕ Simplest code path; no OS branching
  • ➖ Likely duplicates Ctrl on Windows/Linux where Shortcut already equals Ctrl
  • ➖ Could change existing serialized shortcut strings unexpectedly

Recommendation: The current approach (add Ctrl only on macOS) is the safest minimal fix because it preserves existing Windows/Linux behavior and shortcut serialization. If CI reliability becomes a concern, consider the injected mapper/provider approach to replace the OS static check and enable non-macOS runners to validate macOS modifier behavior deterministically.

Files changed (3) +78 / -0

Bug fix (1) +5 / -0
KeyBindingViewModel.javaInclude Ctrl modifier in macOS shortcut capture +5/-0

Include Ctrl modifier in macOS shortcut capture

• Extends modifier collection during keybinding capture to include Control on macOS via an OS guard. This fixes cases where Ctrl+<key> was previously ignored because Ctrl is distinct from the Shortcut (Cmd) modifier on macOS.

jabgui/src/main/java/org/jabref/gui/preferences/keybindings/KeyBindingViewModel.java

Tests (1) +72 / -0
KeyBindingViewModelTest.javaAdd macOS-only regression tests for Ctrl-based bindings +72/-0

Add macOS-only regression tests for Ctrl-based bindings

• Introduces two tests asserting that Ctrl+A and Shift+Ctrl+A are persisted as expected on macOS. Tests are gated with assumeTrue(OS.OS_X) and additionally disabled on CI.

jabgui/src/test/java/org/jabref/gui/preferences/keybindings/KeyBindingViewModelTest.java

Documentation (1) +1 / -0
CHANGELOG.mdDocument macOS Ctrl shortcut recording fix +1/-0

Document macOS Ctrl shortcut recording fix

• Adds a user-facing changelog entry noting that Ctrl can now be recorded when creating new shortcuts on macOS, referencing issue #16604.

CHANGELOG.md

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Action required

1. Ctrl bindings rewritten on startup ✓ Resolved 🐞 Bug ≡ Correctness
Description
On macOS, KeyBindingViewModel#setNewBinding now records Control shortcuts as ctrl+…, but
PreferencesMigrations#upgradeKeyBindingsToJavaFX is run on every startup and replaces ctrl+ with
shortcut+, converting the saved Control binding into a Command(Shortcut) binding after restart.
This makes the fix appear to work in-session but silently changes user settings later.
Code

jabgui/src/main/java/org/jabref/gui/preferences/keybindings/KeyBindingViewModel.java[R112-115]

+        // Control and Shortcut are the same key on Windows/Linux; only macOS needs Control handled separately
+        if (OS.OS_X && evt.isControlDown()) {
+            modifiers += "ctrl+";
+        }
Evidence
The PR now generates bindings containing the literal prefix ctrl+ on macOS; keybindings are
persisted via JabRefGuiPreferences.BINDINGS and migrations run on startup. The existing migration
unconditionally replaces ctrl+ with shortcut+, so any saved macOS Control binding will be
rewritten to a Shortcut(Command) binding next time the app runs migrations.

jabgui/src/main/java/org/jabref/gui/preferences/keybindings/KeyBindingViewModel.java[101-126]
jabgui/src/main/java/org/jabref/migrations/PreferencesMigrations.java[47-57]
jabgui/src/main/java/org/jabref/migrations/PreferencesMigrations.java[280-294]
jabgui/src/main/java/org/jabref/gui/preferences/JabRefGuiPreferences.java[1368-1378]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
macOS control bindings are saved as `ctrl+...` but a preferences migration rewrites `ctrl+` to `shortcut+` on startup, so the recorded control shortcut will not persist.
### Issue Context
- `KeyBindingViewModel#setNewBinding` now appends `"ctrl+"` on macOS when `evt.isControlDown()`.
- `PreferencesMigrations.runMigrations(...)` always calls `upgradeKeyBindingsToJavaFX(...)`.
- `upgradeKeyBindingsToJavaFX(...)` unconditionally does `result.replace("ctrl+", "shortcut+")`, which will also rewrite newly created control bindings.
### Fix Focus Areas
- jabgui/src/main/java/org/jabref/gui/preferences/keybindings/KeyBindingViewModel.java[112-115]
- jabgui/src/main/java/org/jabref/migrations/PreferencesMigrations.java[47-57]
- jabgui/src/main/java/org/jabref/migrations/PreferencesMigrations.java[280-294]
### Suggested change
Make `upgradeKeyBindingsToJavaFX` only transform *legacy* keybinding strings (e.g., those containing `"ctrl "`, `"shift "`, `"alt "`, `"meta "` with spaces), and do **not** rewrite already-JavaFX-form strings that use `"ctrl+"` intentionally. For example:
- Detect legacy format first (`if (!str.contains("ctrl ") && !str.contains("shift ") ... ) return str;`).
- Replace `"ctrl "` directly to `"shortcut+"` (legacy shortcut modifier), but leave `"ctrl+"` untouched.
This preserves backward compatibility while allowing new macOS Control bindings to persist.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

2. macOS tests disabled on CI ✓ Resolved 📘 Rule violation ☼ Reliability
Description
The newly added macOS Control-key recording tests are annotated with @DisabledOnCIServer and
additionally gated by assumeTrue(OS.OS_X), so they never run in CI and are skipped on non-macOS
machines, reducing deterministic, continuous coverage for this behavior change and leaving
regressions unguarded.
Code

jabgui/src/test/java/org/jabref/gui/preferences/keybindings/KeyBindingViewModelTest.java[R91-94]

+    @Test
+    @DisabledOnCIServer("locally runs fine")
+    void controlKeyIsRecordedAsBindingOnMacOs() {
+        assumeTrue(OS.OS_X);
Evidence
PR Compliance ID 22 expects behavior-change tests to remain deterministic and strong, but the cited
tests are annotated with @DisabledOnCIServer, which is implemented as
@DisabledIfEnvironmentVariable(named = "CI", matches = "true"), meaning they will not execute in
CI when CI=true. The same tests also include assumeTrue(OS.OS_X), so they are skipped unless
running on macOS; together, these conditions prevent the new behavior from being continuously
validated by CI (while still safely skipping on non-macOS environments if CI runs them).

AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong: AGENTS.md: Testing Must Be Updated for Behavior Changes and Kept Deterministic and Strong
jabgui/src/test/java/org/jabref/gui/preferences/keybindings/KeyBindingViewModelTest.java[91-95]
jabgui/src/test/java/org/jabref/gui/preferences/keybindings/KeyBindingViewModelTest.java[126-130]
test-support/src/main/java/org/jabref/support/DisabledOnCIServer.java[10-15]
jabgui/src/test/java/org/jabref/gui/preferences/keybindings/KeyBindingViewModelTest.java[91-159]
test-support/src/main/java/org/jabref/support/DisabledOnCIServer.java[8-13]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new tests validating macOS Control-modifier shortcut/recording behavior are disabled in CI (and skipped on non-macOS), which weakens deterministic, continuous verification of the behavior change and means CI won’t catch regressions.
## Issue Context
`@DisabledOnCIServer` disables tests whenever the environment variable `CI=true` (via `@DisabledIfEnvironmentVariable(named = "CI", matches = "true")`). The tests also use `assumeTrue(OS.OS_X)`, so they will be skipped (not fail) on non-macOS environments, making it safe to run them in CI even when CI is not macOS; optionally, they can be executed on macOS CI runners if available.
## Fix Focus Areas
- jabgui/src/test/java/org/jabref/gui/preferences/keybindings/KeyBindingViewModelTest.java[91-159]
- test-support/src/main/java/org/jabref/support/DisabledOnCIServer.java[8-15]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Tip of the day
💡 Did you know, you can hide the parts of a finding you never read, like the evidence or the agent prompt

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

@github-actions github-actions Bot added status: changes-required Pull requests that are not yet complete status: no-bot-comments and removed status: changes-required Pull requests that are not yet complete status: no-bot-comments labels Aug 21, 2026
@github-actions

Copy link
Copy Markdown
Contributor

Your pull request conflicts with the target branch.

Please merge upstream/main with your code. For a step-by-step guide to resolve merge conflicts, see https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/addressing-merge-conflicts/resolving-a-merge-conflict-using-the-command-line.


@Test
void controlKeyCombinedWithShiftIsRecordedAsBindingOnMacOs() {
assumeTrue(OS.OS_X);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

use @EnabeldOnOS(OS.Mac) here and in the other tes

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

This is fixed in the latest commit.

@koppor koppor added status: changes-required Pull requests that are not yet complete and removed status: no-bot-comments labels Aug 24, 2026
… macOS

The keybinding preferences UI checked isShortcutDown(), isShiftDown(),
and isAltDown() when capturing a new shortcut, but never isControlDown().
On macOS, Control is a separate modifier from Shortcut (Cmd), so pressing
Control plus any key was silently ignored and no binding was recorded.

Windows/Linux are unaffected since Control is already their Shortcut key,
so isControlDown() and isShortcutDown() fire together there; the fix is
guarded to only add the extra Control handling on macOS to avoid
duplicating the modifier.

Fixes JabRef#16604
… macOS

The keybinding preferences UI checked isShortcutDown(), isShiftDown(),
and isAltDown() when capturing a new shortcut, but never isControlDown().
On macOS, Control is a separate modifier from Shortcut (Cmd), so pressing
Control plus any key was silently ignored and no binding was recorded.

Windows/Linux are unaffected since Control is already their Shortcut key,
so isControlDown() and isShortcutDown() fire together there; the fix is
guarded to only add the extra Control handling on macOS to avoid
duplicating the modifier.

Also fixes upgradeKeyBindingsToJavaFX, a startup migration that
unconditionally rewrote any "ctrl+" substring to "shortcut+". This
predates Control being a distinct modifier and was only ever meant to
convert the legacy space-separated format (e.g. "ctrl A"); left as-is,
it would have silently rewritten our new intentional "ctrl+" bindings
back into "shortcut+" bindings on every app restart. The migration now
only touches strings still in the legacy space-separated format.

Fixes JabRef#16604
Switched the macOS-only tests from a manual assumeTrue(OS.OS_X) check
to JUnit 5's declarative @EnabledOnOs(OS.MAC), per maintainer review.

Also shortened the CHANGELOG.md entry to fit the template's updated
one-sentence, max-20-words guideline.
@Siedlerchr
Siedlerchr added this pull request to the merge queue Aug 25, 2026
@github-actions github-actions Bot added the status: to-be-merged PRs which are accepted and should go into the merge-queue. label Aug 25, 2026
Merged via the queue into JabRef:main with commit ab2eba9 Aug 25, 2026
71 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Control key on macOS cannot be used to set shortcuts

3 participants