From ba79b5b611209232eb7912493a548209c2e712b5 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Mon, 24 Jan 2022 20:34:50 +0100 Subject: [PATCH 001/168] :tada: Make it possible to select window open effects --- prefs.js | 26 +++++++ resources/ui/gtk3/prefs.ui | 67 ++++++++++++++++++- resources/ui/gtk4/prefs.ui | 47 ++++++++++++- ...ell.extensions.burn-my-windows.gschema.xml | 54 +++++++++++++++ 4 files changed, 192 insertions(+), 2 deletions(-) diff --git a/prefs.js b/prefs.js index 2182911..83f14e7 100644 --- a/prefs.js +++ b/prefs.js @@ -138,6 +138,28 @@ var PreferencesDialog = class PreferencesDialog { // clang-format on } + // Populate the open-effects drop-down menu. + { + const menu = this._builder.get_object('open-effect-menu'); + const group = Gio.SimpleActionGroup.new(); + window.insert_action_group('open-effects', group); + + ALL_EFFECTS.forEach(Effect => { + const [minMajor, minMinor] = Effect.getMinShellVersion(); + if (utils.shellVersionIsAtLeast(minMajor, minMinor)) { + const nick = Effect.getNick(); + const label = Effect.getLabel(); + const actionName = nick + '-open-effect'; + const fullName = 'open-effects.' + actionName; + + const action = this._settings.create_action(actionName); + group.add_action(action); + + menu.append_item(Gio.MenuItem.new(label, fullName)); + } + }); + } + // Populate the close-effects drop-down menu. { const menu = this._builder.get_object('close-effect-menu'); @@ -299,8 +321,12 @@ var PreferencesDialog = class PreferencesDialog { this._button.connect('clicked', () => { // Set the to-be-previewed effect. + dialog.getSettings().set_string('open-preview-effect', Effect.getNick()); dialog.getSettings().set_string('close-preview-effect', Effect.getNick()); + // Make sure that the window.show() firther below "sees" this change. + Gio.Settings.sync(); + // Create the preview-window. const window = new Gtk.Window({ title: `Preview for ${Effect.getLabel()}`, diff --git a/resources/ui/gtk3/prefs.ui b/resources/ui/gtk3/prefs.ui index 8b70434..708d1f5 100644 --- a/resources/ui/gtk3/prefs.ui +++ b/resources/ui/gtk3/prefs.ui @@ -3,6 +3,7 @@ + main-menu @@ -68,6 +69,70 @@ none + + + 10 + 10 + 10 + 10 + 0 + + + 8 + + + vertical + 3 + + + Open Window Animation + 0 + start + center + 1 + + + + + If multiple are selected, one is chosen randomly. + 0 + start + center + 1 + + + + + + + + open-effect-menu + + + 8 + + + Choose Effects + + + + + pan-down-symbolic + 1 + + + + + + + + + + + 10 @@ -144,7 +209,7 @@ 8 - Also Burn Dialogs + Also Add Effects to Dialogs 0 start center diff --git a/resources/ui/gtk4/prefs.ui b/resources/ui/gtk4/prefs.ui index 9d77674..a4182b1 100644 --- a/resources/ui/gtk4/prefs.ui +++ b/resources/ui/gtk4/prefs.ui @@ -3,6 +3,7 @@ + main-menu @@ -70,6 +71,50 @@ + + + 0 + + + + + vertical + 3 + + + Open Window Animation + 0 + start + center + 1 + + + + + If multiple are selected, one is chosen randomly. + 0 + start + center + 1 + + + + + + + + Choose Effects + open-effect-menu + + + + + + + 0 @@ -121,7 +166,7 @@ - Also Burn Dialogs + Also Add Effects to Dialogs 0 start center 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 73845d9..6637fbb 100644 --- a/schemas/org.gnome.shell.extensions.burn-my-windows.gschema.xml +++ b/schemas/org.gnome.shell.extensions.burn-my-windows.gschema.xml @@ -19,6 +19,12 @@ The effect with this nick will be used for the next window-close animation. + + "" + Open Preview Effect + The effect with this nick will be used for the next window-open animation. + + @@ -29,6 +35,12 @@ Use the fire effect for window closing. + + false + Fire Open Effect + Use the fire effect for window opening. + + 1500 Fire Animation Time @@ -93,6 +105,12 @@ Use the matrix effect for window closing. + + false + Matrix Open Effect + Use the matrix effect for window opening. + + 3000 Matrix Animation Time @@ -139,6 +157,12 @@ Use the tv effect for window closing. + + false + TV Open Effect + Use the tv effect for window opening. + + 400 TV Animation Time @@ -161,6 +185,12 @@ Use the trex effect for window closing. + + false + T-Rex Open Effect + Use the trex effect for window opening. + + 1500 T-Rex Animation Time @@ -201,6 +231,12 @@ Use the Energize A effect for window closing. + + false + Energize A Open Effect + Use the Energize A effect for window opening. + + 2000 Energize A Animation Time @@ -229,6 +265,12 @@ Use the Energize B effect for window closing. + + false + Energize B Open Effect + Use the Energize B effect for window opening. + + 2000 Energize B Animation Time @@ -257,6 +299,12 @@ Use the wisps effect for window closing. + + false + Wisps Open Effect + Use the wisps effect for window opening. + + 2000 Wisps Animation Time @@ -285,6 +333,12 @@ Use the broken glass effect for window closing. + + false + Broken Glass Open Effect + Use the broken glass effect for window opening. + + 1500 Broken Glass Animation Time From 28754a93c2eed6a9727d04fa985c241053e14836 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Mon, 24 Jan 2022 20:36:23 +0100 Subject: [PATCH 002/168] :wrench: Reduce default animation time of some effects --- docs/changelog.md | 1 + ...org.gnome.shell.extensions.burn-my-windows.gschema.xml | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/changelog.md b/docs/changelog.md index a8bd78d..cb33ec1 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -13,6 +13,7 @@ * Added a menu entry with a link to the guide for creating new effect types. * Added a new option to the Matrix Effect: **Vertical Overshooting**: This can add some vertical variation to the start and end position of the letter drops. +* Thanks to improved timing, the default animation time of several effects could be reduced. ## [Burn My Window 9](https://github.com/schneegans/Burn-My-Windows/releases/tag/v9) 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 6637fbb..a889297 100644 --- a/schemas/org.gnome.shell.extensions.burn-my-windows.gschema.xml +++ b/schemas/org.gnome.shell.extensions.burn-my-windows.gschema.xml @@ -112,7 +112,7 @@ - 3000 + 1500 Matrix Animation Time The time the matrix effect takes. @@ -192,7 +192,7 @@ - 1500 + 1000 T-Rex Animation Time The time the trex effect takes. @@ -306,7 +306,7 @@ - 2000 + 1500 Wisps Animation Time The time the wisps effect takes. @@ -340,7 +340,7 @@ - 1500 + 1000 Broken Glass Animation Time The time the broken glass effect takes. From b6cb78330d2100b76af11af5b8f81ca9025dfb03 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Thu, 27 Jan 2022 05:07:00 +0100 Subject: [PATCH 003/168] :lipstick: Add headerbar to preview windows --- prefs.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/prefs.js b/prefs.js index 83f14e7..068bbfc 100644 --- a/prefs.js +++ b/prefs.js @@ -337,6 +337,10 @@ var PreferencesDialog = class PreferencesDialog { this._button.get_toplevel() }); + // Add a header bar to the window. + const header = Gtk.HeaderBar.new(); + window.set_titlebar(header); + const box = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL, valign: Gtk.Align.CENTER, From 6b218d049fc1ac951ab35ce47b5d466cfb525213 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Thu, 27 Jan 2022 05:07:30 +0100 Subject: [PATCH 004/168] :hammer: Initial attempt on window-opening animation --- docs/how-to-create-new-effects.md | 19 +- extension.js | 392 +++++++++++++++++------------- src/BrokenGlass.js | 33 ++- src/EnergizeA.js | 28 ++- src/EnergizeB.js | 28 ++- src/Fire.js | 32 ++- src/Matrix.js | 29 ++- src/TRexAttack.js | 41 ++-- src/TVEffect.js | 34 ++- src/Wisps.js | 36 ++- 10 files changed, 405 insertions(+), 267 deletions(-) diff --git a/docs/how-to-create-new-effects.md b/docs/how-to-create-new-effects.md index c1a14f5..0d10d04 100644 --- a/docs/how-to-create-new-effects.md +++ b/docs/how-to-create-new-effects.md @@ -150,12 +150,19 @@ var SimpleFade = class SimpleFade { return new Shader(settings); } - // 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. 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}}; + // This is also called from extension.js. It is used to tweak a window's open / close + // transitions - usually windows are faded in / out and scaled up / down by GNOME Shell. + // forOpening is set to true if this is called for a window-open transition, for a + // window-close transition it is set to false. The modes can be set to any value from + // here: https://gjs-docs.gnome.org/clutter8~8_api/clutter.animationmode. This also + // determines how the uProgress uniform value will progress in the shader. + // For this effect, windows should neither be scaled nor faded. + static tweakTransition(actor, settings, forOpening) { + return { + 'opacity': {from: 255, to: 255, mode: 4}, + 'scale-x': {from: 1.0, to: 1.0, mode: 4}, + 'scale-y': {from: 1.0, to: 1.0, mode: 4} + }; } } diff --git a/extension.js b/extension.js index 085491d..6cc0fec 100644 --- a/extension.js +++ b/extension.js @@ -15,6 +15,7 @@ const {Clutter, Gio, Meta} = imports.gi; +const Main = imports.ui.main; const Workspace = imports.ui.workspace.Workspace; const WindowManager = imports.ui.windowManager.WindowManager; @@ -43,13 +44,12 @@ const ALL_EFFECTS = [ ]; ////////////////////////////////////////////////////////////////////////////////////////// -// This extensions modifies the window-close animation to look like the window was set // -// on fire. There are also a few other effects available. All of them are implemented // -// using GLSL shaders which are applied to the window's Clutter.Actor. The extension is // -// actually very simple, most 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... // +// 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... // ////////////////////////////////////////////////////////////////////////////////////////// class Extension { @@ -68,30 +68,82 @@ class Extension { 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; + // opened / closed. + this._currentEffect = 0; - // We will monkey-patch these three methods. Let's store the original ones. + // We will use extensionThis to refer to the extension inside the patched methods. + const extensionThis = this; + + // We will monkey-patch these methods. Let's store the original ones. + this._origAddWindowClone = Workspace.prototype._addWindowClone; this._origWindowRemoved = Workspace.prototype._windowRemoved; this._origDoRemoveWindow = Workspace.prototype._doRemoveWindow; - this._origAddWindowClone = Workspace.prototype._addWindowClone; this._origShouldAnimateActor = WindowManager.prototype._shouldAnimateActor; // We will also override these animation times. this._origWindowTime = imports.ui.windowManager.DESTROY_WINDOW_ANIMATION_TIME; this._origDialogTime = imports.ui.windowManager.DIALOG_DESTROY_WINDOW_ANIMATION_TIME; - // Reset the dialog destroy time if the corresponding setting gets disabled. - this._settings.connect('changed::destroy-dialogs', () => { - if (!this._settings.get_boolean('destroy-dialogs')) { - imports.ui.windowManager.DIALOG_DESTROY_WINDOW_ANIMATION_TIME = - this._origDialogTime; - } - }); + Workspace.prototype._addWindowClone = function(...params) { + const result = extensionThis._origAddWindowClone.apply(this, params); + + const clone = utils.shellVersionIs(3, 36) ? result[0] : result; + const window = params[0].get_compositor_private(); + + const xID = window.connect('notify::scale-x', () => { + if (window.scale_x > 0) { + clone.window_container.scale_x = window.scale_x; + } + }); + + const yID = window.connect('notify::scale-y', () => { + if (window.scale_y > 0) { + clone.window_container.scale_y = window.scale_y; + } + }); + + clone.window_container.connect('destroy', () => { + window.disconnect(xID); + window.disconnect(yID); + }); + + // On GNOME 3.36, the window clone's 'destroy' handler only calls _removeWindowClone + // but not _doRemoveWindow. The latter is required to trigger the repositioning of + // the overview window layout. Therefore we call this method in addition. + // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/gnome-3-36/js/ui/workspace.js#L1877 + // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/workspace.js#L1415 + if (utils.shellVersionIs(3, 36)) { + clone.connect('destroy', () => this._doRemoveWindow(clone.metaWindow)); + } + + return result; + }; + + this._windowCreatedConnection = + global.display.connect('window-created', (d, metaWin) => { + let actor = metaWin.get_compositor_private(); + + if (Main.overview.visible && !Main.overview.closing) { + utils.debug('window-created: setup effect on show'); + const id = actor.connect('show', () => { + extensionThis._setupEffect(actor, true); + actor.disconnect(id); + }); + + } else { + + utils.debug('window-created: setup effect on ease'); + const orig = actor.ease; + actor.ease = function(...params) { + orig.apply(actor, params); + actor.ease = orig; + + extensionThis._setupEffect(actor, true); + }; + } + }); + - // We will use extensionThis to refer to the extension inside the patched methods of - // the WorkspacesView. - const extensionThis = this; // This class is only available in GNOME Shell 3.38+. So no transition tweaking in // GNOME Shell 3.36, but this is not used by any effect available there anyways for @@ -111,26 +163,15 @@ class Extension { } }; - // When a window is removed from the overview, we need adjust the transitions of the - // window clone according to the chosen effect. We do this in the 'unmanaged' signal - // of the WindowPreview's Meta.Window. This is not ideal, as it does not work for - // dialogs which close themselves... Maybe there's a better way? WindowPreview.prototype._init = function(...params) { // Call the original method. extensionThis._origInit.apply(this, params); - // When the user clicks the X in the overview, the window is not deleted - // immediately. However, as soon as the window is really deleted, we need to - // adjust the transition of its clone. const connectionID = this.metaWindow.connect('unmanaged', () => { if (this.window_container) { // Hide the window's icon, name, and close button. this.overlayEnabled = false; this._icon.visible = false; - - const transitionConfig = extensionThis._effect.getCloseTransition( - this.window_container, extensionThis._settings); - extensionThis._tweakTransitions(this.window_container, transitionConfig); } }); @@ -151,19 +192,6 @@ class Extension { }; } - // On GNOME 3.36, the window clone's 'destroy' handler only calls _removeWindowClone - // but not _doRemoveWindow. The latter is required to trigger the repositioning of the - // overview window layout. Therefore we call this method in addition. - // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/gnome-3-36/js/ui/workspace.js#L1877 - // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/workspace.js#L1415 - if (utils.shellVersionIs(3, 36)) { - Workspace.prototype._addWindowClone = function(...params) { - const [clone, overlay] = extensionThis._origAddWindowClone.apply(this, params); - clone.connect('destroy', () => this._doRemoveWindow(clone.metaWindow)); - return [clone, overlay]; - }; - } - // These three method overrides are mega-hacky! They are only required to make the // fire animation work in the overview. Usually, windows are not faded when closed // from the overview (why?). With these overrides we make sure that they are actually @@ -205,92 +233,7 @@ class Extension { // As we cannot monkey-patch the _destroyWindow itself, we connect to the 'destroy' // signal of the window manager and tweak the animation to our needs. this._destroyConnection = global.window_manager.connect('destroy', (wm, actor) => { - // The _destroyWindow method of WindowManager, which was called right before this - // one, set up the window close animation. This usually fades-out the window and - // scales it a bit down. If no transition is in progress, something unexpected - // happened. We rather try not to burn the window! - const transition = actor.get_transition('scale-y'); - if (!transition) { - return; - } - - // We do nothing if a dialog got closed and we should not burn them. - const shouldDestroyDialogs = this._settings.get_boolean('destroy-dialogs'); - const isDialogWindow = - actor.meta_window.window_type == Meta.WindowType.MODAL_DIALOG || - actor.meta_window.window_type == Meta.WindowType.DIALOG; - - // If an effect is to be previewed, we have to affect dialogs es well. This is - // because the preview window is a dialog window... - const previewNick = this._settings.get_string('close-preview-effect'); - - if (isDialogWindow && !shouldDestroyDialogs && previewNick == '') { - return; - } - - // Now we have to choose an effect. - this._effect = null; - - // First we check if an effect is to be previewed. - if (previewNick != '') { - this._effect = ALL_EFFECTS.find(Effect => { - return Effect.getNick() == previewNick; - }); - - // Only preview the effect once. - this._settings.set_string('close-preview-effect', ''); - - } else { - - // Else we choose a random effect from all enabled effects. Therefore, we first - // create a list of all currently enabled effects. - const enabled = ALL_EFFECTS.filter(Effect => { - return this._settings.get_boolean(`${Effect.getNick()}-close-effect`); - }); - - // And then choose a random effect. - if (enabled.length > 0) { - this._effect = enabled[Math.floor(Math.random() * enabled.length)]; - } - } - - // If nothing was enabled, we have to do nothing :) - if (this._effect == null) { - return; - } - - // The effect usually will choose to override the present transitions on the actor. - const transitionConfig = this._effect.getCloseTransition(actor, this._settings); - this._tweakTransitions(actor, transitionConfig); - - // Add a cool shader to our window actor! - const shader = this._effect.createShader(actor, this._settings); - - if (shader) { - actor.add_effect(shader); - - // Update uniforms at each frame. - transition.connect('new-frame', (t) => { - shader.set_uniform_value('uProgress', t.get_progress()); - shader.set_uniform_value('uTime', 0.001 * t.get_elapsed_time()); - shader.set_uniform_value('uSizeX', actor.width); - shader.set_uniform_value('uSizeY', actor.height); - }); - } - - // The code below is not necessary for Burn-My-Windows to function. However, there - // are some extensions such as "Show Application View When Workspace Empty" - // https://extensions.gnome.org/extension/2036/show-application-view-when-workspace-empty/ - // which do something *after* a window was closed. As the window-close animation - // duration depends on the used effect, this may vary each time a window is closed. - // We set the currently used time here, so that others can get an idea how long this - // will take... - const duration = transition.get_duration(); - if (isDialogWindow && shouldDestroyDialogs) { - imports.ui.windowManager.DIALOG_DESTROY_WINDOW_ANIMATION_TIME = duration; - } else { - imports.ui.windowManager.DESTROY_WINDOW_ANIMATION_TIME = duration; - } + this._setupEffect(actor, false); }); } @@ -301,12 +244,13 @@ class Extension { // Unregister our resources. Gio.resources_unregister(this._resources); - // Restore the original behavior. + // Restore the original window-open and window-close animations. global.window_manager.disconnect(this._destroyConnection); + global.display.disconnect(this._windowCreatedConnection); + Workspace.prototype._addWindowClone = this._origAddWindowClone; Workspace.prototype._windowRemoved = this._origWindowRemoved; Workspace.prototype._doRemoveWindow = this._origDoRemoveWindow; - Workspace.prototype._addWindowClone = this._origAddWindowClone; WindowManager.prototype._shouldAnimateActor = this._origShouldAnimateActor; imports.ui.windowManager.DESTROY_WINDOW_ANIMATION_TIME = this._origWindowTime; @@ -323,6 +267,152 @@ class Extension { // ----------------------------------------------------------------------- private stuff + _setupEffect(actor, forOpening) { + 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; + } + + // We do nothing if a dialog got closed and we should not burn them. + const shouldDestroyDialogs = this._settings.get_boolean('destroy-dialogs'); + + // If an effect is to be previewed, we have to affect dialogs es well. This is + // because the preview window is a dialog window... + const action = forOpening ? 'open' : 'close'; + const previewNick = this._settings.get_string(action + '-preview-effect'); + + if (isDialogWindow && !shouldDestroyDialogs && previewNick == '') { + this._fixAnimationTimes(isDialogWindow, forOpening, null); + return; + } + + // ------------------------------------------------------------------ choose an effect + + this._currentEffect = null; + + if (previewNick != '') { + this._currentEffect = ALL_EFFECTS.find(Effect => { + return Effect.getNick() == previewNick; + }); + + // Only preview the effect once. + this._settings.set_string(action + '-preview-effect', ''); + + } else { + + // Else we choose a random effect from all enabled effects. Therefore, we first + // create a list of all currently enabled effects. + const enabled = ALL_EFFECTS.filter(Effect => { + return this._settings.get_boolean(`${Effect.getNick()}-${action}-effect`); + }); + + // And then choose a random effect. + if (enabled.length > 0) { + this._currentEffect = enabled[Math.floor(Math.random() * enabled.length)]; + } + } + + // If nothing was enabled, we have to do nothing :) + if (this._currentEffect == null) { + this._fixAnimationTimes(isDialogWindow, forOpening, null); + return; + } + + // ----------------------------------------------------------- tweak actor transitions + + // 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 in / out scaled up / down slightly by GNOME Shell. Here, we allow + // modifications to this behavior by the effects. The given config object is created + // by the effect's tweakTransition() method. + const config = this._currentEffect.tweakTransition(actor, this._settings, forOpening); + const duration = + this._settings.get_int(this._currentEffect.getNick() + '-animation-time'); + + actor.set_pivot_point(0.5, 0.5); + + for (const property in config) { + const from = config[property].from; + const to = config[property].to; + const mode = config[property].mode; + + let transition = actor.get_transition(property); + + if (!transition) { + actor.set_property(property, 0); + actor.save_easing_state(); + actor.set_easing_duration(1000); + actor.set_property(property, 1); + actor.restore_easing_state(); + + transition = actor.get_transition(property); + } + + if (!transition) { + this._fixAnimationTimes(isDialogWindow, forOpening, null); + return; + } + + transition.set_duration(duration); + transition.set_to(to); + transition.set_from(from); + transition.set_progress_mode(mode); + } + + const transition = actor.get_transition('scale-y'); + transition.connect('completed', () => { + actor.scale_x = 1.0; + actor.scale_y = 1.0; + }); + + // -------------------------------------------------------------------- add the shader + + // Add a cool shader to our window actor! + const shader = this._currentEffect.createShader(actor, this._settings, forOpening); + + if (shader) { + actor.remove_effect_by_name(`burn-my-windows-effect`); + actor.add_effect_with_name(`burn-my-windows-effect`, shader); + + // Update uniforms at each frame. + transition.connect('new-frame', (t) => { + shader.set_uniform_value('uProgress', t.get_progress()); + shader.set_uniform_value('uTime', 0.001 * t.get_elapsed_time()); + shader.set_uniform_value('uSizeX', actor.width); + shader.set_uniform_value('uSizeY', actor.height); + }); + + transition.connect('completed', () => { + actor.remove_effect_by_name(`burn-my-windows-effect`); + }); + } + + this._fixAnimationTimes(isDialogWindow, forOpening, duration); + } + + // The code below is not necessary for Burn-My-Windows to function. However, there + // are some extensions such as "Show Application View When Workspace Empty" + // https://extensions.gnome.org/extension/2036/show-application-view-when-workspace-empty/ + // which do something *after* a window was closed. As the window-close animation + // duration depends on the used effect, this may vary each time a window is + // closed. We set the currently used time here, so that others can get an idea how + // long this will take... + _fixAnimationTimes(isDialogWindow, forOpening, duration) { + if (!forOpening) { + if (isDialogWindow) { + imports.ui.windowManager.DIALOG_DESTROY_WINDOW_ANIMATION_TIME = + duration != null ? duration : this._origDialogTime; + } else { + imports.ui.windowManager.DESTROY_WINDOW_ANIMATION_TIME = + duration != null ? duration : this._origWindowTime; + } + } + } + // 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) { @@ -340,42 +430,6 @@ 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/BrokenGlass.js b/src/BrokenGlass.js index aa77df0..3646693 100644 --- a/src/BrokenGlass.js +++ b/src/BrokenGlass.js @@ -79,17 +79,21 @@ var BrokenGlass = class BrokenGlass { // ---------------------------------------------------------------- API for extension.js // This is called from extension.js whenever a window is closed with this effect. - static createShader(actor, settings) { - return new Shader(actor, settings); + static createShader(actor, settings, forOpening) { + return new Shader(actor, settings, forOpening); } - // 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. For this effect, windows are set to twice their original size, so that + // This is also called from extension.js. It is used to tweak a window's open / close + // transitions - usually windows are faded in / out and scaled up / down by GNOME Shell. + // forOpening is set to true if this is called for a window-open transition, for a + // window-close transition it is set to false. The modes can be set to any value from + // here: https://gjs-docs.gnome.org/clutter8~8_api/clutter.animationmode. This also + // determines how the uProgress uniform value will progress in the shader. + // For this effect, windows are set to twice their original size, so that // we have some space to draw the shards. We also set the animation mode to "Linear". - static getCloseTransition(actor, settings) { + static tweakTransition(actor, settings, forOpening) { return { - 'opacity': {to: 255, mode: 1}, + 'opacity': {from: 255, to: 255, mode: 1}, 'scale-x': {from: 2.0, to: 2.0, mode: 1}, 'scale-y': {from: 2.0, to: 2.0, mode: 1} }; @@ -118,7 +122,7 @@ if (utils.isInShellProcess()) { // resources/img/shards.png. The red channel of the texture contains the distance to the // shard edges. This information is used to fade out the shards. Shader = GObject.registerClass({}, class Shader extends Clutter.ShaderEffect { - _init(actor, settings) { + _init(actor, settings, forOpening) { super._init({shader_type: Clutter.ShaderType.FRAGMENT_SHADER}); // Load the shards texture. As the shader is re-created for each window animation, @@ -151,16 +155,19 @@ if (utils.isInShellProcess()) { const vec2 SEED = vec2(${Math.random()}, ${Math.random()}); const float SHARD_SCALE = ${settings.get_double('broken-glass-scale')}; const float SHARD_LAYERS = 5; - const float GRAVITY = ${settings.get_double('broken-glass-gravity')}; const float BLOW_FORCE = ${settings.get_double('broken-glass-blow-force')}; const float ACTOR_SCALE = 2.0; const float PADDING = ACTOR_SCALE / 2.0 - 0.5; const vec2 EPICENTER = vec2(${epicenterX}, ${epicenterY}); + const float GRAVITY = ${forOpening ? '-1.0' : '1.0'} * + ${settings.get_double('broken-glass-gravity')}; void main() { cogl_color_out = vec4(0, 0, 0, 0); + float progress = ${forOpening ? '1.0-uProgress' : 'uProgress'}; + // Draw the individual shard layers. for (float i=0; i 0 ? 1: 0; + float dissolve = (shardMap.x - pow(progress+0.1, 2)) > 0 ? 1: 0; cogl_color_out = mix(cogl_color_out, windowColor, dissolve); } } diff --git a/src/EnergizeA.js b/src/EnergizeA.js index cbceeb7..a7ef50d 100644 --- a/src/EnergizeA.js +++ b/src/EnergizeA.js @@ -74,15 +74,23 @@ var EnergizeA = class EnergizeA { // ---------------------------------------------------------------- API for extension.js // This is called from extension.js whenever a window is closed with this effect. - static createShader(actor, settings) { - return new Shader(settings); + static createShader(actor, settings, forOpening) { + return new Shader(settings, forOpening); } - // 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. 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}}; + // This is also called from extension.js. It is used to tweak a window's open / close + // transitions - usually windows are faded in / out and scaled up / down by GNOME Shell. + // forOpening is set to true if this is called for a window-open transition, for a + // window-close transition it is set to false. The modes can be set to any value from + // here: https://gjs-docs.gnome.org/clutter8~8_api/clutter.animationmode. This also + // determines how the uProgress uniform value will progress in the shader. + // For this effect, windows should neither be scaled nor faded. + static tweakTransition(actor, settings, forOpening) { + return { + 'opacity': {from: 255, to: 255, mode: 3}, + 'scale-x': {from: 1.0, to: 1.0, mode: 3}, + 'scale-y': {from: 1.0, to: 1.0, mode: 3} + }; } } @@ -99,7 +107,7 @@ if (utils.isInShellProcess()) { const shaderSnippets = Me.imports.src.shaderSnippets; Shader = GObject.registerClass({}, class Shader extends Clutter.ShaderEffect { - _init(settings) { + _init(settings, forOpening) { super._init({shader_type: Clutter.ShaderType.FRAGMENT_SHADER}); const color = Clutter.Color.from_string(settings.get_string('energize-a-color'))[1]; @@ -144,6 +152,10 @@ if (utils.isInShellProcess()) { // Compute fading window opacity. float windowMask = pow(1.0 - fadeOutProgress, 2.0); + #if ${forOpening ? '1' : '0'} + windowMask = 1.0 - windowMask; + #endif + return vec2(atomMask, windowMask); } diff --git a/src/EnergizeB.js b/src/EnergizeB.js index 4592679..0f0a6b7 100644 --- a/src/EnergizeB.js +++ b/src/EnergizeB.js @@ -74,15 +74,23 @@ var EnergizeB = class EnergizeB { // ---------------------------------------------------------------- API for extension.js // This is called from extension.js whenever a window is closed with this effect. - static createShader(actor, settings) { - return new Shader(settings); + static createShader(actor, settings, forOpening) { + return new Shader(settings, forOpening); } - // 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. 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}}; + // This is also called from extension.js. It is used to tweak a window's open / close + // transitions - usually windows are faded in / out and scaled up / down by GNOME Shell. + // forOpening is set to true if this is called for a window-open transition, for a + // window-close transition it is set to false. The modes can be set to any value from + // here: https://gjs-docs.gnome.org/clutter8~8_api/clutter.animationmode. This also + // determines how the uProgress uniform value will progress in the shader. + // For this effect, windows should neither be scaled nor faded. + static tweakTransition(actor, settings, forOpening) { + return { + 'opacity': {from: 255, to: 255, mode: 3}, + 'scale-x': {from: 1.0, to: 1.0, mode: 3}, + 'scale-y': {from: 1.0, to: 1.0, mode: 3} + }; } } @@ -99,7 +107,7 @@ if (utils.isInShellProcess()) { const shaderSnippets = Me.imports.src.shaderSnippets; Shader = GObject.registerClass({}, class Shader extends Clutter.ShaderEffect { - _init(settings) { + _init(settings, forOpening) { super._init({shader_type: Clutter.ShaderType.FRAGMENT_SHADER}); const color = Clutter.Color.from_string(settings.get_string('energize-b-color'))[1]; @@ -162,6 +170,10 @@ if (utils.isInShellProcess()) { // Compute fading window opacity. float windowMask = pow(1.0 - fadeProgress, 2.0); + #if ${forOpening ? '1' : '0'} + windowMask = 1.0 - windowMask; + #endif + return vec4(showerMask, streakMask, atomMask, windowMask); } diff --git a/src/Fire.js b/src/Fire.js index a04310c..e7640e0 100644 --- a/src/Fire.js +++ b/src/Fire.js @@ -96,15 +96,23 @@ var Fire = class Fire { // ---------------------------------------------------------------- API for extension.js // This is called from extension.js whenever a window is closed with this effect. - static createShader(actor, settings) { - return new Shader(settings); + static createShader(actor, settings, forOpening) { + return new Shader(settings, forOpening); } - // 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. 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}}; + // This is also called from extension.js. It is used to tweak a window's open / close + // transitions - usually windows are faded in / out and scaled up / down by GNOME Shell. + // forOpening is set to true if this is called for a window-open transition, for a + // window-close transition it is set to false. The modes can be set to any value from + // here: https://gjs-docs.gnome.org/clutter8~8_api/clutter.animationmode. This also + // determines how the uProgress uniform value will progress in the shader. + // For this effect, windows should neither be scaled nor faded. + static tweakTransition(actor, settings, forOpening) { + return { + 'opacity': {from: 255, to: 255, mode: 3}, + 'scale-x': {from: 1.0, to: 1.0, mode: 3}, + 'scale-y': {from: 1.0, to: 1.0, mode: 3} + }; } // ----------------------------------------------------------------------- private stuff @@ -210,7 +218,7 @@ if (utils.isInShellProcess()) { const shaderSnippets = Me.imports.src.shaderSnippets; Shader = GObject.registerClass({}, class Shader extends Clutter.ShaderEffect { - _init(settings) { + _init(settings, forOpening) { super._init({shader_type: Clutter.ShaderType.FRAGMENT_SHADER}); // Load the gradient values from the settings. We directly inject the values in the @@ -233,7 +241,7 @@ if (utils.isInShellProcess()) { ${shaderSnippets.edgeMask()} // These may be configurable in the future. - const float EDGE_FADE = 90; + const float EDGE_FADE = 70; const float FADE_WIDTH = 0.1; const float HIDE_TIME = 0.4; const vec2 FIRE_SCALE = vec2(400, 600) * ${settings.get_double('flame-scale')}; @@ -295,6 +303,10 @@ if (utils.isInShellProcess()) { // Fade at window borders. effectMask *= getAbsoluteEdgeMask(edgeFadeWidth); + #if ${forOpening ? '1' : '0'} + windowMask = 1.0 - windowMask; + #endif + return vec2(windowMask, effectMask); } @@ -322,7 +334,7 @@ if (utils.isInShellProcess()) { cogl_color_out = texture2D(uTexture, cogl_tex_coord_in[0].st) * effectMask.x; // Add the fire to the window. - cogl_color_out += fire; + cogl_color_out = mix(cogl_color_out, fire, fire.a); // These are pretty useful for understanding how this works. // cogl_color_out = vec4(vec3(noise), 1); diff --git a/src/Matrix.js b/src/Matrix.js index 678d5ce..329ea42 100644 --- a/src/Matrix.js +++ b/src/Matrix.js @@ -81,19 +81,24 @@ var Matrix = class Matrix { // ---------------------------------------------------------------- API for extension.js // This is called from extension.js whenever a window is closed with this effect. - static createShader(actor, settings) { - return new Shader(settings); + static createShader(actor, settings, forOpening) { + return new Shader(settings, forOpening); } - // 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. For this effect, windows should neither be scaled nor faded. - static getCloseTransition(actor, settings) { + // This is also called from extension.js. It is used to tweak a window's open / close + // transitions - usually windows are faded in / out and scaled up / down by GNOME Shell. + // forOpening is set to true if this is called for a window-open transition, for a + // window-close transition it is set to false. The modes can be set to any value from + // here: https://gjs-docs.gnome.org/clutter8~8_api/clutter.animationmode. This also + // determines how the uProgress uniform value will progress in the shader. + // For this effect, windows should not be faded but scaled vertically to allow for some + // overshooting. + static tweakTransition(actor, settings, forOpening) { const yScale = 1.0 + settings.get_double('matrix-overshoot'); return { - 'opacity': {to: 255}, - 'scale-x': {to: 1.0}, - 'scale-y': {from: yScale, to: yScale} + 'opacity': {from: 255, to: 255, mode: 1}, + 'scale-x': {from: 1.0, to: 1.0, mode: 1}, + 'scale-y': {from: yScale, to: yScale, mode: 1} }; } } @@ -111,7 +116,7 @@ if (utils.isInShellProcess()) { const shaderSnippets = Me.imports.src.shaderSnippets; Shader = GObject.registerClass({}, class Shader extends Clutter.ShaderEffect { - _init(settings) { + _init(settings, forOpening) { super._init({shader_type: Clutter.ShaderType.FRAGMENT_SHADER}); // Load the font texture. As the shader is re-created for each window animation, @@ -187,6 +192,10 @@ if (utils.isInShellProcess()) { rainAlpha *= smoothstep(0, 1, clamp(cogl_tex_coord_in[0].y / shorten, 0, 1)); rainAlpha *= smoothstep(0, 1, clamp((1.0 - cogl_tex_coord_in[0].y) / shorten, 0, 1)); + #if ${forOpening ? '1' : '0'} + windowAlpha = 1.0 - windowAlpha; + #endif + return vec2(rainAlpha, windowAlpha); } diff --git a/src/TRexAttack.js b/src/TRexAttack.js index 380c675..640ebb6 100644 --- a/src/TRexAttack.js +++ b/src/TRexAttack.js @@ -78,20 +78,23 @@ var TRexAttack = class TRexAttack { // ---------------------------------------------------------------- API for extension.js // This is called from extension.js whenever a window is closed with this effect. - static createShader(actor, settings) { - return new Shader(settings); + static createShader(actor, settings, forOpening) { + return new Shader(settings, forOpening); } - // 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. 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'); + // This is also called from extension.js. It is used to tweak a window's open / close + // transitions - usually windows are faded in / out and scaled up / down by GNOME Shell. + // forOpening is set to true if this is called for a window-open transition, for a + // window-close transition it is set to false. The modes can be set to any value from + // here: https://gjs-docs.gnome.org/clutter8~8_api/clutter.animationmode. This also + // determines how the uProgress uniform value will progress in the shader. + // For this effect, we slightly increase the window's scale as part of the warp effect. + static tweakTransition(actor, settings, forOpening) { + const warp = 1.0 + 0.5 * settings.get_double('claw-scratch-warp'); return { - 'opacity': {to: 255}, - 'scale-x': {to: 1.0 + warp}, - 'scale-y': {to: 1.0 + warp} + 'opacity': {from: 255, to: 255, mode: 3}, + 'scale-x': {from: forOpening ? warp : 1.0, to: forOpening ? 1.0 : warp, mode: 3}, + 'scale-y': {from: forOpening ? warp : 1.0, to: forOpening ? 1.0 : warp, mode: 3} }; } } @@ -109,7 +112,7 @@ if (utils.isInShellProcess()) { const shaderSnippets = Me.imports.src.shaderSnippets; Shader = GObject.registerClass({}, class Shader extends Clutter.ShaderEffect { - _init(settings) { + _init(settings, forOpening) { super._init({shader_type: Clutter.ShaderType.FRAGMENT_SHADER}); // Load the claw texture. As the shader is re-created for each window animation, @@ -180,11 +183,13 @@ if (utils.isInShellProcess()) { void main() { + float progress = ${forOpening ? '1.0-uProgress' : 'uProgress'}; + // Warp the texture coordinates to create a blow-up effect. vec2 coords = cogl_tex_coord_in[0].st * 2.0 - 1.0; float dist = length(coords); coords = (coords/dist * pow(dist, WARP_INTENSITY)) * 0.5 + 0.5; - coords = mix(cogl_tex_coord_in[0].st, coords, uProgress); + coords = mix(cogl_tex_coord_in[0].st, coords, progress); // Accumulate several random scratches. The color in the scratch map refers to the // relative time when the respective part will become invisible. Therefore we can @@ -198,11 +203,11 @@ if (utils.isInShellProcess()) { // Get the window texture. We shift the texture lookup by the local derivative of // the claw texture in order to mimic some folding distortion. - vec2 offset = vec2(dFdx(scratchMap), dFdy(scratchMap)) * uProgress * 0.5; + vec2 offset = vec2(dFdx(scratchMap), dFdy(scratchMap)) * progress * 0.5; cogl_color_out = texture2D(uTexture, coords + offset); // Add colorful flashes. - float flashIntensity = 1.0 / FLASH_INTENSITY * (scratchMap - uProgress) + 1; + float flashIntensity = 1.0 / FLASH_INTENSITY * (scratchMap - progress) + 1; if (flashIntensity < 0 || flashIntensity >= 1) { flashIntensity = 0; } @@ -211,16 +216,16 @@ if (utils.isInShellProcess()) { flashIntensity *= cogl_color_out.a; // Hide scratched out parts. - cogl_color_out *= (scratchMap > uProgress ? 1 : 0); + cogl_color_out *= (scratchMap > progress ? 1 : 0); vec3 flashColor = vec3(${color.red / 255}, ${color.green / 255}, ${color.blue / 255}) * ${color.alpha / 255}; - cogl_color_out.rgb += flashIntensity * mix(flashColor, vec3(0), uProgress); + cogl_color_out.rgb += flashIntensity * mix(flashColor, vec3(0), progress); // Fade out the remaining shards. - float fade = smoothstep(0, 1, 1 - clamp((uProgress - 1.0 + FF_TIME)/FF_TIME, 0, 1)); + float fade = smoothstep(0, 1, 1 - clamp((progress - 1.0 + FF_TIME)/FF_TIME, 0, 1)); cogl_color_out *= fade; // These are pretty useful for understanding how this works. diff --git a/src/TVEffect.js b/src/TVEffect.js index b171caf..979252a 100644 --- a/src/TVEffect.js +++ b/src/TVEffect.js @@ -75,15 +75,23 @@ var TVEffect = class TVEffect { // ---------------------------------------------------------------- API for extension.js // This is called from extension.js whenever a window is closed with this effect. - static createShader(actor, settings) { - return new Shader(settings); + static createShader(actor, settings, forOpening) { + return new Shader(settings, forOpening); } - // 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. 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}}; + // This is also called from extension.js. It is used to tweak a window's open / close + // transitions - usually windows are faded in / out and scaled up / down by GNOME Shell. + // forOpening is set to true if this is called for a window-open transition, for a + // window-close transition it is set to false. The modes can be set to any value from + // here: https://gjs-docs.gnome.org/clutter8~8_api/clutter.animationmode. This also + // determines how the uProgress uniform value will progress in the shader. + // For this effect, windows are scaled down vertically. + static tweakTransition(actor, settings, forOpening) { + return { + 'opacity': {from: 255, to: 255, mode: 3}, + 'scale-x': {from: 1.0, to: 1.0, mode: 3}, + 'scale-y': {from: forOpening ? 0.5 : 1.0, to: forOpening ? 1.0 : 0.5, mode: 3} + }; } } @@ -100,7 +108,7 @@ if (utils.isInShellProcess()) { const shaderSnippets = Me.imports.src.shaderSnippets; Shader = GObject.registerClass({}, class Shader extends Clutter.ShaderEffect { - _init(settings) { + _init(settings, forOpening) { super._init({shader_type: Clutter.ShaderType.FRAGMENT_SHADER}); const color = Clutter.Color.from_string(settings.get_string('tv-effect-color'))[1]; @@ -118,13 +126,15 @@ if (utils.isInShellProcess()) { void main() { + float progress = ${forOpening ? '1.0-uProgress' : 'uProgress'}; + // All of these are in [0..1] during the different stages of the animation. // tb refers to the top-bottom animation. // lr refers to the left-right animation. // ff refers to the final fade animation. - float tbProgress = smoothstep(0, 1, clamp(uProgress/TB_TIME, 0, 1)); - float lrProgress = smoothstep(0, 1, clamp((uProgress - LR_DELAY)/LR_TIME, 0, 1)); - float ffProgress = smoothstep(0, 1, clamp((uProgress - 1.0 + FF_TIME)/FF_TIME, 0, 1)); + float tbProgress = smoothstep(0, 1, clamp(progress/TB_TIME, 0, 1)); + float lrProgress = smoothstep(0, 1, clamp((progress - LR_DELAY)/LR_TIME, 0, 1)); + float ffProgress = smoothstep(0, 1, clamp((progress - 1.0 + FF_TIME)/FF_TIME, 0, 1)); // This is a top-center-bottom gradient in [0..1..0] float tb = cogl_tex_coord_in[0].t * 2; @@ -147,7 +157,7 @@ if (utils.isInShellProcess()) { ${color.green / 255}, ${color.blue / 255}, 1.0) * windowColor.a; - windowColor.rgb = mix(windowColor.rgb, effectColor.rgb, smoothstep(0, 1, uProgress)); + windowColor.rgb = mix(windowColor.rgb, effectColor.rgb, smoothstep(0, 1, progress)); cogl_color_out = windowColor * mask; diff --git a/src/Wisps.js b/src/Wisps.js index 030339f..4722af9 100644 --- a/src/Wisps.js +++ b/src/Wisps.js @@ -75,15 +75,23 @@ var Wisps = class Wisps { // ---------------------------------------------------------------- API for extension.js // This is called from extension.js whenever a window is closed with this effect. - static createShader(actor, settings) { - return new Shader(settings); + static createShader(actor, settings, forOpening) { + return new Shader(settings, forOpening); } - // 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. 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}}; + // This is also called from extension.js. It is used to tweak a window's open / close + // transitions - usually windows are faded in / out and scaled up / down by GNOME Shell. + // forOpening is set to true if this is called for a window-open transition, for a + // window-close transition it is set to false. The modes can be set to any value from + // here: https://gjs-docs.gnome.org/clutter8~8_api/clutter.animationmode. This also + // determines how the uProgress uniform value will progress in the shader. + // For this effect, windows should be scaled down slightly but not faded. + static tweakTransition(actor, settings, forOpening) { + return { + 'opacity': {from: 255, to: 255, mode: 3}, + 'scale-x': {from: forOpening ? 0.9 : 1.0, to: forOpening ? 1.0 : 0.9, mode: 3}, + 'scale-y': {from: forOpening ? 0.9 : 1.0, to: forOpening ? 1.0 : 0.9, mode: 3} + }; } } @@ -100,7 +108,7 @@ if (utils.isInShellProcess()) { const shaderSnippets = Me.imports.src.shaderSnippets; Shader = GObject.registerClass({}, class Shader extends Clutter.ShaderEffect { - _init(settings) { + _init(settings, forOpening) { super._init({shader_type: Clutter.ShaderType.FRAGMENT_SHADER}); const color = Clutter.Color.from_string(settings.get_string('wisps-color'))[1]; @@ -159,6 +167,8 @@ if (utils.isInShellProcess()) { } void main() { + + float progress = ${forOpening ? '1.0-uProgress' : 'uProgress'}; // Get the color of the window. vec4 windowColor = texture2D(uTexture, cogl_tex_coord_in[0].st); @@ -167,7 +177,7 @@ if (utils.isInShellProcess()) { ${color.blue / 255}, 1.0) * windowColor.a; // Compute several layers of moving wisps. - vec2 uv = (cogl_tex_coord_in[0].st-0.5) / mix(1.0, 0.5, uProgress) + 0.5; + vec2 uv = (cogl_tex_coord_in[0].st-0.5) / mix(1.0, 0.5, progress) + 0.5; uv /= ${settings.get_double('wisps-scale')}; float wisps = 0; for (int i=0; i Date: Thu, 27 Jan 2022 05:21:15 +0100 Subject: [PATCH 005/168] :beetle: Fix some GNOME 3.36 issues --- extension.js | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/extension.js b/extension.js index 6cc0fec..37e51dc 100644 --- a/extension.js +++ b/extension.js @@ -92,13 +92,25 @@ class Extension { const xID = window.connect('notify::scale-x', () => { if (window.scale_x > 0) { - clone.window_container.scale_x = window.scale_x; + if (utils.shellVersionIs(3, 36)) { + clone.scale_x = window.scale_x; + } else if (utils.shellVersionIs(3, 38)) { + clone._windowContainer.scale_x = window.scale_x; + } else { + clone.window_container.scale_x = window.scale_x; + } } }); const yID = window.connect('notify::scale-y', () => { if (window.scale_y > 0) { - clone.window_container.scale_y = window.scale_y; + if (utils.shellVersionIs(3, 36)) { + clone.scale_y = window.scale_y; + } else if (utils.shellVersionIs(3, 38)) { + clone._windowContainer.scale_y = window.scale_y; + } else { + clone.window_container.scale_y = window.scale_y; + } } }); From bf95e349da50bcd8f82e1d6528d3c6981cd8e3ae Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Thu, 27 Jan 2022 05:24:32 +0100 Subject: [PATCH 006/168] :beetle: Fix some GNOME 3.36 issues --- extension.js | 44 ++++++++++++++++++++------------------------ 1 file changed, 20 insertions(+), 24 deletions(-) diff --git a/extension.js b/extension.js index 37e51dc..01f4ffe 100644 --- a/extension.js +++ b/extension.js @@ -85,38 +85,34 @@ class Extension { this._origDialogTime = imports.ui.windowManager.DIALOG_DESTROY_WINDOW_ANIMATION_TIME; Workspace.prototype._addWindowClone = function(...params) { - const result = extensionThis._origAddWindowClone.apply(this, params); + const result = extensionThis._origAddWindowClone.apply(this, params); + const realWindow = params[0].get_compositor_private(); - const clone = utils.shellVersionIs(3, 36) ? result[0] : result; - const window = params[0].get_compositor_private(); + let clone; - const xID = window.connect('notify::scale-x', () => { - if (window.scale_x > 0) { - if (utils.shellVersionIs(3, 36)) { - clone.scale_x = window.scale_x; - } else if (utils.shellVersionIs(3, 38)) { - clone._windowContainer.scale_x = window.scale_x; - } else { - clone.window_container.scale_x = window.scale_x; - } + if (utils.shellVersionIs(3, 36)) { + clone = result[0]; + } else if (utils.shellVersionIs(3, 38)) { + clone = result._windowContainer; + } else { + clone = result.window_container; + } + + const xID = realWindow.connect('notify::scale-x', () => { + if (realWindow.scale_x > 0) { + clone.scale_x = realWindow.scale_x; } }); - const yID = window.connect('notify::scale-y', () => { - if (window.scale_y > 0) { - if (utils.shellVersionIs(3, 36)) { - clone.scale_y = window.scale_y; - } else if (utils.shellVersionIs(3, 38)) { - clone._windowContainer.scale_y = window.scale_y; - } else { - clone.window_container.scale_y = window.scale_y; - } + const yID = realWindow.connect('notify::scale-y', () => { + if (realWindow.scale_y > 0) { + clone.scale_y = realWindow.scale_y; } }); - clone.window_container.connect('destroy', () => { - window.disconnect(xID); - window.disconnect(yID); + clone.connect('destroy', () => { + realWindow.disconnect(xID); + realWindow.disconnect(yID); }); // On GNOME 3.36, the window clone's 'destroy' handler only calls _removeWindowClone From f5e58b100f389ffad27d4ecc6360f6fc00032f94 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Thu, 27 Jan 2022 05:31:38 +0100 Subject: [PATCH 007/168] :beetle: Fix some GNOME 3.36 issues --- extension.js | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/extension.js b/extension.js index 01f4ffe..fd393f2 100644 --- a/extension.js +++ b/extension.js @@ -85,17 +85,19 @@ class Extension { this._origDialogTime = imports.ui.windowManager.DIALOG_DESTROY_WINDOW_ANIMATION_TIME; Workspace.prototype._addWindowClone = function(...params) { - const result = extensionThis._origAddWindowClone.apply(this, params); - const realWindow = params[0].get_compositor_private(); + const result = extensionThis._origAddWindowClone.apply(this, params); - let clone; + let realWindow, clone; if (utils.shellVersionIs(3, 36)) { - clone = result[0]; + clone = result[0]; + realWindow = clone.realWindow; } else if (utils.shellVersionIs(3, 38)) { - clone = result._windowContainer; + clone = result._windowContainer; + realWindow = params[0].get_compositor_private(); } else { - clone = result.window_container; + clone = result.window_container; + realWindow = params[0].get_compositor_private(); } const xID = realWindow.connect('notify::scale-x', () => { From c107083cde73ecb9fb3aa9bafde76ee3f3405a7d Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Thu, 27 Jan 2022 05:46:10 +0100 Subject: [PATCH 008/168] :beetle: Fix some GNOME 3.36 issues --- docs/how-to-create-new-effects.md | 9 ++++---- extension.js | 37 +++++++++++++++++-------------- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/docs/how-to-create-new-effects.md b/docs/how-to-create-new-effects.md index 0d10d04..730c131 100644 --- a/docs/how-to-create-new-effects.md +++ b/docs/how-to-create-new-effects.md @@ -152,10 +152,11 @@ var SimpleFade = class SimpleFade { // This is also called from extension.js. It is used to tweak a window's open / close // transitions - usually windows are faded in / out and scaled up / down by GNOME Shell. - // forOpening is set to true if this is called for a window-open transition, for a - // window-close transition it is set to false. The modes can be set to any value from - // here: https://gjs-docs.gnome.org/clutter8~8_api/clutter.animationmode. This also - // determines how the uProgress uniform value will progress in the shader. + // The parameter 'forOpening' is set to true if this is called for a window-open + // transition, for a window-close transition it is set to false. The modes can be set to + // any value from here: https://gjs-docs.gnome.org/clutter8~8_api/clutter.animationmode. + // This also determines how the uProgress uniform value will progress in the shader. + // Tweaking the actor's scale during the transition only works properly for GNOME 3.38+. // For this effect, windows should neither be scaled nor faded. static tweakTransition(actor, settings, forOpening) { return { diff --git a/extension.js b/extension.js index fd393f2..5115b3e 100644 --- a/extension.js +++ b/extension.js @@ -100,22 +100,26 @@ class Extension { realWindow = params[0].get_compositor_private(); } - const xID = realWindow.connect('notify::scale-x', () => { - if (realWindow.scale_x > 0) { - clone.scale_x = realWindow.scale_x; - } - }); + // Syncing the real window's scale with the scale of its clone only works on GNOME + // Shell 3.38+. So effects cannot scale windows in the overview of GNOME 3.36... + if (utils.shellVersionIsAtLeast(3, 38)) { + const xID = realWindow.connect('notify::scale-x', () => { + if (realWindow.scale_x > 0) { + clone.scale_x = realWindow.scale_x; + } + }); - const yID = realWindow.connect('notify::scale-y', () => { - if (realWindow.scale_y > 0) { - clone.scale_y = realWindow.scale_y; - } - }); + const yID = realWindow.connect('notify::scale-y', () => { + if (realWindow.scale_y > 0) { + clone.scale_y = realWindow.scale_y; + } + }); - clone.connect('destroy', () => { - realWindow.disconnect(xID); - realWindow.disconnect(yID); - }); + clone.connect('destroy', () => { + realWindow.disconnect(xID); + realWindow.disconnect(yID); + }); + } // On GNOME 3.36, the window clone's 'destroy' handler only calls _removeWindowClone // but not _doRemoveWindow. The latter is required to trigger the repositioning of @@ -155,9 +159,8 @@ class Extension { - // This class is only available in GNOME Shell 3.38+. So no transition tweaking in - // GNOME Shell 3.36, but this is not used by any effect available there anyways for - // now... + // This class is only available in GNOME Shell 3.38+. So no overlay-hiding on + // GNOME Shell 3.36 for now. if (WindowPreview) { this._origDeleteAll = WindowPreview.prototype._deleteAll; this._origRestack = WindowPreview.prototype._restack; From 38458e4a4cba8aedc35e230c9bfb204f24083988 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Thu, 27 Jan 2022 05:47:59 +0100 Subject: [PATCH 009/168] :beetle: Fix some GNOME 3.36 and 3.38 issues --- prefs.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/prefs.js b/prefs.js index 068bbfc..af5bc0d 100644 --- a/prefs.js +++ b/prefs.js @@ -360,11 +360,11 @@ var PreferencesDialog = class PreferencesDialog { if (utils.isGTK4()) { window.set_child(box); + window.show(); } else { window.add(box); + window.show_all(); } - - window.show(); }); } }); From a8d75de4c949f1f932f59ea85e36bf292d4ff9b8 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Thu, 27 Jan 2022 05:52:49 +0100 Subject: [PATCH 010/168] :lipstick: Only add headerbar on GTK4 --- prefs.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/prefs.js b/prefs.js index af5bc0d..e206641 100644 --- a/prefs.js +++ b/prefs.js @@ -338,8 +338,10 @@ var PreferencesDialog = class PreferencesDialog { }); // Add a header bar to the window. - const header = Gtk.HeaderBar.new(); - window.set_titlebar(header); + if (utils.isGTK4()) { + const header = Gtk.HeaderBar.new(); + window.set_titlebar(header); + } const box = new Gtk.Box({ orientation: Gtk.Orientation.VERTICAL, From 1b79cd4aa49c15c2179d84dc6c17dcb89b68d1c2 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Thu, 27 Jan 2022 05:53:13 +0100 Subject: [PATCH 011/168] :wrench: Remove debug print --- extension.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/extension.js b/extension.js index 5115b3e..eab1a01 100644 --- a/extension.js +++ b/extension.js @@ -138,15 +138,12 @@ class Extension { let actor = metaWin.get_compositor_private(); if (Main.overview.visible && !Main.overview.closing) { - utils.debug('window-created: setup effect on show'); const id = actor.connect('show', () => { extensionThis._setupEffect(actor, true); actor.disconnect(id); }); } else { - - utils.debug('window-created: setup effect on ease'); const orig = actor.ease; actor.ease = function(...params) { orig.apply(actor, params); From 5ff26324995bc7e3c185e047fa1ea67cad3c77e2 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Thu, 27 Jan 2022 06:09:18 +0100 Subject: [PATCH 012/168] :wrench: Reduce default energize b time --- schemas/org.gnome.shell.extensions.burn-my-windows.gschema.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 a889297..826c5ca 100644 --- a/schemas/org.gnome.shell.extensions.burn-my-windows.gschema.xml +++ b/schemas/org.gnome.shell.extensions.burn-my-windows.gschema.xml @@ -272,7 +272,7 @@ - 2000 + 1500 Energize B Animation Time The time the Energize B effect takes. From 68712fb842673e342ee3515e9d6cbcb8e13ad2d5 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Thu, 27 Jan 2022 06:16:07 +0100 Subject: [PATCH 013/168] :memo: Add changelog entry --- docs/changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelog.md b/docs/changelog.md index cb33ec1..18b212e 100644 --- a/docs/changelog.md +++ b/docs/changelog.md @@ -6,6 +6,7 @@ #### New Features +* **Effects for Window Opening.** You can now select effects which are applied on newly opened windows! I expect that there are some bugs left, so please [report any issue you find](https://github.com/Schneegans/Burn-My-Windows/issues)! * **New Effect: Broken Glass.** Shatter your windows into a shower sharp shards! This effect can be configured so that the shards fly away from your mouse pointer position! * The effect-configuration pages of the preferences dialog now have **Preview Buttons** which con be used to, well, preview the current settings (without having to enable the effect first). From acff1da6c2426c02d396bedf97e306ae407f7f21 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Thu, 27 Jan 2022 06:53:30 +0100 Subject: [PATCH 014/168] :beetle: Prevent registering the same type twice --- prefs.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/prefs.js b/prefs.js index e206641..ffe9c17 100644 --- a/prefs.js +++ b/prefs.js @@ -304,6 +304,7 @@ var PreferencesDialog = class PreferencesDialog { // Each effect page is based on a template widget. This template contains the title // and the preview button. // clang-format off + if (GObject.type_from_name('BurnMyWindowsEffectPage') == null) { BurnMyWindowsEffectPage = GObject.registerClass({ GTypeName: 'BurnMyWindowsEffectPage', @@ -370,7 +371,8 @@ var PreferencesDialog = class PreferencesDialog { }); } }); - // clang-format on + // clang-format on + } } } From e2d9015490d694bf9d4b3e4bc8e8d7cacd7a6a10 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Thu, 27 Jan 2022 20:59:02 +0100 Subject: [PATCH 015/168] :memo: Add plenty of comments --- extension.js | 250 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 151 insertions(+), 99 deletions(-) diff --git a/extension.js b/extension.js index eab1a01..dc33e09 100644 --- a/extension.js +++ b/extension.js @@ -67,8 +67,8 @@ 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 - // opened / closed. + // This will store an item of ALL_EFFECTS array which was used the last time a window + // was opened / closed. this._currentEffect = 0; // We will use extensionThis to refer to the extension inside the patched methods. @@ -84,9 +84,52 @@ class Extension { this._origWindowTime = imports.ui.windowManager.DESTROY_WINDOW_ANIMATION_TIME; this._origDialogTime = imports.ui.windowManager.DIALOG_DESTROY_WINDOW_ANIMATION_TIME; + + // ------------------------------------------------ patching the window-open animation + + // Here we add an effect to the window-open animation. This is done whenever a new + // window is created. + this._windowCreatedConnection = + global.display.connect('window-created', (d, metaWin) => { + let actor = metaWin.get_compositor_private(); + + // If we are currently in the overview, we add the effect to the original window + // actor. The window preview in the overview is basically a Clutter.Clone which + // shows the original window. + if (Main.overview.visible && !Main.overview.closing) { + const id = actor.connect('show', () => { + extensionThis._setupEffect(actor, true); + actor.disconnect(id); + }); + + } + // If a window is created outside of the overview, the transitions are set up in + // the async _mapWindow of the WindowManager which can defer the actual showing + // of the window significantly, especially when currently leaving the overview: + // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/windowManager.js#L1449 + // 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 - the next time it will be + // called by the _mapWindow(), we will intercept it! + else { + const orig = actor.ease; + actor.ease = function(...params) { + orig.apply(actor, params); + actor.ease = orig; + + extensionThis._setupEffect(actor, true); + }; + } + }); + + // 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 result = extensionThis._origAddWindowClone.apply(this, params); + // The parameters of this method changed a bit through the versions... let realWindow, clone; if (utils.shellVersionIs(3, 36)) { @@ -121,6 +164,7 @@ class Extension { }); } + // This is actually need for the window-close animation on GNOME Shell 3.36. // On GNOME 3.36, the window clone's 'destroy' handler only calls _removeWindowClone // but not _doRemoveWindow. The latter is required to trigger the repositioning of // the overview window layout. Therefore we call this method in addition. @@ -133,83 +177,28 @@ class Extension { return result; }; - this._windowCreatedConnection = - global.display.connect('window-created', (d, metaWin) => { - let actor = metaWin.get_compositor_private(); - if (Main.overview.visible && !Main.overview.closing) { - const id = actor.connect('show', () => { - extensionThis._setupEffect(actor, true); - actor.disconnect(id); - }); + // ----------------------------------------------- patching the window-close animation - } else { - const orig = actor.ease; - actor.ease = function(...params) { - orig.apply(actor, params); - actor.ease = orig; + // The signal handler below is all which is required outside of the overview. All + // other hacks further below are just required to defer the window-hiding in the + // overview until the effect is finished. - extensionThis._setupEffect(actor, true); - }; - } - }); + // The close animation is set up in WindowManager's _destroyWindow: + // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/windowManager.js#L1549 + // As we cannot monkey-patch the _destroyWindow itself, we connect to the 'destroy' + // signal of the window manager and tweak the animation to our needs. + this._destroyConnection = global.window_manager.connect('destroy', (wm, actor) => { + this._setupEffect(actor, false); + }); - - - // This class is only available in GNOME Shell 3.38+. So no overlay-hiding on - // GNOME Shell 3.36 for now. - if (WindowPreview) { - this._origDeleteAll = WindowPreview.prototype._deleteAll; - this._origRestack = WindowPreview.prototype._restack; - this._origInit = WindowPreview.prototype._init; - - // 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) { - // Call the original method. - extensionThis._origRestack.apply(this); - } - }; - - WindowPreview.prototype._init = function(...params) { - // Call the original method. - extensionThis._origInit.apply(this, params); - - const connectionID = this.metaWindow.connect('unmanaged', () => { - if (this.window_container) { - // Hide the window's icon, name, and close button. - 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); - } - }; - } - - // These three method overrides are mega-hacky! They are only required to make the - // fire animation work in the overview. 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. Are the actors removed in the end? I hope so. The - // _destroyWindow of the WindowManager sets the transitions up and should take care of - // removing the actors at the end of the transitions. + // 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. Are the actors removed in the end? I hope so. + // The _destroyWindow of the WindowManager sets the transitions up and should take + // care of removing the actors at the end of the transitions. // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/workspace.js#L1299 Workspace.prototype._windowRemoved = function(ws, metaWin) { if (extensionThis._shouldDestroy(this, metaWin)) { @@ -238,13 +227,54 @@ class Extension { return extensionThis._origShouldAnimateActor.apply(this, params); }; - // The close animation is set up in WindowManager's _destroyWindow: - // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/windowManager.js#L1549 - // As we cannot monkey-patch the _destroyWindow itself, we connect to the 'destroy' - // signal of the window manager and tweak the animation to our needs. - this._destroyConnection = global.window_manager.connect('destroy', (wm, actor) => { - this._setupEffect(actor, false); - }); + // With the code below, we hide the window-overlay (icon, label, close button) in the + // overview once the close-animation is running. As the WindowPreview class is only + // available on GNOME 3.38 and beyond, we cannot hide the overlay on GNOME 3.36. + if (WindowPreview) { + + // 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 @@ -277,7 +307,13 @@ class Extension { // ----------------------------------------------------------------------- private stuff + // This method adds one of the configured effects to the given actor. If forOpening is + // set to true, a effect from the enabled window-open animations is chosen, else an + // enabled window-close animation is used. This will also tweak the transitions of the + // given actor (e.g. scale it up if required). _setupEffect(actor, forOpening) { + + // 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 || @@ -290,7 +326,7 @@ class Extension { // We do nothing if a dialog got closed and we should not burn them. const shouldDestroyDialogs = this._settings.get_boolean('destroy-dialogs'); - // If an effect is to be previewed, we have to affect dialogs es well. This is + // If an effect is to be previewed however, we have to affect dialogs es well. This is // because the preview window is a dialog window... const action = forOpening ? 'open' : 'close'; const previewNick = this._settings.get_string(action + '-preview-effect'); @@ -302,8 +338,10 @@ class Extension { // ------------------------------------------------------------------ choose an effect + // Now we chose a random effect from all enabled effects. this._currentEffect = null; + // First we check if an effect is to be previewed. if (previewNick != '') { this._currentEffect = ALL_EFFECTS.find(Effect => { return Effect.getNick() == previewNick; @@ -312,10 +350,11 @@ class Extension { // Only preview the effect once. this._settings.set_string(action + '-preview-effect', ''); - } else { + } + // Else we choose a random effect from all enabled effects. + else { - // Else we choose a random effect from all enabled effects. Therefore, we first - // create a list of all currently enabled effects. + // Therefore, we first create a list of all currently enabled effects. const enabled = ALL_EFFECTS.filter(Effect => { return this._settings.get_boolean(`${Effect.getNick()}-${action}-effect`); }); @@ -334,24 +373,27 @@ class Extension { // ----------------------------------------------------------- tweak actor transitions - // 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 in / out scaled up / down slightly by GNOME Shell. Here, we allow - // modifications to this behavior by the effects. The given config object is created - // by the effect's tweakTransition() method. + // 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 allow + // modifications to this behavior by the effects. const config = this._currentEffect.tweakTransition(actor, this._settings, forOpening); const duration = this._settings.get_int(this._currentEffect.getNick() + '-animation-time'); + // All animations are relative to the window's center. actor.set_pivot_point(0.5, 0.5); + // This goes through all properties given in the config object and tweaks any ongoing + // transitions accordingly. If there is no ongoing transition for a given property, a + // new one is set up. for (const property in config) { - const from = config[property].from; - const to = config[property].to; - const mode = config[property].mode; - let transition = actor.get_transition(property); + // If there is currently no ongoing transition, we create a new one. Clutter does + // not like to create transitions with the same start and end value - however, we + // need at least one transition for our progress value in the shader. So we trick + // Clutter by creating an arbitrary transition first and then modifying the start + // and end values according to our config object. if (!transition) { actor.set_property(property, 0); actor.save_easing_state(); @@ -359,20 +401,27 @@ class Extension { actor.set_property(property, 1); actor.restore_easing_state(); + // Now there should be a transition! transition = actor.get_transition(property); } + // For some reason, there are rare cases, where no transition is set up. We do not + // try to continue here... if (!transition) { + utils.debug('Failed to set up transitions.'); this._fixAnimationTimes(isDialogWindow, forOpening, null); return; } + // Tweak the transition according to the config object. transition.set_duration(duration); - transition.set_to(to); - transition.set_from(from); - transition.set_progress_mode(mode); + transition.set_to(config[property].to); + transition.set_from(config[property].from); + transition.set_progress_mode(config[property].mode); } + // There should always be a scale-y transitions. Once this is finished, we restore the + // original actor size. const transition = actor.get_transition('scale-y'); transition.connect('completed', () => { actor.scale_x = 1.0; @@ -381,10 +430,11 @@ class Extension { // -------------------------------------------------------------------- add the shader - // Add a cool shader to our window actor! + // Now add a cool shader to our window actor! const shader = this._currentEffect.createShader(actor, this._settings, forOpening); if (shader) { + // First remove any old effect. actor.remove_effect_by_name(`burn-my-windows-effect`); actor.add_effect_with_name(`burn-my-windows-effect`, shader); @@ -401,6 +451,8 @@ class Extension { }); } + // Finally, ensure that all animation times are set properly so that other extensions + // may guess how long it will take until windows are gone :) this._fixAnimationTimes(isDialogWindow, forOpening, duration); } From c9000fcad7a133143fbc451113aa1982e9f7bcd8 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Thu, 27 Jan 2022 21:33:33 +0100 Subject: [PATCH 016/168] :beetle: Fix blending of fire shader --- src/Fire.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Fire.js b/src/Fire.js index e7640e0..eecbeb0 100644 --- a/src/Fire.js +++ b/src/Fire.js @@ -334,7 +334,7 @@ if (utils.isInShellProcess()) { cogl_color_out = texture2D(uTexture, cogl_tex_coord_in[0].st) * effectMask.x; // Add the fire to the window. - cogl_color_out = mix(cogl_color_out, fire, fire.a); + cogl_color_out = cogl_color_out * (1.0 - fire.a) + fire; // These are pretty useful for understanding how this works. // cogl_color_out = vec4(vec3(noise), 1); From bc2f39fac89facf5f5e028731356f3f5b992d130 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Thu, 27 Jan 2022 21:33:53 +0100 Subject: [PATCH 017/168] :wrench: Improve timing of energize b --- src/EnergizeB.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/EnergizeB.js b/src/EnergizeB.js index 0f0a6b7..2292f95 100644 --- a/src/EnergizeB.js +++ b/src/EnergizeB.js @@ -149,7 +149,7 @@ if (utils.isInShellProcess()) { float atomMask = getRelativeEdgeMask(0.2); atomMask = max(0, atomMask - showerMask); atomMask *= streakMask; - atomMask *= (1.0 - fadeProgress); + atomMask *= sqrt(1-fadeProgress*fadeProgress); // Make some particles visible in the streaks. showerMask += 0.05 * streakMask; From 7b7b5cbb46cb0b4638d53263d31b4da0a5f737fc Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Thu, 27 Jan 2022 21:34:11 +0100 Subject: [PATCH 018/168] :wrench: Improve timing of trex attack --- src/TRexAttack.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/TRexAttack.js b/src/TRexAttack.js index 640ebb6..e161100 100644 --- a/src/TRexAttack.js +++ b/src/TRexAttack.js @@ -141,8 +141,8 @@ if (utils.isInShellProcess()) { const float NUM_CLAWS = ${settings.get_int('claw-scratch-count')}; const float WARP_INTENSITY = 1.0 + ${settings.get_double('claw-scratch-warp')}; const float FLASH_INTENSITY = 0.1; - const float MAX_SPAWN_TIME = 0.5; // Scratches will only start in the first half of the animation. - const float FF_TIME = 0.5; // Relative time for the final fade to transparency. + const float MAX_SPAWN_TIME = 0.6; // Scratches will only start in the first half of the animation. + const float FF_TIME = 0.6; // Relative time for the final fade to transparency. // This method generates a grid of randomly rotated, slightly shifted and scaled // UV squares. It returns the texture coords of the UV square at the given actor @@ -225,8 +225,8 @@ if (utils.isInShellProcess()) { cogl_color_out.rgb += flashIntensity * mix(flashColor, vec3(0), progress); // Fade out the remaining shards. - float fade = smoothstep(0, 1, 1 - clamp((progress - 1.0 + FF_TIME)/FF_TIME, 0, 1)); - cogl_color_out *= fade; + float fadeProgress = smoothstep(0, 1, (progress - 1.0 + FF_TIME)/FF_TIME); + cogl_color_out *= sqrt(1-fadeProgress*fadeProgress); // These are pretty useful for understanding how this works. // cogl_color_out = vec4(vec3(flashIntensity), 1); From 765cf6d54cc105a833a59a12ed4c6d0fb54dca51 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Thu, 27 Jan 2022 21:40:58 +0100 Subject: [PATCH 019/168] :wrench: Improve timing of tv effect --- src/TVEffect.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TVEffect.js b/src/TVEffect.js index 979252a..e022f55 100644 --- a/src/TVEffect.js +++ b/src/TVEffect.js @@ -122,7 +122,7 @@ if (utils.isInShellProcess()) { const float TB_TIME = 0.7; // Relative time for the top/bottom animation. const float LR_TIME = 0.4; // Relative time for the left/right animation. const float LR_DELAY = 0.6; // Delay after which the left/right animation starts. - const float FF_TIME = 0.2; // Relative time for the final fade to transparency. + const float FF_TIME = 0.1; // Relative time for the final fade to transparency. void main() { From dcaa28c200e4bf8f5212374eebe2a8a64b4fb0b5 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Thu, 27 Jan 2022 21:43:55 +0100 Subject: [PATCH 020/168] :wrench: Improve timing of energize b --- schemas/org.gnome.shell.extensions.burn-my-windows.gschema.xml | 2 +- src/EnergizeB.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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 826c5ca..4631aca 100644 --- a/schemas/org.gnome.shell.extensions.burn-my-windows.gschema.xml +++ b/schemas/org.gnome.shell.extensions.burn-my-windows.gschema.xml @@ -272,7 +272,7 @@ - 1500 + 1000 Energize B Animation Time The time the Energize B effect takes. diff --git a/src/EnergizeB.js b/src/EnergizeB.js index 2292f95..fe3973e 100644 --- a/src/EnergizeB.js +++ b/src/EnergizeB.js @@ -120,7 +120,7 @@ if (utils.isInShellProcess()) { ${shaderSnippets.edgeMask()} const vec2 SEED = vec2(${Math.random()}, ${Math.random()}); - const float SHOWER_TIME = 0.2; + const float SHOWER_TIME = 0.3; const float SHOWER_WIDTH = 0.3; const float STREAK_TIME = 0.6; const float EDGE_FADE = 50; From 51ba0d06ab87f9c9f2c53c693cce0f0d4e980ab1 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Fri, 28 Jan 2022 07:49:48 +0100 Subject: [PATCH 021/168] :memo: Improve comments --- docs/how-to-create-new-effects.md | 6 ++++-- src/BrokenGlass.js | 13 ++++++++----- src/EnergizeA.js | 13 ++++++++----- src/EnergizeB.js | 13 ++++++++----- src/Fire.js | 13 ++++++++----- src/Matrix.js | 13 ++++++++----- src/TRexAttack.js | 13 ++++++++----- src/TVEffect.js | 13 ++++++++----- src/Wisps.js | 13 ++++++++----- 9 files changed, 68 insertions(+), 42 deletions(-) diff --git a/docs/how-to-create-new-effects.md b/docs/how-to-create-new-effects.md index 730c131..a69d5ae 100644 --- a/docs/how-to-create-new-effects.md +++ b/docs/how-to-create-new-effects.md @@ -150,13 +150,15 @@ var SimpleFade = class SimpleFade { return new Shader(settings); } - // This is also called from extension.js. It is used to tweak a window's open / close + // The tweakTransition() is called from extension.js to tweak a window's open / close // transitions - usually windows are faded in / out and scaled up / down by GNOME Shell. // The parameter 'forOpening' is set to true if this is called for a window-open // transition, for a window-close transition it is set to false. The modes can be set to // any value from here: https://gjs-docs.gnome.org/clutter8~8_api/clutter.animationmode. - // This also determines how the uProgress uniform value will progress in the shader. + // The only required property is 'opacity', even if it transitions from 1.0 to 1.0. The + // current value of the opacity transition is passed as uProgress to the shader. // Tweaking the actor's scale during the transition only works properly for GNOME 3.38+. + // For this effect, windows should neither be scaled nor faded. static tweakTransition(actor, settings, forOpening) { return { diff --git a/src/BrokenGlass.js b/src/BrokenGlass.js index 3646693..26c5cc4 100644 --- a/src/BrokenGlass.js +++ b/src/BrokenGlass.js @@ -83,12 +83,15 @@ var BrokenGlass = class BrokenGlass { return new Shader(actor, settings, forOpening); } - // This is also called from extension.js. It is used to tweak a window's open / close + // The tweakTransition() is called from extension.js to tweak a window's open / close // transitions - usually windows are faded in / out and scaled up / down by GNOME Shell. - // forOpening is set to true if this is called for a window-open transition, for a - // window-close transition it is set to false. The modes can be set to any value from - // here: https://gjs-docs.gnome.org/clutter8~8_api/clutter.animationmode. This also - // determines how the uProgress uniform value will progress in the shader. + // The parameter 'forOpening' is set to true if this is called for a window-open + // transition, for a window-close transition it is set to false. The modes can be set to + // any value from here: https://gjs-docs.gnome.org/clutter8~8_api/clutter.animationmode. + // The only required property is 'opacity', even if it transitions from 1.0 to 1.0. The + // current value of the opacity transition is passed as uProgress to the shader. + // Tweaking the actor's scale during the transition only works properly for GNOME 3.38+. + // For this effect, windows are set to twice their original size, so that // we have some space to draw the shards. We also set the animation mode to "Linear". static tweakTransition(actor, settings, forOpening) { diff --git a/src/EnergizeA.js b/src/EnergizeA.js index a7ef50d..5cbef47 100644 --- a/src/EnergizeA.js +++ b/src/EnergizeA.js @@ -78,12 +78,15 @@ var EnergizeA = class EnergizeA { return new Shader(settings, forOpening); } - // This is also called from extension.js. It is used to tweak a window's open / close + // The tweakTransition() is called from extension.js to tweak a window's open / close // transitions - usually windows are faded in / out and scaled up / down by GNOME Shell. - // forOpening is set to true if this is called for a window-open transition, for a - // window-close transition it is set to false. The modes can be set to any value from - // here: https://gjs-docs.gnome.org/clutter8~8_api/clutter.animationmode. This also - // determines how the uProgress uniform value will progress in the shader. + // The parameter 'forOpening' is set to true if this is called for a window-open + // transition, for a window-close transition it is set to false. The modes can be set to + // any value from here: https://gjs-docs.gnome.org/clutter8~8_api/clutter.animationmode. + // The only required property is 'opacity', even if it transitions from 1.0 to 1.0. The + // current value of the opacity transition is passed as uProgress to the shader. + // Tweaking the actor's scale during the transition only works properly for GNOME 3.38+. + // For this effect, windows should neither be scaled nor faded. static tweakTransition(actor, settings, forOpening) { return { diff --git a/src/EnergizeB.js b/src/EnergizeB.js index fe3973e..37dd1a1 100644 --- a/src/EnergizeB.js +++ b/src/EnergizeB.js @@ -78,12 +78,15 @@ var EnergizeB = class EnergizeB { return new Shader(settings, forOpening); } - // This is also called from extension.js. It is used to tweak a window's open / close + // The tweakTransition() is called from extension.js to tweak a window's open / close // transitions - usually windows are faded in / out and scaled up / down by GNOME Shell. - // forOpening is set to true if this is called for a window-open transition, for a - // window-close transition it is set to false. The modes can be set to any value from - // here: https://gjs-docs.gnome.org/clutter8~8_api/clutter.animationmode. This also - // determines how the uProgress uniform value will progress in the shader. + // The parameter 'forOpening' is set to true if this is called for a window-open + // transition, for a window-close transition it is set to false. The modes can be set to + // any value from here: https://gjs-docs.gnome.org/clutter8~8_api/clutter.animationmode. + // The only required property is 'opacity', even if it transitions from 1.0 to 1.0. The + // current value of the opacity transition is passed as uProgress to the shader. + // Tweaking the actor's scale during the transition only works properly for GNOME 3.38+. + // For this effect, windows should neither be scaled nor faded. static tweakTransition(actor, settings, forOpening) { return { diff --git a/src/Fire.js b/src/Fire.js index eecbeb0..b824c74 100644 --- a/src/Fire.js +++ b/src/Fire.js @@ -100,12 +100,15 @@ var Fire = class Fire { return new Shader(settings, forOpening); } - // This is also called from extension.js. It is used to tweak a window's open / close + // The tweakTransition() is called from extension.js to tweak a window's open / close // transitions - usually windows are faded in / out and scaled up / down by GNOME Shell. - // forOpening is set to true if this is called for a window-open transition, for a - // window-close transition it is set to false. The modes can be set to any value from - // here: https://gjs-docs.gnome.org/clutter8~8_api/clutter.animationmode. This also - // determines how the uProgress uniform value will progress in the shader. + // The parameter 'forOpening' is set to true if this is called for a window-open + // transition, for a window-close transition it is set to false. The modes can be set to + // any value from here: https://gjs-docs.gnome.org/clutter8~8_api/clutter.animationmode. + // The only required property is 'opacity', even if it transitions from 1.0 to 1.0. The + // current value of the opacity transition is passed as uProgress to the shader. + // Tweaking the actor's scale during the transition only works properly for GNOME 3.38+. + // For this effect, windows should neither be scaled nor faded. static tweakTransition(actor, settings, forOpening) { return { diff --git a/src/Matrix.js b/src/Matrix.js index 329ea42..bed7983 100644 --- a/src/Matrix.js +++ b/src/Matrix.js @@ -85,12 +85,15 @@ var Matrix = class Matrix { return new Shader(settings, forOpening); } - // This is also called from extension.js. It is used to tweak a window's open / close + // The tweakTransition() is called from extension.js to tweak a window's open / close // transitions - usually windows are faded in / out and scaled up / down by GNOME Shell. - // forOpening is set to true if this is called for a window-open transition, for a - // window-close transition it is set to false. The modes can be set to any value from - // here: https://gjs-docs.gnome.org/clutter8~8_api/clutter.animationmode. This also - // determines how the uProgress uniform value will progress in the shader. + // The parameter 'forOpening' is set to true if this is called for a window-open + // transition, for a window-close transition it is set to false. The modes can be set to + // any value from here: https://gjs-docs.gnome.org/clutter8~8_api/clutter.animationmode. + // The only required property is 'opacity', even if it transitions from 1.0 to 1.0. The + // current value of the opacity transition is passed as uProgress to the shader. + // Tweaking the actor's scale during the transition only works properly for GNOME 3.38+. + // For this effect, windows should not be faded but scaled vertically to allow for some // overshooting. static tweakTransition(actor, settings, forOpening) { diff --git a/src/TRexAttack.js b/src/TRexAttack.js index e161100..123c9dc 100644 --- a/src/TRexAttack.js +++ b/src/TRexAttack.js @@ -82,12 +82,15 @@ var TRexAttack = class TRexAttack { return new Shader(settings, forOpening); } - // This is also called from extension.js. It is used to tweak a window's open / close + // The tweakTransition() is called from extension.js to tweak a window's open / close // transitions - usually windows are faded in / out and scaled up / down by GNOME Shell. - // forOpening is set to true if this is called for a window-open transition, for a - // window-close transition it is set to false. The modes can be set to any value from - // here: https://gjs-docs.gnome.org/clutter8~8_api/clutter.animationmode. This also - // determines how the uProgress uniform value will progress in the shader. + // The parameter 'forOpening' is set to true if this is called for a window-open + // transition, for a window-close transition it is set to false. The modes can be set to + // any value from here: https://gjs-docs.gnome.org/clutter8~8_api/clutter.animationmode. + // The only required property is 'opacity', even if it transitions from 1.0 to 1.0. The + // current value of the opacity transition is passed as uProgress to the shader. + // Tweaking the actor's scale during the transition only works properly for GNOME 3.38+. + // For this effect, we slightly increase the window's scale as part of the warp effect. static tweakTransition(actor, settings, forOpening) { const warp = 1.0 + 0.5 * settings.get_double('claw-scratch-warp'); diff --git a/src/TVEffect.js b/src/TVEffect.js index e022f55..80be7bc 100644 --- a/src/TVEffect.js +++ b/src/TVEffect.js @@ -79,12 +79,15 @@ var TVEffect = class TVEffect { return new Shader(settings, forOpening); } - // This is also called from extension.js. It is used to tweak a window's open / close + // The tweakTransition() is called from extension.js to tweak a window's open / close // transitions - usually windows are faded in / out and scaled up / down by GNOME Shell. - // forOpening is set to true if this is called for a window-open transition, for a - // window-close transition it is set to false. The modes can be set to any value from - // here: https://gjs-docs.gnome.org/clutter8~8_api/clutter.animationmode. This also - // determines how the uProgress uniform value will progress in the shader. + // The parameter 'forOpening' is set to true if this is called for a window-open + // transition, for a window-close transition it is set to false. The modes can be set to + // any value from here: https://gjs-docs.gnome.org/clutter8~8_api/clutter.animationmode. + // The only required property is 'opacity', even if it transitions from 1.0 to 1.0. The + // current value of the opacity transition is passed as uProgress to the shader. + // Tweaking the actor's scale during the transition only works properly for GNOME 3.38+. + // For this effect, windows are scaled down vertically. static tweakTransition(actor, settings, forOpening) { return { diff --git a/src/Wisps.js b/src/Wisps.js index 4722af9..5d5f6b7 100644 --- a/src/Wisps.js +++ b/src/Wisps.js @@ -79,12 +79,15 @@ var Wisps = class Wisps { return new Shader(settings, forOpening); } - // This is also called from extension.js. It is used to tweak a window's open / close + // The tweakTransition() is called from extension.js to tweak a window's open / close // transitions - usually windows are faded in / out and scaled up / down by GNOME Shell. - // forOpening is set to true if this is called for a window-open transition, for a - // window-close transition it is set to false. The modes can be set to any value from - // here: https://gjs-docs.gnome.org/clutter8~8_api/clutter.animationmode. This also - // determines how the uProgress uniform value will progress in the shader. + // The parameter 'forOpening' is set to true if this is called for a window-open + // transition, for a window-close transition it is set to false. The modes can be set to + // any value from here: https://gjs-docs.gnome.org/clutter8~8_api/clutter.animationmode. + // The only required property is 'opacity', even if it transitions from 1.0 to 1.0. The + // current value of the opacity transition is passed as uProgress to the shader. + // Tweaking the actor's scale during the transition only works properly for GNOME 3.38+. + // For this effect, windows should be scaled down slightly but not faded. static tweakTransition(actor, settings, forOpening) { return { From f87a0a649b900230df4a8fe1ffe57487147f9111 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Fri, 28 Jan 2022 07:50:10 +0100 Subject: [PATCH 022/168] :wrench: Use opacity transition for uProgress --- extension.js | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/extension.js b/extension.js index dc33e09..9fdb8bc 100644 --- a/extension.js +++ b/extension.js @@ -97,7 +97,7 @@ class Extension { // actor. The window preview in the overview is basically a Clutter.Clone which // shows the original window. if (Main.overview.visible && !Main.overview.closing) { - const id = actor.connect('show', () => { + const id = actor.connect('notify::mapped', () => { extensionThis._setupEffect(actor, true); actor.disconnect(id); }); @@ -405,27 +405,21 @@ class Extension { transition = actor.get_transition(property); } - // For some reason, there are rare cases, where no transition is set up. We do not - // try to continue here... - if (!transition) { - utils.debug('Failed to set up transitions.'); - this._fixAnimationTimes(isDialogWindow, forOpening, null); - return; + // Tweak the transition according to the config object. For some reason, there are + // rare cases, where no transition is set up. This happens from time to time... + if (transition) { + transition.set_duration(duration); + transition.set_to(config[property].to); + transition.set_from(config[property].from); + transition.set_progress_mode(config[property].mode); } - - // Tweak the transition according to the config object. - transition.set_duration(duration); - transition.set_to(config[property].to); - transition.set_from(config[property].from); - transition.set_progress_mode(config[property].mode); } - // There should always be a scale-y transitions. Once this is finished, we restore the - // original actor size. - const transition = actor.get_transition('scale-y'); - transition.connect('completed', () => { + // Once the transitions are finished, we restore the original actor size. + actor.connect('transitions-completed', () => { actor.scale_x = 1.0; actor.scale_y = 1.0; + actor.opacity = forOpening ? 1.0 : 0.0; }); // -------------------------------------------------------------------- add the shader @@ -434,6 +428,15 @@ class Extension { const shader = this._currentEffect.createShader(actor, this._settings, forOpening); if (shader) { + // There should always be an opacity transition going on... + const transition = actor.get_transition('opacity'); + + if (!transition) { + this._fixAnimationTimes(isDialogWindow, forOpening, null); + utils.debug('Cannot setup shader without opacity transition.') + return; + } + // First remove any old effect. actor.remove_effect_by_name(`burn-my-windows-effect`); actor.add_effect_with_name(`burn-my-windows-effect`, shader); From bcb7619d3703bee866fe352e9b4db7387bdc2cc5 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Fri, 28 Jan 2022 07:54:20 +0100 Subject: [PATCH 023/168] :wrench: Disconnect from transitions-completed --- extension.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/extension.js b/extension.js index 9fdb8bc..cfa8dfc 100644 --- a/extension.js +++ b/extension.js @@ -416,10 +416,12 @@ class Extension { } // Once the transitions are finished, we restore the original actor size. - actor.connect('transitions-completed', () => { + const connectionID = actor.connect('transitions-completed', () => { actor.scale_x = 1.0; actor.scale_y = 1.0; actor.opacity = forOpening ? 1.0 : 0.0; + + actor.disconnect(connectionID); }); // -------------------------------------------------------------------- add the shader From c41bef6413b60c1b6056837c8ed518184a7d16fb Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Fri, 28 Jan 2022 14:04:40 +0100 Subject: [PATCH 024/168] :beetle: Fix occasional empty window --- extension.js | 103 +++++++++++++++++++++++++-------------------------- 1 file changed, 51 insertions(+), 52 deletions(-) diff --git a/extension.js b/extension.js index cfa8dfc..63e7ba6 100644 --- a/extension.js +++ b/extension.js @@ -75,10 +75,11 @@ class Extension { const extensionThis = this; // We will monkey-patch these methods. Let's store the original ones. - this._origAddWindowClone = Workspace.prototype._addWindowClone; - this._origWindowRemoved = Workspace.prototype._windowRemoved; - this._origDoRemoveWindow = Workspace.prototype._doRemoveWindow; - this._origShouldAnimateActor = WindowManager.prototype._shouldAnimateActor; + this._origAddWindowClone = Workspace.prototype._addWindowClone; + this._origWindowRemoved = Workspace.prototype._windowRemoved; + this._origDoRemoveWindow = Workspace.prototype._doRemoveWindow; + this._origShouldAnimateActor = WindowManager.prototype._shouldAnimateActor; + this._origWaitForOverviewToHide = WindowManager.prototype._waitForOverviewToHide; // We will also override these animation times. this._origWindowTime = imports.ui.windowManager.DESTROY_WINDOW_ANIMATION_TIME; @@ -88,38 +89,28 @@ class Extension { // ------------------------------------------------ patching the window-open animation // Here we add an effect to the window-open animation. This is done whenever a new - // window is created. + // window is created. Usually, there is no real window animation for opening windows + // in the overview - only the window's clone is animated - but thanks to the hacks + // below, we can show the real animations in 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#L1449 + // 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 - the next time it will be + // called by the _mapWindow(), we will intercept it! this._windowCreatedConnection = global.display.connect('window-created', (d, metaWin) => { let actor = metaWin.get_compositor_private(); - // If we are currently in the overview, we add the effect to the original window - // actor. The window preview in the overview is basically a Clutter.Clone which - // shows the original window. - if (Main.overview.visible && !Main.overview.closing) { - const id = actor.connect('notify::mapped', () => { - extensionThis._setupEffect(actor, true); - actor.disconnect(id); - }); + const orig = actor.ease; + actor.ease = function(...params) { + orig.apply(actor, params); + actor.ease = orig; - } - // If a window is created outside of the overview, the transitions are set up in - // the async _mapWindow of the WindowManager which can defer the actual showing - // of the window significantly, especially when currently leaving the overview: - // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/windowManager.js#L1449 - // 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 - the next time it will be - // called by the _mapWindow(), we will intercept it! - else { - const orig = actor.ease; - actor.ease = function(...params) { - orig.apply(actor, params); - actor.ease = orig; - - extensionThis._setupEffect(actor, true); - }; - } + extensionThis._setupEffect(actor, true); + }; }); // Some of the effects require that the window's actor is enlarged to provide a bigger @@ -147,13 +138,13 @@ class Extension { // Shell 3.38+. So effects cannot scale windows in the overview of GNOME 3.36... if (utils.shellVersionIsAtLeast(3, 38)) { const xID = realWindow.connect('notify::scale-x', () => { - if (realWindow.scale_x > 0) { + if (realWindow.scale_x > 0 && clone.allocation.get_size()[0] > 0) { clone.scale_x = realWindow.scale_x; } }); const yID = realWindow.connect('notify::scale-y', () => { - if (realWindow.scale_y > 0) { + if (realWindow.scale_y > 0 && clone.allocation.get_size()[1] > 0) { clone.scale_y = realWindow.scale_y; } }); @@ -164,7 +155,7 @@ class Extension { }); } - // This is actually need for the window-close animation on GNOME Shell 3.36. + // This is actually needed for the window-close animation on GNOME Shell 3.36. // On GNOME 3.36, the window clone's 'destroy' handler only calls _removeWindowClone // but not _doRemoveWindow. The latter is required to trigger the repositioning of // the overview window layout. Therefore we call this method in addition. @@ -177,6 +168,27 @@ class Extension { return result; }; + // Usually, windows are faded in after the overview is completely hidden. We enable + // window-open animations by not waiting for this. + WindowManager.prototype._waitForOverviewToHide = async function() { + return Promise.resolve(); + }; + + // Here comes the ULTRA-HACK: The method below is called (amongst others) by the + // _destroyWindow and _mapWindow methods of the WindowManager. Usually, it returns + // false when we are in the overview. This prevents the window animations. As we + // cannot monkey-patch the _destroyWindow or _mapWindow methods themselves, we check + // inside the method below whether it was called by either of those. If so, we return + // true. Let's see if this breaks stuff left and right... + // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/windowManager.js#L1125 + WindowManager.prototype._shouldAnimateActor = function(...params) { + const caller = (new Error()).stack.split('\n')[1]; + if (caller.includes('_destroyWindow@') || caller.includes('_mapWindow@')) { + return true; + } + return extensionThis._origShouldAnimateActor.apply(this, params); + }; + // ----------------------------------------------- patching the window-close animation @@ -213,20 +225,6 @@ class Extension { } }; - // Here comes the ULTRA-HACK: The method below is called (amongst others) by the - // _destroyWindow method of the WindowManager. Usually, it returns false when we are - // in the overview. This prevents the window-close animation. As we cannot - // monkey-patch the _destroyWindow method itself, we check inside the method below - // whether it was called by _destroyWindow. If so, we return true. Let's see if this - // breaks stuff left and right... - // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/ui/windowManager.js#L1125 - WindowManager.prototype._shouldAnimateActor = function(...params) { - if ((new Error()).stack.split('\n')[1].includes('_destroyWindow@')) { - return true; - } - return extensionThis._origShouldAnimateActor.apply(this, params); - }; - // With the code below, we hide the window-overlay (icon, label, close button) in the // overview once the close-animation is running. As the WindowPreview class is only // available on GNOME 3.38 and beyond, we cannot hide the overlay on GNOME 3.36. @@ -288,10 +286,11 @@ class Extension { global.window_manager.disconnect(this._destroyConnection); global.display.disconnect(this._windowCreatedConnection); - Workspace.prototype._addWindowClone = this._origAddWindowClone; - Workspace.prototype._windowRemoved = this._origWindowRemoved; - Workspace.prototype._doRemoveWindow = this._origDoRemoveWindow; - WindowManager.prototype._shouldAnimateActor = this._origShouldAnimateActor; + Workspace.prototype._addWindowClone = this._origAddWindowClone; + Workspace.prototype._windowRemoved = this._origWindowRemoved; + Workspace.prototype._doRemoveWindow = this._origDoRemoveWindow; + WindowManager.prototype._shouldAnimateActor = this._origShouldAnimateActor; + WindowManager.prototype._waitForOverviewToHide = this._origWaitForOverviewToHide; imports.ui.windowManager.DESTROY_WINDOW_ANIMATION_TIME = this._origWindowTime; imports.ui.windowManager.DIALOG_DESTROY_WINDOW_ANIMATION_TIME = this._origDialogTime; From d014ec2841c7d094956cfed05a85395f111c7dd6 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Fri, 28 Jan 2022 14:35:04 +0100 Subject: [PATCH 025/168] :wrench: Compile locales --- Makefile | 45 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/Makefile b/Makefile index 6dc34d4..c6d8430 100644 --- a/Makefile +++ b/Makefile @@ -1,9 +1,13 @@ SHELL := /bin/bash JS_FILES = $(shell find -type f -and \( -name "*.js" \)) +UI_FILES = $(shell find -type f -and \( -name "*.ui" \)) RESOURCE_FILES = $(shell find resources -mindepth 2 -type f) -.PHONY: zip install uninstall clean +LOCALES_PO = $(wildcard po/*.po) +LOCALES_MO = $(patsubst po/%.po,locale/%/LC_MESSAGES/burn-my-windows.mo,$(LOCALES_PO)) + +.PHONY: zip install uninstall all-po pot clean zip: burn-my-windows@schneegans.github.com.zip @@ -14,23 +18,31 @@ install: burn-my-windows@schneegans.github.com.zip uninstall: gnome-extensions uninstall "burn-my-windows@schneegans.github.com" +all-po: $(LOCALES_PO) + +pot: $(JS_FILES) $(UI_FILES) + @echo "Generating 'burn-my-windows.pot'..." + @xgettext --from-code=UTF-8 \ + --add-comments=Translators \ + --copyright-holder="Simon Schneegans" \ + --package-name="Burn-My-Windows" \ + --output=po/burn-my-windows.pot \ + $(JS_FILES) $(UI_FILES) + clean: rm -rf \ burn-my-windows@schneegans.github.com.zip \ resources/burn-my-windows.gresource \ resources/burn-my-windows.gresource.xml \ - schemas/gschemas.compiled + schemas/gschemas.compiled \ + locale \ + ui/*.ui~ \ + po/*.po~ -burn-my-windows@schneegans.github.com.zip: schemas/gschemas.compiled resources/burn-my-windows.gresource $(JS_FILES) - @# Check if the VERSION variable was passed and set version to it - @if [[ "$(VERSION)" != "" ]]; then \ - sed -i "s| \"version\":.*| \"version\": $(VERSION)|g" metadata.json; \ - fi - @# TODO Maybe echo version number of the release that was built, in order to facilitate double-checking before publishing it? - +burn-my-windows@schneegans.github.com.zip: schemas/gschemas.compiled resources/burn-my-windows.gresource $(JS_FILES) $(LOCALES_MO) @echo "Packing zip file..." @rm --force burn-my-windows@schneegans.github.com.zip - @zip -r burn-my-windows@schneegans.github.com.zip -- *.js src/*.js resources/burn-my-windows.gresource schemas/gschemas.compiled metadata.json LICENSE + @zip -r burn-my-windows@schneegans.github.com.zip -- *.js src/*.js resources/burn-my-windows.gresource schemas/gschemas.compiled $(LOCALES_MO) metadata.json LICENSE @#Check if the zip size is too big to be uploaded @if [[ "$$(stat -c %s burn-my-windows@schneegans.github.com.zip)" -gt 4096000 ]]; then \ @@ -48,4 +60,15 @@ resources/burn-my-windows.gresource.xml: $(RESOURCE_FILES) schemas/gschemas.compiled: schemas/org.gnome.shell.extensions.burn-my-windows.gschema.xml @echo "Compiling schemas..." - @glib-compile-schemas schemas \ No newline at end of file + @glib-compile-schemas schemas + +locale/%/LC_MESSAGES/burn-my-windows.mo: po/%.po + @echo "Compiling $@" + @mkdir -p locale/$*/LC_MESSAGES + @msgfmt -c -o $@ $< + +po/%.po: + @echo "Updating $@" + msgmerge --previous --update $@ po/burn-my-windows.pot + @# Output translation progress + @msgfmt --check --verbose --output-file=/dev/null $@ \ No newline at end of file From 1692be778c836059932f13f3e37fafed20377ee0 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Fri, 28 Jan 2022 14:35:23 +0100 Subject: [PATCH 026/168] :globe_with_meridians: Add initial translation template --- po/burn-my-windows.pot | 182 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 182 insertions(+) create mode 100644 po/burn-my-windows.pot diff --git a/po/burn-my-windows.pot b/po/burn-my-windows.pot new file mode 100644 index 0000000..2dc6f74 --- /dev/null +++ b/po/burn-my-windows.pot @@ -0,0 +1,182 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Simon Schneegans +# This file is distributed under the same license as the Burn-My-Windows package. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: Burn-My-Windows\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-01-28 14:12+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"Language: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: 8bit\n" + +#: resources/ui/common/main-menu.ui:6 +msgid "Visit Homepage" +msgstr "" + +#: resources/ui/common/main-menu.ui:10 +msgid "View Changelog" +msgstr "" + +#: resources/ui/common/main-menu.ui:16 +msgid "Report a Bug" +msgstr "" + +#: resources/ui/common/main-menu.ui:20 +msgid "Create a Custom Effect" +msgstr "" + +#: resources/ui/common/main-menu.ui:24 +msgid "Donate" +msgstr "" + +#: resources/ui/common/main-menu.ui:26 +msgid "Via PayPal" +msgstr "" + +#: resources/ui/common/main-menu.ui:30 +msgid "Via GitHub" +msgstr "" + +#: resources/ui/gtk4/Matrix.ui:24 resources/ui/gtk4/BrokenGlass.ui:24 +#: resources/ui/gtk4/Wisps.ui:24 resources/ui/gtk4/Fire.ui:49 +#: resources/ui/gtk4/TRexAttack.ui:24 resources/ui/gtk4/TVEffect.ui:24 +#: resources/ui/gtk4/EnergizeA.ui:24 resources/ui/gtk4/EnergizeB.ui:24 +#: resources/ui/gtk3/Wisps.ui:42 resources/ui/gtk3/Fire.ui:93 +#: resources/ui/gtk3/TVEffect.ui:35 resources/ui/gtk3/EnergizeA.ui:42 +#: resources/ui/gtk3/EnergizeB.ui:42 +msgid "Animation Time [ms]" +msgstr "" + +#: resources/ui/gtk4/Matrix.ui:70 resources/ui/gtk4/BrokenGlass.ui:70 +#: resources/ui/gtk4/Wisps.ui:70 resources/ui/gtk4/Fire.ui:95 +#: resources/ui/gtk4/EnergizeA.ui:70 resources/ui/gtk4/EnergizeB.ui:70 +#: resources/ui/gtk3/Wisps.ui:91 resources/ui/gtk3/Fire.ui:141 +#: resources/ui/gtk3/EnergizeA.ui:91 resources/ui/gtk3/EnergizeB.ui:91 +msgid "Scale" +msgstr "" + +#: resources/ui/gtk4/Matrix.ui:116 +msgid "Randomness" +msgstr "" + +#: resources/ui/gtk4/Matrix.ui:162 +msgid "Vertical Overshooting" +msgstr "" + +#: resources/ui/gtk4/Matrix.ui:208 +msgid "Trail Color" +msgstr "" + +#: resources/ui/gtk4/Matrix.ui:242 +msgid "Tip Color" +msgstr "" + +#: resources/ui/gtk4/BrokenGlass.ui:116 +msgid "Gravity" +msgstr "" + +#: resources/ui/gtk4/BrokenGlass.ui:162 +msgid "Blow Force" +msgstr "" + +#: resources/ui/gtk4/BrokenGlass.ui:212 +msgid "Shatter From Pointer Location" +msgstr "" + +#: resources/ui/gtk4/BrokenGlass.ui:221 +msgid "" +"The shards will fly away from where your mouse pointer was when closing the " +"window." +msgstr "" + +#: resources/ui/gtk4/Wisps.ui:116 resources/ui/gtk4/TVEffect.ui:70 +#: resources/ui/gtk4/EnergizeA.ui:116 resources/ui/gtk4/EnergizeB.ui:116 +#: resources/ui/gtk3/Wisps.ui:139 resources/ui/gtk3/TVEffect.ui:83 +#: resources/ui/gtk3/EnergizeA.ui:139 resources/ui/gtk3/EnergizeB.ui:139 +msgid "Color" +msgstr "" + +#: resources/ui/gtk4/Fire.ui:25 resources/ui/gtk3/Fire.ui:49 +msgid "Presets" +msgstr "" + +#: resources/ui/gtk4/Fire.ui:141 resources/ui/gtk3/Fire.ui:189 +msgid "Speed" +msgstr "" + +#: resources/ui/gtk4/Fire.ui:191 resources/ui/gtk3/Fire.ui:241 +msgid "3D Noise" +msgstr "" + +#: resources/ui/gtk4/Fire.ui:200 resources/ui/gtk3/Fire.ui:250 +msgid "Creates a more dynamic fire but requires more GPU power." +msgstr "" + +#: resources/ui/gtk4/Fire.ui:240 resources/ui/gtk3/Fire.ui:300 +msgid "Gradient" +msgstr "" + +#: resources/ui/gtk4/TRexAttack.ui:70 +msgid "Claw Scratch Scale" +msgstr "" + +#: resources/ui/gtk4/TRexAttack.ui:116 +msgid "Claw Scratch Count" +msgstr "" + +#: resources/ui/gtk4/TRexAttack.ui:162 +msgid "Warp Effect" +msgstr "" + +#: resources/ui/gtk4/TRexAttack.ui:208 +msgid "Flash Color" +msgstr "" + +#: resources/ui/gtk4/effectPage.ui:41 resources/ui/gtk3/effectPage.ui:41 +msgid "Preview this Effect" +msgstr "" + +#: resources/ui/gtk4/prefs.ui:27 resources/ui/gtk3/prefs.ui:251 +msgid "General Options" +msgstr "" + +#: resources/ui/gtk4/prefs.ui:47 resources/ui/gtk3/prefs.ui:49 +msgid "Welcome to Burn-My-Windows!" +msgstr "" + +#: resources/ui/gtk4/prefs.ui:58 resources/ui/gtk3/prefs.ui:60 +msgid "If you like this extension, recommend it to your friends :)" +msgstr "" + +#: resources/ui/gtk4/prefs.ui:85 resources/ui/gtk3/prefs.ui:88 +msgid "Open Window Animation" +msgstr "" + +#: resources/ui/gtk4/prefs.ui:94 resources/ui/gtk4/prefs.ui:138 +#: resources/ui/gtk3/prefs.ui:97 resources/ui/gtk3/prefs.ui:161 +msgid "If multiple are selected, one is chosen randomly." +msgstr "" + +#: resources/ui/gtk4/prefs.ui:129 resources/ui/gtk3/prefs.ui:152 +msgid "Close Window Animation" +msgstr "" + +#: resources/ui/gtk4/prefs.ui:169 resources/ui/gtk3/prefs.ui:212 +msgid "Also Add Effects to Dialogs" +msgstr "" + +#: resources/ui/gtk3/Fire.ui:63 +msgid "Choose a Preset" +msgstr "" + +#: resources/ui/gtk3/prefs.ui:118 resources/ui/gtk3/prefs.ui:182 +msgid "Choose Effects" +msgstr "" From fc902f2a736e258925929d4a24f6f52e6ecaf161 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Fri, 28 Jan 2022 15:00:22 +0100 Subject: [PATCH 027/168] :globe_with_meridians: Update translation template --- po/burn-my-windows.pot | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/po/burn-my-windows.pot b/po/burn-my-windows.pot index 2dc6f74..998acde 100644 --- a/po/burn-my-windows.pot +++ b/po/burn-my-windows.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Burn-My-Windows\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-01-28 14:12+0100\n" +"POT-Creation-Date: 2022-01-28 14:59+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,6 +17,10 @@ msgstr "" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" +#: prefs.js:355 +msgid "Close this Window to Preview the Effect!" +msgstr "" + #: resources/ui/common/main-menu.ui:6 msgid "Visit Homepage" msgstr "" From f9b6f1ffbc25523c9cb0da43ea2bb91448b8c0dd Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Fri, 28 Jan 2022 15:00:35 +0100 Subject: [PATCH 028/168] :wrench: Load translations --- prefs.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/prefs.js b/prefs.js index ffe9c17..2d5d93a 100644 --- a/prefs.js +++ b/prefs.js @@ -15,6 +15,8 @@ const {Gio, Gtk, Gdk, GLib, GObject} = imports.gi; +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; @@ -350,7 +352,7 @@ var PreferencesDialog = class PreferencesDialog { spacing: 10, }); - const label = Gtk.Label.new('Close this Window to Preview the Effect!'); + const label = Gtk.Label.new(_('Close this Window to Preview the Effect!')); label.get_style_context().add_class('large-title'); const image = new Gtk.Image({ @@ -376,8 +378,10 @@ var PreferencesDialog = class PreferencesDialog { } } -// Nothing to do for now... -function init() {} +// This is used for setting up the translations. +function init() { + ExtensionUtils.initTranslations(); +} // This function is called when the preferences window is created to build and return a // Gtk widget. We create a new instance of the PreferencesDialog class each time this From a3fa8254f74849f0c18bbd74495f7d500a4a6a96 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Fri, 28 Jan 2022 14:50:22 +0100 Subject: [PATCH 029/168] :globe_with_meridians: Added translation using Weblate (German) --- po/de.po | 181 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 po/de.po diff --git a/po/de.po b/po/de.po new file mode 100644 index 0000000..ea532e1 --- /dev/null +++ b/po/de.po @@ -0,0 +1,181 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Simon Schneegans +# This file is distributed under the same license as the Burn-My-Windows package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: Burn-My-Windows\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-01-28 14:12+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: resources/ui/common/main-menu.ui:6 +msgid "Visit Homepage" +msgstr "" + +#: resources/ui/common/main-menu.ui:10 +msgid "View Changelog" +msgstr "" + +#: resources/ui/common/main-menu.ui:16 +msgid "Report a Bug" +msgstr "" + +#: resources/ui/common/main-menu.ui:20 +msgid "Create a Custom Effect" +msgstr "" + +#: resources/ui/common/main-menu.ui:24 +msgid "Donate" +msgstr "" + +#: resources/ui/common/main-menu.ui:26 +msgid "Via PayPal" +msgstr "" + +#: resources/ui/common/main-menu.ui:30 +msgid "Via GitHub" +msgstr "" + +#: resources/ui/gtk4/Matrix.ui:24 resources/ui/gtk4/BrokenGlass.ui:24 +#: resources/ui/gtk4/Wisps.ui:24 resources/ui/gtk4/Fire.ui:49 +#: resources/ui/gtk4/TRexAttack.ui:24 resources/ui/gtk4/TVEffect.ui:24 +#: resources/ui/gtk4/EnergizeA.ui:24 resources/ui/gtk4/EnergizeB.ui:24 +#: resources/ui/gtk3/Wisps.ui:42 resources/ui/gtk3/Fire.ui:93 +#: resources/ui/gtk3/TVEffect.ui:35 resources/ui/gtk3/EnergizeA.ui:42 +#: resources/ui/gtk3/EnergizeB.ui:42 +msgid "Animation Time [ms]" +msgstr "" + +#: resources/ui/gtk4/Matrix.ui:70 resources/ui/gtk4/BrokenGlass.ui:70 +#: resources/ui/gtk4/Wisps.ui:70 resources/ui/gtk4/Fire.ui:95 +#: resources/ui/gtk4/EnergizeA.ui:70 resources/ui/gtk4/EnergizeB.ui:70 +#: resources/ui/gtk3/Wisps.ui:91 resources/ui/gtk3/Fire.ui:141 +#: resources/ui/gtk3/EnergizeA.ui:91 resources/ui/gtk3/EnergizeB.ui:91 +msgid "Scale" +msgstr "" + +#: resources/ui/gtk4/Matrix.ui:116 +msgid "Randomness" +msgstr "" + +#: resources/ui/gtk4/Matrix.ui:162 +msgid "Vertical Overshooting" +msgstr "" + +#: resources/ui/gtk4/Matrix.ui:208 +msgid "Trail Color" +msgstr "" + +#: resources/ui/gtk4/Matrix.ui:242 +msgid "Tip Color" +msgstr "" + +#: resources/ui/gtk4/BrokenGlass.ui:116 +msgid "Gravity" +msgstr "" + +#: resources/ui/gtk4/BrokenGlass.ui:162 +msgid "Blow Force" +msgstr "" + +#: resources/ui/gtk4/BrokenGlass.ui:212 +msgid "Shatter From Pointer Location" +msgstr "" + +#: resources/ui/gtk4/BrokenGlass.ui:221 +msgid "" +"The shards will fly away from where your mouse pointer was when closing the " +"window." +msgstr "" + +#: resources/ui/gtk4/Wisps.ui:116 resources/ui/gtk4/TVEffect.ui:70 +#: resources/ui/gtk4/EnergizeA.ui:116 resources/ui/gtk4/EnergizeB.ui:116 +#: resources/ui/gtk3/Wisps.ui:139 resources/ui/gtk3/TVEffect.ui:83 +#: resources/ui/gtk3/EnergizeA.ui:139 resources/ui/gtk3/EnergizeB.ui:139 +msgid "Color" +msgstr "" + +#: resources/ui/gtk4/Fire.ui:25 resources/ui/gtk3/Fire.ui:49 +msgid "Presets" +msgstr "" + +#: resources/ui/gtk4/Fire.ui:141 resources/ui/gtk3/Fire.ui:189 +msgid "Speed" +msgstr "" + +#: resources/ui/gtk4/Fire.ui:191 resources/ui/gtk3/Fire.ui:241 +msgid "3D Noise" +msgstr "" + +#: resources/ui/gtk4/Fire.ui:200 resources/ui/gtk3/Fire.ui:250 +msgid "Creates a more dynamic fire but requires more GPU power." +msgstr "" + +#: resources/ui/gtk4/Fire.ui:240 resources/ui/gtk3/Fire.ui:300 +msgid "Gradient" +msgstr "" + +#: resources/ui/gtk4/TRexAttack.ui:70 +msgid "Claw Scratch Scale" +msgstr "" + +#: resources/ui/gtk4/TRexAttack.ui:116 +msgid "Claw Scratch Count" +msgstr "" + +#: resources/ui/gtk4/TRexAttack.ui:162 +msgid "Warp Effect" +msgstr "" + +#: resources/ui/gtk4/TRexAttack.ui:208 +msgid "Flash Color" +msgstr "" + +#: resources/ui/gtk4/effectPage.ui:41 resources/ui/gtk3/effectPage.ui:41 +msgid "Preview this Effect" +msgstr "" + +#: resources/ui/gtk4/prefs.ui:27 resources/ui/gtk3/prefs.ui:251 +msgid "General Options" +msgstr "" + +#: resources/ui/gtk4/prefs.ui:47 resources/ui/gtk3/prefs.ui:49 +msgid "Welcome to Burn-My-Windows!" +msgstr "" + +#: resources/ui/gtk4/prefs.ui:58 resources/ui/gtk3/prefs.ui:60 +msgid "If you like this extension, recommend it to your friends :)" +msgstr "" + +#: resources/ui/gtk4/prefs.ui:85 resources/ui/gtk3/prefs.ui:88 +msgid "Open Window Animation" +msgstr "" + +#: resources/ui/gtk4/prefs.ui:94 resources/ui/gtk4/prefs.ui:138 +#: resources/ui/gtk3/prefs.ui:97 resources/ui/gtk3/prefs.ui:161 +msgid "If multiple are selected, one is chosen randomly." +msgstr "" + +#: resources/ui/gtk4/prefs.ui:129 resources/ui/gtk3/prefs.ui:152 +msgid "Close Window Animation" +msgstr "" + +#: resources/ui/gtk4/prefs.ui:169 resources/ui/gtk3/prefs.ui:212 +msgid "Also Add Effects to Dialogs" +msgstr "" + +#: resources/ui/gtk3/Fire.ui:63 +msgid "Choose a Preset" +msgstr "" + +#: resources/ui/gtk3/prefs.ui:118 resources/ui/gtk3/prefs.ui:182 +msgid "Choose Effects" +msgstr "" From b95fbac409407046436d537de878149af64902ce Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Fri, 28 Jan 2022 13:52:16 +0000 Subject: [PATCH 030/168] :globe_with_meridians: Translated using Weblate (German) --- po/de.po | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/po/de.po b/po/de.po index ea532e1..55ef13f 100644 --- a/po/de.po +++ b/po/de.po @@ -8,41 +8,44 @@ msgstr "" "Project-Id-Version: Burn-My-Windows\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-01-28 14:12+0100\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: Automatically generated\n" -"Language-Team: none\n" +"PO-Revision-Date: 2022-01-28 13:52+0000\n" +"Last-Translator: Simon Schneegans \n" +"Language-Team: German \n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 4.11-dev\n" #: resources/ui/common/main-menu.ui:6 msgid "Visit Homepage" -msgstr "" +msgstr "Homepage besuchen" #: resources/ui/common/main-menu.ui:10 msgid "View Changelog" -msgstr "" +msgstr "Changelog anzeigen" #: resources/ui/common/main-menu.ui:16 msgid "Report a Bug" -msgstr "" +msgstr "Fehler melden" #: resources/ui/common/main-menu.ui:20 msgid "Create a Custom Effect" -msgstr "" +msgstr "Einen neuen Effekt erstellen" #: resources/ui/common/main-menu.ui:24 msgid "Donate" -msgstr "" +msgstr "Spenden" #: resources/ui/common/main-menu.ui:26 msgid "Via PayPal" -msgstr "" +msgstr "Mit PayPal" #: resources/ui/common/main-menu.ui:30 msgid "Via GitHub" -msgstr "" +msgstr "Mit GitHub" #: resources/ui/gtk4/Matrix.ui:24 resources/ui/gtk4/BrokenGlass.ui:24 #: resources/ui/gtk4/Wisps.ui:24 resources/ui/gtk4/Fire.ui:49 From 357c5063704b852f6d3005c75513713b9de8e5da Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Fri, 28 Jan 2022 20:09:19 +0100 Subject: [PATCH 031/168] :wrench: Add another translatable string --- .gitignore | 1 + po/burn-my-windows.pot | 10 ++++++++-- prefs.js | 3 ++- resources/ui/gtk3/prefs.ui | 2 +- resources/ui/gtk4/prefs.ui | 2 +- 5 files changed, 13 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 77585ec..11da693 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ *.blend1 *.blend2 *.blend3 +/locale /schemas/gschemas.compiled /resources/burn-my-windows.gresource /resources/burn-my-windows.gresource.xml \ No newline at end of file diff --git a/po/burn-my-windows.pot b/po/burn-my-windows.pot index 998acde..a9c5f3b 100644 --- a/po/burn-my-windows.pot +++ b/po/burn-my-windows.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: Burn-My-Windows\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-01-28 14:59+0100\n" +"POT-Creation-Date: 2022-01-28 20:08+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,7 +17,13 @@ msgstr "" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" -#: prefs.js:355 +#. Translators: %s will be replaced by the effect's name. +#: prefs.js:336 +#, javascript-format +msgid "Preview for %s" +msgstr "" + +#: prefs.js:356 msgid "Close this Window to Preview the Effect!" msgstr "" diff --git a/prefs.js b/prefs.js index 2d5d93a..26e2a23 100644 --- a/prefs.js +++ b/prefs.js @@ -332,7 +332,8 @@ var PreferencesDialog = class PreferencesDialog { // Create the preview-window. const window = new Gtk.Window({ - title: `Preview for ${Effect.getLabel()}`, + // Translators: %s will be replaced by the effect's name. + title: _('Preview for %s').replace("%s", Effect.getLabel()), default_width: 800, default_height: 450, modal: true, diff --git a/resources/ui/gtk3/prefs.ui b/resources/ui/gtk3/prefs.ui index 708d1f5..b52ebf4 100644 --- a/resources/ui/gtk3/prefs.ui +++ b/resources/ui/gtk3/prefs.ui @@ -1,5 +1,5 @@ - + diff --git a/resources/ui/gtk4/prefs.ui b/resources/ui/gtk4/prefs.ui index a4182b1..02ea86b 100644 --- a/resources/ui/gtk4/prefs.ui +++ b/resources/ui/gtk4/prefs.ui @@ -1,5 +1,5 @@ - + From 9d324bfff3175bb01aa674285b15d088fbe82d9a Mon Sep 17 00:00:00 2001 From: "J. Lavoie" Date: Fri, 28 Jan 2022 19:12:43 +0100 Subject: [PATCH 032/168] :globe_with_meridians: Added translation using Weblate (French) --- po/fr.po | 185 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 po/fr.po diff --git a/po/fr.po b/po/fr.po new file mode 100644 index 0000000..cbd992a --- /dev/null +++ b/po/fr.po @@ -0,0 +1,185 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Simon Schneegans +# This file is distributed under the same license as the Burn-My-Windows package. +# FIRST AUTHOR , YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: Burn-My-Windows\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2022-01-28 14:59+0100\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: fr\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: prefs.js:355 +msgid "Close this Window to Preview the Effect!" +msgstr "" + +#: resources/ui/common/main-menu.ui:6 +msgid "Visit Homepage" +msgstr "" + +#: resources/ui/common/main-menu.ui:10 +msgid "View Changelog" +msgstr "" + +#: resources/ui/common/main-menu.ui:16 +msgid "Report a Bug" +msgstr "" + +#: resources/ui/common/main-menu.ui:20 +msgid "Create a Custom Effect" +msgstr "" + +#: resources/ui/common/main-menu.ui:24 +msgid "Donate" +msgstr "" + +#: resources/ui/common/main-menu.ui:26 +msgid "Via PayPal" +msgstr "" + +#: resources/ui/common/main-menu.ui:30 +msgid "Via GitHub" +msgstr "" + +#: resources/ui/gtk4/Matrix.ui:24 resources/ui/gtk4/BrokenGlass.ui:24 +#: resources/ui/gtk4/Wisps.ui:24 resources/ui/gtk4/Fire.ui:49 +#: resources/ui/gtk4/TRexAttack.ui:24 resources/ui/gtk4/TVEffect.ui:24 +#: resources/ui/gtk4/EnergizeA.ui:24 resources/ui/gtk4/EnergizeB.ui:24 +#: resources/ui/gtk3/Wisps.ui:42 resources/ui/gtk3/Fire.ui:93 +#: resources/ui/gtk3/TVEffect.ui:35 resources/ui/gtk3/EnergizeA.ui:42 +#: resources/ui/gtk3/EnergizeB.ui:42 +msgid "Animation Time [ms]" +msgstr "" + +#: resources/ui/gtk4/Matrix.ui:70 resources/ui/gtk4/BrokenGlass.ui:70 +#: resources/ui/gtk4/Wisps.ui:70 resources/ui/gtk4/Fire.ui:95 +#: resources/ui/gtk4/EnergizeA.ui:70 resources/ui/gtk4/EnergizeB.ui:70 +#: resources/ui/gtk3/Wisps.ui:91 resources/ui/gtk3/Fire.ui:141 +#: resources/ui/gtk3/EnergizeA.ui:91 resources/ui/gtk3/EnergizeB.ui:91 +msgid "Scale" +msgstr "" + +#: resources/ui/gtk4/Matrix.ui:116 +msgid "Randomness" +msgstr "" + +#: resources/ui/gtk4/Matrix.ui:162 +msgid "Vertical Overshooting" +msgstr "" + +#: resources/ui/gtk4/Matrix.ui:208 +msgid "Trail Color" +msgstr "" + +#: resources/ui/gtk4/Matrix.ui:242 +msgid "Tip Color" +msgstr "" + +#: resources/ui/gtk4/BrokenGlass.ui:116 +msgid "Gravity" +msgstr "" + +#: resources/ui/gtk4/BrokenGlass.ui:162 +msgid "Blow Force" +msgstr "" + +#: resources/ui/gtk4/BrokenGlass.ui:212 +msgid "Shatter From Pointer Location" +msgstr "" + +#: resources/ui/gtk4/BrokenGlass.ui:221 +msgid "" +"The shards will fly away from where your mouse pointer was when closing the " +"window." +msgstr "" + +#: resources/ui/gtk4/Wisps.ui:116 resources/ui/gtk4/TVEffect.ui:70 +#: resources/ui/gtk4/EnergizeA.ui:116 resources/ui/gtk4/EnergizeB.ui:116 +#: resources/ui/gtk3/Wisps.ui:139 resources/ui/gtk3/TVEffect.ui:83 +#: resources/ui/gtk3/EnergizeA.ui:139 resources/ui/gtk3/EnergizeB.ui:139 +msgid "Color" +msgstr "" + +#: resources/ui/gtk4/Fire.ui:25 resources/ui/gtk3/Fire.ui:49 +msgid "Presets" +msgstr "" + +#: resources/ui/gtk4/Fire.ui:141 resources/ui/gtk3/Fire.ui:189 +msgid "Speed" +msgstr "" + +#: resources/ui/gtk4/Fire.ui:191 resources/ui/gtk3/Fire.ui:241 +msgid "3D Noise" +msgstr "" + +#: resources/ui/gtk4/Fire.ui:200 resources/ui/gtk3/Fire.ui:250 +msgid "Creates a more dynamic fire but requires more GPU power." +msgstr "" + +#: resources/ui/gtk4/Fire.ui:240 resources/ui/gtk3/Fire.ui:300 +msgid "Gradient" +msgstr "" + +#: resources/ui/gtk4/TRexAttack.ui:70 +msgid "Claw Scratch Scale" +msgstr "" + +#: resources/ui/gtk4/TRexAttack.ui:116 +msgid "Claw Scratch Count" +msgstr "" + +#: resources/ui/gtk4/TRexAttack.ui:162 +msgid "Warp Effect" +msgstr "" + +#: resources/ui/gtk4/TRexAttack.ui:208 +msgid "Flash Color" +msgstr "" + +#: resources/ui/gtk4/effectPage.ui:41 resources/ui/gtk3/effectPage.ui:41 +msgid "Preview this Effect" +msgstr "" + +#: resources/ui/gtk4/prefs.ui:27 resources/ui/gtk3/prefs.ui:251 +msgid "General Options" +msgstr "" + +#: resources/ui/gtk4/prefs.ui:47 resources/ui/gtk3/prefs.ui:49 +msgid "Welcome to Burn-My-Windows!" +msgstr "" + +#: resources/ui/gtk4/prefs.ui:58 resources/ui/gtk3/prefs.ui:60 +msgid "If you like this extension, recommend it to your friends :)" +msgstr "" + +#: resources/ui/gtk4/prefs.ui:85 resources/ui/gtk3/prefs.ui:88 +msgid "Open Window Animation" +msgstr "" + +#: resources/ui/gtk4/prefs.ui:94 resources/ui/gtk4/prefs.ui:138 +#: resources/ui/gtk3/prefs.ui:97 resources/ui/gtk3/prefs.ui:161 +msgid "If multiple are selected, one is chosen randomly." +msgstr "" + +#: resources/ui/gtk4/prefs.ui:129 resources/ui/gtk3/prefs.ui:152 +msgid "Close Window Animation" +msgstr "" + +#: resources/ui/gtk4/prefs.ui:169 resources/ui/gtk3/prefs.ui:212 +msgid "Also Add Effects to Dialogs" +msgstr "" + +#: resources/ui/gtk3/Fire.ui:63 +msgid "Choose a Preset" +msgstr "" + +#: resources/ui/gtk3/prefs.ui:118 resources/ui/gtk3/prefs.ui:182 +msgid "Choose Effects" +msgstr "" From 58244cfbb4168fec25bbe75d8b752b36ab1b9806 Mon Sep 17 00:00:00 2001 From: Hosted Weblate Date: Fri, 28 Jan 2022 20:05:55 +0100 Subject: [PATCH 033/168] :globe_with_meridians: Update translation files --- po/de.po | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/po/de.po b/po/de.po index 55ef13f..f35d0ab 100644 --- a/po/de.po +++ b/po/de.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Burn-My-Windows\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-01-28 14:12+0100\n" +"POT-Creation-Date: 2022-01-28 14:59+0100\n" "PO-Revision-Date: 2022-01-28 13:52+0000\n" "Last-Translator: Simon Schneegans \n" "Language-Team: German Date: Fri, 28 Jan 2022 20:09:32 +0100 Subject: [PATCH 034/168] :globe_with_meridians: Update translation files --- po/de.po | 10 ++++++++-- po/fr.po | 10 ++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/po/de.po b/po/de.po index f35d0ab..dbbaa35 100644 --- a/po/de.po +++ b/po/de.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: Burn-My-Windows\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-01-28 14:59+0100\n" +"POT-Creation-Date: 2022-01-28 20:08+0100\n" "PO-Revision-Date: 2022-01-28 13:52+0000\n" "Last-Translator: Simon Schneegans \n" "Language-Team: German Date: Fri, 28 Jan 2022 19:09:51 +0000 Subject: [PATCH 035/168] :globe_with_meridians: Translated using Weblate (German) --- po/de.po | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/po/de.po b/po/de.po index dbbaa35..5f0b32d 100644 --- a/po/de.po +++ b/po/de.po @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: Burn-My-Windows\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2022-01-28 20:08+0100\n" -"PO-Revision-Date: 2022-01-28 13:52+0000\n" +"PO-Revision-Date: 2022-01-28 19:10+0000\n" "Last-Translator: Simon Schneegans \n" "Language-Team: German \n" @@ -23,11 +23,11 @@ msgstr "" #: prefs.js:336 #, javascript-format msgid "Preview for %s" -msgstr "" +msgstr "Vorschau für %s" #: prefs.js:356 msgid "Close this Window to Preview the Effect!" -msgstr "" +msgstr "Schließen Sie dieses Fenster, um eine Vorschau des Effekts anzuzeigen!" #: resources/ui/common/main-menu.ui:6 msgid "Visit Homepage" From e92ab9fe187c9d342155ec8cfe82ac023cf87164 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Fri, 28 Jan 2022 20:26:28 +0100 Subject: [PATCH 036/168] :lipstick: Improve appearance of preview window --- prefs.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/prefs.js b/prefs.js index 26e2a23..9d383c0 100644 --- a/prefs.js +++ b/prefs.js @@ -351,9 +351,13 @@ var PreferencesDialog = class PreferencesDialog { orientation: Gtk.Orientation.VERTICAL, valign: Gtk.Align.CENTER, spacing: 10, + margin_start:50, + margin_end:50 }); const label = Gtk.Label.new(_('Close this Window to Preview the Effect!')); + label.wrap = true; + label.justify = Gtk.Justification.CENTER; label.get_style_context().add_class('large-title'); const image = new Gtk.Image({ From 65969ce7a6ed2c8d33cb444648b36641296ba444 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Fri, 28 Jan 2022 20:29:38 +0100 Subject: [PATCH 037/168] :wrench: Add translation domains --- resources/ui/common/main-menu.ui | 2 +- resources/ui/gtk3/EnergizeA.ui | 2 +- resources/ui/gtk3/EnergizeB.ui | 2 +- resources/ui/gtk3/Fire.ui | 2 +- resources/ui/gtk3/TVEffect.ui | 2 +- resources/ui/gtk3/Wisps.ui | 2 +- resources/ui/gtk3/effectPage.ui | 2 +- resources/ui/gtk4/BrokenGlass.ui | 2 +- resources/ui/gtk4/EnergizeA.ui | 2 +- resources/ui/gtk4/EnergizeB.ui | 2 +- resources/ui/gtk4/Fire.ui | 2 +- resources/ui/gtk4/Matrix.ui | 2 +- resources/ui/gtk4/TRexAttack.ui | 2 +- resources/ui/gtk4/TVEffect.ui | 2 +- resources/ui/gtk4/Wisps.ui | 2 +- resources/ui/gtk4/effectPage.ui | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) diff --git a/resources/ui/common/main-menu.ui b/resources/ui/common/main-menu.ui index 0d8a0b8..94a86b8 100644 --- a/resources/ui/common/main-menu.ui +++ b/resources/ui/common/main-menu.ui @@ -1,5 +1,5 @@ - +
diff --git a/resources/ui/gtk3/EnergizeA.ui b/resources/ui/gtk3/EnergizeA.ui index 79afebc..d4e6bc0 100644 --- a/resources/ui/gtk3/EnergizeA.ui +++ b/resources/ui/gtk3/EnergizeA.ui @@ -1,5 +1,5 @@ - + 10000 diff --git a/resources/ui/gtk3/EnergizeB.ui b/resources/ui/gtk3/EnergizeB.ui index 051821d..c691889 100644 --- a/resources/ui/gtk3/EnergizeB.ui +++ b/resources/ui/gtk3/EnergizeB.ui @@ -1,5 +1,5 @@ - + 10000 diff --git a/resources/ui/gtk3/Fire.ui b/resources/ui/gtk3/Fire.ui index 4b43025..3417f83 100644 --- a/resources/ui/gtk3/Fire.ui +++ b/resources/ui/gtk3/Fire.ui @@ -1,5 +1,5 @@ - + 10000 diff --git a/resources/ui/gtk3/TVEffect.ui b/resources/ui/gtk3/TVEffect.ui index adebe01..e5206da 100644 --- a/resources/ui/gtk3/TVEffect.ui +++ b/resources/ui/gtk3/TVEffect.ui @@ -1,5 +1,5 @@ - + 5000 diff --git a/resources/ui/gtk3/Wisps.ui b/resources/ui/gtk3/Wisps.ui index ff096ae..2cec6ef 100644 --- a/resources/ui/gtk3/Wisps.ui +++ b/resources/ui/gtk3/Wisps.ui @@ -1,5 +1,5 @@ - + 10000 diff --git a/resources/ui/gtk3/effectPage.ui b/resources/ui/gtk3/effectPage.ui index 2ec5311..52419a5 100644 --- a/resources/ui/gtk3/effectPage.ui +++ b/resources/ui/gtk3/effectPage.ui @@ -1,5 +1,5 @@ - +