From ad32af6eeba2f29b2a2a695770c76488dd4c4539 Mon Sep 17 00:00:00 2001 From: purian23 Date: Mon, 22 Jun 2026 21:10:36 -0400 Subject: [PATCH] settings(dbar): add bar inset padding UI opts in framemode/stanalone Fixes #2597 --- quickshell/Common/SettingsData.qml | 7 ++ quickshell/Common/settings/SettingsSpec.js | 5 +- quickshell/Modules/DankBar/DankBarContent.qml | 70 +++++++++---------- quickshell/Modules/Settings/DankBarTab.qml | 69 +++++++++++++++++- quickshell/Modules/Settings/FrameTab.qml | 24 +++++++ 5 files changed, 137 insertions(+), 38 deletions(-) diff --git a/quickshell/Common/SettingsData.qml b/quickshell/Common/SettingsData.qml index a4444f0d..356ded1b 100644 --- a/quickshell/Common/SettingsData.qml +++ b/quickshell/Common/SettingsData.qml @@ -265,6 +265,12 @@ Singleton { onFrameEnabledChanged: saveSettings() property real frameThickness: 16 onFrameThicknessChanged: saveSettings() + property int barInsetPaddingShared: -1 + onBarInsetPaddingSharedChanged: saveSettings() + property bool barInsetPaddingSyncAll: false + onBarInsetPaddingSyncAllChanged: saveSettings() + property int frameBarInsetPadding: -1 + onFrameBarInsetPaddingChanged: saveSettings() property real frameRounding: 23 onFrameRoundingChanged: saveSettings() property string frameColor: "" @@ -849,6 +855,7 @@ Singleton { "rightWidgets": ["systemTray", "clipboard", "cpuUsage", "memUsage", "notificationButton", "battery", "controlCenterButton"], "spacing": 4, "innerPadding": 4, + "barInsetPadding": -1, "bottomGap": 0, "transparency": 1.0, "widgetTransparency": 1.0, diff --git a/quickshell/Common/settings/SettingsSpec.js b/quickshell/Common/settings/SettingsSpec.js index feefc7de..52089444 100644 --- a/quickshell/Common/settings/SettingsSpec.js +++ b/quickshell/Common/settings/SettingsSpec.js @@ -628,7 +628,10 @@ var SPEC = { frameCloseGaps: { def: true }, frameLauncherEmergeSide: { def: "bottom" }, frameLauncherArcExtender: { def: false }, - frameMode: { def: "connected" } + frameMode: { def: "connected" }, + barInsetPaddingShared: { def: -1 }, + barInsetPaddingSyncAll: { def: false }, + frameBarInsetPadding: { def: -1 } }; function getValidKeys() { diff --git a/quickshell/Modules/DankBar/DankBarContent.qml b/quickshell/Modules/DankBar/DankBarContent.qml index a3421d4b..c06b9e88 100644 --- a/quickshell/Modules/DankBar/DankBarContent.qml +++ b/quickshell/Modules/DankBar/DankBarContent.qml @@ -26,46 +26,50 @@ Item { readonly property real _edgeBaseMargin: Math.max(Theme.spacingXS, innerPadding * 0.8) readonly property bool _hasBarWindow: barWindow !== undefined && barWindow !== null readonly property bool _usesFrameBarChrome: _hasBarWindow && (barWindow.usesFrameBarChrome ?? false) - readonly property real _frameEdgeFloorInset: (SettingsData.frameEnabled && _usesFrameBarChrome) ? Math.max(0, SettingsData.frameThickness - _edgeBaseMargin) : 0 readonly property bool _barIsVertical: _hasBarWindow ? barWindow.isVertical : false readonly property string _barScreenName: _hasBarWindow ? (barWindow.screenName || "") : "" readonly property bool hasAdjacentTopBarLive: _hasBarWindow && barWindow.hasAdjacentTopBar readonly property bool hasAdjacentBottomBarLive: _hasBarWindow && barWindow.hasAdjacentBottomBar readonly property bool hasAdjacentLeftBarLive: _hasBarWindow && barWindow.hasAdjacentLeftBar readonly property bool hasAdjacentRightBarLive: _hasBarWindow && barWindow.hasAdjacentRightBar - property bool _hadAdjacentTopBar: false - property bool _hadAdjacentBottomBar: false - property bool _hadAdjacentLeftBar: false - property bool _hadAdjacentRightBar: false - onHasAdjacentTopBarLiveChanged: if (hasAdjacentTopBarLive) - _hadAdjacentTopBar = true - onHasAdjacentBottomBarLiveChanged: if (hasAdjacentBottomBarLive) - _hadAdjacentBottomBar = true - onHasAdjacentLeftBarLiveChanged: if (hasAdjacentLeftBarLive) - _hadAdjacentLeftBar = true - onHasAdjacentRightBarLiveChanged: if (hasAdjacentRightBarLive) - _hadAdjacentRightBar = true + // Standalone/separate Bar Inset Padding (per-bar, optionally synced): absolute gap at BOTH ends. + // Stored value < 0 (default -1) means "auto" — fall back to the natural edge margin so the look is unchanged. + readonly property real _barInsetPaddingRaw: SettingsData.barInsetPaddingSyncAll ? SettingsData.barInsetPaddingShared : (barConfig?.barInsetPadding ?? -1) + readonly property real _barInsetPaddingAuto: _barIsVertical ? Theme.spacingXS : _edgeBaseMargin + readonly property real _barInsetPadding: _barInsetPaddingRaw < 0 ? _barInsetPaddingAuto : _barInsetPaddingRaw + // Connected-frame Bar Inset Padding: absolute free-end inset (auto < 0 = frameThickness, 0 = edge-to-edge). + // Any amount beyond the frameThickness baseline is also added at the bar-clearance ends (all ends). + readonly property real _frameInsetResolved: SettingsData.frameBarInsetPadding < 0 ? SettingsData.frameThickness : SettingsData.frameBarInsetPadding + readonly property real _frameInsetExtra: Math.max(0, _frameInsetResolved - SettingsData.frameThickness) - readonly property real _frameLeftInset: { - if (!_hasBarWindow || !SettingsData.frameEnabled || !_usesFrameBarChrome || _barIsVertical) - return 0; - return hasAdjacentLeftBarLive ? SettingsData.frameBarSize : (_hadAdjacentLeftBar ? _frameEdgeFloorInset : 0); + readonly property real _leftMargin: { + if (_barIsVertical) + return _edgeBaseMargin; + if (_usesFrameBarChrome) + return hasAdjacentLeftBarLive ? (_edgeBaseMargin + SettingsData.frameBarSize + _frameInsetExtra) : Math.max(0, _frameInsetResolved); + return Math.max(0, _barInsetPadding); } - readonly property real _frameRightInset: { - if (!_hasBarWindow || !SettingsData.frameEnabled || !_usesFrameBarChrome || _barIsVertical) - return 0; - return hasAdjacentRightBarLive ? SettingsData.frameBarSize : (_hadAdjacentRightBar ? _frameEdgeFloorInset : 0); + readonly property real _rightMargin: { + if (_barIsVertical) + return _edgeBaseMargin; + if (_usesFrameBarChrome) + return hasAdjacentRightBarLive ? (_edgeBaseMargin + SettingsData.frameBarSize + _frameInsetExtra) : Math.max(0, _frameInsetResolved); + return Math.max(0, _barInsetPadding); } - readonly property real _frameTopInset: { - if (!_hasBarWindow || !SettingsData.frameEnabled || !_usesFrameBarChrome || !_barIsVertical) + readonly property real _topMargin: { + if (!_barIsVertical) return 0; - return hasAdjacentTopBarLive ? SettingsData.frameThickness : (_hadAdjacentTopBar ? _frameEdgeFloorInset : 0); + if (_usesFrameBarChrome) + return hasAdjacentTopBarLive ? (outlineThickness + SettingsData.frameThickness + _frameInsetExtra) : Math.max(0, _frameInsetResolved); + return Math.max(0, _barInsetPadding); } - readonly property real _frameBottomInset: { - if (!_hasBarWindow || !SettingsData.frameEnabled || !_usesFrameBarChrome || !_barIsVertical) + readonly property real _bottomMargin: { + if (!_barIsVertical) return 0; - return hasAdjacentBottomBarLive ? SettingsData.frameThickness : (_hadAdjacentBottomBar ? _frameEdgeFloorInset : 0); + if (_usesFrameBarChrome) + return hasAdjacentBottomBarLive ? (outlineThickness + SettingsData.frameThickness + _frameInsetExtra) : Math.max(0, _frameInsetResolved); + return Math.max(0, _barInsetPadding); } property alias hLeftSection: hLeftSection @@ -76,10 +80,10 @@ Item { property alias vRightSection: vRightSection anchors.fill: parent - anchors.leftMargin: _edgeBaseMargin + _frameLeftInset - anchors.rightMargin: _edgeBaseMargin + _frameRightInset - anchors.topMargin: (_barIsVertical ? (hasAdjacentTopBarLive ? outlineThickness : Theme.spacingXS) : 0) + _frameTopInset - anchors.bottomMargin: (_barIsVertical ? (hasAdjacentBottomBarLive ? outlineThickness : Theme.spacingXS) : 0) + _frameBottomInset + anchors.leftMargin: _leftMargin + anchors.rightMargin: _rightMargin + anchors.topMargin: _topMargin + anchors.bottomMargin: _bottomMargin clip: false DeferredAction { @@ -88,10 +92,6 @@ Item { } Component.onCompleted: { - _hadAdjacentTopBar = hasAdjacentTopBarLive; - _hadAdjacentBottomBar = hasAdjacentBottomBarLive; - _hadAdjacentLeftBar = hasAdjacentLeftBarLive; - _hadAdjacentRightBar = hasAdjacentRightBarLive; enableFrameInsetAnimation.schedule(); } diff --git a/quickshell/Modules/Settings/DankBarTab.qml b/quickshell/Modules/Settings/DankBarTab.qml index 578c3d83..9df9269b 100644 --- a/quickshell/Modules/Settings/DankBarTab.qml +++ b/quickshell/Modules/Settings/DankBarTab.qml @@ -52,6 +52,13 @@ Item { } readonly property bool connectedFrameModeActive: SettingsData.connectedFrameModeActive + // Bar Inset Padding: resolve the "auto" sentinel (stored < 0) to each mode's natural inset for the slider display. + readonly property real insetPadAutoUI: SettingsData.connectedFrameModeActive ? SettingsData.frameThickness : (selectedBarIsVertical ? Theme.spacingXS : Math.max(Theme.spacingXS, (selectedBarConfig?.innerPadding ?? 4) * 0.8)) + readonly property int insetPadDisplayValue: { + const raw = SettingsData.barInsetPaddingSyncAll ? SettingsData.barInsetPaddingShared : (selectedBarConfig?.barInsetPadding ?? -1); + return raw < 0 ? Math.round(insetPadAutoUI) : raw; + } + Timer { id: horizontalBarChangeDebounce interval: 500 @@ -863,10 +870,18 @@ Item { iconName: "space_bar" title: I18n.tr("Spacing") settingKey: "barSpacing" - visible: dankBarTab.appearanceOnly && (selectedBarConfig?.enabled ?? false) && !SettingsData.frameEnabled + visible: dankBarTab.appearanceOnly && (selectedBarConfig?.enabled ?? false) + + SettingsControlledByFrame { + visible: SettingsData.frameEnabled + parentModal: dankBarTab.parentModal + settingLabel: I18n.tr("Bar Spacing") + reason: I18n.tr("Edge spacing, exclusive zone, and popup gaps are managed by Frame") + } SettingsSliderRow { id: edgeSpacingSlider + visible: !SettingsData.frameEnabled text: I18n.tr("Edge Spacing") description: I18n.tr("Space between the bar and screen edges") value: selectedBarConfig?.spacing ?? 4 @@ -889,6 +904,7 @@ Item { SettingsSliderRow { id: exclusiveZoneSlider + visible: !SettingsData.frameEnabled text: I18n.tr("Exclusive Zone Offset") description: I18n.tr("Fine-tune the space reserved for the bar from the screen edge") value: selectedBarConfig?.bottomGap ?? 0 @@ -911,6 +927,7 @@ Item { SettingsSliderRow { id: sizeSlider + visible: !SettingsData.frameEnabled text: I18n.tr("Size") description: I18n.tr("Adjust the bar height via inner padding") value: selectedBarConfig?.innerPadding ?? 4 @@ -933,6 +950,7 @@ Item { SettingsSliderRow { id: widgetPaddingSlider + visible: !SettingsData.frameEnabled text: I18n.tr("Padding") description: I18n.tr("Inner padding applied to each widget") value: selectedBarConfig?.widgetPadding ?? 8 @@ -961,9 +979,56 @@ Item { height: 1 color: Theme.outline opacity: 0.15 + visible: !SettingsData.frameEnabled + } + + SettingsSliderRow { + id: barInsetPaddingSlider + visible: !SettingsData.frameEnabled + text: I18n.tr("Bar Inset Padding") + description: I18n.tr("Gap between the end widgets and both bar ends (0 = edge-to-edge)") + tags: ["bar", "padding", "inset", "edge", "corner", "end"] + unit: "px" + minimum: 0 + maximum: 48 + defaultValue: Math.round(dankBarTab.insetPadAutoUI) + value: dankBarTab.insetPadDisplayValue + onSliderDragFinished: finalValue => { + if (SettingsData.barInsetPaddingSyncAll) + SettingsData.set("barInsetPaddingShared", finalValue); + else + SettingsData.updateBarConfig(selectedBarId, { + barInsetPadding: finalValue + }); + } + + Binding { + target: barInsetPaddingSlider + property: "value" + value: dankBarTab.insetPadDisplayValue + restoreMode: Binding.RestoreBinding + } } SettingsToggleRow { + visible: !SettingsData.frameEnabled + text: I18n.tr("Sync Bar Inset Padding") + description: I18n.tr("Use one inset value for every bar") + tags: ["bar", "padding", "inset", "edge", "sync", "all", "global"] + checked: SettingsData.barInsetPaddingSyncAll + onToggled: checked => SettingsData.set("barInsetPaddingSyncAll", checked) + } + + Rectangle { + width: parent.width + height: 1 + color: Theme.outline + opacity: 0.15 + visible: !SettingsData.frameEnabled + } + + SettingsToggleRow { + visible: !SettingsData.frameEnabled text: I18n.tr("Auto Popup Gaps") description: I18n.tr("Automatically calculate popup gap based on bar spacing") checked: selectedBarConfig?.popupGapsAuto ?? true @@ -978,7 +1043,7 @@ Item { width: parent.width leftPadding: Theme.spacingM spacing: Theme.spacingM - visible: !(selectedBarConfig?.popupGapsAuto ?? true) + visible: !SettingsData.frameEnabled && !(selectedBarConfig?.popupGapsAuto ?? true) Rectangle { width: parent.width - parent.leftPadding diff --git a/quickshell/Modules/Settings/FrameTab.qml b/quickshell/Modules/Settings/FrameTab.qml index cce94e64..78bb5b65 100644 --- a/quickshell/Modules/Settings/FrameTab.qml +++ b/quickshell/Modules/Settings/FrameTab.qml @@ -12,6 +12,9 @@ Item { LayoutMirroring.enabled: I18n.isRtl LayoutMirroring.childrenInherit: true + // Bar Inset Padding: resolve the "auto" sentinel (stored < 0) to the frame thickness for the slider display. + readonly property int frameInsetPaddingDisplay: SettingsData.frameBarInsetPadding < 0 ? Math.round(SettingsData.frameThickness) : SettingsData.frameBarInsetPadding + DankFlickable { anchors.fill: parent clip: true @@ -158,6 +161,27 @@ Item { } } + SettingsSliderRow { + id: frameBarInsetPaddingSlider + settingKey: "frameBarInsetPadding" + tags: ["frame", "bar", "edge", "inset", "padding", "corner", "end"] + text: I18n.tr("Bar Inset Padding") + description: I18n.tr("Gap between the end widgets and the bar ends (0 = edge-to-edge)") + unit: "px" + minimum: 0 + maximum: 48 + step: 1 + defaultValue: Math.round(SettingsData.frameThickness) + value: root.frameInsetPaddingDisplay + onSliderDragFinished: v => SettingsData.set("frameBarInsetPadding", v) + + Binding { + target: frameBarInsetPaddingSlider + property: "value" + value: root.frameInsetPaddingDisplay + } + } + SettingsToggleRow { id: frameBlurToggle settingKey: "frameBlurEnabled"