From f69518aec4ad1794fbace2655431258aa8799507 Mon Sep 17 00:00:00 2001 From: Amaro Lopes Date: Fri, 10 Oct 2025 20:24:51 -0300 Subject: [PATCH] Move notificationswapper to common, change defaul wrap mode --- {Widgets => Common}/NotificationWrapper.qml | 26 ++++++--- Common/Styled/StyledText.qml | 2 +- Services/HyprlandService.qml | 45 ++++++++------- Services/NotificationService.qml | 63 ++++++++++----------- Widgets/NotificationWindow.qml | 23 ++++++-- 5 files changed, 90 insertions(+), 69 deletions(-) rename {Widgets => Common}/NotificationWrapper.qml (76%) diff --git a/Widgets/NotificationWrapper.qml b/Common/NotificationWrapper.qml similarity index 76% rename from Widgets/NotificationWrapper.qml rename to Common/NotificationWrapper.qml index 31868d8..0aa2833 100644 --- a/Widgets/NotificationWrapper.qml +++ b/Common/NotificationWrapper.qml @@ -33,7 +33,7 @@ BackgroundRectangle { // implicitHeight: Math.max(notifLayout.implicitHeight, 100) Component.onCompleted: { - notificationWrapper.implicitHeight = targetHeight + notificationWrapper.implicitHeight = targetHeight; } clip: true @@ -45,8 +45,10 @@ BackgroundRectangle { } ScriptAction { script: { - if(clicked) notificationWrapper.dismissed() - if(notificationWrapper.implicitHeight === 0) notificationWrapper.timedout() + if (clicked) + notificationWrapper.dismissed(); + if (notificationWrapper.implicitHeight === 0) + notificationWrapper.timedout(); } } } @@ -55,8 +57,8 @@ BackgroundRectangle { MouseArea { anchors.fill: parent onClicked: { - notificationWrapper.clicked = true - notificationWrapper.implicitHeight = 0 + notificationWrapper.clicked = true; + notificationWrapper.implicitHeight = 0; } } @@ -83,10 +85,10 @@ BackgroundRectangle { IconImage { id: iconImage - Layout.alignment: Qt.AlignLeft| Qt.AlignVCenter + Layout.alignment: Qt.AlignLeft | Qt.AlignVCenter Layout.leftMargin: 10 implicitSize: 80 - visible: notificationWrapper.image? true: false + visible: notificationWrapper.image ? true : false source: notificationWrapper.image } @@ -103,6 +105,9 @@ BackgroundRectangle { id: summaryRectangle Layout.fillWidth: true + MarginWrapperManager { + margin: 10 + } implicitHeight: summaryText.implicitHeight + 10 @@ -113,7 +118,7 @@ BackgroundRectangle { anchors.fill: parent - text: notificationWrapper.notification? notificationWrapper.notification.summary : "" + text: notificationWrapper.notification ? notificationWrapper.notification.summary : "" } } @@ -127,12 +132,15 @@ BackgroundRectangle { visible: bodyText.text ? true : false + MarginWrapperManager { + margin: 15 + } StyledText { id: bodyText anchors.fill: parent - text: notificationWrapper.notification? notificationWrapper.notification.body : "" + text: notificationWrapper.notification ? notificationWrapper.notification.body : "" } } } diff --git a/Common/Styled/StyledText.qml b/Common/Styled/StyledText.qml index 913998d..1bdee8b 100644 --- a/Common/Styled/StyledText.qml +++ b/Common/Styled/StyledText.qml @@ -7,7 +7,7 @@ Text { anchors.margins: 5 horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter - wrapMode: Text.WordWrap + wrapMode: Text.Wrap textFormat: Text.MarkdownText font.bold: true font.pixelSize: Theme.pixelSize diff --git a/Services/HyprlandService.qml b/Services/HyprlandService.qml index 2a2b811..39f2ed0 100644 --- a/Services/HyprlandService.qml +++ b/Services/HyprlandService.qml @@ -4,9 +4,10 @@ import Quickshell import Quickshell.Hyprland import Quickshell.Wayland import Quickshell.Io +import qs.Common Singleton { - id:root + id: root readonly property string hyprlandSignature: Quickshell.env("HYPRLAND_INSTANCE_SIGNATURE") @@ -93,32 +94,32 @@ Singleton { return workspaceDesktopEntries; } - Socket { - path: `${Quickshell.env("XDG_RUNTIME_DIR")}/hypr/${Quickshell.env("HYPRLAND_INSTANCE_SIGNATURE")}/.socket2.sock` - connected: true + Socket { + path: `${Quickshell.env("XDG_RUNTIME_DIR")}/hypr/${Quickshell.env("HYPRLAND_INSTANCE_SIGNATURE")}/.socket2.sock` + connected: true - parser: SplitParser { - property var fullscreenRegex: new RegExp("fullscreen>>."); + parser: SplitParser { + property var fullscreenRegex: new RegExp("fullscreen>>.") property var screencastRegex: new RegExp("screencast>>.*") - onRead: msg => { - let match = fullscreenRegex.exec(msg); - if (match != null) { - if(msg.split(">>")[1] === "1") { - root.hasFullscreen = true + onRead: msg => { + let match = fullscreenRegex.exec(msg); + if (match != null) { + if (msg.split(">>")[1] === "1") { + root.hasFullscreen = true; } else { - root.hasFullscreen = false + root.hasFullscreen = false; } - } - match = screencastRegex.exec(msg); - if (match != null) { - if(msg.split(">>")[1].split(',')[0] === "1") { - root.isScreencasting = true + } + match = screencastRegex.exec(msg); + if (match != null) { + if (msg.split(">>")[1].split(',')[0] === "1") { + root.isScreencasting = true; } else { - root.isScreencasting = false + root.isScreencasting = false; } - } - } - } - } + } + } + } + } } diff --git a/Services/NotificationService.qml b/Services/NotificationService.qml index bdadb00..280229f 100644 --- a/Services/NotificationService.qml +++ b/Services/NotificationService.qml @@ -4,7 +4,7 @@ pragma ComponentBehavior: Bound import QtQuick import Quickshell import Quickshell.Services.Notifications -import qs.Widgets +import qs.Common import qs.Services Singleton { @@ -27,21 +27,21 @@ Singleton { Connections { target: notificationServer function onNotification(notif) { - if(notif.transient || notif.body === "MediaOngoingActivity") - return; + if (notif.transient || notif.body === "MediaOngoingActivity") + return; notif.tracked = true; root.addNotification(trackedNotifications, notif); if (notif.lastGeneration) - return; + return; // Use the refactored helper - if(notificationList.count < root.maxShown && !root.receivingLock ) { - root.addNotification(notificationList, notif) + if (notificationList.count < root.maxShown && !root.receivingLock) { + root.addNotification(notificationList, notif); } else { - root.receivingLock = true - root.addNotification(pendingList, notif) + root.receivingLock = true; + root.addNotification(pendingList, notif); } } } @@ -58,7 +58,6 @@ Singleton { * @param {var} targetNotif */ function removeNotification(model, targetNotif) { - if (!model || typeof model.remove !== "function") { console.warn("removeNotification(): invalid model"); return; @@ -85,7 +84,7 @@ Singleton { // Avoid duplicates for (let i = 0; i < model.count; i++) { if (model.get(i).notif === notif) - return; + return; } model.append({ @@ -98,48 +97,47 @@ Singleton { } function notificationDismiss(notif) { - let pendingIdx = -1 + let pendingIdx = -1; for (let i = 0; i < pendingList.count; i++) { if (pendingList.get(i).notif === notif) { - pendingIdx = i - break + pendingIdx = i; + break; } } if (pendingIdx >= 0) { - pendingList.remove(pendingIdx, 1) + pendingList.remove(pendingIdx, 1); } else { - removeNotification(notificationList, notif) + removeNotification(notificationList, notif); } - removeNotification(trackedNotifications, notif) + removeNotification(trackedNotifications, notif); if (notif && typeof notif.dismiss === "function") - notif.dismiss() + notif.dismiss(); - tryShowNext() + tryShowNext(); } function timeoutNotification(notif) { + removeNotification(notificationList, notif); - removeNotification(notificationList, notif) - - tryShowNext() + tryShowNext(); } function tryShowNext() { - let filled = false + let filled = false; while (notificationList.count < root.maxShown && pendingList.count > 0) { - const nextNotif = pendingList.get(0).notif - pendingList.remove(0, 1) - addNotification(notificationList, nextNotif) - filled = true + const nextNotif = pendingList.get(0).notif; + pendingList.remove(0, 1); + addNotification(notificationList, nextNotif); + filled = true; } // Only lock if there are still more pending than fit onscreen - root.receivingLock = pendingList.count > 0 + root.receivingLock = pendingList.count > 0; } LazyLoader { @@ -157,7 +155,9 @@ Singleton { implicitWidth: 400 implicitHeight: screen.height color: "transparent" - mask: Region { item: listView } + mask: Region { + item: listView + } ListView { id: listView @@ -176,17 +176,16 @@ Singleton { notification: modelData implicitWidth: listView.width - - startTimer: NotificationUrgency.toString(notification?.urgency) === "Critical"? false: true + startTimer: NotificationUrgency.toString(notification?.urgency) === "Critical" ? false : true timerDuration: 5000 onDismissed: { if (notification && typeof notification.dismiss === "function") - root.notificationDismiss(notification); + root.notificationDismiss(notification); } onTimedout: { - root.timeoutNotification(notification) + root.timeoutNotification(notification); } } diff --git a/Widgets/NotificationWindow.qml b/Widgets/NotificationWindow.qml index b6ddaac..071ca36 100644 --- a/Widgets/NotificationWindow.qml +++ b/Widgets/NotificationWindow.qml @@ -8,12 +8,18 @@ import qs.Services import qs.Widgets import qs.Common.Styled import qs.Common -import QtQuick.Window +import Quickshell.Wayland -PopupWindow { +PanelWindow { id: notificationRoot - anchor.item: root + anchors { + left: true + bottom: true + right: true + top: true + } + implicitWidth: screen.width // implicitWidth: 400 implicitHeight: screen.height @@ -21,6 +27,14 @@ PopupWindow { visible: true signal clear + WlrLayershell.keyboardFocus: WlrKeyboardFocus.OnDemand + + contentItem { + focus: true + Keys.onPressed: event => { + if (event.key == Qt.Key_Escape) notificationRoot.clear(); + } + } MouseArea { anchors.fill: parent onClicked: notificationRoot.clear() @@ -32,7 +46,6 @@ PopupWindow { anchors{ top: parent.top left: parent.left - topMargin: 40 } border.width: 1 color: Theme.color2 @@ -60,7 +73,7 @@ PopupWindow { } } StyledText { - anchors.centerIn: parent + anchors.fill: parent text: "NOTIFICAÇÕES" } }