Repository navigation
fix(next-ui): 修复内嵌子应用分页切回时卡死在加载遮罩及黑屏问题 - #233
Merged
lioensky merged 1 commit intoOct 6, 2026
Merged
Conversation
infinite-vector
force-pushed
the
fix/embedded-app-tab-switch-reload
branch
from
October 6, 2026 10:26
78704dc to
0e85b2d
Compare
4 of 7 tasks
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.
动机与背景
在 Next UI 架构中,通过左上角「+」组件库以内嵌标签页形式打开子应用(如工程施工台、主题等基于 WebContentsView 的内嵌分页)后,当用户在 VChat 主对话与子应用分页之间往复切换时,存在概率性卡死在带有旋转图标的“正在打开应用…”遮罩上,或切回后呈现空白/黑屏的缺陷。
排查确认该问题存在三重并发根因:
loading遮罩,在底层应用就绪变为data-state="ready"后,该 DOM 节点未被清理,且 CSS 缺少强隐藏规则;hidden(display: none),切回瞬间若在重排完成前抓取getBoundingClientRect()会得到 0,旧逻辑兜底为 1px 并通过 IPC 写入主进程,将会话视口破坏性压缩为 1x1 像素;setVisible(false)隐藏后合成帧暂停,单纯重新执行setVisible(true)时若未重新排布置顶或唤醒 GPU,视图可能处于未刷新状态,从而透出底盘的旋转加载动画。解决方案与架构设计
建立三层防御与自愈闭环:
embeddedAppSessionManager.js):setBounds中增设最小有效边界保护网(width/height <= 1 时安全忽略),杜绝异常 0 尺寸污染健康会话;activate时,依据insets紧贴当前主窗口边界自适应对齐最新视口;同时在contentView中重新置顶原生视图,并调用invalidate()强制激活 Chromium 合成管线。next-shell-controller.js):ready状态后,立即从 DOM 树中移除.next-ui-embedded-app-status状态节点;syncEmbeddedActivation异步回调严格校验当前活动的activeViewId,杜绝切标签过快时的陈旧回调串扰;并在下一帧安全对齐真实排版尺寸。ui-next.css):html .next-ui-embedded-app-view[data-state="ready"] .next-ui-embedded-app-status { display: none !important; }。测试与验证
app-tab-host.test.js、embedded-app-controller.test.js、embedded-app-security.test.js、overlay-coordinator.test.js、launchpad-controller.test.js、creation-controller.test.js共 29 项),全部 100% PASS;test-next-ui-tab-lifecycle.mjs),无错误通过;……
嗯?怎么ai给我塞了个!important……算了就一个。