Add Drag and drop position, for x11, wayland and MACOSX

This commit is contained in:
Sylvain
2023-03-06 11:16:18 +01:00
committed by Sam Lantinga
parent 813c586edb
commit a946a34452
7 changed files with 112 additions and 15 deletions

View File

@@ -27,9 +27,11 @@
#include "../video/SDL_sysvideo.h" /* for SDL_Window internals. */
static int SDL_SendDrop(SDL_Window *window, const SDL_EventType evtype, const char *data)
static int SDL_SendDrop(SDL_Window *window, const SDL_EventType evtype, const char *data, float x, float y)
{
static SDL_bool app_is_dropping = SDL_FALSE;
static float last_drop_x = 0;
static float last_drop_y = 0;
int posted = 0;
/* Post the event, if desired */
@@ -58,6 +60,13 @@ static int SDL_SendDrop(SDL_Window *window, const SDL_EventType evtype, const ch
event.common.timestamp = 0;
event.drop.file = data ? SDL_strdup(data) : NULL;
event.drop.windowID = window ? window->id : 0;
if (evtype == SDL_EVENT_DROP_POSITION) {
last_drop_x = x;
last_drop_y = y;
}
event.drop.x = last_drop_x;
event.drop.y = last_drop_y;
posted = (SDL_PushEvent(&event) > 0);
if (posted && (evtype == SDL_EVENT_DROP_COMPLETE)) {
@@ -66,6 +75,9 @@ static int SDL_SendDrop(SDL_Window *window, const SDL_EventType evtype, const ch
} else {
app_is_dropping = SDL_FALSE;
}
last_drop_x = 0;
last_drop_y = 0;
}
}
return posted;
@@ -73,15 +85,21 @@ static int SDL_SendDrop(SDL_Window *window, const SDL_EventType evtype, const ch
int SDL_SendDropFile(SDL_Window *window, const char *file)
{
return SDL_SendDrop(window, SDL_EVENT_DROP_FILE, file);
return SDL_SendDrop(window, SDL_EVENT_DROP_FILE, file, 0, 0);
}
int SDL_SendDropPosition(SDL_Window *window, const char *file, 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);
}
int SDL_SendDropText(SDL_Window *window, const char *text)
{
return SDL_SendDrop(window, SDL_EVENT_DROP_TEXT, text);
return SDL_SendDrop(window, SDL_EVENT_DROP_TEXT, text, 0, 0);
}
int SDL_SendDropComplete(SDL_Window *window)
{
return SDL_SendDrop(window, SDL_EVENT_DROP_COMPLETE, NULL);
return SDL_SendDrop(window, SDL_EVENT_DROP_COMPLETE, NULL, 0, 0);
}

View File

@@ -24,6 +24,7 @@
#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_SendDropText(SDL_Window *window, const char *text);
extern int SDL_SendDropComplete(SDL_Window *window);

View File

@@ -85,6 +85,7 @@
/* Handle drag-and-drop of files onto the SDL window. */
- (NSDragOperation)draggingEntered:(id<NSDraggingInfo>)sender;
- (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)sender;
- (BOOL)performDragOperation:(id<NSDraggingInfo>)sender;
- (BOOL)wantsPeriodicDraggingUpdates;
- (BOOL)validateMenuItem:(NSMenuItem *)menuItem;
@@ -158,6 +159,21 @@
return NSDragOperationNone; /* no idea what to do with this, reject it. */
}
- (NSDragOperation)draggingUpdated:(id<NSDraggingInfo>)sender
{
if (([sender draggingSourceOperationMask] & NSDragOperationGeneric) == NSDragOperationGeneric) {
SDL_Window *sdlwindow = [self findSDLWindow];
NSPoint point = [sender draggingLocation];
float x, y;
x = point.x;
y = (sdlwindow->h - point.y);
SDL_SendDropPosition(sdlwindow, NULL, x, y); /* FIXME, should we get the filename */
return NSDragOperationGeneric;
}
return NSDragOperationNone; /* no idea what to do with this, reject it. */
}
- (BOOL)performDragOperation:(id<NSDraggingInfo>)sender
{
@autoreleasepool {

View File

@@ -96,6 +96,8 @@ struct SDL_WaylandTouchPointList
static struct SDL_WaylandTouchPointList touch_points = { NULL, NULL };
static char *Wayland_URIToLocal(char *uri);
static void touch_add(SDL_TouchID id, float x, float y, struct wl_surface *surface)
{
struct SDL_WaylandTouchPoint *tp = SDL_malloc(sizeof(struct SDL_WaylandTouchPoint));
@@ -1845,6 +1847,30 @@ static void data_device_handle_leave(void *data, struct wl_data_device *wl_data_
static void data_device_handle_motion(void *data, struct wl_data_device *wl_data_device,
uint32_t time, wl_fixed_t x, wl_fixed_t y)
{
SDL_WaylandDataDevice *data_device = data;
if (data_device->drag_offer != NULL) {
/* TODO: SDL Support more mime types */
size_t length;
void *buffer = Wayland_data_offer_receive(data_device->drag_offer,
&length, FILE_MIME, SDL_TRUE);
if (buffer) {
char *saveptr = NULL;
char *token = SDL_strtokr((char *)buffer, "\r\n", &saveptr);
while (token != NULL) {
char *fn = Wayland_URIToLocal(token);
if (fn) {
double dx;
double dy;
dx = wl_fixed_to_double(x);
dy = wl_fixed_to_double(y);
SDL_SendDropPosition(data_device->dnd_window, fn, (float)dx, (float)dy);
}
token = SDL_strtokr(NULL, "\r\n", &saveptr);
}
SDL_free(buffer);
}
}
}
/* Decodes URI escape sequences in string buf of len bytes

View File

@@ -1222,6 +1222,18 @@ static void X11_DispatchEvent(_THIS, XEvent *xevent)
}
printf("Action requested by user is : %s\n", X11_XGetAtomName(display, act));
#endif
{
/* Drag and Drop position */
int root_x, root_y, window_x, window_y;
Window ChildReturn;
root_x = xevent->xclient.data.l[2] >> 16;
root_y = xevent->xclient.data.l[2] & 0xffff;
/* Translate from root to current window position */
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 ? */
}
/* reply with status */
SDL_memset(&m, 0, sizeof(XClientMessageEvent));