arch: widen final void* vtable signatures to WMEvent*; event.c is _x11_raw-free

Three more vtable slots that took void* (intended for an XEvent*) widened
to take WMEvent*; the X11 impls extract _x11_raw internally:

  event_handle_extensions(WMEvent*)
  netwm_process_client_message(WMEvent*)
  xdnd_process_client_message(WMEvent*)

Also added a new client_message_forward(WMEvent*, WNativeWindow) slot for
the OffiX DND ClientMessage redirect (icon frame -> real client_win).
The X11 backend rewrites xclient.window and XSendEvent's it; the Wayland
backend does the same on wl_state.x_display for XWayland clients.

After this change, src/event.c contains zero _x11_raw references — the
last X11 escape from the shared event dispatch layer is closed.
This commit is contained in:
Window Maker 2026-05-24 08:49:44 +02:00
parent ee1e5b0f70
commit d79f7b5243
4 changed files with 50 additions and 23 deletions

View File

@ -1206,7 +1206,7 @@ typedef struct WMBackend {
* RRScreenChangeNotify (calls XRRUpdateConfiguration then restarts).
* No-op for event types not matching any known extension.
*/
void (*event_handle_extensions)(void *event);
void (*event_handle_extensions)(WMEvent *event);
/*
* Notify the backend of a ConfigureNotify on the root window.
@ -1795,6 +1795,15 @@ typedef struct WMBackend {
int (*event_check_type)(int event_type, WMEvent *event_out);
void (*client_send_event)(WNativeWindow win, void *event_data);
/*
* Forward a ClientMessage event that was delivered to one window
* to a different target window. Used by handleClientMessage to
* redirect OffiX DND ClientMessages from icon frames to the actual
* client_win. Only meaningful for X11 (and XWayland clients via
* the Wayland backend).
*/
void (*client_message_forward)(WMEvent *event, WNativeWindow target_win);
/*
* Deliver a synthetic key press/release to a client window. Used by
* usermenu.c to translate menu entries into keystrokes for the
@ -1819,8 +1828,8 @@ typedef struct WMBackend {
int (*window_get_command)(WNativeWindow win, char ***argv_out, int *argc_out);
/* NETWM/XDND mechanism (Phase 80s) */
int (*netwm_process_client_message)(void *xevent);
int (*xdnd_process_client_message)(void *xevent);
int (*netwm_process_client_message)(WMEvent *event);
int (*xdnd_process_client_message)(WMEvent *event);
void (*xdnd_process_selection)(WMEvent *event);
void (*xdnd_make_awareness)(WNativeWindow win);
void (*netwm_check_client_hint_change)(WWindow *wwin, void *event);

View File

@ -6252,7 +6252,7 @@ static void wl_event_sync(int discard)
static int wl_event_pending(void) { return 0; }
static void wl_event_drain_motion(void) {}
static void wl_event_discard_enter_leave_until(unsigned long timestamp) { (void)timestamp; }
static void wl_event_handle_extensions(void *event) { (void)event; }
static void wl_event_handle_extensions(WMEvent *event) { (void)event; }
static void wl_event_randr_update(WMEvent *event) { (void)event; }
/* ------------------------------------------------------------------ */
@ -8863,6 +8863,16 @@ static void wl_noop_event_flush_type(int t) { (void)t; }
static int wl_noop_event_check_window(WNativeWindow win, int t) { (void)win; (void)t; return 0; }
static int wl_noop_event_check_type(int t, WMEvent *e) { (void)t; (void)e; return 0; }
static void wl_noop_client_send_event(WNativeWindow win, void *d) { (void)win; (void)d; }
static void wl_client_message_forward(WMEvent *event, WNativeWindow target_win)
{
/* Forward OffiX DND ClientMessage to the real client_win for
* XWayland clients. Native Wayland clients have no analog. */
if (!wl_state.x_display || !event) return;
XEvent *xev = (XEvent *)event->_x11_raw;
if (!xev) return;
xev->xclient.window = (Window)target_win;
XSendEvent(wl_state.x_display, (Window)target_win, False, 0L, xev);
}
static void wl_client_send_key(WNativeWindow win, unsigned int keycode,
unsigned int modifier_mask, int press)
{
@ -8895,8 +8905,8 @@ static void wl_pointer_get_position(int *x, int *y) {
}
static const char *wl_noop_keysym_to_string(unsigned long ks) { (void)ks; return ""; }
static int wl_noop_window_get_command(WNativeWindow win, char ***a, int *c) { (void)win; (void)a; *c=0; return 0; }
static int wl_noop_netwm_process_client_message(void *x) { (void)x; return 0; }
static int wl_noop_xdnd_process_client_message(void *x) { (void)x; return 0; }
static int wl_noop_netwm_process_client_message(WMEvent *e) { (void)e; return 0; }
static int wl_noop_xdnd_process_client_message(WMEvent *e) { (void)e; return 0; }
static void wl_noop_xdnd_process_selection(WMEvent *e) { (void)e; }
static void wl_noop_xdnd_make_awareness(WNativeWindow w) { (void)w; }
static void wl_noop_handle_selection_request(WMEvent *e) { (void)e; }
@ -9165,6 +9175,7 @@ const WMBackend wl_backend = {
.event_check_window = wl_noop_event_check_window,
.event_check_type = wl_noop_event_check_type,
.client_send_event = wl_noop_client_send_event,
.client_message_forward = wl_client_message_forward,
.client_send_key = wl_client_send_key,
.window_exists = wl_noop_window_exists,
.window_get_colormap = wl_noop_window_get_colormap,

View File

@ -2319,9 +2319,9 @@ x11_handle_xkb_indicator_state(XEvent *event)
#endif /* KEEP_XKB_LOCK_STATUS */
static void
x11_event_handle_extensions(void *raw_event)
x11_event_handle_extensions(WMEvent *wev)
{
XEvent *event = (XEvent *)raw_event;
XEvent *event = wev ? (XEvent *)wev->_x11_raw : NULL;
if (!event) return;
#ifdef USE_XSHAPE
if (w_global.xext.shape.supported &&
@ -3550,6 +3550,14 @@ static void x11_client_send_event(WNativeWindow win, void *event_data)
XSendEvent(dpy, (Window)win, False, 0L, (XEvent *)event_data);
}
static void x11_client_message_forward(WMEvent *event, WNativeWindow target_win)
{
XEvent *xev = event ? (XEvent *)event->_x11_raw : NULL;
if (!xev) return;
xev->xclient.window = (Window)target_win;
XSendEvent(dpy, (Window)target_win, False, 0L, xev);
}
static void x11_client_send_key(WNativeWindow win, unsigned int keycode,
unsigned int modifier_mask, int press)
{
@ -3682,13 +3690,17 @@ static int x11_window_get_command(WNativeWindow win, char ***argv_out, int *argc
return 0;
}
static int x11_netwm_process_client_message(void *xevent)
static int x11_netwm_process_client_message(WMEvent *event)
{
return wNETWMProcessClientMessage(&((XEvent *)xevent)->xclient);
XEvent *xev = event ? (XEvent *)event->_x11_raw : NULL;
if (!xev) return 0;
return wNETWMProcessClientMessage(&xev->xclient);
}
static int x11_xdnd_process_client_message(void *xevent)
static int x11_xdnd_process_client_message(WMEvent *event)
{
return wXDNDProcessClientMessage(&((XEvent *)xevent)->xclient);
XEvent *xev = event ? (XEvent *)event->_x11_raw : NULL;
if (!xev) return 0;
return wXDNDProcessClientMessage(&xev->xclient);
}
static void x11_xdnd_process_selection(WMEvent *event)
{
@ -4672,6 +4684,7 @@ const WMBackend x11_backend = {
.event_check_window = x11_event_check_window,
.event_check_type = x11_event_check_type,
.client_send_event = x11_client_send_event,
.client_message_forward = x11_client_message_forward,
.client_send_key = x11_client_send_key,
.window_exists = x11_window_exists,
.window_get_colormap = x11_window_get_colormap,

View File

@ -430,8 +430,7 @@ static int matchWindow(const void *item, const void *cdata)
static void handleExtensions(WMEvent * event)
{
if (event->_x11_raw)
wm_backend->event_handle_extensions((void *)event->_x11_raw);
wm_backend->event_handle_extensions(event);
}
static void handleMapRequest(WMEvent * ev)
@ -948,10 +947,10 @@ static void handleClientMessage(WMEvent * event)
if (!scr)
return;
scr->flags.ignore_focus_events = event->u.clientMessage.data.l[0] ? 1 : 0;
} else if (event->_x11_raw && wm_backend->netwm_process_client_message(event->_x11_raw)) {
} else if (wm_backend->netwm_process_client_message(event)) {
/* do nothing */
#ifdef USE_DOCK_XDND
} else if (event->_x11_raw && wm_backend->xdnd_process_client_message(event->_x11_raw)) {
} else if (wm_backend->xdnd_process_client_message(event)) {
/* do nothing */
#endif /* USE_DOCK_XDND */
} else {
@ -969,13 +968,8 @@ static void handleClientMessage(WMEvent * event)
icon = ((WAppIcon *) desc->parent)->icon;
}
if (icon && (wwin = icon->owner)) {
if (wwin->client_win != event->u.clientMessage.window) {
XEvent *xev = (XEvent *)event->_x11_raw;
if (xev) {
xev->xclient.window = wwin->client_win;
wm_backend->client_send_event((WNativeWindow)wwin->client_win, xev);
}
}
if (wwin->client_win != event->u.clientMessage.window)
wm_backend->client_message_forward(event, wwin->client_win);
}
}
}