diff --git a/docs/changelog.rst b/docs/changelog.rst index f8089957c..25b3a524e 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -127,6 +127,8 @@ Detailed list of changes - Show number of windows per tab in the :ac:`select_tab` action (:pull:`4523`) +- macOS: Fix the shift key not clearing pre-edit text in IME (:iss:`4541`) + 0.24.1 [2022-01-06] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/glfw/cocoa_window.m b/glfw/cocoa_window.m index 18ec0af4a..30d0fefd1 100644 --- a/glfw/cocoa_window.m +++ b/glfw/cocoa_window.m @@ -752,6 +752,7 @@ static const NSRange kEmptyRange = { NSNotFound, 0 }; NSMutableAttributedString* markedText; NSRect markedRect; bool marked_text_cleared_by_insert; + bool in_key_down; NSString *input_source_at_last_key_event; } @@ -1150,12 +1151,14 @@ is_ascii_control_char(char x) { debug_key("\x1b[31mPress:\x1b[m native_key: 0x%x (%s) glfw_key: 0x%x %schar_count: %lu deadKeyState: %u repeat: %d ", keycode, safe_name_for_keycode(keycode), key, format_mods(mods), char_count, window->ns.deadKeyState, event.ARepeat); marked_text_cleared_by_insert = false; + in_key_down = true; if (process_text) { // this will call insertText which will fill up _glfw.ns.text [self interpretKeyEvents:@[event]]; } else { window->ns.deadKeyState = 0; } + in_key_down = false; if (window->ns.deadKeyState && (char_count == 0 || keycode == 0x75)) { // 0x75 is the delete key which needs to be ignored during a compose sequence debug_key("Sending pre-edit text for dead key (text: %s markedText: %s).\n", format_text(_glfw.ns.text), glfw_keyevent.text); @@ -1181,6 +1184,7 @@ 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; } @@ -1419,6 +1423,11 @@ void _glfwPlatformUpdateIMEState(_GLFWwindow *w, const GLFWIMEUpdateEvent *ev) { char *s = _glfw.ns.text + strnlen(_glfw.ns.text, sizeof(_glfw.ns.text)); snprintf(s, sizeof(_glfw.ns.text) - (s - _glfw.ns.text), "%s", utf8); _glfw.ns.text[sizeof(_glfw.ns.text) - 1] = 0; + if (!in_key_down && !_glfw.ns.text[0]) { + // is called by cocoa when a modifier is pressed, for example shift + GLFWkeyevent dummy = {.action = GLFW_RELEASE, .ime_state = GLFW_IME_PREEDIT_CHANGED}; + _glfwInputKeyboard(window, &dummy); + } } - (void)doCommandBySelector:(SEL)selector