diff --git a/gtk/gtkimcontextwayland.c b/gtk/gtkimcontextwayland.c index 069070509a..e4469b05aa 100644 --- a/gtk/gtkimcontextwayland.c +++ b/gtk/gtkimcontextwayland.c @@ -98,6 +98,11 @@ struct _GtkIMContextWayland static void gtk_im_context_wayland_focus_out (GtkIMContext *context); +static void commit_state (GtkIMContextWayland *context); +static void notify_surrounding_text (GtkIMContextWayland *context); +static void notify_cursor_location (GtkIMContextWayland *context); +static void notify_content_type (GtkIMContextWayland *context); + G_DEFINE_TYPE_WITH_CODE (GtkIMContextWayland, gtk_im_context_wayland, GTK_TYPE_IM_CONTEXT_SIMPLE, gtk_im_module_ensure_extension_point (); g_io_extension_point_implement (GTK_IM_MODULE_EXTENSION_POINT_NAME, @@ -128,7 +133,8 @@ gtk_im_context_wayland_get_global (GtkIMContextWayland *self) } static void -notify_external_change (GtkIMContextWayland *context) +notify_im_change (GtkIMContextWayland *context, + enum zwp_text_input_v3_change_cause cause) { GtkIMContextWaylandGlobal *global; gboolean result; @@ -137,9 +143,13 @@ notify_external_change (GtkIMContextWayland *context) if (global == NULL) return; - context->surrounding_change = ZWP_TEXT_INPUT_V3_CHANGE_CAUSE_OTHER; + context->surrounding_change = cause; g_signal_emit_by_name (global->current, "retrieve-surrounding", &result); + notify_surrounding_text (context); + notify_content_type (context); + notify_cursor_location (context); + commit_state (context); } static void @@ -265,17 +275,25 @@ text_input_done (void *data, uint32_t serial) { GtkIMContextWaylandGlobal *global = data; - gboolean result; + GtkIMContextWayland *context; + gboolean update_im; global->done_serial = serial; if (!global->current) return; + context = GTK_IM_CONTEXT_WAYLAND (global->current); + update_im = (context->pending_commit != NULL || + g_strcmp0 (context->pending_preedit.text, + context->current_preedit.text) != 0); + text_input_delete_surrounding_text_apply (global); text_input_commit_apply (global); - g_signal_emit_by_name (global->current, "retrieve-surrounding", &result); text_input_preedit_apply (global); + + if (update_im && global->serial == serial) + notify_im_change (context, ZWP_TEXT_INPUT_V3_CHANGE_CAUSE_INPUT_METHOD); } static void @@ -292,8 +310,6 @@ notify_surrounding_text (GtkIMContextWayland *context) global = gtk_im_context_wayland_get_global (context); if (global == NULL) return; - if (global->done_serial != global->serial) - return; len = strlen (context->surrounding.text); cursor = context->surrounding.cursor_idx; @@ -368,8 +384,6 @@ notify_cursor_location (GtkIMContextWayland *context) global = gtk_im_context_wayland_get_global (context); if (global == NULL) return; - if (global->done_serial != global->serial) - return; rect = context->cursor_rect; gtk_widget_translate_coordinates (context->widget, @@ -460,8 +474,6 @@ notify_content_type (GtkIMContextWayland *context) global = gtk_im_context_wayland_get_global (context); if (global == NULL) return; - if (global->done_serial != global->serial) - return; g_object_get (context, "input-hints", &hints, @@ -527,7 +539,6 @@ released_cb (GtkGestureClick *gesture, { GtkIMContextWaylandGlobal *global; GtkInputHints hints; - gboolean result; global = gtk_im_context_wayland_get_global (context); if (global == NULL) @@ -544,8 +555,8 @@ released_cb (GtkGestureClick *gesture, x, y)) { zwp_text_input_v3_enable (global->text_input); - g_signal_emit_by_name (global->current, "retrieve-surrounding", &result); - commit_state (context); + notify_im_change (GTK_IM_CONTEXT_WAYLAND (context), + ZWP_TEXT_INPUT_V3_CHANGE_CAUSE_OTHER); } } @@ -677,12 +688,9 @@ static void enable (GtkIMContextWayland *context_wayland, GtkIMContextWaylandGlobal *global) { - gboolean result; zwp_text_input_v3_enable (global->text_input); - g_signal_emit_by_name (global->current, "retrieve-surrounding", &result); - notify_content_type (context_wayland); - notify_cursor_location (context_wayland); - commit_state (context_wayland); + notify_im_change (context_wayland, + ZWP_TEXT_INPUT_V3_CHANGE_CAUSE_OTHER); } static void @@ -692,6 +700,12 @@ disable (GtkIMContextWayland *context_wayland, zwp_text_input_v3_disable (global->text_input); commit_state (context_wayland); + /* The commit above will still count in the .done event accounting, + * we should account for it, lest the serial gets out of sync after + * a future focus_in/enable. + */ + global->done_serial++; + /* after disable, incoming state changes won't take effect anyway */ if (context_wayland->current_preedit.text) { @@ -854,7 +868,8 @@ gtk_im_context_wayland_focus_out (GtkIMContext *context) static void gtk_im_context_wayland_reset (GtkIMContext *context) { - notify_external_change (GTK_IM_CONTEXT_WAYLAND (context)); + notify_im_change (GTK_IM_CONTEXT_WAYLAND (context), + ZWP_TEXT_INPUT_V3_CHANGE_CAUSE_OTHER); GTK_IM_CONTEXT_CLASS (gtk_im_context_wayland_parent_class)->reset (context); } @@ -889,8 +904,6 @@ gtk_im_context_wayland_set_cursor_location (GtkIMContext *context, gtk_event_controller_reset (GTK_EVENT_CONTROLLER (context_wayland->gesture)); context_wayland->cursor_rect = *rect; - notify_cursor_location (context_wayland); - commit_state (context_wayland); } static void @@ -924,9 +937,6 @@ gtk_im_context_wayland_set_surrounding (GtkIMContext *context, context_wayland->surrounding.text = g_strndup (text, len); context_wayland->surrounding.cursor_idx = cursor_index; context_wayland->surrounding.anchor_idx = selection_bound; - - notify_surrounding_text (context_wayland); - commit_state (context_wayland); } static gboolean