From 80e5bd0785ca91a70f0b5fe511a3bd8e143d8d05 Mon Sep 17 00:00:00 2001 From: Takao Fujiwara Date: Wed, 27 Apr 2011 07:48:50 -0400 Subject: [PATCH] Fix the zombie process of ibus-gconf when ibus-daemon restarts. - Fix the typo in bus_dbus_impl_destroy() (dbusimpl.c) - Modify bus_server_run() and _ibus_exit() (ibusimpl.c, server.c) bus_ibus_impl_destroy() needs to be called so that waitpid() prevents processes from becoming zombie. - Change the declaration of bus_server_quit(). (server.h) BUG=redhat#697471 TEST=Linux desktop Review URL: http://codereview.appspot.com/4440059 Patch from Takao Fujiwara . --- bus/dbusimpl.c | 5 ++--- bus/ibusimpl.c | 40 +--------------------------------------- bus/server.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- bus/server.h | 3 ++- src/ibusbus.c | 8 +++++++- 5 files changed, 61 insertions(+), 45 deletions(-) diff --git a/bus/dbusimpl.c b/bus/dbusimpl.c index d67a3ce..5616222 100644 --- a/bus/dbusimpl.c +++ b/bus/dbusimpl.c @@ -577,11 +577,10 @@ bus_dbus_impl_destroy (BusDBusImpl *dbus) dbus->rules = NULL; for (p = dbus->connections; p != NULL; p = p->next) { - GDBusConnection *connection = G_DBUS_CONNECTION (p->data); + BusConnection *connection = BUS_CONNECTION (p->data); g_signal_handlers_disconnect_by_func (connection, bus_dbus_impl_connection_destroy_cb, dbus); - /* FIXME should handle result? */ - g_dbus_connection_close (connection, NULL, NULL, NULL); + ibus_object_destroy (IBUS_OBJECT (connection)); g_object_unref (connection); } g_list_free (dbus->connections); diff --git a/bus/ibusimpl.c b/bus/ibusimpl.c index a7ae52b..b356b2c 100644 --- a/bus/ibusimpl.c +++ b/bus/ibusimpl.c @@ -24,9 +24,7 @@ #include #include #include -#include #include -#include #include #include "types.h" #include "ibusimpl.h" @@ -937,7 +935,6 @@ bus_ibus_impl_destroy (BusIBusImpl *ibus) ibus->fake_context = NULL; } - bus_server_quit (); IBUS_OBJECT_CLASS (bus_ibus_impl_parent_class)->destroy (IBUS_OBJECT (ibus)); } @@ -1682,43 +1679,8 @@ _ibus_exit (BusIBusImpl *ibus, g_dbus_connection_flush_sync (g_dbus_method_invocation_get_connection (invocation), NULL, NULL); - bus_server_quit (); - if (!restart) { - exit (0); - } - else { - extern gchar **g_argv; - gchar *exe; - gint fd; - - exe = g_strdup_printf ("/proc/%d/exe", getpid ()); - exe = g_file_read_link (exe, NULL); - - if (exe == NULL) - exe = BINDIR "/ibus-daemon"; - - /* close all fds except stdin, stdout, stderr */ - for (fd = 3; fd <= sysconf (_SC_OPEN_MAX); fd ++) { - close (fd); - } - - execv (exe, g_argv); - - /* If the server binary is replaced while the server is running, - * "readlink /proc/[pid]/exe" might return a path with " (deleted)" - * suffix. */ - const gchar suffix[] = " (deleted)"; - if (g_str_has_suffix (exe, suffix)) { - exe [strlen (exe) - sizeof (suffix) + 1] = '\0'; - execv (exe, g_argv); - } - g_warning ("execv %s failed!", g_argv[0]); - exit (-1); - } - - /* should not reach here */ - g_assert_not_reached (); + bus_server_quit (restart); } /** diff --git a/bus/server.c b/bus/server.c index d180513..c2ab9a4 100644 --- a/bus/server.c +++ b/bus/server.c @@ -21,6 +21,8 @@ */ #include "server.h" #include +#include +#include #include "dbusimpl.h" #include "ibusimpl.h" #include "option.h" @@ -30,6 +32,40 @@ static GMainLoop *mainloop = NULL; static BusDBusImpl *dbus = NULL; static BusIBusImpl *ibus = NULL; static gchar *address = NULL; +static gboolean _restart = FALSE; + +static void +_restart_server (void) +{ + extern gchar **g_argv; + gchar *exe; + gint fd; + + exe = g_strdup_printf ("/proc/%d/exe", getpid ()); + exe = g_file_read_link (exe, NULL); + + if (exe == NULL) + exe = BINDIR "/ibus-daemon"; + + /* close all fds except stdin, stdout, stderr */ + for (fd = 3; fd <= sysconf (_SC_OPEN_MAX); fd ++) { + close (fd); + } + + _restart = FALSE; + execv (exe, g_argv); + + /* If the server binary is replaced while the server is running, + * "readlink /proc/[pid]/exe" might return a path with " (deleted)" + * suffix. */ + const gchar suffix[] = " (deleted)"; + if (g_str_has_suffix (exe, suffix)) { + exe [strlen (exe) - sizeof (suffix) + 1] = '\0'; + execv (exe, g_argv); + } + g_warning ("execv %s failed!", g_argv[0]); + exit (-1); +} /** * bus_new_connection_cb: @@ -112,11 +148,23 @@ bus_server_run (void) mainloop = NULL; g_free (address); address = NULL; + + /* When _ibus_exit() is called, bus_ibus_impl_destroy() needs + * to be called so that waitpid() prevents the processes from + * becoming the daemons. So we run execv() after + * ibus_object_destroy(ibus) is called here. */ + if (_restart) { + _restart_server (); + + /* should not reach here */ + g_assert_not_reached (); + } } void -bus_server_quit (void) +bus_server_quit (gboolean restart) { + _restart = restart; if (mainloop) g_main_loop_quit (mainloop); } diff --git a/bus/server.h b/bus/server.h index 6dfd79a..e1cb3ec 100644 --- a/bus/server.h +++ b/bus/server.h @@ -43,10 +43,11 @@ void bus_server_run (void); /** * bus_server_quit: + * @restart: TRUE if ibus-daemon restarts. * * Quit the glib main loop. */ -void bus_server_quit (void); +void bus_server_quit (gboolean restart); /** * bus_server_get_address: diff --git a/src/ibusbus.c b/src/ibusbus.c index 0e9418e..39ad784 100644 --- a/src/ibusbus.c +++ b/src/ibusbus.c @@ -236,7 +236,13 @@ _connection_closed_cb (GDBusConnection *connection, IBusBus *bus) { if (error) { - g_warning ("_connection_closed_cb: %s", error->message); + /* We replaced g_warning with g_debug here because + * currently when ibus-daemon restarts, GTK client calls this and + * _g_dbus_worker_do_read_cb() sets the error message: + * "Underlying GIOStream returned 0 bytes on an async read" + * http://git.gnome.org/browse/glib/tree/gio/gdbusprivate.c#n693 + * However we think the error message is almost harmless. */ + g_debug ("_connection_closed_cb: %s", error->message); } g_assert (bus->priv->connection == connection); -- 1.7.4.4 From d059132885d3c90647f08f3083e39daa9f82b700 Mon Sep 17 00:00:00 2001 From: Ryo Onodera Date: Tue, 17 May 2011 20:07:40 +0900 Subject: [PATCH] fix wrong forward key event signature --- ibus/engine.py | 4 ++-- ibus/interface/iengine.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ibus/engine.py b/ibus/engine.py index 8cbcee3..fe5dd98 100644 --- a/ibus/engine.py +++ b/ibus/engine.py @@ -114,8 +114,8 @@ class EngineBase(object.Object): text = serializable.serialize_object(text) return self.__proxy.CommitText(text) - def forward_key_event(self, keyval, state): - return self.__proxy.ForwardKeyEvent(keyval, state) + def forward_key_event(self, keyval, keycode, state): + return self.__proxy.ForwardKeyEvent(keyval, keycode, state) def update_preedit_text(self, text, cursor_pos, visible, mode=common.IBUS_ENGINE_PREEDIT_CLEAR): text = serializable.serialize_object(text) diff --git a/ibus/interface/iengine.py b/ibus/interface/iengine.py index 0e0f4ee..9e0d981 100644 --- a/ibus/interface/iengine.py +++ b/ibus/interface/iengine.py @@ -104,8 +104,8 @@ class IEngine(dbus.service.Object): @signal(signature="v") def CommitText(self, text): pass - @signal(signature="uu") - def ForwardKeyEvent(self, keyval, state): pass + @signal(signature="uuu") + def ForwardKeyEvent(self, keyval, keycode, state): pass @signal(signature="vubu") def UpdatePreeditText(self, text, cursor_pos, visible, mode): pass -- 1.7.4.4 From d3e750eab6db7035f494fcdb328b87b2923e33a2 Mon Sep 17 00:00:00 2001 From: Yusuke Sato Date: Wed, 1 Jun 2011 23:37:14 +0900 Subject: [PATCH] Send the new capabilities to ibus-daemon in ibus_im_context_set_use_preedit. BUG=none TEST=none Review URL: http://codereview.appspot.com/4529103 --- client/gtk2/ibusimcontext.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-) diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c index ebae09d..4a894b0 100644 --- a/client/gtk2/ibusimcontext.c +++ b/client/gtk2/ibusimcontext.c @@ -942,6 +942,8 @@ ibus_im_context_set_use_preedit (GtkIMContext *context, gboolean use_preedit) else { ibusimcontext->caps &= ~IBUS_CAP_PREEDIT_TEXT; } + ibus_input_context_set_capabilities (ibusimcontext->ibuscontext, + ibusimcontext->caps); } gtk_im_context_set_use_preedit (ibusimcontext->slave, use_preedit); } -- 1.7.4.4 From 52425daa537a32bed1781958e1ef62dbf199ad8b Mon Sep 17 00:00:00 2001 From: Peng Huang Date: Mon, 6 Jun 2011 09:30:27 -0400 Subject: [PATCH] Fix Python input context binding. Export "forward-key-event" and "delete-surrounding-text" signals to Python; clear __needs_surrounding_text property on "enabled" and "disabled" signals. BUG=none TEST=briefly tested, at least I don't see any regression Review URL: http://codereview.appspot.com/4437062 --- ibus/inputcontext.py | 26 +++++++++++++++++++++++++- ibus/interface/iinputcontext.py | 3 +++ 2 files changed, 28 insertions(+), 1 deletions(-) diff --git a/ibus/inputcontext.py b/ibus/inputcontext.py index d143727..ceeb56d 100644 --- a/ibus/inputcontext.py +++ b/ibus/inputcontext.py @@ -116,6 +116,16 @@ class InputContext(object.Object): gobject.TYPE_NONE, () ), + "forward-key-event" : ( + gobject.SIGNAL_RUN_LAST, + gobject.TYPE_NONE, + (gobject.TYPE_UINT, gobject.TYPE_UINT, gobject.TYPE_UINT) + ), + "delete-surrounding-text" : ( + gobject.SIGNAL_RUN_LAST, + gobject.TYPE_NONE, + (gobject.TYPE_INT, gobject.TYPE_UINT) + ), } def __init__(self, bus, path, watch_signals=False): @@ -142,8 +152,14 @@ class InputContext(object.Object): self.__signal_matches.append(m) m = self.__context.connect_to_signal("RequireSurroundingText", self.__require_surrounding_text_cb) self.__signal_matches.append(m) + m = self.__context.connect_to_signal("Enabled", self.__enabled_cb) + self.__signal_matches.append(m) + m = self.__context.connect_to_signal("Disabled", self.__disabled_cb) + self.__signal_matches.append(m) - m = self.__context.connect_to_signal("Enabled", lambda *args: self.emit("enabled")) + m = self.__context.connect_to_signal("ForwardKeyEvent", lambda *args: self.emit("forward-key-event", *args)) + self.__signal_matches.append(m) + m = self.__context.connect_to_signal("DeleteSurroundingText", lambda *args: self.emit("delete-surrounding-text", *args)) self.__signal_matches.append(m) m = self.__context.connect_to_signal("Disabled", lambda *args: self.emit("disabled")) self.__signal_matches.append(m) @@ -168,6 +184,14 @@ class InputContext(object.Object): m = self.__context.connect_to_signal("CursorDownLookupTable", lambda *args: self.emit("cursor-down-lookup-table")) self.__signal_matches.append(m) + def __enabled_cb(self, *args): + self.__needs_surrounding_text = False + self.emit("enabled") + + def __disabled_cb(self, *args): + self.__needs_surrounding_text = False + self.emit("disabled") + def __commit_text_cb(self, *args): text = serializable.deserialize_object(args[0]) self.emit("commit-text", text) diff --git a/ibus/interface/iinputcontext.py b/ibus/interface/iinputcontext.py index 2db1c9b..1d3cd2a 100644 --- a/ibus/interface/iinputcontext.py +++ b/ibus/interface/iinputcontext.py @@ -95,6 +95,9 @@ class IInputContext(dbus.service.Object): @signal(signature="uuu") def ForwardKeyEvent(self, keyval, keycode, state): pass + @signal(signature="iu") + def DeleteSurroundingText(self, offset_from_cursor, nchars): pass + @signal(signature="vub") def UpdatePreeditText(self, text, cursor_pos, visible): pass -- 1.7.4.4 From 59ce675e335e599ed18d74ab8849b9a5fe75d4be Mon Sep 17 00:00:00 2001 From: Peng Huang Date: Mon, 13 Jun 2011 13:18:29 -0400 Subject: [PATCH] Fix some race condition between idle and timeout events. Also fix a memory leak. BUG=http://crosbug.com/16387 TEST=Linux desktop Review URL: http://codereview.appspot.com/4568072 --- bus/engineproxy.c | 46 ++++++++++++++++++++++++++++++---------------- 1 files changed, 30 insertions(+), 16 deletions(-) diff --git a/bus/engineproxy.c b/bus/engineproxy.c index 0c6f45d..f74af12 100644 --- a/bus/engineproxy.c +++ b/bus/engineproxy.c @@ -603,7 +603,8 @@ bus_engine_proxy_new_internal (const gchar *path, g_assert (IBUS_IS_ENGINE_DESC (desc)); g_assert (G_IS_DBUS_CONNECTION (connection)); - + GDBusProxyFlags flags = G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START | + G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES; BusEngineProxy *engine = (BusEngineProxy *) g_initable_new (BUS_TYPE_ENGINE_PROXY, NULL, @@ -613,7 +614,7 @@ bus_engine_proxy_new_internal (const gchar *path, "g-interface-name", IBUS_INTERFACE_ENGINE, "g-object-path", path, "g-default-timeout", g_gdbus_timeout, - "g-flags", G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START | G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES, + "g-flags", flags, NULL); const gchar *layout = ibus_engine_desc_get_layout (desc); if (layout != NULL && layout[0] != '\0') { @@ -638,24 +639,33 @@ static void engine_proxy_new_data_free (EngineProxyNewData *data) { if (data->simple != NULL) { - if (data->handler_id != 0) - g_signal_handler_disconnect (data->component, data->handler_id); g_object_unref (data->simple); } - if (data->component != NULL) + if (data->desc != NULL) { + g_object_unref (data->desc); + } + + if (data->component != NULL) { + if (data->handler_id != 0) { + g_signal_handler_disconnect (data->component, data->handler_id); + } g_object_unref (data->component); + } - if (data->factory != NULL) + if (data->factory != NULL) { g_object_unref (data->factory); + } - if (data->timeout_id != 0) + if (data->timeout_id != 0) { g_source_remove (data->timeout_id); + } if (data->cancellable != NULL) { - if (data->cancelled_handler_id != 0) + if (data->cancelled_handler_id != 0) { g_cancellable_disconnect (data->cancellable, - data->cancelled_handler_id); + data->cancelled_handler_id); + } g_object_unref (data->cancellable); } @@ -772,7 +782,8 @@ timeout_cb (EngineProxyNewData *data) /** * cancelled_cb: * - * A callback function to be called when someone calls g_cancellable_cancel() for the cancellable object for bus_engine_proxy_new. + * A callback function to be called when someone calls g_cancellable_cancel() + * for the cancellable object for bus_engine_proxy_new. * Call the GAsyncReadyCallback. */ static gboolean @@ -793,8 +804,12 @@ static void cancelled_cb (GCancellable *cancellable, EngineProxyNewData *data) { - /* Cancel the bus_engine_proxy_new() in idle to avoid deadlock */ - g_idle_add ((GSourceFunc) cancelled_idle_cb, data); + /* Cancel the bus_engine_proxy_new() in idle to avoid deadlock. + * And use HIGH priority to avoid timeout event happening before + * idle callback. */ + g_idle_add_full (G_PRIORITY_HIGH, + (GSourceFunc) cancelled_idle_cb, + data, NULL); } void @@ -831,13 +846,12 @@ bus_engine_proxy_new (IBusEngineDesc *desc, data->simple = simple; data->timeout = timeout; - g_object_set_data ((GObject *)data->simple, "EngineProxyNewData", data); - data->factory = bus_component_get_factory (data->component); if (data->factory == NULL) { - /* The factory is not ready yet. Create the factory first, and wait for the "notify::factory" signal. - * In the handler of "notify::factory", we'll create the engine proxy. */ + /* The factory is not ready yet. Create the factory first, and wait for + * the "notify::factory" signal. In the handler of "notify::factory", + * we'll create the engine proxy. */ data->handler_id = g_signal_connect (data->component, "notify::factory", G_CALLBACK (notify_factory_cb), -- 1.7.4.4 From fc9dedec30f724e91e7b3bb9111177e96b58ee43 Mon Sep 17 00:00:00 2001 From: Peng Huang Date: Wed, 15 Jun 2011 10:38:17 -0400 Subject: [PATCH] Add IBUS_ERROR domain and reply IBUS_ERROR_NO_ENGINE in org.freedesktop.IBus.InputContext.GetEngine BUG=None TEST=Manually Review URL: http://codereview.appspot.com/4528140 --- bus/inputcontext.c | 7 ++++- src/Makefile.am | 2 + src/ibus.h | 1 + src/ibuserror.c | 41 +++++++++++++++++++++++++++++++++ src/ibuserror.h | 46 +++++++++++++++++++++++++++++++++++++ src/ibusinputcontext.c | 15 +++++++++-- src/ibusshare.c | 1 + src/ibustypes.h | 9 +++++++ src/tests/ibus-gi-inputcontext.py | 34 +++++++++++++++++++++++++++ 9 files changed, 151 insertions(+), 5 deletions(-) create mode 100644 src/ibuserror.c create mode 100644 src/ibuserror.h create mode 100755 src/tests/ibus-gi-inputcontext.py diff --git a/bus/inputcontext.c b/bus/inputcontext.c index bad90ec..1567c5f 100644 --- a/bus/inputcontext.c +++ b/bus/inputcontext.c @@ -1040,8 +1040,11 @@ _ic_get_engine (BusInputContext *context, g_variant_new ("(v)", ibus_serializable_serialize ((IBusSerializable *)desc))); } else { - g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, - "Input context does not have engine."); + g_dbus_method_invocation_return_error ( + invocation, + IBUS_ERROR, + IBUS_ERROR_NO_ENGINE, + "Input context does not have engine."); } } diff --git a/src/Makefile.am b/src/Makefile.am index 632fc72..a53bd23 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -70,6 +70,7 @@ ibus_sources = \ ibusservice.c \ ibusfactory.c \ ibusengine.c \ + ibuserror.c \ ibustext.c \ ibuskeymap.c \ ibusattribute.c \ @@ -114,6 +115,7 @@ ibus_headers = \ ibusservice.h \ ibusfactory.h \ ibusengine.h \ + ibuserror.h \ ibustext.h \ ibuskeymap.h \ ibusattribute.h \ diff --git a/src/ibus.h b/src/ibus.h index 8df7160..c408f3d 100644 --- a/src/ibus.h +++ b/src/ibus.h @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include diff --git a/src/ibuserror.c b/src/ibuserror.c new file mode 100644 index 0000000..c50c164 --- /dev/null +++ b/src/ibuserror.c @@ -0,0 +1,41 @@ +/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ +/* vim:set et sts=4: */ +/* ibus - The Input Bus + * Copyright (C) 2011 Peng Huang + * + * 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. + */ + +#include "ibuserror.h" + +#include +#include "ibustypes.h" + +static const GDBusErrorEntry ibus_error_entries[] = +{ + { IBUS_ERROR_NO_ENGINE, "org.freedesktop.IBus.Error.NoEngine" }, +}; + +GQuark +ibus_error_quark (void) +{ + static volatile gsize quark_volatile = 0; + g_dbus_error_register_error_domain ("ibus-error-quark", + &quark_volatile, + ibus_error_entries, + G_N_ELEMENTS (ibus_error_entries)); + return (GQuark) quark_volatile; +} diff --git a/src/ibuserror.h b/src/ibuserror.h new file mode 100644 index 0000000..75c64b9 --- /dev/null +++ b/src/ibuserror.h @@ -0,0 +1,46 @@ +/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ +/* vim:set et sts=4: */ +/* ibus - The Input Bus + * Copyright (C) 2011 Peng Huang + * + * 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. + */ + +#if !defined (__IBUS_H_INSIDE__) && !defined (IBUS_COMPILATION) +#error "Only can be included directly" +#endif + +/** + * SECTION: ibusshare + * @short_description: Shared utility functions and definition. + * @stability: Stable + * + * This file defines some utility functions and definition + * which are shared among ibus component and services. + */ + +#ifndef __IBUS_ERROR_H_ +#define __IBUS_ERROR_H_ + +#include + +G_BEGIN_DECLS + +#define IBUS_ERROR ibus_error_quark() +GQuark ibus_error_quark (void); + +G_END_DECLS +#endif diff --git a/src/ibusinputcontext.c b/src/ibusinputcontext.c index e6f97e8..78d454e 100644 --- a/src/ibusinputcontext.c +++ b/src/ibusinputcontext.c @@ -27,6 +27,7 @@ #include "ibusattribute.h" #include "ibuslookuptable.h" #include "ibusproplist.h" +#include "ibuserror.h" #define IBUS_INPUT_CONTEXT_GET_PRIVATE(o) \ (G_TYPE_INSTANCE_GET_PRIVATE ((o), IBUS_TYPE_INPUT_CONTEXT, IBusInputContextPrivate)) @@ -1164,7 +1165,7 @@ IBusEngineDesc * ibus_input_context_get_engine (IBusInputContext *context) { g_assert (IBUS_IS_INPUT_CONTEXT (context)); - GVariant *result; + GVariant *result = NULL; GError *error = NULL; result = g_dbus_proxy_call_sync ((GDBusProxy *) context, "GetEngine", /* method_name */ @@ -1174,9 +1175,17 @@ ibus_input_context_get_engine (IBusInputContext *context) NULL, /* cancellable */ &error /* error */ ); - if (result == NULL) { - g_warning ("%s.GetEngine: %s", IBUS_INTERFACE_INPUT_CONTEXT, error->message); + if (g_error_matches (error, IBUS_ERROR, IBUS_ERROR_NO_ENGINE)) { + g_debug ("%s.GetEngine: %s", + IBUS_INTERFACE_INPUT_CONTEXT, + error->message); + } + else { + g_warning ("%s.GetEngine: %s", + IBUS_INTERFACE_INPUT_CONTEXT, + error->message); + } g_error_free (error); return NULL; } diff --git a/src/ibusshare.c b/src/ibusshare.c index 1b8ae2a..19f9f65 100644 --- a/src/ibusshare.c +++ b/src/ibusshare.c @@ -318,6 +318,7 @@ void ibus_init (void) { g_type_init (); + IBUS_ERROR; IBUS_TYPE_TEXT; IBUS_TYPE_ATTRIBUTE; IBUS_TYPE_ATTR_LIST; diff --git a/src/ibustypes.h b/src/ibustypes.h index 6a31847..8146719 100644 --- a/src/ibustypes.h +++ b/src/ibustypes.h @@ -177,6 +177,15 @@ typedef enum { } IBusBusRequestNameReply; /** + * IBusError: + * @IBUS_ERROR_NO_ENGINE: + * There is no engine associated with input context. + */ +typedef enum { + IBUS_ERROR_NO_ENGINE, +} IBusError; + +/** * IBusRectangle: * @x: x coordinate. * @y: y coordinate. diff --git a/src/tests/ibus-gi-inputcontext.py b/src/tests/ibus-gi-inputcontext.py new file mode 100755 index 0000000..80fb97b --- /dev/null +++ b/src/tests/ibus-gi-inputcontext.py @@ -0,0 +1,34 @@ +#!/usr/bin/env python +# vim:set et sts=4 sw=4: +# +# ibus - The Input Bus +# +# Copyright (c) 2011 Peng Huang +# +# 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 program; if not, write to the +# Free Software Foundation, Inc., 59 Temple Place, Suite 330, +# Boston, MA 02111-1307 USA + + +import glib +import gio +from gi.repository import IBus +IBus.init() +main = glib.MainLoop() +bus = IBus.Bus() +ic = bus.create_input_context("ibus-test") +ic.get_engine() +ic.get_engine() +ic.get_engine() +ic.get_engine() -- 1.7.4.4 From aec97ac090980dfcd7eeef55c1755f6cd3f87a01 Mon Sep 17 00:00:00 2001 From: Daiki Ueno Date: Sat, 18 Jun 2011 00:03:07 -0400 Subject: [PATCH] Simplify surrounding-text initialization. Currently the immodule tries to retrieve surrounding-text unconditionally on focus_in and enabled. These calls could be eliminated if engine were able to proclaim that it will need surrounding-text. This patch extends ibus_engine_get_surrounding_text() to allow this. Engines that need surrounding-text are expected to have: /* Indicate we will use surrounding-text. */ ibus_engine_get_surrounding_text (engine, NULL, NULL); in their enable() method. This would work because enable() is called before SetCapabilities DBus call. BUG=none TEST=manually with ibus-m17n, with the above change. Review URL: http://codereview.appspot.com/4613043 Patch from Daiki Ueno . --- client/gtk2/ibusimcontext.c | 23 +++++++++-------------- src/ibusengine.c | 10 ++++++---- src/ibusengine.h | 9 +++++++-- 3 files changed, 22 insertions(+), 20 deletions(-) diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c index ec764ef..a4e7a16 100644 --- a/client/gtk2/ibusimcontext.c +++ b/client/gtk2/ibusimcontext.c @@ -147,8 +147,7 @@ static gboolean _slave_delete_surroundin gint offset_from_cursor, guint nchars, IBusIMContext *context); -static void _request_surrounding_text (IBusIMContext *context, - gboolean force); +static void _request_surrounding_text (IBusIMContext *context); static void _create_fake_input_context (void); @@ -263,17 +262,13 @@ _process_key_event_done (GObject *o /* emit "retrieve-surrounding" glib signal of GtkIMContext, if * context->caps has IBUS_CAP_SURROUNDING_TEXT and the current IBus * engine needs surrounding-text. - * - * if "force" is TRUE, emit the signal regardless of whether the - * engine needs surrounding-text. */ static void -_request_surrounding_text (IBusIMContext *context, gboolean force) +_request_surrounding_text (IBusIMContext *context) { - if (context->enable && + if (context && context->enable && (context->caps & IBUS_CAP_SURROUNDING_TEXT) != 0 && - (force || - ibus_input_context_needs_surrounding_text (context->ibuscontext))) { + ibus_input_context_needs_surrounding_text (context->ibuscontext)) { gboolean return_value; IDEBUG ("requesting surrounding text"); g_signal_emit (context, _signal_retrieve_surrounding_id, 0, @@ -368,9 +363,8 @@ _key_snooper_cb (GtkWidget *widget, } while (0); - _request_surrounding_text (ibusimcontext, FALSE); - if (ibusimcontext != NULL) { + _request_surrounding_text (ibusimcontext); ibusimcontext->time = event->time; } @@ -680,7 +674,7 @@ ibus_im_context_filter_keypress (GtkIMCo if (ibusimcontext->client_window == NULL && event->window != NULL) gtk_im_context_set_client_window ((GtkIMContext *)ibusimcontext, event->window); - _request_surrounding_text (ibusimcontext, FALSE); + _request_surrounding_text (ibusimcontext); if (ibusimcontext != NULL) { ibusimcontext->time = event->time; @@ -763,7 +757,7 @@ ibus_im_context_focus_in (GtkIMContext * /* retrieve the initial surrounding-text (regardless of whether * the current IBus engine needs surrounding-text) */ - _request_surrounding_text (ibusimcontext, TRUE); + _request_surrounding_text (ibusimcontext); g_object_add_weak_pointer ((GObject *) context, (gpointer *) &_focus_im_context); @@ -1000,7 +996,7 @@ _ibus_context_commit_text_cb (IBusInputC g_signal_emit (ibusimcontext, _signal_commit_id, 0, text->text); - _request_surrounding_text (ibusimcontext, FALSE); + _request_surrounding_text (ibusimcontext); } static gboolean @@ -1296,7 +1292,7 @@ _ibus_context_show_preedit_text_cb (IBus g_signal_emit (ibusimcontext, _signal_preedit_start_id, 0); g_signal_emit (ibusimcontext, _signal_preedit_changed_id, 0); - _request_surrounding_text (ibusimcontext, FALSE); + _request_surrounding_text (ibusimcontext); } static void @@ -1323,7 +1319,7 @@ _ibus_context_enabled_cb (IBusInputConte /* retrieve the initial surrounding-text (regardless of whether * the current IBus engine needs surrounding-text) */ - _request_surrounding_text (ibusimcontext, TRUE); + _request_surrounding_text (ibusimcontext); } static void diff --git a/src/ibusengine.c b/src/ibusengine.c index f545bef..620d07f 100644 --- a/src/ibusengine.c +++ b/src/ibusengine.c @@ -1382,13 +1382,15 @@ ibus_engine_get_surrounding_text (IBusEngine *engine, IBusEnginePrivate *priv; g_return_if_fail (IBUS_IS_ENGINE (engine)); - g_return_if_fail (text != NULL); - g_return_if_fail (cursor_pos != NULL); + g_return_if_fail ((text != NULL && cursor_pos != NULL) || + (text == NULL && cursor_pos == NULL)); priv = IBUS_ENGINE_GET_PRIVATE (engine); - *text = g_object_ref (priv->surrounding_text); - *cursor_pos = priv->surrounding_cursor_pos; + if (text && cursor_pos) { + *text = g_object_ref (priv->surrounding_text); + *cursor_pos = priv->surrounding_cursor_pos; + } /* tell the client that this engine will utilize surrounding-text * feature, which causes periodical update. Note that the client diff --git a/src/ibusengine.h b/src/ibusengine.h index 29b8f1d..6da342a 100644 --- a/src/ibusengine.h +++ b/src/ibusengine.h @@ -407,11 +407,16 @@ void ibus_engine_delete_surrounding_text(IBusEngine *engine, /** * ibus_engine_get_surrounding_text: * @engine: An IBusEngine. - * @text: Location to store surrounding text. - * @cursor_pos: Cursor position in characters in @text. + * @text: (allow-none): Location to store surrounding text. + * @cursor_pos: (allow-none): Cursor position in characters in @text. * * Get surrounding text. * + * It is also used to tell the input-context that the engine will + * utilize surrounding-text. In that case, it must be called in + * #IBusEngine::enable handler, with both @text and @cursor set to + * %NULL. + * * @see_also #IBusEngine::set-surrounding-text */ void ibus_engine_get_surrounding_text(IBusEngine *engine, -- 1.7.4.4 From a25187a315e9dfbb36a3e4a4f8e96f18e2cc6e0d Mon Sep 17 00:00:00 2001 From: fujiwarat Date: Tue, 5 Jul 2011 12:15:55 +0900 Subject: [PATCH] Fix SEGV in ibus_keymap_lookup_keysym --- bus/engineproxy.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/bus/engineproxy.c b/bus/engineproxy.c index 95e9e0b..a49d6fd 100644 --- a/bus/engineproxy.c +++ b/bus/engineproxy.c @@ -907,7 +907,7 @@ bus_engine_proxy_process_key_event (BusEngineProxy *engine, if (keymap == NULL) keymap = BUS_DEFAULT_KEYMAP; if (keymap != NULL) { - guint t = ibus_keymap_lookup_keysym (engine->keymap, keycode, state); + guint t = ibus_keymap_lookup_keysym (keymap, keycode, state); if (t != IBUS_VoidSymbol) { keyval = t; } -- 1.7.5.4 From 83d4b3ac538320bfb8e872dd9282ca5bbedf4652 Mon Sep 17 00:00:00 2001 From: Peng Huang Date: Mon, 4 Jul 2011 03:27:23 +0800 Subject: [PATCH] Fix BusEngineProxy instance leak. BUG=none TEST=manually with / without global-engine setting Review URL: http://codereview.appspot.com/4662043 --- bus/engineproxy.c | 9 --------- bus/inputcontext.c | 5 +---- 2 files changed, 1 insertions(+), 13 deletions(-) diff --git a/bus/engineproxy.c b/bus/engineproxy.c index f74af12..95e9e0b 100644 --- a/bus/engineproxy.c +++ b/bus/engineproxy.c @@ -397,15 +397,6 @@ bus_engine_proxy_real_destroy (IBusProxy *proxy) { BusEngineProxy *engine = (BusEngineProxy *)proxy; - g_dbus_proxy_call ((GDBusProxy *)proxy, - "org.freedesktop.IBus.Service.Destroy", - NULL, - G_DBUS_CALL_FLAGS_NONE, - -1, - NULL, - NULL, - NULL); - if (engine->desc) { g_object_unref (engine->desc); engine->desc = NULL; diff --git a/bus/inputcontext.c b/bus/inputcontext.c index 1567c5f..2164e7c 100644 --- a/bus/inputcontext.c +++ b/bus/inputcontext.c @@ -1020,8 +1020,6 @@ _ic_set_engine (BusInputContext *context, NULL, (GAsyncReadyCallback)_ic_set_engine_done, invocation); - - g_object_unref (desc); } /** @@ -2091,7 +2089,6 @@ bus_input_context_enable (BusInputContext *context) NULL, /* we do not cancel the call. */ NULL, /* use the default callback function. */ NULL); - g_object_unref (desc); } } @@ -2192,7 +2189,6 @@ bus_input_context_unset_engine (BusInputContext *context) for (i = 0; engine_signals[i].name != NULL; i++) { g_signal_handlers_disconnect_by_func (context->engine, engine_signals[i].callback, context); } - /* Do not destroy the engine anymore, because of global engine feature */ g_object_unref (context->engine); context->engine = NULL; } @@ -2291,6 +2287,7 @@ new_engine_cb (GObject *obj, } else { bus_input_context_set_engine (data->context, engine); + g_object_unref (engine); bus_input_context_enable (data->context); g_simple_async_result_set_op_res_gboolean (data->simple, TRUE); } -- 1.7.5.4 From 624c4451da2bd171bd8ac53a9b9dd2a4227ef67f Mon Sep 17 00:00:00 2001 From: Peng Huang Date: Thu, 7 Jul 2011 12:42:52 -0400 Subject: [PATCH] Fix several GVariant related issues. And remove a wrong unref. BUG=None TEST=Linux desktop Review URL: http://codereview.appspot.com/4667067 --- bus/ibusimpl.c | 11 +++++------ bus/inputcontext.c | 1 - src/ibusconfig.c | 8 ++------ 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/bus/ibusimpl.c b/bus/ibusimpl.c index b356b2c..42afeec 100644 --- a/bus/ibusimpl.c +++ b/bus/ibusimpl.c @@ -2183,8 +2183,8 @@ bus_ibus_impl_save_global_engine_name_to_config (BusIBusImpl *ibus) ibus->use_global_engine && ibus->global_engine_name) { ibus_config_set_value (ibus->config, - "general", "global_engine", - g_variant_new ("s", ibus->global_engine_name)); + "general", "global_engine", + g_variant_new_string (ibus->global_engine_name)); } } @@ -2206,8 +2206,7 @@ bus_ibus_impl_load_global_previous_engine_name_from_config (BusIBusImpl *ibus) GVariant *value = ibus_config_get_value (ibus->config, "general", "global_previous_engine"); if (value == NULL) return NULL; - gchar *engine_name = NULL; - g_variant_get (value, "(s)", &engine_name); + gchar *engine_name = g_variant_dup_string (value, NULL); g_variant_unref (value); return engine_name; } @@ -2226,8 +2225,8 @@ bus_ibus_impl_save_global_previous_engine_name_to_config (BusIBusImpl *ibus) ibus->use_global_engine && ibus->global_previous_engine_name) { ibus_config_set_value (ibus->config, - "general", "global_previous_engine", - g_variant_new ("s", ibus->global_previous_engine_name)); + "general", "global_previous_engine", + g_variant_new_string (ibus->global_previous_engine_name)); } } diff --git a/bus/inputcontext.c b/bus/inputcontext.c index 2164e7c..47ac9d5 100644 --- a/bus/inputcontext.c +++ b/bus/inputcontext.c @@ -1171,7 +1171,6 @@ bus_input_context_focus_in (BusInputContext *context) NULL, /* we do not cancel the call. */ NULL, /* use the default callback function. */ NULL); - g_object_unref (desc); } } diff --git a/src/ibusconfig.c b/src/ibusconfig.c index 36ef44b..b691277 100644 --- a/src/ibusconfig.c +++ b/src/ibusconfig.c @@ -191,7 +191,6 @@ ibus_config_get_value (IBusConfig *conf GVariant *value = NULL; g_variant_get (result, "(v)", &value); - g_variant_ref (value); g_variant_unref (result); return value; @@ -235,7 +234,6 @@ ibus_config_get_value_async_finish (IBus error); if (retval != NULL) { g_variant_get (retval, "(v)", &value); - g_variant_ref (value); g_variant_unref (retval); } -- 1.7.5.4 From 55a5652ac7d91fb319ef6576500e421eb53e80f4 Mon Sep 17 00:00:00 2001 From: Yusuke Sato Date: Mon, 11 Jul 2011 11:55:19 +0900 Subject: [PATCH] Remove the callback on destroy. BUG=crosbug.com/17293 TEST=src/tests/ibus-bus.c Review URL: http://codereview.appspot.com/4675074 --- src/ibusbus.c | 4 ++++ 1 files changed, 6 insertions(+), 0 deletions(-) diff --git a/src/ibusbus.c b/src/ibusbus.c index 39ad784..2607448 100644 --- a/src/ibusbus.c +++ b/src/ibusbus.c @@ -398,8 +398,12 @@ ibus_bus_destroy (IBusObject *object) } if (bus->priv->connection) { + g_signal_handlers_disconnect_by_func (bus->priv->connection, + G_CALLBACK (_connection_closed_cb), + bus); /* FIXME should use async close function */ g_dbus_connection_close_sync (bus->priv->connection, NULL, NULL); + g_object_unref (bus->priv->connection); bus->priv->connection = NULL; } -- 1.7.5.4 From 290a37e1d4e3ec44dfea4b99744520f781c92592 Mon Sep 17 00:00:00 2001 From: Yusuke Sato Date: Tue, 12 Jul 2011 14:04:30 +0900 Subject: [PATCH] Use g_variant_dup_string for consistency. This fix is similar to https://github.com/ibus/ibus/commit/624c4451da2bd171bd8ac53a9b9dd2a4227ef67f . BUG=None TEST=None Review URL: http://codereview.appspot.com/4641101 --- bus/ibusimpl.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/bus/ibusimpl.c b/bus/ibusimpl.c index 42afeec..b6b2441 100644 --- a/bus/ibusimpl.c +++ b/bus/ibusimpl.c @@ -2163,7 +2163,7 @@ bus_ibus_impl_load_global_engine_name_from_config (BusIBusImpl *ibus) GVariant *variant = ibus_config_get_value (ibus->config, "general", "global_engine"); gchar *engine_name = NULL; if (variant != NULL) { - g_variant_get (variant, "s", &engine_name); + engine_name = g_variant_dup_string (variant, NULL); g_variant_unref (variant); } return engine_name; -- 1.7.5.4 From 48cc200d7dbe999f92b05507a7c59bea42ac6f1c Mon Sep 17 00:00:00 2001 From: fujiwarat Date: Tue, 12 Jul 2011 15:14:59 +0900 Subject: [PATCH] Fixed an error in IBus.Bus.register_component TEST=Linux desktop Review URL: http://codereview.appspot.com/4668060 --- ibus/component.py | 9 +++++---- 1 files changed, 5 insertions(+), 4 deletions(-) diff --git a/ibus/component.py b/ibus/component.py index 12f593d..7255ee1 100644 --- a/ibus/component.py +++ b/ibus/component.py @@ -94,6 +94,11 @@ class Component(Serializable): engine = EngineDesc(name, longname, description, language, license, author, icon, layout, hotkeys) self.__engines.append(engine) + def add_engines(self, engines): + if not isinstance(engines, list): + raise TypeError("engines must be an instance of list") + self.__engines.extend(engines) + def serialize(self, struct): super(Component, self).serialize(struct) struct.append (dbus.String(self.__name)) @@ -106,8 +111,6 @@ class Component(Serializable): struct.append (dbus.String(self.__textdomain)) struct.append (dbus.Array(map(serialize_object,self.__observed_paths), signature="v")) struct.append (dbus.Array(map(serialize_object,self.__engines), signature="v")) - # New properties of Component will use dict for serialize - struct.append(dbus.Array({}, signature=None)) def deserialize(self, struct): super(Component, self).deserialize(struct) @@ -123,8 +126,6 @@ class Component(Serializable): self.__observed_paths = map(deserialize_object, struct.pop(0)) self.__engines = map(deserialize_object, struct.pop(0)) - # New properties of Component will use dict for serialize - #value = struct.pop(0) def test(): text = Component("Hello", "", "", "", "", "", "", "") -- 1.7.5.4 From 88a44759ce5d3d785c7be96525130c67e8c63e1e Mon Sep 17 00:00:00 2001 From: Daiki Ueno Date: Fri, 15 Jul 2011 09:51:07 +0900 Subject: [PATCH] Fix GObject ref/unref issues. BUG=none TEST=manual Review URL: http://codereview.appspot.com/4700048 --- bus/registry.c | 5 +++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bus/registry.c b/bus/registry.c index bc6680d..7b74781 100644 --- a/bus/registry.c +++ b/bus/registry.c @@ -424,7 +424,9 @@ bus_registry_load_in_dir (BusRegistry *registry, if (component != NULL) { BusComponent *buscomp = bus_component_new (component, NULL /* factory */); - registry->components = g_list_append (registry->components, buscomp); + g_object_ref_sink (buscomp); + registry->components = + g_list_append (registry->components, buscomp); } g_free (path); @@ -654,7 +656,6 @@ bus_registry_name_owner_changed (BusRegistry *registry, factory = bus_factory_proxy_new (connection); if (factory == NULL) return; - g_object_ref_sink (factory); bus_component_set_factory (component, factory); g_object_unref (factory); } -- 1.7.5.4 From 0cb912cfe5664714e612206d955d458532adc707 Mon Sep 17 00:00:00 2001 From: Peng Huang Date: Sat, 23 Jul 2011 09:23:41 +0800 Subject: [PATCH] Always enable the new focused BusInputContext BUG=http://crosbug.com/17013 TEST=On ChromeOS Review URL: http://codereview.appspot.com/4816047 --- bus/ibusimpl.c | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-) diff --git a/bus/ibusimpl.c b/bus/ibusimpl.c index b6b2441..853465c 100644 --- a/bus/ibusimpl.c +++ b/bus/ibusimpl.c @@ -1203,8 +1203,7 @@ bus_ibus_impl_set_focused_context (BusIBusImpl *ibus, /* attach engine to the focused context */ if (engine != NULL) { bus_input_context_set_engine (context, engine); - if (bus_engine_proxy_is_enabled (engine)) - bus_input_context_enable (context); + bus_input_context_enable (context); g_object_unref (engine); } -- 1.7.5.4 From 52804b99ba639e17a8a2563f3e2c6e76b79fcdef Mon Sep 17 00:00:00 2001 From: fujiwarat Date: Fri, 19 Aug 2011 12:02:51 +0900 Subject: [PATCH] Check if BusInputContext has an enabled engine in global input method. --- bus/ibusimpl.c | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-) diff --git a/bus/ibusimpl.c b/bus/ibusimpl.c index 853465c..1942504 100644 --- a/bus/ibusimpl.c +++ b/bus/ibusimpl.c @@ -1176,12 +1176,14 @@ bus_ibus_impl_set_focused_context (BusIBusImpl *ibus, } BusEngineProxy *engine = NULL; + gboolean is_enabled = FALSE; if (ibus->focused_context) { if (ibus->use_global_engine) { /* dettach engine from the focused context */ engine = bus_input_context_get_engine (ibus->focused_context); if (engine) { + is_enabled = bus_input_context_is_enabled (ibus->focused_context); g_object_ref (engine); bus_input_context_set_engine (ibus->focused_context, NULL); } @@ -1203,7 +1205,9 @@ bus_ibus_impl_set_focused_context (BusIBusImpl *ibus, /* attach engine to the focused context */ if (engine != NULL) { bus_input_context_set_engine (context, engine); - bus_input_context_enable (context); + if (is_enabled) { + bus_input_context_enable (context); + } g_object_unref (engine); } -- 1.7.5.4