From a246f0ca905cd4115ce05537aca25af5b5e3138e Mon Sep 17 00:00:00 2001 From: Peng Wu Date: Fri, 27 Mar 2020 15:35:25 +0800 Subject: [PATCH 1/3] update wayland protocols --- modules/input/text-input-unstable-v3.xml | 28 +++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/modules/input/text-input-unstable-v3.xml b/modules/input/text-input-unstable-v3.xml index 8b710fd68b..f4ac913291 100644 --- a/modules/input/text-input-unstable-v3.xml +++ b/modules/input/text-input-unstable-v3.xml @@ -47,7 +47,7 @@ interface version number is reset. - + The zwp_text_input_v3 interface represents text input and input methods associated with a seat. It provides enter/leave events to follow the @@ -417,6 +417,32 @@ + + + + Pre-edit commit mode when the focus widget or the cursor position + is changed. + + + + + + + + Specify how the visible preedit should be handled + when switching the focus widget or changing the cursor position, + whether to commit the preedit text or clear the preedit text. + + This is usually used together with the preedit_string event. + + The commit behavior is the same for focus switch and + cursor position change. + + The parameter mode selects the desired behavior and + its value is one from the commit mode enum. + + + -- 2.29.2 From 225b1f53e0ce1f30d03c9c6bd49be50e453a939e Mon Sep 17 00:00:00 2001 From: Peng Wu Date: Sat, 9 May 2020 11:44:14 +0800 Subject: [PATCH 2/3] imwayland: Support ibus update_preedit_string_with_mode feature --- modules/input/imwayland.c | 95 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 92 insertions(+), 3 deletions(-) diff --git a/modules/input/imwayland.c b/modules/input/imwayland.c index 87c4ae806f..2525c16fe1 100644 --- a/modules/input/imwayland.c +++ b/modules/input/imwayland.c @@ -58,6 +58,7 @@ struct preedit { gchar *text; gint cursor_begin; gint cursor_end; + guint mode; }; struct surrounding_delete { @@ -123,6 +124,15 @@ static void gtk_im_context_wayland_focus_out (GtkIMContext *context); #define MODULE_ENTRY(type, function) type _gtk_immodule_wayland_ ## function #endif +static void +notify_surrounding_text (GtkIMContextWayland *context); +static void +commit_state (GtkIMContextWayland *context); +static void +clear_preedit_text (GtkIMContextWayland *context); +static void +gtk_im_context_wayland_reset (GtkIMContext *context); + static void notify_external_change (GtkIMContextWayland *context) { @@ -157,6 +167,23 @@ text_input_preedit (void *data, context->pending_preedit.text = g_strdup (text); context->pending_preedit.cursor_begin = cursor_begin; context->pending_preedit.cursor_end = cursor_end; + context->pending_preedit.mode = ZWP_TEXT_INPUT_V3_COMMIT_MODE_CLEAR; +} + +static void +text_input_preedit_commit_mode (void *data, + struct zwp_text_input_v3 *text_input, + guint mode) +{ + GtkIMContextWayland *context; + GtkIMContextWaylandGlobal *global = data; + + if (!global->current) + return; + + context = GTK_IM_CONTEXT_WAYLAND (global->current); + + context->pending_preedit.mode = mode; } static void @@ -272,6 +299,35 @@ text_input_done (void *data, text_input_preedit_apply(global); } +static void +clear_preedit_text (GtkIMContextWayland *context) +{ + gchar *preedit_string = NULL; + + if (!global || !global->text_input) + return; + if (global->current != GTK_IM_CONTEXT (context)) + return; + + if (context->current_preedit.text && + context->current_preedit.mode == ZWP_TEXT_INPUT_V3_COMMIT_MODE_COMMIT) + { + preedit_string = g_strdup (context->current_preedit.text); + } + + text_input_preedit (global, global->text_input, NULL, 0, 0); + text_input_preedit_apply (global); + + if (preedit_string) + { + text_input_commit (global, global->text_input, preedit_string); + text_input_commit_apply (global, TRUE); + g_free (preedit_string); + notify_surrounding_text (context); + commit_state (context); + } +} + static void notify_surrounding_text (GtkIMContextWayland *context) { @@ -543,6 +599,16 @@ gtk_im_context_wayland_filter_keypress (GtkIMContext *context, return GTK_IM_CONTEXT_CLASS (parent_class)->filter_keypress (context, key); } +static void +notify_reset (GtkIMContextWayland *context_wayland) +{ + if (global->current != GTK_IM_CONTEXT (context_wayland)) + return; + + zwp_text_input_v3_disable (global->text_input); + zwp_text_input_v3_enable (global->text_input); +} + static void enable (GtkIMContextWayland *context_wayland) { @@ -569,11 +635,11 @@ disable (GtkIMContextWayland *context_wayland) if (context_wayland->current_preedit.text) { text_input_preedit (global, global->text_input, NULL, 0, 0); + text_input_preedit_commit_mode (global, global->text_input, ZWP_TEXT_INPUT_V3_COMMIT_MODE_CLEAR); text_input_preedit_apply (global); } } - static void pressed_cb (GtkGestureMultiPress *gesture, gint n_press, @@ -585,6 +651,13 @@ pressed_cb (GtkGestureMultiPress *gesture, { context->press_x = x; context->press_y = y; + + /* clear the preedit text before the client commit. */ + if (global->current == GTK_IM_CONTEXT (context)) + { + clear_preedit_text (context); + gtk_im_context_wayland_reset (GTK_IM_CONTEXT (context)); + } } } @@ -671,7 +744,12 @@ text_input_leave (void *data, global->focused = FALSE; if (global->current) - disable (GTK_IM_CONTEXT_WAYLAND (global->current)); + { + GtkIMContextWayland *context_wayland = GTK_IM_CONTEXT_WAYLAND (global->current); + + clear_preedit_text (context_wayland); + disable (context_wayland); + } } @@ -682,6 +760,7 @@ static const struct zwp_text_input_v3_listener text_input_listener = { text_input_commit, text_input_delete_surrounding_text, text_input_done, + text_input_preedit_commit_mode, }; static void @@ -767,7 +846,10 @@ gtk_im_context_wayland_focus_out (GtkIMContext *context) return; if (global->focused) - disable (context_wayland); + { + clear_preedit_text (context_wayland); + disable (context_wayland); + } global->current = NULL; } @@ -775,6 +857,13 @@ gtk_im_context_wayland_focus_out (GtkIMContext *context) static void gtk_im_context_wayland_reset (GtkIMContext *context) { + GtkIMContextWayland *context_wayland; + + context_wayland = GTK_IM_CONTEXT_WAYLAND (context); + + notify_reset (context_wayland); + commit_state (context_wayland); + notify_external_change (GTK_IM_CONTEXT_WAYLAND (context)); GTK_IM_CONTEXT_CLASS (parent_class)->reset (context); -- 2.29.2 From 8fe3a41073af544921ae20d97284f77304bb15b4 Mon Sep 17 00:00:00 2001 From: Peng Wu Date: Tue, 23 Feb 2021 17:39:34 +0800 Subject: [PATCH 3/3] imwayland: check protocol version --- modules/input/imwayland.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modules/input/imwayland.c b/modules/input/imwayland.c index 2525c16fe1..80013202f5 100644 --- a/modules/input/imwayland.c +++ b/modules/input/imwayland.c @@ -768,17 +768,19 @@ registry_handle_global (void *data, struct wl_registry *registry, uint32_t id, const char *interface, - uint32_t version) + uint32_t server_version) { GtkIMContextWaylandGlobal *global = data; GdkSeat *seat = gdk_display_get_default_seat (gdk_display_get_default ()); if (strcmp (interface, "zwp_text_input_manager_v3") == 0) { + const uint32_t client_version = 2; + uint32_t bind_version = MIN(client_version, server_version); global->text_input_manager_wl_id = id; global->text_input_manager = wl_registry_bind (global->registry, global->text_input_manager_wl_id, - &zwp_text_input_manager_v3_interface, 1); + &zwp_text_input_manager_v3_interface, bind_version); global->text_input = zwp_text_input_manager_v3_get_text_input (global->text_input_manager, gdk_wayland_seat_get_wl_seat (seat)); -- 2.29.2