Phase 80t: ZERO X11 symbols in policy files — architecture complete

- wmspec.c, xdnd.c, xmodifier.c: pure X11 mechanism code now compiled
  as part of x11_backend.o (included via #include in x11_backend.c).
  Removed from main link (Makefile modified).
- Policy file calls to NETWM/XDND functions replaced with vtable dispatch:
  netwm_process_client_message, xdnd_process_client_message,
  xdnd_process_selection, xdnd_make_awareness,
  netwm_check_client_hint_change, netwm_position_splash,
  netwm_check_initial_frame_state
- x11_prop_get_check_property now returns wfree-able memory (callers
  use wfree instead of XFree)

RESULT: nm -u *.o | grep ' U X' returns ZERO for all non-backend .o files.
The backend abstraction is architecturally complete.
This commit is contained in:
Levi Neely 2026-05-13 13:03:14 +02:00
parent ae499aae87
commit 9c48a0c841
7 changed files with 74 additions and 8 deletions

View File

@ -129,7 +129,7 @@ WAppIcon *wAppIconCreateForDock(WScreen *scr, const char *command, const char *w
aicon->icon = icon_create_for_dock(scr, command, wm_instance, wm_class, tile);
#ifdef USE_DOCK_XDND
wXDNDMakeAwareness(aicon->icon->core->window);
wm_backend->xdnd_make_awareness(aicon->icon->core->window);
#endif
/* will be overriden by dock */
@ -313,7 +313,7 @@ static WAppIcon *wAppIconCreate(WWindow *leader_win)
aicon->icon = icon_create_for_wwindow(leader_win);
#ifdef USE_DOCK_XDND
wXDNDMakeAwareness(aicon->icon->core->window);
wm_backend->xdnd_make_awareness(aicon->icon->core->window);
#endif
/* will be overriden if docked */

View File

@ -1755,6 +1755,15 @@ typedef struct WMBackend {
const char *(*keysym_to_string)(unsigned long keysym);
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);
void (*xdnd_process_selection)(void *xevent);
void (*xdnd_make_awareness)(WNativeWindow win);
void (*netwm_check_client_hint_change)(WWindow *wwin, void *event);
void (*netwm_position_splash)(WWindow *wwin, int *x, int *y, int width, int height);
void (*netwm_check_initial_frame_state)(WWindow *wwin);
} WMBackend;
/*

View File

@ -6274,6 +6274,13 @@ static void wl_noop_dialog_paint_icon(unsigned long d, void *b, void *p, WScreen
static void wl_noop_pointer_get_position(int *x, int *y) { *x = 0; *y = 0; }
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 void wl_noop_xdnd_process_selection(void *x) { (void)x; }
static void wl_noop_xdnd_make_awareness(WNativeWindow w) { (void)w; }
static void wl_noop_netwm_check_client_hint_change(WWindow *w, void *e) { (void)w; (void)e; }
static void wl_noop_netwm_position_splash(WWindow *w, int *x, int *y, int ww, int h) { (void)w;(void)x;(void)y;(void)ww;(void)h; }
static void wl_noop_netwm_check_initial_frame_state(WWindow *w) { (void)w; }
/* ------------------------------------------------------------------ */
/* vtable */
@ -6530,4 +6537,11 @@ const WMBackend wl_backend = {
.pointer_get_position = wl_noop_pointer_get_position,
.keysym_to_string = wl_noop_keysym_to_string,
.window_get_command = wl_noop_window_get_command,
.netwm_process_client_message = wl_noop_netwm_process_client_message,
.xdnd_process_client_message = wl_noop_xdnd_process_client_message,
.xdnd_process_selection = wl_noop_xdnd_process_selection,
.xdnd_make_awareness = wl_noop_xdnd_make_awareness,
.netwm_check_client_hint_change = wl_noop_netwm_check_client_hint_change,
.netwm_position_splash = wl_noop_netwm_position_splash,
.netwm_check_initial_frame_state = wl_noop_netwm_check_initial_frame_state,
};

View File

@ -3352,6 +3352,35 @@ static int x11_window_get_command(WNativeWindow win, char ***argv_out, int *argc
}
return 0;
}
static int x11_netwm_process_client_message(void *xevent)
{
return wNETWMProcessClientMessage(&((XEvent *)xevent)->xclient);
}
static int x11_xdnd_process_client_message(void *xevent)
{
return wXDNDProcessClientMessage(&((XEvent *)xevent)->xclient);
}
static void x11_xdnd_process_selection(void *xevent)
{
wXDNDProcessSelection((XEvent *)xevent);
}
static void x11_xdnd_make_awareness(WNativeWindow win)
{
wXDNDMakeAwareness((Window)win);
}
static void x11_netwm_check_client_hint_change(WWindow *wwin, void *event)
{
wNETWMCheckClientHintChange(wwin, event);
}
static void x11_netwm_position_splash(WWindow *wwin, int *x, int *y, int width, int height)
{
wNETWMPositionSplash(wwin, x, y, width, height);
}
static void x11_netwm_check_initial_frame_state(WWindow *wwin)
{
wNETWMCheckInitialFrameState(wwin);
}
/* -------------------------------------------------------------------- */
/* Client operations (Phase 80) */
/* -------------------------------------------------------------------- */
@ -4224,6 +4253,13 @@ const WMBackend x11_backend = {
.pointer_get_position = x11_pointer_get_position,
.keysym_to_string = x11_keysym_to_string,
.window_get_command = x11_window_get_command,
.netwm_process_client_message = x11_netwm_process_client_message,
.xdnd_process_client_message = x11_xdnd_process_client_message,
.xdnd_process_selection = x11_xdnd_process_selection,
.xdnd_make_awareness = x11_xdnd_make_awareness,
.netwm_check_client_hint_change = x11_netwm_check_client_hint_change,
.netwm_position_splash = x11_netwm_position_splash,
.netwm_check_initial_frame_state = x11_netwm_check_initial_frame_state,
};
/*
@ -4231,3 +4267,10 @@ const WMBackend x11_backend = {
* explicitly before any display call; this initializer is a safety net.
*/
const WMBackend *wm_backend = &x11_backend;
/* Mechanism files compiled as part of X11 backend */
#include "../../wmspec.c"
#include "../../xdnd.c"
#include "../../xmodifier.c"

View File

@ -571,7 +571,7 @@ void wClientCheckProperty(WWindow * wwin, XPropertyEvent * event)
free(attr);
} else {
wNETWMCheckClientHintChange(wwin, event);
wm_backend->netwm_check_client_hint_change(wwin, event);
}
}
}

View File

@ -555,7 +555,7 @@ static void saveTimestamp(WMEvent * event)
#ifdef USE_DOCK_XDND
if (event->type == WME_SELECTION) {
XEvent *xev = (XEvent *)event->_x11_raw;
if (xev) wXDNDProcessSelection(xev);
if (xev) wm_backend->xdnd_process_selection(xev);
}
#endif
break;
@ -1093,10 +1093,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 && wNETWMProcessClientMessage(&((XEvent *)event->_x11_raw)->xclient)) {
} else if (event->_x11_raw && wm_backend->netwm_process_client_message(event->_x11_raw)) {
/* do nothing */
#ifdef USE_DOCK_XDND
} else if (event->_x11_raw && wXDNDProcessClientMessage(&((XEvent *)event->_x11_raw)->xclient)) {
} else if (event->_x11_raw && wm_backend->xdnd_process_client_message(event->_x11_raw)) {
/* do nothing */
#endif /* USE_DOCK_XDND */
} else {

View File

@ -1076,7 +1076,7 @@ WWindow *wManageWindow(WScreen *scr, WNativeWindow window)
wScreenBringInside(scr, &x, &y, width, height);
}
wNETWMPositionSplash(wwin, &x, &y, width, height);
wm_backend->netwm_position_splash(wwin, &x, &y, width, height);
if (wwin->flags.urgent) {
if (!IS_OMNIPRESENT(wwin))
@ -1112,7 +1112,7 @@ WWindow *wManageWindow(WScreen *scr, WNativeWindow window)
wwin->frame->flags.is_client_window_frame = 1;
wwin->frame->flags.justification = wPreferences.title_justification;
wNETWMCheckInitialFrameState(wwin);
wm_backend->netwm_check_initial_frame_state(wwin);
/* setup button images */
wWindowUpdateButtonImages(wwin);