From fd58294ec3ff5c8c5c2646abf8e4191319ca5373 Mon Sep 17 00:00:00 2001 From: Julian Sparber Date: Thu, 7 Mar 2024 11:00:35 +0100 Subject: [PATCH] messageTray: Ensure that a notification is removed from Source correctly We need to make sure that we always emit the `notification-removed` signal on the source object when a notification is removed or destroyed. Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/7463 Part-of: --- js/ui/messageTray.js | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/js/ui/messageTray.js b/js/ui/messageTray.js index 10ae5b2fb..1a9ac6655 100644 --- a/js/ui/messageTray.js +++ b/js/ui/messageTray.js @@ -541,13 +541,13 @@ export const Source = GObject.registerClass({ _onNotificationDestroy(notification) { let index = this.notifications.indexOf(notification); if (index < 0) - return; + throw new Error('Notification was already removed previously'); this.notifications.splice(index, 1); this.emit('notification-removed', notification); this.countUpdated(); - if (this.notifications.length === 0) + if (!this._inDestruction && this.notifications.length === 0) this.destroy(); } @@ -555,8 +555,10 @@ export const Source = GObject.registerClass({ if (this.notifications.includes(notification)) return; - while (this.notifications.length >= MAX_NOTIFICATIONS_PER_SOURCE) - this.notifications.shift().destroy(NotificationDestroyedReason.EXPIRED); + while (this.notifications.length >= MAX_NOTIFICATIONS_PER_SOURCE) { + const [oldest] = this.notifications; + oldest.destroy(NotificationDestroyedReason.EXPIRED); + } notification.connect('destroy', this._onNotificationDestroy.bind(this)); notification.connect('notify::acknowledged', () => { @@ -573,11 +575,12 @@ export const Source = GObject.registerClass({ } destroy(reason) { - let notifications = this.notifications; - this.notifications = []; + this._inDestruction = true; - for (let i = 0; i < notifications.length; i++) - notifications[i].destroy(reason); + while (this.notifications.length > 0) { + const [oldest] = this.notifications; + oldest.destroy(reason); + } this.emit('destroy', reason);