Major architectural milestone: WINGs Wayland-only files now have ZERO
transitive X11 header dependency at the preprocessor level (verified by
gcc -E grep: 0 mentions of X11/Xlib.h after preprocessing).
Changes:
1. WUtil.h, WINGs.h: stop including <X11/Xlib.h>. wnative.h provides
forward declarations for Display, GC, XftDraw, XftFont; opaque
pointer-only typedefs that don't conflict with Xlib.h's actual
definitions when the X11 backend later includes it.
2. WINGsP.h.in: stop including <X11/Xlib.h>, <X11/Xutil.h>. Drop or
re-route every X11-typed prototype:
- W_HandleDNDClientMessage / W_DragSourceStateHandler /
W_DragDestinationStoreEnterMsgInfo / etc.
→ moved to new private header WINGs/WINGsX11.h
- W_HandleSelectionEvent → moved
- W_LookupString / W_KeycodeToKeysym → moved
- W_DndState typedef → moved (renamed to W_X11DndState)
- XClientMessageEvent / XEvent / XKeyPressedEvent in prototypes
→ use void * in shared protos, cast in WINGsX11.h
3. W_View struct: replaces XSetWindowAttributes by-value field with a
small backend-neutral 'attribs' struct holding only the fields
wmaker/WPrefs actually use (background_pixmap, background_pixel,
border_pixel, colormap, cursor, override_redirect, save_under,
event_mask, do_not_propagate_mask). The X11 view backend
translates to XSetWindowAttributes when calling XCreateWindow.
XIC xic field replaced with void *xic.
4. W_Color struct: replaces XColor by-value with a same-layout
anonymous struct (pixel/red/green/blue/flags/pad). X11 backend
uses memcpy to populate from XColor.
5. WINGs/WINGsX11.h (new): private header for X11 backend. Includes
<X11/Xlib.h>, declares X11-typed internal prototypes used by drag*,
selection, IME, x11_backend, KeyboardShortcuts. Required by every
*_x11.c file plus a handful of cross-component callers
(KeyboardShortcuts.c, MouseSettings.c, xmodifier.c, wmiv.c,
x11_backend.c).
6. wraster.h.in: gain a WRASTER_NO_XLIB compile-time switch. When
defined the header skips <X11/Xlib.h> and provides forward decls
for Display/Visual/XImage/GC/XftFont/etc. All Wayland-only WINGs
files (wclient_wl.c, w*_wl.c) define WRASTER_NO_XLIB on line 1.
7. wfont.c: adds W_ParseXLFDToFcPattern (a hand-written XLFD parser)
replacing XftXlfdParse. Removes <X11/Xft/Xft.h> include from the
shared font dispatcher (and from wfontpanel.c too).
Verification:
$ for f in WINGs/.libs/{*_wl.o,wclient_wl.o}; do
nm $f | awk '$1=="U"{print $2}' | grep -cE '^X[A-Z][a-z]'
done
0 for every Wayland file
$ for f in WINGs/.libs/*.o; do
case $f in *_x11.o|*_wl.o|wclient_wl.o) continue;; esac
c=$(nm $f | awk '$1=="U"{print $2}' | grep -cE '^X[A-Z][a-z]')
[ $c -gt 0 ] && echo "$c $f"
done
(empty — no shared file leaks an X11 symbol either)
$ gcc -E ... wclient_wl.c | grep -c X11/Xlib.h
0 (no transitive Xlib include)
The library still pulls libX11 through the *_x11.c files when those are
linked in. A future configure flag --disable-x11-backend will exclude
*_x11.c entirely; at that point libWINGs will be a pure-Wayland library
with zero libX11 dependency.
Sed pass restricted to files outside src/backend/x11 and outside
*_x11.c — i.e. all code that should not depend on X11 typedefs.
Window → WNativeWindow (existing typedef in WMEvent.h)
Atom → WMNativeAtom
Pixmap → WMNativePixmap
Cursor → WMNativeCursor
Drawable → WMDrawable (existing typedef)
KeySym → WMNativeKeysym
Colormap → WMNativeColormap
X11 backend files keep using the original Xlib type names because
they make Xlib API calls that take those types. All typedefs are
ultimately 'unsigned long' so values pass through opaquely between
shared code and the backend.
Public WINGs API affected: WMSelectionCallback, WMSelectionProcs,
and a handful of widget signatures that took Atom/Window arguments
now take WMNativeAtom/WNativeWindow. Source-compatible at the
binary level; consumers must rebuild.
Time and XID typedefs left for a follow-up — both are heavily used
in field/variable names that need careful auditing. Display* and
GC stay in W_Screen for now; phase δ moves them into an X11-only
sub-struct.
Mass rename of X11 enum values used in shared/Wayland code, with the
numeric values preserved so the wire layout of WMEvent fields and
the X11-backend translation tables remain unchanged.
NotifyNormal/Grab/Ungrab/WhileGrabbed → WM_NOTIFY_*
NotifyAncestor/Virtual/Inferior/Nonlinear/
NonlinearVirtual/Pointer/PointerRoot/
DetailNone → WM_NOTIFY_*
PropertyNewValue/Delete → WM_PROPERTY_*
MappingModifier/Keyboard/Pointer → WM_MAPPING_*
VisibilityUnobscured/PartiallyObscured/
FullyObscured → WM_VISIBILITY_*
GrabModeAsync/Sync, GrabSuccess → WM_GRAB_*
RevertToParent/PointerRoot/None → WM_REVERT_TO_*
CurrentTime → WM_CURRENT_TIME
None → WM_NATIVE_NONE
The 'None' rename was done with conservative regex passes restricted
to clear C-context patterns (= None;, , None,, !=None, etc.) so that
'"None"' string literals in defaults and XPM 'c None' colour names
are preserved untouched. Comments containing the English word 'None'
are also left alone. X11 backend files that legitimately use the
X11 macros (Xlib calls returning None, etc.) are unchanged.
Build clean across WINGs, src, WPrefs.app.
Sed pass. KeyPressMask, KeyReleaseMask, ButtonPressMask,
ButtonReleaseMask, EnterWindowMask, LeaveWindowMask,
PointerMotionMask, PointerMotionHintMask, Button{1..5}MotionMask,
ButtonMotionMask, KeymapStateMask, ExposureMask,
VisibilityChangeMask, StructureNotifyMask, ResizeRedirectMask,
SubstructureNotifyMask, SubstructureRedirectMask, FocusChangeMask,
PropertyChangeMask, ColormapChangeMask all renamed to the
corresponding WM_EVMASK_* names defined in wnative.h.
Numeric values still match the X11 layout, so wevent_x11.c's
matching tables and any code that masks bits keep working
unchanged. Build clean across WINGs/, src/, WPrefs.app/.
- wevent_wl.c: W_IsValidView() validates _view_target against view_table
at fetch boundary (wl_fetch, wl_check_mask, wl_check_typed_window);
nulls target before returning event if view was destroyed
- wevent_wl.c: W_WL_InvalidateView() nulls queue entries at destroy time
- wview.c: set view->screen=NULL before wfree(view)
- wevent.c: defense-in-depth: check !view->screen || alreadyDead before use
On shade, the client scene node was lowered and disabled, and the
frame_buf scene node was disabled. On unshade, the frame_buf node
was not re-enabled, and the client node was enabled but remained
behind the frame (at bottom of Z-order from stacking_lower).
Fix: re-enable frame_buf node when show_resizebar is true, and
raise the client scene node to top on window_map so it's above
the frame background.
WMHandleEvent is the middle layer — it must not contain any
backend-specific code. Move view lookup to _view_target field
set by each event backend during fetch. Move XRefreshKeyboardMapping
and XFilterEvent into x11_fetch. Selection and DND handling removed
from middle layer (handled by extraEventHandler in the WM layer).
The _x11_raw field remains in WMEvent for now (used by src/event.c
and other WM-layer code that still needs the raw XEvent), but the
middle layer no longer touches it.
Key changes in wl_backend.c:
- wl_atom_intern: call XInternAtom on XWayland display (was returning 0)
- Add wl_or_view struct to track override_redirect XWayland surfaces
- handle_xwayland_new_surface: composite OR surfaces via scene graph
- frame_create_toplevel/child: create real X11 windows on XWayland
- frame_destroy/configure: delegate to Xlib
- window_map/unmap/move/resize: fall through to Xlib for frame windows
- stacking_raise/lower: update scene graph + Xlib fallback
- event_flush/sync: call XFlush/XSync on XWayland display
- window_set_border/border_width/clear: delegate to Xlib
- window_get_rect: query XWayland geometry for non-toplevel windows
Note: frame creation via XWayland is a temporary bridge. The correct
architectural approach is native scene-buffer rendering with pixman.