import Quickshell import QtQuick // for Text import QtQuick.Controls import QtQuick.Layouts import Quickshell.Services.Notifications import Quickshell.Io import Quickshell.Widgets import Quickshell.Hyprland Item { width: 50 height: 30 ClippingWrapperRectangle { id: barbutton radius: 5 anchors.fill: parent Button { id: button text: "󰂚" //text: server.trackedNotifications.values.length == 0 ? "󰂚" : '󱅫 ' + server.trackedNotifications.values.length //icon.source: '' font.pointSize: 16 onClicked: { menu.visible = true grab.active = true } implicitHeight: parent.height } } NotificationServer { id: server persistenceSupported: true imageSupported: true actionsSupported: true bodyImagesSupported: true bodySupported: true bodyHyperlinksSupported: true inlineReplySupported: true actionIconsSupported: true onNotification: (n) => { n.tracked = true console.log(n?.body) button.text = '󱅫 ' + (server.trackedNotifications.values.length + 1) } } required property PanelWindow window id: root PopupWindow { id: menu anchor.window: window anchor.rect.x: window.width - width anchor.rect.y: 50 implicitWidth: 400 implicitHeight: 1080 - anchor.rect.y visible: false color: "transparent" ClippingWrapperRectangle { radius: 5 color: "#ff706050" implicitHeight: parent.height - 20 implicitWidth: parent.width ColumnLayout { id: lay spacing: 10 ClippingWrapperRectangle { radius: 5 Layout.margins: 5 Layout.alignment: Qt.AlignVCenter | Qt.AlignTop implicitWidth: menu.width - 2 * Layout.margins RowLayout { width: parent.width Text { Layout.margins: 5 Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter text: 'Notifications' } Button { Layout.alignment: Qt.AlignRight | Qt.AlignVCenter Layout.margins: 5 implicitWidth: 20 implicitHeight: 20 text: 'x' onClicked: { while(server.trackedNotifications.values.length > 0) { server.trackedNotifications.values[0].dismiss() } } } } } Repeater { id: rep model: server.trackedNotifications.values ClippingWrapperRectangle { Layout.alignment: Qt.AlignHCenter | Qt.AlignTop Layout.margins: 5 radius: 10 implicitWidth: parent.width - 2 * Layout.margins implicitHeight: 100 MouseArea { anchors.fill: parent RowLayout { Image { //anchors.fill: parent source: { let icon = rep.model[index].image if (icon.includes("?path=")) { const [name, path] = icon.split("?path="); icon = Qt.resolvedUrl(`${path}/${name.slice(name.lastIndexOf("/") + 1)}`); } return icon } Layout.maximumWidth: 100 Layout.maximumHeight: 100 } ColumnLayout { Layout.topMargin: 10 Layout.alignment: Qt.AlignLeft | Qt.AlignTop Text { Layout.alignment: Qt.AlignLeft | Qt.AlignTop text: rep.model[index].summary Layout.leftMargin: 10 font.pointSize: 14 } Text { Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter text: rep.model[index].body Layout.leftMargin: 10 font.pointSize: 12 } } } acceptedButtons: Qt.LeftButton | Qt.RightButton onClicked: mouse => { if(mouse.button == Qt.LeftButton) { button.text = rep.count - 1 <= 0 ? "󰂚" : '󱅫 ' + (rep.count - 1) rep.model[index].dismiss() //button.text = server.trackedNotifications.values.length == 0 ? "󰂚" : '󱅫 ' + server.trackedNotifications.values.length } else if(mouse.button == Qt.RightButton) { } } } } } } } HyprlandFocusGrab { id: grab windows: [ menu ] onCleared: menu.visible = false } } }