wl_backend: forward pointer events to client surface in client area

frame_buf_at() matches the entire window frame tree including the
client content area. This caused wl_update_pointer_focus to never
set seat pointer focus on the client surface, so Wayland clients
(like WPrefs) never received pointer enter/motion/button events.

Fix: when frame_buf_at returns a hit, also check view_surface_at.
If a client surface is found at the pointer position, use it instead
of treating the area as WM-internal decorations.
This commit is contained in:
Window Maker 2026-05-24 16:04:25 +02:00
parent 7e21ae259a
commit 1d1f5bdc71
1 changed files with 17 additions and 2 deletions

View File

@ -5846,11 +5846,26 @@ wl_update_pointer_focus(uint32_t time_msec)
struct wlr_surface *surface = NULL;
/* If pointer is over an internal frame_buf (menu, titlebar, etc.),
* don't send pointer events to any client surface. */
* don't send pointer events to any client surface — UNLESS the
* pointer is actually over the client content area within the frame. */
struct wl_frame_buf *fb = frame_buf_at(wl_state.pointer_x, wl_state.pointer_y);
if (!fb)
if (fb) {
/* Check if this frame_buf has a client surface (toplevel view)
* and the pointer is over the client area, not the decorations. */
double sx, sy;
struct wl_toplevel_view *v = NULL;
struct wlr_surface *cs = view_surface_at(
wl_state.pointer_x, wl_state.pointer_y, &sx, &sy, &v);
if (cs) {
surface = cs;
view = v;
fb = NULL; /* not over decorations */
}
}
if (!fb && !surface) {
surface = view_surface_at(
wl_state.pointer_x, wl_state.pointer_y, &sx, &sy, &view);
}
static struct wlr_surface *last_focused_surface = NULL;
if (surface) {