From 0c0547f4dda47feb747c0c42bf39223a8c6e408b Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Mon, 17 Jan 2022 21:11:06 +0100 Subject: [PATCH 1/3] :beetle: Fix crash when clicking the close buttons in the overview twice --- extension.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/extension.js b/extension.js index a7a0b44..63e20fe 100644 --- a/extension.js +++ b/extension.js @@ -17,6 +17,7 @@ const {Clutter, Gio, Meta} = imports.gi; const Workspace = imports.ui.workspace.Workspace; const WindowManager = imports.ui.windowManager.WindowManager; +const WindowPreview = imports.ui.windowPreview.WindowPreview; const WINDOW_REPOSITIONING_DELAY = imports.ui.workspace.WINDOW_REPOSITIONING_DELAY; const ExtensionUtils = imports.misc.extensionUtils; @@ -64,11 +65,20 @@ class Extension { this._origDoRemoveWindow = Workspace.prototype._doRemoveWindow; this._origAddWindowClone = Workspace.prototype._addWindowClone; this._origShouldAnimateActor = WindowManager.prototype._shouldAnimateActor; + this._origDeleteAll = WindowPreview.prototype._deleteAll; // We will use extensionThis to refer to the extension inside the patched methods of // the WorkspacesView. const extensionThis = this; + // Do not attempt to close windows twice. Due to the animation in the overview, the + // close button can be clicked twice which normally would lead to a crash. + WindowPreview.prototype._deleteAll = function() { + if (!this._closeRequested) { + extensionThis._origDeleteAll.apply(this); + } + }; + // On GNOME 3.36, the window clone's 'destroy' handler only calls _removeWindowClone // but not _doRemoveWindow. The latter is required to trigger the repositioning of the // overview window layout. Therefore we call this method in addition. @@ -186,6 +196,7 @@ class Extension { Workspace.prototype._doRemoveWindow = this._origDoRemoveWindow; Workspace.prototype._addWindowClone = this._origAddWindowClone; WindowManager.prototype._shouldAnimateActor = this._origShouldAnimateActor; + WindowPreview.prototype._deleteAll = this._origDeleteAll; this._settings = null; } From c21313dd341c70b7e0ba14c565a97ed37e33c087 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Mon, 17 Jan 2022 21:23:03 +0100 Subject: [PATCH 2/3] :wrench: Do not try to fix #49 on GS 3.36 --- extension.js | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/extension.js b/extension.js index 63e20fe..c8dcc3b 100644 --- a/extension.js +++ b/extension.js @@ -13,17 +13,17 @@ 'use strict'; -const {Clutter, Gio, Meta} = imports.gi; - -const Workspace = imports.ui.workspace.Workspace; -const WindowManager = imports.ui.windowManager.WindowManager; -const WindowPreview = imports.ui.windowPreview.WindowPreview; -const WINDOW_REPOSITIONING_DELAY = imports.ui.workspace.WINDOW_REPOSITIONING_DELAY; - const ExtensionUtils = imports.misc.extensionUtils; const Me = imports.misc.extensionUtils.getCurrentExtension(); const utils = Me.imports.src.utils; +const {Clutter, Gio, Meta} = imports.gi; + +const Workspace = imports.ui.workspace.Workspace; +const WindowManager = imports.ui.windowManager.WindowManager; +const WindowPreview = + utils.shellVersionIsAtLeast(3, 38) ? imports.ui.windowPreview.WindowPreview : null; + // New effects must be registered here and in prefs.js. const ALL_EFFECTS = [ Me.imports.src.EnergizeA.EnergizeA, @@ -65,7 +65,6 @@ class Extension { this._origDoRemoveWindow = Workspace.prototype._doRemoveWindow; this._origAddWindowClone = Workspace.prototype._addWindowClone; this._origShouldAnimateActor = WindowManager.prototype._shouldAnimateActor; - this._origDeleteAll = WindowPreview.prototype._deleteAll; // We will use extensionThis to refer to the extension inside the patched methods of // the WorkspacesView. @@ -73,11 +72,15 @@ class Extension { // Do not attempt to close windows twice. Due to the animation in the overview, the // close button can be clicked twice which normally would lead to a crash. - WindowPreview.prototype._deleteAll = function() { - if (!this._closeRequested) { - extensionThis._origDeleteAll.apply(this); - } - }; + if (WindowPreview) { + this._origDeleteAll = WindowPreview.prototype._deleteAll; + + WindowPreview.prototype._deleteAll = function() { + if (!this._closeRequested) { + extensionThis._origDeleteAll.apply(this); + } + }; + } // On GNOME 3.36, the window clone's 'destroy' handler only calls _removeWindowClone // but not _doRemoveWindow. The latter is required to trigger the repositioning of the @@ -196,7 +199,10 @@ class Extension { Workspace.prototype._doRemoveWindow = this._origDoRemoveWindow; Workspace.prototype._addWindowClone = this._origAddWindowClone; WindowManager.prototype._shouldAnimateActor = this._origShouldAnimateActor; - WindowPreview.prototype._deleteAll = this._origDeleteAll; + + if (WindowPreview) { + WindowPreview.prototype._deleteAll = this._origDeleteAll; + } this._settings = null; } From b8db5daa12e39066404dca520275d05d0d47c36b Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Mon, 17 Jan 2022 21:30:54 +0100 Subject: [PATCH 3/3] :wrench: Use try/catch for more robust import --- extension.js | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/extension.js b/extension.js index c8dcc3b..86c340e 100644 --- a/extension.js +++ b/extension.js @@ -13,16 +13,22 @@ 'use strict'; -const ExtensionUtils = imports.misc.extensionUtils; -const Me = imports.misc.extensionUtils.getCurrentExtension(); -const utils = Me.imports.src.utils; - const {Clutter, Gio, Meta} = imports.gi; const Workspace = imports.ui.workspace.Workspace; const WindowManager = imports.ui.windowManager.WindowManager; -const WindowPreview = - utils.shellVersionIsAtLeast(3, 38) ? imports.ui.windowPreview.WindowPreview : null; + +// The WindowPreview class is only available on GNOME Shell 3.38+; +let WindowPreview = null; +try { + WindowPreview = imports.ui.windowPreview.WindowPreview; +} catch (error) { + // Nothing to be done, we are on GNOME Shell 3.36. +} + +const ExtensionUtils = imports.misc.extensionUtils; +const Me = imports.misc.extensionUtils.getCurrentExtension(); +const utils = Me.imports.src.utils; // New effects must be registered here and in prefs.js. const ALL_EFFECTS = [