From 9873cd216531f213e39e41a871551bf9430c7420 Mon Sep 17 00:00:00 2001 From: chenyuanbo Date: Tue, 16 Jun 2026 14:22:02 +0800 Subject: [PATCH] fix(dock): Adjust the calculation logic of dockItemMaxSize MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the empirical formula with an algebraic solution that folds other-applet space into the equation denominator. Move remaining-space computation into TaskManager to clarify ownership. No reference on dockItemMaxSize — all inputs are independent properties. 将经验公式替换为精确的代数求解,消除 dockItemMaxSize 绑定循环,精简属性结构。 Log: 修改 dockItemMaxSize 的计算逻辑 PMS: BUG-360867 Influence: 显示/折叠右侧区域,中间区域空间充足,不自动放缩中间区域应用图标;任务栏水平和垂直显示时,消除中间区域与右侧区域的重叠; --- panels/dock/package/main.qml | 16 ++---- .../dock/taskmanager/package/TaskManager.qml | 52 ++++++++++++++++++- 2 files changed, 55 insertions(+), 13 deletions(-) diff --git a/panels/dock/package/main.qml b/panels/dock/package/main.qml index b7d7e87b1..ded6c54e4 100644 --- a/panels/dock/package/main.qml +++ b/panels/dock/package/main.qml @@ -21,19 +21,11 @@ Window { property bool useColumnLayout: positionForAnimation % 2 property int dockCenterPartCount: dockCenterPartModel.count - property int dockRemainingSpaceForCenter: { - const otherCount = dockCenterPartCount - 1; // not include taskmanager - const spacing = useColumnLayout ? gridLayout.rowSpacing : gridLayout.columnSpacing; - - let otherOccupied = 0; - if (otherCount > 0) { - otherOccupied = otherCount * dockItemIconSize + otherCount * spacing; - } - + readonly property int dockRawCenterSpace: { if (useColumnLayout) { - return Screen.height - dockLeftPart.implicitHeight - dockRightPart.implicitHeight - otherOccupied; + return Screen.height - dockLeftPart.implicitHeight - dockRightPart.implicitHeight; } else { - return Screen.width - dockLeftPart.implicitWidth - dockRightPart.implicitWidth - otherOccupied; + return Screen.width - dockLeftPart.implicitWidth - dockRightPart.implicitWidth; } } @@ -538,6 +530,8 @@ Window { id: dockCenterPart implicitWidth: centerLoader.implicitWidth implicitHeight: centerLoader.implicitHeight + Layout.maximumWidth: useColumnLayout ? -1 : dockRawCenterSpace + Layout.maximumHeight: useColumnLayout ? dockRawCenterSpace : -1 onXChanged: dockCenterPartPosChanged() onYChanged: dockCenterPartPosChanged() Layout.leftMargin: !useColumnLayout && Panel.itemAlignment === Dock.CenterAlignment ? diff --git a/panels/dock/taskmanager/package/TaskManager.qml b/panels/dock/taskmanager/package/TaskManager.qml index d2cb25e4e..e143b060e 100644 --- a/panels/dock/taskmanager/package/TaskManager.qml +++ b/panels/dock/taskmanager/package/TaskManager.qml @@ -14,7 +14,11 @@ ContainmentItem { id: taskmanager property bool useColumnLayout: Panel.rootObject.useColumnLayout property int dockOrder: 16 - property real remainingSpacesForTaskManager: Panel.rootObject.dockRemainingSpaceForCenter + readonly property real remainingSpacesForTaskManager: { + const otherCount = Panel.rootObject.dockCenterPartCount - 1; + const otherOccupied = otherCount > 0 ? otherCount * Panel.rootObject.dockItemMaxSize * 0.8 : 0; + return Panel.rootObject.dockRawCenterSpace - otherOccupied; + } readonly property int appTitleSpacing: Math.max(10, Math.round(Panel.rootObject.dockItemMaxSize * 9 / 14) / 3) // Start padding for the app container so that the visual gap // (multitask icon right edge → first app icon left edge) = appTitleSpacing. @@ -289,9 +293,53 @@ ContainmentItem { } } + + // Solve for S (dockItemMaxSize). The forward layout equation is: + // totalSpace = appCount×S×itemRatio + gaps×max(10, S×spacingRatio) + // + max(0, spacing - S×k) + otherCount×S×multitaskViewIconRatio + // + // The max(10,…) makes this piecewise. Ignoring Math.round (continuous approx): + // + // Regime 1 (S×spacingRatio ≥ 10): no clamp, every term ∝ S. + // Factor out S → S = totalSpace / sum_of_coefficients. + // + // Regime 2 (S×spacingRatio < 10): spacing clamped to 10 (constant). + // startPad flips from S×(spacingRatio-k) to 10 - S×k. + // Separate constants from S-terms → S = (total - constants) / S_coefficient. + function solveMaxSizeFull(totalSpace, appCount, otherCount) { + if (appCount <= 0) { + return totalSpace; + } + + const spacingRatio = iconWidthToMaxSizeRatio / 3; // 9/14 / 3 + const k = (multitaskViewIconRatio - iconWidthToMaxSizeRatio) / 2; // ≈ 0.0786 + const gaps = Math.max(0, appCount - 1); + const otherRatio = otherCount > 0 ? otherCount * multitaskViewIconRatio : 0; + + // Regime 1: continuous spacing model + const S = totalSpace / (appCount * iconWidthToMaxSizeRatio + gaps * spacingRatio + otherRatio + spacingRatio - k); + + // Regime 2: spacing clamped to 10 + if (S * spacingRatio < 10) { + return Math.max(0, (totalSpace - gaps * 10 - 10) / (appCount * iconWidthToMaxSizeRatio - k + otherRatio)); + } + return Math.max(0, S); + } + Component.onCompleted: { Panel.rootObject.dockItemMaxSize = Qt.binding(function(){ - return Math.min(Panel.rootObject.dockSize, Panel.rootObject.dockRemainingSpaceForCenter * 1.2 / (Panel.rootObject.dockCenterPartCount - 1 + visualModel.count) - 2) + const dockSize = Panel.rootObject.dockSize; + const appCount = visualModel.count; + + if (appCount <= 0 || dockSize <= 0) + return dockSize; + + if (textCalculator.enabled && textCalculator.totalWidth > 0) + return dockSize; + + const otherItems = Math.max(0, Panel.rootObject.dockCenterPartCount - 1); + const optimal = solveMaxSizeFull(Panel.rootObject.dockRawCenterSpace, appCount, otherItems); + return optimal >= dockSize ? dockSize : optimal; }) } }