diff --git a/include/SDL3/SDL_events.h b/include/SDL3/SDL_events.h index ad87c5ccb..2afa92f3e 100644 --- a/include/SDL3/SDL_events.h +++ b/include/SDL3/SDL_events.h @@ -523,6 +523,7 @@ typedef struct SDL_DropEvent SDL_WindowID windowID; /**< The window that was dropped on, if any */ float x; /**< X coordinate, relative to window (not on begin) */ float y; /**< Y coordinate, relative to window (not on begin) */ + char *source; /**< The source app that sent this drop event, or NULL if that isn't available */ char *data; /**< The text for SDL_EVENT_DROP_TEXT and the file name for SDL_EVENT_DROP_FILE, NULL for other events */ char short_data[SDL_DROPEVENT_DATA_SIZE]; /**< Memory space for short data, use 'data' instead */ } SDL_DropEvent; diff --git a/src/core/android/SDL_android.c b/src/core/android/SDL_android.c index 99ebd7492..8626a6b6f 100644 --- a/src/core/android/SDL_android.c +++ b/src/core/android/SDL_android.c @@ -878,7 +878,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeDropFile)( jstring filename) { const char *path = (*env)->GetStringUTFChars(env, filename, NULL); - SDL_SendDropFile(NULL, path); + SDL_SendDropFile(NULL, NULL, path); (*env)->ReleaseStringUTFChars(env, filename, path); SDL_SendDropComplete(NULL); } diff --git a/src/core/haiku/SDL_BeApp.cc b/src/core/haiku/SDL_BeApp.cc index 16eb58aff..8403f9a18 100644 --- a/src/core/haiku/SDL_BeApp.cc +++ b/src/core/haiku/SDL_BeApp.cc @@ -69,7 +69,7 @@ public: entry_ref entryRef; for (int32 i = 0; message->FindRef("refs", i, &entryRef) == B_OK; i++) { BPath referencePath = BPath(&entryRef); - SDL_SendDropFile(NULL, referencePath.Path()); + SDL_SendDropFile(NULL, NULL, referencePath.Path()); } return; } diff --git a/src/events/SDL_dropevents.c b/src/events/SDL_dropevents.c index 211b8d3b3..a7b9fa7a7 100644 --- a/src/events/SDL_dropevents.c +++ b/src/events/SDL_dropevents.c @@ -27,7 +27,7 @@ #include "../video/SDL_sysvideo.h" /* for SDL_Window internals. */ -static int SDL_SendDrop(SDL_Window *window, const SDL_EventType evtype, const char *data, float x, float y) +static int SDL_SendDrop(SDL_Window *window, const SDL_EventType evtype, const char *source, const char *data, float x, float y) { static SDL_bool app_is_dropping = SDL_FALSE; static float last_drop_x = 0; @@ -58,6 +58,9 @@ static int SDL_SendDrop(SDL_Window *window, const SDL_EventType evtype, const ch SDL_zero(event); event.type = evtype; event.common.timestamp = 0; + if (source) { + event.drop.source = SDL_strdup(source); + } if (data) { size_t len = SDL_strlen(data); if (len < sizeof(event.drop.short_data)) { @@ -91,23 +94,22 @@ static int SDL_SendDrop(SDL_Window *window, const SDL_EventType evtype, const ch return posted; } -int SDL_SendDropFile(SDL_Window *window, const char *file) +int SDL_SendDropFile(SDL_Window *window, const char *source, const char *file) { - return SDL_SendDrop(window, SDL_EVENT_DROP_FILE, file, 0, 0); + return SDL_SendDrop(window, SDL_EVENT_DROP_FILE, source, file, 0, 0); } -int SDL_SendDropPosition(SDL_Window *window, const char *file, float x, float y) +int SDL_SendDropPosition(SDL_Window *window, float x, float y) { - /* Don't send 'file' since this is an malloc per position, which may be forgotten to be freed */ - return SDL_SendDrop(window, SDL_EVENT_DROP_POSITION, NULL, x, y); + return SDL_SendDrop(window, SDL_EVENT_DROP_POSITION, NULL, NULL, x, y); } int SDL_SendDropText(SDL_Window *window, const char *text) { - return SDL_SendDrop(window, SDL_EVENT_DROP_TEXT, text, 0, 0); + return SDL_SendDrop(window, SDL_EVENT_DROP_TEXT, NULL, text, 0, 0); } int SDL_SendDropComplete(SDL_Window *window) { - return SDL_SendDrop(window, SDL_EVENT_DROP_COMPLETE, NULL, 0, 0); + return SDL_SendDrop(window, SDL_EVENT_DROP_COMPLETE, NULL, NULL, 0, 0); } diff --git a/src/events/SDL_dropevents_c.h b/src/events/SDL_dropevents_c.h index 9a485cd0b..f2396d5d3 100644 --- a/src/events/SDL_dropevents_c.h +++ b/src/events/SDL_dropevents_c.h @@ -23,8 +23,8 @@ #ifndef SDL_dropevents_c_h_ #define SDL_dropevents_c_h_ -extern int SDL_SendDropFile(SDL_Window *window, const char *file); -extern int SDL_SendDropPosition(SDL_Window *window, const char *file, float x, float y); +extern int SDL_SendDropFile(SDL_Window *window, const char *source, const char *file); +extern int SDL_SendDropPosition(SDL_Window *window, float x, float y); extern int SDL_SendDropText(SDL_Window *window, const char *text); extern int SDL_SendDropComplete(SDL_Window *window); diff --git a/src/events/SDL_events.c b/src/events/SDL_events.c index 1ce42ad57..3f18641a7 100644 --- a/src/events/SDL_events.c +++ b/src/events/SDL_events.c @@ -1073,6 +1073,10 @@ void SDL_CleanupEvent(SDL_Event *event) switch (event->type) { case SDL_EVENT_DROP_FILE: case SDL_EVENT_DROP_TEXT: + if (event->drop.source) { + SDL_free(event->drop.source); + event->drop.data = NULL; + } if (event->drop.data && event->drop.data != event->drop.short_data) { SDL_free(event->drop.data); event->drop.data = NULL; diff --git a/src/video/cocoa/SDL_cocoaevents.m b/src/video/cocoa/SDL_cocoaevents.m index 221a61d91..3674965c8 100644 --- a/src/video/cocoa/SDL_cocoaevents.m +++ b/src/video/cocoa/SDL_cocoaevents.m @@ -287,7 +287,7 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent) - (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename { - return (BOOL)SDL_SendDropFile(NULL, [filename UTF8String]) && SDL_SendDropComplete(NULL); + return (BOOL)SDL_SendDropFile(NULL, NULL, [filename UTF8String]) && SDL_SendDropComplete(NULL); } - (void)applicationDidFinishLaunching:(NSNotification *)notification @@ -315,7 +315,7 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent) - (void)handleURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent { NSString *path = [[event paramDescriptorForKeyword:keyDirectObject] stringValue]; - SDL_SendDropFile(NULL, [path UTF8String]); + SDL_SendDropFile(NULL, NULL, [path UTF8String]); SDL_SendDropComplete(NULL); } diff --git a/src/video/cocoa/SDL_cocoawindow.m b/src/video/cocoa/SDL_cocoawindow.m index f86027e0e..970e8e1f1 100644 --- a/src/video/cocoa/SDL_cocoawindow.m +++ b/src/video/cocoa/SDL_cocoawindow.m @@ -177,7 +177,7 @@ float x, y; x = point.x; y = (sdlwindow->h - point.y); - SDL_SendDropPosition(sdlwindow, NULL, x, y); /* FIXME, should we get the filename */ + SDL_SendDropPosition(sdlwindow, x, y); return NSDragOperationGeneric; } @@ -242,7 +242,7 @@ } } - if (!SDL_SendDropFile(sdlwindow, [[fileURL path] UTF8String])) { + if (!SDL_SendDropFile(sdlwindow, NULL, [[fileURL path] UTF8String])) { return NO; } } diff --git a/src/video/uikit/SDL_uikitappdelegate.m b/src/video/uikit/SDL_uikitappdelegate.m index e9d6ca337..8a4c0e460 100644 --- a/src/video/uikit/SDL_uikitappdelegate.m +++ b/src/video/uikit/SDL_uikitappdelegate.m @@ -212,7 +212,7 @@ static UIImage *SDL_LoadLaunchImageNamed(NSString *name, int screenh) NSArray *launchimages = [bundle objectForInfoDictionaryKey:@"UILaunchImages"]; NSString *imagename = nil; UIImage *image = nil; - + #if TARGET_OS_XR int screenw = SDL_XR_SCREENWIDTH; int screenh = SDL_XR_SCREENHEIGHT; @@ -221,7 +221,7 @@ static UIImage *SDL_LoadLaunchImageNamed(NSString *name, int screenh) int screenh = (int)([UIScreen mainScreen].bounds.size.height + 0.5); #endif - + #if !TARGET_OS_TV && !TARGET_OS_XR UIInterfaceOrientation curorient = [UIApplication sharedApplication].statusBarOrientation; @@ -505,13 +505,14 @@ static UIImage *SDL_LoadLaunchImageNamed(NSString *name, int screenh) /* Do nothing. */ } -- (void)sendDropFileForURL:(NSURL *)url +- (void)sendDropFileForURL:(NSURL *)url fromSourceApplication:(NSString *)sourceApplication { NSURL *fileURL = url.filePathURL; + char *sourceApplicationCString = sourceApplication ? [sourceApplication UTF8String] : NULL; if (fileURL != nil) { - SDL_SendDropFile(NULL, fileURL.path.UTF8String); + SDL_SendDropFile(NULL, sourceApplicationCString, fileURL.path.UTF8String); } else { - SDL_SendDropFile(NULL, url.absoluteString.UTF8String); + SDL_SendDropFile(NULL, sourceApplicationCString, url.absoluteString.UTF8String); } SDL_SendDropComplete(NULL); } @@ -521,7 +522,7 @@ static UIImage *SDL_LoadLaunchImageNamed(NSString *name, int screenh) - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options { /* TODO: Handle options */ - [self sendDropFileForURL:url]; + [self sendDropFileForURL:url fromSourceApplication:NULL]; return YES; } @@ -529,7 +530,7 @@ static UIImage *SDL_LoadLaunchImageNamed(NSString *name, int screenh) - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { - [self sendDropFileForURL:url]; + [self sendDropFileForURL:url fromSourceApplication:sourceApplication]; return YES; } diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c index c68b49c3c..2e9583cc7 100644 --- a/src/video/wayland/SDL_waylandevents.c +++ b/src/video/wayland/SDL_waylandevents.c @@ -1909,7 +1909,7 @@ static void data_device_handle_motion(void *data, struct wl_data_device *wl_data * Any future implementation should cache the filenames, as otherwise this could * hammer the DBus interface hundreds or even thousands of times per second. */ - SDL_SendDropPosition(data_device->dnd_window, NULL, dx, dy); + SDL_SendDropPosition(data_device->dnd_window, dx, dy); } } @@ -2055,7 +2055,7 @@ static void data_device_handle_drop(void *data, struct wl_data_device *wl_data_d /* If dropped files contain a directory the list is empty */ if (paths && path_count > 0) { for (int i = 0; i < path_count; i++) { - SDL_SendDropFile(data_device->dnd_window, paths[i]); + SDL_SendDropFile(data_device->dnd_window, NULL, paths[i]); } dbus->free_string_array(paths); SDL_SendDropComplete(data_device->dnd_window); @@ -2080,7 +2080,7 @@ static void data_device_handle_drop(void *data, struct wl_data_device *wl_data_d while (token != NULL) { char *fn = Wayland_URIToLocal(token); if (fn) { - SDL_SendDropFile(data_device->dnd_window, fn); + SDL_SendDropFile(data_device->dnd_window, NULL, fn); } token = SDL_strtok_r(NULL, "\r\n", &saveptr); } diff --git a/src/video/windows/SDL_windowsevents.c b/src/video/windows/SDL_windowsevents.c index f2e747ee9..042667c84 100644 --- a/src/video/windows/SDL_windowsevents.c +++ b/src/video/windows/SDL_windowsevents.c @@ -1478,7 +1478,7 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) if (buffer) { if (DragQueryFile(drop, i, buffer, size)) { char *file = WIN_StringToUTF8(buffer); - SDL_SendDropFile(data->window, file); + SDL_SendDropFile(data->window, NULL, file); SDL_free(file); } SDL_small_free(buffer, isstack); diff --git a/src/video/x11/SDL_x11events.c b/src/video/x11/SDL_x11events.c index d414ee66a..9c7afcf44 100644 --- a/src/video/x11/SDL_x11events.c +++ b/src/video/x11/SDL_x11events.c @@ -1327,7 +1327,7 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent) X11_XTranslateCoordinates(display, DefaultRootWindow(display), data->xwindow, root_x, root_y, &window_x, &window_y, &ChildReturn); - SDL_SendDropPosition(data->window, NULL, (float)window_x, (float)window_y); /* FIXME, can we get the filename ? */ + SDL_SendDropPosition(data->window, (float)window_x, (float)window_y); } /* reply with status */ @@ -1629,7 +1629,7 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent) } else if (SDL_strcmp("text/uri-list", name) == 0) { char *fn = X11_URIToLocal(token); if (fn) { - SDL_SendDropFile(data->window, fn); + SDL_SendDropFile(data->window, NULL, fn); } } token = SDL_strtok_r(NULL, "\r\n", &saveptr);