From 423a6da31257b6cbe0797deb4304deb19cb2efb1 Mon Sep 17 00:00:00 2001 From: sunrisepeak Date: Sun, 30 Aug 2026 18:29:28 +0800 Subject: [PATCH 1/4] =?UTF-8?q?feat(libinput):=20=E8=AE=A9=E8=BE=93?= =?UTF-8?q?=E5=85=A5=E9=93=BE=E7=9A=84=E9=A1=B6=E7=AB=AF=E7=AC=AC=E4=B8=80?= =?UTF-8?q?=E6=AC=A1=E7=9C=9F=E7=9A=84=E8=A2=AB=E7=BC=96=E8=AF=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit compat.libinput 随 #294 进了索引,而它从未被编译过——没有测试成员消费它, 而没人编译的包不会编译失败。加上 tests/examples/libinput 之后一次构建暴露出 四类问题,都是"上游用 meson,我们不用"才会有的: 1. 缺 libinput-version.h。meson 从 .h.in 生成,libinput-private.h:45 无条件 include 它,所以 40 个源文件全挂。补成 generated_files。 2. config.h 只写了一半。HTTP_DOC_LINK / LIBINPUT_QUIRKS_OVERRIDE_FILE / LIBINPUT_PLUGIN_{LIB,ETC}DIR / HAVE_VERSIONSORT / HAVE_MTDEV 都缺。 HAVE_VERSIONSORT 尤其关键:不定义它,libinput-versionsort.h 会给出自己的 static strverscmp,而 glibc 已经 extern 声明过——是硬错误不是遮蔽。 3. include_dirs 少了包根。全树只有 libinput-plugin-mouse-wheel-lowres.c:31 写 `#include "src/evdev-frame.h"`,上游因为从项目根编译而免费拿到这个拼法。 4. typeof。util-mem.h:180 的 (typeof(*ptr_))_steal(ptr_) 是 GNU 关键字, -std=c11 下被当成未声明函数调用,cast 塌成 int,伤害落在十几个根本没提 typeof 的文件里,报成 -Wint-conversion。 c_standard = "gnu11" 不是解法:mcpp 收下这个字符串,仍然发 -std=c11。 这次是实测的——设过 gnu11,上面这些错误原样还在。所以走 -Dtypeof=__typeof__。 测试成员断言的是四包交接处(libudev 起 context、udev 枚举 seat、dispatch、 可 poll 的 fd),不断言能打开 /dev/input/event*——那需要权限,设 MCPP_RUN_INPUT_DEVICES=1 才要求。6 项全过。 顺带把 quirks 那段注释改准:LIBINPUT_QUIRKS_DIR 是有环境变量出口的 (libinput.c:1911),和 GBM_BACKENDS_PATH 同一形状,缺的是提供方而不是机制。 --- mcpp.toml | 1 + pkgs/c/compat.libinput.lua | 120 ++++++++++++++++-- tests/examples/libinput/mcpp.toml | 22 ++++ .../libxkbcommon/tests/libxkbcommon.cpp | 43 +++++++ 4 files changed, 178 insertions(+), 8 deletions(-) create mode 100644 tests/examples/libinput/mcpp.toml diff --git a/mcpp.toml b/mcpp.toml index 0f4aa13..c94aeef 100644 --- a/mcpp.toml +++ b/mcpp.toml @@ -89,6 +89,7 @@ members = [ "tests/examples/egl", "tests/examples/gl", "tests/examples/libevdev", + "tests/examples/libinput", "tests/examples/libseat", "tests/examples/libudev", "tests/examples/libxkbcommon", diff --git a/pkgs/c/compat.libinput.lua b/pkgs/c/compat.libinput.lua index ada2e39..df1ac88 100644 --- a/pkgs/c/compat.libinput.lua +++ b/pkgs/c/compat.libinput.lua @@ -31,13 +31,25 @@ -- way. Nothing in this index provides it, and without it libinput falls back -- to generic tablet handling rather than failing. -- --- The quirks database (`quirks.c`) reads `.quirks` files at runtime from a --- directory compiled in as `LIBINPUT_QUIRKS_DIR`. That path is EMPTY here for --- the same reason libgbm's backend path and libxkbcommon's config root are: --- upstream's default points into the build prefix, which after relocation is --- the HOST's dataset. Empty means devices get libinput's built-in defaults --- rather than a host machine's model quirks — correct behaviour, one fewer --- silent host edge. +-- The quirks database (`quirks.c`) reads `.quirks` files at runtime — model +-- specific tuning like a touchpad's pressure range. `libinput.c:1911` takes the +-- directory from `getenv("LIBINPUT_QUIRKS_DIR")` and falls back to a +-- compiled-in path, and the compiled-in path is EMPTY here for the same reason +-- libgbm's backend path and libxkbcommon's config root are: upstream's default +-- points into the build prefix, which after relocation is the HOST's dataset. +-- +-- So this is a WIRING question, not a dead end — the same shape as +-- GBM_BACKENDS_PATH, down to the environment variable. What is missing is a +-- provider: the `.quirks` files ship inside libinput's own tarball, but +-- mcpp-index has no way for a package to publish a data DIRECTORY, so nothing +-- currently fills the variable. Until something does, libinput logs +-- +-- failed to find data files ... will negatively affect device behavior +-- +-- and runs on its built-in defaults. That is a real degradation and it is +-- graceful: enumeration, events and gestures all work — what is lost is +-- per-model tuning. Verified in tests/examples/libinput, which passes with the +-- message present. package = { spec = "1", namespace = "compat", @@ -62,9 +74,20 @@ package = { mcpp = { language = "c++23", import_std = false, + -- Upstream asks for `c_std=gnu99` and means it — see the `typeof` + -- note in cflags. `c_standard = "gnu11"` was tried here first and is + -- NOT the fix: mcpp accepts the string and still emits `-std=c11`, so + -- the descriptor would claim a dialect the compiler never sees. c_standard = "c11", - include_dirs = { "*/src", "*/include", "mcpp_generated" }, + -- `"*"` is the package ROOT, and it is here for exactly one file: + -- `libinput-plugin-mouse-wheel-lowres.c:31` writes + -- `#include "src/evdev-frame.h"` while every other source in the tree + -- writes `#include "evdev-frame.h"`. Upstream gets both spellings for + -- free because meson compiles from the project root; a package that + -- only puts `*/src` on the search path resolves 39 files and fails the + -- fortieth. + include_dirs = { "*", "*/src", "*/include", "mcpp_generated" }, generated_files = { ["mcpp_generated/config.h"] = [==[ @@ -82,10 +105,70 @@ package = { would add a dependency this package does not need to do its job. */ #define LIBINPUT_QUIRKS_DIR "" #define LIBINPUT_QUIRKS_SRCDIR "" +/* The user's quirks override, `/libinput/local-overrides.quirks` + upstream. Empty for the reason above: relocated, it names the HOST's file. */ +#define LIBINPUT_QUIRKS_OVERRIDE_FILE "" + +/* Plugin search paths, both EMPTY and both required to exist: + `libinput_plugin_system_append_default_paths` (libinput-plugin.c:387) names + them unconditionally, outside any HAVE_PLUGINS guard. Empty paths append + nothing, which is the behaviour this package wants — see the header comment + on why the Lua plugin system is off. */ +#define LIBINPUT_PLUGIN_LIBDIR "" +#define LIBINPUT_PLUGIN_ETCDIR "" + +/* Printed into log messages that point a user at the documentation for the + behaviour being reported. meson builds it from the version: micro < 90 means + a release, so the URL names this release rather than `latest`. */ +#define HTTP_DOC_LINK "https://wayland.freedesktop.org/libinput/doc/1.31.3" + #define HAVE_LIBEVDEV_DISABLE_PROPERTY 1 #define HAVE_MEMFD_CREATE 1 #define HAVE_LOCALE_H 1 #define HAVE_STRERRORNAME_NP 1 +#define HAVE_SIGABBREV_NP 1 +#define HAVE_PIDFD_OPEN 1 + +/* glibc has versionsort(3), and saying so is load-bearing rather than + cosmetic: `libinput-versionsort.h` provides its OWN static fallback when + this is unset, and a static definition of a name glibc already declared + extern is a hard error, not a shadow. */ +#define HAVE_VERSIONSORT 1 + +/* mtdev is a declared dependency of this package, so the plugin that uses it + is compiled unconditionally (see `libinput-plugin-mtdev.c` in sources). */ +#define HAVE_MTDEV 1 + +/* HAVE_C23_AUTO is deliberately ABSENT. meson probes for it by compiling + `auto foo = gmtime(NULL);`, which needs C23; this package builds as gnu11, + so the probe would fail there too and upstream's non-auto path is correct. */ +#endif +]==], + + -- meson's `src/libinput-version.h.in`, substituted for 1.31.3. + -- + -- `libinput-private.h:45` includes it unconditionally, so every one + -- of the 40 sources below needs it — this is not an optional + -- convenience header. It went missing in the first version of this + -- descriptor and NOTHING CAUGHT IT: the package validated, entered + -- the index and shipped, because no test member consumed it and a + -- package nobody compiles cannot fail to compile. The + -- `tests/examples/libinput` member exists so that stays true only + -- until someone builds it — which is what found this. + -- + -- The three numbers are the version in `xpm` above, split. They are + -- the package's public version macros, so a consumer doing + -- `#if LIBINPUT_VERSION_MAJOR >= 1` gets a real answer; leaving + -- them at 0 would compile just as well and lie. + ["mcpp_generated/libinput-version.h"] = [==[ +#ifndef LIBINPUT_VERSION_H +#define LIBINPUT_VERSION_H + +#define LIBINPUT_VERSION_MAJOR 1 +#define LIBINPUT_VERSION_MINOR 31 +#define LIBINPUT_VERSION_MICRO 3 +#define LIBINPUT_VERSION "1.31.3" + #endif ]==], }, @@ -144,6 +227,27 @@ package = { cflags = { "-D_GNU_SOURCE", "-DHAVE_CONFIG_H", + + -- The GNU `typeof` keyword, supplied by hand. + -- + -- `util-mem.h:180` is `(typeof(*ptr_))_steal(ptr_)` — the cast that + -- makes every `steal()` in the tree type-safe. Bare `typeof` is a + -- GNU extension (and C23's spelling); ISO C11 has only + -- `__typeof__`. Under `-std=c11` GCC parses `typeof(...)` as a call + -- to an undeclared function, the cast collapses to `int`, and the + -- damage lands as `-Wint-conversion` errors in a dozen unrelated + -- files that never mention typeof. + -- + -- This is a `-D` rather than `c_standard = "gnu11"` because the + -- gnu dialects do not reach the compiler: mcpp accepts the string + -- and still emits `-std=c11`. Measured, not assumed — gnu11 was + -- set here and these exact errors survived it. + -- + -- Safe because `__typeof__` IS `typeof`, always available in any + -- dialect, and nothing can be named `typeof` in code that expects + -- gnu99 anyway. + "-Dtypeof=__typeof__", + "-fPIC", }, diff --git a/tests/examples/libinput/mcpp.toml b/tests/examples/libinput/mcpp.toml new file mode 100644 index 0000000..2e0c7fe --- /dev/null +++ b/tests/examples/libinput/mcpp.toml @@ -0,0 +1,22 @@ +# libinput test project — the top of the input chain. +# +# NO `[indices]` OF ITS OWN, and that is the interesting part. +# +# This member needs packages from TWO namespaces: `compat.libinput` (and the +# `compat.libudev` / `compat.mtdev` it depends on) from this checkout, and +# `freedesktop.libevdev` which libinput also links. A member-level `[indices]` +# REPLACES the root's rather than merging, and one path can only be registered +# under one namespace — so declaring `freedesktop = { path = "../../.." }` here +# would make `compat.libinput` resolve against the published index instead. +# +# Inheriting the root's `compat = { path = "." }` is what works: the compat +# packages come from the checkout, and `freedesktop.libevdev` resolves from the +# PUBLISHED index — which is correct, because it is published. Same arrangement +# tests/examples/asio-ssl relies on for the opposite reason. +[package] +name = "libinput-tests" +version = "0.1.0" +standard = "c++23" + +[target.'cfg(linux)'.dependencies.compat] +libinput = "1.31.3" diff --git a/tests/examples/libxkbcommon/tests/libxkbcommon.cpp b/tests/examples/libxkbcommon/tests/libxkbcommon.cpp index 87d24c9..644bd60 100644 --- a/tests/examples/libxkbcommon/tests/libxkbcommon.cpp +++ b/tests/examples/libxkbcommon/tests/libxkbcommon.cpp @@ -16,6 +16,7 @@ #include #include +#include namespace { @@ -103,6 +104,48 @@ int main() check(xkb_keysym_from_name("Escape", XKB_KEYSYM_NO_FLAGS) == XKB_KEY_Escape, "xkb_keysym_from_name resolves a name to its keysym"); + // ── 6. RMLVO, if a dataset is reachable ────────────────────────────── + // + // This is the OTHER half of libxkbcommon, and the half this package + // deliberately cannot satisfy on its own: `xkb_keymap_new_from_names` + // takes rules/model/layout/variant/options and reads them out of + // xkeyboard-config's data tree. DFLT_XKB_CONFIG_ROOT is compiled in EMPTY + // here on purpose, so the path has to come from the environment — + // XKB_CONFIG_ROOT, which is what an ecosystem package declares. + // + // Reported rather than asserted when unset: a machine with no dataset is + // not a defect in this package. When it IS set, the compile must succeed, + // because then the dataset is the thing under test. + { + const char *root = std::getenv("XKB_CONFIG_ROOT"); + std::printf("\n XKB_CONFIG_ROOT = %s\n", + root ? root : "(unset — the ecosystem declares it)"); + if (root != nullptr) { + xkb_context *c2 = xkb_context_new(XKB_CONTEXT_NO_FLAGS); + xkb_rule_names names{}; + names.rules = "evdev"; + names.model = "pc105"; + names.layout = "us"; + xkb_keymap *k2 = c2 ? xkb_keymap_new_from_names( + c2, &names, XKB_KEYMAP_COMPILE_NO_FLAGS) : nullptr; + check(k2 != nullptr, + "xkb_keymap_new_from_names(evdev/pc105/us) against that root"); + if (k2 != nullptr) { + xkb_state *s2 = xkb_state_new(k2); + if (s2 != nullptr) { + char b[16] = {0}; + xkb_state_key_get_utf8(s2, 24, b, sizeof b); + std::printf(" real layout: keycode 24 -> \"%s\"\n", b); + check(b[0] == 'q', + "…and the real us layout maps keycode 24 to \"q\""); + xkb_state_unref(s2); + } + xkb_keymap_unref(k2); + } + if (c2) xkb_context_unref(c2); + } + } + xkb_keymap_unref(km); xkb_context_unref(ctx); From f713d18d36c5671795392546fecb6f2659017a47 Mon Sep 17 00:00:00 2001 From: sunrisepeak Date: Sun, 30 Aug 2026 18:40:22 +0800 Subject: [PATCH 2/4] =?UTF-8?q?docs:=20=E8=AE=B0=E5=BD=95=20xkeyboard-conf?= =?UTF-8?q?ig=20=E8=B7=A8=E7=B4=A2=E5=BC=95=E9=97=AD=E7=8E=AF=E4=B8=8E=20l?= =?UTF-8?q?ibinput=20=E7=9A=84=E5=9B=9B=E4=B8=AA=20bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit §10.9.1 xkeyboard-config 已落地(xim-pkgindex#732),含实现中改的两处 discovery 形状:XKB_CONFIG_ROOT 是标量所以用 op=set(表里第一个非列表项),以及 declare_xkb —— 声明变量和放置内容是两件事,只声明的那一版让变量指向不存在的目录。 §10.9.2 新增:libinput quirks 是同一形状的第三处。之前注释里写的「编译期路径」 不准确,libinput.c:1911 是 getenv 优先。所以不是死路,是缺提供方。 §10.10 G5 从「待接上」改为已做,并把测试成员抓出的四个 bug 列出来——它们全都是 「包进了索引但从没被编译过」造成的。另加一张发现变量总表,标出哪两行仍是空的。 --- ...26-08-30-graphics-stack-coverage-design.md | 112 ++++++++++++++++-- 1 file changed, 105 insertions(+), 7 deletions(-) diff --git a/.agents/docs/2026-08-30-graphics-stack-coverage-design.md b/.agents/docs/2026-08-30-graphics-stack-coverage-design.md index 0cc4ced..bfd15ab 100644 --- a/.agents/docs/2026-08-30-graphics-stack-coverage-design.md +++ b/.agents/docs/2026-08-30-graphics-stack-coverage-design.md @@ -600,17 +600,115 @@ share/{bash-completion,man}` —— **不带 xkb 数据**。所以 `XKB_CONFIG_R ⚠ 顺带一提:一个**只需要 `xkb_keymap_new_from_string`** 的合成器不需要这份数据 —— 那正是它从客户端收到 keymap 的路径,也是本索引测试跑通 parser 的方式。 +#### 10.9.1 已落地(openxlings/xim-pkgindex#732) + +上面的结论已实现,并在实现过程中改了 discovery 层的两处形状: + +**`XKB_CONFIG_ROOT` 是表里第一个非列表项。** DISCOVERY 的另外四行都是冒号分隔的搜索 +路径,`prepend` 在那里既正确又无损(而且必须是 prepend:一个提供方 `set` 会盖掉另一 +个,NVIDIA vendor 目录消失就是这么来的)。`XKB_CONFIG_ROOT` 是**标量** —— libxkbcommon +读一次当一个目录用,`prepend` 上第二个提供方就变成 `dirA:dirB`,一个不存在的路径,而 +报错只会说「keymap 编译失败」。所以给 DISCOVERY 行加了可选的 `op`,默认仍是 `prepend`, +这一行写 `set`。 + +> 这与记忆里那条 `xvm envs 是 PATH 式合并`(标量 env 会被冒号拼接)是同一件事的第二次 +> 撞见。第一次的答案是「生成 launcher」;这次因为发现点在 discovery 层内部,所以修在 +> 了机制里。 + +**声明变量 ≠ 放置内容。** 第一版只加了 DISCOVERY 行和 `declare_subos_env` 调用,装完之后: + +``` +XKB_CONFIG_ROOT=[.../subos/eco-2026-8-30-1/share/X11/xkb] +ls: cannot access '.../share/X11/xkb': No such file or directory +``` + +变量在 shell 里读得好好的,指向不存在的目录。补 `graphics.declare_xkb`,与 +`declare_dri` / `declare_gbm` 同形(`xvm.files` 把树放进 subos)。 + +**跨索引闭环已实测** —— mcpp 侧的 `freedesktop.libxkbcommon` 消费 xim 侧的数据集: + +``` +XKB_CONFIG_ROOT = .../subos/eco-2026-8-30-1/share/X11/xkb +xkb_keymap_new_from_names(evdev/pc105/us) against that root ok + real layout: keycode 24 -> "q" +…and the real us layout maps keycode 24 to "q" ok +0 check(s) failed +``` + +消费侧断言写在 `tests/examples/libxkbcommon`,且是**条件式**的:`XKB_CONFIG_ROOT` 未 +设置时只报告,设置了才要求编得出来。没有数据集的机器不是这个包的缺陷。 + +#### 10.9.2 同一形状的第三处:libinput quirks + +写 `compat.libinput` 时把 `LIBINPUT_QUIRKS_DIR` 也编译成空,注释里当时写的是「编译期 +路径,空即用内置默认」。**这句话不准确**:`libinput.c:1911` 是 +`getenv("LIBINPUT_QUIRKS_DIR")` 优先、编译期值兜底 —— 和 `GBM_BACKENDS_PATH` +一模一样的形状。 + +所以这不是死路,是**缺提供方**:`.quirks` 文件就在 libinput 自己的 tarball 里,但 +mcpp-index 没有发布数据目录的机制(与 §10.9 同因)。在有东西填上之前,libinput 打印 + +``` +failed to find data files ... will negatively affect device behavior +``` + +并跑在内置默认上。这是**优雅降级**:枚举、事件、手势都正常,丢的是逐机型调校(比如 +某块触摸板的压力区间)。`tests/examples/libinput` 就是在这条消息存在的情况下全绿的。 + +补法与 xkeyboard-config 完全对称(xim 数据包 + 一行 DISCOVERY),优先级低于布局数据: +布局缺了是**硬失败**,quirks 缺了只是不够贴合。 + ### 10.10 仍未做 - ~~G4b `libxkbcommon`~~ **已做**(fork,bison parser 预生成)。它需要的数据集见 §10.9: 属于生态,不属于这里。 -- ~~G5 `libinput`~~ **描述符已做**;测试成员待本 PR 合并、`freedesktop.libevdev` 发布 - 后接上 —— 它同时需要 `compat.*` 和 `freedesktop.*` 两个 namespace 指向同一个 - checkout,而成员级 `[indices]` 是替换而非合并。 +- ~~G5 `libinput`~~ **已做,并且测试成员一接上就抓出了四个 bug**(#298)。 + 形态问题解决得很朴素:这个成员**不声明 `[indices]`**,继承根的 + `compat = { path = "." }` —— compat 来自 checkout,`freedesktop.libevdev` 来自已发布 + 索引(它确实已发布)。声明 `freedesktop` 反而会让 `compat.libinput` 去查已发布索引。 + + 四个 bug 值得单列,因为它们**全都是"包进了索引但从没被编译过"造成的** —— + 没有测试成员消费它,而没人编译的包不会编译失败(记忆里那条「绿 CI 不等于包被编译」 + 的教科书案例): + + | 问题 | 症状落点 | + |------|---------| + | 缺 `libinput-version.h`(meson 从 `.h.in` 生成) | `libinput-private.h:45` 无条件 include,40 个源文件全挂 | + | `config.h` 只写了一半 | `HTTP_DOC_LINK` / `LIBINPUT_QUIRKS_OVERRIDE_FILE` / `LIBINPUT_PLUGIN_{LIB,ETC}DIR` / `HAVE_VERSIONSORT` / `HAVE_MTDEV` | + | `include_dirs` 少了包根 | 全树只有一个文件写 `#include "src/evdev-frame.h"` | + | `typeof` 是 GNU 关键字 | `-std=c11` 下 cast 塌成 `int`,错误落在十几个没提 typeof 的文件里 | + + 其中两条有普遍意义: + + **`HAVE_VERSIONSORT`** —— 不定义它,`libinput-versionsort.h` 会给出自己的 + `static strverscmp`,而 glibc 已经 `extern` 声明过。这是硬错误,不是遮蔽。 + 「少定义一个 HAVE_ 宏最多退化」的直觉在这里是错的。 + + **`c_standard = "gnu11"` 不生效,这次是实测的** —— mcpp 收下这个字符串,仍然发 + `-std=c11`,那些 typeof 错误原样还在。所以走 `-Dtypeof=__typeof__`。这与记忆里 + 「c_standard 的 gnu 模式被静默忽略」一致,但那条记的是 `_GNU_SOURCE` 类的**库特性 + 宏**;`typeof` 是**语言方言**,`-D_GNU_SOURCE` 对它无效。两者要分开记。 - ~~G6 `libudev` / `libseat`~~ **已做**,而且没有碰 systemd:libudev 用 **libudev-zero**(三个实现里唯一既活着又可独立分发的),libseat 只开 seatd 与 builtin 后端。两者的代价都在描述符里点名了。 -- **xkeyboard-config**:见 §10.9,应进 xim-pkgindex。 - -前两条是普通工作量;G6 是需要决策的。合成器可以在「已有 DRM master」的前提下开发 -(从 TTY 直接启动、或 `SEATD_SOCK`),把 session 管理留到最后。 +- ~~**xkeyboard-config**~~ **已做**(xim-pkgindex#732),见 §10.9.1。跨索引闭环已实测。 +- **libinput quirks 数据**:见 §10.9.2。形状与 xkeyboard-config 对称,优先级更低 —— + 布局缺了是硬失败,quirks 缺了只是不够贴合。**未做**。 + +至此渲染链与输入链都不再有「静默落到宿主」的边: + +| 子系统 | 发现变量 | 提供方 | 状态 | +|--------|---------|--------|------| +| DRI 驱动 | `LIBGL_DRIVERS_PATH` | `xim:mesa` | ✅ | +| EGL vendor | `__EGL_VENDOR_LIBRARY_DIRS` | `xim:mesa` + host-link 哨兵 | ✅ | +| Vulkan ICD | `XDG_DATA_DIRS` / 共享 vendor 目录 | 同上 | ✅ #731 待合 | +| GBM 后端 | `GBM_BACKENDS_PATH` | `xim:mesa` | ✅ | +| 键盘布局 | `XKB_CONFIG_ROOT` | `xim:xkeyboard-config` | ✅ #732 待合 | +| 输入 quirks | `LIBINPUT_QUIRKS_DIR` | *(无)* | ⬜ 优雅降级中 | +| USB 名字库 | `USB_IDS_PATH` | *(无)* | ⬜ 优雅降级中 | + +最后两行是同一类:机制在、提供方缺、缺了只丢锦上添花的东西。**它们缺失时会说出来** +—— 这正是当初把编译期默认值一律留空要换的东西。 + +G6 仍是需要决策的:合成器可以在「已有 DRM master」的前提下开发(从 TTY 直接启动、或 +`SEATD_SOCK`),把 session 管理留到最后。 From cda5632f38aa3183f9914c1798adbb969774168e Mon Sep 17 00:00:00 2001 From: sunrisepeak Date: Sun, 30 Aug 2026 18:45:48 +0800 Subject: [PATCH 3/4] =?UTF-8?q?docs(libinput):=20=E5=AF=B9=E9=BD=90?= =?UTF-8?q?=E4=B8=A4=E5=A4=84=E4=B8=8E=E6=94=B9=E5=8A=A8=E5=90=8E=E4=B8=8D?= =?UTF-8?q?=E7=AC=A6=E7=9A=84=E6=B3=A8=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit c_standard 从 gnu11 改回 c11 之后,config.h 里 HAVE_C23_AUTO 那段还写着 「builds as gnu11」。 以及 config.h 顶部对 LIBINPUT_QUIRKS_DIR 的说明还停在「编译期路径」, 与文件头已改准的版本不一致——libinput.c:1911 是 getenv 优先、编译期值兜底。 --- pkgs/c/compat.libinput.lua | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/pkgs/c/compat.libinput.lua b/pkgs/c/compat.libinput.lua index df1ac88..6aa13a7 100644 --- a/pkgs/c/compat.libinput.lua +++ b/pkgs/c/compat.libinput.lua @@ -95,11 +95,13 @@ package = { #define MCPP_LIBINPUT_CONFIG_H /* meson's config.h, written out for Linux with a GCC-compatible toolchain. - LIBINPUT_QUIRKS_DIR is EMPTY on purpose. quirks.c reads model-specific - `.quirks` files from it at runtime; upstream's default points into the - build prefix, which after relocation is the HOST's dataset. Empty means a - device gets libinput's built-in defaults instead of another machine's - quirks — the same stance compat.libgbm takes with GBM_BACKENDS_PATH. + LIBINPUT_QUIRKS_DIR is EMPTY on purpose, and it is a FALLBACK rather than + the only way in: `libinput.c:1911` reads `getenv("LIBINPUT_QUIRKS_DIR")` + first. Upstream's compiled-in default points into the build prefix, which + after relocation is the HOST's dataset — so empty means a device gets + libinput's built-in defaults instead of another machine's quirks, and an + environment that has a dataset can still name it. Exactly the shape + compat.libgbm has with GBM_BACKENDS_PATH, down to the variable. HAVE_LUA and HAVE_LIBWACOM are absent: both are optional upstream and both would add a dependency this package does not need to do its job. */ @@ -140,8 +142,8 @@ package = { #define HAVE_MTDEV 1 /* HAVE_C23_AUTO is deliberately ABSENT. meson probes for it by compiling - `auto foo = gmtime(NULL);`, which needs C23; this package builds as gnu11, - so the probe would fail there too and upstream's non-auto path is correct. */ + `auto foo = gmtime(NULL);`, which needs C23; this package builds as c11, so + the probe would fail here too and upstream's non-auto path is correct. */ #endif ]==], From 067c6b875b69956abea839b7c619fa08e50d3029 Mon Sep 17 00:00:00 2001 From: sunrisepeak Date: Sun, 30 Aug 2026 18:49:28 +0800 Subject: [PATCH 4/4] =?UTF-8?q?docs:=20=E8=A1=A5=E8=AE=B0=E4=BB=8E?= =?UTF-8?q?=E5=B7=B2=E5=8F=91=E5=B8=83=E7=B4=A2=E5=BC=95=E7=9A=84=E5=A4=8D?= =?UTF-8?q?=E9=AA=8C,=E4=BB=A5=E5=8F=8A=E5=AE=83=E6=8A=93=E5=88=B0?= =?UTF-8?q?=E7=9A=84=20store=20=E6=92=9E=E5=90=8D=E9=99=B7=E9=98=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 合并 xim#732 后又从「已发布索引 + 全新 subos + 沙箱」复验一遍——上一次用的是 --add-xpkg 的本地副本,证明力不同。 第一次复验数据没放进去,差点得出「包坏了」。真因是 store 里还留着本地验证时的 local:xkeyboard-config@2.48,而 store 查找忽略 namespace,(name, version) 撞上 就把 install() 静默跳过、payload 为空,config() 照常跑。 顺带记下:declare_xkb 的 os.isdir 守卫确实触发了,但那条 log.warn 在 install 输出里没出现(同一次输出里 xlings 自己的 [warn] 是打出来的)。所以 declare_dri / declare_gbm / declare_xkb 的警告都不能当诊断依赖。 --- ...26-08-30-graphics-stack-coverage-design.md | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/.agents/docs/2026-08-30-graphics-stack-coverage-design.md b/.agents/docs/2026-08-30-graphics-stack-coverage-design.md index bfd15ab..50ff941 100644 --- a/.agents/docs/2026-08-30-graphics-stack-coverage-design.md +++ b/.agents/docs/2026-08-30-graphics-stack-coverage-design.md @@ -638,6 +638,32 @@ xkb_keymap_new_from_names(evdev/pc105/us) against that root ok 消费侧断言写在 `tests/examples/libxkbcommon`,且是**条件式**的:`XKB_CONFIG_ROOT` 未 设置时只报告,设置了才要求编得出来。没有数据集的机器不是这个包的缺陷。 +**合并后又从「已发布索引 + 全新 subos + 沙箱」复验了一遍**,因为上面那次用的是 +`xlings config --add-xpkg` 的本地副本: + +``` +xim:xkeyboard-config@2.48 installed ← 来自已发布索引,不是 local: +ROOT=[.../subos/eco-2026-8-30-2/share/X11/xkb] +compat geometry keycodes rules symbols types + rules/evdev 行数: 512 + 布局数: 151 +``` + +**这次复验抓到一个真实陷阱,而且差点得出"包坏了"的结论**:第一次从已发布索引装, +数据**没有**放进去。原因不在包 —— store 里还留着本地验证时的 +`local:xkeyboard-config@2.48`,而 xlings 的 store 查找**忽略 namespace**, +`(name, version)` 撞上就把 `install()` 静默跳过,payload 是空的,而 `config()` 照常跑。 +清掉 store 重装即正常。 + +**两条要记住的**: + +1. 用 `--add-xpkg` 本地验证过的包,发布后必须**先清 store 再验一遍**,否则验的 + 仍然是本地那份。 +2. `declare_xkb` 的 `os.isdir` 守卫确实触发了,但那条 `log.warn` + **在 install 输出里根本没出现**(同一次输出里 xlings 自己的 `[warn]` 是打出来的)。 + 所以 `declare_dri` / `declare_gbm` / `declare_xkb` 的警告都不能当诊断依赖 —— + 判断内容有没有真放进去只能直接 `ls`。 + #### 10.9.2 同一形状的第三处:libinput quirks 写 `compat.libinput` 时把 `LIBINPUT_QUIRKS_DIR` 也编译成空,注释里当时写的是「编译期