diff options
-rw-r--r-- | modules/input/imwayland.c | 51 |
1 files changed, 32 insertions, 19 deletions
diff --git a/modules/input/imwayland.c b/modules/input/imwayland.c index 1e93123aa2..facb9f2d31 100644 --- a/modules/input/imwayland.c +++ b/modules/input/imwayland.c @@ -116,6 +116,11 @@ static const GtkIMContextInfo *info_list[] = 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); + #define GTK_IM_CONTEXT_WAYLAND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), type_wayland, GtkIMContextWayland)) #ifndef INCLUDE_IM_wayland @@ -125,7 +130,8 @@ static void gtk_im_context_wayland_focus_out (GtkIMContext *context); #endif static void -notify_external_change (GtkIMContextWayland *context) +notify_im_change (GtkIMContextWayland *context, + enum zwp_text_input_v3_change_cause cause) { gboolean result; @@ -135,8 +141,12 @@ notify_external_change (GtkIMContextWayland *context) if (!context->enabled) 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 @@ -262,17 +272,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 @@ -289,8 +307,6 @@ notify_surrounding_text (GtkIMContextWayland *context) return; if (!context->enabled || !context->surrounding.text) return; - if (global->done_serial != global->serial) - return; len = strlen (context->surrounding.text); cursor = context->surrounding.cursor_idx; @@ -366,8 +382,6 @@ notify_cursor_location (GtkIMContextWayland *context) return; if (!context->enabled || !context->window) return; - if (global->done_serial != global->serial) - return; rect = context->cursor_rect; gdk_window_get_root_coords (context->window, rect.x, rect.y, @@ -450,8 +464,6 @@ notify_content_type (GtkIMContextWayland *context) if (!context->enabled) return; - if (global->done_serial != global->serial) - return; g_object_get (context, "input-hints", &hints, @@ -592,16 +604,13 @@ gtk_im_context_wayland_filter_keypress (GtkIMContext *context, static void enable (GtkIMContextWayland *context_wayland) { - gboolean result; /* Technically, text input isn't enabled until after the commit. * In reality, enable can't fail, and notify functions need to know * that they are free to send requests. */ context_wayland->enabled = TRUE; 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 @@ -611,6 +620,12 @@ disable (GtkIMContextWayland *context_wayland) commit_state (context_wayland); context_wayland->enabled = FALSE; + /* 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) { @@ -821,7 +836,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 (parent_class)->reset (context); } @@ -856,8 +872,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 @@ -893,7 +907,6 @@ gtk_im_context_wayland_set_surrounding (GtkIMContext *context, context_wayland->surrounding.anchor_idx = cursor_index; notify_surrounding_text (context_wayland); - commit_state (context_wayland); } static gboolean |