diff options
Diffstat (limited to 'src/common/surface.c')
| -rw-r--r-- | src/common/surface.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/src/common/surface.c b/src/common/surface.c index 6b805be..683bbaa 100644 --- a/src/common/surface.c +++ b/src/common/surface.c @@ -669,6 +669,18 @@ int yasl_clipboard_request(yasl_surface *s, enum yasl_selection selection) return -errno; return STATUS(yasl_private_clipboard_request(s, (enum yasl_private_selection)selection) != 0); } +/* A drag that drops on no surface would end unheard, so its origin hears + * the end. ud is the origin's id: the origin may be gone by then. */ +static void drag_ended(void *ud, enum yasl_private_drag_end how) +{ + (void)how; + if (!display || display->drag_dropped) + return; + yasl_surface *origin = yasl_private_events_find(display, (uint64_t)(uintptr_t)ud); + if (origin) + yasl_private_surface_notify_drag(origin, YASL_PRIVATE_DRAG_CANCEL, + (struct yasl_private_vector2i){0, 0}); +} int yasl_drag_start(yasl_surface *s, const struct yasl_drag_image *source) { if (!yasl_public_connected(s)) @@ -679,7 +691,10 @@ int yasl_drag_start(yasl_surface *s, const struct yasl_drag_image *source) .pixels = source->pixels, .size = {source->pixel_width, source->pixel_height}, .hotspot = {source->hotspot_x, source->hotspot_y}}; - return STATUS(yasl_private_display_drag_start(display, s, source ? &image : NULL, NULL, NULL)); + display->drag_dropped = false; + const struct yasl_private_drag_listener listener = {.end = drag_ended}; + return STATUS(yasl_private_display_drag_start(display, s, source ? &image : NULL, &listener, + (void *)(uintptr_t)s->id)); } int yasl_drag_cancel(void) { @@ -886,9 +901,10 @@ static bool convert_event(const struct yasl_private_event *p, yasl_event *e) return true; case YASL_PRIVATE_EVENT_DRAG: e->type = YASL_EVENT_DRAG; - e->action = p->drag.action == YASL_PRIVATE_DRAG_OVER ? YASL_DROP_OVER - : p->drag.action == YASL_PRIVATE_DRAG_LEAVE ? YASL_DROP_LEAVE - : YASL_DROP_RELEASE; + e->action = p->drag.action == YASL_PRIVATE_DRAG_OVER ? YASL_DROP_OVER + : p->drag.action == YASL_PRIVATE_DRAG_LEAVE ? YASL_DROP_LEAVE + : p->drag.action == YASL_PRIVATE_DRAG_CANCEL ? YASL_DROP_CANCEL + : YASL_DROP_RELEASE; e->x = p->drag.pos.x / scale; e->y = p->drag.pos.y / scale; return true; |
