diff --git a/settings/hyprland.nix b/settings/hyprland.nix index a832e26..6250fd6 100644 --- a/settings/hyprland.nix +++ b/settings/hyprland.nix @@ -458,6 +458,10 @@ in import Qt5Compat.GraphicalEffects ShellRoot { + id: root + property var latestNotification: null + signal notificationReceived() + NotificationServer { id: notifServer bodySupported: true @@ -467,7 +471,8 @@ in keepOnReload: true onNotification: (notification) => { notification.tracked = true; - notifToast.show(notification); + root.latestNotification = notification; + root.notificationReceived(); } } @@ -1660,157 +1665,171 @@ in } } } - // Notification toast popup - PopupWindow { - id: notifToast - property var currentNotif: null - property bool open: false + } + } - function show(notification) { - currentNotif = notification; - visible = true; - open = true; - _toastTimer.restart(); + // Notification toast popup + Variants { + model: Quickshell.screens + + PopupWindow { + id: notifToast + required property var modelData + screen: modelData + property var currentNotif: null + property bool open: false + + Connections { + target: root + function onNotificationReceived() { + if (notifToast.modelData === Quickshell.screens[0]) { + notifToast.show(root.latestNotification); + } } + } - function dismiss() { - open = false; - _toastCloseDelay.start(); + function show(notification) { + currentNotif = notification; + visible = true; + open = true; + _toastTimer.restart(); + } + + function dismiss() { + open = false; + _toastCloseDelay.start(); + } + + anchor.rect.x: (screen ? screen.width / 2 : 0) - 160 + anchor.rect.y: 30 + anchor.edges: Edges.Top | Edges.Left + visible: false + implicitWidth: 320 + implicitHeight: toastContent.height + 2 + color: "transparent" + + Timer { + id: _toastTimer + interval: 5000 + onTriggered: notifToast.dismiss() + } + + Timer { + id: _toastCloseDelay + interval: 230 + onTriggered: { notifToast.visible = false; notifToast.open = false; } + } + + HoverHandler { + onHoveredChanged: { + if (hovered) _toastTimer.stop(); + else _toastTimer.restart(); } + } - anchor.window: bar - anchor.rect.x: bar.width / 2 - 160 - anchor.rect.y: bar.height - anchor.edges: Edges.Top | Edges.Left - anchor.gravity: Edges.Bottom | Edges.Right - visible: false - width: 320 - height: toastContent.height + 2 - color: "transparent" + Rectangle { + id: toastContent + anchors.top: parent.top + anchors.topMargin: 2 + anchors.horizontalCenter: parent.horizontalCenter + width: 316 + height: toastCol.height + 16 + radius: 8 + color: "#E6${c.base00}" + clip: true - Timer { - id: _toastTimer - interval: 5000 - onTriggered: notifToast.dismiss() - } - - Timer { - id: _toastCloseDelay - interval: 230 - onTriggered: { notifToast.visible = false; notifToast.open = false; } - } - - HoverHandler { - onHoveredChanged: { - if (hovered) _toastTimer.stop(); - else _toastTimer.restart(); + transform: Translate { + y: notifToast.open ? 0 : -(toastContent.height + 10) + Behavior on y { + NumberAnimation { duration: 220; easing.type: Easing.OutCubic } } } - Rectangle { - id: toastContent + opacity: notifToast.open ? 1.0 : 0.0 + Behavior on opacity { + NumberAnimation { duration: 200; easing.type: Easing.OutCubic } + } + + Column { + id: toastCol + anchors.left: parent.left + anchors.right: toastDismiss.left anchors.top: parent.top - anchors.topMargin: 2 - anchors.horizontalCenter: parent.horizontalCenter - width: 316 - height: toastCol.height + 16 - radius: 8 - color: "#E6${c.base00}" - clip: true + anchors.margins: 8 + spacing: 2 - transform: Translate { - y: notifToast.open ? 0 : -(toastContent.height + 10) - Behavior on y { - NumberAnimation { duration: 220; easing.type: Easing.OutCubic } - } + Text { + width: parent.width + text: notifToast.currentNotif ? (notifToast.currentNotif.summary || notifToast.currentNotif.appName) : "" + color: "#${c.base05}" + font.family: "FiraMono Nerd Font" + font.pixelSize: 12 + font.weight: Font.Medium + elide: Text.ElideRight } - opacity: notifToast.open ? 1.0 : 0.0 - Behavior on opacity { - NumberAnimation { duration: 200; easing.type: Easing.OutCubic } + Text { + width: parent.width + text: notifToast.currentNotif ? (notifToast.currentNotif.body || "") : "" + color: "#${c.base04}" + font.family: "FiraMono Nerd Font" + font.pixelSize: 11 + elide: Text.ElideRight + maximumLineCount: 3 + wrapMode: Text.Wrap + visible: text !== "" } - Column { - id: toastCol - anchors.left: parent.left - anchors.right: toastDismiss.left - anchors.top: parent.top - anchors.margins: 8 - spacing: 2 - - Text { - width: parent.width - text: notifToast.currentNotif ? (notifToast.currentNotif.summary || notifToast.currentNotif.appName) : "" - color: "#${c.base05}" - font.family: "FiraMono Nerd Font" - font.pixelSize: 12 - font.weight: Font.Medium - elide: Text.ElideRight - } - - Text { - width: parent.width - text: notifToast.currentNotif ? (notifToast.currentNotif.body || "") : "" - color: "#${c.base04}" - font.family: "FiraMono Nerd Font" - font.pixelSize: 11 - elide: Text.ElideRight - maximumLineCount: 3 - wrapMode: Text.Wrap - visible: text !== "" - } - - // Action buttons - Row { - spacing: 4 - visible: notifToast.currentNotif && notifToast.currentNotif.actions.length > 0 - Repeater { - model: notifToast.currentNotif ? notifToast.currentNotif.actions : [] - Rectangle { - required property var modelData - width: toastActionText.width + 12 - height: toastActionText.height + 6 - radius: 4 - color: toastActionMa.containsMouse ? "#${c.base02}" : "#${c.base01}" - border.width: 1 - border.color: "#${c.base02}" - Text { - id: toastActionText - anchors.centerIn: parent - text: modelData.text - color: "#${c.base05}" - font.family: "FiraMono Nerd Font" - font.pixelSize: 10 - } - MouseArea { - id: toastActionMa - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: { modelData.invoke(); notifToast.dismiss(); } - } + // Action buttons + Row { + spacing: 4 + visible: notifToast.currentNotif && notifToast.currentNotif.actions.length > 0 + Repeater { + model: notifToast.currentNotif ? notifToast.currentNotif.actions : [] + Rectangle { + required property var modelData + width: toastActionText.width + 12 + height: toastActionText.height + 6 + radius: 4 + color: toastActionMa.containsMouse ? "#${c.base02}" : "#${c.base01}" + border.width: 1 + border.color: "#${c.base02}" + Text { + id: toastActionText + anchors.centerIn: parent + text: modelData.text + color: "#${c.base05}" + font.family: "FiraMono Nerd Font" + font.pixelSize: 10 + } + MouseArea { + id: toastActionMa + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onClicked: { modelData.invoke(); notifToast.dismiss(); } } } } } + } - // Dismiss X - Text { - id: toastDismiss - anchors.right: parent.right - anchors.top: parent.top - anchors.margins: 8 - text: "\u{f0156}" - color: toastDismissMa.containsMouse ? "#${c.base05}" : "#${c.base03}" - font.family: "FiraMono Nerd Font" - font.pixelSize: 13 - MouseArea { - id: toastDismissMa - anchors.fill: parent - hoverEnabled: true - cursorShape: Qt.PointingHandCursor - onClicked: { notifToast.currentNotif.dismiss(); notifToast.dismiss(); } - } + // Dismiss X + Text { + id: toastDismiss + anchors.right: parent.right + anchors.top: parent.top + anchors.margins: 8 + text: "\u{f0156}" + color: toastDismissMa.containsMouse ? "#${c.base05}" : "#${c.base03}" + font.family: "FiraMono Nerd Font" + font.pixelSize: 13 + MouseArea { + id: toastDismissMa + anchors.fill: parent + hoverEnabled: true + cursorShape: Qt.PointingHandCursor + onClicked: { notifToast.currentNotif.dismiss(); notifToast.dismiss(); } } } }