arch: eliminate last _x11_raw escape from src/ (winspector)

The Window Inspector's 'select window' feature grabbed the pointer on
the root window then read XEvent.xbutton.subwindow to learn which
window was clicked.  This was the last access to _x11_raw in shared
src/ code.

Add a subwindow field to WMEButton.  The X11 backend's WMEvent
translation populates it from xbutton.subwindow.  The Wayland backend
leaves it 0 (Wayland has no equivalent grab semantic — the click
reports the actual frame as event.window directly).  winspector.c
now uses event.u.button.subwindow with fallback to
event.u.button.window, working on both backends.

Net: src/ has zero _x11_raw escapes from shared code.  Remaining
references are inside the X11 backend (legitimately consuming the
field set by its own event translator).
This commit is contained in:
Window Maker 2026-05-24 08:40:38 +02:00
parent 1c1f261fb2
commit a789abc09f
3 changed files with 9 additions and 2 deletions

View File

@ -82,6 +82,7 @@ typedef struct {
typedef struct {
WNativeWindow window;
WNativeWindow subwindow; /* deepest child under pointer at click time */
unsigned int button; /* 1=left, 2=middle, 3=right, 4+=extra */
unsigned int state; /* modifier mask */
int x, y;

View File

@ -40,6 +40,7 @@ xev_to_wme(const XEvent *xev, WMEvent *out)
case ButtonRelease:
out->type = (xev->type == ButtonPress) ? WME_BUTTON_PRESS : WME_BUTTON_RELEASE;
out->u.button.window = (WNativeWindow)xev->xbutton.window;
out->u.button.subwindow = (WNativeWindow)xev->xbutton.subwindow;
out->u.button.button = xev->xbutton.button;
out->u.button.state = xev->xbutton.state;
out->u.button.x = xev->xbutton.x;

View File

@ -1035,8 +1035,13 @@ static void selectWindow(WMWidget *bPtr, void *data)
wm_backend->pointer_ungrab(0);
{
XEvent *_xev = (XEvent *)event._x11_raw;
iwin = _xev ? wWindowFor(_xev->xbutton.subwindow) : NULL;
/* On X11 with the pointer grabbed on root_win, the click reports
* window=root and subwindow=clicked window. On Wayland there
* is no such grab semantic; the event reports window=clicked
* window directly with subwindow==0. Prefer subwindow when set. */
WNativeWindow target = event.u.button.subwindow ?
event.u.button.subwindow : event.u.button.window;
iwin = wWindowFor(target);
}
if (iwin && !iwin->flags.internal_window && iwin != wwin && !iwin->flags.inspector_open) {
iwin->flags.inspector_open = 1;