1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2026-04-12 16:52:10 -04:00

theme: Continue to iterate m3 specs

This commit is contained in:
purian23
2026-02-26 16:18:59 -05:00
parent 788c1fa9e6
commit 972bc8397d
13 changed files with 189 additions and 40 deletions

View File

@@ -167,6 +167,10 @@ Singleton {
onEnableRippleEffectsChanged: saveSettings() onEnableRippleEffectsChanged: saveSettings()
property bool m3ElevationEnabled: true property bool m3ElevationEnabled: true
onM3ElevationEnabledChanged: saveSettings() onM3ElevationEnabledChanged: saveSettings()
property bool modalElevationEnabled: true
onModalElevationEnabledChanged: saveSettings()
property bool popoutElevationEnabled: true
onPopoutElevationEnabledChanged: 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

View File

@@ -674,16 +674,55 @@ Singleton {
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 bool elevationEnabled: typeof SettingsData !== "undefined" && (SettingsData.m3ElevationEnabled ?? true)
readonly property real elevationBlurMax: 64 readonly property real elevationBlurMax: 16
readonly property var elevationLevel1: ({ blurPx: 4, offsetY: 1, spreadPx: 0, alpha: 0.2 }) readonly property var elevationLevel1: ({
readonly property var elevationLevel2: ({ blurPx: 8, offsetY: 4, spreadPx: 0, alpha: 0.25 }) blurPx: 4,
readonly property var elevationLevel3: ({ blurPx: 12, offsetY: 6, spreadPx: 0, alpha: 0.3 }) offsetY: 1,
readonly property var elevationLevel4: ({ blurPx: 16, offsetY: 8, spreadPx: 0, alpha: 0.3 }) spreadPx: 0,
readonly property var elevationLevel5: ({ blurPx: 20, offsetY: 10, spreadPx: 0, alpha: 0.3 }) 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) { function elevationShadowColor(level) {
const alpha = (level && level.alpha !== undefined) ? level.alpha : 0.3; const alpha = (level && level.alpha !== undefined) ? level.alpha : 0.3;
const baseColor = isLightMode ? Qt.rgba(0, 0, 0, 1) : surfaceContainerHighest; return Qt.rgba(0, 0, 0, alpha);
return Theme.withAlpha(baseColor, alpha * (typeof SettingsData !== "undefined" ? SettingsData.popupTransparency : 1)); }
function elevationTintOpacity(level) {
if (!level)
return 0;
if (level === elevationLevel1)
return 0.05;
if (level === elevationLevel2)
return 0.08;
if (level === elevationLevel3)
return 0.11;
if (level === elevationLevel4)
return 0.12;
if (level === elevationLevel5)
return 0.14;
return 0.08;
} }
readonly property var animationDurations: [ readonly property var animationDurations: [

View File

@@ -47,6 +47,8 @@ var SPEC = {
modalCustomAnimationDuration: { def: 150 }, modalCustomAnimationDuration: { def: 150 },
enableRippleEffects: { def: true }, enableRippleEffects: { def: true },
m3ElevationEnabled: { def: true }, m3ElevationEnabled: { def: true },
modalElevationEnabled: { def: true },
popoutElevationEnabled: { def: true },
wallpaperFillMode: { def: "Fill" }, wallpaperFillMode: { def: "Fill" },
blurredWallpaperLayer: { def: false }, blurredWallpaperLayer: { def: false },
blurWallpaperOnOverview: { def: false }, blurWallpaperOnOverview: { def: false },

View File

@@ -35,7 +35,7 @@ Item {
property color borderColor: Theme.outlineMedium property color borderColor: Theme.outlineMedium
property real borderWidth: 1 property real borderWidth: 1
property real cornerRadius: Theme.cornerRadius property real cornerRadius: Theme.cornerRadius
property bool enableShadow: false property bool enableShadow: true
property alias modalFocusScope: focusScope property alias modalFocusScope: focusScope
property bool shouldBeVisible: false property bool shouldBeVisible: false
property bool shouldHaveFocus: shouldBeVisible property bool shouldHaveFocus: shouldBeVisible
@@ -143,7 +143,7 @@ Item {
} }
} }
readonly property real shadowBuffer: 5 readonly property real shadowBuffer: 24
readonly property real alignedWidth: Theme.px(modalWidth, dpr) readonly property real alignedWidth: Theme.px(modalWidth, dpr)
readonly property real alignedHeight: Theme.px(modalHeight, dpr) readonly property real alignedHeight: Theme.px(modalHeight, dpr)
@@ -381,13 +381,10 @@ Item {
readonly property var elev: Theme.elevationLevel3 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)) readonly property real shadowBlurNorm: Math.max(0, Math.min(1, (elev && elev.blurPx !== undefined ? elev.blurPx : 12) / Theme.elevationBlurMax))
Rectangle { Item {
id: modalShadowShape id: modalShadowLayer
anchors.fill: parent anchors.fill: parent
radius: root.cornerRadius layer.enabled: root.enableShadow && Theme.elevationEnabled && SettingsData.modalElevationEnabled && Quickshell.env("DMS_DISABLE_LAYER") !== "true" && Quickshell.env("DMS_DISABLE_LAYER") !== "1"
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.smooth: false
layer.effect: MultiEffect { layer.effect: MultiEffect {
@@ -395,20 +392,27 @@ Item {
shadowEnabled: true shadowEnabled: true
blurEnabled: false blurEnabled: false
maskEnabled: false maskEnabled: false
shadowBlur: modalShadowShape.parent.shadowBlurNorm shadowBlur: animatedContent.shadowBlurNorm
shadowScale: 1 shadowScale: 1
shadowVerticalOffset: modalShadowShape.parent.elev && modalShadowShape.parent.elev.offsetY !== undefined ? modalShadowShape.parent.elev.offsetY : 6 shadowVerticalOffset: animatedContent.elev && animatedContent.elev.offsetY !== undefined ? animatedContent.elev.offsetY : 6
shadowHorizontalOffset: 0 shadowHorizontalOffset: 0
shadowColor: Theme.elevationShadowColor(Theme.elevationLevel3) shadowColor: Theme.elevationShadowColor(Theme.elevationLevel3)
} }
Rectangle {
anchors.fill: parent
radius: root.cornerRadius
color: root.backgroundColor
border.color: root.borderColor
border.width: root.borderWidth
}
} }
Rectangle { Rectangle {
anchors.fill: parent anchors.fill: parent
color: root.backgroundColor
border.color: root.borderColor
border.width: root.borderWidth
radius: root.cornerRadius radius: root.cornerRadius
color: Theme.surfaceTint
opacity: Theme.elevationEnabled ? Theme.elevationTintOpacity(Theme.elevationLevel3) : 0
} }
FocusScope { FocusScope {

View File

@@ -1,4 +1,5 @@
import QtQuick import QtQuick
import QtQuick.Effects
import Quickshell import Quickshell
import Quickshell.Wayland import Quickshell.Wayland
import Quickshell.Hyprland import Quickshell.Hyprland
@@ -390,12 +391,37 @@ Item {
} }
} }
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
blurEnabled: false
maskEnabled: false
shadowBlur: Math.max(0, Math.min(1, Theme.elevationLevel3.blurPx / Theme.elevationBlurMax))
shadowScale: 1
shadowVerticalOffset: Theme.elevationLevel3.offsetY
shadowHorizontalOffset: 0
shadowColor: Theme.elevationShadowColor(Theme.elevationLevel3)
}
Rectangle {
anchors.fill: parent
color: root.backgroundColor
border.color: root.borderColor
border.width: root.borderWidth
radius: root.cornerRadius
}
}
Rectangle { Rectangle {
anchors.fill: parent anchors.fill: parent
color: root.backgroundColor
border.color: root.borderColor
border.width: root.borderWidth
radius: root.cornerRadius radius: root.cornerRadius
color: Theme.surfaceTint
opacity: Theme.elevationEnabled ? Theme.elevationTintOpacity(Theme.elevationLevel3) : 0
} }
MouseArea { MouseArea {

View File

@@ -814,12 +814,11 @@ Item {
layer.enabled: true layer.enabled: true
layer.effect: MultiEffect { layer.effect: MultiEffect {
shadowEnabled: true shadowEnabled: Theme.elevationEnabled
shadowHorizontalOffset: 0 shadowHorizontalOffset: 0
shadowVerticalOffset: 4 shadowVerticalOffset: 4
shadowBlur: 0.8 shadowBlur: 0.8
shadowColor: Qt.rgba(0, 0, 0, 0.2) shadowColor: Theme.elevationShadowColor(Theme.elevationLevel2)
shadowOpacity: 0.2
} }
} }
@@ -836,12 +835,11 @@ Item {
layer.enabled: true layer.enabled: true
layer.effect: MultiEffect { layer.effect: MultiEffect {
shadowEnabled: true shadowEnabled: Theme.elevationEnabled
shadowHorizontalOffset: 0 shadowHorizontalOffset: 0
shadowVerticalOffset: 4 shadowVerticalOffset: 4
shadowBlur: 0.8 shadowBlur: 0.8
shadowColor: Qt.rgba(0, 0, 0, 0.2) shadowColor: Theme.elevationShadowColor(Theme.elevationLevel2)
shadowOpacity: 0.2
} }
} }
} }

View File

@@ -1,4 +1,5 @@
import QtQuick import QtQuick
import QtQuick.Effects
import Quickshell import Quickshell
import qs.Common import qs.Common
import qs.Services import qs.Services
@@ -32,6 +33,20 @@ Rectangle {
radius: Theme.cornerRadius radius: Theme.cornerRadius
clip: true clip: true
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
blurEnabled: false
maskEnabled: false
shadowBlur: Math.max(0, Math.min(1, Theme.elevationLevel1.blurPx / Theme.elevationBlurMax))
shadowScale: 1
shadowVerticalOffset: Theme.elevationLevel1.offsetY
shadowHorizontalOffset: 0
shadowColor: Theme.elevationShadowColor(Theme.elevationLevel1)
}
color: { color: {
if (isSelected && keyboardNavigationActive) if (isSelected && keyboardNavigationActive)
return Theme.primaryPressed; return Theme.primaryPressed;

View File

@@ -1,5 +1,6 @@
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Effects
import Quickshell import Quickshell
import Quickshell.Services.Notifications import Quickshell.Services.Notifications
import qs.Common import qs.Common
@@ -99,6 +100,20 @@ Rectangle {
} }
clip: true clip: true
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
blurEnabled: false
maskEnabled: false
shadowBlur: Math.max(0, Math.min(1, Theme.elevationLevel1.blurPx / Theme.elevationBlurMax))
shadowScale: 1
shadowVerticalOffset: Theme.elevationLevel1.offsetY
shadowHorizontalOffset: 0
shadowColor: Theme.elevationShadowColor(Theme.elevationLevel1)
}
HoverHandler { HoverHandler {
id: cardHoverHandler id: cardHoverHandler
} }

View File

@@ -341,7 +341,7 @@ PanelWindow {
layer.textureSize: Qt.size(Math.round(width * win.dpr), Math.round(height * win.dpr)) layer.textureSize: Qt.size(Math.round(width * win.dpr), Math.round(height * win.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
@@ -391,6 +391,13 @@ PanelWindow {
} }
} }
} }
Rectangle {
anchors.fill: parent
radius: shadowShapeSource.radius
color: Theme.surfaceTint
opacity: Theme.elevationEnabled ? Theme.elevationTintOpacity(content.elevLevel) : 0
}
} }
Item { Item {

View File

@@ -1602,6 +1602,28 @@ Item {
checked: SettingsData.m3ElevationEnabled ?? true checked: SettingsData.m3ElevationEnabled ?? true
onToggled: checked => SettingsData.set("m3ElevationEnabled", checked) onToggled: checked => SettingsData.set("m3ElevationEnabled", checked)
} }
SettingsToggleRow {
tab: "theme"
tags: ["elevation", "shadow", "modal", "dialog", "m3"]
settingKey: "modalElevationEnabled"
text: I18n.tr("Modal Shadows")
description: I18n.tr("Shadow elevation on modals and dialogs")
checked: SettingsData.modalElevationEnabled ?? true
visible: SettingsData.m3ElevationEnabled ?? true
onToggled: checked => SettingsData.set("modalElevationEnabled", checked)
}
SettingsToggleRow {
tab: "theme"
tags: ["elevation", "shadow", "popout", "popup", "osd", "dropdown", "m3"]
settingKey: "popoutElevationEnabled"
text: I18n.tr("Popout Shadows")
description: I18n.tr("Shadow elevation on popouts, OSDs, and dropdowns")
checked: SettingsData.popoutElevationEnabled ?? true
visible: SettingsData.m3ElevationEnabled ?? true
onToggled: checked => SettingsData.set("popoutElevationEnabled", checked)
}
} }
SettingsCard { SettingsCard {

View File

@@ -263,12 +263,19 @@ Item {
layer.enabled: true layer.enabled: true
layer.effect: MultiEffect { layer.effect: MultiEffect {
shadowEnabled: Theme.elevationEnabled 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 shadowBlur: Theme.elevationEnabled ? Math.max(0, Math.min(1, (Theme.elevationLevel2 && Theme.elevationLevel2.blurPx !== undefined ? Theme.elevationLevel2.blurPx : 8) / Theme.elevationBlurMax)) : 0
shadowColor: Theme.elevationShadowColor(Theme.elevationLevel2) shadowColor: Theme.elevationShadowColor(Theme.elevationLevel2)
shadowVerticalOffset: Theme.elevationLevel2 && Theme.elevationLevel2.offsetY !== undefined ? Theme.elevationLevel2.offsetY : 4 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 { Column {
anchors.fill: parent anchors.fill: parent
anchors.margins: Theme.spacingS anchors.margins: Theme.spacingS

View File

@@ -278,7 +278,7 @@ PanelWindow {
id: bgShadowLayer id: bgShadowLayer
anchors.fill: parent anchors.fill: parent
visible: osdContainer.popupSurfaceAlpha >= 0.95 visible: osdContainer.popupSurfaceAlpha >= 0.95
layer.enabled: Theme.elevationEnabled && Quickshell.env("DMS_DISABLE_LAYER") !== "true" && Quickshell.env("DMS_DISABLE_LAYER") !== "1" layer.enabled: Theme.elevationEnabled && SettingsData.popoutElevationEnabled && 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
@@ -293,10 +293,7 @@ PanelWindow {
maskEnabled: false maskEnabled: false
shadowBlur: Math.max(0, Math.min(1, osdContainer.shadowBlurPx / bgShadowLayer.blurMax)) 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)) shadowScale: 1 + (2 * osdContainer.shadowSpreadPx) / Math.max(1, Math.min(bgShadowLayer.width, bgShadowLayer.height))
shadowColor: { shadowColor: Theme.elevationShadowColor(Theme.elevationLevel3)
const baseColor = Theme.isLightMode ? Qt.rgba(0, 0, 0, 1) : Theme.surfaceContainerHighest;
return Theme.withAlpha(baseColor, osdContainer.effectiveShadowAlpha);
}
} }
Rectangle { Rectangle {
@@ -306,6 +303,13 @@ PanelWindow {
border.color: Theme.outlineMedium border.color: Theme.outlineMedium
border.width: 1 border.width: 1
} }
Rectangle {
anchors.fill: parent
radius: Theme.cornerRadius
color: Theme.surfaceTint
opacity: Theme.elevationEnabled ? Theme.elevationTintOpacity(Theme.elevationLevel3) : 0
}
} }
MouseArea { MouseArea {

View File

@@ -197,7 +197,7 @@ Item {
readonly property real screenHeight: screen ? screen.height : 0 readonly property real screenHeight: screen ? screen.height : 0
readonly property real dpr: screen ? screen.devicePixelRatio : 1 readonly property real dpr: screen ? screen.devicePixelRatio : 1
readonly property real shadowBuffer: 5 readonly property real shadowBuffer: 24
readonly property real alignedWidth: Theme.px(popupWidth, dpr) readonly property real alignedWidth: Theme.px(popupWidth, dpr)
readonly property real alignedHeight: Theme.px(popupHeight, dpr) readonly property real alignedHeight: Theme.px(popupHeight, dpr)
@@ -487,7 +487,6 @@ Item {
height: parent.height height: parent.height
radius: Theme.cornerRadius radius: Theme.cornerRadius
color: "black" color: "black"
visible: false
opacity: contentWrapper.opacity opacity: contentWrapper.opacity
scale: contentWrapper.scale scale: contentWrapper.scale
x: contentWrapper.x x: contentWrapper.x
@@ -501,7 +500,7 @@ Item {
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: Theme.elevationBlurMax readonly property int blurMax: Theme.elevationBlurMax
layer.enabled: Theme.elevationEnabled && Quickshell.env("DMS_DISABLE_LAYER") !== "true" && Quickshell.env("DMS_DISABLE_LAYER") !== "1" && !(root.suspendShadowWhileResizing && root._resizeActive) 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.smooth: false
layer.effect: MultiEffect { layer.effect: MultiEffect {
@@ -548,6 +547,13 @@ Item {
border.width: 1 border.width: 1
} }
Rectangle {
anchors.fill: parent
radius: Theme.cornerRadius
color: Theme.surfaceTint
opacity: Theme.elevationEnabled ? Theme.elevationTintOpacity(Theme.elevationLevel3) : 0
}
Loader { Loader {
id: contentLoader id: contentLoader
anchors.fill: parent anchors.fill: parent