aboutsummaryrefslogtreecommitdiff
path: root/src/pane
diff options
context:
space:
mode:
authorOgulcan Celik <ogulcancelik@gmail.com>2026-07-02 16:22:11 +0300
committerOgulcan Celik <ogulcancelik@gmail.com>2026-07-02 16:22:11 +0300
commitf4d216b63d010987775dc6eaf92afa72f86f2816 (patch)
tree3af6b07d744a581231a6dabf49e658c6640fdfed /src/pane
parent885dbcd19e5dc1ba3ac2fe96ce714cf6906a458c (diff)
fix: preserve windows backspace input
refs #907 refs #920
Diffstat (limited to 'src/pane')
-rw-r--r--src/pane/terminal.rs83
1 files changed, 65 insertions, 18 deletions
diff --git a/src/pane/terminal.rs b/src/pane/terminal.rs
index 708a7d28..79b4a19e 100644
--- a/src/pane/terminal.rs
+++ b/src/pane/terminal.rs
@@ -2689,30 +2689,36 @@ mod tests {
}
#[test]
- fn ghostty_release_still_encoded_for_report_event_pane() {
+ fn ghostty_report_event_pane_keeps_basic_compatibility_keys_legacy() {
let (tx, _rx) = mpsc::channel(4);
// Push kitty flags including REPORT_EVENT_TYPES (0b10) + DISAMBIGUATE (0b1).
let mut terminal = crate::ghostty::Terminal::new(80, 24, 0).unwrap();
terminal.write(b"\x1b[>3u");
let pane = GhosttyPaneTerminal::new(terminal, tx).unwrap();
- let release = pane.encode_terminal_key(
- crate::input::TerminalKey::new(
- crossterm::event::KeyCode::Enter,
- crossterm::event::KeyModifiers::empty(),
- )
- .with_kind(crossterm::event::KeyEventKind::Release),
- pane.keyboard_protocol().unwrap(),
- );
- let parsed =
- crate::input::parse_terminal_key_sequence(std::str::from_utf8(&release).unwrap())
- .unwrap();
- assert_eq!(parsed.code, crossterm::event::KeyCode::Enter);
- assert_eq!(
- parsed.kind,
- crossterm::event::KeyEventKind::Release,
- "report-event pane should encode a release, got {release:?}"
- );
+ for (code, expected) in [
+ (crossterm::event::KeyCode::Enter, b"\r".as_slice()),
+ (crossterm::event::KeyCode::Backspace, b"\x7f".as_slice()),
+ ] {
+ let press = pane.encode_terminal_key(
+ crate::input::TerminalKey::new(code, crossterm::event::KeyModifiers::empty()),
+ pane.keyboard_protocol().unwrap(),
+ );
+ assert_eq!(
+ press, expected,
+ "{code:?} press should stay legacy-compatible without REPORT_ALL_KEYS"
+ );
+
+ let release = pane.encode_terminal_key(
+ crate::input::TerminalKey::new(code, crossterm::event::KeyModifiers::empty())
+ .with_kind(crossterm::event::KeyEventKind::Release),
+ pane.keyboard_protocol().unwrap(),
+ );
+ assert!(
+ release.is_empty(),
+ "{code:?} release should not fall back to legacy bytes, got {release:?}"
+ );
+ }
}
#[test]
@@ -2939,6 +2945,47 @@ mod tests {
}
#[test]
+ fn ghostty_pane_characterizes_ctrl_backspace_encoding() {
+ let (tx, _rx) = mpsc::channel(4);
+ let legacy = GhosttyPaneTerminal::new(
+ crate::ghostty::Terminal::new(80, 24, 0).unwrap(),
+ tx.clone(),
+ )
+ .unwrap();
+
+ let ctrl_backspace = crate::input::TerminalKey::new(
+ crossterm::event::KeyCode::Backspace,
+ crossterm::event::KeyModifiers::CONTROL,
+ );
+ assert_eq!(
+ legacy.encode_terminal_key(ctrl_backspace, crate::input::KeyboardProtocol::Legacy),
+ b"\x08"
+ );
+
+ let plain_backspace = crate::input::TerminalKey::new(
+ crossterm::event::KeyCode::Backspace,
+ crossterm::event::KeyModifiers::empty(),
+ );
+ assert_eq!(
+ legacy.encode_terminal_key(plain_backspace, crate::input::KeyboardProtocol::Legacy),
+ b"\x7f"
+ );
+
+ let kitty = GhosttyPaneTerminal::new(
+ crate::ghostty::Terminal::new(80, 24, 0).unwrap(),
+ tx.clone(),
+ )
+ .unwrap();
+ let pane_id = PaneId::from_raw(1);
+ kitty.process_pty_bytes(pane_id, 0, b"\x1b[>1u", &tx);
+
+ assert_eq!(
+ kitty.encode_terminal_key(ctrl_backspace, crate::input::KeyboardProtocol::Legacy),
+ b"\x1b[127;5u"
+ );
+ }
+
+ #[test]
fn ghostty_key_encoders_are_isolated_per_pane() {
let (tx, _rx) = mpsc::channel(4);
let first = GhosttyPaneTerminal::new(