diff --git a/quickshell/Common/SettingsData.qml b/quickshell/Common/SettingsData.qml index 75fcdca0..423dae6b 100644 --- a/quickshell/Common/SettingsData.qml +++ b/quickshell/Common/SettingsData.qml @@ -167,6 +167,14 @@ Singleton { onEnableRippleEffectsChanged: saveSettings() property bool m3ElevationEnabled: true onM3ElevationEnabledChanged: saveSettings() + property int m3ElevationIntensity: 12 + onM3ElevationIntensityChanged: saveSettings() + property int m3ElevationOpacity: 30 + onM3ElevationOpacityChanged: saveSettings() + property string m3ElevationColorMode: "default" + onM3ElevationColorModeChanged: saveSettings() + property string m3ElevationCustomColor: "#000000" + onM3ElevationCustomColorChanged: saveSettings() property bool modalElevationEnabled: true onModalElevationEnabledChanged: saveSettings() property bool popoutElevationEnabled: true @@ -608,7 +616,7 @@ Singleton { "scrollYBehavior": "workspace", "shadowIntensity": 0, "shadowOpacity": 60, - "shadowColorMode": "text", + "shadowColorMode": "default", "shadowCustomColor": "#000000", "clickThrough": false } diff --git a/quickshell/Common/Theme.qml b/quickshell/Common/Theme.qml index 733bc201..b420ccb4 100644 --- a/quickshell/Common/Theme.qml +++ b/quickshell/Common/Theme.qml @@ -674,40 +674,74 @@ Singleton { property color shadowStrong: Qt.rgba(0, 0, 0, 0.3) readonly property bool elevationEnabled: typeof SettingsData !== "undefined" && (SettingsData.m3ElevationEnabled ?? true) - readonly property real elevationBlurMax: 16 + readonly property real elevationBlurMax: typeof SettingsData !== "undefined" && SettingsData.m3ElevationIntensity !== undefined ? Math.min(128, Math.max(32, SettingsData.m3ElevationIntensity * 2)) : 64 + + readonly property real _elevMult: typeof SettingsData !== "undefined" && SettingsData.m3ElevationIntensity !== undefined ? SettingsData.m3ElevationIntensity / 12 : 1 + readonly property real _opMult: typeof SettingsData !== "undefined" && SettingsData.m3ElevationOpacity !== undefined ? SettingsData.m3ElevationOpacity / 60 : 1 + readonly property var elevationLevel1: ({ - blurPx: 4, - offsetY: 1, + blurPx: 4 * _elevMult, + offsetY: 1 * _elevMult, spreadPx: 0, - alpha: 0.2 + alpha: 0.2 * _opMult }) readonly property var elevationLevel2: ({ - blurPx: 8, - offsetY: 4, + blurPx: 8 * _elevMult, + offsetY: 4 * _elevMult, spreadPx: 0, - alpha: 0.25 + alpha: 0.25 * _opMult }) readonly property var elevationLevel3: ({ - blurPx: 12, - offsetY: 6, + blurPx: 12 * _elevMult, + offsetY: 6 * _elevMult, spreadPx: 0, - alpha: 0.3 + alpha: 0.3 * _opMult }) readonly property var elevationLevel4: ({ - blurPx: 16, - offsetY: 8, + blurPx: 16 * _elevMult, + offsetY: 8 * _elevMult, spreadPx: 0, - alpha: 0.3 + alpha: 0.3 * _opMult }) readonly property var elevationLevel5: ({ - blurPx: 20, - offsetY: 10, + blurPx: 20 * _elevMult, + offsetY: 10 * _elevMult, spreadPx: 0, - alpha: 0.3 + alpha: 0.3 * _opMult }) + function elevationShadowColor(level) { const alpha = (level && level.alpha !== undefined) ? level.alpha : 0.3; - return Qt.rgba(0, 0, 0, alpha); + let r = 0; + let g = 0; + let b = 0; + + if (typeof SettingsData !== "undefined") { + const mode = SettingsData.m3ElevationColorMode || "default"; + if (mode === "default") { + r = 0; + g = 0; + b = 0; + } else if (mode === "text") { + r = surfaceText.r; + g = surfaceText.g; + b = surfaceText.b; + } else if (mode === "primary") { + r = primary.r; + g = primary.g; + b = primary.b; + } else if (mode === "surfaceVariant") { + r = surfaceVariant.r; + g = surfaceVariant.g; + b = surfaceVariant.b; + } else if (mode === "custom" && SettingsData.m3ElevationCustomColor) { + const c = Qt.color(SettingsData.m3ElevationCustomColor); + r = c.r; + g = c.g; + b = c.b; + } + } + return Qt.rgba(r, g, b, alpha); } function elevationTintOpacity(level) { if (!level) diff --git a/quickshell/Common/settings/SettingsSpec.js b/quickshell/Common/settings/SettingsSpec.js index c14def72..289c5167 100644 --- a/quickshell/Common/settings/SettingsSpec.js +++ b/quickshell/Common/settings/SettingsSpec.js @@ -47,6 +47,10 @@ var SPEC = { modalCustomAnimationDuration: { def: 150 }, enableRippleEffects: { def: true }, m3ElevationEnabled: { def: true }, + m3ElevationIntensity: { def: 12 }, + m3ElevationOpacity: { def: 30 }, + m3ElevationColorMode: { def: "default" }, + m3ElevationCustomColor: { def: "#000000" }, modalElevationEnabled: { def: true }, popoutElevationEnabled: { def: true }, wallpaperFillMode: { def: "Fill" }, @@ -428,7 +432,7 @@ var SPEC = { scrollYBehavior: "workspace", shadowIntensity: 0, shadowOpacity: 60, - shadowColorMode: "text", + shadowColorMode: "default", shadowCustomColor: "#000000", clickThrough: false }], onChange: "updateBarConfigs" diff --git a/quickshell/Modals/Common/DankModal.qml b/quickshell/Modals/Common/DankModal.qml index 731b8531..50cd0f5e 100644 --- a/quickshell/Modals/Common/DankModal.qml +++ b/quickshell/Modals/Common/DankModal.qml @@ -33,7 +33,7 @@ Item { property list animationExitCurve: Theme.expressiveCurves.emphasized property color backgroundColor: Theme.surfaceContainer property color borderColor: Theme.outlineMedium - property real borderWidth: 1 + property real borderWidth: 0 property real cornerRadius: Theme.cornerRadius property bool enableShadow: true property alias modalFocusScope: focusScope @@ -143,7 +143,7 @@ Item { } } - readonly property real shadowBuffer: 24 + readonly property real shadowBuffer: Theme.elevationBlurMax * 1.5 + 24 readonly property real alignedWidth: Theme.px(modalWidth, dpr) readonly property real alignedHeight: Theme.px(modalHeight, dpr) @@ -385,7 +385,6 @@ Item { id: modalShadowLayer anchors.fill: parent layer.enabled: root.enableShadow && Theme.elevationEnabled && SettingsData.modalElevationEnabled && Quickshell.env("DMS_DISABLE_LAYER") !== "true" && Quickshell.env("DMS_DISABLE_LAYER") !== "1" - layer.smooth: false layer.effect: MultiEffect { autoPaddingEnabled: true @@ -396,6 +395,7 @@ Item { shadowScale: 1 shadowVerticalOffset: animatedContent.elev && animatedContent.elev.offsetY !== undefined ? animatedContent.elev.offsetY : 6 shadowHorizontalOffset: 0 + blurMax: Theme.elevationBlurMax shadowColor: Theme.elevationShadowColor(Theme.elevationLevel3) } @@ -408,13 +408,6 @@ Item { } } - Rectangle { - anchors.fill: parent - radius: root.cornerRadius - color: Theme.surfaceTint - opacity: Theme.elevationEnabled ? Theme.elevationTintOpacity(Theme.elevationLevel3) : 0 - } - FocusScope { anchors.fill: parent focus: root.shouldBeVisible diff --git a/quickshell/Modals/DankLauncherV2/DankLauncherV2Modal.qml b/quickshell/Modals/DankLauncherV2/DankLauncherV2Modal.qml index dece12bd..fa6e9d95 100644 --- a/quickshell/Modals/DankLauncherV2/DankLauncherV2Modal.qml +++ b/quickshell/Modals/DankLauncherV2/DankLauncherV2Modal.qml @@ -76,7 +76,7 @@ Item { return Theme.primary; } } - readonly property int borderWidth: SettingsData.dankLauncherV2BorderEnabled ? SettingsData.dankLauncherV2BorderThickness : 1 + readonly property int borderWidth: SettingsData.dankLauncherV2BorderEnabled ? SettingsData.dankLauncherV2BorderThickness : 0 signal dialogClosed @@ -395,7 +395,6 @@ Item { id: launcherShadowLayer anchors.fill: parent layer.enabled: Theme.elevationEnabled && SettingsData.modalElevationEnabled && Quickshell.env("DMS_DISABLE_LAYER") !== "true" && Quickshell.env("DMS_DISABLE_LAYER") !== "1" - layer.smooth: false layer.effect: MultiEffect { autoPaddingEnabled: true shadowEnabled: true @@ -405,6 +404,7 @@ Item { shadowScale: 1 shadowVerticalOffset: Theme.elevationLevel3.offsetY shadowHorizontalOffset: 0 + blurMax: Theme.elevationBlurMax shadowColor: Theme.elevationShadowColor(Theme.elevationLevel3) } @@ -417,13 +417,6 @@ Item { } } - Rectangle { - anchors.fill: parent - radius: root.cornerRadius - color: Theme.surfaceTint - opacity: Theme.elevationEnabled ? Theme.elevationTintOpacity(Theme.elevationLevel3) : 0 - } - MouseArea { anchors.fill: parent onPressed: mouse => mouse.accepted = true diff --git a/quickshell/Modules/DankBar/BarCanvas.qml b/quickshell/Modules/DankBar/BarCanvas.qml index 13130fba..b71ca771 100644 --- a/quickshell/Modules/DankBar/BarCanvas.qml +++ b/quickshell/Modules/DankBar/BarCanvas.qml @@ -59,7 +59,7 @@ Item { readonly property real shadowBlurPx: shadowIntensity * 0.2 readonly property real shadowBlur: Math.max(0, Math.min(1, shadowBlurPx / blurMax)) readonly property real shadowOpacity: (barConfig?.shadowOpacity ?? 60) / 100 - readonly property string shadowColorMode: barConfig?.shadowColorMode ?? "text" + readonly property string shadowColorMode: barConfig?.shadowColorMode ?? "default" readonly property color shadowBaseColor: { switch (shadowColorMode) { case "surface": @@ -71,7 +71,7 @@ Item { case "custom": return barConfig?.shadowCustomColor ?? "#000000"; default: - return Theme.surfaceText; + return "#000000"; } } readonly property color shadowColor: Theme.withAlpha(shadowBaseColor, shadowOpacity * barWindow._backgroundAlpha) diff --git a/quickshell/Modules/DankDash/MediaDropdownOverlay.qml b/quickshell/Modules/DankDash/MediaDropdownOverlay.qml index d6bb9ed3..f34f55a9 100644 --- a/quickshell/Modules/DankDash/MediaDropdownOverlay.qml +++ b/quickshell/Modules/DankDash/MediaDropdownOverlay.qml @@ -95,6 +95,7 @@ Item { shadowHorizontalOffset: 0 shadowVerticalOffset: Theme.elevationLevel2 && Theme.elevationLevel2.offsetY !== undefined ? Theme.elevationLevel2.offsetY : 4 shadowBlur: Theme.elevationEnabled ? Math.max(0, Math.min(1, (Theme.elevationLevel2 && Theme.elevationLevel2.blurPx !== undefined ? Theme.elevationLevel2.blurPx : 8) / Theme.elevationBlurMax)) : 0 + blurMax: Theme.elevationBlurMax shadowColor: Theme.elevationShadowColor(Theme.elevationLevel2) shadowOpacity: Theme.elevationLevel2 && Theme.elevationLevel2.alpha !== undefined ? Theme.elevationLevel2.alpha : 0.25 } @@ -229,6 +230,7 @@ Item { shadowHorizontalOffset: 0 shadowVerticalOffset: Theme.elevationLevel2 && Theme.elevationLevel2.offsetY !== undefined ? Theme.elevationLevel2.offsetY : 4 shadowBlur: Theme.elevationEnabled ? Math.max(0, Math.min(1, (Theme.elevationLevel2 && Theme.elevationLevel2.blurPx !== undefined ? Theme.elevationLevel2.blurPx : 8) / Theme.elevationBlurMax)) : 0 + blurMax: Theme.elevationBlurMax shadowColor: Theme.elevationShadowColor(Theme.elevationLevel2) shadowOpacity: Theme.elevationLevel2 && Theme.elevationLevel2.alpha !== undefined ? Theme.elevationLevel2.alpha : 0.25 } @@ -379,6 +381,7 @@ Item { shadowHorizontalOffset: 0 shadowVerticalOffset: Theme.elevationLevel2 && Theme.elevationLevel2.offsetY !== undefined ? Theme.elevationLevel2.offsetY : 4 shadowBlur: Theme.elevationEnabled ? Math.max(0, Math.min(1, (Theme.elevationLevel2 && Theme.elevationLevel2.blurPx !== undefined ? Theme.elevationLevel2.blurPx : 8) / Theme.elevationBlurMax)) : 0 + blurMax: Theme.elevationBlurMax shadowColor: Theme.elevationShadowColor(Theme.elevationLevel2) shadowOpacity: Theme.elevationLevel2 && Theme.elevationLevel2.alpha !== undefined ? Theme.elevationLevel2.alpha : 0.25 } diff --git a/quickshell/Modules/DankDash/MediaPlayerTab.qml b/quickshell/Modules/DankDash/MediaPlayerTab.qml index 8c9deb65..6943dd09 100644 --- a/quickshell/Modules/DankDash/MediaPlayerTab.qml +++ b/quickshell/Modules/DankDash/MediaPlayerTab.qml @@ -535,6 +535,7 @@ Item { shadowHorizontalOffset: 0 shadowVerticalOffset: Theme.elevationLevel1 && Theme.elevationLevel1.offsetY !== undefined ? Theme.elevationLevel1.offsetY : 1 shadowBlur: Theme.elevationEnabled ? Math.max(0, Math.min(1, (Theme.elevationLevel1 && Theme.elevationLevel1.blurPx !== undefined ? Theme.elevationLevel1.blurPx : 4) / Theme.elevationBlurMax)) : 0 + blurMax: Theme.elevationBlurMax shadowColor: Theme.elevationShadowColor(Theme.elevationLevel1) shadowOpacity: Theme.elevationLevel1 && Theme.elevationLevel1.alpha !== undefined ? Theme.elevationLevel1.alpha : 0.2 } diff --git a/quickshell/Modules/DankDash/WeatherTab.qml b/quickshell/Modules/DankDash/WeatherTab.qml index cc4d7771..ce5085d1 100644 --- a/quickshell/Modules/DankDash/WeatherTab.qml +++ b/quickshell/Modules/DankDash/WeatherTab.qml @@ -247,6 +247,7 @@ Item { shadowHorizontalOffset: 0 shadowVerticalOffset: Theme.elevationLevel1 && Theme.elevationLevel1.offsetY !== undefined ? Theme.elevationLevel1.offsetY : 1 shadowBlur: Theme.elevationEnabled ? Math.max(0, Math.min(1, (Theme.elevationLevel1 && Theme.elevationLevel1.blurPx !== undefined ? Theme.elevationLevel1.blurPx : 4) / Theme.elevationBlurMax)) : 0 + blurMax: Theme.elevationBlurMax shadowColor: Theme.elevationShadowColor(Theme.elevationLevel1) shadowOpacity: Theme.elevationLevel1 && Theme.elevationLevel1.alpha !== undefined ? Theme.elevationLevel1.alpha : 0.2 } @@ -818,6 +819,7 @@ Item { shadowHorizontalOffset: 0 shadowVerticalOffset: 4 shadowBlur: 0.8 + blurMax: Theme.elevationBlurMax shadowColor: Theme.elevationShadowColor(Theme.elevationLevel2) } } @@ -839,6 +841,7 @@ Item { shadowHorizontalOffset: 0 shadowVerticalOffset: 4 shadowBlur: 0.8 + blurMax: Theme.elevationBlurMax shadowColor: Theme.elevationShadowColor(Theme.elevationLevel2) } } diff --git a/quickshell/Modules/Notifications/Center/HistoryNotificationCard.qml b/quickshell/Modules/Notifications/Center/HistoryNotificationCard.qml index 6853c3e7..2685a27f 100644 --- a/quickshell/Modules/Notifications/Center/HistoryNotificationCard.qml +++ b/quickshell/Modules/Notifications/Center/HistoryNotificationCard.qml @@ -31,10 +31,9 @@ Rectangle { width: parent ? parent.width : 400 height: baseCardHeight + contentItem.extraHeight radius: Theme.cornerRadius - clip: true + clip: false layer.enabled: Theme.elevationEnabled && Quickshell.env("DMS_DISABLE_LAYER") !== "true" && Quickshell.env("DMS_DISABLE_LAYER") !== "1" - layer.smooth: false layer.effect: MultiEffect { autoPaddingEnabled: true shadowEnabled: Theme.elevationEnabled @@ -44,6 +43,7 @@ Rectangle { shadowScale: 1 shadowVerticalOffset: Theme.elevationLevel1.offsetY shadowHorizontalOffset: 0 + blurMax: Theme.elevationBlurMax shadowColor: Theme.elevationShadowColor(Theme.elevationLevel1) } @@ -64,7 +64,7 @@ Rectangle { return 1.5; if (historyItem.urgency === 2) return 2; - return 1; + return 0; } Behavior on border.color { diff --git a/quickshell/Modules/Notifications/Center/HistoryNotificationList.qml b/quickshell/Modules/Notifications/Center/HistoryNotificationList.qml index 922a4865..7a4f6298 100644 --- a/quickshell/Modules/Notifications/Center/HistoryNotificationList.qml +++ b/quickshell/Modules/Notifications/Center/HistoryNotificationList.qml @@ -264,7 +264,7 @@ Item { width: ListView.view.width height: historyCard.height - clip: true + clip: false HistoryNotificationCard { id: historyCard diff --git a/quickshell/Modules/Notifications/Center/NotificationCard.qml b/quickshell/Modules/Notifications/Center/NotificationCard.qml index ff595d23..20f235b5 100644 --- a/quickshell/Modules/Notifications/Center/NotificationCard.qml +++ b/quickshell/Modules/Notifications/Center/NotificationCard.qml @@ -96,12 +96,11 @@ Rectangle { if (notificationGroup?.latestNotification?.urgency === NotificationUrgency.Critical) { return 2; } - return 1; + return 0; } - clip: true + clip: false layer.enabled: Theme.elevationEnabled && Quickshell.env("DMS_DISABLE_LAYER") !== "true" && Quickshell.env("DMS_DISABLE_LAYER") !== "1" - layer.smooth: false layer.effect: MultiEffect { autoPaddingEnabled: true shadowEnabled: Theme.elevationEnabled @@ -111,6 +110,7 @@ Rectangle { shadowScale: 1 shadowVerticalOffset: Theme.elevationLevel1.offsetY shadowHorizontalOffset: 0 + blurMax: Theme.elevationBlurMax shadowColor: Theme.elevationShadowColor(Theme.elevationLevel1) } @@ -434,9 +434,7 @@ Rectangle { id: delegateRect width: parent.width - readonly property bool isAdjacentToSwipe: root.swipingNotificationIndex !== -1 && - (expandedDelegateWrapper.index === root.swipingNotificationIndex - 1 || - expandedDelegateWrapper.index === root.swipingNotificationIndex + 1) + readonly property bool isAdjacentToSwipe: root.swipingNotificationIndex !== -1 && (expandedDelegateWrapper.index === root.swipingNotificationIndex - 1 || expandedDelegateWrapper.index === root.swipingNotificationIndex + 1) readonly property real adjacentSwipeInfluence: isAdjacentToSwipe ? root.swipingNotificationOffset * 0.10 : 0 readonly property real adjacentScaleInfluence: isAdjacentToSwipe ? 1.0 - Math.abs(root.swipingNotificationOffset) / width * 0.02 : 1.0 diff --git a/quickshell/Modules/Notifications/Popup/NotificationPopup.qml b/quickshell/Modules/Notifications/Popup/NotificationPopup.qml index 8c8c400a..308219f3 100644 --- a/quickshell/Modules/Notifications/Popup/NotificationPopup.qml +++ b/quickshell/Modules/Notifications/Popup/NotificationPopup.qml @@ -185,8 +185,8 @@ PanelWindow { anchors.top: true anchors.bottom: true - anchors.left: SettingsData.notificationPopupPosition === SettingsData.Position.Left || SettingsData.notificationPopupPosition === SettingsData.Position.Bottom - anchors.right: SettingsData.notificationPopupPosition === SettingsData.Position.Top || SettingsData.notificationPopupPosition === SettingsData.Position.Right + anchors.left: true + anchors.right: true mask: contentInputMask @@ -205,10 +205,10 @@ PanelWindow { } margins { - top: _storedTopMargin - bottom: _storedBottomMargin - left: getLeftMargin() - right: getRightMargin() + top: 0 + bottom: 0 + left: 0 + right: 0 } function getBarInfo() { @@ -282,13 +282,29 @@ PanelWindow { Item { id: content - x: Theme.snap((win.width - alignedWidth) / 2, dpr) - y: { - const isTop = isTopCenter || SettingsData.notificationPopupPosition === SettingsData.Position.Top || SettingsData.notificationPopupPosition === SettingsData.Position.Left; - if (isTop) { - return Theme.snap(screenY, dpr); + x: { + const popupPos = SettingsData.notificationPopupPosition; + const barLeft = getLeftMargin(); + const barRight = getRightMargin(); + + if (isCenterPosition) { + return Theme.snap((screen.width - alignedWidth) / 2, dpr); + } else if (popupPos === SettingsData.Position.Left || popupPos === SettingsData.Position.Bottom) { + return Theme.snap(barLeft, dpr); } else { - return Theme.snap(win.height - alignedHeight - screenY, dpr); + return Theme.snap(screen.width - alignedWidth - barRight, dpr); + } + } + y: { + const popupPos = SettingsData.notificationPopupPosition; + const barTop = getTopMargin(); + const barBottom = getBottomMargin(); + + const isTop = isTopCenter || popupPos === SettingsData.Position.Top || popupPos === SettingsData.Position.Left; + if (isTop) { + return Theme.snap(barTop, dpr); + } else { + return Theme.snap(screen.height - alignedHeight - barBottom, dpr); } } width: alignedWidth @@ -315,6 +331,8 @@ PanelWindow { readonly property bool shadowsAllowed: Theme.elevationEnabled && SettingsData.notificationPopupShadowEnabled readonly property var elevLevel: cardHoverHandler.hovered ? Theme.elevationLevel4 : Theme.elevationLevel3 + readonly property real cardInset: Theme.snap(4, win.dpr) + readonly property real shadowRenderPadding: shadowsAllowed ? Theme.snap(Theme.elevationBlurMax * 1.5 + 24, win.dpr) : 0 property real shadowBlurPx: shadowsAllowed ? (elevLevel && elevLevel.blurPx !== undefined ? elevLevel.blurPx : 12) : 0 property real shadowOffsetY: shadowsAllowed ? (elevLevel && elevLevel.offsetY !== undefined ? elevLevel.offsetY : 6) : 0 @@ -335,9 +353,8 @@ PanelWindow { Item { id: bgShadowLayer anchors.fill: parent - anchors.margins: Theme.snap(4, win.dpr) - layer.enabled: !win._isDestroying && win.screenValid - layer.smooth: false + anchors.margins: -content.shadowRenderPadding + layer.enabled: !win._isDestroying && win.screenValid && content.shadowsAllowed layer.textureSize: Qt.size(Math.round(width * win.dpr), Math.round(height * win.dpr)) layer.textureMirroring: ShaderEffectSource.MirrorVertically @@ -353,12 +370,16 @@ PanelWindow { shadowScale: 1 shadowHorizontalOffset: 0 shadowVerticalOffset: content.shadowOffsetY + blurMax: Theme.elevationBlurMax shadowColor: content.shadowsAllowed && content.elevLevel ? Theme.elevationShadowColor(content.elevLevel) : "transparent" } Rectangle { id: shadowShapeSource - anchors.fill: parent + x: content.shadowRenderPadding + content.cardInset + y: content.shadowRenderPadding + content.cardInset + width: Math.max(0, content.width - (content.cardInset * 2)) + height: Math.max(0, content.height - (content.cardInset * 2)) radius: Theme.cornerRadius color: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency) border.color: notificationData && notificationData.urgency === NotificationUrgency.Critical ? Theme.withAlpha(Theme.primary, 0.3) : Theme.withAlpha(Theme.outline, 0.08) @@ -366,7 +387,10 @@ PanelWindow { } Rectangle { - anchors.fill: parent + x: shadowShapeSource.x + y: shadowShapeSource.y + width: shadowShapeSource.width + height: shadowShapeSource.height radius: shadowShapeSource.radius visible: notificationData && notificationData.urgency === NotificationUrgency.Critical opacity: 1 @@ -391,19 +415,12 @@ PanelWindow { } } } - - Rectangle { - anchors.fill: parent - radius: shadowShapeSource.radius - color: Theme.surfaceTint - opacity: Theme.elevationEnabled ? Theme.elevationTintOpacity(content.elevLevel) : 0 - } } Item { id: backgroundContainer anchors.fill: parent - anchors.margins: Theme.snap(4, win.dpr) + anchors.margins: content.cardInset clip: true HoverHandler { diff --git a/quickshell/Modules/Settings/AboutTab.qml b/quickshell/Modules/Settings/AboutTab.qml index a80c45de..59268b55 100644 --- a/quickshell/Modules/Settings/AboutTab.qml +++ b/quickshell/Modules/Settings/AboutTab.qml @@ -884,6 +884,7 @@ Item { shadowOpacity: Theme.elevationLevel1 && Theme.elevationLevel1.alpha !== undefined ? Theme.elevationLevel1.alpha : 0.2 shadowVerticalOffset: Theme.elevationLevel1 && Theme.elevationLevel1.offsetY !== undefined ? Theme.elevationLevel1.offsetY : 1 shadowBlur: Theme.elevationEnabled ? Math.max(0, Math.min(1, (Theme.elevationLevel1 && Theme.elevationLevel1.blurPx !== undefined ? Theme.elevationLevel1.blurPx : 4) / Theme.elevationBlurMax)) : 0 + blurMax: Theme.elevationBlurMax shadowColor: Theme.elevationShadowColor(Theme.elevationLevel1) } diff --git a/quickshell/Modules/Settings/DankBarTab.qml b/quickshell/Modules/Settings/DankBarTab.qml index 36f9552d..7b61ab44 100644 --- a/quickshell/Modules/Settings/DankBarTab.qml +++ b/quickshell/Modules/Settings/DankBarTab.qml @@ -52,9 +52,11 @@ Item { } function _isBarActive(c) { - if (!c.enabled) return false; + if (!c.enabled) + return false; const prefs = c.screenPreferences || ["all"]; - if (prefs.length > 0) return true; + if (prefs.length > 0) + return true; return (c.showOnLastDisplay ?? true) && Quickshell.screens.length === 1; } @@ -64,7 +66,8 @@ Item { return; const hasHorizontal = configs.some(c => { - if (!_isBarActive(c)) return false; + if (!_isBarActive(c)) + return false; const p = c.position ?? SettingsData.Position.Top; return p === SettingsData.Position.Top || p === SettingsData.Position.Bottom; }); @@ -72,7 +75,8 @@ Item { return; const hasVertical = configs.some(c => { - if (!_isBarActive(c)) return false; + if (!_isBarActive(c)) + return false; const p = c.position ?? SettingsData.Position.Top; return p === SettingsData.Position.Left || p === SettingsData.Position.Right; }); @@ -136,7 +140,7 @@ Item { scrollYBehavior: defaultBar.scrollYBehavior ?? "workspace", shadowIntensity: defaultBar.shadowIntensity ?? 0, shadowOpacity: defaultBar.shadowOpacity ?? 60, - shadowColorMode: defaultBar.shadowColorMode ?? "text", + shadowColorMode: defaultBar.shadowColorMode ?? "default", shadowCustomColor: defaultBar.shadowCustomColor ?? "#000000" }; SettingsData.addBarConfig(newBar); @@ -1038,6 +1042,155 @@ Item { } } + SettingsCard { + id: shadowCard + iconName: "layers" + title: I18n.tr("Shadow", "bar shadow settings card") + settingKey: "barShadow" + collapsible: true + expanded: true + visible: selectedBarConfig?.enabled + + readonly property bool shadowActive: (selectedBarConfig?.shadowIntensity ?? 0) > 0 + readonly property bool isCustomColor: (selectedBarConfig?.shadowColorMode ?? "default") === "custom" + + SettingsToggleRow { + text: I18n.tr("Enable Shadow") + description: I18n.tr("Toggle M3 baseline shadow on or off for this bar") + checked: shadowCard.shadowActive + onToggled: checked => { + if (checked) { + SettingsData.updateBarConfig(selectedBarId, { + shadowIntensity: 12, + shadowOpacity: 60 + }); + } else { + SettingsData.updateBarConfig(selectedBarId, { + shadowIntensity: 0 + }); + } + } + } + + SettingsSliderRow { + visible: shadowCard.shadowActive + text: I18n.tr("Intensity", "shadow intensity slider") + minimum: 0 + maximum: 100 + unit: "px" + defaultValue: 12 + value: selectedBarConfig?.shadowIntensity ?? 0 + onSliderValueChanged: newValue => SettingsData.updateBarConfig(selectedBarId, { + shadowIntensity: newValue + }) + } + + SettingsSliderRow { + visible: shadowCard.shadowActive + text: I18n.tr("Opacity") + minimum: 10 + maximum: 100 + unit: "%" + defaultValue: 60 + value: selectedBarConfig?.shadowOpacity ?? 60 + onSliderValueChanged: newValue => SettingsData.updateBarConfig(selectedBarId, { + shadowOpacity: newValue + }) + } + + Column { + visible: shadowCard.shadowActive + width: parent.width + spacing: Theme.spacingS + + StyledText { + text: I18n.tr("Color") + font.pixelSize: Theme.fontSizeMedium + color: Theme.surfaceText + horizontalAlignment: Text.AlignLeft + anchors.left: parent.left + anchors.leftMargin: Theme.spacingM + } + + Item { + width: parent.width + height: shadowColorGroup.implicitHeight + + DankButtonGroup { + id: shadowColorGroup + anchors.horizontalCenter: parent.horizontalCenter + buttonPadding: parent.width < 420 ? Theme.spacingXS : Theme.spacingS + minButtonWidth: parent.width < 420 ? 36 : 56 + textSize: parent.width < 420 ? Theme.fontSizeSmall : Theme.fontSizeMedium + model: [I18n.tr("Default (Black)"), I18n.tr("Surface", "shadow color option"), I18n.tr("Primary"), I18n.tr("Secondary"), I18n.tr("Custom")] + selectionMode: "single" + currentIndex: { + switch (selectedBarConfig?.shadowColorMode || "default") { + case "surface": + return 1; + case "primary": + return 2; + case "secondary": + return 3; + case "custom": + return 4; + default: + return 0; + } + } + onSelectionChanged: (index, selected) => { + if (!selected) + return; + let mode = "default"; + switch (index) { + case 1: + mode = "surface"; + break; + case 2: + mode = "primary"; + break; + case 3: + mode = "secondary"; + break; + case 4: + mode = "custom"; + break; + } + SettingsData.updateBarConfig(selectedBarId, { + shadowColorMode: mode + }); + } + } + } + + Rectangle { + visible: selectedBarConfig?.shadowColorMode === "custom" + width: 32 + height: 32 + radius: 16 + color: selectedBarConfig?.shadowCustomColor ?? "#000000" + border.color: Theme.outline + border.width: 1 + anchors.horizontalCenter: parent.horizontalCenter + + MouseArea { + anchors.fill: parent + cursorShape: Qt.PointingHandCursor + onClicked: { + PopoutService.colorPickerModal.selectedColor = selectedBarConfig?.shadowCustomColor ?? "#000000"; + PopoutService.colorPickerModal.pickerTitle = I18n.tr("Color"); + PopoutService.colorPickerModal.onColorSelectedCallback = function (color) { + SettingsData.updateBarConfig(selectedBarId, { + shadowCustomColor: color.toString() + }); + }; + PopoutService.colorPickerModal.show(); + } + } + } + } + } + SettingsCard { iconName: "rounded_corner" title: I18n.tr("Corners & Background") @@ -1140,134 +1293,6 @@ Item { } } - SettingsCard { - id: shadowCard - iconName: "layers" - title: I18n.tr("Shadow", "bar shadow settings card") - settingKey: "barShadow" - collapsible: true - expanded: false - visible: selectedBarConfig?.enabled - - readonly property bool shadowActive: (selectedBarConfig?.shadowIntensity ?? 0) > 0 - readonly property bool isCustomColor: (selectedBarConfig?.shadowColorMode ?? "text") === "custom" - - SettingsSliderRow { - text: I18n.tr("Intensity", "shadow intensity slider") - minimum: 0 - maximum: 100 - unit: "%" - value: selectedBarConfig?.shadowIntensity ?? 0 - onSliderValueChanged: newValue => SettingsData.updateBarConfig(selectedBarId, { - shadowIntensity: newValue - }) - } - - SettingsSliderRow { - visible: shadowCard.shadowActive - text: I18n.tr("Opacity") - minimum: 10 - maximum: 100 - unit: "%" - value: selectedBarConfig?.shadowOpacity ?? 60 - onSliderValueChanged: newValue => SettingsData.updateBarConfig(selectedBarId, { - shadowOpacity: newValue - }) - } - - Column { - visible: shadowCard.shadowActive - width: parent.width - spacing: Theme.spacingS - - StyledText { - text: I18n.tr("Color") - font.pixelSize: Theme.fontSizeMedium - color: Theme.surfaceText - horizontalAlignment: Text.AlignLeft - anchors.left: parent.left - anchors.leftMargin: Theme.spacingM - } - - Item { - width: parent.width - height: shadowColorGroup.implicitHeight - - DankButtonGroup { - id: shadowColorGroup - anchors.horizontalCenter: parent.horizontalCenter - buttonPadding: parent.width < 420 ? Theme.spacingXS : Theme.spacingS - minButtonWidth: parent.width < 420 ? 36 : 56 - textSize: parent.width < 420 ? Theme.fontSizeSmall : Theme.fontSizeMedium - model: [I18n.tr("Text", "shadow color option"), I18n.tr("Surface", "shadow color option"), I18n.tr("Primary"), I18n.tr("Secondary"), I18n.tr("Custom")] - selectionMode: "single" - currentIndex: { - switch (selectedBarConfig?.shadowColorMode || "text") { - case "surface": - return 1; - case "primary": - return 2; - case "secondary": - return 3; - case "custom": - return 4; - default: - return 0; - } - } - onSelectionChanged: (index, selected) => { - if (!selected) - return; - let mode = "text"; - switch (index) { - case 1: - mode = "surface"; - break; - case 2: - mode = "primary"; - break; - case 3: - mode = "secondary"; - break; - case 4: - mode = "custom"; - break; - } - SettingsData.updateBarConfig(selectedBarId, { - shadowColorMode: mode - }); - } - } - } - - Rectangle { - visible: selectedBarConfig?.shadowColorMode === "custom" - width: 32 - height: 32 - radius: 16 - color: selectedBarConfig?.shadowCustomColor ?? "#000000" - border.color: Theme.outline - border.width: 1 - anchors.horizontalCenter: parent.horizontalCenter - - MouseArea { - anchors.fill: parent - cursorShape: Qt.PointingHandCursor - onClicked: { - PopoutService.colorPickerModal.selectedColor = selectedBarConfig?.shadowCustomColor ?? "#000000"; - PopoutService.colorPickerModal.pickerTitle = I18n.tr("Color"); - PopoutService.colorPickerModal.onColorSelectedCallback = function (color) { - SettingsData.updateBarConfig(selectedBarId, { - shadowCustomColor: color.toString() - }); - }; - PopoutService.colorPickerModal.show(); - } - } - } - } - } - SettingsToggleCard { iconName: "border_style" title: I18n.tr("Border") diff --git a/quickshell/Modules/Settings/ThemeColorsTab.qml b/quickshell/Modules/Settings/ThemeColorsTab.qml index 8824dc18..3705413c 100644 --- a/quickshell/Modules/Settings/ThemeColorsTab.qml +++ b/quickshell/Modules/Settings/ThemeColorsTab.qml @@ -126,6 +126,15 @@ Item { return Theme.warning; } + function openM3ShadowColorPicker() { + PopoutService.colorPickerModal.selectedColor = SettingsData.m3ElevationCustomColor ?? "#000000"; + PopoutService.colorPickerModal.pickerTitle = I18n.tr("Shadow Color"); + PopoutService.colorPickerModal.onColorSelectedCallback = function (color) { + SettingsData.set("m3ElevationCustomColor", color.toString()); + }; + PopoutService.colorPickerModal.show(); + } + function formatThemeAutoTime(isoString) { if (!isoString) return ""; @@ -1597,12 +1606,115 @@ Item { tab: "theme" tags: ["elevation", "shadow", "lift", "m3", "material"] settingKey: "m3ElevationEnabled" - text: I18n.tr("M3 Elevation & Shadows") + text: I18n.tr("Shadows") description: I18n.tr("Material Design 3 shadows and elevation on modals, popouts, and dialogs") checked: SettingsData.m3ElevationEnabled ?? true onToggled: checked => SettingsData.set("m3ElevationEnabled", checked) } + SettingsSliderRow { + tab: "theme" + tags: ["elevation", "shadow", "intensity", "blur", "m3"] + settingKey: "m3ElevationIntensity" + text: I18n.tr("Shadow Intensity") + description: I18n.tr("Controls the base blur radius and offset of shadows") + value: SettingsData.m3ElevationIntensity ?? 12 + minimum: 0 + maximum: 100 + unit: "px" + defaultValue: 12 + visible: SettingsData.m3ElevationEnabled ?? true + onSliderValueChanged: newValue => SettingsData.set("m3ElevationIntensity", newValue) + } + + SettingsSliderRow { + tab: "theme" + tags: ["elevation", "shadow", "opacity", "transparency", "m3"] + settingKey: "m3ElevationOpacity" + text: I18n.tr("Shadow Opacity") + description: I18n.tr("Controls the transparency of the shadow") + value: SettingsData.m3ElevationOpacity ?? 30 + minimum: 0 + maximum: 100 + unit: "%" + defaultValue: 30 + visible: SettingsData.m3ElevationEnabled ?? true + onSliderValueChanged: newValue => SettingsData.set("m3ElevationOpacity", newValue) + } + + SettingsDropdownRow { + tab: "theme" + tags: ["elevation", "shadow", "color", "m3"] + settingKey: "m3ElevationColorMode" + text: I18n.tr("Shadow Color") + description: I18n.tr("Base color for shadows (opacity is applied automatically)") + options: [I18n.tr("Default (Black)", "shadow color option"), I18n.tr("Text Color", "shadow color option"), I18n.tr("Primary", "shadow color option"), I18n.tr("Surface Variant", "shadow color option"), I18n.tr("Custom", "shadow color option")] + currentValue: { + switch (SettingsData.m3ElevationColorMode) { + case "text": + return I18n.tr("Text Color", "shadow color option"); + case "primary": + return I18n.tr("Primary", "shadow color option"); + case "surfaceVariant": + return I18n.tr("Surface Variant", "shadow color option"); + case "custom": + return I18n.tr("Custom", "shadow color option"); + default: + return I18n.tr("Default (Black)", "shadow color option"); + } + } + visible: SettingsData.m3ElevationEnabled ?? true + onValueChanged: value => { + if (value === I18n.tr("Primary", "shadow color option")) { + SettingsData.set("m3ElevationColorMode", "primary"); + } else if (value === I18n.tr("Surface Variant", "shadow color option")) { + SettingsData.set("m3ElevationColorMode", "surfaceVariant"); + } else if (value === I18n.tr("Custom", "shadow color option")) { + SettingsData.set("m3ElevationColorMode", "custom"); + openM3ShadowColorPicker(); + } else if (value === I18n.tr("Text Color", "shadow color option")) { + SettingsData.set("m3ElevationColorMode", "text"); + } else { + SettingsData.set("m3ElevationColorMode", "default"); + } + } + } + + Item { + visible: (SettingsData.m3ElevationEnabled ?? true) && SettingsData.m3ElevationColorMode === "custom" + width: parent.width + implicitHeight: 36 + height: implicitHeight + + Row { + anchors.left: parent.left + anchors.verticalCenter: parent.verticalCenter + spacing: Theme.spacingM + + StyledText { + text: I18n.tr("Custom Shadow Color") + color: Theme.surfaceText + font.pixelSize: Theme.fontSizeMedium + verticalAlignment: Text.AlignVCenter + } + + Rectangle { + width: 26 + height: 26 + radius: 13 + color: SettingsData.m3ElevationCustomColor ?? "#000000" + border.color: Theme.outline + border.width: 1 + + MouseArea { + anchors.fill: parent + cursorShape: Qt.PointingHandCursor + onClicked: openM3ShadowColorPicker() + } + } + } + } + SettingsToggleRow { tab: "theme" tags: ["elevation", "shadow", "modal", "dialog", "m3"] diff --git a/quickshell/Modules/Settings/TimeWeatherTab.qml b/quickshell/Modules/Settings/TimeWeatherTab.qml index 6bb52c21..35b0be5c 100644 --- a/quickshell/Modules/Settings/TimeWeatherTab.qml +++ b/quickshell/Modules/Settings/TimeWeatherTab.qml @@ -669,6 +669,7 @@ Item { shadowHorizontalOffset: 0 shadowVerticalOffset: Theme.elevationLevel1 && Theme.elevationLevel1.offsetY !== undefined ? Theme.elevationLevel1.offsetY : 1 shadowBlur: Theme.elevationEnabled ? Math.max(0, Math.min(1, (Theme.elevationLevel1 && Theme.elevationLevel1.blurPx !== undefined ? Theme.elevationLevel1.blurPx : 4) / Theme.elevationBlurMax)) : 0 + blurMax: Theme.elevationBlurMax shadowColor: Theme.elevationShadowColor(Theme.elevationLevel1) shadowOpacity: Theme.elevationLevel1 && Theme.elevationLevel1.alpha !== undefined ? Theme.elevationLevel1.alpha : 0.2 } diff --git a/quickshell/Modules/Toast.qml b/quickshell/Modules/Toast.qml index f74a0159..450b3252 100644 --- a/quickshell/Modules/Toast.qml +++ b/quickshell/Modules/Toast.qml @@ -411,6 +411,7 @@ PanelWindow { shadowHorizontalOffset: 0 shadowVerticalOffset: Theme.elevationLevel3 && Theme.elevationLevel3.offsetY !== undefined ? Theme.elevationLevel3.offsetY : 6 shadowBlur: Theme.elevationEnabled ? Math.max(0, Math.min(1, (Theme.elevationLevel3 && Theme.elevationLevel3.blurPx !== undefined ? Theme.elevationLevel3.blurPx : 12) / Theme.elevationBlurMax)) : 0 + blurMax: Theme.elevationBlurMax shadowColor: Theme.elevationShadowColor(Theme.elevationLevel3) shadowOpacity: Theme.elevationLevel3 && Theme.elevationLevel3.alpha !== undefined ? Theme.elevationLevel3.alpha : 0.3 } diff --git a/quickshell/Modules/WorkspaceOverlays/OverviewWidget.qml b/quickshell/Modules/WorkspaceOverlays/OverviewWidget.qml index 1028c260..7f141ac0 100644 --- a/quickshell/Modules/WorkspaceOverlays/OverviewWidget.qml +++ b/quickshell/Modules/WorkspaceOverlays/OverviewWidget.qml @@ -17,59 +17,61 @@ Item { readonly property var allWorkspaces: Hyprland.workspaces?.values || [] readonly property var allWorkspaceIds: { - const workspaces = allWorkspaces - if (!workspaces || workspaces.length === 0) return [] + const workspaces = allWorkspaces; + if (!workspaces || workspaces.length === 0) + return []; try { - const ids = workspaces.map(ws => ws?.id).filter(id => id !== null && id !== undefined) - return ids.sort((a, b) => a - b) + const ids = workspaces.map(ws => ws?.id).filter(id => id !== null && id !== undefined); + return ids.sort((a, b) => a - b); } catch (e) { - return [] + return []; } } readonly property var thisMonitorWorkspaceIds: { - const workspaces = allWorkspaces - const mon = monitor - if (!workspaces || workspaces.length === 0 || !mon) return [] + const workspaces = allWorkspaces; + const mon = monitor; + if (!workspaces || workspaces.length === 0 || !mon) + return []; try { - const filtered = workspaces.filter(ws => ws?.monitor?.name === mon.name) - return filtered.map(ws => ws?.id).filter(id => id !== null && id !== undefined).sort((a, b) => a - b) + const filtered = workspaces.filter(ws => ws?.monitor?.name === mon.name); + return filtered.map(ws => ws?.id).filter(id => id !== null && id !== undefined).sort((a, b) => a - b); } catch (e) { - return [] + return []; } } readonly property var displayedWorkspaceIds: { if (!allWorkspaceIds || allWorkspaceIds.length === 0) { - const result = [] + const result = []; for (let i = 1; i <= workspacesShown; i++) { - result.push(i) + result.push(i); } - return result + return result; } try { - const maxExisting = Math.max(...allWorkspaceIds) - const totalNeeded = Math.max(workspacesShown, allWorkspaceIds.length) - const result = [] + const maxExisting = Math.max(...allWorkspaceIds); + const totalNeeded = Math.max(workspacesShown, allWorkspaceIds.length); + const result = []; for (let i = 1; i <= maxExisting; i++) { - result.push(i) + result.push(i); } - let nextId = maxExisting + 1 + let nextId = maxExisting + 1; while (result.length < totalNeeded) { - result.push(nextId) - nextId++ + result.push(nextId); + nextId++; } - return result + return result; } catch (e) { - const result = [] + const result = []; for (let i = 1; i <= workspacesShown; i++) { - result.push(i) + result.push(i); } - return result + return result; } } @@ -81,24 +83,27 @@ Item { readonly property int effectiveRows: Math.max(SettingsData.overviewRows, Math.ceil(displayWorkspaceCount / effectiveColumns)) function getWorkspaceMonitorName(workspaceId) { - if (!allWorkspaces || !workspaceId) return "" + if (!allWorkspaces || !workspaceId) + return ""; try { - const ws = allWorkspaces.find(w => w?.id === workspaceId) - return ws?.monitor?.name ?? "" + const ws = allWorkspaces.find(w => w?.id === workspaceId); + return ws?.monitor?.name ?? ""; } catch (e) { - return "" + return ""; } } function workspaceHasWindows(workspaceId) { - if (!workspaceId) return false + if (!workspaceId) + return false; try { - const workspace = allWorkspaces.find(ws => ws?.id === workspaceId) - if (!workspace) return false - const toplevels = workspace?.toplevels?.values || [] - return toplevels.length > 0 + const workspace = allWorkspaces.find(ws => ws?.id === workspaceId); + if (!workspace) + return false; + const toplevels = workspace?.toplevels?.values || []; + return toplevels.length > 0; } catch (e) { - return false + return false; } } @@ -124,16 +129,16 @@ Item { implicitHeight: overviewBackground.implicitHeight + Theme.spacingL * 2 Component.onCompleted: { - Hyprland.refreshToplevels() - Hyprland.refreshWorkspaces() - Hyprland.refreshMonitors() + Hyprland.refreshToplevels(); + Hyprland.refreshWorkspaces(); + Hyprland.refreshMonitors(); } onOverviewOpenChanged: { if (overviewOpen) { - Hyprland.refreshToplevels() - Hyprland.refreshWorkspaces() - Hyprland.refreshMonitors() + Hyprland.refreshToplevels(); + Hyprland.refreshWorkspaces(); + Hyprland.refreshMonitors(); } } @@ -154,9 +159,9 @@ Item { shadowBlur: Theme.elevationEnabled ? Math.max(0, Math.min(1, (Theme.elevationLevel2 && Theme.elevationLevel2.blurPx !== undefined ? Theme.elevationLevel2.blurPx : 8) / Theme.elevationBlurMax)) : 0 shadowHorizontalOffset: 0 shadowVerticalOffset: Theme.elevationLevel2 && Theme.elevationLevel2.offsetY !== undefined ? Theme.elevationLevel2.offsetY : 4 + blurMax: Theme.elevationBlurMax shadowColor: Theme.elevationShadowColor(Theme.elevationLevel2) shadowOpacity: Theme.elevationLevel2 && Theme.elevationLevel2.alpha !== undefined ? Theme.elevationLevel2.alpha : 0.25 - blurMax: 32 } ColumnLayout { @@ -217,8 +222,8 @@ Item { acceptedButtons: Qt.LeftButton onClicked: { if (root.draggingTargetWorkspace === -1) { - root.overviewOpen = false - Hyprland.dispatch(`workspace ${workspaceValue}`) + root.overviewOpen = false; + Hyprland.dispatch(`workspace ${workspaceValue}`); } } } @@ -226,13 +231,15 @@ Item { DropArea { anchors.fill: parent onEntered: { - root.draggingTargetWorkspace = workspaceValue - if (root.draggingFromWorkspace == root.draggingTargetWorkspace) return - hoveredWhileDragging = true + root.draggingTargetWorkspace = workspaceValue; + if (root.draggingFromWorkspace == root.draggingTargetWorkspace) + return; + hoveredWhileDragging = true; } onExited: { - hoveredWhileDragging = false - if (root.draggingTargetWorkspace == workspaceValue) root.draggingTargetWorkspace = -1 + hoveredWhileDragging = false; + if (root.draggingTargetWorkspace == workspaceValue) + root.draggingTargetWorkspace = -1; } } } @@ -250,27 +257,28 @@ Item { Repeater { model: ScriptModel { values: { - const workspaces = root.allWorkspaces - const minId = root.minWorkspaceId - const maxId = root.maxWorkspaceId + const workspaces = root.allWorkspaces; + const minId = root.minWorkspaceId; + const maxId = root.maxWorkspaceId; - if (!workspaces || workspaces.length === 0) return [] + if (!workspaces || workspaces.length === 0) + return []; try { - const result = [] + const result = []; for (const workspace of workspaces) { - const wsId = workspace?.id ?? -1 + const wsId = workspace?.id ?? -1; if (wsId >= minId && wsId <= maxId) { - const toplevels = workspace?.toplevels?.values || [] + const toplevels = workspace?.toplevels?.values || []; for (const toplevel of toplevels) { - result.push(toplevel) + result.push(toplevel); } } } - return result + return result; } catch (e) { - console.error("OverviewWidget filter error:", e) - return [] + console.error("OverviewWidget filter error:", e); + return []; } } } @@ -282,17 +290,19 @@ Item { readonly property int windowWorkspaceId: modelData?.workspace?.id ?? -1 function getWorkspaceIndex() { - if (!root.displayedWorkspaceIds || root.displayedWorkspaceIds.length === 0) return 0 - if (!windowWorkspaceId || windowWorkspaceId < 0) return 0 + if (!root.displayedWorkspaceIds || root.displayedWorkspaceIds.length === 0) + return 0; + if (!windowWorkspaceId || windowWorkspaceId < 0) + return 0; try { for (let i = 0; i < root.displayedWorkspaceIds.length; i++) { if (root.displayedWorkspaceIds[i] === windowWorkspaceId) { - return i + return i; } } - return 0 + return 0; } catch (e) { - return 0 + return 0; } } @@ -325,48 +335,48 @@ Item { acceptedButtons: Qt.LeftButton | Qt.MiddleButton drag.target: parent - onPressed: (mouse) => { - root.draggingFromWorkspace = windowData?.workspace.id - window.pressed = true - window.Drag.active = true - window.Drag.source = window - window.Drag.hotSpot.x = mouse.x - window.Drag.hotSpot.y = mouse.y + onPressed: mouse => { + root.draggingFromWorkspace = windowData?.workspace.id; + window.pressed = true; + window.Drag.active = true; + window.Drag.source = window; + window.Drag.hotSpot.x = mouse.x; + window.Drag.hotSpot.y = mouse.y; } onReleased: { - const targetWorkspace = root.draggingTargetWorkspace - window.pressed = false - window.Drag.active = false - root.draggingFromWorkspace = -1 - root.draggingTargetWorkspace = -1 + const targetWorkspace = root.draggingTargetWorkspace; + window.pressed = false; + window.Drag.active = false; + root.draggingFromWorkspace = -1; + root.draggingTargetWorkspace = -1; if (targetWorkspace !== -1 && targetWorkspace !== windowData?.workspace.id) { - Hyprland.dispatch(`movetoworkspacesilent ${targetWorkspace},address:${windowData?.address}`) + Hyprland.dispatch(`movetoworkspacesilent ${targetWorkspace},address:${windowData?.address}`); Qt.callLater(() => { - Hyprland.refreshToplevels() - Hyprland.refreshWorkspaces() + Hyprland.refreshToplevels(); + Hyprland.refreshWorkspaces(); Qt.callLater(() => { - window.x = window.initX - window.y = window.initY - }) - }) + window.x = window.initX; + window.y = window.initY; + }); + }); } else { - window.x = window.initX - window.y = window.initY + window.x = window.initX; + window.y = window.initY; } } - onClicked: (event) => { - if (!windowData || !windowData.address) return - + onClicked: event => { + if (!windowData || !windowData.address) + return; if (event.button === Qt.LeftButton) { - root.overviewOpen = false - Hyprland.dispatch(`focuswindow address:${windowData.address}`) - event.accepted = true + root.overviewOpen = false; + Hyprland.dispatch(`focuswindow address:${windowData.address}`); + event.accepted = true; } else if (event.button === Qt.MiddleButton) { - Hyprland.dispatch(`closewindow address:${windowData.address}`) - event.accepted = true + Hyprland.dispatch(`closewindow address:${windowData.address}`); + event.accepted = true; } } } diff --git a/quickshell/Widgets/DankDropdown.qml b/quickshell/Widgets/DankDropdown.qml index 7163ff4a..643cb834 100644 --- a/quickshell/Widgets/DankDropdown.qml +++ b/quickshell/Widgets/DankDropdown.qml @@ -265,17 +265,11 @@ Item { layer.effect: MultiEffect { shadowEnabled: Theme.elevationEnabled && SettingsData.popoutElevationEnabled shadowBlur: Theme.elevationEnabled ? Math.max(0, Math.min(1, (Theme.elevationLevel2 && Theme.elevationLevel2.blurPx !== undefined ? Theme.elevationLevel2.blurPx : 8) / Theme.elevationBlurMax)) : 0 + blurMax: Theme.elevationBlurMax shadowColor: Theme.elevationShadowColor(Theme.elevationLevel2) shadowVerticalOffset: Theme.elevationLevel2 && Theme.elevationLevel2.offsetY !== undefined ? Theme.elevationLevel2.offsetY : 4 } - Rectangle { - anchors.fill: parent - radius: Theme.cornerRadius - color: Theme.surfaceTint - opacity: Theme.elevationEnabled ? Theme.elevationTintOpacity(Theme.elevationLevel2) : 0 - } - Column { anchors.fill: parent anchors.margins: Theme.spacingS diff --git a/quickshell/Widgets/DankIconPicker.qml b/quickshell/Widgets/DankIconPicker.qml index d0d9e841..f7656043 100644 --- a/quickshell/Widgets/DankIconPicker.qml +++ b/quickshell/Widgets/DankIconPicker.qml @@ -138,6 +138,7 @@ Rectangle { layer.enabled: Theme.elevationEnabled layer.effect: MultiEffect { shadowEnabled: Theme.elevationEnabled + blurMax: Theme.elevationBlurMax shadowColor: Theme.elevationShadowColor(Theme.elevationLevel2) shadowBlur: Theme.elevationEnabled ? Math.max(0, Math.min(1, (Theme.elevationLevel2 && Theme.elevationLevel2.blurPx !== undefined ? Theme.elevationLevel2.blurPx : 8) / Theme.elevationBlurMax)) : 0 shadowHorizontalOffset: 0 diff --git a/quickshell/Widgets/DankOSD.qml b/quickshell/Widgets/DankOSD.qml index 9e5ab901..1f6c0e23 100644 --- a/quickshell/Widgets/DankOSD.qml +++ b/quickshell/Widgets/DankOSD.qml @@ -270,7 +270,7 @@ PanelWindow { radius: Theme.cornerRadius color: Theme.withAlpha(Theme.surfaceContainer, osdContainer.popupSurfaceAlpha) border.color: Theme.outlineMedium - border.width: 1 + border.width: 0 z: -1 } @@ -279,7 +279,6 @@ PanelWindow { anchors.fill: parent visible: osdContainer.popupSurfaceAlpha >= 0.95 layer.enabled: Theme.elevationEnabled && SettingsData.popoutElevationEnabled && Quickshell.env("DMS_DISABLE_LAYER") !== "true" && Quickshell.env("DMS_DISABLE_LAYER") !== "1" - layer.smooth: false layer.textureSize: Qt.size(Math.round(width * root.dpr), Math.round(height * root.dpr)) layer.textureMirroring: ShaderEffectSource.MirrorVertically @@ -293,6 +292,7 @@ PanelWindow { maskEnabled: false shadowBlur: Math.max(0, Math.min(1, osdContainer.shadowBlurPx / bgShadowLayer.blurMax)) shadowScale: 1 + (2 * osdContainer.shadowSpreadPx) / Math.max(1, Math.min(bgShadowLayer.width, bgShadowLayer.height)) + blurMax: Theme.elevationBlurMax shadowColor: Theme.elevationShadowColor(Theme.elevationLevel3) } @@ -303,13 +303,6 @@ PanelWindow { border.color: Theme.outlineMedium border.width: 1 } - - Rectangle { - anchors.fill: parent - radius: Theme.cornerRadius - color: Theme.surfaceTint - opacity: Theme.elevationEnabled ? Theme.elevationTintOpacity(Theme.elevationLevel3) : 0 - } } MouseArea { diff --git a/quickshell/Widgets/DankPopout.qml b/quickshell/Widgets/DankPopout.qml index bbe6273a..9445b689 100644 --- a/quickshell/Widgets/DankPopout.qml +++ b/quickshell/Widgets/DankPopout.qml @@ -197,7 +197,7 @@ Item { readonly property real screenHeight: screen ? screen.height : 0 readonly property real dpr: screen ? screen.devicePixelRatio : 1 - readonly property real shadowBuffer: 24 + readonly property real shadowBuffer: Theme.elevationBlurMax * 1.5 + 24 readonly property real alignedWidth: Theme.px(popupWidth, dpr) readonly property real alignedHeight: Theme.px(popupHeight, dpr) @@ -501,7 +501,6 @@ Item { readonly property int blurMax: Theme.elevationBlurMax layer.enabled: Theme.elevationEnabled && SettingsData.popoutElevationEnabled && Quickshell.env("DMS_DISABLE_LAYER") !== "true" && Quickshell.env("DMS_DISABLE_LAYER") !== "1" && !(root.suspendShadowWhileResizing && root._resizeActive) - layer.smooth: false layer.effect: MultiEffect { id: shadowFx @@ -512,6 +511,7 @@ Item { shadowBlur: Math.max(0, Math.min(1, shadowSource.shadowBlurPx / shadowSource.blurMax)) shadowScale: 1 + (2 * shadowSource.shadowSpreadPx) / Math.max(1, Math.min(shadowSource.width, shadowSource.height)) shadowVerticalOffset: parent.elev && parent.elev.offsetY !== undefined ? parent.elev.offsetY : 6 + blurMax: Theme.elevationBlurMax shadowColor: Theme.elevationShadowColor(Theme.elevationLevel3) } } @@ -544,14 +544,7 @@ Item { radius: Theme.cornerRadius color: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency) border.color: Theme.outlineMedium - border.width: 1 - } - - Rectangle { - anchors.fill: parent - radius: Theme.cornerRadius - color: Theme.surfaceTint - opacity: Theme.elevationEnabled ? Theme.elevationTintOpacity(Theme.elevationLevel3) : 0 + border.width: 0 } Loader {