From 72c38acaa82c59f12371578da93ae98ab5494a0a Mon Sep 17 00:00:00 2001 From: Ivy233 Date: Fri, 16 Jan 2026 09:32:01 +0800 Subject: [PATCH] fix: Fix display issues when switching dock position Improve position switching logic with smooth transition animations: 1. Save new position and temporarily restore to old position when switching 2. Play hide animation at old position 3. Switch to new position and play show animation from hidden state 4. Use state flags to precisely control animation flow and avoid flickering This ensures the dock doesn't show blank areas, content overflow, or sudden jumps during position changes. Log: Fix display issues when switching dock position PMS: BUG-346777 --- panels/dock/package/main.qml | 113 ++++++++++++++++++++++++++++------- 1 file changed, 90 insertions(+), 23 deletions(-) diff --git a/panels/dock/package/main.qml b/panels/dock/package/main.qml index 49a935a6d..ec07c3b2f 100644 --- a/panels/dock/package/main.qml +++ b/panels/dock/package/main.qml @@ -165,6 +165,7 @@ Window { id: dockAnimation property bool useTransformBasedAnimation: Qt.platform.pluginName === "xcb" property bool isShowing: false + property bool isPositionChanging: false property var target: useTransformBasedAnimation ? dockTransform : dock property string animProperty: { if (useTransformBasedAnimation) return dock.useColumnLayout ? "x" : "y"; @@ -212,6 +213,17 @@ Window { } else { dock.visible = ((dock.useColumnLayout ? dock.width : dock.height) !== 1); } + + // If this was a hide animation during position change, handle the position change now + if (isPositionChanging && !isShowing) { + isPositionChanging = false; + positionChangeConnections.handlePositionChangeAfterHide(); + } else { + // If this was a show animation and dock should be hidden, trigger auto-hide + if (isShowing && Panel.hideState === Dock.Hide) { + hideTimer.running = true; + } + } } } @@ -221,34 +233,20 @@ Window { required property int value text: name - property var positionChangeCallback: function() { - // Disconnect any existing callback first - dockAnimation.onStopped.disconnect(positionChangeCallback); - // Stop any running animations first --fix bug with do not show dock - dockAnimation.stop(); - // Reset transform before starting new animation--fix bug with change position,will have a blank area - dockTransform.x = 0; - dockTransform.y = 0; + onTriggered: { + if (Applet[prop] === value) { + // Manually restore checked state since Qt already toggled it + checked = true; + return; + } + Applet[prop] = value + } - Applet[prop] = value; + Component.onCompleted: { checked = Qt.binding(function() { return Applet[prop] === value; }); - dockAnimation.startAnimation(true); - } - onTriggered: { - if (prop === "position") { - // Connect the callback and start the hide animation - dockAnimation.onStopped.connect(positionChangeCallback); - dockAnimation.startAnimation(false); - } else { - Applet[prop] = value - checked = Qt.binding(function() { - return Applet[prop] === value - }) - } } - checked: Applet[prop] === value } component MutuallyExclusiveMenu: LP.Menu { id: menu @@ -665,9 +663,78 @@ Window { } Connections { + id: positionChangeConnections + property int previousPosition: Panel.position + property int savedNewPosition: -1 + property bool isRestoringPosition: false + function onPositionChanged() { + // Ignore position changes triggered by our own restore operation + if (isRestoringPosition) { + return; + } + + // Save the new position + savedNewPosition = Panel.position; + + // Set flag to ignore the next position change + isRestoringPosition = true; + + // Temporarily restore to previous position for hide animation + Applet.position = previousPosition; + + // Clear the flag after restore + isRestoringPosition = false; + + // Stop any running animations first + dockAnimation.stop(); + hideShowAnimation.stop(); + + // Mark that we're changing position + dockAnimation.isPositionChanging = true; + + // Check if dock is currently hidden + if (Panel.hideState === Dock.Hide && !dock.visible) { + // Directly handle position change without animation + dockAnimation.isPositionChanging = false; + handlePositionChangeAfterHide(); + } else { + // Start hide animation at old position + dockAnimation.startAnimation(false); + } + } + + function handlePositionChangeAfterHide() { + if (savedNewPosition === -1) return; + + // Apply position change + previousPosition = savedNewPosition; + Applet.position = savedNewPosition; + savedNewPosition = -1; + changeDragAreaAnchor() Panel.requestClosePopup() + + // Set transform to hidden position before showing + if (dockAnimation.useTransformBasedAnimation) { + var hideOffset = (Applet.position === Dock.Left || Applet.position === Dock.Top) ? -Panel.dockSize : Panel.dockSize; + if (dock.useColumnLayout) { + dockTransform.x = hideOffset; + dockTransform.y = 0; + } else { + dockTransform.x = 0; + dockTransform.y = hideOffset; + } + } else { + dockTransform.x = 0; + dockTransform.y = 0; + } + + dockAnimation.startAnimation(true); + } + + Component.onCompleted: { + previousPosition = Panel.position } function onDockSizeChanged() { dock.dockSize = Panel.dockSize