From b916f9677e2f60311012283e716a119cb2c1e0a5 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Sat, 1 Jan 2022 21:49:31 +0100 Subject: [PATCH] :wrench: Do not attempt to animate window closing in the overview of GNOME 3.36 --- extension.js | 82 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 49 insertions(+), 33 deletions(-) diff --git a/extension.js b/extension.js index f186385..82778cd 100644 --- a/extension.js +++ b/extension.js @@ -15,6 +15,9 @@ const {Clutter, Gio, Meta} = imports.gi; +const Config = imports.misc.config; +const [GS_MAJOR, GS_MINOR] = Config.PACKAGE_VERSION.split('.'); + const Workspace = imports.ui.workspace.Workspace; const WindowManager = imports.ui.windowManager.WindowManager; const WINDOW_REPOSITIONING_DELAY = imports.ui.workspace.WINDOW_REPOSITIONING_DELAY; @@ -77,41 +80,51 @@ class Extension { // the WorkspacesView. const extensionThis = this; - // These three method overrides are mega-hacky! They are only required to make the - // fire animation work in the overview. Usually, windows are not faded when closed - // from the overview (why?). With these overrides we make sure that they are actually - // faded out. To do this, _windowRemoved and _doRemoveWindow now check whether there - // is a transition ongoing (via extensionThis._shouldDestroy). If that's the case, - // these methods do nothing. Are the actors removed in the end? I hope so. The - // _destroyWindow of the WindowManager sets the transitions up and should take care of - // removing the actors at the end of the transitions. - // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/workspace.js#L1299 - Workspace.prototype._windowRemoved = function(ws, metaWin) { - if (extensionThis._shouldDestroy(this, metaWin)) { - extensionThis._origWindowRemoved.apply(this, [ws, metaWin]); - } - }; + // I have not yet found a way to create a close animation for window clones in the + // overview of GNOME Shell 3.36. The destruction of the clones was handled differently + // back then and it seems that the developers noticed that animating the closing is + // difficult / impossible with how things are set up. See this comment: + // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/gnome-3-36/js/ui/workspace.js#L1481 + const cannotCreateCloseAnimationForOverview = GS_MAJOR < 40 && GS_MINOR < 38; - // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/workspace.js#L1178 - Workspace.prototype._doRemoveWindow = function(metaWin) { - if (extensionThis._shouldDestroy(this, metaWin)) { - extensionThis._origDoRemoveWindow.apply(this, [metaWin]); - } - }; + if (!cannotCreateCloseAnimationForOverview) { - // Here comes the ULTRA-HACK: The method below is called (amongst others) by the - // _destroyWindow method of the WindowManager. Usually, it returns false when we are - // in the overview. This prevents the window-close animation. As we cannot - // monkey-patch the _destroyWindow method itself, we check inside the method below - // whether it was called by _destroyWindow. If so, we return true. Let's see if this - // breaks stuff left and right... - // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/windowManager.js#L1125 - WindowManager.prototype._shouldAnimateActor = function(actor, types) { - if ((new Error()).stack.split('\n')[1].includes('_destroyWindow@')) { - return true; - } - return extensionThis._origShouldAnimateActor.apply(this, [actor, types]); - }; + // These three method overrides are mega-hacky! They are only required to make the + // fire animation work in the overview. Usually, windows are not faded when closed + // from the overview (why?). With these overrides we make sure that they are + // actually faded out. To do this, _windowRemoved and _doRemoveWindow now check + // whether there is a transition ongoing (via extensionThis._shouldDestroy). If + // that's the case, these methods do nothing. Are the actors removed in the end? I + // hope so. The _destroyWindow of the WindowManager sets the transitions up and + // should take care of removing the actors at the end of the transitions. + // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/workspace.js#L1299 + Workspace.prototype._windowRemoved = function(ws, metaWin) { + if (extensionThis._shouldDestroy(this, metaWin)) { + extensionThis._origWindowRemoved.apply(this, [ws, metaWin]); + } + }; + + // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/workspace.js#L1178 + Workspace.prototype._doRemoveWindow = function(metaWin) { + if (extensionThis._shouldDestroy(this, metaWin)) { + extensionThis._origDoRemoveWindow.apply(this, [metaWin]); + } + }; + + // Here comes the ULTRA-HACK: The method below is called (amongst others) by the + // _destroyWindow method of the WindowManager. Usually, it returns false when we are + // in the overview. This prevents the window-close animation. As we cannot + // monkey-patch the _destroyWindow method itself, we check inside the method below + // whether it was called by _destroyWindow. If so, we return true. Let's see if this + // breaks stuff left and right... + // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/windowManager.js#L1125 + WindowManager.prototype._shouldAnimateActor = function(actor, types) { + if ((new Error()).stack.split('\n')[1].includes('_destroyWindow@')) { + return true; + } + return extensionThis._origShouldAnimateActor.apply(this, [actor, types]); + }; + } // The close animation is set up in WindowManager's _destroyWindow: // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/windowManager.js#L1549 @@ -211,6 +224,9 @@ class Extension { return true; } + // This was called "realWindow" in GNOME 3.36 but destroying the clones does not + // really work anyways... So we simply do not attempt to animate the closing of + // windows in the overview of GNOME Shell 3.36. const actor = workspace._windows[index]._windowActor; if (!actor.get_transition('scale-y')) { return true;