mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-04-13 01:02:18 -04:00
feat: Implement Material Design 3 elevation and shadow effects
- Added global toggle for enabling M3 elevation & shadow effects - Refactored various components to sync updated specs
This commit is contained in:
@@ -165,6 +165,8 @@ Singleton {
|
|||||||
property int modalCustomAnimationDuration: 150
|
property int modalCustomAnimationDuration: 150
|
||||||
property bool enableRippleEffects: true
|
property bool enableRippleEffects: true
|
||||||
onEnableRippleEffectsChanged: saveSettings()
|
onEnableRippleEffectsChanged: saveSettings()
|
||||||
|
property bool m3ElevationEnabled: true
|
||||||
|
onM3ElevationEnabledChanged: saveSettings()
|
||||||
property string wallpaperFillMode: "Fill"
|
property string wallpaperFillMode: "Fill"
|
||||||
property bool blurredWallpaperLayer: false
|
property bool blurredWallpaperLayer: false
|
||||||
property bool blurWallpaperOnOverview: false
|
property bool blurWallpaperOnOverview: false
|
||||||
|
|||||||
@@ -673,6 +673,19 @@ Singleton {
|
|||||||
property color shadowMedium: Qt.rgba(0, 0, 0, 0.08)
|
property color shadowMedium: Qt.rgba(0, 0, 0, 0.08)
|
||||||
property color shadowStrong: Qt.rgba(0, 0, 0, 0.3)
|
property color shadowStrong: Qt.rgba(0, 0, 0, 0.3)
|
||||||
|
|
||||||
|
readonly property bool elevationEnabled: typeof SettingsData !== "undefined" && (SettingsData.m3ElevationEnabled ?? true)
|
||||||
|
readonly property real elevationBlurMax: 64
|
||||||
|
readonly property var elevationLevel1: ({ blurPx: 4, offsetY: 1, spreadPx: 0, alpha: 0.2 })
|
||||||
|
readonly property var elevationLevel2: ({ blurPx: 8, offsetY: 4, spreadPx: 0, alpha: 0.25 })
|
||||||
|
readonly property var elevationLevel3: ({ blurPx: 12, offsetY: 6, spreadPx: 0, alpha: 0.3 })
|
||||||
|
readonly property var elevationLevel4: ({ blurPx: 16, offsetY: 8, spreadPx: 0, alpha: 0.3 })
|
||||||
|
readonly property var elevationLevel5: ({ blurPx: 20, offsetY: 10, spreadPx: 0, alpha: 0.3 })
|
||||||
|
function elevationShadowColor(level) {
|
||||||
|
const alpha = (level && level.alpha !== undefined) ? level.alpha : 0.3;
|
||||||
|
const baseColor = isLightMode ? Qt.rgba(0, 0, 0, 1) : surfaceContainerHighest;
|
||||||
|
return Theme.withAlpha(baseColor, alpha * (typeof SettingsData !== "undefined" ? SettingsData.popupTransparency : 1));
|
||||||
|
}
|
||||||
|
|
||||||
readonly property var animationDurations: [
|
readonly property var animationDurations: [
|
||||||
{
|
{
|
||||||
"shorter": 0,
|
"shorter": 0,
|
||||||
|
|||||||
@@ -46,6 +46,7 @@ var SPEC = {
|
|||||||
modalAnimationSpeed: { def: 1 },
|
modalAnimationSpeed: { def: 1 },
|
||||||
modalCustomAnimationDuration: { def: 150 },
|
modalCustomAnimationDuration: { def: 150 },
|
||||||
enableRippleEffects: { def: true },
|
enableRippleEffects: { def: true },
|
||||||
|
m3ElevationEnabled: { def: true },
|
||||||
wallpaperFillMode: { def: "Fill" },
|
wallpaperFillMode: { def: "Fill" },
|
||||||
blurredWallpaperLayer: { def: false },
|
blurredWallpaperLayer: { def: false },
|
||||||
blurWallpaperOnOverview: { def: false },
|
blurWallpaperOnOverview: { def: false },
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import QtQuick
|
import QtQuick
|
||||||
|
import QtQuick.Effects
|
||||||
import Quickshell
|
import Quickshell
|
||||||
import Quickshell.Wayland
|
import Quickshell.Wayland
|
||||||
import qs.Common
|
import qs.Common
|
||||||
@@ -377,6 +378,31 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
readonly property var elev: Theme.elevationLevel3
|
||||||
|
readonly property real shadowBlurNorm: Math.max(0, Math.min(1, (elev && elev.blurPx !== undefined ? elev.blurPx : 12) / Theme.elevationBlurMax))
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: modalShadowShape
|
||||||
|
anchors.fill: parent
|
||||||
|
radius: root.cornerRadius
|
||||||
|
color: "black"
|
||||||
|
visible: false
|
||||||
|
layer.enabled: root.enableShadow && Theme.elevationEnabled && Quickshell.env("DMS_DISABLE_LAYER") !== "true" && Quickshell.env("DMS_DISABLE_LAYER") !== "1"
|
||||||
|
layer.smooth: false
|
||||||
|
|
||||||
|
layer.effect: MultiEffect {
|
||||||
|
autoPaddingEnabled: true
|
||||||
|
shadowEnabled: true
|
||||||
|
blurEnabled: false
|
||||||
|
maskEnabled: false
|
||||||
|
shadowBlur: modalShadowShape.parent.shadowBlurNorm
|
||||||
|
shadowScale: 1
|
||||||
|
shadowVerticalOffset: modalShadowShape.parent.elev && modalShadowShape.parent.elev.offsetY !== undefined ? modalShadowShape.parent.elev.offsetY : 6
|
||||||
|
shadowHorizontalOffset: 0
|
||||||
|
shadowColor: Theme.elevationShadowColor(Theme.elevationLevel3)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
color: root.backgroundColor
|
color: root.backgroundColor
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ Item {
|
|||||||
Loader {
|
Loader {
|
||||||
id: shadowLoader
|
id: shadowLoader
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
active: root.shadowEnabled && mainPathCorrectShape
|
active: root.shadowEnabled && mainPathCorrectShape && Theme.elevationEnabled
|
||||||
asynchronous: false
|
asynchronous: false
|
||||||
sourceComponent: Item {
|
sourceComponent: Item {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|||||||
@@ -940,9 +940,10 @@ BasePill {
|
|||||||
}
|
}
|
||||||
})(), overflowMenu.dpr)
|
})(), overflowMenu.dpr)
|
||||||
|
|
||||||
property real shadowBlurPx: 10
|
readonly property var elev: Theme.elevationLevel2
|
||||||
property real shadowSpreadPx: 0
|
property real shadowBlurPx: elev && elev.blurPx !== undefined ? elev.blurPx : 8
|
||||||
property real shadowBaseAlpha: 0.60
|
property real shadowSpreadPx: elev && elev.spreadPx !== undefined ? elev.spreadPx : 0
|
||||||
|
property real shadowBaseAlpha: elev && elev.alpha !== undefined ? elev.alpha : 0.25
|
||||||
readonly property real popupSurfaceAlpha: Theme.popupTransparency
|
readonly property real popupSurfaceAlpha: Theme.popupTransparency
|
||||||
readonly property real effectiveShadowAlpha: Math.max(0, Math.min(1, shadowBaseAlpha * popupSurfaceAlpha))
|
readonly property real effectiveShadowAlpha: Math.max(0, Math.min(1, shadowBaseAlpha * popupSurfaceAlpha))
|
||||||
|
|
||||||
@@ -966,7 +967,7 @@ BasePill {
|
|||||||
Item {
|
Item {
|
||||||
id: bgShadowLayer
|
id: bgShadowLayer
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
layer.enabled: true
|
layer.enabled: Theme.elevationEnabled
|
||||||
layer.smooth: true
|
layer.smooth: true
|
||||||
layer.textureSize: Qt.size(Math.round(width * overflowMenu.dpr * 2), Math.round(height * overflowMenu.dpr * 2))
|
layer.textureSize: Qt.size(Math.round(width * overflowMenu.dpr * 2), Math.round(height * overflowMenu.dpr * 2))
|
||||||
layer.textureMirroring: ShaderEffectSource.MirrorVertically
|
layer.textureMirroring: ShaderEffectSource.MirrorVertically
|
||||||
@@ -1412,9 +1413,10 @@ BasePill {
|
|||||||
}
|
}
|
||||||
})(), menuWindow.dpr)
|
})(), menuWindow.dpr)
|
||||||
|
|
||||||
property real shadowBlurPx: 10
|
readonly property var elev: Theme.elevationLevel2
|
||||||
property real shadowSpreadPx: 0
|
property real shadowBlurPx: elev && elev.blurPx !== undefined ? elev.blurPx : 8
|
||||||
property real shadowBaseAlpha: 0.60
|
property real shadowSpreadPx: elev && elev.spreadPx !== undefined ? elev.spreadPx : 0
|
||||||
|
property real shadowBaseAlpha: elev && elev.alpha !== undefined ? elev.alpha : 0.25
|
||||||
readonly property real popupSurfaceAlpha: Theme.popupTransparency
|
readonly property real popupSurfaceAlpha: Theme.popupTransparency
|
||||||
readonly property real effectiveShadowAlpha: Math.max(0, Math.min(1, shadowBaseAlpha * popupSurfaceAlpha))
|
readonly property real effectiveShadowAlpha: Math.max(0, Math.min(1, shadowBaseAlpha * popupSurfaceAlpha))
|
||||||
|
|
||||||
@@ -1438,7 +1440,7 @@ BasePill {
|
|||||||
Item {
|
Item {
|
||||||
id: menuBgShadowLayer
|
id: menuBgShadowLayer
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
layer.enabled: true
|
layer.enabled: Theme.elevationEnabled
|
||||||
layer.smooth: true
|
layer.smooth: true
|
||||||
layer.textureSize: Qt.size(Math.round(width * menuWindow.dpr), Math.round(height * menuWindow.dpr))
|
layer.textureSize: Qt.size(Math.round(width * menuWindow.dpr), Math.round(height * menuWindow.dpr))
|
||||||
layer.textureMirroring: ShaderEffectSource.MirrorVertically
|
layer.textureMirroring: ShaderEffectSource.MirrorVertically
|
||||||
|
|||||||
@@ -89,14 +89,14 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
layer.enabled: true
|
layer.enabled: Theme.elevationEnabled
|
||||||
layer.effect: MultiEffect {
|
layer.effect: MultiEffect {
|
||||||
shadowEnabled: true
|
shadowEnabled: Theme.elevationEnabled
|
||||||
shadowHorizontalOffset: 0
|
shadowHorizontalOffset: 0
|
||||||
shadowVerticalOffset: 8
|
shadowVerticalOffset: Theme.elevationLevel2 && Theme.elevationLevel2.offsetY !== undefined ? Theme.elevationLevel2.offsetY : 4
|
||||||
shadowBlur: 1.0
|
shadowBlur: Theme.elevationEnabled ? Math.max(0, Math.min(1, (Theme.elevationLevel2 && Theme.elevationLevel2.blurPx !== undefined ? Theme.elevationLevel2.blurPx : 8) / Theme.elevationBlurMax)) : 0
|
||||||
shadowColor: Qt.rgba(0, 0, 0, 0.4)
|
shadowColor: Theme.elevationShadowColor(Theme.elevationLevel2)
|
||||||
shadowOpacity: 0.7
|
shadowOpacity: Theme.elevationLevel2 && Theme.elevationLevel2.alpha !== undefined ? Theme.elevationLevel2.alpha : 0.25
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
@@ -223,14 +223,14 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
layer.enabled: true
|
layer.enabled: Theme.elevationEnabled
|
||||||
layer.effect: MultiEffect {
|
layer.effect: MultiEffect {
|
||||||
shadowEnabled: true
|
shadowEnabled: Theme.elevationEnabled
|
||||||
shadowHorizontalOffset: 0
|
shadowHorizontalOffset: 0
|
||||||
shadowVerticalOffset: 8
|
shadowVerticalOffset: Theme.elevationLevel2 && Theme.elevationLevel2.offsetY !== undefined ? Theme.elevationLevel2.offsetY : 4
|
||||||
shadowBlur: 1.0
|
shadowBlur: Theme.elevationEnabled ? Math.max(0, Math.min(1, (Theme.elevationLevel2 && Theme.elevationLevel2.blurPx !== undefined ? Theme.elevationLevel2.blurPx : 8) / Theme.elevationBlurMax)) : 0
|
||||||
shadowColor: Qt.rgba(0, 0, 0, 0.4)
|
shadowColor: Theme.elevationShadowColor(Theme.elevationLevel2)
|
||||||
shadowOpacity: 0.7
|
shadowOpacity: Theme.elevationLevel2 && Theme.elevationLevel2.alpha !== undefined ? Theme.elevationLevel2.alpha : 0.25
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
@@ -373,14 +373,14 @@ Item {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
layer.enabled: true
|
layer.enabled: Theme.elevationEnabled
|
||||||
layer.effect: MultiEffect {
|
layer.effect: MultiEffect {
|
||||||
shadowEnabled: true
|
shadowEnabled: Theme.elevationEnabled
|
||||||
shadowHorizontalOffset: 0
|
shadowHorizontalOffset: 0
|
||||||
shadowVerticalOffset: 8
|
shadowVerticalOffset: Theme.elevationLevel2 && Theme.elevationLevel2.offsetY !== undefined ? Theme.elevationLevel2.offsetY : 4
|
||||||
shadowBlur: 1.0
|
shadowBlur: Theme.elevationEnabled ? Math.max(0, Math.min(1, (Theme.elevationLevel2 && Theme.elevationLevel2.blurPx !== undefined ? Theme.elevationLevel2.blurPx : 8) / Theme.elevationBlurMax)) : 0
|
||||||
shadowColor: Qt.rgba(0, 0, 0, 0.4)
|
shadowColor: Theme.elevationShadowColor(Theme.elevationLevel2)
|
||||||
shadowOpacity: 0.7
|
shadowOpacity: Theme.elevationLevel2 && Theme.elevationLevel2.alpha !== undefined ? Theme.elevationLevel2.alpha : 0.25
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
|
|||||||
@@ -529,14 +529,14 @@ Item {
|
|||||||
onClicked: activePlayer && activePlayer.togglePlaying()
|
onClicked: activePlayer && activePlayer.togglePlaying()
|
||||||
}
|
}
|
||||||
|
|
||||||
layer.enabled: true
|
layer.enabled: Theme.elevationEnabled
|
||||||
layer.effect: MultiEffect {
|
layer.effect: MultiEffect {
|
||||||
shadowEnabled: true
|
shadowEnabled: Theme.elevationEnabled
|
||||||
shadowHorizontalOffset: 0
|
shadowHorizontalOffset: 0
|
||||||
shadowVerticalOffset: 0
|
shadowVerticalOffset: Theme.elevationLevel1 && Theme.elevationLevel1.offsetY !== undefined ? Theme.elevationLevel1.offsetY : 1
|
||||||
shadowBlur: 1.0
|
shadowBlur: Theme.elevationEnabled ? Math.max(0, Math.min(1, (Theme.elevationLevel1 && Theme.elevationLevel1.blurPx !== undefined ? Theme.elevationLevel1.blurPx : 4) / Theme.elevationBlurMax)) : 0
|
||||||
shadowColor: Qt.rgba(0, 0, 0, 0.3)
|
shadowColor: Theme.elevationShadowColor(Theme.elevationLevel1)
|
||||||
shadowOpacity: 0.3
|
shadowOpacity: Theme.elevationLevel1 && Theme.elevationLevel1.alpha !== undefined ? Theme.elevationLevel1.alpha : 0.2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -241,14 +241,14 @@ Item {
|
|||||||
color: Theme.primary
|
color: Theme.primary
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
layer.enabled: true
|
layer.enabled: Theme.elevationEnabled
|
||||||
layer.effect: MultiEffect {
|
layer.effect: MultiEffect {
|
||||||
shadowEnabled: true
|
shadowEnabled: Theme.elevationEnabled
|
||||||
shadowHorizontalOffset: 0
|
shadowHorizontalOffset: 0
|
||||||
shadowVerticalOffset: 4
|
shadowVerticalOffset: Theme.elevationLevel1 && Theme.elevationLevel1.offsetY !== undefined ? Theme.elevationLevel1.offsetY : 1
|
||||||
shadowBlur: 0.8
|
shadowBlur: Theme.elevationEnabled ? Math.max(0, Math.min(1, (Theme.elevationLevel1 && Theme.elevationLevel1.blurPx !== undefined ? Theme.elevationLevel1.blurPx : 4) / Theme.elevationBlurMax)) : 0
|
||||||
shadowColor: Qt.rgba(0, 0, 0, 0.2)
|
shadowColor: Theme.elevationShadowColor(Theme.elevationLevel1)
|
||||||
shadowOpacity: 0.2
|
shadowOpacity: Theme.elevationLevel1 && Theme.elevationLevel1.alpha !== undefined ? Theme.elevationLevel1.alpha : 0.2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -313,12 +313,10 @@ PanelWindow {
|
|||||||
readonly property bool swipeActive: swipeDragHandler.active
|
readonly property bool swipeActive: swipeDragHandler.active
|
||||||
property bool swipeDismissing: false
|
property bool swipeDismissing: false
|
||||||
|
|
||||||
readonly property real radiusForShadow: Theme.cornerRadius
|
readonly property bool shadowsAllowed: Theme.elevationEnabled && SettingsData.notificationPopupShadowEnabled
|
||||||
property real shadowBlurPx: SettingsData.notificationPopupShadowEnabled ? ((2 + radiusForShadow * 0.2) * (cardHoverHandler.hovered ? 1.2 : 1)) : 0
|
readonly property var elevLevel: cardHoverHandler.hovered ? Theme.elevationLevel4 : Theme.elevationLevel3
|
||||||
property real shadowSpreadPx: SettingsData.notificationPopupShadowEnabled ? (radiusForShadow * (cardHoverHandler.hovered ? 0.06 : 0)) : 0
|
property real shadowBlurPx: shadowsAllowed ? (elevLevel && elevLevel.blurPx !== undefined ? elevLevel.blurPx : 12) : 0
|
||||||
property real shadowBaseAlpha: 0.35
|
property real shadowOffsetY: shadowsAllowed ? (elevLevel && elevLevel.offsetY !== undefined ? elevLevel.offsetY : 6) : 0
|
||||||
readonly property real popupSurfaceAlpha: SettingsData.popupTransparency
|
|
||||||
readonly property real effectiveShadowAlpha: Math.max(0, Math.min(1, shadowBaseAlpha * popupSurfaceAlpha))
|
|
||||||
|
|
||||||
Behavior on shadowBlurPx {
|
Behavior on shadowBlurPx {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
@@ -327,7 +325,7 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on shadowSpreadPx {
|
Behavior on shadowOffsetY {
|
||||||
NumberAnimation {
|
NumberAnimation {
|
||||||
duration: Theme.shortDuration
|
duration: Theme.shortDuration
|
||||||
easing.type: Theme.standardEasing
|
easing.type: Theme.standardEasing
|
||||||
@@ -348,15 +346,14 @@ PanelWindow {
|
|||||||
layer.effect: MultiEffect {
|
layer.effect: MultiEffect {
|
||||||
id: shadowFx
|
id: shadowFx
|
||||||
autoPaddingEnabled: true
|
autoPaddingEnabled: true
|
||||||
shadowEnabled: SettingsData.notificationPopupShadowEnabled
|
shadowEnabled: content.shadowsAllowed
|
||||||
blurEnabled: false
|
blurEnabled: false
|
||||||
maskEnabled: false
|
maskEnabled: false
|
||||||
shadowBlur: Math.max(0, Math.min(1, content.shadowBlurPx / bgShadowLayer.blurMax))
|
shadowBlur: Math.max(0, Math.min(1, content.shadowBlurPx / bgShadowLayer.blurMax))
|
||||||
shadowScale: 1 + (2 * content.shadowSpreadPx) / Math.max(1, Math.min(bgShadowLayer.width, bgShadowLayer.height))
|
shadowScale: 1
|
||||||
shadowColor: {
|
shadowHorizontalOffset: 0
|
||||||
const baseColor = Theme.isLightMode ? Qt.rgba(0, 0, 0, 1) : Theme.surfaceContainerHighest;
|
shadowVerticalOffset: content.shadowOffsetY
|
||||||
return Theme.withAlpha(baseColor, content.effectiveShadowAlpha);
|
shadowColor: content.shadowsAllowed && content.elevLevel ? Theme.elevationShadowColor(content.elevLevel) : "transparent"
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
|||||||
@@ -878,12 +878,13 @@ Item {
|
|||||||
x: hoveredButton ? hoveredButton.mapToItem(aboutTab, hoveredButton.width / 2, 0).x - width / 2 : 0
|
x: hoveredButton ? hoveredButton.mapToItem(aboutTab, hoveredButton.width / 2, 0).x - width / 2 : 0
|
||||||
y: hoveredButton ? communityIcons.mapToItem(aboutTab, 0, 0).y - height - 8 : 0
|
y: hoveredButton ? communityIcons.mapToItem(aboutTab, 0, 0).y - height - 8 : 0
|
||||||
|
|
||||||
layer.enabled: true
|
layer.enabled: Theme.elevationEnabled
|
||||||
layer.effect: MultiEffect {
|
layer.effect: MultiEffect {
|
||||||
shadowEnabled: true
|
shadowEnabled: Theme.elevationEnabled
|
||||||
shadowOpacity: 0.15
|
shadowOpacity: Theme.elevationLevel1 && Theme.elevationLevel1.alpha !== undefined ? Theme.elevationLevel1.alpha : 0.2
|
||||||
shadowVerticalOffset: 2
|
shadowVerticalOffset: Theme.elevationLevel1 && Theme.elevationLevel1.offsetY !== undefined ? Theme.elevationLevel1.offsetY : 1
|
||||||
shadowBlur: 0.5
|
shadowBlur: Theme.elevationEnabled ? Math.max(0, Math.min(1, (Theme.elevationLevel1 && Theme.elevationLevel1.blurPx !== undefined ? Theme.elevationLevel1.blurPx : 4) / Theme.elevationBlurMax)) : 0
|
||||||
|
shadowColor: Theme.elevationShadowColor(Theme.elevationLevel1)
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
|
|||||||
@@ -274,7 +274,7 @@ Item {
|
|||||||
settingKey: "notificationPopupShadowEnabled"
|
settingKey: "notificationPopupShadowEnabled"
|
||||||
tags: ["notification", "popup", "shadow", "radius", "rounded"]
|
tags: ["notification", "popup", "shadow", "radius", "rounded"]
|
||||||
text: I18n.tr("Popup Shadow")
|
text: I18n.tr("Popup Shadow")
|
||||||
description: I18n.tr("Show drop shadow on notification popups")
|
description: I18n.tr("Show drop shadow on notification popups. Requires M3 Elevation to be enabled in Theme & Colors.")
|
||||||
checked: SettingsData.notificationPopupShadowEnabled
|
checked: SettingsData.notificationPopupShadowEnabled
|
||||||
onToggled: checked => SettingsData.set("notificationPopupShadowEnabled", checked)
|
onToggled: checked => SettingsData.set("notificationPopupShadowEnabled", checked)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1592,6 +1592,16 @@ Item {
|
|||||||
defaultValue: 12
|
defaultValue: 12
|
||||||
onSliderValueChanged: newValue => SettingsData.setCornerRadius(newValue)
|
onSliderValueChanged: newValue => SettingsData.setCornerRadius(newValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SettingsToggleRow {
|
||||||
|
tab: "theme"
|
||||||
|
tags: ["elevation", "shadow", "lift", "m3", "material"]
|
||||||
|
settingKey: "m3ElevationEnabled"
|
||||||
|
text: I18n.tr("M3 Elevation & 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)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SettingsCard {
|
SettingsCard {
|
||||||
|
|||||||
@@ -663,14 +663,14 @@ Item {
|
|||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
|
||||||
layer.enabled: true
|
layer.enabled: Theme.elevationEnabled
|
||||||
layer.effect: MultiEffect {
|
layer.effect: MultiEffect {
|
||||||
shadowEnabled: true
|
shadowEnabled: Theme.elevationEnabled
|
||||||
shadowHorizontalOffset: 0
|
shadowHorizontalOffset: 0
|
||||||
shadowVerticalOffset: 4
|
shadowVerticalOffset: Theme.elevationLevel1 && Theme.elevationLevel1.offsetY !== undefined ? Theme.elevationLevel1.offsetY : 1
|
||||||
shadowBlur: 0.8
|
shadowBlur: Theme.elevationEnabled ? Math.max(0, Math.min(1, (Theme.elevationLevel1 && Theme.elevationLevel1.blurPx !== undefined ? Theme.elevationLevel1.blurPx : 4) / Theme.elevationBlurMax)) : 0
|
||||||
shadowColor: Qt.rgba(0, 0, 0, 0.2)
|
shadowColor: Theme.elevationShadowColor(Theme.elevationLevel1)
|
||||||
shadowOpacity: 0.2
|
shadowOpacity: Theme.elevationLevel1 && Theme.elevationLevel1.alpha !== undefined ? Theme.elevationLevel1.alpha : 0.2
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -407,12 +407,12 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
layer.effect: MultiEffect {
|
layer.effect: MultiEffect {
|
||||||
shadowEnabled: true
|
shadowEnabled: Theme.elevationEnabled
|
||||||
shadowHorizontalOffset: 0
|
shadowHorizontalOffset: 0
|
||||||
shadowVerticalOffset: 4
|
shadowVerticalOffset: Theme.elevationLevel3 && Theme.elevationLevel3.offsetY !== undefined ? Theme.elevationLevel3.offsetY : 6
|
||||||
shadowBlur: 0.8
|
shadowBlur: Theme.elevationEnabled ? Math.max(0, Math.min(1, (Theme.elevationLevel3 && Theme.elevationLevel3.blurPx !== undefined ? Theme.elevationLevel3.blurPx : 12) / Theme.elevationBlurMax)) : 0
|
||||||
shadowColor: Qt.rgba(0, 0, 0, 0.3)
|
shadowColor: Theme.elevationShadowColor(Theme.elevationLevel3)
|
||||||
shadowOpacity: 0.3
|
shadowOpacity: Theme.elevationLevel3 && Theme.elevationLevel3.alpha !== undefined ? Theme.elevationLevel3.alpha : 0.3
|
||||||
}
|
}
|
||||||
|
|
||||||
Behavior on opacity {
|
Behavior on opacity {
|
||||||
|
|||||||
@@ -148,14 +148,14 @@ Item {
|
|||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
color: Theme.surfaceContainer
|
color: Theme.surfaceContainer
|
||||||
|
|
||||||
layer.enabled: true
|
layer.enabled: Theme.elevationEnabled
|
||||||
layer.effect: MultiEffect {
|
layer.effect: MultiEffect {
|
||||||
shadowEnabled: true
|
shadowEnabled: Theme.elevationEnabled
|
||||||
shadowBlur: 0.5
|
shadowBlur: Theme.elevationEnabled ? Math.max(0, Math.min(1, (Theme.elevationLevel2 && Theme.elevationLevel2.blurPx !== undefined ? Theme.elevationLevel2.blurPx : 8) / Theme.elevationBlurMax)) : 0
|
||||||
shadowHorizontalOffset: 0
|
shadowHorizontalOffset: 0
|
||||||
shadowVerticalOffset: 4
|
shadowVerticalOffset: Theme.elevationLevel2 && Theme.elevationLevel2.offsetY !== undefined ? Theme.elevationLevel2.offsetY : 4
|
||||||
shadowColor: Theme.shadowStrong
|
shadowColor: Theme.elevationShadowColor(Theme.elevationLevel2)
|
||||||
shadowOpacity: 1
|
shadowOpacity: Theme.elevationLevel2 && Theme.elevationLevel2.alpha !== undefined ? Theme.elevationLevel2.alpha : 0.25
|
||||||
blurMax: 32
|
blurMax: 32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ Item {
|
|||||||
sourceComponent: IconImage {
|
sourceComponent: IconImage {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
source: root.iconPath
|
source: root.iconPath
|
||||||
backer.sourceSize: Qt.size(root.iconSize, root.iconSize)
|
backer.sourceSize: Qt.size(root.iconSize * 2, root.iconSize * 2)
|
||||||
mipmap: true
|
mipmap: true
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
visible: status === Image.Ready
|
visible: status === Image.Ready
|
||||||
|
|||||||
@@ -81,6 +81,8 @@ Rectangle {
|
|||||||
mipmap: true
|
mipmap: true
|
||||||
cache: true
|
cache: true
|
||||||
visible: false
|
visible: false
|
||||||
|
sourceSize.width: Math.max(width * 2, 128)
|
||||||
|
sourceSize.height: Math.max(height * 2, 128)
|
||||||
source: !root.shouldProbe ? root.imageSource : ""
|
source: !root.shouldProbe ? root.imageSource : ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -263,10 +263,10 @@ Item {
|
|||||||
|
|
||||||
layer.enabled: true
|
layer.enabled: true
|
||||||
layer.effect: MultiEffect {
|
layer.effect: MultiEffect {
|
||||||
shadowEnabled: true
|
shadowEnabled: Theme.elevationEnabled
|
||||||
shadowBlur: 0.4
|
shadowBlur: Theme.elevationEnabled ? Math.max(0, Math.min(1, (Theme.elevationLevel2 && Theme.elevationLevel2.blurPx !== undefined ? Theme.elevationLevel2.blurPx : 8) / Theme.elevationBlurMax)) : 0
|
||||||
shadowColor: Theme.shadowStrong
|
shadowColor: Theme.elevationShadowColor(Theme.elevationLevel2)
|
||||||
shadowVerticalOffset: 4
|
shadowVerticalOffset: Theme.elevationLevel2 && Theme.elevationLevel2.offsetY !== undefined ? Theme.elevationLevel2.offsetY : 4
|
||||||
}
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
|
|||||||
@@ -135,13 +135,14 @@ Rectangle {
|
|||||||
color: Theme.surface
|
color: Theme.surface
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
|
|
||||||
layer.enabled: true
|
layer.enabled: Theme.elevationEnabled
|
||||||
layer.effect: MultiEffect {
|
layer.effect: MultiEffect {
|
||||||
shadowEnabled: true
|
shadowEnabled: Theme.elevationEnabled
|
||||||
shadowColor: Theme.shadowStrong
|
shadowColor: Theme.elevationShadowColor(Theme.elevationLevel2)
|
||||||
shadowBlur: 0.8
|
shadowBlur: Theme.elevationEnabled ? Math.max(0, Math.min(1, (Theme.elevationLevel2 && Theme.elevationLevel2.blurPx !== undefined ? Theme.elevationLevel2.blurPx : 8) / Theme.elevationBlurMax)) : 0
|
||||||
shadowHorizontalOffset: 0
|
shadowHorizontalOffset: 0
|
||||||
shadowVerticalOffset: 4
|
shadowVerticalOffset: Theme.elevationLevel2 && Theme.elevationLevel2.offsetY !== undefined ? Theme.elevationLevel2.offsetY : 4
|
||||||
|
shadowOpacity: Theme.elevationLevel2 && Theme.elevationLevel2.alpha !== undefined ? Theme.elevationLevel2.alpha : 0.25
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
|||||||
@@ -257,9 +257,10 @@ PanelWindow {
|
|||||||
scale: shouldBeVisible ? 1 : 0.9
|
scale: shouldBeVisible ? 1 : 0.9
|
||||||
|
|
||||||
property bool childHovered: false
|
property bool childHovered: false
|
||||||
property real shadowBlurPx: 10
|
readonly property var elev: Theme.elevationLevel3
|
||||||
property real shadowSpreadPx: 0
|
property real shadowBlurPx: elev && elev.blurPx !== undefined ? elev.blurPx : 12
|
||||||
property real shadowBaseAlpha: 0.60
|
property real shadowSpreadPx: elev && elev.spreadPx !== undefined ? elev.spreadPx : 0
|
||||||
|
property real shadowBaseAlpha: elev && elev.alpha !== undefined ? elev.alpha : 0.3
|
||||||
readonly property real popupSurfaceAlpha: SettingsData.popupTransparency
|
readonly property real popupSurfaceAlpha: SettingsData.popupTransparency
|
||||||
readonly property real effectiveShadowAlpha: shouldBeVisible ? Math.max(0, Math.min(1, shadowBaseAlpha * popupSurfaceAlpha)) : 0
|
readonly property real effectiveShadowAlpha: shouldBeVisible ? Math.max(0, Math.min(1, shadowBaseAlpha * popupSurfaceAlpha)) : 0
|
||||||
|
|
||||||
@@ -277,12 +278,12 @@ PanelWindow {
|
|||||||
id: bgShadowLayer
|
id: bgShadowLayer
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
visible: osdContainer.popupSurfaceAlpha >= 0.95
|
visible: osdContainer.popupSurfaceAlpha >= 0.95
|
||||||
layer.enabled: Quickshell.env("DMS_DISABLE_LAYER") !== "true" && Quickshell.env("DMS_DISABLE_LAYER") !== "1"
|
layer.enabled: Theme.elevationEnabled && Quickshell.env("DMS_DISABLE_LAYER") !== "true" && Quickshell.env("DMS_DISABLE_LAYER") !== "1"
|
||||||
layer.smooth: false
|
layer.smooth: false
|
||||||
layer.textureSize: Qt.size(Math.round(width * root.dpr), Math.round(height * root.dpr))
|
layer.textureSize: Qt.size(Math.round(width * root.dpr), Math.round(height * root.dpr))
|
||||||
layer.textureMirroring: ShaderEffectSource.MirrorVertically
|
layer.textureMirroring: ShaderEffectSource.MirrorVertically
|
||||||
|
|
||||||
readonly property int blurMax: 64
|
readonly property int blurMax: Theme.elevationBlurMax
|
||||||
|
|
||||||
layer.effect: MultiEffect {
|
layer.effect: MultiEffect {
|
||||||
id: shadowFx
|
id: shadowFx
|
||||||
|
|||||||
@@ -493,14 +493,15 @@ Item {
|
|||||||
x: contentWrapper.x
|
x: contentWrapper.x
|
||||||
y: contentWrapper.y
|
y: contentWrapper.y
|
||||||
|
|
||||||
property real shadowBlurPx: 10
|
readonly property var elev: Theme.elevationLevel3
|
||||||
property real shadowSpreadPx: 0
|
property real shadowBlurPx: elev && elev.blurPx !== undefined ? elev.blurPx : 12
|
||||||
property real shadowBaseAlpha: 0.60
|
property real shadowSpreadPx: elev && elev.spreadPx !== undefined ? elev.spreadPx : 0
|
||||||
|
property real shadowBaseAlpha: elev && elev.alpha !== undefined ? elev.alpha : 0.3
|
||||||
readonly property real popupSurfaceAlpha: SettingsData.popupTransparency
|
readonly property real popupSurfaceAlpha: SettingsData.popupTransparency
|
||||||
readonly property real effectiveShadowAlpha: Math.max(0, Math.min(1, shadowBaseAlpha * popupSurfaceAlpha))
|
readonly property real effectiveShadowAlpha: Math.max(0, Math.min(1, shadowBaseAlpha * popupSurfaceAlpha))
|
||||||
readonly property int blurMax: 64
|
readonly property int blurMax: Theme.elevationBlurMax
|
||||||
|
|
||||||
layer.enabled: Quickshell.env("DMS_DISABLE_LAYER") !== "true" && Quickshell.env("DMS_DISABLE_LAYER") !== "1" && !(root.suspendShadowWhileResizing && root._resizeActive)
|
layer.enabled: Theme.elevationEnabled && Quickshell.env("DMS_DISABLE_LAYER") !== "true" && Quickshell.env("DMS_DISABLE_LAYER") !== "1" && !(root.suspendShadowWhileResizing && root._resizeActive)
|
||||||
layer.smooth: false
|
layer.smooth: false
|
||||||
|
|
||||||
layer.effect: MultiEffect {
|
layer.effect: MultiEffect {
|
||||||
@@ -511,10 +512,8 @@ Item {
|
|||||||
maskEnabled: false
|
maskEnabled: false
|
||||||
shadowBlur: Math.max(0, Math.min(1, shadowSource.shadowBlurPx / shadowSource.blurMax))
|
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))
|
shadowScale: 1 + (2 * shadowSource.shadowSpreadPx) / Math.max(1, Math.min(shadowSource.width, shadowSource.height))
|
||||||
shadowColor: {
|
shadowVerticalOffset: parent.elev && parent.elev.offsetY !== undefined ? parent.elev.offsetY : 6
|
||||||
const baseColor = Theme.isLightMode ? Qt.rgba(0, 0, 0, 1) : Theme.surfaceContainerHighest;
|
shadowColor: Theme.elevationShadowColor(Theme.elevationLevel3)
|
||||||
return Theme.withAlpha(baseColor, shadowSource.effectiveShadowAlpha);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -53,8 +53,11 @@
|
|||||||
--m3-radius: 12px;
|
--m3-radius: 12px;
|
||||||
--m3-radius-sm: 10px;
|
--m3-radius-sm: 10px;
|
||||||
--m3-elev-0: none;
|
--m3-elev-0: none;
|
||||||
--m3-elev-1: 0 1px 2px rgba(0,0,0,.08), 0 1px 3px rgba(0,0,0,.06);
|
--m3-elev-1: 0 1px 2px color-mix(in srgb, var(--md-sys-color-shadow) 8%, transparent), 0 1px 3px color-mix(in srgb, var(--md-sys-color-shadow) 6%, transparent);
|
||||||
--m3-elev-2: 0 2px 6px rgba(0,0,0,.10), 0 1px 3px rgba(0,0,0,.06);
|
--m3-elev-2: 0 2px 6px color-mix(in srgb, var(--md-sys-color-shadow) 10%, transparent), 0 1px 3px color-mix(in srgb, var(--md-sys-color-shadow) 6%, transparent);
|
||||||
|
--m3-elev-3: 0 11px 7px color-mix(in srgb, var(--md-sys-color-shadow) 19%, transparent), 0 13px 25px color-mix(in srgb, var(--md-sys-color-shadow) 30%, transparent);
|
||||||
|
--m3-elev-4: 0 14px 12px color-mix(in srgb, var(--md-sys-color-shadow) 17%, transparent), 0 20px 40px color-mix(in srgb, var(--md-sys-color-shadow) 30%, transparent);
|
||||||
|
--m3-elev-5: 0 17px 17px color-mix(in srgb, var(--md-sys-color-shadow) 15%, transparent), 0 27px 55px color-mix(in srgb, var(--md-sys-color-shadow) 30%, transparent);
|
||||||
|
|
||||||
--tab-height: 34px;
|
--tab-height: 34px;
|
||||||
--urlbar-height: 38px;
|
--urlbar-height: 38px;
|
||||||
@@ -118,8 +121,11 @@
|
|||||||
--md-sys-color-surface-container-high: {{colors.surface_container_high.dark.hex}};
|
--md-sys-color-surface-container-high: {{colors.surface_container_high.dark.hex}};
|
||||||
--md-sys-color-surface-container-highest: {{colors.surface_container_highest.dark.hex}};
|
--md-sys-color-surface-container-highest: {{colors.surface_container_highest.dark.hex}};
|
||||||
|
|
||||||
--m3-elev-1: 0 1px 2px rgba(0,0,0,.50), 0 1px 3px rgba(0,0,0,.35);
|
--m3-elev-1: 0 1px 2px color-mix(in srgb, var(--md-sys-color-shadow) 50%, transparent), 0 1px 3px color-mix(in srgb, var(--md-sys-color-shadow) 35%, transparent);
|
||||||
--m3-elev-2: 0 4px 10px rgba(0,0,0,.55), 0 1px 3px rgba(0,0,0,.35);
|
--m3-elev-2: 0 4px 10px color-mix(in srgb, var(--md-sys-color-shadow) 55%, transparent), 0 1px 3px color-mix(in srgb, var(--md-sys-color-shadow) 35%, transparent);
|
||||||
|
--m3-elev-3: 0 11px 7px color-mix(in srgb, var(--md-sys-color-shadow) 45%, transparent), 0 13px 25px color-mix(in srgb, var(--md-sys-color-shadow) 55%, transparent);
|
||||||
|
--m3-elev-4: 0 14px 12px color-mix(in srgb, var(--md-sys-color-shadow) 42%, transparent), 0 20px 40px color-mix(in srgb, var(--md-sys-color-shadow) 55%, transparent);
|
||||||
|
--m3-elev-5: 0 17px 17px color-mix(in srgb, var(--md-sys-color-shadow) 40%, transparent), 0 27px 55px color-mix(in srgb, var(--md-sys-color-shadow) 55%, transparent);
|
||||||
|
|
||||||
--state-hover: color-mix(in srgb, var(--md-sys-color-on-surface) 6%, transparent);
|
--state-hover: color-mix(in srgb, var(--md-sys-color-on-surface) 6%, transparent);
|
||||||
--state-press: color-mix(in srgb, var(--md-sys-color-on-surface) 10%, transparent);
|
--state-press: color-mix(in srgb, var(--md-sys-color-on-surface) 10%, transparent);
|
||||||
|
|||||||
@@ -2400,6 +2400,23 @@
|
|||||||
],
|
],
|
||||||
"description": "0 = square corners"
|
"description": "0 = square corners"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"section": "m3ElevationEnabled",
|
||||||
|
"label": "M3 Elevation & Shadows",
|
||||||
|
"tabIndex": 10,
|
||||||
|
"category": "Theme & Colors",
|
||||||
|
"keywords": [
|
||||||
|
"appearance",
|
||||||
|
"elevation",
|
||||||
|
"lift",
|
||||||
|
"material",
|
||||||
|
"m3",
|
||||||
|
"shadow",
|
||||||
|
"shadows",
|
||||||
|
"theme"
|
||||||
|
],
|
||||||
|
"description": "Material Design 3 shadows and elevation on modals, popouts, and dialogs"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"section": "cursorSize",
|
"section": "cursorSize",
|
||||||
"label": "Cursor Size",
|
"label": "Cursor Size",
|
||||||
|
|||||||
Reference in New Issue
Block a user