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). * RRScreenChangeNotify (calls XRRUpdateConfiguration then restarts).
* No-op for event types not matching any known extension. * 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. * 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); int (*event_check_type)(int event_type, WMEvent *event_out);
void (*client_send_event)(WNativeWindow win, void *event_data); 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 * Deliver a synthetic key press/release to a client window. Used by
* usermenu.c to translate menu entries into keystrokes for the * 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); int (*window_get_command)(WNativeWindow win, char ***argv_out, int *argc_out);
/* NETWM/XDND mechanism (Phase 80s) */ /* NETWM/XDND mechanism (Phase 80s) */
int (*netwm_process_client_message)(void *xevent); int (*netwm_process_client_message)(WMEvent *event);
int (*xdnd_process_client_message)(void *xevent); int (*xdnd_process_client_message)(WMEvent *event);
void (*xdnd_process_selection)(WMEvent *event); void (*xdnd_process_selection)(WMEvent *event);
void (*xdnd_make_awareness)(WNativeWindow win); void (*xdnd_make_awareness)(WNativeWindow win);
void (*netwm_check_client_hint_change)(WWindow *wwin, void *event); 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 int wl_event_pending(void) { return 0; }
static void wl_event_drain_motion(void) {} static void wl_event_drain_motion(void) {}
static void wl_event_discard_enter_leave_until(unsigned long timestamp) { (void)timestamp; } 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; } 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_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 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_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, static void wl_client_send_key(WNativeWindow win, unsigned int keycode,
unsigned int modifier_mask, int press) 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 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_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_netwm_process_client_message(WMEvent *e) { (void)e; return 0; }
static int wl_noop_xdnd_process_client_message(void *x) { (void)x; 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_process_selection(WMEvent *e) { (void)e; }
static void wl_noop_xdnd_make_awareness(WNativeWindow w) { (void)w; } static void wl_noop_xdnd_make_awareness(WNativeWindow w) { (void)w; }
static void wl_noop_handle_selection_request(WMEvent *e) { (void)e; } 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_window = wl_noop_event_check_window,
.event_check_type = wl_noop_event_check_type, .event_check_type = wl_noop_event_check_type,
.client_send_event = wl_noop_client_send_event, .client_send_event = wl_noop_client_send_event,
.client_message_forward = wl_client_message_forward,
.client_send_key = wl_client_send_key, .client_send_key = wl_client_send_key,
.window_exists = wl_noop_window_exists, .window_exists = wl_noop_window_exists,
.window_get_colormap = wl_noop_window_get_colormap, .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 */ #endif /* KEEP_XKB_LOCK_STATUS */
static void 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; if (!event) return;
#ifdef USE_XSHAPE #ifdef USE_XSHAPE
if (w_global.xext.shape.supported && 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); 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, static void x11_client_send_key(WNativeWindow win, unsigned int keycode,
unsigned int modifier_mask, int press) 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; 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) 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_window = x11_event_check_window,
.event_check_type = x11_event_check_type, .event_check_type = x11_event_check_type,
.client_send_event = x11_client_send_event, .client_send_event = x11_client_send_event,
.client_message_forward = x11_client_message_forward,
.client_send_key = x11_client_send_key, .client_send_key = x11_client_send_key,
.window_exists = x11_window_exists, .window_exists = x11_window_exists,
.window_get_colormap = x11_window_get_colormap, .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) static void handleExtensions(WMEvent * event)
{ {
if (event->_x11_raw) wm_backend->event_handle_extensions(event);
wm_backend->event_handle_extensions((void *)event->_x11_raw);
} }
static void handleMapRequest(WMEvent * ev) static void handleMapRequest(WMEvent * ev)
@ -948,10 +947,10 @@ static void handleClientMessage(WMEvent * event)
if (!scr) if (!scr)
return; return;
scr->flags.ignore_focus_events = event->u.clientMessage.data.l[0] ? 1 : 0; 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 */ /* do nothing */
#ifdef USE_DOCK_XDND #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 */ /* do nothing */
#endif /* USE_DOCK_XDND */ #endif /* USE_DOCK_XDND */
} else { } else {
@ -969,13 +968,8 @@ static void handleClientMessage(WMEvent * event)
icon = ((WAppIcon *) desc->parent)->icon; icon = ((WAppIcon *) desc->parent)->icon;
} }
if (icon && (wwin = icon->owner)) { if (icon && (wwin = icon->owner)) {
if (wwin->client_win != event->u.clientMessage.window) { if (wwin->client_win != event->u.clientMessage.window)
XEvent *xev = (XEvent *)event->_x11_raw; wm_backend->client_message_forward(event, wwin->client_win);
if (xev) {
xev->xclient.window = wwin->client_win;
wm_backend->client_send_event((WNativeWindow)wwin->client_win, xev);
}
}
} }
} }
} }