diff options
author | Matthias Clasen <mclasen@redhat.com> | 2018-09-03 18:36:56 -0400 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2019-12-12 14:25:33 -0500 |
commit | a20c8af678d6ffc05d0da088d34290b3f1ecb7ab (patch) | |
tree | 77dd6f37fab90e1f94eed648f6d30abf2f5e6052 /gdk/gdkcontentserializer.c | |
parent | 88da95d921f902ee3599ac39b26553a7c4eeb2fa (diff) | |
download | gtk+-a20c8af678d6ffc05d0da088d34290b3f1ecb7ab.tar.gz |
clipboard: file transfer portal support
Implement file-list <-> application/vnd.flatpak.file-list
serialization by talking to the file transfer portal.
See https://github.com/flatpak/xdg-desktop-portal/pull/222
Diffstat (limited to 'gdk/gdkcontentserializer.c')
-rw-r--r-- | gdk/gdkcontentserializer.c | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/gdk/gdkcontentserializer.c b/gdk/gdkcontentserializer.c index 7b99690224..cac4378cc2 100644 --- a/gdk/gdkcontentserializer.c +++ b/gdk/gdkcontentserializer.c @@ -23,6 +23,7 @@ #include "gdkcontentformats.h" #include "gdkpixbuf.h" +#include "filetransferportalprivate.h" #include "gdktextureprivate.h" #include <gdk-pixbuf/gdk-pixbuf.h> @@ -702,6 +703,63 @@ file_serializer_finish (GObject *source, } static void +portal_ready (GObject *object, + GAsyncResult *result, + gpointer serializer) +{ + GError *error = NULL; + char *key; + + if (!file_transfer_portal_register_files_finish (result, &key, &error)) + { + gdk_content_serializer_return_error (serializer, error); + return; + } + + g_output_stream_write_all_async (gdk_content_serializer_get_output_stream (serializer), + key, + strlen (key) + 1, + gdk_content_serializer_get_priority (serializer), + gdk_content_serializer_get_cancellable (serializer), + file_serializer_finish, + serializer); + gdk_content_serializer_set_task_data (serializer, key, g_free); +} + +static void +portal_file_serializer (GdkContentSerializer *serializer) +{ + GFile *file; + const GValue *value; + GPtrArray *files; + + files = g_ptr_array_new_with_free_func (g_free); + + value = gdk_content_serializer_get_value (serializer); + + if (G_VALUE_HOLDS (value, G_TYPE_FILE)) + { + file = g_value_get_object (gdk_content_serializer_get_value (serializer)); + if (file) + g_ptr_array_add (files, g_file_get_path (file)); + g_ptr_array_add (files, NULL); + } + else if (G_VALUE_HOLDS (value, GDK_TYPE_FILE_LIST)) + { + GSList *l; + + for (l = g_value_get_boxed (value); l; l = l->next) + g_ptr_array_add (files, g_file_get_path (l->data)); + + g_ptr_array_add (files, NULL); + } + + /* this call doesn't copy the strings, so keep the array around until the registration is done */ + file_transfer_portal_register_files ((const char **)files->pdata, TRUE, portal_ready, serializer); + gdk_content_serializer_set_task_data (serializer, files, (GDestroyNotify)g_ptr_array_unref); +} + +static void file_uri_serializer (GdkContentSerializer *serializer) { GFile *file; @@ -808,6 +866,7 @@ init (void) static gboolean initialized = FALSE; GSList *formats, *f; const char *charset; + gboolean has_portal; if (initialized) return; @@ -863,6 +922,14 @@ init (void) g_slist_free (formats); + has_portal = file_transfer_portal_available (); + + if (has_portal) + gdk_content_register_serializer (G_TYPE_FILE, + "application/vnd.portal.files", + portal_file_serializer, + NULL, + NULL); gdk_content_register_serializer (G_TYPE_FILE, "text/uri-list", file_uri_serializer, @@ -873,6 +940,12 @@ init (void) file_text_serializer, NULL, NULL); + if (has_portal) + gdk_content_register_serializer (GDK_TYPE_FILE_LIST, + "application/vnd.portal.files", + portal_file_serializer, + NULL, + NULL); gdk_content_register_serializer (GDK_TYPE_FILE_LIST, "text/uri-list", file_uri_serializer, |