From: Huang Peng Date: Fri, 6 Feb 2009 06:54:00 +0000 (+0800) Subject: Add restart menu item in system menu. X-Git-Tag: 1.1.0.20090211~12 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=7818373100d18f04dc049a466f9f30bb32965176;p=platform%2Fupstream%2Fibus.git Add restart menu item in system menu. --- diff --git a/bus/dbusimpl.c b/bus/dbusimpl.c index 6a70f89..f8b8566 100644 --- a/bus/dbusimpl.c +++ b/bus/dbusimpl.c @@ -25,9 +25,6 @@ #include "connection.h" #include "matchrule.h" -#define BUS_DBUS_IMPL_GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), BUS_TYPE_DBUS_IMPL, BusDBusImplPrivate)) - enum { NAME_ACQUIRED, NAME_LOST, @@ -39,33 +36,25 @@ enum { PROP_0, }; - -/* IBusDBusImplPriv */ -struct _BusDBusImplPrivate { - GHashTable *unique_names; - GHashTable *names; - GHashTable *objects; - GList *connections; - GList *rules; - gint id; -}; - -typedef struct _BusDBusImplPrivate BusDBusImplPrivate; - static guint dbus_signals[LAST_SIGNAL] = { 0 }; /* functions prototype */ -static void bus_dbus_impl_class_init (BusDBusImplClass *klass); -static void bus_dbus_impl_init (BusDBusImpl *dbus); -static void bus_dbus_impl_dispose (BusDBusImpl *dbus); -static gboolean bus_dbus_impl_ibus_message (BusDBusImpl *dbus, - BusConnection *connection, - IBusMessage *message); -static void bus_dbus_impl_name_owner_changed - (BusDBusImpl *dbus, - gchar *name, - gchar *old_name, - gchar *new_name); +static void bus_dbus_impl_class_init (BusDBusImplClass *klass); +static void bus_dbus_impl_init (BusDBusImpl *dbus); +static void bus_dbus_impl_destroy (BusDBusImpl *dbus); +static gboolean bus_dbus_impl_ibus_message (BusDBusImpl *dbus, + BusConnection *connection, + IBusMessage *message); +static void bus_dbus_impl_name_owner_changed(BusDBusImpl *dbus, + gchar *name, + gchar *old_name, + gchar *new_name); + + +static void _connection_destroy_cb (BusConnection *connection, + BusDBusImpl *dbus); +static void _rule_destroy_cb (BusMatchRule *rule, + BusDBusImpl *dbus); static IBusServiceClass *parent_class = NULL; @@ -98,7 +87,6 @@ bus_dbus_impl_get_type (void) BusDBusImpl * bus_dbus_impl_get_default (void) { - // BusDBusImplPrivate *priv; static BusDBusImpl *dbus = NULL; if (dbus == NULL) { @@ -118,9 +106,7 @@ bus_dbus_impl_class_init (BusDBusImplClass *klass) parent_class = (IBusServiceClass *) g_type_class_peek_parent (klass); - g_type_class_add_private (klass, sizeof (BusDBusImplPrivate)); - - gobject_class->dispose = (GObjectFinalizeFunc) bus_dbus_impl_dispose; + IBUS_OBJECT_CLASS (gobject_class)->destroy = (IBusObjectDestroyFunc) bus_dbus_impl_destroy; service_class->ibus_message = (ServiceIBusMessageFunc) bus_dbus_impl_ibus_message; @@ -145,25 +131,48 @@ bus_dbus_impl_class_init (BusDBusImplClass *klass) static void bus_dbus_impl_init (BusDBusImpl *dbus) { - BusDBusImplPrivate *priv; - priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus); - - priv->unique_names = g_hash_table_new (g_str_hash, g_str_equal); - priv->names = g_hash_table_new (g_str_hash, g_str_equal); - priv->objects = g_hash_table_new (g_str_hash, g_str_equal); - priv->connections = NULL; - priv->rules = NULL; - priv->id = 1; + dbus->unique_names = g_hash_table_new (g_str_hash, g_str_equal); + dbus->names = g_hash_table_new (g_str_hash, g_str_equal); + dbus->objects = g_hash_table_new (g_str_hash, g_str_equal); + dbus->connections = NULL; + dbus->rules = NULL; + dbus->id = 1; g_object_ref (dbus); - g_hash_table_insert (priv->objects, DBUS_PATH_DBUS, dbus); + g_hash_table_insert (dbus->objects, DBUS_PATH_DBUS, dbus); } static void -bus_dbus_impl_dispose (BusDBusImpl *dbus) +bus_dbus_impl_destroy (BusDBusImpl *dbus) { - BusDBusImplPrivate *priv; - priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus); + GList *p; + + for (p = dbus->rules; p != NULL; p = p->next) { + BusMatchRule *rule = BUS_MATCH_RULE (p->data); + g_signal_handlers_disconnect_by_func (rule, _rule_destroy_cb, dbus); + ibus_object_destroy ((IBusObject *) rule); + g_object_unref (rule); + } + g_list_free (dbus->rules); + dbus->rules = NULL; + + for (p = dbus->connections; p != NULL; p = p->next) { + BusConnection *connection = BUS_CONNECTION (p->data); + g_signal_handlers_disconnect_by_func (connection, _connection_destroy_cb, dbus); + ibus_connection_close ((IBusConnection *) connection); + ibus_object_destroy ((IBusObject *) connection); + g_object_unref (connection); + } + g_list_free (dbus->connections); + dbus->connections = NULL; + + g_hash_table_remove_all (dbus->unique_names); + g_hash_table_remove_all (dbus->names); + g_hash_table_remove_all (dbus->objects); + + dbus->unique_names = NULL; + dbus->names = NULL; + dbus->objects = NULL; G_OBJECT_CLASS(parent_class)->dispose (G_OBJECT (dbus)); } @@ -293,9 +302,6 @@ _dbus_hello (BusDBusImpl *dbus, IBusMessage *message, BusConnection *connection) { - BusDBusImplPrivate *priv; - priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus); - IBusMessage *reply_message; if (bus_connection_get_unique_name (connection) != NULL) { @@ -306,12 +312,12 @@ _dbus_hello (BusDBusImpl *dbus, else { gchar *name; - name = g_strdup_printf (":1.%d", priv->id ++); + name = g_strdup_printf (":1.%d", dbus->id ++); bus_connection_set_unique_name (connection, name); g_free (name); name = (gchar *) bus_connection_get_unique_name (connection); - g_hash_table_insert (priv->unique_names, name, connection); + g_hash_table_insert (dbus->unique_names, name, connection); reply_message = ibus_message_new_method_return (message); ibus_message_append_args (reply_message, @@ -340,9 +346,6 @@ _dbus_list_names (BusDBusImpl *dbus, IBusMessage *message, BusConnection *connection) { - BusDBusImplPrivate *priv; - priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus); - IBusMessage *reply_message; IBusMessageIter iter, sub_iter; GList *name, *names; @@ -353,7 +356,7 @@ _dbus_list_names (BusDBusImpl *dbus, ibus_message_iter_open_container (&iter, IBUS_TYPE_ARRAY, "s", &sub_iter); // append unique names - names = g_hash_table_get_keys (priv->unique_names); + names = g_hash_table_get_keys (dbus->unique_names); names = g_list_sort (names, (GCompareFunc) g_strcmp0); for (name = names; name != NULL; name = name->next) { @@ -362,7 +365,7 @@ _dbus_list_names (BusDBusImpl *dbus, g_list_free (names); // append well-known names - names = g_hash_table_get_keys (priv->names); + names = g_hash_table_get_keys (dbus->names); names = g_list_sort (names, (GCompareFunc) g_strcmp0); for (name = names; name != NULL; name = name->next) { ibus_message_iter_append (&sub_iter, G_TYPE_STRING, &(name->data)); @@ -379,9 +382,6 @@ _dbus_name_has_owner (BusDBusImpl *dbus, IBusMessage *message, BusConnection *connection) { - BusDBusImplPrivate *priv; - priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus); - gchar *name; gboolean retval; gboolean has_owner; @@ -402,10 +402,10 @@ _dbus_name_has_owner (BusDBusImpl *dbus, } if (name[0] == ':') { - has_owner = g_hash_table_lookup (priv->unique_names, name) != NULL; + has_owner = g_hash_table_lookup (dbus->unique_names, name) != NULL; } else { - has_owner = g_hash_table_lookup (priv->names, name) != NULL; + has_owner = g_hash_table_lookup (dbus->names, name) != NULL; } reply_message = ibus_message_new_method_return (message); @@ -422,9 +422,6 @@ _dbus_get_name_owner (BusDBusImpl *dbus, IBusMessage *message, BusConnection *connection) { - BusDBusImplPrivate *priv; - priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus); - gchar *name; BusConnection *owner; gboolean retval; @@ -477,9 +474,6 @@ _dbus_get_id (BusDBusImpl *dbus, IBusMessage *message, BusConnection *connection) { - BusDBusImplPrivate *priv; - priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus); - IBusMessage *reply_message; const gchar *name; @@ -506,10 +500,7 @@ _rule_destroy_cb (BusMatchRule *rule, g_assert (BUS_IS_MATCH_RULE (rule)); g_assert (BUS_IS_DBUS_IMPL (dbus)); - BusDBusImplPrivate *priv; - priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus); - - priv->rules = g_list_remove (priv->rules, rule); + dbus->rules = g_list_remove (dbus->rules, rule); g_object_unref (rule); } @@ -518,9 +509,6 @@ _dbus_add_match (BusDBusImpl *dbus, IBusMessage *message, BusConnection *connection) { - BusDBusImplPrivate *priv; - priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus); - IBusMessage *reply_message; IBusError *error; gboolean retval; @@ -551,7 +539,7 @@ _dbus_add_match (BusDBusImpl *dbus, return reply_message; } - for (link = priv->rules; link != NULL; link = link->next) { + for (link = dbus->rules; link != NULL; link = link->next) { if (bus_match_rule_is_equal (rule, BUS_MATCH_RULE (link->data))) { bus_match_rule_add_recipient (BUS_MATCH_RULE (link->data), connection); g_object_unref (rule); @@ -562,7 +550,7 @@ _dbus_add_match (BusDBusImpl *dbus, if (rule) { bus_match_rule_add_recipient (rule, connection); - priv->rules = g_list_append (priv->rules, rule); + dbus->rules = g_list_append (dbus->rules, rule); g_signal_connect (rule, "destroy", G_CALLBACK (_rule_destroy_cb), dbus); } @@ -575,9 +563,6 @@ _dbus_remove_match (BusDBusImpl *dbus, IBusMessage *message, BusConnection *connection) { - BusDBusImplPrivate *priv; - priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus); - IBusMessage *reply_message; IBusError *error; gchar *rule_text; @@ -605,7 +590,7 @@ _dbus_remove_match (BusDBusImpl *dbus, return reply_message; } - for (link = priv->rules; link != NULL; link = link->next) { + for (link = dbus->rules; link != NULL; link = link->next) { if (bus_match_rule_is_equal (rule, BUS_MATCH_RULE (link->data))) { bus_match_rule_remove_recipient (BUS_MATCH_RULE (link->data), connection); break; @@ -623,9 +608,6 @@ _dbus_request_name (BusDBusImpl *dbus, IBusMessage *message, BusConnection *connection) { - BusDBusImplPrivate *priv; - priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus); - IBusMessage *reply_message; IBusError *error; gchar *name; @@ -644,7 +626,7 @@ _dbus_request_name (BusDBusImpl *dbus, return reply_message; } - if (g_hash_table_lookup (priv->names, name) != NULL) { + if (g_hash_table_lookup (dbus->names, name) != NULL) { reply_message = ibus_message_new_error_printf (message, DBUS_ERROR_FAILED, "Name %s has owner", @@ -653,7 +635,7 @@ _dbus_request_name (BusDBusImpl *dbus, } retval = 1; - g_hash_table_insert (priv->names, + g_hash_table_insert (dbus->names, (gpointer )bus_connection_add_name (connection, name), connection); reply_message = ibus_message_new_method_return (message); @@ -680,9 +662,6 @@ _dbus_release_name (BusDBusImpl *dbus, IBusMessage *message, BusConnection *connection) { - BusDBusImplPrivate *priv; - priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus); - IBusMessage *reply_message; IBusError *error; gchar *name; @@ -826,6 +805,10 @@ _connection_ibus_message_cb (BusConnection *connection, const gchar *dest; + if (G_UNLIKELY (IBUS_OBJECT_DESTROYED (dbus))) { + return; + } + if (ibus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected")) { @@ -872,12 +855,9 @@ _connection_ibus_message_cb (BusConnection *connection, const gchar *path; IBusService *object; - BusDBusImplPrivate *priv; - priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus); - path = ibus_message_get_path (message); - object = g_hash_table_lookup (priv->objects, path); + object = g_hash_table_lookup (dbus->objects, path); if (object == NULL || ibus_service_handle_message (object, @@ -915,10 +895,6 @@ _connection_ibus_message_sent_cb (BusConnection *connection, IBusMessage *message, BusDBusImpl *dbus) { - g_assert (BUS_IS_CONNECTION (connection)); - g_assert (message != NULL); - g_assert (BUS_IS_DBUS_IMPL (dbus)); - bus_dbus_impl_dispatch_message_by_rule (dbus, message, connection); } @@ -929,9 +905,6 @@ _connection_destroy_cb (BusConnection *connection, g_assert (BUS_IS_CONNECTION (connection)); g_assert (BUS_IS_DBUS_IMPL (dbus)); - BusDBusImplPrivate *priv; - priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus); - /* ibus_service_remove_from_connection ( IBUS_SERVICE (dbus), @@ -940,7 +913,7 @@ _connection_destroy_cb (BusConnection *connection, const gchar *unique_name = bus_connection_get_unique_name (connection); if (unique_name != NULL) { - g_hash_table_remove (priv->unique_names, unique_name); + g_hash_table_remove (dbus->unique_names, unique_name); g_signal_emit (dbus, dbus_signals[NAME_OWNER_CHANGED], 0, @@ -952,7 +925,7 @@ _connection_destroy_cb (BusConnection *connection, const GList *name = bus_connection_get_names (connection); while (name != NULL) { - g_hash_table_remove (priv->names, name->data); + g_hash_table_remove (dbus->names, name->data); g_signal_emit (dbus, dbus_signals[NAME_OWNER_CHANGED], 0, @@ -962,7 +935,7 @@ _connection_destroy_cb (BusConnection *connection, name = name->next; } - priv->connections = g_list_remove (priv->connections, connection); + dbus->connections = g_list_remove (dbus->connections, connection); g_object_unref (connection); } @@ -974,13 +947,10 @@ bus_dbus_impl_new_connection (BusDBusImpl *dbus, g_assert (BUS_IS_DBUS_IMPL (dbus)); g_assert (BUS_IS_CONNECTION (connection)); - BusDBusImplPrivate *priv; - priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus); - - g_assert (g_list_find (priv->connections, connection) == NULL); + g_assert (g_list_find (dbus->connections, connection) == NULL); g_object_ref (connection); - priv->connections = g_list_append (priv->connections, connection); + dbus->connections = g_list_append (dbus->connections, connection); g_signal_connect (connection, "ibus-message", @@ -1010,17 +980,14 @@ bus_dbus_impl_get_connection_by_name (BusDBusImpl *dbus, BusConnection *connection = NULL; - BusDBusImplPrivate *priv; - priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus); - if (name[0] == ':') { connection = BUS_CONNECTION (g_hash_table_lookup ( - priv->unique_names, + dbus->unique_names, name)); } else { connection = BUS_CONNECTION (g_hash_table_lookup ( - priv->names, + dbus->names, name)); } @@ -1038,6 +1005,10 @@ bus_dbus_impl_dispatch_message (BusDBusImpl *dbus, const gchar *destination; BusConnection *dest_connection = NULL; + if (G_UNLIKELY (IBUS_OBJECT_DESTROYED (dbus))) { + return; + } + destination = ibus_message_get_destination (message); if (destination != NULL) { @@ -1074,8 +1045,9 @@ bus_dbus_impl_dispatch_message_by_rule (BusDBusImpl *dbus, static gint32 data_slot = -1; - BusDBusImplPrivate *priv; - priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus); + if (G_UNLIKELY (IBUS_OBJECT_DESTROYED (dbus))) { + return; + } if (data_slot == -1) { dbus_message_allocate_data_slot (&data_slot); @@ -1093,7 +1065,7 @@ bus_dbus_impl_dispatch_message_by_rule (BusDBusImpl *dbus, } #endif - for (link = priv->rules; link != NULL; link = link->next) { + for (link = dbus->rules; link != NULL; link = link->next) { if (bus_match_rule_get_recipients (BUS_MATCH_RULE (link->data), message, &recipients)) { @@ -1116,11 +1088,7 @@ static void _object_destroy_cb (IBusService *object, BusDBusImpl *dbus) { - gboolean retval; - - retval = bus_dbus_impl_unregister_object (dbus, object); - - g_assert (retval); + bus_dbus_impl_unregister_object (dbus, object); } gboolean @@ -1131,17 +1099,19 @@ bus_dbus_impl_register_object (BusDBusImpl *dbus, g_assert (IBUS_IS_SERVICE (object)); const gchar *path; - BusDBusImplPrivate *priv; - priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus); + + if (G_UNLIKELY (IBUS_OBJECT_DESTROYED (dbus))) { + return FALSE; + } path = ibus_service_get_path (object); g_return_val_if_fail (path, FALSE); - g_return_val_if_fail (g_hash_table_lookup (priv->objects, path) == NULL, FALSE); + g_return_val_if_fail (g_hash_table_lookup (dbus->objects, path) == NULL, FALSE); g_object_ref (object); - g_hash_table_insert (priv->objects, (gpointer)path, object); + g_hash_table_insert (dbus->objects, (gpointer)path, object); g_signal_connect (object, "destroy", G_CALLBACK (_object_destroy_cb), dbus); @@ -1156,17 +1126,19 @@ bus_dbus_impl_unregister_object (BusDBusImpl *dbus, g_assert (IBUS_IS_SERVICE (object)); const gchar *path; - BusDBusImplPrivate *priv; - priv = BUS_DBUS_IMPL_GET_PRIVATE (dbus); + + if (G_UNLIKELY (IBUS_OBJECT_DESTROYED (dbus))) { + return FALSE; + } path = ibus_service_get_path (object); g_return_val_if_fail (path, FALSE); - g_return_val_if_fail (g_hash_table_lookup (priv->objects, path) == object, FALSE); + g_return_val_if_fail (g_hash_table_lookup (dbus->objects, path) == object, FALSE); g_signal_handlers_disconnect_by_func (object, G_CALLBACK (_object_destroy_cb), dbus); - g_hash_table_remove (priv->objects, path); + g_hash_table_remove (dbus->objects, path); g_object_unref (object); return TRUE; diff --git a/bus/dbusimpl.h b/bus/dbusimpl.h index d04326e..7ef856b 100644 --- a/bus/dbusimpl.h +++ b/bus/dbusimpl.h @@ -52,6 +52,12 @@ typedef struct _BusDBusImplClass BusDBusImplClass; struct _BusDBusImpl { IBusService parent; /* instance members */ + GHashTable *unique_names; + GHashTable *names; + GHashTable *objects; + GList *connections; + GList *rules; + gint id; }; struct _BusDBusImplClass { diff --git a/bus/ibusimpl.c b/bus/ibusimpl.c index 31799d6..e92b373 100644 --- a/bus/ibusimpl.c +++ b/bus/ibusimpl.c @@ -18,6 +18,10 @@ * Boston, MA 02111-1307, USA. */ +#include +#include +#include +#include #include "ibusimpl.h" #include "dbusimpl.h" #include "server.h" @@ -828,19 +832,59 @@ _ibus_list_active_engines (BusIBusImpl *ibus, return reply; } +extern gchar **g_argv; + static IBusMessage * -_ibus_kill (BusIBusImpl *ibus, +_ibus_exit (BusIBusImpl *ibus, IBusMessage *message, BusConnection *connection) { IBusMessage *reply; + IBusError *error; + gboolean restart; + + if (!ibus_message_get_args (message, + &error, + G_TYPE_BOOLEAN, &restart, + G_TYPE_INVALID)) { + reply = ibus_message_new_error (message, + DBUS_ERROR_INVALID_ARGS, + "Argument 1 of Exit should be an boolean"); + ibus_error_free (error); + return reply; + } reply = ibus_message_new_method_return (message); ibus_connection_send ((IBusConnection *) connection, reply); ibus_connection_flush ((IBusConnection *) connection); ibus_message_unref (reply); - ibus_object_destroy (IBUS_OBJECT (ibus)); + + if (!restart) { + exit (0); + } + else { + glong timeout; + gint fd; + gint status; + + bus_registry_stop_all_components (ibus->registry); + ibus_object_destroy ((IBusObject *) BUS_DEFAULT_SERVER); + for (fd = 3; fd <= sysconf (_SC_OPEN_MAX); fd++) { + close (fd); + } + for (timeout = 0; waitpid (0, &status, WNOHANG) != -1;) { + usleep (1000); + timeout += 1000; + if (timeout >= G_USEC_PER_SEC * 2) { + g_warning ("Not every child processes exited!"); + } + }; + execv (g_argv[0], g_argv); + g_warning ("execv %s failed!", g_argv[0]); + exit (-1); + } + return NULL; } @@ -870,7 +914,7 @@ bus_ibus_impl_ibus_message (BusIBusImpl *ibus, { IBUS_INTERFACE_IBUS, "RegisterComponent", _ibus_register_component }, { IBUS_INTERFACE_IBUS, "ListEngines", _ibus_list_engines }, { IBUS_INTERFACE_IBUS, "ListActiveEngines", _ibus_list_active_engines }, - { IBUS_INTERFACE_IBUS, "Kill", _ibus_kill }, + { IBUS_INTERFACE_IBUS, "Exit", _ibus_exit }, { NULL, NULL, NULL } }; diff --git a/bus/main.c b/bus/main.c index 74e05d8..4650bfc 100644 --- a/bus/main.c +++ b/bus/main.c @@ -24,12 +24,16 @@ #include "server.h" #include "ibusimpl.h" +gchar **g_argv = NULL; + static gboolean daemonize = FALSE; static gboolean single = FALSE; static gboolean xim = FALSE; static gchar *panel = "default"; static gchar *config = "default"; static gchar *desktop = "gnome"; +static gchar *address = ""; +static gboolean rescan = FALSE; static gboolean verbose = FALSE; static const GOptionEntry entries[] = @@ -40,6 +44,8 @@ static const GOptionEntry entries[] = { "desktop", 'n', 0, G_OPTION_ARG_STRING, &desktop, "specify the name of desktop session. [default=gnome]", "name" }, { "panel", 'p', 0, G_OPTION_ARG_STRING, &panel, "specify the cmdline of panel program.", "cmdline" }, { "config", 'c', 0, G_OPTION_ARG_STRING, &config, "specify the cmdline of config program.", "cmdline" }, + { "address", 'a', 0, G_OPTION_ARG_STRING, &address, "specify the address of ibus daemon.", "address" }, + { "rescan", 'r', 0, G_OPTION_ARG_NONE, &rescan, "force to rescan components, and recreate registry cache.", NULL }, { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "verbose.", NULL }, { NULL }, }; @@ -91,11 +97,15 @@ main (gint argc, gchar **argv) g_option_context_add_main_entries (context, entries, "ibus-daemon"); + g_argv = g_strdupv (argv); if (!g_option_context_parse (context, &argc, &argv, &error)) { g_printerr ("Option parsing failed: %s\n", error->message); exit (-1); } + /* create a new process group */ + setpgrp (); + if (daemonize) { if (daemon (1, 0) != 0) { g_printerr ("Can not daemonize ibus.\n"); diff --git a/bus/matchrule.c b/bus/matchrule.c index 6884fd6..6bf75c5 100644 --- a/bus/matchrule.c +++ b/bus/matchrule.c @@ -24,10 +24,11 @@ (G_TYPE_INSTANCE_GET_PRIVATE ((o), BUS_TYPE_CONFIG_PROXY, BusMatchRulePrivate)) -static void bus_match_rule_class_init (BusMatchRuleClass *klass); -static void bus_match_rule_init (BusMatchRule *rule); -static void bus_match_rule_destroy (BusMatchRule *rule); - +static void bus_match_rule_class_init (BusMatchRuleClass *klass); +static void bus_match_rule_init (BusMatchRule *rule); +static void bus_match_rule_destroy (BusMatchRule *rule); +static void _connection_destroy_cb (BusConnection *connection, + BusMatchRule *rule); static IBusObjectClass *parent_class = NULL; GType @@ -98,6 +99,8 @@ bus_match_rule_destroy (BusMatchRule *rule) for (link = rule->recipients; link != NULL; link = link->next) { BusRecipient *recipient = (BusRecipient *) link->data; + g_signal_handlers_disconnect_by_func (recipient->connection, + G_CALLBACK (_connection_destroy_cb), rule); g_object_unref (recipient->connection); g_slice_free (BusRecipient, recipient); } diff --git a/bus/matchrule.h b/bus/matchrule.h index e8aaf39..b69825d 100644 --- a/bus/matchrule.h +++ b/bus/matchrule.h @@ -63,7 +63,7 @@ struct _BusRecipient { }; struct _BusMatchRule { - IBusProxy parent; + IBusObject parent; /* instance members */ gint flags; gint message_type; @@ -77,7 +77,7 @@ struct _BusMatchRule { }; struct _BusMatchRuleClass { - IBusProxyClass parent; + IBusObjectClass parent; /* class members */ }; diff --git a/bus/registry.c b/bus/registry.c index cdc1aa7..516554e 100644 --- a/bus/registry.c +++ b/bus/registry.c @@ -409,6 +409,14 @@ bus_registry_find_engine_by_name (BusRegistry *registry, return (IBusEngineDesc *) g_hash_table_lookup (registry->engine_table, name); } +void +bus_registry_stop_all_components (BusRegistry *registry) +{ + g_assert (BUS_IS_REGISTRY (registry)); + + g_list_foreach (registry->components, (GFunc) ibus_component_stop, NULL); + +} BusFactoryProxy * bus_registry_name_owner_changed (BusRegistry *registry, diff --git a/bus/registry.h b/bus/registry.h index 9dadda6..377ac45 100644 --- a/bus/registry.h +++ b/bus/registry.h @@ -67,10 +67,8 @@ GType bus_registry_get_type (void); BusRegistry *bus_registry_new (void); GList *bus_registry_get_components (BusRegistry *registry); GList *bus_registry_get_engines (BusRegistry *registry); -gboolean bus_registry_exec_component (BusRegistry *registry, - const gchar *name); -gboolean bus_registry_kill_component (BusRegistry *registry, - const gchar *name); +void bus_registry_stop_all_components + (BusRegistry *registry); IBusComponent *bus_registry_lookup_component_by_name (BusRegistry *registry, diff --git a/bus/server.c b/bus/server.c index 2ae36bf..3a957db 100644 --- a/bus/server.c +++ b/bus/server.c @@ -128,6 +128,8 @@ static void bus_server_init (BusServer *server) { server->loop = g_main_loop_new (NULL, FALSE); + server->dbus = bus_dbus_impl_get_default (); + server->ibus = bus_ibus_impl_get_default (); } static void @@ -135,7 +137,7 @@ bus_server_new_connection (BusServer *server, BusConnection *connection) { g_assert (BUS_IS_SERVER (server)); - bus_dbus_impl_new_connection (BUS_DEFAULT_DBUS, connection); + bus_dbus_impl_new_connection (server->dbus, connection); } static void @@ -143,6 +145,11 @@ bus_server_destroy (BusServer *server) { g_assert (BUS_IS_SERVER (server)); + ibus_object_destroy ((IBusObject *) server->dbus); + g_object_unref (server->dbus); + ibus_object_destroy ((IBusObject *) server->ibus); + g_object_unref (server->ibus); + while (g_main_loop_is_running (server->loop)) { g_main_loop_quit (server->loop); } diff --git a/bus/server.h b/bus/server.h index 9ea5794..fd9bf11 100644 --- a/bus/server.h +++ b/bus/server.h @@ -21,6 +21,8 @@ #define __SERVER_H_ #include +#include "dbusimpl.h" +#include "ibusimpl.h" /* * Type macros. @@ -53,6 +55,9 @@ struct _BusServer { /* instance members */ GMainLoop *loop; + BusDBusImpl *dbus; + BusIBusImpl *ibus; + }; struct _BusServerClass { diff --git a/client/x11/main.c b/client/x11/main.c index 734c898..db29eab 100644 --- a/client/x11/main.c +++ b/client/x11/main.c @@ -982,7 +982,7 @@ static void _atexit_cb () { if (_bus) { - ibus_bus_kill(_bus); + ibus_bus_exit(_bus, False); } } diff --git a/ibus/bus.py b/ibus/bus.py index 6ca5f7d..3925385 100644 --- a/ibus/bus.py +++ b/ibus/bus.py @@ -125,8 +125,8 @@ class Bus(object.Object): def create_input_context(self, client_name): return self.__ibus.CreateInputContext(client_name) - def kill(self): - return self.__ibus.Kill() + def exit(self, restart): + return self.__ibus.Exit(restart) def get_config(self): try: diff --git a/ibus/interface/iibus.py b/ibus/interface/iibus.py index 848f798..fa71a71 100644 --- a/ibus/interface/iibus.py +++ b/ibus/interface/iibus.py @@ -66,6 +66,6 @@ class IIBus(dbus.service.Object): @method(out_signature="av") def ListActiveEngines(self, dbusconn): pass - @async_method() - def Kill(self, dbusconn, reply_cb, error_cb): pass + @method(in_signature="b") + def Exit(self, restart, dbusconn): pass diff --git a/src/ibusbus.c b/src/ibusbus.c index be72770..481d303 100644 --- a/src/ibusbus.c +++ b/src/ibusbus.c @@ -684,7 +684,8 @@ ibus_bus_get_connection (IBusBus *bus) } gboolean -ibus_bus_kill (IBusBus *bus) +ibus_bus_exit (IBusBus *bus, + gboolean restart) { g_assert (IBUS_IS_BUS (bus)); @@ -694,6 +695,7 @@ ibus_bus_kill (IBusBus *bus) IBUS_PATH_IBUS, IBUS_INTERFACE_IBUS, "Kill", + G_TYPE_BOOLEAN, &restart, G_TYPE_INVALID, G_TYPE_INVALID); return result; diff --git a/src/ibusbus.h b/src/ibusbus.h index e548c82..be1fba8 100644 --- a/src/ibusbus.h +++ b/src/ibusbus.h @@ -81,7 +81,8 @@ void ibus_bus_remove_match (IBusBus *bus, const gchar *ibus_bus_get_name_owner (IBusBus *bus, const gchar *name); /* declare ibus methods */ -gboolean ibus_bus_kill (IBusBus *bus); +gboolean ibus_bus_exit (IBusBus *bus, + gboolean restart); IBusInputContext *ibus_bus_create_input_context (IBusBus *bus, diff --git a/src/ibusobject.h b/src/ibusobject.h index 2c09882..67fb95b 100644 --- a/src/ibusobject.h +++ b/src/ibusobject.h @@ -50,9 +50,10 @@ typedef enum { IBUS_RESERVED_2 = (1 << 3), } IBusObjectFlags; -#define IBUS_OBJECT_FLAGS(obj) (IBUS_OBJECT (obj)->flags) +#define IBUS_OBJECT_FLAGS(obj) (IBUS_OBJECT (obj)->flags) #define IBUS_OBJECT_SET_FLAGS(obj,flag) G_STMT_START{ (IBUS_OBJECT_FLAGS (obj) |= (flag)); }G_STMT_END #define IBUS_OBJECT_UNSET_FLAGS(obj,flag) G_STMT_START{ (IBUS_OBJECT_FLAGS (obj) &= ~(flag)); }G_STMT_END +#define IBUS_OBJECT_DESTROYED(obj) (IBUS_OBJECT_FLAGS (obj) & IBUS_DESTROYED) G_BEGIN_DECLS diff --git a/ui/gtk/panel.py b/ui/gtk/panel.py index 284dbb6..759fb56 100644 --- a/ui/gtk/panel.py +++ b/ui/gtk/panel.py @@ -278,6 +278,10 @@ class Panel(ibus.PanelBase): self.__sys_menu_item_activate_cb, gtk.STOCK_ABOUT) menu.add(item) menu.add(gtk.SeparatorMenuItem()) + item = gtk.MenuItem(_("Restart")) + item.connect("activate", + self.__sys_menu_item_activate_cb, "Restart") + menu.add(item) item = gtk.ImageMenuItem(gtk.STOCK_QUIT) item.connect("activate", self.__sys_menu_item_activate_cb, gtk.STOCK_QUIT) @@ -375,8 +379,10 @@ class Panel(ibus.PanelBase): about_dialog.set_logo_icon_name("ibus") about_dialog.run() about_dialog.destroy() - elif command == gtk.STOCK_QUIT: - self.__bus.kill() + elif command == gtk.STOCK_QUIT: + self.__bus.exit(False) + elif command == "Restart": + self.__bus.exit(True) else: print >> sys.stderr, "Unknown command %s" % command diff --git a/xinput-ibus b/xinput-ibus index be3dc26..b0bab2e 100644 --- a/xinput-ibus +++ b/xinput-ibus @@ -1,7 +1,7 @@ XIM=ibus XIM_PROGRAM="/usr/bin/ibus-daemon" ICON="/usr/share/ibus/icons/ibus.svg" -# XIM_ARGS="0xffffffff" +XIM_ARGS="-x" PREFERENCE_PROGRAM=/usr/bin/ibus-setup SHORT_DESC="IBus" GTK_IM_MODULE=ibus