fix(dock): layout & indicator misalignment on orientation switch (#3256)

* fix(dock): fix solid mask regression and geometry distortion when switching orientation in frame mode

* fix(dock): fix running app indicator misalignment on orientation change

* fix(dock): center multi-window running indicators around app icon

* fix(dock): fix vertical hit area collapse and transient background flicker on position change
This commit is contained in:
Huỳnh Thiện Lộc
2026-09-02 00:39:23 -04:00
committed by GitHub
parent dd068dbd13
commit 226868b6f0
3 changed files with 54 additions and 57 deletions
+11 -11
View File
@@ -584,19 +584,15 @@ Item {
}
Loader {
anchors.horizontalCenter: SettingsData.dockPosition === SettingsData.Position.Left || SettingsData.dockPosition === SettingsData.Position.Right ? undefined : parent.horizontalCenter
anchors.verticalCenter: SettingsData.dockPosition === SettingsData.Position.Left || SettingsData.dockPosition === SettingsData.Position.Right ? parent.verticalCenter : undefined
anchors.bottom: SettingsData.dockPosition === SettingsData.Position.Bottom ? parent.bottom : undefined
anchors.top: SettingsData.dockPosition === SettingsData.Position.Top ? parent.top : undefined
anchors.left: SettingsData.dockPosition === SettingsData.Position.Left ? parent.left : undefined
anchors.right: SettingsData.dockPosition === SettingsData.Position.Right ? parent.right : undefined
anchors.bottomMargin: SettingsData.dockPosition === SettingsData.Position.Bottom ? -(SettingsData.dockSpacing / 2 + 1.4) : 0
anchors.topMargin: SettingsData.dockPosition === SettingsData.Position.Top ? -(SettingsData.dockSpacing / 2 + 1.4) : 0
anchors.leftMargin: SettingsData.dockPosition === SettingsData.Position.Left ? -(SettingsData.dockSpacing / 2 + 1.4) : 0
anchors.rightMargin: SettingsData.dockPosition === SettingsData.Position.Right ? -(SettingsData.dockSpacing / 2 + 1.4) : 0
readonly property real indicatorOffset: SettingsData.dockSpacing / 2 + 1.4
sourceComponent: SettingsData.dockPosition === SettingsData.Position.Left || SettingsData.dockPosition === SettingsData.Position.Right ? columnIndicator : rowIndicator
width: item ? item.implicitWidth : 0
height: item ? item.implicitHeight : 0
x: !root.isVertical ? Math.round((parent.width - width) / 2) : (SettingsData.dockPosition === SettingsData.Position.Right ? parent.width - width + indicatorOffset : -indicatorOffset)
y: root.isVertical ? Math.round((parent.height - height) / 2) : (SettingsData.dockPosition === SettingsData.Position.Bottom ? parent.height - height + indicatorOffset : -indicatorOffset)
sourceComponent: root.isVertical ? columnIndicator : rowIndicator
visible: root.shouldShowIndicator
}
}
@@ -606,6 +602,8 @@ Item {
Row {
spacing: Theme.spacingXXS
width: implicitWidth
height: implicitHeight
Repeater {
model: {
@@ -664,6 +662,8 @@ Item {
Column {
spacing: Theme.spacingXXS
width: implicitWidth
height: implicitHeight
Repeater {
model: {
+10 -5
View File
@@ -44,6 +44,7 @@ Item {
readonly property real baseAppHeight: iconSize
clip: false
property bool _switchingPosition: false
implicitWidth: isVertical ? appLayout.height : appLayout.width
implicitHeight: isVertical ? appLayout.width : appLayout.height
@@ -77,6 +78,7 @@ Item {
height: layoutFlow.height
Behavior on width {
enabled: !root._switchingPosition
NumberAnimation {
duration: Theme.shortDuration
easing.type: Easing.OutCubic
@@ -84,16 +86,13 @@ Item {
}
Behavior on height {
enabled: !root._switchingPosition
NumberAnimation {
duration: Theme.shortDuration
easing.type: Easing.OutCubic
}
}
anchors.horizontalCenter: root.isVertical ? undefined : parent.horizontalCenter
anchors.verticalCenter: root.isVertical ? parent.verticalCenter : undefined
anchors.left: root.isVertical && SettingsData.dockPosition === SettingsData.Position.Left ? parent.left : undefined
anchors.right: root.isVertical && SettingsData.dockPosition === SettingsData.Position.Right ? parent.right : undefined
anchors.top: root.isVertical ? undefined : parent.top
anchors.centerIn: parent
Flow {
id: layoutFlow
@@ -722,6 +721,12 @@ Item {
Connections {
target: SettingsData
function onDockPositionChanged() {
root._switchingPosition = true;
Qt.callLater(() => {
root._switchingPosition = false;
});
}
function onDockIsolateDisplaysChanged() {
repeater.updateModel();
}
+33 -41
View File
@@ -403,7 +403,17 @@ Item {
onHeightChanged: dock._syncDockChromeState()
onVisibleChanged: dock._syncDockChromeState()
onHasAppsChanged: dock._syncDockChromeState()
onConnectedBarSideChanged: dock._syncDockChromeState()
property bool _switchingPosition: false
onConnectedBarSideChanged: {
dock._switchingPosition = true;
slideXSpring.snapTo(dock.isVertical ? dockSlide.targetX : 0);
slideYSpring.snapTo(!dock.isVertical ? dockSlide.targetY : 0);
dockChromeSync.schedule();
Qt.callLater(() => {
dock._switchingPosition = false;
});
}
onUsesConnectedFrameChromeChanged: dock._syncDockChromeState()
Connections {
@@ -623,8 +633,8 @@ Item {
height: {
if (dock.isVertical) {
// Keep the taller hit area regardless of the reveal state to prevent shrinking loop
return Math.min(Math.max(dockBackground.height + 64, 200), maxDockHeight);
const h = dockApps.implicitWidth + SettingsData.dockSpacing * 2;
return Math.min(Math.max(h + 64, 200), maxDockHeight);
}
return dock.reveal ? Theme.px(dockGeometry.motionThickness, _dpr) : 1;
}
@@ -632,21 +642,16 @@ Item {
if (dock.isVertical) {
return dock.reveal ? Theme.px(dockGeometry.motionThickness, _dpr) : 1;
}
// Keep the wider hit area regardless of the reveal state to prevent shrinking loop
return Math.min(dockBackground.width + 8 + dock.borderThickness, maxDockWidth);
}
anchors {
top: !dock.isVertical ? (SettingsData.dockPosition === SettingsData.Position.Bottom ? undefined : parent.top) : undefined
bottom: !dock.isVertical ? (SettingsData.dockPosition === SettingsData.Position.Bottom ? parent.bottom : undefined) : undefined
horizontalCenter: !dock.isVertical ? parent.horizontalCenter : undefined
left: dock.isVertical ? (SettingsData.dockPosition === SettingsData.Position.Right ? undefined : parent.left) : undefined
right: dock.isVertical ? (SettingsData.dockPosition === SettingsData.Position.Right ? parent.right : undefined) : undefined
verticalCenter: dock.isVertical ? parent.verticalCenter : undefined
const w = dockApps.implicitWidth + SettingsData.dockSpacing * 2;
return Math.min(w + 8 + dock.borderThickness, maxDockWidth);
}
x: !dock.isVertical ? Math.round((parent.width - width) / 2) : (SettingsData.dockPosition === SettingsData.Position.Right ? parent.width - width : 0)
y: dock.isVertical ? Math.round((parent.height - height) / 2) : (SettingsData.dockPosition === SettingsData.Position.Bottom ? parent.height - height : 0)
hoverEnabled: true
acceptedButtons: Qt.NoButton
Behavior on height {
enabled: !dock._switchingPosition
NumberAnimation {
duration: Theme.shortDuration
easing.type: Easing.OutCubic
@@ -654,12 +659,16 @@ Item {
}
Behavior on width {
enabled: !dock._switchingPosition
NumberAnimation {
duration: Theme.shortDuration
easing.type: Easing.OutCubic
}
}
onXChanged: dockChromeSync.schedule()
onYChanged: dockChromeSync.schedule()
Item {
id: dockContainer
anchors.fill: parent
@@ -702,8 +711,8 @@ Item {
}
}
x: slideXSpring.value
y: slideYSpring.value
x: dock.isVertical ? slideXSpring.value : 0
y: !dock.isVertical ? slideYSpring.value : 0
onTargetXChanged: slideXSpring.retarget(targetX)
onTargetYChanged: slideYSpring.retarget(targetY)
@@ -716,18 +725,8 @@ Item {
id: dockBackground
objectName: "dockBackground"
visible: dock.hasApps
anchors {
top: !dock.isVertical ? (SettingsData.dockPosition === SettingsData.Position.Top ? parent.top : undefined) : undefined
bottom: !dock.isVertical ? (SettingsData.dockPosition === SettingsData.Position.Bottom ? parent.bottom : undefined) : undefined
horizontalCenter: !dock.isVertical ? parent.horizontalCenter : undefined
left: dock.isVertical ? (SettingsData.dockPosition === SettingsData.Position.Left ? parent.left : undefined) : undefined
right: dock.isVertical ? (SettingsData.dockPosition === SettingsData.Position.Right ? parent.right : undefined) : undefined
verticalCenter: dock.isVertical ? parent.verticalCenter : undefined
}
anchors.topMargin: !dock.isVertical && SettingsData.dockPosition === SettingsData.Position.Top ? dockGeometry.bodyEdgeMargin : 0
anchors.bottomMargin: !dock.isVertical && SettingsData.dockPosition === SettingsData.Position.Bottom ? dockGeometry.bodyEdgeMargin : 0
anchors.leftMargin: dock.isVertical && SettingsData.dockPosition === SettingsData.Position.Left ? dockGeometry.bodyEdgeMargin : 0
anchors.rightMargin: dock.isVertical && SettingsData.dockPosition === SettingsData.Position.Right ? dockGeometry.bodyEdgeMargin : 0
x: !dock.isVertical ? Math.round((parent.width - width) / 2) : (SettingsData.dockPosition === SettingsData.Position.Right ? parent.width - width - dockGeometry.bodyEdgeMargin : dockGeometry.bodyEdgeMargin)
y: dock.isVertical ? Math.round((parent.height - height) / 2) : (SettingsData.dockPosition === SettingsData.Position.Bottom ? parent.height - height - dockGeometry.bodyEdgeMargin : dockGeometry.bodyEdgeMargin)
implicitWidth: dock.isVertical ? (dockApps.implicitHeight + SettingsData.dockSpacing * 2) : (dockApps.implicitWidth + SettingsData.dockSpacing * 2)
implicitHeight: dock.isVertical ? (dockApps.implicitWidth + SettingsData.dockSpacing * 2) : (dockApps.implicitHeight + SettingsData.dockSpacing * 2)
@@ -762,10 +761,10 @@ Item {
}
// Sync dockBackground geometry to ConnectedModeState
onXChanged: dock._syncDockChromeState()
onYChanged: dock._syncDockChromeState()
onWidthChanged: dock._syncDockChromeState()
onHeightChanged: dock._syncDockChromeState()
onXChanged: dockChromeSync.schedule()
onYChanged: dockChromeSync.schedule()
onWidthChanged: dockChromeSync.schedule()
onHeightChanged: dockChromeSync.schedule()
}
Item {
@@ -865,16 +864,9 @@ Item {
DockApps {
id: dockApps
anchors.top: !dock.isVertical ? (SettingsData.dockPosition === SettingsData.Position.Top ? dockBackground.top : undefined) : undefined
anchors.bottom: !dock.isVertical ? (SettingsData.dockPosition === SettingsData.Position.Bottom ? dockBackground.bottom : undefined) : undefined
anchors.horizontalCenter: !dock.isVertical ? dockBackground.horizontalCenter : undefined
anchors.left: dock.isVertical ? (SettingsData.dockPosition === SettingsData.Position.Left ? dockBackground.left : undefined) : undefined
anchors.right: dock.isVertical ? (SettingsData.dockPosition === SettingsData.Position.Right ? dockBackground.right : undefined) : undefined
anchors.verticalCenter: dock.isVertical ? dockBackground.verticalCenter : undefined
anchors.topMargin: !dock.isVertical ? SettingsData.dockSpacing : 0
anchors.bottomMargin: !dock.isVertical ? SettingsData.dockSpacing : 0
anchors.leftMargin: dock.isVertical ? SettingsData.dockSpacing : 0
anchors.rightMargin: dock.isVertical ? SettingsData.dockSpacing : 0
width: dock.isVertical ? implicitHeight : implicitWidth
height: dock.isVertical ? implicitWidth : implicitHeight
anchors.centerIn: dockBackground
contextMenu: dock.contextMenu
trashContextMenu: dock.trashContextMenu