diff --git a/quickshell/Modules/ControlCenter/ControlCenterPopout.qml b/quickshell/Modules/ControlCenter/ControlCenterPopout.qml index eedc3bb04..61345cc2a 100644 --- a/quickshell/Modules/ControlCenter/ControlCenterPopout.qml +++ b/quickshell/Modules/ControlCenter/ControlCenterPopout.qml @@ -21,7 +21,7 @@ DankPopout { property string pendingSection: "" property var triggerScreen: null property bool editMode: false - readonly property int gridColumnCap: CcMetrics.columnCapFor((triggerScreen?.width ?? CcMetrics.sheetWidthDefault + Theme.spacingL * 2) - Theme.spacingL * 2) + readonly property int gridColumnCap: CcMetrics.columnCapFor(maxBodyWidth > 0 ? maxBodyWidth - PopoutMetrics.editOverflow * 2 : CcMetrics.sheetWidthDefault) readonly property int gridColumns: Math.min(CcMetrics.gridColumns, gridColumnCap) readonly property real sheetContentWidth: CcMetrics.sheetWidthFor(gridColumns) readonly property real availableHeight: _maxPopupHeight() @@ -82,8 +82,9 @@ DankPopout { signal lockRequested function _maxPopupHeight() { - const screenHeight = triggerScreen?.height ?? CcMetrics.fallbackScreenHeight; - return screenHeight - CcMetrics.maxHeightInset; + if (maxBodyHeight <= 0) + return CcMetrics.fallbackScreenHeight - CcMetrics.maxHeightInset; + return maxBodyHeight - PopoutMetrics.editOverflow * 2; } function collapseAll() { diff --git a/quickshell/Widgets/DankPopout.qml b/quickshell/Widgets/DankPopout.qml index 108eaf0e7..1a8142ab5 100644 --- a/quickshell/Widgets/DankPopout.qml +++ b/quickshell/Widgets/DankPopout.qml @@ -110,6 +110,8 @@ Item { readonly property real renderedAlignedY: impl.item ? (impl.item.renderedAlignedY ?? impl.item.alignedY) : 0 readonly property real renderedAlignedWidth: impl.item ? (impl.item.renderedAlignedWidth ?? impl.item.alignedWidth) : 0 readonly property real renderedAlignedHeight: impl.item ? (impl.item.renderedAlignedHeight ?? impl.item.alignedHeight) : 0 + readonly property real maxBodyWidth: impl.item ? impl.item.maxBodyWidth : 0 + readonly property real maxBodyHeight: impl.item ? impl.item.maxBodyHeight : 0 function alignedXFor(width) { return impl.item?.alignedXFor(width) ?? 0; diff --git a/quickshell/Widgets/DankPopoutHost.qml b/quickshell/Widgets/DankPopoutHost.qml index adfbf29e9..07012ccf2 100644 --- a/quickshell/Widgets/DankPopoutHost.qml +++ b/quickshell/Widgets/DankPopoutHost.qml @@ -1256,6 +1256,54 @@ Item { readonly property real alignedX: alignedXFor(popupWidth) readonly property real alignedY: Theme.snap(connected ? _connectedAlignedY() : _standaloneAlignedY(), dpr) + function _maxBodyWidthFor(startGap, endGap, anchorX) { + switch (effectiveBarPosition) { + case SettingsData.Position.Left: + return screenWidth - anchorX - endGap; + case SettingsData.Position.Right: + return anchorX - startGap; + default: + return screenWidth - startGap - endGap; + } + } + + function _maxBodyHeightFor(startGap, endGap, anchorY) { + switch (effectiveBarPosition) { + case SettingsData.Position.Top: + return screenHeight - anchorY - endGap; + case SettingsData.Position.Bottom: + return anchorY - startGap; + default: + return screenHeight - startGap - endGap; + } + } + + readonly property real maxBodyWidth: { + if (connected) { + const popupGap = _popupGapValue(); + const startGap = Math.max(_edgeGapFor("left", popupGap), adjacentBarClearance(adjacentBarInfo.leftBar)); + const endGap = Math.max(_edgeGapFor("right", popupGap), adjacentBarClearance(adjacentBarInfo.rightBar)); + return Math.max(0, _maxBodyWidthFor(startGap, endGap, usesConnectedSurfaceChrome ? connectedAnchorX : triggerX)); + } + const popupGap = _standalonePopupGap(); + const startGap = _edgeClearance("left", popupGap, Math.max(0, adjacentBarInfo.leftBar)); + const endGap = _edgeClearance("right", popupGap, Math.max(0, adjacentBarInfo.rightBar)); + return Math.max(0, _maxBodyWidthFor(startGap, endGap, triggerX)); + } + + readonly property real maxBodyHeight: { + if (connected) { + const popupGap = _popupGapValue(); + const startGap = Math.max(_edgeGapFor("top", popupGap), adjacentBarClearance(adjacentBarInfo.topBar)); + const endGap = Math.max(_edgeGapFor("bottom", popupGap), adjacentBarClearance(adjacentBarInfo.bottomBar)); + return Math.max(0, _maxBodyHeightFor(startGap, endGap, usesConnectedSurfaceChrome ? connectedAnchorY : triggerY)); + } + const popupGap = _standalonePopupGap(); + const startGap = _edgeClearance("top", popupGap, Math.max(0, adjacentBarInfo.topBar)); + const endGap = _edgeClearance("bottom", popupGap, Math.max(0, adjacentBarInfo.bottomBar)); + return Math.max(0, _maxBodyHeightFor(startGap, endGap, triggerY)); + } + readonly property vector4d surfaceCornerRadii: chromeLoader.item?.surfaceCornerRadii ?? Qt.vector4d(Theme.windowRadius, Theme.windowRadius, Theme.windowRadius, Theme.windowRadius) readonly property real maskX: _dismissZone.x readonly property real maskY: _dismissZone.y