From e417682ed46373f93b4cdd3affe43f38a0a3e356 Mon Sep 17 00:00:00 2001 From: Ollie Date: Sat, 30 May 2026 13:28:35 +0200 Subject: [PATCH] fix: event coordinates must be relative to WINGs target view, not toplevel W_FindViewAtPoint finds the correct child view (slider, checkbox, etc.) but does not adjust event coordinates. The WMEvent x/y were set relative to the top-level WINGs view (fb->x, fb->y origin), while widget event handlers (getSliderPart, valueForMousePoint, etc.) expect coordinates relative to the widget view itself. Fixed by computing the accumulated offset from the target view up to the toplevel and subtracting it from the event coordinates. Applied to both handle_pointer_button and handle_pointer_motion. --- src/backend/wayland/wl_backend.c | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/backend/wayland/wl_backend.c b/src/backend/wayland/wl_backend.c index 00d9307..062c5f6 100644 --- a/src/backend/wayland/wl_backend.c +++ b/src/backend/wayland/wl_backend.c @@ -5233,9 +5233,22 @@ handle_pointer_motion(struct wl_listener *listener, void *data) extern W_View *W_GetViewForWindow(unsigned long id); extern struct W_View *W_FindViewAtPoint(struct W_View *parent, int x, int y); W_View *toplevel = W_GetViewForWindow((unsigned long)fb->id); - if (toplevel) + if (toplevel) { mtarget = W_FindViewAtPoint(toplevel, wev.u.motion.x, wev.u.motion.y); + /* Adjust event coordinates to target view's local space */ + if (mtarget && mtarget != toplevel) { + W_View *p = mtarget; + int ox = 0, oy = 0; + while (p && p != toplevel) { + ox += p->pos.x; + oy += p->pos.y; + p = p->parent; + } + wev.u.motion.x -= ox; + wev.u.motion.y -= oy; + } + } } W_WL_EnqueueEvent(wmscr, &wev, mtarget); /* Emit synthetic LEAVE/ENTER when pointer crosses WM sub-window @@ -6311,6 +6324,18 @@ handle_pointer_button(struct wl_listener *listener, void *data) wev.u.button.x, wev.u.button.y); if (!target) target = toplevel; + /* Adjust event coordinates to target view's local space */ + if (target != toplevel) { + W_View *p = target; + int ox = 0, oy = 0; + while (p && p != toplevel) { + ox += p->pos.x; + oy += p->pos.y; + p = p->parent; + } + wev.u.button.x -= ox; + wev.u.button.y -= oy; + } } } W_WL_EnqueueEvent(wmscr, &wev, target);