From 48fb145b56e44c3fa8d2dd84161d268892b823e0 Mon Sep 17 00:00:00 2001 From: Takao Fujiwara Date: Apr 19 2011 03:14:20 +0000 Subject: Fixed Bug 696481 - no the variant maps without language codes - Updated to 1.3.99.20110408 - Added ibus-xx-setup-frequent-lang.patch - Updated ibus-541492-xkb.patch - Added dependency of imsettings-gnome. Fixed Bug 696510 - need a dependency in ibus-gtk3 for imsettings-gnome --- diff --git a/.gitignore b/.gitignore index c2a4fe2..fa5a886 100644 --- a/.gitignore +++ b/.gitignore @@ -8,8 +8,7 @@ ibus-1.3.6.tar.gz /ibus-1.3.99.20110117.tar.gz /ibus-1.3.99.20110127.tar.gz /ibus-1.3.99.20110206.tar.gz -/ibus-ui-gjs-plugins-20110214.tar.bz2 /ibus-1.3.99.20110228.tar.gz +/ibus-1.3.99.20110408.tar.gz /gnome-shell-ibus-plugins-20110317.tar.bz2 -/ibus-icons-20110325.tar.bz2 -/ibus-po-20110404.tar.bz2 +/ibus_master_da.po diff --git a/ibus-435880-surrounding-text.patch b/ibus-435880-surrounding-text.patch index acd40b2..2bde53c 100644 --- a/ibus-435880-surrounding-text.patch +++ b/ibus-435880-surrounding-text.patch @@ -1,369 +1,69 @@ -From 27788fb3bf62411c2b13d24bac45eb060483162f Mon Sep 17 00:00:00 2001 +From c72e8177099fb9079e2f295c0bb2118b998cb0e8 Mon Sep 17 00:00:00 2001 From: Daiki Ueno -Date: Tue, 8 Feb 2011 18:27:00 +0900 -Subject: [PATCH] Support surrounding-text retrieval. +Date: Wed, 13 Apr 2011 16:26:54 +0900 +Subject: [PATCH] Backport caps feature from the Fedora internal patch. -This change adds a new API function ibus_engine_get_surrounding_text(). -In the implementation, engines do not proactively requests surrounding-text to -target applications via the GTK+ client (IBusIMContext) every time the -function is called. Instead, IBusIMContext retrieves surrounding-text when -certain events occur in the input context (IBusInputContext) and maintains -it within the input context. - -This logic is similar to Qt's QInputContext. The following events trigger -surrounding-text retrieval: - -- focus_in -- commit_text -- show_preedit_text -- (just before) process_key_event - -Also, -- destroy -resets the current surrounding-text. --- - bus/engineproxy.c | 43 ++++++++++++ - bus/engineproxy.h | 11 +++ - bus/inputcontext.c | 36 ++++++++++ - client/gtk2/ibusimcontext.c | 138 ++++++++++++++++++++++++++++++++++----- - configure.ac | 14 ++++ - ibus/engine.py | 6 ++ - ibus/interface/iengine.py | 3 + - ibus/interface/iinputcontext.py | 5 ++ - src/ibusengine.c | 138 +++++++++++++++++++++++++++++++++++++++ - src/ibusengine.h | 21 ++++++- - src/ibusenginedesc.c | 132 +++++++++++++++++++++++++++++++++++++ - src/ibusenginedesc.h | 11 +++ - src/ibusinputcontext.c | 91 +++++++++++++++++++++++++ - src/ibusinputcontext.h | 11 +++ - src/ibusmarshalers.list | 1 + - 15 files changed, 644 insertions(+), 17 deletions(-) + client/gtk2/ibusimcontext.c | 34 ++++++++++- + src/ibusenginedesc.c | 132 +++++++++++++++++++++++++++++++++++++++++++ + src/ibusenginedesc.h | 11 ++++ + 3 files changed, 173 insertions(+), 4 deletions(-) -diff --git a/bus/engineproxy.c b/bus/engineproxy.c -index f808727..b35933f 100644 ---- a/bus/engineproxy.c -+++ b/bus/engineproxy.c -@@ -47,6 +47,10 @@ struct _BusEngineProxy { - /* a key mapping for the engine that converts keycode into keysym. the mapping is used only when use_sys_layout is FALSE. */ - IBusKeymap *keymap; - /* private member */ -+ -+ /* surrounding text */ -+ IBusText *surrounding_text; -+ guint surrounding_cursor_pos; - }; - - struct _BusEngineProxyClass { -@@ -83,6 +87,8 @@ enum { - - static guint engine_signals[LAST_SIGNAL] = { 0 }; - -+static IBusText *text_empty = NULL; -+ - /* functions prototype */ - static void bus_engine_proxy_set_property (BusEngineProxy *engine, - guint prop_id, -@@ -330,11 +336,16 @@ bus_engine_proxy_class_init (BusEngineProxyClass *class) - G_TYPE_NONE, - 1, - IBUS_TYPE_PROPERTY); -+ -+ text_empty = ibus_text_new_from_static_string (""); -+ g_object_ref_sink (text_empty); - } - - static void - bus_engine_proxy_init (BusEngineProxy *engine) - { -+ engine->surrounding_text = g_object_ref_sink (text_empty); -+ engine->surrounding_cursor_pos = 0; - } - - static void -@@ -393,6 +404,11 @@ bus_engine_proxy_real_destroy (IBusProxy *proxy) - engine->keymap = NULL; - } - -+ if (engine->surrounding_text) { -+ g_object_unref (engine->surrounding_text); -+ engine->surrounding_text = NULL; -+ } -+ - IBUS_PROXY_CLASS (bus_engine_proxy_parent_class)->destroy ((IBusProxy *)engine); - } - -@@ -950,6 +966,33 @@ void bus_engine_proxy_property_hide (BusEngineProxy *engine, - NULL); - } - -+void bus_engine_proxy_set_surrounding_text (BusEngineProxy *engine, -+ IBusText *text, -+ guint cursor_pos) -+{ -+ g_assert (BUS_IS_ENGINE_PROXY (engine)); -+ g_assert (text != NULL); -+ -+ if (!engine->surrounding_text || -+ g_strcmp0 (text->text, engine->surrounding_text->text) != 0 || -+ cursor_pos != engine->surrounding_cursor_pos) { -+ GVariant *variant = ibus_serializable_serialize ((IBusSerializable *)text); -+ if (engine->surrounding_text) -+ g_object_unref (engine->surrounding_text); -+ engine->surrounding_text = (IBusText *) g_object_ref_sink (text); -+ engine->surrounding_cursor_pos = cursor_pos; -+ -+ g_dbus_proxy_call ((GDBusProxy *)engine, -+ "SetSurroundingText", -+ g_variant_new ("(vu)", variant, cursor_pos), -+ G_DBUS_CALL_FLAGS_NONE, -+ -1, -+ NULL, -+ NULL, -+ NULL); -+ } -+} -+ - /* a macro to generate a function to call a nullary D-Bus method. */ - #define DEFINE_FUNCTION(Name, name) \ - void \ -diff --git a/bus/engineproxy.h b/bus/engineproxy.h -index 2a82fc6..0680917 100644 ---- a/bus/engineproxy.h -+++ b/bus/engineproxy.h -@@ -212,5 +212,16 @@ void bus_engine_proxy_property_hide (BusEngineProxy *engine, - */ - gboolean bus_engine_proxy_is_enabled (BusEngineProxy *engine); - -+/** -+ * bus_engine_proxy_set_surrounding_text: -+ * -+ * Call "SetSurroundingText" method of an engine asynchronously. -+ */ -+void bus_engine_proxy_set_surrounding_text -+ (BusEngineProxy *engine, -+ IBusText *text, -+ guint cursor_pos); -+ -+ - G_END_DECLS - #endif -diff --git a/bus/inputcontext.c b/bus/inputcontext.c -index 32d51e8..20f561c 100644 ---- a/bus/inputcontext.c -+++ b/bus/inputcontext.c -@@ -247,6 +247,11 @@ static const gchar introspection_xml[] = - " " - " " - " " -+ " " -+ " " -+ " " -+ " " -+ - /* signals */ - " " - " " -@@ -961,6 +966,32 @@ _ic_get_engine (BusInputContext *context, - * Handle a D-Bus method call whose destination and interface name are both "org.freedesktop.IBus.InputContext" - */ - static void -+_ic_set_surrounding_text (BusInputContext *context, -+ GVariant *parameters, -+ GDBusMethodInvocation *invocation) -+{ -+ GVariant *variant = NULL; -+ IBusText *text; -+ guint cursor_pos = 0; -+ -+ g_variant_get (parameters, "(vu)", &variant, &cursor_pos); -+ text = IBUS_TEXT (ibus_serializable_deserialize (variant)); -+ g_variant_unref (variant); -+ -+ if ((context->capabilities & IBUS_CAP_SURROUNDING_TEXT) && -+ context->has_focus && context->enabled && context->engine) { -+ bus_engine_proxy_set_surrounding_text (context->engine, -+ text, -+ cursor_pos); -+ } -+ -+ if (g_object_is_floating (text)) -+ g_object_unref (text); -+ -+ g_dbus_method_invocation_return_value (invocation, NULL); -+} -+ -+static void - bus_input_context_service_method_call (IBusService *service, - GDBusConnection *connection, - const gchar *sender, -@@ -999,6 +1030,7 @@ bus_input_context_service_method_call (IBusService *service, - { "IsEnabled", _ic_is_enabled }, - { "SetEngine", _ic_set_engine }, - { "GetEngine", _ic_get_engine }, -+ { "SetSurroundingText", _ic_set_surrounding_text}, - }; - - gint i; -@@ -2059,6 +2091,10 @@ bus_input_context_set_engine (BusInputContext *context, - bus_engine_proxy_set_cursor_location (context->engine, context->x, context->y, context->w, context->h); - } - } -+ bus_input_context_emit_signal (context, -+ "EngineChanged", -+ NULL, -+ NULL); - g_signal_emit (context, - context_signals[ENGINE_CHANGED], - 0); diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c -index a4e46cb..d029b5c 100644 +index dc3640e..0ac1b70 100644 --- a/client/gtk2/ibusimcontext.c +++ b/client/gtk2/ibusimcontext.c -@@ -27,6 +27,7 @@ - #include - #include - #include -+#include - #include "ibusimcontext.h" - - #if !GTK_CHECK_VERSION (2, 91, 0) -@@ -60,7 +61,8 @@ struct _IBusIMContext { +@@ -61,6 +61,7 @@ struct _IBusIMContext { gboolean has_focus; guint32 time; -- gint caps; + guint supported_caps; -+ guint caps; - }; + gint caps; - struct _IBusIMContextClass { -@@ -111,11 +113,18 @@ static void ibus_im_context_set_cursor_location - static void ibus_im_context_set_use_preedit - (GtkIMContext *context, - gboolean use_preedit); -+static void ibus_im_context_set_surrounding -+ (GtkIMContext *slave, -+ const gchar *text, -+ gint len, -+ gint cursor_index); -+ - - /* static methods*/ - static void _create_input_context (IBusIMContext *context); - static void _set_cursor_location_internal - (GtkIMContext *context); -+static void _negotiate_capabilities (IBusIMContext *context); - - static void _bus_connected_cb (IBusBus *bus, - IBusIMContext *context); -@@ -129,14 +138,15 @@ static void _slave_preedit_start_cb (GtkIMContext *slave, - IBusIMContext *context); - static void _slave_preedit_end_cb (GtkIMContext *slave, - IBusIMContext *context); --static void _slave_retrieve_surrounding_cb -+static gboolean _slave_retrieve_surrounding_cb - (GtkIMContext *slave, -- IBusIMContext *context); --static void _slave_delete_surrounding_cb -+ IBusIMContext *context); -+static gboolean _slave_delete_surrounding_cb - (GtkIMContext *slave, -- gint offset_from_cursor, -- guint nchars, -- IBusIMContext *context); -+ gint offset_from_cursor, -+ guint nchars, -+ IBusIMContext *context); -+static void _request_surrounding_text (IBusIMContext *context); + /* cancellable */ +@@ -150,6 +151,7 @@ static gboolean _slave_delete_surrounding_cb + static void _request_surrounding_text (IBusIMContext *context, + gboolean force); static void _create_fake_input_context (void); ++static void _negotiate_capabilities (IBusIMContext *context); -@@ -248,6 +258,17 @@ _process_key_event_done (GObject *object, - } - - -+static void -+_request_surrounding_text (IBusIMContext *context) -+{ -+ if (context->enable && -+ (context->caps & IBUS_CAP_SURROUNDING_TEXT)) { -+ gboolean return_value; -+ g_signal_emit (context, _signal_retrieve_surrounding_id, 0, -+ &return_value); -+ } -+} -+ - static gint - _key_snooper_cb (GtkWidget *widget, - GdkEventKey *event, -@@ -334,6 +355,8 @@ _key_snooper_cb (GtkWidget *widget, - - } while (0); - -+ _request_surrounding_text (ibusimcontext); -+ - if (ibusimcontext != NULL) { - ibusimcontext->time = event->time; - } -@@ -430,6 +453,7 @@ ibus_im_context_class_init (IBusIMContextClass *class) - im_context_class->set_client_window = ibus_im_context_set_client_window; - im_context_class->set_cursor_location = ibus_im_context_set_cursor_location; - im_context_class->set_use_preedit = ibus_im_context_set_use_preedit; -+ im_context_class->set_surrounding = ibus_im_context_set_surrounding; - gobject_class->finalize = ibus_im_context_finalize; - _signal_commit_id = -@@ -577,7 +601,12 @@ ibus_im_context_init (GObject *obj) - ibusimcontext->ibuscontext = NULL; +@@ -580,10 +582,11 @@ ibus_im_context_init (GObject *obj) ibusimcontext->has_focus = FALSE; ibusimcontext->time = GDK_CURRENT_TIME; + #ifdef ENABLE_SURROUNDING - ibusimcontext->caps = IBUS_CAP_PREEDIT_TEXT | IBUS_CAP_FOCUS | IBUS_CAP_SURROUNDING_TEXT; -+#ifdef ENABLE_SURROUNDING + ibusimcontext->supported_caps = IBUS_CAP_PREEDIT_TEXT | IBUS_CAP_FOCUS | IBUS_CAP_SURROUNDING_TEXT; -+#else + #else +- ibusimcontext->caps = IBUS_CAP_PREEDIT_TEXT | IBUS_CAP_FOCUS; + ibusimcontext->supported_caps = IBUS_CAP_PREEDIT_TEXT | IBUS_CAP_FOCUS; -+#endif + #endif + ibusimcontext->caps = ibusimcontext->supported_caps; // Create slave im context -@@ -674,6 +703,8 @@ ibus_im_context_filter_keypress (GtkIMContext *context, - if (ibusimcontext->client_window == NULL && event->window != NULL) - gtk_im_context_set_client_window ((GtkIMContext *)ibusimcontext, event->window); - -+ _request_surrounding_text (ibusimcontext); -+ - if (ibusimcontext != NULL) { - ibusimcontext->time = event->time; - } -@@ -768,6 +799,8 @@ ibus_im_context_focus_in (GtkIMContext *context) - (gpointer *) &_focus_im_context); - _focus_im_context = context; - } -+ -+ _request_surrounding_text (ibusimcontext); - } - - static void -@@ -925,6 +958,25 @@ ibus_im_context_set_cursor_location (GtkIMContext *context, GdkRectangle *area) +@@ -930,6 +933,27 @@ ibus_im_context_set_cursor_location (GtkIMContext *context, GdkRectangle *area) } static void +_negotiate_capabilities (IBusIMContext *context) +{ -+ IBusEngineDesc *engine; -+ -+ engine = ibus_input_context_get_engine (context->ibuscontext); -+ if (engine) { -+ context->caps = context->supported_caps & -+ ibus_engine_desc_get_requires (engine); -+ ibus_input_context_set_capabilities (context->ibuscontext, -+ context->caps); ++ if (context->enable) { ++ IBusEngineDesc *engine = ++ ibus_input_context_get_engine (context->ibuscontext); ++ ++ if (engine) { ++ context->caps = context->supported_caps & ++ ibus_engine_desc_get_requires (engine); ++ ibus_input_context_set_capabilities (context->ibuscontext, ++ context->caps); + IDEBUG ("engine %s: supported caps = %u, engine wants = %u, caps = %u", -+ ibus_engine_desc_get_name (engine) ++ ibus_engine_desc_get_name (engine), + context->supported_caps, + ibus_engine_desc_get_requires (engine), + context->caps); ++ } + } +} + @@ -371,7 +71,7 @@ index a4e46cb..d029b5c 100644 ibus_im_context_set_use_preedit (GtkIMContext *context, gboolean use_preedit) { IDEBUG ("%s", __FUNCTION__); -@@ -933,17 +985,50 @@ ibus_im_context_set_use_preedit (GtkIMContext *context, gboolean use_preedit) +@@ -938,11 +962,12 @@ ibus_im_context_set_use_preedit (GtkIMContext *context, gboolean use_preedit) if(ibusimcontext->ibuscontext) { if (use_preedit) { @@ -382,493 +82,18 @@ index a4e46cb..d029b5c 100644 - ibusimcontext->caps &= ~IBUS_CAP_PREEDIT_TEXT; + ibusimcontext->supported_caps &= ~IBUS_CAP_PREEDIT_TEXT; } -- ibus_input_context_set_capabilities (ibusimcontext->ibuscontext, ibusimcontext->caps); + _negotiate_capabilities (ibusimcontext); } gtk_im_context_set_use_preedit (ibusimcontext->slave, use_preedit); } - - static void -+ibus_im_context_set_surrounding (GtkIMContext *context, -+ const gchar *text, -+ gint len, -+ gint cursor_index) -+{ -+ g_return_if_fail (context != NULL); -+ g_return_if_fail (IBUS_IS_IM_CONTEXT (context)); -+ g_return_if_fail (text != NULL); -+ g_return_if_fail (strlen (text) >= len); -+ g_return_if_fail (0 <= cursor_index && cursor_index <= len); -+ -+ IBusIMContext *ibusimcontext = IBUS_IM_CONTEXT (context); -+ -+ if (ibusimcontext->enable && ibusimcontext->ibuscontext) { -+ IBusText *ibustext; -+ guint cursor_pos; -+ gchar *p; -+ -+ p = g_strndup (text, len); -+ cursor_pos = g_utf8_strlen (p, cursor_index); -+ ibustext = ibus_text_new_from_string (p); -+ g_free (p); -+ ibus_input_context_set_surrounding_text (ibusimcontext->ibuscontext, -+ ibustext, -+ cursor_pos); -+ } -+ gtk_im_context_set_surrounding (ibusimcontext->slave, -+ text, -+ len, -+ cursor_index); -+} -+ -+static void - _bus_connected_cb (IBusBus *bus, - IBusIMContext *ibusimcontext) - { -@@ -962,6 +1047,8 @@ _ibus_context_commit_text_cb (IBusInputContext *ibuscontext, +@@ -1320,6 +1345,7 @@ _ibus_context_enabled_cb (IBusInputContext *ibuscontext, IDEBUG ("%s", __FUNCTION__); - g_signal_emit (ibusimcontext, _signal_commit_id, 0, text->text); -+ -+ _request_surrounding_text (ibusimcontext); - } - - static gboolean -@@ -1256,6 +1343,8 @@ _ibus_context_show_preedit_text_cb (IBusInputContext *ibuscontext, - ibusimcontext->preedit_visible = TRUE; - g_signal_emit (ibusimcontext, _signal_preedit_start_id, 0); - g_signal_emit (ibusimcontext, _signal_preedit_changed_id, 0); -+ -+ _request_surrounding_text (ibusimcontext); - } - - static void -@@ -1321,6 +1410,14 @@ _ibus_context_destroy_cb (IBusInputContext *ibuscontext, - } - - static void -+_ibus_context_engine_changed_cb (IBusInputContext *ibuscontext, -+ IBusIMContext *ibusimcontext) -+{ -+ IDEBUG ("%s", __FUNCTION__); + ibusimcontext->enable = TRUE; + _negotiate_capabilities (ibusimcontext); -+} -+ -+static void - _create_input_context (IBusIMContext *ibusimcontext) - { - IDEBUG ("%s", __FUNCTION__); -@@ -1363,6 +1460,10 @@ _create_input_context (IBusIMContext *ibusimcontext) - "disabled", - G_CALLBACK (_ibus_context_disabled_cb), - ibusimcontext); -+ g_signal_connect (ibusimcontext->ibuscontext, -+ "engine-changed", -+ G_CALLBACK (_ibus_context_engine_changed_cb), -+ ibusimcontext); - g_signal_connect (ibusimcontext->ibuscontext, "destroy", - G_CALLBACK (_ibus_context_destroy_cb), - ibusimcontext); -@@ -1419,17 +1520,21 @@ _slave_preedit_end_cb (GtkIMContext *slave, - g_signal_emit (ibusimcontext, _signal_preedit_end_id, 0); - } - --static void -+static gboolean - _slave_retrieve_surrounding_cb (GtkIMContext *slave, - IBusIMContext *ibusimcontext) - { -+ gboolean return_value; -+ - if (ibusimcontext->enable && ibusimcontext->ibuscontext) { -- return; -+ return FALSE; - } -- g_signal_emit (ibusimcontext, _signal_retrieve_surrounding_id, 0); -+ g_signal_emit (ibusimcontext, _signal_retrieve_surrounding_id, 0, -+ &return_value); -+ return return_value; - } - --static void -+static gboolean - _slave_delete_surrounding_cb (GtkIMContext *slave, - gint offset_from_cursor, - guint nchars, -@@ -1438,9 +1543,10 @@ _slave_delete_surrounding_cb (GtkIMContext *slave, - gboolean return_value; - - if (ibusimcontext->enable && ibusimcontext->ibuscontext) { -- return; -+ return FALSE; - } - g_signal_emit (ibusimcontext, _signal_delete_surrounding_id, 0, offset_from_cursor, nchars, &return_value); -+ return return_value; - } - - #ifdef OS_CHROMEOS -diff --git a/configure.ac b/configure.ac -index 81efe81..e5fe925 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -364,6 +364,19 @@ AC_ARG_WITH(sync-mode-apps, - AC_DEFINE_UNQUOTED(SYNC_MODE_APPS, "$SYNC_MODE_APPS", - [Enbale sync mode in those applications]) - -+# option for enable surrounding-text -+AC_ARG_ENABLE(surrounding-text, -+ AS_HELP_STRING([--enable-surrounding-text], -+ [Enable surrounding-text support]), -+ [enable_surrounding_text=$enableval], -+ [enable_surrounding_text=no] -+) -+if test x"$enable_surrounding_text" = x"yes"; then -+ AC_DEFINE(ENABLE_SURROUNDING, TRUE, [Enable surrounding-text support]) -+else -+ enable_surrounding_text="no (disabled, use --enable-surrounding-text to enable)" -+fi -+ - # check iso-codes - PKG_CHECK_MODULES(ISOCODES, [ - iso-codes -@@ -435,5 +448,6 @@ Build options: - Enable key snooper $enable_key_snooper - Sync mode regexes "$SYNC_MODE_APPS" - No snooper regexes "$NO_SNOOPER_APPS" -+ Enable surrounding-text $enable_surrounding_text - ]) - -diff --git a/ibus/engine.py b/ibus/engine.py -index b1df2fe..ec42fa4 100644 ---- a/ibus/engine.py -+++ b/ibus/engine.py -@@ -46,6 +46,9 @@ class EngineBase(object.Object): - def set_cursor_location(self, x, y, w, h): - pass - -+ def set_surrounding_text(self, text, cursor_index): -+ pass -+ - def set_capabilities(self, cap): - pass - -@@ -163,6 +166,9 @@ class EngineProxy(interface.IEngine): - def SetCursorLocation(self, x, y, w, h): - return self.__engine.set_cursor_location(x, y, w, h) - -+ def SetSurroundingText(self, text, cursor_index): -+ return self.__engine.set_surrounding_text(text, cursor_index) -+ - def SetCapabilities(self, caps): - return self.__engine.set_capabilities(caps) - -diff --git a/ibus/interface/iengine.py b/ibus/interface/iengine.py -index 2386c0f..5db2012 100644 ---- a/ibus/interface/iengine.py -+++ b/ibus/interface/iengine.py -@@ -50,6 +50,9 @@ class IEngine(dbus.service.Object): - @method(in_signature="iiii") - def SetCursorLocation(self, x, y, w, h): pass - -+ @method(in_signature="vu") -+ def SetSurroundingText(self, text, cursor_index): pass -+ - @method(in_signature="u") - def SetCapabilities(self, cap): pass - -diff --git a/ibus/interface/iinputcontext.py b/ibus/interface/iinputcontext.py -index 89f6dbd..bb25c5a 100644 ---- a/ibus/interface/iinputcontext.py -+++ b/ibus/interface/iinputcontext.py -@@ -49,6 +49,9 @@ class IInputContext(dbus.service.Object): - @method(in_signature="iiii") - def SetCursorLocation(self, x, y, w, h): pass - -+ @method(in_signature="vu") -+ def SetSurroundingText(self, text, cursor_index): pass -+ - @method() - def FocusIn(self): pass - -@@ -137,4 +140,6 @@ class IInputContext(dbus.service.Object): - @signal(signature="v") - def UpdateProperty(self, prop): pass - -+ @signal() -+ def EngineChanged(self): pass - -diff --git a/src/ibusengine.c b/src/ibusengine.c -index 519d7ca..fc129a2 100644 ---- a/src/ibusengine.c -+++ b/src/ibusengine.c -@@ -45,6 +45,7 @@ enum { - PROPERTY_SHOW, - PROPERTY_HIDE, - CANDIDATE_CLICKED, -+ SET_SURROUNDING_TEXT, - LAST_SIGNAL, - }; - -@@ -58,10 +59,15 @@ enum { - struct _IBusEnginePrivate { - gchar *engine_name; - GDBusConnection *connection; -+ -+ IBusText *surrounding_text; -+ guint surrounding_cursor_pos; - }; - - static guint engine_signals[LAST_SIGNAL] = { 0 }; - -+static IBusText *text_empty = NULL; -+ - /* functions prototype */ - static void ibus_engine_destroy (IBusEngine *engine); - static void ibus_engine_set_property (IBusEngine *engine, -@@ -135,6 +141,10 @@ static void ibus_engine_property_show (IBusEngine *engine, - const gchar *prop_name); - static void ibus_engine_property_hide (IBusEngine *engine, - const gchar *prop_name); -+static void ibus_engine_set_surrounding_text -+ (IBusEngine *engine, -+ IBusText *text, -+ guint cursor_pos); - static void ibus_engine_emit_signal (IBusEngine *engine, - const gchar *signal_name, - GVariant *parameters); -@@ -185,6 +195,10 @@ static const gchar introspection_xml[] = - " " - " " - " " -+ " " -+ " " -+ " " -+ " " - /* FIXME signals */ - " " - " " -@@ -250,6 +264,7 @@ ibus_engine_class_init (IBusEngineClass *class) - class->property_hide = ibus_engine_property_hide; - class->set_cursor_location = ibus_engine_set_cursor_location; - class->set_capabilities = ibus_engine_set_capabilities; -+ class->set_surrounding_text = ibus_engine_set_surrounding_text; - - /* install properties */ - /** -@@ -616,12 +631,39 @@ ibus_engine_class_init (IBusEngineClass *class) - G_TYPE_STRING); - - g_type_class_add_private (class, sizeof (IBusEnginePrivate)); -+ -+ /** -+ * IBusEngine::set-surrounding-text: -+ * @engine: An IBusEngine. -+ * -+ * Emitted when a surrounding text is set. -+ * Implement the member function set_surrounding_text() in extended class to receive this signal. -+ * -+ * Argument @user_data is ignored in this function. -+ */ -+ engine_signals[SET_SURROUNDING_TEXT] = -+ g_signal_new (I_("set-surrounding-text"), -+ G_TYPE_FROM_CLASS (gobject_class), -+ G_SIGNAL_RUN_LAST, -+ G_STRUCT_OFFSET (IBusEngineClass, set_surrounding_text), -+ NULL, NULL, -+ _ibus_marshal_VOID__OBJECT_UINT, -+ G_TYPE_NONE, -+ 2, -+ G_TYPE_OBJECT, -+ G_TYPE_UINT); -+ -+ text_empty = ibus_text_new_from_static_string (""); -+ g_object_ref_sink (text_empty); - } - - static void - ibus_engine_init (IBusEngine *engine) - { - engine->priv = IBUS_ENGINE_GET_PRIVATE (engine); -+ -+ engine->priv->surrounding_text = g_object_ref_sink (text_empty); -+ engine->priv->surrounding_cursor_pos = 0; - } - - static void -@@ -630,6 +672,11 @@ ibus_engine_destroy (IBusEngine *engine) - g_free (engine->priv->engine_name); - engine->priv->engine_name = NULL; - -+ if (engine->priv->surrounding_text) { -+ g_object_unref (engine->priv->surrounding_text); -+ engine->priv->surrounding_text = NULL; -+ } -+ - IBUS_OBJECT_CLASS(ibus_engine_parent_class)->destroy (IBUS_OBJECT (engine)); - } - -@@ -801,6 +848,25 @@ ibus_engine_service_method_call (IBusService *service, - return; - } - -+ if (g_strcmp0 (method_name, "SetSurroundingText") == 0) { -+ GVariant *variant = NULL; -+ IBusText *text; -+ guint cursor_pos; -+ -+ g_variant_get (parameters, "(vu)", &variant, &cursor_pos); -+ text = IBUS_TEXT (ibus_serializable_deserialize (variant)); -+ g_variant_unref (variant); -+ -+ g_signal_emit (engine, engine_signals[SET_SURROUNDING_TEXT], 0, -+ text, -+ cursor_pos); -+ if (g_object_is_floating (text)) { -+ g_object_unref (text); -+ } -+ g_dbus_method_invocation_return_value (invocation, NULL); -+ return; -+ } -+ - /* should not be reached */ - g_return_if_reached (); - } -@@ -955,6 +1021,26 @@ ibus_engine_property_hide (IBusEngine *engine, const gchar *prop_name) - } - - static void -+ibus_engine_set_surrounding_text (IBusEngine *engine, -+ IBusText *text, -+ guint cursor_pos) -+{ -+ g_assert (IBUS_IS_ENGINE (engine)); -+ -+ IBusEnginePrivate *priv; -+ -+ priv = IBUS_ENGINE_GET_PRIVATE (engine); -+ -+ if (priv->surrounding_text) { -+ g_object_unref (priv->surrounding_text); -+ } -+ -+ priv->surrounding_text = (IBusText *) g_object_ref_sink (text ? text : text_empty); -+ priv->surrounding_cursor_pos = cursor_pos; -+ // g_debug ("set-surrounding-text ('%s', %d)", text->text, cursor_pos); -+} -+ -+static void - ibus_engine_emit_signal (IBusEngine *engine, - const gchar *signal_name, - GVariant *parameters) -@@ -1138,14 +1224,66 @@ void ibus_engine_delete_surrounding_text (IBusEngine *engine, - gint offset_from_cursor, - guint nchars) - { -+ IBusEnginePrivate *priv; -+ - g_return_if_fail (IBUS_IS_ENGINE (engine)); - -+ priv = IBUS_ENGINE_GET_PRIVATE (engine); -+ -+ /* Update surrounding-text cache. This is necessary since some -+ engines call ibus_engine_get_surrounding_text() immediately -+ after ibus_engine_delete_surrounding_text(). */ -+ if (priv->surrounding_text) { -+ IBusText *text; -+ glong cursor_pos, len; -+ -+ cursor_pos = priv->surrounding_cursor_pos + offset_from_cursor; -+ len = ibus_text_get_length (priv->surrounding_text); -+ if (cursor_pos >= 0 && len - cursor_pos >= nchars) { -+ gunichar *ucs; -+ -+ ucs = g_utf8_to_ucs4_fast (priv->surrounding_text->text, -+ -1, -+ NULL); -+ memmove (&ucs[cursor_pos], -+ &ucs[cursor_pos + nchars], -+ sizeof(gunichar) * (len - cursor_pos - nchars)); -+ ucs[len - nchars] = 0; -+ text = ibus_text_new_from_ucs4 (ucs); -+ g_free (ucs); -+ priv->surrounding_cursor_pos = cursor_pos; -+ } else { -+ text = text_empty; -+ priv->surrounding_cursor_pos = 0; -+ } -+ -+ g_object_unref (priv->surrounding_text); -+ priv->surrounding_text = g_object_ref_sink (text); -+ } -+ - ibus_engine_emit_signal (engine, - "DeleteSurroundingText", - g_variant_new ("(iu)", offset_from_cursor, nchars)); - } - - void -+ibus_engine_get_surrounding_text (IBusEngine *engine, -+ IBusText **text, -+ guint *cursor_pos) -+{ -+ IBusEnginePrivate *priv; -+ -+ g_return_if_fail (IBUS_IS_ENGINE (engine)); -+ g_return_if_fail (text != NULL); -+ g_return_if_fail (cursor_pos != NULL); -+ -+ priv = IBUS_ENGINE_GET_PRIVATE (engine); -+ -+ *text = g_object_ref (priv->surrounding_text); -+ *cursor_pos = priv->surrounding_cursor_pos; -+} -+ -+void - ibus_engine_register_properties (IBusEngine *engine, - IBusPropList *prop_list) - { -diff --git a/src/ibusengine.h b/src/ibusengine.h -index 46d0a04..a5f5aea 100644 ---- a/src/ibusengine.h -+++ b/src/ibusengine.h -@@ -136,10 +136,14 @@ struct _IBusEngineClass { - guint index, - guint button, - guint state); -+ void (* set_surrounding_text) -+ (IBusEngine *engine, -+ IBusText *text, -+ guint cursor_index); - /*< private >*/ - /* padding */ -- gpointer pdummy[8]; -+ gpointer pdummy[7]; - }; - - GType ibus_engine_get_type (void); -@@ -394,6 +398,21 @@ void ibus_engine_delete_surrounding_text(IBusEngine *engine, - guint nchars); - - /** -+ * ibus_engine_get_surrounding_text: -+ * @engine: An IBusEngine. -+ * @text: Location to store surrounding text. -+ * @cursor_pos: Cursor position in characters in @text. -+ * -+ * Get surrounding text. -+ * -+ * @see_also #IBusEngine::set-surrounding-text -+ */ -+void ibus_engine_get_surrounding_text(IBusEngine *engine, -+ IBusText **text, -+ guint *cursor_pos); -+ -+ -+/** - * ibus_engine_get_name: - * @engine: An IBusEngine. - * @returns: Name of IBusEngine. + /* retrieve the initial surrounding-text (regardless of whether + * the current IBus engine needs surrounding-text) */ diff --git a/src/ibusenginedesc.c b/src/ibusenginedesc.c index ca5ef60..956ce73 100644 --- a/src/ibusenginedesc.c @@ -1145,204 +370,6 @@ index 9718b15..209d460 100644 * ibus_engine_desc_output: * @info: An IBusEngineDesc * @output: XML-formatted Input method engine description. -diff --git a/src/ibusinputcontext.c b/src/ibusinputcontext.c -index f8f5848..9556df3 100644 ---- a/src/ibusinputcontext.c -+++ b/src/ibusinputcontext.c -@@ -28,6 +28,9 @@ - #include "ibuslookuptable.h" - #include "ibusproplist.h" - -+#define IBUS_INPUT_CONTEXT_GET_PRIVATE(o) \ -+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), IBUS_TYPE_INPUT_CONTEXT, IBusInputContextPrivate)) -+ - enum { - ENABLED, - DISABLED, -@@ -49,12 +52,25 @@ enum { - CURSOR_DOWN_LOOKUP_TABLE, - REGISTER_PROPERTIES, - UPDATE_PROPERTY, -+ ENGINE_CHANGED, - LAST_SIGNAL, - }; - -+/* BusInputContextPrivate */ -+struct _IBusInputContextPrivate { -+ /* surrounding text */ -+ IBusText *surrounding_text; -+ guint surrounding_cursor_pos; -+}; -+ -+typedef struct _IBusInputContextPrivate IBusInputContextPrivate; -+ - static guint context_signals[LAST_SIGNAL] = { 0 }; - -+static IBusText *text_empty = NULL; -+ - /* functions prototype */ -+static void ibus_input_context_real_destroy (IBusProxy *context); - static void ibus_input_context_g_signal (GDBusProxy *proxy, - const gchar *sender_name, - const gchar *signal_name, -@@ -65,8 +81,13 @@ G_DEFINE_TYPE (IBusInputContext, ibus_input_context, IBUS_TYPE_PROXY) - static void - ibus_input_context_class_init (IBusInputContextClass *class) - { -+ IBusProxyClass *ibus_proxy_class = IBUS_PROXY_CLASS (class); - GDBusProxyClass *g_dbus_proxy_class = G_DBUS_PROXY_CLASS (class); - -+ g_type_class_add_private (class, sizeof (IBusInputContextPrivate)); -+ -+ ibus_proxy_class->destroy = ibus_input_context_real_destroy; -+ - g_dbus_proxy_class->g_signal = ibus_input_context_g_signal; - - /* install signals */ -@@ -101,6 +122,21 @@ ibus_input_context_class_init (IBusInputContextClass *class) - G_TYPE_NONE, 0); - - /** -+ * IBusInputContext::engine-changed: -+ * @context: An IBusInputContext. -+ * -+ * Emitted when an IME is changed. -+ */ -+ context_signals[ENGINE_CHANGED] = -+ g_signal_new (I_("engine-changed"), -+ G_TYPE_FROM_CLASS (class), -+ G_SIGNAL_RUN_LAST, -+ 0, -+ NULL, NULL, -+ _ibus_marshal_VOID__VOID, -+ G_TYPE_NONE, 0); -+ -+ /** - * IBusInputContext::commit-text: - * @context: An IBusInputContext. - * @text: Text to be committed. -@@ -429,11 +465,33 @@ ibus_input_context_class_init (IBusInputContextClass *class) - G_TYPE_NONE, - 1, - IBUS_TYPE_PROPERTY); -+ -+ text_empty = ibus_text_new_from_static_string (""); -+ g_object_ref_sink (text_empty); - } - - static void - ibus_input_context_init (IBusInputContext *context) - { -+ IBusInputContextPrivate *priv; -+ -+ priv = IBUS_INPUT_CONTEXT_GET_PRIVATE (context); -+ priv->surrounding_text = g_object_ref_sink (text_empty); -+ priv->surrounding_cursor_pos = 0; -+} -+ -+static void -+ibus_input_context_real_destroy (IBusProxy *context) -+{ -+ IBusInputContextPrivate *priv; -+ priv = IBUS_INPUT_CONTEXT_GET_PRIVATE (IBUS_INPUT_CONTEXT (context)); -+ -+ if (priv->surrounding_text) { -+ g_object_unref (priv->surrounding_text); -+ priv->surrounding_text = NULL; -+ } -+ -+ IBUS_PROXY_CLASS(ibus_input_context_parent_class)->destroy (context); - } - - static void -@@ -463,6 +521,7 @@ ibus_input_context_g_signal (GDBusProxy *proxy, - { "PageDownLookupTable", PAGE_DOWN_LOOKUP_TABLE }, - { "CursorUpLookupTable", CURSOR_UP_LOOKUP_TABLE }, - { "CursorDownLookupTable", CURSOR_DOWN_LOOKUP_TABLE }, -+ { "EngineChanged", ENGINE_CHANGED }, - }; - - if (g_strcmp0 (signal_name, "CommitText") == 0) { -@@ -848,6 +907,38 @@ ibus_input_context_property_hide (IBusInputContext *context, - ); - } - -+void -+ibus_input_context_set_surrounding_text (IBusInputContext *context, -+ IBusText *text, -+ guint32 cursor_pos) -+{ -+ g_assert (IBUS_IS_INPUT_CONTEXT (context)); -+ g_assert (IBUS_IS_TEXT (text)); -+ -+ IBusInputContextPrivate *priv; -+ priv = IBUS_INPUT_CONTEXT_GET_PRIVATE (context); -+ -+ if (priv->surrounding_text == NULL || -+ g_strcmp0 (text->text, priv->surrounding_text->text) != 0 || -+ cursor_pos != priv->surrounding_cursor_pos) { -+ GVariant *variant = ibus_serializable_serialize ((IBusSerializable *)text); -+ if (priv->surrounding_text) -+ g_object_unref (priv->surrounding_text); -+ priv->surrounding_text = (IBusText *) g_object_ref_sink (text); -+ priv->surrounding_cursor_pos = cursor_pos; -+ -+ g_dbus_proxy_call ((GDBusProxy *) context, -+ "SetSurroundingText", /* method_name */ -+ g_variant_new ("(vu)", variant, cursor_pos), /* parameters */ -+ G_DBUS_CALL_FLAGS_NONE, /* flags */ -+ -1, /* timeout */ -+ NULL, /* cancellable */ -+ NULL, /* callback */ -+ NULL /* user_data */ -+ ); -+ } -+} -+ - gboolean - ibus_input_context_is_enabled (IBusInputContext *context) - { -diff --git a/src/ibusinputcontext.h b/src/ibusinputcontext.h -index 96fd00e..1f8ae86 100644 ---- a/src/ibusinputcontext.h -+++ b/src/ibusinputcontext.h -@@ -41,6 +41,7 @@ - - #include "ibusproxy.h" - #include "ibusenginedesc.h" -+#include "ibustext.h" - - /* - * Type macros. -@@ -324,6 +325,16 @@ IBusEngineDesc - void ibus_input_context_set_engine (IBusInputContext *context, - const gchar *name); - -+/** -+ * ibus_input_context_set_surrounding_text: -+ * @context: An IBusInputContext. -+ * @text: An IBusText surrounding the current cursor on the application. -+ * @cursor_po: Current cursor position in characters in @text. -+*/ -+void ibus_input_context_set_surrounding_text -+ (IBusInputContext *context, -+ IBusText *text, -+ guint32 cursor_pos); - - G_END_DECLS - #endif -diff --git a/src/ibusmarshalers.list b/src/ibusmarshalers.list -index 5184278..5dc7fc2 100644 ---- a/src/ibusmarshalers.list -+++ b/src/ibusmarshalers.list -@@ -13,6 +13,7 @@ VOID:INT,INT,INT,INT - VOID:UINT,UINT - VOID:INT,UINT - VOID:UINT,UINT,UINT -+VOID:OBJECT,UINT - VOID:OBJECT,UINT,BOOL - VOID:OBJECT,UINT,BOOL,UINT - VOID:OBJECT,BOOL -- -1.7.3.2 +1.7.4.2 diff --git a/ibus-530711-preload-sys.patch b/ibus-530711-preload-sys.patch index 9a4905b..b071d6e 100644 --- a/ibus-530711-preload-sys.patch +++ b/ibus-530711-preload-sys.patch @@ -30,7 +30,7 @@ diff --git a/bus/ibusimpl.c b/bus/ibusimpl.c index 8d4ec36..0caa8c7 100644 --- a/bus/ibusimpl.c +++ b/bus/ibusimpl.c -@@ -144,6 +144,9 @@ static void bus_ibus_impl_set_previous_engine +@@ -144,6 +144,9 @@ static void bus_ibus_impl_set_previo static void bus_ibus_impl_set_preload_engines (BusIBusImpl *ibus, GVariant *value); @@ -40,7 +40,7 @@ index 8d4ec36..0caa8c7 100644 static void bus_ibus_impl_set_use_sys_layout (BusIBusImpl *ibus, GVariant *value); -@@ -278,6 +281,141 @@ _panel_destroy_cb (BusPanelProxy *panel, +@@ -284,6 +287,142 @@ _panel_destroy_cb (BusPanelProxy *panel, g_object_unref (panel); } @@ -127,6 +127,7 @@ index 8d4ec36..0caa8c7 100644 + } + } + ++ bus_ibus_impl_check_global_engine (ibus); + bus_ibus_impl_update_engines_hotkey_profile (ibus); +} + @@ -182,7 +183,7 @@ index 8d4ec36..0caa8c7 100644 static void bus_ibus_impl_set_hotkey (BusIBusImpl *ibus, GQuark hotkey, -@@ -388,34 +526,50 @@ static void +@@ -394,35 +533,50 @@ static void bus_ibus_impl_set_preload_engines (BusIBusImpl *ibus, GVariant *value) { @@ -244,6 +245,7 @@ index 8d4ec36..0caa8c7 100644 + preload_engine_mode = _get_config_preload_engine_mode (ibus); } +- bus_ibus_impl_check_global_engine (ibus); - bus_ibus_impl_update_engines_hotkey_profile (ibus); + if (preload_engine_mode == IBUS_PRELOAD_ENGINE_MODE_USER) { + return; @@ -254,7 +256,7 @@ index 8d4ec36..0caa8c7 100644 } /** -@@ -496,89 +650,48 @@ bus_ibus_impl_set_use_global_engine (BusIBusImpl *ibus, +@@ -503,89 +657,48 @@ bus_ibus_impl_set_use_global_engine (Bus } } @@ -367,7 +369,7 @@ index 8d4ec36..0caa8c7 100644 #endif } -@@ -594,6 +707,7 @@ const static struct { +@@ -601,6 +714,7 @@ const static struct { { "general/hotkey", "next_engine_in_menu", bus_ibus_impl_set_next_engine_in_menu }, { "general/hotkey", "previous_engine", bus_ibus_impl_set_previous_engine }, { "general", "preload_engines", bus_ibus_impl_set_preload_engines }, @@ -403,18 +405,18 @@ diff --git a/ibus/common.py b/ibus/common.py index e105f18..20c0710 100644 --- a/ibus/common.py +++ b/ibus/common.py -@@ -33,6 +33,8 @@ __all__ = ( - "ORIENTATION_HORIZONTAL", - "ORIENTATION_VERTICAL", - "ORIENTATION_SYSTEM", +@@ -40,6 +40,8 @@ __all__ = ( + "BUS_REQUEST_NAME_REPLY_IN_QUEUE", + "BUS_REQUEST_NAME_REPLY_EXISTS", + "BUS_REQUEST_NAME_REPLY_ALREADY_OWNER", + "PRELOAD_ENGINE_MODE_USER", + "PRELOAD_ENGINE_MODE_LANG_RELATIVE", "default_reply_handler", "default_error_handler", "DEFAULT_ASYNC_HANDLERS", -@@ -132,6 +134,10 @@ ORIENTATION_HORIZONTAL = 0 - ORIENTATION_VERTICAL = 1 - ORIENTATION_SYSTEM = 2 +@@ -150,6 +152,10 @@ BUS_REQUEST_NAME_REPLY_IN_QUEUE = 2 + BUS_REQUEST_NAME_REPLY_EXISTS = 3 + BUS_REQUEST_NAME_REPLY_ALREADY_OWNER = 4 +# define preload engine mode +PRELOAD_ENGINE_MODE_USER = 0 @@ -539,8 +541,8 @@ diff --git a/src/ibustypes.h b/src/ibustypes.h index 035d124..0a9d7b2 100644 --- a/src/ibustypes.h +++ b/src/ibustypes.h -@@ -144,6 +144,16 @@ typedef enum { - } IBusOrientation; +@@ -177,6 +177,16 @@ typedef enum { + } IBusBusRequestNameReply; /** + * IBusPreloadEngineMode: diff --git a/ibus-541492-xkb.patch b/ibus-541492-xkb.patch index 3374c0f..9b64fe0 100644 --- a/ibus-541492-xkb.patch +++ b/ibus-541492-xkb.patch @@ -1723,9 +1723,9 @@ index 0000000..0d57a1a + layout_lang = xkbconfig.get_layout_lang() + variant_desc = xkbconfig.get_variant_desc() + for layout in layout_list.keys(): -+ if layout not in layout_lang: -+ continue -+ langs = layout_lang[layout] ++ langs = [] ++ if layout in layout_lang: ++ langs = layout_lang[layout] + for lang in langs: + engine = ibus.XKBConfigRegistry.engine_desc_new( + lang, diff --git a/ibus-657165-panel-libs.patch b/ibus-657165-panel-libs.patch deleted file mode 100644 index b7b5b73..0000000 --- a/ibus-657165-panel-libs.patch +++ /dev/null @@ -1,1445 +0,0 @@ -From 71689f16ab8d19045ed44f2609c90202a6bf5db7 Mon Sep 17 00:00:00 2001 -From: fujiwarat -Date: Fri, 4 Mar 2011 00:04:34 +0900 -Subject: [PATCH] Implement APIs for another non-Python panel. - -1. Support icon and prop_list = null in ibus_property_new with GIR. -2. Add getter methods in IBusText and IBusProperty since GJS cannot access - the members in C-Structure. -3. Add ibus_get_language_name() since GIR libxml2 does not provide the - useful APIs. -4. Implement flags in ibus_bus_request_name() to follow DBus - RequestName signal spec. - http://dbus.freedesktop.org/doc/dbus-specification.html#message-bus-names - This is needed to terminate the current IBus panel. - E.g. IBus GTK panel is launched by ibus-daemon but another panel is - launched by gnome-shell. -5. Support IBUS_BUS_NAME_FLAG_ALLOW_REPLACEMENT in ui/gtk/main.py -6. Fix bus_component_set_factory() not to call - bus_component_factory_destroy_cb() twice. -7. Hide ibus_text_new_from_static_string() for GIR. -8. Add ibus_is_running_gnome_shell() for ibus-ui-gtk because - gnome-shell runs earlier than ibus-ui-gtk. ---- - bus/component.c | 2 +- - bus/connection.c | 8 + - bus/connection.h | 12 +- - bus/dbusimpl.c | 480 +++++++++++++++++++++++++++++++++++++++++++-- - bus/marshalers.list | 3 +- - ibus/common.py | 24 +++- - src/Makefile.am | 2 + - src/ibusbus.c | 6 +- - src/ibusbus.h | 8 +- - src/ibusproperty.c | 24 +++ - src/ibusproperty.h | 85 ++++++++- - src/ibustext.c | 18 ++ - src/ibustext.h | 29 +++- - src/ibustypes.h | 33 +++ - src/ibusutil.c | 180 ++++++++++++++++ - src/ibusutil.h | 39 ++++ - ui/gtk/gtkpanel.xml.in.in | 2 +- - ui/gtk/main.py | 23 ++- - 18 files changed, 928 insertions(+), 39 deletions(-) - create mode 100644 src/ibusutil.c - create mode 100644 src/ibusutil.h - -diff --git a/bus/component.c b/bus/component.c -index c1ff85a..fdff9c3 100644 ---- a/bus/component.c -+++ b/bus/component.c -@@ -256,7 +256,7 @@ bus_component_set_factory (BusComponent *component, - } - - if (component->factory) { -- g_signal_handlers_disconnect_by_func (factory, -+ g_signal_handlers_disconnect_by_func (component->factory, - bus_component_factory_destroy_cb, - component); - g_object_unref (component->factory); -diff --git a/bus/connection.c b/bus/connection.c -index a3b4c9c..9e73213 100644 ---- a/bus/connection.c -+++ b/bus/connection.c -@@ -204,6 +204,14 @@ bus_connection_remove_name (BusConnection *connection, - return FALSE; - } - -+gboolean -+bus_connection_has_name (BusConnection *connection, -+ const gchar *name) -+{ -+ GList *list = g_list_find_custom (connection->names, name, (GCompareFunc) g_strcmp0); -+ return list != NULL; -+} -+ - GDBusConnection * - bus_connection_get_dbus_connection (BusConnection *connection) - { -diff --git a/bus/connection.h b/bus/connection.h -index df86036..2a34319 100644 ---- a/bus/connection.h -+++ b/bus/connection.h -@@ -85,7 +85,7 @@ const gchar *bus_connection_add_name (BusConnection *connect - const gchar *name); - - /** -- * bus_connection_add_name: -+ * bus_connection_remove_name: - * @name: a well-known name for the connection. - * @returns: TRUE on success. - * -@@ -95,6 +95,16 @@ gboolean bus_connection_remove_name (BusConnection *connect - const gchar *name); - - /** -+ * bus_connection_has_name: -+ * @name: a well-known name for the connection. -+ * @returns: TRUE if found the name. -+ * -+ * Lookup the well-known name from the connection. -+ */ -+gboolean bus_connection_has_name (BusConnection *connection, -+ const gchar *name); -+ -+/** - * bus_connection_get_dbus_connection: - * - * Get the underlying GDBus connection. -diff --git a/bus/dbusimpl.c b/bus/dbusimpl.c -index 48dbd42..8002bac 100644 ---- a/bus/dbusimpl.c -+++ b/bus/dbusimpl.c -@@ -27,6 +27,8 @@ - - enum { - NAME_OWNER_CHANGED, -+ NAME_LOST, -+ NAME_ACQUIRED, - LAST_SIGNAL, - }; - -@@ -68,6 +70,14 @@ struct _BusDBusImplClass { - gchar *name, - gchar *old_name, - gchar *new_name); -+ -+ void (* name_lost) (BusDBusImpl *dbus, -+ BusConnection *connection, -+ gchar *name); -+ -+ void (* name_acquired) (BusDBusImpl *dbus, -+ BusConnection *connection, -+ gchar *name); - }; - - typedef struct _BusDispatchData BusDispatchData; -@@ -76,6 +86,19 @@ struct _BusDispatchData { - BusConnection *skip_connection; - }; - -+typedef struct _BusNameService BusNameService; -+struct _BusNameService { -+ gchar *name; -+ GSList *owners; -+}; -+ -+typedef struct _BusConnectionOwner BusConnectionOwner; -+struct _BusConnectionOwner { -+ BusConnection *conn; -+ -+ guint allow_replacement : 1; -+ guint do_not_queue : 1; -+}; - - /* functions prototype */ - static void bus_dbus_impl_destroy (BusDBusImpl *dbus); -@@ -111,6 +134,14 @@ static void bus_dbus_impl_name_owner_changed - gchar *name, - gchar *old_name, - gchar *new_name); -+static void bus_dbus_impl_name_lost -+ (BusDBusImpl *dbus, -+ BusConnection *connection, -+ gchar *name); -+static void bus_dbus_impl_name_acquired -+ (BusDBusImpl *dbus, -+ BusConnection *connection, -+ gchar *name); - static void bus_dbus_impl_connection_destroy_cb - (BusConnection *connection, - BusDBusImpl *dbus); -@@ -205,6 +236,188 @@ static const gchar introspection_xml[] = - ""; - - static void -+bus_connection_owner_set_flags (BusConnectionOwner *owner, -+ guint32 flags) -+{ -+ owner->allow_replacement = -+ (flags & IBUS_BUS_NAME_FLAG_ALLOW_REPLACEMENT) != 0; -+ -+ owner->do_not_queue = -+ (flags & IBUS_BUS_NAME_FLAG_DO_NOT_QUEUE) != 0; -+} -+ -+static BusConnectionOwner * -+bus_connection_owner_new (BusConnection *connection, -+ guint32 flags) -+{ -+ BusConnectionOwner *owner = NULL; -+ -+ g_assert (connection != NULL); -+ -+ owner = (BusConnectionOwner *) g_new0 (BusConnectionOwner, 1); -+ if (owner != NULL) { -+ owner->conn = g_object_ref (connection); -+ bus_connection_owner_set_flags (owner, flags); -+ } -+ -+ return owner; -+} -+ -+static void -+bus_connection_owner_free (BusConnectionOwner *owner) -+{ -+ g_assert (owner != NULL); -+ -+ g_object_unref (owner->conn); -+ owner->conn = NULL; -+ g_free (owner); -+} -+ -+static GSList * -+_bus_name_service_find_owner_link (BusNameService *service, -+ BusConnection *connection) -+{ -+ GSList *owners = service->owners; -+ -+ while (owners) { -+ BusConnectionOwner *owner = (BusConnectionOwner *) owners->data; -+ if (owner->conn == connection) { -+ break; -+ } -+ owners = owners->next; -+ } -+ -+ return owners; -+} -+ -+static BusNameService * -+bus_name_service_new (const gchar *name) -+{ -+ BusNameService *service = NULL; -+ -+ g_assert (name != NULL); -+ -+ service = g_new0 (BusNameService, 1); -+ if (service != NULL) { -+ service->name = g_strdup (name); -+ } -+ -+ return service; -+} -+ -+static void -+bus_name_service_free (BusNameService *service) -+{ -+ GSList *list = NULL; -+ -+ g_assert (service != NULL); -+ -+ list = service->owners; -+ -+ while (list) { -+ bus_connection_owner_free ((BusConnectionOwner *) list->data); -+ list->data = NULL; -+ list = list->next; -+ } -+ if (service->owners) { -+ g_slist_free (service->owners); -+ service->owners = NULL; -+ } -+ g_free (service->name); -+ service->name = NULL; -+ g_free (service); -+} -+ -+static void -+bus_name_service_add_primary_owner (BusNameService *service, -+ BusConnectionOwner *owner, -+ BusDBusImpl *dbus) -+{ -+ g_assert (service != NULL); -+ -+ if (dbus) { -+ g_signal_emit (dbus, -+ dbus_signals[NAME_ACQUIRED], -+ 0, -+ g_object_ref (owner->conn), -+ service->name ? service->name : ""); -+ } -+ -+ service->owners = g_slist_prepend (service->owners, (gpointer) owner); -+} -+ -+static BusConnectionOwner * -+bus_name_service_get_primary_owner (BusNameService *service) -+{ -+ g_assert (service != NULL); -+ -+ if (service->owners == NULL) { -+ return NULL; -+ } -+ -+ return (BusConnectionOwner *) service->owners->data; -+} -+ -+static void -+bus_name_service_add_owner (BusNameService *service, -+ BusConnectionOwner *owner, -+ BusDBusImpl *dbus) -+{ -+ g_assert (service != NULL); -+ -+ if (dbus && service->owners == NULL) { -+ g_signal_emit (dbus, -+ dbus_signals[NAME_ACQUIRED], -+ 0, -+ g_object_ref (owner->conn), -+ service->name ? service->name : ""); -+ } -+ -+ service->owners = g_slist_append (service->owners, (gpointer) owner); -+} -+ -+static void -+bus_name_service_remove_owner (BusNameService *service, -+ BusConnectionOwner *owner, -+ BusDBusImpl *dbus) -+{ -+ GSList *owners; -+ -+ g_assert (service != NULL); -+ g_assert (owner != NULL); -+ -+ owners = _bus_name_service_find_owner_link (service, owner->conn); -+ if (owners == NULL) { -+ return; -+ } -+ -+ if (dbus && -+ owners->data == bus_name_service_get_primary_owner (service)) { -+ g_signal_emit (dbus, -+ dbus_signals[NAME_LOST], -+ 0, -+ g_object_ref (owner->conn), -+ service->name ? service->name : ""); -+ } -+ -+ service->owners = g_slist_remove_link (service->owners, (gpointer) owners); -+} -+ -+static gboolean -+bus_name_service_get_allow_replacement (BusNameService *service) -+{ -+ BusConnectionOwner *owner = NULL; -+ -+ g_assert (service != NULL); -+ -+ owner = bus_name_service_get_primary_owner (service); -+ if (owner == NULL) { -+ return TRUE; -+ } -+ return owner->allow_replacement; -+} -+ -+static void - bus_dbus_impl_class_init (BusDBusImplClass *class) - { - GObjectClass *gobject_class = G_OBJECT_CLASS (class); -@@ -221,6 +434,12 @@ bus_dbus_impl_class_init (BusDBusImplClass *class) - /* register a handler of the name-owner-changed signal below. */ - class->name_owner_changed = bus_dbus_impl_name_owner_changed; - -+ /* register a handler of the name-lost signal below. */ -+ class->name_lost = bus_dbus_impl_name_lost; -+ -+ /* register a handler of the name-acquired signal below. */ -+ class->name_acquired = bus_dbus_impl_name_acquired; -+ - /* install signals */ - dbus_signals[NAME_OWNER_CHANGED] = - g_signal_new (I_("name-owner-changed"), -@@ -234,13 +453,39 @@ bus_dbus_impl_class_init (BusDBusImplClass *class) - G_TYPE_STRING, - G_TYPE_STRING, - G_TYPE_STRING); -+ -+ dbus_signals[NAME_LOST] = -+ g_signal_new (I_("name-lost"), -+ G_TYPE_FROM_CLASS (class), -+ G_SIGNAL_RUN_FIRST, -+ G_STRUCT_OFFSET (BusDBusImplClass, name_lost), -+ NULL, NULL, -+ bus_marshal_VOID__OBJECT_STRING, -+ G_TYPE_NONE, -+ 2, -+ BUS_TYPE_CONNECTION, -+ G_TYPE_STRING); -+ -+ dbus_signals[NAME_ACQUIRED] = -+ g_signal_new (I_("name-acquired"), -+ G_TYPE_FROM_CLASS (class), -+ G_SIGNAL_RUN_FIRST, -+ G_STRUCT_OFFSET (BusDBusImplClass, name_acquired), -+ NULL, NULL, -+ bus_marshal_VOID__OBJECT_STRING, -+ G_TYPE_NONE, -+ 2, -+ BUS_TYPE_CONNECTION, -+ G_TYPE_STRING); - } - - static void - bus_dbus_impl_init (BusDBusImpl *dbus) - { - 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->names = g_hash_table_new_full (g_str_hash, g_str_equal, -+ (GDestroyNotify) g_free, -+ (GDestroyNotify) bus_name_service_free); - - dbus->dispatch_lock = g_mutex_new (); - dbus->forward_lock = g_mutex_new (); -@@ -557,10 +802,15 @@ bus_dbus_impl_request_name (BusDBusImpl *dbus, - GVariant *parameters, - GDBusMethodInvocation *invocation) - { -- /* FIXME need to handle flags defined in: -- * http://dbus.freedesktop.org/doc/dbus-specification.html#message-bus-names */ - const gchar *name = NULL; // e.g. "org.freedesktop.IBus.Panel" -- guint flags = 0; -+ guint32 flags = 0; -+ guint32 retval = 0; -+ gchar *old_owner_name = NULL; -+ BusNameService *service = NULL; -+ BusConnectionOwner *primary_owner = NULL; -+ BusConnectionOwner *owner = NULL; -+ BusConnection *old_owner_conn = NULL; -+ - g_variant_get (parameters, "(&su)", &name, &flags); - - if (name == NULL || -@@ -580,25 +830,82 @@ bus_dbus_impl_request_name (BusDBusImpl *dbus, - return; - } - -- if (g_hash_table_lookup (dbus->names, name) != NULL) { -- g_dbus_method_invocation_return_error (invocation, -- G_DBUS_ERROR, G_DBUS_ERROR_FAILED, -- "Service name '%s' already has an owner.", name); -- return; -+ service = (BusNameService *) g_hash_table_lookup (dbus->names, name); -+ -+ if (service != NULL) { -+ primary_owner = bus_name_service_get_primary_owner (service); -+ if (primary_owner != NULL) { -+ old_owner_conn = primary_owner->conn; -+ } else { -+ old_owner_conn = NULL; -+ } -+ } else { -+ old_owner_conn = NULL; - } - -- const guint retval = 1; /* DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER */ -- g_dbus_method_invocation_return_value (invocation, g_variant_new ("(u)", retval)); -- g_hash_table_insert (dbus->names, -- (gpointer) bus_connection_add_name (connection, name), -- connection); -+ if (old_owner_conn == NULL) { -+ retval = IBUS_BUS_REQUEST_NAME_REPLY_PRIMARY_OWNER; -+ } -+ else if (old_owner_conn == connection) { -+ retval = IBUS_BUS_REQUEST_NAME_REPLY_ALREADY_OWNER; -+ goto out; -+ } -+ else if (((flags & IBUS_BUS_NAME_FLAG_DO_NOT_QUEUE) && -+ !(bus_name_service_get_allow_replacement (service))) || -+ ((flags & IBUS_BUS_NAME_FLAG_DO_NOT_QUEUE) && -+ !(flags & IBUS_BUS_NAME_FLAG_REPLACE_EXISTING))) { -+ retval = IBUS_BUS_REQUEST_NAME_REPLY_EXISTS; -+ goto out; -+ } -+ else if (!(flags & IBUS_BUS_NAME_FLAG_DO_NOT_QUEUE) && -+ (!(flags & IBUS_BUS_NAME_FLAG_REPLACE_EXISTING) || -+ !(bus_name_service_get_allow_replacement (service)))) { -+ if (!bus_connection_has_name (connection, name)) { -+ bus_connection_add_name (connection, name); -+ } -+ owner = bus_connection_owner_new (connection, flags); -+ bus_name_service_add_owner (service, owner, dbus); -+ retval = IBUS_BUS_REQUEST_NAME_REPLY_IN_QUEUE; -+ goto out; -+ } -+ else { -+ if (!bus_connection_has_name (connection, name)) { -+ bus_connection_add_name (connection, name); -+ } -+ owner = bus_connection_owner_new (connection, flags); -+ old_owner_name = g_strdup (bus_connection_get_unique_name (primary_owner->conn)); -+ bus_name_service_remove_owner (service, primary_owner, dbus); -+ bus_name_service_add_primary_owner (service, owner, dbus); -+ if (primary_owner->do_not_queue == 0) { -+ bus_name_service_add_owner (service, primary_owner, dbus); -+ } else { -+ if (bus_connection_has_name (primary_owner->conn, name)) { -+ bus_connection_remove_name (primary_owner->conn, name); -+ } -+ bus_connection_owner_free (primary_owner); -+ } -+ retval = IBUS_BUS_REQUEST_NAME_REPLY_PRIMARY_OWNER; -+ } -+ -+ if (service == NULL) { -+ service = bus_name_service_new (name); -+ owner = bus_connection_owner_new (connection, flags); -+ bus_name_service_add_owner (service, owner, dbus); -+ g_hash_table_insert (dbus->names, -+ (gpointer) g_strdup (bus_connection_add_name (connection, name)), -+ service); -+ } - - g_signal_emit (dbus, - dbus_signals[NAME_OWNER_CHANGED], - 0, - name, -- "", -+ old_owner_name ? old_owner_name : "", - bus_connection_get_unique_name (connection)); -+ g_free (old_owner_name); -+ -+out: -+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("(u)", retval)); - } - - /** -@@ -682,6 +989,70 @@ bus_dbus_impl_name_owner_changed (BusDBusImpl *dbus, - } - - /** -+ * bus_dbus_impl_name_lost: -+ * -+ * The function is called on name-lost signal, typically when g_signal_emit (dbus, NAME_LOST) -+ * is called, and broadcasts the signal to clients. -+ */ -+static void -+bus_dbus_impl_name_lost (BusDBusImpl *dbus, -+ BusConnection *connection, -+ gchar *name) -+{ -+ static guint32 serial = 0; -+ -+ g_assert (BUS_IS_DBUS_IMPL (dbus)); -+ g_assert (name != NULL); -+ -+ GDBusMessage *message = g_dbus_message_new_signal ("/org/freedesktop/DBus", -+ "org.freedesktop.DBus", -+ "NameLost"); -+ g_dbus_message_set_sender (message, "org.freedesktop.DBus"); -+ g_dbus_message_set_destination (message, bus_connection_get_unique_name (connection)); -+ -+ /* set a non-zero serial to make libdbus happy */ -+ g_dbus_message_set_serial (message, ++serial); -+ g_dbus_message_set_body (message, -+ g_variant_new ("(s)", name)); -+ -+ bus_dbus_impl_forward_message (dbus, connection, message); -+ g_object_unref (message); -+ g_object_unref (connection); -+} -+ -+/** -+ * bus_dbus_impl_name_acquired: -+ * -+ * The function is called on name-acquired signal, typically when g_signal_emit (dbus, NAME_LOST) -+ * is called, and broadcasts the signal to clients. -+ */ -+static void -+bus_dbus_impl_name_acquired (BusDBusImpl *dbus, -+ BusConnection *connection, -+ gchar *name) -+{ -+ static guint32 serial = 0; -+ -+ g_assert (BUS_IS_DBUS_IMPL (dbus)); -+ g_assert (name != NULL); -+ -+ GDBusMessage *message = g_dbus_message_new_signal ("/org/freedesktop/DBus", -+ "org.freedesktop.DBus", -+ "NameAcquired"); -+ g_dbus_message_set_sender (message, "org.freedesktop.DBus"); -+ g_dbus_message_set_destination (message, bus_connection_get_unique_name (connection)); -+ -+ /* set a non-zero serial to make libdbus happy */ -+ g_dbus_message_set_serial (message, ++serial); -+ g_dbus_message_set_body (message, -+ g_variant_new ("(s)", name)); -+ -+ bus_dbus_impl_forward_message (dbus, connection, message); -+ g_object_unref (message); -+ g_object_unref (connection); -+} -+ -+/** - * bus_dbus_impl_service_method_call: - * - * Handle a D-Bus method call from a client. This function overrides an implementation in src/ibusservice.c. -@@ -935,6 +1306,10 @@ bus_dbus_impl_connection_destroy_cb (BusConnection *connection, - BusDBusImpl *dbus) - { - const gchar *unique_name = bus_connection_get_unique_name (connection); -+ const GList *names = NULL; -+ BusNameService *service = NULL; -+ GSList *owners = NULL; -+ - if (unique_name != NULL) { - g_hash_table_remove (dbus->unique_names, unique_name); - g_signal_emit (dbus, -@@ -945,16 +1320,71 @@ bus_dbus_impl_connection_destroy_cb (BusConnection *connection, - ""); - } - -- const GList *name = bus_connection_get_names (connection); -- while (name != NULL) { -- g_hash_table_remove (dbus->names, name->data); -+ /* service->owners is the queue of connections. -+ * If the connection is the primary owner and -+ * bus_name_service_remove_owner() is called, the owner is removed -+ * in the queue and the next owner will become the primary owner -+ * automatically because service->owners is just a GSList. -+ * If service->owners == NULL, it's good to remove the service in -+ * dbus->names. -+ * I suppose dbus->names are global queue for every connection and -+ * connection->names are private queue of the connection. -+ */ -+ names = bus_connection_get_names (connection); -+ while (names != NULL) { -+ service = (BusNameService *) g_hash_table_lookup (dbus->names, -+ names->data); -+ if (service) { -+ owners = _bus_name_service_find_owner_link (service, connection); -+ if (owners) { -+ BusConnectionOwner *owner = owners->data; -+ bus_name_service_remove_owner (service, owner, dbus); -+ bus_connection_owner_free (owner); -+ } -+ if (service->owners == NULL) { -+ /* g_hash_table_remove() will call bus_name_service_free() -+ * due to g_hash_table_new_full() */ -+ g_hash_table_remove (dbus->names, names->data); -+ service = NULL; -+ } -+ } -+ /* if service == NULL, the names->data should be removed in -+ * the connection by bus_connection_remove_name(). -+ * But connection->names is GSList so it cannot be removed -+ * during this while loop because names->next would not -+ * become the wrong pointer here. -+ * the next while loop can call bus_connection_remove_name(). -+ */ -+ - g_signal_emit (dbus, - dbus_signals[NAME_OWNER_CHANGED], - 0, -- name->data, -+ names->data, - unique_name, - ""); -- name = name->next; -+ names = names->next; -+ } -+ -+ while ((names = bus_connection_get_names (connection)) != NULL) { -+ const gchar *name = NULL; -+ service = NULL; -+ -+ while (names != NULL) { -+ name = (const gchar *) names->data; -+ service = (BusNameService *) g_hash_table_lookup (dbus->names, -+ name); -+ if (service == NULL) { -+ break; -+ } -+ names = names->next; -+ } -+ if (names == NULL) { -+ break; -+ } -+ if (name == NULL) { -+ break; -+ } -+ bus_connection_remove_name (connection, name); - } - - dbus->connections = g_list_remove (dbus->connections, connection); -@@ -1004,7 +1434,15 @@ bus_dbus_impl_get_connection_by_name (BusDBusImpl *dbus, - return (BusConnection *) g_hash_table_lookup (dbus->unique_names, name); - } - else { -- return (BusConnection *) g_hash_table_lookup (dbus->names, name); -+ BusNameService *service; -+ BusConnectionOwner *owner; -+ -+ service = (BusNameService *) g_hash_table_lookup (dbus->names, name); -+ if (service == NULL) { -+ return NULL; -+ } -+ owner = bus_name_service_get_primary_owner (service); -+ return owner ? owner->conn : NULL; - } - } - -diff --git a/bus/marshalers.list b/bus/marshalers.list -index 15bdf02..514d6ea 100644 ---- a/bus/marshalers.list -+++ b/bus/marshalers.list -@@ -4,6 +4,7 @@ VOID:INT,UINT - VOID:INT,INT,INT,INT - VOID:OBJECT - VOID:OBJECT,BOOLEAN -+VOID:OBJECT,STRING - VOID:OBJECT,UINT,BOOLEAN - VOID:OBJECT,UINT,BOOLEAN,UINT - VOID:STRING -diff --git a/ibus/common.py b/ibus/common.py -index cbc8d56..614d782 100644 ---- a/ibus/common.py -+++ b/ibus/common.py -@@ -35,6 +35,13 @@ __all__ = ( - "ORIENTATION_SYSTEM", - "PRELOAD_ENGINE_MODE_USER", - "PRELOAD_ENGINE_MODE_LANG_RELATIVE", -+ "BUS_NAME_FLAG_ALLOW_REPLACEMENT", -+ "BUS_NAME_FLAG_REPLACE_EXISTING", -+ "BUS_NAME_FLAG_DO_NOT_QUEUE", -+ "BUS_REQUEST_NAME_REPLY_PRIMARY_OWNER", -+ "BUS_REQUEST_NAME_REPLY_IN_QUEUE", -+ "BUS_REQUEST_NAME_REPLY_EXISTS", -+ "BUS_REQUEST_NAME_REPLY_ALREADY_OWNER", - "default_reply_handler", - "default_error_handler", - "DEFAULT_ASYNC_HANDLERS", -@@ -47,7 +54,8 @@ __all__ = ( - "main_quit", - "main_iteration", - "get_address", -- "get_socket_path" -+ "get_socket_path", -+ "is_running_gnome_shell", - ) - - import os -@@ -106,6 +114,9 @@ get_address.restype=ctypes.c_char_p - get_socket_path = libibus.ibus_get_socket_path - get_socket_path.restype=ctypes.c_char_p - -+is_running_gnome_shell = libibus.ibus_is_running_gnome_shell -+is_running_gnome_shell.restype = ctypes.c_bool -+ - # __session_id = os.getenv ("IBUS_SESSION_ID") - # - # IBUS_ADDR = "unix:path=/tmp/ibus-%s%s/ibus-%s-%s" % (__username, -@@ -138,6 +149,17 @@ ORIENTATION_SYSTEM = 2 - PRELOAD_ENGINE_MODE_USER = 0 - PRELOAD_ENGINE_MODE_LANG_RELATIVE = 1 - -+# define bus name flag -+BUS_NAME_FLAG_ALLOW_REPLACEMENT = (1 << 0) -+BUS_NAME_FLAG_REPLACE_EXISTING = (1 << 1) -+BUS_NAME_FLAG_DO_NOT_QUEUE = (1 << 2) -+ -+# define bus request name reply -+BUS_REQUEST_NAME_REPLY_PRIMARY_OWNER = 1 -+BUS_REQUEST_NAME_REPLY_IN_QUEUE = 2 -+BUS_REQUEST_NAME_REPLY_EXISTS = 3 -+BUS_REQUEST_NAME_REPLY_ALREADY_OWNER = 4 -+ - def default_reply_handler( *args): - pass - -diff --git a/src/Makefile.am b/src/Makefile.am -index 08152a7..d422106 100644 ---- a/src/Makefile.am -+++ b/src/Makefile.am -@@ -87,6 +87,7 @@ ibus_sources = \ - ibusenginedesc.c \ - ibusobservedpath.c \ - ibuscomponent.c \ -+ ibusutil.c \ - $(NULL) - libibus_1_0_la_SOURCES = \ - $(ibus_sources) \ -@@ -131,6 +132,7 @@ ibus_headers = \ - ibusenginedesc.h \ - ibusobservedpath.h \ - ibuscomponent.h \ -+ ibusutil.h \ - $(NULL) - ibusincludedir = $(includedir)/ibus-@IBUS_API_VERSION@ - ibus_public_headers = \ -diff --git a/src/ibusbus.c b/src/ibusbus.c -index 5a3b978..78808a4 100644 ---- a/src/ibusbus.c -+++ b/src/ibusbus.c -@@ -613,15 +613,15 @@ ibus_bus_hello (IBusBus *bus) - #endif - } - --guint -+guint32 - ibus_bus_request_name (IBusBus *bus, - const gchar *name, -- guint flags) -+ guint32 flags) - { - g_return_val_if_fail (IBUS_IS_BUS (bus), 0); - g_return_val_if_fail (name != NULL, 0); - -- guint retval = 0; -+ guint32 retval = 0; - GVariant *result; - result = ibus_bus_call_sync (bus, - DBUS_SERVICE_DBUS, -diff --git a/src/ibusbus.h b/src/ibusbus.h -index b1ec63c..de4cd36 100644 ---- a/src/ibusbus.h -+++ b/src/ibusbus.h -@@ -122,16 +122,16 @@ const gchar *ibus_bus_hello - * ibus_bus_request_name: - * @bus: the IBusBus instance to be processed. - * @name: Name to be requested. -- * @flags: Flags (FixMe). -- * @returns: 0 if failed; positive number otherwise. -+ * @flags: IBusBusNameFlag. -+ * @returns: 0 if failed; IBusBusRequestNameReply otherwise. - * - * Request a name from IBus daemon synchronously. - * - * FIXME add an asynchronous version. - */ --guint ibus_bus_request_name (IBusBus *bus, -+guint32 ibus_bus_request_name (IBusBus *bus, - const gchar *name, -- guint flags); -+ guint32 flags); - - /** - * ibus_bus_release_name: -diff --git a/src/ibusproperty.c b/src/ibusproperty.c -index bb9cc21..5a2dd78 100644 ---- a/src/ibusproperty.c -+++ b/src/ibusproperty.c -@@ -217,6 +217,30 @@ ibus_property_new (const gchar *key, - return prop; - } - -+#define IBUS_PROPERTY_GET_FIELD(field, return_type) \ -+return_type \ -+ibus_property_get_ ## field (IBusProperty *prop) \ -+{ \ -+ return prop->field; \ -+} -+ -+IBUS_PROPERTY_GET_FIELD (key, const gchar *) -+IBUS_PROPERTY_GET_FIELD (icon, const gchar *) -+IBUS_PROPERTY_GET_FIELD (label, const IBusText *) -+IBUS_PROPERTY_GET_FIELD (tooltip, const IBusText *) -+IBUS_PROPERTY_GET_FIELD (sensitive, gboolean) -+IBUS_PROPERTY_GET_FIELD (visible, gboolean) -+IBUS_PROPERTY_GET_FIELD (state, IBusPropState) -+IBUS_PROPERTY_GET_FIELD (sub_props, const IBusPropList *) -+#undef IBUS_PROPERTY_GET_FIELD -+ -+/* ibus_property_get_type() exists */ -+IBusPropType -+ibus_property_get_prop_type (IBusProperty *prop) -+{ -+ return prop->type; -+} -+ - void - ibus_property_set_label (IBusProperty *prop, - IBusText *label) -diff --git a/src/ibusproperty.h b/src/ibusproperty.h -index 0f8d427..5e76c8f 100644 ---- a/src/ibusproperty.h -+++ b/src/ibusproperty.h -@@ -164,12 +164,12 @@ GType ibus_property_get_type (); - * @key: Unique Identity for the IBusProperty. - * @type: IBusPropType of IBusProperty. - * @label: Text shown in UI. -- * @icon: Icon file for the IBusProperty. -+ * @icon: (allow-none): Icon file for the IBusProperty. - * @tooltip: Message shown if mouse hovered the IBusProperty. - * @sensitive: Whether the IBusProperty is sensitive to keyboard and mouse event. - * @visible: Whether the IBusProperty is visible. - * @state: IBusPropState of IBusProperty. -- * @prop_list: IBusPropList that contains sub IBusProperties. -+ * @prop_list: (allow-none): IBusPropList that contains sub IBusProperties. - * @returns: A newly allocated IBusProperty. - * - * New a IBusProperty. -@@ -185,6 +185,33 @@ IBusProperty *ibus_property_new (const gchar *key, - IBusPropList *prop_list); - - /** -+ * ibus_property_get_key: -+ * @prop: An IBusProperty. -+ * @returns: the key of IBusProperty. Should not be freed. -+ * -+ * Get the key of IBusProperty. -+ */ -+const gchar * ibus_property_get_key (IBusProperty *prop); -+ -+/** -+ * ibus_property_get_prop_type: -+ * @prop: An IBusProperty. -+ * @returns: the type of IBusProperty. -+ * -+ * Get the type of IBusProperty. -+ */ -+IBusPropType ibus_property_get_prop_type(IBusProperty *prop); -+ -+/** -+ * ibus_property_get_label: -+ * @prop: An IBusProperty. -+ * @returns: the label of IBusProperty. Should not be freed. -+ * -+ * Get the label of IBusProperty. -+ */ -+const IBusText * ibus_property_get_label (IBusProperty *prop); -+ -+/** - * ibus_property_set_label: - * @prop: An IBusProperty. - * @label: Text shown in UI. -@@ -195,6 +222,15 @@ void ibus_property_set_label (IBusProperty *prop, - IBusText *label); - - /** -+ * ibus_property_get_icon: -+ * @prop: An IBusProperty. -+ * @returns: the icon of IBusProperty. Should not be freed. -+ * -+ * Get the icon of IBusProperty. -+ */ -+const gchar * ibus_property_get_icon (IBusProperty *prop); -+ -+/** - * ibus_property_set_icon: - * @prop: An IBusProperty. - * @icon: Icon shown in UI. It could be a full path of an icon file or an icon name. -@@ -205,6 +241,15 @@ void ibus_property_set_icon (IBusProperty *prop, - const gchar *icon); - - /** -+ * ibus_property_get_tooltip: -+ * @prop: An IBusProperty. -+ * @returns: the tooltip of IBusProperty. Should not be freed. -+ * -+ * Get the tooltip of IBusProperty. -+ */ -+const IBusText * ibus_property_get_tooltip (IBusProperty *prop); -+ -+/** - * ibus_property_set_tooltip: - * @prop: An IBusProperty. - * @tooltip: Text of the tooltip. -@@ -215,6 +260,15 @@ void ibus_property_set_tooltip (IBusProperty *prop, - IBusText *tooltip); - - /** -+ * ibus_property_get_sensitive: -+ * @prop: An IBusProperty. -+ * @returns: the sensitive of IBusProperty. -+ * -+ * Get the sensitive of IBusProperty. -+ */ -+gboolean ibus_property_get_sensitive(IBusProperty *prop); -+ -+/** - * ibus_property_set_sensitive: - * @prop: An IBusProperty. - * @sensitive: Whether the IBusProperty is sensitive. -@@ -225,6 +279,15 @@ void ibus_property_set_sensitive(IBusProperty *prop, - gboolean sensitive); - - /** -+ * ibus_property_get_visible: -+ * @prop: An IBusProperty. -+ * @returns: the visible of IBusProperty. -+ * -+ * Get the visible of IBusProperty. -+ */ -+gboolean ibus_property_get_visible (IBusProperty *prop); -+ -+/** - * ibus_property_set_visible: - * @prop: An IBusProperty. - * @visible: Whether the IBusProperty is visible. -@@ -235,6 +298,15 @@ void ibus_property_set_visible (IBusProperty *prop, - gboolean visible); - - /** -+ * ibus_property_get_state: -+ * @prop: An IBusProperty. -+ * @returns: the state of IBusProperty. -+ * -+ * Get the state of IBusProperty. -+ */ -+IBusPropState ibus_property_get_state (IBusProperty *prop); -+ -+/** - * ibus_property_set_state: - * @prop: An IBusProperty. - * @state: The state of the IBusProperty. -@@ -244,6 +316,15 @@ void ibus_property_set_visible (IBusProperty *prop, - void ibus_property_set_state (IBusProperty *prop, - IBusPropState state); - -+/** -+ * ibus_property_get_sub_props: -+ * @prop: An IBusProperty. -+ * @returns: the IBusPropList of IBusProperty. Should not be freed. -+ * -+ * Get the IBusPropList of IBusProperty. -+ */ -+const IBusPropList * -+ ibus_property_get_sub_props(IBusProperty *prop); - - /** - * ibus_property_set_sub_props: -diff --git a/src/ibustext.c b/src/ibustext.c -index b63cbc9..5889b64 100644 ---- a/src/ibustext.c -+++ b/src/ibustext.c -@@ -268,3 +268,21 @@ ibus_text_get_length (IBusText *text) - { - return g_utf8_strlen (text->text, -1); - } -+ -+gboolean -+ibus_text_get_is_static (IBusText *text) -+{ -+ return text->is_static; -+} -+ -+const gchar * -+ibus_text_get_text (IBusText *text) -+{ -+ return text->text; -+} -+ -+const IBusAttrList * -+ibus_text_get_attributes (IBusText *text) -+{ -+ return text->attrs; -+} -diff --git a/src/ibustext.h b/src/ibustext.h -index 246e5ab..6f7c505 100644 ---- a/src/ibustext.h -+++ b/src/ibustext.h -@@ -110,7 +110,7 @@ IBusText *ibus_text_new_from_string (const gchar *str); - IBusText *ibus_text_new_from_ucs4 (const gunichar *str); - - /** -- * ibus_text_new_from_static_string: -+ * ibus_text_new_from_static_string: (skip) - * @str: An text string to be set. - * @returns: A newly allocated IBusText. - * -@@ -169,6 +169,33 @@ void ibus_text_append_attribute (IBusText *text, - */ - guint ibus_text_get_length (IBusText *text); - -+/** -+ * ibus_text_get_is_static: -+ * @text: An IBusText. -+ * @returns: the is_static in @text. -+ * -+ * Return the is_static in an IBusText. -+ */ -+gboolean ibus_text_get_is_static (IBusText *text); -+ -+/** -+ * ibus_text_get_text: -+ * @text: An IBusText. -+ * @returns: the text in @text. -+ * -+ * Return the text in an IBusText. Should not be freed. -+ */ -+const gchar * ibus_text_get_text (IBusText *text); -+ -+/** -+ * ibus_text_get_attributes: -+ * @text: An IBusText. -+ * @returns: the attrs in @text. -+ * -+ * Return the attributes in an IBusText. Should not be freed. -+ */ -+const IBusAttrList * -+ ibus_text_get_attributes (IBusText *text); - G_END_DECLS - #endif - -diff --git a/src/ibustypes.h b/src/ibustypes.h -index 035d124..6a31847 100644 ---- a/src/ibustypes.h -+++ b/src/ibustypes.h -@@ -154,6 +154,39 @@ typedef enum { - } IBusPreloadEngineMode; - - /** -+ * IBusBusNameFlag: -+ * @IBUS_BUS_NAME_FLAG_ALLOW_REPLACEMENT: -+ * same as DBUS_NAME_FLAG_ALLOW_REPLACEMENT -+ * @IBUS_BUS_NAME_FLAG_REPLACE_EXISTING: -+ * same as DBUS_NAME_FLAG_REPLACE_EXISTING -+ * @IBUS_BUS_NAME_FLAG_DO_NOT_QUEUE: -+ * same as DBUS_NAME_FLAG_DO_NOT_QUEUE -+ */ -+typedef enum { -+ IBUS_BUS_NAME_FLAG_ALLOW_REPLACEMENT = (1 << 0), -+ IBUS_BUS_NAME_FLAG_REPLACE_EXISTING = (1 << 1), -+ IBUS_BUS_NAME_FLAG_DO_NOT_QUEUE = (1 << 2), -+} IBusBusNameFlag; -+ -+/** -+ * IBusBusRequestNameReply: -+ * @IBUS_BUS_REQUEST_NAME_REPLY_PRIMARY_OWNER: -+ * same as DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER -+ * @IBUS_BUS_REQUEST_NAME_REPLY_IN_QUEUE: -+ * same as DBUS_REQUEST_NAME_REPLY_IN_QUEUE -+ * @IBUS_BUS_REQUEST_NAME_REPLY_EXISTS: -+ * same as DBUS_REQUEST_NAME_REPLY_EXISTS -+ * @IBUS_BUS_REQUEST_NAME_REPLY_ALREADY_OWNER: -+ * same as DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER -+ */ -+typedef enum { -+ IBUS_BUS_REQUEST_NAME_REPLY_PRIMARY_OWNER = 1, -+ IBUS_BUS_REQUEST_NAME_REPLY_IN_QUEUE = 2, -+ IBUS_BUS_REQUEST_NAME_REPLY_EXISTS = 3, -+ IBUS_BUS_REQUEST_NAME_REPLY_ALREADY_OWNER = 4, -+} IBusBusRequestNameReply; -+ -+/** - * IBusRectangle: - * @x: x coordinate. - * @y: y coordinate. -diff --git a/src/ibusutil.c b/src/ibusutil.c -new file mode 100644 -index 0000000..59291f9 ---- /dev/null -+++ b/src/ibusutil.c -@@ -0,0 +1,180 @@ -+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ -+/* vim:set et sts=4: */ -+/* bus - The Input Bus -+ * Copyright (C) 2008-2011 Peng Huang -+ * Copyright (C) 2010-2011 Takao Fujiwara -+ * Copyright (C) 2008-2011 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. -+ */ -+#ifdef HAVE_CONFIG_H -+#include -+#endif -+ -+#include -+#include -+#include -+#include -+#include "ibusxml.h" -+ -+#ifdef ENABLE_NLS -+#include -+#endif -+ -+static GHashTable *__languages_dict; -+ -+static gboolean -+_iso_codes_parse_xml_node (XMLNode *node) -+{ -+ GList *p; -+ g_assert (node); -+ -+ if (G_UNLIKELY (g_strcmp0 (node->name, "iso_639_entries") != 0)) { -+ return FALSE; -+ } -+ -+ for (p = node->sub_nodes; p != NULL; p = p->next) { -+ XMLNode *sub_node = (XMLNode *)p->data; -+ gchar **attributes = NULL; -+ int i, j; -+ struct { -+ const gchar *key; -+ gchar *value; -+ } entries[] = { -+ { "iso_639_2B_code", NULL }, -+ { "iso_639_2T_code", NULL }, -+ { "iso_639_1_code", NULL }, -+ { NULL, NULL }, -+ }; -+ -+ -+ if (sub_node->attributes == NULL) { -+ continue; -+ } -+ attributes = sub_node->attributes; -+ for (i = 0; attributes[i]; i+=2) { -+ if (g_strcmp0 (attributes[i], "name") == 0) { -+ for (j = 0; entries[j].key; j++) { -+ if (entries[j].value == NULL) { -+ continue; -+ } -+ g_hash_table_insert (__languages_dict, -+ (gpointer) entries[j].value, -+ (gpointer) g_strdup (attributes[i + 1])); -+ entries[j].value = NULL; -+ } -+ } else { -+ for (j = 0; entries[j].key; j++) { -+ if (g_strcmp0 (attributes[i], entries[j].key) == 0 && -+ attributes[i + 1] != NULL) { -+ entries[j].value = g_strdup (attributes[i + 1]); -+ } -+ } -+ } -+ } -+ } -+ -+ return TRUE; -+} -+ -+void -+_load_lang() -+{ -+ gchar *filename; -+ XMLNode *node; -+ struct stat buf; -+ -+ __languages_dict = g_hash_table_new (g_str_hash, (GEqualFunc) g_str_equal); -+ filename = g_build_filename ("/usr", "share/xml/iso-codes/iso_639.xml", NULL); -+ if (g_stat (filename, &buf) != 0) { -+ g_warning ("Can not get stat of file %s", filename); -+ g_free (filename); -+ return; -+ } -+ -+ node = ibus_xml_parse_file (filename); -+ g_free (filename); -+ -+ if (!node) { -+ return; -+ } -+ -+ _iso_codes_parse_xml_node (node); -+ ibus_xml_free (node); -+} -+ -+const gchar * -+ibus_get_language_name(const gchar *_locale) { -+ const gchar *retval; -+ gchar *p = NULL; -+ gchar *lang = NULL; -+ -+ if (__languages_dict == NULL ) { -+ _load_lang(); -+ } -+ if ((p = strchr (_locale, '_')) != NULL) { -+ p = g_strndup (_locale, p - _locale); -+ } else { -+ p = g_strdup (_locale); -+ } -+ lang = g_ascii_strdown (p, -1); -+ g_free (p); -+ retval = (const gchar *) g_hash_table_lookup (__languages_dict, lang); -+ g_free (lang); -+ if (retval != NULL) { -+#ifdef ENABLE_NLS -+ return dgettext("iso_639", retval); -+#else -+ return retval; -+#endif -+ } -+ return retval; -+} -+ -+gboolean -+ibus_is_running_gnome_shell (void) -+{ -+ GDBusConnection *connection = NULL; -+ GVariant *result; -+ gboolean is_running = FALSE; -+ -+ connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, NULL); -+ if (connection == NULL) { -+ return FALSE; -+ } -+ -+ result = g_dbus_connection_call_sync (connection, -+ "org.freedesktop.DBus", -+ "/org/freedesktop/DBus", -+ "org.freedesktop.DBus", -+ "GetNameOwner", -+ g_variant_new ("(s)", "org.gnome.Shell"), -+ G_VARIANT_TYPE ("(s)"), -+ G_DBUS_CALL_FLAGS_NONE, -+ -1, -+ NULL, -+ NULL); -+ -+ if (result != NULL) { -+ is_running = TRUE; -+ g_variant_unref (result); -+ } else { -+ is_running = FALSE; -+ } -+ g_object_unref (connection); -+ -+ return is_running; -+} -diff --git a/src/ibusutil.h b/src/ibusutil.h -new file mode 100644 -index 0000000..8892996 ---- /dev/null -+++ b/src/ibusutil.h -@@ -0,0 +1,39 @@ -+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ -+/* vim:set et sts=4: */ -+/* bus - The Input Bus -+ * Copyright (C) 2008-2011 Peng Huang -+ * Copyright (C) 2010-2011 Takao Fujiwara -+ * Copyright (C) 2008-2011 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. -+ */ -+ -+#if !defined (__IBUS_H_INSIDE__) && !defined (IBUS_COMPILATION) -+#error "Only can be included directly" -+#endif -+ -+/** -+ * ibus_get_language_name: -+ * @_locale: A const locale name. -+ * @returns: language name -+ */ -+const gchar * ibus_get_language_name (const gchar *_locale); -+ -+/** -+ * ibus_is_running_gnome_shell: -+ * @returns: TRUE if gnome-shell is running -+ */ -+gboolean ibus_is_running_gnome_shell (void); -diff --git a/ui/gtk/gtkpanel.xml.in.in b/ui/gtk/gtkpanel.xml.in.in -index edeed1c..1e1e656 100644 ---- a/ui/gtk/gtkpanel.xml.in.in -+++ b/ui/gtk/gtkpanel.xml.in.in -@@ -3,7 +3,7 @@ - - org.freedesktop.IBus.Panel - Gtk Panel Component -- ${libexecdir}/ibus-ui-gtk -+ ${libexecdir}/ibus-ui-gtk -s - @VERSION@ - Peng Huang <shawn.p.huang@gmail.com> - GPL -diff --git a/ui/gtk/main.py b/ui/gtk/main.py -index f4c901d..5e75ab7 100644 ---- a/ui/gtk/main.py -+++ b/ui/gtk/main.py -@@ -50,7 +50,13 @@ class UIApplication: - self.__bus.add_match(match_rule) - - self.__panel = panel.Panel(self.__bus) -- self.__bus.request_name(ibus.IBUS_SERVICE_PANEL, 0) -+ self.__bus.request_name(ibus.IBUS_SERVICE_PANEL, -+ ibus.BUS_NAME_FLAG_ALLOW_REPLACEMENT | -+ ibus.BUS_NAME_FLAG_REPLACE_EXISTING) -+ self.__bus.add_match("type='signal',\ -+ sender='org.freedesktop.DBus',\ -+ member='NameLost'") -+ self.__bus.get_dbusconn().add_signal_receiver(self.__name_lost_cb, signal_name="NameLost") - self.__notify = pynotify.Notification("IBus", \ - _("Some input methods have been installed, removed or updated. " \ - "Please restart ibus input platform."), \ -@@ -66,6 +72,10 @@ class UIApplication: - def __registry_changed_cb(self, bus): - self.__notify.show() - -+ def __name_lost_cb(self, name): -+ print "Got NameLost signal", name -+ gtk.main_quit() -+ - def run(self): - try: - gtk.main() -@@ -84,8 +94,9 @@ def print_help(out, v = 0): - - def main(): - daemonize = False -- shortopt = "hd" -- longopt = ["help", "daemonize"] -+ stop_by_shell = False -+ shortopt = "hds" -+ longopt = ["help", "daemonize", "stop-by-shell"] - try: - opts, args = getopt.getopt(sys.argv[1:], shortopt, longopt) - except getopt.GetoptError, err: -@@ -96,10 +107,16 @@ def main(): - print_help(sys.stdout) - elif o in("-d", "--daemonize"): - daemonize = True -+ elif o in("-s", "--stop-by-shell"): -+ stop_by_shell = True - else: - print >> sys.stderr, "Unknown argument: %s" % o - print_help(sys.stderr, 1) - -+ if stop_by_shell and ibus.is_running_gnome_shell(): -+ print "Exit because GNOME-Shell is running" -+ sys.exit() -+ - if daemonize: - if os.fork(): - sys.exit() --- -1.7.4.1 - diff --git a/ibus-675503-gnome-shell-workaround.patch b/ibus-675503-gnome-shell-workaround.patch deleted file mode 100644 index a324d64..0000000 --- a/ibus-675503-gnome-shell-workaround.patch +++ /dev/null @@ -1,87 +0,0 @@ -From c6949a852235bedb44126c3c6f36e1fba4b71bce Mon Sep 17 00:00:00 2001 -From: fujiwarat -Date: Tue, 8 Feb 2011 18:21:50 +0900 -Subject: [PATCH] Added the optional sync mode apps in IBusIMContext. - ---- - client/gtk2/ibusimcontext.c | 27 +++++++++++++++++++++++++++ - configure.ac | 11 +++++++++++ - 2 files changed, 38 insertions(+), 0 deletions(-) - -diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c -index bb5ae5c..a4e46cb 100644 ---- a/client/gtk2/ibusimcontext.c -+++ b/client/gtk2/ibusimcontext.c -@@ -79,6 +79,7 @@ static const gchar *_no_snooper_apps = NO_SNOOPER_APPS; - static gboolean _use_key_snooper = ENABLE_SNOOPER; - static guint _key_snooper_id = 0; - -+static const gchar *_sync_mode_apps = SYNC_MODE_APPS; - static gboolean _use_sync_mode = FALSE; - - static GtkIMContext *_focus_im_context = NULL; -@@ -477,6 +478,32 @@ ibus_im_context_class_init (IBusIMContextClass *class) - g_strfreev (apps); - } - -+ /* env IBUS_SYNC_MODE_APPS for sync mode apps */ -+ /* It seems MetaDisplay does not take the events from gdk_event_put() -+ * in async mode. So if gnome-shell + mutter are used, -+ * the key events are lost in async mode. -+ * gnome-shell search box, actually st_im_text_key_press_event(), -+ * does not call the parent filter_keypress() when the IM client -+ * returns TRUE. The class inherits ClutterActor which is not -+ * GtkWidget so the clutter does not call GTK snoopers. -+ * So ibus_im_context_filter_keypress() needs to return FALSE. */ -+ if (!_use_sync_mode) { -+ /* enable sync mode if app is in _sync_mode_apps */ -+ const gchar * prgname = g_get_prgname (); -+ if (g_getenv ("IBUS_SYNC_MODE_APPS")) { -+ _sync_mode_apps = g_getenv ("IBUS_SYNC_MODE_APPS"); -+ } -+ gchar **p; -+ gchar ** apps = g_strsplit (_sync_mode_apps, ",", 0); -+ for (p = apps; *p != NULL; p++) { -+ if (g_regex_match_simple (*p, prgname, 0, 0)) { -+ _use_sync_mode = TRUE; -+ break; -+ } -+ } -+ g_strfreev (apps); -+ } -+ - /* init bus object */ - if (_bus == NULL) { - ibus_set_display (gdk_display_get_name (gdk_display_get_default ())); -diff --git a/configure.ac b/configure.ac -index 1a1e663..81efe81 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -354,6 +354,16 @@ AC_ARG_WITH(no-snooper-apps, - AC_DEFINE_UNQUOTED(NO_SNOOPER_APPS, "$NO_SNOOPER_APPS", - [Does not enbale keyboard snooper in those applications]) - -+# option for sync mode applications. -+AC_ARG_WITH(sync-mode-apps, -+ AS_HELP_STRING([--with-sync-mode-apps[=regex1,regex2]], -+ [Enable sync mode in those applications (like: .*chrome.*,firefox.*)]), -+ [SYNC_MODE_APPS=$with_sync_mode_apps], -+ [SYNC_MODE_APPS=[mutter]] -+) -+AC_DEFINE_UNQUOTED(SYNC_MODE_APPS, "$SYNC_MODE_APPS", -+ [Enbale sync mode in those applications]) -+ - # check iso-codes - PKG_CHECK_MODULES(ISOCODES, [ - iso-codes -@@ -423,6 +433,7 @@ Build options: - Build vala binding $enable_vala - Build document $enable_gtk_doc - Enable key snooper $enable_key_snooper -+ Sync mode regexes "$SYNC_MODE_APPS" - No snooper regexes "$NO_SNOOPER_APPS" - ]) - --- -1.7.3.2 - diff --git a/ibus-688034-fedora-g-s.patch b/ibus-688034-fedora-g-s.patch deleted file mode 100644 index 026fb2c..0000000 --- a/ibus-688034-fedora-g-s.patch +++ /dev/null @@ -1,14 +0,0 @@ ---- ibus/ui/gtk/main.py.bak 2011-03-23 13:15:53.150298531 +0900 -+++ ibus/ui/gtk/main.py 2011-03-23 13:16:35.336275938 +0900 -@@ -114,8 +114,9 @@ def main(): - print_help(sys.stderr, 1) - - if stop_by_shell and ibus.is_running_gnome_shell(): -- print "Exit because GNOME-Shell is running" -- sys.exit() -+ if os.path.exists('/usr/share/gnome-shell/js/ui/status/ibus'): -+ print "Exit because GNOME-Shell is running" -+ sys.exit() - - if daemonize: - if os.fork(): diff --git a/ibus-HEAD.patch b/ibus-HEAD.patch index 4d47b17..8b13789 100644 --- a/ibus-HEAD.patch +++ b/ibus-HEAD.patch @@ -1,427 +1 @@ -From fbdd157b2ab1e6e873818132530dd9e55e4f94dd Mon Sep 17 00:00:00 2001 -From: Peng Huang -Date: Mon, 7 Mar 2011 10:26:04 -0500 -Subject: [PATCH] Move gtk_key_snooper_remove from function object_fini to class_fini. - -BUG=http://crosbug.com/12803 -TEST=Linux desktop - -Review URL: http://codereview.appspot.com/4267044 ---- - client/gtk2/ibusimcontext.c | 24 +++++++++++++++--------- - 1 files changed, 15 insertions(+), 9 deletions(-) - -diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c -index a634d0e..31a415d 100644 ---- a/client/gtk2/ibusimcontext.c -+++ b/client/gtk2/ibusimcontext.c -@@ -88,6 +88,7 @@ static GtkWidget *_input_widget = NULL; - - /* functions prototype */ - static void ibus_im_context_class_init (IBusIMContextClass *class); -+static void ibus_im_context_class_fini (IBusIMContextClass *class); - static void ibus_im_context_init (GObject *obj); - static void ibus_im_context_finalize (GObject *obj); - static void ibus_im_context_reset (GtkIMContext *context); -@@ -152,10 +153,10 @@ ibus_im_context_register_type (GTypeModule *type_module) - - static const GTypeInfo ibus_im_context_info = { - sizeof (IBusIMContextClass), -- (GBaseInitFunc) NULL, -- (GBaseFinalizeFunc) NULL, -+ (GBaseInitFunc) NULL, -+ (GBaseFinalizeFunc) NULL, - (GClassInitFunc) ibus_im_context_class_init, -- NULL, /* class finialize */ -+ (GClassFinalizeFunc) ibus_im_context_class_fini, - NULL, /* class data */ - sizeof (IBusIMContext), - 0, -@@ -477,6 +478,16 @@ ibus_im_context_class_init (IBusIMContextClass *class) - _key_snooper_id = gtk_key_snooper_install (_key_snooper_cb, NULL); - } - -+static void -+ibus_im_context_class_fini (IBusIMContextClass *class) -+{ -+ if (_key_snooper_id != 0) { -+ IDEBUG ("snooper is terminated."); -+ gtk_key_snooper_remove (_key_snooper_id); -+ _key_snooper_id = 0; -+ } -+} -+ - /* Copied from gtk+2.0-2.20.1/modules/input/imcedilla.c to fix crosbug.com/11421. - * Overwrite the original Gtk+'s compose table in gtk+-2.x.y/gtk/gtkimcontextsimple.c. */ - -@@ -601,12 +612,6 @@ ibus_im_context_finalize (GObject *obj) - pango_attr_list_unref (ibusimcontext->preedit_attrs); - } - -- if (_key_snooper_id != 0) { -- IDEBUG ("snooper is terminated."); -- gtk_key_snooper_remove (_key_snooper_id); -- _key_snooper_id = 0; -- } -- - G_OBJECT_CLASS(parent_class)->finalize (obj); - } - --- -1.7.4.1 - -From c0489ba017f298e51efe86bc7f5def1928389197 Mon Sep 17 00:00:00 2001 -From: fujiwarat -Date: Fri, 11 Mar 2011 15:53:53 +0900 -Subject: [PATCH] Fix preedit_string = NULL in ibus-x11 _free_ic() - ---- - client/x11/main.c | 1 + - 1 files changed, 1 insertions(+), 0 deletions(-) - -diff --git a/client/x11/main.c b/client/x11/main.c -index a2967cc..16104de 100644 ---- a/client/x11/main.c -+++ b/client/x11/main.c -@@ -526,6 +526,7 @@ _free_ic (gpointer data, gpointer user_data) - g_return_if_fail (x11ic != NULL); - - g_free (x11ic->preedit_string); -+ x11ic->preedit_string = NULL; - - if (x11ic->preedit_attrs) { - g_object_unref (x11ic->preedit_attrs); --- -1.7.4.1 - -From b9b2c42596e1a7394e89c11025074aed2fcb099a Mon Sep 17 00:00:00 2001 -From: Peng Huang -Date: Wed, 16 Mar 2011 10:02:47 -0400 -Subject: [PATCH] Fix issue of InputContext.SetEngine. - -InputContext.SetEngine returns error sometimes, because "request-engine" -signal handler calls an async function to set the engine of the context. -So checking context->engine != NULL just after emiting "request-engine" -signal is not correct. - -BUG=none -TEST=Linux desktop - -Review URL: http://codereview.appspot.com/4287049 ---- - bus/ibusimpl.c | 68 ++++++++++++++++++++++++----------- - bus/inputcontext.c | 97 +++++++++++++++++++++++++++++++++++++++++++-------- - bus/marshalers.list | 14 ++++---- - 3 files changed, 136 insertions(+), 43 deletions(-) - -diff --git a/bus/ibusimpl.c b/bus/ibusimpl.c -index 8d4ec36..5a8e134 100644 ---- a/bus/ibusimpl.c -+++ b/bus/ibusimpl.c -@@ -186,6 +186,9 @@ static BusInputContext - (BusIBusImpl *ibus, - BusConnection *connection, - const gchar *client); -+static IBusEngineDesc -+ *bus_ibus_impl_get_engine_desc (BusIBusImpl *ibus, -+ const gchar *engine_name); - /* some callback functions */ - static void _context_engine_changed_cb (BusInputContext *context, - BusIBusImpl *ibus); -@@ -975,21 +978,30 @@ _find_engine_desc_by_name (BusIBusImpl *ibus, - * - * A callback function to be called when the "request-engine" signal is sent to the context. - */ --static void -+static IBusEngineDesc * - _context_request_engine_cb (BusInputContext *context, - const gchar *engine_name, - BusIBusImpl *ibus) - { -- IBusEngineDesc *desc = NULL; -+ return bus_ibus_impl_get_engine_desc (ibus, engine_name); -+} - -- /* context should has focus before request an engine */ -- g_return_if_fail (bus_input_context_has_focus (context) || -- context == ibus->focused_context); -+/** -+ * bus_ibus_impl_get_engine_desc: -+ * -+ * Get the IBusEngineDesc by engine_name. If the engine_name is NULL, return -+ * a default engine desc. -+ */ -+static IBusEngineDesc * -+bus_ibus_impl_get_engine_desc (BusIBusImpl *ibus, -+ const gchar *engine_name) -+{ -+ IBusEngineDesc *desc = NULL; - - if (engine_name != NULL && engine_name[0] != '\0') { - /* request engine by name */ - desc = _find_engine_desc_by_name (ibus, engine_name); -- g_return_if_fail (desc != NULL); -+ g_return_val_if_fail (desc != NULL, NULL); - } - else { - /* Use global engine if possible. */ -@@ -1018,11 +1030,11 @@ _context_request_engine_cb (BusInputContext *context, - * not find any default engines. another possiblity is that the - * user hasn't installed an engine yet? just give up. */ - g_warning ("No engine is available. Run ibus-setup first."); -- return; -+ return NULL; - } - } - -- bus_ibus_impl_set_context_engine_from_desc (ibus, context, desc); -+ return desc; - } - - /** -@@ -1041,7 +1053,11 @@ bus_ibus_impl_context_request_next_engine_in_menu (BusIBusImpl *ibus, - - engine = bus_input_context_get_engine (context); - if (engine == NULL) { -- _context_request_engine_cb (context, NULL, ibus); -+ desc = bus_ibus_impl_get_engine_desc (ibus, NULL); -+ if (desc != NULL) -+ bus_ibus_impl_set_context_engine_from_desc (ibus, -+ context, -+ desc); - return; - } - -@@ -1112,7 +1128,14 @@ bus_ibus_impl_context_request_previous_engine (BusIBusImpl *ibus, - bus_ibus_impl_context_request_next_engine_in_menu (ibus, context); - return; - } -- _context_request_engine_cb (context, engine_name, ibus); -+ -+ IBusEngineDesc *desc = NULL; -+ desc = bus_ibus_impl_get_engine_desc (ibus, engine_name); -+ if (desc != NULL) { -+ bus_ibus_impl_set_context_engine_from_desc (ibus, -+ context, -+ desc); -+ } - } - - static void -diff --git a/bus/inputcontext.c b/bus/inputcontext.c -index c226a20..6d65830 100644 ---- a/bus/inputcontext.c -+++ b/bus/inputcontext.c -@@ -20,11 +20,13 @@ - * Boston, MA 02111-1307, USA. - */ - #include "inputcontext.h" --#include "types.h" --#include "marshalers.h" --#include "ibusimpl.h" -+ - #include "engineproxy.h" - #include "factoryproxy.h" -+#include "ibusimpl.h" -+#include "marshalers.h" -+#include "option.h" -+#include "types.h" - - struct _SetEngineByDescData { - /* context related to the data */ -@@ -565,8 +567,8 @@ bus_input_context_class_init (BusInputContextClass *class) - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, -- bus_marshal_VOID__STRING, -- G_TYPE_NONE, -+ bus_marshal_OBJECT__STRING, -+ IBUS_TYPE_ENGINE_DESC, - 1, - G_TYPE_STRING); - -@@ -917,6 +919,26 @@ _ic_is_enabled (BusInputContext *context, - g_dbus_method_invocation_return_value (invocation, g_variant_new ("(b)", context->enabled)); - } - -+static void -+_ic_set_engine_done (BusInputContext *context, -+ GAsyncResult *res, -+ GDBusMethodInvocation *invocation) -+{ -+ gboolean retval = FALSE; -+ GError *error = NULL; -+ -+ retval = bus_input_context_set_engine_by_desc_finish (context, -+ res, &error); -+ -+ if (!retval) { -+ g_dbus_method_invocation_return_gerror (invocation, error); -+ g_error_free (error); -+ } -+ else { -+ g_dbus_method_invocation_return_value (invocation, NULL); -+ } -+} -+ - /** - * _ic_set_engine: - * -@@ -930,16 +952,34 @@ _ic_set_engine (BusInputContext *context, - gchar *engine_name = NULL; - g_variant_get (parameters, "(&s)", &engine_name); - -- g_signal_emit (context, context_signals[REQUEST_ENGINE], 0, engine_name); -- -- if (context->engine == NULL) { -- g_dbus_method_invocation_return_error (invocation, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, -- "Can not find engine '%s'.", engine_name); -+ if (!bus_input_context_has_focus (context)) { -+ g_dbus_method_invocation_return_error (invocation, -+ G_DBUS_ERROR, G_DBUS_ERROR_FAILED, -+ "Context which does not has focus can not change engine to %s.", -+ engine_name); -+ return; - } -- else { -- bus_input_context_enable (context); -- g_dbus_method_invocation_return_value (invocation, NULL); -+ -+ IBusEngineDesc *desc = NULL; -+ g_signal_emit (context, -+ context_signals[REQUEST_ENGINE], 0, -+ engine_name, -+ &desc); -+ if (desc == NULL) { -+ g_dbus_method_invocation_return_error (invocation, -+ G_DBUS_ERROR, G_DBUS_ERROR_FAILED, -+ "Can not find engine %s.", engine_name); -+ return; - } -+ -+ bus_input_context_set_engine_by_desc (context, -+ desc, -+ g_gdbus_timeout, -+ NULL, -+ (GAsyncReadyCallback)_ic_set_engine_done, -+ invocation); -+ -+ g_object_unref (desc); - } - - /** -@@ -1045,7 +1085,21 @@ bus_input_context_focus_in (BusInputContext *context) - - if (context->engine == NULL && context->enabled) { - /* request an engine, e.g. a global engine if the feature is enabled. */ -- g_signal_emit (context, context_signals[REQUEST_ENGINE], 0, NULL); -+ IBusEngineDesc *desc = NULL; -+ g_signal_emit (context, -+ context_signals[REQUEST_ENGINE], 0, -+ NULL, -+ &desc); -+ -+ if (desc != NULL) { -+ bus_input_context_set_engine_by_desc (context, -+ desc, -+ g_gdbus_timeout, /* timeout in msec. */ -+ NULL, /* we do not cancel the call. */ -+ NULL, /* use the default callback function. */ -+ NULL); -+ g_object_unref (desc); -+ } - } - - if (context->engine && context->enabled) { -@@ -1927,7 +1981,20 @@ bus_input_context_enable (BusInputContext *context) - } - - if (context->engine == NULL) { -- g_signal_emit (context, context_signals[REQUEST_ENGINE], 0, NULL); -+ IBusEngineDesc *desc = NULL; -+ g_signal_emit (context, -+ context_signals[REQUEST_ENGINE], 0, -+ NULL, -+ &desc); -+ if (desc != NULL) { -+ bus_input_context_set_engine_by_desc (context, -+ desc, -+ g_gdbus_timeout, /* timeout in msec. */ -+ NULL, /* we do not cancel the call. */ -+ NULL, /* use the default callback function. */ -+ NULL); -+ g_object_unref (desc); -+ } - } - - if (context->engine == NULL) -diff --git a/bus/marshalers.list b/bus/marshalers.list -index 15bdf02..159bc24 100644 ---- a/bus/marshalers.list -+++ b/bus/marshalers.list -@@ -1,13 +1,13 @@ --VOID:VOID --VOID:STRING --VOID:OBJECT -+BOOL:UINT,UINT,UINT -+OBJECT:STRING - VOID:INT,UINT --VOID:UINT,UINT,UINT - VOID:INT,INT,INT,INT --VOID:STRING,INT - VOID:OBJECT --VOID:STRING,STRING,STRING - VOID:OBJECT,BOOLEAN - VOID:OBJECT,UINT,BOOLEAN - VOID:OBJECT,UINT,BOOLEAN,UINT --BOOL:UINT,UINT,UINT -+VOID:STRING -+VOID:STRING,INT -+VOID:STRING,STRING,STRING -+VOID:UINT,UINT,UINT -+VOID:VOID --- -1.7.4.1 - -From a9a7d77b540826259889aa8c8936b7a3cae1593d Mon Sep 17 00:00:00 2001 -From: fujiwarat -Date: Fri, 25 Mar 2011 13:57:31 +0900 -Subject: [PATCH] Set WM_CLASS name instead of main.py - ---- - ui/gtk/panel.py | 11 ++++++++++- - 1 files changed, 11 insertions(+), 1 deletions(-) - -diff --git a/ui/gtk/panel.py b/ui/gtk/panel.py -index 07b0fa2..9d63a17 100644 ---- a/ui/gtk/panel.py -+++ b/ui/gtk/panel.py -@@ -37,7 +37,7 @@ - - from i18n import _, N_ - --ICON_KEYBOARD = "ibus-keyboard" -+ICON_KEYBOARD = "input-keyboard-symbolic" - ICON_ENGINE = "ibus-engine" - - def show_uri(screen, link): -@@ -103,6 +103,16 @@ class Panel(ibus.PanelBase): - - - self.__status_icon = gtk.StatusIcon() -+ # gnome-shell checks XClassHint.res_class with ShellTrayIcon. -+ # gtk_status_icon_set_name() can set XClassHint.res_class . -+ # However gtk_status_icon_new() also calls gtk_window_realize() so -+ # gtk_status_icon_set_visible() needs to be called to set WM_CLASS -+ # so that gtk_window_realize() is called later again. -+ # set_title is for gnome-shell notificationDaemon in bottom right. -+ self.__status_icon.set_visible(False) -+ self.__status_icon.set_name('ibus-ui-gtk') -+ self.__status_icon.set_title(_("IBus Panel")) -+ self.__status_icon.set_visible(True) - self.__status_icon.connect("popup-menu", self.__status_icon_popup_menu_cb) - self.__status_icon.connect("activate", self.__status_icon_activate_cb) - self.__status_icon.set_from_icon_name(ICON_KEYBOARD) --- -1.7.4.1 diff --git a/ibus-xx-setup-frequent-lang.patch b/ibus-xx-setup-frequent-lang.patch new file mode 100644 index 0000000..1d28a22 --- /dev/null +++ b/ibus-xx-setup-frequent-lang.patch @@ -0,0 +1,428 @@ +From 8e982ef7d76f40f3e516c2f2a96b2e4f68e65fc2 Mon Sep 17 00:00:00 2001 +From: fujiwarat +Date: Tue, 19 Apr 2011 11:43:03 +0900 +Subject: [PATCH] Enable ibus-setup to show the frequent used languages only in IME list. + +--- + data/ibus.schemas.in | 168 +++++++++++++++++++++++++++++++++++++++++++++++ + setup/enginecombobox.py | 153 ++++++++++++++++++++++++++++++++++++------ + setup/main.py | 1 + + 3 files changed, 300 insertions(+), 22 deletions(-) + +diff --git a/data/ibus.schemas.in b/data/ibus.schemas.in +index 39922a0..2e33b2c 100644 +--- a/data/ibus.schemas.in ++++ b/data/ibus.schemas.in +@@ -239,6 +239,174 @@ + + + ++ /schemas/desktop/ibus/general/xkblayoutconfig/system/group_list ++ /desktop/ibus/general/xkblayoutconfig/system/group_list ++ ibus ++ list ++ string ++ [west_europe,south_europe,east_europe,north_europe,west_asia,center_asia,east_asia,india,australia] ++ ++ List of system keyboard layout groups on ibus-setup ++ The group list is used not to show all the system ++ keyboard layouts by default. The list item will be ++ appended at the end of gconf key. e.g. ++ .../xkblayoutconfig/system/item1 ++ ++ ++ ++ /schemas/desktop/ibus/general/xkblayoutconfig/system/west_europe ++ /desktop/ibus/general/xkblayoutconfig/system/west_europe ++ ibus ++ list ++ string ++ ++ [ca,cs,de,en,es,fr,gd,hu,it,nl,pt,sk,sl] ++ ++ List of European languages on ibus-setup ++ ibus-setup shows the languages only in input method list ++ when you run ibus-setup on one of the languages. ++ Other languages are hidden under an extended button. ++ ++ ++ ++ /schemas/desktop/ibus/general/xkblayoutconfig/system/south_europe ++ /desktop/ibus/general/xkblayoutconfig/system/south_europe ++ ibus ++ list ++ string ++ ++ [bg,bs,el,mk,mt,ro,sq,sr] ++ ++ List of European languages on ibus-setup ++ ibus-setup shows the languages only in input method list ++ when you run ibus-setup on one of the languages. ++ Other languages are hidden under an extended button. ++ ++ ++ ++ /schemas/desktop/ibus/general/xkblayoutconfig/system/east_europe ++ /desktop/ibus/general/xkblayoutconfig/system/east_europe ++ ibus ++ list ++ string ++ ++ [be,csb,cv,et,ka,kk,ky,lt,lv,pl,ru,tt,uk,uz] ++ ++ List of European languages on ibus-setup ++ ibus-setup shows the languages only in input method list ++ when you run ibus-setup on one of the languages. ++ Other languages are hidden under an extended button. ++ ++ ++ ++ /schemas/desktop/ibus/general/xkblayoutconfig/system/north_europe ++ /desktop/ibus/general/xkblayoutconfig/system/north_europe ++ ibus ++ list ++ string ++ ++ [da,fi,fo,is,no,se,sv] ++ ++ List of European languages on ibus-setup ++ ibus-setup shows the languages only in input method list ++ when you run ibus-setup on one of the languages. ++ Other languages are hidden under an extended button. ++ ++ ++ ++ /schemas/desktop/ibus/general/xkblayoutconfig/system/west_asia ++ /desktop/ibus/general/xkblayoutconfig/system/west_asia ++ ibus ++ list ++ string ++ ++ [am,ar,az,ber,fa,ha,he,hy,ig,ku,tg,tr,yo] ++ ++ List of Asian languages on ibus-setup ++ ibus-setup shows the languages only in input method list ++ when you run ibus-setup on one of the languages. ++ Other languages are hidden under an extended button. ++ ++ ++ ++ /schemas/desktop/ibus/general/xkblayoutconfig/system/center_asia ++ /desktop/ibus/general/xkblayoutconfig/system/center_asia ++ ibus ++ list ++ string ++ ++ [bo,zh] ++ ++ List of Asian languages on ibus-setup ++ ibus-setup shows the languages only in input method list ++ when you run ibus-setup on one of the languages. ++ Other languages are hidden under an extended button. ++ ++ ++ ++ /schemas/desktop/ibus/general/xkblayoutconfig/system/east_asia ++ /desktop/ibus/general/xkblayoutconfig/system/east_asia ++ ibus ++ list ++ string ++ ++ [dz,km,lo,my,th,vi] ++ ++ List of Asian languages on ibus-setup ++ ibus-setup shows the languages only in input method list ++ when you run ibus-setup on one of the languages. ++ Other languages are hidden under an extended button. ++ ++ ++ ++ /schemas/desktop/ibus/general/xkblayoutconfig/system/india ++ /desktop/ibus/general/xkblayoutconfig/system/india ++ ibus ++ list ++ string ++ ++ [bn,dv,gu,hi,kn,ml,ne,or,pa,si,ta,te,ur] ++ ++ List of Asian languages on ibus-setup ++ ibus-setup shows the languages only in input method list ++ when you run ibus-setup on one of the languages. ++ Other languages are hidden under an extended button. ++ ++ ++ ++ /schemas/desktop/ibus/general/xkblayoutconfig/system/australia ++ /desktop/ibus/general/xkblayoutconfig/system/australia ++ ibus ++ list ++ string ++ ++ [mi] ++ ++ List of Asian languages on ibus-setup ++ ibus-setup shows the languages only in input method list ++ when you run ibus-setup on one of the languages. ++ Other languages are hidden under an extended button. ++ ++ ++ + /schemas/desktop/ibus/panel/use_custom_font + /desktop/ibus/panel/use_custom_font + ibus +diff --git a/setup/enginecombobox.py b/setup/enginecombobox.py +index 7383177..c5b194f 100644 +--- a/setup/enginecombobox.py ++++ b/setup/enginecombobox.py +@@ -43,7 +43,10 @@ class EngineComboBox(gtk.ComboBox): + self.connect("notify::active", self.__notify_active_cb) + + self.__model = None ++ self.__all_model = None ++ self.__config = None + self.__title = _("Select an input method") ++ self.__show_sub_lang = False + + renderer = gtk.CellRendererPixbuf() + renderer.set_property("xalign", 0) +@@ -57,18 +60,51 @@ class EngineComboBox(gtk.ComboBox): + self.pack_start(renderer, True) + self.set_cell_data_func(renderer, self.__name_cell_data_cb) + +- def set_engines(self, engines): +- self.__model = gtk.TreeStore(gobject.TYPE_PYOBJECT) ++ def __gconf_get_lang_list_from_locale(self): ++ common_list = ['en', 'Other'] ++ if self.__config == None: ++ return None ++ loc = None ++ try: ++ loc = locale.setlocale (locale.LC_ALL) ++ except: ++ pass ++ if loc == None: ++ return common_list ++ current_lang = ibus.get_language_name(loc) ++ if current_lang == None: ++ return common_list ++ group_list = self.__config.get_value("general/xkblayoutconfig/system", ++ "group_list", None) ++ if group_list == None: ++ return [loc] + common_list ++ group_list = list(group_list) ++ lang_list = None ++ for group in group_list: ++ group = str(group) ++ langs = self.__config.get_value("general/xkblayoutconfig/system", ++ group, []) ++ for lang in langs: ++ lang = str(lang) ++ if current_lang == ibus.get_language_name(lang): ++ lang_list = langs ++ break ++ if lang_list != None: ++ break ++ if lang_list == None: ++ return [loc] + common_list ++ return lang_list + common_list + +- iter1 = self.__model.append(None) +- self.__model.set(iter1, 0, 0) +- lang = {} +- for e in engines: +- l = ibus.get_language_name(e.language) +- if l not in lang: +- lang[l] = [] +- lang[l].append(e) ++ def __has_engine_in_lang_list(self, engine, lang_list): ++ retval = False ++ for lang in lang_list: ++ if ibus.get_language_name(lang) == \ ++ ibus.get_language_name(engine.language): ++ retval = True ++ break ++ return retval + ++ def __model_append_langs(self, model, lang, visible): + keys = lang.keys() + keys.sort(locale.strcoll) + #add "Others" to the end of the combo box +@@ -76,29 +112,86 @@ class EngineComboBox(gtk.ComboBox): + keys.remove(ibus.get_language_name("Other")) + keys += [ibus.get_language_name("Other")] + for l in keys: +- iter1 = self.__model.append(None) +- self.__model.set(iter1, 0, l) ++ iter1 = model.append(None) ++ model.set(iter1, 0, l) + def cmp_engine(a, b): + if a.rank == b.rank: + return locale.strcoll(a.longname, b.longname) + return int(b.rank - a.rank) + lang[l].sort(cmp_engine) + for e in lang[l]: +- iter2 = self.__model.append(iter1) +- self.__model.set(iter2, 0, e) ++ iter2 = model.append(iter1) ++ model.set(iter2, 0, e) ++ ++ def set_engines(self, engines): ++ self.__model = gtk.TreeStore(gobject.TYPE_PYOBJECT) ++ ++ iter1 = self.__model.append(None) ++ self.__model.set(iter1, 0, 0) ++ lang_list = self.__gconf_get_lang_list_from_locale() ++ lang = {} ++ sub_lang = {} ++ for e in engines: ++ l = ibus.get_language_name(e.language) ++ if lang_list == None or \ ++ self.__has_engine_in_lang_list(e, lang_list): ++ if l not in lang: ++ lang[l] = [] ++ lang[l].append(e) ++ else: ++ if l not in sub_lang: ++ sub_lang[l] = [] ++ sub_lang[l].append(e) ++ ++ self.__model_append_langs(self.__model, lang, True) ++ iter1 = self.__model.append(None) ++ self.__model.set(iter1, 0, -1) ++ ++ self.__all_model = gtk.TreeStore(gobject.TYPE_PYOBJECT) ++ iter1 = self.__all_model.append(None) ++ self.__all_model.set(iter1, 0, 0) ++ self.__model_append_langs(self.__all_model, lang, False) ++ iter1 = self.__all_model.append(None) ++ self.__all_model.set(iter1, 0, -1) ++ self.__model_append_langs(self.__all_model, sub_lang, False) ++ ++ self.__toggle_sub_lang() + +- self.set_model(self.__model) ++ def __toggle_sub_lang(self): ++ self.set_model(None) ++ if self.__show_sub_lang: ++ self.set_model(self.__all_model) ++ else: ++ self.set_model(self.__model) + self.set_active(0) + + def __icon_cell_data_cb(self, celllayout, renderer, model, iter): +- engine = self.__model.get_value(iter, 0) ++ model = self.get_model() ++ engine = model.get_value(iter, 0) + + if isinstance(engine, str) or isinstance (engine, unicode): + renderer.set_property("visible", False) + renderer.set_property("sensitive", False) + elif isinstance(engine, int): +- renderer.set_property("visible", False) +- renderer.set_property("sensitive", False) ++ if engine == 0: ++ renderer.set_property("visible", False) ++ renderer.set_property("sensitive", False) ++ renderer.set_property("pixbuf", None) ++ elif engine < 0: ++ if not self.__show_sub_lang: ++ pixbuf = load_icon("list-add", gtk.ICON_SIZE_LARGE_TOOLBAR) ++ else: ++ pixbuf = load_icon("list-remove", gtk.ICON_SIZE_LARGE_TOOLBAR) ++ if pixbuf == None: ++ pixbuf = load_icon("gtk-missing-image", ++ gtk.ICON_SIZE_LARGE_TOOLBAR) ++ if pixbuf == None: ++ renderer.set_property("visible", False) ++ renderer.set_property("sensitive", False) ++ return ++ renderer.set_property("visible", True) ++ renderer.set_property("sensitive", True) ++ renderer.set_property("pixbuf", pixbuf) + else: + renderer.set_property("visible", True) + renderer.set_property("sensitive", True) +@@ -110,7 +203,8 @@ class EngineComboBox(gtk.ComboBox): + renderer.set_property("pixbuf", pixbuf) + + def __name_cell_data_cb(self, celllayout, renderer, model, iter): +- engine = self.__model.get_value(iter, 0) ++ model = self.get_model() ++ engine = model.get_value(iter, 0) + + if isinstance (engine, str) or isinstance (engine, unicode): + renderer.set_property("sensitive", False) +@@ -118,8 +212,15 @@ class EngineComboBox(gtk.ComboBox): + renderer.set_property("weight", pango.WEIGHT_NORMAL) + elif isinstance(engine, int): + renderer.set_property("sensitive", True) +- renderer.set_property("text", self.__title) +- renderer.set_property("weight", pango.WEIGHT_NORMAL) ++ if engine == 0: ++ renderer.set_property("text", self.__title) ++ renderer.set_property("weight", pango.WEIGHT_NORMAL) ++ elif engine < 0: ++ if not self.__show_sub_lang: ++ renderer.set_property("text", _("Show all languages")) ++ else: ++ renderer.set_property("text", _("Show frequent used languages only")) ++ renderer.set_property("weight", pango.WEIGHT_BOLD) + else: + renderer.set_property("sensitive", True) + renderer.set_property("text", engine.longname) +@@ -134,13 +235,21 @@ class EngineComboBox(gtk.ComboBox): + if i == 0 or i == -1: + return None + iter = self.get_active_iter() +- return self.get_model()[iter][0] ++ model = self.get_model() ++ if model[iter][0] == -1: ++ self.__show_sub_lang = not self.__show_sub_lang ++ self.__toggle_sub_lang() ++ return None ++ return model[iter][0] + else: + raise AttributeError, 'unknown property %s' % property.name + + def get_active_engine(self): + return self.get_property("active-engine") + ++ def set_config(self, config): ++ self.__config = config ++ + def get_title(self): + return self.__title + +diff --git a/setup/main.py b/setup/main.py +index 9cdce02..5201139 100644 +--- a/setup/main.py ++++ b/setup/main.py +@@ -226,6 +226,7 @@ class Setup(object): + button.connect("toggled", self.__checkbutton_preload_engine_mode_toggled_cb) + self.__engines = self.__bus.list_engines() + self.__combobox = self.__builder.get_object("combobox_engines") ++ self.__combobox.set_config(self.__config) + self.__combobox.set_engines(self.__engines) + + engines = self.__bus.list_active_engines() +-- +1.7.4.2 + diff --git a/ibus.spec b/ibus.spec index c8181ac..ee9f5dd 100644 --- a/ibus.spec +++ b/ibus.spec @@ -12,8 +12,8 @@ %define gnome_icon_theme_legacy_version 2.91.6 Name: ibus -Version: 1.3.99.20110228 -Release: 7%{?dist} +Version: 1.3.99.20110408 +Release: 1%{?dist} Summary: Intelligent Input Bus for Linux OS License: LGPLv2+ Group: System Environment/Libraries @@ -23,16 +23,12 @@ Source1: xinput-ibus %if %have_gjsfile Source2: http://fujiwara.fedorapeople.org/ibus/gnome-shell/gnome-shell-ibus-plugins-20110317.tar.bz2 %endif -Source3: http://fujiwara.fedorapeople.org/ibus/20110404/ibus-po-20110404.tar.bz2 -Patch0: ibus-HEAD.patch +Source3: https://www.transifex.net/projects/p/ibus/resource/master/l/da/download/ibus_master_da.po +# Patch0: ibus-HEAD.patch Patch1: ibus-435880-surrounding-text.patch Patch2: ibus-541492-xkb.patch Patch3: ibus-530711-preload-sys.patch -Patch4: ibus-657165-panel-libs.patch -# This will be removed after the new gnome-shell is integrated. -Patch99: ibus-675503-gnome-shell-workaround.patch -# This will be removed after the gnome-shell ibus patch is integrated. -Patch100: ibus-688034-fedora-g-s.patch +Patch4: ibus-xx-setup-frequent-lang.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) @@ -116,6 +112,7 @@ Summary: IBus im module for gtk3 Group: System Environment/Libraries Requires: %{name} = %{version}-%{release} Requires: %{name}-libs = %{version}-%{release} +Requires: imsettings-gnome Requires(post): glib2 >= %{glib_ver} %description gtk3 @@ -147,9 +144,8 @@ The ibus-devel-docs package contains developer documentation for ibus %if %have_gjsfile bzcat %SOURCE2 | tar xf - %endif -bzcat %SOURCE3 | tar xf - -%patch0 -p1 -%patch99 -p1 -b .g-s-typo +cp %SOURCE3 po/da.po +# %patch0 -p1 # start surrounding patch %patch1 -p1 -b .surrounding cp client/gtk2/ibusimcontext.c client/gtk3/ibusimcontext.c @@ -158,9 +154,7 @@ cp client/gtk2/ibusimcontext.c client/gtk3/ibusimcontext.c %patch2 -p1 -b .xkb %endif %patch3 -p1 -b .preload-sys -%patch4 -p1 -b .panel-libs -# workaround until the ibus feature is integrated into gnome-shell. -%patch100 -p1 -b .fedora-g-s +%patch4 -p1 -b .setup-frequent-lang %build %if %have_libxkbfile @@ -334,13 +328,17 @@ fi %{_datadir}/gtk-doc/html/* %changelog -* Tue Apr 05 2011 Takao Fujiwara - 1.3.99.20110228-7 -- Updated ibus-HEAD.patch +* Tue Apr 19 2011 Takao Fujiwara - 1.3.99.20110408-1 +- Updated to 1.3.99.20110408 Fixed Bug 683484 - Timed out SetEngine when select an engine from panel. Fixed Bug 657165 - IBus for gnome-shell for Fedora 15. -- Updated ibus-657165-panel-libs.patch -- Added ibus-688034-fedora-g-s.patch for Fedora workaround. -- Added ibus-po-20110404.tar.bz2 for po files. +- Upstreamed ibus-657165-panel-libs.patch +- Removed ibus-675503-gnome-shell-workaround.patch +- Added ibus-xx-setup-frequent-lang.patch +- Updated ibus-541492-xkb.patch + Fixed Bug 696481 - no the variant maps without language codes +- Added dependency of imsettings-gnome. + Fixed Bug 696510 - need a dependency in ibus-gtk3 for imsettings-gnome * Thu Mar 10 2011 Takao Fujiwara - 1.3.99.20110228-1 - Updated to 1.3.99.20110228 diff --git a/sources b/sources index ceb8733..afe4d57 100644 --- a/sources +++ b/sources @@ -1,3 +1,3 @@ -223ce787c5357f833ba34cdaf502ef76 ibus-1.3.99.20110228.tar.gz +6ce34da8e9283d6df076bf6af9bbf815 ibus-1.3.99.20110408.tar.gz 2d6991ca7d3147aa486b6297872bed5f gnome-shell-ibus-plugins-20110317.tar.bz2 -6d102835e2cd2efe459fb3c08823e66d ibus-po-20110404.tar.bz2 +698c90edf0f037488e1aa969804e891f ibus_master_da.po