pragma ComponentBehavior: Bound import QtQuick import Quickshell import Quickshell.Services.Notifications import Quickshell.Widgets import ZShell.Components import ZShell.Config import ZShell.Services import qs.Components import qs.Services ButtonRow { id: root required property NotificationRow notif required property color buttonColour readonly property color fillColour: notif.urgency === NotificationUrgency.Critical ? Colors.palette.m3secondary : buttonColour readonly property color buttonTextColour: notif.urgency === NotificationUrgency.Critical ? Colors.palette.m3onSecondary : Colors.palette.m3onSurfaceVariant function invoke(action: var): void { action.invoke(); if (!notif.resident) notif.dismiss(); } spacing: Tokens.spacing.extraSmall IconButton { isRound: true shapeMorph: true fillWidth: root.notif.actions.length === 0 inactiveColor: root.fillColour inactiveOnColor: root.buttonTextColour icon: "close" padding: Tokens.padding.extraSmall onClicked: root.notif.dismiss() } Repeater { model: root.notif.actions delegate: root.notif.hasActionIcons ? iconAction : textAction } IconButton { isRound: true shapeMorph: true fillWidth: root.notif.actions.length === 0 inactiveColor: root.fillColour inactiveOnColor: root.buttonTextColour icon: copyTimer.running ? "inventory" : "content_copy" padding: Tokens.padding.extraSmall onClicked: { Quickshell.clipboardText = root.notif.body; copyTimer.restart(); } label.animate: true Timer { id: copyTimer interval: 3000 } } Component { id: textAction TextButton { required property var modelData isRound: true shapeMorph: true fillWidth: true inactiveColor: root.fillColour inactiveOnColor: root.buttonTextColour text: modelData.text onClicked: root.invoke(modelData) label.horizontalAlignment: Text.AlignHCenter label.anchors.left: left label.anchors.right: right label.anchors.verticalCenter: verticalCenter label.anchors.centerIn: undefined label.anchors.margins: Tokens.padding.medium label.elide: Text.ElideRight } } Component { id: iconAction ButtonBase { id: button required property var modelData isRound: true shapeMorph: true fillWidth: true padding: Tokens.padding.extraSmall inactiveColor: root.fillColour inactiveOnColor: root.buttonTextColour implicitWidth: implicitHeight implicitHeight: icon.implicitHeight + padding * 2 onClicked: root.invoke(modelData) IconImage { id: icon anchors.centerIn: parent implicitSize: Math.round(Tokens.font.icon.medium.pointSize * 1.3) asynchronous: true source: Quickshell.iconPath(button.modelData.identifier) } } } }