ishcherb / rpms / ibus

Forked from rpms/ibus 6 years ago
Clone
ecac051
From 8ac534fc002356b93e2015a8866f1ea89e3895f9 Mon Sep 17 00:00:00 2001
28f7f62
From: fujiwarat <takao.fujiwara1@gmail.com>
ecac051
Date: Sat, 15 Dec 2012 17:40:18 +0900
ecac051
Subject: [PATCH] Use Variant.unpack() instead of Variant.dup_strv().
28f7f62
ecac051
Variant.dup_strv() returns a tuple in pygobject 3.2, e.g. (['<Control>space'], 1L), and a list in pygobject 3.4, e.g. ['<Control>space'] .
ecac051
ecac051
BUG=RH#887153
ecac051
ecac051
Review URL: https://codereview.appspot.com/6941051
28f7f62
---
ecac051
 setup/main.py | 2 +-
ecac051
 1 file changed, 1 insertion(+), 1 deletion(-)
28f7f62
ecac051
diff --git a/setup/main.py b/setup/main.py
ecac051
index a8acc7a..707faa4 100644
ecac051
--- a/setup/main.py
ecac051
+++ b/setup/main.py
ecac051
@@ -87,7 +87,7 @@ class Setup(object):
ecac051
         label = 'switch_engine'
ecac051
         variant = self.__config.get_value('general/hotkey', name)
ecac051
         if variant != None:
ecac051
-            shortcuts = variant.dup_strv()
ecac051
+            shortcuts = variant.unpack()
ecac051
         else:
ecac051
             shortcuts =  ['<Control>space']
ecac051
 
28f7f62
-- 
ecac051
1.7.12.1
e429e12
ecac051
From 62cd0492e3459416e1775aedc327bced53f66828 Mon Sep 17 00:00:00 2001
ecac051
From: Rui Matos <tiagomatos@gmail.com>
ecac051
Date: Wed, 9 Jan 2013 10:14:55 -0500
ecac051
Subject: [PATCH] client: Queue events while the IBus context isn't ready
ecac051
ecac051
There are actually 3 patches here.
ecac051
ecac051
---
ecac051
client: Queue events while the IBus context isn't ready
ecac051
ecac051
We may lose events that ought to be processed while the IBus context
ecac051
isn't ready or if the connection to IBus isn't fully established yet.
ecac051
ecac051
To avoid that, enqueue events to be processed later when the IBus
ecac051
context creation finishes.
ecac051
ecac051
---
ecac051
client: Don't cancel an ongoing create input context on another request
ecac051
ecac051
This would only add more delays.
ecac051
ecac051
---
ecac051
client: Cancel any ongoing create input context request on finalize
ecac051
ecac051
BUG=
81afe7c
ecac051
Review URL: https://codereview.appspot.com/6988047
ecac051
Patch from Rui Matos <tiagomatos@gmail.com>.
81afe7c
---
ecac051
 client/gtk2/ibusimcontext.c | 220 ++++++++++++++++++++++++++------------------
ecac051
 1 file changed, 133 insertions(+), 87 deletions(-)
81afe7c
ecac051
diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c
ecac051
index 011676f..94005b7 100644
ecac051
--- a/client/gtk2/ibusimcontext.c
ecac051
+++ b/client/gtk2/ibusimcontext.c
ecac051
@@ -40,6 +40,8 @@
ecac051
 #  define IDEBUG(a...)
ecac051
 #endif
ecac051
 
ecac051
+#define MAX_QUEUED_EVENTS 20
ecac051
+
ecac051
 struct _IBusIMContext {
ecac051
     GtkIMContext parent;
ecac051
 
ecac051
@@ -63,6 +65,7 @@ struct _IBusIMContext {
ecac051
 
ecac051
     /* cancellable */
ecac051
     GCancellable    *cancellable;
ecac051
+    GQueue          *events_queue;
ecac051
 };
ecac051
 
ecac051
 struct _IBusIMContextClass {
ecac051
@@ -154,6 +157,8 @@ static GType                _ibus_type_im_context = 0;
ecac051
 static GtkIMContextClass    *parent_class = NULL;
ecac051
 
ecac051
 static IBusBus              *_bus = NULL;
ecac051
+static guint                _daemon_name_watch_id = 0;
ecac051
+static gboolean             _daemon_is_running = FALSE;
ecac051
 
ecac051
 void
ecac051
 ibus_im_context_register_type (GTypeModule *type_module)
ecac051
@@ -261,6 +266,46 @@ _process_key_event_done (GObject      *object,
ecac051
     gdk_event_free ((GdkEvent *)event);
ecac051
 }
ecac051
 
ecac051
+static gboolean
ecac051
+_process_key_event (IBusInputContext *context,
ecac051
+                    GdkEventKey      *event)
ecac051
+{
ecac051
+    guint state = event->state;
ecac051
+    gboolean retval = FALSE;
ecac051
+
ecac051
+    if (event->type == GDK_KEY_RELEASE) {
ecac051
+        state |= IBUS_RELEASE_MASK;
ecac051
+    }
ecac051
+
ecac051
+    if (_use_sync_mode) {
ecac051
+        retval = ibus_input_context_process_key_event (context,
ecac051
+            event->keyval,
ecac051
+            event->hardware_keycode - 8,
ecac051
+            state);
ecac051
+    }
ecac051
+    else {
ecac051
+        ibus_input_context_process_key_event_async (context,
ecac051
+            event->keyval,
ecac051
+            event->hardware_keycode - 8,
ecac051
+            state,
ecac051
+            -1,
ecac051
+            NULL,
ecac051
+            _process_key_event_done,
ecac051
+            gdk_event_copy ((GdkEvent *) event));
ecac051
+
ecac051
+        retval = TRUE;
ecac051
+    }
ecac051
+
ecac051
+    if (retval) {
ecac051
+        event->state |= IBUS_HANDLED_MASK;
ecac051
+    }
ecac051
+    else {
ecac051
+        event->state |= IBUS_IGNORED_MASK;
ecac051
+    }
ecac051
+
ecac051
+    return retval;
ecac051
+}
ecac051
+
ecac051
 
ecac051
 /* emit "retrieve-surrounding" glib signal of GtkIMContext, if
ecac051
  * context->caps has IBUS_CAP_SURROUNDING_TEXT and the current IBus
ecac051
@@ -387,38 +432,7 @@ _key_snooper_cb (GtkWidget   *widget,
ecac051
         ibusimcontext->time = event->time;
ecac051
     }
ecac051
 
ecac051
-    guint state = event->state;
ecac051
-    if (event->type == GDK_KEY_RELEASE) {
ecac051
-        state |= IBUS_RELEASE_MASK;
ecac051
-    }
ecac051
-
ecac051
-    if (_use_sync_mode) {
ecac051
-        retval = ibus_input_context_process_key_event (
ecac051
-                                        ibuscontext,
ecac051
-                                        event->keyval,
ecac051
-                                        event->hardware_keycode - 8,
ecac051
-                                        state);
ecac051
-    }
ecac051
-    else {
ecac051
-        ibus_input_context_process_key_event_async (
ecac051
-                                        ibuscontext,
ecac051
-                                        event->keyval,
ecac051
-                                        event->hardware_keycode - 8,
ecac051
-                                        state,
ecac051
-                                        -1,
ecac051
-                                        NULL,
ecac051
-                                        _process_key_event_done,
ecac051
-                                        gdk_event_copy ((GdkEvent *) event));
ecac051
-        retval = TRUE;
ecac051
-
ecac051
-    }
ecac051
-
ecac051
-    if (retval) {
ecac051
-        event->state |= IBUS_HANDLED_MASK;
ecac051
-    }
ecac051
-    else {
ecac051
-        event->state |= IBUS_IGNORED_MASK;
ecac051
-    }
ecac051
+    retval = _process_key_event (ibuscontext, event);
ecac051
 
ecac051
     if (ibusimcontext != NULL) {
ecac051
         /* unref ibusimcontext could call ibus_im_context_finalize here
ecac051
@@ -450,6 +464,23 @@ _get_boolean_env(const gchar *name,
ecac051
 }
ecac051
 
ecac051
 static void
ecac051
+daemon_name_appeared (GDBusConnection *connection,
ecac051
+                      const gchar     *name,
ecac051
+                      const gchar     *owner,
ecac051
+                      gpointer         data)
ecac051
+{
ecac051
+    _daemon_is_running = TRUE;
ecac051
+}
ecac051
+
ecac051
+static void
ecac051
+daemon_name_vanished (GDBusConnection *connection,
ecac051
+                      const gchar     *name,
ecac051
+                      gpointer         data)
ecac051
+{
ecac051
+    _daemon_is_running = FALSE;
ecac051
+}
ecac051
+
ecac051
+static void
ecac051
 ibus_im_context_class_init (IBusIMContextClass *class)
ecac051
 {
ecac051
     IDEBUG ("%s", __FUNCTION__);
ecac051
@@ -533,6 +564,14 @@ ibus_im_context_class_init (IBusIMContextClass *class)
ecac051
     /* always install snooper */
ecac051
     if (_key_snooper_id == 0)
ecac051
         _key_snooper_id = gtk_key_snooper_install (_key_snooper_cb, NULL);
ecac051
+
ecac051
+    _daemon_name_watch_id = g_bus_watch_name (G_BUS_TYPE_SESSION,
ecac051
+                                              IBUS_SERVICE_IBUS,
ecac051
+                                              G_BUS_NAME_WATCHER_FLAGS_NONE,
ecac051
+                                              daemon_name_appeared,
ecac051
+                                              daemon_name_vanished,
ecac051
+                                              NULL,
ecac051
+                                              NULL);
ecac051
 }
ecac051
 
ecac051
 static void
ecac051
@@ -543,6 +582,8 @@ ibus_im_context_class_fini (IBusIMContextClass *class)
ecac051
         gtk_key_snooper_remove (_key_snooper_id);
ecac051
         _key_snooper_id = 0;
ecac051
     }
ecac051
+
ecac051
+    g_bus_unwatch_name (_daemon_name_watch_id);
ecac051
 }
ecac051
 
ecac051
 /* Copied from gtk+2.0-2.20.1/modules/input/imcedilla.c to fix crosbug.com/11421.
ecac051
@@ -602,6 +643,7 @@ ibus_im_context_init (GObject *obj)
ecac051
     ibusimcontext->caps = IBUS_CAP_PREEDIT_TEXT | IBUS_CAP_FOCUS;
ecac051
 #endif
ecac051
 
ecac051
+    ibusimcontext->events_queue = g_queue_new ();
ecac051
 
ecac051
     // Create slave im context
ecac051
     ibusimcontext->slave = gtk_im_context_simple_new ();
ecac051
@@ -651,6 +693,13 @@ ibus_im_context_finalize (GObject *obj)
ecac051
 
ecac051
     g_signal_handlers_disconnect_by_func (_bus, G_CALLBACK (_bus_connected_cb), obj);
ecac051
 
ecac051
+    if (ibusimcontext->cancellable != NULL) {
ecac051
+        /* Cancel any ongoing create input context request */
ecac051
+        g_cancellable_cancel (ibusimcontext->cancellable);
ecac051
+        g_object_unref (ibusimcontext->cancellable);
ecac051
+        ibusimcontext->cancellable = NULL;
ecac051
+    }
ecac051
+
ecac051
     if (ibusimcontext->ibuscontext) {
ecac051
         ibus_proxy_destroy ((IBusProxy *)ibusimcontext->ibuscontext);
ecac051
     }
ecac051
@@ -670,6 +719,9 @@ ibus_im_context_finalize (GObject *obj)
ecac051
         pango_attr_list_unref (ibusimcontext->preedit_attrs);
ecac051
     }
ecac051
 
ecac051
+    g_queue_free_full (ibusimcontext->events_queue,
ecac051
+                       (GDestroyNotify)gdk_event_free);
ecac051
+
ecac051
     G_OBJECT_CLASS(parent_class)->finalize (obj);
ecac051
 }
ecac051
 
ecac051
@@ -681,65 +733,56 @@ ibus_im_context_filter_keypress (GtkIMContext *context,
ecac051
 
ecac051
     IBusIMContext *ibusimcontext = IBUS_IM_CONTEXT (context);
ecac051
 
ecac051
-    if (G_LIKELY (ibusimcontext->ibuscontext && ibusimcontext->has_focus)) {
ecac051
-        /* If context does not have focus, ibus will process key event in sync mode.
ecac051
-         * It is a workaround for increase search in treeview.
ecac051
-         */
ecac051
-        gboolean retval = FALSE;
ecac051
-
ecac051
-        if (event->state & IBUS_HANDLED_MASK)
ecac051
-            return TRUE;
ecac051
+    if (!_daemon_is_running)
ecac051
+        return gtk_im_context_filter_keypress (ibusimcontext->slave, event);
ecac051
 
ecac051
-        if (event->state & IBUS_IGNORED_MASK)
ecac051
-            return gtk_im_context_filter_keypress (ibusimcontext->slave, event);
ecac051
+    /* If context does not have focus, ibus will process key event in
ecac051
+     * sync mode.  It is a workaround for increase search in treeview.
ecac051
+     */
ecac051
+    if (!ibusimcontext->has_focus)
ecac051
+        return gtk_im_context_filter_keypress (ibusimcontext->slave, event);
ecac051
 
ecac051
-        /* XXX it is a workaround for some applications do not set client window. */
ecac051
-        if (ibusimcontext->client_window == NULL && event->window != NULL)
ecac051
-            gtk_im_context_set_client_window ((GtkIMContext *)ibusimcontext, event->window);
ecac051
+    if (event->state & IBUS_HANDLED_MASK)
ecac051
+        return TRUE;
ecac051
 
ecac051
-        _request_surrounding_text (ibusimcontext);
ecac051
+    if (event->state & IBUS_IGNORED_MASK)
ecac051
+        return gtk_im_context_filter_keypress (ibusimcontext->slave, event);
ecac051
 
ecac051
-        if (ibusimcontext != NULL) {
ecac051
-            ibusimcontext->time = event->time;
ecac051
-        }
ecac051
+    /* XXX it is a workaround for some applications do not set client
ecac051
+     * window. */
ecac051
+    if (ibusimcontext->client_window == NULL && event->window != NULL)
ecac051
+        gtk_im_context_set_client_window ((GtkIMContext *)ibusimcontext,
ecac051
+                                          event->window);
ecac051
 
ecac051
-        guint state = event->state;
ecac051
-        if (event->type == GDK_KEY_RELEASE) {
ecac051
-            state |= IBUS_RELEASE_MASK;
ecac051
-        }
ecac051
+    _request_surrounding_text (ibusimcontext);
ecac051
 
ecac051
-        if (_use_sync_mode) {
ecac051
-            retval = ibus_input_context_process_key_event (
ecac051
-                                        ibusimcontext->ibuscontext,
ecac051
-                                        event->keyval,
ecac051
-                                        event->hardware_keycode - 8,
ecac051
-                                        state);
ecac051
-        }
ecac051
-        else {
ecac051
-            ibus_input_context_process_key_event_async (
ecac051
-                                        ibusimcontext->ibuscontext,
ecac051
-                                        event->keyval,
ecac051
-                                        event->hardware_keycode - 8,
ecac051
-                                        state,
ecac051
-                                        -1,
ecac051
-                                        NULL,
ecac051
-                                        _process_key_event_done,
ecac051
-                                        gdk_event_copy ((GdkEvent *) event));
ecac051
-            retval = TRUE;
ecac051
-        }
ecac051
+    ibusimcontext->time = event->time;
ecac051
 
ecac051
-        if (retval) {
ecac051
-            event->state |= IBUS_HANDLED_MASK;
ecac051
+    if (ibusimcontext->ibuscontext) {
ecac051
+        if (_process_key_event (ibusimcontext->ibuscontext, event))
ecac051
             return TRUE;
ecac051
-        }
ecac051
-        else {
ecac051
-            event->state |= IBUS_IGNORED_MASK;
ecac051
-            return gtk_im_context_filter_keypress (ibusimcontext->slave, event);
ecac051
-        }
ecac051
+        else
ecac051
+            return gtk_im_context_filter_keypress (ibusimcontext->slave,
ecac051
+                                                   event);
ecac051
     }
ecac051
-    else {
ecac051
-        return gtk_im_context_filter_keypress (ibusimcontext->slave, event);
ecac051
+
ecac051
+    /* At this point we _should_ be waiting for the IBus context to be
ecac051
+     * created or the connection to IBus to be established. If that's
ecac051
+     * the case we queue events to be processed when the IBus context
ecac051
+     * is ready. */
ecac051
+    g_return_val_if_fail (ibusimcontext->cancellable != NULL ||
ecac051
+                          ibus_bus_is_connected (_bus) == FALSE,
ecac051
+                          FALSE);
ecac051
+    g_queue_push_tail (ibusimcontext->events_queue,
ecac051
+                       gdk_event_copy ((GdkEvent *)event));
ecac051
+
ecac051
+    if (g_queue_get_length (ibusimcontext->events_queue) > MAX_QUEUED_EVENTS) {
ecac051
+        g_warning ("Events queue growing too big, will start to drop.");
ecac051
+        gdk_event_free ((GdkEvent *)
ecac051
+                        g_queue_pop_head (ibusimcontext->events_queue));
ecac051
     }
ecac051
+
ecac051
+    return TRUE;
ecac051
 }
ecac051
 
ecac051
 static void
ecac051
@@ -1482,6 +1525,14 @@ _create_input_context_done (IBusBus       *bus,
ecac051
             ibus_input_context_focus_in (ibusimcontext->ibuscontext);
ecac051
             _set_cursor_location_internal (ibusimcontext);
ecac051
         }
ecac051
+
ecac051
+        if (!g_queue_is_empty (ibusimcontext->events_queue)) {
ecac051
+            GdkEventKey *event;
ecac051
+            while (event = g_queue_pop_head (ibusimcontext->events_queue)) {
ecac051
+                _process_key_event (context, event);
ecac051
+                gdk_event_free ((GdkEvent *)event);
ecac051
+            }
ecac051
+        }
ecac051
     }
ecac051
 
ecac051
     g_object_unref (ibusimcontext);
ecac051
@@ -1494,12 +1545,7 @@ _create_input_context (IBusIMContext *ibusimcontext)
ecac051
 
ecac051
     g_assert (ibusimcontext->ibuscontext == NULL);
ecac051
 
ecac051
-    if (ibusimcontext->cancellable != NULL) {
ecac051
-        /* Cancel previous create input context request */
ecac051
-        g_cancellable_cancel (ibusimcontext->cancellable);
ecac051
-        g_object_unref (ibusimcontext->cancellable);
ecac051
-        ibusimcontext->cancellable = NULL;
ecac051
-    }
ecac051
+    g_return_if_fail (ibusimcontext->cancellable == NULL);
ecac051
 
ecac051
     ibusimcontext->cancellable = g_cancellable_new ();
ecac051
 
81afe7c
-- 
81afe7c
1.8.0
81afe7c