From 195fc1a27099ddc80b660907af43f40954532ede Mon Sep 17 00:00:00 2001 From: pagedown Date: Sun, 23 Jan 2022 18:45:18 +0800 Subject: [PATCH 1/5] Minor tweaks to macOS key event debug log --- glfw/cocoa_window.m | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/glfw/cocoa_window.m b/glfw/cocoa_window.m index 0f5344959..3efee782a 100644 --- a/glfw/cocoa_window.m +++ b/glfw/cocoa_window.m @@ -1218,7 +1218,7 @@ is_ascii_control_char(char x) { switch(key) { case GLFW_FKEY_CAPS_LOCK: - mod_name = "caps"; + mod_name = "capslock"; action = modifierFlags & NSEventModifierFlagCapsLock ? GLFW_PRESS : GLFW_RELEASE; break; case GLFW_FKEY_LEFT_SUPER: case GLFW_FKEY_RIGHT_SUPER: @@ -1240,7 +1240,7 @@ is_ascii_control_char(char x) { return; } GLFWkeyevent glfw_keyevent = {.key = key, .native_key = keycode, .native_key_id = keycode, .action = action, .mods = mods}; - debug_key("\x1b[33mflagsChanged:\x1b[m modifer: %s native_key: 0x%x (%s) glfw_key: 0x%x %s\n", + debug_key("\x1b[33mflagsChanged:\x1b[m modifier: %s native_key: 0x%x (%s) glfw_key: 0x%x %s\n", mod_name, keycode, safe_name_for_keycode(keycode), key, format_mods(mods)); marked_text_cleared_by_insert = false; NSTextInputContext *inpctx = [NSTextInputContext currentInputContext]; @@ -1250,14 +1250,13 @@ is_ascii_control_char(char x) { [inpctx handleEvent:event]; in_key_handler = 0; if (marked_text_cleared_by_insert) { - debug_key("Clearing pre-edit text"); + debug_key("Clearing pre-edit text because insertText called from flagsChanged\n"); CLEAR_PRE_EDIT_TEXT; if (_glfw.ns.text[0]) glfw_keyevent.text = _glfw.ns.text; else _glfw.ns.text[0] = old_first_char; } } glfw_keyevent.ime_state = GLFW_IME_NONE; - debug_key("\n"); _glfwInputKeyboard(window, &glfw_keyevent); } @@ -1381,7 +1380,7 @@ is_ascii_control_char(char x) { bool had_marked_text = [self hasMarkedText]; [self unmarkText]; if (had_marked_text && !in_key_handler) { - debug_key("clearing pre-edit because setMarkedText called from event loop\n"); + debug_key("Clearing pre-edit because setMarkedText called from event loop\n"); GLFWkeyevent glfw_keyevent = {.ime_state = GLFW_IME_PREEDIT_CHANGED}; _glfwInputKeyboard(window, &glfw_keyevent); _glfw.ns.text[0] = 0; @@ -1398,7 +1397,7 @@ is_ascii_control_char(char x) { markedText = [[NSMutableAttributedString alloc] initWithString:string]; } if (!in_key_handler) { - debug_key("updating IME text in kitty from setMarkedText called from event loop: %s\n", _glfw.ns.text); + debug_key("Updating IME text in kitty from setMarkedText called from event loop: %s\n", _glfw.ns.text); GLFWkeyevent glfw_keyevent = {.text=[[markedText string] UTF8String], .ime_state = GLFW_IME_PREEDIT_CHANGED}; _glfwInputKeyboard(window, &glfw_keyevent); _glfw.ns.text[0] = 0; @@ -1467,7 +1466,7 @@ void _glfwPlatformUpdateIMEState(_GLFWwindow *w, const GLFWIMEUpdateEvent *ev) { [self unmarkText]; marked_text_cleared_by_insert = true; if (!in_key_handler) { - debug_key("clearing pre-edit because insertText called from event loop\n"); + debug_key("Clearing pre-edit because insertText called from event loop\n"); GLFWkeyevent glfw_keyevent = {.ime_state = GLFW_IME_PREEDIT_CHANGED}; _glfwInputKeyboard(window, &glfw_keyevent); _glfw.ns.text[0] = 0; @@ -1478,7 +1477,7 @@ void _glfwPlatformUpdateIMEState(_GLFWwindow *w, const GLFWIMEUpdateEvent *ev) { snprintf(s, sizeof(_glfw.ns.text) - (s - _glfw.ns.text), "%s", utf8); _glfw.ns.text[sizeof(_glfw.ns.text) - 1] = 0; if ((!in_key_handler || in_key_handler == 2) && _glfw.ns.text[0]) { - debug_key("sending text to kitty from insertText called from event loop: %s\n", _glfw.ns.text); + debug_key("Sending text to kitty from insertText called from event loop: %s\n", _glfw.ns.text); GLFWkeyevent glfw_keyevent = {.text=_glfw.ns.text, .ime_state=GLFW_IME_COMMIT_TEXT}; _glfwInputKeyboard(window, &glfw_keyevent); _glfw.ns.text[0] = 0; From 57e2866b686ca821a78716eee8210ca8ddd016f9 Mon Sep 17 00:00:00 2001 From: pagedown Date: Sun, 23 Jan 2022 18:50:55 +0800 Subject: [PATCH 2/5] macOS: Fix caps_lock not clearing pre-edit text when using IME --- glfw/cocoa_window.m | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/glfw/cocoa_window.m b/glfw/cocoa_window.m index 3efee782a..ec774e474 100644 --- a/glfw/cocoa_window.m +++ b/glfw/cocoa_window.m @@ -1379,8 +1379,8 @@ is_ascii_control_char(char x) { if (string == nil || !s[0]) { bool had_marked_text = [self hasMarkedText]; [self unmarkText]; - if (had_marked_text && !in_key_handler) { - debug_key("Clearing pre-edit because setMarkedText called from event loop\n"); + if (had_marked_text && (!in_key_handler || in_key_handler == 2)) { + debug_key("Clearing pre-edit because setMarkedText called from event loop or flagsChanged\n"); GLFWkeyevent glfw_keyevent = {.ime_state = GLFW_IME_PREEDIT_CHANGED}; _glfwInputKeyboard(window, &glfw_keyevent); _glfw.ns.text[0] = 0; @@ -1396,8 +1396,8 @@ is_ascii_control_char(char x) { [markedText release]; markedText = [[NSMutableAttributedString alloc] initWithString:string]; } - if (!in_key_handler) { - debug_key("Updating IME text in kitty from setMarkedText called from event loop: %s\n", _glfw.ns.text); + if (!in_key_handler || in_key_handler == 2) { + debug_key("Updating IME text in kitty from setMarkedText called from event loop or flagsChanged: %s\n", _glfw.ns.text); GLFWkeyevent glfw_keyevent = {.text=[[markedText string] UTF8String], .ime_state = GLFW_IME_PREEDIT_CHANGED}; _glfwInputKeyboard(window, &glfw_keyevent); _glfw.ns.text[0] = 0; @@ -1477,7 +1477,7 @@ void _glfwPlatformUpdateIMEState(_GLFWwindow *w, const GLFWIMEUpdateEvent *ev) { snprintf(s, sizeof(_glfw.ns.text) - (s - _glfw.ns.text), "%s", utf8); _glfw.ns.text[sizeof(_glfw.ns.text) - 1] = 0; if ((!in_key_handler || in_key_handler == 2) && _glfw.ns.text[0]) { - debug_key("Sending text to kitty from insertText called from event loop: %s\n", _glfw.ns.text); + debug_key("Sending text to kitty from insertText called from called from event loop or flagsChanged: %s\n", _glfw.ns.text); GLFWkeyevent glfw_keyevent = {.text=_glfw.ns.text, .ime_state=GLFW_IME_COMMIT_TEXT}; _glfwInputKeyboard(window, &glfw_keyevent); _glfw.ns.text[0] = 0; From 1ce4fc9c8ce03a91e687be09109f2aaec1ead04e Mon Sep 17 00:00:00 2001 From: pagedown Date: Sun, 23 Jan 2022 21:40:27 +0800 Subject: [PATCH 3/5] Check for ASCII control chars before sending text --- glfw/cocoa_window.m | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/glfw/cocoa_window.m b/glfw/cocoa_window.m index ec774e474..bb3f24f32 100644 --- a/glfw/cocoa_window.m +++ b/glfw/cocoa_window.m @@ -1477,9 +1477,11 @@ void _glfwPlatformUpdateIMEState(_GLFWwindow *w, const GLFWIMEUpdateEvent *ev) { snprintf(s, sizeof(_glfw.ns.text) - (s - _glfw.ns.text), "%s", utf8); _glfw.ns.text[sizeof(_glfw.ns.text) - 1] = 0; if ((!in_key_handler || in_key_handler == 2) && _glfw.ns.text[0]) { - debug_key("Sending text to kitty from insertText called from called from event loop or flagsChanged: %s\n", _glfw.ns.text); - GLFWkeyevent glfw_keyevent = {.text=_glfw.ns.text, .ime_state=GLFW_IME_COMMIT_TEXT}; - _glfwInputKeyboard(window, &glfw_keyevent); + if (!is_ascii_control_char(_glfw.ns.text[0])) { + debug_key("Sending text to kitty from insertText called from called from event loop or flagsChanged: %s\n", _glfw.ns.text); + GLFWkeyevent glfw_keyevent = {.text=_glfw.ns.text, .ime_state=GLFW_IME_COMMIT_TEXT}; + _glfwInputKeyboard(window, &glfw_keyevent); + } _glfw.ns.text[0] = 0; } } From 3ee12082f2476ce5ac6064d57e8f6e4538d26362 Mon Sep 17 00:00:00 2001 From: pagedown Date: Sun, 23 Jan 2022 22:16:26 +0800 Subject: [PATCH 4/5] No need to update the pre-edit text --- glfw/cocoa_window.m | 1 - 1 file changed, 1 deletion(-) diff --git a/glfw/cocoa_window.m b/glfw/cocoa_window.m index bb3f24f32..5ec9434c1 100644 --- a/glfw/cocoa_window.m +++ b/glfw/cocoa_window.m @@ -1185,7 +1185,6 @@ is_ascii_control_char(char x) { } if (([self hasMarkedText] || previous_has_marked_text) && !_glfw.ns.text[0]) { // do not pass keys like BACKSPACE while there's pre-edit text, let IME handle it - UPDATE_PRE_EDIT_TEXT; debug_key("Ignoring key press as IME is active and it generated no text\n"); return; } From b2d0c35fc2ad091d79461157a46a1ff963b9574b Mon Sep 17 00:00:00 2001 From: pagedown Date: Sun, 23 Jan 2022 22:22:24 +0800 Subject: [PATCH 5/5] Clear the pre-edit text only when inserting non-control characters Maintains the pre-edit input state after pressing the modifier key combination or function key while using the IME. --- glfw/cocoa_window.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/glfw/cocoa_window.m b/glfw/cocoa_window.m index 5ec9434c1..a2f79e809 100644 --- a/glfw/cocoa_window.m +++ b/glfw/cocoa_window.m @@ -1461,7 +1461,7 @@ void _glfwPlatformUpdateIMEState(_GLFWwindow *w, const GLFWIMEUpdateEvent *ev) { { const char *utf8 = polymorphic_string_as_utf8(string); debug_key("\n\tinsertText: %s replacementRange: (%lu, %lu)\n", utf8, replacementRange.location, replacementRange.length); - if ([self hasMarkedText]) { + if ([self hasMarkedText] && !is_ascii_control_char(utf8[0])) { [self unmarkText]; marked_text_cleared_by_insert = true; if (!in_key_handler) {