Mac: Add drag & drop support. Fixes bug https://bugzilla.libsdl.org/show_bug.cgi?id=2757 Thanks to Alex Szpakowski for the patch!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
diff --git a/src/video/cocoa/SDL_cocoawindow.m b/src/video/cocoa/SDL_cocoawindow.m
index 48621a4..d545529 100644
--- a/src/video/cocoa/SDL_cocoawindow.m
+++ b/src/video/cocoa/SDL_cocoawindow.m
@@ -34,6 +34,7 @@
#include "../../events/SDL_mouse_c.h"
#include "../../events/SDL_touch_c.h"
#include "../../events/SDL_windowevents_c.h"
+#include "../../events/SDL_dropevents_c.h"
#include "SDL_cocoavideo.h"
#include "SDL_cocoashape.h"
#include "SDL_cocoamouse.h"
@@ -52,15 +53,21 @@
#define FULLSCREEN_MASK (SDL_WINDOW_FULLSCREEN_DESKTOP | SDL_WINDOW_FULLSCREEN)
-@interface SDLWindow : NSWindow
+@interface SDLWindow : NSWindow <NSDraggingDestination>
/* These are needed for borderless/fullscreen windows */
- (BOOL)canBecomeKeyWindow;
- (BOOL)canBecomeMainWindow;
- (void)sendEvent:(NSEvent *)event;
- (void)doCommandBySelector:(SEL)aSelector;
+
+/* Handle drag-and-drop of files onto the SDL window. */
+- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender;
+- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender;
+- (BOOL)wantsPeriodicDraggingUpdates;
@end
@implementation SDLWindow
+
- (BOOL)canBecomeKeyWindow
{
return YES;
@@ -96,6 +103,51 @@
{
/*NSLog(@"doCommandBySelector: %@\n", NSStringFromSelector(aSelector));*/
}
+
+- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
+{
+ return NSDragOperationGeneric;
+}
+
+- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
+{
+ NSURL *fileURL = [NSURL URLFromPasteboard:[sender draggingPasteboard]];
+ NSNumber *isAlias = nil;
+
+ if (fileURL == nil) {
+ return NO;
+ }
+
+ /* Functionality for resolving URL aliases was added with OS X 10.6. */
+ if ([fileURL respondsToSelector:@selector(getResourceValue:forKey:error:)]) {
+ [fileURL getResourceValue:&isAlias forKey:NSURLIsAliasFileKey error:nil];
+ }
+
+ /* If the URL is an alias, resolve it. */
+ if ([isAlias boolValue]) {
+ NSURLBookmarkResolutionOptions opts = NSURLBookmarkResolutionWithoutMounting | NSURLBookmarkResolutionWithoutUI;
+ NSData *bookmark = [NSURL bookmarkDataWithContentsOfURL:fileURL error:nil];
+ if (bookmark != nil) {
+ NSURL *resolvedURL = [NSURL URLByResolvingBookmarkData:bookmark
+ options:opts
+ relativeToURL:nil
+ bookmarkDataIsStale:nil
+ error:nil];
+
+ if (resolvedURL != nil) {
+ fileURL = resolvedURL;
+ }
+ }
+ }
+
+ return (BOOL) SDL_SendDropFile([[fileURL path] UTF8String]);
+}
+
+- (BOOL)wantsPeriodicDraggingUpdates
+{
+ return NO;
+}
+
@end
@@ -1120,6 +1172,9 @@ Cocoa_CreateWindow(_THIS, SDL_Window * window)
[nswindow setContentView: contentView];
[contentView release];
+ /* Allow files and folders to be dragged onto the window by users */
+ [nswindow registerForDraggedTypes:[NSArray arrayWithObject:(NSString *)kUTTypeFileURL]];
+
[pool release];
if (SetupWindowData(_this, window, nswindow, SDL_TRUE) < 0) {
@@ -1351,6 +1406,7 @@ Cocoa_RebuildWindow(SDL_WindowData * data, NSWindow * nswindow, unsigned style)
[data->listener close];
data->nswindow = [[SDLWindow alloc] initWithContentRect:[[nswindow contentView] frame] styleMask:style backing:NSBackingStoreBuffered defer:NO screen:[nswindow screen]];
[data->nswindow setContentView:[nswindow contentView]];
+ [data->nswindow registerForDraggedTypes:[NSArray arrayWithObject:(NSString *)kUTTypeFileURL]];
/* See comment in SetupWindowData. */
[data->nswindow setOneShot:NO];
[data->listener listen:data];