From ef45983b5b1f56ae92403e35f25eee1b0b2c956b Mon Sep 17 00:00:00 2001 From: Window Maker Date: Thu, 4 Jun 2026 09:58:16 +0200 Subject: [PATCH] fix WINGs dialog input: match XDG toplevel clicks to WINGs frame buffers by bounds --- src/backend/wayland/wl_framebuf.c | 4 +++- src/backend/wayland/wl_handlers.c | 24 +++++++++++++++++++----- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/backend/wayland/wl_framebuf.c b/src/backend/wayland/wl_framebuf.c index acc70bb..421c83f 100644 --- a/src/backend/wayland/wl_framebuf.c +++ b/src/backend/wayland/wl_framebuf.c @@ -206,7 +206,9 @@ frame_buf_at(int px, int py) return fb; } - /* Step 6: topmost node was a client surface — not a WM frame. */ + + + /* Step 7: topmost node was a client surface — not a WM frame. */ return NULL; } diff --git a/src/backend/wayland/wl_handlers.c b/src/backend/wayland/wl_handlers.c index 99a426a..37ca363 100644 --- a/src/backend/wayland/wl_handlers.c +++ b/src/backend/wayland/wl_handlers.c @@ -219,16 +219,30 @@ handle_pointer_button(struct wl_listener *listener, void *data) wev.u.button.y = wl_state.pointer_y - fb->y; } else { /* No frame buffer — check if the click landed on an XDG toplevel - * (WINGs dialog, popup, etc.) and use its view ID as the window. */ + * and look up its WINGs view ID from the frame list. */ double _sx, _sy; struct wl_toplevel_view *_tv = NULL; view_surface_at(wl_state.pointer_x, wl_state.pointer_y, &_sx, &_sy, &_tv); if (_tv) { - wev.window = _tv->id; - wev.u.button.window = _tv->id; - wev.u.button.x = (int)_sx; - wev.u.button.y = (int)_sy; + /* Try to find a WINGs view frame buffer at this position. + * The compositor's view ID (_tv->id) is synthetic and not + * known to WINGs, so we match by bounds against frame_buf + * entries with WINGs view IDs (>= 0x20000000). */ + struct wl_frame_buf *_wtb = NULL; + wl_list_for_each(_wtb, &wl_state.frame_list, link) { + if (_wtb->id >= 0x20000000 && + wl_state.pointer_x >= _wtb->x && + wl_state.pointer_x < _wtb->x + _wtb->width && + wl_state.pointer_y >= _wtb->y && + wl_state.pointer_y < _wtb->y + _wtb->height) { + break; + } + } + wev.window = _wtb ? _wtb->id : _tv->id; + wev.u.button.window = wev.window; + wev.u.button.x = _wtb ? (wl_state.pointer_x - _wtb->x) : (int)_sx; + wev.u.button.y = _wtb ? (wl_state.pointer_y - _wtb->y) : (int)_sy; } else { WScreen *scr0 = wScreenWithNumber(0); WNativeWindow root = scr0 ? scr0->root_win : (WNativeWindow)0x0FFFFFFF;