fix(tui): accept macOS command modifier for control shortcuts

Harvests the macOS shortcut fix from PR #2943 for the #2938 release lane, but scopes the SUPER-as-control mapping to the affected task/background and sidebar-focus shortcuts so Cmd+C/Cmd+V keep their existing platform behavior.

Co-authored-by: idling11 <8055620+idling11@users.noreply.github.com>
This commit is contained in:
Hunter B
2026-06-12 01:43:10 -07:00
parent 862cb2e394
commit c16a32150e
5 changed files with 50 additions and 4 deletions
+4
View File
@@ -50,6 +50,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
survives the CLI/TUI boundary by honoring the CodeWhale model env alias and
legacy DeepSeek model handoff before falling back to provider defaults.
Thanks @hongchen1993 for the PR.
- **macOS shortcut modifiers (#2938/#2943).** Ctrl-like shortcuts that are
reported as `SUPER` by macOS terminals now work for backgrounding tasks and
sidebar-focus chords without rewriting clipboard shortcuts. Thanks @idling11
for the PR.
- **TUI mouse-report leak (#3063/#3067).** Strip raw SGR mouse coordinate
tails from the composer even when `use_mouse_capture` is false, covering
orphaned terminal reporting state after crashes or focus races.
+4
View File
@@ -50,6 +50,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
survives the CLI/TUI boundary by honoring the CodeWhale model env alias and
legacy DeepSeek model handoff before falling back to provider defaults.
Thanks @hongchen1993 for the PR.
- **macOS shortcut modifiers (#2938/#2943).** Ctrl-like shortcuts that are
reported as `SUPER` by macOS terminals now work for backgrounding tasks and
sidebar-focus chords without rewriting clipboard shortcuts. Thanks @idling11
for the PR.
- **TUI mouse-report leak (#3063/#3067).** Strip raw SGR mouse coordinate
tails from the composer even when `use_mouse_capture` is false, covering
orphaned terminal reporting state after crashes or focus races.
+12
View File
@@ -9,6 +9,18 @@
use crossterm::event::{KeyCode, KeyEvent, KeyModifiers};
pub(super) fn has_control_like_modifier(modifiers: KeyModifiers) -> bool {
has_control_like_modifier_for_platform(modifiers, cfg!(target_os = "macos"))
}
pub(super) fn has_control_like_modifier_for_platform(
modifiers: KeyModifiers,
is_macos: bool,
) -> bool {
modifiers.contains(KeyModifiers::CONTROL)
|| (is_macos && modifiers.contains(KeyModifiers::SUPER))
}
/// Copy-to-clipboard: `Cmd+C` on macOS or `Ctrl+Shift+C` elsewhere.
pub(super) fn is_copy_shortcut(key: &KeyEvent) -> bool {
let is_c = matches!(key.code, KeyCode::Char('c') | KeyCode::Char('C'));
+4 -4
View File
@@ -3382,7 +3382,7 @@ async fn run_event_loop(
}
if matches!(key.code, KeyCode::Char('b') | KeyCode::Char('B'))
&& key.modifiers.contains(KeyModifiers::CONTROL)
&& key_shortcuts::has_control_like_modifier(key.modifiers)
&& app.view_stack.is_empty()
{
// #3032: Ctrl+B directly backgrounds the active foreground
@@ -3582,7 +3582,7 @@ async fn run_event_loop(
continue;
}
KeyCode::Char('1') if key.modifiers.contains(KeyModifiers::ALT) => {
if key.modifiers.contains(KeyModifiers::CONTROL) {
if key_shortcuts::has_control_like_modifier(key.modifiers) {
app.set_sidebar_focus(SidebarFocus::Work);
app.status_message = Some("Sidebar focus: work".to_string());
} else {
@@ -3591,7 +3591,7 @@ async fn run_event_loop(
continue;
}
KeyCode::Char('2') if key.modifiers.contains(KeyModifiers::ALT) => {
if key.modifiers.contains(KeyModifiers::CONTROL) {
if key_shortcuts::has_control_like_modifier(key.modifiers) {
app.set_sidebar_focus(SidebarFocus::Tasks);
app.status_message = Some("Sidebar focus: tasks".to_string());
} else {
@@ -3600,7 +3600,7 @@ async fn run_event_loop(
continue;
}
KeyCode::Char('3') if key.modifiers.contains(KeyModifiers::ALT) => {
if key.modifiers.contains(KeyModifiers::CONTROL) {
if key_shortcuts::has_control_like_modifier(key.modifiers) {
app.set_sidebar_focus(SidebarFocus::Agents);
app.status_message = Some("Sidebar focus: agents".to_string());
} else {
+26
View File
@@ -1262,6 +1262,32 @@ fn copy_shortcut_accepts_cmd_and_ctrl_shift_only() {
));
}
#[test]
fn control_like_modifier_accepts_super_only_on_macos() {
use crate::tui::key_shortcuts::has_control_like_modifier_for_platform;
assert!(has_control_like_modifier_for_platform(
KeyModifiers::CONTROL,
false
));
assert!(has_control_like_modifier_for_platform(
KeyModifiers::CONTROL,
true
));
assert!(!has_control_like_modifier_for_platform(
KeyModifiers::SUPER,
false
));
assert!(has_control_like_modifier_for_platform(
KeyModifiers::SUPER,
true
));
assert!(has_control_like_modifier_for_platform(
KeyModifiers::SUPER | KeyModifiers::ALT,
true
));
}
#[test]
fn file_tree_shortcut_does_not_steal_plain_ctrl_e() {
assert!(!crate::tui::key_shortcuts::is_file_tree_toggle_shortcut(