From 209d574d109917036429fcb76470f9de9e5906b5 Mon Sep 17 00:00:00 2001 From: fuleyi Date: Thu, 16 Jul 2026 13:39:15 +0800 Subject: [PATCH] fix(dock): smart hide fails to show dock after window dragged away MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SmartHide 模式下,show 动画结束后 onStopped 无条件重启 hideTimer, 导致 dock 显示后 500ms 又被隐藏。同时 onHideStateChanged 的 Show 分支未停掉 QML hideTimer,且 hideShowAnimation.restart() 可能被 已运行的动画阻塞。 1. onStopped 中增加 Panel.hideState !== Dock.Show 判断,Show 状态 下不再重启 hideTimer 2. onHideStateChanged Show 分支中先 hideTimer.stop() 再 restart() show 动画,并强制设置 dock.visible = true Log: 修复 SmartHide 模式下拖动窗口脱离任务栏后任务栏不自动显示的问题 PMS: BUG-370149 Influence: 1. SmartHide 模式下拖动窗口与任务栏重叠后移开,验证任务栏自动显示 2. SmartHide 模式下快速反复拖动窗口进出任务栏区域,验证无闪烁或卡住 3. KeepShowing 和 KeepHidden 模式下验证任务栏行为无回归 4. 任务栏显示动画过程中再次触发隐藏,验证动画状态正确切换 5. 右键菜单弹出时拖动窗口,验证菜单和任务栏状态无冲突 --- panels/dock/package/main.qml | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/panels/dock/package/main.qml b/panels/dock/package/main.qml index 68e8931e6..91b4ea2f6 100644 --- a/panels/dock/package/main.qml +++ b/panels/dock/package/main.qml @@ -106,6 +106,7 @@ Window { id: hideShowAnimation; // Currently, Wayland (Treeland) doesn't support StyledBehindWindowBlur inside the window, thus we keep using the window size approach on Wayland property bool useTransformBasedAnimation: Qt.platform.pluginName === "xcb" + property bool hiding: false target: useTransformBasedAnimation ? dockTransform : dock; property: { if (useTransformBasedAnimation) return dock.useColumnLayout ? "x" : "y"; @@ -118,6 +119,7 @@ Window { duration: 500 easing.type: Easing.OutCubic onStarted: { + hiding = Panel.hideState === Dock.Hide dock.visible = true } onStopped: { @@ -253,15 +255,10 @@ Window { setTransformToHiddenPosition(); startAnimation(true); - } else if (isShowing) { - // After show animation completes, check if we need to auto-hide - // For KeepHidden and SmartHide modes, trigger hide check immediately - if (Panel.hideMode === Dock.KeepHidden || Panel.hideMode === Dock.SmartHide) { - hideTimer.running = true; - } else if (Panel.hideState === Dock.Hide) { - // For other cases, if hideState is already Hide, trigger hide animation - hideTimer.running = true; - } + } else if (isShowing && Panel.hideState === Dock.Hide) { + // Restore the backend-requested hidden state after the + // position-change show animation has completed. + hideTimer.restart(); } } } @@ -735,6 +732,8 @@ Window { Connections { function onBeforePositionChanged(beforePosition) { + // Prevent the delayed hide animation from racing the position animation. + hideTimer.stop(); // Stop any running animations first dockAnimation.stop(); hideShowAnimation.stop(); @@ -776,12 +775,16 @@ Window { function onHideStateChanged() { if (Panel.hideState === Dock.Hide) { - hideTimer.running = true - } else { - // Only restart animation if not already running or if visible state doesn't match - if (!hideShowAnimation.running || !dock.visible) { + hideTimer.restart() + } else if (Panel.hideState === Dock.Show) { + hideTimer.stop() + + // Reverse an in-flight hide animation, but do not restart an + // animation that is already moving towards the shown state. + if (!hideShowAnimation.running || hideShowAnimation.hiding || !dock.visible) { hideShowAnimation.restart() } + dock.visible = true } } function onRequestClosePopup() {