From c907ff38e6f6de6637d79945efb9d1365b15a327 Mon Sep 17 00:00:00 2001 From: fujiwarat Date: Fri, 19 Apr 2013 09:47:18 +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'. --- data/ibus.schemas.in | 24 +++++++++ setup/main.py | 73 ++++++++++++++++++++++++--- setup/setup.ui | 22 +++++++-- src/ibustypes.h | 10 ++++ ui/gtk3/panel.vala | 136 +++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 254 insertions(+), 11 deletions(-) diff --git a/data/ibus.schemas.in b/data/ibus.schemas.in index 704ba60..136c192 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 707faa4..4826037 100644 --- a/setup/main.py +++ b/setup/main.py @@ -190,16 +190,27 @@ class Setup(object): self.__checkbutton_use_global_engine.connect("toggled", self.__checkbutton_use_global_engine_toggled_cb) + # set preload mode + preload_engine_mode = IBus.PreloadEngineMode.USER + variant = self.__config.get_value("general", "preload_engine_mode") + if variant != None: + preload_engine_mode = variant.get_int32() + button = self.__builder.get_object("checkbutton_preload_engine_mode") + if preload_engine_mode == IBus.PreloadEngineMode.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) + # 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 = values.get("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) @@ -243,6 +254,7 @@ class Setup(object): self.__checkbutton_auto_start_toggled_cb) self.__config = self.__bus.get_config() + self.__config.connect("value-changed", self.__config_value_changed_cb) self.__init_hotkey() self.__init_panel() @@ -251,8 +263,8 @@ class Setup(object): def __combobox_notify_active_engine_cb(self, combobox, property): engine = self.__combobox.get_active_engine() button = self.__builder.get_object("button_engine_add") - button.set_sensitive( - engine != None and engine not in self.__treeview.get_engines()) + button.set_sensitive(engine != None and \ + engine.get_name() not in map(lambda e: e.get_name(), self.__treeview.get_engines())) def __get_engine_setup_exec_args(self, engine): args = [] @@ -272,6 +284,13 @@ class Setup(object): 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 @@ -324,6 +343,34 @@ class Setup(object): 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(): + variant = GLib.Variant.new_int32(IBus.PreloadEngineMode.USER) + self.__config.set_value("general", + "preload_engine_mode", + variant) + 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 + variant = GLib.Variant.new_int32(IBus.PreloadEngineMode.LANG_RELATIVE) + self.__config.set_value("general", + "preload_engine_mode", + variant) + self.__builder.get_object("hbox_customize_active_input_methods").set_sensitive(False) + def __init_bus(self): self.__bus = IBus.Bus() if self.__bus.is_connected(): @@ -538,8 +585,18 @@ class Setup(object): value = GLib.Variant.new_boolean(value) self.__config.set_value("general", "use_global_engine", value) - def __config_value_changed_cb(self, bus, section, name, value): - pass + def __config_value_changed_cb(self, bus, section, name, variant): + if section == 'general' and name == 'preload_engines': + value = [] + if variant != None: + value = variant.unpack() + engines = self.__get_engine_descs_from_names(value) + current_engines = self.__treeview.get_engines() + engines_csv = str.join(',', map(lambda e: e.get_name(), engines)) + current_engines_csv = \ + str.join(',', map(lambda e: e.get_name(), current_engines)) + if engines_csv != current_engines_csv: + self.__treeview.set_engines(engines) def __config_reloaded_cb(self, bus): pass diff --git a/setup/setup.ui b/setup/setup.ui index e56e917..b3165aa 100644 --- a/setup/setup.ui +++ b/setup/setup.ui @@ -669,7 +669,23 @@ True False - + + True + Customize active input _methods + True + True + False + Customize active input methods + True + + + False + True + 0 + + + + True False @@ -858,7 +874,7 @@ True True - 0 + 1 @@ -905,7 +921,7 @@ You may use up/down buttons to change it.</i></small> False True - 1 + 2 diff --git a/src/ibustypes.h b/src/ibustypes.h index 737b3e2..8ce5a16 100644 --- a/src/ibustypes.h +++ b/src/ibustypes.h @@ -204,6 +204,16 @@ typedef enum { } 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 10eaa0c..0a12c0f 100644 --- a/ui/gtk3/panel.vala +++ b/ui/gtk3/panel.vala @@ -308,6 +308,8 @@ class Panel : IBus.PanelService { if (m_config != null) { m_config.value_changed.connect(config_value_changed_cb); m_config.watch("general", "preload_engines"); + m_config.watch("general", "preload_engines_inited"); + m_config.watch("general", "preload_engine_mode"); m_config.watch("general", "engines_order"); m_config.watch("general", "switcher_delay_time"); m_config.watch("general", "use_system_keyboard_layout"); @@ -379,7 +381,136 @@ class Panel : IBus.PanelService { init_gkbd(); } + GLib.Variant var_engines = + m_config.get_value("general", "preload_engines"); + string[] preload_engines = {}; + + if (var_engines != null) { + preload_engines = var_engines.dup_strv(); + } + + bool preload_engines_inited = false; + GLib.Variant var_preload_engines_inited = + m_config.get_value("general", "preload_engines_inited"); + + if (var_preload_engines_inited != null) { + preload_engines_inited = var_preload_engines_inited.get_boolean(); + } + + // Set preload_engines_inited = true for back compatibility + if (preload_engines.length != 0 && !preload_engines_inited) { + preload_engines_inited = true; + m_config.set_value("general", + "preload_engines_inited", + new GLib.Variant.boolean(true)); + } + update_xkb_engines(); + + // Before update preload_engine_mode, update_xkb_engines() is called + // because config_value_changed_cb() calls update_im_engines(). + if (!preload_engines_inited) { + GLib.Variant variant = new GLib.Variant.int32( + IBus.PreloadEngineMode.LANG_RELATIVE); + m_config.set_value("general", + "preload_engine_mode", + variant); + } + + update_im_engines(); + + if (!preload_engines_inited) { + m_config.set_value("general", + "preload_engines_inited", + new GLib.Variant.boolean(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; + } + + GLib.Variant var_engines = + m_config.get_value("general", "preload_engines"); + string[] orig_preload_engines = {}; + string[] preload_engines = {}; + + if (var_engines != null) { + orig_preload_engines = var_engines.dup_strv(); + } + + // 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 ("".joinv(",", orig_preload_engines) != + "".joinv(",", preload_engines)) { + m_config.set_value("general", + "preload_engines", + new GLib.Variant.strv(preload_engines)); + } + + return true; + } + + private void update_im_engines() { + int preload_engine_mode = IBus.PreloadEngineMode.USER; + GLib.Variant var_preload_engine_mode = + m_config.get_value("general", "preload_engine_mode"); + + if (var_preload_engine_mode != null) { + preload_engine_mode = var_preload_engine_mode.get_int32(); + } + + if (preload_engine_mode == IBus.PreloadEngineMode.USER) { + return; + } + + set_lang_relative_preload_engines(); } private void update_xkb_engines() { @@ -596,6 +727,11 @@ class Panel : IBus.PanelService { string section, string name, Variant variant) { + if (section == "general" && name == "preload_engine_mode") { + update_im_engines(); + return; + } + if (section == "general" && name == "preload_engines") { update_engines(variant, null); return; -- 1.8.0