Skip to content

feat(eui-neo): 托盘示例——让「后端掉了」不再和「没测过」同一个读数 - #274

Merged
Sunrisepeak merged 1 commit into
mainfrom
feat/eui-neo-tray-example
Aug 28, 2026
Merged

feat(eui-neo): 托盘示例——让「后端掉了」不再和「没测过」同一个读数#274
Sunrisepeak merged 1 commit into
mainfrom
feat/eui-neo-tray-example

Conversation

@Sunrisepeak

Copy link
Copy Markdown
Member

承接 #269(接上 Linux 托盘 EUI_TRAY_SNI)。那个 PR 让托盘能用了,这个 PR 让它能被发现坏掉,并给用户一份可抄的写法。

为什么需要

tray_bridge.c 在预处理期四选一(EUI_TRAY_WINAPI / APPKIT / SNI / APPINDICATOR),都没定义时落到 #else stub。stub 定义了全部六个同名符号,每个返回 0。

所以 Linux 腿一旦丢掉 -DEUI_TRAY_SNI=1:照样编译、照样链接、索引里现有六个 eui-neo 示例全部照常变绿,而托盘静默消失。「没有托盘」和「没测过」读数完全一样。

六个示例没有一个碰托盘,也没有一个碰。

新增 tests/examples/eui-neo-tray

一、用户可抄的写法。 走公开的 core::platform 接口,不走内部的 core/platform/tray_bridge.h

core::platform::TrayOptions options;
options.tooltip = "EUI NEO tray example";
if (!core::platform::initializeTray(options)) return 1;
while (!core::platform::consumeTrayExitRequested()) {
    core::platform::pollTray(false);
    if (core::platform::consumeTrayShowRequested()) std::println("  -> Show");
}
core::platform::shutdownTray();

托盘不需要窗口、不需要 GL、不需要 DSL app loop —— 一个纯托盘程序就这十行,mcpp.toml 里一行依赖。

二、判据。 做了两版,第一版是钝的,而且是实测证伪的:

  • dlsym(RTLD_DEFAULT, "g_bus_get_sync") != nullptr —— 把 define 拿掉重建,它照样通过。描述文件的 ldflags 无条件带 -lgio-2.0,gio 始终在 DT_NEEDED 里。它回答的是「gio 链上了吗」,不是「后端是真的吗」。
  • ✅ 自起一条私有 session bus,断言 initializeTray() 为真。不需要显示器、不需要面板、不需要桌面会话。

双向实测 —— 把实现退回去再跑,是确认一条判据不空转的唯一办法:

构建 结果
真后端 linux tray backend verified over a private session busok
stub(拿掉 define) FAIL (exit 1),并指出是描述文件哪一行

dbus-run-session 起不来时报错退出而不是跳过 —— 「没验成」不能和「验过了」同一个读数,那正是本 member 存在的理由。它随 dbus 包提供。

Windows / macOS 只有编译链接覆盖:两边的后端在描述文件里是无条件的,也没有同样廉价、无头 runner 能做的探针。

描述文件的三处更正

净代码 −5 行,但文件 +16 行 —— 加的是实测记录,不是简化。

  1. 删掉「扁平归档」回落分支。 它建立在 os.cp("*", layer) 上,而 libxpkg 的 os.cp 取字面路径,遇到 glob 静默什么都不拷。那个分支只可能在下一行返回 false —— 形状上的回落,不是实际的回落。
  2. 文件自相矛盾。 -- ⚠️ DONE IN THE SHELL 就压在一个首行写着 -- ⚠️ NO SHELL 的函数上面;前者是被取代的旧设计留下的。
  3. 把运行时归给了 xmake。 不是 —— 是 libxpkg。两者 API 面不同,正是这个误认让人去读了错的 sandbox,得出「os.files 存在」的结论,而它在运行期是 nil。

三条实测到的运行时约束都写进了注释:os.cp 不展开 glob、os.files/path.basename 不存在、ldflags 里的 -L 会让包无法以动态库形态构建。它们都只在整套依赖下载完之后才暴露,所以值那几行。

本地验证

  • 新 member:真后端 ok / stub FAIL,双向都跑过
  • 其余六个 eui-neo member 不受影响(描述文件走的是 wrapped 路径,反复安装验证过)
  • 桌面实机:图标在 GNOME Shell 里注册为 Id=eui-neo-tray,与 steam/flameshot 并列;人工点击 Show ×2 与 Exit ×1,shut down cleanly 退出码 0
  • ⚠️ 本机无 lua/xmake,索引那五个 check_*.lua 没跑成(只跑了 check_graphics_install_side_effects.sh,通过)。未动版本 / URL / 包名,但这条得说清楚,交给 CI。

索引里六个 eui-neo 示例,没有一个碰托盘,也没有一个**能**碰:
tray_bridge.c 的 `#else` stub 定义了全部六个同名符号、每个返回 0。
Linux 腿一旦丢掉 `-DEUI_TRAY_SNI=1`,照样编译、照样链接、六个示例
全部照常变绿,而托盘静默消失。

新增 tests/examples/eui-neo-tray,两件事:

1. 用户可抄的写法。走公开的 `core::platform` 接口(六个自由函数 +
   两字段结构体),不走内部的 core/platform/tray_bridge.h。托盘不需要
   窗口、不需要 GL、不需要 DSL app loop —— 一个纯托盘程序就十行。

2. 判据。做了两版,第一版是钝的,而且是实测证伪的:
   - `dlsym(RTLD_DEFAULT, "g_bus_get_sync") != nullptr` —— 把 define
     拿掉重建,它照样通过。描述文件的 ldflags 无条件带 `-lgio-2.0`,
     所以 gio 始终在 DT_NEEDED 里。它回答的是「gio 链上了吗」,
     不是「后端是真的吗」。
   - 自起一条私有 session bus,断言 `initializeTray()` 为真。不需要
     显示器、不需要面板、不需要桌面会话,普通 runner 就能跑。

   双向实测(把实现退回去再跑,确认判据不是空转的唯一办法):
     真后端  -> ok,"verified over a private session bus"
     stub    -> FAIL (exit 1),并指出是描述文件哪一行

   dbus-run-session 起不来时报错退出而不是跳过 —— 「没验成」不能和
   「验过了」同一个读数,这正是本 member 存在的理由。

描述文件同时更正三处(净代码 -5 行,但文件 +16 行,因为加的是实测记录):
- 删掉「扁平归档」回落分支。它建立在 `os.cp("*", layer)` 上,而
  libxpkg 的 os.cp 取字面路径,遇到 glob 静默什么都不拷 —— 这个分支
  只可能在下一行返回 false,是形状上的回落而非实际的回落。
- 文件自相矛盾:`-- DONE IN THE SHELL` 就压在一个首行写着
  `-- NO SHELL` 的函数上面,前者是被取代的旧设计留下的。
- 把运行时归给了 xmake。不是 —— 是 libxpkg,两者的 API 面不同,
  正是这个误认让人去读了错的 sandbox,得出 os.files 存在的结论。

Windows/macOS 只有编译链接覆盖:两边的后端在描述文件里是无条件的,
也没有同样廉价、无头 runner 能做的探针。
@Sunrisepeak
Sunrisepeak merged commit 9927799 into main Aug 28, 2026
11 checks passed
@Sunrisepeak
Sunrisepeak deleted the feat/eui-neo-tray-example branch August 28, 2026 05:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant