From 94539137a2948814235d89fc05da05a6e9c3f4cb Mon Sep 17 00:00:00 2001 From: "J?rgen P. Tjern?" Date: Mon, 24 Nov 2014 11:46:20 -0800 Subject: [PATCH] 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 | 58 ++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/src/video/cocoa/SDL_cocoawindow.m b/src/video/cocoa/SDL_cocoawindow.m index 48621a4f1..d5455290a 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 /* 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 )sender; +- (BOOL)performDragOperation:(id )sender; +- (BOOL)wantsPeriodicDraggingUpdates; @end @implementation SDLWindow + - (BOOL)canBecomeKeyWindow { return YES; @@ -96,6 +103,51 @@ { /*NSLog(@"doCommandBySelector: %@\n", NSStringFromSelector(aSelector));*/ } + +- (NSDragOperation)draggingEntered:(id )sender +{ + return NSDragOperationGeneric; +} + +- (BOOL)performDragOperation:(id )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];