From 7ea0dfdd5dc03a7541bde7181ac1957a13542899 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Wed, 6 Dec 2023 09:04:59 -0800 Subject: [PATCH] macos: if a preedit state is cleared, don't send key event Fixes #992 --- macos/Sources/Ghostty/SurfaceView.swift | 14 +++++++++++--- src/Surface.zig | 7 ++++++- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/macos/Sources/Ghostty/SurfaceView.swift b/macos/Sources/Ghostty/SurfaceView.swift index 51e9e5eec..ee79d0cc3 100644 --- a/macos/Sources/Ghostty/SurfaceView.swift +++ b/macos/Sources/Ghostty/SurfaceView.swift @@ -781,14 +781,19 @@ extension Ghostty { ) ?? event } + let action = event.isARepeat ? GHOSTTY_ACTION_REPEAT : GHOSTTY_ACTION_PRESS + // By setting this to non-nil, we note that we'rein a keyDown event. From here, // we call interpretKeyEvents so that we can handle complex input such as Korean // language. keyTextAccumulator = [] defer { keyTextAccumulator = nil } + + // We need to know what the length of marked text was before this event to + // know if these events cleared it. + let markedTextBefore = markedText.length > 0 + self.interpretKeyEvents([translationEvent]) - - let action = event.isARepeat ? GHOSTTY_ACTION_REPEAT : GHOSTTY_ACTION_PRESS // If we have text, then we've composed a character, send that down. We do this // first because if we completed a preedit, the text will be available here @@ -802,7 +807,10 @@ extension Ghostty { } // If we have marked text, we're in a preedit state. Send that down. - if (markedText.length > 0) { + // If we don't have marked text but we had marked text before, then the preedit + // was cleared so we want to send down an empty string to ensure we've cleared + // the preedit. + if (markedText.length > 0 || markedTextBefore) { handled = true keyAction(action, event: event, preedit: markedText.string) } diff --git a/src/Surface.zig b/src/Surface.zig index cb0ee0991..67aeb2d1d 100644 --- a/src/Surface.zig +++ b/src/Surface.zig @@ -1085,6 +1085,8 @@ fn resize(self: *Surface, size: renderer.ScreenSize) !void { /// /// The preedit input must be UTF-8 encoded. pub fn preeditCallback(self: *Surface, preedit_: ?[]const u8) !void { + // log.debug("text preeditCallback value={any}", .{preedit_}); + self.renderer_state.mutex.lock(); defer self.renderer_state.mutex.unlock(); @@ -1124,7 +1126,10 @@ pub fn preeditCallback(self: *Surface, preedit_: ?[]const u8) !void { } // If we have no codepoints, then we're done. - if (codepoints.items.len == 0) return; + if (codepoints.items.len == 0) { + try self.queueRender(); + return; + } self.renderer_state.preedit = .{ .codepoints = try codepoints.toOwnedSlice(self.alloc),