KWindowSystem ships fixx11h.h (X11 macro cleanup), netwm.h and netwm_def.h
(EWMH) only with its X11 component, so a Wayland-only install lacks them. They
carry no X11/ or xcb/ path prefix, so the prefix-only rule missed them:
logout-greeter/shutdowndlg.cpp:51: fatal error: fixx11h.h: No such file
The single remaining unguarded case is libtaskmanager/xwindowtasksmodel.cpp,
which upstream excludes from the build via if(HAVE_X11) in
libtaskmanager/CMakeLists.txt -- it is never compiled, so it is left alone
rather than edited for appearance.
Converting `#ifdef HAVE_X11` to `#if HAVE_X11` changes the question from "does
this macro exist" to "what is its value", so the definition must actually be in
scope. Doing the conversion without guaranteeing the include turned a silently
inert guard into a hard error:
shell/panelview.h:13: error: 'HAVE_X11' is not defined, evaluates to 0
KDE builds with -Werror=undef, so an undefined macro in #if is fatal. The
previous commit fixed the guard form and introduced this; the transform now
inserts #include <config-X11.h> when it converts a guard in a file that lacks
it.
Verified: panelview.h now carries the include, and a second run is a no-op.
libtaskmanager/virtualdesktopinfo.cpp defines namespace X11Info at namespace
scope in terms of QNativeInterface::QX11Application, which does not exist in a
Qt built without the xcb platform:
error: 'QX11Application' is not a member of 'QNativeInterface'
All three call sites were already inside #if HAVE_X11 -- only the definition
was exposed -- so wrapping the block changes no reachable behaviour.
Restricted to depth-0 'namespace' blocks whose body names an X11-only native
interface. Narrow on purpose: brace-matching arbitrary function definitions is
much easier to get wrong, and a bad transform here produces invalid C++ rather
than a clean failure.
Distinct from the KWindowSystem-API gating: these are the Xlib/XCB headers
themselves, which a Wayland-only sysroot does not ship, so each is a hard
compile failure rather than a lost feature:
appmenu/appmenu.h:13: fatal error: xcb/xcb.h: No such file or directory
Two of the affected directories are genuinely compiled and would have failed in
turn: kcms/kfontinst (gated only on FONTCONFIG_FOUND) and logout-greeter
(CMakeLists.txt:428, outside any X11 gate). kcms/cursortheme is already gated
upstream by `if(WITH_X11 AND X11_Xcursor_FOUND)` and ksmserver by if(WITH_X11);
guarding them too is harmless and keeps the rule uniform rather than
maintaining a list of exceptions.
Only touches includes at preprocessor depth 0 with respect to HAVE_X11, so
anything already guarded is left alone.
Verified: preprocessor balance OK across all 59 files carrying guards, and a
second run is a no-op (0 files, 0 includes) -- the recipe re-runs this on every
build, so idempotency is a correctness requirement, not a nicety.
config-X11.h.cmake declares the macro with `#cmakedefine01 HAVE_X11`, which
always DEFINES it -- as 0 when X11 is off, not undefined. So `#ifdef HAVE_X11`
is true in BOTH configurations and the guard does nothing:
#ifdef HAVE_X11
#include <xcb/xcb.h> <- compiled even with HAVE_X11 == 0
#endif
That is how appmenu.h reached
appmenu/appmenu.h:13:10: fatal error: xcb/xcb.h: No such file or directory
while looking correctly guarded. `#if HAVE_X11` reads the value and behaves as
intended.
An upstream bug invisible on any system that has X11 headers installed, because
there the include just succeeds. 3 occurrences across appmenu.h and
panelview.h; plasma-desktop has none. Normalisation runs on every file rather
than only those using the X11-only KWindowSystem APIs, since the defect is
about the guard form, not the guarded content.
libcanberra: plasma-workspace calls find_package(Canberra) TYPE REQUIRED and
includes <canberra.h> from four translation units with no HAVE_CANBERRA guard,
one of them libnotificationmanager (the core notification library). It cannot
be made optional, so it is ported for real. Built shared: it dlopens its
backend through libltdl, the libtool recipe stages libltdl.so only (no .a), so
a static build left every consumer with an undefined lt_dlopenext.
Audio is SILENT. Upstream 0.30 offers alsa/oss/pulse/gstreamer/null and none
speak Redox; the pulse driver needs PulseAudio's client library, which PipeWire
does not provide. The null driver is real upstream code, so the API/ABI is
genuine and all consumers work -- but nothing reaches the speakers until a
native /scheme/audio driver exists.
KX11Extras et al: gate the five X11-only KWindowSystem headers behind the
HAVE_X11 that plasma-workspace already defines. X11 is compiled OUT, not added.
gate-kx11extras.py brace-matches each block and keeps any trailing else outside
the guard, since wrapping a whole if/else-if chain yields invalid C++.
check-recipe-escapes.py: a single backslash in a TOML multi-line string is a
TOML escape, so a sed written as \bFoo\b parses to <BS>Foo<BS> and silently
matches nothing -- no TOML error, no sed error. This class bit the tree three
times. Now gated in preflight; it also found openssh, which used an invalid \$
and could not be parsed by any compliant parser.
cook_build.rs: build git-tracked vendored sources OUT OF TREE. Recipe scripts
rewrite their source, so builds were mutating version-controlled files: a
no-op sed became indistinguishable from a working one, and the integrity gate
fired so often that clearing it stopped being protective. Uses
cp -a --reflink=auto, not cp -al: sed -i is link-safe but `cp -f` and `>`
truncate in place and would write through a hard link into the tracked
original. Content hashing still runs against the pristine tree, so hashes now
describe committed state. Escape hatch: REDBEAR_IN_TREE_BUILD=1.