diff --git a/include/wlr/types/wlr_data_device.h b/include/wlr/types/wlr_data_device.h index c36b1a5cb..4ae883eb7 100644 --- a/include/wlr/types/wlr_data_device.h +++ b/include/wlr/types/wlr_data_device.h @@ -210,6 +210,20 @@ void wlr_seat_start_pointer_drag(struct wlr_seat *seat, struct wlr_drag *drag, void wlr_seat_start_touch_drag(struct wlr_seat *seat, struct wlr_drag *drag, uint32_t serial, struct wlr_touch_point *point); +void wlr_drag_start(struct wlr_drag *drag); + +void wlr_drag_enter(struct wlr_drag *drag, struct wlr_surface *surface, + double sx, double sy); + +void wlr_drag_clear_focus(struct wlr_drag *drag); + +void wlr_drag_send_motion(struct wlr_drag *drag, uint32_t time_msec, + double sx, double sy); + +void wlr_drag_drop_and_destroy(struct wlr_drag *drag, uint32_t time_msec); + +void wlr_drag_destroy(struct wlr_drag *drag); + /** * Initializes the data source with the provided implementation. */ diff --git a/types/data_device/wlr_drag.c b/types/data_device/wlr_drag.c index b780eedac..1c9beaabc 100644 --- a/types/data_device/wlr_drag.c +++ b/types/data_device/wlr_drag.c @@ -10,6 +10,8 @@ #include #include "types/wlr_data_device.h" +// TODO: drop seat grabs + static void drag_handle_seat_client_destroy(struct wl_listener *listener, void *data) { struct wlr_drag *drag = @@ -539,3 +541,54 @@ void wlr_seat_start_touch_drag(struct wlr_seat *seat, struct wlr_drag *drag, wlr_seat_start_drag(seat, drag, serial); } + +void wlr_drag_start(struct wlr_drag *drag) { + wlr_seat_start_drag(drag->seat, drag, 0); +} + +void wlr_drag_enter(struct wlr_drag *drag, struct wlr_surface *surface, + double sx, double sy) { + drag_set_focus(drag, surface, sx, sy); +} + +void wlr_drag_clear_focus(struct wlr_drag *drag) { + drag_set_focus(drag, NULL, 0, 0); +} + +void wlr_drag_send_motion(struct wlr_drag *drag, uint32_t time_msec, + double sx, double sy) { + if (drag->focus != NULL && drag->focus_client != NULL) { + struct wl_resource *resource; + wl_resource_for_each(resource, &drag->focus_client->data_devices) { + wl_data_device_send_motion(resource, time_msec, wl_fixed_from_double(sx), + wl_fixed_from_double(sy)); + } + + struct wlr_drag_motion_event event = { + .drag = drag, + .time = time_msec, + .sx = sx, + .sy = sy, + }; + wl_signal_emit_mutable(&drag->events.motion, &event); + } +} + +void wlr_drag_drop_and_destroy(struct wlr_drag *drag, uint32_t time_msec) { + if (drag->source != NULL) { + if (drag->focus_client != NULL && drag->source->current_dnd_action && + drag->source->accepted) { + drag_drop(drag, time_msec); + } else if (drag->source->impl->dnd_finish) { + // This will end the grab and free `drag` + wlr_data_source_destroy(drag->source); + return; + } + } + + drag_destroy(drag); +} + +void wlr_drag_destroy(struct wlr_drag *drag) { + drag_destroy(drag); +}