Backend-Specific Branches Remaining in src/ Policy Code
Status (2026-05-26): This document was written during the initial abstraction
analysis. Since then, wmspec.c and xdnd.c have been moved to
src/backend/x11/ and all _x11_raw references have been eliminated from
policy code (src/*.c now has zero _x11_raw accesses and zero direct Xlib
calls). The information below remains useful as a historical reference for the
abstraction work that was performed.
The backend vtable (wm_backend->*()) handles most display-system dispatch, but significant X11-specific code still lives directly in the policy files. Here's every category.
1. Compile-Time #ifdef Branches
USE_WAYLAND_BACKEND (2 sites)
| File |
Line |
Purpose |
main.c |
60 |
#include wayland backend header |
main.c |
771 |
Select wl_backend vs x11_backend vtable |
This is clean — it's the backend selection switch.
XKB_BUTTON_HINT (38 sites — the biggest offender)
Sprayed across the frame window and window management code. Adds a "language indicator" button to the titlebar.
| File |
Sites |
What it guards |
framewin.c |
22 |
Language button creation, layout, drawing, click handling, destroy |
framewin.h |
10 |
Language button fields in WFrameWindow struct, function prototypes |
window.c |
10 |
Language button setup during window manage/unmanage, attribute updates |
wdefaults.c |
3 |
Language button in per-window attribute defaults |
WindowMaker.h |
1 |
WBUT_XKBGROUP* button constants, PRED_BPIXMAPS count |
window.h |
1 |
language_button field in WWindow |
def_pixmaps.h |
1 |
Language button pixmap data |
dialog.c |
2 |
Feature reporting in info dialog |
winspector.c |
1 |
Window inspector language option |
KEEP_XKB_LOCK_STATUS (6 sites)
| File |
Line(s) |
What it guards |
framewin.c |
23, 86 |
XKB include, language state tracking in frame |
framewin.h |
93 |
languagemode / last_languagemode fields |
event.c |
1853 |
XKB state-change event handling |
window.c |
1727 |
XKB lock status update on focus |
WindowMaker.h |
359, 622 |
XKB state in preferences, XKB event base in globals |
keybind.h |
161 |
WKBD_TOGGLE keybinding |
USE_DOCK_XDND (7 sites)
| File |
Line(s) |
What it guards |
appicon.c |
52, 131, 315, 338 |
XDND include, DND-aware setup, DND event handling on app icons |
dock.c |
76 |
XDND include |
event.c |
(via backend) |
XDND client message dispatch |
dialog.c |
1433 |
Feature reporting |
Plus xdnd.c itself (312 lines) is entirely X11-specific — raw XInternAtom, XGetWindowProperty, XSendEvent, XGetSelectionOwner throughout.
| File |
Line(s) |
What it guards |
window.c |
654, 2012, 2236, 2301 |
Shape extension queries on client windows |
window.h |
263, 345 |
net_has_shape flag, shape update prototype |
WindowMaker.h |
615 |
Shape event base in globals |
balloon.h |
26 |
SHAPED_BALLOON for shaped tooltip windows |
USE_XINERAMA (10 sites)
| File |
Line(s) |
What it guards |
workspace.c |
252, 280, 295, 303, 328 |
Per-monitor workspace geometry calculations |
wmspec.c |
78, 165, 294, 1043, 1087, 1820 |
EWMH multi-monitor strut/workarea handling |
actions.c |
975 |
Maximize to monitor bounds |
dialog.c |
1445, 1447 |
Feature reporting, Solaris Xinerama variant |
USE_RANDR (1 site + header)
| File |
Line(s) |
What it guards |
dialog.c |
1458 |
Feature reporting |
WindowMaker.h |
629 |
RandR event base in globals |
USE_MWM_HINTS (2 sites)
| File |
Line(s) |
What it guards |
window.c |
63, 360 |
Motif WM hints include and processing |
dialog.c |
1429 |
Feature reporting |
HAVE_INOTIFY (6 sites)
| File |
Line(s) |
What it guards |
main.c |
23, 487, 787 |
Inotify includes, setup, watch creation |
event.c |
25 |
Inotify includes |
shutdown.c |
61, 91 |
Inotify fd cleanup |
WindowMaker.h |
553 |
Inotify fd in globals |
Minor HAVE_* guards
| Guard |
File |
Purpose |
HAVE_SETSID |
main.c:326,378, dock.c:3000 |
setsid() availability |
HAVE_MALLOC_H |
dialog.c:39 |
Include path |
HAVE_XINTERNATOMS |
wmspec.c:662 |
Batch atom intern optimization |
HAVE_STDNORETURN |
event.h:28, main.h:27 |
C11 _Noreturn |
2. Runtime _x11_raw Escape Hatch (16 sites — NOW ZERO in policy code)
The WMEvent struct carries a void *_x11_raw field — a pointer to the original XEvent. Policy code reaches through it when the abstracted event fields aren't sufficient:
| File |
Line(s) |
What it does |
event.c |
249, 264, 269, 276 |
handleConfigureRequest — passes raw XEvent to backend for RandR, Shape, XKB extension events |
event.c |
431 |
handleMapRequest — raw XEvent for wManageWindow |
event.c |
446–447 |
handleExtensions — passes raw event to backend |
event.c |
782 |
handleButtonPress — raw XEvent for wDockReceiveDNDDrop |
event.c |
831, 834, 852, 857 |
handleClientMessage — raw XEvent for EWMH, XDND, selection |
event.c |
971, 974 |
handleClientMessage — raw XEvent to netwm_process_client_message, xdnd_process_client_message |
event.c |
993 |
handleClientMessage — raw XEvent for colormap install |
event.c |
1354 |
handleKeyPress — raw XEvent for root menu shortcuts |
framewin.c |
1165 |
Frame titlebar click — raw XEvent |
icon.c |
861 |
Miniwindow double-click — raw XEvent |
cycling.c |
227–234 |
Window cycling — synthesizes XEvent for switch panel, with Wayland fallback |
menu.c |
738 |
Menu key handling — raw XEvent |
winspector.c |
1038 |
Window inspector — raw XEvent |
3. X11 Types in Function Signatures
Functions in policy code that take raw X11 types as parameters — these are API boundaries that can't work on Wayland without the _x11_raw escape hatch or a cast:
| File |
Function |
X11 parameter type |
client.c:119 |
wClientConfigure() |
XConfigureRequestEvent * |
client.c:247 |
wClientCheckProperty() |
XPropertyEvent * |
rootmenu.c:320 |
wRootMenuPerformShortcut() |
XEvent * |
switchpanel.c:684 |
wSwitchPanelHandleEvent() |
XEvent * |
dock.c:1978 |
findDock() |
XEvent * |
dock.c:2009 |
wDockReceiveDNDDrop() |
XEvent * |
icon.c:57 |
miniwindowDblClick() |
XEvent * |
menu.c:677 |
check_key() |
XKeyEvent * |
window.c:90 |
windowLanguageClick() |
XEvent * |
wmspec.c:1701 |
wNETWMProcessClientMessage() |
XClientMessageEvent * |
event.c:94–95 |
handle_selection_request/clear() |
XSelectionRequestEvent/ClearEvent * |
4. Direct Xlib Calls in Policy Code (by file)
Files that call Xlib functions directly instead of going through wm_backend:
| File |
Call count |
What's leaking |
wmspec.c |
65 |
XGetWindowProperty, XChangeProperty, XDeleteProperty, XInternAtom(s), XFlush — the entire EWMH implementation is raw Xlib |
xdnd.c |
33 |
XInternAtom, XGetWindowProperty, XSendEvent, XGetSelectionOwner, XFree — 100% X11 |
event.c |
26 |
XInternAtom, XChangeProperty, selection handling, DefaultRootWindow |
defaults.c |
20 |
XColor parsing via XParseColor/XAllocColor for color preferences |
xmodifier.c |
11 |
XGetModifierMapping, XFreeModifiermap — keyboard modifier detection |
misc.c |
8 |
XKeysymToKeycode, XLookupString, DefaultRootWindow |
moveres.c |
6 |
XSetForeground, XDrawLine — XOR rubber-band lines on root window |
menu.c |
5 |
Debug logging with window IDs |
icon.c |
5 |
XWindowAttributes, XGetWindowAttributes |
cycling.c |
5 |
XEvent synthesis for switch panel |
usermenu.c |
4 |
XSendEvent, XStringToKeysym — synthetic key events to client |
dock.c |
3 |
XEvent in DND drop handling |
client.c |
3 |
XWindowChanges, XConfigureRequestEvent |
appicon.c |
1 |
XClearArea for dock icon label |
5. X11 Types Embedded in Data Structures
These X11 types are used as field types in core structs, meaning the data model itself is X11-flavored:
| Type |
Usage count in src/*.h |
Where |
Pixmap |
~46 |
screen.h, texture.h, pixmap.h, framewin.h — everywhere pixmaps are stored |
GC |
~10 |
screen.h (7 GC fields), texture.h (6 GC fields), balloon.h |
XColor |
~39 (in .c) |
defaults.c, texture.c, resources.c |
Visual * |
~5 |
framewin.h, screen.h |
Colormap |
~5 |
framewin.h, screen.h, resources.h |
Atom |
~96 (in .c) |
wmspec.c (95), xdnd.c (19), scattered elsewhere |
Cursor |
in screen.h |
Cursor array in WScreen |
Summary: Heat Map
Fully Partially Entirely
Abstracted Abstracted X11-Raw
────────── ────────── ────────
wcore.c ██████████
stacking.c ██████████
placement.c ██████████
workspace.c ████████░░ (XINERAMA)
actions.c ████████░░ (XINERAMA)
window.c ██████░░░░ (XKB, SHAPE, MWM)
framewin.c █████░░░░░ (XKB 22 sites, _x11_raw)
event.c ████░░░░░░ (_x11_raw 16 sites, Xlib)
defaults.c ████░░░░░░ (XColor)
cycling.c ███░░░░░░░ (XEvent synthesis)
moveres.c ███░░░░░░░ (XDrawLine)
dock.c ███░░░░░░░ (XEvent, XDND)
icon.c ███░░░░░░░ (XWindowAttributes, _x11_raw)
menu.c ███░░░░░░░ (XKeyEvent, _x11_raw)
client.c ██░░░░░░░░ (X11 event types in API)
wmspec.c ░░░░░░░░░░ ██████████ (65 Xlib calls)
xdnd.c ░░░░░░░░░░ ██████████ (33 Xlib calls)
xmodifier.c ░░░░░░░░░░ ██████████ (11 Xlib calls)
usermenu.c ░░░░░░░░░░ ████████░░ (XSendEvent)
UPDATE (2026-05-26): All three problems have been resolved:
wmspec.c — moved to src/backend/x11/wmspec.c. On Wayland, EWMH vtable slots are no-ops.
xdnd.c — moved to src/backend/x11/xdnd.c. Wayland DnD handled by wlroots.
event.c's _x11_raw escape hatch — all 16 sites eliminated from policy code. The remaining _x11_raw accesses (15) are exclusively in src/backend/ where they belong.
wrlib/ — Backend-Specific Branch Inventory
File Classification
Entirely X11-Free (pure image manipulation)
These files have zero Xlib calls and no X11 type usage. Some #include <X11/Xlib.h> transitively through wraster.h but don't use it:
| File |
LOC |
Purpose |
alpha_combine.c |
71 |
Alpha compositing |
draw.c |
504 |
Line/pixel drawing on RImage |
gradient.c |
501 |
Gradient rendering |
load_gif.c |
232 |
GIF loader |
load_jpeg.c |
196 |
JPEG loader |
load_magick.c |
130 |
ImageMagick loader |
load_png.c |
220 |
PNG loader |
load_tiff.c |
153 |
TIFF loader |
load_webp.c |
172 |
WebP loader |
load_xpm_normalized.c |
459 |
Pure-C XPM parser (no libXpm) |
save_jpeg.c |
104 |
JPEG saver |
save_png.c |
127 |
PNG saver |
save_xpm.c |
283 |
XPM saver |
| Total |
3152 |
36% of wrlib — fully portable |
These files #include <X11/Xlib.h> (pulled in transitively via wraster.h) but make zero Xlib function calls. The include is unnecessary:
| File |
LOC |
Actual purpose |
color.c |
130 |
RColor ↔ pixel conversion (uses RContext fields only) |
convolve.c |
145 |
Image convolution/blur |
flip.c |
163 |
Image flip |
load.c |
395 |
Format dispatch (calls RLoadPNG, etc.) |
load_ppm.c |
394 |
PPM loader |
misc.c |
279 |
Error strings, format support queries |
raster.c |
640 |
RCreateImage, RCloneImage, RGetSubImage, etc. |
rotate.c |
434 |
Image rotation |
save.c |
61 |
Save format dispatch |
scale.c |
499 |
Image scaling |
| Total |
3140 |
36% of wrlib — portable code with unnecessary X11 header dep |
Genuinely X11-Dependent
| File |
LOC |
Xlib calls |
What it does |
context.c |
772 |
44 |
RCreateContext() — the big one. Visual selection, colormap allocation, GC creation, XShm probing. Also contains RCreateContextWayland() (the Wayland alternative). |
xutil.c |
263 |
32 |
RCreateXImage, RDestroyXImage, RGetXImage, RPutXImage — XImage/XShm lifecycle |
convert.c |
985 |
14 |
image2TrueColor, image2PseudoColor, image2GrayScale, image2Bitmap — RImage→XImage pixel conversion |
convert_x11.c |
96 |
6 |
x11_convert_image, x11_convert_image_mask — XImage→Pixmap via XCreatePixmap/XCopyArea |
xpixmap.c |
183 |
13 |
RCreateImageFromXImage, RCreateImageFromDrawable — Pixmap/Drawable→RImage extraction |
load_xpm.c |
180 |
2 |
RLoadXPM, RGetImageFromXPMData — uses libXpm + XParseColor for color resolution |
| Total |
2479 |
111 |
28% of wrlib — hard X11 dependency |
Wayland Backend
| File |
LOC |
What it does |
convert_wl.c |
58 |
wl_convert_image, wl_convert_image_mask — RImage→pixman_image_t (cast to Pixmap) |
1. Compile-Time #ifdef Branches
USE_XSHM (10 sites — 2 files)
The XShm (shared memory) extension for fast image transfer to the X server:
| File |
Line(s) |
What it guards |
context.c |
639 |
XShm version check, shared pixmap capability probe |
xutil.c |
34, 44, 71, 158, 195, 238, 251 |
XShm include, XShmCreateImage, XShmAttach, XShmDetach, XShmGetImage, XShmPutImage, shared pixmap creation. The entire RCreateXImage/RDestroyXImage have dual paths (shm vs non-shm). |
convert_x11.c |
16, 43 |
Shared pixmap fast path in x11_convert_image |
xutil.h |
24 |
R_CreateXImageMappedPixmap prototype |
HAVE_LIBXMU (2 sites)
| File |
Line(s) |
What it guards |
context.c |
29, 145 |
XmuLookupStandardColormap — optional shortcut for standard colormap lookup |
USE_* Image Format Guards (16 sites)
All in load.c, save.c, and imgformat.h — these are feature toggles, not backend-specific:
| Guard |
Sites |
Files |
USE_TIFF |
3 |
load.c, imgformat.h |
USE_PNG |
3 |
load.c, save.c, imgformat.h |
USE_JPEG |
3 |
load.c, save.c, imgformat.h |
USE_GIF |
5 |
load.c, load_gif.c, imgformat.h |
USE_WEBP |
2 |
load.c, imgformat.h |
USE_MAGICK |
3 |
load.c, load_magick.c, misc.c, imgformat.h |
Minor Guards
| Guard |
File |
Purpose |
WRLIB_DEBUG |
context.c (4), convert.c (6) |
Debug logging |
HAVE_FLOAT_MATHFUNC |
context.c:46 |
floorf() availability |
HAVE_STDNORETURN |
load_jpeg.c:34 |
C11 _Noreturn |
I18N |
misc.c:248 |
Internationalization |
2. Runtime Backend Dispatch
There is exactly one runtime dispatch point — the convert_image function pointer in RContext:
// wraster.h.in:210-211
int (*convert_image)(struct RContext *ctx, RImage *image, Pixmap *pixmap);
int (*convert_image_mask)(struct RContext *ctx, RImage *image, Pixmap *pixmap, Pixmap *mask, int threshold);
Set at context creation time:
- X11 path (
context.c:660-661): context->convert_image = x11_convert_image
- Wayland path (
context.c:768-769): context->convert_image = wl_convert_image
Called from convert.c:869,882:
return context->convert_image(context, image, pixmap);
This is the only abstraction seam in wrlib. Everything else is either pure image manipulation or hardcoded X11.
3. X11 Types in the Public API (wraster.h.in)
The public header exposes X11 types directly:
| API function |
X11 types in signature |
RCreateContext() |
Display *dpy |
RGetClosestXColor() |
XColor *retColor |
RCreateImageFromXImage() |
XImage *image, XImage *mask |
RCreateImageFromDrawable() |
Drawable drawable, Pixmap mask |
RConvertImage() |
Pixmap *pixmap (return) |
RConvertImageMask() |
Pixmap *pixmap, Pixmap *mask (return) |
RCreateXImage() |
returns RXImage * (wraps XImage) |
RGetXImage() |
Drawable d |
RPutXImage() |
Drawable d, GC gc |
RContext struct fields that are X11 types
| Field |
Type |
Used by |
dpy |
Display * |
Everything in context.c, xutil.c, xpixmap.c, convert_x11.c, load_xpm.c |
cmap |
Colormap |
context.c (colormap allocation), load_xpm.c (color parsing) |
copy_gc |
GC |
convert_x11.c (pixmap copy) |
visual |
Visual * |
context.c (visual selection), xutil.c (XImage creation) |
drawable |
Window |
convert_x11.c (XCreatePixmap root window) |
colors |
XColor * |
context.c (PseudoColor palette) |
RXImage struct — entirely X11
// wraster.h.in:265-268
XImage *image;
// USE_XSHM:
XShmSegmentInfo info;
4. Direct Xlib Calls by File
| File |
Calls |
Functions used |
context.c |
44 |
XAllocColor, XQueryColors, XInternAtom, XGetRGBColormaps, XAllocStandardColormap, XFree, XCreateColormap, XGetVisualInfo, XCreateWindow, XCreateGC, XFreeGC, XDestroyWindow, XShmQueryVersion, XShmPixmapFormat, XSetWindowAttributes |
xutil.c |
32 |
XCreateImage, XDestroyImage, XShmCreateImage, XShmAttach, XShmDetach, XShmGetImage, XShmPutImage, XSync, XSetErrorHandler, XGetGeometry, XGetImage, XPutImage, XCreatePixmap, XFreePixmap |
convert.c |
14 |
RCreateXImage, RDestroyXImage (wrlib wrappers, but they call Xlib internally) |
xpixmap.c |
13 |
XGetPixel, XGetGeometry, XGetImage, XDestroyImage |
convert_x11.c |
6 |
XCreatePixmap, XCopyArea, XFreePixmap, XCreateGC, XFreeGC, RPutXImage |
load_xpm.c |
2 |
XParseColor (color name→RGB), XpmCreateXpmImageFromData, XpmReadFileToXpmImage, XpmFreeXpmImage (libXpm, not Xlib proper) |
5. Summary: Heat Map
Pure Gratuitous Genuinely
Portable X11 Header X11-Dependent
────────── ────────── ────────
alpha_combine.c ██████████
draw.c ██████████
gradient.c ██████████
load_gif.c ██████████
load_jpeg.c ██████████
load_magick.c ██████████
load_png.c ██████████
load_tiff.c ██████████
load_webp.c ██████████
load_xpm_normalized.c ██████████
save_jpeg.c ██████████
save_png.c ██████████
save_xpm.c ██████████
convert_wl.c ██████████ (Wayland backend)
color.c ██████████
convolve.c ██████████
flip.c ██████████
load.c ██████████
load_ppm.c ██████████
misc.c ██████████
raster.c ██████████
rotate.c ██████████
save.c ██████████
scale.c ██████████
load_xpm.c ████████░░ (libXpm + XParseColor)
convert.c ██████████ (RXImage converters)
convert_x11.c ██████████ (X11 convert backend)
xpixmap.c ██████████ (Drawable→RImage)
xutil.c ██████████ (XImage/XShm lifecycle)
context.c ██████████ (RContext creation, 44 calls)
By the numbers:
| Category |
Files |
LOC |
% of wrlib |
| Fully portable |
14 |
3210 |
36% |
Portable but needlessly includes X11/Xlib.h |
10 |
3140 |
36% |
| Genuinely X11-dependent |
6 |
2479 |
28% |
The Wayland story in wrlib is already partially told. The convert_image function pointer dispatch and RCreateContextWayland() exist, and convert_wl.c provides the pixman-based conversion path. What remains X11-bound:
context.c — RCreateContext() (525 lines of X11 visual/colormap setup) vs RCreateContextWayland() (45 lines). The X11 path is 10× larger but they're already separate functions.
xutil.c + xpixmap.c — the entire RXImage abstraction is X11-only. On Wayland, these are dead code (the wl_convert_image path never touches RXImage).
convert.c — the image2TrueColor/image2PseudoColor/etc. converters produce RXImage (X11). On Wayland, they're bypassed entirely by the function pointer dispatch.
load_xpm.c — uses libXpm and XParseColor. The alternative load_xpm_normalized.c is a pure-C XPM parser that doesn't need X11 (already exists as the Wayland-compatible path).
- The public API —
wraster.h exposes Display *, Pixmap, Drawable, GC, XImage, XColor in function signatures. On Wayland, Pixmap is reused as a uintptr_t cast of pixman_image_t * — a type pun, not a real abstraction.
wmlib/ — Backend-Specific Branch Inventory
wmlib is tiny — 481 lines of C across 4 files, plus 2 headers (238 lines). It's a client-side helper library that lets external applications communicate with the WindowMaker WM via X11 properties and client messages. It is 100% X11.
File Map
| File |
LOC |
Purpose |
Xlib calls |
command.c |
75 |
Send WM commands (hide app, hide others, set GNUstep attributes) via XSendEvent + XChangeProperty |
5 |
event.c |
87 |
Process incoming _WINDOWMAKER_MENU client messages from the WM |
1 |
menu.c |
239 |
Build menu tree in memory, serialize to X text property via XSetTextProperty |
3 |
app.c |
80 |
Application context (WMAppContext) — stores Display *, main window, window list |
0 (stores X11 types, doesn't call Xlib) |
WMaker.h |
162 |
Public API header |
— |
app.h |
41 |
Private wmAppContext struct |
— |
menu.h |
76 |
Private wmMenu/wmMenuEntry structs |
— |
1. Compile-Time #ifdef Branches
None. Zero #ifdef guards of any kind (beyond header include guards and __cplusplus). No conditional compilation, no feature toggles, no backend switches.
2. Runtime Backend Dispatch
None. No function pointers, no vtables, no is_wayland checks.
3. X11 Types in the Public API (WMaker.h)
Every public function takes X11 types:
| Function |
X11 types |
WMAppCreateWithMain() |
Display *display, Window main_window |
WMAppCreate() |
Display *display |
WMAppAddWindow() |
Window window |
WMProcessEvent() |
XEvent *event |
WMSetWindowAttributes() |
Display *dpy, Window window |
WMMenuAction callback |
Time timestamp |
The GNUstepWMAttributes struct contains Pixmap fields.
4. X11 Types in Private Structs
wmAppContext (app.h)
Display *dpy;
Window main_window;
Window *windows;
No X11 types — pure C data structures (strings, tags, linked list pointers). The X11 dependency comes only at serialization time.
5. Direct Xlib Calls — Complete List
There are only 9 Xlib calls in the entire library:
| File |
Line |
Call |
Purpose |
command.c:31 |
XInternAtom(dpy, "_WINDOWMAKER_WM_FUNCTION", False) |
Get the WM command atom |
|
command.c:47 |
XSendEvent(...) |
Send "hide application" command to WM |
|
command.c:62 |
XSendEvent(...) |
Send "hide others" command to WM |
|
command.c:70 |
XInternAtom(dpy, "_GNUSTEP_WM_ATTR", False) |
Get the GNUstep attributes atom |
|
command.c:71 |
XChangeProperty(...) |
Set GNUstep WM attributes on a window |
|
event.c:76 |
XInternAtom(app->dpy, "_WINDOWMAKER_MENU", False) |
Get the menu event atom |
|
menu.c:199 |
XInternAtom(dpy, WMMENU_PROPNAME, False) |
Get the menu property atom |
|
menu.c:226 |
XStringListToTextProperty(...) |
Serialize menu string list |
|
menu.c:232 |
XSetTextProperty(...) |
Write serialized menu to window property |
|
Plus one XFree() call (menu.c:234).
6. Communication Protocol
The library implements a simple IPC protocol built entirely on X11 mechanisms:
- App → WM:
XSendEvent with ClientMessage type _WINDOWMAKER_WM_FUNCTION to the root window
- App → WM (menus):
XSetTextProperty writes a serialized menu tree to _WINDOWMAKER_MENU on the app's main window
- WM → App:
ClientMessage events with type _WINDOWMAKER_MENU carrying a menu item tag
Summary
Pure X11-Dependent
Portable
────────── ──────────
app.c (data only) ████░░░░░░ (stores Display*/Window)
menu.c (data + serial) ░░░░░░░░░░ ██████████ (XSetTextProperty)
command.c ░░░░░░░░░░ ██████████ (XSendEvent, XChangeProperty)
event.c ░░░░░░░░░░ ██████████ (XInternAtom, ClientMessage)
WMaker.h ░░░░░░░░░░ ██████████ (Display, Window, Pixmap, XEvent, Time)
wmlib is entirely X11. There is no abstraction layer, no backend dispatch, no Wayland path, and no compile-time guards. The entire library is a thin wrapper around X11 client messages and properties for the GNUstep/WindowMaker protocol.
For a Wayland port, wmlib would either need to be:
- Replaced with a Wayland-native protocol (e.g., a custom
wl_protocol extension), or
- Kept as-is for XWayland clients only, with a parallel Wayland-native equivalent, or
- Dropped — its functionality (app hide/show, WM-managed menus) could be subsumed into the compositor's own protocol.
Given its size (481 lines of C, 9 Xlib calls), any of these options is straightforward.
util/ — Backend-Specific Branch Inventory
util/ contains 15 standalone CLI programs (7336 LOC). They range from fully X11-dependent GUI apps to pure file-manipulation tools with zero display-system dependency.
File Classification
Entirely X11-Free (pure file/text manipulation)
| File |
LOC |
Purpose |
X11 calls |
convertfonts.c |
167 |
Convert old WM font config to new format |
0 |
fontconv.c |
200 |
XLFD font name conversion helpers |
0 |
wdread.c |
110 |
Read a key from the WM defaults database |
0 |
wdwrite.c |
114 |
Write a key to the WM defaults database |
0 |
getstyle.c |
418 |
Export style/theme from WM defaults to file |
0 |
geticonset.c |
124 |
Export icon set from WM defaults to file |
0 |
seticons.c |
129 |
Import icon set into WM defaults |
0 |
wmmenugen.c |
393 |
Generate WM menu from .desktop files (PropList output) |
0 |
wmmenugen_misc.c |
172 |
Menu generator helpers (terminal detection) |
0 |
wmmenugen_parse_xdg.c |
737 |
XDG .desktop file parser |
0 |
wmmenugen_parse_wmconfig.c |
297 |
wmconfig file parser |
0 |
wmgenmenu.c |
519 |
Another menu generator (hardcoded menu templates) |
0¹ |
| Total |
3380 |
|
|
¹ wmgenmenu.c has the string "XTerm" as a menu item label — no actual Xlib call.
X11-Dependent GUI Applications
| File |
LOC |
Xlib calls |
Purpose |
wmiv.c + wmiv.h |
1020 + 1279 |
60 |
Image viewer — full X11 window, event loop, keyboard handling |
wmsetbg.c |
1444 |
53 |
Set desktop background — pixmap creation, root window manipulation |
wmagnify.c |
491 |
20 |
Screen magnifier — XGetImage from root, WINGs GUI |
wxpaste.c |
232 |
18 |
Paste from X selection/clipboard |
wxcopy.c |
246 |
12 |
Copy to X cut buffers/selection |
setstyle.c |
523 |
10 |
Import style into WM defaults + send reload command via XSendEvent |
| Total |
3956 (excl. wmiv.h) |
173 |
|
1. Compile-Time #ifdef Branches
Backend/Extension Guards
| Guard |
File |
Sites |
What it guards |
USE_XINERAMA |
wmsetbg.c |
7 |
Xinerama include, XineramaQueryScreens, per-head background stretching, --xinerama CLI flag |
USE_XPM |
wmiv.c |
4 |
XPM icon loading for the image viewer window |
HAVE_EXIF |
wmiv.c |
3 |
EXIF orientation auto-rotation |
HAVE_PTHREAD |
wmiv.c |
5 |
Background image preloading thread |
Portability Guards (not backend-specific)
| Guard |
Files |
Sites |
What it guards |
__GLIBC__ |
8 files |
8 |
#define _GNU_SOURCE |
HAVE_STDNORETURN |
7 files |
7 |
C11 _Noreturn |
_GNU_SOURCE |
wmiv.c |
1 |
GNU extensions |
HAVE_SYS_SELECT_H |
wxpaste.c |
1 |
<sys/select.h> include |
HAVE_LIBINTL_H + I18N |
wmgenmenu.c |
1 |
Gettext |
PATH_MAX |
getstyle.c |
1 |
Fallback definition |
DEBUG |
wmsetbg.c (6), wmmenugen.c (2), wmmenugen_parse_*.c (3) |
11 |
Debug logging |
2. Runtime Backend Dispatch
_x11_raw Escape Hatch (1 site)
| File |
Line |
What it does |
wmagnify.c |
314 |
XEvent *xev = (XEvent *)event->_x11_raw — casts the WINGs event to get the raw XKeyEvent for XLookupString |
No other runtime backend checks (is_wayland, dpy == NULL, etc.) in any util file.
3. X11 Types in Function Signatures / Structs
wmsetbg.c
Display *dpy; // global
Pixmap texture->pixmap; // background storage
XColor color; // color parsing
XRectangle head[]; // Xinerama head geometry
wmiv.c
Display *dpy; // global
Window win; // viewer window
XTextProperty title_property; // window title
XClassHint, XSizeHints, XWMHints // window manager hints
XEvent e; // event loop
XKeyEvent event; // synthetic key events
wmagnify.c
Display *dpy, *vdpy; // two display connections (magnify from one, draw to other)
XImage *image; // captured screen region
XRectangle rects[]; // magnified pixel rectangles
GC gc; // drawing context
wxcopy.c / wxpaste.c
Display *dpy; // global
Atom selatom, clipatom; // selection atoms
XEvent ev; // selection events
Window win; // hidden window for selection protocol
setstyle.c
Display *dpy; // opened only to send reload command
XEvent ev; // client message
XColor color1, color2; // color validation
4. Direct Xlib Calls — Per File
wmiv.c (60 calls) — Image Viewer
Full X11 application: window creation, event loop, pixmap management.
| Category |
Calls |
| Window lifecycle |
XOpenDisplay, XCreateSimpleWindow, XMapWindow, XCloseDisplay, XSelectInput |
| Drawing |
XCopyArea (×6), XClearWindow (×3), XResizeWindow (×4), XFreePixmap (×3) |
| Window properties |
XSetWMProperties, XSetWMName, XSetWMProtocols, XStringListToTextProperty, XAllocClassHint, XAllocSizeHints, XAllocWMHints |
| Event loop |
XNextEvent, XSendEvent, XFlush, XSync |
| EWMH |
XInternAtom (×2 — _NET_WM_STATE, _NET_WM_STATE_FULLSCREEN) |
| Input |
XKeysymToKeycode, XGetWindowAttributes |
wmsetbg.c (53 calls) — Background Setter
Root window pixmap manipulation, color allocation, property management.
| Category |
Calls |
| Color |
XParseColor (×7), XAllocColor (×2), XFreeColors |
| Pixmap |
XCreatePixmap (×3), XFreePixmap (×2), XCopyArea (×3), XSetForeground (×2), XFillRectangle (×2) |
| Root window |
XSetWindowBackground, XSetWindowBackgroundPixmap, XClearWindow |
| Properties |
XInternAtom, XGetWindowProperty, XChangeProperty, XDeleteProperty — _XROOTPMAP_ID management |
| Connection |
XOpenDisplay (×2 — main + RetainPermanent trick), XCloseDisplay, XSetCloseDownMode, XSync, XFlush, XSynchronize |
| Server grab |
XGrabServer, XUngrabServer |
| Error handling |
XSetErrorHandler, XKillClient |
| Xinerama |
XineramaIsActive, XineramaQueryScreens, XFree |
wmagnify.c (20 calls) — Screen Magnifier
Captures screen pixels and renders magnified view via WINGs.
| Category |
Calls |
| Capture |
XGetImage, XDestroyImage, XGetPixel, XQueryPointer |
| Drawing |
XCreateGC, XSetForeground, XFillRectangles (×3) |
| Connection |
XOpenDisplay (×2 — main + virtual display), XMaxRequestSize |
| Input |
XLookupString (via _x11_raw) |
wxpaste.c (18 calls) — Clipboard Paste
X11 selection protocol client.
| Category |
Calls |
| Selection |
XConvertSelection, XGetWindowProperty, XFetchBuffer |
| Connection |
XOpenDisplay, XCloseDisplay, XDisplayName |
| Window |
XCreateSimpleWindow, XSelectInput, XStoreName |
| Events |
XNextEvent, XPending, XInternAtom (×2) |
wxcopy.c (12 calls) — Clipboard Copy
X11 cut buffer / selection protocol.
| Category |
Calls |
| Buffers |
XStoreBuffer, XRotateBuffers, XListProperties, XSetSelectionOwner |
| Connection |
XOpenDisplay, XCloseDisplay, XDisplayName, XSetErrorHandler, XFlush |
| Properties |
XFree |
setstyle.c (10 calls) — Style Importer
Mostly file manipulation; X11 used only for color validation and sending a reload command.
| Category |
Calls |
| Color validation |
XParseColor (×2) — validates color names in the style |
| WM command |
XOpenDisplay, XInternAtom (_WINDOWMAKER_COMMAND), XSendEvent, XFlush |
5. Summary: Heat Map
Pure X11-Dependent
Portable
────────── ──────────
convertfonts.c ██████████
fontconv.c ██████████
wdread.c ██████████
wdwrite.c ██████████
getstyle.c ██████████
geticonset.c ██████████
seticons.c ██████████
wmmenugen.c ██████████
wmmenugen_misc.c ██████████
wmmenugen_parse_xdg.c ██████████
wmmenugen_parse_wmc.. ██████████
wmgenmenu.c ██████████
setstyle.c ██████░░░░ (XParseColor, XSendEvent for reload)
wxcopy.c ░░░░░░░░░░ ██████████ (X cut buffers/selection)
wxpaste.c ░░░░░░░░░░ ██████████ (X selection protocol)
wmagnify.c ░░░░░░░░░░ ██████████ (XGetImage, WINGs GUI)
wmsetbg.c ░░░░░░░░░░ ██████████ (root pixmap, 53 Xlib calls)
wmiv.c ░░░░░░░░░░ ██████████ (full X11 app, 60 Xlib calls)
By the numbers:
| Category |
Files |
LOC |
% of util |
| Fully portable (no X11) |
12 |
3380 |
46% |
| Mostly portable (minor X11 for WM command) |
1 (setstyle.c) |
523 |
7% |
| Entirely X11-dependent |
5 |
3433 |
47% |
The five X11-dependent utilities are all standalone GUI programs. For a Wayland port, each would need either:
wmsetbg.c — Wayland compositors typically own the background; this tool would become a protocol message to the compositor rather than root window pixmap manipulation.
wmiv.c — Full rewrite against Wayland client APIs (or just use WINGs, which already has a Wayland view backend).
wmagnify.c — Already uses WINGs widgets; the X11 dependency is XGetImage for screen capture (no Wayland equivalent without a screencopy protocol).
wxcopy.c / wxpaste.c — X11 selection protocol → Wayland wl_data_device / zwp_primary_selection_v1. Completely different protocol, complete rewrite.
The 12 portable utilities (defaults DB tools, menu generators, font converters) work on any platform unchanged.
WINGs/ — Backend-Specific Branch Inventory
WINGs is the largest component at ~40k LOC across 62 .c files. It has a well-developed five-vtable backend abstraction but significant X11 leakage remains in widget code.
Architecture: The Five Backend Vtables
WINGs uses runtime vtable dispatch set in widgets.c:777-812 based on WMAKER_USE_WAYLAND env var:
scrPtr->viewBackend = wayland ? &W_ViewBackendWL : &W_ViewBackendX11;
scrPtr->eventBackend = wayland ? &W_EventBackendWL : &W_EventBackendX11;
scrPtr->renderBackend = wayland ? &W_RenderBackendWL : &W_RenderBackendX11;
scrPtr->fontBackend = wayland ? &W_FontBackendWL : &W_FontBackendX11;
scrPtr->colorBackend = wayland ? &W_ColorBackendWL : &W_ColorBackendX11;
| Vtable |
Slots |
X11 impl |
Wayland impl |
W_ViewBackend |
19 (realize, map, unmap, move, resize, raise, lower, reparent, destroy, set_background_color, set_cursor, redisplay, selection, flush…) |
wview_x11.c (238 LOC) |
wview_wl.c (368 LOC) |
W_EventBackend |
5 (screen_init, screen_fini, fetch, check_mask, post_dispatch) |
wevent_x11.c (354 LOC) |
wevent_wl.c (235 LOC) |
W_RenderBackend |
12 (pixmap_create, pixmap_free, pixmap_copy, draw_line, draw_rect, fill_rect, fill_stippled, composite_pixmap, fill_polygon, fill_arc, create_disabled_mask) |
wrender_x11.c (175 LOC) |
wrender_wl.c (279 LOC) |
W_FontBackend |
8 (screen_init, screen_fini, create, destroy, measure, draw_string, draw_image_string, height) |
wfont_x11.c (212 LOC) |
wfont_wl.c (235 LOC) |
W_ColorBackend |
5 (screen_init, screen_fini, alloc_color, find_close_color, free_color, parse_named) |
wcolor_x11.c (130 LOC) |
wcolor_wl.c (106 LOC) |
Backend split files total: X11 = 1109 LOC, Wayland = 1223 LOC.
File Classification
Fully Portable (zero Xlib calls, zero X11 types)
| File |
LOC |
Purpose |
proplist.c |
1878 |
NeXTSTEP property list parser/serializer |
wfilepanel.c |
896 |
File open/save panel |
wpanel.c |
847 |
Alert/input panels |
wscroller.c |
830 |
Scrollbar widget |
wfontpanel.c |
825 |
Font chooser panel |
wbutton.c |
755 |
Button widget |
bagtree.c |
745 |
Balanced tree data structure |
userdefaults.c |
641 |
User defaults system |
handlers.c |
566 |
Timer/idle handler dispatch |
wscrollview.c |
561 |
Scroll container widget |
notification.c |
482 |
Notification center |
string.c |
425 |
String utilities |
hashtable.c |
422 |
Hash table |
array.c |
363 |
Dynamic array |
wfont.c |
329 |
Font dispatch (delegates to fontBackend) |
data.c |
289 |
WMData wrapper |
tree.c |
255 |
Tree data structure |
wbox.c |
247 |
Box layout widget |
wprogressindicator.c |
243 |
Progress bar widget |
wframe.c |
230 |
Group box widget |
wmenuitem.c |
226 |
Menu item data |
memory.c |
223 |
Memory allocation wrappers |
wapplication.c |
216 |
Application context |
wlabel.c |
214 |
Label widget |
wcolor.c |
187 |
Color dispatch (delegates to colorBackend) |
configuration.c |
132 |
Configuration file handling |
usleep.c |
26 |
Microsecond sleep |
wutil.c |
24 |
Misc utilities |
| + Wayland backends |
|
|
wview_wl.c |
368 |
Wayland view backend |
wevent_wl.c |
235 |
Wayland event backend |
wfont_wl.c |
235 |
Wayland font backend |
wrender_wl.c |
279 |
Wayland render backend |
wcolor_wl.c |
106 |
Wayland color backend |
| Total |
12,474 |
31% of WINGs |
X11 Backend Split Files (properly abstracted)
| File |
LOC |
Xlib calls |
Purpose |
wview_x11.c |
238 |
29 |
X11 view lifecycle (XCreateWindow, XMapWindow, etc.) |
wrender_x11.c |
175 |
24 |
X11 drawing (XCreatePixmap, XFillRectangle, etc.) |
wevent_x11.c |
354 |
20 |
X11 event fetching (XNextEvent, XPending, etc.) |
wcolor_x11.c |
130 |
11 |
X11 color allocation (XAllocColor, etc.) |
wfont_x11.c |
212 |
2 |
X11 font rendering (Xft) |
| Total |
1109 |
86 |
3% of WINGs — properly isolated |
Widget Files with Xlib Leakage (should be backend-neutral but aren't)
| File |
LOC |
Xlib calls |
What's leaking |
wcolorpanel.c |
3556 |
89 |
XCreatePixmap, XCopyArea, XFillRectangle, XFreePixmap, XGetImage, XGetPixel, XPutPixel, XPutImage, XSubImage, XDestroyImage, XImage, XColor, XGrabPointer, XUngrabPointer, XQueryPointer, XSetWindowBackgroundPixmap, XRecolorCursor, XSetForeground, XSetClipMask, XSetClipOrigin, XCreatePixmapCursor, XFreeCursor, XCreatePixmapFromBitmapData, XFlush, XPending, XPeekEvent, XNextEvent, XCheckTypedEvent |
dragsource.c |
1179 |
45 |
XDND protocol: XSendEvent, XGetWindowProperty, XChangeProperty, XSetSelectionOwner, XConvertSelection, XGrabPointer, XUngrabPointer, XInternAtom, XGetInputFocus, XQueryTree, XTranslateCoordinates, shape extension |
wwindow.c |
712 |
41 |
Window properties: XSetWMName, XSetWMProtocols, XGetWMProtocols, XSetWMHints, XGetWMHints, XSetWMNormalHints, XSetClassHint, XSetTransientForHint, XChangeProperty, XWithdrawWindow, XAllocSizeHints, XAllocWMHints, XAllocClassHint, XmbTextListToTextProperty, XStoreName, XSetIconName, XFree |
winputmethod.c |
243 |
40 |
XIM/XIC: XOpenIM, XCreateIC, XDestroyIC, XSetICValues, XGetICValues, XSetICFocus, XUnsetICFocus, XSetIMValues, XGetIMValues, XRegisterIMInstantiateCallback, XUnregisterIMInstantiateCallback, XVaCreateNestedList, XSetInputFocus, XLookupString, XSelectInput, XDisplayKeycodes, XGetKeyboardMapping, XFree |
dragdestination.c |
999 |
37 |
XDND protocol: XSendEvent, XGetWindowProperty, XChangeProperty, XConvertSelection, XInternAtom, XTranslateCoordinates |
widgets.c |
1137 |
35 |
Screen init: XOpenDisplay, XCreateGC (×8), XCreateBitmapFromData, XCreatePixmap, XCreateFontCursor, XCreatePixmapCursor, XSetForeground, XFillRectangle, XFreePixmap, XInternAtom(s), XListProperties, XStoreBuffer, XGetModifierMapping, XFreeModifiermap, XKeysymToKeycode, XDisplayName, XColor |
wballoon.c |
476 |
28 |
Tooltip drawing: XFillArc, XFillRectangle, XFillPolygon, XSetForeground, XCreateGC, XTranslateCoordinates, shape extension |
wtext.c |
3998 |
23 |
Rich text: XBell, XFetchBuffer, XStoreBuffer, XFree, XUngrabPointer, XGrabPointer, XFlush, XInternAtom, XCreateGC, XCreateBitmapFromData, XChangeWindowAttributes, XSetWindowAttributes, XMapWindow, XRectangle, XEvent |
selection.c |
392 |
21 |
X selection protocol: XConvertSelection, XGetWindowProperty, XChangeProperty, XSendEvent, XSetSelectionOwner, XGetSelectionOwner, XDeleteProperty, XInternAtom, XFree |
dragcommon.c |
259 |
16 |
XDND shared: XInternAtom, XGetWindowProperty, XChangeProperty, XFree |
wappresource.c |
148 |
15 |
App icon: XGetWindowProperty, XFree, XInternAtom |
wtextfield.c |
1579 |
10 |
Text input: XBell, XFetchBuffer, XStoreBuffer, XFree, XUngrabPointer, XGrabPointer, XFlush, XInternAtom, XDrawRectangle |
wpopupbutton.c |
697 |
7 |
Popup: XGrabPointer, XUngrabPointer, XFlush |
wruler.c |
526 |
3 |
Ruler: XRectangle type usage |
wmisc.c |
351 |
2 |
Misc: XTranslateCoordinates |
| Total |
16,252 |
412 |
41% of WINGs |
Utility Files (WUtil sub-library, no X11)
| File |
LOC |
Purpose |
menuparser.c |
652 |
Menu file parser |
menuparser_macros.c |
723 |
Menu parser macro expansion |
findfile.c |
523 |
File path search |
error.c |
147 |
Error/warning output |
misc.c |
45 |
Misc WUtil helpers |
| Total |
2090 |
5% of WINGs |
1. Compile-Time #ifdef Branches
Backend/Extension Guards
| Guard |
File(s) |
Sites |
What it guards |
USE_XSHAPE |
dragsource.c (2), wballoon.c (2), wcolorpanel.c (6) |
10 |
Shape extension for DND drag icons, balloon tooltips, color picker magnifier |
USE_PANGO |
wfont_x11.c |
9 |
Pango text rendering in X11 font backend |
XDND_DEBUG |
dragsource.c (4), dragdestination.c (3), dragcommon.c (3) |
10 |
DND protocol debug logging |
HAVE_XINTERNATOMS |
widgets.c |
1 |
Batch atom intern optimization |
X_HAVE_UTF8_STRING |
winputmethod.c |
1 |
Xutf8LookupString availability |
DOUBLE_BUFFER |
wmisc.c (3), wscroller.c (8) |
11 |
Double-buffered drawing |
Portability Guards (not backend-specific)
| Guard |
File(s) |
Sites |
What it guards |
HAVE_SYSLOG / HAVE_SYSLOG_H |
error.c, misc.c |
6 |
Syslog logging |
HAVE_INOTIFY |
userdefaults.c |
4 |
File change monitoring |
USE_BOEHM_GC |
memory.c |
6 |
Boehm garbage collector |
HAVE_SYS_SELECT_H |
handlers.c |
1 |
<sys/select.h> |
HAVE_POLL |
handlers.c |
1 |
poll() vs select() |
HAVE_MKSTEMP |
proplist.c |
2 |
Secure temp file creation |
HAVE_STDNORETURN |
memory.c |
1 |
C11 _Noreturn |
HAVE_STRLCAT / HAVE_STRLCPY |
string.c |
2 |
BSD string functions |
HAVE_BSD_STRING_H |
string.c |
1 |
BSD string header |
HAVE_SYSCONF |
error.c |
1 |
sysconf() |
HAVE_SELECT |
handlers.c |
1 |
select() availability |
STRICT_NEXT_BEHAVIOUR |
wscroller.c (3), wslider.c (1) |
4 |
NeXTSTEP-strict scrollbar behavior |
I18N |
wapplication.c |
1 |
Internationalization |
DEBUG |
menuparser_macros.c (4), various |
~6 |
Debug logging |
VERBOSE |
wfilepanel.c (2), memory.c (3) |
5 |
Verbose logging |
2. X11 Types in Core Structs (WINGsP.h.in)
W_Screen (the WINGs screen object)
| Field |
Type |
Count |
display |
Display * |
1 |
rootWin |
Window |
1 |
applicationIconWindow, groupLeader |
Window |
2 |
stipple |
Pixmap |
1 |
| GCs |
GC |
8 (stippleGC, copyGC, clipGC, monoGC, xorGC, ixorGC, drawStringGC, drawImStringGC) |
colormap |
Colormap |
1 |
visual |
Visual * |
1 |
| Cursors |
Cursor |
(in defaultCursor, textCursor, invisibleCursor) |
| Atoms |
Atom |
(multiple protocol atoms) |
W_DragSourceInfo / W_DragDestinationInfo
| Field |
Type |
sourceAction, destinationAction |
Atom |
3. Direct Xlib Calls — Summary by Category
In properly-split _x11 files (86 calls — correctly isolated)
| File |
Calls |
Category |
wview_x11.c |
29 |
Window create/map/unmap/move/resize/destroy |
wrender_x11.c |
24 |
Pixmap create/free/copy, drawing primitives |
wevent_x11.c |
20 |
Event fetch, pending check, XSync |
wcolor_x11.c |
11 |
Color allocation |
wfont_x11.c |
2 |
Xft font rendering |
In non-split widget files (412 calls — leaking)
| Category |
Calls |
Files |
| DND (XDND protocol) |
98 |
dragsource.c (45), dragdestination.c (37), dragcommon.c (16) |
| Color picker |
89 |
wcolorpanel.c — pixmap manipulation, image capture, pointer grabs |
| Window properties |
41 |
wwindow.c — ICCCM hints, WM protocols |
| Input methods |
40 |
winputmethod.c — XIM/XIC lifecycle |
| Screen init |
35 |
widgets.c — GC creation, cursor creation, modifier mapping |
| Tooltips |
28 |
wballoon.c — shaped balloon drawing |
| Rich text |
23 |
wtext.c — clipboard, grabs |
| Selection/clipboard |
21 |
selection.c — X selection protocol |
| App resources |
15 |
wappresource.c — icon property reading |
| Text field |
10 |
wtextfield.c — clipboard, grabs |
| Popup button |
7 |
wpopupbutton.c — pointer grabs |
| Ruler |
3 |
wruler.c — XRectangle type |
| Misc |
2 |
wmisc.c — coordinate translation |
4. Summary: Heat Map
Fully Backend-Split Xlib
Portable (vtable) Leaking
────────── ────────── ────────
WUtil layer:
proplist.c ██████████
bagtree/array/hash/.. ██████████
handlers.c ██████████
menuparser*.c ██████████
findfile/string/etc ██████████
Backend split files:
wview_x11/wl.c ██████████
wevent_x11/wl.c ██████████
wrender_x11/wl.c ██████████
wfont_x11/wl.c ██████████
wcolor_x11/wl.c ██████████
Clean widgets (0 Xlib):
wbutton.c ██████████
wscroller.c ██████████
wscrollview.c ██████████
wlist.c ██████████
wbrowser.c ██████████
wslider.c ██████████
wsplitview.c ██████████
wtabview.c ██████████
wfilepanel.c ██████████
wfontpanel.c ██████████
wpanel.c ██████████
wframe.c ██████████
wlabel.c ██████████
wbox.c ██████████
wprogressindicator.c ██████████
wcolorwell.c ██████████
wmenuitem.c ██████████
Leaking widgets:
wcolorpanel.c ██████████ (89 calls)
dragsource.c ██████████ (45 calls)
wwindow.c ██████████ (41 calls)
winputmethod.c ██████████ (40 calls)
dragdestination.c ██████████ (37 calls)
widgets.c ██████████ (35 calls)
wballoon.c ██████████ (28 calls)
wtext.c ████████░░ (23 calls)
selection.c ████████░░ (21 calls)
dragcommon.c ██████░░░░ (16 calls)
wappresource.c ████░░░░░░ (15 calls)
wtextfield.c ███░░░░░░░ (10 calls)
wpopupbutton.c ██░░░░░░░░ (7 calls)
wruler.c █░░░░░░░░░ (3 calls)
wmisc.c █░░░░░░░░░ (2 calls)
By the numbers:
| Category |
Files |
LOC |
Xlib calls |
% of WINGs |
| Fully portable (WUtil + clean widgets + Wayland backends) |
34 |
14,564 |
0 |
36% |
Backend-split _x11 files (properly isolated) |
5 |
1,109 |
86 |
3% |
| Leaking widget files (X11 in non-split code) |
15 |
16,252 |
412 |
41% |
| WUtil utility code (no X11) |
8 |
2,090 |
0 |
5% |
| Remaining clean widgets (0 calls but use X11 types transitively) |
~6k |
|
|
15% |
The three biggest remaining problems for Wayland parity:
-
DND subsystem (dragsource.c + dragdestination.c + dragcommon.c = 2437 LOC, 98 Xlib calls) — the entire XDND protocol implementation. Wayland has wl_data_device. Needs a sixth vtable or full replacement.
-
wcolorpanel.c (3556 LOC, 89 Xlib calls) — the color picker does raw pixmap manipulation, screen capture (XGetImage), pointer grabs, and cursor recoloring. Needs to route through renderBackend and viewBackend.
-
wwindow.c + winputmethod.c + widgets.c (2092 LOC, 116 Xlib calls combined) — ICCCM window properties, XIM/XIC input method lifecycle, and screen initialization. These are protocol-level concerns that need backend abstraction (ICCCM doesn't exist on Wayland; input methods use zwp_text_input_v3).
WPrefs.app/ — Backend-Specific Branch Inventory
WPrefs.app is the WindowMaker preferences editor — a WINGs-based GUI application with 15,540 LOC across 21 .c files. Each file is a preference panel.
File Map
| File |
LOC |
Purpose |
Appearance.c |
2356 |
Titlebar/menu texture and color configuration |
Menu.c |
1825 |
Menu structure editor |
TexturePanel.c |
1549 |
Texture creation/editing dialog |
editmenu.c |
1361 |
Drag-and-drop menu editor widget |
WPrefs.c |
927 |
Main window, panel switching, save/revert |
MouseSettings.c |
798 |
Mouse speed, button mapping, modifier keys |
FontSimple.c |
751 |
Font configuration for titlebars, menus, etc. |
KeyboardShortcuts.c |
695 |
Keyboard shortcut binding editor |
WindowHandling.c |
612 |
Window placement, focus, maximize behavior |
Icons.c |
485 |
Icon size, position, animation |
HotCornerShortcuts.c |
465 |
Screen corner actions |
Configurations.c |
445 |
Misc settings (icon size, edge resistance, etc.) |
Expert.c |
363 |
Expert-level toggle options |
Focus.c |
362 |
Focus mode, auto-raise delay |
Preferences.c |
359 |
Size/position display, dialog behavior |
Docks.c |
335 |
Dock/clip behavior |
Paths.c |
328 |
Pixmap/icon search paths |
xmodifier.c |
311 |
Keyboard modifier detection (from XEmacs) |
Workspace.c |
240 |
Workspace naming |
MenuPreferences.c |
234 |
Menu behavior options |
Themes.c |
221 |
Theme import/export |
main.c |
180 |
Entry point, display open, WINGs init |
double.c |
163 |
Double-click speed test widget |
WPrefs.h |
175 |
Shared header |
TexturePanel.h |
56 |
Texture panel header |
editmenu.h |
113 |
Menu editor header |
File Classification
Fully Portable (zero Xlib calls, zero meaningful X11 types)
These files use only WINGs widget APIs and WMPropList for defaults manipulation:
| File |
LOC |
Purpose |
FontSimple.c |
751 |
Font configuration |
WindowHandling.c |
612 |
Window placement/behavior |
Icons.c |
485 |
Icon preferences |
Configurations.c |
445 |
Misc configuration |
Expert.c |
363 |
Expert toggles |
Focus.c |
362 |
Focus mode |
Preferences.c |
359 |
Size/position display |
Docks.c |
335 |
Dock behavior |
Workspace.c |
240 |
Workspace naming |
MenuPreferences.c |
234 |
Menu behavior |
Themes.c |
221 |
Theme management |
KeyboardSettings.c |
175 |
Keyboard repeat/delay |
| Total |
4582 |
29% of WPrefs.app |
Note: several of these files reference Display * or Window in variable declarations (obtained via WMScreenDisplay()) but only pass them to WINGs functions — they never call Xlib directly. The X11 types flow through transitively from WINGs.
X11-Dependent Files
| File |
LOC |
Xlib calls |
What's leaking |
Appearance.c |
2356 |
67 |
Texture preview rendering: XCreatePixmap, XCopyArea (×20), XDrawLine (×15), XDrawRectangle (×6), XFillRectangle (×4), XFillPolygon (×2), XFreePixmap (×6), XCreateGC/XFreeGC, XParseColor |
editmenu.c |
1361 |
37 |
Drag-and-drop menu editing: XGrabPointer/XUngrabPointer, XTranslateCoordinates (×4), XRecolorCursor (×4), XQueryTree, XQueryPointer, XGetWindowAttributes, XGetGeometry, XMoveWindow, XClearWindow, XFlush, XChangeProperty, XSetWMNormalHints, XAllocSizeHints, XSetErrorHandler |
Menu.c |
1825 |
24 |
Menu editor: XGrabKeyboard/XUngrabKeyboard, XDrawLine (×7), XSetForeground (×2), XFillRectangle, XCreateGC/XFreeGC — mostly drawing crosshair markers and key capture |
TexturePanel.c |
1549 |
14 |
Texture editor: XFillRectangle (×3), XCopyArea (×2), XFreePixmap, XParseColor, XCreateSimpleWindow, XMapRaised, XFlush, XOpenDisplay, XColor |
xmodifier.c |
311 |
12 |
Modifier key detection: XGetModifierMapping, XFreeModifiermap, XKeysymToKeycode — entirely X11 |
KeyboardShortcuts.c |
695 |
12 |
Shortcut capture: XGrabKeyboard/XUngrabKeyboard, XKeysymToKeycode, XKeysymToString, XAllowEvents, XGetModifierMapping, XFreeModifiermap, XConvertCase, XFillRectangle |
HotCornerShortcuts.c |
465 |
11 |
Hot corner icon rendering: XCreatePixmap (×5), XCopyArea (×5), XFreePixmap (×5), XCreateGC/XFreeGC — icon quadrant assembly |
WPrefs.c |
927 |
7 |
WM command: XInternAtom, XSendEvent, XFlush (×2) — sends _WINDOWMAKER_COMMAND to reload |
MouseSettings.c |
798 |
6 |
Mouse config: XChangePointerControl, XGetPointerControl, XGetModifierMapping, XFreeModifiermap, XKeysymToString |
main.c |
180 |
4 |
Startup: XSupportsLocale, XSetLocaleModifiers, XOpenDisplay, XDisplayName |
double.c |
163 |
2 |
Double-click widget: XFillRectangle, XClearWindow |
Paths.c |
328 |
1 |
List drawing: XFillRectangle (in custom list cell renderer) |
| Total |
8958 |
197 |
|
1. Compile-Time #ifdef Branches
Backend/Feature Guards
| Guard |
File |
Sites |
What it guards |
XKB_MODELOCK |
Expert.c:87, KeyboardShortcuts.c:166 |
2 |
XKB mode lock toggle option, extra keybinding |
HAVE_XCONVERTCASE |
KeyboardShortcuts.c:171 |
1 |
Whether to use system XConvertCase or local implementation |
Portability Guards
| Guard |
File |
Sites |
What it guards |
HAVE_STDNORETURN |
WPrefs.c:27, main.c:33 |
2 |
C11 _Noreturn |
I18N |
main.c:131 |
1 |
Gettext initialization |
FC_WEIGHT_NORMAL |
FontSimple.c:28 |
1 |
Fontconfig constant fallback |
DEBUG |
Expert.c:286 |
1 |
Debug panel option |
Total: 8 #ifdef sites. Remarkably few for a 15k LOC application.
2. Runtime Backend Dispatch
None. No vtable calls, no is_wayland checks, no _x11_raw access, no dpy == NULL guards. WPrefs.app is a pure WINGs client — it gets its X11 dependency entirely through WINGs APIs and direct Xlib calls.
WPrefs.h
int ModifierFromKey(Display *dpy, const char *key); // line 144
One function prototype with Display *. The rest of the header is WINGs types (WMScreen *, WMWindow *, etc.).
4. Direct Xlib Calls — By Category
Drawing / Pixmap Manipulation (120 calls — 61%)
The dominant category. WPrefs renders texture previews, menu editor decorations, and icon composites directly via Xlib:
| Operation |
Count |
Files |
XCopyArea |
27 |
Appearance.c (20), HotCornerShortcuts.c (5), TexturePanel.c (2) |
XDrawLine |
22 |
Appearance.c (15), Menu.c (7) |
XFillRectangle |
13 |
Appearance.c (4), Menu.c (1), TexturePanel.c (3), Paths.c (1), double.c (1), KeyboardShortcuts.c (1), HotCornerShortcuts.c (1), editmenu.c (1) |
XCreatePixmap |
8 |
Appearance.c (3), HotCornerShortcuts.c (5) |
XFreePixmap |
8 |
Appearance.c (4), HotCornerShortcuts.c (3), TexturePanel.c (1) |
XDrawRectangle |
6 |
Appearance.c |
XCreateGC / XFreeGC |
6 |
Appearance.c (4), Menu.c (2) |
XFillPolygon / XDrawLines |
4 |
Appearance.c |
XSetForeground |
2 |
Menu.c |
These should all route through WINGs' W_RenderBackend vtable but don't.
Keyboard / Input (24 calls — 12%)
| Operation |
Count |
Files |
XGrabKeyboard / XUngrabKeyboard |
4 |
KeyboardShortcuts.c, Menu.c |
XKeysymToKeycode / XKeysymToString |
5 |
KeyboardShortcuts.c, MouseSettings.c |
XGetModifierMapping / XFreeModifiermap |
6 |
KeyboardShortcuts.c, MouseSettings.c, xmodifier.c |
XConvertCase |
1 |
KeyboardShortcuts.c |
XAllowEvents |
1 |
KeyboardShortcuts.c |
Window / Pointer Manipulation (22 calls — 11%)
| Operation |
Count |
Files |
XGrabPointer / XUngrabPointer |
4 |
editmenu.c |
XTranslateCoordinates |
5 |
editmenu.c |
XRecolorCursor |
4 |
editmenu.c |
XQueryTree / XQueryPointer |
2 |
editmenu.c |
XGetWindowAttributes / XGetGeometry |
2 |
editmenu.c |
XMoveWindow / XClearWindow |
2 |
editmenu.c, double.c |
XChangePointerControl / XGetPointerControl |
2 |
MouseSettings.c |
WM Communication (7 calls — 4%)
| Operation |
Count |
Files |
XInternAtom |
1 |
WPrefs.c |
XSendEvent |
1 |
WPrefs.c |
XFlush |
3 |
WPrefs.c (2), TexturePanel.c (1) |
XChangeProperty / XSetWMNormalHints |
2 |
editmenu.c |
Color Parsing (3 calls — 2%)
| Operation |
Count |
Files |
XParseColor |
2 |
Appearance.c, TexturePanel.c |
XColor type |
2 |
Appearance.c, TexturePanel.c |
Display Connection (4 calls — 2%)
| Operation |
Count |
Files |
XOpenDisplay |
2 |
main.c, TexturePanel.c |
XSupportsLocale / XSetLocaleModifiers |
2 |
main.c |
5. Summary: Heat Map
Fully X11
Portable Leaking
────────── ────────
FontSimple.c ██████████
WindowHandling.c ██████████
Icons.c ██████████
Configurations.c ██████████
Expert.c ██████████
Focus.c ██████████
Preferences.c ██████████
Docks.c ██████████
Workspace.c ██████████
MenuPreferences.c ██████████
Themes.c ██████████
KeyboardSettings.c ██████████
Paths.c █████████░ (1 XFillRectangle)
double.c ████████░░ (2 calls)
WPrefs.c ███████░░░ (7 calls - WM reload command)
main.c ███████░░░ (4 calls - display open)
MouseSettings.c ██████░░░░ (6 calls - pointer control)
HotCornerShortcuts.c █████░░░░░ (11 calls - icon pixmap assembly)
KeyboardShortcuts.c █████░░░░░ (12 calls - key grab/detect)
TexturePanel.c ████░░░░░░ (14 calls - texture preview)
Menu.c ███░░░░░░░ (24 calls - menu editor drawing)
editmenu.c ██░░░░░░░░ (37 calls - DnD menu editing)
xmodifier.c ░░░░░░░░░░ ██████████ (12 calls - entirely X11)
Appearance.c ░░░░░░░░░░ ██████████ (67 calls - texture preview)
By the numbers:
| Category |
Files |
LOC |
Xlib calls |
% of WPrefs.app |
| Fully portable |
12 |
4582 |
0 |
29% |
| Minor X11 leakage (≤7 calls) |
5 |
1876 |
20 |
12% |
| Moderate X11 leakage (8–37 calls) |
5 |
3834 |
86 |
25% |
| Heavy X11 dependency (>37 calls) |
2 |
3717 |
91 |
24% |
| Entirely X11 (xmodifier.c) |
1 |
311 |
12 |
2% |
The three biggest problems for Wayland parity:
-
Appearance.c (67 Xlib calls) — all texture preview rendering. Uses XCopyArea, XDrawLine, XDrawRectangle, XFillPolygon directly on pixmaps. Should use WINGs' W_RenderBackend instead.
-
editmenu.c (37 Xlib calls) — the drag-and-drop menu editor. Pointer grabs, coordinate translation, window tree queries, cursor recoloring. These are interaction-model operations that need backend abstraction.
-
Keyboard/modifier detection (KeyboardShortcuts.c + xmodifier.c = 24 Xlib calls) — XGrabKeyboard, XGetModifierMapping, XKeysymToKeycode. On Wayland, keyboard handling uses xkbcommon directly rather than X11 modifier mapping.