Skip to content

Fix #4934 返回页面时可能卡进空白页面#5305

Merged
Glavo merged 2 commits into
HMCL-dev:mainfrom
CiiLu:qwq
Jan 24, 2026
Merged

Fix #4934 返回页面时可能卡进空白页面#5305
Glavo merged 2 commits into
HMCL-dev:mainfrom
CiiLu:qwq

Conversation

@CiiLu

@CiiLu CiiLu commented Jan 24, 2026

Copy link
Copy Markdown
Contributor

在我和 Glavo 群的一位群友的设备上之前基本随便点击几下就会卡出空白页面,应用这个修复之后测了几分钟都没卡出来

Gemini 3 解释 这是一个非常典型的 JavaFX 动画与状态并发导致的 Race Condition(竞态条件)问题。

问题诊断

问题出现在 TransitionPane.java 中,特别是在快速连续导航的场景下(例如 A -> B -> A)。

  1. 初始状态:当前显示页面 A (currentNode = A)。
  2. 动作 1(导航到 B):调用 setContent(B)
    • currentNode 更新为 B。
    • previousNode 被捕获为 A。
    • Platform.runLater 启动动画 A -> B。
  3. 动作 2(快速返回 A):在动画 A -> B 尚未结束时,用户立即点击返回或触发导航回 A。调用 setContent(A)
    • currentNode 更新为 A。
    • previousNode 被捕获为 B。
    • 子节点列表被设置为 [B, A] (将 A 重新加回场景)。
  4. Bug 触发:动作 1 的动画(A -> B)结束。
    • 它的 onFinished 回调被触发。
    • 回调中执行 getChildren().remove(previousNode),此时该闭包中的 previousNodeA
    • 关键点:尽管此时 currentNode 已经是 A 了,但旧的动画回调强制移除了 A。
    • 结果:场景中只剩下 B(且 B 可能正在执行淡出动画或随后被动作 2 的回调移除),最终导致 TransitionPane 为空,屏幕白屏。

修复方案

TransitionPane 的动画结束回调 (onFinished) 中,在移除 previousNode 之前,必须检查它是否意外地变回了当前的 currentNode。如果它现在是当前应当显示的节点,就不应该将其移除。

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

修复 JavaFX 页面快速往返切换时,旧动画 onFinished 回调误移除当前页面节点导致的白屏问题(#4934)。

Changes:

  • 在过渡动画结束回调中增加保护条件,避免当 previousNode 已重新成为 currentNode 时被移除。

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 83 to +87
newAnimation.setOnFinished(e -> {
setMouseTransparent(false);
getChildren().remove(previousNode);
if (previousNode != currentNode) {
getChildren().remove(previousNode);
}

Copilot AI Jan 24, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

onFinished can still run after a newer setContent(...) call has already started (or is about to start) another transition. In that case this callback may (a) call setMouseTransparent(false) too early for the newer transition, and (b) remove a node that a newer transition is currently animating (even if it’s not currentNode). Consider tracking a monotonically increasing transition/id (or storing the currently active Animation) and in onFinished only performing cleanup when this callback corresponds to the latest transition.

Copilot uses AI. Check for mistakes.
@Glavo Glavo merged commit e68b96f into HMCL-dev:main Jan 24, 2026
8 checks passed
@CiiLu CiiLu deleted the qwq branch January 24, 2026 14:03
Glavo added a commit that referenced this pull request Jan 28, 2026
#5305

Co-authored-by: 辞庐 <109708109+CiiLu@users.noreply.github.com>
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.

3 participants