mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-27 06:00:22 +00:00
macos: abstract pasteboard for use in clipboard and drag
This will allow us to share a single NSPasteboardItem and data provider implementation for both GdkClipboard and GdkDrag.
This commit is contained in:
parent
eb5cf831b1
commit
9c3629653f
@ -43,15 +43,6 @@ NSPasteboardType _gdk_macos_clipboard_to_ns_type (const char
|
|||||||
const char *_gdk_macos_clipboard_from_ns_type (NSPasteboardType ns_type);
|
const char *_gdk_macos_clipboard_from_ns_type (NSPasteboardType ns_type);
|
||||||
void _gdk_macos_clipboard_register_drag_types (NSWindow *window);
|
void _gdk_macos_clipboard_register_drag_types (NSWindow *window);
|
||||||
|
|
||||||
@interface GdkMacosClipboardDataProvider : GdkMacosPasteboardDataProvider
|
|
||||||
{
|
|
||||||
GdkClipboard *clipboard;
|
|
||||||
}
|
|
||||||
|
|
||||||
-(id)initClipboard:(GdkMacosClipboard *)gdkClipboard mimetypes:(const char * const *)mime_types;
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
#endif /* __GDK_MACOS_CLIPBOARD_PRIVATE_H__ */
|
#endif /* __GDK_MACOS_CLIPBOARD_PRIVATE_H__ */
|
||||||
|
@ -33,26 +33,8 @@ struct _GdkMacosClipboard
|
|||||||
NSInteger last_change_count;
|
NSInteger last_change_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
GMemoryOutputStream *stream;
|
|
||||||
NSPasteboardItem *item;
|
|
||||||
NSPasteboardType type;
|
|
||||||
GMainContext *main_context;
|
|
||||||
guint done : 1;
|
|
||||||
} WriteRequest;
|
|
||||||
|
|
||||||
G_DEFINE_TYPE (GdkMacosClipboard, _gdk_macos_clipboard, GDK_TYPE_CLIPBOARD)
|
G_DEFINE_TYPE (GdkMacosClipboard, _gdk_macos_clipboard, GDK_TYPE_CLIPBOARD)
|
||||||
|
|
||||||
static void
|
|
||||||
write_request_free (WriteRequest *wr)
|
|
||||||
{
|
|
||||||
g_clear_pointer (&wr->main_context, g_main_context_unref);
|
|
||||||
g_clear_object (&wr->stream);
|
|
||||||
[wr->item release];
|
|
||||||
g_slice_free (WriteRequest, wr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_gdk_macos_clipboard_load_contents (GdkMacosClipboard *self)
|
_gdk_macos_clipboard_load_contents (GdkMacosClipboard *self)
|
||||||
{
|
{
|
||||||
@ -100,25 +82,27 @@ static void
|
|||||||
_gdk_macos_clipboard_send_to_pasteboard (GdkMacosClipboard *self,
|
_gdk_macos_clipboard_send_to_pasteboard (GdkMacosClipboard *self,
|
||||||
GdkContentProvider *content)
|
GdkContentProvider *content)
|
||||||
{
|
{
|
||||||
GdkMacosClipboardDataProvider *dataProvider;
|
GdkMacosPasteboardItem *item;
|
||||||
GdkContentFormats *serializable;
|
NSArray<NSPasteboardItem *> *items;
|
||||||
const char * const *mime_types;
|
|
||||||
gsize n_mime_types;
|
|
||||||
|
|
||||||
g_assert (GDK_IS_MACOS_CLIPBOARD (self));
|
g_assert (GDK_IS_MACOS_CLIPBOARD (self));
|
||||||
g_assert (GDK_IS_CONTENT_PROVIDER (content));
|
g_assert (GDK_IS_CONTENT_PROVIDER (content));
|
||||||
|
|
||||||
serializable = gdk_content_provider_ref_storable_formats (content);
|
if (self->pasteboard == NULL)
|
||||||
serializable = gdk_content_formats_union_serialize_mime_types (serializable);
|
return;
|
||||||
mime_types = gdk_content_formats_get_mime_types (serializable, &n_mime_types);
|
|
||||||
|
|
||||||
dataProvider = [[GdkMacosClipboardDataProvider alloc] initClipboard:self mimetypes:mime_types];
|
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||||
_gdk_macos_pasteboard_send_content (self->pasteboard, content, dataProvider);
|
|
||||||
[dataProvider release];
|
item = [[GdkMacosPasteboardItem alloc] initForClipboard:GDK_CLIPBOARD (self) withContentProvider:content];
|
||||||
|
items = [NSArray arrayWithObject:item];
|
||||||
|
|
||||||
|
[self->pasteboard clearContents];
|
||||||
|
if ([self->pasteboard writeObjects:items] == NO)
|
||||||
|
g_warning ("Failed to send clipboard to pasteboard");
|
||||||
|
|
||||||
self->last_change_count = [self->pasteboard changeCount];
|
self->last_change_count = [self->pasteboard changeCount];
|
||||||
|
|
||||||
g_clear_pointer (&serializable, gdk_content_formats_unref);
|
GDK_END_MACOS_ALLOC_POOL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -210,111 +194,3 @@ _gdk_macos_clipboard_check_externally_modified (GdkMacosClipboard *self)
|
|||||||
if ([self->pasteboard changeCount] != self->last_change_count)
|
if ([self->pasteboard changeCount] != self->last_change_count)
|
||||||
_gdk_macos_clipboard_load_contents (self);
|
_gdk_macos_clipboard_load_contents (self);
|
||||||
}
|
}
|
||||||
|
|
||||||
@implementation GdkMacosClipboardDataProvider
|
|
||||||
|
|
||||||
-(id)initClipboard:(GdkMacosClipboard *)gdkClipboard mimetypes:(const char * const *)mime_types;
|
|
||||||
{
|
|
||||||
[super initPasteboard:gdkClipboard->pasteboard mimetypes:mime_types];
|
|
||||||
|
|
||||||
self->clipboard = g_object_ref (GDK_CLIPBOARD (gdkClipboard));
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
-(void)dealloc
|
|
||||||
{
|
|
||||||
g_clear_object (&self->clipboard);
|
|
||||||
|
|
||||||
[super dealloc];
|
|
||||||
}
|
|
||||||
|
|
||||||
-(void)pasteboardFinishedWithDataProvider:(NSPasteboard *)pasteboard
|
|
||||||
{
|
|
||||||
g_clear_object (&self->clipboard);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
on_data_ready_cb (GObject *object,
|
|
||||||
GAsyncResult *result,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
|
||||||
|
|
||||||
GdkClipboard *clipboard = (GdkClipboard *)object;
|
|
||||||
WriteRequest *wr = user_data;
|
|
||||||
GError *error = NULL;
|
|
||||||
NSData *data = nil;
|
|
||||||
|
|
||||||
g_assert (GDK_IS_CLIPBOARD (clipboard));
|
|
||||||
g_assert (G_IS_ASYNC_RESULT (result));
|
|
||||||
g_assert (wr != NULL);
|
|
||||||
g_assert (G_IS_MEMORY_OUTPUT_STREAM (wr->stream));
|
|
||||||
g_assert ([wr->item isKindOfClass:[NSPasteboardItem class]]);
|
|
||||||
|
|
||||||
if (gdk_clipboard_write_finish (clipboard, result, &error))
|
|
||||||
{
|
|
||||||
gsize size;
|
|
||||||
gpointer bytes;
|
|
||||||
|
|
||||||
g_output_stream_close (G_OUTPUT_STREAM (wr->stream), NULL, NULL);
|
|
||||||
|
|
||||||
size = g_memory_output_stream_get_data_size (wr->stream);
|
|
||||||
bytes = g_memory_output_stream_steal_data (wr->stream);
|
|
||||||
data = [[NSData alloc] initWithBytesNoCopy:bytes
|
|
||||||
length:size
|
|
||||||
deallocator:^(void *alloc, NSUInteger length) { g_free (alloc); }];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g_warning ("Failed to serialize clipboard contents: %s",
|
|
||||||
error->message);
|
|
||||||
g_clear_error (&error);
|
|
||||||
}
|
|
||||||
|
|
||||||
[wr->item setData:data forType:wr->type];
|
|
||||||
|
|
||||||
wr->done = TRUE;
|
|
||||||
|
|
||||||
GDK_END_MACOS_ALLOC_POOL;
|
|
||||||
}
|
|
||||||
|
|
||||||
-(void)pasteboard:(NSPasteboard *)pasteboard item:(NSPasteboardItem *)item provideDataForType:(NSPasteboardType)type
|
|
||||||
{
|
|
||||||
const char *mime_type = _gdk_macos_pasteboard_from_ns_type (type);
|
|
||||||
GMainContext *main_context = g_main_context_default ();
|
|
||||||
WriteRequest *wr;
|
|
||||||
|
|
||||||
if (self->clipboard == NULL || mime_type == NULL)
|
|
||||||
{
|
|
||||||
[item setData:[NSData data] forType:type];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
wr = g_slice_new0 (WriteRequest);
|
|
||||||
wr->item = [item retain];
|
|
||||||
wr->stream = G_MEMORY_OUTPUT_STREAM (g_memory_output_stream_new_resizable ());
|
|
||||||
wr->type = type;
|
|
||||||
wr->main_context = g_main_context_ref (main_context);
|
|
||||||
wr->done = FALSE;
|
|
||||||
|
|
||||||
gdk_clipboard_write_async (self->clipboard,
|
|
||||||
mime_type,
|
|
||||||
G_OUTPUT_STREAM (wr->stream),
|
|
||||||
G_PRIORITY_DEFAULT,
|
|
||||||
self->cancellable,
|
|
||||||
on_data_ready_cb,
|
|
||||||
wr);
|
|
||||||
|
|
||||||
/* We're forced to provide data synchronously via this API
|
|
||||||
* so we must block on the main loop. Using another main loop
|
|
||||||
* than the default tends to get us locked up here, so that is
|
|
||||||
* what we'll do for now.
|
|
||||||
*/
|
|
||||||
while (!wr->done)
|
|
||||||
g_main_context_iteration (wr->main_context, TRUE);
|
|
||||||
|
|
||||||
write_request_free (wr);
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
@ -27,15 +27,28 @@
|
|||||||
|
|
||||||
G_BEGIN_DECLS
|
G_BEGIN_DECLS
|
||||||
|
|
||||||
@interface GdkMacosPasteboardDataProvider : NSObject <NSPasteboardItemDataProvider>
|
@interface GdkMacosPasteboardItemDataProvider : NSObject <NSPasteboardItemDataProvider>
|
||||||
{
|
{
|
||||||
NSPasteboard *pasteboard;
|
GdkContentProvider *_contentProvider;
|
||||||
GCancellable *cancellable;
|
GdkClipboard *_clipboard;
|
||||||
char **mimeTypes;
|
GdkDrag *_drag;
|
||||||
}
|
}
|
||||||
|
|
||||||
-(id)initPasteboard:(NSPasteboard *)pasteBoard mimetypes:(const char * const *)mime_types;
|
-(id)initForClipboard:(GdkClipboard *)clipboard withContentProvider:(GdkContentProvider *)contentProvider;
|
||||||
-(NSArray<NSPasteboardType> *)types;
|
-(id)initForDrag:(GdkDrag *)drag withContentProvider:(GdkContentProvider *)contentProvider;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface GdkMacosPasteboardItem : NSPasteboardItem
|
||||||
|
{
|
||||||
|
GdkContentProvider *_contentProvider;
|
||||||
|
GdkClipboard *_clipboard;
|
||||||
|
GdkDrag *_drag;
|
||||||
|
NSRect _draggingFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(id)initForClipboard:(GdkClipboard *)clipboard withContentProvider:(GdkContentProvider *)contentProvider;
|
||||||
|
-(id)initForDrag:(GdkDrag *)drag withContentProvider:(GdkContentProvider *)contentProvider;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@ -55,9 +68,6 @@ GInputStream *_gdk_macos_pasteboard_read_finish (GObject
|
|||||||
GAsyncResult *result,
|
GAsyncResult *result,
|
||||||
const char **out_mime_type,
|
const char **out_mime_type,
|
||||||
GError **error);
|
GError **error);
|
||||||
void _gdk_macos_pasteboard_send_content (NSPasteboard *pasteboard,
|
|
||||||
GdkContentProvider *content,
|
|
||||||
GdkMacosPasteboardDataProvider *dataProvider);
|
|
||||||
|
|
||||||
G_END_DECLS
|
G_END_DECLS
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include <glib/gi18n.h>
|
#include <glib/gi18n.h>
|
||||||
|
|
||||||
|
#include "gdkdragprivate.h"
|
||||||
#include "gdkmacospasteboard-private.h"
|
#include "gdkmacospasteboard-private.h"
|
||||||
#include "gdkmacosutils-private.h"
|
#include "gdkmacosutils-private.h"
|
||||||
|
|
||||||
@ -165,87 +166,6 @@ _gdk_macos_pasteboard_load_formats (NSPasteboard *pasteboard)
|
|||||||
return load_offer_formats (pasteboard);
|
return load_offer_formats (pasteboard);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
_gdk_macos_pasteboard_send_content (NSPasteboard *pasteboard,
|
|
||||||
GdkContentProvider *content,
|
|
||||||
GdkMacosPasteboardDataProvider *dataProvider)
|
|
||||||
{
|
|
||||||
GDK_BEGIN_MACOS_ALLOC_POOL;
|
|
||||||
|
|
||||||
NSPasteboardItem *item;
|
|
||||||
|
|
||||||
g_return_if_fail (pasteboard != NULL);
|
|
||||||
g_return_if_fail (GDK_IS_CONTENT_PROVIDER (content));
|
|
||||||
|
|
||||||
item = [[NSPasteboardItem alloc] init];
|
|
||||||
[item setDataProvider:dataProvider forTypes:[dataProvider types]];
|
|
||||||
|
|
||||||
[pasteboard clearContents];
|
|
||||||
if ([pasteboard writeObjects:[NSArray arrayWithObject:item]] == NO)
|
|
||||||
g_warning ("Failed to write object to pasteboard");
|
|
||||||
|
|
||||||
GDK_END_MACOS_ALLOC_POOL;
|
|
||||||
}
|
|
||||||
|
|
||||||
@implementation GdkMacosPasteboardDataProvider
|
|
||||||
|
|
||||||
-(id)initPasteboard:(NSPasteboard *)pasteBoard mimetypes:(const char * const *)mime_types;
|
|
||||||
{
|
|
||||||
[super init];
|
|
||||||
|
|
||||||
self->mimeTypes = g_strdupv ((char **)mime_types);
|
|
||||||
self->pasteboard = [pasteBoard retain];
|
|
||||||
|
|
||||||
return self;
|
|
||||||
}
|
|
||||||
|
|
||||||
-(void)dealloc
|
|
||||||
{
|
|
||||||
g_cancellable_cancel (self->cancellable);
|
|
||||||
|
|
||||||
if (self->pasteboard)
|
|
||||||
{
|
|
||||||
[self->pasteboard release];
|
|
||||||
self->pasteboard = nil;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_clear_pointer (&self->mimeTypes, g_strfreev);
|
|
||||||
g_clear_object (&self->cancellable);
|
|
||||||
|
|
||||||
[super dealloc];
|
|
||||||
}
|
|
||||||
|
|
||||||
-(void)pasteboardFinishedWithDataProvider:(NSPasteboard *)pasteboard
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
-(void)pasteboard:(NSPasteboard *)pasteboard item:(NSPasteboardItem *)item provideDataForType:(NSPasteboardType)type
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
-(NSArray<NSPasteboardType> *)types
|
|
||||||
{
|
|
||||||
NSMutableArray *ret = [[NSMutableArray alloc] init];
|
|
||||||
|
|
||||||
for (guint i = 0; self->mimeTypes[i]; i++)
|
|
||||||
{
|
|
||||||
const char *mime_type = self->mimeTypes[i];
|
|
||||||
NSPasteboardType type;
|
|
||||||
NSPasteboardType alternate = nil;
|
|
||||||
|
|
||||||
if ((type = _gdk_macos_pasteboard_to_ns_type (mime_type, &alternate)))
|
|
||||||
{
|
|
||||||
[ret addObject:type];
|
|
||||||
if (alternate)
|
|
||||||
[ret addObject:alternate];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return g_steal_pointer (&ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
static GInputStream *
|
static GInputStream *
|
||||||
create_stream_from_nsdata (NSData *data)
|
create_stream_from_nsdata (NSData *data)
|
||||||
{
|
{
|
||||||
@ -414,3 +334,250 @@ _gdk_macos_pasteboard_register_drag_types (NSWindow *window)
|
|||||||
PTYPE(PNG),
|
PTYPE(PNG),
|
||||||
nil]];
|
nil]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@implementation GdkMacosPasteboardItemDataProvider
|
||||||
|
|
||||||
|
-(id)initForClipboard:(GdkClipboard*)clipboard withContentProvider:(GdkContentProvider*)contentProvider
|
||||||
|
{
|
||||||
|
[super init];
|
||||||
|
g_set_object (&self->_clipboard, clipboard);
|
||||||
|
g_set_object (&self->_contentProvider, contentProvider);
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(id)initForDrag:(GdkDrag*)drag withContentProvider:(GdkContentProvider*)contentProvider
|
||||||
|
{
|
||||||
|
[super init];
|
||||||
|
g_set_object (&self->_drag, drag);
|
||||||
|
g_set_object (&self->_contentProvider, contentProvider);
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)dealloc
|
||||||
|
{
|
||||||
|
g_clear_object (&self->_contentProvider);
|
||||||
|
g_clear_object (&self->_clipboard);
|
||||||
|
g_clear_object (&self->_drag);
|
||||||
|
[super dealloc];
|
||||||
|
}
|
||||||
|
|
||||||
|
-(NSArray<NSPasteboardType> *)types
|
||||||
|
{
|
||||||
|
NSMutableArray *ret = [[NSMutableArray alloc] init];
|
||||||
|
GdkContentFormats *serializable;
|
||||||
|
const char * const *mime_types;
|
||||||
|
gsize n_mime_types;
|
||||||
|
|
||||||
|
serializable = gdk_content_provider_ref_storable_formats (self->_contentProvider);
|
||||||
|
serializable = gdk_content_formats_union_serialize_mime_types (serializable);
|
||||||
|
mime_types = gdk_content_formats_get_mime_types (serializable, &n_mime_types);
|
||||||
|
|
||||||
|
for (guint i = 0; mime_types[i]; i++)
|
||||||
|
{
|
||||||
|
const char *mime_type = mime_types[i];
|
||||||
|
NSPasteboardType type;
|
||||||
|
NSPasteboardType alternate = nil;
|
||||||
|
|
||||||
|
if ((type = _gdk_macos_pasteboard_to_ns_type (mime_type, &alternate)))
|
||||||
|
{
|
||||||
|
[ret addObject:type];
|
||||||
|
if (alternate)
|
||||||
|
[ret addObject:alternate];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return g_steal_pointer (&ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
GMemoryOutputStream *stream;
|
||||||
|
NSPasteboardItem *item;
|
||||||
|
NSPasteboardType type;
|
||||||
|
GMainContext *main_context;
|
||||||
|
guint done : 1;
|
||||||
|
} WriteRequest;
|
||||||
|
|
||||||
|
static void
|
||||||
|
write_request_free (WriteRequest *wr)
|
||||||
|
{
|
||||||
|
g_clear_pointer (&wr->main_context, g_main_context_unref);
|
||||||
|
g_clear_object (&wr->stream);
|
||||||
|
[wr->item release];
|
||||||
|
g_slice_free (WriteRequest, wr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
on_data_ready_cb (GObject *object,
|
||||||
|
GAsyncResult *result,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
GDK_BEGIN_MACOS_ALLOC_POOL;
|
||||||
|
|
||||||
|
WriteRequest *wr = user_data;
|
||||||
|
GError *error = NULL;
|
||||||
|
NSData *data = nil;
|
||||||
|
gboolean ret;
|
||||||
|
|
||||||
|
g_assert (G_IS_OBJECT (object));
|
||||||
|
g_assert (GDK_IS_CLIPBOARD (object) || GDK_IS_DRAG (object));
|
||||||
|
g_assert (G_IS_ASYNC_RESULT (result));
|
||||||
|
g_assert (wr != NULL);
|
||||||
|
g_assert (G_IS_MEMORY_OUTPUT_STREAM (wr->stream));
|
||||||
|
g_assert ([wr->item isKindOfClass:[NSPasteboardItem class]]);
|
||||||
|
|
||||||
|
if (GDK_IS_CLIPBOARD (object))
|
||||||
|
ret = gdk_clipboard_write_finish (GDK_CLIPBOARD (object), result, &error);
|
||||||
|
else if (GDK_IS_DRAG (object))
|
||||||
|
ret = gdk_drag_write_finish (GDK_DRAG (object), result, &error);
|
||||||
|
else
|
||||||
|
g_return_if_reached ();
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
{
|
||||||
|
gsize size;
|
||||||
|
gpointer bytes;
|
||||||
|
|
||||||
|
g_output_stream_close (G_OUTPUT_STREAM (wr->stream), NULL, NULL);
|
||||||
|
|
||||||
|
size = g_memory_output_stream_get_data_size (wr->stream);
|
||||||
|
bytes = g_memory_output_stream_steal_data (wr->stream);
|
||||||
|
data = [[NSData alloc] initWithBytesNoCopy:bytes
|
||||||
|
length:size
|
||||||
|
deallocator:^(void *alloc, NSUInteger length) { g_free (alloc); }];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_warning ("Failed to serialize pasteboard contents: %s",
|
||||||
|
error->message);
|
||||||
|
g_clear_error (&error);
|
||||||
|
}
|
||||||
|
|
||||||
|
[wr->item setData:data forType:wr->type];
|
||||||
|
|
||||||
|
wr->done = TRUE;
|
||||||
|
|
||||||
|
GDK_END_MACOS_ALLOC_POOL;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)pasteboard:(NSPasteboard *)pasteboard item:(NSPasteboardItem *)item provideDataForType:(NSPasteboardType)type
|
||||||
|
{
|
||||||
|
const char *mime_type = _gdk_macos_pasteboard_from_ns_type (type);
|
||||||
|
GMainContext *main_context = g_main_context_default ();
|
||||||
|
WriteRequest *wr;
|
||||||
|
|
||||||
|
if (self->_contentProvider == NULL || mime_type == NULL)
|
||||||
|
{
|
||||||
|
[item setData:[NSData data] forType:type];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wr = g_slice_new0 (WriteRequest);
|
||||||
|
wr->item = [item retain];
|
||||||
|
wr->stream = G_MEMORY_OUTPUT_STREAM (g_memory_output_stream_new_resizable ());
|
||||||
|
wr->type = type;
|
||||||
|
wr->main_context = g_main_context_ref (main_context);
|
||||||
|
wr->done = FALSE;
|
||||||
|
|
||||||
|
if (GDK_IS_CLIPBOARD (self->_clipboard))
|
||||||
|
gdk_clipboard_write_async (self->_clipboard,
|
||||||
|
mime_type,
|
||||||
|
G_OUTPUT_STREAM (wr->stream),
|
||||||
|
G_PRIORITY_DEFAULT,
|
||||||
|
NULL,
|
||||||
|
on_data_ready_cb,
|
||||||
|
wr);
|
||||||
|
else if (GDK_IS_DRAG (self->_drag))
|
||||||
|
gdk_drag_write_async (self->_drag,
|
||||||
|
mime_type,
|
||||||
|
G_OUTPUT_STREAM (wr->stream),
|
||||||
|
G_PRIORITY_DEFAULT,
|
||||||
|
NULL,
|
||||||
|
on_data_ready_cb,
|
||||||
|
wr);
|
||||||
|
else
|
||||||
|
g_return_if_reached ();
|
||||||
|
|
||||||
|
/* We're forced to provide data synchronously via this API
|
||||||
|
* so we must block on the main loop. Using another main loop
|
||||||
|
* than the default tends to get us locked up here, so that is
|
||||||
|
* what we'll do for now.
|
||||||
|
*/
|
||||||
|
while (!wr->done)
|
||||||
|
g_main_context_iteration (wr->main_context, TRUE);
|
||||||
|
|
||||||
|
write_request_free (wr);
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)pasteboardFinishedWithDataProvider:(NSPasteboard *)pasteboard
|
||||||
|
{
|
||||||
|
g_clear_object (&self->_clipboard);
|
||||||
|
g_clear_object (&self->_drag);
|
||||||
|
g_clear_object (&self->_contentProvider);
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation GdkMacosPasteboardItem
|
||||||
|
|
||||||
|
-(id)initForClipboard:(GdkClipboard*)clipboard withContentProvider:(GdkContentProvider*)contentProvider
|
||||||
|
{
|
||||||
|
GdkMacosPasteboardItemDataProvider *dataProvider;
|
||||||
|
|
||||||
|
dataProvider = [[GdkMacosPasteboardItemDataProvider alloc] initForClipboard:clipboard withContentProvider:contentProvider];
|
||||||
|
|
||||||
|
[super init];
|
||||||
|
g_set_object (&self->_clipboard, clipboard);
|
||||||
|
g_set_object (&self->_contentProvider, contentProvider);
|
||||||
|
[self setDataProvider:dataProvider forTypes:[dataProvider types]];
|
||||||
|
|
||||||
|
[dataProvider release];
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(id)initForDrag:(GdkDrag*)drag withContentProvider:(GdkContentProvider*)contentProvider
|
||||||
|
{
|
||||||
|
GdkMacosPasteboardItemDataProvider *dataProvider;
|
||||||
|
|
||||||
|
dataProvider = [[GdkMacosPasteboardItemDataProvider alloc] initForDrag:drag withContentProvider:contentProvider];
|
||||||
|
|
||||||
|
[super init];
|
||||||
|
g_set_object (&self->_drag, drag);
|
||||||
|
g_set_object (&self->_contentProvider, contentProvider);
|
||||||
|
[self setDataProvider:dataProvider forTypes:[dataProvider types]];
|
||||||
|
|
||||||
|
[dataProvider release];
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)dealloc
|
||||||
|
{
|
||||||
|
g_clear_object (&self->_contentProvider);
|
||||||
|
g_clear_object (&self->_clipboard);
|
||||||
|
g_clear_object (&self->_drag);
|
||||||
|
[super dealloc];
|
||||||
|
}
|
||||||
|
|
||||||
|
-(NSRect)draggingFrame
|
||||||
|
{
|
||||||
|
return self->_draggingFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)setDraggingFrame:(NSRect)draggingFrame;
|
||||||
|
{
|
||||||
|
self->_draggingFrame = draggingFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(id)item
|
||||||
|
{
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(NSArray* (^) (void))imageComponentsProvider
|
||||||
|
{
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
Loading…
Reference in New Issue
Block a user