From f67627875ffc723ca1a1e96e3677e387e3395659 Mon Sep 17 00:00:00 2001 From: Dorota Czaplejewicz Date: Tue, 16 Oct 2018 16:29:08 +0000 Subject: imwayland: Handle enter and leave events Before this patch, imwayland would assume that text-input enter and leave events follow the general (wl_keyboard) focus, and was unable to handle the situation where they would not be provided at the same time. --- gtk/gtkimcontextwayland.c | 85 +++++++++++++++++++++++++++++++---------------- 1 file changed, 57 insertions(+), 28 deletions(-) (limited to 'gtk/gtkimcontextwayland.c') diff --git a/gtk/gtkimcontextwayland.c b/gtk/gtkimcontextwayland.c index 891d948c8a..6e52c5f0c5 100644 --- a/gtk/gtkimcontextwayland.c +++ b/gtk/gtkimcontextwayland.c @@ -42,6 +42,10 @@ struct _GtkIMContextWaylandGlobal GtkIMContext *current; + /* The input-method.enter event may happen before or after GTK focus-in, + * so the context may not exist at the time. Same for leave and focus-out. */ + gboolean focused; + guint serial; }; @@ -100,6 +104,13 @@ static GtkIMContextWaylandGlobal *global = NULL; #define GTK_IM_CONTEXT_WAYLAND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), gtk_im_context_wayland_get_type (), GtkIMContextWayland)) + +static void +enable (GtkIMContextWayland *context_wayland); + +static void +disable (GtkIMContextWayland *context_wayland); + static void notify_external_change (GtkIMContextWayland *context) { @@ -116,13 +127,23 @@ static void text_input_enter (void *data, struct zwp_text_input_v3 *text_input, struct wl_surface *surface) -{} +{ + global->focused = TRUE; + + if (global->current) + enable (GTK_IM_CONTEXT_WAYLAND (global->current)); +} static void text_input_leave (void *data, struct zwp_text_input_v3 *text_input, struct wl_surface *surface) -{} +{ + global->focused = FALSE; + + if (global->current) + disable (GTK_IM_CONTEXT_WAYLAND (global->current)); +} static void text_input_preedit (void *data, @@ -455,12 +476,6 @@ commit_state (GtkIMContextWayland *context) context->surrounding_change = ZWP_TEXT_INPUT_V3_CHANGE_CAUSE_INPUT_METHOD; } -static void -enable_text_input (GtkIMContextWayland *context) -{ - zwp_text_input_v3_enable (global->text_input); -} - static void gtk_im_context_wayland_finalize (GObject *object) { @@ -498,14 +513,15 @@ released_cb (GtkGestureMultiPress *gesture, g_object_get (context, "input-hints", &hints, NULL); - if (n_press == 1 && + if (global->focused && + n_press == 1 && (hints & GTK_INPUT_HINT_INHIBIT_OSK) == 0 && !gtk_drag_check_threshold (context->widget, context->press_x, context->press_y, x, y)) { - enable_text_input (GTK_IM_CONTEXT_WAYLAND (context)); + zwp_text_input_v3_enable (global->text_input); g_signal_emit_by_name (global->current, "retrieve-surrounding", &result); commit_state (context); } @@ -604,18 +620,10 @@ gtk_im_context_wayland_filter_keypress (GtkIMContext *context, } static void -gtk_im_context_wayland_focus_in (GtkIMContext *context) +enable (GtkIMContextWayland *context_wayland) { - GtkIMContextWayland *context_wayland = GTK_IM_CONTEXT_WAYLAND (context); gboolean result; - - if (global->current == context) - return; - if (!global->text_input) - return; - - global->current = context; - enable_text_input (context_wayland); + 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); @@ -623,15 +631,8 @@ gtk_im_context_wayland_focus_in (GtkIMContext *context) } static void -gtk_im_context_wayland_focus_out (GtkIMContext *context) +disable (GtkIMContextWayland *context_wayland) { - GtkIMContextWayland *context_wayland; - - if (global->current != context) - return; - - context_wayland = GTK_IM_CONTEXT_WAYLAND (context); - zwp_text_input_v3_disable (global->text_input); commit_state (context_wayland); @@ -641,6 +642,34 @@ gtk_im_context_wayland_focus_out (GtkIMContext *context) text_input_preedit (global, global->text_input, NULL, 0, 0); text_input_preedit_apply (global); } +} + +static void +gtk_im_context_wayland_focus_in (GtkIMContext *context) +{ + GtkIMContextWayland *context_wayland = GTK_IM_CONTEXT_WAYLAND (context); + + if (global->current == context) + return; + if (!global->text_input) + return; + + global->current = context; + + if (global->focused) + enable (context_wayland); +} + +static void +gtk_im_context_wayland_focus_out (GtkIMContext *context) +{ + GtkIMContextWayland *context_wayland = GTK_IM_CONTEXT_WAYLAND (context); + + if (global->current != context) + return; + + if (global->focused) + disable (context_wayland); global->current = NULL; } -- cgit v1.2.1