diff --git a/README.md b/README.md index 3664689..6b4434e 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ Effect | Preview -----|-------- **Apparition**
This effect hides your windows by violently sucking them into the void of magic! | **Broken Glass**
Shatter your windows into a shower sharp shards! This effect can be configured so that the shards fly away from your mouse pointer position!| +**Doom**
Melt your windows. Inspired by the legendary screen transitions of the original Doom. | **Energize A**
Beam your windows away! | **Energize B**
Using different transporter technology results in an alternative visual effect. | **Fire**
The classic effect inspired by Compiz. However, this is implemented using a GLSL shader and not with a particle system like in the old days. | @@ -50,6 +51,7 @@ Below is a table which summarizes the current availability for all effects. 3.363.384041425.25.0 Apparition ✅ ✅✅✅ Broken Glass ✅✅✅ +Doom ✅ ✅✅✅✅ Energize A ✅ ✅ ✅✅✅✅ Energize B ✅ ✅ ✅✅✅✅ Fire ✅ ✅ ✅✅✅✅ diff --git a/docs/pics/doom.gif b/docs/pics/doom.gif new file mode 100644 index 0000000..a354e02 Binary files /dev/null and b/docs/pics/doom.gif differ diff --git a/extension.js b/extension.js index 207a8ce..6a8ebc7 100644 --- a/extension.js +++ b/extension.js @@ -52,6 +52,7 @@ class Extension { this._ALL_EFFECTS = [ new Me.imports.src.Apparition.Apparition(), new Me.imports.src.BrokenGlass.BrokenGlass(), + new Me.imports.src.Doom.Doom(), new Me.imports.src.EnergizeA.EnergizeA(), new Me.imports.src.EnergizeB.EnergizeB(), new Me.imports.src.Fire.Fire(), @@ -433,7 +434,7 @@ class Extension { // windows are faded in / out scaled up / down slightly by GNOME Shell. Here, we tweak // the transitions so that nothing changes. The window stays opaque and is scaled to // actorScale. - const actorScale = effect.getActorScale(this._settings); + const actorScale = effect.getActorScale(this._settings, actor); // To make things deterministic during testing, we set the effect duration to 5 // seconds. diff --git a/prefs.js b/prefs.js index 3bc0863..b8e8bc2 100644 --- a/prefs.js +++ b/prefs.js @@ -48,6 +48,7 @@ var PreferencesDialog = class PreferencesDialog { this._ALL_EFFECTS = [ new Me.imports.src.Apparition.Apparition(), new Me.imports.src.BrokenGlass.BrokenGlass(), + new Me.imports.src.Doom.Doom(), new Me.imports.src.EnergizeA.EnergizeA(), new Me.imports.src.EnergizeB.EnergizeB(), new Me.imports.src.Fire.Fire(), diff --git a/resources/shaders/doom.frag b/resources/shaders/doom.frag new file mode 100644 index 0000000..804da44 --- /dev/null +++ b/resources/shaders/doom.frag @@ -0,0 +1,42 @@ +////////////////////////////////////////////////////////////////////////////////////////// +// ) ( // +// ( /( ( ( ) ( ( ( ( )\ ) ( ( // +// )\()) ))\ )( ( ( )\ ) )\))( )\ ( (()/( ( )\))( ( // +// ((_)\ /((_|()\ )\ ) )\ '(()/( ((_)()((_) )\ ) ((_)))\((_)()\ )\ // +// | |(_|_))( ((_)_(_/( _((_)) )(_)) _(()((_|_)_(_/( _| |((_)(()((_|(_) // +// | '_ \ || | '_| ' \)) | ' \()| || | \ V V / | ' \)) _` / _ \ V V (_-< // +// |_.__/\_,_|_| |_||_| |_|_|_| \_, | \_/\_/|_|_||_|\__,_\___/\_/\_//__/ // +// |__/ // +// Copyright (c) 2021 Simon Schneegans // +// Released under the GPLv3 or later. See LICENSE file for details. // +////////////////////////////////////////////////////////////////////////////////////////// + +// The content from common.glsl is automatically prepended to each shader effect. + +uniform float uActorScale; +uniform float uHorizontalScale; +uniform float uVerticalScale; +uniform float uPixelSize; + +void main() { + + float pixelSize = ceil(uPixelSize * uProgress + 1.0); + vec2 pixelGrid = vec2(pixelSize) / uSize; + + vec2 texcoord = iTexCoord.st; + texcoord.y = texcoord.y * uActorScale + 0.5 - uActorScale * 0.5; + texcoord -= mod(iTexCoord.st, pixelGrid); + texcoord += pixelGrid * 0.5; + + float hScale = uHorizontalScale * uSize.x * 0.001; + float vScale = uVerticalScale * uSize.y * 0.0001; + float shift = max(simplex2DFractal(texcoord.xx * hScale) * vScale + + (1.0 + vScale * 0.8) * uProgress - 0.8 * vScale, + 0.0); + + texcoord.y -= uActorScale * shift; + + vec4 oColor = getInputColor(texcoord); + + setOutputColor(oColor); +} \ No newline at end of file diff --git a/resources/ui/gtk3/Doom.ui b/resources/ui/gtk3/Doom.ui new file mode 100644 index 0000000..acb69bd --- /dev/null +++ b/resources/ui/gtk3/Doom.ui @@ -0,0 +1,248 @@ + + + + + 10000 + 100 + 1 + 100 + + + + 50 + 1 + 1 + 10 + + + + 50 + 1 + 1 + 10 + + + + 50 + 1 + 1 + 10 + + + + vertical + + + + + + none + + + + + 10 + 10 + 10 + 10 + 0 + + + 8 + + + Animation Time [ms] + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + doom-animation-time + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + + + + 10 + 10 + 10 + 10 + 0 + + + 8 + + + Horizontal Scale + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + doom-horizontal-scale + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + + + + 10 + 10 + 10 + 10 + 0 + + + 8 + + + Vertical Scale + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + doom-vertical-scale + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + + + + 10 + 10 + 10 + 10 + 0 + + + 8 + + + Pixel Size + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + doom-pixel-size + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/resources/ui/gtk4/Doom.ui b/resources/ui/gtk4/Doom.ui new file mode 100644 index 0000000..36ff248 --- /dev/null +++ b/resources/ui/gtk4/Doom.ui @@ -0,0 +1,209 @@ + + + + + vertical + + + + + + none + 1 + + + + + 0 + + + + + Animation Time [ms] + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + + + 10000 + 100 + 1 + 100 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Horizontal Scale + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + + + 50 + 1 + 1 + 10 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Vertical Scale + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + + + 50 + 1 + 1 + 10 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Pixel Size + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + + + 50 + 1 + 1 + 10 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + + + + + + + \ No newline at end of file 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 ee26406..4147b5a 100644 --- a/schemas/org.gnome.shell.extensions.burn-my-windows.gschema.xml +++ b/schemas/org.gnome.shell.extensions.burn-my-windows.gschema.xml @@ -83,6 +83,46 @@ The amount of suction of the apparition effect. + + + + + + false + Doom Close Effect + Use the Doom effect for window closing. + + + + false + Doom Open Effect + Use the Doom effect for window opening. + + + + 1500 + Doom Animation Time + The time the Doom effect takes. + + + + 10.0 + Doom Horizontal Scale + The X scale of the effect. + + + + 10.0 + Doom Vertical Scale + The Y scale of the effect. + + + + 10 + Doom Pixel Size + The size of the maximum pixelation. + + diff --git a/src/Doom.js b/src/Doom.js new file mode 100644 index 0000000..ee20212 --- /dev/null +++ b/src/Doom.js @@ -0,0 +1,110 @@ +////////////////////////////////////////////////////////////////////////////////////////// +// ) ( // +// ( /( ( ( ) ( ( ( ( )\ ) ( ( // +// )\()) ))\ )( ( ( )\ ) )\))( )\ ( (()/( ( )\))( ( // +// ((_)\ /((_|()\ )\ ) )\ '(()/( ((_)()((_) )\ ) ((_)))\((_)()\ )\ // +// | |(_|_))( ((_)_(_/( _((_)) )(_)) _(()((_|_)_(_/( _| |((_)(()((_|(_) // +// | '_ \ || | '_| ' \)) | ' \()| || | \ V V / | ' \)) _` / _ \ V V (_-< // +// |_.__/\_,_|_| |_||_| |_|_|_| \_, | \_/\_/|_|_||_|\__,_\___/\_/\_//__/ // +// |__/ // +// Copyright (c) 2021 Simon Schneegans // +// Released under the GPLv3 or later. See LICENSE file for details. // +////////////////////////////////////////////////////////////////////////////////////////// + +'use strict'; + +const GObject = imports.gi.GObject; + +const _ = imports.gettext.domain('burn-my-windows').gettext; + +const ExtensionUtils = imports.misc.extensionUtils; +const Me = imports.misc.extensionUtils.getCurrentExtension(); +const utils = Me.imports.src.utils; +const ShaderFactory = Me.imports.src.ShaderFactory.ShaderFactory; + +////////////////////////////////////////////////////////////////////////////////////////// +// This effect melts your windows. Inspired by the legendary screen transitions of the // +// original Doom. // +////////////////////////////////////////////////////////////////////////////////////////// + +// The effect class can be used to get some metadata (like the effect's name or supported +// GNOME Shell versions), to initialize the respective page of the settings dialog, as +// well as to create the actual shader for the effect. +var Doom = class { + + // The constructor creates a ShaderFactory which will be used by extension.js to create + // shader instances for this effect. The shaders will be automagically created using the + // GLSL file in resources/shaders/.glsl. The callback will be called for each + // newly created shader instance. + constructor() { + this.shaderFactory = new ShaderFactory(this.getNick(), (shader) => { + // Store uniform locations of newly created shaders. + shader._uActorScale = shader.get_uniform_location('uActorScale'); + shader._uHorizontalScale = shader.get_uniform_location('uHorizontalScale'); + shader._uVerticalScale = shader.get_uniform_location('uVerticalScale'); + shader._uPixelSize = shader.get_uniform_location('uPixelSize'); + + // Write all uniform values at the start of each animation. + shader.connect('begin-animation', (shader, settings, forOpening, actor) => { + let actorScale = 2.0 * Math.max(1.0, global.stage.height / actor.height); + // clang-format off + shader.set_uniform_float(shader._uActorScale, 1, [actorScale]); + shader.set_uniform_float(shader._uHorizontalScale, 1, [settings.get_double('doom-horizontal-scale')]); + shader.set_uniform_float(shader._uVerticalScale, 1, [settings.get_double('doom-vertical-scale')]); + shader.set_uniform_float(shader._uPixelSize, 1, [settings.get_double('doom-pixel-size')]); + // clang-format on + }); + }); + } + + // ---------------------------------------------------------------------------- metadata + + // The effect is not available on GNOME Shell 3.36 as it requires scaling of the window + // actor. + getMinShellVersion() { + return [3, 38]; + } + + // This will be called in various places where a unique identifier for this effect is + // required. It should match the prefix of the settings keys which store whether the + // effect is enabled currently (e.g. '*-close-effect'), and its animation time + // (e.g. '*-animation-time'). + getNick() { + return 'doom'; + } + + // This will be shown in the sidebar of the preferences dialog as well as in the + // drop-down menus where the user can choose the effect. + getLabel() { + return _('Doom'); + } + + // -------------------------------------------------------------------- API for prefs.js + + // This is called by the preferences dialog. It loads the settings page for this effect, + // and binds all properties to the settings. + getPreferences(dialog) { + + // Add the settings page to the builder. + dialog.getBuilder().add_from_resource(`/ui/${utils.getGTKString()}/Doom.ui`); + + // Bind all properties. + dialog.bindAdjustment('doom-animation-time'); + dialog.bindAdjustment('doom-horizontal-scale'); + dialog.bindAdjustment('doom-vertical-scale'); + dialog.bindAdjustment('doom-pixel-size'); + + // Finally, return the new settings page. + return dialog.getBuilder().get_object('doom-prefs'); + } + + // ---------------------------------------------------------------- API for extension.js + + // The getActorScale() is called from extension.js to adjust the actor's size during the + // animation. This is useful if the effect requires drawing something beyond the usual + // bounds of the actor. This only works for GNOME 3.38+. + getActorScale(settings, actor) { + let actorScale = 2.0 * Math.max(1.0, global.stage.height / actor.height); + return {x: 1.0, y: actorScale}; + } +}