[gnome-shell] NotificationDaemon: remove source if notification sender is removed from DBus



commit 153768ef7ffbea5760bcd7611aa75aef71310ba5
Author: Neha Doijode <ndoijode gmail com>
Date:   Thu Jul 7 02:31:07 2011 +0530

    NotificationDaemon: remove source if notification sender is removed from DBus
    
    We don't want sources that are no longer associated with a running application
    to stick around in the message tray.
    
    Message tray sources were removed when the associated applicationâs state
    changed to Shell.AppState.STOPPED . This caused sources for applications
    that were still running, but did not have any open windows to be removed.
    Instead, we should use the notificationâs sender removal from DBus as an
    indicator for when to remove the associated source from the message tray.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=645764

 js/ui/notificationDaemon.js |   57 ++++++++++++++++++++----------------------
 1 files changed, 27 insertions(+), 30 deletions(-)
---
diff --git a/js/ui/notificationDaemon.js b/js/ui/notificationDaemon.js
index 66bd0c5..37009d9 100644
--- a/js/ui/notificationDaemon.js
+++ b/js/ui/notificationDaemon.js
@@ -148,7 +148,7 @@ NotificationDaemon.prototype = {
     //
     // Either a pid or ndata.notification is needed to retrieve or
     // create a source.
-    _getSource: function(title, pid, ndata) {
+    _getSource: function(title, pid, ndata, sender) {
         if (!pid && !(ndata && ndata.notification))
             return null;
 
@@ -171,7 +171,7 @@ NotificationDaemon.prototype = {
             return source;
         }
 
-        let source = new Source(title, pid);
+        let source = new Source(title, pid, sender);
         source.setTransient(isForTransientNotification);
 
         if (!isForTransientNotification) {
@@ -245,7 +245,7 @@ NotificationDaemon.prototype = {
         let sender = DBus.getCurrentMessageContext().sender;
         let pid = this._senderToPid[sender];
 
-        let source = this._getSource(appName, pid, ndata);
+        let source = this._getSource(appName, pid, ndata, sender);
 
         if (source) {
             this._notifyForSource(source, ndata);
@@ -266,7 +266,7 @@ NotificationDaemon.prototype = {
                 if (!ndata)
                     return;
 
-                source = this._getSource(appName, pid, ndata);
+                source = this._getSource(appName, pid, ndata, sender);
 
                 // We only store sender-pid entries for persistent sources.
                 // Removing the entries once the source is destroyed
@@ -415,7 +415,7 @@ NotificationDaemon.prototype = {
     },
 
     _onTrayIconAdded: function(o, icon) {
-        let source = this._getSource(icon.title || icon.wm_class || _("Unknown"), icon.pid, null);
+        let source = this._getSource(icon.title || icon.wm_class || _("Unknown"), icon.pid, null, null);
         source.setTrayIcon(icon);
     },
 
@@ -428,18 +428,28 @@ NotificationDaemon.prototype = {
 
 DBus.conformExport(NotificationDaemon.prototype, NotificationDaemonIface);
 
-function Source(title, pid) {
-    this._init(title, pid);
+function Source(title, pid, sender) {
+    this._init(title, pid, sender);
 }
 
 Source.prototype = {
     __proto__:  MessageTray.Source.prototype,
 
-    _init: function(title, pid) {
+    _init: function(title, pid, sender) {
         MessageTray.Source.prototype._init.call(this, title);
 
         this._pid = pid;
-        this._appStateChangedId = 0;
+        if (sender)
+            // TODO: dbus-glib implementation of watch_name() doesnât return an id to be used for
+            // unwatch_name() or implement unwatch_name(), however when we move to using GDBus implementation,
+            // we should save the id here and call unwatch_name() with it in destroy().
+            // Moving to GDBus is the work in progress: https://bugzilla.gnome.org/show_bug.cgi?id=648651
+            // and https://bugzilla.gnome.org/show_bug.cgi?id=622921 .
+            DBus.session.watch_name(sender,
+                                    false,
+                                    null,
+                                    Lang.bind(this, this._onNameVanished));
+
         this._setApp();
         if (this.app)
             this.title = this.app.get_name();
@@ -448,6 +458,14 @@ Source.prototype = {
         this._trayIcon = null;
     },
 
+    _onNameVanished: function() {
+        // Destroy the notification source when its sender is removed from DBus.
+        // Sender being removed from DBus would normally result in a tray icon being removed,
+        // so allow the code path that handles the tray icon being removed to handle that case.
+        if (!this.trayIcon)
+            this.destroy();
+    },
+
     processNotification: function(notification, icon) {
         if (!this.app)
             this._setApp();
@@ -500,10 +518,6 @@ Source.prototype = {
         if (!this.app)
             return;
 
-        // We only update the app if this.app is null, so we can't disconnect the old this._appStateChangedId
-        // even if it were non-zero for some reason.
-        this._appStateChangedId = this.app.connect('notify::state', Lang.bind(this,  this._appStateChanged));
-
         // Only override the icon if we were previously using
         // notification-based icons (ie, not a trayicon) or if it was unset before
         if (!this._trayIcon) {
@@ -528,19 +542,6 @@ Source.prototype = {
             this.destroy();
     },
 
-    _appStateChanged: function() {
-        // Destroy notification sources when their apps exit.
-        // The app exiting would normally result in a tray icon being removed,
-        // so the associated source would be destroyed through the code path
-        // that handles the tray icon being removed. We should not destroy
-        // the source associated with a tray icon when the application state
-        // is Shell.AppState.STOPPED because running applications that have
-        // no open windows would also have that state. This is often the case
-        // for applications that use tray icons.
-        if (!this._trayIcon && this.app.get_state() == Shell.AppState.STOPPED)
-            this.destroy();
-    },
-
     openApp: function() {
         if (this.app == null)
             return;
@@ -553,10 +554,6 @@ Source.prototype = {
     },
 
     destroy: function() {
-        if (this.app && this._appStateChangedId) {
-            this.app.disconnect(this._appStateChangedId);
-            this._appStateChangedId = 0;
-        }
         MessageTray.Source.prototype.destroy.call(this);
     }
 };



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