From 523f6d1e1e9e4d277fbbb4bcb4eb2de6333fa0b6434a1467280a5b3a4f84dcd4 Mon Sep 17 00:00:00 2001 From: Marguerite Su Date: Thu, 31 Jul 2014 17:55:01 +0000 Subject: [PATCH] Accepting request 243221 from home:ftake:branches:M17N - remove patches merged by upstream * add-libgnomekbd-and-load-preload-engines.patch * reload-preload-engines-until-users-customize-the-list.patch - obsoletes python-ibus when packaged for Python 3 OBS-URL: https://build.opensuse.org/request/show/243221 OBS-URL: https://build.opensuse.org/package/show/M17N/ibus?expand=0&rev=115 --- ...libgnomekbd-and-load-preload-engines.patch | 1953 ----------------- ibus.changes | 8 + ibus.spec | 30 +- ...gines-until-users-customize-the-list.patch | 353 --- 4 files changed, 11 insertions(+), 2333 deletions(-) delete mode 100644 add-libgnomekbd-and-load-preload-engines.patch delete mode 100644 reload-preload-engines-until-users-customize-the-list.patch diff --git a/add-libgnomekbd-and-load-preload-engines.patch b/add-libgnomekbd-and-load-preload-engines.patch deleted file mode 100644 index 664ed6d..0000000 --- a/add-libgnomekbd-and-load-preload-engines.patch +++ /dev/null @@ -1,1953 +0,0 @@ -From 167a8f31107dc3a4c6e06a7cf3674372654db2a9 Mon Sep 17 00:00:00 2001 -From: fujiwarat -Date: Fri, 7 Mar 2014 16:41:37 +0900 -Subject: [PATCH] Add libgnomekbd and load preload engines. - ---- - bindings/vala/Gkbd-3.0.metadata | 1 + - bindings/vala/Makefile.am | 19 +- - bindings/vala/Xkl-1.0.metadata | 3 + - bindings/vala/gkbd.deps | 3 + - bus/ibusimpl.c | 12 +- - configure.ac | 40 ++++ - data/ibus.schemas.in | 59 +++++ - ibus-1.0.pc.in | 1 + - ibus.spec.in | 12 ++ - src/Makefile.am | 3 + - src/ibus.h | 1 + - src/ibusxkbxml.c | 466 ++++++++++++++++++++++++++++++++++++++++ - src/ibusxkbxml.h | 187 ++++++++++++++++ - ui/gtk3/Makefile.am | 36 ++++ - ui/gtk3/gkbdlayout.vala.false | 63 ++++++ - ui/gtk3/gkbdlayout.vala.true | 108 ++++++++++ - ui/gtk3/panel.vala | 196 ++++++++++++++++- - ui/gtk3/xkblayout.vala | 429 ++++++++++++++++++++++++++++++++++++ - 18 files changed, 1634 insertions(+), 5 deletions(-) - create mode 100644 bindings/vala/Gkbd-3.0.metadata - create mode 100644 bindings/vala/Xkl-1.0.metadata - create mode 100644 bindings/vala/gkbd.deps - create mode 100644 src/ibusxkbxml.c - create mode 100644 src/ibusxkbxml.h - create mode 100644 ui/gtk3/gkbdlayout.vala.false - create mode 100644 ui/gtk3/gkbdlayout.vala.true - create mode 100644 ui/gtk3/xkblayout.vala - -diff --git a/bindings/vala/Gkbd-3.0.metadata b/bindings/vala/Gkbd-3.0.metadata -new file mode 100644 -index 0000000..661e6fd ---- /dev/null -+++ b/bindings/vala/Gkbd-3.0.metadata -@@ -0,0 +1 @@ -+Configuration cheader_filename="libgnomekbd/gkbd-configuration.h" -diff --git a/bindings/vala/Makefile.am b/bindings/vala/Makefile.am -index 29cc1eb..1d28501 100644 ---- a/bindings/vala/Makefile.am -+++ b/bindings/vala/Makefile.am -@@ -28,8 +28,6 @@ vapi_deps = \ - $(top_builddir)/src/IBus-1.0.gir \ - $(NULL) - --ibus-1.0.vapi: $(vapi_deps) -- - VAPIGEN_VAPIS = ibus-1.0.vapi - - ibus_1_0_vapi_DEPS = gio-2.0 -@@ -39,19 +37,34 @@ ibus_1_0_vapi_FILES = \ - $(srcdir)/IBus-1.0-custom.vala \ - $(NULL) - -+if ENABLE_LIBGNOMEKBD -+ibus-1.0.vapi: $(vapi_deps) gkbd.vapi -+ -+VAPIGEN_VAPIS += gkbd.vapi -+ -+gkbd_vapi_DEPS = gtk+-3.0 glib-2.0 gmodule-2.0 -+gkbd_vapi_METADATADIRS = $(srcdir) -+gkbd_vapi_FILES = /usr/share/gir-1.0/Gkbd-3.0.gir -+else -+ibus-1.0.vapi: $(vapi_deps) -+endif -+ - vapidir = $(datadir)/vala/vapi --vapi_DATA = $(VAPIGEN_VAPIS) $(VAPIGEN_VAPIS:.vapi=.deps) -+vapi_DATA = ibus-1.0.vapi ibus-1.0.deps - - MAINTAINERCLEANFILES = $(VAPIGEN_VAPIS) - - EXTRA_DIST = \ - $(VAPIGEN_VAPIS) \ -+ Gkbd-3.0.metadata \ -+ gkbd.deps \ - IBus-1.0.metadata \ - IBus-1.0-custom.vala \ - ibus-1.0.deps \ - ibus-private.vapi \ - config.vapi \ - xi.vapi \ -+ Xkl-1.0.metadata \ - $(NULL) - - -include $(top_srcdir)/git.mk -diff --git a/bindings/vala/Xkl-1.0.metadata b/bindings/vala/Xkl-1.0.metadata -new file mode 100644 -index 0000000..4961d0c ---- /dev/null -+++ b/bindings/vala/Xkl-1.0.metadata -@@ -0,0 +1,3 @@ -+Xkl cheader_filename="libxklavier/xklavier.h" -+Engine -+ .filter_events.evt ref type="X.Event" -diff --git a/bindings/vala/gkbd.deps b/bindings/vala/gkbd.deps -new file mode 100644 -index 0000000..172632c ---- /dev/null -+++ b/bindings/vala/gkbd.deps -@@ -0,0 +1,3 @@ -+gtk+-3.0 -+glib-2.0 -+gmodule-2.0 -diff --git a/bus/ibusimpl.c b/bus/ibusimpl.c -index eec6da3..f84c034 100644 ---- a/bus/ibusimpl.c -+++ b/bus/ibusimpl.c -@@ -1135,7 +1135,17 @@ enum { - g_variant_builder_init (&builder, G_VARIANT_TYPE ("av")); - while (names[i] != NULL) { - IBusEngineDesc *desc = (IBusEngineDesc *) g_hash_table_lookup ( -- ibus->engine_table, names[i++]); -+ ibus->engine_table, names[i]); -+ -+ /* preload engines return user XKB so if the engine does not -+ * exist in simple.xml, fall back to 'us' layout. */ -+ if (desc == NULL && g_str_has_prefix (names[i], "xkb:")) { -+ desc = (IBusEngineDesc *) g_hash_table_lookup ( -+ ibus->engine_table, "xkb:us::eng"); -+ } -+ -+ i++; -+ - if (desc == NULL) - continue; - g_variant_builder_add ( -diff --git a/configure.ac b/configure.ac -index 9a502ec..3ec629d 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -261,6 +261,45 @@ else - enable_wayland="no (disabled, use --enable-wayland to enable)" - fi - -+# Option for XKB command. -+PKG_CHECK_MODULES(XKB, -+ [xkbfile],, -+ [XKB_LIBS="-lxkbfile"] -+) -+ -+# --enable-libgnomekbd option. -+AC_ARG_ENABLE(libgnomekbd, -+ AS_HELP_STRING([--enable-libgnomekbd], -+ [Use libgnomekbd to handle the keymaps]), -+ [enable_libgnomekbd=$enableval], -+ [enable_libgnomekbd=no] -+) -+AM_CONDITIONAL([ENABLE_LIBGNOMEKBD], [test x"$enable_libgnomekbd" = x"yes"]) -+if test x"$enable_libgnomekbd" = x"yes"; then -+ # check for libgnomekbd -+ PKG_CHECK_MODULES(LIBGNOMEKBDUI, [ -+ libgnomekbdui -+ ]) -+ PKG_CHECK_MODULES(ATK, [ -+ atk -+ ]) -+ HAVE_IBUS_GKBD=true -+else -+ enable_libgnomekbd="no (disabled, use --enable-libgnomekbd to enable)" -+ HAVE_IBUS_GKBD=false -+fi -+AC_SUBST(HAVE_IBUS_GKBD) -+ -+# Define XKB rules file -+AC_ARG_WITH(xkb-rules-xml, -+ AS_HELP_STRING([--with-xkb-rules-xml[=$DIR/evdev.xml]], -+ [Set evdev.xml file path (default: /usr/share/X11/xkb/rules/evdev.xml)]), -+ XKB_RULES_XML_FILE=$with_xkb_rules_xml, -+ XKB_RULES_XML_FILE="/usr/share/X11/xkb/rules/evdev.xml" -+) -+AC_DEFINE_UNQUOTED(XKB_RULES_XML_FILE, "$XKB_RULES_XML_FILE", -+ [Define file path of evdev.xml]) -+ - # GObject introspection - GOBJECT_INTROSPECTION_CHECK([0.6.8]) - -@@ -640,6 +679,7 @@ Build options: - Panel icon "$IBUS_ICON_KEYBOARD" - Enable surrounding-text $enable_surrounding_text - Enable libnotify $enable_libnotify -+ Build libgnomebkd $enable_libgnomekbd - Run test cases $enable_tests - ]) - -diff --git a/data/ibus.schemas.in b/data/ibus.schemas.in -index 2f76ce3..caec315 100644 ---- a/data/ibus.schemas.in -+++ b/data/ibus.schemas.in -@@ -56,6 +56,52 @@ - - - -+ /schemas/desktop/ibus/general/use_xmodmap -+ /desktop/ibus/general/use_xmodmap -+ ibus -+ bool -+ true -+ -+ Use xmodmap -+ Run xmodmap if .xmodmap/.Xmodmap exists. -+ -+ -+ -+ /schemas/desktop/ibus/general/xkb_latin_layouts -+ /desktop/ibus/general/xkb_latin_layouts -+ ibus -+ list -+ string -+ [ara,bg,cz,dev,gr,gur,in,jp(kana),mal,mkd,ru,ua] -+ -+ Latin layout which have no ASCII -+ us layout is appended to the latin layouts. variant is not needed. -+ -+ -+ -+ /schemas/desktop/ibus/general/load_xkb_layouts -+ /desktop/ibus/general/load_xkb_layouts -+ ibus -+ list -+ string -+ [us,us(chr),us(dvorak),ad,al,am,ara,az,ba,bd,be,bg,br,bt,by, -+de,dk,ca,ch,cn(tib),cz,ee,epo,es,et,fi,fo,fr, -+gb,ge,ge(dsb),ge(ru),ge(os),gh,gh(akan),gh(ewe),gh(fula),gh(ga),gh(hausa), -+gn,gr,hu,hr,ie,ie(CloGaelach),il, -+in, -+in(tel),in(bolnagri),iq,iq(ku),ir,ir(ku),is,it,jp, -+kg,kh,kz,la,latam,lk,lk(tam_unicode),lt,lv,ma,ma(tifinagh),mal,mao, -+me,mk,mm,mt,mv,ng,ng(hausa),ng,ng(igbo),ng(yoruba),nl,no,no(smi),np, -+pk,pl,pl(csb),pt,ro,rs,ru,ru(cv),ru(kom),ru(sah),ru(tt),ru(xal), -+se,si,sk,sy,sy(ku),th,tj,tr,ua,uz,vn -+] -+ -+ XKB layout list which is shown on ibus-setup -+ XKB layout list which is shown on ibus-setup. -+ The format is "layout" or "layout(variant)". -+ -+ -+ - /schemas/desktop/ibus/general/hotkey/trigger - /desktop/ibus/general/hotkey/trigger - ibus -@@ -80,6 +126,19 @@ - - - -+ /schemas/desktop/ibus/general/hotkey/triggers-no-modifiers -+ /desktop/ibus/general/hotkey/triggers-no-modifiers -+ ibus -+ list -+ string -+ [] -+ -+ Trigger shortcut keys without modifier keys -+ Trigger shortcut keys without modifier keys. -+ The list is used by ibus-gjs. -+ -+ -+ - /schemas/desktop/ibus/general/hotkey/enable_unconditional - /desktop/ibus/general/hotkey/enable_unconditional - ibus -diff --git a/ibus-1.0.pc.in b/ibus-1.0.pc.in -index 9f593ab..c93a0ed 100644 ---- a/ibus-1.0.pc.in -+++ b/ibus-1.0.pc.in -@@ -4,6 +4,7 @@ libdir=@libdir@ - includedir=@includedir@ - datadir=@datadir@ - pkgdatadir=@datadir@/ibus -+have_ibus_gkbd=@HAVE_IBUS_GKBD@ - - Name: IBus - Description: IBus Library -diff --git a/ibus.spec.in b/ibus.spec.in -index 334f37e..2017af9 100644 ---- a/ibus.spec.in -+++ b/ibus.spec.in -@@ -5,6 +5,7 @@ - - # Build flags - %define build_python_library 0 -+%define build_libgnomekbd 0 - - %define glib_ver %([ -a %{_libdir}/pkgconfig/glib-2.0.pc ] && pkg-config --modversion glib-2.0 | cut -d. -f 1,2 || echo -n "999") - %define gconf2_version 2.12.0 -@@ -40,6 +41,10 @@ BuildRequires: dconf-devel - BuildRequires: pygobject2-devel - BuildRequires: intltool - BuildRequires: iso-codes-devel -+%if %{build_libgnomekbd} -+BuildRequires: libxkbfile-devel -+BuildRequires: libgnomekbd-devel -+%endif - - Requires: %{name}-libs = %{version}-%{release} - Requires: %{name}-gtk2 = %{version}-%{release} -@@ -52,6 +57,9 @@ Requires: dbus-python >= %{dbus_python_version} - Requires: im-chooser >= %{im_chooser_version} - Requires: notify-python - Requires: librsvg2 -+%if %{build_libgnomekbd} -+Requires: libgnomekbd -+%endif - - Requires(post): desktop-file-utils - Requires(postun): desktop-file-utils -@@ -152,6 +160,10 @@ OPTIONS="$OPTIONS --enable-python-library" - OPTIONS="$OPTIONS --disable-python-library" - %endif - -+%if %{build_libgnomekbd} -+OPTIONS="$OPTIONS --enable-libgnomekbd" -+%endif -+ - %configure $OPTIONS - - # make -C po update-gmo -diff --git a/src/Makefile.am b/src/Makefile.am -index 404e1d2..f00fab7 100644 ---- a/src/Makefile.am -+++ b/src/Makefile.am -@@ -202,6 +202,9 @@ typelibs_DATA = $(INTROSPECTION_GIRS:.gir=.typelib) - CLEANFILES += $(dist_gir_DATA) $(typelibs_DATA) - endif - -+ibus_sources += ibusxkbxml.c -+ibus_headers += ibusxkbxml.h -+ - # gen enum types - ibusenumtypes.h: $(ibus_headers) ibusenumtypes.h.template - $(AM_V_GEN) ( top_builddir=`cd $(top_builddir) && pwd`; \ -diff --git a/src/ibus.h b/src/ibus.h -index d8e226e..f0a9456 100644 ---- a/src/ibus.h -+++ b/src/ibus.h -@@ -47,6 +47,7 @@ - #include - #include - #include -+#include - #include - #include - #include -diff --git a/src/ibusxkbxml.c b/src/ibusxkbxml.c -new file mode 100644 -index 0000000..f815e5d ---- /dev/null -+++ b/src/ibusxkbxml.c -@@ -0,0 +1,466 @@ -+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ -+/* vim:set et sts=4: */ -+/* bus - The Input Bus -+ * Copyright (C) 2013 Takao Fujiwara -+ * Copyright (C) 2013 Peng Huang -+ * Copyright (C) 2013 Red Hat, Inc. -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the -+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330, -+ * Boston, MA 02111-1307, USA. -+ */ -+#ifdef HAVE_CONFIG_H -+#include -+#endif -+ -+#include -+ -+#include "ibus.h" -+#include "ibusxkbxml.h" -+ -+#ifndef XKB_RULES_XML_FILE -+#define XKB_RULES_XML_FILE "/usr/share/X11/xkb/rules/evdev.xml" -+#endif -+ -+#define IBUS_XKB_CONFIG_REGISTRY_GET_PRIVATE(o) \ -+ (G_TYPE_INSTANCE_GET_PRIVATE ((o), IBUS_TYPE_XKB_CONFIG_REGISTRY, IBusXKBConfigRegistryPrivate)) -+ -+typedef struct _IBusXKBConfigRegistryPrivate IBusXKBConfigRegistryPrivate; -+ -+struct _IBusXKBConfigRegistryPrivate { -+ GHashTable *layout_list; -+ GHashTable *layout_lang; -+ GHashTable *layout_desc; -+ GHashTable *variant_desc; -+}; -+ -+ -+/* functions prototype */ -+static void ibus_xkb_config_registry_destroy -+ (IBusXKBConfigRegistry *xkb_config); -+ -+G_DEFINE_TYPE (IBusXKBConfigRegistry, ibus_xkb_config_registry, IBUS_TYPE_OBJECT) -+ -+static void -+parse_xkb_xml_languagelist_node (IBusXKBConfigRegistryPrivate *priv, -+ XMLNode *parent_node, -+ const gchar *layout_name) -+{ -+ XMLNode *node = parent_node; -+ XMLNode *sub_node; -+ GList *p; -+ GList *lang_list = NULL; -+ -+ g_assert (node != NULL); -+ g_assert (layout_name != NULL); -+ for (p = node->sub_nodes; p; p = p->next) { -+ sub_node = (XMLNode *) p->data; -+ if (g_strcmp0 (sub_node->name, "iso639Id") == 0) { -+ lang_list = g_list_append (lang_list, -+ (gpointer) g_strdup (sub_node->text)); -+ continue; -+ } -+ } -+ if (lang_list == NULL) { -+ /* some nodes have no lang */ -+ return; -+ } -+ if (g_hash_table_lookup (priv->layout_lang, layout_name) != NULL) { -+ g_warning ("duplicated name %s exists", layout_name); -+ return; -+ } -+ g_hash_table_insert (priv->layout_lang, -+ (gpointer) g_strdup (layout_name), -+ (gpointer) lang_list); -+} -+ -+static const gchar * -+parse_xkb_xml_configitem_node (IBusXKBConfigRegistryPrivate *priv, -+ XMLNode *parent_node) -+{ -+ XMLNode *node = parent_node; -+ XMLNode *sub_node; -+ GList *p; -+ gchar *name = NULL; -+ gchar *description = NULL; -+ -+ g_assert (node != NULL); -+ for (p = node->sub_nodes; p; p = p->next) { -+ sub_node = (XMLNode *) p->data; -+ if (g_strcmp0 (sub_node->name, "name") == 0) { -+ name = sub_node->text; -+ continue; -+ } -+ if (g_strcmp0 (sub_node->name, "description") == 0) { -+ description = sub_node->text; -+ continue; -+ } -+ if (g_strcmp0 (sub_node->name, "languageList") == 0) { -+ if (name == NULL) { -+ g_warning ("layout name is NULL in node %s", node->name); -+ continue; -+ } -+ parse_xkb_xml_languagelist_node (priv, sub_node, name); -+ continue; -+ } -+ } -+ if (name == NULL) { -+ g_warning ("No name in layout node"); -+ return NULL; -+ } -+ if (g_hash_table_lookup (priv->layout_desc, name) != NULL) { -+ g_warning ("duplicated name %s exists", name); -+ return name; -+ } -+ g_hash_table_insert (priv->layout_desc, -+ (gpointer) g_strdup (name), -+ (gpointer) g_strdup (description)); -+ -+ return name; -+} -+ -+static const gchar * -+parse_xkb_xml_variant_configitem_node (IBusXKBConfigRegistryPrivate *priv, -+ XMLNode *parent_node, -+ const gchar *layout_name) -+{ -+ XMLNode *node = parent_node; -+ XMLNode *sub_node; -+ GList *p; -+ gchar *name = NULL; -+ gchar *description = NULL; -+ gchar *variant_lang_name = NULL; -+ -+ g_assert (node != NULL); -+ g_assert (layout_name != NULL); -+ for (p = node->sub_nodes; p; p = p->next) { -+ sub_node = (XMLNode *) p->data; -+ if (g_strcmp0 (sub_node->name, "name") == 0) { -+ name = sub_node->text; -+ continue; -+ } -+ if (g_strcmp0 (sub_node->name, "description") == 0) { -+ description = sub_node->text; -+ continue; -+ } -+ if (g_strcmp0 (sub_node->name, "languageList") == 0) { -+ if (name == NULL) { -+ g_warning ("layout name is NULL in node %s", node->name); -+ continue; -+ } -+ variant_lang_name = g_strdup_printf ("%s(%s)", layout_name, name); -+ parse_xkb_xml_languagelist_node (priv, sub_node, variant_lang_name); -+ g_free (variant_lang_name); -+ continue; -+ } -+ } -+ if (name == NULL) { -+ g_warning ("No name in layout node"); -+ return NULL; -+ } -+ if (g_hash_table_lookup (priv->variant_desc, name) != NULL) { -+ /* This is an expected case. */ -+ return name; -+ } -+ variant_lang_name = g_strdup_printf ("%s(%s)", layout_name, name); -+ g_hash_table_insert (priv->variant_desc, -+ (gpointer) variant_lang_name, -+ (gpointer) g_strdup (description)); -+ return name; -+} -+ -+static const gchar * -+parse_xkb_xml_variant_node (IBusXKBConfigRegistryPrivate *priv, -+ XMLNode *parent_node, -+ const gchar *layout_name) -+{ -+ XMLNode *node = parent_node; -+ XMLNode *sub_node; -+ GList *p; -+ const gchar *variant_name = NULL; -+ -+ g_assert (node != NULL); -+ g_assert (layout_name != NULL); -+ for (p = node->sub_nodes; p; p = p->next) { -+ sub_node = (XMLNode *) p->data; -+ if (g_strcmp0 (sub_node->name, "configItem") == 0) { -+ variant_name = parse_xkb_xml_variant_configitem_node (priv, sub_node, layout_name); -+ continue; -+ } -+ } -+ return variant_name; -+} -+ -+static GList * -+parse_xkb_xml_variantlist_node (IBusXKBConfigRegistryPrivate *priv, -+ XMLNode *parent_node, -+ const gchar *layout_name, -+ GList *variant_list) -+{ -+ XMLNode *node = parent_node; -+ XMLNode *sub_node; -+ GList *p; -+ const gchar *variant_name = NULL; -+ -+ g_assert (node != NULL); -+ g_assert (layout_name != NULL); -+ for (p = node->sub_nodes; p; p = p->next) { -+ sub_node = (XMLNode *) p->data; -+ if (g_strcmp0 (sub_node->name, "variant") == 0) { -+ variant_name = parse_xkb_xml_variant_node (priv, sub_node, layout_name); -+ if (variant_name != NULL) { -+ variant_list = g_list_append (variant_list, -+ (gpointer) g_strdup (variant_name)); -+ } -+ continue; -+ } -+ } -+ return variant_list; -+} -+ -+static void -+parse_xkb_xml_layout_node (IBusXKBConfigRegistryPrivate *priv, -+ XMLNode *parent_node) -+{ -+ XMLNode *node = parent_node; -+ XMLNode *sub_node; -+ GList *p; -+ const gchar *name = NULL; -+ GList *variant_list = NULL; -+ -+ g_assert (node != NULL); -+ for (p = node->sub_nodes; p; p = p->next) { -+ sub_node = (XMLNode *) p->data; -+ if (g_strcmp0 (sub_node->name, "configItem") == 0) { -+ name = parse_xkb_xml_configitem_node (priv, sub_node); -+ continue; -+ } -+ if (g_strcmp0 (sub_node->name, "variantList") == 0) { -+ if (name == NULL) { -+ g_warning ("layout name is NULL in node %s", node->name); -+ continue; -+ } -+ variant_list = parse_xkb_xml_variantlist_node (priv, sub_node, -+ name, -+ variant_list); -+ continue; -+ } -+ } -+ if (g_hash_table_lookup (priv->layout_list, name) != NULL) { -+ g_warning ("duplicated name %s exists", name); -+ return; -+ } -+ g_hash_table_insert (priv->layout_list, -+ (gpointer) g_strdup (name), -+ (gpointer) variant_list); -+} -+ -+static void -+parse_xkb_xml_top_node (IBusXKBConfigRegistryPrivate *priv, -+ XMLNode *parent_node) -+{ -+ XMLNode *node = parent_node; -+ XMLNode *sub_node; -+ GList *p; -+ -+ g_assert (priv != NULL); -+ g_assert (node != NULL); -+ -+ if (g_strcmp0 (node->name, "xkbConfigRegistry") != 0) { -+ g_warning ("node has no xkbConfigRegistry name"); -+ return; -+ } -+ for (p = node->sub_nodes; p; p = p->next) { -+ sub_node = (XMLNode *) p->data; -+ if (g_strcmp0 (sub_node->name, "layoutList") == 0) { -+ break; -+ } -+ } -+ if (p == NULL) { -+ g_warning ("xkbConfigRegistry node has no layoutList node"); -+ return; -+ } -+ node = sub_node; -+ for (p = node->sub_nodes; p; p = p->next) { -+ sub_node = (XMLNode *) p->data; -+ if (g_strcmp0 (sub_node->name, "layout") == 0) { -+ parse_xkb_xml_layout_node (priv, sub_node); -+ continue; -+ } -+ } -+} -+ -+static void -+free_lang_list (GList *list) -+{ -+ GList *l = list; -+ while (l) { -+ g_free (l->data); -+ l->data = NULL; -+ l = l->next; -+ } -+ g_list_free (list); -+} -+ -+static void -+parse_xkb_config_registry_file (IBusXKBConfigRegistryPrivate *priv, -+ const gchar *file) -+{ -+ XMLNode *node; -+ -+ g_assert (file != NULL); -+ -+ priv->layout_list = g_hash_table_new_full (g_str_hash, -+ (GEqualFunc) g_str_equal, -+ (GDestroyNotify) g_free, -+ (GDestroyNotify) free_lang_list); -+ priv->layout_desc = g_hash_table_new_full (g_str_hash, -+ (GEqualFunc) g_str_equal, -+ (GDestroyNotify) g_free, -+ (GDestroyNotify) g_free); -+ priv->layout_lang = g_hash_table_new_full (g_str_hash, -+ (GEqualFunc) g_str_equal, -+ (GDestroyNotify) g_free, -+ (GDestroyNotify) free_lang_list); -+ priv->variant_desc = g_hash_table_new_full (g_str_hash, -+ (GEqualFunc) g_str_equal, -+ (GDestroyNotify) g_free, -+ (GDestroyNotify) g_free); -+ node = ibus_xml_parse_file (file); -+ parse_xkb_xml_top_node (priv, node); -+ ibus_xml_free (node); -+} -+ -+static void -+ibus_xkb_config_registry_init (IBusXKBConfigRegistry *xkb_config) -+{ -+ IBusXKBConfigRegistryPrivate *priv; -+ const gchar *file = XKB_RULES_XML_FILE; -+ -+ priv = IBUS_XKB_CONFIG_REGISTRY_GET_PRIVATE (xkb_config); -+ parse_xkb_config_registry_file (priv, file); -+} -+ -+static void -+ibus_xkb_config_registry_destroy (IBusXKBConfigRegistry *xkb_config) -+{ -+ IBusXKBConfigRegistryPrivate *priv; -+ -+ g_return_if_fail (xkb_config != NULL); -+ -+ priv = IBUS_XKB_CONFIG_REGISTRY_GET_PRIVATE (xkb_config); -+ -+ g_hash_table_destroy (priv->layout_list); -+ priv->layout_list = NULL; -+ g_hash_table_destroy (priv->layout_lang); -+ priv->layout_lang= NULL; -+ g_hash_table_destroy (priv->layout_desc); -+ priv->layout_desc= NULL; -+ g_hash_table_destroy (priv->variant_desc); -+ priv->variant_desc = NULL; -+ -+ IBUS_OBJECT_CLASS(ibus_xkb_config_registry_parent_class)->destroy (IBUS_OBJECT (xkb_config)); -+} -+ -+static void -+ibus_xkb_config_registry_class_init (IBusXKBConfigRegistryClass *klass) -+{ -+ IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS (klass); -+ -+ g_type_class_add_private (klass, sizeof (IBusXKBConfigRegistryPrivate)); -+ -+ ibus_object_class->destroy = (IBusObjectDestroyFunc) ibus_xkb_config_registry_destroy; -+} -+ -+IBusXKBConfigRegistry * -+ibus_xkb_config_registry_new (void) -+{ -+ IBusXKBConfigRegistry *xkb_config; -+ -+ xkb_config = IBUS_XKB_CONFIG_REGISTRY (g_object_new (IBUS_TYPE_XKB_CONFIG_REGISTRY, NULL)); -+ return xkb_config; -+} -+ -+#define TABLE_FUNC(field_name) const GHashTable * \ -+ibus_xkb_config_registry_get_##field_name (IBusXKBConfigRegistry *xkb_config) \ -+{ \ -+ IBusXKBConfigRegistryPrivate *priv; \ -+ \ -+ g_return_val_if_fail (xkb_config != NULL, NULL); \ -+ priv = IBUS_XKB_CONFIG_REGISTRY_GET_PRIVATE (xkb_config); \ -+ return priv->field_name; \ -+} -+ -+TABLE_FUNC (layout_list) -+TABLE_FUNC (layout_lang) -+TABLE_FUNC (layout_desc) -+TABLE_FUNC (variant_desc) -+ -+#undef TABLE_FUNC -+ -+GList * -+ibus_xkb_config_registry_layout_list_get_layouts (IBusXKBConfigRegistry *xkb_config) -+{ -+ GHashTable *table; -+ GList *list = NULL; -+ -+ table = (GHashTable *) -+ ibus_xkb_config_registry_get_layout_list (xkb_config); -+ list = (GList *) g_hash_table_get_keys (table); -+ return list; -+} -+ -+/* vala could use GLib.List for the returned pointer and -+ * the declaration calls g_list_foreach (retval, g_free, NULL). -+ * When I think about GLib.List v.s. GLib.List, probably -+ * I think GLib.List is better for the function and set -+ * g_strdup() here. I do not know about GJS implementation. -+ */ -+#define TABLE_LOOKUP_LIST_FUNC(field_name, value) GList * \ -+ibus_xkb_config_registry_##field_name##_get_##value (IBusXKBConfigRegistry *xkb_config, const gchar *key) \ -+{ \ -+ GHashTable *table; \ -+ GList *list = NULL; \ -+ GList *retval= NULL; \ -+ GList *p = NULL; \ -+ \ -+ table = (GHashTable *) \ -+ ibus_xkb_config_registry_get_##field_name (xkb_config); \ -+ list = (GList *) g_hash_table_lookup (table, key); \ -+ retval = g_list_copy (list); \ -+ for (p = retval; p; p = p->next) { \ -+ p->data = g_strdup (p->data); \ -+ } \ -+ return retval; \ -+} -+ -+#define TABLE_LOOKUP_STRING_FUNC(field_name, value) gchar * \ -+ibus_xkb_config_registry_##field_name##_get_##value (IBusXKBConfigRegistry *xkb_config, const gchar *key) \ -+{ \ -+ GHashTable *table; \ -+ const gchar *desc = NULL; \ -+ \ -+ table = (GHashTable *) \ -+ ibus_xkb_config_registry_get_##field_name (xkb_config); \ -+ desc = (const gchar *) g_hash_table_lookup (table, key); \ -+ return g_strdup (desc); \ -+} -+ -+TABLE_LOOKUP_LIST_FUNC (layout_list, variants) -+TABLE_LOOKUP_LIST_FUNC (layout_lang, langs) -+TABLE_LOOKUP_STRING_FUNC (layout_desc, desc) -+TABLE_LOOKUP_STRING_FUNC (variant_desc, desc) -+ -+#undef TABLE_LOOKUP_LIST_FUNC -+#undef TABLE_LOOKUP_STRING_FUNC -diff --git a/src/ibusxkbxml.h b/src/ibusxkbxml.h -new file mode 100644 -index 0000000..5aa486d ---- /dev/null -+++ b/src/ibusxkbxml.h -@@ -0,0 +1,187 @@ -+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */ -+/* vim:set et sts=4: */ -+/* bus - The Input Bus -+ * Copyright (C) 2013 Takao Fujiwara -+ * Copyright (C) 2013 Peng Huang -+ * Copyright (C) 2013 Red Hat, Inc. -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the -+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330, -+ * Boston, MA 02111-1307, USA. -+ */ -+#ifndef __IBUS_XKBXML_H_ -+#define __IBUS_XKBXML_H_ -+ -+#if !defined (__IBUS_H_INSIDE__) && !defined (IBUS_COMPILATION) -+#error "Only can be included directly" -+#endif -+ -+#include "ibus.h" -+ -+/* -+ * Type macros. -+ */ -+/* define IBusXKBConfigRegistry macros */ -+#define IBUS_TYPE_XKB_CONFIG_REGISTRY \ -+ (ibus_xkb_config_registry_get_type ()) -+#define IBUS_XKB_CONFIG_REGISTRY(obj) \ -+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), IBUS_TYPE_XKB_CONFIG_REGISTRY, IBusXKBConfigRegistry)) -+#define IBUS_XKB_CONFIG_REGISTRY_CLASS(klass) \ -+ (G_TYPE_CHECK_CLASS_CAST ((klass), IBUS_TYPE_XKB_CONFIG_REGISTRY, IBusXKBConfigRegistryClass)) -+#define IBUS_IS_XKB_CONFIG_REGISTRY(obj) \ -+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IBUS_TYPE_XKB_CONFIG_REGISTRY)) -+#define IBUS_IS_XKB_CONFIG_REGISTRY_CLASS(klass) \ -+ (G_TYPE_CHECK_CLASS_TYPE ((klass), IBUS_TYPE_XKB_CONFIG_REGISTRY)) -+#define IBUS_XKB_CONFIG_REGISTRY_GET_CLASS(obj) \ -+ (G_TYPE_INSTANCE_GET_CLASS ((obj), IBUS_TYPE_XKB_CONFIG_REGISTRY, IBusXKBConfigRegistryClass)) -+ -+G_BEGIN_DECLS -+ -+typedef struct _IBusXKBConfigRegistry IBusXKBConfigRegistry; -+typedef struct _IBusXKBConfigRegistryClass IBusXKBConfigRegistryClass; -+ -+struct _IBusXKBConfigRegistry { -+ IBusObject parent; -+}; -+ -+struct _IBusXKBConfigRegistryClass { -+ IBusObjectClass parent; -+ /* signals */ -+ /*< private >*/ -+ /* padding */ -+ gpointer pdummy[8]; -+}; -+ -+ -+GType ibus_xkb_config_registry_get_type -+ (void); -+ -+/** -+ * ibus_xkb_config_registry_new: -+ * @returns: A newly allocated IBusXKBConfigRegistry -+ * -+ * New an IBusXKBConfigRegistry. -+ */ -+IBusXKBConfigRegistry * -+ ibus_xkb_config_registry_new -+ (void); -+ -+/** -+ * ibus_xkb_config_registry_get_layout_list: (skip) -+ * @xkb_config: An IBusXKBConfigRegistry. -+ * @returns: A const GHashTable -+ * -+ * a const GHashTable -+ */ -+const GHashTable * -+ ibus_xkb_config_registry_get_layout_list -+ (IBusXKBConfigRegistry *xkb_config); -+ -+/** -+ * ibus_xkb_config_registry_get_layout_lang: (skip) -+ * @xkb_config: An IBusXKBConfigRegistry. -+ * @returns: A const GHashTable -+ * -+ * a const GHashTable -+ */ -+const GHashTable * -+ ibus_xkb_config_registry_get_layout_lang -+ (IBusXKBConfigRegistry *xkb_config); -+ -+/** -+ * ibus_xkb_config_registry_get_layout_desc: (skip) -+ * @xkb_config: An IBusXKBConfigRegistry. -+ * @returns: A const GHashTable -+ * -+ * a const GHashTable -+ */ -+const GHashTable * -+ ibus_xkb_config_registry_get_layout_desc -+ (IBusXKBConfigRegistry *xkb_config); -+ -+/** -+ * ibus_xkb_config_registry_get_variant_desc: (skip) -+ * @xkb_config: An IBusXKBConfigRegistry. -+ * @returns: A const GHashTable -+ * -+ * a const GHashTable -+ */ -+const GHashTable * -+ ibus_xkb_config_registry_get_variant_desc -+ (IBusXKBConfigRegistry *xkb_config); -+ -+/** -+ * ibus_xkb_config_registry_layout_list_get_layouts: -+ * @xkb_config: An IBusXKBConfigRegistry. -+ * @returns: (transfer container) (element-type utf8): A GList of layouts -+ * -+ * a GList of layouts -+ */ -+GList * -+ ibus_xkb_config_registry_layout_list_get_layouts -+ (IBusXKBConfigRegistry *xkb_config); -+ -+/** -+ * ibus_xkb_config_registry_layout_list_get_variants: -+ * @xkb_config: An IBusXKBConfigRegistry. -+ * @layout: A layout. -+ * @returns: (transfer container) (element-type utf8): A GList -+ * -+ * a GList -+ */ -+GList * -+ ibus_xkb_config_registry_layout_list_get_variants -+ (IBusXKBConfigRegistry *xkb_config, -+ const gchar *layout); -+ -+/** -+ * ibus_xkb_config_registry_layout_lang_get_langs: -+ * @xkb_config: An IBusXKBConfigRegistry. -+ * @layout: A layout. -+ * @returns: (transfer container) (element-type utf8): A GList -+ * -+ * a GList -+ */ -+GList * -+ ibus_xkb_config_registry_layout_lang_get_langs -+ (IBusXKBConfigRegistry *xkb_config, -+ const gchar *layout); -+ -+/** -+ * ibus_xkb_config_registry_layout_desc_get_desc: -+ * @xkb_config: An IBusXKBConfigRegistry. -+ * @layout: A layout. -+ * @returns: A layout description -+ * -+ * a layout description -+ */ -+gchar * -+ ibus_xkb_config_registry_layout_desc_get_desc -+ (IBusXKBConfigRegistry *xkb_config, -+ const gchar *layout); -+ -+/** -+ * ibus_xkb_config_registry_variant_desc_get_desc: -+ * @xkb_config: An IBusXKBConfigRegistry. -+ * @variant: A variant. -+ * @returns: A variant description -+ * -+ * a variant description -+ */ -+gchar * -+ ibus_xkb_config_registry_variant_desc_get_desc -+ (IBusXKBConfigRegistry *xkb_config, -+ const gchar *variant); -+G_END_DECLS -+#endif -diff --git a/ui/gtk3/Makefile.am b/ui/gtk3/Makefile.am -index b2fb800..f148202 100644 ---- a/ui/gtk3/Makefile.am -+++ b/ui/gtk3/Makefile.am -@@ -35,6 +35,8 @@ gtkpanel.xml: gtkpanel.xml.in - -e 's|@libexecdir[@]|$(libexecdir)|g' $< > $@.tmp && \ - mv $@.tmp $@ - -+HAVE_IBUS_GKBD_C = $(strip $(subst false, FALSE, $(subst true, TRUE, $(HAVE_IBUS_GKBD)))) -+ - # force include config.h before gi18n.h. - AM_CPPFLAGS = \ - -I$(top_srcdir)/src \ -@@ -51,6 +53,8 @@ AM_CFLAGS = \ - -DG_LOG_DOMAIN=\"IBUS\" \ - -DBINDIR=\"$(bindir)\" \ - -DIBUS_DISABLE_DEPRECATED \ -+ -DHAVE_IBUS_GKBD=$(HAVE_IBUS_GKBD_C) \ -+ -DXKB_LAYOUTS_MAX_LENGTH=4 \ - -Wno-unused-variable \ - -Wno-unused-but-set-variable \ - -Wno-unused-function \ -@@ -94,12 +98,40 @@ AM_VALAFLAGS += \ - $(NULL) - endif - -+if ENABLE_LIBGNOMEKBD -+AM_CFLAGS += \ -+ @LIBGNOMEKBDUI_CFLAGS@ \ -+ @ATK_CFLAGS@ \ -+ $(NULL) -+ -+AM_LDADD += \ -+ @LIBGNOMEKBDUI_LIBS@ \ -+ @ATK_LIBS@ \ -+ $(NULL) -+ -+AM_VALAFLAGS += \ -+ --vapidir=. \ -+ --metadatadir=$(top_srcdir)/bindings/vala \ -+ --pkg=glib-2.0 \ -+ --pkg=gmodule-2.0 \ -+ --pkg=gkbd \ -+ --pkg=Xkl-1.0 \ -+ $(NULL) -+ -+$(srcdir)/gkbdlayout.vala: $(top_builddir)/bindings/vala/gkbd.vapi -+ @cp $(srcdir)/gkbdlayout.vala.true $(srcdir)/gkbdlayout.vala -+else -+$(srcdir)/gkbdlayout.vala: -+ @cp $(srcdir)/gkbdlayout.vala.false $(srcdir)/gkbdlayout.vala -+endif -+ - libexec_PROGRAMS = ibus-ui-gtk3 - - ibus_ui_gtk3_SOURCES = \ - application.vala \ - candidatearea.vala \ - candidatepanel.vala \ -+ gkbdlayout.vala \ - handle.vala \ - iconwidget.vala \ - keybindingmanager.vala \ -@@ -109,6 +141,7 @@ ibus_ui_gtk3_SOURCES = \ - propertypanel.vala \ - separator.vala \ - switcher.vala \ -+ xkblayout.vala \ - $(NULL) - - ibus_ui_gtk3_LDADD = \ -@@ -117,9 +150,12 @@ ibus_ui_gtk3_LDADD = \ - - CLEANFILES = \ - gtkpanel.xml \ -+ gkbdlayout.vala \ - $(NULL) - - EXTRA_DIST = \ -+ gkbdlayout.vala.false \ -+ gkbdlayout.vala.true \ - gtkpanel.xml.in \ - $(NULL) - -diff --git a/ui/gtk3/gkbdlayout.vala.false b/ui/gtk3/gkbdlayout.vala.false -new file mode 100644 -index 0000000..506aff2 ---- /dev/null -+++ b/ui/gtk3/gkbdlayout.vala.false -@@ -0,0 +1,63 @@ -+/* vim:set et sts=4 sw=4: -+ * -+ * ibus - The Input Bus -+ * -+ * Copyright(c) 2013 Red Hat, Inc. -+ * Copyright(c) 2013 Peng Huang -+ * Copyright(c) 2013 Takao Fujiwara -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2 of the License, or(at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this program; if not, write to the -+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330, -+ * Boston, MA 02111-1307 USA -+ */ -+ -+public class GkbdLayout -+{ -+ public signal void changed(); -+ public signal void group_changed (int object); -+ -+ public GkbdLayout() { -+ } -+ -+ public string[] get_layouts() { -+ return new string[0]; -+ } -+ -+ public string[] get_group_names() { -+ return new string[0]; -+ } -+ -+ public void lock_group(int id) { -+ } -+ -+ public void start_listen() { -+ } -+ -+ public void stop_listen() { -+ } -+ -+ /* -+ public static int main(string[] args) { -+ GkbdLayout ibus_layouts = new GkbdLayout(); -+ -+ string[] layouts = ibus_layouts.get_layouts(); -+ string[] names = ibus_layouts.get_group_names(); -+ for (int i = 0; layouts != null && i < layouts.length; i++) { -+ stdout.printf("%s %s\n", layouts[i], names[i]); -+ } -+ -+ return 0; -+ } -+ */ -+} -diff --git a/ui/gtk3/gkbdlayout.vala.true b/ui/gtk3/gkbdlayout.vala.true -new file mode 100644 -index 0000000..a6e0f8d ---- /dev/null -+++ b/ui/gtk3/gkbdlayout.vala.true -@@ -0,0 +1,108 @@ -+/* vim:set et sts=4 sw=4: -+ * -+ * ibus - The Input Bus -+ * -+ * Copyright(c) 2013 Red Hat, Inc. -+ * Copyright(c) 2013 Peng Huang -+ * Copyright(c) 2013 Takao Fujiwara -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2 of the License, or(at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this program; if not, write to the -+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330, -+ * Boston, MA 02111-1307 USA -+ */ -+ -+public class GkbdLayout -+{ -+ public signal void changed(); -+ public signal void group_changed (int object); -+ -+ private Gkbd.Configuration m_config = null; -+ -+ public GkbdLayout() { -+ m_config = Gkbd.Configuration.get(); -+ if (m_config != null) { -+ m_config.changed.connect(config_changed_cb); -+ m_config.group_changed.connect(config_group_changed_cb); -+ } -+ } -+ -+ ~GkbdLayout() { -+ if (m_config != null) { -+ m_config.changed.disconnect(config_changed_cb); -+ m_config.group_changed.disconnect(config_group_changed_cb); -+ /* gkbd_configuration_get reuses the object and do not -+ * destroy m_config here. */ -+ m_config.ref(); -+ m_config = null; -+ } -+ } -+ -+ private void config_changed_cb() { -+ changed(); -+ } -+ -+ private void config_group_changed_cb(int object) { -+ group_changed(object); -+ } -+ -+ public string[] get_layouts() { -+ if (m_config == null) { -+ return new string[0]; -+ } -+ return m_config.get_short_group_names(); -+ } -+ -+ public string[] get_group_names() { -+ if (m_config == null) { -+ return new string[0]; -+ } -+ return m_config.get_group_names(); -+ } -+ -+ public void lock_group(int id) { -+ if (m_config == null) { -+ return; -+ } -+ m_config.lock_group(id); -+ } -+ -+ public void start_listen() { -+ if (m_config == null) { -+ return; -+ } -+ m_config.start_listen(); -+ } -+ -+ public void stop_listen() { -+ if (m_config == null) { -+ return; -+ } -+ m_config.stop_listen(); -+ } -+ -+ /* -+ public static int main(string[] args) { -+ Gtk.init(ref args); -+ GkbdLayout ibus_layouts = new GkbdLayout(); -+ -+ string[] layouts = ibus_layouts.get_layouts(); -+ string[] names = ibus_layouts.get_group_names(); -+ for (int i = 0; layouts != null && i < layouts.length; i++) { -+ stdout.printf("%s %s\n", layouts[i], names[i]); -+ } -+ -+ return 0; -+ } -+ */ -+} -diff --git a/ui/gtk3/panel.vala b/ui/gtk3/panel.vala -index 748cb32..2323ac4 100644 ---- a/ui/gtk3/panel.vala -+++ b/ui/gtk3/panel.vala -@@ -63,6 +63,13 @@ class Panel : IBus.PanelService { - GLib.str_equal); - private Gdk.RGBA m_xkb_icon_rgba = Gdk.RGBA(){ - red = 0.0, green = 0.0, blue = 0.0, alpha = 1.0 }; -+ private GkbdLayout m_gkbdlayout = null; -+ private XKBLayout m_xkblayout = null; -+ private string[] m_layouts = {}; -+ private string[] m_variants = {}; -+ private int m_fallback_lock_id = -1; -+ private bool m_changed_xkb_option = false; -+ private GLib.Timer m_changed_layout_timer; - - private GLib.List m_keybindings = new GLib.List(); - -@@ -113,6 +120,14 @@ class Panel : IBus.PanelService { - - ~Panel() { - unbind_switch_shortcut(); -+ -+ if (HAVE_IBUS_GKBD && m_gkbdlayout != null) { -+ m_gkbdlayout.changed.disconnect(gkbdlayout_changed_cb); -+ m_gkbdlayout.stop_listen(); -+ m_gkbdlayout = null; -+ } -+ -+ m_xkblayout = null; - } - - private void init_settings() { -@@ -487,6 +502,7 @@ class Panel : IBus.PanelService { - } - - public void load_settings() { -+ init_engines_order(); - // Update m_use_system_keyboard_layout before update_engines() - // is called. - set_use_system_keyboard_layout(); -@@ -508,6 +524,184 @@ class Panel : IBus.PanelService { - set_version(); - } - -+ private void gkbdlayout_changed_cb() { -+ /* The callback is called four times after set_layout is called -+ * so check the elapsed and take the first signal only. */ -+ double elapsed = m_changed_layout_timer.elapsed(); -+ if (elapsed < 1.0 && elapsed > 0.0) { -+ return; -+ } -+ -+ if (m_fallback_lock_id != -1) { -+ /* Call lock_group only when set_layout is called. */ -+ m_gkbdlayout.lock_group(m_fallback_lock_id); -+ m_fallback_lock_id = -1; -+ } else { -+ /* Reset default layout when gnome-control-center is called. */ -+ m_xkblayout.reset_layout(); -+ } -+ -+ update_xkb_engines(); -+ m_changed_layout_timer.reset(); -+ } -+ -+ private void init_gkbd() { -+ m_gkbdlayout = new GkbdLayout(); -+ m_gkbdlayout.changed.connect(gkbdlayout_changed_cb); -+ -+ /* Probably we cannot support both keyboard and ibus indicators -+ * How can I get the engine from keymap of group_id? -+ * e.g. 'en' could be owned by xkb:en and pinyin engines. */ -+ //m_gkbdlayout.group_changed.connect((object) => {}); -+ -+ m_changed_layout_timer = new GLib.Timer(); -+ m_changed_layout_timer.start(); -+ m_gkbdlayout.start_listen(); -+ } -+ -+ private void init_engines_order() { -+ m_xkblayout = new XKBLayout(); -+ string session = Environment.get_variable("DESKTOP_SESSION"); -+ -+ if (HAVE_IBUS_GKBD && -+ session != null && session.length >= 5 && -+ session[0:5] == "gnome") { -+ init_gkbd(); -+ } -+ -+ update_xkb_engines(); -+ } -+ -+ private void update_xkb_engines() { -+ string var_layout = m_xkblayout.get_layout(); -+ string var_variant = m_xkblayout.get_variant(); -+ if (var_layout == "") { -+ return; -+ } -+ -+ m_layouts = var_layout.split(","); -+ m_variants = var_variant.split(","); -+ -+ IBus.XKBConfigRegistry registry = new IBus.XKBConfigRegistry(); -+ string[] var_xkb_engine_names = {}; -+ for (int i = 0; i < m_layouts.length; i++) { -+ string name = m_layouts[i]; -+ string lang = null; -+ -+ if (i < m_variants.length && m_variants[i] != "") { -+ name = "%s:%s".printf(name, m_variants[i]); -+ string layout = "%s(%s)".printf(name, m_variants[i]); -+ GLib.List langs = -+ registry.layout_lang_get_langs(layout); -+ if (langs.length() != 0) { -+ lang = langs.data; -+ } -+ } else { -+ name = "%s:".printf(name); -+ } -+ -+ if (lang == null) { -+ GLib.List langs = -+ registry.layout_lang_get_langs(m_layouts[i]); -+ if (langs.length() != 0) { -+ lang = langs.data; -+ } -+ } -+ -+ var_xkb_engine_names += "%s:%s:%s".printf("xkb", name, lang); -+ } -+ -+ string[] engine_names = -+ m_settings_general.get_strv("preload-engines"); -+ bool updated_engine_names = false; -+ -+ foreach (string name in var_xkb_engine_names) { -+ if (name in engine_names) -+ continue; -+ updated_engine_names = true; -+ engine_names += name; -+ } -+ -+ if (updated_engine_names) -+ m_settings_general.set_strv("preload-engines", engine_names); -+ -+ string[] order_names = -+ m_settings_general.get_strv("engines-order"); -+ bool updated_order_names = false; -+ -+ foreach (var name in var_xkb_engine_names) { -+ if (name in order_names) -+ continue; -+ order_names += name; -+ updated_order_names = true; -+ } -+ -+ if (updated_order_names) -+ m_settings_general.set_strv("engines-order", order_names); -+ } -+ -+ private void set_xkb_group_layout(IBus.EngineDesc engine) { -+ int[] retval = m_xkblayout.set_layout(engine, true); -+ if (retval[0] >= 0) { -+ /* If an XKB keymap is added into the XKB group, -+ * this._gkbdlayout.lock_group will be called after -+ * 'group-changed' signal is received. */ -+ m_fallback_lock_id = retval[0]; -+ m_changed_xkb_option = (retval[1] != 0) ? true : false; -+ } -+ } -+ -+ private bool set_gkbd_layout(IBus.EngineDesc engine) { -+ string layout = engine.get_layout(); -+ string variant = engine.get_layout_variant(); -+ -+ /* If a previous ibus engine changed XKB options, need to set the -+ * default XKB option. */ -+ if (m_changed_xkb_option == true) { -+ m_changed_xkb_option = false; -+ return false; -+ } -+ -+ if (variant != "" && variant != "default") { -+ layout = "%s(%s)".printf(layout, variant); -+ } -+ -+ int gkbd_len = m_gkbdlayout.get_group_names().length; -+ for (int i = 0; i < m_layouts.length && i < gkbd_len; i++) { -+ string sys_layout = m_layouts[i]; -+ if (i < m_variants.length && m_variants[i] != "") { -+ sys_layout = "%s(%s)".printf(sys_layout, m_variants[i]); -+ } -+ if (sys_layout == layout) { -+ m_gkbdlayout.lock_group(i); -+ return true; -+ } -+ } -+ return false; -+ } -+ -+ private void set_layout(IBus.EngineDesc engine) { -+ string layout = engine.get_layout(); -+ -+ if (layout == "" || layout == null) { -+ return; -+ } -+ -+ if (m_xkblayout == null) { -+ init_engines_order(); -+ } -+ -+ if (HAVE_IBUS_GKBD && m_gkbdlayout != null) { -+ if (set_gkbd_layout(engine)) { -+ return; -+ } -+ set_xkb_group_layout(engine); -+ return; -+ } -+ -+ m_xkblayout.set_layout(engine); -+ } -+ - private void exec_setxkbmap(IBus.EngineDesc engine) { - string layout = engine.get_layout(); - string variant = engine.get_layout_variant(); -@@ -573,7 +767,7 @@ class Panel : IBus.PanelService { - - // set xkb layout - if (!m_use_system_keyboard_layout) -- exec_setxkbmap(engine); -+ set_layout(engine); - - engine_contexts_insert(engine); - } -diff --git a/ui/gtk3/xkblayout.vala b/ui/gtk3/xkblayout.vala -new file mode 100644 -index 0000000..b7dfb3e ---- /dev/null -+++ b/ui/gtk3/xkblayout.vala -@@ -0,0 +1,429 @@ -+/* vim:set et sts=4 sw=4: -+ * -+ * ibus - The Input Bus -+ * -+ * Copyright(c) 2013 Red Hat, Inc. -+ * Copyright(c) 2013 Peng Huang -+ * Copyright(c) 2013 Takao Fujiwara -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2 of the License, or(at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this program; if not, write to the -+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330, -+ * Boston, MA 02111-1307 USA -+ */ -+ -+public extern const bool HAVE_IBUS_GKBD; -+public extern const int XKB_LAYOUTS_MAX_LENGTH; -+ -+class XKBLayout -+{ -+ string m_xkb_command = "setxkbmap"; -+ GLib.Settings m_settings_general; -+ string[] m_xkb_latin_layouts = {}; -+ GLib.Pid m_xkb_pid = -1; -+ GLib.Pid m_xmodmap_pid = -1; -+ string m_xmodmap_command = "xmodmap"; -+ bool m_use_xmodmap = true; -+ string[] m_xmodmap_known_files = {".xmodmap", ".xmodmaprc", -+ ".Xmodmap", ".Xmodmaprc"}; -+ string m_default_layout = ""; -+ string m_default_variant = ""; -+ string m_default_option = ""; -+ -+ public XKBLayout() { -+ m_settings_general = new GLib.Settings("org.freedesktop.ibus.general"); -+ -+ var value = m_settings_general.get_value("xkb-latin-layouts"); -+ for (int i = 0; value != null && i < value.n_children(); i++) { -+ m_xkb_latin_layouts += -+ value.get_child_value(i).dup_string(); -+ } -+ if (m_use_xmodmap) { -+ m_use_xmodmap = m_settings_general.get_boolean("use-xmodmap"); -+ } -+ } -+ -+ private string get_output_from_cmdline(string arg, string element) { -+ string[] exec_command = {}; -+ exec_command += m_xkb_command; -+ exec_command += arg; -+ string standard_output = null; -+ string standard_error = null; -+ int exit_status = 0; -+ string retval = ""; -+ try { -+ GLib.Process.spawn_sync(null, -+ exec_command, -+ null, -+ GLib.SpawnFlags.SEARCH_PATH, -+ null, -+ out standard_output, -+ out standard_error, -+ out exit_status); -+ } catch (GLib.SpawnError err) { -+ stderr.printf("IBUS_ERROR: %s\n", err.message); -+ } -+ if (exit_status != 0) { -+ stderr.printf("IBUS_ERROR: %s\n", standard_error ?? ""); -+ } -+ if (standard_output == null) { -+ return ""; -+ } -+ foreach (string line in standard_output.split("\n")) { -+ if (element.length <= line.length && -+ line[0:element.length] == element) { -+ retval = line[element.length:line.length]; -+ if (retval == null) { -+ retval = ""; -+ } else { -+ retval = retval.strip(); -+ } -+ } -+ } -+ return retval; -+ } -+ -+ private void set_layout_cb(GLib.Pid pid, int status) { -+ if (m_xkb_pid != pid) { -+ stderr.printf("IBUS_ERROR: set_layout_cb has another pid\n"); -+ return; -+ } -+ GLib.Process.close_pid(m_xkb_pid); -+ m_xkb_pid = -1; -+ set_xmodmap(); -+ } -+ -+ private void set_xmodmap_cb(GLib.Pid pid, int status) { -+ if (m_xmodmap_pid != pid) { -+ stderr.printf("IBUS_ERROR: set_xmodmap_cb has another pid\n"); -+ return; -+ } -+ GLib.Process.close_pid(m_xmodmap_pid); -+ m_xmodmap_pid = -1; -+ } -+ -+ private string get_fullpath(string command) { -+ string envpath = GLib.Environment.get_variable("PATH"); -+ foreach (string dir in envpath.split(":")) { -+ string filepath = GLib.Path.build_filename(dir, command); -+ if (GLib.FileUtils.test(filepath, GLib.FileTest.EXISTS)) { -+ return filepath; -+ } -+ } -+ return ""; -+ } -+ -+ private string[] get_xkb_group_layout (string layout, -+ string variant, -+ int layouts_max_length) { -+ int group_id = 0; -+ int i = 0; -+ string[] layouts = m_default_layout.split(","); -+ string[] variants = m_default_variant.split(","); -+ string group_layouts = ""; -+ string group_variants = ""; -+ bool has_variant = false; -+ bool include_keymap = false; -+ -+ for (i = 0; i < layouts.length; i++) { -+ if (i >= layouts_max_length - 1) { -+ break; -+ } -+ -+ if (i == 0) { -+ group_layouts = layouts[i]; -+ } else { -+ group_layouts = "%s,%s".printf(group_layouts, layouts[i]); -+ } -+ -+ if (i >= variants.length) { -+ if (i == 0) { -+ group_variants = ""; -+ } else { -+ group_variants += ","; -+ } -+ if (layout == layouts[i] && variant == "") { -+ include_keymap = true; -+ group_id = i; -+ } -+ continue; -+ } -+ if (layout == layouts[i] && variant == variants[i]) { -+ include_keymap = true; -+ group_id = i; -+ } -+ -+ if (variants[i] != "") { -+ has_variant = true; -+ } -+ -+ if (i == 0) { -+ group_variants = variants[i]; -+ } else { -+ group_variants = "%s,%s".printf(group_variants, variants[i]); -+ } -+ } -+ -+ if (variant != "") { -+ has_variant = true; -+ } -+ -+ if (!include_keymap) { -+ group_layouts = "%s,%s".printf(group_layouts, layout); -+ group_variants = "%s,%s".printf(group_variants, variant); -+ group_id = i; -+ } -+ -+ if (!has_variant) { -+ group_variants = null; -+ } -+ -+ return {group_layouts, group_variants, group_id.to_string()}; -+ } -+ -+ public string[] get_variant_from_layout(string layout) { -+ int left_bracket = layout.index_of("("); -+ int right_bracket = layout.index_of(")"); -+ if (left_bracket >= 0 && right_bracket > left_bracket) { -+ return {layout[0:left_bracket] + -+ layout[right_bracket + 1:layout.length], -+ layout[left_bracket + 1:right_bracket]}; -+ } -+ return {layout, "default"}; -+ } -+ -+ public string[] get_option_from_layout(string layout) { -+ int left_bracket = layout.index_of("["); -+ int right_bracket = layout.index_of("]"); -+ if (left_bracket >= 0 && right_bracket > left_bracket) { -+ return {layout[0:left_bracket] + -+ layout[right_bracket + 1:layout.length], -+ layout[left_bracket + 1:right_bracket]}; -+ } -+ return {layout, "default"}; -+ } -+ -+ public string get_layout() { -+ return get_output_from_cmdline("-query", "layout: "); -+ } -+ -+ public string get_variant() { -+ return get_output_from_cmdline("-query", "variant: "); -+ } -+ -+ public string get_option() { -+ return get_output_from_cmdline("-query", "options: "); -+ } -+ -+ /* -+ public string get_group() { -+ return get_output_from_cmdline("--get-group", "group: "); -+ } -+ */ -+ -+ public int[] set_layout(IBus.EngineDesc engine, -+ bool use_group_layout=false) { -+ string layout = engine.get_layout(); -+ string variant = engine.get_layout_variant(); -+ string option = engine.get_layout_option(); -+ -+ assert (layout != null); -+ -+ int xkb_group_id = 0; -+ int changed_option = 0; -+ -+ if (m_xkb_pid != -1) { -+ return {-1, 0}; -+ } -+ -+ if (layout == "default" && -+ (variant == "default" || variant == "") && -+ (option == "default" || option == "")) { -+ return {-1, 0}; -+ } -+ -+ bool need_us_layout = false; -+ foreach (string latin_layout in m_xkb_latin_layouts) { -+ if (layout == latin_layout && variant != "eng") { -+ need_us_layout = true; -+ break; -+ } -+ if (variant != null && -+ "%s(%s)".printf(layout, variant) == latin_layout) { -+ need_us_layout = true; -+ break; -+ } -+ } -+ -+ int layouts_max_length = XKB_LAYOUTS_MAX_LENGTH; -+ if (need_us_layout) { -+ layouts_max_length--; -+ } -+ -+ if (m_default_layout == "") { -+ m_default_layout = get_layout(); -+ } -+ if (m_default_variant == "") { -+ m_default_variant = get_variant(); -+ } -+ if (m_default_option == "") { -+ m_default_option = get_option(); -+ } -+ -+ if (layout == "default") { -+ layout = m_default_layout; -+ variant = m_default_variant; -+ } else { -+ if (use_group_layout) { -+ if (variant == "default") { -+ variant = ""; -+ } -+ string[] retval = get_xkb_group_layout (layout, variant, -+ layouts_max_length); -+ layout = retval[0]; -+ variant = retval[1]; -+ xkb_group_id = int.parse(retval[2]); -+ } -+ } -+ -+ if (layout == "") { -+ warning("Could not get the correct layout"); -+ return {-1, 0}; -+ } -+ -+ if (variant == "default" || variant == "") { -+ variant = null; -+ } -+ -+ if (option == "default" || option == "") { -+ option = m_default_option; -+ } else { -+ if (!(option in m_default_option.split(","))) { -+ option = "%s,%s".printf(m_default_option, option); -+ changed_option = 1; -+ } else { -+ option = m_default_option; -+ } -+ } -+ -+ if (option == "") { -+ option = null; -+ } -+ -+ if (need_us_layout) { -+ layout += ",us"; -+ if (variant != null) { -+ variant += ","; -+ } -+ } -+ -+ string[] args = {}; -+ args += m_xkb_command; -+ args += "-layout"; -+ args += layout; -+ if (variant != null) { -+ args += "-variant"; -+ args += variant; -+ } -+ if (option != null) { -+ /* TODO: Need to get the session XKB options */ -+ args += "-option"; -+ args += "-option"; -+ args += option; -+ } -+ -+ GLib.Pid child_pid; -+ try { -+ GLib.Process.spawn_async(null, -+ args, -+ null, -+ GLib.SpawnFlags.DO_NOT_REAP_CHILD | -+ GLib.SpawnFlags.SEARCH_PATH, -+ null, -+ out child_pid); -+ } catch (GLib.SpawnError err) { -+ stderr.printf("Execute setxkbmap failed: %s\n", err.message); -+ return {-1, 0}; -+ } -+ m_xkb_pid = child_pid; -+ GLib.ChildWatch.add(m_xkb_pid, set_layout_cb); -+ -+ return {xkb_group_id, changed_option}; -+ } -+ -+ public void set_xmodmap() { -+ if (!m_use_xmodmap) { -+ return; -+ } -+ -+ if (m_xmodmap_pid != -1) { -+ return; -+ } -+ -+ string xmodmap_cmdpath = get_fullpath(m_xmodmap_command); -+ if (xmodmap_cmdpath == "") { -+ xmodmap_cmdpath = m_xmodmap_command; -+ } -+ string homedir = GLib.Environment.get_home_dir(); -+ foreach (string xmodmap_file in m_xmodmap_known_files) { -+ string xmodmap_filepath = GLib.Path.build_filename(homedir, xmodmap_file); -+ if (!GLib.FileUtils.test(xmodmap_filepath, GLib.FileTest.EXISTS)) { -+ continue; -+ } -+ string[] args = {xmodmap_cmdpath, xmodmap_filepath}; -+ -+ GLib.Pid child_pid; -+ try { -+ GLib.Process.spawn_async(null, -+ args, -+ null, -+ GLib.SpawnFlags.DO_NOT_REAP_CHILD | -+ GLib.SpawnFlags.SEARCH_PATH, -+ null, -+ out child_pid); -+ } catch (GLib.SpawnError err) { -+ stderr.printf("IBUS_ERROR: %s\n", err.message); -+ return; -+ } -+ m_xmodmap_pid = child_pid; -+ GLib.ChildWatch.add(m_xmodmap_pid, set_xmodmap_cb); -+ -+ break; -+ } -+ } -+ -+ public void reset_layout() { -+ m_default_layout = get_layout(); -+ m_default_variant = get_variant(); -+ m_default_option = get_option(); -+ } -+ -+ /* -+ public static int main(string[] args) { -+ IBus.Bus bus = new IBus.Bus(); -+ IBus.Config config = bus.get_config(); -+ XKBLayout xkblayout = new XKBLayout(config); -+ stdout.printf ("layout: %s\n", xkblayout.get_layout()); -+ stdout.printf ("variant: %s\n", xkblayout.get_variant()); -+ stdout.printf ("option: %s\n", xkblayout.get_option()); -+ xkblayout.set_layout("jp"); -+ if (config != null) { -+ IBus.main(); -+ } else { -+ Gtk.init (ref args); -+ Gtk.main(); -+ } -+ return 0; -+ } -+ */ -+} --- -1.8.5.5 - diff --git a/ibus.changes b/ibus.changes index 81df323..ed10482 100644 --- a/ibus.changes +++ b/ibus.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Thu Jul 31 12:07:24 UTC 2014 - ftake@geeko.jp + +- remove patches merged by upstream + * add-libgnomekbd-and-load-preload-engines.patch + * reload-preload-engines-until-users-customize-the-list.patch +- obsoletes python-ibus when packaged for Python 3 + ------------------------------------------------------------------- Sun Jul 27 15:15:28 UTC 2014 - i@marguerite.su diff --git a/ibus.spec b/ibus.spec index 0a155a2..e1d59be 100644 --- a/ibus.spec +++ b/ibus.spec @@ -16,7 +16,6 @@ # -%define with_automatic_config 1 %define gtk_binary_version %(pkg-config --variable=gtk_binary_version gtk+-2.0) %define with_python3 1 %if 0%{?suse_version} >= 1310 @@ -43,14 +42,6 @@ Source7: macros.ibus Source99: baselibs.conf # PATCH-FIX-OPENSUSE ibus-python-install-dir.patch ftake@geeko.jp Patch0: ibus-python-install-dir.patch - -%if %{with_automatic_config} -# PATCH-FEATURE-UPSTREAM add-libgnomekbd-and-load-preload-engines.patch Issue 1641 ftake@geeko.jp -Patch1: add-libgnomekbd-and-load-preload-engines.patch -# PATCH-FEATURE-UPSTREAM reload-preload-engines-until-users-customize-the-list.patch Issue 1641 ftake@geeko.jp -Patch2: reload-preload-engines-until-users-customize-the-list.patch -%endif - # PATCH-FIX-OPENSUSE reload-preload-engines-until-users-customize-the-list.patch ftake@geeko.jp Patch3: show-input-mode-icon.patch # PATFH-FIX-SUSE ibus-xim-fix-re-focus-after-lock.patch bnc#874869 tiwa@suse.de -- Fix lost XIM input after screenlock @@ -66,10 +57,6 @@ Patch5: ibus-force-python3.patch Patch6: ibus-vala-0.18.patch BuildRequires: dbus-1-glib-devel BuildRequires: dbus-1-python-devel >= 0.83.0 -%if %{with_automatic_config} -BuildRequires: dbus-1-x11 -BuildRequires: libgnomekbd-devel -%endif BuildRequires: dconf-devel >= 0.7.5 BuildRequires: fdupes BuildRequires: gconf2-devel @@ -121,6 +108,9 @@ Supplements: packageand(libreoffice:libreoffice-gnome) Provides: locale(ja;ko;zh) Obsoletes: ibus-gnome-shell Obsoletes: libibus-1_0-0 +%if %{with_python3} +Obsoletes: python-ibus +%endif BuildRoot: %{_tmppath}/%{name}-%{version}-build %description @@ -229,13 +219,6 @@ sed -i \ %{SOURCE99} %endif -%if %{with_automatic_config} -#%patch1 -p1 -#%patch2 -p1 -rm -f bindings/vala/ibus-1.0.vapi -rm -f data/dconf/00-upstream-settings -%endif - %patch3 -p1 %patch4 -p1 @@ -262,17 +245,10 @@ intltoolize -f --enable-gtk-doc \ %if %{with_wayland} --enable-wayland \ -%endif -%if %{with_automatic_config} - --enable-libgnomekbd \ %endif --enable-surrounding-text \ --libexecdir=%{_libdir}/ibus -%if %{with_automatic_config} -make -C ui/gtk3 maintainer-clean-generic %{?_smp_mflags} -%endif - make %{?_smp_mflags} %install diff --git a/reload-preload-engines-until-users-customize-the-list.patch b/reload-preload-engines-until-users-customize-the-list.patch deleted file mode 100644 index fe57bf9..0000000 --- a/reload-preload-engines-until-users-customize-the-list.patch +++ /dev/null @@ -1,353 +0,0 @@ -From 68a504f7ab44c4977d15e0bd83c7e76dd8d2b06e Mon Sep 17 00:00:00 2001 -From: fujiwarat -Date: Fri, 7 Mar 2014 16:43:49 +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, -users would prefer to load the system default engines again by login. -The gsettings value 'preload-engine-mode' is -IBUS_PRELOAD_ENGINE_MODE_USER by default but set -IBUS_PRELOAD_ENGINE_MODE_LANG_RELATIVE for the initial login. -If 'preload-engine-mode' is IBUS_PRELOAD_ENGINE_MODE_LANG_RELATIVE, -ibus-daemon loads the system preload engines by langs. -If 'preload-engine-mode' is IBUS_PRELOAD_ENGINE_MODE_USER, -ibus-daemon do not update the gsettings value 'preload-engines' -On the other hand, if users enable the customized engine checkbutton -on ibus-setup, ibus-setup sets 'preload-engine-mode' as -IBUS_PRELOAD_ENGINE_MODE_USER and users can customize the value -'preload-engines'. ---- - data/ibus.schemas.in | 24 ++++++++++++++ - setup/main.py | 71 +++++++++++++++++++++++++++++++++++---- - setup/setup.ui | 22 +++++++++++-- - src/ibustypes.h | 10 ++++++ - ui/gtk3/panel.vala | 93 ++++++++++++++++++++++++++++++++++++++++++++++++++++ - 5 files changed, 211 insertions(+), 9 deletions(-) - -diff --git a/data/ibus.schemas.in b/data/ibus.schemas.in -index caec315..1f9b1eb 100644 ---- a/data/ibus.schemas.in -+++ b/data/ibus.schemas.in -@@ -2,6 +2,30 @@ - - - -+ /schemas/desktop/ibus/general/preload_engine_mode -+ /desktop/ibus/general/preload_engine_mode -+ ibus -+ int -+ 0 -+ -+ Preload engine mode -+ Preload engines are loaded with this mode. -+ 0 = user customized engines. -+ 1 = language related engines. -+ -+ -+ -+ /schemas/desktop/ibus/general/preload_engines_inited -+ /desktop/ibus/general/preload_engines_inited -+ ibus -+ bool -+ false -+ -+ The key preload_engines is initialized -+ The key preload_engines is initialized -+ -+ -+ - /schemas/desktop/ibus/general/preload_engines - /desktop/ibus/general/preload_engines - ibus -diff --git a/setup/main.py b/setup/main.py -index dee7be4..d70da6b 100644 ---- a/setup/main.py -+++ b/setup/main.py -@@ -190,16 +190,30 @@ def __init_general(self): - 'active', - Gio.SettingsBindFlags.DEFAULT) - -+ # set preload mode -+ preload_engine_mode = \ -+ self.__settings_general.get_int('preload-engine-mode') -+ button = self.__builder.get_object("checkbutton_preload_engine_mode") -+ hbox = self.__builder.get_object("hbox_customize_active_input_methods") -+ if preload_engine_mode == IBus.PreloadEngineMode.USER: -+ button.set_active(True) -+ hbox.set_sensitive(True) -+ else: -+ button.set_active(False) -+ hbox.set_sensitive(False) -+ button.connect('toggled', -+ self.__checkbutton_preload_engine_mode_toggled_cb) -+ -+ self.__settings_general.connect('changed::preload-engines', -+ self.__settings_general_preload_engines_cb) -+ - # init engine page - self.__engines = self.__bus.list_engines() - self.__combobox = self.__builder.get_object("combobox_engines") - self.__combobox.set_engines(self.__engines) - -- tmp_dict = {} -- for e in self.__engines: -- tmp_dict[e.get_name()] = e - engine_names = self.__settings_general.get_strv('preload-engines') -- engines = [tmp_dict[name] for name in engine_names if name in tmp_dict] -+ engines = self.__get_engine_descs_from_names(engine_names) - - self.__treeview = self.__builder.get_object("treeview_engines") - self.__treeview.set_engines(engines) -@@ -249,8 +263,9 @@ def __init_ui(self): - def __combobox_notify_active_engine_cb(self, combobox, property): - engine = self.__combobox.get_active_engine() - button = self.__builder.get_object("button_engine_add") -- button.set_sensitive( -- engine != None and engine not in self.__treeview.get_engines()) -+ button.set_sensitive(engine != None and \ -+ engine.get_name() not in [e.get_name() for e \ -+ in self.__treeview.get_engines()]) - - def __get_engine_setup_exec_args(self, engine): - args = [] -@@ -270,6 +285,13 @@ def __get_engine_setup_exec_args(self, engine): - args.append(path.basename(setup_path)) - return args - -+ def __get_engine_descs_from_names(self, engine_names): -+ tmp_dict = {} -+ for e in self.__engines: -+ tmp_dict[e.get_name()] = e -+ engines = [tmp_dict[name] for name in engine_names if name in tmp_dict] -+ return engines -+ - def __treeview_notify_cb(self, treeview, prop): - if prop.name not in ("active-engine", "engines"): - return -@@ -321,6 +343,43 @@ def __button_engine_preferences_cb(self, button): - del self.__engine_setup_exec_list[name] - self.__engine_setup_exec_list[name] = os.spawnl(os.P_NOWAIT, *args) - -+ def __checkbutton_preload_engine_mode_toggled_cb(self, button): -+ if button.get_active(): -+ self.__settings_general.set_int('preload-engine-mode', -+ IBus.PreloadEngineMode.USER) -+ self.__builder.get_object( -+ "hbox_customize_active_input_methods").set_sensitive(True) -+ self.__treeview.notify('engines') -+ else: -+ message = _("The list of your saved input methods will be " \ -+ "cleared immediately and the list will be " \ -+ "configured by the login language every time. " \ -+ "Do you agree with this?") -+ dlg = Gtk.MessageDialog(type = Gtk.MessageType.QUESTION, -+ buttons = Gtk.ButtonsType.YES_NO, -+ message_format = message) -+ id = dlg.run() -+ dlg.destroy() -+ self.__flush_gtk_events() -+ if id != Gtk.ResponseType.YES: -+ button.set_active(True) -+ return -+ self.__settings_general.set_int( -+ 'preload-engine-mode', -+ IBus.PreloadEngineMode.LANG_RELATIVE) -+ self.__builder.get_object( -+ "hbox_customize_active_input_methods").set_sensitive(False) -+ -+ def __settings_general_preload_engines_cb(self, settings, key): -+ engine_names = self.__settings_general.get_strv('preload-engines') -+ engines = self.__get_engine_descs_from_names(engine_names) -+ current_engines = self.__treeview.get_engines() -+ engines_csv = str.join(',', [e.get_name() for e in engines]) -+ current_engines_csv = \ -+ str.join(',', [e.get_name() for e in current_engines]) -+ if engines_csv != current_engines_csv: -+ self.__treeview.set_engines(engines) -+ - def __init_bus(self): - self.__bus = IBus.Bus() - if self.__bus.is_connected(): -diff --git a/setup/setup.ui b/setup/setup.ui -index ad5386b..68e0faa 100644 ---- a/setup/setup.ui -+++ b/setup/setup.ui -@@ -677,7 +677,23 @@ - True - False - -- -+ -+ True -+ Customize active input _methods -+ True -+ True -+ False -+ Customize active input methods -+ True -+ -+ -+ False -+ True -+ 0 -+ -+ -+ -+ - horizontal - True - False -@@ -868,7 +884,7 @@ - - True - True -- 0 -+ 1 - - - -@@ -916,7 +932,7 @@ - - False - True -- 1 -+ 2 - - - -diff --git a/src/ibustypes.h b/src/ibustypes.h -index 86fc2cc..cb9eb22 100644 ---- a/src/ibustypes.h -+++ b/src/ibustypes.h -@@ -206,6 +206,16 @@ - } IBusError; - - /** -+ * IBusPreloadEngineMode: -+ * @IBUS_PRELOAD_ENGINE_MODE_USER: user custimized engines -+ * @IBUS_PRELOAD_ENGINE_MODE_LANG_RELATIVE: language related engines. -+ */ -+typedef enum { -+ IBUS_PRELOAD_ENGINE_MODE_USER = 0, -+ IBUS_PRELOAD_ENGINE_MODE_LANG_RELATIVE = 1, -+} IBusPreloadEngineMode; -+ -+/** - * IBusRectangle: - * @x: x coordinate. - * @y: y coordinate. -diff --git a/ui/gtk3/panel.vala b/ui/gtk3/panel.vala -index 7a15049..e6c128a 100644 ---- a/ui/gtk3/panel.vala -+++ b/ui/gtk3/panel.vala -@@ -141,6 +141,10 @@ class Panel : IBus.PanelService { - null); - }); - -+ m_settings_general.changed["preload-engine-mode"].connect((key) => { -+ update_im_engines(); -+ }); -+ - m_settings_general.changed["switcher-delay-time"].connect((key) => { - set_switcher_delay_time(); - }); -@@ -569,7 +573,96 @@ class Panel : IBus.PanelService { - init_gkbd(); - } - -+ string[] preload_engines = -+ m_settings_general.get_strv("preload-engines"); -+ -+ bool preload_engines_inited = -+ m_settings_general.get_boolean("preload-engines-inited"); -+ -+ // Set preload_engines_inited = true for back compatibility -+ if (preload_engines.length != 0 && !preload_engines_inited) { -+ preload_engines_inited = true; -+ m_settings_general.set_boolean("preload-engines-inited", true); -+ } -+ - update_xkb_engines(); -+ -+ // Before update preload_engine_mode, update_xkb_engines() is called -+ // because "preload-engine-mode" signal calls update_im_engines(). -+ if (!preload_engines_inited) -+ m_settings_general.set_int("preload-engine-mode", -+ IBus.PreloadEngineMode.LANG_RELATIVE); -+ -+ update_im_engines(); -+ -+ if (!preload_engines_inited) -+ m_settings_general.set_boolean("preload-engines-inited", true); -+ } -+ -+ private bool set_lang_relative_preload_engines() { -+ string locale = Intl.setlocale(LocaleCategory.CTYPE, null); -+ -+ if (locale == null) -+ locale = "C"; -+ -+ string lang = locale.split(".")[0]; -+ GLib.List engines = m_bus.list_engines(); -+ string[] im_engines = {}; -+ -+ for (unowned GLib.List p = engines; -+ p != null; -+ p = p.next) { -+ unowned IBus.EngineDesc engine = p.data; -+ if (engine.get_language() == lang && engine.get_rank() > 0) -+ im_engines += engine.get_name(); -+ } -+ -+ lang = lang.split("_")[0]; -+ if (im_engines.length == 0) { -+ for (unowned GLib.List p = engines; -+ p != null; -+ p = p.next) { -+ unowned IBus.EngineDesc engine = p.data; -+ if (engine.get_language() == lang && engine.get_rank() > 0) -+ im_engines += engine.get_name(); -+ } -+ } -+ -+ if (im_engines.length == 0) -+ return false; -+ -+ string[] orig_preload_engines = -+ m_settings_general.get_strv("preload-engines"); -+ string[] preload_engines = {}; -+ -+ // clear input method engines -+ foreach (string name in orig_preload_engines) { -+ if (name.ascii_ncasecmp("xkb:", 4) != 0) -+ continue; -+ -+ preload_engines += name; -+ } -+ -+ foreach (string name in im_engines) { -+ if (!(name in preload_engines)) -+ preload_engines += name; -+ } -+ -+ if (string.joinv(",", orig_preload_engines) != -+ string.joinv(",", preload_engines)) -+ m_settings_general.set_strv("preload-engines", preload_engines); -+ -+ return true; -+ } -+ -+ private void update_im_engines() { -+ int preload_engine_mode = -+ m_settings_general.get_int("preload-engine-mode"); -+ -+ if (preload_engine_mode == IBus.PreloadEngineMode.USER) -+ return; -+ -+ set_lang_relative_preload_engines(); - } - - private void update_xkb_engines() { --- -1.8.5.5 -