fix(tui): normalize macOS SUPER (Cmd) to CONTROL for keyboard shortcuts (#2938)#2943
fix(tui): normalize macOS SUPER (Cmd) to CONTROL for keyboard shortcuts (#2938)#2943idling11 wants to merge 3 commits into
Conversation
…ts (Hmbown#2938) On macOS, terminal emulators may report Cmd (SUPER) instead of Ctrl (CONTROL) for keyboard shortcuts, depending on the terminal app and its configuration. This caused Ctrl+B, Ctrl+Alt+2, and other shortcuts to be inconsistent. Fix: - Add normalize_macos_modifiers() in composer_ui.rs - On macOS: map SUPER to CONTROL when CONTROL is not already set - On other platforms: no-op - Apply normalization at the key event entry point in ui.rs Tests: - normalize_macos_modifiers_maps_super_to_control - normalize_macos_modifiers_preserves_existing_control - normalize_macos_modifiers_leaves_alt_unchanged
There was a problem hiding this comment.
Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.
There was a problem hiding this comment.
Code Review
This pull request introduces modifier normalization on macOS to map the SUPER (Cmd) key to CONTROL, ensuring keyboard shortcuts work consistently across different terminal emulators. The feedback highlights a critical issue where keeping the SUPER modifier alongside CONTROL would break exact modifier equality checks (e.g., key.modifiers == KeyModifiers::CONTROL). The reviewer suggests stripping SUPER entirely when mapping it to CONTROL and provides corresponding updates for both the normalization logic and the unit tests.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| #[cfg(target_os = "macos")] | ||
| pub(crate) fn normalize_macos_modifiers(modifiers: KeyModifiers) -> KeyModifiers { | ||
| if modifiers.contains(KeyModifiers::SUPER) && !modifiers.contains(KeyModifiers::CONTROL) { | ||
| modifiers | KeyModifiers::CONTROL | ||
| } else { | ||
| modifiers | ||
| } | ||
| } |
There was a problem hiding this comment.
If SUPER is kept in the modifiers, exact modifier checks like key.modifiers == KeyModifiers::CONTROL (such as the Ctrl+S stashing shortcut in ui.rs) will fail because the modifiers will be evaluated as CONTROL | SUPER instead of just CONTROL. On macOS, we should strip SUPER entirely and ensure CONTROL is set whenever SUPER is present.
| #[cfg(target_os = "macos")] | |
| pub(crate) fn normalize_macos_modifiers(modifiers: KeyModifiers) -> KeyModifiers { | |
| if modifiers.contains(KeyModifiers::SUPER) && !modifiers.contains(KeyModifiers::CONTROL) { | |
| modifiers | KeyModifiers::CONTROL | |
| } else { | |
| modifiers | |
| } | |
| } | |
| #[cfg(target_os = "macos")] | |
| pub(crate) fn normalize_macos_modifiers(modifiers: KeyModifiers) -> KeyModifiers { | |
| if modifiers.contains(KeyModifiers::SUPER) { | |
| (modifiers & !KeyModifiers::SUPER) | KeyModifiers::CONTROL | |
| } else { | |
| modifiers | |
| } | |
| } |
| #[test] | ||
| fn normalize_macos_modifiers_maps_super_to_control() { | ||
| use crate::tui::composer_ui::normalize_macos_modifiers; | ||
| // SUPER (Cmd) without CONTROL should gain CONTROL. | ||
| let normalized = normalize_macos_modifiers(KeyModifiers::SUPER); | ||
| assert!(normalized.contains(KeyModifiers::CONTROL)); | ||
| assert!(normalized.contains(KeyModifiers::SUPER)); | ||
| } |
There was a problem hiding this comment.
Update the test to assert that SUPER is removed during normalization, ensuring exact modifier equality checks work correctly.
| #[test] | |
| fn normalize_macos_modifiers_maps_super_to_control() { | |
| use crate::tui::composer_ui::normalize_macos_modifiers; | |
| // SUPER (Cmd) without CONTROL should gain CONTROL. | |
| let normalized = normalize_macos_modifiers(KeyModifiers::SUPER); | |
| assert!(normalized.contains(KeyModifiers::CONTROL)); | |
| assert!(normalized.contains(KeyModifiers::SUPER)); | |
| } | |
| #[test] | |
| fn normalize_macos_modifiers_maps_super_to_control() { | |
| use crate::tui::composer_ui::normalize_macos_modifiers; | |
| // SUPER (Cmd) without CONTROL should gain CONTROL and lose SUPER. | |
| let normalized = normalize_macos_modifiers(KeyModifiers::SUPER); | |
| assert!(normalized.contains(KeyModifiers::CONTROL)); | |
| assert!(!normalized.contains(KeyModifiers::SUPER)); | |
| } |
| #[test] | ||
| fn normalize_macos_modifiers_preserves_existing_control() { | ||
| use crate::tui::composer_ui::normalize_macos_modifiers; | ||
| // CONTROL already set — shouldn't be removed. | ||
| let normalized = normalize_macos_modifiers(KeyModifiers::CONTROL | KeyModifiers::SUPER); | ||
| assert!(normalized.contains(KeyModifiers::CONTROL)); | ||
| assert!(normalized.contains(KeyModifiers::SUPER)); | ||
| } |
There was a problem hiding this comment.
Update the test to assert that SUPER is removed even when CONTROL is already present, ensuring exact modifier equality checks work correctly.
| #[test] | |
| fn normalize_macos_modifiers_preserves_existing_control() { | |
| use crate::tui::composer_ui::normalize_macos_modifiers; | |
| // CONTROL already set — shouldn't be removed. | |
| let normalized = normalize_macos_modifiers(KeyModifiers::CONTROL | KeyModifiers::SUPER); | |
| assert!(normalized.contains(KeyModifiers::CONTROL)); | |
| assert!(normalized.contains(KeyModifiers::SUPER)); | |
| } | |
| #[test] | |
| fn normalize_macos_modifiers_preserves_existing_control() { | |
| use crate::tui::composer_ui::normalize_macos_modifiers; | |
| // CONTROL already set — SUPER should be removed. | |
| let normalized = normalize_macos_modifiers(KeyModifiers::CONTROL | KeyModifiers::SUPER); | |
| assert!(normalized.contains(KeyModifiers::CONTROL)); | |
| assert!(!normalized.contains(KeyModifiers::SUPER)); | |
| } |
There was a problem hiding this comment.
Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.
|
Thanks @idling11 — the normalization approach looks right, but Test (windows-latest) is failing and I believe it's the new tests rather than the logic: Could you either |
There was a problem hiding this comment.
Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.
On macOS, terminal emulators may report Cmd (SUPER) instead of Ctrl (CONTROL) for keyboard shortcuts, depending on the terminal app and its configuration. This caused Ctrl+B, Ctrl+Alt+2, and other shortcuts to be inconsistent.
Fix:
Tests:
Close #2938
Summary
Testing
cargo fmt --all -- --checkcargo clippy --workspace --all-targets --all-featurescargo test --workspace --all-featuresChecklist