[gnome-shell/gnome-3-36] notificationDaemon: Fix grouping by PID



commit e74e691d845a7f734cee05933c50ec41018c90d5
Author: Florian Müllner <fmuellner gnome org>
Date:   Fri May 15 15:28:17 2020 +0200

    notificationDaemon: Fix grouping by PID
    
    For fd.o notifications, we are taking the sender's PID into
    account when associating notifications with sources (mainly
    to deal with notify-send).
    
    This broke when the implementation under the well-known name
    was moved into a separate service, as the implementation in
    gnome-shell will now always see the public notification-daemon
    as sender.
    
    Restore the old behavior by resolving the sender PID in the
    separate service, and pass it as hint to the implementation
    in gnome-shell.
    
    https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/2592

 .../notifications/notificationDaemon.js            | 27 +++++++++++-
 js/ui/notificationDaemon.js                        | 50 ++--------------------
 2 files changed, 29 insertions(+), 48 deletions(-)
---
diff --git a/js/dbusServices/notifications/notificationDaemon.js 
b/js/dbusServices/notifications/notificationDaemon.js
index c2d2ef6f9f..bf0f85b1c3 100644
--- a/js/dbusServices/notifications/notificationDaemon.js
+++ b/js/dbusServices/notifications/notificationDaemon.js
@@ -9,6 +9,8 @@ const { ServiceImplementation } = imports.dbusService;
 const NotificationsIface = loadInterfaceXML('org.freedesktop.Notifications');
 const NotificationsProxy = Gio.DBusProxy.makeProxyWrapper(NotificationsIface);
 
+Gio._promisify(Gio.DBusConnection.prototype, 'call', 'call_finish');
+
 var NotificationDaemon = class extends ServiceImplementation {
     constructor() {
         super(NotificationsIface, '/org/freedesktop/Notifications');
@@ -42,7 +44,15 @@ var NotificationDaemon = class extends ServiceImplementation {
             null, null);
     }
 
-    NotifyAsync(params, invocation) {
+    async NotifyAsync(params, invocation) {
+        const pid = await this._getSenderPid(invocation.get_sender());
+        const hints = params[6];
+
+        params[6] = {
+            ...hints,
+            'sender-pid': new GLib.Variant('u', pid),
+        };
+
         this._proxy.NotifyRemote(...params, (res, error) => {
             if (this._handleError(invocation, error))
                 return;
@@ -77,4 +87,19 @@ var NotificationDaemon = class extends ServiceImplementation {
             invocation.return_value(new GLib.Variant('(ssss)', res));
         });
     }
+
+    async _getSenderPid(sender) {
+        const res = await Gio.DBus.session.call(
+            'org.freedesktop.DBus',
+            '/',
+            'org.freedesktop.DBus',
+            'GetConnectionUnixProcessID',
+            new GLib.Variant('(s)', [sender]),
+            new GLib.VariantType('(u)'),
+            Gio.DBusCallFlags.NONE,
+            -1,
+            null);
+        const [pid] = res.deepUnpack();
+        return pid;
+    }
 };
diff --git a/js/ui/notificationDaemon.js b/js/ui/notificationDaemon.js
index 3331355ab9..28fe8ba066 100644
--- a/js/ui/notificationDaemon.js
+++ b/js/ui/notificationDaemon.js
@@ -10,13 +10,6 @@ const Params = imports.misc.params;
 
 const { loadInterfaceXML } = imports.misc.fileUtils;
 
-// Should really be defined in Gio.js
-const BusIface = loadInterfaceXML('org.freedesktop.DBus');
-var BusProxy = Gio.DBusProxy.makeProxyWrapper(BusIface);
-function Bus() {
-    return new BusProxy(Gio.DBus.session, 'org.freedesktop.DBus', '/org/freedesktop/DBus');
-}
-
 const FdoNotificationsIface = loadInterfaceXML('org.freedesktop.Notifications');
 
 var NotificationClosedReason = {
@@ -49,9 +42,7 @@ var FdoNotificationDaemon = class FdoNotificationDaemon {
         this._dbusImpl.export(Gio.DBus.session, '/org/freedesktop/Notifications');
 
         this._sources = [];
-        this._senderToPid = {};
         this._notifications = {};
-        this._busProxy = new Bus();
 
         this._nextNotificationId = 1;
 
@@ -116,12 +107,9 @@ var FdoNotificationDaemon = class FdoNotificationDaemon {
     //
     // If no existing source is found, a new source is created as long as
     // pid is provided.
-    //
-    // Either a pid or ndata.notification is needed to retrieve or
-    // create a source.
     _getSource(title, pid, ndata, sender) {
         if (!pid && !(ndata && ndata.notification))
-            return null;
+            throw new Error('Either a pid or ndata.notification is needed');
 
         // We use notification's source for the notifications we still have
         // around that are getting replaced because we don't keep sources
@@ -218,42 +206,10 @@ var FdoNotificationDaemon = class FdoNotificationDaemon {
         this._notifications[id] = ndata;
 
         let sender = invocation.get_sender();
-        let pid = this._senderToPid[sender];
+        let pid = hints['sender-pid'];
 
         let source = this._getSource(appName, pid, ndata, sender, null);
-
-        if (source) {
-            this._notifyForSource(source, ndata);
-            return invocation.return_value(GLib.Variant.new('(u)', [id]));
-        }
-
-        if (replacesId) {
-            // There's already a pending call to GetConnectionUnixProcessID,
-            // which will see the new notification data when it finishes,
-            // so we don't have to do anything.
-            return invocation.return_value(GLib.Variant.new('(u)', [id]));
-        }
-
-        this._busProxy.GetConnectionUnixProcessIDRemote(sender, (result, excp) => {
-            // The app may have updated or removed the notification
-            ndata = this._notifications[id];
-            if (!ndata)
-                return;
-
-            if (excp) {
-                logError(excp, 'Call to GetConnectionUnixProcessID failed');
-                return;
-            }
-
-            [pid] = result;
-            source = this._getSource(appName, pid, ndata, sender, null);
-
-            this._senderToPid[sender] = pid;
-            source.connect('destroy', () => {
-                delete this._senderToPid[sender];
-            });
-            this._notifyForSource(source, ndata);
-        });
+        this._notifyForSource(source, ndata);
 
         return invocation.return_value(GLib.Variant.new('(u)', [id]));
     }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]