summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYusuke Sato <yusukes@chromium.org>2011-01-19 09:55:46 +0900
committerYusuke Sato <yusukes@chromium.org>2011-01-19 09:55:50 +0900
commit44155f9608749a0800da214967d6a87317f4b897 (patch)
tree260ffb91e7158d0298536b0442f8d62ffd3c1613
parentb4f36a1fbd5edaba5c6126c34f74376258cef8f6 (diff)
downloadibus-chromeos.tar.gz
Port the following ibus-1.3 patches to 1.4.chromeos
o Temporary fix for a race condition between ibus_config_set_value("preload_engines") and ibus_bus_set_global_engine() https://github.com/ibus/ibus/commit/0f8cc67a33d4c0e1257a016de659f7e7a603bd62 o Fix potential race condition between ibus_config_set_value("preload_engines") and ibus_bus_list_active_engines() https://github.com/ibus/ibus/commit/c7b03330bdb297c9601c83c3ac041661e04fecd3 o Do not block the connection between ibus-daemon and ibus-memconf. https://github.com/ibus/ibus/commit/8df70865024aeab9950ecfcb5a34d45ec012878b Original patches are by Peng Huang and Yusuke Sato. BUG=http://crosbug.com/11032 TEST=see the bug Review URL: http://codereview.appspot.com/4027042/
-rw-r--r--bus/ibusimpl.c56
1 files changed, 55 insertions, 1 deletions
diff --git a/bus/ibusimpl.c b/bus/ibusimpl.c
index c171aaf1..a301d1f8 100644
--- a/bus/ibusimpl.c
+++ b/bus/ibusimpl.c
@@ -583,6 +583,23 @@ bus_ibus_impl_reload_config (BusIBusImpl *ibus)
}
}
+struct _SetValueData {
+ void (* func) (BusIBusImpl *, GVariant *);
+ BusIBusImpl *ibus;
+ GVariant *value;
+};
+typedef struct _SetValueData SetValueData;
+
+static gboolean
+_set_value_in_idle_cb (SetValueData *data)
+{
+ data->func (data->ibus, data->value);
+ g_object_unref (data->ibus);
+ g_variant_unref (data->value);
+ g_slice_free (SetValueData, data);
+ return FALSE;
+}
+
/**
* _config_value_changed_cb:
*
@@ -605,7 +622,16 @@ _config_value_changed_cb (IBusConfig *config,
for (i = 0; i < G_N_ELEMENTS (bus_ibus_impl_config_items); i++) {
if (g_strcmp0 (bus_ibus_impl_config_items[i].section, section) == 0 &&
g_strcmp0 (bus_ibus_impl_config_items[i].key, key) == 0) {
- bus_ibus_impl_config_items[i].func (ibus, value);
+ SetValueData *data = g_slice_new0 (SetValueData);
+
+ data->func = bus_ibus_impl_config_items[i].func;
+ data->ibus = g_object_ref (ibus);
+ data->value = g_variant_ref_sink (value);
+
+ /* Avoid blocking the connection with config process,
+ * we will use idle callback to delay the set function call.
+ */
+ g_idle_add ((GSourceFunc) _set_value_in_idle_cb, data);
break;
}
}
@@ -1561,6 +1587,32 @@ _ibus_list_engines (BusIBusImpl *ibus,
g_dbus_method_invocation_return_value (invocation, g_variant_new ("(av)", &builder));
}
+static void
+_reload_preload_engines (BusIBusImpl *ibus)
+{
+ // Chrome for Chrome OS sometimes calls set_global_engine and
+ // list_active_engine APIs right after updating preload_engines. In this
+ // case, if _ibus_set_global_engine function is called before
+ // _config_value_changed_cb is called, _ibus_set_global_engine would fail
+ // with the "Invalid engine name" error. The same is true for the list
+ // active engines API -- the function might return an obsolete list.
+ // To resolve the issues, this function force to update ibus->engine_list by
+ // fetching the latest config from the config daemon.
+ //
+ // Note that this is NOT a perfect solution. e.g. other functions that calls
+ // _find_engine_desc_by_name might still fail. We might also have to do the
+ // same for other config keys like "use_global_engine". So, for now, we use
+ // this hack only on Chrome OS.
+ if (ibus->config == NULL)
+ return;
+ GVariant *value = ibus_config_get_value (ibus->config,
+ "general", "preload_engines");
+ if (value) {
+ bus_ibus_impl_set_preload_engines (ibus, value);
+ g_variant_unref (value);
+ }
+}
+
/**
* _ibus_list_active_engines:
*
@@ -1573,6 +1625,7 @@ _ibus_list_active_engines (BusIBusImpl *ibus,
{
GVariantBuilder builder;
g_variant_builder_init (&builder, G_VARIANT_TYPE ("av"));
+ _reload_preload_engines (ibus);
GList *p;
for (p = ibus->engine_list; p != NULL; p = p->next) {
@@ -1776,6 +1829,7 @@ _ibus_set_global_engine (BusIBusImpl *ibus,
return;
}
+ _reload_preload_engines (ibus);
IBusEngineDesc *desc = _find_engine_desc_by_name (ibus, new_engine_name);
if (desc == NULL) {
g_dbus_method_invocation_return_error (invocation,