diff --git a/.agents/docs/2026-10-14-bump-eui-neo-0.6.1-plan.md b/.agents/docs/2026-10-14-bump-eui-neo-0.6.1-plan.md new file mode 100644 index 00000000..31c155e9 --- /dev/null +++ b/.agents/docs/2026-10-14-bump-eui-neo-0.6.1-plan.md @@ -0,0 +1,132 @@ +# Design doc: bump `compat.eui-neo` to 0.6.1 + +Date: 2026-10-14 + +Follow-up to `.agents/docs/2026-09-26-bump-eui-neo-0.6.0-plan.md` and commit `2863bb1` (0.6.0). +Upstream released 0.6.1; this bumps the index from 0.6.0 to 0.6.1. + +## Source and version + +| | | +|---|---| +| Upstream | `https://github.com/sudoevolve/EUI-NEO` | +| Version | `0.6.1` (latest release) | +| Tarball | `archive/refs/tags/v0.6.1.tar.gz` | +| sha256 | `cd0bd6bd437177db097da146fc20f4b8b01c70d0db561a6f8e26baa26dbbbf5f` (computed twice, stable) | +| Wrap dir | `EUI-NEO-0.6.1/` — absorbed by the existing `install()` hook (`normalise_layout`) | +| CN mirror | **pending** — no `mcpp-res` write access on this machine; plain-string url fallback per SOP | +| License | Apache-2.0 (unchanged) | + +## What changed upstream (0.6.0 → 0.6.1) + +Release notes: `docs/releases/v0.6.1.md` (window lifecycle + self-drawn windows, Linux input, +component interaction, cross-backend build stability). + +- **`CORE_SOURCES` and `VULKAN_SOURCES` are byte-identical to 0.6.0** (extracted and diffed from + both `CMakeLists.txt`). The lib's source list, deps, features and flags carry over unchanged. +- `core/window/x11_moveresize.h` is **new but header-only**: EWMH `_NET_WM_MOVERESIZE` + move/resize delegation. libX11 is dlopen'd at runtime — the header states verbatim that "no + build configuration gains a link-time X11 dependency", and `-ldl` is already on the linux + ldflags (glad). It DOES add a compile-time `` on linux: + `window_backend.cpp` includes the header **unconditionally** (line 3) and the header guards + its X11 block only on `__linux__ && !__ANDROID__`. Resolution path: the transitive + `compat.glfw → compat.x11` dep chain (dep `include_dirs` propagate to consumers — the same + propagation the glib `private_include_dirs` pairing exists to suppress). Verified by the + build, not assumed — see below. +- `ime_bridge.c` grows a third arm, `#elif defined(__linux__) && + defined(EUI_GLFW_X11_IME_POSITION)`, the X11 IME candidate-follows-caret fix. The arm calls + `glfwSetX11InputMethodCursorPos`, a function upstream's `scripts/patch_glfw_x11_ime.cmake` + **adds to its bundled glfw** (`3rd/dependencies.cmake` now rewrites the bundled target's + sources at configure time). The index builds `compat.glfw`, unpatched upstream 3.4 — the + define is never set here, the arm is inert, and our linux IME keeps the 0.6.0 `#else` stub. + Enabling the fix would mean patching `compat.glfw`, out of scope for a version bump. +- `3rd/dependencies.cmake` also tightens `find_package(glfw3 3.4)` — applies to upstream's + bundled-vs-system glfw choice only; we pin `compat.glfw` 3.4. +- The rest is header/app-level — with ONE exception, found by testing rather + than reading: in the SDL2 backend, `beginWindowMove` / `beginWindowResize` + call `sendX11MoveResizeForWindow` **unguarded**, but the SDL2 branch's + declaration sits inside `#if __linux__ && … && defined(SDL_VIDEO_DRIVER_X11)` + (window_backend.cpp:223-298) — unlike the GLFW branch's copy (:608), which + upstream hoisted out of the guard with its own `#else return false`. Three + builds fail, all measured: + - linux + `compat.sdl2` — its config is dummy+offscreen only, so the macro is + absent (local eui-neo-sdl2 run): `'sendX11MoveResizeForWindow' was not + declared` at :571. + - **macOS and Windows** (PR #531 CI legs): `use of undeclared identifier` at + :567/:571 — `__linux__` is false there, so NO macro can wake the + declaration; it does not exist at all. Upstream's own CI builds the SDL2 + backend on Linux only and never sees this. The other SDL2 X11 helper, + `x11ContentScale`, is safe — its call site is inside the same triple guard + as its body. +- `apps/vcd_viewer` removed, new upstream tests/docs — none reach the lib or this index. + +## Descriptor changes (`pkgs/e/compat.eui-neo.lua`) + +- `xpm.["0.6.1"]`: plain-string GLOBAL url (no CN mirror), sha256 above. +- **One functional change**, in `generated_files["mcpp_generated/mcpp_eui_backends.h"]`, + split by platform, active only when `MCPP_FEATURE_SDL2` is on (the header is already + force-included into every one of this package's TUs): + - **linux**: `#define SDL_VIDEO_DRIVER_X11 1` wakes the guarded declaration. It can + never fire at runtime — compat.sdl2 has no X11 driver, so no SDL window is ever an + X11 window, `SDL_GetWindowWMInfo` never reports `SDL_SYSWM_X11`, and every delegation + returns false (upstream's "unavailable → report failure" contract). The + `` / `` it pulls resolve through the same transitive + `compat.glfw → compat.x11` chain the GLFW leg already uses. + - **macOS / Windows**: `__linux__` is false, so no macro can wake the block — instead a + `core::window` stub `sendX11MoveResizeForWindow(void*, int)` returning false, guarded + by `defined(__cplusplus)` so force-included C TUs (`tray_bridge.c`, `native_bridge.c`) + do not hit `unknown type name 'namespace'`. That is + the fallback upstream's GLFW branch (:608) and its own release notes both describe + ("on non-X11 platforms the delegation returns false and callers keep their + programmatic fallback"). `Handle` is `void*` in the SDL2 branch (`window_types.h`), + so the signature matches the unguarded call sites exactly, and the real linux-only + definition cannot exist on this branch of the `#if`, so there is no redefinition. + - Both halves stay package-private; neither may become an interface define — consumers + would inherit the lie on every platform (on macOS, SDL_syswm.h would then demand X11 + headers consumers don't have). The stub branch is additionally syntax-checked against + the exact call-site pattern in both C and C++ modes. +- No source list, dep, feature-shape or flag changes otherwise. + +## Test members + +All seven `tests/examples/eui-neo*` members bumped to `0.6.1` (from 0.6.0). No test source +changes: the 0.6.1 surface this workspace exercises (backends, app-mains, tray, markdown, +network, window) is unchanged in shape; the new API (transparent framebuffer, delegated +move/resize, onStart/appId) is window-lifecycle surface that needs a compositor and is not +assertable headless. + +## Verification + +Locally, mcpp 2026.10.1.2 (same as CI `MCPP_VERSION`), Linux x86_64, `MCPP_INDEX_MIRROR=GLOBAL`: + +- Index lint: `check_mirror_urls`, `check_package_name`, `check_reserved_namespace`, + `check_cross_package_refs`, `check_platform_version_parity`, `check_duplicate_versions` — + all clean; `mcpp xpkg parse` accepts the descriptor. +- First pass: six of seven members green, **eui-neo-sdl2 failed to compile** — + `'sendX11MoveResizeForWindow' was not declared in this scope` + (window_backend.cpp:571), the upstream guard asymmetry described above. That is what + produced the `SDL_VIDEO_DRIVER_X11` shim; it is measured, not hypothetical. +- Second pass, with the shim: all seven members `mcpp test` green: eui-neo (headless), + eui-neo-window, eui-neo-app-main, eui-neo-markdown, eui-neo-sdl2 (sdl2+network), + eui-neo-vulkan, eui-neo-tray. +- **PR #531 CI then failed the macOS and Windows workspace legs**: + - First CI revision: `use of undeclared identifier 'sendX11MoveResizeForWindow'` + at :567/:571. Same root cause, worse shape: off linux the declaration does not + exist at all, so the linux macro shim did not apply. + - Second CI revision: the `core::window` stub was introduced, but because + `mcpp_eui_backends.h` is force-included into all package TUs via `cflags`, C TUs + (`tray_bridge.c`, `native_bridge.c`) failed with `error: unknown type name 'namespace'`. + - Third revision: guarded the stub with `defined(__cplusplus)`, ensuring C TUs + bypass the C++ namespace block while C++ TUs retain the fallback declaration. +- `compile_commands.json` (fresh, from the passing builds): the 0.6.1 + `window_backend.cpp` TU carries `compat-x-x11/1.8.13/include` via the transitive + `compat.glfw → compat.x11` chain — `` resolves with no direct dep added. + The shim reaches the sdl2 TU through the same force-include + (`-include mcpp_eui_backends.h`) every eui-neo TU already carries — the macro lives in + the header, so it never appears as a `-D` on the compile line; the evidence it is in + effect is the failed-then-passing eui-neo-sdl2 compile across the two runs. + +CI status: linux legs (default + llvm×4), lint, build, select, measure, timings, +mirror-cn-reachable and graphics-side-effects passed on earlier revisions; macOS and +Windows failed on the SDL2 member only due to the unguarded C TU namespace in the stub, +which the `__cplusplus` guard (this revision) resolves. diff --git a/pkgs/e/compat.eui-neo.lua b/pkgs/e/compat.eui-neo.lua index dcf3533d..a5d1c28a 100644 --- a/pkgs/e/compat.eui-neo.lua +++ b/pkgs/e/compat.eui-neo.lua @@ -17,7 +17,7 @@ -- them as `"3rd/stb_image.h"` — except miniaudio, which audio.cpp includes -- BARE; see the 0.6.0 note below. -- --- The build recipe below tracks upstream `CMakeLists.txt` (v0.6.0): CORE_SOURCES +-- The build recipe below tracks upstream `CMakeLists.txt` (v0.6.1): CORE_SOURCES -- plus the OpenGL backend and, for the glfw window backend, `ime_bridge.c`. -- 0.5.5 grew a Shadertoy subsystem: render_backend.h and include/eui/types.h now -- include core/render/shadertoy.h unconditionally, and opengl_backend.cpp calls @@ -80,8 +80,59 @@ -- of tray_bridge.c (diff vs 0.5.9: comments + EOF newline only). `3rd/`, -- deps and the backend/app-main source lists are unchanged. -- +-- 0.6.1: CORE_SOURCES and VULKAN_SOURCES are byte-identical to 0.6.0, so +-- the lib's source list, deps, features and flags carry over unchanged. +-- The release is window lifecycle + component fixes, and two of its pieces +-- deserve notes because they LOOK like descriptor work and are not: +-- * `core/window/x11_moveresize.h` is NEW but header-only: EWMH +-- _NET_WM_MOVERESIZE move/resize delegation, with libX11 dlopen'd at +-- RUNTIME (no link-time X11 dependency — upstream says so verbatim in +-- the header, and -ldl is already on the linux ldflags for glad). +-- It DOES add a compile-time `` on linux, because +-- window_backend.cpp includes it UNCONDITIONALLY and the header guards +-- its X11 block only on `__linux__ && !__ANDROID__`. That include +-- resolves through the transitive compat.glfw → compat.x11 dep chain +-- (verified by the 0.6.1 build of the eui-neo member — do not add a +-- direct compat.x11 dep without measuring a failure first). +-- * ime_bridge.c grows a third arm, +-- `#elif defined(__linux__) && defined(EUI_GLFW_X11_IME_POSITION)`, +-- implementing the X11 IME candidate-window-follows-caret fix. The arm +-- calls glfwSetX11InputMethodCursorPos, a function upstream's +-- `scripts/patch_glfw_x11_ime.cmake` ADDS TO ITS BUNDLED glfw — the +-- index builds compat.glfw, which is unpatched upstream 3.4, so the +-- define is never set here and the arm is inert; our linux IME keeps +-- the `#else` stub exactly as 0.6.0 did. Enabling the fix would +-- require patching compat.glfw, which is out of scope for a bump. +-- * ⚠️ THE ONE REAL DESCRIPTOR CHANGE. In the SDL2 backend, +-- window_backend.cpp calls sendX11MoveResizeForWindow from +-- beginWindowMove/beginWindowResize UNGUARDED, but the SDL2 branch's +-- declaration sits INSIDE `#if __linux__ && … && +-- defined(SDL_VIDEO_DRIVER_X11)` (:223-298) — unlike the GLFW branch's +-- copy (:608), which upstream hoisted out of the guard with its own +-- `#else return false`. Three builds fail (all measured): linux + +-- compat.sdl2 (dummy+offscreen config, macro absent — local eui-neo-sdl2 +-- run), macOS and Windows (`__linux__` false, so NO macro can wake the +-- declaration — both CI legs of PR #531; upstream's own CI builds the +-- SDL2 backend on Linux only). The fix is one package-private shim in +-- mcpp_eui_backends.h, split by platform: on linux define +-- SDL_VIDEO_DRIVER_X11 for this package's own TUs, waking the guarded +-- block (it can never fire at runtime — compat.sdl2 has no X11 driver to +-- produce an X11 window, so every delegation returns false); elsewhere +-- supply the core::window stub the GLFW branch and upstream's release +-- notes both describe ("on non-X11 platforms the delegation returns +-- false and callers keep their programmatic fallback"), guarded by +-- `__cplusplus` so C TUs (tray_bridge.c, native_bridge.c) don't choke +-- on `namespace`. It must NOT be an interface define: consumers would +-- inherit the lie on every platform. +-- The rest is header/app-level: transparent framebuffer +-- (DslAppConfig::transparent / framebufferTransparent), beginWindowMove / +-- beginWindowResize (the consumers of x11_moveresize.h), DslAppConfig +-- onStart()/appId(), GLFW 3.3/3.4 macro guards (we pin 3.4), platform.cpp +-- dialog-diagnostics capture (mkstemp, POSIX-guarded), dropdown/slider +-- z-order and OpenGL pixel-unpack fixes. No `3rd/` pin moves. +-- -- All `mcpp` paths are GLOBS relative to the verdir; the leading `*/` absorbs --- the GitHub tarball's `EUI-NEO-0.6.0/` wrap layer. +-- the GitHub tarball's `EUI-NEO-0.6.1/` wrap layer. package = { spec = "1", namespace = "compat", @@ -187,6 +238,11 @@ package = { url = "https://github.com/sudoevolve/EUI-NEO/archive/refs/tags/v0.6.0.tar.gz", sha256 = "11d0725bcc6f16abbbea6052b58c6949008cf78ceaa1645002ba1b3abf9772a1", }, + -- 0.6.1: see the linux block — plain-string GLOBAL, no CN mirror. + ["0.6.1"] = { + url = "https://github.com/sudoevolve/EUI-NEO/archive/refs/tags/v0.6.1.tar.gz", + sha256 = "cd0bd6bd437177db097da146fc20f4b8b01c70d0db561a6f8e26baa26dbbbf5f", + }, }, macosx = { ["0.5.3"] = { @@ -234,6 +290,11 @@ package = { url = "https://github.com/sudoevolve/EUI-NEO/archive/refs/tags/v0.6.0.tar.gz", sha256 = "11d0725bcc6f16abbbea6052b58c6949008cf78ceaa1645002ba1b3abf9772a1", }, + -- 0.6.1: see the linux block — plain-string GLOBAL, no CN mirror. + ["0.6.1"] = { + url = "https://github.com/sudoevolve/EUI-NEO/archive/refs/tags/v0.6.1.tar.gz", + sha256 = "cd0bd6bd437177db097da146fc20f4b8b01c70d0db561a6f8e26baa26dbbbf5f", + }, }, windows = { ["0.5.3"] = { @@ -281,6 +342,11 @@ package = { url = "https://github.com/sudoevolve/EUI-NEO/archive/refs/tags/v0.6.0.tar.gz", sha256 = "11d0725bcc6f16abbbea6052b58c6949008cf78ceaa1645002ba1b3abf9772a1", }, + -- 0.6.1: see the linux block — plain-string GLOBAL, no CN mirror. + ["0.6.1"] = { + url = "https://github.com/sudoevolve/EUI-NEO/archive/refs/tags/v0.6.1.tar.gz", + sha256 = "cd0bd6bd437177db097da146fc20f4b8b01c70d0db561a6f8e26baa26dbbbf5f", + }, }, }, @@ -340,6 +406,49 @@ package = { * the SDL2 define, which is how upstream spells it too). */ #if defined(MCPP_FEATURE_SDL2) # define EUI_WINDOW_BACKEND_SDL2 1 +/* 0.6.1, SDL2 backend only: in window_backend.cpp upstream hoists the GLFW + * branch's sendX11MoveResizeForWindow OUT of any platform guard (the :608 + * definition carries its own `#else return false`), but the SDL2 branch's + * copy sits INSIDE `#if __linux__ && !__ANDROID__ && + * defined(SDL_VIDEO_DRIVER_X11)` (:223-298) — while beginWindowMove / + * beginWindowResize call it UNGUARDED (:567/:571). Three builds fail with + * 'sendX11MoveResizeForWindow' not declared, all measured: + * + * * linux + compat.sdl2 — its linux config is dummy+offscreen only, so + * SDL_VIDEO_DRIVER_X11 is absent (eui-neo-sdl2 member, local). Wake the + * guarded block by defining the macro for THIS PACKAGE'S OWN TUs. It + * can never fire at runtime: no SDL window is ever an X11 window under + * compat.sdl2, so SDL_GetWindowWMInfo never reports SDL_SYSWM_X11 and + * every delegation returns false — upstream's own "unavailable → + * report failure" contract. The / it + * pulls resolve through the same transitive compat.glfw → compat.x11 + * chain the GLFW leg already relies on. + * + * Both halves must NOT become interface defines — consumers would inherit + * the lie on every platform (on macOS, SDL_syswm.h would then demand X11 + * headers consumers do not have). */ +# if defined(__linux__) && !defined(__ANDROID__) +# define SDL_VIDEO_DRIVER_X11 1 +# elif defined(__cplusplus) +/* macOS / Windows: `__linux__` is false, so no macro can wake the guarded + * declaration — upstream's own CI builds the SDL2 backend on Linux only and + * never sees it (measured on both CI legs: use of undeclared identifier at + * :567/:571). Supply the fallback upstream's GLFW branch and its release + * notes both describe — "on non-X11 platforms the delegation returns false + * and callers keep their programmatic fallback" — as a core::window stub. + * Handle is void* in the SDL2 branch (window_types.h), so the signature + * matches exactly, and the later real definition cannot exist on this branch + * of the #if (it is linux-only), so there is no redefinition. Guarded by + * __cplusplus because mcpp_eui_backends.h is force-included into the package's + * C TUs (tray_bridge.c, native_bridge.c) as well as its C++ ones. */ +namespace core::window { +inline bool sendX11MoveResizeForWindow(void* window, int direction) { + (void)window; + (void)direction; + return false; +} +} +# endif #endif ]==], ["mcpp_generated/eui_neo_platform_tu.cpp"] = [==[ diff --git a/tests/examples/eui-neo-app-main/mcpp.toml b/tests/examples/eui-neo-app-main/mcpp.toml index 01438d27..517297f2 100644 --- a/tests/examples/eui-neo-app-main/mcpp.toml +++ b/tests/examples/eui-neo-app-main/mcpp.toml @@ -30,4 +30,4 @@ name = "eui-neo-app-main-tests" version = "0.1.0" [dependencies.compat] -eui-neo = { version = "0.6.0", features = ["app-main"] } +eui-neo = { version = "0.6.1", features = ["app-main"] } diff --git a/tests/examples/eui-neo-markdown/mcpp.toml b/tests/examples/eui-neo-markdown/mcpp.toml index 1f93b09a..908eac45 100644 --- a/tests/examples/eui-neo-markdown/mcpp.toml +++ b/tests/examples/eui-neo-markdown/mcpp.toml @@ -7,4 +7,4 @@ version = "0.1.0" # what switches components/markdown.h from its fallback to the real parser. [dependencies.compat] -eui-neo = { version = "0.6.0", features = ["markdown"] } +eui-neo = { version = "0.6.1", features = ["markdown"] } diff --git a/tests/examples/eui-neo-sdl2/mcpp.toml b/tests/examples/eui-neo-sdl2/mcpp.toml index c867f4c1..78f0fb81 100644 --- a/tests/examples/eui-neo-sdl2/mcpp.toml +++ b/tests/examples/eui-neo-sdl2/mcpp.toml @@ -7,4 +7,4 @@ version = "0.1.0" # into a real libcurl-backed implementation. The render backend stays OpenGL, # unnamed — naming a feature no longer costs you the defaults. [dependencies.compat] -eui-neo = { version = "0.6.0", features = ["sdl2", "network"] } +eui-neo = { version = "0.6.1", features = ["sdl2", "network"] } diff --git a/tests/examples/eui-neo-tray/mcpp.toml b/tests/examples/eui-neo-tray/mcpp.toml index 7bcaf11b..261d6247 100644 --- a/tests/examples/eui-neo-tray/mcpp.toml +++ b/tests/examples/eui-neo-tray/mcpp.toml @@ -25,4 +25,4 @@ name = "eui-neo-tray-tests" version = "0.1.0" [dependencies.compat] -eui-neo = "0.6.0" +eui-neo = "0.6.1" diff --git a/tests/examples/eui-neo-vulkan/mcpp.toml b/tests/examples/eui-neo-vulkan/mcpp.toml index 87caf368..7b19bb5b 100644 --- a/tests/examples/eui-neo-vulkan/mcpp.toml +++ b/tests/examples/eui-neo-vulkan/mcpp.toml @@ -6,7 +6,7 @@ version = "0.1.0" # package resolves the exclusive choice in its own preprocessor from the # MCPP_FEATURE_* flags. The window backend stays GLFW, unnamed. [dependencies.compat] -eui-neo = { version = "0.6.0", features = ["vulkan"] } +eui-neo = { version = "0.6.1", features = ["vulkan"] } [build] cxxflags = ["-DHAVE_EUI_VULKAN=1"] diff --git a/tests/examples/eui-neo-window/mcpp.toml b/tests/examples/eui-neo-window/mcpp.toml index eaec5601..83d191c9 100644 --- a/tests/examples/eui-neo-window/mcpp.toml +++ b/tests/examples/eui-neo-window/mcpp.toml @@ -34,4 +34,4 @@ name = "eui-neo-window-tests" version = "0.1.0" [dependencies.compat] -eui-neo = "0.6.0" +eui-neo = "0.6.1" diff --git a/tests/examples/eui-neo/mcpp.toml b/tests/examples/eui-neo/mcpp.toml index 716849cf..39bffba2 100644 --- a/tests/examples/eui-neo/mcpp.toml +++ b/tests/examples/eui-neo/mcpp.toml @@ -3,4 +3,4 @@ name = "eui-neo-tests" version = "0.1.0" [dependencies.compat] -eui-neo = "0.6.0" +eui-neo = "0.6.1"