summaryrefslogtreecommitdiff
path: root/raveos-theme/gnome/theme-data/extensions/installed/burn-my-windows@schneegans.github.com/extension.js
diff options
context:
space:
mode:
authorAlexanderCurl <alexc@alexc.hu>2026-04-18 17:46:06 +0100
committerAlexanderCurl <alexc@alexc.hu>2026-04-18 17:46:06 +0100
commit70ca3fef77ee8bdc6e3ac28589a6fa08c024cc69 (patch)
treeab1123d4067c1b086dd6faa7ee4ea643236b565a /raveos-theme/gnome/theme-data/extensions/installed/burn-my-windows@schneegans.github.com/extension.js
parent5d94c0a7d44a2255b81815a52a7056a94a39842d (diff)
downloadRaveOS-PKGBUILD-70ca3fef77ee8bdc6e3ac28589a6fa08c024cc69.tar.gz
RaveOS-PKGBUILD-70ca3fef77ee8bdc6e3ac28589a6fa08c024cc69.zip
Replaced file structures for themes in the correct format
Diffstat (limited to 'raveos-theme/gnome/theme-data/extensions/installed/burn-my-windows@schneegans.github.com/extension.js')
-rw-r--r--raveos-theme/gnome/theme-data/extensions/installed/burn-my-windows@schneegans.github.com/extension.js631
1 files changed, 0 insertions, 631 deletions
diff --git a/raveos-theme/gnome/theme-data/extensions/installed/burn-my-windows@schneegans.github.com/extension.js b/raveos-theme/gnome/theme-data/extensions/installed/burn-my-windows@schneegans.github.com/extension.js
deleted file mode 100644
index cff39d8..0000000
--- a/raveos-theme/gnome/theme-data/extensions/installed/burn-my-windows@schneegans.github.com/extension.js
+++ /dev/null
@@ -1,631 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////////////////
-// ) ( //
-// ( /( ( ( ) ( ( ( ( )\ ) ( ( //
-// )\()) ))\ )( ( ( )\ ) )\))( )\ ( (()/( ( )\))( ( //
-// ((_)\ /((_|()\ )\ ) )\ '(()/( ((_)()((_) )\ ) ((_)))\((_)()\ )\ //
-// | |(_|_))( ((_)_(_/( _((_)) )(_)) _(()((_|_)_(_/( _| |((_)(()((_|(_) //
-// | '_ \ || | '_| ' \)) | ' \()| || | \ V V / | ' \)) _` / _ \ V V (_-< //
-// |_.__/\_,_|_| |_||_| |_|_|_| \_, | \_/\_/|_|_||_|\__,_\___/\_/\_//__/ //
-// |__/ //
-//////////////////////////////////////////////////////////////////////////////////////////
-
-// SPDX-FileCopyrightText: Simon Schneegans <code@simonschneegans.de>
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-'use strict';
-
-import Gio from 'gi://Gio';
-import Meta from 'gi://Meta';
-
-import {fromVersion26} from './src/migrate.js';
-import {ProfileManager} from './src/ProfileManager.js';
-import {WindowPicker} from './src/WindowPicker.js';
-import * as utils from './src/utils.js';
-
-import Apparition from './src/effects/Apparition.js';
-import AuraGlow from './src/effects/AuraGlow.js';
-import BrokenGlass from './src/effects/BrokenGlass.js';
-import Doom from './src/effects/Doom.js';
-import EnergizeA from './src/effects/EnergizeA.js';
-import EnergizeB from './src/effects/EnergizeB.js';
-import Fire from './src/effects/Fire.js';
-import Focus from './src/effects/Focus.js';
-import Glide from './src/effects/Glide.js';
-import Glitch from './src/effects/Glitch.js';
-import Hexagon from './src/effects/Hexagon.js';
-import Incinerate from './src/effects/Incinerate.js';
-import Matrix from './src/effects/Matrix.js';
-import Mushroom from './src/effects/Mushroom.js';
-import PaintBrush from './src/effects/PaintBrush.js';
-import Pixelate from './src/effects/Pixelate.js';
-import PixelWheel from './src/effects/PixelWheel.js';
-import PixelWipe from './src/effects/PixelWipe.js';
-import Portal from './src/effects/Portal.js';
-import RGBWarp from './src/effects/RGBWarp.js';
-import SnapOfDisintegration from './src/effects/SnapOfDisintegration.js';
-import TeamRocket from './src/effects/TeamRocket.js';
-import TRexAttack from './src/effects/TRexAttack.js';
-import TVEffect from './src/effects/TVEffect.js';
-import TVGlitch from './src/effects/TVGlitch.js';
-import Wisps from './src/effects/Wisps.js';
-
-import * as Main from 'resource:///org/gnome/shell/ui/main.js';
-import {Workspace} from 'resource:///org/gnome/shell/ui/workspace.js';
-import {WindowPreview} from 'resource:///org/gnome/shell/ui/windowPreview.js';
-import {Extension} from 'resource:///org/gnome/shell/extensions/extension.js';
-
-
-//////////////////////////////////////////////////////////////////////////////////////////
-// This extensions modifies the window-close and window-open animations with all kinds //
-// of effects. The effects are implemented using GLSL shaders which are applied to the //
-// window's Clutter.Actor. The extension is actually very simple, much of the //
-// complexity comes from the fact that GNOME Shell usually does not show an animation //
-// when a window is closed in the overview. Several methods need to be monkey-patched //
-// to get this working. For more details, read the other comments in this file... //
-//////////////////////////////////////////////////////////////////////////////////////////
-
-export default class BurnMyWindows extends Extension {
-
- // ------------------------------------------------------------------------ public stuff
-
- // This function could be called after the extension is enabled, which could be done
- // from GNOME Tweaks, when you log in or when the screen is unlocked.
- enable() {
-
- // New effects must be registered here and in prefs.js.
- this._ALL_EFFECTS = [
- new Apparition(), new AuraGlow(), new BrokenGlass(), new Doom(),
- new EnergizeA(), new EnergizeB(), new Fire(), new Focus(),
- new Glide(), new Glitch(), new Hexagon(), new Incinerate(),
- new Matrix(), new PaintBrush(), new Pixelate(), new PixelWheel(),
- new PixelWipe(), new Portal(), new RGBWarp(), new SnapOfDisintegration(),
- new TeamRocket(), new TRexAttack(), new TVEffect(), new TVGlitch(),
- new Wisps(), new Mushroom()
- ];
-
- // Load all of our resources.
- this._resources =
- Gio.Resource.load(this.path + '/resources/burn-my-windows.gresource');
- Gio.resources_register(this._resources);
-
- // Store a reference to the settings object.
- this._settings = this.getSettings();
-
- // Now we check whether the extension settings need to be migrated from a previous
- // version. If this is the case, we defer the profile loading until this is finished.
- const lastVersion = this._settings.get_int('last-extension-version');
- if (lastVersion < this.metadata.version) {
- if (lastVersion <= 26) {
- // If the profile migration fails for some reason, the callback will create a
- // default profile instead.
- fromVersion26().finally(() => {
- this._loadProfiles();
- this._settings.set_int('last-extension-version', this.metadata.version);
- });
- } else {
- this._loadProfiles();
- }
-
- } else {
- this._loadProfiles();
- }
-
- // We reload all effect profiles whenever the currently edited profile in the
- // preferences dialog changes. This is most likely a bit too often, but it will also
- // happen whenever a new profile is created and whenever an old profile is deleted.
- this._settings.connect('changed::active-profile', () => {
- this._loadProfiles();
- });
-
- // This is used to get the desktop's color scheme.
- this._shellSettings = new Gio.Settings({schema: 'org.gnome.desktop.interface'});
-
- // Enable the window-picking D-Bus API for the preferences dialog.
- this._windowPicker = new WindowPicker();
- this._windowPicker.export();
-
- // We will use extensionThis to refer to the extension inside the patched methods.
- const extensionThis = this;
-
- // This is used to get the battery state.
- const UPowerProxy = Gio.DBusProxy.makeProxyWrapper(
- utils.getStringResource('/interfaces/org.freedesktop.UPower.xml'));
- this._upowerProxy = new UPowerProxy(Gio.DBus.system, 'org.freedesktop.UPower',
- '/org/freedesktop/UPower');
-
- // This is used to get the current power profile.
- try {
- const PowerProfilesProxy = Gio.DBusProxy.makeProxyWrapper(
- utils.getStringResource('/interfaces/net.hadess.PowerProfiles.xml'));
- this._powerProfilesProxy = new PowerProfilesProxy(
- Gio.DBus.system, 'net.hadess.PowerProfiles', '/net/hadess/PowerProfiles');
- } catch (e) {
- // Maybe the service is masked...
- }
-
- // We will monkey-patch these methods. Let's store the original ones.
- this._origShouldAnimateActor = Main.wm._shouldAnimateActor;
- this._origWaitForOverviewToHide = Main.wm._waitForOverviewToHide;
- this._origAddWindowClone = Workspace.prototype._addWindowClone;
- this._origWindowRemoved = Workspace.prototype._windowRemoved;
- this._origDoRemoveWindow = Workspace.prototype._doRemoveWindow;
-
- // ------------------------------- patching the window animations outside the overview
-
- // If a window is created, the transitions are set up in the async _mapWindow() of the
- // WindowManager:
- // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/windowManager.js#L1436
- // AFAIK, overriding this method is not possible as it's called by a signal to which
- // it is bound via the bind() method. To tweak the async transition anyways, we
- // override the actors ease() method once. We do this in _shouldAnimateActor() which
- // is called right before the ease() in _mapWindow:
- // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/windowManager.js#L1465
-
- // The same trick is done for the window-close animation. This is set up in a similar
- // fashion in the WindowManager's _destroyWindow():
- // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/windowManager.js#L1525
- // Here is _shouldAnimateActor() also called right before. So we use it again to
- // monkey-patch the window actor's ease() once.
-
- // We override WindowManager._shouldAnimateActor() also for another purpose: Usually,
- // it returns false when we are in the overview. This prevents the window animations
- // there. To enable animations in the overview, we check inside the method whether it
- // was called by either _mapWindow or _destroyWindow. If so, we return true. Let's see
- // if this breaks stuff left and right...
- Main.wm._shouldAnimateActor = function(actor, types) {
- const stack = (new Error()).stack;
- const forClosing = stack.includes('_destroyWindow@');
- const forOpening = stack.includes('_mapWindow@');
-
- // This is also called in other cases, for instance when minimizing windows. We are
- // only interested in window opening and window closing for now.
- if (forClosing || forOpening) {
-
- // If there is an applicable effect profile, we intercept the ease() method to
- // setup our own effect.
- const chosenEffect = extensionThis._chooseEffect(actor, forOpening);
-
- if (chosenEffect) {
- // Store the original ease() method of the actor.
- const orig = actor.ease;
-
- // Now intercept the next call to actor.ease().
- actor.ease = function(...params) {
- // There is a really weird issue in GNOME Shell 44: A few non-GTK windows are
- // resized directly after they are mapped on X11. This happens for instance
- // for keepassxc after it was closed in the maximized state. As the
- // _mapWindow() method is called asynchronously, the window is not yet visible
- // when the resize happens. Hence, our ease-override is called for the resize
- // animation instead of the window-open or window-close animation. This is not
- // what we want. So we check again whether the ease() call is for the
- // window-open or window-close animation. If not, we just call the original
- // ease() method. See also:
- // https://github.com/Schneegans/Burn-My-Windows/issues/335
- const stack = (new Error()).stack;
- const forClosing = stack.includes('_destroyWindow@');
- const forOpening = stack.includes('_mapWindow@');
-
- if (forClosing || forOpening) {
- // Quickly restore the original behavior. Nobody noticed, I guess :D
- actor.ease = orig;
-
- // And then create the effect!
- extensionThis._setupEffect(actor, forOpening, chosenEffect.effect,
- chosenEffect.profile);
- } else {
- orig.apply(this, params);
- }
- };
-
- return true;
- }
- }
-
- return extensionThis._origShouldAnimateActor.apply(this, [actor, types]);
- };
-
- // Make sure to remove any effects if requested by the window manager.
- this._killEffectsSignal =
- global.window_manager.connect('kill-window-effects', (wm, actor) => {
- const shader = actor.get_effect('burn-my-windows-effect');
- if (shader) {
- shader.endAnimation();
- }
- });
-
-
- // --------------------------------------------- fix window animations in the overview
-
- // Some of the effects require that the window's actor is enlarged to provide a bigger
- // canvas to draw the effects. Outside the overview we can simply increase the scale
- // of the actor. However, if we are in the overview, we have to enlarge the clone of
- // the window as well.
- Workspace.prototype._addWindowClone = function(...params) {
- const clone = extensionThis._origAddWindowClone.apply(this, params);
- const container = clone.window_container;
- const realWindow = params[0].get_compositor_private();
-
- // Store the overview clone as temporary members of the real window actor. When we
- // set up the effect, we will check for the existence of these and enlarge the clone
- // as needed.
- realWindow._bmwOverviewClone = clone;
- realWindow._bmwOverviewCloneContainer = container;
-
- // Remove the temporary members again once the clone is deleted.
- container.connect('destroy', () => {
- delete realWindow._bmwOverviewClone;
- delete realWindow._bmwOverviewCloneContainer;
- });
-
- return clone;
- };
-
- // Usually, windows are faded in after the overview is completely hidden. We enable
- // window-open animations by not waiting for this.
- Main.wm._waitForOverviewToHide = async function() {
- return Promise.resolve();
- };
-
- // These three method overrides are mega-hacky! Usually, windows are not faded when
- // closed from the overview (why?). With these overrides we make sure that they are
- // actually faded out. To do this, _windowRemoved and _doRemoveWindow now check
- // whether there is a transition ongoing (via extensionThis._shouldDestroy). If that's
- // the case, these methods do nothing.
- // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/workspace.js#L1258
- Workspace.prototype._windowRemoved = function(ws, metaWin) {
- if (extensionThis._shouldDestroy(this, metaWin)) {
- extensionThis._origWindowRemoved.apply(this, [ws, metaWin]);
- }
- };
-
- // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/workspace.js#L1137
- Workspace.prototype._doRemoveWindow = function(metaWin) {
- if (extensionThis._shouldDestroy(this, metaWin)) {
- extensionThis._origDoRemoveWindow.apply(this, [metaWin]);
- }
- };
-
- // With the code below, we hide the window-overlay (icon, label, close button) in the
- // overview once the close-animation is running.
-
- // We will monkey-patch these methods.
- this._origDeleteAll = WindowPreview.prototype._deleteAll;
- this._origRestack = WindowPreview.prototype._restack;
- this._origInit = WindowPreview.prototype._init;
-
- // Whenever a WindowPreview is created, we connect to the referenced Meta.Window's
- // 'unmanaged' signal to hide the overlay.
- WindowPreview.prototype._init = function(...params) {
- extensionThis._origInit.apply(this, params);
-
- // Hide the window's icon, name, and close button.
- const connectionID = this.metaWindow.connect('unmanaged', () => {
- if (this.window_container) {
- this.overlayEnabled = false;
- this._icon.visible = false;
- }
- });
-
- // Make sure to not call the callback above if the Meta.Window was not unmanaged
- // before leaving the overview.
- this.connect('destroy', () => {
- this.metaWindow.disconnect(connectionID);
- });
- };
-
- // The _deleteAll is called when the user clicks the X in the overview. We should
- // not attempt to close windows twice. Due to the animation in the overview, the
- // close button can be clicked twice which normally would lead to a crash.
- WindowPreview.prototype._deleteAll = function() {
- if (!this._closeRequested) {
- 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.
- WindowPreview.prototype._restack = function() {
- if (!this._closeRequested) {
- extensionThis._origRestack.apply(this);
- }
- };
- }
-
- // This function could be called after the extension is uninstalled, disabled in GNOME
- // Tweaks, when you log out or when the screen locks.
- disable() {
-
- // Free all effect resources.
- this._ALL_EFFECTS = [];
-
- // Unregister our resources.
- Gio.resources_unregister(this._resources);
-
- // Disable the window-picking D-Bus API.
- this._windowPicker.unexport();
-
- global.window_manager.disconnect(this._killEffectsSignal);
-
- // Restore the original window-open and window-close animations.
- Workspace.prototype._addWindowClone = this._origAddWindowClone;
- Workspace.prototype._windowRemoved = this._origWindowRemoved;
- Workspace.prototype._doRemoveWindow = this._origDoRemoveWindow;
- Main.wm._shouldAnimateActor = this._origShouldAnimateActor;
- Main.wm._waitForOverviewToHide = this._origWaitForOverviewToHide;
-
- WindowPreview.prototype._deleteAll = this._origDeleteAll;
- WindowPreview.prototype._restack = this._origRestack;
- WindowPreview.prototype._init = this._origInit;
-
- this._settings = null;
- }
-
- // ----------------------------------------------------------------------- private stuff
-
- // This loads all effect profiles and assigns a priority to each profile. Whenever a
- // window is opened or closed, the matching effect profile with the highest priority
- // will be chosen.
- // This method is called whenever the currently edited profile in the/ preferences
- // dialog changes. This is most likely a bit too often, but it will also happen whenever
- // a new profile is created and whenever an old profile is deleted.
- _loadProfiles() {
-
- // Get all currently available profiles.
- const profileManager = new ProfileManager(this.metadata);
- this._profiles = profileManager.getProfiles();
-
- // Whenever the properties of a profile is changed in the settings, we may have to
- // resort all profiles according to their priority.
- const updatePriority = (p) => {
- p.priority = profileManager.getProfilePriority(p.settings);
- this._profiles.sort((a, b) => b.priority - a.priority);
- };
-
- // For each profile, assign an initial priority and update the priority whenever a
- // related setting changes.
- this._profiles.forEach(p => {
- p.priority = profileManager.getProfilePriority(p.settings);
- p.settings.connect('changed::profile-app', () => updatePriority(p));
- p.settings.connect('changed::profile-animation-type', () => updatePriority(p));
- p.settings.connect('changed::profile-window-type', () => updatePriority(p));
- p.settings.connect('changed::profile-color-scheme', () => updatePriority(p));
- p.settings.connect('changed::profile-power-mode', () => updatePriority(p));
- p.settings.connect('changed::profile-power-profile', () => updatePriority(p));
- p.settings.connect('changed::profile-high-priority', () => updatePriority(p));
- });
-
- // Sort all profiles initially according to their initial priority.
- this._profiles.sort((a, b) => b.priority - a.priority);
- }
-
- // This method selects an effect profile matching the current circumstances. Then a
- // random effect from its enabled effects will be selected. It returns null if no
- // profile is currently applicable.
- _chooseEffect(actor, forOpening) {
-
- // For now, we only add effects to normal windows and dialog windows.
- const isNormalWindow = actor.meta_window.window_type == Meta.WindowType.NORMAL;
- const isDialogWindow =
- actor.meta_window.window_type == Meta.WindowType.MODAL_DIALOG ||
- actor.meta_window.window_type == Meta.WindowType.DIALOG;
-
- if (!isNormalWindow && !isDialogWindow) {
- return null;
- }
-
- // ----------------------------------------------- choose a profile and then an effect
-
- // Usually, we use the effect profile with the highest priority which matches the
- // current circumstances. From this profile, we choose a random effect. However, if an
- // effect is to be previewed, we choose the currently edited profile regardless of the
- // circumstances.
- let profile = null;
- let effect = null;
-
- // Hence, we first check if an effect is to be previewed.
- const previewNick = this._settings.get_string('preview-effect');
-
- if (previewNick != '') {
- const activeProfile = this._settings.get_string('active-profile');
- effect =
- this._ALL_EFFECTS.find(effect => effect.constructor.getNick() == previewNick);
- profile = this._profiles.find(p => p.path == activeProfile);
-
- // Only preview the effect until the preview window is closed.
- if (!profile || !forOpening) {
- this._settings.set_string('preview-effect', '');
- }
- }
- // If no effect is previewed, we use the effect profile with the highest priority
- // which matches the current circumstances. From this profile, we choose a random
- // effect.
- else {
-
- // These numbers match the indices in the Gtk.StringLists defined in the UI files
- // (e.g. resources/ui/adw/prefs.ui).
- const animationType = forOpening ? 1 : 2;
- const windowType = isNormalWindow ? 1 : 2;
- const powerMode = this._upowerProxy.OnBattery ? 1 : 2;
-
- // Get the first profile whose constraints match the circumstances. The list is
- // sorted by priority, so we are good to take the first match.
- profile = this._profiles.find(p => {
- const profileApp = p.settings.get_string('profile-app');
- const profileAnimationType = p.settings.get_int('profile-animation-type');
- const profileWindowType = p.settings.get_int('profile-window-type');
- const profilePowerMode = p.settings.get_int('profile-power-mode');
- const profileColorScheme = p.settings.get_int('profile-color-scheme');
- const profilePowerProfile = p.settings.get_int('profile-power-profile');
-
- // First we check whether the animation type, window type, and power mode are
- // matching.
- let matches =
- (profileAnimationType == 0 || profileAnimationType == animationType) &&
- (profileWindowType == 0 || profileWindowType == windowType) &&
- (profilePowerMode == 0 || profilePowerMode == powerMode);
-
- // If that was the case, we also check the application name.
- if (matches && profileApp != '') {
- const wmClass = actor.meta_window.get_wm_class();
-
- if (wmClass) {
- const app = wmClass.toLowerCase();
-
- // Split app names at |, remove any whitespace, and transform to lower case.
- const profileApps =
- profileApp.split('|').map(item => item.trim().toLowerCase());
- matches = profileApps.includes(app);
- } else {
- matches = false;
- }
- }
-
- // If the profile is still matching, we also check the color scheme.
- if (matches && profileColorScheme != 0) {
- const colorScheme = this._shellSettings.get_string('color-scheme');
- matches &= (profileColorScheme == 1 && colorScheme == 'default') ||
- (profileColorScheme == 2 && colorScheme == 'prefer-dark');
- }
-
- // Finally, we may also have to check the power profile.
- if (matches && profilePowerProfile != 0 && this._powerProfilesProxy) {
- const powerProfile = this._powerProfilesProxy.ActiveProfile;
-
- // To understand the numbers, please refer to the indices in the Gtk.StringList
- // of the profile-power-profile Adw.ComboRow in resources/ui/adw/prefs.ui.
- if (powerProfile == 'power-saver') {
- matches &= profilePowerProfile == 1 || profilePowerProfile == 4;
- } else if (powerProfile == 'balanced') {
- matches &= profilePowerProfile == 2 || profilePowerProfile == 4 ||
- profilePowerProfile == 5;
- } else {
- matches &= profilePowerProfile == 3 || profilePowerProfile == 5;
- }
- }
-
- return matches;
- });
-
- // If we found a matching profile, choose a random effect from it.
- if (profile) {
-
- // Create a list of all enabled effects of this profile.
- const enabled = this._ALL_EFFECTS.filter(effect => {
- return profile.settings.get_boolean(
- `${effect.constructor.getNick()}-enable-effect`);
- });
-
- // And then choose a random effect.
- if (enabled.length > 0) {
- effect = enabled[Math.floor(Math.random() * enabled.length)];
- }
- }
- }
-
- // If nothing was enabled, we have to do nothing :)
- if (!effect || !profile) {
- return null;
- }
-
- return {effect: effect, profile: profile};
- }
-
- // This method adds the given effect using the settings from the given profile to the
- // given actor.
- _setupEffect(actor, forOpening, effect, profile) {
-
- // There is the weird case where an animation is already ongoing. This happens when a
- // window is closed which has been created before the session was started (e.g. when
- // GNOME Shell has been restarted in the meantime).
- const oldShader = actor.get_effect('burn-my-windows-effect');
- if (oldShader) {
- oldShader.endAnimation();
- }
-
- // If we are currently performing integration test, all animations are set to a fixed
- // duration and show a fixed frame from the middle of the animation.
- const testMode = this._settings.get_boolean('test-mode');
-
- // The following is used to tweak the ongoing transitions of a window actor. Usually
- // 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.constructor.getActorScale(profile.settings, forOpening, actor);
-
- // All scaling is relative to the window's center.
- actor.set_pivot_point(0.5, 0.5);
- actor.opacity = 255;
- actor.scale_x = actorScale.x;
- actor.scale_y = actorScale.y;
-
- // If we are in the overview, we have to enlarge the window's clone as well. We also
- // disable the clone's overlay (e.g. its icon, name, and close button) during the
- // animation.
- if (actor._bmwOverviewClone) {
- actor._bmwOverviewClone.overlayEnabled = false;
- actor._bmwOverviewCloneContainer.set_pivot_point(0.5, 0.5);
- actor._bmwOverviewCloneContainer.scale_x = actorScale.x;
- actor._bmwOverviewCloneContainer.scale_y = actorScale.y;
- }
-
- // Now add a cool shader to our window actor!
- const shader = effect.shaderFactory.getShader();
- actor.add_effect_with_name('burn-my-windows-effect', shader);
-
- // At the end of the animation, we restore the scale of the overview clone (if any)
- // and call the methods which would have been called by the original ease() calls at
- // the end of the standard fade-in animation.
- const endID = shader.connect('end-animation', () => {
- shader.disconnect(endID);
-
- if (actor._bmwOverviewClone) {
- actor._bmwOverviewClone.overlayEnabled = true;
- actor._bmwOverviewCloneContainer.scale_x = 1.0;
- actor._bmwOverviewCloneContainer.scale_y = 1.0;
- }
-
- // Restore the original scale of the window actor.
- actor.scale_x = 1.0;
- actor.scale_y = 1.0;
-
- // Remove the shader and mark it being re-usable for future animations.
- actor.remove_effect(shader);
- shader.returnToFactory();
-
- // Finally, once the animation is done or interrupted, we call the methods which
- // should have been called by the original ease() methods.
- // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/windowManager.js#L1487
- // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/windowManager.js#L1558.
- if (forOpening) {
- Main.wm._mapWindowDone(global.window_manager, actor);
- } else {
- Main.wm._destroyWindowDone(global.window_manager, actor);
- }
- });
-
- // To make things deterministic during testing, we set the effect duration to 8
- // seconds.
- const duration = testMode ?
- 8000 :
- profile.settings.get_int(effect.constructor.getNick() + '-animation-time');
-
- // Finally start the animation!
- shader.beginAnimation(profile.settings, forOpening, testMode, duration, actor);
- }
-
- // This is required to enable window-close animations in the overview. See the comment
- // for Workspace.prototype._windowRemoved above for an explanation.
- _shouldDestroy(workspace, metaWindow) {
- const index = workspace._lookupIndex(metaWindow);
- if (index == -1) {
- return true;
- }
-
- const actor = workspace._windows[index]._windowActor;
- const shader = actor.get_effect('burn-my-windows-effect');
-
- return shader == null;
- }
-}