diff -Nru ibus-1.4.1/debian/changelog ibus-1.4.1/debian/changelog --- ibus-1.4.1/debian/changelog 2012-03-18 00:26:29.000000000 +0900 +++ ibus-1.4.1/debian/changelog 2012-03-21 21:52:15.000000000 +0900 @@ -1,3 +1,22 @@ +ibus (1.4.1-3ubuntu1) precise; urgency=low + + * Merge from Debian unstable, remaining changes: + - debian/control: Install im-switch instead of im-config by default. + - debian/rules: Build with dh_translations. Add dh-translations build + dependency. + - Add 02_title_update.patch: Rename "IBus Preferences" to "Keyboard Input + Methods" + - Add 05_appindicator.patch: Use an indicator rather than a notification + icon. Add python-appindicator recommends. + - debian/control: Recommends on ibus-gtk, ibus-qt4, ibus-clutter need to + be alternatives, because we want derivatives to be able to pick the ones + they need. + - add ibus-530711-preload-sys.patch: Set default IMEngine (LP: #944035). + Taken from Fedora: + https://bugzilla.redhat.com/show_bug.cgi?id=530711 + + -- Ikuya Awashiro Wed, 21 Mar 2012 21:45:55 +0900 + ibus (1.4.1-3) unstable; urgency=low * Fixed im-switch hook script. Closes: #664201 diff -Nru ibus-1.4.1/debian/control ibus-1.4.1/debian/control --- ibus-1.4.1/debian/control 2012-02-12 01:12:27.000000000 +0900 +++ ibus-1.4.1/debian/control 2012-03-21 21:45:21.000000000 +0900 @@ -1,7 +1,8 @@ Source: ibus Section: utils Priority: optional -Maintainer: IME Packaging Team +Maintainer: Ubuntu Developers +XSBC-Original-Maintainer: IME Packaging Team Uploaders: LI Daobing , Zhengpeng Hou , @@ -11,6 +12,7 @@ Build-Depends: debhelper (>= 8.1.3~), autotools-dev, dh-autoreconf, + dh-translations, autoconf, automake, libtool, @@ -36,7 +38,7 @@ Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends}, ${python:Depends}, python-ibus (= ${source:Version}), python-xdg, librsvg2-common, python-notify -Recommends: ibus-gtk3, ibus-gtk, ibus-qt4, ibus-clutter, im-config | im-switch +Recommends: ibus-gtk3 | ibus-qt4 | ibus-clutter, ibus-gtk | ibus-qt4 | ibus-clutter, python-appindicator, im-switch | im-config Breaks: ibus-anthy (<< 1.2), ibus-table (<< 1.2), ibus-pinyin (<< 1.2.99), diff -Nru ibus-1.4.1/debian/patches/02_title_update.patch ibus-1.4.1/debian/patches/02_title_update.patch --- ibus-1.4.1/debian/patches/02_title_update.patch 1970-01-01 09:00:00.000000000 +0900 +++ ibus-1.4.1/debian/patches/02_title_update.patch 2012-03-21 21:38:44.000000000 +0900 @@ -0,0 +1,45 @@ +#! /bin/sh /usr/share/dpatch/dpatch-run +## 02_title_update.dpatch by Sebastien Bacher +## +## All lines beginning with `## DP:' are a description of the patch. +## DP: No description. + +@DPATCH@ +Index: ibus-1.4.1/setup/ibus-setup.desktop.in +=================================================================== +--- ibus-1.4.1.orig/setup/ibus-setup.desktop.in 2012-02-02 05:55:34.000000000 +0100 ++++ ibus-1.4.1/setup/ibus-setup.desktop.in 2012-03-06 09:45:27.880594235 +0100 +@@ -1,6 +1,6 @@ + [Desktop Entry] +-_Name=IBus Preferences +-_Comment=Set IBus Preferences ++_Name=Keyboard Input Methods ++_Comment=Adjust methods for keyboard input. + Exec=ibus-setup + Icon=ibus-setup + Terminal=false +Index: ibus-1.4.1/setup/main.py +=================================================================== +--- ibus-1.4.1.orig/setup/main.py 2012-02-02 05:54:54.000000000 +0100 ++++ ibus-1.4.1/setup/main.py 2012-03-06 09:45:06.620593206 +0100 +@@ -329,7 +329,7 @@ + # self.__bus.config_add_watch("/panel") + except: + while self.__bus == None: +- message = _("IBus daemon is not started. Do you want to start it now?") ++ message = _("Keyboard Input Methods (IBus Daemon) has not been started. Do you want to start it now?") + dlg = gtk.MessageDialog(type = gtk.MESSAGE_QUESTION, + buttons = gtk.BUTTONS_YES_NO, + message_format = message) +@@ -345,10 +345,7 @@ + except: + continue + message = _("IBus has been started! " +- "If you can not use IBus, please add below lines in $HOME/.bashrc, and relogin your desktop.\n" +- " export GTK_IM_MODULE=ibus\n" +- " export XMODIFIERS=@im=ibus\n" +- " export QT_IM_MODULE=ibus" ++ "If you can not use IBus, please open System Menu -> System Settings -> Language Support and set the \"Keyboard Input Method\" to \"ibus\", then log out and back in again." + ) + dlg = gtk.MessageDialog(type = gtk.MESSAGE_INFO, + buttons = gtk.BUTTONS_OK, diff -Nru ibus-1.4.1/debian/patches/05_appindicator.patch ibus-1.4.1/debian/patches/05_appindicator.patch --- ibus-1.4.1/debian/patches/05_appindicator.patch 1970-01-01 09:00:00.000000000 +0900 +++ ibus-1.4.1/debian/patches/05_appindicator.patch 2012-03-21 21:38:44.000000000 +0900 @@ -0,0 +1,321 @@ +Index: ibus-1.4.1/ui/gtk/main.py +=================================================================== +--- ibus-1.4.1.orig/ui/gtk/main.py 2012-02-02 05:54:54.000000000 +0100 ++++ ibus-1.4.1/ui/gtk/main.py 2012-03-06 09:45:41.056594873 +0100 +@@ -63,8 +63,9 @@ + "Please restart ibus input platform."), \ + "ibus") + self.__notify.set_timeout(10 * 1000) +- self.__notify.add_action("restart", _("Restart Now"), self.__restart_cb, None) +- self.__notify.add_action("ignore", _("Later"), lambda *args: None, None) ++ if "actions" in pynotify.get_server_caps(): ++ self.__notify.add_action("restart", _("Restart Now"), self.__restart_cb, None) ++ self.__notify.add_action("ignore", _("Later"), lambda *args: None, None) + + def __restart_cb(self, notify, action, data): + if action == "restart": +Index: ibus-1.4.1/ui/gtk/panel.py +=================================================================== +--- ibus-1.4.1.orig/ui/gtk/panel.py 2012-02-02 05:54:54.000000000 +0100 ++++ ibus-1.4.1/ui/gtk/panel.py 2012-03-06 09:45:41.060594873 +0100 +@@ -37,6 +37,11 @@ + + from i18n import _, N_ + ++try: ++ import appindicator ++except: ++ appindicator = None ++ + ICON_KEYBOARD = ibus.get_ICON_KEYBOARD() + ICON_ENGINE = "ibus-engine" + +@@ -62,7 +67,9 @@ + self.__bus = bus + self.__config = self.__bus.get_config() + self.__focus_ic = None ++ self.__previous_focus_ic = None + self.__setup_pid = None ++ self.__block_activate = False + self.__prefix = os.getenv("IBUS_PREFIX") + self.__data_dir = path.join(self.__prefix, "share", "ibus") + # self.__icons_dir = path.join(self.__data_dir, "icons") +@@ -102,26 +109,38 @@ + lambda widget, index, button, state: self.candidate_clicked(index, button, state)) + + +- self.__status_icon = gtk.StatusIcon() +- # gnome-shell checks XClassHint.res_class with ShellTrayIcon. +- # gtk_status_icon_set_name() can set XClassHint.res_class . +- # However gtk_status_icon_new() also calls gtk_window_realize() so +- # gtk_status_icon_set_visible() needs to be called to set WM_CLASS +- # so that gtk_window_realize() is called later again. +- # set_title is for gnome-shell notificationDaemon in bottom right. +- self.__status_icon.set_visible(False) +- # gtk_status_icon_set_name() is not available in pygtk2 2.17 +- if hasattr(self.__status_icon, 'set_name'): +- self.__status_icon.set_name('ibus-ui-gtk') +- self.__status_icon.set_title(_("IBus Panel")) +- # Hide icon until bus get the name owner. +- #self.__status_icon.set_visible(True) +- self.__status_icon.connect("popup-menu", self.__status_icon_popup_menu_cb) +- self.__status_icon.connect("activate", self.__status_icon_activate_cb) +- self.__status_icon.set_from_icon_name(ICON_KEYBOARD) +- self.__status_icon.set_tooltip(_("IBus input method framework")) +- # Hide icon until bus get the name owner. +- #self.__status_icon.set_visible(True) ++ if appindicator is None: ++ self.__status_icon = gtk.StatusIcon() ++ # gnome-shell checks XClassHint.res_class with ShellTrayIcon. ++ # gtk_status_icon_set_name() can set XClassHint.res_class . ++ # However gtk_status_icon_new() also calls gtk_window_realize() so ++ # gtk_status_icon_set_visible() needs to be called to set WM_CLASS ++ # so that gtk_window_realize() is called later again. ++ # set_title is for gnome-shell notificationDaemon in bottom right. ++ self.__status_icon.set_visible(False) ++ # gtk_status_icon_set_name() is not available in pygtk2 2.17 ++ if hasattr(self.__status_icon, 'set_name'): ++ self.__status_icon.set_name('ibus-ui-gtk') ++ self.__status_icon.set_title(_("IBus Panel")) ++ # Hide icon until bus get the name owner. ++ #self.__status_icon.set_visible(True) ++ self.__status_icon.connect("popup-menu", self.__status_icon_popup_menu_cb) ++ self.__status_icon.connect("activate", self.__status_icon_activate_cb) ++ self.__status_icon.set_from_icon_name(ICON_KEYBOARD) ++ self.__status_icon.set_tooltip(_("IBus input method framework")) ++ # Hide icon until bus get the name owner. ++ #self.__status_icon.set_visible(True) ++ else: ++ self.__appindicator = appindicator.Indicator( ++ "ibus-ui-gtk", ICON_KEYBOARD, ++ appindicator.CATEGORY_APPLICATION_STATUS) ++ if self.__config.get_value("panel", "show_icon_on_systray", True): ++ self.__appindicator.set_status(appindicator.STATUS_ACTIVE) ++ else: ++ self.__appindicator.set_status(appindicator.STATUS_PASSIVE) ++ self.__appindicator_update_menu() ++ self.__status_icon = None ++ + + self.__config_load_lookup_table_orientation() + self.__config_load_show() +@@ -209,10 +228,13 @@ + if not icon_name: + icon_name = ICON_ENGINE + self.__language_bar.set_im_icon(icon_name) +- if icon_name.startswith("/"): +- self.__status_icon.set_from_file(icon_name) ++ if self.__appindicator: ++ self.__appindicator.set_icon(icon_name) + else: +- self.__status_icon.set_from_icon_name(icon_name) ++ if icon_name.startswith("/"): ++ self.__status_icon.set_from_file(icon_name) ++ else: ++ self.__status_icon.set_from_icon_name(icon_name) + + def __set_im_name(self, name): + self.__language_bar.set_im_name(name) +@@ -234,15 +256,24 @@ + else: + self.__set_im_icon(ICON_KEYBOARD) + self.__set_im_name(None) ++ + self.__language_bar.focus_in() ++ while gtk.events_pending(): ++ gtk.main_iteration(False) ++ if self.__appindicator: ++ self.__appindicator_update_menu() + + def focus_out(self, ic): + self.reset() ++ self.__previous_focus_ic = self.__focus_ic + self.__focus_ic = None + self.__language_bar.set_enabled(False) + self.__language_bar.focus_out() + self.__set_im_icon(ICON_KEYBOARD) + self.__set_im_name(None) ++ ++ while gtk.events_pending(): ++ gtk.main_iteration(False) + + def state_changed(self): + if not self.__focus_ic: +@@ -311,7 +342,13 @@ + + def __config_load_show_icon_on_systray(self): + value = self.__config.get_value("panel", "show_icon_on_systray", True) +- self.__status_icon.set_visible(True if value else False) ++ if self.__appindicator: ++ if value: ++ self.__appindicator.set_status(appindicator.STATUS_ACTIVE) ++ else: ++ self.__appindicator.set_status(appindicator.STATUS_PASSIVE) ++ else: ++ self.__status_icon.set_visible(True if value else False) + + def __config_load_show_im_name(self): + value = self.__config.get_value("panel", "show_im_name", False) +@@ -338,8 +375,7 @@ + def __config_reloaded_cb(self, bus): + pass + +- def __create_sys_menu(self): +- menu = gtk.Menu() ++ def __create_sys_menu(self, menu): + item = gtk.ImageMenuItem(gtk.STOCK_PREFERENCES) + item.connect("activate", + self.__sys_menu_item_activate_cb, gtk.STOCK_PREFERENCES) +@@ -358,8 +394,6 @@ + self.__sys_menu_item_activate_cb, gtk.STOCK_QUIT) + menu.add(item) + +- menu.show_all() +- menu.set_take_focus(False) + return menu + + # def __create_im_menu(self): +@@ -422,33 +456,50 @@ + + size = gtk.icon_size_lookup(gtk.ICON_SIZE_MENU) + menu = gtk.Menu() ++ ++ group = None + for i, engine in enumerate(engines): + lang = ibus.get_language_name(engine.language) +- item = gtk.ImageMenuItem("%s - %s" % (lang, engine.longname)) +- if current_engine and current_engine.name == engine.name: +- for widget in item.get_children(): +- if isinstance(widget, gtk.Label): +- widget.set_markup("%s" % widget.get_text()) +- if engine.icon: +- item.set_image(_icon.IconWidget(engine.icon, size[0])) ++ if self.__appindicator: ++ item = gtk.RadioMenuItem(group, "%s - %s" % (lang, engine.longname)) ++ if not group: group = item + else: +- item.set_image(_icon.IconWidget(ICON_ENGINE, size[0])) ++ item = gtk.ImageMenuItem("%s - %s" % (lang, engine.longname)) ++ if current_engine and current_engine.name == engine.name: ++ if self.__appindicator: ++ item.set_active(True) ++ else: ++ for widget in item.get_children(): ++ if isinstance(widget, gtk.Label): ++ widget.set_markup("%s" % widget.get_text()) ++ if not self.__appindicator: ++ if engine.icon: ++ item.set_image(_icon.IconWidget(engine.icon, size[0])) ++ else: ++ item.set_image(_icon.IconWidget(ICON_ENGINE, size[0])) + item.connect("activate", self.__im_menu_item_activate_cb, engine) + menu.add(item) + +- item = gtk.ImageMenuItem(_("Turn off input method")) +- item.set_image(_icon.IconWidget("gtk-close", size[0])) +- item.connect("activate", self.__im_menu_item_activate_cb, None) +- if self.__focus_ic == None or not self.__focus_ic.is_enabled(): +- item.set_sensitive(False) ++ ++ if self.__appindicator: ++ item = gtk.RadioMenuItem(group, _("Input method Off")) ++ if self.__focus_ic == None or not self.__focus_ic.is_enabled(): ++ item.set_active(True) ++ item.connect("activate", self.__im_menu_item_activate_cb, None) ++ else: ++ item = gtk.ImageMenuItem(_("Turn off input method")) ++ item.set_image(_icon.IconWidget("gtk-close", size[0])) ++ item.connect("activate", self.__im_menu_item_activate_cb, None) ++ if self.__focus_ic == None or not self.__focus_ic.is_enabled(): ++ item.set_sensitive(False) + menu.add(item) + +- menu.show_all() +- menu.set_take_focus(False) + return menu + + def __get_im_menu_cb(self, languagebar): + menu = self.__create_im_menu() ++ menu.set_take_focus(False) ++ menu.show_all() + return menu + + def __show_engine_about_cb(self, langagebar): +@@ -465,7 +516,12 @@ + self.__config.set_value("panel", "y", y) + + def __status_icon_popup_menu_cb(self, status_icon, button, active_time): +- menu = self.__create_sys_menu() ++ menu = gtk.Menu() ++ self.__create_sys_menu(menu) ++ ++ menu.show_all() ++ menu.set_take_focus(False) ++ + menu.popup(None, None, + gtk.status_icon_position_menu, + button, +@@ -479,23 +535,57 @@ + size = gtk.icon_size_lookup(gtk.ICON_SIZE_MENU) + item.set_image(_icon.IconWidget("gtk-dialog-info", size[0])) + menu.add(item) +- menu.show_all() + else: + menu = self.__create_im_menu() + self.__language_bar.create_im_menu(menu) ++ menu.set_take_focus(False) ++ menu.show_all() + menu.popup(None, None, + gtk.status_icon_position_menu, + 0, + gtk.get_current_event_time(), + self.__status_icon) + +- def __im_menu_item_activate_cb(self, item, engine): +- if not self.__focus_ic: ++ def __appindicator_update_menu(self): ++ self.__block_activate = True ++ if not self.__appindicator: + return +- if engine: +- self.__focus_ic.set_engine(engine) ++ if not self.__previous_focus_ic: ++ menu = gtk.Menu() ++ item = gtk.ImageMenuItem(_("No input window")) ++ size = gtk.icon_size_lookup(gtk.ICON_SIZE_MENU) ++ item.set_image(_icon.IconWidget("gtk-info", size[0])) ++ menu.add(item) + else: +- self.__focus_ic.disable() ++ menu = self.__create_im_menu() ++ ++ menu.add(gtk.SeparatorMenuItem()) ++ ++ self.__create_sys_menu(menu) ++ menu.set_take_focus(False) ++ menu.show_all() ++ self.__appindicator.set_menu(menu) ++ self.__block_activate = False ++ ++ def __im_menu_item_activate_cb(self, item, engine): ++ if self.__block_activate: return ++ self.__block_activate = True ++ focus_ic = self.__focus_ic ++ if self.__previous_focus_ic: ++ focus_ic = self.__previous_focus_ic ++ if not focus_ic: ++ return ++ ++ current_engine = focus_ic.get_engine() ++ ++ if not engine: ++ focus_ic.disable() ++ elif engine != current_engine: ++ focus_ic.enable() ++ focus_ic.set_engine(engine) ++ ++ item.set_active(True) ++ self.__block_activate = False + + def __sys_menu_item_activate_cb(self, item, command): + if command == gtk.STOCK_PREFERENCES: diff -Nru ibus-1.4.1/debian/patches/ibus-530711-preload-sys.patch ibus-1.4.1/debian/patches/ibus-530711-preload-sys.patch --- ibus-1.4.1/debian/patches/ibus-530711-preload-sys.patch 1970-01-01 09:00:00.000000000 +0900 +++ ibus-1.4.1/debian/patches/ibus-530711-preload-sys.patch 2012-03-21 21:38:44.000000000 +0900 @@ -0,0 +1,739 @@ +From 8f5bb828744532bcfded7e92f3a1db1f26e567e8 Mon Sep 17 00:00:00 2001 +From: fujiwarat +Date: Fri, 30 Dec 2011 15:46:56 +0900 +Subject: [PATCH] Reload preload engines until users customize the list. + +The idea is, if users don't customize the preload_engines with ibus-setup, +users would prefer to load the system default engines again by login. +The gconf 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 gconf 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'. +--- + bus/ibusimpl.c | 412 +++++++++++++++++++++++++++++++++++++++----------- + data/ibus.schemas.in | 15 ++- + ibus/common.py | 6 + + setup/main.py | 73 ++++++++- + setup/setup.ui | 21 +++- + src/ibustypes.h | 10 ++ + 6 files changed, 440 insertions(+), 97 deletions(-) + +--- a/bus/ibusimpl.c ++++ b/bus/ibusimpl.c +@@ -142,6 +142,9 @@ + static void bus_ibus_impl_set_preload_engines + (BusIBusImpl *ibus, + GVariant *value); ++static void bus_ibus_impl_set_preload_engine_mode ++ (BusIBusImpl *ibus, ++ GVariant *value); + static void bus_ibus_impl_set_use_sys_layout + (BusIBusImpl *ibus, + GVariant *value); +@@ -283,6 +286,269 @@ + } + + static void ++_config_set_value_done (GObject *object, ++ GAsyncResult *res, ++ gpointer user_data) ++{ ++ IBusConfig *config = (IBusConfig *) object; ++ GVariant *value = (GVariant *) user_data; ++ GError *error = NULL; ++ ++ g_assert (IBUS_IS_CONFIG (config)); ++ ++ if (!ibus_config_set_value_async_finish (config, res, &error)) { ++ if (error) { ++ g_error_free (error); ++ } ++ } ++ g_variant_unref (value); ++} ++ ++#ifndef OS_CHROMEOS ++static gint ++_engine_desc_cmp (IBusEngineDesc *desc1, ++ IBusEngineDesc *desc2) ++{ ++ return - ((gint) ibus_engine_desc_get_rank (desc1)) + ++ ((gint) ibus_engine_desc_get_rank (desc2)); ++} ++#endif ++ ++#ifndef OS_CHROMEOS ++static gint ++_get_config_preload_engine_mode (BusIBusImpl *ibus) ++{ ++ GVariant *variant = NULL; ++ gint preload_engine_mode = IBUS_PRELOAD_ENGINE_MODE_USER; ++ ++ g_assert (BUS_IS_IBUS_IMPL (ibus)); ++ ++ if (ibus->config == NULL) { ++ return preload_engine_mode; ++ } ++ ++ variant = ibus_config_get_value (ibus->config, "general", ++ "preload_engines"); ++ if (variant != NULL && g_variant_classify (variant) == G_VARIANT_CLASS_ARRAY) { ++ GVariantIter iter; ++ const gchar *engine_name = NULL; ++ g_variant_iter_init (&iter, variant); ++ g_variant_iter_loop (&iter, "&s", &engine_name); ++ if (g_strcmp0 (engine_name, "ibus_null_engine") == 0) { ++ g_variant_unref (variant); ++ variant = NULL; ++ } ++ } ++ if (variant == NULL) { ++ /* Set LANG_RELATIVE mode for the initial login */ ++ preload_engine_mode = IBUS_PRELOAD_ENGINE_MODE_LANG_RELATIVE; ++ variant = g_variant_ref_sink (g_variant_new ("i", preload_engine_mode)); ++ ibus_config_set_value_async (ibus->config, "general", ++ "preload_engine_mode", variant, ++ -1, ++ NULL, ++ _config_set_value_done, ++ variant); ++ return preload_engine_mode; ++ } else { ++ g_variant_unref (variant); ++ } ++ ++ variant = ibus_config_get_value (ibus->config, "general", ++ "preload_engine_mode"); ++ if (variant != NULL) { ++ if (g_variant_classify (variant) == G_VARIANT_CLASS_INT32) { ++ preload_engine_mode = g_variant_get_int32 (variant); ++ } ++ g_variant_unref (variant); ++ } ++ ++ return preload_engine_mode; ++} ++#endif ++ ++static int ++_compare_engine_list_value (GVariant *value_a, GVariant *value_b) ++{ ++ GVariant *value; ++ GVariantIter iter; ++ const gchar *engine_name = NULL; ++ gchar *concat_engine_names; ++ gchar *concat_engine_names_a = NULL; ++ gchar *concat_engine_names_b = NULL; ++ int retval = 0; ++ ++ value = value_a; ++ concat_engine_names = NULL; ++ if (value != NULL && g_variant_classify (value) == G_VARIANT_CLASS_ARRAY) { ++ g_variant_iter_init (&iter, value); ++ while (g_variant_iter_loop (&iter, "&s", &engine_name)) { ++ gchar *tmp = g_strdup_printf ("%s::%s", ++ concat_engine_names ? concat_engine_names : "", ++ engine_name ? engine_name : ""); ++ g_free (concat_engine_names); ++ concat_engine_names = tmp; ++ } ++ } ++ concat_engine_names_a = concat_engine_names; ++ ++ value = value_b; ++ concat_engine_names = NULL; ++ if (value != NULL && g_variant_classify (value) == G_VARIANT_CLASS_ARRAY) { ++ g_variant_iter_init (&iter, value); ++ while (g_variant_iter_loop (&iter, "&s", &engine_name)) { ++ gchar *tmp = g_strdup_printf ("%s::%s", ++ concat_engine_names ? concat_engine_names : "", ++ engine_name ? engine_name : ""); ++ g_free (concat_engine_names); ++ concat_engine_names = tmp; ++ } ++ } ++ concat_engine_names_b = concat_engine_names; ++ ++ retval = g_strcmp0 (concat_engine_names_a, concat_engine_names_b); ++ g_free (concat_engine_names_a); ++ g_free (concat_engine_names_b); ++ return retval; ++} ++ ++static void ++_preload_engines_config_get_value_done (GObject *object, ++ GAsyncResult *res, ++ gpointer user_data) ++{ ++ IBusConfig *config = (IBusConfig *) object; ++ GVariant *new_value = (GVariant *) user_data; ++ GVariant *value = NULL; ++ GError *error = NULL; ++ ++ g_assert (IBUS_IS_CONFIG (config)); ++ ++ value = ibus_config_get_value_async_finish (config, res, &error); ++ if (error) { ++ g_error_free (error); ++ } ++ if (_compare_engine_list_value (value, new_value) != 0) { ++ ibus_config_set_value_async (config, "general", ++ "preload_engines", new_value, ++ -1, ++ NULL, ++ _config_set_value_done, ++ new_value); ++ } else if (new_value) { ++ g_variant_unref (new_value); ++ } ++ if (value) { ++ g_variant_unref (value); ++ } ++} ++ ++static void ++_set_preload_engines (BusIBusImpl *ibus, ++ GVariant *value) ++{ ++ GList *engine_list = NULL; ++ ++ g_assert (BUS_IS_IBUS_IMPL (ibus)); ++ ++ g_list_foreach (ibus->engine_list, (GFunc) g_object_unref, NULL); ++ g_list_free (ibus->engine_list); ++ ++ if (value != NULL && g_variant_classify (value) == G_VARIANT_CLASS_ARRAY) { ++ GVariantIter iter; ++ g_variant_iter_init (&iter, value); ++ const gchar *engine_name = NULL; ++ while (g_variant_iter_loop (&iter, "&s", &engine_name)) { ++ IBusEngineDesc *engine = bus_registry_find_engine_by_name (ibus->registry, engine_name); ++ if (engine == NULL || g_list_find (engine_list, engine) != NULL) ++ continue; ++ engine_list = g_list_append (engine_list, engine); ++ } ++ ++ if (engine_list != NULL && ++ ibus->config != NULL) { ++ /* sync function will effects the startup performance. ++ * We'd always like to save the value so that ibus-setup ++ * get the updated engine list. */ ++ ibus_config_get_value_async (ibus->config, "general", ++ "preload_engines", ++ -1, ++ NULL, ++ _preload_engines_config_get_value_done, ++ g_variant_ref_sink (value)); ++ } else { ++ /* We don't update preload_engines with an empty string for safety. ++ * Just unref the floating value. */ ++ g_variant_unref (value); ++ } ++ } else if (value != NULL) { ++ g_variant_unref (value); ++ } ++ ++ g_list_foreach (engine_list, (GFunc) g_object_ref, NULL); ++ ibus->engine_list = engine_list; ++ ++ if (ibus->engine_list) { ++ BusComponent *component = bus_component_from_engine_desc ((IBusEngineDesc *) ibus->engine_list->data); ++ if (component && !bus_component_is_running (component)) { ++ bus_component_start (component, g_verbose); ++ } ++ } ++ ++ bus_ibus_impl_check_global_engine (ibus); ++ bus_ibus_impl_update_engines_hotkey_profile (ibus); ++} ++ ++#ifndef OS_CHROMEOS ++static void ++_set_language_relative_preload_engines (BusIBusImpl *ibus) ++{ ++ gchar *lang = NULL; ++ gchar *p = NULL; ++ GList *engines = NULL; ++ GList *list; ++ GVariantBuilder builder; ++ ++ g_assert (BUS_IS_IBUS_IMPL (ibus)); ++ ++ /* The setlocale call first checks LC_ALL. If it's not available, checks ++ * LC_CTYPE. If it's also not available, checks LANG. */ ++ lang = g_strdup (setlocale (LC_CTYPE, NULL)); ++ if (lang == NULL) { ++ return; ++ } ++ ++ p = index (lang, '.'); ++ if (p) { ++ *p = '\0'; ++ } ++ ++ engines = bus_registry_get_engines_by_language (ibus->registry, lang); ++ if (engines == NULL) { ++ p = index (lang, '_'); ++ if (p) { ++ *p = '\0'; ++ engines = bus_registry_get_engines_by_language (ibus->registry, lang); ++ } ++ } ++ g_free (lang); ++ ++ /* sort engines by rank */ ++ engines = g_list_sort (engines, (GCompareFunc) _engine_desc_cmp); ++ ++ g_variant_builder_init (&builder, G_VARIANT_TYPE ("as")); ++ for (list = engines; list != NULL; list = list->next) { ++ IBusEngineDesc *desc = (IBusEngineDesc *)list->data; ++ /* ignore engines with rank <== 0 */ ++ if (ibus_engine_desc_get_rank (desc) > 0) ++ g_variant_builder_add (&builder, "s", ibus_engine_desc_get_name (desc)); ++ } ++ _set_preload_engines (ibus, g_variant_builder_end (&builder)); ++ g_list_free (engines); ++} ++#endif ++ ++static void + bus_ibus_impl_set_hotkey (BusIBusImpl *ibus, + GQuark hotkey, + GVariant *value) +@@ -392,35 +658,50 @@ + bus_ibus_impl_set_preload_engines (BusIBusImpl *ibus, + GVariant *value) + { +- GList *engine_list = NULL; +- +- g_list_foreach (ibus->engine_list, (GFunc) g_object_unref, NULL); +- g_list_free (ibus->engine_list); ++#ifndef OS_CHROMEOS ++ gint preload_engine_mode = _get_config_preload_engine_mode (ibus); + +- if (value != NULL && g_variant_classify (value) == G_VARIANT_CLASS_ARRAY) { +- GVariantIter iter; +- g_variant_iter_init (&iter, value); +- const gchar *engine_name = NULL; +- while (g_variant_iter_loop (&iter, "&s", &engine_name)) { +- IBusEngineDesc *engine = bus_registry_find_engine_by_name (ibus->registry, engine_name); +- if (engine == NULL || g_list_find (engine_list, engine) != NULL) +- continue; +- engine_list = g_list_append (engine_list, engine); ++ if (preload_engine_mode == IBUS_PRELOAD_ENGINE_MODE_USER) { ++ if (value == NULL) { ++ _set_language_relative_preload_engines (ibus); ++ } else { ++ _set_preload_engines (ibus, value); + } + } ++#else ++ _set_preload_engines (ibus, value); ++#endif ++} + +- g_list_foreach (engine_list, (GFunc) g_object_ref, NULL); +- ibus->engine_list = engine_list; ++/** ++ * bus_ibus_impl_set_preload_engine_mode: ++ * ++ * A function to be called when "preload_engine_mode" config is updated. ++ */ ++static void ++bus_ibus_impl_set_preload_engine_mode (BusIBusImpl *ibus, ++ GVariant *value) ++{ ++#ifndef OS_CHROMEOS ++ gint preload_engine_mode = IBUS_PRELOAD_ENGINE_MODE_USER; + +- if (ibus->engine_list) { +- BusComponent *component = bus_component_from_engine_desc ((IBusEngineDesc *) ibus->engine_list->data); +- if (component && !bus_component_is_running (component)) { +- bus_component_start (component, g_verbose); +- } ++ /* bus_ibus_impl_reload_config() sets value = NULL. ++ * bus_ibus_impl_reload_config() is always called when ++ * RequestName signal is sent so it is good to get the gconf value ++ * again when value == NULL. ++ */ ++ if (value != NULL && g_variant_classify (value) == G_VARIANT_CLASS_INT32) { ++ preload_engine_mode = g_variant_get_int32 (value); ++ } else { ++ preload_engine_mode = _get_config_preload_engine_mode (ibus); + } + +- bus_ibus_impl_check_global_engine (ibus); +- bus_ibus_impl_update_engines_hotkey_profile (ibus); ++ if (preload_engine_mode == IBUS_PRELOAD_ENGINE_MODE_USER) { ++ return; ++ } ++ ++ _set_language_relative_preload_engines (ibus); ++#endif + } + + /** +@@ -501,89 +782,47 @@ + } + } + +-#ifndef OS_CHROMEOS +-static gint +-_engine_desc_cmp (IBusEngineDesc *desc1, +- IBusEngineDesc *desc2) +-{ +- return - ((gint) ibus_engine_desc_get_rank (desc1)) + +- ((gint) ibus_engine_desc_get_rank (desc2)); +-} +-#endif +- + /** + * bus_ibus_impl_set_default_preload_engines: + * +- * If the "preload_engines" config variable is not set yet, set the default value which is determined based on a current locale. ++ * bus_ibus_impl_set_default_preload_engines handles the gconf value ++ * /desktop/ibus/general/preload_engines and preload_engine_mode. ++ * 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 gconf 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 gconf 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'. + */ + static void + bus_ibus_impl_set_default_preload_engines (BusIBusImpl *ibus) + { + #ifndef OS_CHROMEOS +- g_assert (BUS_IS_IBUS_IMPL (ibus)); +- + static gboolean done = FALSE; ++ gint preload_engine_mode = IBUS_PRELOAD_ENGINE_MODE_USER; ++ ++ g_assert (BUS_IS_IBUS_IMPL (ibus)); + + if (done || ibus->config == NULL) { + return; + } + +- GVariant *variant = ibus_config_get_value (ibus->config, "general", "preload_engines"); +- if (variant != NULL) { ++ preload_engine_mode = _get_config_preload_engine_mode (ibus); ++ ++ if (preload_engine_mode == IBUS_PRELOAD_ENGINE_MODE_USER) { + done = TRUE; +- g_variant_unref (variant); + return; + } + + done = TRUE; +- +- /* The setlocale call first checks LC_ALL. If it's not available, checks +- * LC_CTYPE. If it's also not available, checks LANG. */ +- gchar *lang = g_strdup (setlocale (LC_CTYPE, NULL)); +- if (lang == NULL) { +- return; +- } +- +- gchar *p = index (lang, '.'); +- if (p) { +- *p = '\0'; +- } +- +- GList *engines = bus_registry_get_engines_by_language (ibus->registry, lang); +- if (engines == NULL) { +- p = index (lang, '_'); +- if (p) { +- *p = '\0'; +- engines = bus_registry_get_engines_by_language (ibus->registry, lang); +- } +- } +- g_free (lang); +- +- /* sort engines by rank */ +- engines = g_list_sort (engines, (GCompareFunc) _engine_desc_cmp); +- +- GVariantBuilder builder; +- g_variant_builder_init (&builder, G_VARIANT_TYPE ("as")); +- GList *list; +- for (list = engines; list != NULL; list = list->next) { +- IBusEngineDesc *desc = (IBusEngineDesc *) list->data; +- /* ignore engines with rank <= 0 */ +- if (ibus_engine_desc_get_rank (desc) > 0) +- g_variant_builder_add (&builder, "s", ibus_engine_desc_get_name (desc)); +- } +- +- GVariant *value = g_variant_builder_end (&builder); +- if (value != NULL) { +- if (g_variant_n_children (value) > 0) { +- ibus_config_set_value (ibus->config, +- "general", "preload_engines", value); +- } else { +- /* We don't update preload_engines with an empty string for safety. +- * Just unref the floating value. */ +- g_variant_unref (value); +- } +- } +- g_list_free (engines); ++ _set_language_relative_preload_engines (ibus); + #endif + } + +@@ -599,6 +838,7 @@ + { "general/hotkey", "next_engine_in_menu", bus_ibus_impl_set_next_engine_in_menu }, + { "general/hotkey", "previous_engine", bus_ibus_impl_set_previous_engine }, + { "general", "preload_engines", bus_ibus_impl_set_preload_engines }, ++ { "general", "preload_engine_mode", bus_ibus_impl_set_preload_engine_mode }, + { "general", "use_system_keyboard_layout", bus_ibus_impl_set_use_sys_layout }, + { "general", "use_global_engine", bus_ibus_impl_set_use_global_engine }, + { "general", "embed_preedit_text", bus_ibus_impl_set_embed_preedit_text }, +--- a/data/ibus.schemas.in ++++ b/data/ibus.schemas.in +@@ -6,7 +6,7 @@ + /desktop/ibus/general/preload_engines + ibus + list +- [] ++ [ibus_null_engine] + string + + Preload engines +@@ -14,6 +14,19 @@ + + + ++ /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/hotkey/trigger + /desktop/ibus/general/hotkey/trigger + ibus +--- a/ibus/common.py ++++ b/ibus/common.py +@@ -40,6 +40,8 @@ + "BUS_REQUEST_NAME_REPLY_IN_QUEUE", + "BUS_REQUEST_NAME_REPLY_EXISTS", + "BUS_REQUEST_NAME_REPLY_ALREADY_OWNER", ++ "PRELOAD_ENGINE_MODE_USER", ++ "PRELOAD_ENGINE_MODE_LANG_RELATIVE", + "default_reply_handler", + "default_error_handler", + "DEFAULT_ASYNC_HANDLERS", +@@ -150,6 +152,10 @@ + BUS_REQUEST_NAME_REPLY_EXISTS = 3 + BUS_REQUEST_NAME_REPLY_ALREADY_OWNER = 4 + ++# define preload engine mode ++PRELOAD_ENGINE_MODE_USER = 0 ++PRELOAD_ENGINE_MODE_LANG_RELATIVE = 1 ++ + def default_reply_handler( *args): + pass + +--- a/setup/main.py ++++ b/setup/main.py +@@ -91,6 +91,7 @@ + # keyboard shortcut + # trigger + self.__config = self.__bus.get_config() ++ self.__config.connect("value-changed", self.__config_value_changed_cb) + shortcuts = self.__config.get_value( + "general/hotkey", "trigger", + ibus.CONFIG_GENERAL_SHORTCUT_TRIGGER_DEFAULT) +@@ -212,15 +213,22 @@ + self.__checkbutton_use_global_engine.connect("toggled", self.__checkbutton_use_global_engine_toggled_cb) + + # init engine page ++ preload_engine_mode = self.__config.get_value("general", ++ "preload_engine_mode", ++ ibus.common.PRELOAD_ENGINE_MODE_USER) ++ button = self.__builder.get_object("checkbutton_preload_engine_mode") ++ if preload_engine_mode == ibus.common.PRELOAD_ENGINE_MODE_USER: ++ button.set_active(True) ++ self.__builder.get_object("hbox_customize_active_input_methods").set_sensitive(True) ++ else: ++ button.set_active(False) ++ self.__builder.get_object("hbox_customize_active_input_methods").set_sensitive(False) ++ button.connect("toggled", self.__checkbutton_preload_engine_mode_toggled_cb) + self.__engines = self.__bus.list_engines() + self.__combobox = self.__builder.get_object("combobox_engines") + self.__combobox.set_engines(self.__engines) + +- tmp_dict = {} +- for e in self.__engines: +- tmp_dict[e.name] = e +- engine_names = self.__config.get_value("general", "preload_engines", []) +- engines = [tmp_dict[name] for name in engine_names if name in tmp_dict] ++ engines = self.__bus.list_active_engines() + + self.__treeview = self.__builder.get_object("treeview_engines") + self.__treeview.set_engines(engines) +@@ -248,7 +256,8 @@ + 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.name not in map(lambda e: e.name, self.__treeview.get_engines())) + + def __get_engine_setup_exec_args(self, engine): + args = [] +@@ -290,6 +299,26 @@ + engine_names = map(lambda e: e.name, engines) + self.__config.set_list("general", "preload_engines", engine_names, "s") + ++ def __get_engine_descs_from_names(self, engine_names): ++ tmp_dict = {} ++ for e in self.__engines: ++ tmp_dict[e.name] = e ++ engines = [tmp_dict[name] for name in engine_names if name in tmp_dict] ++ return engines ++ ++ def __compare_descs(self, engines_a, engines_b): ++ engines = engines_a ++ concat_engine_names = "" ++ for engine in engines: ++ concat_engine_names = "%s::%s" % (concat_engine_names, engine.name) ++ concat_engine_names_a = concat_engine_names ++ engines = engines_b ++ concat_engine_names = "" ++ for engine in engines: ++ concat_engine_names = "%s::%s" % (concat_engine_names, engine.name) ++ concat_engine_names_b = concat_engine_names ++ return concat_engine_names_a == concat_engine_names_b ++ + def __button_engine_add_cb(self, button): + engine = self.__combobox.get_active_engine() + self.__treeview.append_engine(engine) +@@ -319,6 +348,32 @@ + 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.__config.set_value("general", ++ "preload_engine_mode", ++ ibus.common.PRELOAD_ENGINE_MODE_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.MESSAGE_QUESTION, ++ buttons = gtk.BUTTONS_YES_NO, ++ message_format = message) ++ id = dlg.run() ++ dlg.destroy() ++ self.__flush_gtk_events() ++ if id != gtk.RESPONSE_YES: ++ button.set_active(True) ++ return ++ self.__config.set_value("general", ++ "preload_engine_mode", ++ ibus.common.PRELOAD_ENGINE_MODE_LANG_RELATIVE) ++ self.__builder.get_object("hbox_customize_active_input_methods").set_sensitive(False) ++ + def __init_bus(self): + try: + self.__bus = ibus.Bus() +@@ -506,7 +561,11 @@ + self.__config.set_value("general", "use_global_engine", value) + + def __config_value_changed_cb(self, bus, section, name, value): +- pass ++ if section == 'general' and name == 'preload_engines': ++ engines = self.__get_engine_descs_from_names(value) ++ current_engines = self.__treeview.get_engines() ++ if self.__compare_descs(engines, current_engines) == False: ++ self.__treeview.set_engines(engines) + + def __config_reloaded_cb(self, bus): + pass +--- a/setup/setup.ui ++++ b/setup/setup.ui +@@ -585,7 +585,22 @@ + True + vertical + +- ++ ++ True ++ Customize active input _methods ++ True ++ True ++ False ++ Customize active input methods ++ True ++ ++ ++ False ++ 0 ++ ++ ++ ++ + True + + +@@ -752,7 +767,7 @@ + + + +- 0 ++ 1 + + + +@@ -791,7 +806,7 @@ + + + False +- 1 ++ 2 + + + +--- a/src/ibustypes.h ++++ b/src/ibustypes.h +@@ -198,6 +198,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 -Nru ibus-1.4.1/debian/patches/series ibus-1.4.1/debian/patches/series --- ibus-1.4.1/debian/patches/series 2012-02-12 16:46:36.000000000 +0900 +++ ibus-1.4.1/debian/patches/series 2012-03-21 21:38:44.000000000 +0900 @@ -1,2 +1,5 @@ proper-gtk-plugin-path.patch g-ir-scanner-pkg-export.patch +02_title_update.patch +05_appindicator.patch +ibus-530711-preload-sys.patch diff -Nru ibus-1.4.1/debian/rules ibus-1.4.1/debian/rules --- ibus-1.4.1/debian/rules 2012-03-16 22:07:20.000000000 +0900 +++ ibus-1.4.1/debian/rules 2012-03-21 21:43:02.000000000 +0900 @@ -1,6 +1,6 @@ #!/usr/bin/make -f %: - dh $@ --with python2 --with autoreconf + dh $@ --with python2 --with autoreconf --with translations override_dh_auto_configure: dh_auto_configure -- \