[gnome-documents] preview, selections: Be nice to the garbage collector during shutdown



commit 96bd8f9f8b54bc4cee18299592108a9f3fb07c6c
Author: Debarshi Ray <debarshir gnome org>
Date:   Tue Aug 14 19:20:31 2018 +0200

    preview, selections: Be nice to the garbage collector during shutdown
    
    GJS' garbage collector doesn't like having the virtual function for
    GtkWidget::destroy overridden. Doing that either causes a crash or
    leads to CRITICALs like these:
      Gjs-CRITICAL **: Attempting to call back into JSAPI during the
        sweeping phase of GC. This is most likely caused by not destroying
        a Clutter actor or Gtk+ widget with ::destroy signals connected,
        but can also be caused by using the destroy() or dispose() vfuncs.
        Because it would crash the application, it has been blocked and
        the JS callback not invoked.
    
    For some reason unknown to me, connecting to the signal instead of
    overriding the virtual function seems to be fine. This is backed by
    gnome-shell commit 98b50fd9423e57 [1] and observed behaviour.
    
    [1] https://gitlab.gnome.org/GNOME/gnome-shell/commit/98b50fd9423e57
    
    https://bugzilla.gnome.org/show_bug.cgi?id=747506

 src/preview.js    | 79 +++++++++++++++++++++++++++----------------------------
 src/selections.js |  8 +++---
 2 files changed, 43 insertions(+), 44 deletions(-)
---
diff --git a/src/preview.js b/src/preview.js
index a4975dc6..d436f276 100644
--- a/src/preview.js
+++ b/src/preview.js
@@ -73,6 +73,45 @@ var Preview = new Lang.Class({
 
         this._nightModeId = Application.application.connect('action-state-changed::night-mode',
             Lang.bind(this, this._updateNightMode));
+
+        this.connect('destroy', Lang.bind(this,
+            function() {
+                if (this._loadStartedId > 0) {
+                    Application.documentManager.disconnect(this._loadStartedId);
+                    this._loadStartedId = 0;
+                }
+                if (this._loadFinishedId > 0) {
+                    Application.documentManager.disconnect(this._loadFinishedId);
+                    this._loadFinishedId = 0;
+                }
+                if (this._loadErrorId > 0) {
+                    Application.documentManager.disconnect(this._loadErrorId);
+                    this._loadErrorId = 0;
+                }
+                if (this._passwordNeededId > 0) {
+                    Application.documentManager.disconnect(this._passwordNeededId);
+                    this._passwordNeededId = 0;
+                }
+                if (this.navControls) {
+                    this.navControls.destroy();
+                    this.navControls = null;
+                }
+
+                if (this._fsToolbar) {
+                    this._fsToolbar.destroy();
+                    this._fsToolbar = null;
+                }
+
+                if (this._fullscreenAction) {
+                    this._fullscreenAction.change_state(new GLib.Variant('b', false));
+                    this._fullscreenAction.disconnect(this._fsStateId);
+                }
+
+                if (this._nightModeId > 0) {
+                    Application.application.disconnect(this._nightModeId);
+                    this._nightModeId = 0;
+                }
+            }));
     },
 
     _getDefaultActions: function() {
@@ -205,46 +244,6 @@ var Preview = new Lang.Class({
         }
     },
 
-    vfunc_destroy: function() {
-        if (this._loadStartedId > 0) {
-            Application.documentManager.disconnect(this._loadStartedId);
-            this._loadStartedId = 0;
-        }
-        if (this._loadFinishedId > 0) {
-            Application.documentManager.disconnect(this._loadFinishedId);
-            this._loadFinishedId = 0;
-        }
-        if (this._loadErrorId > 0) {
-            Application.documentManager.disconnect(this._loadErrorId);
-            this._loadErrorId = 0;
-        }
-        if (this._passwordNeededId > 0) {
-            Application.documentManager.disconnect(this._passwordNeededId);
-            this._passwordNeededId = 0;
-        }
-        if (this.navControls) {
-            this.navControls.destroy();
-            this.navControls = null;
-        }
-
-        if (this._fsToolbar) {
-            this._fsToolbar.destroy();
-            this._fsToolbar = null;
-        }
-
-        if (this._fullscreenAction) {
-            this._fullscreenAction.change_state(new GLib.Variant('b', false));
-            this._fullscreenAction.disconnect(this._fsStateId);
-        }
-
-        if (this._nightModeId > 0) {
-            Application.application.disconnect(this._nightModeId);
-            this._nightModeId = 0;
-        }
-
-        this.parent();
-    },
-
     _createActionGroup: function() {
         let actions = this.createActions().concat(this._getDefaultActions());
         let actionGroup = new Gio.SimpleActionGroup();
diff --git a/src/selections.js b/src/selections.js
index d65dd2c4..b1813211 100644
--- a/src/selections.js
+++ b/src/selections.js
@@ -885,11 +885,11 @@ var SelectionToolbar = new Lang.Class({
         Application.selectionController.connect('selection-changed',
             Lang.bind(this, this._onSelectionChanged));
         this._onSelectionChanged();
-    },
 
-    vfunc_destroy: function() {
-        this._disconnectDocToPrint();
-        this.parent();
+        this.connect('destroy', Lang.bind(this,
+            function() {
+                this._disconnectDocToPrint();
+            }));
     },
 
     vfunc_hide: function() {


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