🎉 Support ovierview animations in GNOME 3.36

This commit is contained in:
Simon Schneegans
2022-01-02 07:58:35 +01:00
parent 403fac3367
commit 976533ccc8
2 changed files with 56 additions and 47 deletions
+4
View File
@@ -4,6 +4,10 @@
**Release Date:** TBD **Release Date:** TBD
Sadly, it does not seem to be enough. `WINDOW_REPOSITIONING_DELAY` is set to 750ms per default; setting the window-close animation time to 500ms does not solve the issue.
It's quite difficult to trace the code flow for me. One difference seems to be that `Workspace._doRemoveWindow` is called after the clone is destroyed on GNOME 3.38 and beyond but not on GNOME 3.36.
#### New Features #### New Features
* Added a new ridiculous close-animation: the T-Rex-Attack! * Added a new ridiculous close-animation: the T-Rex-Attack!
+26 -21
View File
@@ -55,6 +55,7 @@ class Extension {
// We will monkey-patch these three methods. Let's store the original ones. // We will monkey-patch these three methods. Let's store the original ones.
this._origWindowRemoved = Workspace.prototype._windowRemoved; this._origWindowRemoved = Workspace.prototype._windowRemoved;
this._origDoRemoveWindow = Workspace.prototype._doRemoveWindow; this._origDoRemoveWindow = Workspace.prototype._doRemoveWindow;
this._origAddWindowClone = Workspace.prototype._addWindowClone;
this._origShouldAnimateActor = WindowManager.prototype._shouldAnimateActor; this._origShouldAnimateActor = WindowManager.prototype._shouldAnimateActor;
// We may also override these animation times. // We may also override these animation times.
@@ -80,23 +81,27 @@ class Extension {
// the WorkspacesView. // the WorkspacesView.
const extensionThis = this; const extensionThis = this;
// I have not yet found a way to create a close animation for window clones in the // On GNOME 3.36, the window clone's 'destroy' handler only calls _removeWindowClone
// overview of GNOME Shell 3.36. The destruction of the clones was handled differently // but not _doRemoveWindow. The latter is required to trigger the repositioning of the
// back then and it seems that the developers noticed that animating the closing is // overview window layout. Therefore we call this method in addition.
// 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#L1877
// https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/gnome-3-36/js/ui/workspace.js#L1481 // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/workspace.js#L1415
const cannotCreateCloseAnimationForOverview = GS_MAJOR < 40 && GS_MINOR < 38; if (GS_MAJOR == 3 && GS_MINOR == 36) {
Workspace.prototype._addWindowClone = function(...params) {
if (!cannotCreateCloseAnimationForOverview) { const [clone, overlay] = extensionThis._origAddWindowClone.apply(this, params);
clone.connect('destroy', () => this._doRemoveWindow(clone.metaWindow));
return [clone, overlay];
};
}
// These three method overrides are mega-hacky! They are only required to make the // 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 // 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 // from the overview (why?). With these overrides we make sure that they are actually
// actually faded out. To do this, _windowRemoved and _doRemoveWindow now check // faded out. To do this, _windowRemoved and _doRemoveWindow now check whether there
// whether there is a transition ongoing (via extensionThis._shouldDestroy). If // is a transition ongoing (via extensionThis._shouldDestroy). If that's the case,
// that's the case, these methods do nothing. Are the actors removed in the end? I // these methods do nothing. Are the actors removed in the end? I hope so. The
// hope so. The _destroyWindow of the WindowManager sets the transitions up and // _destroyWindow of the WindowManager sets the transitions up and should take care of
// should take care of removing the actors at the end of the transitions. // removing the actors at the end of the transitions.
// https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/workspace.js#L1299 // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/workspace.js#L1299
Workspace.prototype._windowRemoved = function(ws, metaWin) { Workspace.prototype._windowRemoved = function(ws, metaWin) {
if (extensionThis._shouldDestroy(this, metaWin)) { if (extensionThis._shouldDestroy(this, metaWin)) {
@@ -107,6 +112,7 @@ class Extension {
// https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/workspace.js#L1178 // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/workspace.js#L1178
Workspace.prototype._doRemoveWindow = function(metaWin) { Workspace.prototype._doRemoveWindow = function(metaWin) {
if (extensionThis._shouldDestroy(this, metaWin)) { if (extensionThis._shouldDestroy(this, metaWin)) {
utils.debug((new Error()).stack);
extensionThis._origDoRemoveWindow.apply(this, [metaWin]); extensionThis._origDoRemoveWindow.apply(this, [metaWin]);
} }
}; };
@@ -118,13 +124,12 @@ class Extension {
// whether it was called by _destroyWindow. If so, we return true. Let's see if this // whether it was called by _destroyWindow. If so, we return true. Let's see if this
// breaks stuff left and right... // breaks stuff left and right...
// https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/windowManager.js#L1125 // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/windowManager.js#L1125
WindowManager.prototype._shouldAnimateActor = function(actor, types) { WindowManager.prototype._shouldAnimateActor = function(...params) {
if ((new Error()).stack.split('\n')[1].includes('_destroyWindow@')) { if ((new Error()).stack.split('\n')[1].includes('_destroyWindow@')) {
return true; return true;
} }
return extensionThis._origShouldAnimateActor.apply(this, [actor, types]); return extensionThis._origShouldAnimateActor.apply(this, params);
}; };
}
// The close animation is set up in WindowManager's _destroyWindow: // The close animation is set up in WindowManager's _destroyWindow:
// https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/windowManager.js#L1549 // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/windowManager.js#L1549
@@ -206,6 +211,7 @@ class Extension {
Workspace.prototype._windowRemoved = this._origWindowRemoved; Workspace.prototype._windowRemoved = this._origWindowRemoved;
Workspace.prototype._doRemoveWindow = this._origDoRemoveWindow; Workspace.prototype._doRemoveWindow = this._origDoRemoveWindow;
Workspace.prototype._addWindowClone = this._origAddWindowClone;
WindowManager.prototype._shouldAnimateActor = this._origShouldAnimateActor; WindowManager.prototype._shouldAnimateActor = this._origShouldAnimateActor;
imports.ui.windowManager.DESTROY_WINDOW_ANIMATION_TIME = this._origWindowTime; imports.ui.windowManager.DESTROY_WINDOW_ANIMATION_TIME = this._origWindowTime;
@@ -224,10 +230,9 @@ class Extension {
return true; return true;
} }
// This was called "realWindow" in GNOME 3.36 but destroying the clones does not // This was called "realWindow" in GNOME 3.36.
// really work anyways... So we simply do not attempt to animate the closing of const GS_336 = GS_MAJOR == 3 && GS_MINOR == 36;
// windows in the overview of GNOME Shell 3.36. const actor = workspace._windows[index][GS_336 ? 'realWindow' : '_windowActor'];
const actor = workspace._windows[index]._windowActor;
if (!actor.get_transition('scale-y')) { if (!actor.get_transition('scale-y')) {
return true; return true;
} }