fix(input): carry key and preedit text as bytes like Zig
Zig's KeyEvent.utf8 and the embedded API's key/preedit text are byte slices passed through to key encoding and the pty; the port converted them lossily to UTF-8. - KeyEvent.utf8 is &[u8] end to end (ghostty-input encoder, core, ghostty-lib C API, libghostty-vt key events, GTK callers). Where Zig validates with Utf8View (alternates, modify-other-keys, ctrl CSI-u, associated text, binding unicode lookup) invalid text takes the same "no UTF-8" fallback. - Invalid preedit UTF-8 behaves like Zig's `try Utf8View.init`: the prior preedit is cleared and marked dirty, the callback returns an error (logged by the C API) and no preedit is set. - The inspector key widget shows invalid key text lossily, display only. Test Plan: - cargo test --workspace --no-fail-fast (3407 passed) - cargo test -p ghostty-lib --features test-platform (C-API key text 0xff 0xfe reaches the pty unchanged) - just check-macos (both), just check-windows, just check-wasm
This commit is contained in:
1 parent
1327e63811
commit
c8113345a5
19 files changed
+277
-144
No files matched your search
@@ -1679,7 +1679,7 @@ impl Surface {
|
||||
/// The core surface will NOT reset the preedit state on charCallback or
|
||||
/// keyCallback and we rely completely on the apprt implementation to
|
||||
/// track the preedit state correctly.
|
||||
pub fn preedit_callback(&self, preedit: Option<&str>) -> Result<(), CoreError> {
|
||||
pub fn preedit_callback(&self, preedit: Option<&[u8]>) -> Result<(), CoreError> {
|
||||
let cfg = self.cfg();
|
||||
let mut st = self.lock_state();
|
||||
|
||||
@@ -1704,7 +1704,16 @@ impl Surface {
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
// We convert the UTF-8 text to codepoints.
|
||||
// We convert the UTF-8 text to codepoints. Like Zig's
|
||||
// `Utf8View.init(text)`, invalid UTF-8 is an error: the prior preedit
|
||||
// is already cleared and marked dirty, and no new preedit is set.
|
||||
let text = match std::str::from_utf8(text) {
|
||||
Ok(t) => t,
|
||||
Err(e) => {
|
||||
drop(st);
|
||||
return Err(Box::new(e));
|
||||
}
|
||||
};
|
||||
let mut codepoints: Vec<PreeditCodepoint> = Vec::new();
|
||||
for cp in text.chars() {
|
||||
let width = usize::from(ghostty_unicode::table().get(u32::from(cp)).width);
|
||||
@@ -1993,7 +2002,7 @@ impl CoreSurface for Surface {
|
||||
Surface::key_callback(self, event)
|
||||
}
|
||||
|
||||
fn preedit_callback(&self, text: Option<&str>) -> Result<(), CoreError> {
|
||||
fn preedit_callback(&self, text: Option<&[u8]>) -> Result<(), CoreError> {
|
||||
let _crash = self.crash_guard();
|
||||
Surface::preedit_callback(self, text)
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user