diff --git a/README.md b/README.md index 7d3c84c..0084907 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,8 @@ Effect | Preview **Incinerate**
A less snappy but definitely more fancy take on the fire effect. | **Matrix**
Turn your windows into a shower of green letters! The color is actually configurable.| **Pixelate**
Pixelate your windows and randomly hide pixels until the entire window is gone.| +**Pixel Wheel**
This simple effect pixelates the window and hides the pixels in a wheel-like fashion.| +**Pixel Wipe**
This effect pixelates the window and hides the pixels radially, starting from the pointer position.| **Snap of Disintegration**
Dissolve your windows into a cloud of dust.| **T-Rex Attack**
Destroy your windows with a series of violent slashes!| **TV-Effect**
This is a very simple effect to demonstrate that this extension could also be used in a more professional environment. | @@ -60,6 +62,8 @@ Below is a table which summarizes the current availability for all effects. Incinerate ✅ ✅ ✅✅✅✅ Matrix ✅✅✅ Pixelate ✅ ✅ ✅✅✅✅ +Pixel Wheel ✅ ✅ ✅✅✅✅ +Pixel Wipe ✅ ✅ ✅✅✅✅ Snap of Disintegration ✅✅✅ T-Rex Attack ✅✅✅ TV-Effect ✅ ✅ ✅✅✅✅ diff --git a/docs/changelog.md b/docs/changelog.md index 62d60de..8b93e98 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -8,6 +8,8 @@ * **New Effect: Doom.** Melt your windows. Inspired by the legendary screen transitions of the original Doom. * **New Effect: Pixelate.** Pixelate your windows and randomly hide pixels until the entire window is gone. +* **New Effect: Pixel Wheel.** This simple effect pixelates the window and hides the pixels in a wheel-like fashion. +* **New Effect: Pixel Wipe.** This effect pixelates the window and hides the pixels radially, starting from the pointer position. #### Enhancements diff --git a/docs/pics/pixel-wheel.gif b/docs/pics/pixel-wheel.gif new file mode 100644 index 0000000..2cbd8d7 Binary files /dev/null and b/docs/pics/pixel-wheel.gif differ diff --git a/docs/pics/pixel-wipe.gif b/docs/pics/pixel-wipe.gif new file mode 100644 index 0000000..66dec6e Binary files /dev/null and b/docs/pics/pixel-wipe.gif differ diff --git a/extension.js b/extension.js index b13952d..8fbe62d 100644 --- a/extension.js +++ b/extension.js @@ -60,6 +60,8 @@ class Extension { new Me.imports.src.Incinerate.Incinerate(), new Me.imports.src.Matrix.Matrix(), new Me.imports.src.Pixelate.Pixelate(), + new Me.imports.src.PixelWheel.PixelWheel(), + new Me.imports.src.PixelWipe.PixelWipe(), new Me.imports.src.SnapOfDisintegration.SnapOfDisintegration(), new Me.imports.src.TRexAttack.TRexAttack(), new Me.imports.src.TVEffect.TVEffect(), diff --git a/kwin/build.sh b/kwin/build.sh index e7678f7..e12c9ab 100755 --- a/kwin/build.sh +++ b/kwin/build.sh @@ -128,15 +128,17 @@ generate() { # window canvas during the animation. #generate "apparition" "[BMW] Apparition" "This effect hides your windows by violently sucking them into the void of magic" -generate "energize-a" "Energize A [Burn-My-Windows]" "Beam your windows away" -generate "energize-b" "Energize B [Burn-My-Windows]" "Using different transporter technology results in an alternative visual effect" -generate "doom" "Doom [Burn-My-Windows]" "Melt your windows" -generate "fire" "Fire [Burn-My-Windows]" "The classic effect inspired by Compiz" -generate "hexagon" "Hexagon [Burn-My-Windows]" "With glowing lines and hexagon-shaped tiles, this effect looks very sci-fi" -generate "incinerate" "Incinerate [Burn-My-Windows]" "A less snappy but definitely more fancy take on the fire effect" -generate "pixelate" "Pixelate [Burn-My-Windows]" "Pixelate the window and randomly hide the pixels" -generate "tv" "TV Effect [Burn-My-Windows]" "Make windows close like turning off a TV" -generate "wisps" "Wisps [Burn-My-Windows]" "Let your windows be carried away to the realm of dreams by these little fairies" +generate "energize-a" "Energize A [Burn-My-Windows]" "Beam your windows away" +generate "energize-b" "Energize B [Burn-My-Windows]" "Using different transporter technology results in an alternative visual effect" +generate "doom" "Doom [Burn-My-Windows]" "Melt your windows" +generate "fire" "Fire [Burn-My-Windows]" "The classic effect inspired by Compiz" +generate "hexagon" "Hexagon [Burn-My-Windows]" "With glowing lines and hexagon-shaped tiles, this effect looks very sci-fi" +generate "incinerate" "Incinerate [Burn-My-Windows]" "A less snappy but definitely more fancy take on the fire effect" +generate "pixelate" "Pixelate [Burn-My-Windows]" "Pixelate the window and randomly hide the pixels" +generate "pixel-wheel" "Pixel Wheel [Burn-My-Windows]" "Pixelate the window and hide the pixels in a wheel-like fashion" +generate "pixel-wipe" "Pixel Wipe [Burn-My-Windows]" "Pixelate the window and hide the pixels radially, starting from the pointer position" +generate "tv" "TV Effect [Burn-My-Windows]" "Make windows close like turning off a TV" +generate "wisps" "Wisps [Burn-My-Windows]" "Let your windows be carried away to the realm of dreams by these little fairies" # Finally, create an archive for the effects. # shellcheck disable=SC2046 diff --git a/kwin/incinerate/onAnimationBegin.js b/kwin/incinerate/onAnimationBegin.js index b077f37..de6a541 100644 --- a/kwin/incinerate/onAnimationBegin.js +++ b/kwin/incinerate/onAnimationBegin.js @@ -7,10 +7,10 @@ let startPos = seed[0] > seed[1] ? [seed[0], Math.floor(seed[1] + 0.5)] : if (effect.readConfig('UsePointer', true)) { startPos = [ - (effects.cursorPos.x - window.x) / window.width, - (effects.cursorPos.y - window.y) / window.height + Math.min(1.0, Math.max(0.0, (effects.cursorPos.x - window.x) / window.width)), + Math.min(1.0, Math.max(0.0, (effects.cursorPos.y - window.y) / window.height)) ]; } effect.setUniform(this.shader, 'uSeed', seed); -effect.setUniform(this.shader, 'uStartPos', startPos); \ No newline at end of file +effect.setUniform(this.shader, 'uStartPos', startPos); diff --git a/kwin/pixel-wheel/config.ui b/kwin/pixel-wheel/config.ui new file mode 100755 index 0000000..5daa327 --- /dev/null +++ b/kwin/pixel-wheel/config.ui @@ -0,0 +1,90 @@ + + + BMWConfigForm + + + + 0 + 0 + 562 + 365 + + + + + + + Duration: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Pixel Size + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + milliseconds + + + 100 + + + 9999 + + + 100 + + + + + + + Spoke Count + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + 0 + + + 1.000000000000000 + + + 50.000000000000000 + + + + + + + 0 + + + 1.000000000000000 + + + 50.000000000000000 + + + + + + + + \ No newline at end of file diff --git a/kwin/pixel-wheel/main.xml b/kwin/pixel-wheel/main.xml new file mode 100755 index 0000000..d048ffc --- /dev/null +++ b/kwin/pixel-wheel/main.xml @@ -0,0 +1,16 @@ + + + + + + 300 + + + 12 + + + 10 + + + \ No newline at end of file diff --git a/kwin/pixel-wheel/onSettingsChanged.js b/kwin/pixel-wheel/onSettingsChanged.js new file mode 100644 index 0000000..0d66dc2 --- /dev/null +++ b/kwin/pixel-wheel/onSettingsChanged.js @@ -0,0 +1,6 @@ +// This part is automatically included in the effect's source during the build process. +// The code below is called whenever the user changes something in the configuration of +// the effect. + +effect.setUniform(this.shader, 'uSpokeCount', effect.readConfig('SpokeCount', 1.0)); +effect.setUniform(this.shader, 'uPixelSize', effect.readConfig('PixelSize', 1.0)); diff --git a/kwin/pixel-wipe/config.ui b/kwin/pixel-wipe/config.ui new file mode 100755 index 0000000..0833c60 --- /dev/null +++ b/kwin/pixel-wipe/config.ui @@ -0,0 +1,67 @@ + + + BMWConfigForm + + + + 0 + 0 + 562 + 365 + + + + + + + Duration: + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + Pixel Size + + + Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter + + + + + + + milliseconds + + + 100 + + + 9999 + + + 100 + + + + + + + 0 + + + 1.000000000000000 + + + 50.000000000000000 + + + + + + + + \ No newline at end of file diff --git a/kwin/pixel-wipe/main.xml b/kwin/pixel-wipe/main.xml new file mode 100755 index 0000000..4f31d34 --- /dev/null +++ b/kwin/pixel-wipe/main.xml @@ -0,0 +1,13 @@ + + + + + + 1000 + + + 10 + + + \ No newline at end of file diff --git a/kwin/pixel-wipe/onAnimationBegin.js b/kwin/pixel-wipe/onAnimationBegin.js new file mode 100644 index 0000000..980edc6 --- /dev/null +++ b/kwin/pixel-wipe/onAnimationBegin.js @@ -0,0 +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. + +let startPos = [ + Math.min(1.0, Math.max(0.0, (effects.cursorPos.x - window.x) / window.width)), + Math.min(1.0, Math.max(0.0, (effects.cursorPos.y - window.y) / window.height)) +]; + +effect.setUniform(this.shader, 'uStartPos', startPos); diff --git a/kwin/pixel-wipe/onSettingsChanged.js b/kwin/pixel-wipe/onSettingsChanged.js new file mode 100644 index 0000000..03c5f03 --- /dev/null +++ b/kwin/pixel-wipe/onSettingsChanged.js @@ -0,0 +1,5 @@ +// This part is automatically included in the effect's source during the build process. +// The code below is called whenever the user changes something in the configuration of +// the effect. + +effect.setUniform(this.shader, 'uPixelSize', effect.readConfig('PixelSize', 1.0)); diff --git a/prefs.js b/prefs.js index 05b9d5d..7e0b499 100644 --- a/prefs.js +++ b/prefs.js @@ -56,6 +56,8 @@ var PreferencesDialog = class PreferencesDialog { new Me.imports.src.Incinerate.Incinerate(), new Me.imports.src.Matrix.Matrix(), new Me.imports.src.Pixelate.Pixelate(), + new Me.imports.src.PixelWheel.PixelWheel(), + new Me.imports.src.PixelWipe.PixelWipe(), new Me.imports.src.SnapOfDisintegration.SnapOfDisintegration(), new Me.imports.src.TRexAttack.TRexAttack(), new Me.imports.src.TVEffect.TVEffect(), diff --git a/resources/shaders/common.glsl b/resources/shaders/common.glsl index 98507b1..1c06bc0 100644 --- a/resources/shaders/common.glsl +++ b/resources/shaders/common.glsl @@ -142,6 +142,7 @@ vec3 tritone(float val, vec3 shadows, vec3 midtones, vec3 highlights) { // https://gitlab.gnome.org/GNOME/mutter/-/blob/main/clutter/clutter/clutter-easing.c float easeOutQuad(float x) { return -1.0 * x * (x - 2.0); } +float easeInQuad(float x) { return x * x; } // --------------------------------------------------------------------- edge mask helpers diff --git a/resources/shaders/pixel-wheel.frag b/resources/shaders/pixel-wheel.frag new file mode 100644 index 0000000..3cbeb5a --- /dev/null +++ b/resources/shaders/pixel-wheel.frag @@ -0,0 +1,46 @@ +////////////////////////////////////////////////////////////////////////////////////////// +// ) ( // +// ( /( ( ( ) ( ( ( ( )\ ) ( ( // +// )\()) ))\ )( ( ( )\ ) )\))( )\ ( (()/( ( )\))( ( // +// ((_)\ /((_|()\ )\ ) )\ '(()/( ((_)()((_) )\ ) ((_)))\((_)()\ )\ // +// | |(_|_))( ((_)_(_/( _((_)) )(_)) _(()((_|_)_(_/( _| |((_)(()((_|(_) // +// | '_ \ || | '_| ' \)) | ' \()| || | \ 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 uPixelSize; +uniform float uSpokeCount; + +void main() { + // We simply inverse the progress for opening windows. + float progress = smoothstep(0.0, 1.0, uForOpening ? 1.0 - uProgress : uProgress); + + // The current level of pixelation increases with the progress. + float pixelSize = ceil(uPixelSize * progress + 1.0); + vec2 pixelGrid = vec2(pixelSize) / uSize; + vec2 texcoord = iTexCoord.st - mod(iTexCoord.st, pixelGrid) + pixelGrid * 0.5; + vec4 oColor = getInputColor(texcoord); + + // Now hide the spoke sections. + vec2 down = vec2(0.0, 1.0); + vec2 fragDir = normalize(texcoord - 0.5); + + // Compute angle to down direction. + float angle = 0.5 * acos(dot(down, fragDir)) / 3.14159265359; + if (fragDir.x < 0.0) { + angle = 1.0 - angle; + } + + // Progressively hide the spokes. + float threshold = mod(angle * uSpokeCount, 1.0); + if (progress > threshold) { + oColor.a = 0.0; + } + + setOutputColor(oColor); +} \ No newline at end of file diff --git a/resources/shaders/pixel-wipe.frag b/resources/shaders/pixel-wipe.frag new file mode 100644 index 0000000..1f2a8f5 --- /dev/null +++ b/resources/shaders/pixel-wipe.frag @@ -0,0 +1,51 @@ +////////////////////////////////////////////////////////////////////////////////////////// +// ) ( // +// ( /( ( ( ) ( ( ( ( )\ ) ( ( // +// )\()) ))\ )( ( ( )\ ) )\))( )\ ( (()/( ( )\))( ( // +// ((_)\ /((_|()\ )\ ) )\ '(()/( ((_)()((_) )\ ) ((_)))\((_)()\ )\ // +// | |(_|_))( ((_)_(_/( _((_)) )(_)) _(()((_|_)_(_/( _| |((_)(()((_|(_) // +// | '_ \ || | '_| ' \)) | ' \()| || | \ 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 uPixelSize; +uniform vec2 uStartPos; + +const float FADE_WIDTH = 1.0; // Width of the transition. + +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 at uStartPos. + float circle = length(iTexCoord - uStartPos); + + float progress = easeOutQuad(uProgress); + progress = ((1.0 - progress) * (1.0 + FADE_WIDTH) - 1.0 + circle) / FADE_WIDTH; + progress = smoothstep(0.0, 1.0, progress); + + progress = uForOpening ? progress : 1.0 - progress; + + // The current level of pixelation increases with the progress. + float pixelSize = ceil(uPixelSize * progress + 1.0); + vec2 pixelGrid = vec2(pixelSize) / uSize; + vec2 texcoord = iTexCoord.st - mod(iTexCoord.st, pixelGrid) + pixelGrid * 0.5; + vec4 oColor = getInputColor(texcoord); + + // Hide pixels in the transition zone. + float random = simplex2DFractal(texcoord * uSize / 20.0) * 1.5 - 0.25; + if (progress > random) { + oColor.a *= max(0.0, 1.0 - (progress - random) * 10.0); + } + + // These are pretty useful for understanding how this works. + // oColor = vec4(progress, 0.0, 0.0, 1.0); + // oColor = vec4(random, 0.0, 0.0, 1.0); + + setOutputColor(oColor); +} \ No newline at end of file diff --git a/resources/shaders/pixelate.frag b/resources/shaders/pixelate.frag index 12e4557..5ef05ac 100644 --- a/resources/shaders/pixelate.frag +++ b/resources/shaders/pixelate.frag @@ -27,9 +27,9 @@ void main() { vec4 oColor = getInputColor(texcoord); // Hide selected pixels based on some random noise. - float random = simplex2DFractal(texcoord * uNoise * uSize / 1000.0); - if (random * 1.5 - 0.25 < progress) { - oColor.a = 0.0; + float random = simplex2DFractal(texcoord * uNoise * uSize / 1000.0) * 1.5 - 0.25; + if (progress > random) { + oColor.a *= max(0.0, 1.0 - (progress - random) * 20.0); } setOutputColor(oColor); diff --git a/resources/ui/gtk3/PixelWheel.ui b/resources/ui/gtk3/PixelWheel.ui new file mode 100644 index 0000000..4b1b1a9 --- /dev/null +++ b/resources/ui/gtk3/PixelWheel.ui @@ -0,0 +1,192 @@ + + + + + 2000 + 100 + 1 + 100 + + + + 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 + pixel-wheel-animation-time + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + + + + 10 + 10 + 10 + 10 + 0 + + + 8 + + + Spoke Count + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + pixel-wheel-spoke-count + + + + + + + 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 + pixel-wheel-pixel-size + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/resources/ui/gtk3/PixelWipe.ui b/resources/ui/gtk3/PixelWipe.ui new file mode 100644 index 0000000..f3830f2 --- /dev/null +++ b/resources/ui/gtk3/PixelWipe.ui @@ -0,0 +1,143 @@ + + + + + 5000 + 100 + 1 + 100 + + + + 360 + 0 + 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 + pixel-wipe-animation-time + + + + + + + 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 + pixel-wipe-pixel-size + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/resources/ui/gtk4/PixelWheel.ui b/resources/ui/gtk4/PixelWheel.ui new file mode 100644 index 0000000..ae51709 --- /dev/null +++ b/resources/ui/gtk4/PixelWheel.ui @@ -0,0 +1,163 @@ + + + + + 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 + + + + + Spoke Count + 0 + start + center + 1 + + + + + end + center + 1 + 0 + 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/resources/ui/gtk4/PixelWipe.ui b/resources/ui/gtk4/PixelWipe.ui new file mode 100644 index 0000000..c7fca0b --- /dev/null +++ b/resources/ui/gtk4/PixelWipe.ui @@ -0,0 +1,117 @@ + + + + + vertical + + + + + + none + 1 + + + + + 0 + + + + + Animation Time [ms] + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + + + 5000 + 100 + 1 + 100 + + + + + + + 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 b54d4e5..8426023 100644 --- a/schemas/org.gnome.shell.extensions.burn-my-windows.gschema.xml +++ b/schemas/org.gnome.shell.extensions.burn-my-windows.gschema.xml @@ -112,12 +112,75 @@ The noise of the effect. - + 10 Pixelate Pixel Size The size of the maximum pixelation. + + + + + + + false + Pixel Wipe Close Effect + Use the Pixel Wipe effect for window closing. + + + + false + Pixel Wipe Open Effect + Use the Pixel Wipe effect for window opening. + + + + 1000 + Pixel Wipe Animation Time + The time the Pixel Wipe effect takes. + + + + 10 + Pixel Wipe Pixel Size + The size of the maximum pixelation. + + + + + + + + false + Pixel Wheel Close Effect + Use the Pixel Wheel effect for window closing. + + + + false + Pixel Wheel Open Effect + Use the Pixel Wheel effect for window opening. + + + + 300 + Pixel Wheel Animation Time + The time the Pixel Wheel effect takes. + + + + 12 + Pixel Wheel Spoke Count + The number of sections in the wheel. + + + + 10 + Pixel Wheel Pixel Size + The size of the maximum pixelation. + + @@ -152,7 +215,7 @@ The Y scale of the effect. - + 10 Doom Pixel Size The size of the maximum pixelation. diff --git a/src/PixelWheel.js b/src/PixelWheel.js new file mode 100644 index 0000000..dcd3fb0 --- /dev/null +++ b/src/PixelWheel.js @@ -0,0 +1,102 @@ +////////////////////////////////////////////////////////////////////////////////////////// +// ) ( // +// ( /( ( ( ) ( ( ( ( )\ ) ( ( // +// )\()) ))\ )( ( ( )\ ) )\))( )\ ( (()/( ( )\))( ( // +// ((_)\ /((_|()\ )\ ) )\ '(()/( ((_)()((_) )\ ) ((_)))\((_)()\ )\ // +// | |(_|_))( ((_)_(_/( _((_)) )(_)) _(()((_|_)_(_/( _| |((_)(()((_|(_) // +// | '_ \ || | '_| ' \)) | ' \()| || | \ 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 simple effect pixelates the window texture and hides the pixels in a wheel-like // +// fashion. // +////////////////////////////////////////////////////////////////////////////////////////// + +// 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 PixelWheel = 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._uPixelSize = shader.get_uniform_location('uPixelSize'); + shader._uSpokeCount = shader.get_uniform_location('uSpokeCount'); + + // Write all uniform values at the start of each animation. + shader.connect('begin-animation', (shader, settings) => { + // clang-format off + shader.set_uniform_float(shader._uPixelSize, 1, [settings.get_double('pixel-wheel-pixel-size')]); + shader.set_uniform_float(shader._uSpokeCount, 1, [settings.get_int('pixel-wheel-spoke-count')]); + // 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 'pixel-wheel'; + } + + // 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 _('Pixel Wheel'); + } + + // -------------------------------------------------------------------- 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()}/PixelWheel.ui`); + + // Bind all properties. + dialog.bindAdjustment('pixel-wheel-animation-time'); + dialog.bindAdjustment('pixel-wheel-pixel-size'); + dialog.bindAdjustment('pixel-wheel-spoke-count'); + + // Finally, return the new settings page. + return dialog.getBuilder().get_object('pixel-wheel-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}; + } +} diff --git a/src/PixelWipe.js b/src/PixelWipe.js new file mode 100644 index 0000000..ae4237d --- /dev/null +++ b/src/PixelWipe.js @@ -0,0 +1,127 @@ +////////////////////////////////////////////////////////////////////////////////////////// +// ) ( // +// ( /( ( ( ) ( ( ( ( )\ ) ( ( // +// )\()) ))\ )( ( ( )\ ) )\))( )\ ( (()/( ( )\))( ( // +// ((_)\ /((_|()\ )\ ) )\ '(()/( ((_)()((_) )\ ) ((_)))\((_)()\ )\ // +// | |(_|_))( ((_)_(_/( _((_)) )(_)) _(()((_|_)_(_/( _| |((_)(()((_|(_) // +// | '_ \ || | '_| ' \)) | ' \()| || | \ 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 pixelates the window texture and hides the pixels radially, starting // +// from the pointer position. // +////////////////////////////////////////////////////////////////////////////////////////// + +// 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 PixelWipe = 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._uPixelSize = shader.get_uniform_location('uPixelSize'); + shader._uStartPos = shader.get_uniform_location('uStartPos'); + + // Write all uniform values at the start of each animation. + shader.connect('begin-animation', (shader, settings, forOpening, actor) => { + // Because the actor position may change after the begin-animation signal is + // called, we set the uDirection uniform during the update callback. + this._startPointerPos = global.get_pointer(); + this._actor = actor; + + // clang-format off + shader.set_uniform_float(shader._uPixelSize, 1, [settings.get_int('pixel-wipe-pixel-size')]); + // clang-format on + }); + + // We set the uDirection 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; + }); + }); + } + + // ---------------------------------------------------------------------------- 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 'pixel-wipe'; + } + + // 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 _('Pixel Wipe'); + } + + // -------------------------------------------------------------------- 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()}/PixelWipe.ui`); + + // Bind all properties. + dialog.bindAdjustment('pixel-wipe-animation-time'); + dialog.bindAdjustment('pixel-wipe-pixel-size'); + + // Finally, return the new settings page. + return dialog.getBuilder().get_object('pixel-wipe-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}; + } +} diff --git a/src/Pixelate.js b/src/Pixelate.js index 248f39a..368e58a 100644 --- a/src/Pixelate.js +++ b/src/Pixelate.js @@ -46,7 +46,7 @@ var Pixelate = class { shader.connect('begin-animation', (shader, settings) => { // clang-format off shader.set_uniform_float(shader._uNoise, 1, [settings.get_double('pixelate-noise')]); - shader.set_uniform_float(shader._uPixelSize, 1, [settings.get_double('pixelate-pixel-size')]); + shader.set_uniform_float(shader._uPixelSize, 1, [settings.get_int('pixelate-pixel-size')]); // clang-format on }); }); diff --git a/tests/generate-references.sh b/tests/generate-references.sh index 9810c6c..b5b1335 100755 --- a/tests/generate-references.sh +++ b/tests/generate-references.sh @@ -187,6 +187,8 @@ capture_effect "fire" capture_effect "hexagon" capture_effect "incinerate" capture_effect "pixelate" +capture_effect "pixel-wheel" +capture_effect "pixel-wipe" capture_effect "tv" capture_effect "wisps" diff --git a/tests/references/pixel-wheel-close-gnome-wayland-nested-32.png b/tests/references/pixel-wheel-close-gnome-wayland-nested-32.png new file mode 100644 index 0000000..cb6e4dc Binary files /dev/null and b/tests/references/pixel-wheel-close-gnome-wayland-nested-32.png differ diff --git a/tests/references/pixel-wheel-close-gnome-wayland-nested-33.png b/tests/references/pixel-wheel-close-gnome-wayland-nested-33.png new file mode 100644 index 0000000..04d4a60 Binary files /dev/null and b/tests/references/pixel-wheel-close-gnome-wayland-nested-33.png differ diff --git a/tests/references/pixel-wheel-close-gnome-wayland-nested-34.png b/tests/references/pixel-wheel-close-gnome-wayland-nested-34.png new file mode 100644 index 0000000..0487347 Binary files /dev/null and b/tests/references/pixel-wheel-close-gnome-wayland-nested-34.png differ diff --git a/tests/references/pixel-wheel-close-gnome-wayland-nested-35.png b/tests/references/pixel-wheel-close-gnome-wayland-nested-35.png new file mode 100644 index 0000000..b88cbf2 Binary files /dev/null and b/tests/references/pixel-wheel-close-gnome-wayland-nested-35.png differ diff --git a/tests/references/pixel-wheel-close-gnome-wayland-nested-36.png b/tests/references/pixel-wheel-close-gnome-wayland-nested-36.png new file mode 100644 index 0000000..b88cbf2 Binary files /dev/null and b/tests/references/pixel-wheel-close-gnome-wayland-nested-36.png differ diff --git a/tests/references/pixel-wheel-close-gnome-xsession-32.png b/tests/references/pixel-wheel-close-gnome-xsession-32.png new file mode 100644 index 0000000..2283bcc Binary files /dev/null and b/tests/references/pixel-wheel-close-gnome-xsession-32.png differ diff --git a/tests/references/pixel-wheel-close-gnome-xsession-33.png b/tests/references/pixel-wheel-close-gnome-xsession-33.png new file mode 100644 index 0000000..bdb2d5c Binary files /dev/null and b/tests/references/pixel-wheel-close-gnome-xsession-33.png differ diff --git a/tests/references/pixel-wheel-close-gnome-xsession-34.png b/tests/references/pixel-wheel-close-gnome-xsession-34.png new file mode 100644 index 0000000..b5043c5 Binary files /dev/null and b/tests/references/pixel-wheel-close-gnome-xsession-34.png differ diff --git a/tests/references/pixel-wheel-close-gnome-xsession-35.png b/tests/references/pixel-wheel-close-gnome-xsession-35.png new file mode 100644 index 0000000..db9c38e Binary files /dev/null and b/tests/references/pixel-wheel-close-gnome-xsession-35.png differ diff --git a/tests/references/pixel-wheel-close-gnome-xsession-36.png b/tests/references/pixel-wheel-close-gnome-xsession-36.png new file mode 100644 index 0000000..db9c38e Binary files /dev/null and b/tests/references/pixel-wheel-close-gnome-xsession-36.png differ diff --git a/tests/references/pixel-wheel-open-gnome-wayland-nested-32.png b/tests/references/pixel-wheel-open-gnome-wayland-nested-32.png new file mode 100644 index 0000000..cb6e4dc Binary files /dev/null and b/tests/references/pixel-wheel-open-gnome-wayland-nested-32.png differ diff --git a/tests/references/pixel-wheel-open-gnome-wayland-nested-33.png b/tests/references/pixel-wheel-open-gnome-wayland-nested-33.png new file mode 100644 index 0000000..04d4a60 Binary files /dev/null and b/tests/references/pixel-wheel-open-gnome-wayland-nested-33.png differ diff --git a/tests/references/pixel-wheel-open-gnome-wayland-nested-34.png b/tests/references/pixel-wheel-open-gnome-wayland-nested-34.png new file mode 100644 index 0000000..0487347 Binary files /dev/null and b/tests/references/pixel-wheel-open-gnome-wayland-nested-34.png differ diff --git a/tests/references/pixel-wheel-open-gnome-wayland-nested-35.png b/tests/references/pixel-wheel-open-gnome-wayland-nested-35.png new file mode 100644 index 0000000..b88cbf2 Binary files /dev/null and b/tests/references/pixel-wheel-open-gnome-wayland-nested-35.png differ diff --git a/tests/references/pixel-wheel-open-gnome-wayland-nested-36.png b/tests/references/pixel-wheel-open-gnome-wayland-nested-36.png new file mode 100644 index 0000000..b88cbf2 Binary files /dev/null and b/tests/references/pixel-wheel-open-gnome-wayland-nested-36.png differ diff --git a/tests/references/pixel-wheel-open-gnome-xsession-32.png b/tests/references/pixel-wheel-open-gnome-xsession-32.png new file mode 100644 index 0000000..2283bcc Binary files /dev/null and b/tests/references/pixel-wheel-open-gnome-xsession-32.png differ diff --git a/tests/references/pixel-wheel-open-gnome-xsession-33.png b/tests/references/pixel-wheel-open-gnome-xsession-33.png new file mode 100644 index 0000000..bdb2d5c Binary files /dev/null and b/tests/references/pixel-wheel-open-gnome-xsession-33.png differ diff --git a/tests/references/pixel-wheel-open-gnome-xsession-34.png b/tests/references/pixel-wheel-open-gnome-xsession-34.png new file mode 100644 index 0000000..b5043c5 Binary files /dev/null and b/tests/references/pixel-wheel-open-gnome-xsession-34.png differ diff --git a/tests/references/pixel-wheel-open-gnome-xsession-35.png b/tests/references/pixel-wheel-open-gnome-xsession-35.png new file mode 100644 index 0000000..db9c38e Binary files /dev/null and b/tests/references/pixel-wheel-open-gnome-xsession-35.png differ diff --git a/tests/references/pixel-wheel-open-gnome-xsession-36.png b/tests/references/pixel-wheel-open-gnome-xsession-36.png new file mode 100644 index 0000000..db9c38e Binary files /dev/null and b/tests/references/pixel-wheel-open-gnome-xsession-36.png differ diff --git a/tests/references/pixel-wipe-close-gnome-wayland-nested-32.png b/tests/references/pixel-wipe-close-gnome-wayland-nested-32.png new file mode 100644 index 0000000..ea35c3f Binary files /dev/null and b/tests/references/pixel-wipe-close-gnome-wayland-nested-32.png differ diff --git a/tests/references/pixel-wipe-close-gnome-wayland-nested-33.png b/tests/references/pixel-wipe-close-gnome-wayland-nested-33.png new file mode 100644 index 0000000..d6346be Binary files /dev/null and b/tests/references/pixel-wipe-close-gnome-wayland-nested-33.png differ diff --git a/tests/references/pixel-wipe-close-gnome-wayland-nested-34.png b/tests/references/pixel-wipe-close-gnome-wayland-nested-34.png new file mode 100644 index 0000000..fffda59 Binary files /dev/null and b/tests/references/pixel-wipe-close-gnome-wayland-nested-34.png differ diff --git a/tests/references/pixel-wipe-close-gnome-wayland-nested-35.png b/tests/references/pixel-wipe-close-gnome-wayland-nested-35.png new file mode 100644 index 0000000..2275dea Binary files /dev/null and b/tests/references/pixel-wipe-close-gnome-wayland-nested-35.png differ diff --git a/tests/references/pixel-wipe-close-gnome-wayland-nested-36.png b/tests/references/pixel-wipe-close-gnome-wayland-nested-36.png new file mode 100644 index 0000000..2275dea Binary files /dev/null and b/tests/references/pixel-wipe-close-gnome-wayland-nested-36.png differ diff --git a/tests/references/pixel-wipe-close-gnome-xsession-32.png b/tests/references/pixel-wipe-close-gnome-xsession-32.png new file mode 100644 index 0000000..be809a3 Binary files /dev/null and b/tests/references/pixel-wipe-close-gnome-xsession-32.png differ diff --git a/tests/references/pixel-wipe-close-gnome-xsession-33.png b/tests/references/pixel-wipe-close-gnome-xsession-33.png new file mode 100644 index 0000000..9f51114 Binary files /dev/null and b/tests/references/pixel-wipe-close-gnome-xsession-33.png differ diff --git a/tests/references/pixel-wipe-close-gnome-xsession-34.png b/tests/references/pixel-wipe-close-gnome-xsession-34.png new file mode 100644 index 0000000..64424bf Binary files /dev/null and b/tests/references/pixel-wipe-close-gnome-xsession-34.png differ diff --git a/tests/references/pixel-wipe-close-gnome-xsession-35.png b/tests/references/pixel-wipe-close-gnome-xsession-35.png new file mode 100644 index 0000000..888f659 Binary files /dev/null and b/tests/references/pixel-wipe-close-gnome-xsession-35.png differ diff --git a/tests/references/pixel-wipe-close-gnome-xsession-36.png b/tests/references/pixel-wipe-close-gnome-xsession-36.png new file mode 100644 index 0000000..888f659 Binary files /dev/null and b/tests/references/pixel-wipe-close-gnome-xsession-36.png differ diff --git a/tests/references/pixel-wipe-open-gnome-wayland-nested-32.png b/tests/references/pixel-wipe-open-gnome-wayland-nested-32.png new file mode 100644 index 0000000..df4e84d Binary files /dev/null and b/tests/references/pixel-wipe-open-gnome-wayland-nested-32.png differ diff --git a/tests/references/pixel-wipe-open-gnome-wayland-nested-33.png b/tests/references/pixel-wipe-open-gnome-wayland-nested-33.png new file mode 100644 index 0000000..8b83b6e Binary files /dev/null and b/tests/references/pixel-wipe-open-gnome-wayland-nested-33.png differ diff --git a/tests/references/pixel-wipe-open-gnome-wayland-nested-34.png b/tests/references/pixel-wipe-open-gnome-wayland-nested-34.png new file mode 100644 index 0000000..61bf2d6 Binary files /dev/null and b/tests/references/pixel-wipe-open-gnome-wayland-nested-34.png differ diff --git a/tests/references/pixel-wipe-open-gnome-wayland-nested-35.png b/tests/references/pixel-wipe-open-gnome-wayland-nested-35.png new file mode 100644 index 0000000..e178da6 Binary files /dev/null and b/tests/references/pixel-wipe-open-gnome-wayland-nested-35.png differ diff --git a/tests/references/pixel-wipe-open-gnome-wayland-nested-36.png b/tests/references/pixel-wipe-open-gnome-wayland-nested-36.png new file mode 100644 index 0000000..e178da6 Binary files /dev/null and b/tests/references/pixel-wipe-open-gnome-wayland-nested-36.png differ diff --git a/tests/references/pixel-wipe-open-gnome-xsession-32.png b/tests/references/pixel-wipe-open-gnome-xsession-32.png new file mode 100644 index 0000000..2b0ba36 Binary files /dev/null and b/tests/references/pixel-wipe-open-gnome-xsession-32.png differ diff --git a/tests/references/pixel-wipe-open-gnome-xsession-33.png b/tests/references/pixel-wipe-open-gnome-xsession-33.png new file mode 100644 index 0000000..81dc1db Binary files /dev/null and b/tests/references/pixel-wipe-open-gnome-xsession-33.png differ diff --git a/tests/references/pixel-wipe-open-gnome-xsession-34.png b/tests/references/pixel-wipe-open-gnome-xsession-34.png new file mode 100644 index 0000000..5d9242b Binary files /dev/null and b/tests/references/pixel-wipe-open-gnome-xsession-34.png differ diff --git a/tests/references/pixel-wipe-open-gnome-xsession-35.png b/tests/references/pixel-wipe-open-gnome-xsession-35.png new file mode 100644 index 0000000..fb229e2 Binary files /dev/null and b/tests/references/pixel-wipe-open-gnome-xsession-35.png differ diff --git a/tests/references/pixel-wipe-open-gnome-xsession-36.png b/tests/references/pixel-wipe-open-gnome-xsession-36.png new file mode 100644 index 0000000..fb229e2 Binary files /dev/null and b/tests/references/pixel-wipe-open-gnome-xsession-36.png differ diff --git a/tests/run-test.sh b/tests/run-test.sh index f3690f7..6b07aba 100755 --- a/tests/run-test.sh +++ b/tests/run-test.sh @@ -215,6 +215,8 @@ test_effect "fire" test_effect "hexagon" test_effect "incinerate" test_effect "pixelate" +test_effect "pixel-wheel" +test_effect "pixel-wipe" test_effect "tv" test_effect "wisps"