From d8d2ed837c5b86b0329a2ec9747fd6a670042d90 Mon Sep 17 00:00:00 2001 From: vasilito Date: Tue, 4 Aug 2026 21:26:14 +0300 Subject: [PATCH] gate-kx11extras: guard namespace blocks using QX11Application 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. --- local/scripts/gate-kx11extras.py | 59 +++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) diff --git a/local/scripts/gate-kx11extras.py b/local/scripts/gate-kx11extras.py index 1c3a670840..afea3e07b0 100755 --- a/local/scripts/gate-kx11extras.py +++ b/local/scripts/gate-kx11extras.py @@ -403,6 +403,60 @@ def gate_raw_x11_includes(text: str) -> tuple[str, int]: return "\n".join(out) + ("\n" if text.endswith("\n") else ""), changed +def gate_x11_namespace_blocks(text: str) -> tuple[str, int]: + r"""Guard a namespace block defined in terms of an X11-only Qt interface. + + libtaskmanager/virtualdesktopinfo.cpp defines + + namespace X11Info + { + [[nodiscard]] inline auto connection() + { + return qGuiApp->nativeInterface() + ->connection(); + } + } + + at namespace scope. QNativeInterface::QX11Application does not exist in a Qt + built without the xcb platform, so this fails to compile even though all + THREE call sites are already inside #if HAVE_X11: + error: 'QX11Application' is not a member of 'QNativeInterface' + + Only the definition is exposed, so wrapping the block is sufficient and + changes no reachable behaviour. Restricted to depth-0 `namespace` blocks + whose body names an X11-only native interface -- narrow on purpose, since + brace-matching arbitrary function definitions is far easier to get wrong. + """ + changed = 0 + search = 0 + while True: + m = re.compile(r"^namespace\s+\w+\s*$", re.M).search(text, search) + if not m: + break + brace = text.find("{", m.end()) + if brace < 0: + search = m.end() + continue + end = find_block_end(text, brace) + if end < 0: + search = m.end() + continue + body = text[m.start():end] + if "QX11Application" not in body: + search = end + continue + ls = line_start(text, m.start()) + prev_nl = text.rfind("\n", 0, ls - 1) + if text[prev_nl + 1: ls - 1].strip() == GUARD_OPEN: + search = end + continue + new = f"{GUARD_OPEN}\n" + text[ls:end] + f"\n{GUARD_CLOSE}" + text = text[:ls] + new + text[end:] + changed += 1 + search = ls + len(new) + return text, changed + + def main() -> int: root = Path(sys.argv[1]) # libtaskmanager's X11 backend is excluded from the build entirely (Wayland @@ -426,6 +480,8 @@ def main() -> int: print(f" {path.relative_to(root)}: {n_ifdef} inert #ifdef HAVE_X11 -> #if") if not any(sym in original for sym in X11_HEADERS): text, n_raw = gate_raw_x11_includes(original) + text, n_ns = gate_x11_namespace_blocks(text) + n_raw += n_ns if n_raw: path.write_text(text) total_files += 1 @@ -438,7 +494,8 @@ def main() -> int: text, n_els = gate_else_blocks(text) text, n_st = gate_statements(text) text, n_raw = gate_raw_x11_includes(text) - n_blk += n_els + n_st + text, n_ns = gate_x11_namespace_blocks(text) + n_blk += n_els + n_st + n_ns n_inc += n_raw if text != original: path.write_text(text)