From 937a0c2a3a699cbefde9ee9b66c2980508092f8b Mon Sep 17 00:00:00 2001 From: Levi Neely <141506390+lneely@users.noreply.github.com> Date: Wed, 13 May 2026 12:39:24 +0200 Subject: [PATCH] Phase 80q: clean X11 from event.c - XAllowEvents -> event_allow_async / event_replay_pointer - XRefreshKeyboardMapping -> keyboard_mapping_refresh - XCheckTypedWindowEvent -> event_check_window / event_flush_window - XCheckTypedEvent -> event_check_type / event_flush_type - XGetGeometry (existence check) -> window_exists - XGetWindowAttributes (colormap) -> window_get_colormap - XQueryPointer -> pointer_query_window - XSendEvent -> client_send_event - XWarpPointer -> pointer_warp_to (existing) - XInstallColormap -> colormap_install (existing) New vtable slots: event_allow_async, event_replay_pointer, keyboard_mapping_refresh, event_flush_window, event_flush_type, event_check_window, event_check_type, client_send_event, window_exists, window_get_colormap, pointer_query_window. event.o verified X11-free with nm. --- src/backend/backend.h | 14 +++++++ src/backend/wayland/wl_backend.c | 23 +++++++++++ src/backend/x11/x11_backend.c | 67 ++++++++++++++++++++++++++++++++ src/event.c | 36 ++++++++--------- 4 files changed, 122 insertions(+), 18 deletions(-) diff --git a/src/backend/backend.h b/src/backend/backend.h index 2a40c53..cf89b1a 100644 --- a/src/backend/backend.h +++ b/src/backend/backend.h @@ -38,6 +38,7 @@ typedef struct WWindow WWindow; typedef struct GNUstepWMAttributes GNUstepWMAttributes; struct WObjDescriptor; struct WFrameWindow; +typedef struct WMEvent WMEvent; typedef struct _WCoreWindow WCoreWindow; typedef union WTexture WTexture; typedef struct WPixmap WPixmap; @@ -1735,6 +1736,19 @@ typedef struct WMBackend { void (*window_fill_stipple)(WNativeWindow win, int x, int y, int w, int h); int (*event_check_enter_leave)(void *dock); + /* Event mechanism (Phase 80p) */ + void (*event_allow_async)(void); + void (*event_replay_pointer)(void); + void (*keyboard_mapping_refresh)(WMEvent *event); + void (*event_flush_window)(WNativeWindow win, int event_type); + void (*event_flush_type)(int event_type); + int (*event_check_window)(WNativeWindow win, int event_type); + int (*event_check_type)(int event_type, WMEvent *event_out); + void (*client_send_event)(WNativeWindow win, void *event_data); + int (*window_exists)(WNativeWindow win); + void (*window_get_colormap)(WNativeWindow win, unsigned long *colormap_out); + WNativeWindow (*pointer_query_window)(WNativeWindow root); + } WMBackend; /* diff --git a/src/backend/wayland/wl_backend.c b/src/backend/wayland/wl_backend.c index db4e834..41adf2c 100644 --- a/src/backend/wayland/wl_backend.c +++ b/src/backend/wayland/wl_backend.c @@ -6258,6 +6258,18 @@ static void wl_noop_window_fill_stipple(WNativeWindow win, int x, int y, int w, { (void)win; (void)x; (void)y; (void)w; (void)h; } static int wl_noop_event_check_enter_leave(void *dock) { (void)dock; return 1; } +static void wl_noop_event_allow_async(void) { } +static void wl_noop_event_replay_pointer(void) { } +static void wl_noop_keyboard_mapping_refresh(WMEvent *event) { (void)event; } +static void wl_noop_event_flush_window(WNativeWindow win, int t) { (void)win; (void)t; } +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 int wl_noop_window_exists(WNativeWindow win) { (void)win; return 1; } +static void wl_noop_window_get_colormap(WNativeWindow win, unsigned long *c) { (void)win; (void)c; } +static WNativeWindow wl_noop_pointer_query_window(WNativeWindow root) { (void)root; return WNATIVE_NONE; } + /* ------------------------------------------------------------------ */ /* vtable */ /* ------------------------------------------------------------------ */ @@ -6498,4 +6510,15 @@ const WMBackend wl_backend = { .balloon_show = wl_noop_balloon_show, .window_fill_stipple = wl_noop_window_fill_stipple, .event_check_enter_leave = wl_noop_event_check_enter_leave, + .event_allow_async = wl_noop_event_allow_async, + .event_replay_pointer = wl_noop_event_replay_pointer, + .keyboard_mapping_refresh = wl_noop_keyboard_mapping_refresh, + .event_flush_window = wl_noop_event_flush_window, + .event_flush_type = wl_noop_event_flush_type, + .event_check_window = wl_noop_event_check_window, + .event_check_type = wl_noop_event_check_type, + .client_send_event = wl_noop_client_send_event, + .window_exists = wl_noop_window_exists, + .window_get_colormap = wl_noop_window_get_colormap, + .pointer_query_window = wl_noop_pointer_query_window, }; diff --git a/src/backend/x11/x11_backend.c b/src/backend/x11/x11_backend.c index 50ff575..9e3bd24 100644 --- a/src/backend/x11/x11_backend.c +++ b/src/backend/x11/x11_backend.c @@ -3192,6 +3192,62 @@ static int x11_event_check_enter_leave(void *dock) } return 0; } + +static void x11_event_allow_async(void) { XAllowEvents(dpy, AsyncPointer, CurrentTime); } +static void x11_event_replay_pointer(void) { XAllowEvents(dpy, ReplayPointer, CurrentTime); } +static void x11_keyboard_mapping_refresh(WMEvent *event) +{ + XEvent *xev = event ? (XEvent *)event->_x11_raw : NULL; + if (xev) XRefreshKeyboardMapping(&xev->xmapping); +} +static void x11_event_flush_window(WNativeWindow win, int event_type) +{ + XEvent ev; + (void)event_type; + while (XCheckTypedWindowEvent(dpy, (Window)win, Expose, &ev)) ; +} +static void x11_event_flush_type(int event_type) +{ + XEvent ev; + while (XCheckTypedEvent(dpy, event_type == WME_FOCUS_IN ? FocusIn : event_type, &ev)) ; +} +static int x11_event_check_window(WNativeWindow win, int event_type) +{ + XEvent ev; + int xtype = Expose; + if (event_type == WME_DESTROY) xtype = DestroyNotify; + else if (event_type == WME_REPARENT) xtype = ReparentNotify; + else if (event_type == WME_LEAVE) xtype = LeaveNotify; + return XCheckTypedWindowEvent(dpy, (Window)win, xtype, &ev); +} +static int x11_event_check_type(int event_type, WMEvent *event_out) +{ + (void)event_type; + return XCheckTypedEvent(dpy, ColormapNotify, (XEvent *)event_out->_x11_raw); +} +static void x11_client_send_event(WNativeWindow win, void *event_data) +{ + XSendEvent(dpy, (Window)win, False, 0L, (XEvent *)event_data); +} +static int x11_window_exists(WNativeWindow win) +{ + Window jr; int ji; unsigned int ju; + return XGetGeometry(dpy, (Window)win, &jr, &ji, &ji, &ju, &ju, &ju, &ju); +} +static void x11_window_get_colormap(WNativeWindow win, unsigned long *colormap_out) +{ + XWindowAttributes attr; + if (XGetWindowAttributes(dpy, (Window)win, &attr)) + *colormap_out = attr.colormap; +} +static WNativeWindow x11_pointer_query_window(WNativeWindow root) +{ + Window bar, win; + int foo; unsigned int mask; + if (XQueryPointer(dpy, (Window)root, &bar, &win, &foo, &foo, &foo, &foo, &mask)) + return (WNativeWindow)win; + return WNATIVE_NONE; +} /* -------------------------------------------------------------------- */ /* Client operations (Phase 80) */ /* -------------------------------------------------------------------- */ @@ -4011,6 +4067,17 @@ const WMBackend x11_backend = { .balloon_show = x11_balloon_show, .window_fill_stipple = x11_window_fill_stipple, .event_check_enter_leave = x11_event_check_enter_leave, + .event_allow_async = x11_event_allow_async, + .event_replay_pointer = x11_event_replay_pointer, + .keyboard_mapping_refresh = x11_keyboard_mapping_refresh, + .event_flush_window = x11_event_flush_window, + .event_flush_type = x11_event_flush_type, + .event_check_window = x11_event_check_window, + .event_check_type = x11_event_check_type, + .client_send_event = x11_client_send_event, + .window_exists = x11_window_exists, + .window_get_colormap = x11_window_get_colormap, + .pointer_query_window = x11_pointer_query_window, }; /* diff --git a/src/event.c b/src/event.c index 0b4e347..2dafd9c 100644 --- a/src/event.c +++ b/src/event.c @@ -246,7 +246,7 @@ void DispatchEvent(WMEvent * event) case WME_MAPPING: if (event->u.mapping.request == MappingKeyboard || event->u.mapping.request == MappingModifier) { XEvent *xev = (XEvent *)event->_x11_raw; - if (xev) XRefreshKeyboardMapping(&xev->xmapping); + if (xev) wm_backend->keyboard_mapping_refresh(event); } break; @@ -697,7 +697,7 @@ static void handleExpose(WMEvent * event) WObjDescriptor *desc; XEvent ev; - while (XCheckTypedWindowEvent(dpy, event->u.expose.window, Expose, &ev)) ; + wm_backend->event_flush_window((WNativeWindow)event->u.expose.window, WME_EXPOSE); desc = wm_backend->context_find(event->u.expose.window, WM_CTX_CLIENT_WIN); if (!desc) { @@ -840,13 +840,13 @@ static void handleButtonPress(WMEvent * event) wm_backend->event_sync(0); if (event->u.button.state & ( MOD_MASK | ControlMask )) { - XAllowEvents(dpy, AsyncPointer, CurrentTime); + wm_backend->event_allow_async(); } else { /* if (wPreferences.focus_mode == WKF_CLICK) { */ if (wPreferences.ignore_focus_click) { - XAllowEvents(dpy, AsyncPointer, CurrentTime); + wm_backend->event_allow_async(); } - XAllowEvents(dpy, ReplayPointer, CurrentTime); + wm_backend->event_replay_pointer(); /* } */ } wm_backend->event_sync(0); @@ -854,7 +854,7 @@ static void handleButtonPress(WMEvent * event) || desc->parent_type == WCLASS_MINIWINDOW || desc->parent_type == WCLASS_DOCK_ICON) { if (event->u.button.state & MOD_MASK) { wm_backend->event_sync(0); - XAllowEvents(dpy, AsyncPointer, CurrentTime); + wm_backend->event_allow_async(); wm_backend->event_sync(0); } } @@ -922,14 +922,14 @@ static void handleUnmapNotify(WMEvent * event) wwin->flags.mapped = 0; wm_backend->event_sync(0); /* check if the window was destroyed */ - if (XCheckTypedWindowEvent(dpy, wwin->client_win, DestroyNotify, &ev)) { + if (wm_backend->event_check_window((WNativeWindow)wwin->client_win, WME_DESTROY)) { WMEvent wev; x11_translate_event(&ev, &wev); DispatchEvent(&wev); } else { Bool reparented = False; - if (XCheckTypedWindowEvent(dpy, wwin->client_win, ReparentNotify, &ev)) + if (wm_backend->event_check_window((WNativeWindow)wwin->client_win, WME_REPARENT)) reparented = True; /* withdraw window */ @@ -971,7 +971,7 @@ static void handlePropertyNotify(WMEvent * event) wwin = wWindowFor(event->u.property.window); if (wwin) { - if (!XGetGeometry(dpy, wwin->client_win, &jr, &ji, &ji, &ju, &ju, &ju, &ju)) { + if (!wm_backend->window_exists((WNativeWindow)wwin->client_win)) { return; } XEvent *xev = (XEvent *)event->_x11_raw; @@ -1118,7 +1118,7 @@ static void handleClientMessage(WMEvent * event) XEvent *xev = (XEvent *)event->_x11_raw; if (xev) { xev->xclient.window = wwin->client_win; - XSendEvent(dpy, wwin->client_win, False, NoEventMask, xev); + wm_backend->client_send_event((WNativeWindow)wwin->client_win, xev); } } } @@ -1150,7 +1150,7 @@ static void handleEnterNotify(WMEvent * event) XEvent ev; WScreen *scr = wScreenForRootWindow(event->u.crossing.window); - if (XCheckTypedWindowEvent(dpy, event->u.crossing.window, LeaveNotify, &ev)) { + if (wm_backend->event_check_window((WNativeWindow)event->u.crossing.window, WME_LEAVE)) { /* already left the window... */ WMEvent wev; x11_translate_event(&ev, &wev); @@ -1251,7 +1251,7 @@ static void handleColormapNotify(WMEvent * event) if (event->u.colormap.c_new) { XWindowAttributes attr; - XGetWindowAttributes(dpy, wwin->client_win, &attr); + wm_backend->window_get_colormap((WNativeWindow)wwin->client_win, &attr.colormap); if (wwin == scr->cmap_window && wwin->cmap_window_no == 0) scr->current_colormap = attr.colormap; @@ -1269,12 +1269,12 @@ static void handleColormapNotify(WMEvent * event) reinstall = False; } } - } while (XCheckTypedEvent(dpy, ColormapNotify, (XEvent *)event->_x11_raw) + } while (wm_backend->event_check_type(WME_COLORMAP, event) && ((wwin = wWindowFor(event->u.colormap.window)) || 1)); if (reinstall && scr->current_colormap != None) { if (!scr->flags.colormap_stuff_blocked) - XInstallColormap(dpy, scr->current_colormap); + wm_backend->colormap_install(scr, NULL); } } @@ -1285,7 +1285,7 @@ static void handleFocusIn(WMEvent * event) /* * For applications that like stealing the focus. */ - while (XCheckTypedEvent(dpy, FocusIn, (XEvent *)event->_x11_raw)) ; + wm_backend->event_flush_type(WME_FOCUS_IN); saveTimestamp(event); if (event->u.focus.mode == NotifyUngrab || event->u.focus.mode == NotifyGrab || event->u.focus.detail > NotifyNonlinearVirtual) { @@ -1311,7 +1311,7 @@ static WWindow *windowUnderPointer(WScreen * scr) int foo; Window bar, win; - if (XQueryPointer(dpy, scr->root_win, &bar, &win, &foo, &foo, &foo, &foo, &mask)) + win = (Window)wm_backend->pointer_query_window((WNativeWindow)scr->root_win); if (win) return wWindowFor(win); return NULL; } @@ -1913,7 +1913,7 @@ static void handleKeyPress(WMEvent * event) scr2 = wScreenWithNumber(i); if (scr2) { - XWarpPointer(dpy, scr->root_win, scr2->root_win, 0, 0, 0, 0, + wm_backend->pointer_warp_to( scr2->scr_width / 2, scr2->scr_height / 2); } } @@ -2165,7 +2165,7 @@ static void handle_selection_request(XSelectionRequestEvent *event) XGetAtomName(dpy, event->selection), XGetAtomName(dpy, event->target), (long) event->requestor); /* Send the answer to the requestor */ - XSendEvent(dpy, event->requestor, False, 0L, (XEvent *) ¬ify); + wm_backend->client_send_event((WNativeWindow)event->requestor, (void *)¬ify); #else /*