diff --git a/docs/changelog.rst b/docs/changelog.rst index 3655a10b2..42d024107 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -72,6 +72,10 @@ Detailed list of changes - Linux: Load libfontconfig at runtime to allow the binaries to work for running kittens on servers without FontConfig +- GNOME: Fix for high CPU usage caused by GNOME's text input subsystem going + into an infinite loop when IME cursor position is updated after a done event + (:iss:`5105`) + 0.25.0 [2022-04-11] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/glfw/glfw3.h b/glfw/glfw3.h index 311490d47..d47561b1d 100644 --- a/glfw/glfw3.h +++ b/glfw/glfw3.h @@ -1216,7 +1216,8 @@ typedef enum { typedef enum { GLFW_IME_NONE, GLFW_IME_PREEDIT_CHANGED, - GLFW_IME_COMMIT_TEXT + GLFW_IME_COMMIT_TEXT, + GLFW_IME_WAYLAND_DONE_EVENT, } GLFWIMEState; typedef enum { diff --git a/glfw/wl_text_input.c b/glfw/wl_text_input.c index cc862c9ea..71208b66e 100644 --- a/glfw/wl_text_input.c +++ b/glfw/wl_text_input.c @@ -84,7 +84,7 @@ text_input_delete_surrounding_text( } static void -text_input_done(void *data UNUSED, struct zwp_text_input_v3 *txt_input UNUSED, uint32_t serial UNUSED) { +text_input_done(void *data UNUSED, struct zwp_text_input_v3 *txt_input UNUSED, uint32_t serial) { debug("text-input: done event: serial: %u current_commit_serial: %u\n", serial, commit_serial); if (serial != commit_serial) { _glfwInputError(GLFW_PLATFORM_ERROR, "Wayland: text_input_done serial mismatch, expected=%u got=%u\n", commit_serial, serial); @@ -95,7 +95,7 @@ text_input_done(void *data UNUSED, struct zwp_text_input_v3 *txt_input UNUSED, u free(pending_pre_edit); pending_pre_edit = NULL; } else { // Clear pre-edit text - send_text(NULL, GLFW_IME_PREEDIT_CHANGED); + send_text(NULL, GLFW_IME_WAYLAND_DONE_EVENT); } if (pending_commit) { send_text(pending_commit, GLFW_IME_COMMIT_TEXT); diff --git a/kitty/glfw-wrapper.h b/kitty/glfw-wrapper.h index 2230e8488..0c8901e75 100644 --- a/kitty/glfw-wrapper.h +++ b/kitty/glfw-wrapper.h @@ -954,7 +954,8 @@ typedef enum { typedef enum { GLFW_IME_NONE, GLFW_IME_PREEDIT_CHANGED, - GLFW_IME_COMMIT_TEXT + GLFW_IME_COMMIT_TEXT, + GLFW_IME_WAYLAND_DONE_EVENT, } GLFWIMEState; typedef enum { diff --git a/kitty/keys.c b/kitty/keys.c index 7c48fb3c3..26fa06cde 100644 --- a/kitty/keys.c +++ b/kitty/keys.c @@ -136,6 +136,12 @@ on_key_input(GLFWkeyevent *ev) { id_type active_window_id = w->id; switch(ev->ime_state) { + case GLFW_IME_WAYLAND_DONE_EVENT: + // If we update IME position here it sends GNOME's text input system into + // an infinite loop. See https://github.com/kovidgoyal/kitty/issues/5105 + screen_draw_overlay_text(screen, NULL); + debug("handled wayland IME done event"); + return; case GLFW_IME_PREEDIT_CHANGED: update_ime_position(w, screen); screen_draw_overlay_text(screen, text);