import Quickshell import Quickshell.Wayland import Quickshell.Services.Notifications import QtQuick import QtQuick.Layouts import "config.js" as Config Scope { id: root NotificationServer { id: server actionsSupported: true bodySupported: true imageSupported: true onNotification: n => { n.tracked = true } } PanelWindow { anchors { top: true; right: true } margins { top: 12; right: 12 } implicitWidth: 380 implicitHeight: Math.max(1, column.implicitHeight) color: "transparent" exclusionMode: ExclusionMode.Ignore ColumnLayout { id: column width: parent.width spacing: 10 Repeater { model: server.trackedNotifications delegate: Rectangle { id: card required property var modelData Layout.fillWidth: true implicitHeight: cardLayout.implicitHeight + 20 radius: 12 color: Config.colors.bgDark border.color: hoverArea.containsMouse ? Config.colors.purple : "transparent" border.width: 1 Behavior on border.color { ColorAnimation { duration: 150 } } Timer { id: dismissTimer running: card.modelData.urgency !== NotificationUrgency.Critical && !hoverArea.containsMouse interval: Config.notifications.timeout repeat: false onTriggered: card.modelData.dismiss() } Rectangle { anchors.left: parent.left anchors.top: parent.top anchors.bottom: parent.bottom width: 4 radius: 12 color: card.modelData.urgency === NotificationUrgency.Critical ? Config.colors.red : Config.colors.purple } ColumnLayout { id: cardLayout anchors.fill: parent anchors.margins: 10 anchors.leftMargin: 18 spacing: 8 RowLayout { Layout.fillWidth: true spacing: 10 Image { Layout.preferredWidth: 36 Layout.preferredHeight: 36 Layout.alignment: Qt.AlignTop fillMode: Image.PreserveAspectFit visible: source.toString() !== "" source: card.modelData.image || card.modelData.appIcon || "" } ColumnLayout { Layout.fillWidth: true spacing: 2 Text { Layout.fillWidth: true text: card.modelData.summary color: Config.colors.cyan font.family: Config.bar.fontFamily font.pixelSize: Config.bar.fontSize font.bold: true elide: Text.ElideRight } Text { Layout.fillWidth: true visible: text !== "" text: card.modelData.body color: Config.colors.fg font.family: Config.bar.fontFamily font.pixelSize: Config.bar.fontSize - 1 wrapMode: Text.WordWrap maximumLineCount: 4 elide: Text.ElideRight } } } RowLayout { Layout.fillWidth: true visible: card.modelData.actions.length > 0 spacing: 8 Repeater { model: card.modelData.actions delegate: Rectangle { required property var modelData Layout.fillWidth: true Layout.preferredHeight: 26 radius: 6 color: actionArea.containsMouse ? Config.colors.purple : Qt.rgba(1, 1, 1, 0.05) Text { anchors.centerIn: parent text: parent.modelData.text color: Config.colors.fg font.family: Config.bar.fontFamily font.pixelSize: Config.bar.fontSize - 2 } MouseArea { id: actionArea anchors.fill: parent hoverEnabled: true cursorShape: Qt.PointingHandCursor onClicked: card.modelData.invokeAction(parent.modelData.identifier) } } } } } MouseArea { id: hoverArea anchors.fill: parent hoverEnabled: true cursorShape: Qt.PointingHandCursor onClicked: card.modelData.dismiss() z: -1 } } } } } }