diff --git a/.pql/changelog/ticket_idmap/2026-06.sql b/.pql/changelog/ticket_idmap/2026-06.sql index a6215aba..173c1715 100644 --- a/.pql/changelog/ticket_idmap/2026-06.sql +++ b/.pql/changelog/ticket_idmap/2026-06.sql @@ -173,3 +173,4 @@ INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_ INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB4VG3N3YJSV8G7M1HFSYW2W', 'T-346', '2026-06-10 16:46:54', '2026-06-10 16:46:54', NULL, 'a64940cb0b4ec4fb489eac27065dc447', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_idmap.updated_at OR (excluded.updated_at = ticket_idmap.updated_at AND excluded.hash > ticket_idmap.hash); INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB4XCM5KBXDDSCWJ37GPYG3R', 'T-347', '2026-06-10 16:55:10', '2026-06-10 16:55:10', NULL, '9d40226dbc6136072d2d5d0eda71f141', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_idmap.updated_at OR (excluded.updated_at = ticket_idmap.updated_at AND excluded.hash > ticket_idmap.hash); INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB50YE6S6YWNP2ZSFWES9B2W', 'T-348', '2026-06-10 17:10:42', '2026-06-10 17:10:42', NULL, '8bb5ad92551f272417840869a0774668', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_idmap.updated_at OR (excluded.updated_at = ticket_idmap.updated_at AND excluded.hash > ticket_idmap.hash); +INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB58X0TFJ02YTMVPD0D9Q838', 'T-349', '2026-06-10 17:45:28', '2026-06-10 17:45:28', NULL, '0b12f14fa83254ab113c870531628359', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_idmap.updated_at OR (excluded.updated_at = ticket_idmap.updated_at AND excluded.hash > ticket_idmap.hash); diff --git a/.pql/changelog/tickets/2026-06.sql b/.pql/changelog/tickets/2026-06.sql index cd4cb6a9..99793b2f 100644 --- a/.pql/changelog/tickets/2026-06.sql +++ b/.pql/changelog/tickets/2026-06.sql @@ -3203,3 +3203,8 @@ Make the hook path-aware: diff the commits being pushed (remote_sha..local_sha f INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB50YE6S6YWNP2ZSFWES9B2W', 'task', NULL, 'Pre-push gate: skip the test suite for docs/changelog/pql/meta-only pushes', 'The .githooks/pre-push hook runs ''make push-check'' unconditionally — the full ~2min coverage + test-core suite even when a push touches only documentation, the changelog, pql ticket data, or other meta files that cannot affect the Flutter/Dart build or tests. Make the hook path-aware: diff the commits being pushed (remote_sha..local_sha from the hook''s stdin). If every changed file is under an allowlist that can''t affect tests — docs/, governance/, .pql/, .claude/, CHANGELOG.md, README.md, CLAUDE.md — run only the instant gates (decisions-validate + changelog-gate) and skip test-coverage/coverage-gate/test-core. Any code-ish path (lib/, test/, assets/, pubspec.*, native/, ci/, .githooks/, Makefile, platform dirs) → full gate. Fail safe: unknown/new-branch states run the full gate.', 'done', 'medium', NULL, NULL, NULL, '2026-06-10 17:10:42', '2026-06-10 17:13:53', NULL, 'f846b01b35bda1b8e247f360c46d472f', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash); +INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FB58X0TFJ02YTMVPD0D9Q838', 'bug', NULL, 'Linux build silently drops frameless chrome when wayland-client missing', 'linux/runner/CMakeLists.txt does pkg_check_modules(WAYLAND_CLIENT IMPORTED_TARGET wayland-client) WITHOUT REQUIRED, then only links it + defines HAS_WAYLAND_CLIENT inside if(WAYLAND_CLIENT_FOUND). The entire frameless custom-chrome path (D-057, KDE server-decoration protocol in clide_app.cc) is #ifdef HAS_WAYLAND_CLIENT. + +So a build host/container missing the Wayland client dev headers (very plausible in a Bazzite/immutable distrobox or toolbox) silently compiles out the decoration suppression — the rebuilt app ships with the compositor''s native title bar (double title bar on KDE Plasma Wayland). Reported live on Bazzite KDE. + +Fix: make wayland-client a hard build requirement — fail the CMake configure with a clear, actionable message (name the package: Fedora wayland-devel, Debian/Ubuntu libwayland-dev) instead of dropping the feature. Frameless chrome is a core guardrail; never ship without it. Also fix the stale ''xdg-decoration'' comment (the code uses the KDE server-decoration protocol, not xdg-decoration).', 'backlog', 'high', NULL, NULL, NULL, '2026-06-10 17:45:28', '2026-06-10 17:45:28', NULL, 'a60bee185c5bae1a8bf8bca98303883f', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash); diff --git a/linux/runner/CMakeLists.txt b/linux/runner/CMakeLists.txt index b831f3cf..23640d89 100644 --- a/linux/runner/CMakeLists.txt +++ b/linux/runner/CMakeLists.txt @@ -13,15 +13,24 @@ apply_standard_settings(${BINARY_NAME}) add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}") -# Find wayland-client for xdg-decoration protocol (D-057). +# Frameless custom chrome (D-057) drives the Wayland server-decoration protocol, +# which needs wayland-client at build time. It is a HARD requirement on a Linux +# desktop build host: without it the decoration-suppression path is compiled out +# and the app silently ships the compositor's native title bar — the exact thing +# D-057 removes (double title bar on KDE Plasma Wayland). Fail the configure +# loudly rather than drop a core feature (T-349). pkg_check_modules(WAYLAND_CLIENT IMPORTED_TARGET wayland-client) +if(NOT WAYLAND_CLIENT_FOUND) + message(FATAL_ERROR + "wayland-client (Wayland client dev headers) not found, but clide's " + "frameless window chrome (D-057) requires it. Install it — Fedora: " + "wayland-devel, Debian/Ubuntu: libwayland-dev — and rebuild.") +endif() target_link_libraries(${BINARY_NAME} PRIVATE flutter) target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK) -if(WAYLAND_CLIENT_FOUND) - target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::WAYLAND_CLIENT) - target_compile_definitions(${BINARY_NAME} PRIVATE HAS_WAYLAND_CLIENT=1) -endif() +target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::WAYLAND_CLIENT) +target_compile_definitions(${BINARY_NAME} PRIVATE HAS_WAYLAND_CLIENT=1) target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}") target_include_directories(${BINARY_NAME} PRIVATE "${CMAKE_SOURCE_DIR}/runner")