Repository navigation
Releases
v0.1.15 — 引擎环境不再被 PyInstaller 遮蔽
症状
引擎正常启动、界面能开,但配置管理的同步失败:
读取远端快照失败:git clone https://github.com/<user>/<repo>.git 失败 (exit 128)
… /_MEI0000054cWWSwqE/libssl.so.3: version `OPENSSL_3.5.0' not found
(required by /usr/lib/libcurl.so.4) …
致命错误:remote helper 'https' aborted session
根因
SteamOS 的 /usr/bin/flatpak 是 PyInstaller 打包的,它把自带的旧 OpenSSL 解包到 $TMPDIR/_MEIxxxxxx/。Decky 服务进程的 LD_LIBRARY_PATH 指向这种目录,于是所有子进程(node、git、git-remote-https)都优先从那里加载 libssl,版本不够就 abort。
v0.1.6 修过一模一样的坑,但只修了「启动浏览器的环境」(_gui_env);启动引擎的环境(_build_env)仍然原样继承 os.environ —— 引擎活了,它下面的 git 死了。
修法
清洗提到最外层统一入口 _sanitize_inherited_env(),引擎与浏览器两条 spawn 路径都走它。比 v0.1.6 更克制也更彻底:
LD_LIBRARY_PATH/LD_PRELOAD里只删指向_MEI…的条目和已不存在的目录,你手动设的合法值会被保留(v0.1.6 是整条丢掉)- 整条都被遮蔽时移除变量而不是留空(空条目在加载器语义里等于「当前目录」)
TMPDIR只在「是_MEI目录 / 不可写 / 不存在」时才换成/tmp
升级
下载下方的 dsh-decky.zip 覆盖安装,然后重启引擎(插件改的是启动环境,不重启不生效)。
应急(不升级也能救)
env -u LD_LIBRARY_PATH TMPDIR=/tmp <原来的 dsh 启动命令> --profile web --no-open --port 3080或把配置管理的同步通道从 Git 换成 Gist / WebDAV —— 那两条走 Node 的 HTTPS,根本不 spawn git。
测试
tests/run_tests.py 新增 8 项 env 清洗回归检查,全量 95 项通过。
v0.1.14 — 方案C:注册为游戏库条目(游戏模式内可见)
真机定案(v0.1.12/13):外部浏览器确实能启动,但窗口开在桌面显示 :0 上,游戏模式看不到——gamescope 只合成自己的 Wayland 画面,X11 客户端无法盖在游戏之上。方案 B 在游戏模式结构性走不通。
方案 C 把启动交给 Steam 自己:由 gamescope 会话内启动浏览器,窗口自然得到合成。
- 后端 prepare_nonsteam():生成稳定的启动脚本,并把会轮换的 token URL 写入 last-url.txt(Steam 注册时会快照 Exec 目标,URL 必须放在脚本外);引擎每打印新 token 都自动刷新该文件
- 前端通过 SteamClient.Apps.AddShortcut 注册(先移除同名条目保持幂等),API 不可用时给出手动「添加非 Steam 游戏」的准确路径
- 有意不手写 shortcuts.vdf:那是 Steam 自己的二进制格式,写错会毁掉用户整个游戏库
用法:游戏模式 → 插件 → 添加为游戏库条目(方案 C)→ 回首页启动「DSH Browser」。
v0.1.13 — 分离启动延迟回读诊断
真机确认:v0.1.12 的 X11 路线让 Firefox 窗口成功开出来了——但开在桌面模式的 :0 显示上,游戏模式(gamescope)看不到它。X11 窗口无法进入 gamescope 合成,方案 B 的外部浏览器在游戏模式里天生受限。
本版为诊断增强:flatpak 交接启动后 6 秒回读——pgrep 应用真实进程存活状态 + 读取继承的 stderr + 记录实际 DISPLAY,写入面板日志。用于区分"活在别的显示"与"交接后崩溃"。(方案 C:注册为 Non-Steam 游戏由 Steam/gamescope 直接启动,下一版。)
v0.1.12 — 强制 X11:Wayland 注入导致 GTK seat 崩溃
真机日志显示 Firefox 已能启动(org.mozilla.firefox:2),随即死在 gdk_seat_get_keyboard: assertion 'GDK IS SEAT (seat)' failed(附 minidump)。原因:插件注入了 WAYLAND_DISPLAY=gamescope-0,但 flatpak 沙箱内的浏览器够不着 gamescope 的 Wayland socket,GTK 拿到空 seat 直接断言崩溃。
本版强制走 X11(XWayland :0,与 Steam 内置浏览器同一显示路线):移除 WAYLAND_DISPLAY、设 GDK_BACKEND=x11、MOZ_ENABLE_WAYLAND=0。
v0.1.11 — 接受 flatpak run 的 fork 语义(退出码0=成功)
真机日志:这台机器的 flatpak 不认识 --nofork(未知选项)。不再对抗 fork:flatpak run 派生应用后自己退 0 被判定为启动成功(detached_ok 候选专属语义),仅非 0 退出才换下一个候选。
注意:「关闭外部窗口」对分离启动的应用用 pkill -f 按 app id 精确匹配——若桌面上同时开着另一个 flatpak Firefox,会一并被关闭(如实声明的已知限制)。
v0.1.10 — 修复探测路径双拼 bug + 手填浏览器路径
v0.1.9 的"未找到浏览器"根因复查确认:存在性检查把路径拼成了 /var/lib/flatpak/app/app/(root 已含 /app 又 join 一次 app),永远为假——是代码 bug,不是环境问题。本版修复。
新增保险:①探测失败时面板直接显示诊断(插件 HOME/uid + 各 flatpak 根目录存在性与内容清单);②高级设置新增「浏览器路径」手填项(配置的绝对路径作为第一候选);③flatpak 用户级根目录额外扫 /home/*/.local/share/flatpak/app。dist/index.js 已随版重建。
v0.1.9 — 修复 v0.1.8 的"未找到浏览器"回归
v0.1.8 把 exports/bin 移出候选后,flatpak 安装的唯一判据只剩 flatpak info 子调用——它自己也是 PyInstaller 二进制,同样死于 TMPDIR 污染,于是对已安装的 Firefox 回答"没装"。
本版:flatpak 应用是否存在改由文件系统判定(磁盘上有 app 树 = 装了;系统级与用户级根都查),彻底不再拿 CLI 探测当神谕。
v0.1.8 — 追踪真实进程(--nofork),去掉包装器候选
v0.1.7 日志解读:exports/bin 包装器 fork 出 flatpak run 后自己退 0——存活检查把它误判为死亡,而分离出去的子进程其实已经把 Firefox GTK 跑起来了(日志里的 portal Gtk-WARNING 就是证据;命名空间 EPERM 可越过)。我们随后又重试别的候选,把真正的窗口孤立了。
本版:①flatpak run 候选改用 --nofork(spawn 的进程就是应用本体);②exports/bin 包装器从候选中彻底移除;③直跑 firefox/chromium 加 --no-sandbox + 独立 profile(它们自己的沙箱同样建不了用户命名空间)。
v0.1.7 — 修复 TMPDIR 污染导致的 flatpak OpenSSL 崩溃
面板日志(v0.1.6)终于看到真相:每次 spawn 都死在 SteamOS 的 PyInstaller 版 /usr/bin/flatpak 里,报 _MEI…/libcrypto.so.3: version OPENSSL 3.4.0 not found——Decky 服务环境的 TMPDIR 被污染,flatpak 解包自带的旧版 OpenSSL 遮蔽了系统库。
本版:①子进程环境强制 TMPDIR=/tmp 并剥离继承的 LD_LIBRARY_PATH;②直跑 Firefox 的 LD_LIBRARY_PATH 补上 freedesktop Platform 运行时的库目录(GTK 在 runtime 树里,不在 app 树——v0.1.5 退 1 的缺口);③候选逐个重试机制不变。
v0.1.6 — 逐个候选重试 + 补会话总线 + 完整错误进日志
v0.1.5 的直跑二进制在真机仍退出码 1(flatpak 应用还依赖 freedesktop 运行时的 GTK 库,LD_LIBRARY_PATH 不够)。真正该修的是沙箱路:flatpak run 在 Decky 服务进程里失败只是因为缺 DBUS_SESSION_BUS_ADDRESS——socket 一直在 $XDG_RUNTIME_DIR/bus。
本版:①spawn 环境自动注入会话总线地址;②「用外部窗口打开」按顺序逐个尝试所有候选(直跑二进制→原生→flatpak run),活过 2.5 秒才算成功;③浏览器完整 stderr 写入面板日志(toast 会把错误尾巴截断到没法看);④flatpak 探测兼容精简 PATH(直接查 /usr/bin/flatpak)。