aboutsummaryrefslogtreecommitdiff
path: root/src/ghostty
diff options
context:
space:
mode:
authorOgulcan Celik <ogulcancelik@gmail.com>2026-05-28 04:11:56 +0300
committerOgulcan Celik <ogulcancelik@gmail.com>2026-05-28 04:12:53 +0300
commitbf9cc201244946496b4d950046bf7edcc4892994 (patch)
tree920c866e67783cf31d2feff9642457204999c8eb /src/ghostty
parent789738cada5afaa20bbd77a0d479fb689c455bfe (diff)
fix: preserve live handoff terminal state
Diffstat (limited to 'src/ghostty')
-rw-r--r--src/ghostty/mod.rs58
1 files changed, 58 insertions, 0 deletions
diff --git a/src/ghostty/mod.rs b/src/ghostty/mod.rs
index 62d55835..9eda90d7 100644
--- a/src/ghostty/mod.rs
+++ b/src/ghostty/mod.rs
@@ -806,6 +806,64 @@ impl Terminal {
)
}
+ pub fn keyboard_state_ansi(&self) -> Result<String, Error> {
+ self.format_keyboard_state_ansi(false)
+ }
+
+ pub fn kitty_keyboard_state_ansi(&self) -> Result<String, Error> {
+ self.format_keyboard_state_ansi(true)
+ }
+
+ fn format_keyboard_state_ansi(&self, kitty_keyboard: bool) -> Result<String, Error> {
+ let mut formatter: ffi::GhosttyFormatter_ptr = ptr::null_mut();
+ let options = ffi::GhosttyFormatterTerminalOptions {
+ size: mem::size_of::<ffi::GhosttyFormatterTerminalOptions>(),
+ emit: FormatterFormat::Vt.as_raw(),
+ unwrap: false,
+ trim: false,
+ extra: ffi::GhosttyFormatterTerminalExtra {
+ size: mem::size_of::<ffi::GhosttyFormatterTerminalExtra>(),
+ keyboard: true,
+ screen: ffi::GhosttyFormatterScreenExtra {
+ size: mem::size_of::<ffi::GhosttyFormatterScreenExtra>(),
+ kitty_keyboard,
+ ..Default::default()
+ },
+ ..Default::default()
+ },
+ selection: ptr::null(),
+ };
+ unsafe {
+ ffi::ghostty_formatter_terminal_new(ptr::null(), &mut formatter, self.raw, options)
+ .into_result()?;
+ }
+
+ let mut out_ptr = ptr::null_mut();
+ let mut out_len = 0usize;
+ let result = unsafe {
+ ffi::ghostty_formatter_format_alloc(formatter, ptr::null(), &mut out_ptr, &mut out_len)
+ };
+ unsafe {
+ ffi::ghostty_formatter_free(formatter);
+ }
+ result.into_result()?;
+
+ let text = if out_len == 0 {
+ String::new()
+ } else {
+ let bytes = unsafe { slice::from_raw_parts(out_ptr.cast_const(), out_len) };
+ String::from_utf8_lossy(bytes).into_owned()
+ };
+
+ if !out_ptr.is_null() {
+ unsafe {
+ ffi::ghostty_free(ptr::null(), out_ptr, out_len);
+ }
+ }
+
+ Ok(text)
+ }
+
fn read_formatted_selection(
&self,
start: ffi::GhosttyPoint,