diff --git a/docs/changelog.md b/docs/changelog.md
index 4be9f53..524e9c4 100644
--- a/docs/changelog.md
+++ b/docs/changelog.md
@@ -1,5 +1,17 @@
# Changelog of the Burn-My-Windows Extension
+## [Burn My Windows 19](https://github.com/schneegans/Burn-My-Windows/releases/tag/v19)
+
+**Release Date:** TBD
+
+#### New Features
+
+* On GNOME, the incinerate effect now uses the current mouse pointer position as starting position of the burn effect. The old random behaviour can be enabled in the settings.
+
+#### Enhancements
+
+* On GNOME, effects can now execute code whenever an animation ended. This is useful for cleaning up resources.
+
## [Burn My Windows 18](https://github.com/schneegans/Burn-My-Windows/releases/tag/v18)
**Release Date:** 2022-06-30
diff --git a/extension.js b/extension.js
index 067ab2e..207a8ce 100644
--- a/extension.js
+++ b/extension.js
@@ -229,6 +229,7 @@ class Extension {
const shader = actor.get_effect('burn-my-windows-effect');
if (shader) {
actor.remove_effect(shader);
+ shader.endAnimation();
shader.returnToFactory();
}
}
@@ -385,6 +386,7 @@ class Extension {
const oldShader = actor.get_effect('burn-my-windows-effect');
if (oldShader) {
actor.remove_effect(oldShader);
+ oldShader.endAnimation();
oldShader.returnToFactory();
}
@@ -520,6 +522,7 @@ class Extension {
const oldShader = actor.get_effect('burn-my-windows-effect');
if (oldShader) {
actor.remove_effect(oldShader);
+ oldShader.endAnimation();
oldShader.returnToFactory();
}
});
diff --git a/kwin/incinerate/onAnimationBegin.js b/kwin/incinerate/onAnimationBegin.js
index 12be257..18f72bc 100644
--- a/kwin/incinerate/onAnimationBegin.js
+++ b/kwin/incinerate/onAnimationBegin.js
@@ -1,4 +1,9 @@
// This part is automatically included in the effect's source during the build process.
// The code below is called whenever a window is closed or opened.
-effect.setUniform(this.shader, 'uSeed', [Math.random(), Math.random()]);
+let seed = [Math.random(), Math.random()];
+let startPos = seed[0] > seed[1] ? [seed[0], Math.floor(seed[1] + 0.5)] :
+ [Math.floor(seed[0] + 0.5), seed[1]];
+
+effect.setUniform(this.shader, 'uSeed', seed);
+effect.setUniform(this.shader, 'uStartPos', startPos);
\ No newline at end of file
diff --git a/resources/shaders/incinerate.frag b/resources/shaders/incinerate.frag
index c33da41..61558b9 100644
--- a/resources/shaders/incinerate.frag
+++ b/resources/shaders/incinerate.frag
@@ -17,6 +17,7 @@ uniform vec2 uSeed;
uniform vec3 uColor;
uniform float uScale;
uniform float uTurbulence;
+uniform vec2 uStartPos;
// This maps a given value in [0..1] to a color from the rgba color ramp
// [transparent black ... semi-transparent uColor ... opaque white].
@@ -75,11 +76,8 @@ void main() {
// Now we compute a 2D gradient in [0..1] which covers the entire window. The dark
// regions will be burned first, the bright regions in the end. We mix a radial gradient
- // with some noise. The center of the radial gradient is positioned somewhere at the
- // window boundary.
- vec2 center = uSeed.x > uSeed.y ? vec2(uSeed.x, floor(uSeed.y + 0.5))
- : vec2(floor(uSeed.x + 0.5), uSeed.y);
- float circle = length(iTexCoord - center);
+ // with some noise. The center of the radial gradient is positioned at uStartPos.
+ float circle = length(iTexCoord - uStartPos);
vec2 uv = iTexCoord / uScale * uSize / 1.5;
float smokeNoise =
diff --git a/resources/ui/gtk3/Incinerate.ui b/resources/ui/gtk3/Incinerate.ui
index 808eba4..816b0f9 100644
--- a/resources/ui/gtk3/Incinerate.ui
+++ b/resources/ui/gtk3/Incinerate.ui
@@ -181,6 +181,68 @@
+
+
+
+
10
diff --git a/resources/ui/gtk4/Incinerate.ui b/resources/ui/gtk4/Incinerate.ui
index 958cd5e..71e5521 100644
--- a/resources/ui/gtk4/Incinerate.ui
+++ b/resources/ui/gtk4/Incinerate.ui
@@ -152,6 +152,59 @@
+
+
+ 0
+
+
+
+
+ vertical
+ 3
+
+
+ Start at Pointer
+ 0
+ start
+ center
+ 1
+
+
+
+
+ If disabled, a random location will be chosen.
+ 0
+ start
+ center
+ 1
+
+
+
+
+
+
+
+ end
+ center
+
+
+
+
+ edit-clear-symbolic
+ Reset to Default Value
+
+
+
+
+
+
+
+
0
diff --git a/schemas/org.gnome.shell.extensions.burn-my-windows.gschema.xml b/schemas/org.gnome.shell.extensions.burn-my-windows.gschema.xml
index 50f69e0..ee26406 100644
--- a/schemas/org.gnome.shell.extensions.burn-my-windows.gschema.xml
+++ b/schemas/org.gnome.shell.extensions.burn-my-windows.gschema.xml
@@ -371,6 +371,12 @@
The color of the effect.
+
+ true
+ Incinerate Use Pointer
+ Use the pointer location for the incinerate effect.
+
+
diff --git a/src/Incinerate.js b/src/Incinerate.js
index dd3e777..0277929 100644
--- a/src/Incinerate.js
+++ b/src/Incinerate.js
@@ -47,22 +47,65 @@ var Incinerate = class {
shader._uColor = shader.get_uniform_location('uColor');
shader._uScale = shader.get_uniform_location('uScale');
shader._uTurbulence = shader.get_uniform_location('uTurbulence');
+ shader._uStartPos = shader.get_uniform_location('uStartPos');
// Write all uniform values at the start of each animation.
- shader.connect('begin-animation', (shader, settings) => {
- const c = Clutter.Color.from_string(settings.get_string('incinerate-color'))[1];
-
+ shader.connect('begin-animation', (shader, settings, forOpening, actor) => {
// If we are currently performing integration test, the animation uses a fixed
// seed.
const testMode = settings.get_boolean('test-mode');
+ let seed = [testMode ? 0 : Math.random(), testMode ? 0 : Math.random()];
+
+ // If this option is set, we use the mouse pointer position. Because the actor
+ // position may change after the begin-animation signal is called, we set the
+ // uStartPos uniform during the update callback.
+ if (settings.get_boolean('incinerate-use-pointer')) {
+ this._startPointerPos = global.get_pointer();
+ this._actor = actor;
+
+ } else {
+ // Else, a random position along the window boundary is used as start position
+ // for the incinerate effect.
+ let startPos = seed[0] > seed[1] ? [seed[0], Math.floor(seed[1] + 0.5)] :
+ [Math.floor(seed[0] + 0.5), seed[1]];
+
+ shader.set_uniform_float(shader._uStartPos, 2, startPos);
+
+ this._startPointerPos = null;
+ }
+
+ const c = Clutter.Color.from_string(settings.get_string('incinerate-color'))[1];
// clang-format off
- shader.set_uniform_float(shader._uSeed, 2, [testMode ? 0 : Math.random(), testMode ? 0 : Math.random()]);
- shader.set_uniform_float(shader._uColor, 3, [c.red / 255, c.green / 255, c.blue / 255]);
- shader.set_uniform_float(shader._uScale, 1, [settings.get_double('incinerate-scale')]);
+ shader.set_uniform_float(shader._uSeed, 2, seed);
+ shader.set_uniform_float(shader._uColor, 3, [c.red / 255, c.green / 255, c.blue / 255]);
+ shader.set_uniform_float(shader._uScale, 1, [settings.get_double('incinerate-scale')]);
shader.set_uniform_float(shader._uTurbulence, 1, [settings.get_double('incinerate-turbulence')]);
// clang-format on
});
+
+ // If the mouse pointer position is used as start position, we set the uStartPos
+ // uniform during the update callback as the actor position may not be set up
+ // properly before the begin animation callback.
+ shader.connect('update-animation', (shader) => {
+ if (this._startPointerPos) {
+ const [x, y] = this._startPointerPos;
+ const [ok, localX, localY] = this._actor.transform_stage_point(x, y);
+
+ if (ok) {
+ let startPos = [
+ Math.max(0.0, Math.min(1.0, localX / this._actor.width)),
+ Math.max(0.0, Math.min(1.0, localY / this._actor.height))
+ ];
+ shader.set_uniform_float(shader._uStartPos, 2, startPos);
+ }
+ }
+ });
+
+ // Make sure to drop the reference to the actor.
+ shader.connect('end-animation', (shader) => {
+ shader._actor = null;
+ });
});
}
@@ -100,6 +143,7 @@ var Incinerate = class {
dialog.bindAdjustment('incinerate-animation-time');
dialog.bindAdjustment('incinerate-scale');
dialog.bindAdjustment('incinerate-turbulence');
+ dialog.bindSwitch('incinerate-use-pointer');
dialog.bindColorButton('incinerate-color');
// Finally, return the new settings page.
diff --git a/src/Shader.js b/src/Shader.js
index 2ae1ad0..630cb25 100644
--- a/src/Shader.js
+++ b/src/Shader.js
@@ -48,7 +48,8 @@ var Shader = GObject.registerClass(
Signals: {
'begin-animation':
{param_types: [Gio.Settings.$gtype, GObject.TYPE_BOOLEAN, Clutter.Actor.$gtype]},
- 'update-animation': {param_types: [GObject.TYPE_DOUBLE]}
+ 'update-animation': {param_types: [GObject.TYPE_DOUBLE]},
+ 'end-animation': {}
}
},
class Shader extends Shell.GLSLEffect { // --------------------------------------------
@@ -99,6 +100,12 @@ var Shader = GObject.registerClass(
this._progress = progress;
}
+ // This will just emit the end-animation signal. It can be used to clean up any
+ // resources required during the animation.
+ endAnimation() {
+ this.emit('end-animation');
+ }
+
// This is called by the constructor. This means, it's only called when the
// effect is used for the first time.
vfunc_build_pipeline() {
diff --git a/tests/references/incinerate-close-gnome-wayland-nested-32.png b/tests/references/incinerate-close-gnome-wayland-nested-32.png
index e509e00..a64987e 100644
Binary files a/tests/references/incinerate-close-gnome-wayland-nested-32.png and b/tests/references/incinerate-close-gnome-wayland-nested-32.png differ
diff --git a/tests/references/incinerate-close-gnome-wayland-nested-33.png b/tests/references/incinerate-close-gnome-wayland-nested-33.png
index 5073673..bd400af 100644
Binary files a/tests/references/incinerate-close-gnome-wayland-nested-33.png and b/tests/references/incinerate-close-gnome-wayland-nested-33.png differ
diff --git a/tests/references/incinerate-close-gnome-wayland-nested-34.png b/tests/references/incinerate-close-gnome-wayland-nested-34.png
index 902ffcb..03f2b53 100644
Binary files a/tests/references/incinerate-close-gnome-wayland-nested-34.png and b/tests/references/incinerate-close-gnome-wayland-nested-34.png differ
diff --git a/tests/references/incinerate-close-gnome-wayland-nested-35.png b/tests/references/incinerate-close-gnome-wayland-nested-35.png
index 902ffcb..03f2b53 100644
Binary files a/tests/references/incinerate-close-gnome-wayland-nested-35.png and b/tests/references/incinerate-close-gnome-wayland-nested-35.png differ
diff --git a/tests/references/incinerate-close-gnome-wayland-nested-36.png b/tests/references/incinerate-close-gnome-wayland-nested-36.png
index 9684afe..a027162 100644
Binary files a/tests/references/incinerate-close-gnome-wayland-nested-36.png and b/tests/references/incinerate-close-gnome-wayland-nested-36.png differ
diff --git a/tests/references/incinerate-close-gnome-xsession-32.png b/tests/references/incinerate-close-gnome-xsession-32.png
index e509e00..a64987e 100644
Binary files a/tests/references/incinerate-close-gnome-xsession-32.png and b/tests/references/incinerate-close-gnome-xsession-32.png differ
diff --git a/tests/references/incinerate-close-gnome-xsession-33.png b/tests/references/incinerate-close-gnome-xsession-33.png
index 5073673..bd400af 100644
Binary files a/tests/references/incinerate-close-gnome-xsession-33.png and b/tests/references/incinerate-close-gnome-xsession-33.png differ
diff --git a/tests/references/incinerate-close-gnome-xsession-34.png b/tests/references/incinerate-close-gnome-xsession-34.png
index 22febf8..c214b01 100644
Binary files a/tests/references/incinerate-close-gnome-xsession-34.png and b/tests/references/incinerate-close-gnome-xsession-34.png differ
diff --git a/tests/references/incinerate-close-gnome-xsession-35.png b/tests/references/incinerate-close-gnome-xsession-35.png
index 22febf8..c214b01 100644
Binary files a/tests/references/incinerate-close-gnome-xsession-35.png and b/tests/references/incinerate-close-gnome-xsession-35.png differ
diff --git a/tests/references/incinerate-close-gnome-xsession-36.png b/tests/references/incinerate-close-gnome-xsession-36.png
index bf4760d..a95fb9c 100644
Binary files a/tests/references/incinerate-close-gnome-xsession-36.png and b/tests/references/incinerate-close-gnome-xsession-36.png differ
diff --git a/tests/references/incinerate-open-gnome-wayland-nested-32.png b/tests/references/incinerate-open-gnome-wayland-nested-32.png
index 04aa1f7..93cda9e 100644
Binary files a/tests/references/incinerate-open-gnome-wayland-nested-32.png and b/tests/references/incinerate-open-gnome-wayland-nested-32.png differ
diff --git a/tests/references/incinerate-open-gnome-wayland-nested-33.png b/tests/references/incinerate-open-gnome-wayland-nested-33.png
index 4faa883..f94b8a4 100644
Binary files a/tests/references/incinerate-open-gnome-wayland-nested-33.png and b/tests/references/incinerate-open-gnome-wayland-nested-33.png differ
diff --git a/tests/references/incinerate-open-gnome-wayland-nested-34.png b/tests/references/incinerate-open-gnome-wayland-nested-34.png
index 306d54a..87f5233 100644
Binary files a/tests/references/incinerate-open-gnome-wayland-nested-34.png and b/tests/references/incinerate-open-gnome-wayland-nested-34.png differ
diff --git a/tests/references/incinerate-open-gnome-wayland-nested-35.png b/tests/references/incinerate-open-gnome-wayland-nested-35.png
index 306d54a..87f5233 100644
Binary files a/tests/references/incinerate-open-gnome-wayland-nested-35.png and b/tests/references/incinerate-open-gnome-wayland-nested-35.png differ
diff --git a/tests/references/incinerate-open-gnome-wayland-nested-36.png b/tests/references/incinerate-open-gnome-wayland-nested-36.png
index d5ef62d..ce1d46c 100644
Binary files a/tests/references/incinerate-open-gnome-wayland-nested-36.png and b/tests/references/incinerate-open-gnome-wayland-nested-36.png differ
diff --git a/tests/references/incinerate-open-gnome-xsession-32.png b/tests/references/incinerate-open-gnome-xsession-32.png
index 04aa1f7..2da2df2 100644
Binary files a/tests/references/incinerate-open-gnome-xsession-32.png and b/tests/references/incinerate-open-gnome-xsession-32.png differ
diff --git a/tests/references/incinerate-open-gnome-xsession-33.png b/tests/references/incinerate-open-gnome-xsession-33.png
index 4faa883..3cd2fad 100644
Binary files a/tests/references/incinerate-open-gnome-xsession-33.png and b/tests/references/incinerate-open-gnome-xsession-33.png differ
diff --git a/tests/references/incinerate-open-gnome-xsession-34.png b/tests/references/incinerate-open-gnome-xsession-34.png
index 0e7557b..7a20201 100644
Binary files a/tests/references/incinerate-open-gnome-xsession-34.png and b/tests/references/incinerate-open-gnome-xsession-34.png differ
diff --git a/tests/references/incinerate-open-gnome-xsession-35.png b/tests/references/incinerate-open-gnome-xsession-35.png
index 0e7557b..7a20201 100644
Binary files a/tests/references/incinerate-open-gnome-xsession-35.png and b/tests/references/incinerate-open-gnome-xsession-35.png differ
diff --git a/tests/references/incinerate-open-gnome-xsession-36.png b/tests/references/incinerate-open-gnome-xsession-36.png
index 410b154..9bd9e09 100644
Binary files a/tests/references/incinerate-open-gnome-xsession-36.png and b/tests/references/incinerate-open-gnome-xsession-36.png differ