diff --git a/docs/how-to-create-new-effects.md b/docs/how-to-create-new-effects.md index 3296cfe..a2a1f30 100644 --- a/docs/how-to-create-new-effects.md +++ b/docs/how-to-create-new-effects.md @@ -121,7 +121,8 @@ var SimpleFade = class SimpleFade { // 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. the '*-close-effect'). + // effect is enabled currently (e.g. '*-close-effect'), and its animation time + // (e.g. '*-animation-time'). static getNick() { return 'simple-fade'; } @@ -148,24 +149,12 @@ var SimpleFade = class SimpleFade { return new Shader(settings); } - // This is also called from extension.js. It is used to tweak the ongoing transitions of + // This is also called from extension.js. It is used to tweak the ongoing transition of // the actor - usually windows are faded to transparency and scaled down slightly by - // GNOME Shell. Here, we modify this behavior as well as the transition duration. - static tweakTransitions(actor, settings) { - const animationTime = settings.get_int('simple-fade-animation-time'); - - const tweakTransition = (property, value) => { - const transition = actor.get_transition(property); - if (transition) { - transition.set_to(value); - transition.set_duration(animationTime); - } - }; - - // We re-target these transitions so that the window is neither scaled nor faded. - tweakTransition('opacity', 255); - tweakTransition('scale-x', 1); - tweakTransition('scale-y', 1); + // GNOME Shell. For each property, you can set a "from", "to", and a "mode". For this + // effect, windows should neither be scaled nor faded. + static getCloseTransition(actor, settings) { + return {'opacity': {to: 255}, 'scale-x': {to: 1.0}, 'scale-y': {to: 1.0}}; } } diff --git a/extension.js b/extension.js index 74909df..b4de8ae 100644 --- a/extension.js +++ b/extension.js @@ -66,6 +66,10 @@ class Extension { // Store a reference to the settings object. this._settings = ExtensionUtils.getSettings(); + // This will store an item of ALL_EFFECTS which was used the last time a window was + // closed. + this._effect = 0; + // We will monkey-patch these three methods. Let's store the original ones. this._origWindowRemoved = Workspace.prototype._windowRemoved; this._origDoRemoveWindow = Workspace.prototype._doRemoveWindow; @@ -87,7 +91,20 @@ class Extension { WindowPreview.prototype._deleteAll = function() { if (!this._closeRequested) { + + this.metaWindow.connect('unmanaged', () => { + const transitionConfig = extensionThis._effect.getCloseTransition( + this.window_container, extensionThis._settings); + extensionThis._tweakTransitions(this.window_container, transitionConfig); + }); + extensionThis._origDeleteAll.apply(this); + + // This is required, else WindowPreview's _restack() which is called by the + // "this.overlayEnabled = false", sometimes tries to access an already delete + // WindowPreview. + this._stackAbove = null; + this.overlayEnabled = false; } }; } @@ -175,13 +192,14 @@ class Extension { } // Choose a random effect. - const Effect = enabledEffects[Math.floor(Math.random() * enabledEffects.length)]; + this._effect = enabledEffects[Math.floor(Math.random() * enabledEffects.length)]; // The effect usually will choose to override the present transitions on the actor. - Effect.tweakTransitions(actor, this._settings); + const transitionConfig = this._effect.getCloseTransition(actor, this._settings); + this._tweakTransitions(actor, transitionConfig); // Add a cool shader to our window actor! - const shader = Effect.createShader(actor, this._settings); + const shader = this._effect.createShader(actor, this._settings); if (shader) { actor.add_effect(shader); @@ -255,6 +273,42 @@ class Extension { return false; } + + // This is used to tweak the ongoing transitions of a window actor. This is either the + // actual actor of the Meta.Window or a clone in the overview. Usually windows are faded + // to transparency and scaled down slightly by GNOME Shell. Here, we allow modifications + // to this behavior by the effects. + _tweakTransitions(actor, config) { + const duration = this._settings.get_int(this._effect.getNick() + '-animation-time'); + + for (const property in config) { + const from = config[property].from; + const to = config[property].to; + const mode = config[property].mode; + + const transition = actor.get_transition(property); + + if (transition) { + transition.set_duration(duration); + + if (to != undefined) transition.set_to(to); + if (from != undefined) transition.set_from(from); + if (mode != undefined) transition.set_progress_mode(mode); + + } else { + + if (from != undefined) actor[property] = from; + + if (to != undefined) { + actor.save_easing_state(); + actor.set_easing_duration(duration) + if (mode != undefined) actor.set_easing_mode(mode); + actor[property] = to; + actor.restore_easing_state(); + } + } + } + } } // This function is called once when the extension is loaded, not enabled. diff --git a/src/EnergizeA.js b/src/EnergizeA.js index b20be00..c1c0913 100644 --- a/src/EnergizeA.js +++ b/src/EnergizeA.js @@ -40,7 +40,8 @@ var EnergizeA = class EnergizeA { // 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. the '*-close-effect'). + // effect is enabled currently (e.g. '*-close-effect'), and its animation time + // (e.g. '*-animation-time'). static getNick() { return 'energize-a'; } @@ -80,24 +81,11 @@ var EnergizeA = class EnergizeA { return new Shader(settings); } - // This is also called from extension.js. It is used to tweak the ongoing transitions of + // This is also called from extension.js. It is used to tweak the ongoing transition of // the actor - usually windows are faded to transparency and scaled down slightly by - // GNOME Shell. Here, we modify this behavior as well as the transition duration. - static tweakTransitions(actor, settings) { - const animationTime = settings.get_int('energize-a-animation-time'); - - const tweakTransition = (property, value) => { - const transition = actor.get_transition(property); - if (transition) { - transition.set_to(value); - transition.set_duration(animationTime); - } - }; - - // We re-target these transitions so that the window is neither scaled nor faded. - tweakTransition('opacity', 255); - tweakTransition('scale-x', 1); - tweakTransition('scale-y', 1); + // GNOME Shell. For this effect, windows should neither be scaled nor faded. + static getCloseTransition(actor, settings) { + return {'opacity': {to: 255}, 'scale-x': {to: 1.0}, 'scale-y': {to: 1.0}}; } } diff --git a/src/EnergizeB.js b/src/EnergizeB.js index 0bf87d8..afb6365 100644 --- a/src/EnergizeB.js +++ b/src/EnergizeB.js @@ -40,7 +40,8 @@ var EnergizeB = class EnergizeB { // 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. the '*-close-effect'). + // effect is enabled currently (e.g. '*-close-effect'), and its animation time + // (e.g. '*-animation-time'). static getNick() { return 'energize-b'; } @@ -80,24 +81,11 @@ var EnergizeB = class EnergizeB { return new Shader(settings); } - // This is also called from extension.js. It is used to tweak the ongoing transitions of + // This is also called from extension.js. It is used to tweak the ongoing transition of // the actor - usually windows are faded to transparency and scaled down slightly by - // GNOME Shell. Here, we modify this behavior as well as the transition duration. - static tweakTransitions(actor, settings) { - const animationTime = settings.get_int('energize-b-animation-time'); - - const tweakTransition = (property, value) => { - const transition = actor.get_transition(property); - if (transition) { - transition.set_to(value); - transition.set_duration(animationTime); - } - }; - - // We re-target these transitions so that the window is neither scaled nor faded. - tweakTransition('opacity', 255); - tweakTransition('scale-x', 1); - tweakTransition('scale-y', 1); + // GNOME Shell. For this effect, windows should neither be scaled nor faded. + static getCloseTransition(actor, settings) { + return {'opacity': {to: 255}, 'scale-x': {to: 1.0}, 'scale-y': {to: 1.0}}; } } diff --git a/src/Fire.js b/src/Fire.js index 5060b5e..2cf1b44 100644 --- a/src/Fire.js +++ b/src/Fire.js @@ -44,7 +44,8 @@ var Fire = class Fire { // 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. the '*-close-effect'). + // effect is enabled currently (e.g. '*-close-effect'), and its animation time + // (e.g. '*-animation-time'). static getNick() { return 'fire'; } @@ -101,24 +102,11 @@ var Fire = class Fire { return new Shader(settings); } - // This is also called from extension.js. It is used to tweak the ongoing transitions of + // This is also called from extension.js. It is used to tweak the ongoing transition of // the actor - usually windows are faded to transparency and scaled down slightly by - // GNOME Shell. Here, we modify this behavior as well as the transition duration. - static tweakTransitions(actor, settings) { - const animationTime = settings.get_int('fire-animation-time'); - - const tweakTransition = (property, value) => { - const transition = actor.get_transition(property); - if (transition) { - transition.set_to(value); - transition.set_duration(animationTime); - } - }; - - // We re-target these transitions so that the window is neither scaled nor faded. - tweakTransition('opacity', 255); - tweakTransition('scale-x', 1); - tweakTransition('scale-y', 1); + // GNOME Shell. For this effect, windows should neither be scaled nor faded. + static getCloseTransition(actor, settings) { + return {'opacity': {to: 255}, 'scale-x': {to: 1.0}, 'scale-y': {to: 1.0}}; } // ----------------------------------------------------------------------- private stuff diff --git a/src/Matrix.js b/src/Matrix.js index 8d8ab66..9ae7dad 100644 --- a/src/Matrix.js +++ b/src/Matrix.js @@ -44,7 +44,8 @@ var Matrix = class Matrix { // 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. the '*-close-effect'). + // effect is enabled currently (e.g. '*-close-effect'), and its animation time + // (e.g. '*-animation-time'). static getNick() { return 'matrix'; } @@ -86,24 +87,11 @@ var Matrix = class Matrix { return new Shader(settings); } - // This is also called from extension.js. It is used to tweak the ongoing transitions of + // This is also called from extension.js. It is used to tweak the ongoing transition of // the actor - usually windows are faded to transparency and scaled down slightly by - // GNOME Shell. Here, we modify this behavior as well as the transition duration. - static tweakTransitions(actor, settings) { - const animationTime = settings.get_int('matrix-animation-time'); - - const tweakTransition = (property, value) => { - const transition = actor.get_transition(property); - if (transition) { - transition.set_to(value); - transition.set_duration(animationTime); - } - }; - - // We re-target these transitions so that the window is neither scaled nor faded. - tweakTransition('opacity', 255); - tweakTransition('scale-x', 1); - tweakTransition('scale-y', 1); + // GNOME Shell. For this effect, windows should neither be scaled nor faded. + static getCloseTransition(actor, settings) { + return {'opacity': {to: 255}, 'scale-x': {to: 1.0}, 'scale-y': {to: 1.0}}; } } diff --git a/src/TRexAttack.js b/src/TRexAttack.js index 2c57293..5c8a478 100644 --- a/src/TRexAttack.js +++ b/src/TRexAttack.js @@ -42,7 +42,8 @@ var TRexAttack = class TRexAttack { // 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. the '*-close-effect'). + // effect is enabled currently (e.g. '*-close-effect'), and its animation time + // (e.g. '*-animation-time'). static getNick() { return 'trex'; } @@ -84,26 +85,17 @@ var TRexAttack = class TRexAttack { return new Shader(settings); } - // This is also called from extension.js. It is used to tweak the ongoing transitions of + // This is also called from extension.js. It is used to tweak the ongoing transition of // the actor - usually windows are faded to transparency and scaled down slightly by - // GNOME Shell. Here, we modify this behavior as well as the transition duration. - static tweakTransitions(actor, settings) { - const animationTime = settings.get_int('trex-animation-time'); - - const tweakTransition = (property, value) => { - const transition = actor.get_transition(property); - if (transition) { - transition.set_to(value); - transition.set_duration(animationTime); - } - }; - - // For this effect, we slightly increase the window's scale as part of the warp - // effect. + // GNOME Shell. For this effect, we slightly increase the window's scale as part of the + // warp effect. + static getCloseTransition(actor, settings) { const warp = 0.5 * settings.get_double('claw-scratch-warp'); - tweakTransition('opacity', 255); - tweakTransition('scale-x', 1.0 + warp); - tweakTransition('scale-y', 1.0 + warp); + return { + 'opacity': {to: 255}, + 'scale-x': {to: 1.0 + warp}, + 'scale-y': {to: 1.0 + warp} + }; } } diff --git a/src/TVEffect.js b/src/TVEffect.js index 0d37efc..12bd8e9 100644 --- a/src/TVEffect.js +++ b/src/TVEffect.js @@ -42,7 +42,8 @@ var TVEffect = class TVEffect { // 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. the '*-close-effect'). + // effect is enabled currently (e.g. '*-close-effect'), and its animation time + // (e.g. '*-animation-time'). static getNick() { return 'tv'; } @@ -81,24 +82,11 @@ var TVEffect = class TVEffect { return new Shader(settings); } - // This is also called from extension.js. It is used to tweak the ongoing transitions of + // This is also called from extension.js. It is used to tweak the ongoing transition of // the actor - usually windows are faded to transparency and scaled down slightly by - // GNOME Shell. Here, we modify this behavior as well as the transition duration. - static tweakTransitions(actor, settings) { - const animationTime = settings.get_int('tv-animation-time'); - - const tweakTransition = (property, value) => { - const transition = actor.get_transition(property); - if (transition) { - transition.set_to(value); - transition.set_duration(animationTime); - } - }; - - // For this effect, we scale the window only vertically. - tweakTransition('opacity', 255); - tweakTransition('scale-x', 1); - tweakTransition('scale-y', 0.5); + // GNOME Shell. For this effect, windows are scaled down vertically. + static getCloseTransition(actor, settings) { + return {'opacity': {to: 255}, 'scale-x': {to: 1.0}, 'scale-y': {to: 0.5}}; } } diff --git a/src/Wisps.js b/src/Wisps.js index e73b29a..87d6e2a 100644 --- a/src/Wisps.js +++ b/src/Wisps.js @@ -27,9 +27,10 @@ const utils = Me.imports.src.utils; // The shader class for this effect is registered further down in this file. let Shader = null; -// The effect class is completely static. It 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. +// 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'). var Wisps = class Wisps { // ---------------------------------------------------------------------------- metadata @@ -80,25 +81,11 @@ var Wisps = class Wisps { return new Shader(settings); } - // This is also called from extension.js. It is used to tweak the ongoing transitions of + // This is also called from extension.js. It is used to tweak the ongoing transition of // the actor - usually windows are faded to transparency and scaled down slightly by - // GNOME Shell. Here, we modify this behavior as well as the transition duration. - static tweakTransitions(actor, settings) { - const animationTime = settings.get_int('wisps-animation-time'); - - const tweakTransition = (property, value) => { - const transition = actor.get_transition(property); - if (transition) { - transition.set_to(value); - transition.set_duration(animationTime); - } - }; - - // We re-target these transitions so that the window is not faded but scaled down a - // tiny bit. - tweakTransition('opacity', 255); - tweakTransition('scale-x', 0.9); - tweakTransition('scale-y', 0.9); + // GNOME Shell. For this effect, windows should be scaled down slightly but not faded. + static getCloseTransition(actor, settings) { + return {'opacity': {to: 255}, 'scale-x': {to: 0.9}, 'scale-y': {to: 0.9}}; } }