summaryrefslogtreecommitdiff
path: root/src/platform/wayland/drag.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/platform/wayland/drag.c')
-rw-r--r--src/platform/wayland/drag.c37
1 files changed, 29 insertions, 8 deletions
diff --git a/src/platform/wayland/drag.c b/src/platform/wayland/drag.c
index 07e31b5..4317d0d 100644
--- a/src/platform/wayland/drag.c
+++ b/src/platform/wayland/drag.c
@@ -136,15 +136,16 @@ static const struct wl_data_source_listener source_listener = {
.action = source_action,
};
+/* A seat whose press is still held over the origin window; its serial starts the drag. */
static struct seat *drag_seat(struct wayland_display *c, struct wayland_surface *origin)
{
struct wayland_surface *root = surface_root(origin);
struct seat *active = c->active_seat ? c->active_seat : c->seats;
- if (active && active->press_serial &&
+ if (active && seat_held_press_serial(active) &&
surface_root(active->press_surface) == root)
return active;
for (struct seat *s = c->seats; s; s = s->next)
- if (s->press_serial && surface_root(s->press_surface) == root)
+ if (seat_held_press_serial(s) && surface_root(s->press_surface) == root)
return s;
return NULL;
}
@@ -153,20 +154,33 @@ bool wayland_display_drag_start(struct wayland_display *c, struct wayland_surfac
const struct yasl_private_drag_image *image,
const struct yasl_private_drag_listener *l, void *ud)
{
- if (!c || !origin || origin->conn != c || !l || c->drag.source)
+ if (!c || !origin || origin->conn != c || !l) {
+ errno = EINVAL;
return false;
+ }
+ if (c->drag.source) {
+ errno = EBUSY;
+ return false;
+ }
struct seat *seat = drag_seat(c, origin);
- if (!seat)
+ if (!seat) {
+ errno = ESTALE;
return false;
+ }
struct wl_data_device *device = clipboard_data_device(seat->clipboard);
- if (!device || wl_data_device_get_version(device) < 3)
+ if (!device || wl_data_device_get_version(device) < 3) {
+ errno = ENOTSUP;
return false;
+ }
c->drag.scale_120 = origin->scale_120;
- if (image && !icon_create(c, image))
+ if (image && !icon_create(c, image)) {
+ errno = ENOMEM;
return false;
+ }
struct wl_data_source *s = wl_data_device_manager_create_data_source(c->data_manager);
if (!s) {
icon_clear(&c->drag.icon);
+ errno = ENOMEM;
return false;
}
c->drag.source = s;
@@ -180,7 +194,7 @@ bool wayland_display_drag_start(struct wayland_display *c, struct wayland_surfac
c->drag.toplevel = xdg_toplevel_drag_manager_v1_get_xdg_toplevel_drag(
c->toplevel_drag_mgr, s);
wl_data_device_start_drag(device, s, seat->press_surface->surface,
- c->drag.icon.surface, seat->press_serial);
+ c->drag.icon.surface, seat_held_press_serial(seat));
if (image)
icon_show(c, image);
wl_display_flush(c->wl);
@@ -196,8 +210,14 @@ void wayland_display_drag_cancel(struct wayland_display *c)
bool wayland_surface_drag_carry(struct wayland_surface *w, struct yasl_private_vector2i offset)
{
struct wayland_display *c = w ? w->conn : NULL;
- if (!c || !c->drag.source || !c->drag.toplevel || !w->toplevel)
+ if (!c || !c->drag.source || !w->toplevel) {
+ errno = EINVAL;
+ return false;
+ }
+ if (!c->drag.toplevel) {
+ errno = ENOTSUP;
return false;
+ }
uint32_t scale = c->drag.scale_120;
xdg_toplevel_drag_v1_attach(c->drag.toplevel, w->toplevel,
yasl_private_scale_to_logical(offset.x, scale),
@@ -210,6 +230,7 @@ bool wayland_surface_place_under_pointer(struct wayland_surface *w, struct yasl_
{
(void)w;
(void)at;
+ errno = ENOTSUP;
return false;
}