Skip to content

Commit 825b423

Browse files
committed
test(sandbox): 第 8 步——按「没有抱怨」检验生态供给的数据集
xim#734 补上 libinput-quirks 之后,把最后一格也变成断言,并做了一次性整体闭环 验证(不再分阶段)。 第 8 步的判据是**没有抱怨**,这不是偷懒而是唯一可观测的信号:两条数据变量都优雅 降级——不设也照样一路 PASS,libinput 用内置默认、xkbcommon 只编字符串 keymap。 所以它们必须有自己的检查: 不设 LIBINPUT_QUIRKS_DIR: libinput error: failed to find data files ← 在 设了: (无) ← 没了 变量未设时报告而不失败——没装数据集的 subos 是合法配置,不是缺陷。 为此第 7 步改成捕获输出(仍原样打印),因为断言是关于 libinput 打了什么。 eco-2026-8-30-3,--sandbox --gpu,五个发现变量齐备: PASS: the host's copies were present and reachable, and none of them won PASS: none of libinput/libevdev/libmtdev/libxkbcommon/pixman is a DT_NEEDED glReadPixels 64 128 191 255 (wanted 64 128 191 255) ×2 个 DRM 节点 libinput assign_seat=0 fd=3 dispatch=0 evdev/pc105/us keycode 24 -> "q" LIBINPUT_QUIRKS_DIR = .../share/libinput (52 files) ok: libinput loaded the quirks database XKB_CONFIG_ROOT = .../share/X11/xkb (151 layouts) RESULT: PASS 文档: - §10.8.2 这次一次性闭环验证的完整输出 - §10.9.3 libinput-quirks 已落地(xim#734),含「数据是不是构建出来的」这条判据 ——它决定要不要重新发布归档;以及 install() 的 os 表是受限子集这个坑 - §10.9.4 USB_IDS_PATH 是**不该补**的那一格:libudev-zero 零个 getenv(机制不在), 且 libinput 从不读那两个属性(补了也没用)。之前把它与 quirks 并列是错的 - §10.9.5 发行版为什么不需要这些变量:它们拥有 /usr。需要环境变量的是可重定位的 那一类——Nix / Flatpak / Snap / Conda / 我们 - §10.10 发现变量表全部闭合,没有一格是留着的
1 parent 78b8e04 commit 825b423

2 files changed

Lines changed: 177 additions & 13 deletions

File tree

‎.agents/docs/2026-08-30-graphics-stack-coverage-design.md‎

Lines changed: 135 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -619,8 +619,54 @@ RESULT: PASS
619619
生态 payload 共存;这是那条判断第一次被放进「宿主有同名库、可达、就在 `/usr/lib`」的
620620
环境里正面检验 —— 而它赢了。
621621

622-
> 运行期那两条 `libinput error: failed to find data files` 是**预期的**,见 §10.9.2:
623-
> quirks 数据集还没有提供方。枚举、事件、dispatch 全部正常,丢的是逐机型调校。
622+
#### 10.8.2 最终一次性闭环验证(全部数据集齐备)
623+
624+
上一节跑的时候 quirks 还没有提供方,输出里带着两条 `libinput error: failed to find
625+
data files`。xim#734 之后重跑,**一次跑完整条链**,`eco-2026-8-30-3`,`--sandbox --gpu`:
626+
627+
```
628+
===== 6. did anything come from the host? =====
629+
PASS: the host's copies were present and reachable, and none of them won
630+
===== 6b. and the merged-in ones brought no shared library at all =====
631+
PASS: none of libinput/libevdev/libmtdev/libxkbcommon/pixman is a DT_NEEDED
632+
633+
===== 7. run it =====
634+
EGL_VERSION 1.5 libglvnd
635+
/dev/dri/renderD128 nvidia-drm GL_VERSION OpenGL ES 3.2 Mesa 25.0.7
636+
glReadPixels 64 128 191 255 (wanted 64 128 191 255)
637+
/dev/dri/card0 simpledrm gbm_bo_create 256x256 stride=1024
638+
glReadPixels 64 128 191 255 (wanted 64 128 191 255)
639+
reached EGL on a real device: yes
640+
drew and read the pixel back: yes
641+
642+
-- input --
643+
libevdev KEY_A -> KEY_A
644+
xkbcommon keycode 24 -> "q"
645+
libinput assign_seat=0 fd=3 dispatch=0
646+
libinput came up on libudev: yes
647+
evdev/pc105/us keycode 24 -> "q"
648+
the real us layout compiled: yes
649+
input chain answers: yes
650+
651+
===== 8. the datasets the ecosystem supplies, checked by their absence of complaint =====
652+
LIBINPUT_QUIRKS_DIR = .../share/libinput (52 files)
653+
ok: libinput loaded the quirks database (no 'failed to find data files')
654+
XKB_CONFIG_ROOT = .../share/X11/xkb (151 layouts)
655+
656+
===== RESULT =====
657+
PASS
658+
```
659+
660+
**第 8 步是新加的,而且它的判据是「没有抱怨」。** 两条数据变量都**优雅降级** ——
661+
不设也照样一路 PASS,libinput 用内置默认、xkbcommon 只编字符串 keymap。所以它们必须
662+
有自己的检查,而唯一可观测的信号是那条消息在不在:
663+
664+
```
665+
不设 LIBINPUT_QUIRKS_DIR: libinput error: failed to find data files ← 在
666+
设了: (无) ← 没了
667+
```
668+
669+
变量未设时这一步**报告而不失败** —— 没装数据集的 subos 是合法配置,不是缺陷。
624670

625671
### 10.9 xkeyboard-config 属于生态,不属于 mcpp-index
626672

@@ -728,8 +774,83 @@ failed to find data files ... will negatively affect device behavior
728774
并跑在内置默认上。这是**优雅降级**:枚举、事件、手势都正常,丢的是逐机型调校(比如
729775
某块触摸板的压力区间)。`tests/examples/libinput` 就是在这条消息存在的情况下全绿的。
730776

731-
补法与 xkeyboard-config 完全对称(xim 数据包 + 一行 DISCOVERY),优先级低于布局数据:
732-
布局缺了是**硬失败**,quirks 缺了只是不够贴合。
777+
补法与 xkeyboard-config 对称(xim 数据包 + 一行 DISCOVERY)。**已做**,见 §10.9.3。
778+
779+
#### 10.9.3 已落地(openxlings/xim-pkgindex#734)
780+
781+
**没建新仓,也没发新 release** —— 这是它与 xkeyboard-config 的关键差别,而差别的
782+
判据是**数据是不是构建出来的**:
783+
784+
| | 数据来源 | 结论 |
785+
|---|---|---|
786+
| xkeyboard-config | 上游 meson 跑规则编译器,`rules/evdev` 由 ~40 片段拼出 | 必须预生成 + 重新发布 |
787+
| libinput quirks | 签在 libinput 树里,`install_subdir` 原样安装 | **直接用上游 tarball** |
788+
789+
所以 `libinput-quirks` 下的是 libinput **自己的** tarball —— 与 `compat.libinput`
790+
**同一个 URL、同一个 sha256** —— 只保留 `quirks/`。为 240KB 数据下 1.1MB,换来没有第二
791+
份归档要发布、没有镜像要同步,而且数据集**可证明**就是 libinput 1.31.3。
792+
793+
版本跟库走不是装饰:quirks 文件里写 libinput 的特性名(`AttrPressureRange`、
794+
`ModelBouncingKeys`),数据集比库新就可能带库不认识的键。
795+
796+
`LIBINPUT_QUIRKS_DIR` 是 DISCOVERY 表里第二个 `op = "set"` 的标量(`quirks.c:1217`
797+
只 scandir 一个目录),排序用 `versionsort` —— 所以 `10-` / `30-` / `50-` 文件名前缀
798+
决定优先级,与 glvnd vendor JSON 同一套约定,也正是 `compat.libinput` 里
799+
`HAVE_VERSIONSORT` 不可省的原因。
800+
801+
**实现中撞到的:`install()` 里的 `os` 表是受限子集。** 写日志逐个 `type()` 探出来:
802+
803+
| nil | 可用 |
804+
|---|---|
805+
| `os.files` `os.filedirs` `os.exists` `os.curdir` `os.iorunv` | `os.dirs` `os.isdir` `os.isfile` `os.mv` `os.cp` `os.mkdir` `os.tryrm` `os.cd` |
806+
807+
坑不在「调了会报错」,而在惯用的 `#(os.files(...) or {}) == 0` —— 它把**「这个函数
808+
不存在」变成「目录是空的」**。第一版就是这么把一次**已经成功**的移动报成失败的:探针
809+
打出来 `isdir(dst) = true`,数据早就在位,挂的只是计数那一行。
810+
811+
改法:**先做再验结果,不预探测**;计数换成 `os.isdir` + 一个规范文件名
812+
(`10-generic-keyboard.quirks`)。耦合一个文件名比 glob 差,但比受限表下**根本没有
813+
检查**好 —— 空目录是唯一会**静默**失败的情况:scandir 到零个匹配,libinput 用内置
814+
默认继续跑,连那条报错都不打。
815+
816+
前后对照(`tests/examples/libinput`):
817+
818+
```
819+
不设变量: libinput error: failed to find data files ← 在
820+
设了变量: (无) ← 没了
821+
52 个 .quirks 已加载,6 项断言全过
822+
```
823+
824+
#### 10.9.4 `USB_IDS_PATH` 是**不该补**的那一格
825+
826+
`compat.libudev` 也把 `USB_IDS_PATH` 编译成空,本文档早前把它与 quirks 并列成
827+
「机制在、提供方缺」。**核实后两句都是错的**:
828+
829+
1. **机制不在。** libudev-zero 全树**零个 `getenv`**,`udev.c:95` 是
830+
`fopen(USB_IDS_PATH, "r")` —— 编译期常量,没有环境出口。加数据包不会让它生效。
831+
2. **补了也没用。** 它只喂 `udev_hwdb_get_properties_list_entry()` 的两个属性
832+
(`ID_MODEL_FROM_DATABASE` / `ID_VENDOR_FROM_DATABASE`),而 **libinput 一次都没
833+
读过**(`src/*.c` 里 grep `FROM_DATABASE` 为空)。设备名走的是
834+
`libinput_device_get_name → evdev_device_get_name →` 内核 `EVIOCGNAME`。
835+
836+
而且这压根不是 libudev 的标准做法:systemd 的 udev **运行期不读 `usb.ids`**,它读
837+
编译好的 `hwdb.bin`(由 `hwdb.d/*.hwdb` 文本编译,而那些文本在构建期从 usb.ids 生成)。
838+
宿主上 `/usr/share/hwdata/usb.ids` 是给 `lsusb` 之类用的。libudev-zero 直接 parse
839+
文本是它自己对 hwdb 的简化实现。
840+
841+
**结论:这一格留空对本栈影响为零,不列为缺口。**
842+
843+
#### 10.9.5 发行版为什么不需要这些变量
844+
845+
值得单独写一句,因为它解释了整类问题:**发行版拥有 `/usr`**。
846+
847+
```
848+
libinput-bin: /usr/share/libinput/*.quirks ← 库和数据同一个包,--prefix=/usr 写死
849+
/usr/lib/udev/hwdb.d/20-usb-vendor-model.hwdb ← systemd udev 编译成 hwdb.bin
850+
```
851+
852+
路径永远不会错,所以不需要任何环境变量。需要环境变量的恰恰是**可重定位**的那一类 ——
853+
Nix、Flatpak、Snap、Conda,和我们。这不是本生态特殊,是同一类系统的共同解法。
733854

734855
### 10.10 仍未做
735856

@@ -764,11 +885,12 @@ failed to find data files ... will negatively affect device behavior
764885
- ~~G6 `libudev` / `libseat`~~ **已做**,而且没有碰 systemd:libudev 用
765886
**libudev-zero**(三个实现里唯一既活着又可独立分发的),libseat 只开 seatd 与
766887
builtin 后端。两者的代价都在描述符里点名了。
767-
- ~~**xkeyboard-config**~~ **已做**(xim-pkgindex#732),见 §10.9.1。跨索引闭环已实测。
768-
- **libinput quirks 数据**:见 §10.9.2。形状与 xkeyboard-config 对称,优先级更低 ——
769-
布局缺了是硬失败,quirks 缺了只是不够贴合。**未做**。
888+
- ~~**xkeyboard-config**~~ **已做**(xim-pkgindex#732),见 §10.9.1。
889+
- ~~**libinput quirks 数据**~~ **已做**(xim-pkgindex#734),见 §10.9.3。
890+
- ~~**`USB_IDS_PATH`**~~ **不补**,理由见 §10.9.4:机制不在(零 `getenv`),而且补了
891+
也没用(libinput 从不读那两个属性)。
770892

771-
至此渲染链与输入链都不再有「静默落到宿主」的边:
893+
至此渲染链与输入链都不再有「静默落到宿主」的边,而且**没有一格是留着的**:
772894

773895
| 子系统 | 发现变量 | 提供方 | 状态 |
774896
|--------|---------|--------|------|
@@ -777,11 +899,12 @@ failed to find data files ... will negatively affect device behavior
777899
| Vulkan ICD | `XDG_DATA_DIRS` / 共享 vendor 目录 | 同上 | ✅ xim#731 |
778900
| GBM 后端 | `GBM_BACKENDS_PATH` | `xim:mesa` | ✅ |
779901
| 键盘布局 | `XKB_CONFIG_ROOT` | `xim:xkeyboard-config` | ✅ xim#732 |
780-
| 输入 quirks | `LIBINPUT_QUIRKS_DIR` | *(无)* | ⬜ 优雅降级中 |
781-
| USB 名字库 | `USB_IDS_PATH` | *(无)* | ⬜ 优雅降级中 |
902+
| 输入 quirks | `LIBINPUT_QUIRKS_DIR` | `xim:libinput-quirks` | ✅ xim#734 |
903+
| USB 名字库 | `USB_IDS_PATH` | — | ➖ 无影响,见 §10.9.4 |
782904

783-
最后两行是同一类:机制在、提供方缺、缺了只丢锦上添花的东西。**它们缺失时会说出来**
784-
—— 这正是当初把编译期默认值一律留空要换的东西。
905+
**留空编译期默认值换来的东西,到这里可以结账了**:六个子系统里没有一个会悄悄读宿主
906+
的数据;缺失的那些在补上之前**都会自己说出来**(GBM 的 `MESA-LOADER: failed to open`、
907+
libinput 的 `failed to find data files`),而这些消息正是本轮把它们一个个补上的线索。
785908

786909
#### 10.10.1 加一行进这张表,同时是一次对**现有提供方**的改动
787910

‎tests/verify_graphics_closed_loop_sandbox.sh‎

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,48 @@ fi
378378
echo " PASS: none of libinput/libevdev/libmtdev/libxkbcommon/pixman is a DT_NEEDED"
379379

380380
say "7. run it"
381-
"$BIN"
381+
# Captured rather than streamed, because one of the assertions below is about
382+
# what libinput printed. Shown in full either way.
383+
OUT=/home/speak/closed-loop.out
384+
"$BIN" >"$OUT" 2>&1 || true
385+
cat "$OUT"
386+
387+
say "8. the datasets the ecosystem supplies, checked by their absence of complaint"
388+
# Two of the discovery variables lead to DATA rather than to code, and both
389+
# degrade GRACEFULLY when unset — libinput runs on built-in defaults, xkbcommon
390+
# compiles only keymaps handed to it as strings. A run without them still says
391+
# PASS everywhere above, which is exactly why they need their own check.
392+
#
393+
# The observable is the complaint. libinput logs
394+
#
395+
# failed to find data files ... will negatively affect device behavior
396+
#
397+
# when its quirks directory is empty or unset. So: if the variable is set, that
398+
# message must be GONE. If it is not set, this reports rather than fails —
399+
# a subos without the datasets is a legitimate configuration, not a defect.
400+
data_fail=0
401+
if [ -n "${LIBINPUT_QUIRKS_DIR:-}" ]; then
402+
echo " LIBINPUT_QUIRKS_DIR = $LIBINPUT_QUIRKS_DIR ($(ls "$LIBINPUT_QUIRKS_DIR"/*.quirks 2>/dev/null | wc -l) files)"
403+
if grep -q 'failed to find data files' "$OUT"; then
404+
echo " FAIL: the quirks database is declared but libinput did not load it"
405+
data_fail=1
406+
else
407+
echo " ok: libinput loaded the quirks database (no 'failed to find data files')"
408+
fi
409+
else
410+
echo " LIBINPUT_QUIRKS_DIR unset — install xim:libinput-quirks to exercise this"
411+
grep -q 'failed to find data files' "$OUT" \
412+
&& echo " (and libinput said so, as it should)"
413+
fi
414+
415+
if [ -n "${XKB_CONFIG_ROOT:-}" ]; then
416+
echo " XKB_CONFIG_ROOT = $XKB_CONFIG_ROOT ($(ls "$XKB_CONFIG_ROOT/symbols" 2>/dev/null | wc -l) layouts)"
417+
grep -q 'the real us layout compiled: yes' "$OUT" \
418+
|| { echo " FAIL: the dataset is declared but the us layout did not compile"; data_fail=1; }
419+
else
420+
echo " XKB_CONFIG_ROOT unset — install xim:xkeyboard-config to exercise this"
421+
fi
422+
[ "$data_fail" -eq 0 ] || exit 1
382423

383424
say "RESULT"
384425
echo " PASS"

0 commit comments

Comments
 (0)