summaryrefslogtreecommitdiff
path: root/gdk/gdkcontentserializer.c
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2018-09-03 18:36:56 -0400
committerMatthias Clasen <mclasen@redhat.com>2019-12-12 14:25:33 -0500
commita20c8af678d6ffc05d0da088d34290b3f1ecb7ab (patch)
tree77dd6f37fab90e1f94eed648f6d30abf2f5e6052 /gdk/gdkcontentserializer.c
parent88da95d921f902ee3599ac39b26553a7c4eeb2fa (diff)
downloadgtk+-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.c73
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,