ishcherb / rpms / ibus

Forked from rpms/ibus 6 years ago
Clone
Blob Blame History Raw
From f453bf83f502d8b1e2b6f07cf669c14cbcfe008e Mon Sep 17 00:00:00 2001
From: Peng Huang <shawn.p.huang@gmail.com>
Date: Thu, 12 Jul 2012 16:41:30 -0400
Subject: [PATCH] IBusBus: honor new connect-async prop in the socket monitor
 callback

I think we should make use of the async connection here if the
property is set.

But we also need a new flag for ongoing async connection attempts
because the socket monitor callback may be called several times before
the connection is established.

BUG=http://code.google.com/p/ibus/issues/detail?id=1482
TEST=

Review URL: https://codereview.appspot.com/6346090
---
 src/ibusbus.c |  149 +++++++++++++++++++++++++++++++++++----------------------
 1 file changed, 93 insertions(+), 56 deletions(-)

diff --git a/src/ibusbus.c b/src/ibusbus.c
index fc3c11b..9118020 100644
--- a/src/ibusbus.c
+++ b/src/ibusbus.c
@@ -60,6 +60,8 @@ struct _IBusBusPrivate {
     IBusConfig *config;
     gchar *unique_name;
     gboolean connect_async;
+    gchar *bus_address;
+    GCancellable *cancellable;
 };
 
 static guint    bus_signals[LAST_SIGNAL] = { 0 };
@@ -103,6 +105,8 @@ static void      ibus_bus_get_property           (IBusBus                *bus,
                                                   GValue                 *value,
                                                   GParamSpec             *pspec);
 
+static void     ibus_bus_close_connection        (IBusBus                *bus);
+
 G_DEFINE_TYPE (IBusBus, ibus_bus, IBUS_TYPE_OBJECT)
 
 static void
@@ -270,56 +274,57 @@ _connection_closed_cb (GDBusConnection  *connection,
          * However we think the error message is almost harmless. */
         g_debug ("_connection_closed_cb: %s", error->message);
     }
+    ibus_bus_close_connection (bus);
+}
 
-    g_assert (bus->priv->connection == connection);
-    g_signal_handlers_disconnect_by_func (bus->priv->connection,
-                                          G_CALLBACK (_connection_closed_cb),
-                                          bus);
-    g_object_unref (bus->priv->connection);
-    bus->priv->connection = NULL;
-
+static void
+ibus_bus_close_connection (IBusBus *bus)
+{
     g_free (bus->priv->unique_name);
     bus->priv->unique_name = NULL;
 
     bus->priv->watch_dbus_signal_id = 0;
     bus->priv->watch_ibus_signal_id = 0;
 
-    g_signal_emit (bus, bus_signals[DISCONNECTED], 0);
-}
+    g_free (bus->priv->bus_address);
+    bus->priv->bus_address = NULL;
+
+    /* Cancel ongoing connect request. */
+    g_cancellable_cancel (bus->priv->cancellable);
+    g_cancellable_reset (bus->priv->cancellable);
 
-static void
-ibus_bus_disconnect (IBusBus *bus)
-{
     /* unref the old connection at first */
     if (bus->priv->connection != NULL) {
         g_signal_handlers_disconnect_by_func (bus->priv->connection,
                                               G_CALLBACK (_connection_closed_cb),
                                               bus);
+        if (!g_dbus_connection_is_closed(bus->priv->connection))
+            g_dbus_connection_close(bus->priv->connection, NULL, NULL, NULL);
         g_object_unref (bus->priv->connection);
         bus->priv->connection = NULL;
+        g_signal_emit (bus, bus_signals[DISCONNECTED], 0);
     }
 }
 
 static void
-ibus_bus_connect_finish (IBusBus *bus)
-{
-    if (bus->priv->connection) {
-        /* FIXME */
-        ibus_bus_hello (bus);
-
-        g_signal_connect (bus->priv->connection,
-                          "closed",
-                          (GCallback) _connection_closed_cb,
-                          bus);
-        if (bus->priv->watch_dbus_signal) {
-            ibus_bus_watch_dbus_signal (bus);
-        }
-        if (bus->priv->watch_ibus_signal) {
-            ibus_bus_watch_ibus_signal (bus);
-        }
-
-        g_signal_emit (bus, bus_signals[CONNECTED], 0);
+ibus_bus_connect_completed (IBusBus *bus)
+{
+    g_assert (bus->priv->connection);
+    /* FIXME */
+    ibus_bus_hello (bus);
+
+    g_signal_connect (bus->priv->connection,
+                      "closed",
+                      (GCallback) _connection_closed_cb,
+                      bus);
+    if (bus->priv->watch_dbus_signal) {
+        ibus_bus_watch_dbus_signal (bus);
+    }
+    if (bus->priv->watch_ibus_signal) {
+        ibus_bus_watch_ibus_signal (bus);
     }
+
+    g_signal_emit (bus, bus_signals[CONNECTED], 0);
 }
 
 static void
@@ -333,7 +338,8 @@ _bus_connect_async_cb (GObject      *source_object,
     IBusBus *bus   = IBUS_BUS (user_data);
     GError  *error = NULL;
 
-    bus->priv->connection = g_dbus_connection_new_for_address_finish (res, &error);
+    bus->priv->connection =
+                g_dbus_connection_new_for_address_finish (res, &error);
 
     if (error != NULL) {
         g_warning ("Unable to connect to ibus: %s", error->message);
@@ -341,8 +347,13 @@ _bus_connect_async_cb (GObject      *source_object,
         error = NULL;
     }
 
-    if (bus->priv->connection)
-        ibus_bus_connect_finish (bus);
+    if (bus->priv->connection != NULL) {
+        ibus_bus_connect_completed (bus);
+    }
+    else {
+        g_free (bus->priv->bus_address);
+        bus->priv->bus_address = NULL;
+    }
 
     /* unref the ref from ibus_bus_connect */
     g_object_unref (bus);
@@ -351,32 +362,52 @@ _bus_connect_async_cb (GObject      *source_object,
 static void
 ibus_bus_connect_async (IBusBus *bus)
 {
-    ibus_bus_disconnect (bus);
+    const gchar *bus_address = ibus_get_address ();
 
-    if (ibus_get_address () != NULL) {
-        g_object_ref (bus);
-        g_dbus_connection_new_for_address (ibus_get_address (),
-                                           G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT |
-                                           G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION,
-                                           NULL, NULL,
-                                           _bus_connect_async_cb, bus);
-    }
+    if (bus_address == NULL)
+        return;
+
+    if (g_strcmp0 (bus->priv->bus_address, bus_address) == 0)
+        return;
+
+    /* Close current connection and cancel ongoing connect request. */
+    ibus_bus_close_connection (bus);
+
+    bus->priv->bus_address = g_strdup (bus_address);
+    g_object_ref (bus);
+    g_dbus_connection_new_for_address (
+            bus_address,
+            G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT |
+            G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION,
+            NULL,
+            bus->priv->cancellable,
+            _bus_connect_async_cb, bus);
 }
 
 static void
 ibus_bus_connect (IBusBus *bus)
 {
-    ibus_bus_disconnect (bus);
+    const gchar *bus_address = ibus_get_address ();
 
-    if (ibus_get_address () != NULL) {
-        bus->priv->connection =
-            g_dbus_connection_new_for_address_sync (ibus_get_address (),
-                                                    G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT |
-                                                    G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION,
-                                                    NULL, NULL, NULL);
-    }
+    if (bus_address == NULL)
+        return;
 
-    ibus_bus_connect_finish (bus);
+    if (g_strcmp0 (bus_address, bus->priv->bus_address) == 0 &&
+        bus->priv->connection != NULL)
+        return;
+
+    /* Close current connection and cancel ongoing connect request. */
+    ibus_bus_close_connection (bus);
+
+    bus->priv->connection = g_dbus_connection_new_for_address_sync (
+            bus_address,
+            G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT |
+            G_DBUS_CONNECTION_FLAGS_MESSAGE_BUS_CONNECTION,
+            NULL, NULL, NULL);
+    if (bus->priv->connection) {
+        bus->priv->bus_address = g_strdup (bus_address);
+        ibus_bus_connect_completed (bus);
+    }
 }
 
 static void
@@ -391,10 +422,7 @@ _changed_cb (GFileMonitor       *monitor,
         event_type != G_FILE_MONITOR_EVENT_DELETED)
         return;
 
-    if (ibus_bus_is_connected (bus))
-        return;
-
-    ibus_bus_connect (bus);
+    ibus_bus_connect_async (bus);
 }
 
 static void
@@ -414,6 +442,8 @@ ibus_bus_init (IBusBus *bus)
     bus->priv->watch_ibus_signal_id = 0;
     bus->priv->unique_name = NULL;
     bus->priv->connect_async = FALSE;
+    bus->priv->bus_address = NULL;
+    bus->priv->cancellable = g_cancellable_new ();
 
     path = g_path_get_dirname (ibus_get_socket_path ());
 
@@ -523,6 +553,13 @@ ibus_bus_destroy (IBusObject *object)
     g_free (bus->priv->unique_name);
     bus->priv->unique_name = NULL;
 
+    g_free (bus->priv->bus_address);
+    bus->priv->bus_address = NULL;
+
+    g_cancellable_cancel (bus->priv->cancellable);
+    g_object_unref (bus->priv->cancellable);
+    bus->priv->cancellable = NULL;
+
     IBUS_OBJECT_CLASS (ibus_bus_parent_class)->destroy (object);
 }
 
@@ -1621,7 +1658,7 @@ ibus_bus_get_engines_by_names (IBusBus             *bus,
                                  G_VARIANT_TYPE ("(av)"));
     if (result == NULL)
         return NULL;
-    
+
     GArray *array = g_array_new (TRUE, TRUE, sizeof (IBusEngineDesc *));
     GVariantIter *iter = NULL;
     g_variant_get (result, "(av)", &iter);
-- 
1.7.10.4

From a454448111650c3e92fc9ba65c26a57adc9c3c6c Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
Date: Thu, 19 Jul 2012 09:57:01 +0900
Subject: [PATCH] Support dconf 0.13.4

TEST=Manually

Review URL: https://codereview.appspot.com/6426044
---
 conf/dconf/Makefile.am      |    2 +-
 conf/dconf/config-private.h |   56 +++++++++++++++++++++++++++++++++++++++++++
 conf/dconf/config.c         |   26 +++++++++++++++++++-
 conf/dconf/config.h         |   47 ------------------------------------
 conf/dconf/main.c           |    2 +-
 configure.ac                |    3 +++
 6 files changed, 86 insertions(+), 50 deletions(-)
 create mode 100644 conf/dconf/config-private.h
 delete mode 100644 conf/dconf/config.h

diff --git a/conf/dconf/Makefile.am b/conf/dconf/Makefile.am
index 148ba62..f0e24b0 100644
--- a/conf/dconf/Makefile.am
+++ b/conf/dconf/Makefile.am
@@ -29,7 +29,7 @@ libexec_PROGRAMS = \
 ibus_dconf_SOURCES = \
 	main.c \
 	config.c \
-	config.h \
+	config-private.h \
 	$(NULL)
 ibus_dconf_CFLAGS = \
 	@GLIB2_CFLAGS@ \
diff --git a/conf/dconf/config-private.h b/conf/dconf/config-private.h
new file mode 100644
index 0000000..9ba4fd5
--- /dev/null
+++ b/conf/dconf/config-private.h
@@ -0,0 +1,56 @@
+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
+ * Copyright (C) 2008-2010 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __CONFIG_DCONF_H__
+#define __CONFIG_DCONF_H__
+
+#ifdef HAVE_CONFIG_H
+#  include <config.h>
+#endif
+
+#include <ibus.h>
+#ifdef DCONF_0_13_4
+#  include <client/dconf-client.h>
+#  include <common/dconf-paths.h>
+#else
+#  include <dconf/dconf.h>
+#endif
+
+#define IBUS_TYPE_CONFIG_DCONF            \
+    (ibus_config_dconf_get_type ())
+#define IBUS_CONFIG_DCONF(obj)            \
+    (G_TYPE_CHECK_INSTANCE_CAST ((obj), IBUS_TYPE_CONFIG_DCONF, IBusConfigDConf))
+#define IBUS_CONFIG_DCONF_CLASS(klass)     \
+    (G_TYPE_CHECK_CLASS_CAST ((klass), IBUS_TYPE_CONFIG_DCONF, IBusConfigDConfClass))
+#define IBUS_IS_CONFIG_DCONF(obj)          \
+    (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IBUS_TYPE_CONFIG_DCONF))
+#define IBUS_IS_CONFIG_DCONF_CLASS(klass)  \
+    (G_TYPE_CHECK_CLASS_TYPE ((klass), IBUS_TYPE_CONFIG_DCONF))
+#define IBUS_CONFIG_DCONF_GET_CLASS(obj)   \
+    (G_TYPE_INSTANCE_GET_CLASS ((obj), IBUS_TYPE_CONFIG_DCONF, IBusConfigDConfClass))
+
+typedef struct _IBusConfigDConf IBusConfigDConf;
+typedef struct _IBusConfigDConfClass IBusConfigDConfClass;
+
+GType            ibus_config_dconf_get_type (void);
+IBusConfigDConf *ibus_config_dconf_new      (GDBusConnection *connection);
+
+#endif
diff --git a/conf/dconf/config.c b/conf/dconf/config.c
index faca932..44d7031 100644
--- a/conf/dconf/config.c
+++ b/conf/dconf/config.c
@@ -23,7 +23,7 @@
 
 #include <string.h>
 #include <ibus.h>
-#include "config.h"
+#include "config-private.h"
 
 #define DCONF_PREFIX "/desktop/ibus"
 #define DCONF_PRESERVE_NAME_PREFIXES_KEY \
@@ -159,12 +159,19 @@ static void
 _watch_func (DConfClient         *client,
              const gchar         *gpath,
              const gchar * const *items,
+#ifndef DCONF_0_13_4
              gint                 n_items,
+#endif
              const gchar         *tag,
              IBusConfigDConf     *config)
 {
     gchar **gkeys = NULL;
     gint i;
+#ifdef DCONF_0_13_4
+    gint n_items;
+
+    n_items = g_strv_length ((gchar **)items);
+#endif
 
     g_return_if_fail (gpath != NULL);
     g_return_if_fail (n_items >= 0);
@@ -231,6 +238,14 @@ static void
 ibus_config_dconf_init (IBusConfigDConf *config)
 {
     GVariant *variant;
+#ifdef DCONF_0_13_4
+    config->client = dconf_client_new ();
+
+    g_signal_connect (config->client, "changed",
+                      G_CALLBACK (_watch_func), config);
+
+    dconf_client_watch_fast (config->client, DCONF_PREFIX"/");
+#else
     GError *error;
 
     config->client = dconf_client_new ("ibus",
@@ -241,6 +256,7 @@ ibus_config_dconf_init (IBusConfigDConf *config)
     error = NULL;
     if (!dconf_client_watch (config->client, DCONF_PREFIX"/", NULL, &error))
         g_warning ("Can not watch dconf path %s", DCONF_PREFIX"/");
+#endif
 
     config->preserve_name_prefixes = NULL;
     variant = dconf_client_read (config->client,
@@ -265,9 +281,13 @@ static void
 ibus_config_dconf_destroy (IBusConfigDConf *config)
 {
     if (config->client) {
+#ifdef DCONF_0_13_4
+        dconf_client_unwatch_fast (config->client, DCONF_PREFIX"/");
+#else
         GError *error = NULL;
         if (!dconf_client_unwatch (config->client, DCONF_PREFIX"/", NULL, &error))
             g_warning ("Can not unwatch dconf path %s", DCONF_PREFIX"/");
+#endif
 
         g_object_unref (config->client);
         config->client = NULL;
@@ -307,12 +327,16 @@ ibus_config_dconf_set_value (IBusConfigService *config,
         g_free (gname);
     }
 
+#ifdef DCONF_0_13_4
+    retval = dconf_client_write_fast (client, gkey, value, error);
+#else
     retval = dconf_client_write (client,
                                  gkey,
                                  value,
                                  NULL,   /* tag */
                                  NULL,   /* cancellable */
                                  error);
+#endif
     g_free (gkey);
 
     return retval;
diff --git a/conf/dconf/config.h b/conf/dconf/config.h
deleted file mode 100644
index 9f602d6..0000000
--- a/conf/dconf/config.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
-/* vim:set et sts=4: */
-/* ibus - The Input Bus
- * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
- * Copyright (C) 2008-2010 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-#ifndef __CONFIG_DCONF_H__
-#define __CONFIG_DCONF_H__
-
-#include <ibus.h>
-#include <dconf/dconf.h>
-
-#define IBUS_TYPE_CONFIG_DCONF            \
-    (ibus_config_dconf_get_type ())
-#define IBUS_CONFIG_DCONF(obj)            \
-    (G_TYPE_CHECK_INSTANCE_CAST ((obj), IBUS_TYPE_CONFIG_DCONF, IBusConfigDConf))
-#define IBUS_CONFIG_DCONF_CLASS(klass)     \
-    (G_TYPE_CHECK_CLASS_CAST ((klass), IBUS_TYPE_CONFIG_DCONF, IBusConfigDConfClass))
-#define IBUS_IS_CONFIG_DCONF(obj)          \
-    (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IBUS_TYPE_CONFIG_DCONF))
-#define IBUS_IS_CONFIG_DCONF_CLASS(klass)  \
-    (G_TYPE_CHECK_CLASS_TYPE ((klass), IBUS_TYPE_CONFIG_DCONF))
-#define IBUS_CONFIG_DCONF_GET_CLASS(obj)   \
-    (G_TYPE_INSTANCE_GET_CLASS ((obj), IBUS_TYPE_CONFIG_DCONF, IBusConfigDConfClass))
-
-typedef struct _IBusConfigDConf IBusConfigDConf;
-typedef struct _IBusConfigDConfClass IBusConfigDConfClass;
-
-GType            ibus_config_dconf_get_type (void);
-IBusConfigDConf *ibus_config_dconf_new      (GDBusConnection *connection);
-
-#endif
diff --git a/conf/dconf/main.c b/conf/dconf/main.c
index 1b69baa..bffe983 100644
--- a/conf/dconf/main.c
+++ b/conf/dconf/main.c
@@ -23,7 +23,7 @@
 #include <ibus.h>
 #include <stdlib.h>
 #include <locale.h>
-#include "config.h"
+#include "config-private.h"
 
 static IBusBus *bus = NULL;
 static IBusConfigDConf *config = NULL;
diff --git a/configure.ac b/configure.ac
index 8498efe..cc7d0e0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -327,6 +327,9 @@ if test x"$enable_dconf" = x"yes"; then
         [dconf >= 0.7.5], ,
         enable_dconf=no
     )
+    PKG_CHECK_EXISTS([dconf >= 0.13.4],
+        [AC_DEFINE(DCONF_0_13_4, TRUE, [dconf is 0.13.4 or later])],
+        [])
     # check glib-compile-schemas
     GLIB_GSETTINGS
 fi
-- 
1.7.10.4

From 52fbf82dd1babc0d8de7be0f5bb6de622c069b4d Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
Date: Tue, 12 Jun 2012 11:53:29 +0900
Subject: [PATCH] Fix not to switch engines by non-trigger keys.

---
 ui/gtk3/switcher.vala |    6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/ui/gtk3/switcher.vala b/ui/gtk3/switcher.vala
index b543a8f..ea56c07 100644
--- a/ui/gtk3/switcher.vala
+++ b/ui/gtk3/switcher.vala
@@ -128,6 +128,7 @@ class Switcher : Gtk.Window {
                 state & KeybindingManager.MODIFIER_FILTER);
 
         update_engines(engines);
+        m_result = 0;
         m_selected_engine = index;
         m_label.set_text(m_buttons[index].longname);
         m_buttons[index].grab_focus();
@@ -343,6 +344,11 @@ class Switcher : Gtk.Window {
                     break;
                 default:
                     debug("0x%04x", pe->keyval);
+                    if (m_loop != null) {
+                        m_loop.quit();
+                        m_loop = null;
+                    }
+                    retval = false;
                     break;
             }
         } while (false);
-- 
1.7.10.4