diff --git a/extension.js b/extension.js index 3d936d4..2f33920 100644 --- a/extension.js +++ b/extension.js @@ -57,6 +57,7 @@ class Extension { new Me.imports.src.EnergizeA.EnergizeA(), new Me.imports.src.EnergizeB.EnergizeB(), new Me.imports.src.Fire.Fire(), + new Me.imports.src.Glide.Glide(), new Me.imports.src.Hexagon.Hexagon(), new Me.imports.src.Incinerate.Incinerate(), new Me.imports.src.Matrix.Matrix(), diff --git a/prefs.js b/prefs.js index 98f7cf2..4440466 100644 --- a/prefs.js +++ b/prefs.js @@ -53,6 +53,7 @@ var PreferencesDialog = class PreferencesDialog { new Me.imports.src.EnergizeA.EnergizeA(), new Me.imports.src.EnergizeB.EnergizeB(), new Me.imports.src.Fire.Fire(), + new Me.imports.src.Glide.Glide(), new Me.imports.src.Hexagon.Hexagon(), new Me.imports.src.Incinerate.Incinerate(), new Me.imports.src.Matrix.Matrix(), diff --git a/resources/shaders/glide.frag b/resources/shaders/glide.frag new file mode 100644 index 0000000..49af16c --- /dev/null +++ b/resources/shaders/glide.frag @@ -0,0 +1,47 @@ +////////////////////////////////////////////////////////////////////////////////////////// +// ) ( // +// ( /( ( ( ) ( ( ( ( )\ ) ( ( // +// )\()) ))\ )( ( ( )\ ) )\))( )\ ( (()/( ( )\))( ( // +// ((_)\ /((_|()\ )\ ) )\ '(()/( ((_)()((_) )\ ) ((_)))\((_)()\ )\ // +// | |(_|_))( ((_)_(_/( _((_)) )(_)) _(()((_|_)_(_/( _| |((_)(()((_|(_) // +// | '_ \ || | '_| ' \)) | ' \()| || | \ V V / | ' \)) _` / _ \ V V (_-< // +// |_.__/\_,_|_| |_||_| |_|_|_| \_, | \_/\_/|_|_||_|\__,_\___/\_/\_//__/ // +// |__/ // +////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: Simon Schneegans +// SPDX-License-Identifier: GPL-3.0-or-later + +// The content from common.glsl is automatically prepended to each shader effect. + +uniform float uScale; +uniform float uSquish; +uniform float uTilt; + +void main() { + float progress = easeOutQuad(uProgress); + progress = uForOpening ? 1.0 - progress : progress; + + vec2 coords = iTexCoord.st * 2.0 - 1.0; + + coords /= mix(1.0, uScale, progress); + + coords.y /= mix(1.0, (1.0 - uSquish), progress); + + coords.x /= mix(1.0, 1.0 - uTilt * coords.y, progress); + + coords = coords * 0.5 + 0.5; + + vec4 oColor = getInputColor(coords); + + // Dissolve window to effect color / transparency. + oColor.a = oColor.a * (1.0 - progress); + + // These are pretty useful for understanding how this works. + // oColor = vec4(masks, 0.0, 1.0); + // oColor = vec4(vec3(masks.x), 1.0); + // oColor = vec4(vec3(masks.y), 1.0); + // oColor = vec4(vec3(particles), 1.0); + + setOutputColor(oColor); +} \ No newline at end of file diff --git a/resources/ui/gtk3/Glide.ui b/resources/ui/gtk3/Glide.ui new file mode 100644 index 0000000..1527492 --- /dev/null +++ b/resources/ui/gtk3/Glide.ui @@ -0,0 +1,254 @@ + + + + + + + + 2000 + 100 + 1 + 100 + + + + 1 + 0.1 + 0.01 + 0.1 + + + + 1 + 0 + 0.01 + 0.1 + + + + 0.5 + -0.5 + 0.01 + 0.1 + + + + vertical + + + + + + none + + + + + 10 + 10 + 10 + 10 + 0 + + + 8 + + + Animation Time [ms] + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + glide-animation-time + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + + + + 10 + 10 + 10 + 10 + 0 + + + 8 + + + Scale + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + glide-scale + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + + + + 10 + 10 + 10 + 10 + 0 + + + 8 + + + Squish + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + glide-squish + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + + + + 10 + 10 + 10 + 10 + 0 + + + 8 + + + Tilt + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + glide-tilt + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/resources/ui/gtk4/Glide.ui b/resources/ui/gtk4/Glide.ui new file mode 100644 index 0000000..feae530 --- /dev/null +++ b/resources/ui/gtk4/Glide.ui @@ -0,0 +1,216 @@ + + + + + + + + vertical + + + + + + none + 1 + + + + + 0 + + + + + Animation Time [ms] + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + + + 2000 + 100 + 1 + 100 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Scale + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + + + 1 + 0.1 + 0.01 + 0.1 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Squish + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + + + 1 + 0 + 0.01 + 0.1 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Tilt + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + + + 0.5 + -0.5 + 0.01 + 0.1 + + + + + + + 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 a421f56..9dd666b 100644 --- a/schemas/org.gnome.shell.extensions.burn-my-windows.gschema.xml +++ b/schemas/org.gnome.shell.extensions.burn-my-windows.gschema.xml @@ -297,6 +297,46 @@ SPDX-License-Identifier: CC0-1.0 The fifth color of the fire gradient. + + + + + + true + Glide Close Effect + Use the glide effect for window closing. + + + + false + Glide Open Effect + Use the glide effect for window opening. + + + + 200 + Glide Animation Time + The time the glide effect takes. + + + + 0.85 + Glide Scale + The scale of the window. + + + + 0.15 + Glide Squish + The amount of squishing. + + + + -0.15 + Glide Tilt + The amount of tilting. + + diff --git a/src/Glide.js b/src/Glide.js new file mode 100644 index 0000000..350d728 --- /dev/null +++ b/src/Glide.js @@ -0,0 +1,106 @@ +////////////////////////////////////////////////////////////////////////////////////////// +// ) ( // +// ( /( ( ( ) ( ( ( ( )\ ) ( ( // +// )\()) ))\ )( ( ( )\ ) )\))( )\ ( (()/( ( )\))( ( // +// ((_)\ /((_|()\ )\ ) )\ '(()/( ((_)()((_) )\ ) ((_)))\((_)()\ )\ // +// | |(_|_))( ((_)_(_/( _((_)) )(_)) _(()((_|_)_(_/( _| |((_)(()((_|(_) // +// | '_ \ || | '_| ' \)) | ' \()| || | \ V V / | ' \)) _` / _ \ V V (_-< // +// |_.__/\_,_|_| |_||_| |_|_|_| \_, | \_/\_/|_|_||_|\__,_\___/\_/\_//__/ // +// |__/ // +////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: Simon Schneegans +// SPDX-License-Identifier: GPL-3.0-or-later + +'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 very simple effect fades the window to transparency with subtle 3D effects. // +////////////////////////////////////////////////////////////////////////////////////////// + +// 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 Glide = 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._uScale = shader.get_uniform_location('uScale'); + shader._uSquish = shader.get_uniform_location('uSquish'); + shader._uTilt = shader.get_uniform_location('uTilt'); + + // Write all uniform values at the start of each animation. + shader.connect('begin-animation', (shader, settings) => { + // clang-format off + shader.set_uniform_float(shader._uScale, 1, [settings.get_double('glide-scale')]); + shader.set_uniform_float(shader._uSquish, 1, [settings.get_double('glide-squish')]); + shader.set_uniform_float(shader._uTilt, 1, [settings.get_double('glide-tilt')]); + // clang-format on + }); + }); + } + + + // ---------------------------------------------------------------------------- metadata + + // The effect is available on all GNOME Shell versions supported by this extension. + getMinShellVersion() { + return [3, 36]; + } + + // 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 'glide'; + } + + // 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 _('Glide'); + } + + // -------------------------------------------------------------------- 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()}/Glide.ui`); + + // Bind all properties. + dialog.bindAdjustment('glide-animation-time'); + dialog.bindAdjustment('glide-scale'); + dialog.bindAdjustment('glide-squish'); + dialog.bindAdjustment('glide-tilt'); + + // Finally, return the new settings page. + return dialog.getBuilder().get_object('glide-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) { + return {x: 1.0, y: 1.0}; + } +}