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