diff --git a/assets/README.md b/assets/README.md
new file mode 100644
index 0000000..b71ffb7
--- /dev/null
+++ b/assets/README.md
@@ -0,0 +1,7 @@
+# Notes for `claws.blend`
+
+This is the source file for `resources/img/claws.png`. To generate the image, the animation in `claws.blend` is rendered to 256 PNG files and then combined using this command:
+
+```bash
+convert *.png -average claws.png
+```
\ No newline at end of file
diff --git a/assets/claws.blend b/assets/claws.blend
new file mode 100644
index 0000000..ee3bb06
Binary files /dev/null and b/assets/claws.blend differ
diff --git a/docs/changelog.md b/docs/changelog.md
index f001f32..60612ae 100644
--- a/docs/changelog.md
+++ b/docs/changelog.md
@@ -6,6 +6,7 @@
#### New Features
+* Added a new ridiculous close-animation: the T-Rex-Attack!
* Added a new simple close-animation: the TV-Effect!
#### Other Enhancements
diff --git a/extension.js b/extension.js
index 531a85e..f186385 100644
--- a/extension.js
+++ b/extension.js
@@ -25,6 +25,7 @@ const utils = Me.imports.src.common.utils;
const FireShader = Me.imports.src.extension.FireShader.FireShader;
const MatrixShader = Me.imports.src.extension.MatrixShader.MatrixShader;
const TVEffectShader = Me.imports.src.extension.TVEffectShader.TVEffectShader;
+const TRexShader = Me.imports.src.extension.TRexShader.TRexShader;
//////////////////////////////////////////////////////////////////////////////////////////
// This extensions modifies the window-close animation to look like the window was set //
@@ -158,6 +159,12 @@ class Extension {
} else if (mode == 3) {
shader = new TVEffectShader(this._settings);
tweakTransition('scale-y', 0.5);
+ } else if (mode == 4) {
+ shader = new TRexShader(this._settings);
+
+ const warp = 0.5 * this._settings.get_double('claw-scratch-warp');
+ tweakTransition('scale-x', 1.0 + warp);
+ tweakTransition('scale-y', 1.0 + warp);
}
if (shader) {
diff --git a/prefs.js b/prefs.js
index 562b30c..ec05e87 100644
--- a/prefs.js
+++ b/prefs.js
@@ -58,8 +58,12 @@ var PreferencesDialog = class PreferencesDialog {
this._bindColorButton('matrix-trail-color');
this._bindColorButton('matrix-tip-color');
this._bindColorButton('tv-effect-color');
+ this._bindColorButton('claw-scratch-color');
+ this._bindAdjustment('claw-scratch-scale');
+ this._bindAdjustment('claw-scratch-count');
+ this._bindAdjustment('claw-scratch-warp');
- // The fire-gradient-reset button needs to by bound explicitly.
+ // The fire-gradient-reset button needs to be bound explicitly.
this._builder.get_object('reset-fire-colors').connect('clicked', () => {
this._settings.reset('fire-color-1');
this._settings.reset('fire-color-2');
diff --git a/resources/img/claws.png b/resources/img/claws.png
new file mode 100644
index 0000000..9a21cac
Binary files /dev/null and b/resources/img/claws.png differ
diff --git a/resources/ui/gtk4.ui b/resources/ui/gtk4.ui
index dbcc828..f0fefb9 100644
--- a/resources/ui/gtk4.ui
+++ b/resources/ui/gtk4.ui
@@ -20,6 +20,10 @@
TV Effect
tv
+
+ T-Rex Attack
+ trex
+
@@ -574,6 +578,211 @@
+
+
+
+
+
+
+
+
+ none
+ 1
+
+
+
+
+ 0
+
+
+
+
+ Claw Scratch Scale
+ 0
+ start
+ center
+ 1
+
+
+
+
+ end
+ center
+ 1
+ 1
+ left
+ 300
+
+
+ 10
+ 0.1
+ 0.1
+ 1
+
+
+
+
+
+
+ edit-clear-symbolic
+ Reset to Default Value
+
+
+
+
+
+
+
+
+
+
+ 0
+
+
+
+
+ Claw Scratch Count
+ 0
+ start
+ center
+ 1
+
+
+
+
+ end
+ center
+ 1
+ 0
+ left
+ 300
+
+
+ 50
+ 1
+ 1
+ 10
+
+
+
+
+
+
+ edit-clear-symbolic
+ Reset to Default Value
+
+
+
+
+
+
+
+
+
+
+ 0
+
+
+
+
+ Warp Effect
+ 0
+ start
+ center
+ 1
+
+
+
+
+ end
+ center
+ 1
+ 2
+ left
+ 300
+
+
+ 1
+ 0
+ 0.01
+ 0.1
+
+
+
+
+
+
+ edit-clear-symbolic
+ Reset to Default Value
+
+
+
+
+
+
+
+
+
+
+ 0
+
+
+
+
+ Flash Color
+ 0
+ start
+ center
+ 1
+
+
+
+
+ 1
+ 1
+
+
+
+
+ edit-clear-symbolic
+ Reset to Default Value
+
+
+
+
+
+
+
+
+
+
+
+
+
+
30
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 ec84354..08e45c5 100644
--- a/schemas/org.gnome.shell.extensions.burn-my-windows.gschema.xml
+++ b/schemas/org.gnome.shell.extensions.burn-my-windows.gschema.xml
@@ -5,6 +5,7 @@
+
@@ -95,6 +96,7 @@
The color matrix trails.
+
"rgb(255, 255, 255)"
TV Effect Color
@@ -102,6 +104,31 @@
+
+ "rgb(170, 0, 0)"
+ Claw Scratch Color
+ The color of the claw scratches.
+
+
+
+ 1.0
+ Claw Scratch Scale
+ Size of the claw scratches.
+
+
+
+ 0.15
+ Claw Scratch Warp
+ Intensity of the claw scratch warp effect.
+
+
+
+ 5
+ Claw Scratch Count
+ Number of claw scratches drawn on top of each other.
+
+
+
\ No newline at end of file
diff --git a/src/extension/TRexShader.js b/src/extension/TRexShader.js
new file mode 100644
index 0000000..6ae0db6
--- /dev/null
+++ b/src/extension/TRexShader.js
@@ -0,0 +1,157 @@
+//////////////////////////////////////////////////////////////////////////////////////////
+// ) ( //
+// ( /( ( ( ) ( ( ( ( )\ ) ( ( //
+// )\()) ))\ )( ( ( )\ ) )\))( )\ ( (()/( ( )\))( ( //
+// ((_)\ /((_|()\ )\ ) )\ '(()/( ((_)()((_) )\ ) ((_)))\((_)()\ )\ //
+// | |(_|_))( ((_)_(_/( _((_)) )(_)) _(()((_|_)_(_/( _| |((_)(()((_|(_) //
+// | '_ \ || | '_| ' \)) | ' \()| || | \ V V / | ' \)) _` / _ \ V V (_-< //
+// |_.__/\_,_|_| |_||_| |_|_|_| \_, | \_/\_/|_|_||_|\__,_\___/\_/\_//__/ //
+// |__/ //
+// Copyright (c) 2021 Simon Schneegans //
+// Released under the GPLv3 or later. See LICENSE file for details. //
+//////////////////////////////////////////////////////////////////////////////////////////
+
+'use strict';
+
+const {Clutter, GObject, GdkPixbuf, Cogl} = imports.gi;
+
+const ExtensionUtils = imports.misc.extensionUtils;
+const Me = imports.misc.extensionUtils.getCurrentExtension();
+const shaderSnippets = Me.imports.src.extension.shaderSnippets;
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// This effect tears your windows apart with a series of violent scratches! //
+// This effect is not available on GNOME 3.3x, due to the limitation described in the //
+// documentation of vfunc_paint_target further down in this file. //
+//////////////////////////////////////////////////////////////////////////////////////////
+
+var TRexShader = GObject.registerClass({Properties: {}, Signals: {}},
+ class TRexShader extends Clutter.ShaderEffect {
+ _init(settings) {
+ super._init({shader_type: Clutter.ShaderType.FRAGMENT_SHADER});
+
+ // Load the claw texture. As the shader is re-created for each window animation, this
+ // texture is also re-created each time. This could be improved in the future!
+ // See assets/README.md for how this texture was created.
+ const clawData = GdkPixbuf.Pixbuf.new_from_resource('/img/claws.png');
+ this._clawTexture = new Clutter.Image();
+ this._clawTexture.set_data(
+ clawData.get_pixels(), Cogl.PixelFormat.RGB_888, clawData.width, clawData.height,
+ clawData.rowstride);
+
+ const color = Clutter.Color.from_string(settings.get_string('claw-scratch-color'))[1];
+
+ this.set_shader_source(`
+
+ // Inject some common shader snippets.
+ ${shaderSnippets.standardUniforms()}
+ ${shaderSnippets.noise()}
+
+ // See assets/README.md for how this texture was created.
+ uniform sampler2D uClawTexture;
+
+ const vec2 SEED = vec2(${Math.random()}, ${Math.random()});
+ const float CLAW_SIZE = ${settings.get_double('claw-scratch-scale')};
+ const float NUM_CLAWS = ${settings.get_int('claw-scratch-count')};
+ const float WARP_INTENSITY = 1.0 + ${settings.get_double('claw-scratch-warp')};
+ const float FLASH_INTENSITY = 0.1;
+ const float MAX_SPAWN_TIME = 0.5; // Scratches will only start in the first half of the animation.
+ const float FF_TIME = 0.5; // Relative time for the final fade to transparency.
+
+ // This method generates a grid of randomly rotated, slightly shifted and scaled
+ // UV squares. It returns the texture coords of the UV square at the given actor
+ // coordinates. If these do not fall into one of the UV grids, the coordinates of
+ // the closest UV grid will be clamped and returned.
+ vec2 getClawUV(vec2 texCoords, float gridScale, vec2 seed) {
+
+ // Shift coordinates by a random offset and make sure the have a 1:1 aspect ratio.
+ vec2 coords = texCoords + rand2(seed);
+ coords *= uSizeX < uSizeY ? vec2(1.0, 1.0 * uSizeY / uSizeX) : vec2(1.0 * uSizeX / uSizeY, 1.0);
+
+ // Apply global scale.
+ coords *= gridScale;
+
+ // Get grid cell coordinates in [0..1].
+ vec2 cellUV = mod(coords, vec2(1));
+
+ // This is unique for each cell.
+ vec2 cellID = coords-cellUV + vec2(362.456);
+
+ // Add random rotation, scale and offset to each grid cell.
+ float scale = mix(0.8, 1.0, rand(cellID*seed*134.451));
+ float offsetX = mix(0.0, 1.0 - scale, rand(cellID*seed*54.4129));
+ float offsetY = mix(0.0, 1.0 - scale, rand(cellID*seed*25.3089));
+ float rotation = mix(0.0, 2.0 * 3.141, rand(cellID*seed*2.99837));
+
+ cellUV -= vec2(offsetX, offsetY);
+ cellUV /= scale;
+
+ cellUV -= 0.5;
+ cellUV = vec2(cellUV.x * cos(rotation) - cellUV.y * sin(rotation),
+ cellUV.x * sin(rotation) + cellUV.y * cos(rotation));
+ cellUV += 0.5;
+
+ // Clamp resulting coordinates.
+ return clamp(cellUV, vec2(0), vec2(1));
+ }
+
+ void main() {
+
+ // Warp the texture coordinates to create a blow-up effect.
+ vec2 coords = cogl_tex_coord_in[0].st * 2.0 - 1.0;
+ float dist = length(coords);
+ coords = (coords/dist * pow(dist, WARP_INTENSITY)) * 0.5 + 0.5;
+ coords = mix(cogl_tex_coord_in[0].st, coords, uProgress);
+
+ // Accumulate several random scratches. The color in the scratch map refers to the
+ // relative time when the respective part will become invisible. Therefore we can
+ // add a value to make the scratch appear later.
+ float scratchMap = 1.0;
+ for (int i=0; i uProgress ? 1 : 0);
+
+ // Add colorful flashes.
+ float flashIntensity = 1.0 / FLASH_INTENSITY * (scratchMap - uProgress) + 1;
+ if (flashIntensity < 0 || flashIntensity >= 1) {
+ flashIntensity = 0;
+ }
+
+ vec3 flashColor = vec3(${color.red / 255},
+ ${color.green / 255},
+ ${color.blue / 255}) * ${color.alpha / 255};
+
+ cogl_color_out.rgb += flashIntensity * mix(flashColor, vec3(0), uProgress);
+
+ // Fade out the remaining shards.
+ float fade = smoothstep(0, 1, 1 - clamp((uProgress - 1.0 + FF_TIME)/FF_TIME, 0, 1));
+ cogl_color_out *= fade;
+
+ // These are pretty useful for understanding how this works.
+ // cogl_color_out = vec4(vec3(flashIntensity), 1);
+ // cogl_color_out = vec4(vec3(scratchMap), 1);
+ }
+ `);
+ };
+
+ // This is overridden to bind the claw texture for drawing. Sadly, this seems to be
+ // impossible under GNOME 3.3x as this.get_pipeline() is not available. It was called
+ // get_target() back then but this is not wrapped in GJS.
+ // https://gitlab.gnome.org/GNOME/mutter/-/blob/gnome-3-36/clutter/clutter/clutter-offscreen-effect.c#L598
+ vfunc_paint_target(node, paint_context) {
+ const pipeline = this.get_pipeline();
+ pipeline.set_layer_texture(1, this._clawTexture.get_texture());
+ this.set_uniform_value('uClawTexture', 1);
+ super.vfunc_paint_target(node, paint_context);
+ }
+});
\ No newline at end of file