import QtQuick import QtQuick.Controls import QtQuick.Layouts import Quickshell import Quickshell.Services.Notifications import Quickshell.Wayland Item { id: root property bool open: false property bool dnd: false property bool toastOpen: false property var latest: null readonly property int count: server.trackedNotifications ? server.trackedNotifications.values.length : 0 signal dismissed() NotificationServer { id: server keepOnReload: true onNotification: function(notification) { notification.tracked = true; root.latest = notification; if (!root.dnd) { root.toastOpen = true; toastTimer.restart(); } } } Timer { id: toastTimer interval: 5000 repeat: false onTriggered: root.toastOpen = false } PanelWindow { visible: root.toastOpen && !root.open && root.latest !== null color: "transparent" anchors { top: true; bottom: true; left: true; right: true } exclusionMode: ExclusionMode.Ignore WlrLayershell.layer: WlrLayer.Overlay WlrLayershell.keyboardFocus: WlrKeyboardFocus.None WlrLayershell.namespace: "quickshell-notification-toast" Rectangle { width: Math.min(390, parent.width - 32) height: 100 anchors.top: parent.top anchors.right: parent.right anchors.margins: 16 radius: 16 color: "#f5f2ea" border.color: "#d8d0c2" border.width: 1 MouseArea { anchors.fill: parent onClicked: { root.toastOpen = false; root.open = true; } } ColumnLayout { anchors.fill: parent anchors.margins: 14 spacing: 3 Label { text: root.latest ? root.latest.appName : "" color: "#7c756c" font.pixelSize: 11 Layout.fillWidth: true elide: Text.ElideRight } Label { text: root.latest ? root.latest.summary : "" color: "#252321" font.pixelSize: 16 font.bold: true Layout.fillWidth: true elide: Text.ElideRight } Label { text: root.latest ? root.latest.body : "" color: "#5f5952" Layout.fillWidth: true elide: Text.ElideRight } } } } PanelWindow { visible: root.open color: "transparent" anchors { top: true; bottom: true; left: true; right: true } exclusionMode: ExclusionMode.Ignore WlrLayershell.layer: WlrLayer.Overlay WlrLayershell.keyboardFocus: root.open ? WlrKeyboardFocus.Exclusive : WlrKeyboardFocus.None WlrLayershell.namespace: "quickshell-notification-center" MouseArea { anchors.fill: parent onClicked: root.dismissed() } Rectangle { width: Math.min(430, parent.width - 32) height: Math.min(parent.height - 32, 700) anchors.top: parent.top anchors.right: parent.right anchors.margins: 16 radius: 20 color: "#f5f2ea" border.color: "#d8d0c2" border.width: 1 z: 1 MouseArea { anchors.fill: parent onClicked: function(mouse) { mouse.accepted = true } } ColumnLayout { anchors.fill: parent anchors.margins: 18 spacing: 10 RowLayout { Layout.fillWidth: true Label { text: "Notifications" color: "#252321" font.pixelSize: 22 font.bold: true Layout.fillWidth: true } Button { text: root.dnd ? "DND on" : "DND off" onClicked: root.dnd = !root.dnd } Button { text: "Close" onClicked: root.dismissed() } } Label { visible: root.count === 0 text: "No notifications" color: "#7c756c" Layout.alignment: Qt.AlignHCenter Layout.topMargin: 18 } ScrollView { Layout.fillWidth: true Layout.fillHeight: true clip: true ColumnLayout { width: parent.width spacing: 8 Repeater { model: server.trackedNotifications delegate: Rectangle { required property var modelData Layout.fillWidth: true implicitHeight: notificationColumn.implicitHeight + 22 radius: 14 color: "#e8e3da" ColumnLayout { id: notificationColumn anchors.fill: parent anchors.margins: 11 spacing: 3 RowLayout { Layout.fillWidth: true Label { text: modelData.appName color: "#7c756c" font.pixelSize: 11 Layout.fillWidth: true elide: Text.ElideRight } Button { text: "x" onClicked: modelData.dismiss() } } Label { text: modelData.summary color: "#252321" font.pixelSize: 15 font.bold: true Layout.fillWidth: true wrapMode: Text.Wrap } Label { text: modelData.body color: "#5f5952" Layout.fillWidth: true wrapMode: Text.Wrap } } } } } } } } } }