feat(gui): VM GUI 執行中動態解析度——guest 側 resize watcher(vz/WHP 共用)#128
Merged
Conversation
…ot found kernel 給 PID 1 的環境沒有 PATH;init 只賦值不 export,guest-agent 及其子行程 的環境便沒有 PATH——以 PATH 尋找 GUI overlay 工具(wl-copy/wlr-randr)全部 「not found」,剪貼簿與動態解析度被靜默停用(實機 vz e2e 抓到)。 guest-agent 的 which() 另補預設路徑退路(隨 feat commit),讓舊 initramfs 也能運作。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
host 端早已把新尺寸推進 guest(WHP 的 SharedResize 中斷鏈、vz 的 automaticallyReconfiguresDisplay),但 cage 不會因「已連線 connector 的模式清單 變更」re-modeset——wlroots 的 preferred-mode-change → request_state 通知在上游 仍是未合併 draft(MR 5182,目標 0.20),Alpine 出貨版短期拿不到;replug 模擬 又會讓 cage 拆輸出、觸發 fail_fast(見 DESIGN M8-d)。 guest-agent 新增 resize watcher(resize.rs,零新依賴): - netlink 直聽 kernel uevent(不依賴 udevd),drm change 事件 debounce 收斂; - DRM_IOCTL_MODE_GETCONNECTOR 的 count_modes=0 首呼叫觸發 kernel re-probe 取 新 preferred mode(sysfs modes 只反映上次 probe,讀不到新值); - wlr-randr --custom-mode 經 wlr-output-management 要求 cage 換模式(custom mode 繞過 cage 端過期的 mode list);同尺寸抑制、連續失敗自動停用(舊 overlay 相容:回到 host 端縮放的既有行為); - 子行程不能用 Command::output():supervisor 以 waitpid(ANY) 監督服務,會把 wlr-randr 搶先收屍讓 output() 得 ECHILD 誤報失敗(實機 e2e 抓到)——自行讀完 stdout/stderr,wait 遇 ECHILD 以 stderr 是否為空判定; - which() 在 PATH 未設時退回標準路徑(舊 initramfs 的 init 沒 export PATH)。 GUI overlay 升 Alpine 3.20 → 3.22:cage 0.2.0 才有 wlr-output-management (0.1.5 沒有),另附 wlr-randr。vz 維持 main 既定的預設取捨(scanout=點數、 view 縮放——Retina 像素模式會讓 Linux guest UI/游標縮半,翻預設 gated on HiDPI output scale);CHEFER_VZ_DYNAMIC_RESOLUTION=1 的 opt-in 因本 watcher 成為全鏈可用。vz-helper 加 CHEFER_VZ_GUI_TEST_RESIZE 測試鉤子(程式化 setContentSize,與拖拉同一條顯示重組態路徑,僅動態解析度模式生效),vz-smoke --gui 據此可免拖拉驗證;另在有 Docker 時現建新 overlay、恢復動態解析度檢核項。 實機驗證(Apple Silicon,macOS 26):CHEFER_VZ_DYNAMIC_RESOLUTION=1 下 t+20s 程式化縮放 1100x700pt → console「gui: resize: Virtual-1 -> 2200x1400」 → guest 內 xdpyinfo dimensions 2560x1600 → 2200x1400 跟隨(Retina 2x)。 WHP 側裝置/中斷鏈先前已實機驗證,guest 側共用本 watcher,回歸驗證待下次 Windows 實機(WHP 無 opt-in 閘,拖拉即觸發)。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
TimLai666
force-pushed
the
feat/vm-gui-dynamic-resolution
branch
from
July 11, 2026 16:16
440800e to
5a12748
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
摘要
讓 VM GUI(WHP 與 macOS vz 共用的 cage kiosk compositor)支援執行中動態解析度:host 視窗縮放 → guest 真正 re-modeset。補上 #127 實測後記載的 guest 端缺口(「cage 啟動後不跟模式變更;修法在 guest 側」「翻預設 gated on re-modeset + HiDPI output scale」的前半)。
實作
GETCONNECTORcount_modes=0 首呼叫觸發 kernel re-probe 取新 preferred mode(sysfs 只反映上次 probe)→wlr-randr --custom-mode經 wlr-output-management 要 cage 換模式(custom mode 繞過 cage 端過期 mode list)。同尺寸抑制;連續失敗自動停用;舊 overlay/舊 initramfs 相容(which() PATH 退路、缺 wlr-randr 即回到既有縮放行為)。CHEFER_VZ_DYNAMIC_RESOLUTION=1的 opt-in 因本 watcher 成為全鏈可用。WHP 無 opt-in 閘,拖拉即走 watcher。HiDPI output scale(翻預設的另一半)另開後續。CHEFER_VZ_GUI_TEST_RESIZE=<秒>:<W>x<H>測試鉤子(程式化setContentSize,與拖拉同路徑、僅動態解析度模式生效)→ vz-smoke 可免拖拉自動驗證。export PATH(PID 1 環境無 PATH → guest-agent 找不到 overlay 工具,剪貼簿/動態解析度被靜默停用);watcher 子行程改自行收 stdout/stderr(supervisorwaitpid(ANY)會搶先收屍使Command::output()得 ECHILD 誤報失敗——實機 e2e 抓到)。實機驗證(Apple Silicon,macOS 26)
CHEFER_VZ_DYNAMIC_RESOLUTION=1+ 測試鉤子:t+20s 縮放 1100×700pt → consolegui: resize: Virtual-1 -> 2200x1400→ guest 內xdpyinfodimensions 2560×1600 → 2200×1400 跟隨(Retina 2×)✓風險與待辦
🤖 Generated with Claude Code