From eb79d649786473a629b27f61e1d16611223b23a9 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Sun, 31 May 2026 11:23:06 +0200 Subject: [PATCH 1/2] wayland: Only schedule a single cursor location update If the cursor is updated multiple times before the state is applied on the surface, the newer signal handled would overwrite the ID of the previous. We can coalesce these calls and keep just the last value with the already existing signal handler, add a check to make sure we don't add a second signal handler if there's one pending already. Fixes (harmless) warnings like: clutter_input_focus_set_cursor_location: assertion 'CLUTTER_IS_INPUT_FOCUS (focus)' failed When a second handler would stumble upon already cleared data. Easily reproducible when a VTE widget has the IM focus, but there may be other cases. Closes: https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/5096 --- src/wayland/meta-wayland-text-input.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/src/wayland/meta-wayland-text-input.c b/src/wayland/meta-wayland-text-input.c index ab635fda71d..a8fe13fa893 100644 --- a/src/wayland/meta-wayland-text-input.c +++ b/src/wayland/meta-wayland-text-input.c @@ -831,8 +831,11 @@ update_cursor_location (MetaWaylandSurface *surface, { MetaWaylandTextInput *text_input = user_data; - clutter_input_focus_set_cursor_location (text_input->cursor_update.focus, - &text_input->cursor_update.rect); + if (clutter_input_focus_is_focused (text_input->cursor_update.focus)) + { + clutter_input_focus_set_cursor_location (text_input->cursor_update.focus, + &text_input->cursor_update.rect); + } g_clear_object (&text_input->cursor_update.focus); graphene_rect_init (&text_input->cursor_update.rect, 0, 0, 0, 0); @@ -936,10 +939,13 @@ text_input_commit_state (struct wl_client *client, graphene_rect_init (&text_input->cursor_update.rect, x1, y1, x2 - x1, y2 - y1); - text_input->cursor_update.signal_id = - g_signal_connect (text_input->surface, "pre-state-applied", - G_CALLBACK (update_cursor_location), - text_input); + if (text_input->cursor_update.signal_id == 0) + { + text_input->cursor_update.signal_id = + g_signal_connect (text_input->surface, "pre-state-applied", + G_CALLBACK (update_cursor_location), + text_input); + } } if (text_input->pending_state & META_WAYLAND_PENDING_STATE_ACTIONS) -- GitLab From b7bb96ff6a1c515cc97c7ebc6b74375de6f52055 Mon Sep 17 00:00:00 2001 From: Carlos Garnacho Date: Mon, 1 Jun 2026 10:52:07 +0200 Subject: [PATCH 2/2] wayland: Drop semi-temporary variable When scheduling IM cursor rect updates, the ClutterInputFocus is kept around for the purpose of it being updated along with wl_surface updates. There's only one ClutterInputFocus though, from the MetaWaylandTextInput perspective, this intermediate variable can be dropped. --- src/wayland/meta-wayland-text-input.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/wayland/meta-wayland-text-input.c b/src/wayland/meta-wayland-text-input.c index a8fe13fa893..3f57354005b 100644 --- a/src/wayland/meta-wayland-text-input.c +++ b/src/wayland/meta-wayland-text-input.c @@ -623,8 +623,6 @@ text_input_destructor (struct wl_resource *resource) g_clear_pointer (&text_input->preedit_style.hints, g_array_unref); wl_list_remove (wl_resource_get_link (resource)); reset_text_input_focus (text_input); - - g_clear_object (&text_input->cursor_update.focus); } static void @@ -831,13 +829,12 @@ update_cursor_location (MetaWaylandSurface *surface, { MetaWaylandTextInput *text_input = user_data; - if (clutter_input_focus_is_focused (text_input->cursor_update.focus)) + if (clutter_input_focus_is_focused (text_input->input_focus)) { - clutter_input_focus_set_cursor_location (text_input->cursor_update.focus, + clutter_input_focus_set_cursor_location (text_input->input_focus, &text_input->cursor_update.rect); } - g_clear_object (&text_input->cursor_update.focus); graphene_rect_init (&text_input->cursor_update.rect, 0, 0, 0, 0); g_clear_signal_handler (&text_input->cursor_update.signal_id, surface); } @@ -935,7 +932,6 @@ text_input_commit_state (struct wl_client *client, rect.y + rect.height, &x2, &y2); - g_set_object (&text_input->cursor_update.focus, focus); graphene_rect_init (&text_input->cursor_update.rect, x1, y1, x2 - x1, y2 - y1); -- GitLab