Mac: Add drag & drop support.
authorJørgen P. Tjernø <jorgen@uberent.com>
Mon, 24 Nov 2014 11:46:20 -0800
changeset 9237 2cc90bb31777
parent 9236 a845edf98a80
child 9238 3e53bd4510a2
Mac: Add drag & drop support. Fixes bug https://bugzilla.libsdl.org/show_bug.cgi?id=2757 Thanks to Alex Szpakowski for the patch!
src/video/cocoa/SDL_cocoawindow.m
--- a/src/video/cocoa/SDL_cocoawindow.m	Sun Nov 23 15:48:52 2014 -0500
+++ b/src/video/cocoa/SDL_cocoawindow.m	Mon Nov 24 11:46:20 2014 -0800
@@ -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 @@
     [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 @@
     [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];