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:
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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'));
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user