" <method name='IsGlobalEngineEnabled'>\n"
" <arg direction='out' type='b' name='enabled' />\n"
" </method>\n"
+ " <method name='PreloadEngines'>\n"
+ " <arg direction='in' type='as' name='names' />\n"
+ " </method>\n"
" <signal name='RegistryChanged'>\n"
" </signal>\n"
" <signal name='GlobalEngineChanged'>\n"
}
/**
+ * _ibus_preload_engines:
+ *
+ * Implement the "PreloadEngines" method call of the
+ * org.freedesktop.IBus interface.
+ */
+static void
+_ibus_preload_engines (BusIBusImpl *ibus,
+ GVariant *parameters,
+ GDBusMethodInvocation *invocation)
+{
+ int i, j;
+ const gchar **names = NULL;
+ IBusEngineDesc *desc = NULL;
+ BusComponent *component = NULL;
+ BusFactoryProxy *factory = NULL;
+ GPtrArray *array = g_ptr_array_new ();
+
+ g_variant_get (parameters, "(^a&s)", &names);
+
+ for (i = 0; names[i] != NULL; i++) {
+ gboolean has_component = FALSE;
+
+ desc = bus_ibus_impl_get_engine_desc(ibus, names[i]);
+
+ if (desc == NULL) {
+ g_dbus_method_invocation_return_error (invocation,
+ G_DBUS_ERROR,
+ G_DBUS_ERROR_FAILED,
+ "Can not find engine %s.",
+ names[i]);
+ g_ptr_array_free (array, FALSE);
+ return;
+ }
+
+ component = bus_component_from_engine_desc (desc);
+ factory = bus_component_get_factory (component);
+
+ if (factory != NULL) {
+ continue;
+ }
+
+ for (j = 0; j < array->len; j++) {
+ if (component == (BusComponent *) g_ptr_array_index (array, j)) {
+ has_component = TRUE;
+ break;
+ }
+ }
+
+ if (!has_component) {
+ g_ptr_array_add (array, component);
+ }
+ }
+
+ for (j = 0; j < array->len; j++) {
+ bus_component_start ((BusComponent *) g_ptr_array_index (array, j),
+ g_verbose);
+ }
+
+ g_ptr_array_free (array, FALSE);
+
+ g_dbus_method_invocation_return_value (invocation, NULL);
+}
+
+/**
* bus_ibus_impl_service_method_call:
*
* Handle a D-Bus method call whose destination and interface name are both "org.freedesktop.IBus"
{ "GetGlobalEngine", _ibus_get_global_engine },
{ "SetGlobalEngine", _ibus_set_global_engine },
{ "IsGlobalEngineEnabled", _ibus_is_global_engine_enabled },
+ { "PreloadEngines", _ibus_preload_engines },
};
gint i;
return _async_finish_void (res, error);
}
+gboolean
+ibus_bus_preload_engines (IBusBus *bus,
+ const gchar * const *names)
+{
+ GVariant *result;
+
+ g_return_val_if_fail (IBUS_IS_BUS (bus), FALSE);
+ g_return_val_if_fail (names != NULL && names[0] != NULL, FALSE);
+
+ result = ibus_bus_call_sync (bus,
+ IBUS_SERVICE_IBUS,
+ IBUS_PATH_IBUS,
+ IBUS_INTERFACE_IBUS,
+ "PreloadEngines",
+ g_variant_new("(^as)", names),
+ NULL);
+
+ if (result) {
+ g_variant_unref (result);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+void
+ibus_bus_preload_engines_async (IBusBus *bus,
+ const gchar * const *names,
+ gint timeout_msec,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ g_return_if_fail (IBUS_IS_BUS (bus));
+ g_return_if_fail (names != NULL && names[0] != NULL);
+
+ ibus_bus_call_async (bus,
+ IBUS_SERVICE_IBUS,
+ IBUS_PATH_IBUS,
+ IBUS_INTERFACE_IBUS,
+ "PreloadEngines",
+ g_variant_new("(^as)", names),
+ NULL, /* no return value */
+ ibus_bus_preload_engines_async,
+ timeout_msec,
+ cancellable,
+ callback,
+ user_data);
+}
+
+gboolean
+ibus_bus_preload_engines_async_finish (IBusBus *bus,
+ GAsyncResult *res,
+ GError **error)
+{
+ g_assert (IBUS_IS_BUS (bus));
+ g_assert (g_simple_async_result_is_valid (
+ res, (GObject *) bus,
+ ibus_bus_preload_engines_async));
+ return _async_finish_void (res, error);
+}
+
static GVariant *
ibus_bus_call_sync (IBusBus *bus,
const gchar *bus_name,
*/
IBusConfig *ibus_bus_get_config (IBusBus *bus);
+/**
+ * ibus_bus_preload_engines:
+ * @bus: An #IBusBus.
+ * @names: (array zero-terminated=1): A %NULL-terminated array of engine names.
+ * @returns: %TRUE if components start. %FALSE otherwise.
+ *
+ * Start bus components by engine names synchronously.
+ */
+gboolean ibus_bus_preload_engines (IBusBus *bus,
+ const gchar * const *names);
+
+/**
+ * ibus_bus_preload_engines_async:
+ * @bus: An #IBusBus.
+ * @names: (array zero-terminated=1): A %NULL-terminated array of engine names.
+ * @timeout_msec: The timeout in milliseconds or -1 to use the default timeout.
+ * @cancellable: A #GCancellable or %NULL.
+ * @callback: A #GAsyncReadyCallback to call when the request is satisfied
+ * or %NULL if you don't care about the result of the method invocation.
+ * @user_data: The data to pass to callback.
+ *
+ * Start bus components by engine names asynchronously.
+ */
+void ibus_bus_preload_engines_async
+ (IBusBus *bus,
+ const gchar * const
+ *names,
+ gint timeout_msec,
+ GCancellable *cancellable,
+ GAsyncReadyCallback
+ callback,
+ gpointer user_data);
+
+/**
+ * ibus_bus_preload_engines_async_finish:
+ * @bus: An #IBusBus.
+ * @res: A #GAsyncResult obtained from the #GAsyncReadyCallback passed to
+ * ibus_bus_preload_engines_async().
+ * @error: Return location for error or %NULL.
+ * @returns: %TRUE if component starts. %FALSE otherwise.
+ *
+ * Finishes an operation started with ibus_bus_preload_engines_async().
+ */
+gboolean ibus_bus_preload_engines_async_finish
+ (IBusBus *bus,
+ GAsyncResult *res,
+ GError **error);
+
G_END_DECLS
#endif
}
static void
+finish_preload_engines_async (GObject *source_object,
+ GAsyncResult *res,
+ gpointer user_data)
+{
+ GError *error = NULL;
+ ibus_bus_preload_engines_async_finish (bus, res, &error);
+ g_debug ("ibus_bus_preload_engines_async_finish: OK");
+ call_next_async_function ();
+}
+
+static void
+start_preload_engines_async (void)
+{
+ const gchar *preload_engines[] = { "xkb:us::eng", NULL };
+
+ ibus_bus_preload_engines_async (
+ bus,
+ preload_engines,
+ -1, /* timeout */
+ NULL, /* cancellable */
+ finish_preload_engines_async,
+ NULL); /* user_data */
+}
+
+static void
finish_exit_async (GObject *source_object,
GAsyncResult *res,
gpointer user_data)
start_is_global_engine_enabled_async,
start_set_global_engine_async,
start_get_global_engine_async,
+ start_preload_engines_async,
start_exit_async,
};
static guint index = 0;
}
}
+ private void run_preload_engines(IBus.EngineDesc[] engines, int index) {
+ string[] names = {};
+
+ if (engines.length <= index) {
+ return;
+ }
+
+ names += engines[index].get_name();
+ m_bus.preload_engines_async(names, -1, null);
+ }
+
private void update_engines(GLib.Variant? var_engines,
GLib.Variant? var_order) {
string[] engine_names = null;
if (m_engines.length == 0) {
m_engines = engines;
switch_engine(0, true);
+ run_preload_engines(engines, 1);
} else {
var current_engine = m_engines[0];
m_engines = engines;
for (i = 0; i < m_engines.length; i++) {
if (current_engine.get_name() == engines[i].get_name()) {
switch_engine(i);
+ if (i != 0) {
+ run_preload_engines(engines, 0);
+ } else {
+ run_preload_engines(engines, 1);
+ }
return;
}
}
switch_engine(0, true);
+ run_preload_engines(engines, 1);
}
}