Add the source application for drag and drop events (thanks Nathan!)
This is only implemented on iOS, but is useful for third party application integrations. Fixes https://github.com/libsdl-org/SDL/issues/2024
This commit is contained in:
parent
1a8bf31a69
commit
91f0456391
@ -523,6 +523,7 @@ typedef struct SDL_DropEvent
|
|||||||
SDL_WindowID windowID; /**< The window that was dropped on, if any */
|
SDL_WindowID windowID; /**< The window that was dropped on, if any */
|
||||||
float x; /**< X coordinate, relative to window (not on begin) */
|
float x; /**< X coordinate, relative to window (not on begin) */
|
||||||
float y; /**< Y 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 *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 */
|
char short_data[SDL_DROPEVENT_DATA_SIZE]; /**< Memory space for short data, use 'data' instead */
|
||||||
} SDL_DropEvent;
|
} SDL_DropEvent;
|
||||||
|
@ -878,7 +878,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeDropFile)(
|
|||||||
jstring filename)
|
jstring filename)
|
||||||
{
|
{
|
||||||
const char *path = (*env)->GetStringUTFChars(env, filename, NULL);
|
const char *path = (*env)->GetStringUTFChars(env, filename, NULL);
|
||||||
SDL_SendDropFile(NULL, path);
|
SDL_SendDropFile(NULL, NULL, path);
|
||||||
(*env)->ReleaseStringUTFChars(env, filename, path);
|
(*env)->ReleaseStringUTFChars(env, filename, path);
|
||||||
SDL_SendDropComplete(NULL);
|
SDL_SendDropComplete(NULL);
|
||||||
}
|
}
|
||||||
|
@ -69,7 +69,7 @@ public:
|
|||||||
entry_ref entryRef;
|
entry_ref entryRef;
|
||||||
for (int32 i = 0; message->FindRef("refs", i, &entryRef) == B_OK; i++) {
|
for (int32 i = 0; message->FindRef("refs", i, &entryRef) == B_OK; i++) {
|
||||||
BPath referencePath = BPath(&entryRef);
|
BPath referencePath = BPath(&entryRef);
|
||||||
SDL_SendDropFile(NULL, referencePath.Path());
|
SDL_SendDropFile(NULL, NULL, referencePath.Path());
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
#include "../video/SDL_sysvideo.h" /* for SDL_Window internals. */
|
#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 SDL_bool app_is_dropping = SDL_FALSE;
|
||||||
static float last_drop_x = 0;
|
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);
|
SDL_zero(event);
|
||||||
event.type = evtype;
|
event.type = evtype;
|
||||||
event.common.timestamp = 0;
|
event.common.timestamp = 0;
|
||||||
|
if (source) {
|
||||||
|
event.drop.source = SDL_strdup(source);
|
||||||
|
}
|
||||||
if (data) {
|
if (data) {
|
||||||
size_t len = SDL_strlen(data);
|
size_t len = SDL_strlen(data);
|
||||||
if (len < sizeof(event.drop.short_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;
|
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, NULL, x, y);
|
||||||
return SDL_SendDrop(window, SDL_EVENT_DROP_POSITION, NULL, x, y);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int SDL_SendDropText(SDL_Window *window, const char *text)
|
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)
|
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);
|
||||||
}
|
}
|
||||||
|
@ -23,8 +23,8 @@
|
|||||||
#ifndef SDL_dropevents_c_h_
|
#ifndef SDL_dropevents_c_h_
|
||||||
#define SDL_dropevents_c_h_
|
#define SDL_dropevents_c_h_
|
||||||
|
|
||||||
extern int SDL_SendDropFile(SDL_Window *window, const char *file);
|
extern int SDL_SendDropFile(SDL_Window *window, const char *source, const char *file);
|
||||||
extern int SDL_SendDropPosition(SDL_Window *window, const char *file, float x, float y);
|
extern int SDL_SendDropPosition(SDL_Window *window, float x, float y);
|
||||||
extern int SDL_SendDropText(SDL_Window *window, const char *text);
|
extern int SDL_SendDropText(SDL_Window *window, const char *text);
|
||||||
extern int SDL_SendDropComplete(SDL_Window *window);
|
extern int SDL_SendDropComplete(SDL_Window *window);
|
||||||
|
|
||||||
|
@ -1073,6 +1073,10 @@ void SDL_CleanupEvent(SDL_Event *event)
|
|||||||
switch (event->type) {
|
switch (event->type) {
|
||||||
case SDL_EVENT_DROP_FILE:
|
case SDL_EVENT_DROP_FILE:
|
||||||
case SDL_EVENT_DROP_TEXT:
|
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) {
|
if (event->drop.data && event->drop.data != event->drop.short_data) {
|
||||||
SDL_free(event->drop.data);
|
SDL_free(event->drop.data);
|
||||||
event->drop.data = NULL;
|
event->drop.data = NULL;
|
||||||
|
@ -287,7 +287,7 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent)
|
|||||||
|
|
||||||
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
|
- (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
|
- (void)applicationDidFinishLaunching:(NSNotification *)notification
|
||||||
@ -315,7 +315,7 @@ static void Cocoa_DispatchEvent(NSEvent *theEvent)
|
|||||||
- (void)handleURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent
|
- (void)handleURLEvent:(NSAppleEventDescriptor *)event withReplyEvent:(NSAppleEventDescriptor *)replyEvent
|
||||||
{
|
{
|
||||||
NSString *path = [[event paramDescriptorForKeyword:keyDirectObject] stringValue];
|
NSString *path = [[event paramDescriptorForKeyword:keyDirectObject] stringValue];
|
||||||
SDL_SendDropFile(NULL, [path UTF8String]);
|
SDL_SendDropFile(NULL, NULL, [path UTF8String]);
|
||||||
SDL_SendDropComplete(NULL);
|
SDL_SendDropComplete(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,7 +177,7 @@
|
|||||||
float x, y;
|
float x, y;
|
||||||
x = point.x;
|
x = point.x;
|
||||||
y = (sdlwindow->h - point.y);
|
y = (sdlwindow->h - point.y);
|
||||||
SDL_SendDropPosition(sdlwindow, NULL, x, y); /* FIXME, should we get the filename */
|
SDL_SendDropPosition(sdlwindow, x, y);
|
||||||
return NSDragOperationGeneric;
|
return NSDragOperationGeneric;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -242,7 +242,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!SDL_SendDropFile(sdlwindow, [[fileURL path] UTF8String])) {
|
if (!SDL_SendDropFile(sdlwindow, NULL, [[fileURL path] UTF8String])) {
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -212,7 +212,7 @@ static UIImage *SDL_LoadLaunchImageNamed(NSString *name, int screenh)
|
|||||||
NSArray *launchimages = [bundle objectForInfoDictionaryKey:@"UILaunchImages"];
|
NSArray *launchimages = [bundle objectForInfoDictionaryKey:@"UILaunchImages"];
|
||||||
NSString *imagename = nil;
|
NSString *imagename = nil;
|
||||||
UIImage *image = nil;
|
UIImage *image = nil;
|
||||||
|
|
||||||
#if TARGET_OS_XR
|
#if TARGET_OS_XR
|
||||||
int screenw = SDL_XR_SCREENWIDTH;
|
int screenw = SDL_XR_SCREENWIDTH;
|
||||||
int screenh = SDL_XR_SCREENHEIGHT;
|
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);
|
int screenh = (int)([UIScreen mainScreen].bounds.size.height + 0.5);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if !TARGET_OS_TV && !TARGET_OS_XR
|
#if !TARGET_OS_TV && !TARGET_OS_XR
|
||||||
UIInterfaceOrientation curorient = [UIApplication sharedApplication].statusBarOrientation;
|
UIInterfaceOrientation curorient = [UIApplication sharedApplication].statusBarOrientation;
|
||||||
@ -505,13 +505,14 @@ static UIImage *SDL_LoadLaunchImageNamed(NSString *name, int screenh)
|
|||||||
/* Do nothing. */
|
/* Do nothing. */
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)sendDropFileForURL:(NSURL *)url
|
- (void)sendDropFileForURL:(NSURL *)url fromSourceApplication:(NSString *)sourceApplication
|
||||||
{
|
{
|
||||||
NSURL *fileURL = url.filePathURL;
|
NSURL *fileURL = url.filePathURL;
|
||||||
|
char *sourceApplicationCString = sourceApplication ? [sourceApplication UTF8String] : NULL;
|
||||||
if (fileURL != nil) {
|
if (fileURL != nil) {
|
||||||
SDL_SendDropFile(NULL, fileURL.path.UTF8String);
|
SDL_SendDropFile(NULL, sourceApplicationCString, fileURL.path.UTF8String);
|
||||||
} else {
|
} else {
|
||||||
SDL_SendDropFile(NULL, url.absoluteString.UTF8String);
|
SDL_SendDropFile(NULL, sourceApplicationCString, url.absoluteString.UTF8String);
|
||||||
}
|
}
|
||||||
SDL_SendDropComplete(NULL);
|
SDL_SendDropComplete(NULL);
|
||||||
}
|
}
|
||||||
@ -521,7 +522,7 @@ static UIImage *SDL_LoadLaunchImageNamed(NSString *name, int screenh)
|
|||||||
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options
|
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options
|
||||||
{
|
{
|
||||||
/* TODO: Handle options */
|
/* TODO: Handle options */
|
||||||
[self sendDropFileForURL:url];
|
[self sendDropFileForURL:url fromSourceApplication:NULL];
|
||||||
return YES;
|
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
|
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
|
||||||
{
|
{
|
||||||
[self sendDropFileForURL:url];
|
[self sendDropFileForURL:url fromSourceApplication:sourceApplication];
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
* Any future implementation should cache the filenames, as otherwise this could
|
||||||
* hammer the DBus interface hundreds or even thousands of times per second.
|
* 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 dropped files contain a directory the list is empty */
|
||||||
if (paths && path_count > 0) {
|
if (paths && path_count > 0) {
|
||||||
for (int i = 0; i < path_count; i++) {
|
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);
|
dbus->free_string_array(paths);
|
||||||
SDL_SendDropComplete(data_device->dnd_window);
|
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) {
|
while (token != NULL) {
|
||||||
char *fn = Wayland_URIToLocal(token);
|
char *fn = Wayland_URIToLocal(token);
|
||||||
if (fn) {
|
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);
|
token = SDL_strtok_r(NULL, "\r\n", &saveptr);
|
||||||
}
|
}
|
||||||
|
@ -1478,7 +1478,7 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
|||||||
if (buffer) {
|
if (buffer) {
|
||||||
if (DragQueryFile(drop, i, buffer, size)) {
|
if (DragQueryFile(drop, i, buffer, size)) {
|
||||||
char *file = WIN_StringToUTF8(buffer);
|
char *file = WIN_StringToUTF8(buffer);
|
||||||
SDL_SendDropFile(data->window, file);
|
SDL_SendDropFile(data->window, NULL, file);
|
||||||
SDL_free(file);
|
SDL_free(file);
|
||||||
}
|
}
|
||||||
SDL_small_free(buffer, isstack);
|
SDL_small_free(buffer, isstack);
|
||||||
|
@ -1327,7 +1327,7 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent)
|
|||||||
X11_XTranslateCoordinates(display, DefaultRootWindow(display), data->xwindow,
|
X11_XTranslateCoordinates(display, DefaultRootWindow(display), data->xwindow,
|
||||||
root_x, root_y, &window_x, &window_y, &ChildReturn);
|
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 */
|
/* 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) {
|
} else if (SDL_strcmp("text/uri-list", name) == 0) {
|
||||||
char *fn = X11_URIToLocal(token);
|
char *fn = X11_URIToLocal(token);
|
||||||
if (fn) {
|
if (fn) {
|
||||||
SDL_SendDropFile(data->window, fn);
|
SDL_SendDropFile(data->window, NULL, fn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
token = SDL_strtok_r(NULL, "\r\n", &saveptr);
|
token = SDL_strtok_r(NULL, "\r\n", &saveptr);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user