diff --git a/README.md b/README.md index 0fe0987b..f127f09d 100644 --- a/README.md +++ b/README.md @@ -100,6 +100,7 @@ GLFW bundles a number of dependencies in the `deps/` directory. - [X11] Bugfix: `glfwWaitEvents` could return when no events were available - [X11] Bugfix: `XkbGetKeyboard` fails on XWayland - [X11] Bugfix: Character input did not work correctly for non-UTF-8 locales + - [X11] Bugfix: Long input sequences generated by IMEs were discarded - [WGL] Made all WGL functions dynamically loaded - [WGL] Removed `GLFW_USE_DWM_SWAP_INTERVAL` compile-time option - [WGL] Bugfix: Swap interval was ignored when DWM was enabled diff --git a/src/x11_window.c b/src/x11_window.c index 735ae17b..d5c91f69 100644 --- a/src/x11_window.c +++ b/src/x11_window.c @@ -921,31 +921,60 @@ static void processEvent(XEvent *event) if (!filtered) { + int count; + Status status; #if defined(X_HAVE_UTF8_STRING) - Status status; char buffer[96]; - const char* c = buffer; + char* chars = buffer; - const int count = Xutf8LookupString(window->x11.ic, - &event->xkey, - buffer, sizeof(buffer), - NULL, &status); + count = Xutf8LookupString(window->x11.ic, + &event->xkey, + buffer, sizeof(buffer), + NULL, &status); - while (c - buffer < count) - _glfwInputChar(window, decodeUTF8(&c), mods, plain); + if (status == XBufferOverflow) + { + chars = calloc(count, 1); + count = Xutf8LookupString(window->x11.ic, + &event->xkey, + chars, count, + NULL, &status); + } + + if (status == XLookupChars || status == XLookupBoth) + { + const char* c = chars; + while (c - chars < count) + _glfwInputChar(window, decodeUTF8(&c), mods, plain); + } #else - int i; - Status status; wchar_t buffer[16]; + wchar_t* chars = buffer; - const int count = XwcLookupString(window->x11.ic, - &event->xkey, - buffer, sizeof(buffer), - NULL, &status); + count = XwcLookupString(window->x11.ic, + &event->xkey, + buffer, sizeof(buffer) / sizeof(wchar_t), + NULL, &status); - for (i = 0; i < count; i++) - _glfwInputChar(window, buffer[i], mods, plain); + if (status == XBufferOverflow) + { + chars = calloc(count, sizeof(wchar_t)); + count = XwcLookupString(window->x11.ic, + &event->xkey, + chars, count, + NULL, &status); + } + + if (status == XLookupChars || status == XLookupBoth) + { + int i; + for (i = 0; i < count; i++) + _glfwInputChar(window, chars[i], mods, plain); + } #endif + + if (chars != buffer) + free(chars); } } else