|
|
a69c0b0 |
From 873939e8222a778e8f9855944483cb1ee1cb984b Mon Sep 17 00:00:00 2001
|
|
Bastien Nocera |
6539af8 |
From: Bastien Nocera <hadess@hadess.net>
|
|
Bastien Nocera |
6539af8 |
Date: Thu, 6 Feb 2020 15:04:31 +0100
|
|
Bastien Nocera |
8646403 |
Subject: [PATCH] mime-actions: Group files depending on the opening app
|
|
Bastien Nocera |
8646403 |
|
|
Bastien Nocera |
8646403 |
Reinstate the old behaviour which used to look at the files to open,
|
|
Bastien Nocera |
8646403 |
group them by handling application, and pass a single call to each
|
|
Bastien Nocera |
8646403 |
application with all the files it could handle.
|
|
Bastien Nocera |
8646403 |
|
|
Bastien Nocera |
8646403 |
For the common case where it's a single application handling all the
|
|
Bastien Nocera |
8646403 |
files, as is usual for handling media files (images, videos, music,
|
|
Bastien Nocera |
8646403 |
etc.), it changes the launching behaviour from:
|
|
Bastien Nocera |
8646403 |
application.bin foo.mp3
|
|
Bastien Nocera |
8646403 |
application.bin foo2.mp3
|
|
Bastien Nocera |
8646403 |
application.bin foo3.mp3
|
|
Bastien Nocera |
8646403 |
to:
|
|
Bastien Nocera |
8646403 |
application.bin foo.mp3 foo2.mp3 foo3.mp3
|
|
Bastien Nocera |
8646403 |
|
|
Bastien Nocera |
8646403 |
This however impacts the behaviour of nautilus launching applications
|
|
Bastien Nocera |
8646403 |
when inside a Flatpak sandbox, as it cannot enumerate and launch
|
|
Bastien Nocera |
8646403 |
applications itself. As the Flatpak sandbox is a development tool, and
|
|
Bastien Nocera |
8646403 |
for the sake of expediency, we reverted to the old code path.
|
|
Bastien Nocera |
8646403 |
|
|
Bastien Nocera |
8646403 |
Revert "mime-actions: launch default uri handlers when activating files"
|
|
Bastien Nocera |
6539af8 |
|
|
Bastien Nocera |
6539af8 |
This reverts commit f5206a6daf0991d91e885a28bb66795a8ae12a41.
|
|
Bastien Nocera |
8646403 |
|
|
Bastien Nocera |
8646403 |
Closes: #117
|
|
Bastien Nocera |
6539af8 |
---
|
|
Bastien Nocera |
6539af8 |
src/nautilus-mime-actions.c | 268 +++++++++++++++++++++++---------
|
|
|
a69c0b0 |
src/nautilus-program-choosing.c | 188 +++-------------------
|
|
Bastien Nocera |
6539af8 |
src/nautilus-program-choosing.h | 7 -
|
|
|
a69c0b0 |
3 files changed, 211 insertions(+), 252 deletions(-)
|
|
Bastien Nocera |
6539af8 |
|
|
Bastien Nocera |
6539af8 |
diff --git a/src/nautilus-mime-actions.c b/src/nautilus-mime-actions.c
|
|
|
a69c0b0 |
index 26468c597..4a49828a8 100644
|
|
Bastien Nocera |
6539af8 |
--- a/src/nautilus-mime-actions.c
|
|
Bastien Nocera |
6539af8 |
+++ b/src/nautilus-mime-actions.c
|
|
|
a69c0b0 |
@@ -61,6 +61,12 @@ typedef struct
|
|
Bastien Nocera |
6539af8 |
char *uri;
|
|
Bastien Nocera |
6539af8 |
} LaunchLocation;
|
|
Bastien Nocera |
6539af8 |
|
|
Bastien Nocera |
6539af8 |
+typedef struct
|
|
Bastien Nocera |
6539af8 |
+{
|
|
Bastien Nocera |
6539af8 |
+ GAppInfo *application;
|
|
Bastien Nocera |
6539af8 |
+ GList *uris;
|
|
Bastien Nocera |
6539af8 |
+} ApplicationLaunchParameters;
|
|
Bastien Nocera |
6539af8 |
+
|
|
Bastien Nocera |
6539af8 |
typedef struct
|
|
Bastien Nocera |
6539af8 |
{
|
|
Bastien Nocera |
6539af8 |
NautilusWindowSlot *slot;
|
|
|
a69c0b0 |
@@ -80,13 +86,6 @@ typedef struct
|
|
Bastien Nocera |
6539af8 |
gboolean user_confirmation;
|
|
Bastien Nocera |
6539af8 |
} ActivateParameters;
|
|
Bastien Nocera |
6539af8 |
|
|
Bastien Nocera |
6539af8 |
-typedef struct
|
|
Bastien Nocera |
6539af8 |
-{
|
|
Bastien Nocera |
6539af8 |
- ActivateParameters *activation_params;
|
|
Bastien Nocera |
6539af8 |
- GQueue *uris;
|
|
Bastien Nocera |
6539af8 |
- GQueue *unhandled_uris;
|
|
Bastien Nocera |
6539af8 |
-} ApplicationLaunchParameters;
|
|
Bastien Nocera |
6539af8 |
-
|
|
Bastien Nocera |
6539af8 |
/* Microsoft mime types at https://blogs.msdn.microsoft.com/vsofficedeveloper/2008/05/08/office-2007-file-format-mime-types-for-http-content-streaming-2/ */
|
|
Bastien Nocera |
6539af8 |
struct
|
|
Bastien Nocera |
6539af8 |
{
|
|
|
a69c0b0 |
@@ -345,19 +344,27 @@ launch_locations_from_file_list (GList *list)
|
|
Bastien Nocera |
6539af8 |
}
|
|
Bastien Nocera |
6539af8 |
|
|
Bastien Nocera |
6539af8 |
static ApplicationLaunchParameters *
|
|
Bastien Nocera |
6539af8 |
-application_launch_parameters_new (ActivateParameters *activation_params,
|
|
Bastien Nocera |
6539af8 |
- GQueue *uris)
|
|
Bastien Nocera |
6539af8 |
+application_launch_parameters_new (GAppInfo *application,
|
|
Bastien Nocera |
6539af8 |
+ GList *uris)
|
|
Bastien Nocera |
6539af8 |
{
|
|
Bastien Nocera |
6539af8 |
ApplicationLaunchParameters *result;
|
|
Bastien Nocera |
6539af8 |
|
|
Bastien Nocera |
6539af8 |
result = g_new0 (ApplicationLaunchParameters, 1);
|
|
Bastien Nocera |
6539af8 |
- result->activation_params = activation_params;
|
|
Bastien Nocera |
6539af8 |
- result->uris = uris;
|
|
Bastien Nocera |
6539af8 |
- result->unhandled_uris = g_queue_new ();
|
|
Bastien Nocera |
6539af8 |
+ result->application = g_object_ref (application);
|
|
Bastien Nocera |
6539af8 |
+ result->uris = g_list_copy_deep (uris, (GCopyFunc) g_strdup, NULL);
|
|
Bastien Nocera |
6539af8 |
|
|
Bastien Nocera |
6539af8 |
return result;
|
|
Bastien Nocera |
6539af8 |
}
|
|
Bastien Nocera |
6539af8 |
|
|
Bastien Nocera |
6539af8 |
+static void
|
|
Bastien Nocera |
6539af8 |
+application_launch_parameters_free (ApplicationLaunchParameters *parameters)
|
|
Bastien Nocera |
6539af8 |
+{
|
|
Bastien Nocera |
6539af8 |
+ g_object_unref (parameters->application);
|
|
Bastien Nocera |
6539af8 |
+ g_list_free_full (parameters->uris, g_free);
|
|
Bastien Nocera |
6539af8 |
+
|
|
Bastien Nocera |
6539af8 |
+ g_free (parameters);
|
|
Bastien Nocera |
6539af8 |
+}
|
|
Bastien Nocera |
6539af8 |
+
|
|
Bastien Nocera |
6539af8 |
static gboolean
|
|
Bastien Nocera |
6539af8 |
nautilus_mime_actions_check_if_required_attributes_ready (NautilusFile *file)
|
|
Bastien Nocera |
6539af8 |
{
|
|
|
a69c0b0 |
@@ -792,6 +799,114 @@ nautilus_mime_file_opens_in_external_app (NautilusFile *file)
|
|
Bastien Nocera |
6539af8 |
return (activation_action == ACTIVATION_ACTION_OPEN_IN_APPLICATION);
|
|
Bastien Nocera |
6539af8 |
}
|
|
Bastien Nocera |
6539af8 |
|
|
Bastien Nocera |
6539af8 |
+
|
|
Bastien Nocera |
6539af8 |
+static unsigned int
|
|
Bastien Nocera |
6539af8 |
+mime_application_hash (GAppInfo *app)
|
|
Bastien Nocera |
6539af8 |
+{
|
|
Bastien Nocera |
6539af8 |
+ const char *id;
|
|
Bastien Nocera |
6539af8 |
+
|
|
Bastien Nocera |
6539af8 |
+ id = g_app_info_get_id (app);
|
|
Bastien Nocera |
6539af8 |
+
|
|
Bastien Nocera |
6539af8 |
+ if (id == NULL)
|
|
Bastien Nocera |
6539af8 |
+ {
|
|
Bastien Nocera |
6539af8 |
+ return GPOINTER_TO_UINT (app);
|
|
Bastien Nocera |
6539af8 |
+ }
|
|
Bastien Nocera |
6539af8 |
+
|
|
Bastien Nocera |
6539af8 |
+ return g_str_hash (id);
|
|
Bastien Nocera |
6539af8 |
+}
|
|
Bastien Nocera |
6539af8 |
+
|
|
Bastien Nocera |
6539af8 |
+static void
|
|
Bastien Nocera |
6539af8 |
+list_to_parameters_foreach (GAppInfo *application,
|
|
Bastien Nocera |
6539af8 |
+ GList *uris,
|
|
Bastien Nocera |
6539af8 |
+ GList **ret)
|
|
Bastien Nocera |
6539af8 |
+{
|
|
Bastien Nocera |
6539af8 |
+ ApplicationLaunchParameters *parameters;
|
|
Bastien Nocera |
6539af8 |
+
|
|
Bastien Nocera |
6539af8 |
+ uris = g_list_reverse (uris);
|
|
Bastien Nocera |
6539af8 |
+
|
|
Bastien Nocera |
6539af8 |
+ parameters = application_launch_parameters_new
|
|
Bastien Nocera |
6539af8 |
+ (application, uris);
|
|
Bastien Nocera |
6539af8 |
+ *ret = g_list_prepend (*ret, parameters);
|
|
Bastien Nocera |
6539af8 |
+}
|
|
Bastien Nocera |
6539af8 |
+
|
|
Bastien Nocera |
6539af8 |
+
|
|
Bastien Nocera |
6539af8 |
+/**
|
|
Bastien Nocera |
6539af8 |
+ * make_activation_parameters
|
|
Bastien Nocera |
6539af8 |
+ *
|
|
Bastien Nocera |
6539af8 |
+ * Construct a list of ApplicationLaunchParameters from a list of NautilusFiles,
|
|
Bastien Nocera |
6539af8 |
+ * where files that have the same default application are put into the same
|
|
Bastien Nocera |
6539af8 |
+ * launch parameter, and others are put into the unhandled_files list.
|
|
Bastien Nocera |
6539af8 |
+ *
|
|
Bastien Nocera |
6539af8 |
+ * @files: Files to use for construction.
|
|
Bastien Nocera |
6539af8 |
+ * @unhandled_files: Files without any default application will be put here.
|
|
Bastien Nocera |
6539af8 |
+ *
|
|
Bastien Nocera |
6539af8 |
+ * Return value: Newly allocated list of ApplicationLaunchParameters.
|
|
Bastien Nocera |
6539af8 |
+ **/
|
|
Bastien Nocera |
6539af8 |
+static GList *
|
|
Bastien Nocera |
6539af8 |
+make_activation_parameters (GList *uris,
|
|
Bastien Nocera |
6539af8 |
+ GList **unhandled_uris)
|
|
Bastien Nocera |
6539af8 |
+{
|
|
Bastien Nocera |
6539af8 |
+ GList *ret, *l, *app_uris;
|
|
Bastien Nocera |
6539af8 |
+ NautilusFile *file;
|
|
Bastien Nocera |
6539af8 |
+ GAppInfo *app, *old_app;
|
|
Bastien Nocera |
6539af8 |
+ GHashTable *app_table;
|
|
Bastien Nocera |
6539af8 |
+ char *uri;
|
|
Bastien Nocera |
6539af8 |
+
|
|
Bastien Nocera |
6539af8 |
+ ret = NULL;
|
|
Bastien Nocera |
6539af8 |
+ *unhandled_uris = NULL;
|
|
Bastien Nocera |
6539af8 |
+
|
|
Bastien Nocera |
6539af8 |
+ app_table = g_hash_table_new_full
|
|
Bastien Nocera |
6539af8 |
+ ((GHashFunc) mime_application_hash,
|
|
Bastien Nocera |
6539af8 |
+ (GEqualFunc) g_app_info_equal,
|
|
Bastien Nocera |
6539af8 |
+ (GDestroyNotify) g_object_unref,
|
|
Bastien Nocera |
6539af8 |
+ (GDestroyNotify) g_list_free);
|
|
Bastien Nocera |
6539af8 |
+
|
|
Bastien Nocera |
6539af8 |
+ for (l = uris; l != NULL; l = l->next)
|
|
Bastien Nocera |
6539af8 |
+ {
|
|
Bastien Nocera |
6539af8 |
+ uri = l->data;
|
|
Bastien Nocera |
6539af8 |
+ file = nautilus_file_get_by_uri (uri);
|
|
Bastien Nocera |
6539af8 |
+
|
|
Bastien Nocera |
6539af8 |
+ app = nautilus_mime_get_default_application_for_file (file);
|
|
Bastien Nocera |
6539af8 |
+ if (app != NULL)
|
|
Bastien Nocera |
6539af8 |
+ {
|
|
Bastien Nocera |
6539af8 |
+ app_uris = NULL;
|
|
Bastien Nocera |
6539af8 |
+
|
|
Bastien Nocera |
6539af8 |
+ if (g_hash_table_lookup_extended (app_table, app,
|
|
Bastien Nocera |
6539af8 |
+ (gpointer *) &old_app,
|
|
Bastien Nocera |
6539af8 |
+ (gpointer *) &app_uris))
|
|
Bastien Nocera |
6539af8 |
+ {
|
|
Bastien Nocera |
6539af8 |
+ g_hash_table_steal (app_table, old_app);
|
|
Bastien Nocera |
6539af8 |
+
|
|
Bastien Nocera |
6539af8 |
+ app_uris = g_list_prepend (app_uris, uri);
|
|
Bastien Nocera |
6539af8 |
+
|
|
Bastien Nocera |
6539af8 |
+ g_object_unref (app);
|
|
Bastien Nocera |
6539af8 |
+ app = old_app;
|
|
Bastien Nocera |
6539af8 |
+ }
|
|
Bastien Nocera |
6539af8 |
+ else
|
|
Bastien Nocera |
6539af8 |
+ {
|
|
Bastien Nocera |
6539af8 |
+ app_uris = g_list_prepend (NULL, uri);
|
|
Bastien Nocera |
6539af8 |
+ }
|
|
Bastien Nocera |
6539af8 |
+
|
|
Bastien Nocera |
6539af8 |
+ g_hash_table_insert (app_table, app, app_uris);
|
|
Bastien Nocera |
6539af8 |
+ }
|
|
Bastien Nocera |
6539af8 |
+ else
|
|
Bastien Nocera |
6539af8 |
+ {
|
|
Bastien Nocera |
6539af8 |
+ *unhandled_uris = g_list_prepend (*unhandled_uris, uri);
|
|
Bastien Nocera |
6539af8 |
+ }
|
|
Bastien Nocera |
6539af8 |
+ nautilus_file_unref (file);
|
|
Bastien Nocera |
6539af8 |
+ }
|
|
Bastien Nocera |
6539af8 |
+
|
|
Bastien Nocera |
6539af8 |
+ g_hash_table_foreach (app_table,
|
|
Bastien Nocera |
6539af8 |
+ (GHFunc) list_to_parameters_foreach,
|
|
Bastien Nocera |
6539af8 |
+ &ret;;
|
|
Bastien Nocera |
6539af8 |
+
|
|
Bastien Nocera |
6539af8 |
+ g_hash_table_destroy (app_table);
|
|
Bastien Nocera |
6539af8 |
+
|
|
Bastien Nocera |
6539af8 |
+ *unhandled_uris = g_list_reverse (*unhandled_uris);
|
|
Bastien Nocera |
6539af8 |
+
|
|
Bastien Nocera |
6539af8 |
+ return g_list_reverse (ret);
|
|
Bastien Nocera |
6539af8 |
+}
|
|
Bastien Nocera |
6539af8 |
+
|
|
Bastien Nocera |
6539af8 |
static gboolean
|
|
Bastien Nocera |
6539af8 |
file_was_cancelled (NautilusFile *file)
|
|
Bastien Nocera |
6539af8 |
{
|
|
|
a69c0b0 |
@@ -843,16 +958,6 @@ activation_parameters_free (ActivateParameters *parameters)
|
|
Bastien Nocera |
6539af8 |
g_free (parameters);
|
|
Bastien Nocera |
6539af8 |
}
|
|
Bastien Nocera |
6539af8 |
|
|
Bastien Nocera |
6539af8 |
-static void
|
|
Bastien Nocera |
6539af8 |
-application_launch_parameters_free (ApplicationLaunchParameters *parameters)
|
|
Bastien Nocera |
6539af8 |
-{
|
|
Bastien Nocera |
6539af8 |
- g_queue_free (parameters->unhandled_uris);
|
|
Bastien Nocera |
6539af8 |
- g_queue_free (parameters->uris);
|
|
Bastien Nocera |
6539af8 |
- activation_parameters_free (parameters->activation_params);
|
|
Bastien Nocera |
6539af8 |
-
|
|
Bastien Nocera |
6539af8 |
- g_free (parameters);
|
|
Bastien Nocera |
6539af8 |
-}
|
|
Bastien Nocera |
6539af8 |
-
|
|
Bastien Nocera |
6539af8 |
static void
|
|
Bastien Nocera |
6539af8 |
cancel_activate_callback (gpointer callback_data)
|
|
Bastien Nocera |
6539af8 |
{
|
|
|
a69c0b0 |
@@ -1369,55 +1474,22 @@ out:
|
|
Bastien Nocera |
6539af8 |
show_unhandled_type_error (parameters_install);
|
|
Bastien Nocera |
6539af8 |
}
|
|
Bastien Nocera |
6539af8 |
|
|
Bastien Nocera |
6539af8 |
-static void
|
|
Bastien Nocera |
6539af8 |
-on_launch_default_for_uri (GObject *source_object,
|
|
Bastien Nocera |
6539af8 |
- GAsyncResult *res,
|
|
Bastien Nocera |
6539af8 |
- gpointer user_data)
|
|
Bastien Nocera |
6539af8 |
-{
|
|
Bastien Nocera |
6539af8 |
- ApplicationLaunchParameters *params;
|
|
Bastien Nocera |
6539af8 |
- ActivateParameters *activation_params;
|
|
Bastien Nocera |
6539af8 |
- char *uri;
|
|
Bastien Nocera |
6539af8 |
- gboolean sandboxed;
|
|
Bastien Nocera |
6539af8 |
- GError *error = NULL;
|
|
Bastien Nocera |
6539af8 |
-
|
|
Bastien Nocera |
6539af8 |
- params = user_data;
|
|
Bastien Nocera |
6539af8 |
- activation_params = params->activation_params;
|
|
Bastien Nocera |
6539af8 |
- uri = g_queue_pop_head (params->uris);
|
|
Bastien Nocera |
6539af8 |
- sandboxed = g_file_test ("/.flatpak-info", G_FILE_TEST_EXISTS);
|
|
Bastien Nocera |
6539af8 |
-
|
|
Bastien Nocera |
6539af8 |
- nautilus_launch_default_for_uri_finish (res, &error);
|
|
Bastien Nocera |
6539af8 |
- if (!sandboxed && error != NULL && error->code != G_IO_ERROR_CANCELLED)
|
|
Bastien Nocera |
6539af8 |
- {
|
|
Bastien Nocera |
6539af8 |
- g_queue_push_tail (params->unhandled_uris, uri);
|
|
Bastien Nocera |
6539af8 |
- }
|
|
Bastien Nocera |
6539af8 |
-
|
|
Bastien Nocera |
6539af8 |
- if (!g_queue_is_empty (params->uris))
|
|
Bastien Nocera |
6539af8 |
- {
|
|
Bastien Nocera |
6539af8 |
- nautilus_launch_default_for_uri_async (g_queue_peek_head (params->uris),
|
|
Bastien Nocera |
6539af8 |
- activation_params->parent_window,
|
|
Bastien Nocera |
6539af8 |
- activation_params->cancellable,
|
|
Bastien Nocera |
6539af8 |
- on_launch_default_for_uri,
|
|
Bastien Nocera |
6539af8 |
- params);
|
|
Bastien Nocera |
6539af8 |
- }
|
|
Bastien Nocera |
6539af8 |
- else
|
|
Bastien Nocera |
6539af8 |
- {
|
|
Bastien Nocera |
6539af8 |
- while ((uri = g_queue_pop_head (params->unhandled_uris)) != NULL)
|
|
Bastien Nocera |
6539af8 |
- {
|
|
Bastien Nocera |
6539af8 |
- application_unhandled_uri (activation_params, uri);
|
|
Bastien Nocera |
6539af8 |
- }
|
|
Bastien Nocera |
6539af8 |
-
|
|
Bastien Nocera |
6539af8 |
- application_launch_parameters_free (params);
|
|
Bastien Nocera |
6539af8 |
- }
|
|
Bastien Nocera |
6539af8 |
-}
|
|
Bastien Nocera |
6539af8 |
-
|
|
Bastien Nocera |
6539af8 |
static void
|
|
Bastien Nocera |
6539af8 |
activate_files (ActivateParameters *parameters)
|
|
Bastien Nocera |
6539af8 |
{
|
|
Bastien Nocera |
6539af8 |
NautilusFile *file;
|
|
Bastien Nocera |
6539af8 |
NautilusWindowOpenFlags flags;
|
|
Bastien Nocera |
6539af8 |
+ g_autoptr (GList) open_in_app_parameters = NULL;
|
|
Bastien Nocera |
6539af8 |
+ g_autoptr (GList) unhandled_open_in_app_uris = NULL;
|
|
Bastien Nocera |
6539af8 |
+ ApplicationLaunchParameters *one_parameters;
|
|
Bastien Nocera |
6539af8 |
int count;
|
|
Bastien Nocera |
6539af8 |
g_autofree char *old_working_dir = NULL;
|
|
Bastien Nocera |
6539af8 |
GdkScreen *screen;
|
|
Bastien Nocera |
6539af8 |
+ gint num_apps;
|
|
Bastien Nocera |
6539af8 |
+ gint num_unhandled;
|
|
Bastien Nocera |
6539af8 |
+ gint num_files;
|
|
Bastien Nocera |
6539af8 |
+ gboolean open_files;
|
|
Bastien Nocera |
6539af8 |
+ g_autoptr (GQueue) launch_desktop_files = NULL;
|
|
Bastien Nocera |
6539af8 |
g_autoptr (GQueue) launch_files = NULL;
|
|
Bastien Nocera |
6539af8 |
g_autoptr (GQueue) launch_in_terminal_files = NULL;
|
|
Bastien Nocera |
6539af8 |
g_autoptr (GQueue) open_in_app_uris = NULL;
|
|
|
a69c0b0 |
@@ -1612,26 +1684,68 @@ activate_files (ActivateParameters *parameters)
|
|
Bastien Nocera |
6539af8 |
}
|
|
Bastien Nocera |
6539af8 |
}
|
|
Bastien Nocera |
6539af8 |
|
|
Bastien Nocera |
6539af8 |
- if (g_queue_is_empty (open_in_app_uris))
|
|
Bastien Nocera |
6539af8 |
+ if (open_in_app_uris != NULL)
|
|
Bastien Nocera |
6539af8 |
{
|
|
Bastien Nocera |
6539af8 |
- activation_parameters_free (parameters);
|
|
Bastien Nocera |
6539af8 |
+ open_in_app_parameters = make_activation_parameters (g_queue_peek_head_link (open_in_app_uris),
|
|
Bastien Nocera |
6539af8 |
+ &unhandled_open_in_app_uris);
|
|
Bastien Nocera |
6539af8 |
}
|
|
Bastien Nocera |
6539af8 |
- else
|
|
Bastien Nocera |
6539af8 |
+
|
|
Bastien Nocera |
6539af8 |
+ num_apps = g_list_length (open_in_app_parameters);
|
|
Bastien Nocera |
6539af8 |
+ num_unhandled = g_list_length (unhandled_open_in_app_uris);
|
|
Bastien Nocera |
6539af8 |
+ num_files = g_queue_get_length (open_in_app_uris);
|
|
Bastien Nocera |
6539af8 |
+ open_files = TRUE;
|
|
Bastien Nocera |
6539af8 |
+
|
|
Bastien Nocera |
6539af8 |
+ if (g_queue_is_empty (open_in_app_uris) &&
|
|
Bastien Nocera |
6539af8 |
+ (!parameters->user_confirmation ||
|
|
Bastien Nocera |
6539af8 |
+ num_files + num_unhandled > SILENT_OPEN_LIMIT) &&
|
|
Bastien Nocera |
6539af8 |
+ num_apps > 1)
|
|
Bastien Nocera |
6539af8 |
{
|
|
Bastien Nocera |
6539af8 |
- const char *uri;
|
|
Bastien Nocera |
6539af8 |
- ApplicationLaunchParameters *params;
|
|
Bastien Nocera |
6539af8 |
+ GtkDialog *dialog;
|
|
Bastien Nocera |
6539af8 |
+ char *prompt;
|
|
Bastien Nocera |
6539af8 |
+ g_autofree char *detail = NULL;
|
|
Bastien Nocera |
6539af8 |
+ int response;
|
|
Bastien Nocera |
6539af8 |
|
|
Bastien Nocera |
6539af8 |
- uri = g_queue_peek_head (open_in_app_uris);
|
|
Bastien Nocera |
6539af8 |
- params = application_launch_parameters_new (parameters,
|
|
Bastien Nocera |
6539af8 |
- g_queue_copy (open_in_app_uris));
|
|
Bastien Nocera |
6539af8 |
+ pause_activation_timed_cancel (parameters);
|
|
Bastien Nocera |
6539af8 |
|
|
Bastien Nocera |
6539af8 |
- gtk_recent_manager_add_item (gtk_recent_manager_get_default (), uri);
|
|
Bastien Nocera |
6539af8 |
- nautilus_launch_default_for_uri_async (uri,
|
|
Bastien Nocera |
6539af8 |
- parameters->parent_window,
|
|
Bastien Nocera |
6539af8 |
- parameters->cancellable,
|
|
Bastien Nocera |
6539af8 |
- on_launch_default_for_uri,
|
|
Bastien Nocera |
6539af8 |
- params);
|
|
Bastien Nocera |
6539af8 |
+ prompt = _("Are you sure you want to open all files?");
|
|
Bastien Nocera |
6539af8 |
+ detail = g_strdup_printf (ngettext ("This will open %d separate application.",
|
|
Bastien Nocera |
6539af8 |
+ "This will open %d separate applications.", num_apps), num_apps);
|
|
Bastien Nocera |
6539af8 |
+ dialog = eel_show_yes_no_dialog (prompt, detail,
|
|
Bastien Nocera |
6539af8 |
+ _("_OK"), _("_Cancel"),
|
|
Bastien Nocera |
6539af8 |
+ parameters->parent_window);
|
|
Bastien Nocera |
6539af8 |
+ response = gtk_dialog_run (dialog);
|
|
Bastien Nocera |
6539af8 |
+ gtk_widget_destroy (GTK_WIDGET (dialog));
|
|
Bastien Nocera |
6539af8 |
+
|
|
Bastien Nocera |
6539af8 |
+ unpause_activation_timed_cancel (parameters);
|
|
Bastien Nocera |
6539af8 |
+
|
|
Bastien Nocera |
6539af8 |
+ if (response != GTK_RESPONSE_YES)
|
|
Bastien Nocera |
6539af8 |
+ {
|
|
Bastien Nocera |
6539af8 |
+ open_files = FALSE;
|
|
Bastien Nocera |
6539af8 |
+ }
|
|
Bastien Nocera |
6539af8 |
+ }
|
|
Bastien Nocera |
6539af8 |
+
|
|
Bastien Nocera |
6539af8 |
+ if (open_files)
|
|
Bastien Nocera |
6539af8 |
+ {
|
|
Bastien Nocera |
6539af8 |
+ for (l = open_in_app_parameters; l != NULL; l = l->next)
|
|
Bastien Nocera |
6539af8 |
+ {
|
|
Bastien Nocera |
6539af8 |
+ one_parameters = l->data;
|
|
Bastien Nocera |
6539af8 |
+
|
|
Bastien Nocera |
6539af8 |
+ nautilus_launch_application_by_uri (one_parameters->application,
|
|
Bastien Nocera |
6539af8 |
+ one_parameters->uris,
|
|
Bastien Nocera |
6539af8 |
+ parameters->parent_window);
|
|
Bastien Nocera |
6539af8 |
+ application_launch_parameters_free (one_parameters);
|
|
Bastien Nocera |
6539af8 |
+ }
|
|
Bastien Nocera |
6539af8 |
+
|
|
Bastien Nocera |
6539af8 |
+ for (l = unhandled_open_in_app_uris; l != NULL; l = l->next)
|
|
Bastien Nocera |
6539af8 |
+ {
|
|
Bastien Nocera |
6539af8 |
+ char *uri = l->data;
|
|
Bastien Nocera |
6539af8 |
+
|
|
Bastien Nocera |
6539af8 |
+ /* this does not block */
|
|
Bastien Nocera |
6539af8 |
+ application_unhandled_uri (parameters, uri);
|
|
Bastien Nocera |
6539af8 |
+ }
|
|
Bastien Nocera |
6539af8 |
}
|
|
Bastien Nocera |
6539af8 |
+
|
|
Bastien Nocera |
6539af8 |
+ activation_parameters_free (parameters);
|
|
Bastien Nocera |
6539af8 |
}
|
|
Bastien Nocera |
6539af8 |
|
|
Bastien Nocera |
6539af8 |
static void
|
|
Bastien Nocera |
6539af8 |
diff --git a/src/nautilus-program-choosing.c b/src/nautilus-program-choosing.c
|
|
|
a69c0b0 |
index 47362a3f7..35a4ab73f 100644
|
|
Bastien Nocera |
6539af8 |
--- a/src/nautilus-program-choosing.c
|
|
Bastien Nocera |
6539af8 |
+++ b/src/nautilus-program-choosing.c
|
|
Bastien Nocera |
6539af8 |
@@ -126,32 +126,6 @@ nautilus_launch_application (GAppInfo *application,
|
|
Bastien Nocera |
6539af8 |
g_list_free_full (uris, g_free);
|
|
Bastien Nocera |
6539af8 |
}
|
|
Bastien Nocera |
6539af8 |
|
|
Bastien Nocera |
6539af8 |
-static GdkAppLaunchContext *
|
|
Bastien Nocera |
6539af8 |
-get_launch_context (GtkWindow *parent_window)
|
|
Bastien Nocera |
6539af8 |
-{
|
|
Bastien Nocera |
6539af8 |
- GdkDisplay *display;
|
|
Bastien Nocera |
6539af8 |
- GdkAppLaunchContext *launch_context;
|
|
Bastien Nocera |
6539af8 |
-
|
|
Bastien Nocera |
6539af8 |
- if (parent_window != NULL)
|
|
Bastien Nocera |
6539af8 |
- {
|
|
Bastien Nocera |
6539af8 |
- display = gtk_widget_get_display (GTK_WIDGET (parent_window));
|
|
Bastien Nocera |
6539af8 |
- }
|
|
Bastien Nocera |
6539af8 |
- else
|
|
Bastien Nocera |
6539af8 |
- {
|
|
Bastien Nocera |
6539af8 |
- display = gdk_display_get_default ();
|
|
Bastien Nocera |
6539af8 |
- }
|
|
Bastien Nocera |
6539af8 |
-
|
|
Bastien Nocera |
6539af8 |
- launch_context = gdk_display_get_app_launch_context (display);
|
|
Bastien Nocera |
6539af8 |
-
|
|
Bastien Nocera |
6539af8 |
- if (parent_window != NULL)
|
|
Bastien Nocera |
6539af8 |
- {
|
|
Bastien Nocera |
6539af8 |
- gdk_app_launch_context_set_screen (launch_context,
|
|
Bastien Nocera |
6539af8 |
- gtk_window_get_screen (parent_window));
|
|
Bastien Nocera |
6539af8 |
- }
|
|
Bastien Nocera |
6539af8 |
-
|
|
Bastien Nocera |
6539af8 |
- return launch_context;
|
|
Bastien Nocera |
6539af8 |
-}
|
|
Bastien Nocera |
6539af8 |
-
|
|
Bastien Nocera |
6539af8 |
void
|
|
Bastien Nocera |
6539af8 |
nautilus_launch_application_by_uri (GAppInfo *application,
|
|
Bastien Nocera |
6539af8 |
GList *uris,
|
|
Bastien Nocera |
6539af8 |
@@ -163,7 +137,8 @@ nautilus_launch_application_by_uri (GAppInfo *application,
|
|
Bastien Nocera |
6539af8 |
NautilusFile *file;
|
|
Bastien Nocera |
6539af8 |
gboolean result;
|
|
Bastien Nocera |
6539af8 |
GError *error;
|
|
Bastien Nocera |
6539af8 |
- g_autoptr (GdkAppLaunchContext) launch_context = NULL;
|
|
Bastien Nocera |
6539af8 |
+ GdkDisplay *display;
|
|
Bastien Nocera |
6539af8 |
+ GdkAppLaunchContext *launch_context;
|
|
Bastien Nocera |
6539af8 |
NautilusIconInfo *icon;
|
|
Bastien Nocera |
6539af8 |
int count, total;
|
|
Bastien Nocera |
6539af8 |
|
|
Bastien Nocera |
6539af8 |
@@ -186,7 +161,22 @@ nautilus_launch_application_by_uri (GAppInfo *application,
|
|
Bastien Nocera |
6539af8 |
}
|
|
Bastien Nocera |
6539af8 |
locations = g_list_reverse (locations);
|
|
Bastien Nocera |
6539af8 |
|
|
Bastien Nocera |
6539af8 |
- launch_context = get_launch_context (parent_window);
|
|
Bastien Nocera |
6539af8 |
+ if (parent_window != NULL)
|
|
Bastien Nocera |
6539af8 |
+ {
|
|
Bastien Nocera |
6539af8 |
+ display = gtk_widget_get_display (GTK_WIDGET (parent_window));
|
|
Bastien Nocera |
6539af8 |
+ }
|
|
Bastien Nocera |
6539af8 |
+ else
|
|
Bastien Nocera |
6539af8 |
+ {
|
|
Bastien Nocera |
6539af8 |
+ display = gdk_display_get_default ();
|
|
Bastien Nocera |
6539af8 |
+ }
|
|
Bastien Nocera |
6539af8 |
+
|
|
Bastien Nocera |
6539af8 |
+ launch_context = gdk_display_get_app_launch_context (display);
|
|
Bastien Nocera |
6539af8 |
+
|
|
Bastien Nocera |
6539af8 |
+ if (parent_window != NULL)
|
|
Bastien Nocera |
6539af8 |
+ {
|
|
Bastien Nocera |
6539af8 |
+ gdk_app_launch_context_set_screen (launch_context,
|
|
Bastien Nocera |
6539af8 |
+ gtk_window_get_screen (parent_window));
|
|
Bastien Nocera |
6539af8 |
+ }
|
|
Bastien Nocera |
6539af8 |
|
|
Bastien Nocera |
6539af8 |
file = nautilus_file_get_by_uri (uris->data);
|
|
Bastien Nocera |
6539af8 |
icon = nautilus_file_get_icon (file,
|
|
Bastien Nocera |
6539af8 |
@@ -222,6 +212,8 @@ nautilus_launch_application_by_uri (GAppInfo *application,
|
|
Bastien Nocera |
6539af8 |
&error);
|
|
Bastien Nocera |
6539af8 |
}
|
|
Bastien Nocera |
6539af8 |
|
|
Bastien Nocera |
6539af8 |
+ g_object_unref (launch_context);
|
|
Bastien Nocera |
6539af8 |
+
|
|
Bastien Nocera |
6539af8 |
if (result)
|
|
Bastien Nocera |
6539af8 |
{
|
|
Bastien Nocera |
6539af8 |
for (l = uris; l != NULL; l = l->next)
|
|
|
a69c0b0 |
@@ -480,144 +472,4 @@ nautilus_launch_desktop_file (GdkScreen *screen,
|
|
Bastien Nocera |
6539af8 |
g_object_unref (app_info);
|
|
Bastien Nocera |
6539af8 |
}
|
|
|
a69c0b0 |
|
|
Bastien Nocera |
6539af8 |
-/* HAX
|
|
Bastien Nocera |
6539af8 |
- *
|
|
Bastien Nocera |
6539af8 |
- * TODO: remove everything below once it’s doable from GTK+.
|
|
Bastien Nocera |
6539af8 |
- *
|
|
Bastien Nocera |
6539af8 |
- * Context: https://bugzilla.gnome.org/show_bug.cgi?id=781132 and
|
|
Bastien Nocera |
6539af8 |
- * https://bugzilla.gnome.org/show_bug.cgi?id=779312
|
|
Bastien Nocera |
6539af8 |
- *
|
|
Bastien Nocera |
6539af8 |
- * In a sandboxed environment, this is needed to able to get the actual
|
|
Bastien Nocera |
6539af8 |
- * result of the operation, since gtk_show_uri_on_window () neither blocks
|
|
Bastien Nocera |
6539af8 |
- * nor returns a useful value.
|
|
Bastien Nocera |
6539af8 |
- */
|
|
Bastien Nocera |
6539af8 |
-
|
|
Bastien Nocera |
6539af8 |
-static void
|
|
Bastien Nocera |
6539af8 |
-on_launch_default_for_uri (GObject *source,
|
|
Bastien Nocera |
6539af8 |
- GAsyncResult *result,
|
|
Bastien Nocera |
6539af8 |
- gpointer data)
|
|
Bastien Nocera |
6539af8 |
-{
|
|
Bastien Nocera |
6539af8 |
- GTask *task;
|
|
Bastien Nocera |
6539af8 |
- NautilusWindow *window;
|
|
Bastien Nocera |
6539af8 |
- gboolean success;
|
|
Bastien Nocera |
6539af8 |
- GError *error = NULL;
|
|
Bastien Nocera |
6539af8 |
-
|
|
Bastien Nocera |
6539af8 |
- task = data;
|
|
Bastien Nocera |
6539af8 |
- window = g_task_get_source_object (task);
|
|
Bastien Nocera |
6539af8 |
-
|
|
Bastien Nocera |
6539af8 |
- success = g_app_info_launch_default_for_uri_finish (result, &error);
|
|
Bastien Nocera |
6539af8 |
-
|
|
Bastien Nocera |
6539af8 |
- if (window)
|
|
Bastien Nocera |
6539af8 |
- {
|
|
Bastien Nocera |
6539af8 |
- nautilus_window_unexport_handle (window);
|
|
Bastien Nocera |
6539af8 |
- }
|
|
Bastien Nocera |
6539af8 |
-
|
|
Bastien Nocera |
6539af8 |
- if (success)
|
|
Bastien Nocera |
6539af8 |
- {
|
|
Bastien Nocera |
6539af8 |
- g_task_return_boolean (task, success);
|
|
Bastien Nocera |
6539af8 |
- }
|
|
Bastien Nocera |
6539af8 |
- else
|
|
Bastien Nocera |
6539af8 |
- {
|
|
Bastien Nocera |
6539af8 |
- g_task_return_error (task, error);
|
|
Bastien Nocera |
6539af8 |
- }
|
|
Bastien Nocera |
6539af8 |
-
|
|
Bastien Nocera |
6539af8 |
- /* Reffed in the call to nautilus_window_export_handle */
|
|
Bastien Nocera |
6539af8 |
- g_object_unref (task);
|
|
Bastien Nocera |
6539af8 |
-}
|
|
Bastien Nocera |
6539af8 |
-
|
|
Bastien Nocera |
6539af8 |
-static void
|
|
|
a69c0b0 |
-on_window_handle_export (NautilusWindow *window,
|
|
|
a69c0b0 |
- const char *handle_str,
|
|
|
a69c0b0 |
- guint xid,
|
|
|
a69c0b0 |
- gpointer user_data)
|
|
Bastien Nocera |
6539af8 |
-{
|
|
Bastien Nocera |
6539af8 |
- GTask *task = user_data;
|
|
Bastien Nocera |
6539af8 |
- GAppLaunchContext *context = g_task_get_task_data (task);
|
|
Bastien Nocera |
6539af8 |
- const char *uri;
|
|
Bastien Nocera |
6539af8 |
-
|
|
Bastien Nocera |
6539af8 |
- uri = g_object_get_data (G_OBJECT (context), "uri");
|
|
Bastien Nocera |
6539af8 |
-
|
|
Bastien Nocera |
6539af8 |
- g_app_launch_context_setenv (context, "PARENT_WINDOW_ID", handle_str);
|
|
Bastien Nocera |
6539af8 |
-
|
|
Bastien Nocera |
6539af8 |
- g_app_info_launch_default_for_uri_async (uri,
|
|
Bastien Nocera |
6539af8 |
- context,
|
|
Bastien Nocera |
6539af8 |
- g_task_get_cancellable (task),
|
|
Bastien Nocera |
6539af8 |
- on_launch_default_for_uri,
|
|
Bastien Nocera |
6539af8 |
- task);
|
|
Bastien Nocera |
6539af8 |
-}
|
|
Bastien Nocera |
6539af8 |
-
|
|
Bastien Nocera |
6539af8 |
-static void
|
|
Bastien Nocera |
6539af8 |
-launch_default_for_uri_thread_func (GTask *task,
|
|
Bastien Nocera |
6539af8 |
- gpointer source_object,
|
|
Bastien Nocera |
6539af8 |
- gpointer task_data,
|
|
Bastien Nocera |
6539af8 |
- GCancellable *cancellable)
|
|
Bastien Nocera |
6539af8 |
-{
|
|
Bastien Nocera |
6539af8 |
- GAppLaunchContext *launch_context;
|
|
Bastien Nocera |
6539af8 |
- const char *uri;
|
|
Bastien Nocera |
6539af8 |
- gboolean success;
|
|
Bastien Nocera |
6539af8 |
- GError *error = NULL;
|
|
Bastien Nocera |
6539af8 |
-
|
|
Bastien Nocera |
6539af8 |
- launch_context = task_data;
|
|
Bastien Nocera |
6539af8 |
- uri = g_object_get_data (G_OBJECT (launch_context), "uri");
|
|
Bastien Nocera |
6539af8 |
- success = g_app_info_launch_default_for_uri (uri, launch_context, &error);
|
|
Bastien Nocera |
6539af8 |
-
|
|
Bastien Nocera |
6539af8 |
- if (success)
|
|
Bastien Nocera |
6539af8 |
- {
|
|
Bastien Nocera |
6539af8 |
- g_task_return_boolean (task, success);
|
|
Bastien Nocera |
6539af8 |
- }
|
|
Bastien Nocera |
6539af8 |
- else
|
|
Bastien Nocera |
6539af8 |
- {
|
|
Bastien Nocera |
6539af8 |
- g_task_return_error (task, error);
|
|
Bastien Nocera |
6539af8 |
- }
|
|
Bastien Nocera |
6539af8 |
-}
|
|
Bastien Nocera |
6539af8 |
-
|
|
Bastien Nocera |
6539af8 |
-void
|
|
Bastien Nocera |
6539af8 |
-nautilus_launch_default_for_uri_async (const char *uri,
|
|
Bastien Nocera |
6539af8 |
- GtkWindow *parent_window,
|
|
Bastien Nocera |
6539af8 |
- GCancellable *cancellable,
|
|
Bastien Nocera |
6539af8 |
- GAsyncReadyCallback callback,
|
|
Bastien Nocera |
6539af8 |
- gpointer callback_data)
|
|
Bastien Nocera |
6539af8 |
-{
|
|
Bastien Nocera |
6539af8 |
- g_autoptr (GdkAppLaunchContext) launch_context = NULL;
|
|
Bastien Nocera |
6539af8 |
- g_autoptr (GTask) task = NULL;
|
|
Bastien Nocera |
6539af8 |
-
|
|
Bastien Nocera |
6539af8 |
- g_return_if_fail (uri != NULL);
|
|
Bastien Nocera |
6539af8 |
-
|
|
Bastien Nocera |
6539af8 |
- launch_context = get_launch_context (parent_window);
|
|
Bastien Nocera |
6539af8 |
- task = g_task_new (parent_window, cancellable, callback, callback_data);
|
|
Bastien Nocera |
6539af8 |
-
|
|
Bastien Nocera |
6539af8 |
- gdk_app_launch_context_set_timestamp (launch_context, GDK_CURRENT_TIME);
|
|
Bastien Nocera |
6539af8 |
-
|
|
Bastien Nocera |
6539af8 |
- g_object_set_data_full (G_OBJECT (launch_context),
|
|
Bastien Nocera |
6539af8 |
- "uri", g_strdup (uri), g_free);
|
|
Bastien Nocera |
6539af8 |
- g_task_set_task_data (task,
|
|
Bastien Nocera |
6539af8 |
- g_object_ref (launch_context), g_object_unref);
|
|
Bastien Nocera |
6539af8 |
-
|
|
Bastien Nocera |
6539af8 |
- if (parent_window != NULL)
|
|
Bastien Nocera |
6539af8 |
- {
|
|
Bastien Nocera |
6539af8 |
- gboolean handle_exported;
|
|
Bastien Nocera |
6539af8 |
-
|
|
Bastien Nocera |
6539af8 |
- handle_exported = nautilus_window_export_handle (NAUTILUS_WINDOW (parent_window),
|
|
Bastien Nocera |
6539af8 |
- on_window_handle_export,
|
|
Bastien Nocera |
6539af8 |
- g_object_ref (task));
|
|
Bastien Nocera |
6539af8 |
-
|
|
Bastien Nocera |
6539af8 |
- if (handle_exported)
|
|
Bastien Nocera |
6539af8 |
- {
|
|
Bastien Nocera |
6539af8 |
- /* Launching will now be handled from the callback */
|
|
Bastien Nocera |
6539af8 |
- return;
|
|
Bastien Nocera |
6539af8 |
- }
|
|
Bastien Nocera |
6539af8 |
- }
|
|
Bastien Nocera |
6539af8 |
-
|
|
Bastien Nocera |
6539af8 |
- g_task_run_in_thread (task, launch_default_for_uri_thread_func);
|
|
Bastien Nocera |
6539af8 |
-}
|
|
Bastien Nocera |
6539af8 |
-
|
|
Bastien Nocera |
6539af8 |
-gboolean
|
|
Bastien Nocera |
6539af8 |
-nautilus_launch_default_for_uri_finish (GAsyncResult *result,
|
|
Bastien Nocera |
6539af8 |
- GError **error)
|
|
Bastien Nocera |
6539af8 |
-{
|
|
Bastien Nocera |
6539af8 |
- g_return_val_if_fail (G_IS_ASYNC_RESULT (result), FALSE);
|
|
Bastien Nocera |
6539af8 |
-
|
|
Bastien Nocera |
6539af8 |
- return g_task_propagate_boolean (G_TASK (result), error);
|
|
Bastien Nocera |
6539af8 |
-}
|
|
Bastien Nocera |
6539af8 |
-
|
|
|
a69c0b0 |
/* END OF HAX */
|
|
Bastien Nocera |
6539af8 |
diff --git a/src/nautilus-program-choosing.h b/src/nautilus-program-choosing.h
|
|
Bastien Nocera |
6539af8 |
index 51881ff17..a402b79a2 100644
|
|
Bastien Nocera |
6539af8 |
--- a/src/nautilus-program-choosing.h
|
|
Bastien Nocera |
6539af8 |
+++ b/src/nautilus-program-choosing.h
|
|
Bastien Nocera |
6539af8 |
@@ -51,10 +51,3 @@ void nautilus_launch_desktop_file (GdkScreen
|
|
Bastien Nocera |
6539af8 |
const char *desktop_file_uri,
|
|
Bastien Nocera |
6539af8 |
const GList *parameter_uris,
|
|
Bastien Nocera |
6539af8 |
GtkWindow *parent_window);
|
|
Bastien Nocera |
6539af8 |
-void nautilus_launch_default_for_uri_async (const char *uri,
|
|
Bastien Nocera |
6539af8 |
- GtkWindow *parent_window,
|
|
Bastien Nocera |
6539af8 |
- GCancellable *cancellable,
|
|
Bastien Nocera |
6539af8 |
- GAsyncReadyCallback callback,
|
|
Bastien Nocera |
6539af8 |
- gpointer callback_data);
|
|
Bastien Nocera |
6539af8 |
-gboolean nautilus_launch_default_for_uri_finish (GAsyncResult *result,
|
|
Bastien Nocera |
6539af8 |
- GError **error);
|
|
Bastien Nocera |
6539af8 |
\ No newline at end of file
|
|
Bastien Nocera |
6539af8 |
--
|
|
|
a69c0b0 |
GitLab
|
|
Bastien Nocera |
6539af8 |
|