From aef8d6fa4118336f562f74580f0f1986d8054be5 Mon Sep 17 00:00:00 2001 From: fujiwarat Date: Wed, 26 Jan 2011 15:42: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_LANG_RELATIVE by default. 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'. Loading system default may spend the startup time. If you mind it, your dist may like to put TRUE in 'use_local_preload_engines' value. --- bus/ibusimpl.c | 241 ++++++++++++++++++++++++++++++++++---------------- data/ibus.schemas.in | 13 +++ ibus/common.py | 6 ++ setup/main.py | 37 +++++++- setup/setup.ui | 21 ++++- src/ibustypes.h | 10 ++ 6 files changed, 242 insertions(+), 86 deletions(-) diff --git a/bus/ibusimpl.c b/bus/ibusimpl.c index cbcf7f4..1bb159e 100644 --- a/bus/ibusimpl.c +++ b/bus/ibusimpl.c @@ -144,6 +144,9 @@ static void bus_ibus_impl_set_previo 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); @@ -270,6 +273,123 @@ _panel_destroy_cb (BusPanelProxy *panel, g_object_unref (panel); } +static gint +_engine_desc_cmp (IBusEngineDesc *desc1, + IBusEngineDesc *desc2) +{ + return - ((gint) ibus_engine_desc_get_rank (desc1)) + + ((gint) ibus_engine_desc_get_rank (desc2)); +} + +static gint +_get_config_preload_engine_mode (BusIBusImpl *ibus) +{ + GVariant *variant = NULL; + gint preload_engine_mode = IBUS_PRELOAD_ENGINE_MODE_LANG_RELATIVE; + + g_assert (BUS_IS_IBUS_IMPL (ibus)); + + if (ibus->config == NULL) { + return preload_engine_mode; + } + + 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; +} + +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 && + ibus_config_get_value (ibus->config, "general", + "preload_engines") == NULL) { + ibus_config_set_value (ibus->config, "general", + "preload_engines", 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_update_engines_hotkey_profile (ibus); +} + +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)); + + lang = g_strdup (setlocale (LC_ALL, NULL)); + 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); +} + static void bus_ibus_impl_set_hotkey (BusIBusImpl *ibus, GQuark hotkey, @@ -354,34 +474,32 @@ static void bus_ibus_impl_set_preload_engines (BusIBusImpl *ibus, GVariant *value) { - GList *engine_list = NULL; + gint preload_engine_mode = _get_config_preload_engine_mode (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 (preload_engine_mode == IBUS_PRELOAD_ENGINE_MODE_USER) { + if (value == NULL) { + _set_language_relative_preload_engines (ibus); + } else { + _set_preload_engines (ibus, value); } } +} - g_list_foreach (engine_list, (GFunc) g_object_ref, NULL); - ibus->engine_list = engine_list; +static void +bus_ibus_impl_set_preload_engine_mode (BusIBusImpl *ibus, + GVariant *value) +{ + gint preload_engine_mode = IBUS_PRELOAD_ENGINE_MODE_LANG_RELATIVE; - 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); - } + if (value != NULL && g_variant_classify (value) == G_VARIANT_CLASS_INT32) { + preload_engine_mode = g_variant_get_int32 (value); } - bus_ibus_impl_update_engines_hotkey_profile (ibus); + if (preload_engine_mode == IBUS_PRELOAD_ENGINE_MODE_USER) { + return; + } + + _set_language_relative_preload_engines (ibus); } /** @@ -459,79 +577,47 @@ bus_ibus_impl_set_use_global_engine (Bus } } -static gint -_engine_desc_cmp (IBusEngineDesc *desc1, - IBusEngineDesc *desc2) -{ - return - ((gint) ibus_engine_desc_get_rank (desc1)) + - ((gint) ibus_engine_desc_get_rank (desc2)); -} - /** * 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 (LC_ALL). + * 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. + * 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'. + * Loading system default may spend the startup time. If you mind it, + * your dist may like to put TRUE in 'use_local_preload_engines' value. */ static void bus_ibus_impl_set_default_preload_engines (BusIBusImpl *ibus) { - g_assert (BUS_IS_IBUS_IMPL (ibus)); - static gboolean done = FALSE; + gint preload_engine_mode = IBUS_PRELOAD_ENGINE_MODE_LANG_RELATIVE; + + 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; - gchar *lang = g_strdup (setlocale (LC_ALL, NULL)); - 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); } /* The list of config entries that are related to ibus-daemon. */ @@ -544,6 +630,7 @@ const static struct { { "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 }, diff --git a/data/ibus.schemas.in b/data/ibus.schemas.in index 54709ce..2ed0321 100644 --- a/data/ibus.schemas.in +++ b/data/ibus.schemas.in @@ -13,6 +13,19 @@ + /schemas/desktop/ibus/general/preload_engine_mode + /desktop/ibus/general/preload_engine_mode + ibus + int + 1 + + 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 diff --git a/ibus/common.py b/ibus/common.py index 763ed1c..1264787 100644 --- a/ibus/common.py +++ b/ibus/common.py @@ -33,6 +33,8 @@ __all__ = ( "ORIENTATION_HORIZONTAL", "ORIENTATION_VERTICAL", "ORIENTATION_SYSTEM", + "PRELOAD_ENGINE_MODE_USER", + "PRELOAD_ENGINE_MODE_LANG_RELATIVE", "default_reply_handler", "default_error_handler", "DEFAULT_ASYNC_HANDLERS", @@ -133,6 +135,10 @@ ORIENTATION_HORIZONTAL = 0 ORIENTATION_VERTICAL = 1 ORIENTATION_SYSTEM = 2 +# define preload engine mode +PRELOAD_ENGINE_MODE_USER = 0 +PRELOAD_ENGINE_MODE_LANG_RELATIVE = 1 + def default_reply_handler( *args): pass diff --git a/setup/main.py b/setup/main.py index 8bac900..c855b86 100644 --- a/setup/main.py +++ b/setup/main.py @@ -191,15 +191,22 @@ class Setup(object): 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) @@ -243,6 +250,13 @@ class Setup(object): 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 __button_engine_add_cb(self, button): engine = self.__combobox.get_active_engine() self.__treeview.append_engine(engine) @@ -254,6 +268,19 @@ class Setup(object): about.run() about.destroy() + 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: + 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() diff --git a/setup/setup.ui b/setup/setup.ui index de58446..71f723d 100644 --- a/setup/setup.ui +++ b/setup/setup.ui @@ -486,7 +486,22 @@ True vertical - + + True + Customize active input _methods + True + True + False + Customize active input methods + True + + + False + 0 + + + + True @@ -637,7 +652,7 @@ - 0 + 1 @@ -676,7 +691,7 @@ You may use up/down buttons to change it.</i></small> False - 1 + 2 diff --git a/src/ibustypes.h b/src/ibustypes.h index 035d124..0a9d7b2 100644 --- a/src/ibustypes.h +++ b/src/ibustypes.h @@ -144,6 +144,16 @@ typedef enum { } IBusOrientation; /** + * 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. -- 1.7.3.2