SIGUSR2 was being delivered to pango fontconfig threads instead of the
signalfd because those threads were created before the signal mask was
set in wl_event_loop_run. Block SIGUSR2 at the very start of real_main
so all threads (including library-spawned ones) inherit the blocked
mask and the signalfd is the sole recipient.
The previous getppid() approach sent SIGUSR2 to the terminal process
(foot) rather than wmaker, killing the shell. Now wmaker exports
WMAKER_PID at startup and wl_send_wm_command reads it to signal the
correct process.
The phase-β sed pass renamed every C 'Window' identifier to
WNativeWindow. That correctly updated typedef uses but also rewrote
the string 'Window Maker', UI labels like 'Window Manager', 'Window
Placement', 'Window Title', 'Window List', 'Window System session',
etc., plus a number of comments referring to 'Window' as English.
Fixed all of those. The C type uses (WNativeWindow rootWin, etc.)
remain unchanged — only English-language occurrences are reverted.
Verified that wmaker now reports 'Window Maker 0.96.0' again and
build is clean across WINGs/, src/, WPrefs.app/.
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.
XSupportsLocale and XSetLocaleModifiers in main.c were the last
direct Xlib calls in src/main.c. Move them into x11_display_open
(guarded by I18N) where they naturally belong. The Wayland backend
does not need them — locale handling for native Wayland clients is
just standard libc, and XWayland clients still receive locale-aware
input via the wmaker-attached XWayland server's own setup.
main.c is now Xlib-free.
Remove every is_wayland / !is_wayland guard from WM policy files.
All backend-specific logic now lives exclusively in the backends:
- main.c: display_post_open vtable slot handles fatal check, visual ID,
display name, and multiHead parsing (X11) or no-ops (Wayland)
- event.c: EventLoop() unconditionally calls event_loop_run(); the X11
backend's implementation contains the WMNextEvent+inotify loop
- screen.c: screen_init_display vtable slot handles RContext/WMScreen/
color creation (each backend owns its full init path)
- monitor.c: show_crash_dialog vtable slot (X11 shows panel, Wayland
returns abort)
- startup.c: InitializeSwitchMenu called unconditionally (it's
backend-agnostic); defaults polling timer no longer guarded
- shutdown.c: wScreenSaveState called unconditionally
- window.c: client_reparent called unconditionally (Wayland no-ops);
dead frameless-window code removed
Policy code is now completely backend-agnostic. The only references to
is_wayland are the vtable field definitions in the two backend files.
- motif.c: wGetMWMHints moved entirely to x11_backend.c (inlined into
x11_motif_get_hints)
- colormap.c: wColormapInstallForWindow inlined into x11_colormap_install;
policy file now contains only vtable dispatch stubs
- resources.c: wGetColorForColormap and wFreeColor now dispatch through
vtable; X11 implementation inlined into x11_backend.c
- xmodifier.c: wXModifierInitialize now called from x11_extensions_init
(removed from main.c)
motif.o, colormap.o, resources.o verified X11-free with nm.
xmodifier.o retains X11 symbols (mechanism code, only reached through
X11 backend — candidate for physical move to backend/ directory).
scr->rcontext is NULL in the Wayland path (RContextCreate is only
called under dpy). SetupEnvironment() is reachable via shell command
launch and RelaunchWindow; wrap the WRASTER_COLOR_RESOLUTION putenv
in a scr->rcontext NULL-check to prevent a crash.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add display_default_screen, atom_intern, and event_loop_run vtable slots.
Guard all X11-only paths in startup.c/screen.c/shutdown.c/event.c/xdnd.c
with if (!dpy) so the Wayland path reaches wl_display_run() and exits
cleanly (exit 0) on SIGTERM. wl-smoke-test.sh now PASSES.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add three display-lifecycle slots to WMBackend:
display_open(name) — open/init display connection, return Display*
(NULL for Wayland; compositor init side-effect)
display_close() — tear down display connection
display_screen_count() — number of logical screens
x11_backend: implement with XOpenDisplay (including close-on-exec fcntl),
XCloseDisplay, ScreenCount(dpy); remove fcntl/FD_CLOEXEC from main.c.
wl_backend: implement display_open() with full wlroots headless compositor
init — wl_display_create, wlr_headless_backend_create, wlr_renderer_autocreate,
wlr_backend_start. display_close() tears down in reverse order.
Compositor state held in a file-static struct. Adds -DWLR_USE_UNSTABLE
to WLROOTS_CFLAGS in configure.ac.
main.c: move backend selection before display_open() (was in StartUp()),
call wm_backend->display_open() instead of XOpenDisplay(); guard all
X11-specific post-open code (visual-id, DisplayName, wXModifierInitialize)
in if(dpy != NULL).
startup.c: replace ScreenCount(dpy) with wm_backend->display_screen_count();
remove now-redundant backend-selection block (owned by main.c).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>