[gtk/wip/chergert/gdk-macos-gdkdrag: 5/8] macos: make pasteboard usage reusable
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/chergert/gdk-macos-gdkdrag: 5/8] macos: make pasteboard usage reusable
- Date: Sat, 19 Jun 2021 02:29:04 +0000 (UTC)
commit 1acc2ccca18ccf068071e8a2174f9703038507f8
Author: Christian Hergert <chergert redhat com>
Date: Thu Jun 17 17:19:19 2021 -0700
macos: make pasteboard usage reusable
We will want to be able to reuse the pasteboard reading code from
the macOS DnD drop backend. This just removes the pasteboard
bits from the implementation and allows that to be passed in as in
both clipboard and DnD cases we'll have a specific NSPasteboard
to read from.
gdk/macos/gdkmacosclipboard-private.h | 24 ++-
gdk/macos/gdkmacosclipboard.c | 297 +++++++++++++++++++---------------
2 files changed, 182 insertions(+), 139 deletions(-)
---
diff --git a/gdk/macos/gdkmacosclipboard-private.h b/gdk/macos/gdkmacosclipboard-private.h
index e612f73edd..ba0b52bf0a 100644
--- a/gdk/macos/gdkmacosclipboard-private.h
+++ b/gdk/macos/gdkmacosclipboard-private.h
@@ -35,12 +35,24 @@ typedef NSString *NSPasteboardType;
G_DECLARE_FINAL_TYPE (GdkMacosClipboard, _gdk_macos_clipboard, GDK, MACOS_CLIPBOARD, GdkClipboard)
-GdkClipboard *_gdk_macos_clipboard_new (GdkMacosDisplay *display);
-void _gdk_macos_clipboard_check_externally_modified (GdkMacosClipboard *self);
-NSPasteboardType _gdk_macos_clipboard_to_ns_type (const char *mime_type,
- NSPasteboardType *alternate);
-const char *_gdk_macos_clipboard_from_ns_type (NSPasteboardType ns_type);
-void _gdk_macos_clipboard_register_drag_types (NSWindow *window);
+GdkClipboard *_gdk_macos_clipboard_new (GdkMacosDisplay *display);
+void _gdk_macos_clipboard_check_externally_modified (GdkMacosClipboard *self);
+NSPasteboardType _gdk_macos_clipboard_to_ns_type (const char *mime_type,
+ NSPasteboardType *alternate);
+const char *_gdk_macos_clipboard_from_ns_type (NSPasteboardType ns_type);
+void _gdk_macos_clipboard_register_drag_types (NSWindow *window);
+GdkContentFormats *_gdk_macos_pasteboard_load_formats (NSPasteboard *pasteboard);
+void _gdk_macos_pasteboard_read_async (GObject *object,
+ NSPasteboard *pasteboard,
+ GdkContentFormats *formats,
+ int io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data);
+GInputStream *_gdk_macos_pasteboard_read_finish (GObject *object,
+ GAsyncResult *result,
+ const char **out_mime_type,
+ GError **error);
@interface GdkMacosClipboardDataProvider : NSObject <NSPasteboardItemDataProvider>
{
diff --git a/gdk/macos/gdkmacosclipboard.c b/gdk/macos/gdkmacosclipboard.c
index ea0d19f923..ba755db0be 100644
--- a/gdk/macos/gdkmacosclipboard.c
+++ b/gdk/macos/gdkmacosclipboard.c
@@ -172,17 +172,15 @@ populate_content_formats (GdkContentFormatsBuilder *builder,
}
static GdkContentFormats *
-load_offer_formats (GdkMacosClipboard *self)
+load_offer_formats (NSPasteboard *pasteboard)
{
GDK_BEGIN_MACOS_ALLOC_POOL;
GdkContentFormatsBuilder *builder;
GdkContentFormats *formats;
- g_assert (GDK_IS_MACOS_CLIPBOARD (self));
-
builder = gdk_content_formats_builder_new ();
- for (NSPasteboardType type in [self->pasteboard types])
+ for (NSPasteboardType type in [pasteboard types])
populate_content_formats (builder, type);
formats = gdk_content_formats_builder_free_to_formats (builder);
@@ -201,7 +199,7 @@ _gdk_macos_clipboard_load_contents (GdkMacosClipboard *self)
change_count = [self->pasteboard changeCount];
- formats = load_offer_formats (self);
+ formats = load_offer_formats (self->pasteboard);
gdk_clipboard_claim_remote (GDK_CLIPBOARD (self), formats);
gdk_content_formats_unref (formats);
@@ -225,125 +223,13 @@ _gdk_macos_clipboard_read_async (GdkClipboard *clipboard,
GAsyncReadyCallback callback,
gpointer user_data)
{
- GDK_BEGIN_MACOS_ALLOC_POOL;
-
- GdkMacosClipboard *self = (GdkMacosClipboard *)clipboard;
- GdkContentFormats *offer_formats = NULL;
- const char *mime_type;
- GInputStream *stream = NULL;
- GTask *task = NULL;
-
- g_assert (GDK_IS_MACOS_CLIPBOARD (self));
- g_assert (formats != NULL);
-
- task = g_task_new (self, cancellable, callback, user_data);
- g_task_set_source_tag (task, _gdk_macos_clipboard_read_async);
- g_task_set_priority (task, io_priority);
-
- offer_formats = load_offer_formats (GDK_MACOS_CLIPBOARD (clipboard));
- mime_type = gdk_content_formats_match_mime_type (formats, offer_formats);
-
- if (mime_type == NULL)
- {
- g_task_return_new_error (task,
- G_IO_ERROR,
- G_IO_ERROR_NOT_SUPPORTED,
- "%s",
- _("No compatible transfer format found"));
- goto cleanup;
- }
-
- if (strcmp (mime_type, "text/plain;charset=utf-8") == 0)
- {
- NSString *nsstr = [self->pasteboard stringForType:NSPasteboardTypeString];
-
- if (nsstr != NULL)
- {
- const char *str = [nsstr UTF8String];
- stream = g_memory_input_stream_new_from_data (g_strdup (str),
- strlen (str) + 1,
- g_free);
- }
- }
- else if (strcmp (mime_type, "text/uri-list") == 0)
- {
- G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
-
- if ([[self->pasteboard types] containsObject:PTYPE(FILE_URL)])
- {
- GString *str = g_string_new (NULL);
- NSArray *files = [self->pasteboard propertyListForType:NSFilenamesPboardType];
- gsize n_files = [files count];
- char *data;
- guint len;
-
- for (gsize i = 0; i < n_files; ++i)
- {
- NSString* uriString = [files objectAtIndex:i];
- uriString = [@"file://" stringByAppendingString:uriString];
- uriString = [uriString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
-
- g_string_append_printf (str,
- "%s\r\n",
- [uriString cStringUsingEncoding:NSUTF8StringEncoding]);
- }
-
- len = str->len;
- data = g_string_free (str, FALSE);
- stream = g_memory_input_stream_new_from_data (data, len, g_free);
- }
-
- G_GNUC_END_IGNORE_DEPRECATIONS;
- }
- else if (strcmp (mime_type, "application/x-color") == 0)
- {
- NSColorSpace *colorspace;
- NSColor *nscolor;
- guint16 color[4];
-
- colorspace = [NSColorSpace genericRGBColorSpace];
- nscolor = [[NSColor colorFromPasteboard:self->pasteboard]
- colorUsingColorSpace:colorspace];
-
- color[0] = 0xffff * [nscolor redComponent];
- color[1] = 0xffff * [nscolor greenComponent];
- color[2] = 0xffff * [nscolor blueComponent];
- color[3] = 0xffff * [nscolor alphaComponent];
-
- stream = g_memory_input_stream_new_from_data (g_memdup2 (&color, sizeof color),
- sizeof color,
- g_free);
- }
- else if (strcmp (mime_type, "image/tiff") == 0)
- {
- NSData *data = [self->pasteboard dataForType:PTYPE(TIFF)];
- stream = create_stream_from_nsdata (data);
- }
- else if (strcmp (mime_type, "image/png") == 0)
- {
- NSData *data = [self->pasteboard dataForType:PTYPE(PNG)];
- stream = create_stream_from_nsdata (data);
- }
-
- if (stream != NULL)
- {
- g_task_set_task_data (task, g_strdup (mime_type), g_free);
- g_task_return_pointer (task, g_steal_pointer (&stream), g_object_unref);
- }
- else
- {
- g_task_return_new_error (task,
- G_IO_ERROR,
- G_IO_ERROR_FAILED,
- _("Failed to decode contents with mime-type of '%s'"),
- mime_type);
- }
-
-cleanup:
- g_clear_object (&task);
- g_clear_pointer (&offer_formats, gdk_content_formats_unref);
-
- GDK_END_MACOS_ALLOC_POOL;
+ _gdk_macos_pasteboard_read_async (G_OBJECT (clipboard),
+ GDK_MACOS_CLIPBOARD (clipboard)->pasteboard,
+ formats,
+ io_priority,
+ cancellable,
+ callback,
+ user_data);
}
static GInputStream *
@@ -352,15 +238,7 @@ _gdk_macos_clipboard_read_finish (GdkClipboard *clipboard,
const char **out_mime_type,
GError **error)
{
- GTask *task = (GTask *)result;
-
- g_assert (GDK_IS_MACOS_CLIPBOARD (clipboard));
- g_assert (G_IS_TASK (task));
-
- if (out_mime_type != NULL)
- *out_mime_type = g_strdup (g_task_get_task_data (task));
-
- return g_task_propagate_pointer (task, error);
+ return _gdk_macos_pasteboard_read_finish (G_OBJECT (clipboard), result, out_mime_type, error);
}
static void
@@ -636,3 +514,156 @@ _gdk_macos_clipboard_register_drag_types (NSWindow *window)
}
@end
+
+GdkContentFormats *
+_gdk_macos_pasteboard_load_formats (NSPasteboard *pasteboard)
+{
+ return load_offer_formats (pasteboard);
+}
+
+void
+_gdk_macos_pasteboard_read_async (GObject *object,
+ NSPasteboard *pasteboard,
+ GdkContentFormats *formats,
+ int io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GDK_BEGIN_MACOS_ALLOC_POOL;
+
+ GdkContentFormats *offer_formats = NULL;
+ const char *mime_type;
+ GInputStream *stream = NULL;
+ GTask *task = NULL;
+
+ g_assert (G_IS_OBJECT (object));
+ g_assert (pasteboard != NULL);
+ g_assert (formats != NULL);
+
+ task = g_task_new (object, cancellable, callback, user_data);
+ g_task_set_source_tag (task, _gdk_macos_pasteboard_read_async);
+ g_task_set_priority (task, io_priority);
+
+ offer_formats = load_offer_formats (pasteboard);
+ mime_type = gdk_content_formats_match_mime_type (formats, offer_formats);
+
+ if (mime_type == NULL)
+ {
+ g_task_return_new_error (task,
+ G_IO_ERROR,
+ G_IO_ERROR_NOT_SUPPORTED,
+ "%s",
+ _("No compatible transfer format found"));
+ goto cleanup;
+ }
+
+ if (strcmp (mime_type, "text/plain;charset=utf-8") == 0)
+ {
+ NSString *nsstr = [pasteboard stringForType:NSPasteboardTypeString];
+
+ if (nsstr != NULL)
+ {
+ const char *str = [nsstr UTF8String];
+ stream = g_memory_input_stream_new_from_data (g_strdup (str),
+ strlen (str) + 1,
+ g_free);
+ }
+ }
+ else if (strcmp (mime_type, "text/uri-list") == 0)
+ {
+ G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
+
+ if ([[pasteboard types] containsObject:PTYPE(FILE_URL)])
+ {
+ GString *str = g_string_new (NULL);
+ NSArray *files = [pasteboard propertyListForType:NSFilenamesPboardType];
+ gsize n_files = [files count];
+ char *data;
+ guint len;
+
+ for (gsize i = 0; i < n_files; ++i)
+ {
+ NSString* uriString = [files objectAtIndex:i];
+ uriString = [@"file://" stringByAppendingString:uriString];
+ uriString = [uriString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
+
+ g_string_append_printf (str,
+ "%s\r\n",
+ [uriString cStringUsingEncoding:NSUTF8StringEncoding]);
+ }
+
+ len = str->len;
+ data = g_string_free (str, FALSE);
+ stream = g_memory_input_stream_new_from_data (data, len, g_free);
+ }
+
+ G_GNUC_END_IGNORE_DEPRECATIONS;
+ }
+ else if (strcmp (mime_type, "application/x-color") == 0)
+ {
+ NSColorSpace *colorspace;
+ NSColor *nscolor;
+ guint16 color[4];
+
+ colorspace = [NSColorSpace genericRGBColorSpace];
+ nscolor = [[NSColor colorFromPasteboard:pasteboard]
+ colorUsingColorSpace:colorspace];
+
+ color[0] = 0xffff * [nscolor redComponent];
+ color[1] = 0xffff * [nscolor greenComponent];
+ color[2] = 0xffff * [nscolor blueComponent];
+ color[3] = 0xffff * [nscolor alphaComponent];
+
+ stream = g_memory_input_stream_new_from_data (g_memdup2 (&color, sizeof color),
+ sizeof color,
+ g_free);
+ }
+ else if (strcmp (mime_type, "image/tiff") == 0)
+ {
+ NSData *data = [pasteboard dataForType:PTYPE(TIFF)];
+ stream = create_stream_from_nsdata (data);
+ }
+ else if (strcmp (mime_type, "image/png") == 0)
+ {
+ NSData *data = [pasteboard dataForType:PTYPE(PNG)];
+ stream = create_stream_from_nsdata (data);
+ }
+
+ if (stream != NULL)
+ {
+ g_task_set_task_data (task, g_strdup (mime_type), g_free);
+ g_task_return_pointer (task, g_steal_pointer (&stream), g_object_unref);
+ }
+ else
+ {
+ g_task_return_new_error (task,
+ G_IO_ERROR,
+ G_IO_ERROR_FAILED,
+ _("Failed to decode contents with mime-type of '%s'"),
+ mime_type);
+ }
+
+cleanup:
+ g_clear_object (&task);
+ g_clear_pointer (&offer_formats, gdk_content_formats_unref);
+
+ GDK_END_MACOS_ALLOC_POOL;
+}
+
+GInputStream *
+_gdk_macos_pasteboard_read_finish (GObject *object,
+ GAsyncResult *result,
+ const char **out_mime_type,
+ GError **error)
+{
+ GTask *task = (GTask *)result;
+
+ g_assert (G_IS_OBJECT (object));
+ g_assert (G_IS_TASK (task));
+
+ if (out_mime_type != NULL)
+ *out_mime_type = g_strdup (g_task_get_task_data (task));
+
+ return g_task_propagate_pointer (task, error);
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]