fix mouse input on WINGs dialog buttons: route pointer events to XDG toplevel views when no frame buffer is hit

This commit is contained in:
Window Maker 2026-06-04 09:51:47 +02:00
parent 0e582d0580
commit 1e09e5e35f
1 changed files with 36 additions and 18 deletions

View File

@ -176,18 +176,23 @@ handle_pointer_button(struct wl_listener *listener, void *data)
wl_list_insert(&wl_state.toplevel_list, &view->link);
}
} else {
/* No toplevel surface — check if a WINGs dialog frame_buf was clicked */
struct wl_frame_buf *hit = frame_buf_hit(wl_state.pointer_x,
wl_state.pointer_y);
if (hit) {
/* Walk up to the parent frame to find the WWindow */
WNativeWindow lookup = hit->parent_id ? hit->parent_id : hit->id;
WObjDescriptor *desc =
wm_backend->context_find(lookup, WM_CTX_CLIENT_WIN);
if (desc && desc->parent_type == WCLASS_WINDOW) {
WWindow *wwin = (WWindow *)desc->parent;
WScreen *scr = wScreenWithNumber(0);
wSetFocusTo(scr, wwin);
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) {
/* No toplevel surface — check if a WINGs dialog frame_buf was clicked */
struct wl_frame_buf *hit = frame_buf_hit(wl_state.pointer_x,
wl_state.pointer_y);
if (hit) {
WNativeWindow lookup = hit->parent_id ? hit->parent_id : hit->id;
WObjDescriptor *desc =
wm_backend->context_find(lookup, WM_CTX_CLIENT_WIN);
if (desc && desc->parent_type == WCLASS_WINDOW) {
WWindow *wwin = (WWindow *)desc->parent;
WScreen *scr = wScreenWithNumber(0);
wSetFocusTo(scr, wwin);
}
}
}
}
@ -213,12 +218,25 @@ handle_pointer_button(struct wl_listener *listener, void *data)
wev.u.button.x = wl_state.pointer_x - fb->x;
wev.u.button.y = wl_state.pointer_y - fb->y;
} else {
WScreen *scr0 = wScreenWithNumber(0);
WNativeWindow root = scr0 ? scr0->root_win : (WNativeWindow)0x0FFFFFFF;
wev.window = root;
wev.u.button.window = root;
wev.u.button.x = wl_state.pointer_x;
wev.u.button.y = wl_state.pointer_y;
/* No frame buffer — check if the click landed on an XDG toplevel
* (WINGs dialog, popup, etc.) and use its view ID as the window. */
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;
} else {
WScreen *scr0 = wScreenWithNumber(0);
WNativeWindow root = scr0 ? scr0->root_win : (WNativeWindow)0x0FFFFFFF;
wev.window = root;
wev.u.button.window = root;
wev.u.button.x = wl_state.pointer_x;
wev.u.button.y = wl_state.pointer_y;
}
}
wev.u.button.time = ev->time_msec;
wev.u.button.x_root = wl_state.pointer_x;