[ibus/f16] Enhanced ibus-gnome3 shell lookup window.

Takao Fujiwara fujiwara at fedoraproject.org
Fri Dec 30 08:17:35 UTC 2011


commit 8ffe46251de0fafa724d2497c614262fda829c9a
Author: Takao Fujiwara <tfujiwar at redhat.com>
Date:   Fri Dec 30 17:16:36 2011 +0900

    Enhanced ibus-gnome3 shell lookup window.
    
    Updated ibus-HEAD.patch from upstream
     * Fixed Bug 769135 - ibus-x11 SEGV in _process_key_event_done.
    Updated ibus-541492-xkb.patch
     * Fixed Bug 757889 - ibus-setup SEGV without active engine.
     * Fixed Bug 760213 - ibus-setup saves XKB variants correctly.
     * Fixed Bug 769133 - ibus-engine-xkb returns FALSE for ASCII typings.
    Updated ibus-xx-bridge-hotkey.patch for an enhancement.

 .gitignore                    |    1 +
 ibus-530711-preload-sys.patch |   32 +-
 ibus-541492-xkb.patch         |   79 +++-
 ibus-HEAD.patch               | 1005 ++++++++++++++++++++++++++++++++++++++++-
 ibus-xx-bridge-hotkey.patch   |    4 +-
 ibus.spec                     |   16 +-
 sources                       |    2 +-
 7 files changed, 1094 insertions(+), 45 deletions(-)
---
diff --git a/.gitignore b/.gitignore
index 20f05a7..ee43755 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,3 +31,4 @@ ibus-1.3.6.tar.gz
 /ibus-gjs-3.0.2.20111118.tar.gz
 /ibus-gjs-3.2.1.20111118.tar.gz
 /ibus-gjs-3.2.1.20111128.tar.gz
+/ibus-gjs-3.2.1.20111230.tar.gz
diff --git a/ibus-530711-preload-sys.patch b/ibus-530711-preload-sys.patch
index ddd1bbd..941e7e9 100644
--- a/ibus-530711-preload-sys.patch
+++ b/ibus-530711-preload-sys.patch
@@ -1,6 +1,6 @@
-From a7e922f290c1e3eba42ca1c6147ab1704ec272fb Mon Sep 17 00:00:00 2001
+From 8f5bb828744532bcfded7e92f3a1db1f26e567e8 Mon Sep 17 00:00:00 2001
 From: fujiwarat <takao.fujiwara1 at gmail.com>
-Date: Mon, 26 Sep 2011 13:06:05 +0900
+Date: Fri, 30 Dec 2011 15:46:56 +0900
 Subject: [PATCH] Reload preload engines until users customize the list.
 
 The idea is, if users don't customize the preload_engines with ibus-setup,
@@ -26,7 +26,7 @@ IBUS_PRELOAD_ENGINE_MODE_USER and users can customize the value
  6 files changed, 440 insertions(+), 97 deletions(-)
 
 diff --git a/bus/ibusimpl.c b/bus/ibusimpl.c
-index 1942504..3fce912 100644
+index 059d660..bba9353 100644
 --- a/bus/ibusimpl.c
 +++ b/bus/ibusimpl.c
 @@ -142,6 +142,9 @@ static void     bus_ibus_impl_set_previous_engine
@@ -503,7 +503,7 @@ index 1942504..3fce912 100644
      { "general", "use_global_engine",            bus_ibus_impl_set_use_global_engine },
      { "general", "embed_preedit_text",           bus_ibus_impl_set_embed_preedit_text },
 diff --git a/data/ibus.schemas.in b/data/ibus.schemas.in
-index 8979515..fef1810 100644
+index e0a6a37..2418c95 100644
 --- a/data/ibus.schemas.in
 +++ b/data/ibus.schemas.in
 @@ -6,7 +6,7 @@
@@ -560,10 +560,10 @@ index 6483aae..127ed93 100644
      pass
  
 diff --git a/setup/main.py b/setup/main.py
-index 7f4a040..095084b 100644
+index 97e05a4..7d734ae 100644
 --- a/setup/main.py
 +++ b/setup/main.py
-@@ -91,6 +91,7 @@ class Setup(object):
+@@ -92,6 +92,7 @@ class Setup(object):
          # keyboard shortcut
          # trigger
          self.__config = self.__bus.get_config()
@@ -571,7 +571,7 @@ index 7f4a040..095084b 100644
          shortcuts = self.__config.get_value(
                          "general/hotkey", "trigger",
                          ibus.CONFIG_GENERAL_SHORTCUT_TRIGGER_DEFAULT)
-@@ -212,15 +213,22 @@ class Setup(object):
+@@ -213,15 +214,22 @@ class Setup(object):
          self.__checkbutton_use_global_engine.connect("toggled", self.__checkbutton_use_global_engine_toggled_cb)
  
          # init engine page
@@ -599,7 +599,7 @@ index 7f4a040..095084b 100644
  
          self.__treeview = self.__builder.get_object("treeview_engines")
          self.__treeview.set_engines(engines)
-@@ -248,7 +256,8 @@ class Setup(object):
+@@ -251,7 +259,8 @@ class Setup(object):
      def __combobox_notify_active_engine_cb(self, combobox, property):
          engine = self.__combobox.get_active_engine()
          button = self.__builder.get_object("button_engine_add")
@@ -609,7 +609,7 @@ index 7f4a040..095084b 100644
  
      def __get_engine_setup_exec_args(self, engine):
          args = []
-@@ -290,6 +299,26 @@ class Setup(object):
+@@ -293,6 +302,26 @@ class Setup(object):
              engine_names = map(lambda e: e.name, engines)
              self.__config.set_list("general", "preload_engines", engine_names, "s")
  
@@ -636,7 +636,7 @@ index 7f4a040..095084b 100644
      def __button_engine_add_cb(self, button):
          engine = self.__combobox.get_active_engine()
          self.__treeview.append_engine(engine)
-@@ -319,6 +348,32 @@ class Setup(object):
+@@ -322,6 +351,32 @@ class Setup(object):
              del self.__engine_setup_exec_list[name]
          self.__engine_setup_exec_list[name] = os.spawnl(os.P_NOWAIT, *args)
  
@@ -669,7 +669,7 @@ index 7f4a040..095084b 100644
      def __init_bus(self):
          try:
              self.__bus = ibus.Bus()
-@@ -509,7 +564,11 @@ class Setup(object):
+@@ -512,7 +567,11 @@ class Setup(object):
          self.__config.set_value("general", "use_global_engine", value)
  
      def __config_value_changed_cb(self, bus, section, name, value):
@@ -683,10 +683,10 @@ index 7f4a040..095084b 100644
      def __config_reloaded_cb(self, bus):
          pass
 diff --git a/setup/setup.ui b/setup/setup.ui
-index f1e6d0b..562c091 100644
+index 57cb597..b2ceef2 100644
 --- a/setup/setup.ui
 +++ b/setup/setup.ui
-@@ -585,7 +585,22 @@
+@@ -582,7 +582,22 @@
                      <property name="visible">True</property>
                      <property name="orientation">vertical</property>
                      <child>
@@ -710,7 +710,7 @@ index f1e6d0b..562c091 100644
                          <property name="visible">True</property>
                          <child>
                            <object class="GtkAlignment" id="alignment6">
-@@ -752,7 +767,7 @@
+@@ -749,7 +764,7 @@
                          </child>
                        </object>
                        <packing>
@@ -719,7 +719,7 @@ index f1e6d0b..562c091 100644
                        </packing>
                      </child>
                      <child>
-@@ -791,7 +806,7 @@ You may use up/down buttons to change it
+@@ -788,7 +803,7 @@ You may use up/down buttons to change it.&lt;/i&gt;&lt;/small&gt;</property>
                        </object>
                        <packing>
                          <property name="expand">False</property>
@@ -750,5 +750,5 @@ index d916265..422eb84 100644
   * @x: x coordinate.
   * @y: y coordinate.
 -- 
-1.7.6.2
+1.7.7.4
 
diff --git a/ibus-541492-xkb.patch b/ibus-541492-xkb.patch
index 8f7cf00..a7c9667 100644
--- a/ibus-541492-xkb.patch
+++ b/ibus-541492-xkb.patch
@@ -1,6 +1,6 @@
-From a8f02d4be33f87cf97039736407cd13e795b992b Mon Sep 17 00:00:00 2001
+From 5b4c1700b4798f20b61dec5193b3f08d1e60742d Mon Sep 17 00:00:00 2001
 From: fujiwarat <takao.fujiwara1 at gmail.com>
-Date: Fri, 18 Nov 2011 18:05:42 +0900
+Date: Fri, 30 Dec 2011 15:46:13 +0900
 Subject: [PATCH] Add XKB layouts
 
 ---
@@ -18,7 +18,7 @@ Subject: [PATCH] Add XKB layouts
  setup/enginecombobox.py      |    7 +-
  setup/main.py                |    3 +
  setup/setup.ui               |  609 ++++++-
- setup/xkbsetup.py            |  457 +++++
+ setup/xkbsetup.py            |  490 +++++
  src/Makefile.am              |    5 +
  src/ibus.h                   |    1 +
  src/ibusxkbxml.c             |  441 +++++
@@ -29,7 +29,7 @@ Subject: [PATCH] Add XKB layouts
  xkb/gtkimcontextsimpleseqs.h | 4484 ++++++++++++++++++++++++++++++++++++++++++
  xkb/ibus-engine-xkb-main.c   |  303 +++
  xkb/ibus-engine-xkb-main.h   |   32 +
- xkb/ibus-simple-engine.c     | 1003 ++++++++++
+ xkb/ibus-simple-engine.c     | 1007 ++++++++++
  xkb/ibus-simple-engine.h     |   13 +
  xkb/ibus-xkb-main.c          |  112 ++
  xkb/xkblayout.xml.in         |   16 +
@@ -38,7 +38,7 @@ Subject: [PATCH] Add XKB layouts
  xkb/xkblib.h                 |   41 +
  xkb/xkbxml.c                 |  345 ++++
  xkb/xkbxml.h                 |  113 ++
- 34 files changed, 9664 insertions(+), 4 deletions(-)
+ 34 files changed, 9701 insertions(+), 4 deletions(-)
  create mode 100644 ibus/xkblayout.py.in
  create mode 100644 ibus/xkbxml.py.in
  create mode 100644 setup/xkbsetup.py
@@ -1153,7 +1153,7 @@ index 2fd8876..7383177 100644
 +        self.__title = title
  
 diff --git a/setup/main.py b/setup/main.py
-index a22bb0c..7f4a040 100644
+index 6c0fb0e..97e05a4 100644
 --- a/setup/main.py
 +++ b/setup/main.py
 @@ -37,6 +37,7 @@ from gtk import gdk
@@ -1164,7 +1164,7 @@ index a22bb0c..7f4a040 100644
  from i18n import DOMAINNAME, _, N_, init as i18n_init
  
  (
-@@ -241,6 +242,8 @@ class Setup(object):
+@@ -245,6 +246,8 @@ class Setup(object):
          self.__combobox.connect("notify::active-engine", self.__combobox_notify_active_engine_cb)
          self.__treeview.connect("notify", self.__treeview_notify_cb)
  
@@ -1174,7 +1174,7 @@ index a22bb0c..7f4a040 100644
          engine = self.__combobox.get_active_engine()
          button = self.__builder.get_object("button_engine_add")
 diff --git a/setup/setup.ui b/setup/setup.ui
-index 0a69df8..f1e6d0b 100644
+index c7ff564..57cb597 100644
 --- a/setup/setup.ui
 +++ b/setup/setup.ui
 @@ -117,7 +117,6 @@
@@ -1201,7 +1201,7 @@ index 0a69df8..f1e6d0b 100644
                                          <property name="can_focus">True</property>
                                          <property name="receives_default">False</property>
                                          <property name="use_underline">True</property>
-@@ -825,6 +822,7 @@ You may use up/down buttons to change it.&lt;/i&gt;&lt;/small&gt;</property>
+@@ -841,6 +838,7 @@ You may use up/down buttons to change it.&lt;/i&gt;&lt;/small&gt;</property>
                                      <property name="visible">True</property>
                                      <property name="orientation">vertical</property>
                                      <property name="spacing">6</property>
@@ -1209,7 +1209,7 @@ index 0a69df8..f1e6d0b 100644
                                      <child>
                                        <object class="GtkCheckButton" id="checkbutton_use_sys_layout">
                                          <property name="label" translatable="yes">Use system keyboard layout</property>
-@@ -840,6 +838,57 @@ You may use up/down buttons to change it.&lt;/i&gt;&lt;/small&gt;</property>
+@@ -856,6 +854,57 @@ You may use up/down buttons to change it.&lt;/i&gt;&lt;/small&gt;</property>
                                          <property name="position">0</property>
                                        </packing>
                                      </child>
@@ -1267,7 +1267,7 @@ index 0a69df8..f1e6d0b 100644
                                    </object>
                                  </child>
                                </object>
-@@ -1038,4 +1087,558 @@ Homepage: http://code.google.com/p/ibus
+@@ -1054,4 +1103,558 @@ Homepage: http://code.google.com/p/ibus
        </object>
      </child>
    </object>
@@ -1828,10 +1828,10 @@ index 0a69df8..f1e6d0b 100644
  </interface>
 diff --git a/setup/xkbsetup.py b/setup/xkbsetup.py
 new file mode 100644
-index 0000000..af9ec53
+index 0000000..e777cea
 --- /dev/null
 +++ b/setup/xkbsetup.py
-@@ -0,0 +1,457 @@
+@@ -0,0 +1,490 @@
 +# vim:set et sts=4 sw=4:
 +#
 +# ibus - The Input Bus
@@ -2061,7 +2061,15 @@ index 0000000..af9ec53
 +            self.__treeview_system_keyboard_layout.set_engines([engine])
 +            button_reset.set_sensitive(False)
 +        else:
-+            for layout in text.split(','):
++            # The saved string 'cz,us(qwerty,)' needs to be rearranged to
++            # ['cz(qwerty)', 'us'] for each engine.
++            [l, v] = self.__get_model_from_layout(text)
++            variants = []
++            if v != 'default' and v != None:
++                variants = v.split(',')
++            for i, layout in enumerate(l.split(',')):
++                if i < len(variants) and len(variants[i]) > 0:
++                    layout = '%s(%s)' % (layout, variants[i])
 +                layout_engine = None
 +                for engine in xkb_engines:
 +                    if layout == engine.layout:
@@ -2143,6 +2151,14 @@ index 0000000..af9ec53
 +        self.__init_system_keyboard_layout()
 +        self.__init_system_keyboard_option()
 +
++    def __get_model_from_layout(self, layout):
++        left_bracket = layout.find('(')
++        right_bracket = layout.find(')')
++        if left_bracket >= 0 and right_bracket > left_bracket:
++            return (layout[:left_bracket] + layout[right_bracket + 1:], \
++                    layout[left_bracket + 1:right_bracket])
++        return (layout, 'default')
++
 +    def __combobox_notify_active_system_keyboard_layout_cb(self, combobox, property):
 +        engine = self.__combobox_system_keyboard_layout.get_active_engine()
 +        button = self.__builder.get_object("button_system_keyboard_layout_engine_add")
@@ -2168,6 +2184,9 @@ index 0000000..af9ec53
 +    def __button_system_keyboard_layout_add_cb(self, button):
 +        engines = self.__treeview_system_keyboard_layout.get_engines()
 +        engine = self.__combobox_system_keyboard_layout.get_active_engine()
++        if engine == None:
++            return
++        # If engines[0] is the default dummy engine:
 +        if len(engines) > 0 and engines[0].layout == "default":
 +            self.__treeview_system_keyboard_layout.set_engines([engine])
 +        else:
@@ -2226,12 +2245,26 @@ index 0000000..af9ec53
 +
 +    def __button_system_keyboard_layout_ok_cb(self, button):
 +        self.__dialog_system_keyboard_layout.hide()
-+        layout = "default"
++        layout = 'default'
++        variant = ''
++        has_variant = False
++        # if the string is 'cz(qwerty),us[options,...]', it would difficult
++        # to separate layouts by comma. So we rearrange this likes
++        # 'cz,us(qwerty,)[options,...]' here.
 +        for engine in self.__treeview_system_keyboard_layout.get_engines():
++            [l, v] = self.__get_model_from_layout(engine.layout)
++            if v == 'default' or v == None:
++                v = ''
++            if len(v) > 0:
++                has_variant = True
 +            if layout == "default":
-+                layout = engine.layout
++                layout = l
++                variant = v
 +            else:
-+                layout = "%s,%s" % (layout, engine.layout)
++                layout = '%s,%s' % (layout, l)
++                variant = '%s,%s' % (variant, v)
++        if has_variant:
++            layout = '%s(%s)' % (layout, variant)
 +        if layout == None or layout == "":
 +            layout = "default"
 +        org_layout = str(self.__config.get_value("general", "system_keyboard_layout", None))
@@ -8097,10 +8130,10 @@ index 0000000..255e952
 +#endif
 diff --git a/xkb/ibus-simple-engine.c b/xkb/ibus-simple-engine.c
 new file mode 100644
-index 0000000..815311b
+index 0000000..4b5bd83
 --- /dev/null
 +++ b/xkb/ibus-simple-engine.c
-@@ -0,0 +1,1003 @@
+@@ -0,0 +1,1007 @@
 +/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
 +/* vim:set et sts=4: */
 +#ifdef HAVE_CONFIG_H
@@ -8891,7 +8924,11 @@ index 0000000..815311b
 +        }
 +
 +        ch = ibus_keyval_to_unicode (keyval);
-+        if (ch != 0 && !g_unichar_iscntrl (ch)) {
++        /* IBUS_CHANGE: RH#769133
++         * Since we use ibus xkb engines as the disable state,
++         * do not commit the characters locally without in_hex_sequence. */
++        if (ch != 0 && !g_unichar_iscntrl (ch) &&
++            simple->in_hex_sequence) {
 +            ibus_simple_engine_commit_char (simple, ch);
 +            return TRUE;
 +        }
@@ -10126,5 +10163,5 @@ index 0000000..6c00f1d
 +G_END_DECLS
 +#endif
 -- 
-1.7.6.4
+1.7.7.4
 
diff --git a/ibus-HEAD.patch b/ibus-HEAD.patch
index a9f7599..1314c13 100644
--- a/ibus-HEAD.patch
+++ b/ibus-HEAD.patch
@@ -574,14 +574,52 @@ index 0ba826c..58069fc 100644
 -- 
 1.7.6.4
 
-From e7a722948025948f39ac8e7f9d5527a79f23c7ff Mon Sep 17 00:00:00 2001
+From 5d2ac19e1524b1802f5298eedff1ba52423c847f Mon Sep 17 00:00:00 2001
+From: Daiki Ueno <ueno at unixuser.org>
+Date: Wed, 30 Nov 2011 09:40:15 +0900
+Subject: [PATCH] Disable surrounding-text when retrieve-surrounding
+ signal is not handled in GTK.
+
+BUG=https://code.google.com/p/ibus/issues/detail?id=1358
+TEST=On Fedora with ibus-m17n tis820
+
+Review URL: http://codereview.appspot.com/5431086
+---
+ client/gtk2/ibusimcontext.c |    5 +++++
+ 1 files changed, 5 insertions(+), 0 deletions(-)
+
+diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c
+index b6ca12e..5ae5cfc 100644
+--- a/client/gtk2/ibusimcontext.c
++++ b/client/gtk2/ibusimcontext.c
+@@ -278,6 +278,11 @@ _request_surrounding_text (IBusIMContext *context)
+         IDEBUG ("requesting surrounding text");
+         g_signal_emit (context, _signal_retrieve_surrounding_id, 0,
+                        &return_value);
++        if (!return_value) {
++            context->caps &= ~IBUS_CAP_SURROUNDING_TEXT;
++            ibus_input_context_set_capabilities (context->ibuscontext,
++                                                 context->caps);
++        }
+     }
+ }
+ 
+-- 
+1.7.6.4
+
+From 5236e2159f2e6184c18df9a9ecbb05bfb09106d4 Mon Sep 17 00:00:00 2001
 From: fujiwarat <takao.fujiwara1 at gmail.com>
-Date: Fri, 25 Nov 2011 17:19:53 +0900
+Date: Wed, 30 Nov 2011 12:28:22 +0900
 Subject: [PATCH] Add the engine preference button on ibus-setup
 
 The new preference button launches $libexecdir/ibus-setup- + engine.name
 by default. The engine is IBusEngineDesc.
 If engine.setup has a value, the button launches it instead.
+
+BUG=RH#618229
+TEST=Linux desktop
+
+Review URL: http://codereview.appspot.com/5437062
 ---
  ibus/enginedesc.py   |   11 +++++++++--
  setup/ibus-setup.in  |    2 ++
@@ -929,3 +967,966 @@ index 76a7adc..928743e 100644
 -- 
 1.7.6.4
 
+From fd07a5a761fe1c242ba8babaab1060d5679a3618 Mon Sep 17 00:00:00 2001
+From: fujiwarat <takao.fujiwara1 at gmail.com>
+Date: Tue, 20 Dec 2011 13:46:45 +0900
+Subject: [PATCH] Fix a SEGV if ibusimcontext->ibuscontext is null.
+
+BUG=
+TEST=Linux desktop
+
+Review URL: http://codereview.appspot.com/5489086
+---
+ client/gtk2/ibusimcontext.c |    1 +
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+
+diff --git a/client/gtk2/ibusimcontext.c b/client/gtk2/ibusimcontext.c
+index 5ae5cfc..72db581 100644
+--- a/client/gtk2/ibusimcontext.c
++++ b/client/gtk2/ibusimcontext.c
+@@ -273,6 +273,7 @@ _request_surrounding_text (IBusIMContext *context)
+ {
+     if (context && context->enable &&
+         (context->caps & IBUS_CAP_SURROUNDING_TEXT) != 0 &&
++        context->ibuscontext != NULL &&
+         ibus_input_context_needs_surrounding_text (context->ibuscontext)) {
+         gboolean return_value;
+         IDEBUG ("requesting surrounding text");
+-- 
+1.7.7
+
+From ee9c4fba4535e85bd1f02743cab8914dd84e6178 Mon Sep 17 00:00:00 2001
+From: Peng Huang <shawn.p.huang at gmail.com>
+Date: Thu, 22 Dec 2011 09:57:01 -0500
+Subject: [PATCH] Make all fields of IBusProperty as gobject property.
+
+BUG=http://code.google.com/p/ibus/issues/detail?id=1383
+TEST=Linux desktop
+
+Review URL: http://codereview.appspot.com/5500066
+---
+ src/ibusproperty.c |  471 +++++++++++++++++++++++++++++++++++++++------------
+ src/ibusproperty.h |   41 ++---
+ 2 files changed, 376 insertions(+), 136 deletions(-)
+
+diff --git a/src/ibusproperty.c b/src/ibusproperty.c
+index 5a2dd78..e5480fa 100644
+--- a/src/ibusproperty.c
++++ b/src/ibusproperty.c
+@@ -21,8 +21,52 @@
+  */
+ #include "ibusproperty.h"
+ #include "ibusproplist.h"
++#include "ibusenumtypes.h"
++
++enum {
++    LAST_SIGNAL,
++};
++
++enum {
++    PROP_0 = 0,
++    PROP_KEY,
++    PROP_ICON,
++    PROP_LABEL,
++    PROP_TOOLTIP,
++    PROP_SENSITIVE,
++    PROP_VISIBLE,
++    PROP_PROP_TYPE,
++    PROP_STATE,
++    PROP_SUB_PROPS,
++};
++
++/* _IBusPropertyPrivate */
++struct _IBusPropertyPrivate {
++    gchar    *key;
++    gchar    *icon;
++    IBusText *label;
++    IBusText *tooltip;
++
++    gboolean sensitive;
++    gboolean visible;
++    IBusPropType type;
++    IBusPropState state;
++
++    IBusPropList *sub_props;
++};
++
++#define IBUS_PROPERTY_GET_PRIVATE(o)  \
++   (G_TYPE_INSTANCE_GET_PRIVATE ((o), IBUS_TYPE_PROPERTY, IBusPropertyPrivate))
+ 
+ /* functions prototype */
++static void         ibus_property_set_property  (IBusProperty       *prop,
++                                                 guint               prop_id,
++                                                 const GValue       *value,
++                                                 GParamSpec         *pspec);
++static void         ibus_property_get_property  (IBusProperty       *prop,
++                                                 guint               prop_id,
++                                                 GValue             *value,
++                                                 GParamSpec         *pspec);
+ static void         ibus_property_destroy       (IBusProperty       *prop);
+ static gboolean     ibus_property_serialize     (IBusProperty       *prop,
+                                                  GVariantBuilder    *builder);
+@@ -36,53 +80,253 @@ G_DEFINE_TYPE (IBusProperty, ibus_property, IBUS_TYPE_SERIALIZABLE)
+ static void
+ ibus_property_class_init (IBusPropertyClass *class)
+ {
++    GObjectClass *gobject_class = G_OBJECT_CLASS (class);
+     IBusObjectClass *object_class = IBUS_OBJECT_CLASS (class);
+     IBusSerializableClass *serializable_class = IBUS_SERIALIZABLE_CLASS (class);
+ 
++    g_type_class_add_private (class, sizeof (IBusPropertyPrivate));
++
++    gobject_class->set_property = (GObjectSetPropertyFunc) ibus_property_set_property;
++    gobject_class->get_property = (GObjectGetPropertyFunc) ibus_property_get_property;
++
+     object_class->destroy = (IBusObjectDestroyFunc) ibus_property_destroy;
+ 
+     serializable_class->serialize   = (IBusSerializableSerializeFunc) ibus_property_serialize;
+     serializable_class->deserialize = (IBusSerializableDeserializeFunc) ibus_property_deserialize;
+     serializable_class->copy        = (IBusSerializableCopyFunc) ibus_property_copy;
++
++    /* install properties */
++    /**
++     * IBusPropert:key:
++     *
++     * The key of property
++     */
++    g_object_class_install_property (gobject_class,
++            PROP_KEY,
++            g_param_spec_string ("key",
++                    "key",
++                    "The key of property",
++                    "",
++                    G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
++
++    /**
++     * IBusPropert:icon:
++     *
++     * The icon of property
++     */
++    g_object_class_install_property (gobject_class,
++            PROP_ICON,
++            g_param_spec_string ("icon",
++                    "icon",
++                    "The icon of property",
++                    "",
++                    G_PARAM_READWRITE));
++
++    /**
++     * IBusPropert:label:
++     *
++     * The label of property
++     */
++    g_object_class_install_property (gobject_class,
++            PROP_LABEL,
++            g_param_spec_object("label",
++                    "label",
++                    "The label of property",
++                    IBUS_TYPE_TEXT,
++                    G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
++
++    /**
++     * IBusPropert:tooltip:
++     *
++     * The tooltip of property
++     */
++    g_object_class_install_property (gobject_class,
++            PROP_TOOLTIP,
++            g_param_spec_object("tooltip",
++                    "tooltip",
++                    "The tooltip of property",
++                    IBUS_TYPE_TEXT,
++                    G_PARAM_READWRITE));
++
++    /**
++     * IBusPropert:sensitive:
++     *
++     * The sensitive of property
++     */
++    g_object_class_install_property (gobject_class,
++            PROP_SENSITIVE,
++            g_param_spec_boolean("sensitive",
++                    "sensitive",
++                    "The sensitive of property",
++                    TRUE,
++                    G_PARAM_READWRITE));
++
++    /**
++     * IBusPropert:visible:
++     *
++     * The visible of property
++     */
++    g_object_class_install_property (gobject_class,
++            PROP_VISIBLE,
++            g_param_spec_boolean("visible",
++                    "visible",
++                    "The visible of property",
++                    TRUE,
++                    G_PARAM_READWRITE));
++
++    /**
++     * IBusPropert:type:
++     *
++     * The type of property
++     */
++    g_object_class_install_property (gobject_class,
++            PROP_PROP_TYPE,
++            g_param_spec_enum("prop-type",
++                    "prop-type",
++                    "The type of property",
++                    IBUS_TYPE_PROP_TYPE,
++                    PROP_TYPE_NORMAL,
++                    G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
++    /**
++     * IBusPropert:state:
++     *
++     * The state of property
++     */
++    g_object_class_install_property (gobject_class,
++            PROP_STATE,
++            g_param_spec_enum("state",
++                    "state",
++                    "The state of property",
++                    IBUS_TYPE_PROP_STATE,
++                    PROP_STATE_UNCHECKED,
++                    G_PARAM_READWRITE));
++
++    /**
++     * IBusPropert:sub-props:
++     *
++     * The sub properties of property
++     */
++    g_object_class_install_property (gobject_class,
++            PROP_SUB_PROPS,
++            g_param_spec_object("sub-props",
++                    "sub properties",
++                    "The sub properties of property",
++                    IBUS_TYPE_PROP_LIST,
++                    G_PARAM_READWRITE));
+ }
+ 
+ static void
+ ibus_property_init (IBusProperty *prop)
+ {
+-    prop->key = NULL;
+-    prop->type = 0;
+-    prop->label = NULL;
+-    prop->icon = NULL;
+-    prop->tooltip = NULL;
+-    prop->sensitive = FALSE;
+-    prop->visible = FALSE;
+-    prop->state = 0;
+-
+-    prop->sub_props = NULL;
++    prop->priv = IBUS_PROPERTY_GET_PRIVATE (prop);
++
++    ibus_property_set_label (prop, NULL);
++    ibus_property_set_tooltip (prop, NULL);
++    ibus_property_set_sub_props (prop, NULL);
++
++}
++static void
++ibus_property_set_property (IBusProperty *prop,
++                            guint         prop_id,
++                            const GValue *value,
++                            GParamSpec   *pspec)
++{
++    switch (prop_id) {
++    case PROP_KEY:
++        g_assert (prop->priv->key == NULL);
++        prop->priv->key = g_value_dup_string (value);
++        break;
++    case PROP_ICON:
++        ibus_property_set_icon (prop, g_value_get_string (value));
++        break;
++    case PROP_LABEL:
++        ibus_property_set_label (prop, g_value_get_object (value));
++        break;
++    case PROP_TOOLTIP:
++        ibus_property_set_tooltip (prop, g_value_get_object (value));
++        break;
++    case PROP_SENSITIVE:
++        ibus_property_set_sensitive (prop, g_value_get_boolean (value));
++        break;
++    case PROP_VISIBLE:
++        ibus_property_set_visible (prop, g_value_get_boolean (value));
++        break;
++    case PROP_PROP_TYPE:
++        prop->priv->type = g_value_get_enum (value);
++        break;
++    case PROP_STATE:
++        ibus_property_set_state (prop, g_value_get_enum (value));
++        break;
++    case PROP_SUB_PROPS:
++        ibus_property_set_sub_props (prop,
++                (IBusPropList *)g_value_get_object (value));
++        break;
++    default:
++        G_OBJECT_WARN_INVALID_PROPERTY_ID (prop, prop_id, pspec);
++    }
++}
++
++static void
++ibus_property_get_property (IBusProperty *prop,
++                            guint         prop_id,
++                            GValue       *value,
++                            GParamSpec   *pspec)
++{
++    switch (prop_id) {
++    case PROP_KEY:
++        g_value_set_string (value, ibus_property_get_key (prop));
++        break;
++    case PROP_ICON:
++        g_value_set_string (value, ibus_property_get_icon (prop));
++        break;
++    case PROP_LABEL:
++        g_value_set_object (value, ibus_property_get_label (prop));
++        break;
++    case PROP_TOOLTIP:
++        g_value_set_object (value, ibus_property_get_tooltip (prop));
++        break;
++    case PROP_SENSITIVE:
++        g_value_set_boolean (value, ibus_property_get_sensitive (prop));
++        break;
++    case PROP_VISIBLE:
++        g_value_set_boolean (value, ibus_property_get_visible (prop));
++        break;
++    case PROP_PROP_TYPE:
++        g_value_set_enum (value, ibus_property_get_prop_type (prop));
++        break;
++    case PROP_STATE:
++        g_value_set_enum (value, ibus_property_get_state (prop));
++        break;
++    case PROP_SUB_PROPS:
++        g_value_set_object (value, ibus_property_get_sub_props (prop));
++        break;
++    default:
++        G_OBJECT_WARN_INVALID_PROPERTY_ID (prop, prop_id, pspec);
++    }
+ }
+ 
+ static void
+ ibus_property_destroy (IBusProperty *prop)
+ {
+-    g_free (prop->key);
+-    prop->key = NULL;
++    g_free (prop->priv->key);
++    prop->priv->key = NULL;
+ 
+-    g_free (prop->icon);
+-    prop->icon = NULL;
++    g_free (prop->priv->icon);
++    prop->priv->icon = NULL;
+ 
+-    if (prop->label) {
+-        g_object_unref (prop->label);
+-        prop->label = NULL;
++    if (prop->priv->label) {
++        g_object_unref (prop->priv->label);
++        prop->priv->label = NULL;
+     }
+ 
+-    if (prop->tooltip) {
+-        g_object_unref (prop->tooltip);
+-        prop->tooltip = NULL;
++    if (prop->priv->tooltip) {
++        g_object_unref (prop->priv->tooltip);
++        prop->priv->tooltip = NULL;
+     }
+ 
+-    if (prop->sub_props) {
+-        g_object_unref (prop->sub_props);
+-        prop->sub_props = NULL;
++    if (prop->priv->sub_props) {
++        g_object_unref (prop->priv->sub_props);
++        prop->priv->sub_props = NULL;
+     }
+ 
+     IBUS_OBJECT_CLASS (ibus_property_parent_class)->destroy ((IBusObject *)prop);
+@@ -99,15 +343,18 @@ ibus_property_serialize (IBusProperty    *prop,
+ 
+     g_return_val_if_fail (IBUS_IS_PROPERTY (prop), FALSE);
+ 
+-    g_variant_builder_add (builder, "s", prop->key);
+-    g_variant_builder_add (builder, "u", prop->type);
+-    g_variant_builder_add (builder, "v", ibus_serializable_serialize ((IBusSerializable *)prop->label));
+-    g_variant_builder_add (builder, "s", prop->icon);
+-    g_variant_builder_add (builder, "v", ibus_serializable_serialize ((IBusSerializable *)prop->tooltip));
+-    g_variant_builder_add (builder, "b", prop->sensitive);
+-    g_variant_builder_add (builder, "b", prop->visible);
+-    g_variant_builder_add (builder, "u", prop->state);
+-    g_variant_builder_add (builder, "v", ibus_serializable_serialize ((IBusSerializable *)prop->sub_props));
++    g_variant_builder_add (builder, "s", prop->priv->key);
++    g_variant_builder_add (builder, "u", prop->priv->type);
++    g_variant_builder_add (builder, "v",
++            ibus_serializable_serialize ((IBusSerializable *)prop->priv->label));
++    g_variant_builder_add (builder, "s", prop->priv->icon);
++    g_variant_builder_add (builder, "v",
++            ibus_serializable_serialize ((IBusSerializable *)prop->priv->tooltip));
++    g_variant_builder_add (builder, "b", prop->priv->sensitive);
++    g_variant_builder_add (builder, "b", prop->priv->visible);
++    g_variant_builder_add (builder, "u", prop->priv->state);
++    g_variant_builder_add (builder, "v",
++            ibus_serializable_serialize ((IBusSerializable *)prop->priv->sub_props));
+ 
+     return TRUE;
+ }
+@@ -121,28 +368,28 @@ ibus_property_deserialize (IBusProperty *prop,
+     retval = IBUS_SERIALIZABLE_CLASS (ibus_property_parent_class)->deserialize ((IBusSerializable *) prop, variant);
+     g_return_val_if_fail (retval, 0);
+ 
+-    g_variant_get_child (variant, retval++, "s", &prop->key);
+-    g_variant_get_child (variant, retval++, "u", &prop->type);
++    g_variant_get_child (variant, retval++, "s", &prop->priv->key);
++    g_variant_get_child (variant, retval++, "u", &prop->priv->type);
+ 
+     GVariant *subvar = g_variant_get_child_value (variant, retval++);
+-    prop->label = IBUS_TEXT (ibus_serializable_deserialize (subvar));
+-    g_object_ref_sink (prop->label);
++    prop->priv->label = IBUS_TEXT (ibus_serializable_deserialize (subvar));
++    g_object_ref_sink (prop->priv->label);
+     g_variant_unref (subvar);
+ 
+-    g_variant_get_child (variant, retval++, "s", &prop->icon);
++    g_variant_get_child (variant, retval++, "s", &prop->priv->icon);
+ 
+     subvar = g_variant_get_child_value (variant, retval++);
+-    prop->tooltip = IBUS_TEXT (ibus_serializable_deserialize (subvar));
+-    g_object_ref_sink (prop->tooltip);
++    prop->priv->tooltip = IBUS_TEXT (ibus_serializable_deserialize (subvar));
++    g_object_ref_sink (prop->priv->tooltip);
+     g_variant_unref (subvar);
+ 
+-    g_variant_get_child (variant, retval++, "b", &prop->sensitive);
+-    g_variant_get_child (variant, retval++, "b", &prop->visible);
+-    g_variant_get_child (variant, retval++, "u", &prop->state);
++    g_variant_get_child (variant, retval++, "b", &prop->priv->sensitive);
++    g_variant_get_child (variant, retval++, "b", &prop->priv->visible);
++    g_variant_get_child (variant, retval++, "u", &prop->priv->state);
+ 
+     subvar = g_variant_get_child_value (variant, retval++);
+-    prop->sub_props = IBUS_PROP_LIST (ibus_serializable_deserialize (subvar));
+-    g_object_ref_sink (prop->sub_props);
++    prop->priv->sub_props = IBUS_PROP_LIST (ibus_serializable_deserialize (subvar));
++    g_object_ref_sink (prop->priv->sub_props);
+     g_variant_unref (subvar);
+ 
+     return retval;
+@@ -160,25 +407,25 @@ ibus_property_copy (IBusProperty       *dest,
+     g_return_val_if_fail (IBUS_IS_PROPERTY (dest), FALSE);
+     g_return_val_if_fail (IBUS_IS_PROPERTY (src), FALSE);
+ 
+-    dest->key = g_strdup (src->key);
+-    dest->icon = g_strdup (src->icon);
+-    if (src->label) {
+-        dest->label = (IBusText *) ibus_serializable_copy ((IBusSerializable *) src->label);
++    dest->priv->key = g_strdup (src->priv->key);
++    dest->priv->icon = g_strdup (src->priv->icon);
++    if (src->priv->label) {
++        dest->priv->label = (IBusText *) ibus_serializable_copy ((IBusSerializable *) src->priv->label);
+     }
+     else
+-        dest->label = ibus_text_new_from_static_string ("");
+-    if (src->tooltip) {
+-        dest->tooltip = (IBusText *) ibus_serializable_copy ((IBusSerializable *) src->tooltip);
++        dest->priv->label = ibus_text_new_from_static_string ("");
++    if (src->priv->tooltip) {
++        dest->priv->tooltip = (IBusText *) ibus_serializable_copy ((IBusSerializable *) src->priv->tooltip);
+     }
+     else
+-        dest->tooltip = ibus_text_new_from_static_string ("");
++        dest->priv->tooltip = ibus_text_new_from_static_string ("");
+ 
+-    dest->sensitive = src->sensitive;
+-    dest->visible = src->visible;
+-    dest->type = src->type;
+-    dest->state = src->state;
++    dest->priv->sensitive = src->priv->sensitive;
++    dest->priv->visible = src->priv->visible;
++    dest->priv->type = src->priv->type;
++    dest->priv->state = src->priv->state;
+ 
+-    dest->sub_props = (IBusPropList *) ibus_serializable_copy ((IBusSerializable *) src->sub_props);
++    dest->priv->sub_props = (IBusPropList *) ibus_serializable_copy ((IBusSerializable *) src->priv->sub_props);
+ 
+     return TRUE;
+ }
+@@ -192,7 +439,7 @@ ibus_property_new (const gchar   *key,
+                    gboolean       sensitive,
+                    gboolean       visible,
+                    IBusPropState  state,
+-                   IBusPropList  *prop_list)
++                   IBusPropList  *props)
+ {
+     g_return_val_if_fail (key != NULL, NULL);
+     g_return_val_if_fail (type >= PROP_TYPE_NORMAL &&
+@@ -201,19 +448,17 @@ ibus_property_new (const gchar   *key,
+ 
+     IBusProperty *prop;
+ 
+-    prop = (IBusProperty *)g_object_new (IBUS_TYPE_PROPERTY, NULL);
+-
+-    prop->key = g_strdup (key);
+-    prop->type = type;
+-
+-    ibus_property_set_label (prop, label);
+-    ibus_property_set_icon (prop, icon);
+-    ibus_property_set_tooltip (prop, tooltip);
+-    ibus_property_set_sensitive (prop, sensitive);
+-    ibus_property_set_visible (prop, visible);
+-    ibus_property_set_state (prop, state);
+-    ibus_property_set_sub_props (prop, prop_list);
+-
++    prop = (IBusProperty *)g_object_new (IBUS_TYPE_PROPERTY,
++                                         "key", key,
++                                         "prop-type", type,
++                                         "label", label,
++                                         "icon", icon,
++                                         "tooltip", tooltip,
++                                         "sensitive", sensitive,
++                                         "visible", visible,
++                                         "state", state,
++                                         "sub-props", props,
++                                         NULL);
+     return prop;
+ }
+ 
+@@ -221,24 +466,25 @@ ibus_property_new (const gchar   *key,
+ return_type                                                             \
+ ibus_property_get_ ## field (IBusProperty *prop)                        \
+ {                                                                       \
+-    return prop->field;                                                 \
++    return prop->priv->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 (label, IBusText *)
++IBUS_PROPERTY_GET_FIELD (tooltip, 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 *)
++IBUS_PROPERTY_GET_FIELD (sub_props, IBusPropList *)
+ #undef IBUS_PROPERTY_GET_FIELD
+ 
+ /* ibus_property_get_type() exists */
+ IBusPropType
+ ibus_property_get_prop_type (IBusProperty *prop)
+ {
+-    return prop->type;
++    g_assert (IBUS_IS_PROPERTY (prop));
++    return prop->priv->type;
+ }
+ 
+ void
+@@ -248,15 +494,15 @@ ibus_property_set_label (IBusProperty *prop,
+     g_assert (IBUS_IS_PROPERTY (prop));
+     g_return_if_fail (label == NULL || IBUS_IS_TEXT (label));
+ 
+-    if (prop->label) {
+-        g_object_unref (prop->label);
++    if (prop->priv->label) {
++        g_object_unref (prop->priv->label);
+     }
+ 
+     if (label == NULL) {
+-        prop->label = ibus_text_new_from_static_string ("");
++        prop->priv->label = ibus_text_new_from_static_string ("");
+     }
+     else {
+-        prop->label = g_object_ref_sink (label);
++        prop->priv->label = g_object_ref_sink (label);
+     }
+ }
+ 
+@@ -266,8 +512,8 @@ ibus_property_set_icon (IBusProperty *prop,
+ {
+     g_assert (IBUS_IS_PROPERTY (prop));
+ 
+-    g_free (prop->icon);
+-    prop->icon = g_strdup (icon != NULL ? icon : "");
++    g_free (prop->priv->icon);
++    prop->priv->icon = g_strdup (icon != NULL ? icon : "");
+ }
+ 
+ void
+@@ -277,17 +523,19 @@ ibus_property_set_tooltip (IBusProperty *prop,
+     g_assert (IBUS_IS_PROPERTY (prop));
+     g_assert (tooltip == NULL || IBUS_IS_TEXT (tooltip));
+ 
+-    if (prop->tooltip) {
+-        g_object_unref (prop->tooltip);
++    IBusPropertyPrivate *priv = prop->priv;
++
++    if (priv->tooltip) {
++        g_object_unref (priv->tooltip);
+     }
+ 
+     if (tooltip == NULL) {
+-        prop->tooltip = ibus_text_new_from_static_string ("");
+-        g_object_ref_sink (prop->tooltip);
++        priv->tooltip = ibus_text_new_from_static_string ("");
++        g_object_ref_sink (priv->tooltip);
+     }
+     else {
+-        prop->tooltip = tooltip;
+-        g_object_ref_sink (prop->tooltip);
++        priv->tooltip = tooltip;
++        g_object_ref_sink (priv->tooltip);
+     }
+ }
+ 
+@@ -296,7 +544,7 @@ ibus_property_set_sensitive (IBusProperty *prop,
+                              gboolean      sensitive)
+ {
+     g_assert (IBUS_IS_PROPERTY (prop));
+-    prop->sensitive = sensitive;
++    prop->priv->sensitive = sensitive;
+ }
+ 
+ void
+@@ -304,7 +552,7 @@ ibus_property_set_visible (IBusProperty *prop,
+                            gboolean      visible)
+ {
+     g_assert (IBUS_IS_PROPERTY (prop));
+-    prop->visible = visible;
++    prop->priv->visible = visible;
+ }
+ 
+ void
+@@ -316,7 +564,7 @@ ibus_property_set_state (IBusProperty  *prop,
+               state == PROP_STATE_CHECKED ||
+               state == PROP_STATE_INCONSISTENT);
+ 
+-    prop->state = state;
++    prop->priv->state = state;
+ }
+ 
+ void
+@@ -326,17 +574,19 @@ ibus_property_set_sub_props (IBusProperty *prop,
+     g_assert (IBUS_IS_PROPERTY (prop));
+     g_assert (IBUS_IS_PROP_LIST (prop_list) || prop_list == NULL);
+ 
+-    if (prop->sub_props) {
+-        g_object_unref (prop->sub_props);
++    IBusPropertyPrivate *priv = prop->priv;
++
++    if (priv->sub_props) {
++        g_object_unref (priv->sub_props);
+     }
+ 
+     if (prop_list) {
+-        prop->sub_props = prop_list;
++        priv->sub_props = prop_list;
+         g_object_ref_sink (prop_list);
+     }
+     else {
+-        prop->sub_props = ibus_prop_list_new ();
+-        g_object_ref_sink (prop->sub_props);
++        priv->sub_props = ibus_prop_list_new ();
++        g_object_ref_sink (priv->sub_props);
+     }
+ }
+ 
+@@ -347,25 +597,24 @@ ibus_property_update (IBusProperty *prop,
+     g_assert (IBUS_IS_PROPERTY (prop));
+     g_assert (IBUS_IS_PROPERTY (prop_update));
+ 
+-    if (g_strcmp0 (prop->key, prop_update->key) != 0) {
+-        return ibus_prop_list_update_property (prop->sub_props, prop_update);
++    IBusPropertyPrivate *priv = prop->priv;
++    IBusPropertyPrivate *priv_update = prop_update->priv;
++
++    if (g_strcmp0 (priv->key, priv_update->key) != 0) {
++        return ibus_prop_list_update_property (priv->sub_props, prop_update);
+     }
+ 
+-    g_free (prop->icon);
+-    prop->icon = g_strdup (prop_update->icon);
++    /* Do not support update prop type */
++    g_assert (priv->type == priv_update->type);
+ 
+-    if (prop->label) {
+-        g_object_unref (prop->label);
+-    }
+-    prop->label = (IBusText *) g_object_ref_sink (prop_update->label);
++    ibus_property_set_icon (prop, ibus_property_get_icon (prop_update));
++    ibus_property_set_label (prop, ibus_property_get_label (prop_update));
++    ibus_property_set_tooltip (prop, ibus_property_get_tooltip (prop_update));
++    ibus_property_set_visible (prop, ibus_property_get_visible (prop_update));
++    ibus_property_set_state (prop, ibus_property_get_state (prop_update));
++    ibus_property_set_sensitive (prop, ibus_property_get_sensitive (prop_update));
+ 
+-    if (prop->tooltip) {
+-        g_object_unref (prop->tooltip);
+-    }
+-    prop->tooltip = (IBusText *) g_object_ref_sink (prop_update->tooltip);
+-    prop->visible = prop_update->visible;
+-    prop->state = prop_update->state;
+-    prop->sensitive = prop_update->sensitive;
++    /* Do not support update sub props */
+ 
+     return TRUE;
+ }
+diff --git a/src/ibusproperty.h b/src/ibusproperty.h
+index 5e76c8f..ddbadc8 100644
+--- a/src/ibusproperty.h
++++ b/src/ibusproperty.h
+@@ -114,6 +114,7 @@ typedef enum {
+ 
+ typedef struct _IBusProperty IBusProperty;
+ typedef struct _IBusPropertyClass IBusPropertyClass;
++typedef struct _IBusPropertyPrivate IBusPropertyPrivate;
+ 
+ #ifndef __PROPLIST_DEFINED
+ #define __PROPLIST_DEFINED
+@@ -137,20 +138,11 @@ typedef struct _IBusPropListClass IBusPropListClass;
+  * UI component for input method engine property.
+  */
+ struct _IBusProperty {
++    /*< private >*/
+     IBusSerializable parent;
++    IBusPropertyPrivate *priv;
+ 
+-    /*< public >*/
+-    gchar    *key;
+-    gchar    *icon;
+-    IBusText *label;
+-    IBusText *tooltip;
+-
+-    gboolean sensitive;
+-    gboolean visible;
+-    guint type;
+-    guint state;
+-
+-    IBusPropList *sub_props;
++    gpointer pdummy[7];
+ };
+ 
+ struct _IBusPropertyClass {
+@@ -194,22 +186,13 @@ IBusProperty    *ibus_property_new          (const gchar    *key,
+ 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);
++IBusText *      ibus_property_get_label    (IBusProperty   *prop);
+ 
+ /**
+  * ibus_property_set_label:
+@@ -247,7 +230,7 @@ void             ibus_property_set_icon     (IBusProperty   *prop,
+  *
+  * Get the tooltip of IBusProperty.
+  */
+-const IBusText * ibus_property_get_tooltip  (IBusProperty   *prop);
++IBusText *      ibus_property_get_tooltip  (IBusProperty   *prop);
+ 
+ /**
+  * ibus_property_set_tooltip:
+@@ -298,6 +281,15 @@ void             ibus_property_set_visible  (IBusProperty   *prop,
+                                              gboolean        visible);
+ 
+ /**
++ * ibus_property_get_property_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_state:
+  * @prop: An IBusProperty.
+  * @returns: the state of IBusProperty.
+@@ -323,8 +315,7 @@ void             ibus_property_set_state    (IBusProperty   *prop,
+  *
+  * Get the IBusPropList of IBusProperty.
+  */
+-const IBusPropList *
+-                 ibus_property_get_sub_props(IBusProperty   *prop);
++IBusPropList *   ibus_property_get_sub_props(IBusProperty   *prop);
+ 
+ /**
+  * ibus_property_set_sub_props:
+-- 
+1.7.7.4
+
+From df10a24f905c8eea420a5fd33eff78417312410c Mon Sep 17 00:00:00 2001
+From: Peng Huang <shawn.p.huang at gmail.com>
+Date: Thu, 22 Dec 2011 09:57:23 -0500
+Subject: [PATCH] Add ibus_text_set_attributes for scipt language
+ bindings.
+
+BUG=None
+TEST=Linux desktop
+
+Review URL: http://codereview.appspot.com/5500067
+---
+ src/ibustext.c |   12 +++++++++++-
+ src/ibustext.h |   13 +++++++++++--
+ 2 files changed, 22 insertions(+), 3 deletions(-)
+
+diff --git a/src/ibustext.c b/src/ibustext.c
+index f4085e9..e5218d0 100644
+--- a/src/ibustext.c
++++ b/src/ibustext.c
+@@ -272,8 +272,18 @@ ibus_text_get_text (IBusText *text)
+     return text->text;
+ }
+ 
+-const IBusAttrList *
++IBusAttrList *
+ ibus_text_get_attributes (IBusText *text)
+ {
+     return text->attrs;
+ }
++
++void
++ibus_text_set_attributes (IBusText     *text,
++                          IBusAttrList *attrs)
++{
++    if (text->attrs)
++        g_object_unref (text->attrs);
++    text->attrs = attrs;
++    g_object_ref_sink (text->attrs);
++}
+diff --git a/src/ibustext.h b/src/ibustext.h
+index 1dca466..f6e25a7 100644
+--- a/src/ibustext.h
++++ b/src/ibustext.h
+@@ -194,8 +194,17 @@ const gchar *    ibus_text_get_text                 (IBusText       *text);
+  *
+  * Return the attributes in an IBusText. Should not be freed.
+  */
+-const IBusAttrList *
+-                 ibus_text_get_attributes           (IBusText       *text);
++IBusAttrList *   ibus_text_get_attributes           (IBusText       *text);
++
++/**
++ * ibus_text_set_attributes:
++ * @text: An IBusText.
++ * @attrs: An IBusAttrList
++ */
++void             ibus_text_set_attributes           (IBusText       *text,
++                                                     IBusAttrList   *attrs);
++
++
+ G_END_DECLS
+ #endif
+ 
+-- 
+1.7.7.4
+
+From 4d1f38314b3a9c3dc1683053cda10cfa36fd9019 Mon Sep 17 00:00:00 2001
+From: Peng Huang <shawn.p.huang at gmail.com>
+Date: Thu, 22 Dec 2011 09:59:05 -0500
+Subject: [PATCH] Fix a typo in docs/references/ibus/Makefile
+
+BUG=None
+TEST=make
+
+Review URL: http://codereview.appspot.com/5496079
+---
+ docs/reference/ibus/Makefile.am |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/docs/reference/ibus/Makefile.am b/docs/reference/ibus/Makefile.am
+index 4fa77a1..75e3815 100644
+--- a/docs/reference/ibus/Makefile.am
++++ b/docs/reference/ibus/Makefile.am
+@@ -117,7 +117,7 @@ trim-build.stamp: scan-build.stamp
+ 	$(AM_V_GEN) \
+ 	    $(SED) -f $(srcdir)/trim.sed -i.bak \
+ 			$(builddir)/$(DOC_MODULE)-sections.txt && \
+-	    $(RM) $(buildir)/$(DOC_MODULE)-sections.txt.bak && \
++	    $(RM) $(builddir)/$(DOC_MODULE)-sections.txt.bak && \
+ 	    touch trim-build.stamp
+ 
+ tmpl-build.stamp: trim-build.stamp  $(DOC_MODULE)-decl.txt $(SCANOBJ_FILES) $(DOC_MODULE)-overrides.txt
+-- 
+1.7.7.4
+
+From 377cf484ea64fc2f30706d298cf1f33debdd9c30 Mon Sep 17 00:00:00 2001
+From: fujiwarat <takao.fujiwara1 at gmail.com>
+Date: Fri, 30 Dec 2011 13:53:50 +0900
+Subject: [PATCH] Fix ibus-x11 SEGV in _process_key_event_done.
+
+IMForwardEvent() calls _Xi18nFindClient() and it could return NULL.
+Maybe the connect_id would be disconnected during the async
+process_key_event.
+This fix checks XIM_DISCONNECT in ims_protocol_handler() to cancel
+IMForwardEvent() in _process_key_event_done().
+---
+ client/x11/main.c |   17 +++++++++++++++++
+ 1 files changed, 17 insertions(+), 0 deletions(-)
+
+diff --git a/client/x11/main.c b/client/x11/main.c
+index 58069fc..3cb03f0 100644
+--- a/client/x11/main.c
++++ b/client/x11/main.c
+@@ -77,6 +77,8 @@ struct _X11IC {
+     gint             onspot_preedit_length;
+ };
+ 
++static gint disconnected_id = 0;
++
+ static void     _xim_set_cursor_location    (X11IC              *x11ic);
+ static void     _context_commit_text_cb     (IBusInputContext   *context,
+                                              IBusText           *text,
+@@ -464,6 +466,12 @@ _process_key_event_done (GObject      *object,
+         g_error_free (error);
+     }
+ 
++    if (pfe->connect_id == disconnected_id) {
++        g_slice_free (IMForwardEventStruct, pfe);
++        disconnected_id = 0;
++        return;
++    }
++
+     if (retval == FALSE) {
+         IMForwardEvent (_xims, (XPointer) pfe);
+     }
+@@ -734,6 +742,13 @@ xim_reset_ic (XIMS xims, IMResetICStruct *call_data)
+     return 1;
+ }
+ 
++static int
++xim_disconnect_ic (XIMS xims, IMDisConnectStruct *call_data)
++{
++    disconnected_id = call_data->connect_id;
++    return 0;
++}
++
+ int
+ ims_protocol_handler (XIMS xims, IMProtocol *call_data)
+ {
+@@ -773,6 +788,8 @@ ims_protocol_handler (XIMS xims, IMProtocol *call_data)
+     case XIM_SYNC_REPLY:
+         LOG (1, "XIM_SYNC_REPLY");
+         return 0;
++    case XIM_DISCONNECT:
++        return xim_disconnect_ic (xims, (IMDisConnectStruct *)call_data);
+     default:
+         LOG (1, "Unkown (%d)", call_data->major_code);
+         return 0;
+-- 
+1.7.7.4
+
diff --git a/ibus-xx-bridge-hotkey.patch b/ibus-xx-bridge-hotkey.patch
index ffec57c..c3d864f 100644
--- a/ibus-xx-bridge-hotkey.patch
+++ b/ibus-xx-bridge-hotkey.patch
@@ -1784,8 +1784,8 @@ index 8804634..549393a 100644
          if value != 'default':
              self.__xkblayout.set_default_layout(value)
 +            if value.find('(') >= 0:
-+                self.__default_layout = value.split('(')[0]
-+                self.__default_model = value.split('(')[1].split(')')[0]
++                [self.__default_layout, self.__default_model] = \
++                    self.__xkblayout.get_default_layout()
 +            else:
 +                self.__default_layout = value
 +                self.__default_model = None
diff --git a/ibus.spec b/ibus.spec
index 659755e..431a966 100644
--- a/ibus.spec
+++ b/ibus.spec
@@ -7,13 +7,13 @@
 
 %if 0%{?fedora} > 16
 %define have_bridge_hotkey 1
-%define ibus_gjs_version 3.2.1.20111128
+%define ibus_gjs_version 3.2.1.20111230
 %define ibus_gjs_build_failure 1
 %define have_dconf 1
 %else
 %if 0%{?fedora} > 15
 %define have_bridge_hotkey 1
-%define ibus_gjs_version 3.2.1.20111128
+%define ibus_gjs_version 3.2.1.20111230
 %define ibus_gjs_build_failure 0
 %define have_dconf 1
 %else
@@ -33,7 +33,7 @@
 
 Name:       ibus
 Version:    1.4.0
-Release:    14%{?dist}
+Release:    15%{?dist}
 Summary:    Intelligent Input Bus for Linux OS
 License:    LGPLv2+
 Group:      System Environment/Libraries
@@ -435,6 +435,16 @@ fi
 %{_datadir}/gtk-doc/html/*
 
 %changelog
+* Fri Dec 30 2011 Takao Fujiwara <tfujiwar at redhat.com> - 1.4.0-15
+- Enhanced ibus-gnome3 shell lookup window.
+- Updated ibus-HEAD.patch from upstream
+  Fixed Bug 769135 - ibus-x11 SEGV in _process_key_event_done.
+- Updated ibus-541492-xkb.patch
+  Fixed Bug 757889 - ibus-setup SEGV without active engine.
+  Fixed Bug 760213 - ibus-setup saves XKB variants correctly.
+  Fixed Bug 769133 - ibus-engine-xkb returns FALSE for ASCII typings.
+- Updated ibus-xx-bridge-hotkey.patch for an enhancement.
+
 * Wed Nov 30 2011 Takao Fujiwara <tfujiwar at redhat.com> - 1.4.0-14
 - Enabled dconf.
 - Updated ibus-HEAD.patch
diff --git a/sources b/sources
index 0ed76cb..c2020d5 100644
--- a/sources
+++ b/sources
@@ -1,3 +1,3 @@
 b4f063794e89c71eb1f8cb543210da30  ibus-1.4.0.tar.gz
 4257048de65ea404389bb941a51db667  ibus-gjs-3.0.2.20111118.tar.gz
-e79a4f384ff42491ee1e263482bd1bc6  ibus-gjs-3.2.1.20111128.tar.gz
+2d2ad58e3e41429dbd883ba7e501c9b2  ibus-gjs-3.2.1.20111230.tar.gz


More information about the scm-commits mailing list