🪲 Properly scale windows in the overview
This commit is contained in:
+56
-29
@@ -213,42 +213,33 @@ class Extension {
|
|||||||
// of the actor. However, if we are in the overview, we have to enlarge the clone of
|
// of the actor. However, if we are in the overview, we have to enlarge the clone of
|
||||||
// the window as well.
|
// the window as well.
|
||||||
Workspace.prototype._addWindowClone = function(...params) {
|
Workspace.prototype._addWindowClone = function(...params) {
|
||||||
const result = extensionThis._origAddWindowClone.apply(this, params);
|
const clone = extensionThis._origAddWindowClone.apply(this, params);
|
||||||
|
|
||||||
// The parameters of this method changed a bit through the versions...
|
// The parameters of this method changed a bit through the versions...
|
||||||
let realWindow, clone;
|
let realWindow, container;
|
||||||
|
|
||||||
if (utils.shellVersionIs(3, 36)) {
|
if (utils.shellVersionIs(3, 36)) {
|
||||||
clone = result[0];
|
container = clone[0];
|
||||||
realWindow = clone.realWindow;
|
realWindow = container.realWindow;
|
||||||
} else if (utils.shellVersionIs(3, 38)) {
|
} else if (utils.shellVersionIs(3, 38)) {
|
||||||
clone = result._windowContainer;
|
container = clone._windowContainer;
|
||||||
realWindow = params[0].get_compositor_private();
|
realWindow = params[0].get_compositor_private();
|
||||||
} else {
|
} else {
|
||||||
clone = result.window_container;
|
container = clone.window_container;
|
||||||
realWindow = params[0].get_compositor_private();
|
realWindow = params[0].get_compositor_private();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Syncing the real window's scale with the scale of its clone only works on GNOME
|
// Store the overview clone as temporary members of the real window actor. When we
|
||||||
// Shell 3.38+. So effects cannot scale windows in the overview of GNOME 3.36...
|
// set up the effect, we will check for the existence of these and enlarge the clone
|
||||||
if (utils.shellVersionIsAtLeast(3, 38)) {
|
// as needed.
|
||||||
const xID = realWindow.connect('notify::scale-x', () => {
|
realWindow._bmwOverviewClone = clone;
|
||||||
if (realWindow.scale_x > 0 && clone.allocation.get_size()[0] > 0) {
|
realWindow._bmwOverviewCloneContainer = container;
|
||||||
clone.scale_x = realWindow.scale_x;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const yID = realWindow.connect('notify::scale-y', () => {
|
// Remove the temporary members again once the clone is deleted.
|
||||||
if (realWindow.scale_y > 0 && clone.allocation.get_size()[1] > 0) {
|
container.connect('destroy', () => {
|
||||||
clone.scale_y = realWindow.scale_y;
|
delete realWindow._bmwOverviewClone;
|
||||||
}
|
delete realWindow._bmwOverviewCloneContainer;
|
||||||
});
|
});
|
||||||
|
|
||||||
clone.connect('destroy', () => {
|
|
||||||
realWindow.disconnect(xID);
|
|
||||||
realWindow.disconnect(yID);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is actually needed for the window-close animation on GNOME Shell 3.36.
|
// This is actually needed for the window-close animation on GNOME Shell 3.36.
|
||||||
// On GNOME 3.36, the window clone's 'destroy' handler only calls _removeWindowClone
|
// On GNOME 3.36, the window clone's 'destroy' handler only calls _removeWindowClone
|
||||||
@@ -257,10 +248,10 @@ class Extension {
|
|||||||
// 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#L1877
|
||||||
// https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/workspace.js#L1363
|
// https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/workspace.js#L1363
|
||||||
if (utils.shellVersionIs(3, 36)) {
|
if (utils.shellVersionIs(3, 36)) {
|
||||||
clone.connect('destroy', () => this._doRemoveWindow(clone.metaWindow));
|
container.connect('destroy', () => this._doRemoveWindow(container.metaWindow));
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return clone;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Usually, windows are faded in after the overview is completely hidden. We enable
|
// Usually, windows are faded in after the overview is completely hidden. We enable
|
||||||
@@ -559,12 +550,48 @@ class Extension {
|
|||||||
actor.scale_x = actorScale.x;
|
actor.scale_x = actorScale.x;
|
||||||
actor.scale_y = actorScale.y;
|
actor.scale_y = actorScale.y;
|
||||||
|
|
||||||
|
// If we are in the overview, we have to enlarge the window's clone as well. We also
|
||||||
|
// disable the clone's overlay (e.g. its icon, name, and close button) during the
|
||||||
|
// animation.
|
||||||
|
if (actor._bmwOverviewClone) {
|
||||||
|
actor._bmwOverviewClone.overlayEnabled = false;
|
||||||
|
actor._bmwOverviewCloneContainer.scale_x = actorScale.x;
|
||||||
|
actor._bmwOverviewCloneContainer.scale_y = actorScale.y;
|
||||||
|
}
|
||||||
|
|
||||||
// Now add a cool shader to our window actor!
|
// Now add a cool shader to our window actor!
|
||||||
const shader = effect.shaderFactory.getShader();
|
const shader = effect.shaderFactory.getShader();
|
||||||
|
|
||||||
// Assign the effect to the window actor!
|
|
||||||
actor.add_effect_with_name('burn-my-windows-effect', shader);
|
actor.add_effect_with_name('burn-my-windows-effect', shader);
|
||||||
|
|
||||||
|
// At the end of the animation, we restore the scale of the overview clone (if any)
|
||||||
|
// and call the methods which would have been called by the original ease() calls at
|
||||||
|
// the end of the standard fade-in animation.
|
||||||
|
const endID = shader.connect('end-animation', () => {
|
||||||
|
shader.disconnect(endID);
|
||||||
|
|
||||||
|
if (actor._bmwOverviewClone) {
|
||||||
|
actor._bmwOverviewClone.overlayEnabled = true;
|
||||||
|
actor._bmwOverviewCloneContainer.scale_x = 1.0;
|
||||||
|
actor._bmwOverviewCloneContainer.scale_y = 1.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Once the animation is done or interrupted, we call the methods which should have
|
||||||
|
// been called by the original ease() methods.
|
||||||
|
// https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/windowManager.js#L1487
|
||||||
|
// https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/windowManager.js#L1558.
|
||||||
|
if (forOpening) {
|
||||||
|
Main.wm._mapWindowDone(global.window_manager, actor);
|
||||||
|
} else {
|
||||||
|
Main.wm._destroyWindowDone(global.window_manager, actor);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally remove the shader and mark it being re-usable for future animations.
|
||||||
|
actor.remove_effect(shader);
|
||||||
|
shader.returnToFactory();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// To make things deterministic during testing, we set the effect duration to 5
|
// To make things deterministic during testing, we set the effect duration to 5
|
||||||
// seconds.
|
// seconds.
|
||||||
const duration =
|
const duration =
|
||||||
|
|||||||
+6
-23
@@ -37,12 +37,14 @@ const utils = Me.imports.src.utils;
|
|||||||
// hard-coded use of straight alpha (as opposed to premultiplied). This makes the //
|
// hard-coded use of straight alpha (as opposed to premultiplied). This makes the //
|
||||||
// shaders a bit more complicated than required. //
|
// shaders a bit more complicated than required. //
|
||||||
// //
|
// //
|
||||||
// The Shader fires two signals: //
|
// The Shader fires three signals: //
|
||||||
// * begin-animation: This is called each time a new animation is started. It can //
|
// * begin-animation: This is called each time a new animation is started. It can //
|
||||||
// be used to set uniform values which do not change during the //
|
// be used to set uniform values which do not change during the //
|
||||||
// animation. //
|
// animation. //
|
||||||
// * update-animation: This is called at each frame during the animation. It can be //
|
// * update-animation: This is called at each frame during the animation. It can be //
|
||||||
// used to set uniforms which change during the animation. //
|
// used to set uniforms which change during the animation. //
|
||||||
|
// * end-animation: This is called when the animation is stopped. This can be //
|
||||||
|
// used to clean up any resources.
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
var Shader = GObject.registerClass(
|
var Shader = GObject.registerClass(
|
||||||
@@ -112,9 +114,8 @@ var Shader = GObject.registerClass(
|
|||||||
this._timeline.start();
|
this._timeline.start();
|
||||||
|
|
||||||
// Reset progress value.
|
// Reset progress value.
|
||||||
this._progress = 0;
|
this._progress = 0;
|
||||||
this._testMode = testMode;
|
this._testMode = testMode;
|
||||||
this._forOpening = forOpening;
|
|
||||||
|
|
||||||
// This is not necessarily symmetric, but I haven't figured out a way to
|
// This is not necessarily symmetric, but I haven't figured out a way to
|
||||||
// get the actual values...
|
// get the actual values...
|
||||||
@@ -138,8 +139,7 @@ var Shader = GObject.registerClass(
|
|||||||
this.queue_repaint();
|
this.queue_repaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
// This will stop any running animation and emit the end-animation signal. This can be
|
// This will stop any running animation and emit the end-animation signal.
|
||||||
// used to clean up any resources required during the animation.
|
|
||||||
endAnimation() {
|
endAnimation() {
|
||||||
// This will call endAnimation() again, so we can return for now.
|
// This will call endAnimation() again, so we can return for now.
|
||||||
if (this._timeline.is_playing()) {
|
if (this._timeline.is_playing()) {
|
||||||
@@ -147,23 +147,6 @@ var Shader = GObject.registerClass(
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the effect.
|
|
||||||
const actor = this.get_actor();
|
|
||||||
actor.remove_effect(this);
|
|
||||||
|
|
||||||
// Once the animation is done or interrupted, we call the methods which should have
|
|
||||||
// been called by the original ease() methods.
|
|
||||||
// https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/windowManager.js#L1487
|
|
||||||
// https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/windowManager.js#L1558.
|
|
||||||
if (this._forOpening) {
|
|
||||||
Main.wm._mapWindowDone(global.window_manager, actor);
|
|
||||||
} else {
|
|
||||||
Main.wm._destroyWindowDone(global.window_manager, actor);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Mark this shader of being re-usable.
|
|
||||||
this.returnToFactory();
|
|
||||||
|
|
||||||
this.emit('end-animation');
|
this.emit('end-animation');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user