Blob Blame History Raw
From 49ee54f83471542447e1121be15c27ff5d86600b Mon Sep 17 00:00:00 2001
From: Colin Walters <walters@verbum.org>
Date: Fri, 27 Feb 2015 11:32:41 +0900
Subject: [PATCH] dconf: Work around using dbus development builds and
 /etc/machine-id

Recent DBus changed the way it reads /etc/machine-id to be more
strict, and it turns out that this breaks the use of dbus-launch here.

The *correct* fix is to use `dbus-run-session`, but not everyone has
that yet.  This is a quick hack that keeps the build going.

BUG=https://github.com/ibus/ibus/pull/16
TEST=data/dconf/00-upstream-settings

Review URL: https://codereview.appspot.com/209810043
Patch from Colin Walters <walters@verbum.org>.
---
 data/dconf/make-dconf-override-db.sh | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/data/dconf/make-dconf-override-db.sh b/data/dconf/make-dconf-override-db.sh
index 49a6df9..9c650e9 100755
--- a/data/dconf/make-dconf-override-db.sh
+++ b/data/dconf/make-dconf-override-db.sh
@@ -2,6 +2,10 @@
 
 set -e
 
+# gnome-continuous doesn't have a machine-id set, which
+# breaks dbus-launch.  There's dbus-run-session which is
+# better, but not everyone has it yet.
+export DBUS_FATAL_WARNINGS=0
 export TMPDIR=$(mktemp -d --tmpdir="$PWD")
 export XDG_CONFIG_HOME="$TMPDIR/config"
 export XDG_CACHE_HOME="$TMPDIR/cache"
-- 
2.1.0

From 0ba6452740ec6e76344afaa2a9887566d0b62a4d Mon Sep 17 00:00:00 2001
From: Peng Wu <alexepico@gmail.com>
Date: Mon, 9 Mar 2015 13:36:58 +0900
Subject: [PATCH] Add ibus_keyval_convert_case and
 ibus_keyval_to_upper/lower methods

In some input method setup dialog, customization of shortcut keys are supported. But in python Gtk+, when grab the shortcut key, the gdk_keyval_to_lower method will be used.

This patch adds ibus_keyval_convert_case and ibus_keyval_to_upper/lower methods, so ibus-libpinyin can drop the Gdk 3.x C++ dependency.

BUG=https://code.google.com/p/ibus/issues/detail?id=1766
TEST=

Review URL: https://codereview.appspot.com/213760043
Patch from Peng Wu <alexepico@gmail.com>.
---
 src/ibuskeynames.c | 147 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/ibuskeys.h     |  33 ++++++++++++
 2 files changed, 180 insertions(+)

diff --git a/src/ibuskeynames.c b/src/ibuskeynames.c
index 2935bcb..fe7836e 100644
--- a/src/ibuskeynames.c
+++ b/src/ibuskeynames.c
@@ -31,6 +31,7 @@
 #include <string.h>
 #include "ibuskeysyms.h"
 #include "keyname-table.h"
+#include "ibuskeys.h"
 
 #define IBUS_NUM_KEYS G_N_ELEMENTS (gdk_keys_by_keyval)
 
@@ -196,3 +197,149 @@ _out:
     return retval;
 }
 
+guint
+ibus_keyval_to_upper (guint keyval)
+{
+  guint result;
+
+  ibus_keyval_convert_case (keyval, NULL, &result);
+
+  return result;
+}
+
+guint
+ibus_keyval_to_lower (guint keyval)
+{
+  guint result;
+
+  ibus_keyval_convert_case (keyval, &result, NULL);
+
+  return result;
+}
+
+void
+ibus_keyval_convert_case (guint symbol,
+                         guint *lower,
+                         guint *upper)
+{
+  guint xlower, xupper;
+
+  xlower = symbol;
+  xupper = symbol;
+
+  /* Check for directly encoded 24-bit UCS characters: */
+  if ((symbol & 0xff000000) == 0x01000000)
+    {
+      if (lower)
+        *lower = ibus_unicode_to_keyval (g_unichar_tolower (symbol & 0x00ffffff));
+      if (upper)
+        *upper = ibus_unicode_to_keyval (g_unichar_toupper (symbol & 0x00ffffff));
+      return;
+    }
+
+  switch (symbol >> 8)
+    {
+    case 0: /* Latin 1 */
+      if ((symbol >= IBUS_KEY_A) && (symbol <= IBUS_KEY_Z))
+        xlower += (IBUS_KEY_a - IBUS_KEY_A);
+      else if ((symbol >= IBUS_KEY_a) && (symbol <= IBUS_KEY_z))
+        xupper -= (IBUS_KEY_a - IBUS_KEY_A);
+      else if ((symbol >= IBUS_KEY_Agrave) && (symbol <= IBUS_KEY_Odiaeresis))
+        xlower += (IBUS_KEY_agrave - IBUS_KEY_Agrave);
+      else if ((symbol >= IBUS_KEY_agrave) && (symbol <= IBUS_KEY_odiaeresis))
+        xupper -= (IBUS_KEY_agrave - IBUS_KEY_Agrave);
+      else if ((symbol >= IBUS_KEY_Ooblique) && (symbol <= IBUS_KEY_Thorn))
+        xlower += (IBUS_KEY_oslash - IBUS_KEY_Ooblique);
+      else if ((symbol >= IBUS_KEY_oslash) && (symbol <= IBUS_KEY_thorn))
+        xupper -= (IBUS_KEY_oslash - IBUS_KEY_Ooblique);
+      break;
+
+    case 1: /* Latin 2 */
+      /* Assume the KeySym is a legal value (ignore discontinuities) */
+      if (symbol == IBUS_KEY_Aogonek)
+        xlower = IBUS_KEY_aogonek;
+      else if (symbol >= IBUS_KEY_Lstroke && symbol <= IBUS_KEY_Sacute)
+        xlower += (IBUS_KEY_lstroke - IBUS_KEY_Lstroke);
+      else if (symbol >= IBUS_KEY_Scaron && symbol <= IBUS_KEY_Zacute)
+        xlower += (IBUS_KEY_scaron - IBUS_KEY_Scaron);
+      else if (symbol >= IBUS_KEY_Zcaron && symbol <= IBUS_KEY_Zabovedot)
+        xlower += (IBUS_KEY_zcaron - IBUS_KEY_Zcaron);
+      else if (symbol == IBUS_KEY_aogonek)
+        xupper = IBUS_KEY_Aogonek;
+      else if (symbol >= IBUS_KEY_lstroke && symbol <= IBUS_KEY_sacute)
+        xupper -= (IBUS_KEY_lstroke - IBUS_KEY_Lstroke);
+      else if (symbol >= IBUS_KEY_scaron && symbol <= IBUS_KEY_zacute)
+        xupper -= (IBUS_KEY_scaron - IBUS_KEY_Scaron);
+      else if (symbol >= IBUS_KEY_zcaron && symbol <= IBUS_KEY_zabovedot)
+        xupper -= (IBUS_KEY_zcaron - IBUS_KEY_Zcaron);
+      else if (symbol >= IBUS_KEY_Racute && symbol <= IBUS_KEY_Tcedilla)
+        xlower += (IBUS_KEY_racute - IBUS_KEY_Racute);
+      else if (symbol >= IBUS_KEY_racute && symbol <= IBUS_KEY_tcedilla)
+        xupper -= (IBUS_KEY_racute - IBUS_KEY_Racute);
+      break;
+
+    case 2: /* Latin 3 */
+      /* Assume the KeySym is a legal value (ignore discontinuities) */
+      if (symbol >= IBUS_KEY_Hstroke && symbol <= IBUS_KEY_Hcircumflex)
+        xlower += (IBUS_KEY_hstroke - IBUS_KEY_Hstroke);
+      else if (symbol >= IBUS_KEY_Gbreve && symbol <= IBUS_KEY_Jcircumflex)
+        xlower += (IBUS_KEY_gbreve - IBUS_KEY_Gbreve);
+      else if (symbol >= IBUS_KEY_hstroke && symbol <= IBUS_KEY_hcircumflex)
+        xupper -= (IBUS_KEY_hstroke - IBUS_KEY_Hstroke);
+      else if (symbol >= IBUS_KEY_gbreve && symbol <= IBUS_KEY_jcircumflex)
+        xupper -= (IBUS_KEY_gbreve - IBUS_KEY_Gbreve);
+      else if (symbol >= IBUS_KEY_Cabovedot && symbol <= IBUS_KEY_Scircumflex)
+        xlower += (IBUS_KEY_cabovedot - IBUS_KEY_Cabovedot);
+      else if (symbol >= IBUS_KEY_cabovedot && symbol <= IBUS_KEY_scircumflex)
+        xupper -= (IBUS_KEY_cabovedot - IBUS_KEY_Cabovedot);
+      break;
+
+    case 3: /* Latin 4 */
+      /* Assume the KeySym is a legal value (ignore discontinuities) */
+      if (symbol >= IBUS_KEY_Rcedilla && symbol <= IBUS_KEY_Tslash)
+        xlower += (IBUS_KEY_rcedilla - IBUS_KEY_Rcedilla);
+      else if (symbol >= IBUS_KEY_rcedilla && symbol <= IBUS_KEY_tslash)
+        xupper -= (IBUS_KEY_rcedilla - IBUS_KEY_Rcedilla);
+      else if (symbol == IBUS_KEY_ENG)
+        xlower = IBUS_KEY_eng;
+      else if (symbol == IBUS_KEY_eng)
+        xupper = IBUS_KEY_ENG;
+      else if (symbol >= IBUS_KEY_Amacron && symbol <= IBUS_KEY_Umacron)
+        xlower += (IBUS_KEY_amacron - IBUS_KEY_Amacron);
+      else if (symbol >= IBUS_KEY_amacron && symbol <= IBUS_KEY_umacron)
+        xupper -= (IBUS_KEY_amacron - IBUS_KEY_Amacron);
+      break;
+
+    case 6: /* Cyrillic */
+      /* Assume the KeySym is a legal value (ignore discontinuities) */
+      if (symbol >= IBUS_KEY_Serbian_DJE && symbol <= IBUS_KEY_Serbian_DZE)
+        xlower -= (IBUS_KEY_Serbian_DJE - IBUS_KEY_Serbian_dje);
+      else if (symbol >= IBUS_KEY_Serbian_dje && symbol <= IBUS_KEY_Serbian_dze)
+        xupper += (IBUS_KEY_Serbian_DJE - IBUS_KEY_Serbian_dje);
+      else if (symbol >= IBUS_KEY_Cyrillic_YU && symbol <= IBUS_KEY_Cyrillic_HARDSIGN)
+        xlower -= (IBUS_KEY_Cyrillic_YU - IBUS_KEY_Cyrillic_yu);
+      else if (symbol >= IBUS_KEY_Cyrillic_yu && symbol <= IBUS_KEY_Cyrillic_hardsign)
+        xupper += (IBUS_KEY_Cyrillic_YU - IBUS_KEY_Cyrillic_yu);
+      break;
+
+    case 7: /* Greek */
+      /* Assume the KeySym is a legal value (ignore discontinuities) */
+      if (symbol >= IBUS_KEY_Greek_ALPHAaccent && symbol <= IBUS_KEY_Greek_OMEGAaccent)
+        xlower += (IBUS_KEY_Greek_alphaaccent - IBUS_KEY_Greek_ALPHAaccent);
+      else if (symbol >= IBUS_KEY_Greek_alphaaccent && symbol <= IBUS_KEY_Greek_omegaaccent &&
+               symbol != IBUS_KEY_Greek_iotaaccentdieresis &&
+               symbol != IBUS_KEY_Greek_upsilonaccentdieresis)
+        xupper -= (IBUS_KEY_Greek_alphaaccent - IBUS_KEY_Greek_ALPHAaccent);
+      else if (symbol >= IBUS_KEY_Greek_ALPHA && symbol <= IBUS_KEY_Greek_OMEGA)
+        xlower += (IBUS_KEY_Greek_alpha - IBUS_KEY_Greek_ALPHA);
+      else if (symbol >= IBUS_KEY_Greek_alpha && symbol <= IBUS_KEY_Greek_omega &&
+               symbol != IBUS_KEY_Greek_finalsmallsigma)
+        xupper -= (IBUS_KEY_Greek_alpha - IBUS_KEY_Greek_ALPHA);
+      break;
+    }
+
+  if (lower)
+    *lower = xlower;
+  if (upper)
+    *upper = xupper;
+}
diff --git a/src/ibuskeys.h b/src/ibuskeys.h
index 7969929..6ad0a90 100644
--- a/src/ibuskeys.h
+++ b/src/ibuskeys.h
@@ -74,5 +74,38 @@ guint            ibus_unicode_to_keyval (gunichar        wc);
  **/
 gunichar         ibus_keyval_to_unicode (guint           keyval);
 
+/**
+ * ibus_keyval_to_upper:
+ * @keyval: a key value.
+ *
+ * Converts a key value to upper case, if applicable.
+ *
+ * Returns: the upper case form of @keyval, or @keyval itself if it is already
+ *   in upper case or it is not subject to case conversion.
+ */
+guint            ibus_keyval_to_upper (guint keyval);
+
+/**
+ * ibus_keyval_to_lower:
+ * @keyval: a key value.
+ *
+ * Converts a key value to lower case, if applicable.
+ *
+ * Returns: the lower case form of @keyval, or @keyval itself if it is already
+ *  in lower case or it is not subject to case conversion.
+ */
+guint            ibus_keyval_to_lower (guint keyval);
+
+/**
+ * ibus_keyval_convert_case:
+ * @symbol: a keyval
+ * @lower: (out): return location for lowercase version of @symbol
+ * @upper: (out): return location for uppercase version of @symbol
+ *
+ * Obtains the upper- and lower-case versions of the keyval @symbol.
+ * Examples of keyvals are #IBUS_KEY_a, #IBUS_KEY_Enter, #IBUS_KEY_F1, etc.
+ */
+void ibus_keyval_convert_case (guint symbol, guint *lower, guint *upper);
+
 G_END_DECLS
 #endif // __IBUS_KEYS_H_
-- 
2.1.0

From f32e98fdacf50af70fe1e3198463fc75d9ead727 Mon Sep 17 00:00:00 2001
From: Albert Veli <albert.veli@gmail.com>
Date: Thu, 12 Mar 2015 12:12:22 +0900
Subject: [PATCH] Add Swedish svdvorak in simple.xml

TEST=engine/simple.xml

Review URL: https://codereview.appspot.com/215730043
Patch from Albert Veli <albert.veli@gmail.com>.
---
 engine/simple.xml.in | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/engine/simple.xml.in b/engine/simple.xml.in
index c16f86a..93de14a 100644
--- a/engine/simple.xml.in
+++ b/engine/simple.xml.in
@@ -625,6 +625,18 @@
                         <icon>ibus-keyboard</icon>
 			<rank>99</rank>
 		</engine>
+                <engine>
+                        <name>xkb:se:svdvorak:swe</name>
+                        <language>swe</language>
+                        <license>GPL</license>
+                        <author>Peng Huang &lt;shawn.p.huang@gmail.com&gt;</author>
+                        <layout>se</layout>
+                        <layout_variant>svdvorak</layout_variant>
+                        <longname>Swedish (Svdvorak)</longname>
+                        <description>Swedish (Svdvorak)</description>
+                        <icon>ibus-keyboard</icon>
+                        <rank>99</rank>
+                </engine>
 		<engine>
 			<name>xkb:ch::ger</name>
 			<language>ger</language>
-- 
2.1.0

From 4a4bd5fd0cac63b73464039896df123efd372d4a Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
Date: Wed, 18 Mar 2015 13:47:07 +0900
Subject: [PATCH] Change ranks for minor keymaps in simple.xml

TEST=engine/simple.xml

Review URL: https://codereview.appspot.com/217900043
---
 engine/simple.xml.in | 50 +++++++++++++++++++++++++-------------------------
 1 file changed, 25 insertions(+), 25 deletions(-)

diff --git a/engine/simple.xml.in b/engine/simple.xml.in
index 93de14a..5f04f8b 100644
--- a/engine/simple.xml.in
+++ b/engine/simple.xml.in
@@ -30,7 +30,7 @@
 			<longname>English (US, international with dead keys)</longname>
 			<description>English (US, international with dead keys)</description>
                         <icon>ibus-keyboard</icon>
-			<rank>99</rank>
+			<rank>1</rank>
 		</engine>
 		<engine>
 			<name>xkb:us:colemak:eng</name>
@@ -42,7 +42,7 @@
 			<longname>English (Colemak)</longname>
 			<description>English (Colemak)</description>
                         <icon>ibus-keyboard</icon>
-			<rank>99</rank>
+			<rank>1</rank>
 		</engine>
 		<engine>
 			<name>xkb:us:dvorak:eng</name>
@@ -54,7 +54,7 @@
 			<longname>English (Dvorak)</longname>
 			<description>English (Dvorak)</description>
                         <icon>ibus-keyboard</icon>
-			<rank>99</rank>
+			<rank>1</rank>
 		</engine>
 		<engine>
 			<name>xkb:us:altgr-intl:eng</name>
@@ -66,7 +66,7 @@
 			<longname>English (international AltGr dead keys)</longname>
 			<description>English (international AltGr dead keys)</description>
                         <icon>ibus-keyboard</icon>
-			<rank>99</rank>
+			<rank>1</rank>
 		</engine>
 		<engine>
 			<name>xkb:ara::ara</name>
@@ -88,7 +88,7 @@
 			<longname>Belgian</longname>
 			<description>Belgian</description>
                         <icon>ibus-keyboard</icon>
-			<rank>99</rank>
+			<rank>1</rank>
 		</engine>
 		<engine>
 			<name>xkb:be::nld</name>
@@ -110,7 +110,7 @@
 			<longname>Belgian</longname>
 			<description>Belgian</description>
                         <icon>ibus-keyboard</icon>
-			<rank>99</rank>
+			<rank>1</rank>
 		</engine>
 		<engine>
 			<name>xkb:br::por</name>
@@ -133,7 +133,7 @@
 			<longname>Portuguese (Brazil, Dvorak)</longname>
 			<description>Portuguese (Brazil, Dvorak)</description>
                         <icon>ibus-keyboard</icon>
-			<rank>99</rank>
+			<rank>1</rank>
 		</engine>
 		<engine>
 			<name>xkb:bg::bul</name>
@@ -167,7 +167,7 @@
 			<longname>French (Canada)</longname>
 			<description>French (Canada)</description>
                         <icon>ibus-keyboard</icon>
-			<rank>99</rank>
+			<rank>1</rank>
 		</engine>
 		<engine>
 			<name>xkb:ca:eng:eng</name>
@@ -179,7 +179,7 @@
 			<longname>English (Canada)</longname>
 			<description>English (Canada)</description>
                         <icon>ibus-keyboard</icon>
-			<rank>99</rank>
+			<rank>1</rank>
 		</engine>
 		<engine>
 			<name>xkb:hr::scr</name>
@@ -269,7 +269,7 @@
                         <longname>French (alternative)</longname>
                         <description>French (alternative)</description>
                         <icon>ibus-keyboard</icon>
-                        <rank>99</rank>
+                        <rank>1</rank>
                 </engine>
                 <engine>
                         <name>xkb:fr:bepo:fra</name>
@@ -281,7 +281,7 @@
                         <longname>French (Bepo, ergonomic, Dvorak way)</longname>
                         <description>French (Bepo, ergonomic, Dvorak way)</description>
                         <icon>ibus-keyboard</icon>
-                        <rank>99</rank>
+                        <rank>1</rank>
                 </engine>
                 <engine>
                         <name>xkb:fr:dvorak:fra</name>
@@ -316,7 +316,7 @@
 			<longname>German (Dvorak)</longname>
 			<description>German (Dvorak)</description>
                         <icon>ibus-keyboard</icon>
-			<rank>99</rank>
+			<rank>1</rank>
 		</engine>
 		<engine>
 			<name>xkb:de:neo:ger</name>
@@ -328,7 +328,7 @@
 			<longname>German (Neo 2)</longname>
 			<description>German (Neo 2)</description>
                         <icon>ibus-keyboard</icon>
-			<rank>99</rank>
+			<rank>1</rank>
 		</engine>
                 <engine>
                         <name>xkb:de:nodeadkeys:ger</name>
@@ -340,7 +340,7 @@
                         <longname>German (eliminate dead keys)</longname>
                         <description>German (eliminate dead keys)</description>
                         <icon>ibus-keyboard</icon>
-                        <rank>99</rank>
+                        <rank>1</rank>
                 </engine>
 		<engine>
 			<name>xkb:gr::gre</name>
@@ -395,7 +395,7 @@
 			<longname>Japanese</longname>
 			<description>Japanese</description>
                         <icon>ibus-keyboard</icon>
-			<rank>99</rank>
+			<rank>1</rank>
 		</engine>
 		<engine>
 			<name>xkb:latam::spa</name>
@@ -406,7 +406,7 @@
 			<longname>Spanish (Latin American)</longname>
 			<description>Spanish (Latin American)</description>
                         <icon>ibus-keyboard</icon>
-			<rank>99</rank>
+			<rank>1</rank>
 		</engine>
 		<engine>
 			<name>xkb:lt::lit</name>
@@ -452,7 +452,7 @@
 			<longname>Norwegian (Dvorak)</longname>
 			<description>Norwegian (Dvorak)</description>
                         <icon>ibus-keyboard</icon>
-			<rank>99</rank>
+			<rank>1</rank>
 		</engine>
 		<engine>
 			<name>xkb:pl::pol</name>
@@ -475,7 +475,7 @@
 			<longname>Polish (Dvorak)</longname>
 			<description>Polish (Dvorak)</description>
                         <icon>ibus-keyboard</icon>
-			<rank>99</rank>
+			<rank>1</rank>
 		</engine>
                 <engine>
                         <name>xkb:pl:qwertz:pol</name>
@@ -532,7 +532,7 @@
 			<longname>Russian (phonetic)</longname>
 			<description>Russian (phonetic)</description>
                         <icon>ibus-keyboard</icon>
-			<rank>99</rank>
+			<rank>1</rank>
 		</engine>
 		<engine>
 			<name>xkb:rs::srp</name>
@@ -623,7 +623,7 @@
 			<longname>Swedish (Dvorak)</longname>
 			<description>Swedish (Dvorak)</description>
                         <icon>ibus-keyboard</icon>
-			<rank>99</rank>
+			<rank>1</rank>
 		</engine>
                 <engine>
                         <name>xkb:se:svdvorak:swe</name>
@@ -635,7 +635,7 @@
                         <longname>Swedish (Svdvorak)</longname>
                         <description>Swedish (Svdvorak)</description>
                         <icon>ibus-keyboard</icon>
-                        <rank>99</rank>
+                        <rank>1</rank>
                 </engine>
 		<engine>
 			<name>xkb:ch::ger</name>
@@ -646,7 +646,7 @@
 			<longname>German (Switzerland)</longname>
 			<description>German (Switzerland)</description>
                         <icon>ibus-keyboard</icon>
-			<rank>99</rank>
+			<rank>1</rank>
 		</engine>
 		<engine>
 			<name>xkb:ch:fr:fra</name>
@@ -658,7 +658,7 @@
 			<longname>French (Switzerland)</longname>
 			<description>French (Switzerland)</description>
                         <icon>ibus-keyboard</icon>
-			<rank>99</rank>
+			<rank>1</rank>
 		</engine>
 		<engine>
 			<name>xkb:tr::tur</name>
@@ -692,7 +692,7 @@
 			<longname>English (UK, extended WinKeys)</longname>
 			<description>English (UK, extended WinKeys)</description>
                         <icon>ibus-keyboard</icon>
-			<rank>99</rank>
+			<rank>1</rank>
 		</engine>
 		<engine>
 			<name>xkb:gb:dvorak:eng</name>
@@ -704,7 +704,7 @@
 			<longname>English (UK, Dvorak)</longname>
 			<description>English (UK, Dvorak)</description>
                         <icon>ibus-keyboard</icon>
-			<rank>99</rank>
+			<rank>1</rank>
 		</engine>
 	</engines>
 </component>
-- 
2.1.0

From 8b187598215e3af0481e0f9415fe6a21db682e6b Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
Date: Wed, 25 Mar 2015 13:55:50 +0900
Subject: [PATCH] I18N for engine longnames on ibus-setup

New API ibus_get_untranslated_language_name().
Call bindtextdomain() for each textdomains.

TEST=setup

Review URL: https://codereview.appspot.com/218760043
---
 setup/enginedialog.py   | 41 +++++++++++++++++++----------------------
 setup/enginetreeview.py | 16 +++++++++++-----
 setup/main.py           | 10 ++++++----
 src/ibusutil.c          | 47 ++++++++++++++++++++++++++++-------------------
 src/ibusutil.h          | 16 ++++++++++++----
 ui/gtk2/i18n.py         | 38 +++++++++++++++++++++++++++++---------
 ui/gtk2/main.py         |  8 ++++----
 7 files changed, 109 insertions(+), 67 deletions(-)

diff --git a/setup/enginedialog.py b/setup/enginedialog.py
index 2b179ad..2c472de 100644
--- a/setup/enginedialog.py
+++ b/setup/enginedialog.py
@@ -3,9 +3,9 @@
 #
 # ibus - The Input Bus
 #
-# Copyright (c) 2014 Peng Huang <shawn.p.huang@gmail.com>
-# Copyright (c) 2014 Takao Fujiwara <takao.fujiwara1@gmail.com>
-# Copyright (c) 2013-2014 Red Hat, Inc.
+# Copyright (c) 2015 Peng Huang <shawn.p.huang@gmail.com>
+# Copyright (c) 2015 Takao Fujiwara <takao.fujiwara1@gmail.com>
+# Copyright (c) 2013-2015 Red Hat, Inc.
 #
 # This program is free software; you can redistribute it and/or
 # modify it under the terms of the GNU General Public License as
@@ -29,6 +29,7 @@ from gi.repository import IBus
 
 import functools
 import gettext
+import i18n
 import locale
 
 from icon import load_icon
@@ -227,10 +228,13 @@ class EngineDialog(Gtk.Dialog):
 
 
     def __engine_row_new(self, engine):
-        row = self.__list_box_row_new(engine.get_longname())
-        row.set_tooltip_text(engine.get_description())
+        longname = i18n.gettext_engine_longname(engine)
+        description = i18n.gettext_engine_description(engine)
+        row = self.__list_box_row_new(longname)
+        row.untrans = engine.get_longname()
+        row.set_tooltip_text(description)
         row.engine = engine
-        widget = self.__padded_label_new(engine.get_longname(),
+        widget = self.__padded_label_new(longname,
                                          engine.get_icon(),
                                          Gtk.Align.START,
                                          ROW_TRAVEL_DIRECTION_NONE)
@@ -257,7 +261,9 @@ class EngineDialog(Gtk.Dialog):
 
         def cmp_engine(a, b):
             if a.get_rank() == b.get_rank():
-                return locale.strcoll(a.get_longname(), b.get_longname())
+                a_longname = i18n.gettext_engine_longname(a)
+                b_longname = i18n.gettext_engine_longname(b)
+                return locale.strcoll(a_longname, b_longname)
             return int(b.get_rank() - a.get_rank())
 
         self.__engines_for_lang[lang].sort(
@@ -294,6 +300,7 @@ class EngineDialog(Gtk.Dialog):
         self.__list.add(row)
         self.__add_engine_rows_for_lang(row)
         self.__list.show_all()
+        self.__adjustment.set_value(self.__adjustment.get_lower())
 
 
     def __do_filter(self):
@@ -321,24 +328,14 @@ class EngineDialog(Gtk.Dialog):
                 l = ''
             if l not in self.__engines_for_lang:
                 self.__engines_for_lang[l] = []
+            i18n.init_textdomain(e.get_textdomain())
             self.__engines_for_lang[l].append(e)
 
             # Retrieve Untranslated language names.
-            backup_locale = locale.setlocale(locale.LC_ALL, None)
-            def __set_untrans_with_locale(en_locale):
-                locale.setlocale(locale.LC_ALL, en_locale)
-                untrans = IBus.get_language_name(e.get_language())
-                if untrans == None:
-                    untrans = ''
-                self.__untrans_for_lang[l] = untrans
-            try:
-                __set_untrans_with_locale('en_US.UTF-8')
-            except locale.Error:
-                try:
-                    __set_untrans_with_locale('C')
-                except locale.Error:
-                    pass
-            locale.setlocale(locale.LC_ALL, backup_locale)
+            untrans = IBus.get_untranslated_language_name(e.get_language())
+            if untrans == None:
+                untrans = ''
+            self.__untrans_for_lang[l] = untrans
 
         keys = list(self.__engines_for_lang.keys())
         keys.sort(key=functools.cmp_to_key(locale.strcoll))
diff --git a/setup/enginetreeview.py b/setup/enginetreeview.py
index 75ff04b..4de4a51 100644
--- a/setup/enginetreeview.py
+++ b/setup/enginetreeview.py
@@ -2,8 +2,8 @@
 #
 # ibus - The Input Bus
 #
-# Copyright (c) 2007-2014 Peng Huang <shawn.p.huang@gmail.com>
-# Copyright (c) 2007-2014 Red Hat, Inc.
+# Copyright (c) 2007-2015 Peng Huang <shawn.p.huang@gmail.com>
+# Copyright (c) 2007-2015 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
@@ -26,6 +26,8 @@ from gi.repository import Gtk
 from gi.repository import IBus
 from gi.repository import Pango
 
+import i18n
+
 from icon import load_icon
 from i18n import _, N_
 
@@ -106,8 +108,10 @@ class EngineTreeView(Gtk.TreeView):
         engine_b = model[b][0]
         language_a = IBus.get_language_name(engine_a.get_language())
         language_b = IBus.get_language_name(engine_b.get_language())
-        label_a = "%s - %s" % (language_a, engine_a.get_longname())
-        label_b = "%s - %s" % (language_b, engine_b.get_longname())
+        longname_a = i18n.gettext_engine_longname(engine_a)
+        longname_b = i18n.gettext_engine_longname(engine_b)
+        label_a = "%s - %s" % (language_a, longname_a)
+        label_b = "%s - %s" % (language_b, longname_b)
         # http://docs.python.org/3.0/whatsnew/3.0.html#ordering-comparisons
         return (label_a > label_b) - (label_a < label_b)
 
@@ -149,8 +153,9 @@ class EngineTreeView(Gtk.TreeView):
 
         renderer.set_property("sensitive", True)
         language = IBus.get_language_name(engine.get_language())
+        longname = i18n.gettext_engine_longname(engine)
         renderer.set_property("text",
-                "%s - %s" % (language, engine.get_longname()))
+                "%s - %s" % (language, longname))
         renderer.set_property("weight", Pango.Weight.NORMAL)
 
     def __layout_cell_data_cb(self, celllayout, renderer, model, it, data):
@@ -196,6 +201,7 @@ class EngineTreeView(Gtk.TreeView):
             if e in self.__engines:
                 continue
             it = self.__model.append(None)
+            i18n.init_textdomain(e.get_textdomain())
             self.__model.set(it, 0, e)
             self.__engines.append(e)
         self.__emit_changed()
diff --git a/setup/main.py b/setup/main.py
index c1d5c55..22b6dc7 100644
--- a/setup/main.py
+++ b/setup/main.py
@@ -2,8 +2,8 @@
 #
 # ibus - The Input Bus
 #
-# Copyright (c) 2007-2014 Peng Huang <shawn.p.huang@gmail.com>
-# Copyright (c) 2007-2014 Red Hat, Inc.
+# Copyright (c) 2007-2015 Peng Huang <shawn.p.huang@gmail.com>
+# Copyright (c) 2007-2015 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
@@ -39,13 +39,14 @@ from gi.repository import Gtk
 from gi.repository import IBus
 from os import path
 
+import i18n
 import keyboardshortcut
 import locale
 from enginecombobox import EngineComboBox
 from enginedialog import EngineDialog
 from enginetreeview import EngineTreeView
 from engineabout import EngineAbout
-from i18n import DOMAINNAME, _, N_, init as i18n_init
+from i18n import DOMAINNAME, _, N_
 
 (
     COLUMN_NAME,
@@ -543,6 +544,7 @@ if __name__ == "__main__":
         print("Using the fallback 'C' locale", file=sys.stderr)
         locale.setlocale(locale.LC_ALL, 'C')
 
-    i18n_init()
+    i18n.init_textdomain(DOMAINNAME)
+    i18n.init_textdomain('xkeyboard-config')
     setup = Setup()
     setup.run()
diff --git a/src/ibusutil.c b/src/ibusutil.c
index 3eddc99..b9f3fdd 100644
--- a/src/ibusutil.c
+++ b/src/ibusutil.c
@@ -1,9 +1,9 @@
 /* -*- 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 <shawn.p.huang@gmail.com>
- * Copyright (C) 2010-2011 Takao Fujiwara <takao.fujiwara1@gmail.com>
- * Copyright (C) 2008-2011 Red Hat, Inc.
+ * Copyright (C) 2008-2015 Peng Huang <shawn.p.huang@gmail.com>
+ * Copyright (C) 2010-2015 Takao Fujiwara <takao.fujiwara1@gmail.com>
+ * Copyright (C) 2008-2015 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
@@ -98,6 +98,11 @@ _load_lang()
     XMLNode *node;
     struct stat buf;
 
+#ifdef ENABLE_NLS
+    bindtextdomain ("iso_639", GLIB_LOCALE_DIR);
+    bind_textdomain_codeset ("iso_639", "UTF-8");
+#endif
+
     __languages_dict = g_hash_table_new_full (g_str_hash,
             g_str_equal, g_free, g_free);
     filename = g_build_filename (ISOCODES_PREFIX,
@@ -121,37 +126,41 @@ _load_lang()
 }
 
 const gchar *
-ibus_get_language_name(const gchar *_locale) {
+ibus_get_untranslated_language_name (const gchar *_locale)
+{
     const gchar *retval;
     gchar *p = NULL;
     gchar *lang = NULL;
 
-    if (__languages_dict == NULL ) {
+    if (__languages_dict == NULL )
         _load_lang();
-    }
-    if ((p = strchr (_locale, '_')) !=  NULL) {
+    if ((p = strchr (_locale, '_')) !=  NULL)
         p = g_strndup (_locale, p - _locale);
-    } else {
+    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
+    if (retval != NULL)
         return retval;
-#endif
-    }
-    else {
+    else
+        return "Other";
+}
+
+const gchar *
+ibus_get_language_name (const gchar *_locale)
+{
+    const gchar *retval = ibus_get_untranslated_language_name (_locale);
+
 #ifdef ENABLE_NLS
-        return dgettext(GETTEXT_PACKAGE, N_("Other"));
+    if (g_strcmp0 (retval, "Other") == 0)
+        return dgettext (GETTEXT_PACKAGE, N_("Other"));
+    else
+        return dgettext ("iso_639", retval);
 #else
-        return N_("Other");
+    return retval;
 #endif
-    }
 }
 
 void
diff --git a/src/ibusutil.h b/src/ibusutil.h
index d5d593f..b9b6415 100644
--- a/src/ibusutil.h
+++ b/src/ibusutil.h
@@ -1,9 +1,9 @@
 /* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
 /* vim:set et sts=4: */
 /* bus - The Input Bus
- * Copyright (C) 2008-2013 Peng Huang <shawn.p.huang@gmail.com>
- * Copyright (C) 2010-2013 Takao Fujiwara <takao.fujiwara1@gmail.com>
- * Copyright (C) 2008-2013 Red Hat, Inc.
+ * Copyright (C) 2008-2015 Peng Huang <shawn.p.huang@gmail.com>
+ * Copyright (C) 2010-2015 Takao Fujiwara <takao.fujiwara1@gmail.com>
+ * Copyright (C) 2008-2015 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
@@ -37,9 +37,17 @@
  */
 
 /**
+ * ibus_get_untranslated_language_name:
+ * @_locale: A const locale name.
+ * @returns: untranslated language name
+ */
+const gchar *    ibus_get_untranslated_language_name
+                                                (const gchar    *_locale);
+
+/**
  * ibus_get_language_name:
  * @_locale: A const locale name.
- * @returns: language name
+ * @returns: translated language name
  */
 const gchar *    ibus_get_language_name         (const gchar    *_locale);
 
diff --git a/setup/i18n.py b/setup/i18n.py
index 5a73eee..976d1ae 100644
--- a/setup/i18n.py
+++ b/setup/i18n.py
@@ -2,8 +2,8 @@
 #
 # ibus - The Input Bus
 #
-# Copyright(c) 2007-2010 Peng Huang <shawn.p.huang@gmail.com>
-# Copyright(c) 2007-2010 Google, Inc.
+# Copyright(c) 2007-2015 Peng Huang <shawn.p.huang@gmail.com>
+# Copyright(c) 2007-2015 Google, Inc.
 #
 # This library is free software; you can redistribute it and/or
 # modify it under the terms of the GNU Lesser General Public
@@ -29,15 +29,35 @@ DOMAINNAME = "ibus10"
 _ = lambda a: gettext.dgettext(DOMAINNAME, a)
 N_ = lambda a: a
 
-def init():
-    localedir = os.getenv("IBUS_LOCALEDIR")
+LOCALEDIR = os.getenv("IBUS_LOCALEDIR")
+
+def init_textdomain(domainname):
+    if domainname == '':
+        return
     # Python's locale module doesn't provide all methods on some
     # operating systems like FreeBSD
     try:
-        # for non-standard localedir
-        locale.bindtextdomain(DOMAINNAME, localedir)
-        locale.bind_textdomain_codeset(DOMAINNAME, "UTF-8")
+        locale.bindtextdomain(domainname, LOCALEDIR)
+        locale.bind_textdomain_codeset(domainname, 'UTF-8')
     except AttributeError:
         pass
-    gettext.bindtextdomain(DOMAINNAME, localedir)
-    gettext.bind_textdomain_codeset(DOMAINNAME, "UTF-8")
+    gettext.bindtextdomain(domainname, LOCALEDIR)
+    gettext.bind_textdomain_codeset(domainname, 'UTF-8')
+
+def gettext_engine_longname(engine):
+    name = engine.get_name()
+    if (name.startswith('xkb:')):
+        return gettext.dgettext('xkeyboard-config', engine.get_longname())
+    textdomain = engine.get_textdomain()
+    if textdomain == '':
+        return engine.get_longname()
+    return gettext.dgettext(textdomain, engine.get_longname())
+
+def gettext_engine_description(engine):
+    name = engine.get_name()
+    if (name.startswith('xkb:')):
+        return gettext.dgettext('xkeyboard-config', engine.get_description())
+    textdomain = engine.get_textdomain()
+    if textdomain == '':
+        return engine.get_description()
+    return gettext.dgettext(textdomain, engine.get_description())
-- 
2.1.0

From 02156038217e41ebd90e3d1ed4bb88b912a15a06 Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
Date: Mon, 30 Mar 2015 11:07:42 +0900
Subject: [PATCH] I18N for IBus engine about dialog in ibus-setup

TEST=setup

Review URL: https://codereview.appspot.com/219400043
---
 setup/engineabout.py | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/setup/engineabout.py b/setup/engineabout.py
index 09e9b5c..4e6a5ef 100644
--- a/setup/engineabout.py
+++ b/setup/engineabout.py
@@ -2,8 +2,8 @@
 #
 # ibus - The Input Bus
 #
-# Copyright (c) 2007-2014 Peng Huang <shawn.p.huang@gmail.com>
-# Copyright (c) 2007-2014 Red Hat, Inc.
+# Copyright (c) 2007-2015 Peng Huang <shawn.p.huang@gmail.com>
+# Copyright (c) 2007-2015 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
@@ -26,6 +26,8 @@ from gi.repository import GdkPixbuf
 from gi.repository import Gtk
 from gi.repository import Pango
 
+import i18n
+
 from i18n import _, N_
 
 class EngineAbout(Gtk.Dialog):
@@ -64,7 +66,7 @@ class EngineAbout(Gtk.Dialog):
         text_buffer.insert_pixbuf(iter,
                 self.__load_icon(self.__engine_desc.get_icon()))
         text_buffer.insert_with_tags_by_name(iter,
-                "\n%s\n" % self.__engine_desc.get_longname(),
+                "\n%s\n" % i18n.gettext_engine_longname(self.__engine_desc),
                 "heading", "left_margin_16")
         text_buffer.insert_with_tags_by_name(iter,
                 _("Language: %s\n") % IBus.get_language_name(self.__engine_desc.get_language()),
@@ -78,7 +80,7 @@ class EngineAbout(Gtk.Dialog):
         text_buffer.insert_with_tags_by_name(iter,
                 _("Description:\n"), "small", "bold", "left_margin_16")
         text_buffer.insert_with_tags_by_name(iter,
-                self.__engine_desc.get_description(),
+                i18n.gettext_engine_description(self.__engine_desc),
                 "wrap_text", "left_margin_32")
 
 
-- 
2.1.0

From eb4ffa1d9aeccf31318afd1d24cbcbbefa79337b Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
Date: Tue, 31 Mar 2015 11:56:05 +0900
Subject: [PATCH] Put PropertyPanel at bottom right when desktop is KDE

Monitor _NET_WORKAREA atom because PropertyPanel runs
before KDE5 panel runs.
Allocate button sizes on PropertyPanel correctly for KDE5.

TEST=ui/gtk3/ibus-ui-gtk3

Review URL: https://codereview.appspot.com/220500043
---
 ui/gtk3/propertypanel.vala | 168 ++++++++++++++++++++++++++++++++-------------
 1 file changed, 121 insertions(+), 47 deletions(-)

diff --git a/ui/gtk3/propertypanel.vala b/ui/gtk3/propertypanel.vala
index 6c023bf..12e85b0 100644
--- a/ui/gtk3/propertypanel.vala
+++ b/ui/gtk3/propertypanel.vala
@@ -2,9 +2,9 @@
  *
  * ibus - The Input Bus
  *
- * Copyright(c) 2013-2014 Red Hat, Inc.
- * Copyright(c) 2013-2014 Peng Huang <shawn.p.huang@gmail.com>
- * Copyright(c) 2013-2014 Takao Fujiwara <takao.fujiwara1@gmail.com>
+ * Copyright(c) 2013-2015 Red Hat, Inc.
+ * Copyright(c) 2013-2015 Peng Huang <shawn.p.huang@gmail.com>
+ * Copyright(c) 2013-2015 Takao Fujiwara <takao.fujiwara1@gmail.com>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -29,6 +29,8 @@ enum PanelShow {
 }
 
 public class PropertyPanel : Gtk.Box {
+    private unowned Gdk.Window m_root_window;
+    private unowned X.Display m_xdisplay;
     private Gtk.Window m_toplevel;
     private IBus.PropList m_props;
     private IPropToolItem[] m_items;
@@ -38,6 +40,7 @@ public class PropertyPanel : Gtk.Box {
     private uint m_auto_hide_timeout = 10000;
     private uint m_auto_hide_timeout_id = 0;
     private bool m_follow_input_cursor_when_always_shown = false;
+    private const uint MONITOR_NET_WORKAREA_TIMEOUT = 60000;
 
     public PropertyPanel() {
         /* Chain up base class constructor */
@@ -46,6 +49,14 @@ public class PropertyPanel : Gtk.Box {
 
         set_visible(true);
 
+        m_root_window = Gdk.get_default_root_window();
+        unowned Gdk.Display display = m_root_window.get_display();
+#if VALA_0_24
+        m_xdisplay = (display as Gdk.X11.Display).get_xdisplay();
+#else
+        m_xdisplay = Gdk.X11Display.get_xdisplay(display);
+#endif
+
         m_toplevel = new Gtk.Window(Gtk.WindowType.POPUP);
         m_toplevel.add_events(Gdk.EventMask.BUTTON_PRESS_MASK);
 
@@ -64,6 +75,10 @@ public class PropertyPanel : Gtk.Box {
                 m_cursor_location.y = 0;
             }
         });
+
+        // PropertyPanel runs before KDE5 panel runs and
+        // monitor the desktop size.
+        monitor_net_workarea_atom();
     }
 
     public void set_properties(IBus.PropList props) {
@@ -294,9 +309,8 @@ public class PropertyPanel : Gtk.Box {
             cursor_right_bottom.y + allocation.height
         };
 
-        Gdk.Window root = Gdk.get_default_root_window();
-        int root_width = root.get_width();
-        int root_height = root.get_height();
+        int root_width = m_root_window.get_width();
+        int root_height = m_root_window.get_height();
 
         int x, y;
         if (window_right_bottom.x > root_width)
@@ -312,73 +326,125 @@ public class PropertyPanel : Gtk.Box {
         move(x, y);
     }
 
+    private bool is_bottom_panel() {
+        string desktop = Environment.get_variable("XDG_CURRENT_DESKTOP");
+        // LXDE has not implemented DesktopNames yet.
+        if (desktop == null)
+            desktop = Environment.get_variable("XDG_SESSION_DESKTOP");
+        switch (desktop) {
+            case "KDE":         return true;
+            case "LXDE":        return true;
+            default:            return false;
+        }
+    }
+
     private void set_default_location() {
         Gtk.Allocation allocation;
         m_toplevel.get_allocation(out allocation);
 
-        unowned Gdk.Window root = Gdk.get_default_root_window();
-        int root_width = root.get_width();
+        int root_width = m_root_window.get_width();
+        int root_height = m_root_window.get_height();
         int root_x = 0;
         int root_y = 0;
         int ws_num = 0;
 
-        unowned Gdk.Display display = root.get_display();
 #if VALA_0_24
-        unowned X.Display xdisplay =
-                (display as Gdk.X11.Display).get_xdisplay();
-        X.Window xwindow = (root as Gdk.X11.Window).get_xid();
+        X.Window xwindow = (m_root_window as Gdk.X11.Window).get_xid();
 #else
-        unowned X.Display xdisplay = Gdk.X11Display.get_xdisplay(display);
-        X.Window xwindow = Gdk.X11Window.get_xid(root);
+        X.Window xwindow = Gdk.X11Window.get_xid(m_root_window);
 #endif
         X.Atom _net_current_desktop =
-                xdisplay.intern_atom("_NET_CURRENT_DESKTOP", false);
+                m_xdisplay.intern_atom("_NET_CURRENT_DESKTOP", false);
         X.Atom type = X.None;
         int format;
         ulong nitems = 0;
         ulong bytes_after;
         void *prop;
-        xdisplay.get_window_property(xwindow,
-                                     _net_current_desktop,
-                                     0, 32, false, X.XA_CARDINAL,
-                                     out type, out format,
-                                     out nitems, out bytes_after,
-                                     out prop);
+        m_xdisplay.get_window_property(xwindow,
+                                      _net_current_desktop,
+                                      0, 32, false, X.XA_CARDINAL,
+                                      out type, out format,
+                                      out nitems, out bytes_after,
+                                      out prop);
 
         if (type != X.None && nitems >= 1)
             ws_num = (int) ((ulong *)prop)[0];
 
         X.Atom _net_workarea =
-                xdisplay.intern_atom("_NET_WORKAREA", false);
+                m_xdisplay.intern_atom("_NET_WORKAREA", false);
         type = X.None;
         nitems = 0;
 
-        xdisplay.get_window_property(xwindow,
-                                     _net_workarea,
-                                     0, 32, false, X.XA_CARDINAL,
-                                     out type, out format,
-                                     out nitems, out bytes_after,
-                                     out prop);
-
-        if (type != X.None && nitems >= 2) {
-            root_x = (int) ((ulong *)prop)[ws_num * 4];
-            root_y = (int) ((ulong *)prop)[ws_num * 4 + 1];
+        m_xdisplay.get_window_property(xwindow,
+                                      _net_workarea,
+                                      0, 32, false, X.XA_CARDINAL,
+                                      out type, out format,
+                                      out nitems, out bytes_after,
+                                      out prop);
+
+        if (type != X.None) {
+            if (nitems >= 2) {
+                root_x = (int) ((ulong *)prop)[ws_num * 4];
+                root_y = (int) ((ulong *)prop)[ws_num * 4 + 1];
+            }
+            if (nitems >= 4) {
+                root_width = (int) ((ulong *)prop)[ws_num * 4 + 2];
+                root_height = (int) ((ulong *)prop)[ws_num * 4 + 3];
+            }
         }
 
         int x, y;
-        /* Translators: If your locale is RTL, the msgstr is "default:RTL".
-         * Otherwise the msgstr is "default:LTR". */
-        if (_("default:LTR") != "default:RTL") {
-            x = root_width - allocation.width;
-            y = root_y;
+        if (is_bottom_panel()) {
+            /* Translators: If your locale is RTL, the msgstr is "default:RTL".
+             * Otherwise the msgstr is "default:LTR". */
+            if (_("default:LTR") != "default:RTL") {
+                x = root_width - allocation.width;
+                y = root_height - allocation.height;
+            } else {
+                x = root_x;
+                y = root_height - allocation.height;
+            }
         } else {
-            x = root_x;
-            y = root_y;
+            if (_("default:LTR") != "default:RTL") {
+                x = root_width - allocation.width;
+                y = root_y;
+            } else {
+                x = root_x;
+                y = root_y;
+            }
         }
 
         move(x, y);
     }
 
+    private Gdk.FilterReturn root_window_filter(Gdk.XEvent gdkxevent,
+                                                Gdk.Event  event) {
+        X.Event *xevent = (X.Event*) gdkxevent;
+        if (xevent.type == X.EventType.PropertyNotify) {
+            string aname = m_xdisplay.get_atom_name(xevent.xproperty.atom);
+            if (aname == "_NET_WORKAREA" && xevent.xproperty.state == 0) {
+                set_default_location();
+                return Gdk.FilterReturn.CONTINUE;
+            }
+        }
+        return Gdk.FilterReturn.CONTINUE;
+    }
+
+    private void monitor_net_workarea_atom() {
+        Gdk.EventMask events = m_root_window.get_events();
+        if ((events & Gdk.EventMask.PROPERTY_CHANGE_MASK) == 0)
+            m_root_window.set_events (events |
+                                      Gdk.EventMask.PROPERTY_CHANGE_MASK);
+
+        m_root_window.add_filter(root_window_filter);
+
+        GLib.Timeout.add(MONITOR_NET_WORKAREA_TIMEOUT, () => {
+            m_root_window.remove_filter(root_window_filter);
+            return false;
+        },
+        GLib.Priority.DEFAULT_IDLE);
+    }
+
     private void show_with_auto_hide_timer() {
         if (m_items.length == 0) {
             /* Do not blink the panel with focus-in in case the panel
@@ -568,10 +634,12 @@ public class PropToolButton : Gtk.ToolButton, IPropToolItem {
     private IBus.Property m_prop = null;
 
     public PropToolButton(IBus.Property prop) {
-        string label = prop.get_symbol().get_text();
-
-        /* Chain up base class constructor */
-        GLib.Object(label: label);
+        /* Chain up base class constructor
+         *
+         * If the constructor sets "label" property, "halign" property
+         * does not work in KDE5 so use sync() for the label.
+         */
+        GLib.Object(halign: Gtk.Align.START);
 
         m_prop = prop;
 
@@ -627,8 +695,11 @@ public class PropToggleToolButton : Gtk.ToggleToolButton, IPropToolItem {
     private IBus.Property m_prop = null;
 
     public PropToggleToolButton(IBus.Property prop) {
-        /* Chain up base class constructor */
-        GLib.Object();
+        /* Chain up base class constructor
+         *
+         * Need to set halign for KDE5
+         */
+        GLib.Object(halign: Gtk.Align.START);
 
         m_prop = prop;
 
@@ -706,8 +777,11 @@ public class PropMenuToolButton : PropToggleToolButton, IPropToolItem {
     private PropMenu m_menu = null;
 
     public PropMenuToolButton(IBus.Property prop) {
-        /* Chain up base class constructor */
-        GLib.Object();
+        /* Chain up base class constructor
+         *
+         * Need to set halign for KDE5
+         */
+        GLib.Object(halign: Gtk.Align.START);
 
         m_menu = new PropMenu(prop);
         m_menu.deactivate.connect((m) =>
-- 
2.1.0

From 020bd45eda9e3a3a2836122fbe0437cafb71f163 Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
Date: Wed, 1 Apr 2015 11:42:34 +0900
Subject: [PATCH] ibus-ui-gtk3: Draw gray color on PropertyPanel handle

Users can move the position of IBus PropertyPanel with the mouse
but currently it is too hard to find the handle on the panel.
Now the handle is drawn by the gray color for the visibility.

TEST=ui/gtk3/ibus-ui-gtk3

Review URL: https://codereview.appspot.com/219520043
---
 ui/gtk3/handle.vala | 15 ++++++++++++++-
 1 file changed, 14 insertions(+), 1 deletion(-)

diff --git a/ui/gtk3/handle.vala b/ui/gtk3/handle.vala
index b9c3bbc..1edb537 100644
--- a/ui/gtk3/handle.vala
+++ b/ui/gtk3/handle.vala
@@ -2,7 +2,7 @@
  *
  * ibus - The Input Bus
  *
- * Copyright(c) 2011 Peng Huang <shawn.p.huang@gmail.com>
+ * Copyright(c) 2011-2015 Peng Huang <shawn.p.huang@gmail.com>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -36,6 +36,19 @@ class Handle : Gtk.EventBox {
                              Gdk.EventMask.BUTTON1_MOTION_MASK;
         set_events(mask);
         m_move_begined = false;
+
+        // Currently it is too hard to notice this Handle on PropertyPanel
+        // so now this widget is drawn by the gray color for the visibility.
+        Gtk.CssProvider css_provider = new Gtk.CssProvider();
+        try {
+            css_provider.load_from_data(
+                    "GtkEventBox { background-color: gray }", -1);
+        } catch (GLib.Error error) {
+            warning("Parse error in Handle: %s", error.message);
+        }
+        Gtk.StyleContext context = get_style_context();
+        context.add_provider(css_provider,
+                             Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
     }
 
     public override void realize() {
-- 
2.1.0

From cc88075ddae038f90039d58147bb3c9d7eb08364 Mon Sep 17 00:00:00 2001
From: Hodong Kim <hodong@cogno.org>
Date: Thu, 2 Apr 2015 11:18:57 +0900
Subject: [PATCH] Fix compile error in client/x11/Makefile

BUG=https://github.com/ibus/ibus/pull/18
TEST=client/x11/Makefile

Review URL: https://codereview.appspot.com/217590043
Patch from Hodong Kim <hodong@cogno.org>.
---
 client/x11/Makefile.am | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/client/x11/Makefile.am b/client/x11/Makefile.am
index 9813ceb..ba6fe8a 100644
--- a/client/x11/Makefile.am
+++ b/client/x11/Makefile.am
@@ -57,7 +57,7 @@ noinst_HEADERS = \
 	locales.h \
 	$(NULL)
 
-$(IMdkit):
+$(libIMdkit):
 	(cd $(top_builddir)/util/IMdkit; make)
 
 $(libibus):
-- 
2.1.0

From 35d035bfc48e20eecb3b3b3b14712d73c5fc027b Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
Date: Thu, 2 Apr 2015 11:26:24 +0900
Subject: [PATCH] ibus-ui-gtk3: Enable absolute path of engine icon in
 KDE5

plasma-workspace 5.2 supports the icon full path.
Now the build checks if qtbase-devel is 5.4 or later since
there is no way to check the version of plasma-workspace.

BUG=https://github.com/ibus/ibus/pull/17
TEST=ui/gtk3/ibus-ui-gtk3

Review URL: https://codereview.appspot.com/217310044
---
 configure.ac        | 17 +++++++++++++++++
 ui/gtk3/Makefile.am |  8 ++++++--
 ui/gtk3/panel.vala  | 10 ++++++++--
 3 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/configure.ac b/configure.ac
index 39c9cad..8eb6168 100644
--- a/configure.ac
+++ b/configure.ac
@@ -270,9 +270,25 @@ else
     enable_wayland="no (disabled, use --enable-wayland to enable)"
 fi
 
+enable_appindicator_engine_icon="no"
 if test x"$enable_appindicator" = x"yes"; then
     enable_appindicator="yes (enabled, use --disable-appindicator to disable)"
+
+    # Need qt5-qtbase-devel package
+    # There is no way to check the version of KStatusNotifierItem and
+    # check the version of qtbase here.
+    AC_MSG_CHECKING([for KDE5 appindicator engine icon])
+    PKG_CHECK_EXISTS([Qt5Gui >= 5.4],
+        enable_appindicator_engine_icon="yes"
+    )
+    AC_MSG_RESULT([$enable_appindicator_engine_icon])
+
+fi
+if test x"$enable_appindicator_engine_icon" != x"yes" ; then
+    enable_appindicator_engine_icon="no (disabled, need qtbase-devel 5.4 or later)"
 fi
+AM_CONDITIONAL([ENABLE_APPINDICATOR_ENGINE_ICON],
+               [test x"$enable_appindicator_engine_icon" = x"yes"])
 
 # GObject introspection
 GOBJECT_INTROSPECTION_CHECK([0.6.8])
@@ -639,6 +655,7 @@ Build options:
   Build XIM agent server        $enable_xim
   Build wayland support         $enable_wayland
   Build appindicator support    $enable_appindicator
+  Build appindicator engine icon $enable_appindicator_engine_icon
   Build python library          $enable_python_library
   Build gconf modules           $enable_gconf
   Build memconf modules         $enable_memconf
diff --git a/ui/gtk3/Makefile.am b/ui/gtk3/Makefile.am
index 40cce11..2de227d 100644
--- a/ui/gtk3/Makefile.am
+++ b/ui/gtk3/Makefile.am
@@ -98,6 +98,10 @@ if ENABLE_APPINDICATOR
 AM_VALAFLAGS += --define=INDICATOR
 endif
 
+if ENABLE_APPINDICATOR_ENGINE_ICON
+AM_VALAFLAGS += --define=INDICATOR_ENGINE_ICON
+endif
+
 libexec_PROGRAMS = ibus-ui-gtk3
 
 ibus_ui_gtk3_SOURCES = \
@@ -136,8 +140,8 @@ CLEANFILES = \
 # References:
 # libappindicator/src/notification-item.xml
 # libappindicator/src/notification-watcher.xml
-# knotifications/src/org.kde.StatusNotifierItem.xml
-# knotifications/src/org.kde.StatusNotifierWatcher.xml
+# kdelibs/kdeui/knotifications/src/org.kde.StatusNotifierItem.xml
+# kdelibs/kdeui/knotifications/src/org.kde.StatusNotifierWatcher.xml
 EXTRA_DIST = \
 	gtkpanel.xml.in \
 	notification-item.xml \
diff --git a/ui/gtk3/panel.vala b/ui/gtk3/panel.vala
index 1379860..c77bd2f 100644
--- a/ui/gtk3/panel.vala
+++ b/ui/gtk3/panel.vala
@@ -1248,9 +1248,15 @@ class Panel : IBus.PanelService {
                 m_status_icon.set_from_file(icon_name);
             }
             else if (m_icon_type == IconType.INDICATOR) {
-                warning("appindicator requires an icon name in a theme " +
-                        "path instead of the full path: %s", icon_name);
+#if INDICATOR_ENGINE_ICON
+                m_indicator.set_icon_full(icon_name, "");
+#else
+                warning("plasma-workspace 5.2 or later is required to " +
+                        "show the absolute path icon %s. Currently check " +
+                        "qtbase 5.4 since there is no way to check " +
+                        "the version of plasma-workspace.", icon_name);
                 m_indicator.set_icon_full("ibus-engine", "");
+#endif
             }
         } else {
             string language = null;
-- 
2.1.0

From 5d9109b3c56bca60be441ad286688467c67664c8 Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
Date: Tue, 21 Apr 2015 11:26:04 +0900
Subject: [PATCH] Fix to show keyboard shortcuts in ibus-setup.

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

Review URL: https://codereview.appspot.com/233720043
---
 setup/keyboardshortcut.py | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/setup/keyboardshortcut.py b/setup/keyboardshortcut.py
index 86463cb..39a6d47 100644
--- a/setup/keyboardshortcut.py
+++ b/setup/keyboardshortcut.py
@@ -2,8 +2,8 @@
 #
 # ibus - The Input Bus
 #
-# Copyright (c) 2007-2014 Peng Huang <shawn.p.huang@gmail.com>
-# Copyright (c) 2007-2014 Red Hat, Inc.
+# Copyright (c) 2007-2015 Peng Huang <shawn.p.huang@gmail.com>
+# Copyright (c) 2007-2015 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
@@ -51,13 +51,13 @@ class KeyboardShortcutSelection(Gtk.Box):
         # shortcuts view
         self.__shortcut_view = Gtk.TreeView(
                 model = Gtk.ListStore(GObject.TYPE_STRING))
-        self.__shortcut_view.set_size_request(-1, 100)
         renderer = Gtk.CellRendererText()
         column = Gtk.TreeViewColumn(_("Keyboard shortcuts"), renderer, text = 0)
         self.__shortcut_view.append_column(column)
         self.__shortcut_view.connect("cursor-changed", self.__shortcut_view_cursor_changed_cb)
         scrolledwindow = Gtk.ScrolledWindow()
         scrolledwindow.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC)
+        scrolledwindow.set_min_content_height(100)
         scrolledwindow.add(self.__shortcut_view)
         scrolledwindow.set_shadow_type(Gtk.ShadowType.IN)
         self.pack_start(scrolledwindow, True, True, 4)
@@ -265,7 +265,9 @@ class KeyboardShortcutSelection(Gtk.Box):
                               GObject.TYPE_UINT,
                               GObject.TYPE_UINT)
         accel_view = Gtk.TreeView(model = model)
+        accel_view.set_headers_visible(False)
         sw.add(accel_view)
+        sw.set_min_content_height(30)
         column = Gtk.TreeViewColumn()
         renderer = Gtk.CellRendererAccel(accel_mode=Gtk.CellRendererAccelMode.OTHER,
                                          editable=True)
-- 
2.3.5

--- ibus-1.5.10/client/gtk2/ibusimcontext.c.orig	2015-04-24 13:49:05.148023921 +0900
+++ ibus-1.5.10/client/gtk2/ibusimcontext.c	2015-04-24 13:52:58.871389692 +0900
@@ -579,7 +579,11 @@ ibus_im_context_class_init (IBusIMContex
 
     /* init bus object */
     if (_bus == NULL) {
-        ibus_set_display (gdk_display_get_name (gdk_display_get_default ()));
+        const gchar *dname = gdk_display_get_name (gdk_display_get_default ());
+        /* ibus-daemon uses DISPLAY variable. */
+        if (g_strcmp0 (dname, "Wayland") == 0)
+            dname = g_getenv ("DISPLAY");
+        ibus_set_display (dname);
         _bus = ibus_bus_new_async ();
 
         /* init the global fake context */
From 465e16e8691997fe352d3882a1f02c6455759867 Mon Sep 17 00:00:00 2001
From: fujiwarat <takao.fujiwara1@gmail.com>
Date: Fri, 22 May 2015 12:06:52 +0900
Subject: [PATCH] ibus-ui-gtk3: radio and check menu items work with GTK 3.16

GTK 3.16 has cleared the radio buttons' state in
gtk_radio_menu_item_set_group():
https://git.gnome.org/browse/gtk+/commit/?id=955aed9227
---
 ui/gtk3/property.vala | 45 +++++++++++++++++++++++++++++++++++++++++----
 1 file changed, 41 insertions(+), 4 deletions(-)

diff --git a/ui/gtk3/property.vala b/ui/gtk3/property.vala
index aef880f..419f2bf 100644
--- a/ui/gtk3/property.vala
+++ b/ui/gtk3/property.vala
@@ -2,7 +2,7 @@
  *
  * ibus - The Input Bus
  *
- * Copyright(c) 2011-2014 Peng Huang <shawn.p.huang@gmail.com>
+ * Copyright(c) 2011-2015 Peng Huang <shawn.p.huang@gmail.com>
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
@@ -133,7 +133,7 @@ public class PropImageMenuItem : Gtk.MenuItem, IPropItem {
     }
 }
 
-public class PropCheckMenuItem : Gtk.RadioMenuItem, IPropItem {
+public class PropCheckMenuItem : Gtk.CheckMenuItem, IPropItem {
     private IBus.Property m_property;
     public PropCheckMenuItem(IBus.Property property) {
         assert(property != null);
@@ -173,13 +173,50 @@ public class PropCheckMenuItem : Gtk.RadioMenuItem, IPropItem {
     }
 }
 
-public class PropRadioMenuItem : PropCheckMenuItem {
+public class PropRadioMenuItem : Gtk.RadioMenuItem, IPropItem {
+    private IBus.Property m_property;
     public PropRadioMenuItem(IBus.Property property,
         PropRadioMenuItem ?group_source) {
-        base(property);
+        assert(property != null);
+
+        m_property = property;
+        set_no_show_all(true);
 
         if (group_source != null)
             set_group(group_source.get_group());
+
+        /* Call sync() after call set_group() because
+         * gtk_radio_menu_item_set_group() sets active = 0. */
+        sync();
+    }
+
+    public void update_property(IBus.Property property) {
+        if (m_property.get_key() != property.get_key())
+            return;
+
+        m_property.set_label(property.get_label());
+        m_property.set_icon(property.get_icon());
+        m_property.set_visible(property.get_visible());
+        m_property.set_sensitive(property.get_sensitive());
+        m_property.set_tooltip(property.get_tooltip());
+        m_property.set_state(property.get_state());
+        sync();
+    }
+
+    private void sync() {
+        set_label(m_property.get_label().get_text());
+        set_visible(m_property.get_visible());
+        set_sensitive(m_property.get_sensitive());
+        set_active(m_property.get_state() == IBus.PropState.CHECKED);
+    }
+
+    public override void toggled() {
+        IBus.PropState new_state =
+            get_active() ? IBus.PropState.CHECKED : IBus.PropState.UNCHECKED;
+        if (m_property.get_state() != new_state) {
+            m_property.set_state(new_state);
+            property_activate(m_property.get_key(), m_property.get_state());
+        }
     }
 }
 
-- 
2.3.5