[gtk/wip/carlosg/imwayland-serials2] imwayland: Delay state commits during .done
- From: Carlos Garnacho <carlosg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/carlosg/imwayland-serials2] imwayland: Delay state commits during .done
- Date: Wed, 17 Oct 2018 17:10:32 +0000 (UTC)
commit dadb885aab2499923de7085e13677cae7761c079
Author: Carlos Garnacho <carlosg gnome org>
Date: Wed Oct 17 18:53:19 2018 +0200
imwayland: Delay state commits during .done
Mutter/IBus may send multiple done events with the same serial
in a burst with certain IM modules. This is a hack to make gtk+
deal better with it.
Make the IM module coalesce .commit requests as the result of a
.done event, the actual .commit is deferred to an idle with
slightly lesser priority than the event source, so we make sure
that all .done events will be handled in a row.
Closes: https://gitlab.gnome.org/GNOME/gtk/issues/1365
modules/input/imwayland.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 45 insertions(+)
---
diff --git a/modules/input/imwayland.c b/modules/input/imwayland.c
index 05e8c0c3d7..d8b5a107ed 100644
--- a/modules/input/imwayland.c
+++ b/modules/input/imwayland.c
@@ -43,6 +43,9 @@ struct _GtkIMContextWaylandGlobal
GtkIMContext *current;
guint serial;
+ guint commit_idle_id;
+ guint in_done : 1;
+ guint need_state_commit : 1;
};
struct _GtkIMContextWaylandClass
@@ -116,6 +119,8 @@ static const GtkIMContextInfo *info_list[] =
#define MODULE_ENTRY(type, function) type _gtk_immodule_wayland_ ## function
#endif
+static void commit_state (GtkIMContextWayland *context);
+
static void
notify_external_change (GtkIMContextWayland *context)
{
@@ -255,6 +260,17 @@ text_input_delete_surrounding_text_apply (GtkIMContextWaylandGlobal *global,
context->pending_surrounding_delete = defaults;
}
+static gboolean
+commit_idle_cb (gpointer user_data)
+{
+ GtkIMContextWaylandGlobal *global = user_data;
+
+ commit_state (GTK_IM_CONTEXT_WAYLAND (global->current));
+ global->commit_idle_id = 0;
+
+ return G_SOURCE_REMOVE;
+}
+
static void
text_input_done (void *data,
struct zwp_text_input_v3 *text_input,
@@ -267,11 +283,20 @@ text_input_done (void *data,
if (!global->current)
return;
+ global->in_done = TRUE;
valid = serial == global->serial;
text_input_delete_surrounding_text_apply(global, valid);
text_input_commit_apply(global, valid);
g_signal_emit_by_name (global->current, "retrieve-surrounding", &result);
text_input_preedit_apply(global);
+ global->in_done = FALSE;
+
+ if (global->need_state_commit)
+ {
+ global->need_state_commit = FALSE;
+ global->commit_idle_id =
+ g_idle_add_full (GDK_PRIORITY_EVENTS + 1, commit_idle_cb, global, NULL);
+ }
}
static const struct zwp_text_input_v3_listener text_input_listener = {
@@ -461,6 +486,20 @@ commit_state (GtkIMContextWayland *context)
{
if (global->current != GTK_IM_CONTEXT (context))
return;
+ if (global->in_done)
+ {
+ if (!global->commit_idle_id)
+ global->need_state_commit = TRUE;
+ return;
+ }
+
+ if (global->commit_idle_id)
+ {
+ g_source_remove (global->commit_idle_id);
+ global->commit_idle_id = 0;
+ }
+
+ global->need_state_commit = FALSE;
global->serial++;
zwp_text_input_v3_commit (global->text_input);
context->surrounding_change = ZWP_TEXT_INPUT_V3_CHANGE_CAUSE_INPUT_METHOD;
@@ -680,6 +719,12 @@ gtk_im_context_wayland_set_cursor_location (GtkIMContext *context,
context_wayland = GTK_IM_CONTEXT_WAYLAND (context);
+ if (rect->x == context_wayland->cursor_rect.x &&
+ rect->y == context_wayland->cursor_rect.y &&
+ rect->width == context_wayland->cursor_rect.width &&
+ rect->height == context_wayland->cursor_rect.height)
+ return;
+
context_wayland->cursor_rect = *rect;
notify_cursor_location (context_wayland);
commit_state (context_wayland);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]