[glib/wip/oholy/gappinfo-async: 1/4] gfile: Add g_file_query_default_handler_async()
- From: Ondrej Holy <oholy src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib/wip/oholy/gappinfo-async: 1/4] gfile: Add g_file_query_default_handler_async()
- Date: Mon, 28 Jan 2019 10:20:51 +0000 (UTC)
commit 1f1ef2da6e2293cd92288fd86e06873a8676e8cb
Author: Ondrej Holy <oholy redhat com>
Date: Tue Jan 22 15:37:44 2019 +0100
gfile: Add g_file_query_default_handler_async()
This is needed as a first step to fix the
g_app_info_launch_default_for_uri_async() function to be really
asynchronous.
It still uses the g_app_info_get_default_for_uri_scheme() and
g_app_info_get_default_for_type() functions, which may use synchronous
calls to local MIME DB.
This also fixes one leak in g_file_query_default_handler()
implementation.
https://gitlab.gnome.org/GNOME/glib/issues/1347
https://gitlab.gnome.org/GNOME/glib/issues/1249
docs/reference/gio/gio-sections.txt | 2 +
gio/gfile.c | 125 ++++++++++++++++++++++++++++++++++++
gio/gfile.h | 11 ++++
3 files changed, 138 insertions(+)
---
diff --git a/docs/reference/gio/gio-sections.txt b/docs/reference/gio/gio-sections.txt
index 1fe37e488..ea53d2624 100644
--- a/docs/reference/gio/gio-sections.txt
+++ b/docs/reference/gio/gio-sections.txt
@@ -125,6 +125,8 @@ g_file_query_filesystem_info
g_file_query_filesystem_info_async
g_file_query_filesystem_info_finish
g_file_query_default_handler
+g_file_query_default_handler_async
+g_file_query_default_handler_finish
g_file_measure_disk_usage
g_file_measure_disk_usage_async
g_file_measure_disk_usage_finish
diff --git a/gio/gfile.c b/gio/gfile.c
index a5709a4cc..c7926478c 100644
--- a/gio/gfile.c
+++ b/gio/gfile.c
@@ -6851,6 +6851,8 @@ g_file_query_default_handler (GFile *file,
if (appinfo != NULL)
return appinfo;
}
+ else
+ g_free (uri_scheme);
info = g_file_query_info (file,
G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
@@ -6883,6 +6885,129 @@ g_file_query_default_handler (GFile *file,
return NULL;
}
+static void
+query_default_handler_query_info_cb (GObject *object,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GFile *file = G_FILE (object);
+ GTask *task = G_TASK (user_data);
+ GError *error = NULL;
+ GFileInfo *info;
+ const char *content_type;
+ GAppInfo *appinfo = NULL;
+
+ info = g_file_query_info_finish (file, result, &error);
+ if (info == NULL)
+ {
+ g_task_return_error (task, g_steal_pointer (&error));
+ g_object_unref (task);
+ return;
+ }
+
+ content_type = g_file_info_get_content_type (info);
+ if (content_type)
+ {
+ char *path;
+
+ /* Don't use is_native(), as we want to support fuse paths if available */
+ path = g_file_get_path (file);
+
+ /* FIXME: The following still uses blocking calls. */
+ appinfo = g_app_info_get_default_for_type (content_type,
+ path == NULL);
+ g_free (path);
+ }
+
+ g_object_unref (info);
+
+ if (appinfo != NULL)
+ g_task_return_pointer (task, g_steal_pointer (&appinfo), g_object_unref);
+ else
+ g_task_return_new_error (task,
+ G_IO_ERROR,
+ G_IO_ERROR_NOT_SUPPORTED,
+ _("No application is registered as handling this file"));
+ g_object_unref (task);
+}
+
+/**
+ * g_file_query_default_handler_async:
+ * @file: a #GFile to open
+ * @cancellable: optional #GCancellable object, %NULL to ignore
+ * @callback: (nullable): a #GAsyncReadyCallback to call when the request is done
+ * @user_data: (nullable): data to pass to @callback
+ *
+ * Async version of g_file_query_default_handler().
+ *
+ * Since: 2.60
+ */
+void
+g_file_query_default_handler_async (GFile *file,
+ int io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GTask *task;
+ char *uri_scheme;
+
+ task = g_task_new (file, cancellable, callback, user_data);
+ g_task_set_source_tag (task, g_file_query_default_handler_async);
+
+ uri_scheme = g_file_get_uri_scheme (file);
+ if (uri_scheme && uri_scheme[0] != '\0')
+ {
+ GAppInfo *appinfo;
+
+ /* FIXME: The following still uses blocking calls. */
+ appinfo = g_app_info_get_default_for_uri_scheme (uri_scheme);
+ g_free (uri_scheme);
+
+ if (appinfo != NULL)
+ {
+ g_task_return_pointer (task, g_steal_pointer (&appinfo), g_object_unref);
+ g_object_unref (task);
+ return;
+ }
+ }
+ else
+ g_free (uri_scheme);
+
+ g_file_query_info_async (file,
+ G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE,
+ 0,
+ io_priority,
+ cancellable,
+ query_default_handler_query_info_cb,
+ g_steal_pointer (&task));
+}
+
+/**
+ * g_file_query_default_handler_finish:
+ * @file: a #GFile to open
+ * @result: a #GAsyncResult
+ * @error: (nullable): a #GError
+ *
+ * Finishes g_file_query_default_handler_async() operation.
+ *
+ * Returns: (transfer full): a #GAppInfo if the handle was found,
+ * %NULL if there were errors.
+ * When you are done with it, release it with g_object_unref()
+ *
+ * Since: 2.60
+ */
+GAppInfo *
+g_file_query_default_handler_finish (GFile *file,
+ GAsyncResult *result,
+ GError **error)
+{
+ g_return_val_if_fail (G_IS_FILE (file), NULL);
+ g_return_val_if_fail (g_task_is_valid (result, file), NULL);
+
+ return g_task_propagate_pointer (G_TASK (result), error);
+}
+
#define GET_CONTENT_BLOCK_SIZE 8192
/**
diff --git a/gio/gfile.h b/gio/gfile.h
index 4aff644c3..6e25b0de0 100644
--- a/gio/gfile.h
+++ b/gio/gfile.h
@@ -1183,6 +1183,17 @@ GLIB_AVAILABLE_IN_ALL
GAppInfo *g_file_query_default_handler (GFile *file,
GCancellable *cancellable,
GError **error);
+GLIB_AVAILABLE_IN_2_60
+void g_file_query_default_handler_async (GFile *file,
+ int io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+GLIB_AVAILABLE_IN_2_60
+GAppInfo *g_file_query_default_handler_finish (GFile *file,
+ GAsyncResult *result,
+ GError **error);
+
GLIB_AVAILABLE_IN_ALL
gboolean g_file_load_contents (GFile *file,
GCancellable *cancellable,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]