[gnome-shell] Disconnect from window user time notifications, only sort when mapped



commit 4bdd40911ff8c42df1ab6681feb91b89fe0281f5
Author: Colin Walters <walters verbum org>
Date:   Fri Oct 2 15:55:55 2009 -0400

    Disconnect from window user time notifications, only sort when mapped
    
    Before we were badly leaking AppIcons by not disconnecting from the
    window signal handlers when our actor got destroyed.  This caused
    us to repeatedly re-sort the windows for each AppIcon that
    had ever been displayed with obvious bad consequences.
    
    Besides simply chaining the signals to the lifetime of the AppIcon
    actor, we also only do the sorting if we're mapped.  This decreases
    the amount of work to do in the not-mapped case.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=597120

 js/ui/appIcon.js |   29 ++++++++++++++++++++++++++++-
 1 files changed, 28 insertions(+), 1 deletions(-)
---
diff --git a/js/ui/appIcon.js b/js/ui/appIcon.js
index 5585eb0..d7dbd77 100644
--- a/js/ui/appIcon.js
+++ b/js/ui/appIcon.js
@@ -70,13 +70,21 @@ AppIcon.prototype = {
                                            reactive: true });
         this.actor._delegate = this;
         this.highlight_border_color = APPICON_DEFAULT_BORDER_COLOR;
+        this._signalIds = [];
 
+        // Note, we don't presently update the window list dynamically here; this actor
+        // gets destroyed and recreated by AppWell, and in alt-tab the whole thing is
+        // created each time
         this.windows = Shell.AppMonitor.get_default().get_windows_for_app(this.appInfo.get_id());
         for (let i = 0; i < this.windows.length; i++) {
-            this.windows[i].connect('notify::user-time', Lang.bind(this, this._resortWindows));
+            let sigId = this.windows[i].connect('notify::user-time', Lang.bind(this, this._resortWindows));
+            this._signalIds.push([this.windows[i], sigId]);
         }
         this._resortWindows();
 
+        this.actor.connect('destroy', Lang.bind(this, this._destroy));
+        this.actor.connect('notify::mapped', Lang.bind(this, this._onMappedChanged));
+
         if (this._menuType != MenuType.NONE) {
             this.actor.connect('button-press-event', Lang.bind(this, this._updateMenuOnButtonPress));
             this.actor.connect('notify::hover', Lang.bind(this, this._updateMenuOnHoverChanged));
@@ -167,7 +175,26 @@ AppIcon.prototype = {
         }
     },
 
+    _destroy: function() {
+        for (let i = 0; i < this._signalIds.length; i++) {
+            let [obj, sigId] = this._signalIds[i];
+            obj.disconnect(sigId);
+        }
+    },
+
+    _onMappedChanged: function() {
+        let mapped = this.actor.mapped;
+        if (mapped && this._windowSortStale)
+            this._resortWindows();
+    },
+
     _resortWindows: function() {
+        let mapped = this.actor.mapped;
+        if (!mapped) {
+            this._windowSortStale = true;
+            return;
+        }
+        this._windowSortStale = false;
         this.windows.sort(function (a, b) {
             let activeWorkspace = global.screen.get_active_workspace();
             let wsA = a.get_workspace() == activeWorkspace;



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