mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-05-25 14:28:34 +00:00
wayland: Adjust DnD coordinates when dragging over a mask subsurface
This commit is contained in:
@@ -98,6 +98,7 @@ struct SDL_WaylandDataDevice
|
||||
const char *mime_type;
|
||||
bool has_mime_file, has_mime_text;
|
||||
SDL_Window *dnd_window;
|
||||
struct wl_surface *dnd_surface;
|
||||
|
||||
// Clipboard and Primary Selection
|
||||
uint32_t selection_serial;
|
||||
|
||||
@@ -2843,9 +2843,20 @@ static void data_device_handle_enter(void *data, struct wl_data_device *wl_data_
|
||||
|
||||
// Set the destination window and send the initial position.
|
||||
data_device->dnd_window = window->sdlwindow;
|
||||
const float dx = (float)(wl_fixed_to_double(x) * data_device->dnd_window->internal->pointer_scale.x);
|
||||
const float dy = (float)(wl_fixed_to_double(y) * data_device->dnd_window->internal->pointer_scale.y);
|
||||
SDL_SendDropPosition(data_device->dnd_window, dx, dy);
|
||||
data_device->dnd_surface = surface;
|
||||
double dx = wl_fixed_to_double(x);
|
||||
double dy = wl_fixed_to_double(y);
|
||||
|
||||
// If over the mask, adjust the offset.
|
||||
if (surface == window->mask.surface) {
|
||||
dx += (double)window->mask.offset_x;
|
||||
dy += (double)window->mask.offset_y;
|
||||
}
|
||||
|
||||
dx *= window->pointer_scale.x;
|
||||
dy *= window->pointer_scale.y;
|
||||
|
||||
SDL_SendDropPosition(data_device->dnd_window, (float)dx, (float)dy);
|
||||
SDL_LogTrace(SDL_LOG_CATEGORY_INPUT,
|
||||
". In wl_data_device_listener . data_device_handle_enter on data_offer 0x%08x at %d x %d into window %d for serial %d",
|
||||
WAYLAND_wl_proxy_get_id((struct wl_proxy *)id),
|
||||
@@ -2863,6 +2874,7 @@ static void data_device_handle_enter(void *data, struct wl_data_device *wl_data_
|
||||
}
|
||||
} else {
|
||||
data_device->dnd_window = NULL;
|
||||
data_device->dnd_surface = NULL;
|
||||
|
||||
// Decline the offer.
|
||||
if (id) {
|
||||
@@ -2912,14 +2924,24 @@ static void data_device_handle_motion(void *data, struct wl_data_device *wl_data
|
||||
SDL_WaylandDataDevice *data_device = data;
|
||||
|
||||
if (data_device->drag_offer && data_device->dnd_window && (data_device->has_mime_file || data_device->has_mime_text)) {
|
||||
const float dx = (float)(wl_fixed_to_double(x) * data_device->dnd_window->internal->pointer_scale.x);
|
||||
const float dy = (float)(wl_fixed_to_double(y) * data_device->dnd_window->internal->pointer_scale.y);
|
||||
SDL_WindowData *window_data = data_device->dnd_window->internal;
|
||||
double dx = wl_fixed_to_double(x);
|
||||
double dy = wl_fixed_to_double(y);
|
||||
|
||||
// If over the mask, adjust the offset.
|
||||
if (data_device->dnd_surface == window_data->mask.surface) {
|
||||
dx += (double)window_data->mask.offset_x;
|
||||
dy += (double)window_data->mask.offset_y;
|
||||
}
|
||||
|
||||
dx *= window_data->pointer_scale.x;
|
||||
dy *= window_data->pointer_scale.y;
|
||||
|
||||
/* XXX: Send the filename here if the event system ever starts passing it though.
|
||||
* 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, dx, dy);
|
||||
SDL_SendDropPosition(data_device->dnd_window, (float)dx, (float)dy);
|
||||
SDL_LogTrace(SDL_LOG_CATEGORY_INPUT,
|
||||
". In wl_data_device_listener . data_device_handle_motion on data_offer 0x%08x at %d x %d in window %d serial %d",
|
||||
WAYLAND_wl_proxy_get_id((struct wl_proxy *)data_device->drag_offer->offer),
|
||||
|
||||
@@ -543,14 +543,16 @@ static void ConfigureWindowGeometry(SDL_Window *window)
|
||||
SetSurfaceOpaqueRegion(data->mask.surface, 0, 0);
|
||||
}
|
||||
|
||||
data->mask.offset_x = -(data->current.logical_width - viewport_width) / 2;
|
||||
data->mask.offset_y = -(data->current.logical_height - viewport_height) / 2;
|
||||
|
||||
// Can't use an offset subsurface with libdecor (yet), or the decorations won't line up properly.
|
||||
if (data->shell_surface_type != WAYLAND_SHELL_SURFACE_TYPE_LIBDECOR) {
|
||||
wl_subsurface_set_position(data->mask.subsurface, data->mask.offset_x, data->mask.offset_y);
|
||||
data->mask.offset_x = -(data->current.logical_width - viewport_width) / 2;
|
||||
data->mask.offset_y = -(data->current.logical_height - viewport_height) / 2;
|
||||
} else {
|
||||
data->mask.offset_x = 0;
|
||||
data->mask.offset_y = 0;
|
||||
}
|
||||
|
||||
wl_subsurface_set_position(data->mask.subsurface, data->mask.offset_x, data->mask.offset_y);
|
||||
wl_surface_commit(data->mask.surface);
|
||||
|
||||
if (old_buffer) {
|
||||
|
||||
Reference in New Issue
Block a user