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.
This commit is contained in:
Levi Neely 2026-05-13 12:39:24 +02:00
parent 69799ccdab
commit 937a0c2a3a
4 changed files with 122 additions and 18 deletions

View File

@ -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;
/*

View File

@ -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,
};

View File

@ -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,
};
/*

View File

@ -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 *) &notify);
wm_backend->client_send_event((WNativeWindow)event->requestor, (void *)&notify);
#else
/*