1
0
mirror of https://github.com/AvengeMedia/DankMaterialShell.git synced 2025-12-06 05:25:41 -05:00

systemtray: new tray detail menu

This commit is contained in:
bbedward
2025-11-13 16:30:07 -05:00
parent 1858597fc9
commit d46b7528e7
4 changed files with 382 additions and 228 deletions

View File

@@ -1,10 +1,12 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Effects
import Quickshell
import Quickshell.Services.SystemTray
import Quickshell.Wayland
import Quickshell.Widgets
import qs.Common
import qs.Services
import qs.Widgets
Item {
@@ -45,6 +47,7 @@ Item {
visible: allTrayItems.length > 0
property bool menuOpen: false
property bool overflowWasOpenBeforeTrayMenu: false
Rectangle {
id: visualBackground
@@ -157,17 +160,17 @@ Item {
acceptedButtons: Qt.LeftButton | Qt.RightButton
cursorShape: Qt.PointingHandCursor
onClicked: (mouse) => {
if (!delegateRoot.trayItem) {
return;
}
if (!delegateRoot.trayItem) return
if (mouse.button === Qt.LeftButton && !delegateRoot.trayItem.onlyMenu) {
delegateRoot.trayItem.activate();
return ;
}
if (delegateRoot.trayItem.hasMenu) {
root.showForTrayItem(delegateRoot.trayItem, visualContent, parentScreen, root.isAtBottom, root.isVertical, root.axis);
delegateRoot.trayItem.activate()
return
}
if (!delegateRoot.trayItem.hasMenu) return
root.overflowWasOpenBeforeTrayMenu = root.menuOpen
root.showForTrayItem(delegateRoot.trayItem, visualContent, parentScreen, root.isAtBottom, root.isVertical, root.axis)
}
}
}
@@ -289,17 +292,17 @@ Item {
acceptedButtons: Qt.LeftButton | Qt.RightButton
cursorShape: Qt.PointingHandCursor
onClicked: (mouse) => {
if (!delegateRoot.trayItem) {
return;
}
if (!delegateRoot.trayItem) return
if (mouse.button === Qt.LeftButton && !delegateRoot.trayItem.onlyMenu) {
delegateRoot.trayItem.activate();
return ;
}
if (delegateRoot.trayItem.hasMenu) {
root.showForTrayItem(delegateRoot.trayItem, visualContent, parentScreen, root.isAtBottom, root.isVertical, root.axis);
delegateRoot.trayItem.activate()
return
}
if (!delegateRoot.trayItem.hasMenu) return
root.overflowWasOpenBeforeTrayMenu = root.menuOpen
root.showForTrayItem(delegateRoot.trayItem, visualContent, parentScreen, root.isAtBottom, root.isVertical, root.axis)
}
}
}
@@ -349,7 +352,7 @@ Item {
screen: root.parentScreen
WlrLayershell.layer: WlrLayershell.Top
WlrLayershell.exclusiveZone: -1
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
WlrLayershell.keyboardFocus: WlrKeyboardFocus.OnDemand
WlrLayershell.namespace: "dms:tray-overflow-menu"
color: "transparent"
@@ -360,10 +363,26 @@ Item {
bottom: true
}
readonly property real dpr: (typeof CompositorService !== "undefined" && CompositorService.getScreenScale)
? CompositorService.getScreenScale(overflowMenu.screen)
: (screen?.devicePixelRatio || 1)
property point anchorPos: Qt.point(screen.width / 2, screen.height / 2)
onVisibleChanged: {
if (visible) updatePosition()
if (visible) {
updatePosition()
Qt.callLater(() => overflowFocusScope.forceActiveFocus())
}
}
FocusScope {
id: overflowFocusScope
anchors.fill: parent
focus: true
Keys.onEscapePressed: {
root.menuOpen = false
}
}
function updatePosition() {
@@ -395,50 +414,71 @@ Item {
}
}
Rectangle {
Item {
id: menuContainer
width: 250
height: Math.min(screen.height - 100, menuColumn.implicitHeight + Theme.spacingS * 2)
x: {
readonly property real rawWidth: {
const itemCount = root.allTrayItems.length
const cols = Math.min(5, itemCount)
const itemSize = 28
const spacing = 2
return cols * itemSize + (cols - 1) * spacing + Theme.spacingS * 2
}
readonly property real rawHeight: {
const itemCount = root.allTrayItems.length
const cols = Math.min(5, itemCount)
const rows = Math.ceil(itemCount / cols)
const itemSize = 28
const spacing = 2
return rows * itemSize + (rows - 1) * spacing + Theme.spacingS * 2
}
readonly property real alignedWidth: Theme.px(rawWidth, overflowMenu.dpr)
readonly property real alignedHeight: Theme.px(rawHeight, overflowMenu.dpr)
width: alignedWidth
height: alignedHeight
x: Theme.snap((() => {
if (root.isVertical) {
const edge = root.axis?.edge
if (edge === "left") {
const targetX = overflowMenu.anchorPos.x
return Math.min(overflowMenu.screen.width - width - 10, targetX)
return Math.min(overflowMenu.screen.width - alignedWidth - 10, targetX)
} else {
const targetX = overflowMenu.anchorPos.x - width
const targetX = overflowMenu.anchorPos.x - alignedWidth
return Math.max(10, targetX)
}
} else {
const left = 10
const right = overflowMenu.width - width - 10
const want = overflowMenu.anchorPos.x - width / 2
const right = overflowMenu.width - alignedWidth - 10
const want = overflowMenu.anchorPos.x - alignedWidth / 2
return Math.max(left, Math.min(right, want))
}
}
})(), overflowMenu.dpr)
y: {
y: Theme.snap((() => {
if (root.isVertical) {
const top = 10
const bottom = overflowMenu.height - height - 10
const want = overflowMenu.anchorPos.y - height / 2
const bottom = overflowMenu.height - alignedHeight - 10
const want = overflowMenu.anchorPos.y - alignedHeight / 2
return Math.max(top, Math.min(bottom, want))
} else {
if (root.isAtBottom) {
const targetY = overflowMenu.anchorPos.y - height
const targetY = overflowMenu.anchorPos.y - alignedHeight
return Math.max(10, targetY)
} else {
const targetY = overflowMenu.anchorPos.y
return Math.min(overflowMenu.screen.height - height - 10, targetY)
return Math.min(overflowMenu.screen.height - alignedHeight - 10, targetY)
}
}
}
})(), overflowMenu.dpr)
color: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency)
radius: Theme.cornerRadius
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
border.width: 1
property real shadowBlurPx: 10
property real shadowSpreadPx: 0
property real shadowBaseAlpha: 0.60
readonly property real popupSurfaceAlpha: Theme.popupTransparency
readonly property real effectiveShadowAlpha: Math.max(0, Math.min(1, shadowBaseAlpha * popupSurfaceAlpha))
opacity: root.menuOpen ? 1 : 0
scale: root.menuOpen ? 1 : 0.85
@@ -457,156 +497,122 @@ Item {
}
}
Rectangle {
Item {
id: bgShadowLayer
anchors.fill: parent
anchors.topMargin: 4
anchors.leftMargin: 2
anchors.rightMargin: -2
anchors.bottomMargin: -4
radius: parent.radius
color: Qt.rgba(0, 0, 0, 0.15)
z: parent.z - 1
layer.enabled: true
layer.smooth: true
layer.textureSize: Qt.size(Math.round(width * overflowMenu.dpr * 2), Math.round(height * overflowMenu.dpr * 2))
layer.textureMirroring: ShaderEffectSource.MirrorVertically
layer.samples: 4
layer.effect: MultiEffect {
autoPaddingEnabled: true
shadowEnabled: true
blurEnabled: false
maskEnabled: false
property int blurMax: 64
shadowBlur: Math.max(0, Math.min(1, menuContainer.shadowBlurPx / blurMax))
shadowScale: 1 + (2 * menuContainer.shadowSpreadPx) / Math.max(1, Math.min(bgShadowLayer.width, bgShadowLayer.height))
shadowColor: {
const baseColor = Theme.isLightMode ? Qt.rgba(0, 0, 0, 1) : Theme.surfaceContainerHighest
return Theme.withAlpha(baseColor, menuContainer.effectiveShadowAlpha)
}
}
Rectangle {
anchors.fill: parent
color: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency)
radius: Theme.cornerRadius
antialiasing: true
smooth: true
}
}
DankFlickable {
id: scrollView
anchors.fill: parent
anchors.margins: Theme.spacingS
contentWidth: width
contentHeight: menuColumn.implicitHeight
clip: true
Grid {
id: menuGrid
anchors.centerIn: parent
columns: Math.min(5, root.allTrayItems.length)
spacing: 2
rowSpacing: 2
Column {
id: menuColumn
width: parent.width
spacing: 2
Repeater {
model: root.allTrayItems
Repeater {
model: root.allTrayItems
delegate: Rectangle {
property var trayItem: modelData
property string iconSource: {
let icon = trayItem?.icon
if (typeof icon === 'string' || icon instanceof String) {
if (icon === "") return ""
if (icon.includes("?path=")) {
const split = icon.split("?path=")
if (split.length !== 2) return icon
const name = split[0]
const path = split[1]
let fileName = name.substring(name.lastIndexOf("/") + 1)
if (fileName.startsWith("dropboxstatus")) {
fileName = `hicolor/16x16/status/${fileName}`
}
return `file://${path}/${fileName}`
delegate: Rectangle {
property var trayItem: modelData
property string iconSource: {
let icon = trayItem?.icon
if (typeof icon === 'string' || icon instanceof String) {
if (icon === "") return ""
if (icon.includes("?path=")) {
const split = icon.split("?path=")
if (split.length !== 2) return icon
const name = split[0]
const path = split[1]
let fileName = name.substring(name.lastIndexOf("/") + 1)
if (fileName.startsWith("dropboxstatus")) {
fileName = `hicolor/16x16/status/${fileName}`
}
if (icon.startsWith("/") && !icon.startsWith("file://")) {
return `file://${icon}`
}
return icon
return `file://${path}/${fileName}`
}
return ""
if (icon.startsWith("/") && !icon.startsWith("file://")) {
return `file://${icon}`
}
return icon
}
return ""
}
width: menuColumn.width
height: 32
radius: Theme.cornerRadius
color: itemArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent"
width: 28
height: 28
radius: Theme.cornerRadius
color: itemArea.containsMouse ? Theme.primaryHover : Theme.withAlpha(Theme.surfaceContainer, 0)
Row {
anchors.left: parent.left
anchors.leftMargin: Theme.spacingS
anchors.verticalCenter: parent.verticalCenter
spacing: Theme.spacingS
IconImage {
id: menuIconImg
anchors.centerIn: parent
width: Theme.barIconSize(root.barThickness)
height: Theme.barIconSize(root.barThickness)
source: parent.iconSource
asynchronous: true
smooth: true
mipmap: true
visible: status === Image.Ready
}
IconImage {
id: menuIconImg
width: 20
height: 20
anchors.verticalCenter: parent.verticalCenter
source: parent.parent.iconSource
asynchronous: true
smooth: true
mipmap: true
visible: status === Image.Ready
}
Text {
anchors.verticalCenter: parent.verticalCenter
visible: !menuIconImg.visible
text: {
const itemId = trayItem?.id || ""
if (!itemId) return "?"
return itemId.charAt(0).toUpperCase()
}
font.pixelSize: 10
color: Theme.surfaceText
}
StyledText {
text: trayItem?.tooltip?.title || trayItem?.id || "Unknown"
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
elide: Text.ElideRight
anchors.verticalCenter: parent.verticalCenter
width: Math.min(implicitWidth, menuColumn.width - 80)
}
Text {
anchors.centerIn: parent
visible: !menuIconImg.visible
text: {
const itemId = trayItem?.id || ""
if (!itemId) return "?"
return itemId.charAt(0).toUpperCase()
}
font.pixelSize: 10
color: Theme.surfaceText
}
Rectangle {
anchors.right: parent.right
anchors.rightMargin: Theme.spacingS
anchors.verticalCenter: parent.verticalCenter
width: 24
height: 24
radius: Theme.cornerRadius
color: visibilityArea.containsMouse ? Theme.primaryHover : "transparent"
MouseArea {
id: itemArea
anchors.fill: parent
hoverEnabled: true
acceptedButtons: Qt.LeftButton | Qt.RightButton
cursorShape: Qt.PointingHandCursor
onClicked: (mouse) => {
if (!trayItem) return
DankIcon {
anchors.centerIn: parent
name: SessionData.isHiddenTrayId(trayItem?.id || "") ? "visibility_off" : "visibility"
size: 16
color: Theme.surfaceText
if (mouse.button === Qt.LeftButton && !trayItem.onlyMenu) {
trayItem.activate()
root.menuOpen = false
return
}
MouseArea {
id: visibilityArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
const itemId = trayItem?.id || ""
if (!itemId) return
if (SessionData.isHiddenTrayId(itemId)) {
SessionData.showTrayId(itemId)
} else {
SessionData.hideTrayId(itemId)
}
}
}
}
if (!trayItem.hasMenu) return
MouseArea {
id: itemArea
anchors.fill: parent
anchors.rightMargin: 32
hoverEnabled: true
acceptedButtons: Qt.LeftButton | Qt.RightButton
cursorShape: Qt.PointingHandCursor
onClicked: (mouse) => {
if (!trayItem) return
if (mouse.button === Qt.LeftButton && !trayItem.onlyMenu) {
trayItem.activate()
root.menuOpen = false
return
}
if (trayItem.hasMenu) {
root.menuOpen = false
root.showForTrayItem(trayItem, parent, parentScreen, root.isAtBottom, root.isVertical, root.axis)
}
}
root.overflowWasOpenBeforeTrayMenu = true
root.menuOpen = false
root.showForTrayItem(trayItem, parent, parentScreen, root.isAtBottom, root.isVertical, root.axis)
}
}
}
@@ -665,6 +671,20 @@ Item {
function close() {
showMenu = false
if (root.overflowWasOpenBeforeTrayMenu) {
root.menuOpen = true
Qt.callLater(() => {
if (overflowMenu.visible && overflowFocusScope) {
overflowFocusScope.forceActiveFocus()
}
})
}
root.overflowWasOpenBeforeTrayMenu = false
}
function closeWithAction() {
root.overflowWasOpenBeforeTrayMenu = false
close()
}
function showSubMenu(entry) {
@@ -697,7 +717,7 @@ Item {
visible: menuRoot.showMenu && (menuRoot.trayItem?.hasMenu ?? false)
WlrLayershell.layer: WlrLayershell.Top
WlrLayershell.exclusiveZone: -1
WlrLayershell.keyboardFocus: WlrKeyboardFocus.None
WlrLayershell.keyboardFocus: WlrKeyboardFocus.OnDemand
color: "transparent"
anchors {
@@ -707,11 +727,29 @@ Item {
bottom: true
}
readonly property real dpr: (typeof CompositorService !== "undefined" && CompositorService.getScreenScale)
? CompositorService.getScreenScale(menuWindow.screen)
: (screen?.devicePixelRatio || 1)
property point anchorPos: Qt.point(screen.width / 2, screen.height / 2)
onVisibleChanged: {
if (visible) {
updatePosition()
Qt.callLater(() => menuFocusScope.forceActiveFocus())
}
}
FocusScope {
id: menuFocusScope
anchors.fill: parent
focus: true
Keys.onEscapePressed: {
if (entryStack.count > 0) {
menuRoot.goBack()
} else {
menuRoot.close()
}
}
}
@@ -744,64 +782,104 @@ Item {
}
}
Rectangle {
Item {
id: menuContainer
width: Math.min(500, Math.max(250, menuColumn.implicitWidth + Theme.spacingS * 2))
height: Math.max(40, menuColumn.implicitHeight + Theme.spacingS * 2)
readonly property real rawWidth: Math.min(500, Math.max(250, menuColumn.implicitWidth + Theme.spacingS * 2))
readonly property real rawHeight: Math.max(40, menuColumn.implicitHeight + Theme.spacingS * 2)
x: {
readonly property real alignedWidth: Theme.px(rawWidth, menuWindow.dpr)
readonly property real alignedHeight: Theme.px(rawHeight, menuWindow.dpr)
width: alignedWidth
height: alignedHeight
x: Theme.snap((() => {
if (menuRoot.isVertical) {
const edge = menuRoot.axis?.edge
if (edge === "left") {
const targetX = menuWindow.anchorPos.x
return Math.min(menuWindow.screen.width - width - 10, targetX)
return Math.min(menuWindow.screen.width - alignedWidth - 10, targetX)
} else {
const targetX = menuWindow.anchorPos.x - width
const targetX = menuWindow.anchorPos.x - alignedWidth
return Math.max(10, targetX)
}
} else {
const left = 10
const right = menuWindow.width - width - 10
const want = menuWindow.anchorPos.x - width / 2
const right = menuWindow.width - alignedWidth - 10
const want = menuWindow.anchorPos.x - alignedWidth / 2
return Math.max(left, Math.min(right, want))
}
}
})(), menuWindow.dpr)
y: {
y: Theme.snap((() => {
if (menuRoot.isVertical) {
const top = 10
const bottom = menuWindow.height - height - 10
const want = menuWindow.anchorPos.y - height / 2
const bottom = menuWindow.height - alignedHeight - 10
const want = menuWindow.anchorPos.y - alignedHeight / 2
return Math.max(top, Math.min(bottom, want))
} else {
if (menuRoot.isAtBottom) {
const targetY = menuWindow.anchorPos.y - height
const targetY = menuWindow.anchorPos.y - alignedHeight
return Math.max(10, targetY)
} else {
const targetY = menuWindow.anchorPos.y
return Math.min(menuWindow.screen.height - height - 10, targetY)
return Math.min(menuWindow.screen.height - alignedHeight - 10, targetY)
}
}
}
})(), menuWindow.dpr)
color: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency)
radius: Theme.cornerRadius
border.color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.08)
border.width: 1
property real shadowBlurPx: 10
property real shadowSpreadPx: 0
property real shadowBaseAlpha: 0.60
readonly property real popupSurfaceAlpha: Theme.popupTransparency
readonly property real effectiveShadowAlpha: Math.max(0, Math.min(1, shadowBaseAlpha * popupSurfaceAlpha))
opacity: menuRoot.showMenu ? 1 : 0
scale: menuRoot.showMenu ? 1 : 0.85
Rectangle {
Behavior on opacity {
NumberAnimation {
duration: Theme.mediumDuration
easing.type: Theme.emphasizedEasing
}
}
Behavior on scale {
NumberAnimation {
duration: Theme.mediumDuration
easing.type: Theme.emphasizedEasing
}
}
Item {
id: menuBgShadowLayer
anchors.fill: parent
anchors.topMargin: 4
anchors.leftMargin: 2
anchors.rightMargin: -2
anchors.bottomMargin: -4
radius: parent.radius
color: Qt.rgba(0, 0, 0, 0.15)
z: parent.z - 1
layer.enabled: true
layer.smooth: true
layer.textureSize: Qt.size(Math.round(width * menuWindow.dpr), Math.round(height * menuWindow.dpr))
layer.textureMirroring: ShaderEffectSource.MirrorVertically
layer.effect: MultiEffect {
autoPaddingEnabled: true
shadowEnabled: true
blurEnabled: false
maskEnabled: false
property int blurMax: 64
shadowBlur: Math.max(0, Math.min(1, menuContainer.shadowBlurPx / blurMax))
shadowScale: 1 + (2 * menuContainer.shadowSpreadPx) / Math.max(1, Math.min(menuBgShadowLayer.width, menuBgShadowLayer.height))
shadowColor: {
const baseColor = Theme.isLightMode ? Qt.rgba(0, 0, 0, 1) : Theme.surfaceContainerHighest
return Theme.withAlpha(baseColor, menuContainer.effectiveShadowAlpha)
}
}
Rectangle {
anchors.fill: parent
color: Theme.withAlpha(Theme.surfaceContainer, Theme.popupTransparency)
radius: Theme.cornerRadius
antialiasing: true
}
}
QsMenuAnchor {
@@ -832,12 +910,90 @@ Item {
anchors.topMargin: Theme.spacingS
spacing: 1
Rectangle {
visible: entryStack.count === 0
width: parent.width
height: 24
color: "transparent"
StyledText {
anchors.centerIn: parent
text: menuRoot.trayItem?.id || "Unknown"
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceTextMedium
elide: Text.ElideMiddle
width: parent.width - Theme.spacingS * 2
horizontalAlignment: Text.AlignHCenter
}
}
Rectangle {
visible: entryStack.count === 0
width: parent.width
height: 1
color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
}
Rectangle {
visible: entryStack.count === 0
width: parent.width
height: 28
radius: 0
color: visibilityToggleArea.containsMouse ? Theme.primaryHover : Theme.withAlpha(Theme.surfaceContainer, 0)
Row {
anchors.left: parent.left
anchors.leftMargin: Theme.spacingS
anchors.verticalCenter: parent.verticalCenter
spacing: Theme.spacingXS
DankIcon {
name: SessionData.isHiddenTrayId(menuRoot.trayItem?.id || "") ? "visibility" : "visibility_off"
size: 16
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
StyledText {
text: SessionData.isHiddenTrayId(menuRoot.trayItem?.id || "") ? "Show in Tray" : "Hide from Tray"
font.pixelSize: Theme.fontSizeSmall
color: Theme.surfaceText
anchors.verticalCenter: parent.verticalCenter
}
}
MouseArea {
id: visibilityToggleArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: {
const itemId = menuRoot.trayItem?.id || ""
if (!itemId) return
if (SessionData.isHiddenTrayId(itemId)) {
SessionData.showTrayId(itemId)
} else {
SessionData.hideTrayId(itemId)
}
menuRoot.closeWithAction()
}
}
}
Rectangle {
visible: entryStack.count === 0
width: parent.width
height: 1
color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
}
Rectangle {
visible: entryStack.count > 0
width: parent.width
height: 28
radius: Theme.cornerRadius
color: backArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent"
radius: 0
color: backArea.containsMouse ? Theme.primaryHover : Theme.withAlpha(Theme.surfaceContainer, 0)
Row {
anchors.left: parent.left
@@ -863,6 +1019,7 @@ Item {
MouseArea {
id: backArea
anchors.fill: parent
hoverEnabled: true
cursorShape: Qt.PointingHandCursor
onClicked: menuRoot.goBack()
}
@@ -886,33 +1043,35 @@ Item {
width: menuColumn.width
height: menuEntry?.isSeparator ? 1 : 28
radius: menuEntry?.isSeparator ? 0 : Theme.cornerRadius
radius: 0
color: {
if (menuEntry?.isSeparator) {
return Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.2)
}
return itemArea.containsMouse ? Qt.rgba(Theme.primary.r, Theme.primary.g, Theme.primary.b, 0.12) : "transparent"
return itemArea.containsMouse ? Theme.primaryHover : Theme.withAlpha(Theme.surfaceContainer, 0)
}
MouseArea {
id: itemArea
anchors.fill: parent
hoverEnabled: true
enabled: !menuEntry?.isSeparator && (menuEntry?.enabled !== false)
cursorShape: Qt.PointingHandCursor
onClicked: {
if (!menuEntry || menuEntry.isSeparator) return;
if (!menuEntry || menuEntry.isSeparator) return
if (menuEntry.hasChildren) {
menuRoot.showSubMenu(menuEntry);
} else {
if (typeof menuEntry.activate === "function") {
menuEntry.activate();
} else if (typeof menuEntry.triggered === "function") {
menuEntry.triggered();
}
Qt.createQmlObject('import QtQuick; Timer { interval: 80; running: true; repeat: false; onTriggered: menuRoot.close() }', menuRoot);
menuRoot.showSubMenu(menuEntry)
return
}
if (typeof menuEntry.activate === "function") {
menuEntry.activate()
} else if (typeof menuEntry.triggered === "function") {
menuEntry.triggered()
}
Qt.createQmlObject('import QtQuick; Timer { interval: 80; running: true; repeat: false; onTriggered: menuRoot.closeWithAction() }', menuRoot)
}
}
@@ -996,20 +1155,6 @@ Item {
}
}
}
Behavior on opacity {
NumberAnimation {
duration: Theme.mediumDuration
easing.type: Theme.emphasizedEasing
}
}
Behavior on scale {
NumberAnimation {
duration: Theme.mediumDuration
easing.type: Theme.emphasizedEasing
}
}
}
MouseArea {

View File

@@ -250,7 +250,10 @@ PanelWindow {
property int blurMax: 64
shadowBlur: Math.max(0, Math.min(1, content.shadowBlurPx / blurMax))
shadowScale: 1 + (2 * content.shadowSpreadPx) / Math.max(1, Math.min(bgShadowLayer.width, bgShadowLayer.height))
shadowColor: Qt.rgba(0, 0, 0, content.effectiveShadowAlpha)
shadowColor: {
const baseColor = Theme.isLightMode ? Qt.rgba(0, 0, 0, 1) : Theme.surfaceContainerHighest
return Theme.withAlpha(baseColor, content.effectiveShadowAlpha)
}
}
Shape {

View File

@@ -143,7 +143,10 @@ PanelWindow {
property int blurMax: 64
shadowBlur: Math.max(0, Math.min(1, osdContainer.shadowBlurPx / blurMax))
shadowScale: 1 + (2 * osdContainer.shadowSpreadPx) / Math.max(1, Math.min(bgShadowLayer.width, bgShadowLayer.height))
shadowColor: Qt.rgba(0, 0, 0, osdContainer.effectiveShadowAlpha)
shadowColor: {
const baseColor = Theme.isLightMode ? Qt.rgba(0, 0, 0, 1) : Theme.surfaceContainerHighest
return Theme.withAlpha(baseColor, osdContainer.effectiveShadowAlpha)
}
}
DankRectangle {

View File

@@ -224,7 +224,10 @@ PanelWindow {
property int blurMax: 64
shadowBlur: Math.max(0, Math.min(1, contentWrapper.shadowBlurPx / blurMax))
shadowScale: 1 + (2 * contentWrapper.shadowSpreadPx) / Math.max(1, Math.min(bgShadowLayer.width, bgShadowLayer.height))
shadowColor: Qt.rgba(0, 0, 0, contentWrapper.effectiveShadowAlpha)
shadowColor: {
const baseColor = Theme.isLightMode ? Qt.rgba(0, 0, 0, 1) : Theme.surfaceContainerHighest
return Theme.withAlpha(baseColor, contentWrapper.effectiveShadowAlpha)
}
}
DankRectangle {