wayland: Flush text_input.done event after IM key event

We set an idle to coalesce multiple IM events together, as the protocol
requires us to send them in one frame, and unfortunately there is no
idea about whether more IM events are upcoming.

One good hint though are key events generated from the IM, we want to
apply all IM changes before the key event is processed, so make it sure
that the .done event is flushed before the key event is handled.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1286
This commit is contained in:
Carlos Garnacho 2020-07-06 12:13:58 +02:00
parent 98c1a469ad
commit 35680ee7c6

View File

@ -118,10 +118,9 @@ increment_serial (MetaWaylandTextInput *text_input,
GUINT_TO_POINTER (serial + 1));
}
static gboolean
done_idle_cb (gpointer user_data)
static void
clutter_input_focus_send_done (ClutterInputFocus *focus)
{
ClutterInputFocus *focus = user_data;
MetaWaylandTextInput *text_input;
struct wl_resource *resource;
@ -132,6 +131,16 @@ done_idle_cb (gpointer user_data)
zwp_text_input_v3_send_done (resource,
lookup_serial (text_input, resource));
}
}
static gboolean
done_idle_cb (gpointer user_data)
{
ClutterInputFocus *focus = user_data;
MetaWaylandTextInput *text_input;
text_input = META_WAYLAND_TEXT_INPUT_FOCUS (focus)->text_input;
clutter_input_focus_send_done (focus);
text_input->done_idle_id = 0;
return G_SOURCE_REMOVE;
@ -164,6 +173,20 @@ meta_wayland_text_input_focus_defer_done (ClutterInputFocus *focus)
done_idle_cb, focus, NULL);
}
static void
meta_wayland_text_input_focus_flush_done (ClutterInputFocus *focus)
{
MetaWaylandTextInput *text_input;
text_input = META_WAYLAND_TEXT_INPUT_FOCUS (focus)->text_input;
if (text_input->done_idle_id == 0)
return;
g_clear_handle_id (&text_input->done_idle_id, g_source_remove);
clutter_input_focus_send_done (focus);
}
static void
meta_wayland_text_input_focus_delete_surrounding (ClutterInputFocus *focus,
int offset,
@ -737,5 +760,10 @@ meta_wayland_text_input_handle_event (MetaWaylandTextInput *text_input,
!clutter_input_focus_is_focused (text_input->input_focus))
return FALSE;
if ((event->type == CLUTTER_KEY_PRESS ||
event->type == CLUTTER_KEY_RELEASE) &&
clutter_event_get_flags (event) & CLUTTER_EVENT_FLAG_INPUT_METHOD)
meta_wayland_text_input_focus_flush_done (text_input->input_focus);
return clutter_input_focus_filter_event (text_input->input_focus, event);
}