notif: prevent unexpected shuffle on dismiss

This commit is contained in:
end-4 2025-05-25 23:36:18 +02:00
parent a24825f676
commit dbe2a922e3
4 changed files with 46 additions and 9 deletions

View file

@ -14,7 +14,8 @@ Rectangle { // App icon
property var summary: ""
property var urgency: NotificationUrgency.Normal
property var image: ""
property real size: 45
property real scale: 1
property real size: 45 * scale
property real materialIconScale: 0.57
property real appIconScale: 0.7
property real smallAppIconScale: 0.49

View file

@ -152,14 +152,17 @@ Item { // Notification group area
NotificationAppIcon { // Icons
Layout.alignment: Qt.AlignTop
Layout.fillWidth: false
image: root.multipleNotifications ? "" : notificationGroup.notifications[0].image
appIcon: notificationGroup.appIcon
summary: notificationGroup.notifications[root.notificationCount - 1].summary
}
ColumnLayout { // Content
Layout.fillWidth: true
spacing: expanded ? 5 : 0
spacing: expanded ?
((root.multipleNotifications &&
notificationGroup.notifications[root.notificationCount - 1].image != "") ? 35 :
5) : 0
Behavior on spacing {
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
}

View file

@ -23,7 +23,7 @@ Item { // Notification item area
property real padding: 8
property real dragConfirmThreshold: 70 // Drag further to discard notification
property real dismissOvershoot: 20 // Account for gaps and bouncy animations
property real dismissOvershoot: notificationIcon.implicitWidth + 20 // Account for gaps and bouncy animations
property var qmlParent: root?.parent?.parent // There's something between this and the parent ListView
property var parentDragIndex: qmlParent?.dragIndex ?? -1
property var parentDragDistance: qmlParent?.dragDistance ?? 0
@ -89,6 +89,21 @@ Item { // Notification item area
}
}
NotificationAppIcon { // App icon
id: notificationIcon
opacity: (!onlyNotification && notificationObject.image != "" && expanded) ? 1 : 0
visible: opacity > 0
Behavior on opacity {
animation: Appearance.animation.elementMoveFast.numberAnimation.createObject(this)
}
image: notificationObject.image
anchors.right: background.left
anchors.top: background.top
anchors.rightMargin: 10
}
Rectangle { // Background of notification item
id: background
width: parent.width

View file

@ -15,9 +15,22 @@ Singleton {
property var list: []
property var popupList: []
property bool popupInhibited: GlobalStates?.sidebarRightOpen ?? false
// Quickshell's notification IDs starts at 1 on each run, while saved notifications
// can already contain higher IDs. This is for avoiding id collisions
property int idOffset
property var latestTimeForApp: ({})
onListChanged: {
// Update latest time for each app
root.list.forEach((notif) => {
if (!root.latestTimeForApp[notif.appName] || notif.time > root.latestTimeForApp[notif.appName]) {
root.latestTimeForApp[notif.appName] = Math.max(root.latestTimeForApp[notif.appName] || 0, notif.time);
}
});
// Remove apps that no longer have notifications
Object.keys(root.latestTimeForApp).forEach((appName) => {
if (!root.list.some((notif) => notif.appName === appName)) {
delete root.latestTimeForApp[appName];
}
});
}
function appNameListForGroups(groups) {
return Object.keys(groups).sort((a, b) => {
@ -39,7 +52,7 @@ Singleton {
}
groups[notif.appName].notifications.push(notif);
// Always set to the latest time in the group
groups[notif.appName].time = notif.time;
groups[notif.appName].time = latestTimeForApp[notif.appName] || notif.time;
});
return groups;
}
@ -49,6 +62,9 @@ Singleton {
property var appNameList: appNameListForGroups(root.groupsByAppName)
property var popupAppNameList: appNameListForGroups(root.popupGroupsByAppName)
// Quickshell's notification IDs starts at 1 on each run, while saved notifications
// can already contain higher IDs. This is for avoiding id collisions
property int idOffset
signal initDone();
signal notify(notification: var);
signal discard(id: var);
@ -87,7 +103,9 @@ Singleton {
}
root.list = [...root.list, newNotifObject];
// console.log(root.popupInhibited)
if (!root.popupInhibited) root.popupList = [...root.popupList, newNotifObject];
if (!root.popupInhibited) {
root.popupList = [...root.popupList, newNotifObject];
}
root.notify(newNotifObject);
notifFileView.setText(JSON.stringify(root.list, null, 2))
}