Phase θ — wrlib's X11 image-conversion path (RConvertImage,
RPutXImage, the X11 RCreateContext, libXpm-based RLoadXPM) is now
opt-out via --disable-x11-wraster, mirroring the WINGs phase η work.
Result: with --disable-x11-backend --disable-x11-wraster the WINGs
runtime libraries have ZERO libX11 transitive deps:
$ ldd WINGs/.libs/libWINGs.so | grep X11
(empty)
$ ldd wrlib/.libs/libwraster.so | grep X11
(empty)
That was the last libX11 transitive dep coming through WINGs — the
goal of the API surgery is now achieved at the library level.
configure.ac:
- New --enable-x11-wraster (default = same as --enable-x11-backend),
AM_CONDITIONAL([USE_X11_WRASTER]), AC_DEFINE([USE_X11_WRASTER]).
Forcing --disable-x11-wraster while --enable-x11-backend is rejected
(X11 backend depends on the X11 conversion path).
- WRASTER_GFXLIBS_NO_XPM: GFXLIBS with -lXpm filtered (libXpm pulls
libX11; load_xpm_normalized.c is the X11-free XPM loader used in
the disabled-X11 build).
- WINGS_PANGO_LIBS_NO_XFT: PANGO_LIBS with -lpangoxft-* and -lXft
filtered (PangoXft depends on libXft -> libX11; pangoft2 path is
the X11-free Pango variant).
wrlib/Makefile.am:
- Split source list: shared / X11-only / Wayland-only.
- X11 sources (context.c, convert.c, convert_x11.c, xpixmap.c,
xutil.c, load_xpm.c) only built when USE_X11_WRASTER.
- New context_wl.c (always built) — Wayland-mode RCreateContextWayland
extracted from context.c.
- New wstubs_no_x11.c (only built when !USE_X11_WRASTER) — empty
stubs for the public wraster API symbols normally exported from
the X11 path (RCreateContext, RDestroyContext, RConvertImage,
RConvertImageMask, RGetClosestXColor, RCreateImageFromDrawable,
RCreateImageFromXImage, RCreateXImage, RGetXImage, RDestroyXImage,
RPutXImage, RGetImageFromXPMData, RLoadXPM).
- @XLIBS@/@LIBXMU@ only added to libwraster_la_LIBADD when
USE_X11_WRASTER; load_xpm.c only built when (USE_XPM and
USE_X11_WRASTER).
- Added --filter USE_X11_WRASTER to the wraster.h generation rule
so the @!USE_X11_WRASTER@ lines (forcing WRASTER_NO_XLIB) are
retained when X11 is disabled.
wrlib/wraster.h.in:
- When USE_X11_WRASTER is undefined at config time, force
WRASTER_NO_XLIB so consumers see only forward-decl'd opaque types
(Display/Visual/XImage/etc.) and never <X11/Xlib.h>.
- Added True/False/None defines to the WRASTER_NO_XLIB block (raster.c
uses them; previously got via Xlib.h).
wrlib/context.c — RCreateContextWayland moved out to context_wl.c.
wrlib/wstubs_no_x11.c — new (157 lines).
wrlib/context_wl.c — new (extracted Wayland branch).
WINGs/Makefile.am:
- libWINGs_la_LIBADD now uses WINGS_PANGO_LIBS, which is @PANGO_LIBS@
when X11 backend enabled, @WINGS_PANGO_LIBS_NO_XFT@ otherwise.
WINGs/widgets.c — WMCreateScreen + WMCreateSimpleApplicationScreen
moved to widgets_x11.c (they use DefaultScreen() and RCreateContext()
which are X11-only). Stubs added in WINGs/wstubs_no_x11.c.
WINGs shared rootWin assignment now reads context->drawable instead
of calling X11 RootWindow() macro directly.
WINGs/WINGs/wnative.h — added X11-numeric constants used by shared
WINGs widget code:
- Button1..Button5 (X.h pointer-button numbers)
- KeyPress..LASTEvent (X.h event-type constants)
- CWBackPixmap..CWCursor (X.h CreateWindow/ChangeWindowAttributes
mask bits)
- WMShortRect (XRectangle layout-compatible struct)
All guarded by #ifndef so X11 headers can override on the X11 build.
WINGs/configuration.c — dropped unused <X11/Xlocale.h> include.
WINGs/wruler.c, wtabview.c, wtext.c — replaced raw XPoint/XRectangle
with WMShortPoint/WMShortRect; replaced lone XSetWindowAttributes
shim with direct view->attribs.cursor access.
src/WindowMaker.h — explicitly include <X11/Xlib.h>, <X11/Xutil.h>,
<X11/Xresource.h>, <X11/Xatom.h>. The wmaker compositor uses these
extensively in its public headers; previously got them transitively
via WINGs.h. After the WINGs surgery WINGs.h no longer pulls Xlib,
so the compositor must include them itself.
Verified:
Default build (--enable-x11-backend, --enable-x11-wraster):
Window Maker 0.96.0 boots, all features intact.
Pure-Wayland build (--disable-x11-backend --disable-x11-wraster):
libwraster.so / libWINGs.so build cleanly, no libX11 in ldd.
(wmaker compositor binary still has X11 deps from src/* code;
out of scope for this commit — that's a compositor-level
refactor.)
Phase η: completes the WINGs API surgery by adding the configure
option that actually excludes the X11 backend from the build.
./configure --enable-wayland-client --disable-x11-backend
→ libWINGs has zero X11 symbol dependencies in its own objects
configure.ac: --enable-x11-backend (default yes) controls the new
USE_X11_BACKEND m4 conditional and #define.
WINGs/Makefile.am: split source list into:
- backend-neutral / shared sources (always)
- if USE_X11_BACKEND: dragsource_x11.c / dragdestination_x11.c /
dragcommon_x11.c / selection_x11.c / wappresource_x11.c /
wballoon_x11.c / wcolor_x11.c / wcolorpanel_x11.c /
wevent_x11.c / wfont_x11.c / widgets_x11.c /
winputmethod_x11.c / wrender_x11.c / wview_x11.c
- else: wstubs_no_x11.c (new)
XLIBS / XFT_LIBS only added to libWINGs_la_LIBADD when X11 backend
is enabled.
WINGs/wstubs_no_x11.c: empty implementations of every public WINGs
API symbol that normally lives in *_x11.c — DnD setup, selection
handlers, IM context, balloons, color/font panels, application icon
hints, atom helpers. Each stub is a no-op (returns success-neutral
value); calling them in pure-Wayland mode is silent rather than an
error, so future Wayland equivalents can drop in transparently.
WINGs/widgets.c: WMCreateScreenWithRContext uses weak references
to the W_*BackendX11 instances so they can resolve to NULL when not
linked. If the caller asked for X11 mode but X11 backend is not
built, falls back to Wayland with a warning.
WINGs/WINGsP.h.in: backend extern decls (W_*BackendX11) marked weak
so links resolve to NULL when X11 backend is excluded.
Verification:
$ ./configure --disable-x11-backend && make
$ for f in WINGs/.libs/*.o; do nm $f | grep '^.*U X[A-Z][a-z]'; done
(empty)
libWINGs.so still pulls libX11 transitively via wrlib (wraster's X11
image-conversion path); that's a separate refactor. At the WINGs
source level the partition is now complete: shared / X11 / Wayland.
Replaces the inline if-Wayland-else-X11 dispatch in WMOpenScreen with
a proper vtable. Each platform-open backend now provides one
W_PlatformBackend instance:
W_PlatformBackendX11 — widgets_x11.c
W_PlatformBackendWLClient — wclient_wl.c
WMOpenScreen walks an ordered registry of weak references to these
instances:
static const W_PlatformBackend *const wm_platform_backends[] = {
&W_PlatformBackendWLClient,
&W_PlatformBackendX11,
NULL
};
It first asks each backend's .detect() whether it wants the supplied
display string, and calls .open() on the first to claim it. If no
backend claims, it falls back to trying each .open() in order.
Weak references mean a build that excludes a backend (e.g. a future
--disable-x11-backend) link cleanly with the symbol resolving to
NULL — WMOpenScreen just skips it.
The detection logic moves out of shared widgets.c entirely:
x11_detect: explicit non-wayland display string OR $DISPLAY set.
wlclient_detect: 'wayland' prefix, WMAKER_USE_WAYLAND, or
$WAYLAND_DISPLAY set + $DISPLAY unset.
Also replaces WMCreateScreenWithRContext's getenv("WMAKER_USE_WAYLAND")
with an explicit W_SetNextScreenKind(WM_SCREEN_KIND_WAYLAND) flag the
platform backend sets before calling. No env detection in shared code.
Updated wmaker compositor (src/backend/wayland/wl_backend.c) to call
W_SetNextScreenKind(WM_SCREEN_KIND_WAYLAND) before its own
WMCreateScreenWithRContext call.
Verified: wmaker still starts in compositor mode, version string OK,
build clean, vtable dispatch invokes the right backend.
WINGs/widgets.c is now Xlib-call-free. All Xlib code moved to a new
WINGs/widgets_x11.c:
* W_X11PlatformInit (~178 lines): GC creation, modifier-mask probe,
cut-buffer setup, cursor/atom/IM init. Hooked from
W_ViewBackendX11.platform_init exactly as before.
* W_X11OpenDisplay: XOpenDisplay + WMCreateSimpleApplicationScreen.
WMOpenScreen() in widgets.c now calls this for the X11 path.
Dead code removed: the static renderPixmap that nothing called and
that was the last X11-direct-draw path in widgets.c.
X11 includes dropped from widgets.c. Display * typedef still resolves
through WINGsP.h transitively until phase ε removes that.
Build verified clean, wmaker still links and runs.
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.
WINGs API surgery, step 1.
New public header WINGs/WINGs/wnative.h declares WINGs-native types
and constants with no X11 header dependency:
- WMNativePixmap/Atom/Cursor/Keysym/Time/XID/Colormap/Bool typedefs
(all 'unsigned long' — compatible with the existing wire ABI).
- WM_MOD_SHIFT/LOCK/CONTROL/MOD{1..5} modifier mask bits.
- WM_BUTTON{1..5}_MASK pointer button mask bits.
- WM_ANY_MODIFIER/WM_ANY_BUTTON sentinels.
- WM_EVMASK_* event-mask bits (forthcoming patches).
- WM_NOTIFY_* crossing modes/details.
- WM_PROPERTY_* / WM_MAPPING_* / WM_VISIBILITY_* / WM_GRAB_* /
WM_REVERT_TO_* / WM_CURRENT_TIME / WM_NATIVE_NONE.
Numeric values intentionally match X11 layout for binary
compatibility with WMEvent fields (which were defined that way
originally). The architectural property that matters is that NONE
of the symbol *names* below are X11 macros — they belong to WINGs
and are defined without any X11 header.
WMEvent.h, WUtil.h, WINGs.h now #include <WINGs/wnative.h> so every
WINGs consumer picks up the new constants. X11 headers are still
included from the public WINGs headers; phase ε will drop them.
Phase α.1 — first sed pass:
ShiftMask → WM_MOD_SHIFT
ControlMask → WM_MOD_CONTROL
LockMask → WM_MOD_LOCK
Mod{1..5}Mask → WM_MOD_MOD{1..5}
Button{1..5}Mask → WM_BUTTON{1..5}_MASK
AnyModifier → WM_ANY_MODIFIER
AnyButton → WM_ANY_BUTTON
Applied across WINGs/, src/, WPrefs.app/ via sed with word
boundaries. Build verified clean; binary identical in size,
re-linked successfully.
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.
Widget pixmaps (checkbox, radio, arrows, etc.) were created inside
W_X11PlatformInit, so they were NULL in Wayland mode. Since
makePixmap now uses RImage+RConvertImage (backend-neutral), move
all makePixmap calls to common init after platform_init.
Replace X11 XDrawPoint pixel rendering with RImage construction
and RConvertImage, which dispatches through the backend vtable.
Fixes checkbox/radio button images not appearing in Wayland mode.
Was calling redisplay then map_subviews separately, with background
overwriting children. Now calls vb->map which does background first,
then children composite on top, with final commit showing everything.
Eliminated the separate Wayland/X11 code paths. Now ONE path:
1. Backend selection (based on WMAKER_USE_WAYLAND)
2. Backend init
3. Common init (colors, fonts, antialiasedText)
4. viewBackend->platform_init() — X11 does GCs, atoms, cursors,
cut buffers, modifier masks, pixmaps, IM, W_InitApplication.
Wayland is NULL (no platform-specific late init needed).
5. rootView, balloon, return
All X11-specific screen setup moved to W_X11PlatformInit() called
through the view backend vtable. No if-guards, no early returns,
no separate paths.
After WMHandleEvent processes a key press, the text field repaints
into its backing image. The modal loop now re-composites the view tree
and commits to the scene graph so changes are visible immediately.
- WMCreateScreenWithRContext: add Wayland path that skips all X11 calls
(no GCs, no atoms, no XListProperties, no XCreateGC)
- screen.c: skip RCreateContext in Wayland mode (pass NULL rcontext)
- Wayland path initializes: font/event/render backends, colors, fonts
Current issue: W_RealizeView tries to create X11 windows for WINGs
widgets. Need to make view realization work without X11 (views should
be pixman buffers in Wayland mode, not X windows).
The grey background + cursor render correctly. Startup reaches
WINGs init but crashes when widgets try to realize without a display.
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.