diff --git a/src/main.rs b/src/main.rs index 0072c15..5e0fb3a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -727,20 +727,24 @@ impl TerminalWindow { if self.active().ghost_text.is_some() { self.accept_ghost(); } else { - self.pty_write(b"\x1b[C"); + let app = self.active().terminal.state.cursor_keys_app_mode; + self.pty_write(if app { b"\x1bOC" } else { b"\x1b[C" }); } } Key::Named(NamedKey::ArrowUp) => { self.active_mut().ghost_text = None; - self.pty_write(b"\x1b[A"); + let app = self.active().terminal.state.cursor_keys_app_mode; + self.pty_write(if app { b"\x1bOA" } else { b"\x1b[A" }); } Key::Named(NamedKey::ArrowDown) => { self.active_mut().ghost_text = None; - self.pty_write(b"\x1b[B"); + let app = self.active().terminal.state.cursor_keys_app_mode; + self.pty_write(if app { b"\x1bOB" } else { b"\x1b[B" }); } Key::Named(NamedKey::ArrowLeft) => { self.active_mut().ghost_text = None; - self.pty_write(b"\x1b[D"); + let app = self.active().terminal.state.cursor_keys_app_mode; + self.pty_write(if app { b"\x1bOD" } else { b"\x1b[D" }); } Key::Named(NamedKey::Home) => self.pty_write(b"\x1b[H"), Key::Named(NamedKey::End) => self.pty_write(b"\x1b[F"), diff --git a/src/platform.rs b/src/platform.rs index f73f379..86526db 100644 --- a/src/platform.rs +++ b/src/platform.rs @@ -221,7 +221,8 @@ pub fn select_prev_tab(ns_view: *mut std::ffi::c_void) { #[cfg(target_os = "macos")] pub fn set_tab_title(ns_view: *mut std::ffi::c_void, title: &str) { use objc2::{msg_send, runtime::AnyObject}; - use std::os::raw::c_char; + use std::ffi::CString; + let Ok(c_title) = CString::new(title) else { return }; unsafe { let view: *mut AnyObject = ns_view as *mut AnyObject; let win: *mut AnyObject = msg_send![view, window]; @@ -230,7 +231,7 @@ pub fn set_tab_title(ns_view: *mut std::ffi::c_void, title: &str) { if tab.is_null() { return; } let ns_str: *mut AnyObject = msg_send![ objc2::class!(NSString), - stringWithUTF8String: title.as_ptr() as *const c_char + stringWithUTF8String: c_title.as_ptr() ]; if ns_str.is_null() { return; } let _: () = msg_send![tab, setTitle: ns_str]; diff --git a/src/terminal.rs b/src/terminal.rs index a1ff14e..d9d192d 100644 --- a/src/terminal.rs +++ b/src/terminal.rs @@ -87,6 +87,9 @@ pub struct TerminalState { pub osc_52_query: bool, /// Whether the app has enabled bracketed paste mode (?2004h). pub bracketed_paste: bool, + /// Whether cursor key application mode is active (?1h = DECCKM). + /// When true, arrow keys send \x1bO[ABCD] instead of \x1b[[ABCD]. + pub cursor_keys_app_mode: bool, saved_cursor: (usize, usize), saved_attrs: Attrs, wrap_next: bool, @@ -137,6 +140,7 @@ impl TerminalState { alt_saved_cursor: (0, 0), osc_52_query: false, bracketed_paste: false, + cursor_keys_app_mode: false, } } @@ -639,6 +643,7 @@ impl Perform for TerminalState { (b'?', 'h') => { for ¶m in &p { match param { + 1 => self.cursor_keys_app_mode = true, 47 | 1047 => self.enter_alt_screen(false), 1049 => self.enter_alt_screen(true), 2004 => self.bracketed_paste = true, @@ -649,6 +654,7 @@ impl Perform for TerminalState { (b'?', 'l') => { for ¶m in &p { match param { + 1 => self.cursor_keys_app_mode = false, 47 | 1047 => self.leave_alt_screen(false), 1049 => self.leave_alt_screen(true), 2004 => self.bracketed_paste = false,