From 68cb3288be20278da9acf57dd4eaae7cb40e7211 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Thu, 10 Aug 2023 11:51:11 -0700 Subject: [PATCH] do not process charCallback if control character was processed Fixes #267 We have a mechanism `ignore_char` to ignore the `charCallback` exactly once. It is guaranteed by all app runtimes that `keyCallback` is called before `charCallback` and that they're called in order by key press (you'll never get 3 `keyCallbacks` and then `charCallback` for the first press). We use this for example to ensure that if you bind `a` to something, that we never actually print 'a', since the binding consumes it. This commit sets `ignore_char` whenever we detect a key that should be translated to a control character and written to the pty. As the comment in the code states: we probably should've been doing this anyways. It is a complete mystery why macOS behaves the way it does that caused us to figure this out. --- src/Surface.zig | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/Surface.zig b/src/Surface.zig index d40a1dfa5..29455592e 100644 --- a/src/Surface.zig +++ b/src/Surface.zig @@ -1137,6 +1137,18 @@ pub fn keyCallback( }; }; if (char > 0) { + // We are handling this char so don't allow charCallback to do + // anything. Normally it shouldn't because charCallback should not + // be called for control characters. But, we found a scenario where + // it does: https://github.com/mitchellh/ghostty/issues/267 + // + // In case that URL goes away: on macOS, after typing a dead + // key sequence, macOS would call `insertText` with control + // characters. Prior to calling a dead key sequence, it would + // not. I don't know. It doesn't matter, this is more correct + // anyways. + self.ignore_char = true; + // Ask our IO thread to write the data var data: termio.Message.WriteReq.Small.Array = undefined; data[0] = @intCast(char);