From c89f30827ce5947fe7697bcffd9b11061fb5b16d Mon Sep 17 00:00:00 2001 From: werapi Date: Sun, 5 Apr 2026 14:04:27 +0200 Subject: [PATCH] fix: correct touch motion surface-local coordinate calculation --- src/mango.c | 38 +++++++++++++++----------------------- 1 file changed, 15 insertions(+), 23 deletions(-) diff --git a/src/mango.c b/src/mango.c index 1e0ead3f..dae07d78 100644 --- a/src/mango.c +++ b/src/mango.c @@ -455,6 +455,7 @@ typedef struct { typedef struct { struct wl_list link; int32_t touch_id; + double start_x, start_y, start_surface_x, start_surface_y; } TouchPoint; typedef struct TouchGroup { @@ -5910,6 +5911,8 @@ void touchdown(struct wl_listener *listener, void *data) { Monitor *m; t->touch_id = event->touch_id; + t->start_x = lx; + t->start_y = ly; wl_list_insert(&tg->touch_points, &t->link); wlr_idle_notifier_v1_notify_activity(idle_notifier, seat); @@ -5938,6 +5941,8 @@ void touchdown(struct wl_listener *listener, void *data) { /* Find the client under the pointer and send the event along. */ xytonode(lx, ly, &surface, &c, NULL, &sx, &sy); + t->start_surface_x = sx; + t->start_surface_y = sy; if (surface != NULL && wlr_surface_accepts_touch(surface, seat)) { if (c) focusclient(c, 0); @@ -6023,10 +6028,8 @@ void touchmotion(struct wl_listener *listener, void *data) { double lx, ly; double sx, sy; double dx, dy; - int32_t node_x, node_y; struct wlr_surface *surface; Client *c = NULL; - struct wlr_scene_tree *tree; struct wlr_touch_point *p = NULL; wl_list_for_each(t_iter, &tg->touch_points, link) { @@ -6038,10 +6041,11 @@ void touchmotion(struct wl_listener *listener, void *data) { if (!t) // invalid or cancelled return; + wlr_cursor_absolute_to_layout_coords(cursor, &event->touch->base, event->x, + event->y, &lx, &ly); + if (emulating_pointer_from_touch) { if (emulated_pointer_touch_id == event->touch_id) { - wlr_cursor_absolute_to_layout_coords(cursor, &event->touch->base, - event->x, event->y, &lx, &ly); dx = lx - cursor->x; dy = ly - cursor->y; motionnotify(event->time_msec, &event->touch->base, dx, dy, dx, dy); @@ -6055,31 +6059,19 @@ void touchmotion(struct wl_listener *listener, void *data) { return; } - wlr_cursor_absolute_to_layout_coords(cursor, &event->touch->base, event->x, - event->y, &lx, &ly); + sx = t->start_surface_x + (lx - t->start_x); + sy = t->start_surface_y + (ly - t->start_y); + surface = p->surface; if (surface && surface->data) { - tree = surface->data; - wlr_scene_node_coords(&tree->node, &node_x, &node_y); - sx = lx - node_x; - sy = ly - node_y; - toplevel_from_wlr_surface(surface, &c, NULL); if (c) focusclient(c, 0); - - wlr_seat_touch_point_focus(seat, surface, event->time_msec, - event->touch_id, sx, sy); - wlr_seat_touch_notify_motion(seat, event->time_msec, event->touch_id, - sx, sy); - - wlr_idle_notifier_v1_notify_activity(idle_notifier, seat); - } else { - focusclient(NULL, 0); - wlr_seat_touch_point_clear_focus(seat, event->time_msec, - event->touch_id); - wlr_idle_notifier_v1_notify_activity(idle_notifier, seat); } + wlr_seat_touch_notify_motion(seat, event->time_msec, event->touch_id, sx, + sy); + + wlr_idle_notifier_v1_notify_activity(idle_notifier, seat); } void touchcancel(struct wl_listener *listener, void *data) {