From 8fdc958cb9f21b167c5a2853ef09a48ba0d4fee3 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Wed, 11 Jan 2023 05:50:39 +0100 Subject: [PATCH 01/67] :wrench: Start thinking about application profiles --- prefs.js | 9 +- .../actions/bmw-select-app-symbolic.svg | 55 +++++++ resources/ui/adw/prefs.ui | 147 ++++++++---------- 3 files changed, 126 insertions(+), 85 deletions(-) create mode 100644 resources/img/scalable/actions/bmw-select-app-symbolic.svg diff --git a/prefs.js b/prefs.js index 5ab36a1..76f9201 100644 --- a/prefs.js +++ b/prefs.js @@ -101,11 +101,6 @@ var PreferencesDialog = class PreferencesDialog { this._builder.add_from_resource(`/ui/common/main-menu.ui`); this._builder.add_from_resource(`/ui/${utils.getUIDir()}/prefs.ui`); - // Bind general options properties. - this.bindSwitch('destroy-dialogs'); - this.bindSwitch('disable-on-battery'); - this.bindSwitch('disable-on-power-save'); - // Check whether the power profiles daemon is available - if not, we hide the // corresponding settings row. const PowerProfilesProxy = Gio.DBusProxy.makeProxyWrapper( @@ -131,8 +126,7 @@ var PreferencesDialog = class PreferencesDialog { this.gtkBoxAppend(this._widget, generalPrefs); // Then add a preferences group for the effect expander rows. - const group = new Adw.PreferencesGroup({title: _('Effects')}); - this.gtkBoxAppend(this._widget, group); + const group = this._builder.get_object('effects-group'); // This stores all expander rows for the effects. We use this to implement the // accordion-functionality of the effect settings. @@ -280,6 +274,7 @@ var PreferencesDialog = class PreferencesDialog { if (Adw && utils.shellVersionIsAtLeast(42, 'beta')) { const header = this._findWidgetByType(window.get_content(), Adw.HeaderBar); header.pack_start(menu); + header.set_title_widget(this._builder.get_object('profile-button')); // Allow closing of the sub pages. window.can_navigate_back = true; diff --git a/resources/img/scalable/actions/bmw-select-app-symbolic.svg b/resources/img/scalable/actions/bmw-select-app-symbolic.svg new file mode 100644 index 0000000..2ad6301 --- /dev/null +++ b/resources/img/scalable/actions/bmw-select-app-symbolic.svg @@ -0,0 +1,55 @@ + + + + + + + + + + + + diff --git a/resources/ui/adw/prefs.ui b/resources/ui/adw/prefs.ui index 51a65c1..77e5b55 100644 --- a/resources/ui/adw/prefs.ui +++ b/resources/ui/adw/prefs.ui @@ -8,111 +8,102 @@ SPDX-License-Identifier: GPL-3.0-or-later + + center + + + Default Profile + center + + + + + edit-symbolic + center + + + + + main-menu heart-filled-symbolic - + vertical - 60 - 20 - - - - center - burn-my-windows-symbolic - 128 - - - - - - Welcome to Burn-My-Windows! - 8 - 6 - - - - - - - If you like this extension, recommend it to your friends :) - 36 - - - + + 20 - - Also Add Effects to Dialogs - destroy-dialogs + + Application - + + bmw-select-app-symbolic center - - - edit-clear-symbolic - center - Reset to Default Value - - - - - Disable on Battery Power - disable-on-battery - - - center + + Window Type + + + + Any + Normal Windows + Dialogs + - - - - edit-clear-symbolic - center - Reset to Default Value - - - + - - Disable in Power-Save Mode - disable-on-power-save - - - center + + Power Mode + + + + Any + On Battery + Plugged In + - - - - edit-clear-symbolic - center - Reset to Default Value - - - + + + + Power Profile + + + + Any + Power Saver + Balanced + Performance + Power Saver or Balanced + Balanced or Performance + + + + + + + + + + + From 6def4e4a4a7856440a4d0d25f72dc6004b7f6e00 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Wed, 11 Jan 2023 20:13:08 +0100 Subject: [PATCH 02/67] :wrench: Try vertical flap --- resources/ui/adw/prefs.ui | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/resources/ui/adw/prefs.ui b/resources/ui/adw/prefs.ui index 77e5b55..5659c43 100644 --- a/resources/ui/adw/prefs.ui +++ b/resources/ui/adw/prefs.ui @@ -32,12 +32,18 @@ SPDX-License-Identifier: GPL-3.0-or-later heart-filled-symbolic - + vertical + true + true + false + false - + - 20 + @@ -102,11 +108,13 @@ SPDX-License-Identifier: GPL-3.0-or-later - + + + \ No newline at end of file From 532aad1341fe012dce4ffb004010fde6341bdfd4 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Thu, 12 Jan 2023 20:31:24 +0100 Subject: [PATCH 03/67] :wrench: Hack the flap into the widget tree --- prefs.js | 27 +++++-- resources/ui/adw/prefs.ui | 154 +++++++++++++++++++++----------------- 2 files changed, 106 insertions(+), 75 deletions(-) diff --git a/prefs.js b/prefs.js index 76f9201..b7a6746 100644 --- a/prefs.js +++ b/prefs.js @@ -119,11 +119,7 @@ var PreferencesDialog = class PreferencesDialog { if (utils.isADW()) { // This is our top-level widget which we will return later. - this._widget = new Gtk.Box({orientation: Gtk.Orientation.VERTICAL}); - - // Add the general options page to the settings dialog. - const generalPrefs = this._builder.get_object('general-prefs'); - this.gtkBoxAppend(this._widget, generalPrefs); + this._widget = this._builder.get_object('general-prefs'); // Then add a preferences group for the effect expander rows. const group = this._builder.get_object('effects-group'); @@ -276,8 +272,20 @@ var PreferencesDialog = class PreferencesDialog { header.pack_start(menu); header.set_title_widget(this._builder.get_object('profile-button')); - // Allow closing of the sub pages. - window.can_navigate_back = true; + const flap = this._builder.get_object('profile-editor-flap'); + const clamp = this._findWidgetByType(window.get_content(), Adw.Clamp); + const viewport = clamp.get_parent(); + viewport.get_parent().set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.NEVER); + viewport.set_child(flap); + + const scrolledWindow = Gtk.ScrolledWindow.new(); + scrolledWindow.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC); + scrolledWindow.set_propagate_natural_height(true); + scrolledWindow.set_vexpand(true); + scrolledWindow.set_child(clamp); + + flap.set_content(scrolledWindow); + } else { window.get_titlebar().pack_start(menu); } @@ -679,3 +687,8 @@ function buildPrefsWidget() { var dialog = new PreferencesDialog(); return dialog.getWidget(); } + +function fillPreferencesWindow(window) { + var dialog = new PreferencesDialog(); + window.add(dialog.getWidget()); +} \ No newline at end of file diff --git a/resources/ui/adw/prefs.ui b/resources/ui/adw/prefs.ui index 5659c43..8805e11 100644 --- a/resources/ui/adw/prefs.ui +++ b/resources/ui/adw/prefs.ui @@ -2,7 +2,8 @@ @@ -17,9 +18,13 @@ SPDX-License-Identifier: GPL-3.0-or-later - + edit-symbolic center + + + profile-editor-flap + - - main-menu - heart-filled-symbolic - - - + vertical - true - true - false - false - + natural + + + edit-profile-button + + - + - - - Application + + + 20 + 20 + 20 + 20 + - - bmw-select-app-symbolic - center + + Application + + + bmw-select-app-symbolic + center + + - - - - - Window Type - - - - Any - Normal Windows - Dialogs - + + + Window Type + + + + Any + Normal Windows + Dialogs + + + - - - + - - - Power Mode - - - - Any - On Battery - Plugged In - + + + Power Mode + + + + Any + On Battery + Plugged In + + + - - - + - - - Power Profile - - - - Any - Power Saver - Balanced - Performance - Power Saver or Balanced - Balanced or Performance - + + + Power Profile + + + + Any + Power Saver + Balanced + Performance + Power Saver or Balanced + Balanced or Performance + + + - - - + + + + - + + main-menu + heart-filled-symbolic + + + + + 20 + 20 + 20 + 20 - - - \ No newline at end of file From a4b9f70cc3ca817673d58c451e8691ed32efe01c Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Fri, 13 Jan 2023 20:41:28 +0100 Subject: [PATCH 04/67] :wrench: Work on effect profiles --- docs/how-to-create-new-effects.md | 16 +- extension.js | 10 +- prefs.js | 78 +----- resources/ui/adw/prefs.ui | 168 ++++++++---- resources/ui/gtk3/prefs.ui | 73 +----- resources/ui/gtk4/prefs.ui | 53 +--- ...ell.extensions.burn-my-windows.gschema.xml | 240 +++++------------- src/Apparition.js | 2 +- src/BrokenGlass.js | 2 +- src/Doom.js | 2 +- src/EnergizeA.js | 2 +- src/EnergizeB.js | 2 +- src/Fire.js | 2 +- src/Glide.js | 2 +- src/Glitch.js | 2 +- src/Hexagon.js | 2 +- src/Incinerate.js | 2 +- src/Matrix.js | 2 +- src/PixelWheel.js | 2 +- src/PixelWipe.js | 2 +- src/Pixelate.js | 2 +- src/Portal.js | 2 +- src/SnapOfDisintegration.js | 2 +- src/TRexAttack.js | 2 +- src/TVEffect.js | 2 +- src/Wisps.js | 2 +- 26 files changed, 231 insertions(+), 445 deletions(-) diff --git a/docs/how-to-create-new-effects.md b/docs/how-to-create-new-effects.md index 3452fa1..624d5fe 100644 --- a/docs/how-to-create-new-effects.md +++ b/docs/how-to-create-new-effects.md @@ -47,7 +47,7 @@ You will have to ... ### 1. Expanding the Schema -For enabling the new effect, the boolean settings keys `simple-fade-open-effect`, `simple-fade-close-effect`, and `simple-fade-animation-time` are required. +For enabling the new effect, the boolean settings keys `simple-fade-enable-effect` and `simple-fade-animation-time` are required. In this example, we also add a floating point value for storing another property of the effect - we will use them later in the tutorial. Just copy the XML code below to the file [`schemas/org.gnome.shell.extensions.burn-my-windows.gschema.xml`](../schemas/org.gnome.shell.extensions.burn-my-windows.gschema.xml). Just remember to replace `simple-fade` with your custom name! @@ -57,16 +57,10 @@ Just remember to replace `simple-fade` with your custom name! - + false - Simple Fade Close Effect - Use the Simple Fade effect for window closing. - - - - false - Simple Fade Open Effect - Use the Simple Fade effect for window opening. + Simple Fade Enable Effect + Use the Simple Fade effect. @@ -201,7 +195,7 @@ var SimpleFade = class { // This will be called in various places where a unique identifier for this effect is // required. It should match the prefix of the settings keys which store whether the - // effect is enabled currently (e.g. '*-close-effect'), and its animation time + // effect is enabled currently (e.g. '*-enable-effect'), and its animation time // (e.g. '*-animation-time'). getNick() { return 'simple-fade'; diff --git a/extension.js b/extension.js index 4462862..0125c70 100644 --- a/extension.js +++ b/extension.js @@ -379,8 +379,7 @@ class Extension { // 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'); + const previewNick = this._settings.get_string('preview-effect'); if (isDialogWindow && !shouldDestroyDialogs && previewNick == '') { this._fixAnimationTimes(isDialogWindow, forOpening, null); @@ -418,15 +417,16 @@ class Extension { effect = this._ALL_EFFECTS.find(effect => effect.getNick() == previewNick); // Only preview the effect once. - this._settings.set_string(action + '-preview-effect', ''); - + if (!forOpening) { + this._settings.set_string('preview-effect', ''); + } } // Else we choose a random effect from all enabled effects. else { // Therefore, we first create a list of all currently enabled effects. const enabled = this._ALL_EFFECTS.filter(effect => { - return this._settings.get_boolean(`${effect.getNick()}-${action}-effect`); + return this._settings.get_boolean(`${effect.getNick()}-enable-effect`); }); // And then choose a random effect. diff --git a/prefs.js b/prefs.js index b7a6746..9792544 100644 --- a/prefs.js +++ b/prefs.js @@ -155,53 +155,25 @@ var PreferencesDialog = class PreferencesDialog { } }); - // Add three buttons on the right. - const box = new Gtk.Box(); - box.set_spacing(8); - // The preview button. const previewButton = Gtk.Button.new_from_icon_name('bmw-preview-symbolic'); previewButton.add_css_class('circular'); previewButton.add_css_class('flat'); previewButton.set_tooltip_text(_('Preview this effect')); previewButton.set_valign(Gtk.Align.CENTER); - box.append(previewButton); + row.add_action(previewButton); previewButton.connect('clicked', () => { this._previewEffect(effect); }); // Now add the two toggle buttons for enabling and disabling the effect. - const addToggle = (action, tooltip) => { - const button = Gtk.ToggleButton.new(); - button.set_action_name( - `${action}-effects.${effect.getNick()}-${action}-effect`); - button.set_child( - Gtk.Image.new_from_icon_name(`bmw-window-${action}-symbolic`)); - button.set_tooltip_text(tooltip); - button.set_valign(Gtk.Align.CENTER); + const button = Gtk.Switch.new(); + button.set_action_name(`enabled-effects.${effect.getNick()}-enable-effect`); + button.set_tooltip_text(_('Use this effect')); + button.set_valign(Gtk.Align.CENTER); - // We switch some class when the button is enabled in order to make it more - // apparent which effects are currently in use. - button.add_css_class('circular'); - button.add_css_class('flat'); - button.connect('toggled', button => { - if (button.active) { - button.add_css_class('suggested-action'); - button.remove_css_class('flat'); - } else { - button.remove_css_class('suggested-action'); - button.add_css_class('flat'); - } - }); - - box.append(button); - }; - - addToggle('open', _('Use this effect when opening windows')); - addToggle('close', _('Use this effect when closing windows')); - - row.add_action(box); + row.add_prefix(button); group.add(row); this._effectRows.push(row); @@ -277,7 +249,7 @@ var PreferencesDialog = class PreferencesDialog { const viewport = clamp.get_parent(); viewport.get_parent().set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.NEVER); viewport.set_child(flap); - + const scrolledWindow = Gtk.ScrolledWindow.new(); scrolledWindow.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC); scrolledWindow.set_propagate_natural_height(true); @@ -407,47 +379,24 @@ var PreferencesDialog = class PreferencesDialog { group.add_action(aboutAction); } - // Populate the open-effects drop-down menu. + // Populate the enabled-effects drop-down menu. { const group = Gio.SimpleActionGroup.new(); - window.insert_action_group('open-effects', group); + window.insert_action_group('enabled-effects', group); this._ALL_EFFECTS.forEach(effect => { const [minMajor, minMinor] = effect.getMinShellVersion(); if (utils.shellVersionIsAtLeast(minMajor, minMinor)) { - const actionName = effect.getNick() + '-open-effect'; + const actionName = effect.getNick() + '-enable-effect'; const action = this._settings.create_action(actionName); group.add_action(action); // The menu only exists if not using libadwaita. With libadwaita, individual // ToggleButtons are used for triggering the above actions. if (!utils.isADW()) { - const menu = this._builder.get_object('open-effect-menu'); + const menu = this._builder.get_object('enabled-effects-menu'); const label = effect.getLabel(); - menu.append_item(Gio.MenuItem.new(label, 'open-effects.' + actionName)); - } - } - }); - } - - // Populate the close-effects drop-down menu. - { - const group = Gio.SimpleActionGroup.new(); - window.insert_action_group('close-effects', group); - - this._ALL_EFFECTS.forEach(effect => { - const [minMajor, minMinor] = effect.getMinShellVersion(); - if (utils.shellVersionIsAtLeast(minMajor, minMinor)) { - const actionName = effect.getNick() + '-close-effect'; - const action = this._settings.create_action(actionName); - group.add_action(action); - - // The menu only exists if not using libadwaita. With libadwaita, individual - // ToggleButtons are used for triggering the above actions. - if (!utils.isADW()) { - const menu = this._builder.get_object('close-effect-menu'); - const label = effect.getLabel(); - menu.append_item(Gio.MenuItem.new(label, 'close-effects.' + actionName)); + menu.append_item(Gio.MenuItem.new(label, 'enabled-effects.' + actionName)); } } }); @@ -592,8 +541,7 @@ var PreferencesDialog = class PreferencesDialog { _previewEffect(effect) { // Set the to-be-previewed effect. - this.getSettings().set_string('open-preview-effect', effect.getNick()); - this.getSettings().set_string('close-preview-effect', effect.getNick()); + this.getSettings().set_string('preview-effect', effect.getNick()); // Make sure that the window.show() firther below "sees" this change. Gio.Settings.sync(); diff --git a/resources/ui/adw/prefs.ui b/resources/ui/adw/prefs.ui index 8805e11..f04b4c8 100644 --- a/resources/ui/adw/prefs.ui +++ b/resources/ui/adw/prefs.ui @@ -47,69 +47,116 @@ GPL-3.0-or-later - + + vertical 20 20 20 - 20 + 20 + 20 - - Application + + + - - bmw-select-app-symbolic - center + + Choose an Application + + + bmw-select-app-symbolic + center + + + + + + Animation Type + + + + Any + Open Windows + Close Windows + + + + + + + + + Window Type + + + + Any + Normal Windows + Dialogs + + + + + + + + + Power Mode + + + + Any + On Battery + Plugged In + + + + + + + + + Power Profile + + + + Any + Power-Saver Mode + Balanced Mode + Performance Mode + Power Saver or Balanced + Balanced or Performance + + + + + + - - Window Type - - - - Any - Normal Windows - Dialogs - - - - - + - - - Power Mode - - - - Any - On Battery - Plugged In - + + + Delete this Profile... - - - + - - - Power Profile - - - - Any - Power Saver - Balanced - Performance - Power Saver or Balanced - Balanced or Performance - + + + end + true + system-help-symbolic + - + + @@ -131,6 +178,33 @@ GPL-3.0-or-later 20 20 20 + Effect Settings + If multiple are selected, one is chosen randomly. + + + + + + + + + + edit-paste-symbolic + + + + + + edit-paste-symbolic + + + + + + + diff --git a/resources/ui/gtk3/prefs.ui b/resources/ui/gtk3/prefs.ui index 6616832..4b88998 100644 --- a/resources/ui/gtk3/prefs.ui +++ b/resources/ui/gtk3/prefs.ui @@ -8,8 +8,7 @@ SPDX-License-Identifier: GPL-3.0-or-later - - + main-menu @@ -77,7 +76,7 @@ SPDX-License-Identifier: GPL-3.0-or-later 3 - Open Window Animation + Enabled Effects 0 start center @@ -100,72 +99,8 @@ SPDX-License-Identifier: GPL-3.0-or-later - - open-effect-menu - - - 8 - - - Choose Effects - - - - - pan-down-symbolic - 1 - - - - - - - - - - - - - - 10 - 10 - 10 - 10 - 0 - - - 8 - - - vertical - 3 - - - Close Window Animation - 0 - start - center - 1 - - - - - If multiple are selected, one is chosen randomly. - 0 - start - center - 1 - - - - - - - - close-effect-menu + + enabled-effects-menu 8 diff --git a/resources/ui/gtk4/prefs.ui b/resources/ui/gtk4/prefs.ui index b148a91..a20ade9 100644 --- a/resources/ui/gtk4/prefs.ui +++ b/resources/ui/gtk4/prefs.ui @@ -8,8 +8,7 @@ SPDX-License-Identifier: GPL-3.0-or-later - - + main-menu @@ -69,7 +68,7 @@ SPDX-License-Identifier: GPL-3.0-or-later 3 - Open Window Animation + Enabled Effects 0 start center @@ -92,53 +91,9 @@ SPDX-License-Identifier: GPL-3.0-or-later - + Choose Effects - open-effect-menu - - - - - - - - - - 0 - - - - - vertical - 3 - - - Close Window Animation - 0 - start - center - 1 - - - - - If multiple are selected, one is chosen randomly. - 0 - start - center - 1 - - - - - - - - Choose Effects - close-effect-menu + enabled-effects-menu 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 e0e2604..edac16e 100644 --- a/schemas/org.gnome.shell.extensions.burn-my-windows.gschema.xml +++ b/schemas/org.gnome.shell.extensions.burn-my-windows.gschema.xml @@ -31,16 +31,10 @@ SPDX-License-Identifier: CC0-1.0 Enable effects only if power saver is disabled. - + "" - Close Preview Effect - 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. + Preview Effect + The effect with this nick will be used for the next window animation. @@ -53,16 +47,10 @@ SPDX-License-Identifier: CC0-1.0 - + false - Apparition Open Effect - Use the apparition effect for window openeing. - - - - false - Apparition Close Effect - Use the apparition effect for window closing. + Apparition Enable Effect + Use the apparition effect. @@ -100,16 +88,10 @@ SPDX-License-Identifier: CC0-1.0 - + false - Pixelate Close Effect - Use the Pixelate effect for window closing. - - - - false - Pixelate Open Effect - Use the Pixelate effect for window opening. + Pixelate Enable Effect + Use the Pixelate effect. @@ -135,16 +117,10 @@ SPDX-License-Identifier: CC0-1.0 - + false - Pixel Wipe Close Effect - Use the Pixel Wipe effect for window closing. - - - - false - Pixel Wipe Open Effect - Use the Pixel Wipe effect for window opening. + Pixel Wipe Enable Effect + Use the Pixel Wipe effect. @@ -163,16 +139,10 @@ SPDX-License-Identifier: CC0-1.0 - + false - Pixel Wheel Close Effect - Use the Pixel Wheel effect for window closing. - - - - false - Pixel Wheel Open Effect - Use the Pixel Wheel effect for window opening. + Pixel Wheel Enable Effect + Use the Pixel Wheel effect. @@ -197,16 +167,10 @@ SPDX-License-Identifier: CC0-1.0 - + false - Doom Close Effect - Use the Doom effect for window closing. - - - - false - Doom Open Effect - Use the Doom effect for window opening. + Doom Enable Effect + Use the Doom effect. @@ -237,16 +201,10 @@ SPDX-License-Identifier: CC0-1.0 - + true - Fire Close Effect - Use the fire effect for window closing. - - - - false - Fire Open Effect - Use the fire effect for window opening. + Fire Enable Effect + Use the fire effect. @@ -307,16 +265,10 @@ SPDX-License-Identifier: CC0-1.0 - - true - Glide Close Effect - Use the glide effect for window closing. - - - + false - Glide Open Effect - Use the glide effect for window opening. + Glide Enable Effect + Use the glide effect. @@ -353,16 +305,10 @@ SPDX-License-Identifier: CC0-1.0 - + false - Matrix Close Effect - Use the matrix effect for window closing. - - - - false - Matrix Open Effect - Use the matrix effect for window opening. + Matrix Enable Effect + Use the matrix effect. @@ -405,16 +351,10 @@ SPDX-License-Identifier: CC0-1.0 - + false - TV Close Effect - Use the tv effect for window closing. - - - - false - TV Open Effect - Use the tv effect for window opening. + TV Enable Effect + Use the tv effect. @@ -433,16 +373,10 @@ SPDX-License-Identifier: CC0-1.0 - + false - T-Rex Close Effect - Use the trex effect for window closing. - - - - false - T-Rex Open Effect - Use the trex effect for window opening. + T-Rex Enable Effect + Use the trex effect. @@ -479,16 +413,10 @@ SPDX-License-Identifier: CC0-1.0 - + false - Hexagon Close Effect - Use the Hexagon effect for window closing. - - - - false - Hexagon Open Effect - Use the Hexagon effect for window opening. + Hexagon Enable Effect + Use the Hexagon effect. @@ -531,16 +459,10 @@ SPDX-License-Identifier: CC0-1.0 - + false - Incinerate Close Effect - Use the Incinerate effect for window closing. - - - - false - Incinerate Open Effect - Use the Incinerate effect for window opening. + Incinerate Enable Effect + Use the Incinerate effect. @@ -577,16 +499,10 @@ SPDX-License-Identifier: CC0-1.0 - + false - Energize A Close Effect - Use the Energize A effect for window closing. - - - - false - Energize A Open Effect - Use the Energize A effect for window opening. + Energize A Enable Effect + Use the Energize A effect. @@ -611,16 +527,10 @@ SPDX-License-Identifier: CC0-1.0 - + false - Energize B Close Effect - Use the Energize B effect for window closing. - - - - false - Energize B Open Effect - Use the Energize B effect for window opening. + Energize B Enable Effect + Use the Energize B effect. @@ -646,16 +556,10 @@ SPDX-License-Identifier: CC0-1.0 - + false - Glitch Close Effect - Use the Glitch effect for window closing. - - - - false - Glitch Open Effect - Use the Glitch effect for window opening. + Glitch Enable Effect + Use the Glitch effect. @@ -692,16 +596,10 @@ SPDX-License-Identifier: CC0-1.0 - + false - Wisps Close Effect - Use the wisps effect for window closing. - - - - false - Wisps Open Effect - Use the wisps effect for window opening. + Wisps Enable Effect + Use the wisps effect. @@ -726,16 +624,10 @@ SPDX-License-Identifier: CC0-1.0 - + false - Broken Glass Close Effect - Use the broken glass effect for window closing. - - - - false - Broken Glass Open Effect - Use the broken glass effect for window opening. + Broken Glass Enable Effect + Use the broken glass effect. @@ -772,16 +664,10 @@ SPDX-License-Identifier: CC0-1.0 - + false - Portal Close Effect - Use the Portal effect for window closing. - - - - false - Portal Open Effect - Use the Portal effect for window opening. + Portal Enable Effect + Use the Portal effect. @@ -818,16 +704,10 @@ SPDX-License-Identifier: CC0-1.0 - + false - Snap Open Effect - Use the snap effect for window openeing. - - - - false - Snap Close Effect - Use the snap effect for window closing. + Snap Enable Effect + Use the snap effect. diff --git a/src/Apparition.js b/src/Apparition.js index 9c44da1..101fce0 100644 --- a/src/Apparition.js +++ b/src/Apparition.js @@ -69,7 +69,7 @@ var Apparition = class { // This will be called in various places where a unique identifier for this effect is // required. It should match the prefix of the settings keys which store whether the - // effect is enabled currently (e.g. '*-close-effect'), and its animation time + // effect is enabled currently (e.g. '*-enable-effect'), and its animation time // (e.g. '*-animation-time'). getNick() { return 'apparition'; diff --git a/src/BrokenGlass.js b/src/BrokenGlass.js index 3a98030..8eaf49e 100644 --- a/src/BrokenGlass.js +++ b/src/BrokenGlass.js @@ -127,7 +127,7 @@ var BrokenGlass = class { // This will be called in various places where a unique identifier for this effect is // required. It should match the prefix of the settings keys which store whether the - // effect is enabled currently (e.g. '*-close-effect'), and its animation time + // effect is enabled currently (e.g. '*-enable-effect'), and its animation time // (e.g. '*-animation-time'). getNick() { return 'broken-glass'; diff --git a/src/Doom.js b/src/Doom.js index 5e35cf8..4345ff5 100644 --- a/src/Doom.js +++ b/src/Doom.js @@ -76,7 +76,7 @@ var Doom = class { // This will be called in various places where a unique identifier for this effect is // required. It should match the prefix of the settings keys which store whether the - // effect is enabled currently (e.g. '*-close-effect'), and its animation time + // effect is enabled currently (e.g. '*-enable-effect'), and its animation time // (e.g. '*-animation-time'). getNick() { return 'doom'; diff --git a/src/EnergizeA.js b/src/EnergizeA.js index 391d5c9..10d2e67 100644 --- a/src/EnergizeA.js +++ b/src/EnergizeA.js @@ -68,7 +68,7 @@ var EnergizeA = class { // This will be called in various places where a unique identifier for this effect is // required. It should match the prefix of the settings keys which store whether the - // effect is enabled currently (e.g. '*-close-effect'), and its animation time + // effect is enabled currently (e.g. '*-enable-effect'), and its animation time // (e.g. '*-animation-time'). getNick() { return 'energize-a'; diff --git a/src/EnergizeB.js b/src/EnergizeB.js index d6318b9..edd2472 100644 --- a/src/EnergizeB.js +++ b/src/EnergizeB.js @@ -69,7 +69,7 @@ var EnergizeB = class { // This will be called in various places where a unique identifier for this effect is // required. It should match the prefix of the settings keys which store whether the - // effect is enabled currently (e.g. '*-close-effect'), and its animation time + // effect is enabled currently (e.g. '*-enable-effect'), and its animation time // (e.g. '*-animation-time'). getNick() { return 'energize-b'; diff --git a/src/Fire.js b/src/Fire.js index 3123b28..8a2366e 100644 --- a/src/Fire.js +++ b/src/Fire.js @@ -88,7 +88,7 @@ var Fire = class { // This will be called in various places where a unique identifier for this effect is // required. It should match the prefix of the settings keys which store whether the - // effect is enabled currently (e.g. '*-close-effect'), and its animation time + // effect is enabled currently (e.g. '*-enable-effect'), and its animation time // (e.g. '*-animation-time'). getNick() { return 'fire'; diff --git a/src/Glide.js b/src/Glide.js index 846c553..1dcc68e 100644 --- a/src/Glide.js +++ b/src/Glide.js @@ -66,7 +66,7 @@ var Glide = class { // This will be called in various places where a unique identifier for this effect is // required. It should match the prefix of the settings keys which store whether the - // effect is enabled currently (e.g. '*-close-effect'), and its animation time + // effect is enabled currently (e.g. '*-enable-effect'), and its animation time // (e.g. '*-animation-time'). getNick() { return 'glide'; diff --git a/src/Glitch.js b/src/Glitch.js index f9d8878..b932031 100644 --- a/src/Glitch.js +++ b/src/Glitch.js @@ -77,7 +77,7 @@ var Glitch = class { // This will be called in various places where a unique identifier for this effect is // required. It should match the prefix of the settings keys which store whether the - // effect is enabled currently (e.g. '*-close-effect'), and its animation time + // effect is enabled currently (e.g. '*-enable-effect'), and its animation time // (e.g. '*-animation-time'). getNick() { return 'glitch'; diff --git a/src/Hexagon.js b/src/Hexagon.js index 8116c70..678d126 100644 --- a/src/Hexagon.js +++ b/src/Hexagon.js @@ -86,7 +86,7 @@ var Hexagon = class { // This will be called in various places where a unique identifier for this effect is // required. It should match the prefix of the settings keys which store whether the - // effect is enabled currently (e.g. '*-close-effect'), and its animation time + // effect is enabled currently (e.g. '*-enable-effect'), and its animation time // (e.g. '*-animation-time'). getNick() { return 'hexagon'; diff --git a/src/Incinerate.js b/src/Incinerate.js index cc506e1..242ea03 100644 --- a/src/Incinerate.js +++ b/src/Incinerate.js @@ -119,7 +119,7 @@ var Incinerate = class { // This will be called in various places where a unique identifier for this effect is // required. It should match the prefix of the settings keys which store whether the - // effect is enabled currently (e.g. '*-close-effect'), and its animation time + // effect is enabled currently (e.g. '*-enable-effect'), and its animation time // (e.g. '*-animation-time'). getNick() { return 'incinerate'; diff --git a/src/Matrix.js b/src/Matrix.js index 7b0f4f0..fb3103b 100644 --- a/src/Matrix.js +++ b/src/Matrix.js @@ -102,7 +102,7 @@ var Matrix = class { // This will be called in various places where a unique identifier for this effect is // required. It should match the prefix of the settings keys which store whether the - // effect is enabled currently (e.g. '*-close-effect'), and its animation time + // effect is enabled currently (e.g. '*-enable-effect'), and its animation time // (e.g. '*-animation-time'). getNick() { return 'matrix'; diff --git a/src/PixelWheel.js b/src/PixelWheel.js index 46a804e..f878c73 100644 --- a/src/PixelWheel.js +++ b/src/PixelWheel.js @@ -62,7 +62,7 @@ var PixelWheel = class { // This will be called in various places where a unique identifier for this effect is // required. It should match the prefix of the settings keys which store whether the - // effect is enabled currently (e.g. '*-close-effect'), and its animation time + // effect is enabled currently (e.g. '*-enable-effect'), and its animation time // (e.g. '*-animation-time'). getNick() { return 'pixel-wheel'; diff --git a/src/PixelWipe.js b/src/PixelWipe.js index e78e1f1..08745f0 100644 --- a/src/PixelWipe.js +++ b/src/PixelWipe.js @@ -88,7 +88,7 @@ var PixelWipe = class { // This will be called in various places where a unique identifier for this effect is // required. It should match the prefix of the settings keys which store whether the - // effect is enabled currently (e.g. '*-close-effect'), and its animation time + // effect is enabled currently (e.g. '*-enable-effect'), and its animation time // (e.g. '*-animation-time'). getNick() { return 'pixel-wipe'; diff --git a/src/Pixelate.js b/src/Pixelate.js index 3ca6713..3d7ccee 100644 --- a/src/Pixelate.js +++ b/src/Pixelate.js @@ -62,7 +62,7 @@ var Pixelate = class { // This will be called in various places where a unique identifier for this effect is // required. It should match the prefix of the settings keys which store whether the - // effect is enabled currently (e.g. '*-close-effect'), and its animation time + // effect is enabled currently (e.g. '*-enable-effect'), and its animation time // (e.g. '*-animation-time'). getNick() { return 'pixelate'; diff --git a/src/Portal.js b/src/Portal.js index 38063df..55709e7 100644 --- a/src/Portal.js +++ b/src/Portal.js @@ -79,7 +79,7 @@ var Portal = class { // This will be called in various places where a unique identifier for this effect is // required. It should match the prefix of the settings keys which store whether the - // effect is enabled currently (e.g. '*-close-effect'), and its animation time + // effect is enabled currently (e.g. '*-enable-effect'), and its animation time // (e.g. '*-animation-time'). getNick() { return 'portal'; diff --git a/src/SnapOfDisintegration.js b/src/SnapOfDisintegration.js index 3750ff4..f05ca67 100644 --- a/src/SnapOfDisintegration.js +++ b/src/SnapOfDisintegration.js @@ -106,7 +106,7 @@ var SnapOfDisintegration = class { // This will be called in various places where a unique identifier for this effect is // required. It should match the prefix of the settings keys which store whether the - // effect is enabled currently (e.g. '*-close-effect'), and its animation time + // effect is enabled currently (e.g. '*-enable-effect'), and its animation time // (e.g. '*-animation-time'). getNick() { return 'snap'; diff --git a/src/TRexAttack.js b/src/TRexAttack.js index e59cf1f..ae25713 100644 --- a/src/TRexAttack.js +++ b/src/TRexAttack.js @@ -104,7 +104,7 @@ var TRexAttack = class { // This will be called in various places where a unique identifier for this effect is // required. It should match the prefix of the settings keys which store whether the - // effect is enabled currently (e.g. '*-close-effect'), and its animation time + // effect is enabled currently (e.g. '*-enable-effect'), and its animation time // (e.g. '*-animation-time'). getNick() { return 'trex'; diff --git a/src/TVEffect.js b/src/TVEffect.js index 2dabded..ecd6ea2 100644 --- a/src/TVEffect.js +++ b/src/TVEffect.js @@ -66,7 +66,7 @@ var TVEffect = class { // This will be called in various places where a unique identifier for this effect is // required. It should match the prefix of the settings keys which store whether the - // effect is enabled currently (e.g. '*-close-effect'), and its animation time + // effect is enabled currently (e.g. '*-enable-effect'), and its animation time // (e.g. '*-animation-time'). getNick() { return 'tv'; diff --git a/src/Wisps.js b/src/Wisps.js index 76fe75d..1743e5b 100644 --- a/src/Wisps.js +++ b/src/Wisps.js @@ -75,7 +75,7 @@ var Wisps = class { // This will be called in various places where a unique identifier for this effect is // required. It should match the prefix of the settings keys which store whether the - // effect is enabled currently (e.g. the '*-close-effect'). + // effect is enabled currently (e.g. the '*-enable-effect'). getNick() { return 'wisps'; } From 3a7e076067612210691782a66768803fc6033b8a Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Sat, 14 Jan 2023 13:21:48 +0100 Subject: [PATCH 05/67] :wrench: Work on effect profiles --- resources/ui/adw/prefs.ui | 63 +++++++++++++++----------------- resources/ui/common/main-menu.ui | 15 ++++++++ 2 files changed, 45 insertions(+), 33 deletions(-) diff --git a/resources/ui/adw/prefs.ui b/resources/ui/adw/prefs.ui index f04b4c8..d2eb6da 100644 --- a/resources/ui/adw/prefs.ui +++ b/resources/ui/adw/prefs.ui @@ -2,8 +2,7 @@ @@ -12,9 +11,9 @@ GPL-3.0-or-later center - + Default Profile - center + effect-profile-menu @@ -27,6 +26,12 @@ GPL-3.0-or-later + + + user-trash-symbolic + center + + @@ -57,7 +62,8 @@ GPL-3.0-or-later - + Edit Effect Profile + Here you can specify under which circumstances the current effect settings should be applied. @@ -85,7 +91,7 @@ GPL-3.0-or-later - + Window Type @@ -100,7 +106,22 @@ GPL-3.0-or-later - + + + + Desktop Style + + + + Any + Default Mode + Dark Mode + + + + + + Power Mode @@ -137,29 +158,6 @@ GPL-3.0-or-later - - - - - - Delete this Profile... - - - - - - end - true - system-help-symbolic - - - - - - - @@ -186,11 +184,11 @@ GPL-3.0-or-later - + - + edit-paste-symbolic @@ -201,7 +199,6 @@ GPL-3.0-or-later - diff --git a/resources/ui/common/main-menu.ui b/resources/ui/common/main-menu.ui index 4d8260c..1a4f833 100644 --- a/resources/ui/common/main-menu.ui +++ b/resources/ui/common/main-menu.ui @@ -49,4 +49,19 @@ SPDX-License-Identifier: GPL-3.0-or-later + + +
+ + Default Profile + profile.default + +
+
+ + Add New... + profile.new + +
+
\ No newline at end of file From ae0c1309a2ba56d1d789f418c9c6f4c43355e0e3 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Tue, 17 Jan 2023 20:01:41 +0100 Subject: [PATCH 06/67] :wrench: Bind profile combo rows to settings --- prefs.js | 32 ++++++----- resources/ui/adw/prefs.ui | 52 ++++++++--------- .../ui/common/{main-menu.ui => menus.ui} | 8 ++- ...ell.extensions.burn-my-windows.gschema.xml | 57 +++++++++++++------ 4 files changed, 89 insertions(+), 60 deletions(-) rename resources/ui/common/{main-menu.ui => menus.ui} (92%) diff --git a/prefs.js b/prefs.js index 9792544..22265ad 100644 --- a/prefs.js +++ b/prefs.js @@ -98,7 +98,7 @@ var PreferencesDialog = class PreferencesDialog { // Load the general user interface files. this._builder = new Gtk.Builder(); - this._builder.add_from_resource(`/ui/common/main-menu.ui`); + this._builder.add_from_resource(`/ui/common/menus.ui`); this._builder.add_from_resource(`/ui/${utils.getUIDir()}/prefs.ui`); // Check whether the power profiles daemon is available - if not, we hide the @@ -169,7 +169,7 @@ var PreferencesDialog = class PreferencesDialog { // Now add the two toggle buttons for enabling and disabling the effect. const button = Gtk.Switch.new(); - button.set_action_name(`enabled-effects.${effect.getNick()}-enable-effect`); + button.set_action_name(`prefs.${effect.getNick()}-enable-effect`); button.set_tooltip_text(_('Use this effect')); button.set_valign(Gtk.Align.CENTER); @@ -232,6 +232,10 @@ var PreferencesDialog = class PreferencesDialog { // Show the version number in the title bar. window.set_title(`Burn-My-Windows ${Me.metadata.version}`); + // Populate the menu with actions. + const group = Gio.SimpleActionGroup.new(); + window.insert_action_group('prefs', group); + // Add the main menu to the title bar. { // Add the menu button to the title bar. @@ -262,10 +266,6 @@ var PreferencesDialog = class PreferencesDialog { window.get_titlebar().pack_start(menu); } - // Populate the menu with actions. - const group = Gio.SimpleActionGroup.new(); - window.insert_action_group('prefs', group); - const addURIAction = (name, uri) => { const action = Gio.SimpleAction.new(name, null); action.connect('activate', () => Gtk.show_uri(null, uri, Gdk.CURRENT_TIME)); @@ -379,11 +379,17 @@ var PreferencesDialog = class PreferencesDialog { group.add_action(aboutAction); } + // Bind all the profile-related actions. + { + this.bindComboRow('profile-animation-type'); + this.bindComboRow('profile-window-type'); + this.bindComboRow('profile-desktop-style'); + this.bindComboRow('profile-power-mode'); + this.bindComboRow('profile-power-profile'); + } + // Populate the enabled-effects drop-down menu. { - const group = Gio.SimpleActionGroup.new(); - window.insert_action_group('enabled-effects', group); - this._ALL_EFFECTS.forEach(effect => { const [minMajor, minMinor] = effect.getMinShellVersion(); if (utils.shellVersionIsAtLeast(minMajor, minMinor)) { @@ -396,7 +402,7 @@ var PreferencesDialog = class PreferencesDialog { if (!utils.isADW()) { const menu = this._builder.get_object('enabled-effects-menu'); const label = effect.getLabel(); - menu.append_item(Gio.MenuItem.new(label, 'enabled-effects.' + actionName)); + menu.append_item(Gio.MenuItem.new(label, 'prefs.' + actionName)); } } }); @@ -434,10 +440,10 @@ var PreferencesDialog = class PreferencesDialog { return this._widget; } - // Connects a Gtk.ComboBox (or anything else which has an 'active-id' property) to a + // Connects a Gtk.ComboBox (or anything else which has an 'selected' property) to a // settings key. It also binds the corresponding reset button. - bindCombobox(settingsKey) { - this._bind(settingsKey, 'active-id'); + bindComboRow(settingsKey) { + this._bind(settingsKey, 'selected'); } // Connects a Gtk.Adjustment (or anything else which has a 'value' property) to a diff --git a/resources/ui/adw/prefs.ui b/resources/ui/adw/prefs.ui index d2eb6da..98da513 100644 --- a/resources/ui/adw/prefs.ui +++ b/resources/ui/adw/prefs.ui @@ -13,7 +13,7 @@ SPDX-License-Identifier: GPL-3.0-or-later Default Profile - effect-profile-menu + profile-menu @@ -66,10 +66,10 @@ SPDX-License-Identifier: GPL-3.0-or-later Here you can specify under which circumstances the current effect settings should be applied. - + Choose an Application - + bmw-select-app-symbolic center @@ -78,14 +78,14 @@ SPDX-License-Identifier: GPL-3.0-or-later - + Animation Type - Any - Open Windows - Close Windows + Any + Open Windows + Close Windows @@ -93,14 +93,14 @@ SPDX-License-Identifier: GPL-3.0-or-later - + Window Type - Any - Normal Windows - Dialogs + Any + Normal Windows + Dialogs @@ -108,14 +108,14 @@ SPDX-License-Identifier: GPL-3.0-or-later - + Desktop Style - Any - Default Mode - Dark Mode + Any + Default Mode + Dark Mode @@ -123,14 +123,14 @@ SPDX-License-Identifier: GPL-3.0-or-later - + Power Mode - Any - On Battery - Plugged In + Any + On Battery + Plugged In @@ -138,17 +138,17 @@ SPDX-License-Identifier: GPL-3.0-or-later - + Power Profile - Any - Power-Saver Mode - Balanced Mode - Performance Mode - Power Saver or Balanced - Balanced or Performance + Any + Power-Saver Mode + Balanced Mode + Performance Mode + Power Saver or Balanced + Balanced or Performance diff --git a/resources/ui/common/main-menu.ui b/resources/ui/common/menus.ui similarity index 92% rename from resources/ui/common/main-menu.ui rename to resources/ui/common/menus.ui index 1a4f833..cc1248a 100644 --- a/resources/ui/common/main-menu.ui +++ b/resources/ui/common/menus.ui @@ -6,6 +6,7 @@ SPDX-License-Identifier: GPL-3.0-or-later --> +
@@ -50,18 +51,19 @@ SPDX-License-Identifier: GPL-3.0-or-later
- +
Default Profile - profile.default + prefs.profile-default
Add New... - profile.new + prefs.profile-new
+ \ No newline at end of file diff --git a/schemas/org.gnome.shell.extensions.burn-my-windows.gschema.xml b/schemas/org.gnome.shell.extensions.burn-my-windows.gschema.xml index edac16e..4c03baa 100644 --- a/schemas/org.gnome.shell.extensions.burn-my-windows.gschema.xml +++ b/schemas/org.gnome.shell.extensions.burn-my-windows.gschema.xml @@ -13,24 +13,6 @@ SPDX-License-Identifier: CC0-1.0 - - false - Destroy Dialogs - Set to true to burn dialogs as well. - - - - false - Disable on Battery - Enable effects only if plugged in. - - - - false - Disable on Power Save - Enable effects only if power saver is disabled. - - "" Preview Effect @@ -43,6 +25,45 @@ SPDX-License-Identifier: CC0-1.0 If set to true, all animations will show only one still frame to allow for continuous integration tests. + + + + + + 0 + + Profile Animation Type + The animation types for which the current effect settings should be used. + + + + 0 + + Profile Window Type + The window types for which the current effect settings should be used. + + + + 0 + + Profile Desktop Style + The desktop styles for which the current effect settings should be used. + + + + 0 + + Profile Power Mode + The power mode for which the current effect settings should be used. + + + + 0 + + Profile Power Profile + The power profiles in which the current effect settings should be used. + + From 7b5ef70b4d35ca372a86948f9c8d991e09fc9686 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Fri, 20 Jan 2023 20:07:07 +0100 Subject: [PATCH 07/67] :wrench: Add some initial code to load profiles --- extension.js | 29 +- prefs.js | 84 +- resources/ui/adw/prefs.ui | 30 +- ...nsions.burn-my-windows-profile.gschema.xml | 738 ++++++++++++++++++ ...ell.extensions.burn-my-windows.gschema.xml | 730 +---------------- src/Fire.js | 24 +- src/utils.js | 75 +- 7 files changed, 923 insertions(+), 787 deletions(-) create mode 100644 schemas/org.gnome.shell.extensions.burn-my-windows-profile.gschema.xml diff --git a/extension.js b/extension.js index 41dfe4b..b604384 100644 --- a/extension.js +++ b/extension.js @@ -378,28 +378,21 @@ class Extension { 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 previewNick = this._settings.get_string('preview-effect'); - if (isDialogWindow && !shouldDestroyDialogs && previewNick == '') { - this._fixAnimationTimes(isDialogWindow, forOpening, null); - return; - } - + // TODO!. // We may have to do nothing if running on battery power or if in power-save mode. - let disableOnBattery = - this._settings.get_boolean('disable-on-battery') && this._upowerProxy.OnBattery; - let disableOnPowerSave = this._settings.get_boolean('disable-on-power-save') && - this._powerProfilesProxy && this._powerProfilesProxy.ActiveProfile == 'power-saver'; + // let disableOnBattery = + // this._settings.get_boolean('disable-on-battery') && this._upowerProxy.OnBattery; + // let disableOnPowerSave = this._settings.get_boolean('disable-on-power-save') && + // this._powerProfilesProxy && this._powerProfilesProxy.ActiveProfile == + // 'power-saver'; + + // if (!skip! && previewNick == '') { + // this._fixAnimationTimes(isDialogWindow, forOpening, null); + // return; + // } - if ((disableOnBattery || disableOnPowerSave) && previewNick == '') { - this._fixAnimationTimes(isDialogWindow, forOpening, null); - return; - } // There is the weird case where an animation is already ongoing. This happens when a // window is closed which has been created before the session was started (e.g. when diff --git a/prefs.js b/prefs.js index a00e998..af2f693 100644 --- a/prefs.js +++ b/prefs.js @@ -96,6 +96,13 @@ var PreferencesDialog = class PreferencesDialog { // Store a reference to the settings object. this._settings = ExtensionUtils.getSettings(); + let profiles = utils.listProfiles(); + if (profiles.length == 0) { + profiles = [utils.createProfile()]; + } + + this._profileSettings = utils.getProfileSettings(profiles[0]); + // Load the general user interface files. this._builder = new Gtk.Builder(); this._builder.add_from_resource(`/ui/common/menus.ui`); @@ -115,7 +122,7 @@ var PreferencesDialog = class PreferencesDialog { // Maybe the service is masked... } - this._builder.get_object('disable-on-power-save-row').set_visible(hasPowerProfiles); + this._builder.get_object('profile-power-profile').set_visible(hasPowerProfiles); // Starting with GNOME Shell 42, the settings dialog uses libadwaita (at least most of // the time - it seems that pop!_OS does not support libadwaita even on GNOME 42). We @@ -386,11 +393,55 @@ var PreferencesDialog = class PreferencesDialog { // Bind all the profile-related actions. { - this.bindComboRow('profile-animation-type'); - this.bindComboRow('profile-window-type'); - this.bindComboRow('profile-desktop-style'); - this.bindComboRow('profile-power-mode'); - this.bindComboRow('profile-power-profile'); + const updateProfileName = () => { + let items = []; + + const addItems = (settingsKey, options) => { + const option = this._profileSettings.get_int(settingsKey); + if (option > 0) { + items.push(options[option - 1]); + } + }; + + // clang-format off + addItems('profile-animation-type', [_('Opening Windows'), + _('Closing Windows')]); + addItems('profile-window-type', [_('Normal Windows'), + _('Dialog Windows')]); + addItems('profile-desktop-style', [_('Bright Mode'), + _('Dark Mode')]); + addItems('profile-power-mode', [_('On Battery'), + _('Plugged In')]); + addItems('profile-power-profile', [_('Power-Saver Mode'), + _('Balanced Mode'), + _('Performance Mode'), + _('Power Saver or Balanced'), + _('Balanced or Performance')]); + // clang-format on + + let label = ''; + + if (items.length == 0) { + label = _('Default Profile'); + } else { + label = items.join(' · '); + } + + this._builder.get_object('choose-profile-button').label = label; + }; + + const setupProfileOption = (settingsKey) => { + this.bindComboRow(settingsKey); + this._profileSettings.connect('changed::' + settingsKey, updateProfileName); + }; + + setupProfileOption('profile-animation-type'); + setupProfileOption('profile-window-type'); + setupProfileOption('profile-desktop-style'); + setupProfileOption('profile-power-mode'); + setupProfileOption('profile-power-profile'); + + updateProfileName(); } // Populate the enabled-effects drop-down menu. @@ -399,7 +450,7 @@ var PreferencesDialog = class PreferencesDialog { const [minMajor, minMinor] = effect.getMinShellVersion(); if (utils.shellVersionIsAtLeast(minMajor, minMinor)) { const actionName = effect.getNick() + '-enable-effect'; - const action = this._settings.create_action(actionName); + const action = this._profileSettings.create_action(actionName); group.add_action(action); // The menu only exists if not using libadwaita. With libadwaita, individual @@ -435,9 +486,9 @@ var PreferencesDialog = class PreferencesDialog { return this._builder; } - // Returns a Gio.Settings object for this extension. - getSettings() { - return this._settings; + // Returns a Gio.Settings object for the current effect profile. + getProfileSettings() { + return this._profileSettings; } // Returns the widget used for the settings of this extension. @@ -474,17 +525,17 @@ var PreferencesDialog = class PreferencesDialog { // Update the settings when the color is modified. button.connect('color-set', () => { - this._settings.set_string(settingsKey, button.get_rgba().to_string()); + this._profileSettings.set_string(settingsKey, button.get_rgba().to_string()); }); // Update the button state when the settings change. const settingSignalHandler = () => { const rgba = new Gdk.RGBA(); - rgba.parse(this._settings.get_string(settingsKey)); + rgba.parse(this._profileSettings.get_string(settingsKey)); button.rgba = rgba; }; - this._settings.connect('changed::' + settingsKey, settingSignalHandler); + this._profileSettings.connect('changed::' + settingsKey, settingSignalHandler); // Initialize the button with the state in the settings. settingSignalHandler(); @@ -512,7 +563,7 @@ var PreferencesDialog = class PreferencesDialog { const resetButton = this._builder.get_object('reset-' + settingsKey); if (resetButton) { resetButton.connect('clicked', () => { - this._settings.reset(settingsKey); + this._profileSettings.reset(settingsKey); }); } } @@ -523,7 +574,8 @@ var PreferencesDialog = class PreferencesDialog { const object = this._builder.get_object(settingsKey); if (object) { - this._settings.bind(settingsKey, object, property, Gio.SettingsBindFlags.DEFAULT); + this._profileSettings.bind(settingsKey, object, property, + Gio.SettingsBindFlags.DEFAULT); } this._bindResetButton(settingsKey); @@ -552,7 +604,7 @@ var PreferencesDialog = class PreferencesDialog { _previewEffect(effect) { // Set the to-be-previewed effect. - this.getSettings().set_string('preview-effect', effect.getNick()); + this._settings.set_string('preview-effect', effect.getNick()); // Make sure that the window.show() firther below "sees" this change. Gio.Settings.sync(); diff --git a/resources/ui/adw/prefs.ui b/resources/ui/adw/prefs.ui index 98da513..91cb354 100644 --- a/resources/ui/adw/prefs.ui +++ b/resources/ui/adw/prefs.ui @@ -11,8 +11,7 @@ SPDX-License-Identifier: GPL-3.0-or-later center - - Default Profile + profile-menu @@ -26,12 +25,6 @@ SPDX-License-Identifier: GPL-3.0-or-later - - - user-trash-symbolic - center - - @@ -57,7 +50,7 @@ SPDX-License-Identifier: GPL-3.0-or-later 20 20 20 - 20 + 20 20 @@ -84,8 +77,8 @@ SPDX-License-Identifier: GPL-3.0-or-later Any - Open Windows - Close Windows + Opening Windows + Closing Windows @@ -100,7 +93,7 @@ SPDX-License-Identifier: GPL-3.0-or-later Any Normal Windows - Dialogs + Dialog Windows @@ -114,7 +107,7 @@ SPDX-License-Identifier: GPL-3.0-or-later Any - Default Mode + Bright Mode Dark Mode @@ -158,6 +151,14 @@ SPDX-License-Identifier: GPL-3.0-or-later
+ + + user-trash-symbolic + Delete this Profile... + start + + +
@@ -181,14 +182,13 @@ SPDX-License-Identifier: GPL-3.0-or-later + center - - edit-paste-symbolic diff --git a/schemas/org.gnome.shell.extensions.burn-my-windows-profile.gschema.xml b/schemas/org.gnome.shell.extensions.burn-my-windows-profile.gschema.xml new file mode 100644 index 0000000..a8d86cf --- /dev/null +++ b/schemas/org.gnome.shell.extensions.burn-my-windows-profile.gschema.xml @@ -0,0 +1,738 @@ + + + + + + + + + + + + + + 0 + + Profile Animation Type + The animation types for which the current effect settings should be used. + + + + 0 + + Profile Window Type + The window types for which the current effect settings should be used. + + + + 0 + + Profile Desktop Style + The desktop styles for which the current effect settings should be used. + + + + 0 + + Profile Power Mode + The power mode for which the current effect settings should be used. + + + + 0 + + Profile Power Profile + The power profiles in which the current effect settings should be used. + + + + + + + + false + Apparition Enable Effect + Use the apparition effect. + + + + 300 + Apparition Animation Time + The time the apparition effect takes. + + + + 0.5 + Apparition Randomness + The amount of randomness of the apparition effect. + + + + 5.0 + Apparition Twirl Intensity + The amount of twirling of the apparition effect. + + + + 3.0 + Apparition Shake Intensity + The amount of shaking of the apparition effect. + + + + 0.75 + Apparition Suction Intensity + The amount of suction of the apparition effect. + + + + + + + + + false + Pixelate Enable Effect + Use the Pixelate effect. + + + + 500 + Pixelate Animation Time + The time the Pixelate effect takes. + + + + 40 + Pixelate Noise + The noise of the effect. + + + + 10 + Pixelate Pixel Size + The size of the maximum pixelation. + + + + + + + + + false + Pixel Wipe Enable Effect + Use the Pixel Wipe effect. + + + + 1000 + Pixel Wipe Animation Time + The time the Pixel Wipe effect takes. + + + + 10 + Pixel Wipe Pixel Size + The size of the maximum pixelation. + + + + + + + + false + Pixel Wheel Enable Effect + Use the Pixel Wheel effect. + + + + 300 + Pixel Wheel Animation Time + The time the Pixel Wheel effect takes. + + + + 12 + Pixel Wheel Spoke Count + The number of sections in the wheel. + + + + 10 + Pixel Wheel Pixel Size + The size of the maximum pixelation. + + + + + + + + false + Doom Enable Effect + Use the Doom effect. + + + + 1000 + Doom Animation Time + The time the Doom effect takes. + + + + 10.0 + Doom Horizontal Scale + The X scale of the effect. + + + + 10.0 + Doom Vertical Scale + The Y scale of the effect. + + + + 10 + Doom Pixel Size + The size of the maximum pixelation. + + + + + + + + true + Fire Enable Effect + Use the fire effect. + + + + 1500 + Fire Animation Time + The time the fire effect takes. + + + + 0.5 + Fire Movement Speed + The speed at which the fire moves. + + + + 1.0 + Fire Scale + The size of the fire. + + + + false + Fire 3D Noise + Use a 3D noise for the fire. + + + + "rgba(76, 51, 25, 0.0)" + Fire Color 1 + The first color of the fire gradient. + + + + "rgba(180, 55, 30, 0.7)" + Fire Color 2 + The second color of the fire gradient. + + + + "rgba(255, 76, 38, 0.9)" + Fire Color 3 + The third color of the fire gradient. + + + + "rgba(255, 166, 25, 1)" + Fire Color 4 + The fourth color of the fire gradient. + + + + "rgba(255, 255, 255, 1)" + Fire Color 5 + The fifth color of the fire gradient. + + + + + + + + false + Glide Enable Effect + Use the glide effect. + + + + 250 + Glide Animation Time + The time the glide effect takes. + + + + 0.95 + Glide Scale + The scale of the window. + + + + 0.15 + Glide Squish + The amount of squishing. + + + + -0.3 + Glide Tilt + The amount of tilting. + + + + -0.05 + Glide Shift + The amount of shifting. + + + + + + + + false + Matrix Enable Effect + Use the matrix effect. + + + + 1500 + Matrix Animation Time + The time the matrix effect takes. + + + + 20 + Matrix Scale + The size of the matrix letters. + + + + 1.0 + Matrix Randomness + The randomness of the matrix effect. + + + + "rgb(255, 255, 255)" + Matrix Tip Color + The color of the matrix trail tips. + + + + "rgb(25, 255, 89)" + Matrix Trail Color + The color matrix trails. + + + + 0.25 + Matrix Overshoot + The vertical overshooting of the matrix effect. + + + + + + + + false + TV Enable Effect + Use the tv effect. + + + + 400 + TV Animation Time + The time the tv effect takes. + + + + "rgb(255, 255, 255)" + TV Effect Color + The color of the TV effect. + + + + + + + + false + T-Rex Enable Effect + Use the trex effect. + + + + 1000 + T-Rex Animation Time + The time the trex effect takes. + + + + "rgb(170, 0, 0)" + Claw Scratch Color + The color of the claw scratches. + + + + 1.0 + Claw Scratch Scale + Size of the claw scratches. + + + + 0.15 + Claw Scratch Warp + Intensity of the claw scratch warp effect. + + + + 5 + Claw Scratch Count + Number of claw scratches drawn on top of each other. + + + + + + + + false + Hexagon Enable Effect + Use the Hexagon effect. + + + + 1500 + Hexagon Animation Time + The time the Hexagon effect takes. + + + + 3.0 + Hexagon Scale + The size of the effect. + + + + 2.0 + Hexagon Line Width + The width of the lines. + + + + "rgba(200, 255, 255, 0.5)" + Hexagon Line Color + The color of the lines. + + + + "rgba(20, 80, 255, 0.5)" + Hexagon Glow Color + The color of the glow effect. + + + + true + Hexagon Additive Blending + Use additive blending for the line and the glow. + + + + + + + + false + Incinerate Enable Effect + Use the Incinerate effect. + + + + 2000 + Incinerate Animation Time + The time the Incinerate effect takes. + + + + 1.0 + Incinerate Scale + The scale of the effect. + + + + 0.3 + Incinerate Turbulence + The turbulence of the effect. + + + + "rgb(255, 180, 127)" + Incinerate Color + The color of the effect. + + + + true + Incinerate Use Pointer + Use the pointer location for the incinerate effect. + + + + + + + + false + Energize A Enable Effect + Use the Energize A effect. + + + + 2000 + Energize A Animation Time + The time the Energize A effect takes. + + + + 1.0 + Energize A Scale + The size of the effect. + + + + "rgb(255, 200, 50)" + Energize A Color + The color of the effect. + + + + + + + + false + Energize B Enable Effect + Use the Energize B effect. + + + + 1000 + Energize B Animation Time + The time the Energize B effect takes. + + + + 1.0 + Energize B Scale + The size of the effect. + + + + "rgb(160, 180, 255)" + Energize B Color + The color of the effect. + + + + + + + + + false + Glitch Enable Effect + Use the Glitch effect. + + + + 750 + Glitch Animation Time + The time the Glitch effect takes. + + + + 1.0 + Glitch Scale + The size of the effect. + + + + 2.0 + Glitch Strength + The intensity of the effect. + + + + 2.0 + Glitch Speed + The speed of the effect. + + + + "rgb(100, 160, 255)" + Glitch Color + The color of the effect. + + + + + + + + false + Wisps Enable Effect + Use the wisps effect. + + + + 1500 + Wisps Animation Time + The time the wisps effect takes. + + + + 1.0 + Wisps Scale + The size of the wisps. + + + + "rgb(255, 100, 200)" + Wisps Effect Color + The color of the wisps effect. + + + + + + + + false + Broken Glass Enable Effect + Use the broken glass effect. + + + + 1000 + Broken Glass Animation Time + The time the broken glass effect takes. + + + + 1.0 + Broken Glass Scale + The size of the broken glass effect. + + + + -1.0 + Broken Glass Gravity + The gravity of the broken glass effect. + + + + 0.5 + Broken Glass Blow Force + The blow force of the broken glass effect. + + + + false + Broken Glass Use Pointer + Use the pointer location for the broken glass effect. + + + + + + + + false + Portal Enable Effect + Use the Portal effect. + + + + 1250 + Portal Animation Time + The time the Portal effect takes. + + + + "rgb(121, 233, 24)" + Portal Color + The color of the effect. + + + + 0.3 + Portal Rotation Speed + The angular speed of the portal. + + + + 1.0 + Portal Whirling + The amount of distortion. + + + + 15.0 + Portal Details + The amount of details in the portal. + + + + + + + + false + Snap Enable Effect + Use the snap effect. + + + + 1500 + Snap Animation Time + The time the snap effect takes. + + + + 3.0 + Snap Scale + The size of the snap effect. + + + + "rgb(50, 40, 35)" + Snap Effect Color + The color of the dust. + + + + + \ No newline at end of file diff --git a/schemas/org.gnome.shell.extensions.burn-my-windows.gschema.xml b/schemas/org.gnome.shell.extensions.burn-my-windows.gschema.xml index 4c03baa..c8a7593 100644 --- a/schemas/org.gnome.shell.extensions.burn-my-windows.gschema.xml +++ b/schemas/org.gnome.shell.extensions.burn-my-windows.gschema.xml @@ -13,6 +13,12 @@ SPDX-License-Identifier: CC0-1.0 + + "" + Active Profile + The currently active effect profile. + + "" Preview Effect @@ -25,730 +31,6 @@ SPDX-License-Identifier: CC0-1.0 If set to true, all animations will show only one still frame to allow for continuous integration tests. - - - - - - 0 - - Profile Animation Type - The animation types for which the current effect settings should be used. - - - - 0 - - Profile Window Type - The window types for which the current effect settings should be used. - - - - 0 - - Profile Desktop Style - The desktop styles for which the current effect settings should be used. - - - - 0 - - Profile Power Mode - The power mode for which the current effect settings should be used. - - - - 0 - - Profile Power Profile - The power profiles in which the current effect settings should be used. - - - - - - - - false - Apparition Enable Effect - Use the apparition effect. - - - - 300 - Apparition Animation Time - The time the apparition effect takes. - - - - 0.5 - Apparition Randomness - The amount of randomness of the apparition effect. - - - - 5.0 - Apparition Twirl Intensity - The amount of twirling of the apparition effect. - - - - 3.0 - Apparition Shake Intensity - The amount of shaking of the apparition effect. - - - - 0.75 - Apparition Suction Intensity - The amount of suction of the apparition effect. - - - - - - - - - false - Pixelate Enable Effect - Use the Pixelate effect. - - - - 500 - Pixelate Animation Time - The time the Pixelate effect takes. - - - - 40 - Pixelate Noise - The noise of the effect. - - - - 10 - Pixelate Pixel Size - The size of the maximum pixelation. - - - - - - - - - false - Pixel Wipe Enable Effect - Use the Pixel Wipe effect. - - - - 1000 - Pixel Wipe Animation Time - The time the Pixel Wipe effect takes. - - - - 10 - Pixel Wipe Pixel Size - The size of the maximum pixelation. - - - - - - - - false - Pixel Wheel Enable Effect - Use the Pixel Wheel effect. - - - - 300 - Pixel Wheel Animation Time - The time the Pixel Wheel effect takes. - - - - 12 - Pixel Wheel Spoke Count - The number of sections in the wheel. - - - - 10 - Pixel Wheel Pixel Size - The size of the maximum pixelation. - - - - - - - - false - Doom Enable Effect - Use the Doom effect. - - - - 1000 - Doom Animation Time - The time the Doom effect takes. - - - - 10.0 - Doom Horizontal Scale - The X scale of the effect. - - - - 10.0 - Doom Vertical Scale - The Y scale of the effect. - - - - 10 - Doom Pixel Size - The size of the maximum pixelation. - - - - - - - - true - Fire Enable Effect - Use the fire effect. - - - - 1500 - Fire Animation Time - The time the fire effect takes. - - - - 0.5 - Fire Movement Speed - The speed at which the fire moves. - - - - 1.0 - Fire Scale - The size of the fire. - - - - false - Fire 3D Noise - Use a 3D noise for the fire. - - - - "rgba(76, 51, 25, 0.0)" - Fire Color 1 - The first color of the fire gradient. - - - - "rgba(180, 55, 30, 0.7)" - Fire Color 2 - The second color of the fire gradient. - - - - "rgba(255, 76, 38, 0.9)" - Fire Color 3 - The third color of the fire gradient. - - - - "rgba(255, 166, 25, 1)" - Fire Color 4 - The fourth color of the fire gradient. - - - - "rgba(255, 255, 255, 1)" - Fire Color 5 - The fifth color of the fire gradient. - - - - - - - - false - Glide Enable Effect - Use the glide effect. - - - - 250 - Glide Animation Time - The time the glide effect takes. - - - - 0.95 - Glide Scale - The scale of the window. - - - - 0.15 - Glide Squish - The amount of squishing. - - - - -0.3 - Glide Tilt - The amount of tilting. - - - - -0.05 - Glide Shift - The amount of shifting. - - - - - - - - false - Matrix Enable Effect - Use the matrix effect. - - - - 1500 - Matrix Animation Time - The time the matrix effect takes. - - - - 20 - Matrix Scale - The size of the matrix letters. - - - - 1.0 - Matrix Randomness - The randomness of the matrix effect. - - - - "rgb(255, 255, 255)" - Matrix Tip Color - The color of the matrix trail tips. - - - - "rgb(25, 255, 89)" - Matrix Trail Color - The color matrix trails. - - - - 0.25 - Matrix Overshoot - The vertical overshooting of the matrix effect. - - - - - - - - false - TV Enable Effect - Use the tv effect. - - - - 400 - TV Animation Time - The time the tv effect takes. - - - - "rgb(255, 255, 255)" - TV Effect Color - The color of the TV effect. - - - - - - - - false - T-Rex Enable Effect - Use the trex effect. - - - - 1000 - T-Rex Animation Time - The time the trex effect takes. - - - - "rgb(170, 0, 0)" - Claw Scratch Color - The color of the claw scratches. - - - - 1.0 - Claw Scratch Scale - Size of the claw scratches. - - - - 0.15 - Claw Scratch Warp - Intensity of the claw scratch warp effect. - - - - 5 - Claw Scratch Count - Number of claw scratches drawn on top of each other. - - - - - - - - false - Hexagon Enable Effect - Use the Hexagon effect. - - - - 1500 - Hexagon Animation Time - The time the Hexagon effect takes. - - - - 3.0 - Hexagon Scale - The size of the effect. - - - - 2.0 - Hexagon Line Width - The width of the lines. - - - - "rgba(200, 255, 255, 0.5)" - Hexagon Line Color - The color of the lines. - - - - "rgba(20, 80, 255, 0.5)" - Hexagon Glow Color - The color of the glow effect. - - - - true - Hexagon Additive Blending - Use additive blending for the line and the glow. - - - - - - - - false - Incinerate Enable Effect - Use the Incinerate effect. - - - - 2000 - Incinerate Animation Time - The time the Incinerate effect takes. - - - - 1.0 - Incinerate Scale - The scale of the effect. - - - - 0.3 - Incinerate Turbulence - The turbulence of the effect. - - - - "rgb(255, 180, 127)" - Incinerate Color - The color of the effect. - - - - true - Incinerate Use Pointer - Use the pointer location for the incinerate effect. - - - - - - - - false - Energize A Enable Effect - Use the Energize A effect. - - - - 2000 - Energize A Animation Time - The time the Energize A effect takes. - - - - 1.0 - Energize A Scale - The size of the effect. - - - - "rgb(255, 200, 50)" - Energize A Color - The color of the effect. - - - - - - - - false - Energize B Enable Effect - Use the Energize B effect. - - - - 1000 - Energize B Animation Time - The time the Energize B effect takes. - - - - 1.0 - Energize B Scale - The size of the effect. - - - - "rgb(160, 180, 255)" - Energize B Color - The color of the effect. - - - - - - - - - false - Glitch Enable Effect - Use the Glitch effect. - - - - 750 - Glitch Animation Time - The time the Glitch effect takes. - - - - 1.0 - Glitch Scale - The size of the effect. - - - - 2.0 - Glitch Strength - The intensity of the effect. - - - - 2.0 - Glitch Speed - The speed of the effect. - - - - "rgb(100, 160, 255)" - Glitch Color - The color of the effect. - - - - - - - - false - Wisps Enable Effect - Use the wisps effect. - - - - 1500 - Wisps Animation Time - The time the wisps effect takes. - - - - 1.0 - Wisps Scale - The size of the wisps. - - - - "rgb(255, 100, 200)" - Wisps Effect Color - The color of the wisps effect. - - - - - - - - false - Broken Glass Enable Effect - Use the broken glass effect. - - - - 1000 - Broken Glass Animation Time - The time the broken glass effect takes. - - - - 1.0 - Broken Glass Scale - The size of the broken glass effect. - - - - -1.0 - Broken Glass Gravity - The gravity of the broken glass effect. - - - - 0.5 - Broken Glass Blow Force - The blow force of the broken glass effect. - - - - false - Broken Glass Use Pointer - Use the pointer location for the broken glass effect. - - - - - - - - false - Portal Enable Effect - Use the Portal effect. - - - - 1250 - Portal Animation Time - The time the Portal effect takes. - - - - "rgb(121, 233, 24)" - Portal Color - The color of the effect. - - - - 0.3 - Portal Rotation Speed - The angular speed of the portal. - - - - 1.0 - Portal Whirling - The amount of distortion. - - - - 15.0 - Portal Details - The amount of details in the portal. - - - - - - - - false - Snap Enable Effect - Use the snap effect. - - - - 1500 - Snap Animation Time - The time the snap effect takes. - - - - 3.0 - Snap Scale - The size of the snap effect. - - - - "rgb(50, 40, 35)" - Snap Effect Color - The color of the dust. - - \ No newline at end of file diff --git a/src/Fire.js b/src/Fire.js index 8a2366e..523189c 100644 --- a/src/Fire.js +++ b/src/Fire.js @@ -122,11 +122,11 @@ var Fire = class { // The fire-gradient-reset button needs to be bound explicitly. dialog.getBuilder().get_object('reset-fire-colors').connect('clicked', () => { - dialog.getSettings().reset('fire-color-1'); - dialog.getSettings().reset('fire-color-2'); - dialog.getSettings().reset('fire-color-3'); - dialog.getSettings().reset('fire-color-4'); - dialog.getSettings().reset('fire-color-5'); + dialog.getProfileSettings().reset('fire-color-1'); + dialog.getProfileSettings().reset('fire-color-2'); + dialog.getProfileSettings().reset('fire-color-3'); + dialog.getProfileSettings().reset('fire-color-4'); + dialog.getProfileSettings().reset('fire-color-5'); }); // Initialize the fire-preset dropdown. @@ -215,13 +215,13 @@ var Fire = class { // Load the preset on activation. action.connect('activate', () => { - dialog.getSettings().set_double('flame-movement-speed', preset.speed); - dialog.getSettings().set_double('flame-scale', preset.scale); - dialog.getSettings().set_string('fire-color-1', preset.color1); - dialog.getSettings().set_string('fire-color-2', preset.color2); - dialog.getSettings().set_string('fire-color-3', preset.color3); - dialog.getSettings().set_string('fire-color-4', preset.color4); - dialog.getSettings().set_string('fire-color-5', preset.color5); + dialog.getProfileSettings().set_double('flame-movement-speed', preset.speed); + dialog.getProfileSettings().set_double('flame-scale', preset.scale); + dialog.getProfileSettings().set_string('fire-color-1', preset.color1); + dialog.getProfileSettings().set_string('fire-color-2', preset.color2); + dialog.getProfileSettings().set_string('fire-color-3', preset.color3); + dialog.getProfileSettings().set_string('fire-color-4', preset.color4); + dialog.getProfileSettings().set_string('fire-color-5', preset.color5); }); group.add_action(action); diff --git a/src/utils.js b/src/utils.js index 8e5024f..13eddc9 100644 --- a/src/utils.js +++ b/src/utils.js @@ -14,8 +14,8 @@ 'use strict'; -const {Gtk, Gio} = imports.gi; -const ByteArray = imports.byteArray; +const {Gtk, Gio, GLib} = imports.gi; +const ByteArray = imports.byteArray; // libadwaita is available starting with GNOME Shell 42. let Adw = null; @@ -107,4 +107,75 @@ function shellVersionIsAtLeast(major, minor) { function getStringResource(path) { const data = Gio.resources_lookup_data(path, 0); return ByteArray.toString(ByteArray.fromGBytes(data)); +} + +function createProfile() { + const path = + GLib.get_user_config_dir() + `/burn-my-windows/profiles/${GLib.get_real_time()}.conf`; + const file = Gio.File.new_for_path(path); + + if (!file.get_parent().query_exists(null)) { + file.get_parent().make_directory_with_parents(null); + } + + file.create(Gio.FileCreateFlags.NONE, null); + + return path; +} + + +function listProfiles() { + + const profileDir = + Gio.File.new_for_path(GLib.get_user_config_dir() + '/burn-my-windows/profiles'); + + if (!profileDir.query_exists(null)) { + return []; + } + + const files = + profileDir.enumerate_children('standard::*', Gio.FileQueryInfoFlags.NONE, null); + + let profiles = []; + + while (true) { + const presetInfo = files.next_file(null); + + if (presetInfo == null) { + break; + } + + if (presetInfo.get_file_type() == Gio.FileType.REGULAR) { + const suffixPos = presetInfo.get_display_name().indexOf('.conf'); + if (suffixPos > 0) { + profiles.push(profileDir.get_child(presetInfo.get_name()).get_path()); + } + } + } + + return profiles; +} + +// Based on +// https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/misc/extensionUtils.js#L213 +function getProfileSettings(profilePath) { + + // Expect USER extensions to have a schemas/ subfolder, otherwise assume a + // SYSTEM extension that has been installed in the same prefix as the shell + const schemaDir = Me.dir.get_child('schemas'); + let source; + if (schemaDir.query_exists(null)) { + source = Gio.SettingsSchemaSource.new_from_directory( + schemaDir.get_path(), Gio.SettingsSchemaSource.get_default(), false); + } else { + source = Gio.SettingsSchemaSource.get_default(); + } + + const schema = + source.lookup('org.gnome.shell.extensions.burn-my-windows-profile', true); + + const backend = + Gio.keyfile_settings_backend_new(profilePath, '/org/gnome/shell/extensions/', null); + + return new Gio.Settings({settings_schema: schema, backend: backend}); } \ No newline at end of file From 6da3e209b2ff97e643886b09856615b2303f7233 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Sun, 22 Jan 2023 12:51:34 +0100 Subject: [PATCH 08/67] :art: Add new copy-paste icons --- .../actions/bmw-copy-effects-symbolic.svg | 45 +++++++++++++++++++ .../actions/bmw-paste-effects-symbolic.svg | 45 +++++++++++++++++++ resources/ui/adw/prefs.ui | 4 +- 3 files changed, 92 insertions(+), 2 deletions(-) create mode 100644 resources/img/scalable/actions/bmw-copy-effects-symbolic.svg create mode 100644 resources/img/scalable/actions/bmw-paste-effects-symbolic.svg diff --git a/resources/img/scalable/actions/bmw-copy-effects-symbolic.svg b/resources/img/scalable/actions/bmw-copy-effects-symbolic.svg new file mode 100644 index 0000000..680cad3 --- /dev/null +++ b/resources/img/scalable/actions/bmw-copy-effects-symbolic.svg @@ -0,0 +1,45 @@ + + + + + + + + + + diff --git a/resources/img/scalable/actions/bmw-paste-effects-symbolic.svg b/resources/img/scalable/actions/bmw-paste-effects-symbolic.svg new file mode 100644 index 0000000..fc51c35 --- /dev/null +++ b/resources/img/scalable/actions/bmw-paste-effects-symbolic.svg @@ -0,0 +1,45 @@ + + + + + + + + + + diff --git a/resources/ui/adw/prefs.ui b/resources/ui/adw/prefs.ui index 91cb354..9beb5c8 100644 --- a/resources/ui/adw/prefs.ui +++ b/resources/ui/adw/prefs.ui @@ -189,13 +189,13 @@ SPDX-License-Identifier: GPL-3.0-or-later - edit-paste-symbolic + bmw-copy-effects-symbolic - edit-paste-symbolic + bmw-paste-effects-symbolic From 36512372487d0b94aa78233b74a3d4731275ec63 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Mon, 23 Jan 2023 09:59:46 +0100 Subject: [PATCH 09/67] :wrench: Work on loading of profiles --- prefs.js | 141 +++++++++++------- resources/ui/adw/prefs.ui | 25 +++- resources/ui/common/menus.ui | 11 +- ...ell.extensions.burn-my-windows.gschema.xml | 2 +- src/utils.js | 48 ++++++ 5 files changed, 163 insertions(+), 64 deletions(-) diff --git a/prefs.js b/prefs.js index af2f693..6c67950 100644 --- a/prefs.js +++ b/prefs.js @@ -93,21 +93,22 @@ var PreferencesDialog = class PreferencesDialog { // Register the template widgets used in the settings dialog. this._registerCustomClasses(); - // Store a reference to the settings object. - this._settings = ExtensionUtils.getSettings(); - - let profiles = utils.listProfiles(); - if (profiles.length == 0) { - profiles = [utils.createProfile()]; - } - - this._profileSettings = utils.getProfileSettings(profiles[0]); - // Load the general user interface files. this._builder = new Gtk.Builder(); this._builder.add_from_resource(`/ui/common/menus.ui`); this._builder.add_from_resource(`/ui/${utils.getUIDir()}/prefs.ui`); + // Store a reference to the general settings object. + this._settings = ExtensionUtils.getSettings(); + + // Load the current effect profile. If there is none, we create a default profile. + this._settings.connect('changed::active-profile', () => { + this._loadActiveProfile(); + this._updateProfileButton(); + }); + this._loadActiveProfile(); + this._updateProfileButton(); + // Check whether the power profiles daemon is available - if not, we hide the // corresponding settings row. let hasPowerProfiles = false; @@ -124,10 +125,8 @@ var PreferencesDialog = class PreferencesDialog { this._builder.get_object('profile-power-profile').set_visible(hasPowerProfiles); - // Starting with GNOME Shell 42, the settings dialog uses libadwaita (at least most of - // the time - it seems that pop!_OS does not support libadwaita even on GNOME 42). We - // have to use a different layout, as the stack sidebar looks pretty ugly with the - // included Adw.Clamp... + // Starting with GNOME Shell 42, the settings dialog uses libadwaita. We use this to + // create a completely different layout for the settings dialog. if (utils.isADW()) { // This is our top-level widget which we will return later. @@ -192,8 +191,8 @@ var PreferencesDialog = class PreferencesDialog { } }); } - // On older GNOME versions, we use a StackSidebar. The code below works both, on GTK3 - // and GTK4. + // On older GNOME versions, we use a StackSidebar. The code below works on GTK3 and + // GTK4. else { // This is our top-level widget which we will return later. @@ -393,46 +392,10 @@ var PreferencesDialog = class PreferencesDialog { // Bind all the profile-related actions. { - const updateProfileName = () => { - let items = []; - - const addItems = (settingsKey, options) => { - const option = this._profileSettings.get_int(settingsKey); - if (option > 0) { - items.push(options[option - 1]); - } - }; - - // clang-format off - addItems('profile-animation-type', [_('Opening Windows'), - _('Closing Windows')]); - addItems('profile-window-type', [_('Normal Windows'), - _('Dialog Windows')]); - addItems('profile-desktop-style', [_('Bright Mode'), - _('Dark Mode')]); - addItems('profile-power-mode', [_('On Battery'), - _('Plugged In')]); - addItems('profile-power-profile', [_('Power-Saver Mode'), - _('Balanced Mode'), - _('Performance Mode'), - _('Power Saver or Balanced'), - _('Balanced or Performance')]); - // clang-format on - - let label = ''; - - if (items.length == 0) { - label = _('Default Profile'); - } else { - label = items.join(' · '); - } - - this._builder.get_object('choose-profile-button').label = label; - }; - const setupProfileOption = (settingsKey) => { this.bindComboRow(settingsKey); - this._profileSettings.connect('changed::' + settingsKey, updateProfileName); + this._profileSettings.connect('changed::' + settingsKey, + () => this._updateProfileButton()); }; setupProfileOption('profile-animation-type'); @@ -441,7 +404,37 @@ var PreferencesDialog = class PreferencesDialog { setupProfileOption('profile-power-mode'); setupProfileOption('profile-power-profile'); - updateProfileName(); + + const profileAction = this._settings.create_action('active-profile'); + group.add_action(profileAction); + + const newProfileAction = Gio.SimpleAction.new('profile-new', null); + newProfileAction.connect('activate', () => { + const profile = utils.createProfile(); + this._settings.set_string('active-profile', profile); + this._builder.get_object('edit-profile-button').active = true; + }); + + group.add_action(newProfileAction); + + const deleteProfileAction = Gio.SimpleAction.new('profile-delete', null); + deleteProfileAction.connect('activate', () => { + this._builder.get_object('profile-delete-dialog').show(); + }); + + const deleteProfileDialog = this._builder.get_object('profile-delete-dialog'); + deleteProfileDialog.set_transient_for(window); + deleteProfileDialog.connect('response', (d, response) => { + if (response == 'delete') { + this._builder.get_object('edit-profile-button').active = false; + const profile = this._settings.get_string('active-profile'); + utils.deleteProfile(profile); + this._loadActiveProfile(); + this._updateProfileButton(); + } + }); + + group.add_action(deleteProfileAction); } // Populate the enabled-effects drop-down menu. @@ -557,6 +550,44 @@ var PreferencesDialog = class PreferencesDialog { // ----------------------------------------------------------------------- private stuff + _loadActiveProfile() { + + let profiles = utils.listProfiles(); + if (profiles.length == 0) { + profiles = [utils.createProfile()]; + } + + let activeProfile = this._settings.get_string('active-profile'); + if (!profiles.includes(activeProfile)) { + activeProfile = profiles[0]; + this._settings.set_string('active-profile', activeProfile); + } + + utils.debug('loading ' + activeProfile); + + this._profileSettings = utils.getProfileSettings(activeProfile); + } + + _updateProfileButton() { + const activeProfile = this._settings.get_string('active-profile'); + + this._builder.get_object('choose-profile-button').label = + utils.getProfileName(activeProfile); + + const profileSection = this._builder.get_object('profile-section'); + profileSection.remove_all(); + + const profiles = utils.listProfiles(); + + profiles.forEach(profile => { + const label = utils.getProfileName(profile); + const item = Gio.MenuItem.new(label, 'prefs.active-profile'); + item.set_action_and_target_value('prefs.active-profile', + GLib.Variant.new_string(profile)); + profileSection.append_item(item); + }); + } + // Searches for a reset button for the given settings key and make it reset the settings // key when clicked. _bindResetButton(settingsKey) { diff --git a/resources/ui/adw/prefs.ui b/resources/ui/adw/prefs.ui index 9beb5c8..e708eba 100644 --- a/resources/ui/adw/prefs.ui +++ b/resources/ui/adw/prefs.ui @@ -8,6 +8,21 @@ SPDX-License-Identifier: GPL-3.0-or-later + + + true + true + Delete this Profile? + The current effect profile will be permanently lost. + cancel + cancel + + Cancel + Delete + + + + center @@ -153,8 +168,13 @@ SPDX-License-Identifier: GPL-3.0-or-later - user-trash-symbolic - Delete this Profile... + prefs.profile-delete + + + user-trash-symbolic + Delete this Profile... + + start @@ -199,7 +219,6 @@ SPDX-License-Identifier: GPL-3.0-or-later -
diff --git a/resources/ui/common/menus.ui b/resources/ui/common/menus.ui index cc1248a..e126fd7 100644 --- a/resources/ui/common/menus.ui +++ b/resources/ui/common/menus.ui @@ -52,11 +52,12 @@ SPDX-License-Identifier: GPL-3.0-or-later -
- - Default Profile - prefs.profile-default - +
+
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 c8a7593..de978d0 100644 --- a/schemas/org.gnome.shell.extensions.burn-my-windows.gschema.xml +++ b/schemas/org.gnome.shell.extensions.burn-my-windows.gschema.xml @@ -15,7 +15,7 @@ SPDX-License-Identifier: CC0-1.0 "" - Active Profile + Profile The currently active effect profile. diff --git a/src/utils.js b/src/utils.js index 13eddc9..5150f68 100644 --- a/src/utils.js +++ b/src/utils.js @@ -45,6 +45,8 @@ const [GS_MAJOR, GS_MINOR] = Config.PACKAGE_VERSION.split('.').map(toNumericVers const ExtensionUtils = imports.misc.extensionUtils; const Me = imports.misc.extensionUtils.getCurrentExtension(); +const _ = imports.gettext.domain('burn-my-windows').gettext; + // This method can be used to write a message to GNOME Shell's log. This is enhances // the standard log() functionality by prepending the extension's name and the location // where the message was logged. As the extensions name is part of the location, you @@ -123,6 +125,14 @@ function createProfile() { return path; } +function deleteProfile(profilePath) { + const profileDir = GLib.get_user_config_dir() + `/burn-my-windows/profiles`; + const file = Gio.File.new_for_path(profilePath); + if (file.has_prefix(Gio.File.new_for_path(profileDir)) && file.query_exists(null)) { + file.delete(null); + } +} + function listProfiles() { @@ -178,4 +188,42 @@ function getProfileSettings(profilePath) { Gio.keyfile_settings_backend_new(profilePath, '/org/gnome/shell/extensions/', null); return new Gio.Settings({settings_schema: schema, backend: backend}); +} + +function getProfileName(profilePath) { + let items = []; + const settings = getProfileSettings(profilePath); + + const addItems = (settingsKey, options) => { + const option = settings.get_int(settingsKey); + if (option > 0) { + items.push(options[option - 1]); + } + }; + + // clang-format off + addItems('profile-animation-type', [_('Opening Windows'), + _('Closing Windows')]); + addItems('profile-window-type', [_('Normal Windows'), + _('Dialog Windows')]); + addItems('profile-desktop-style', [_('Bright Mode'), + _('Dark Mode')]); + addItems('profile-power-mode', [_('On Battery'), + _('Plugged In')]); + addItems('profile-power-profile', [_('Power-Saver Mode'), + _('Balanced Mode'), + _('Performance Mode'), + _('Power Saver or Balanced'), + _('Balanced or Performance')]); + // clang-format on + + let label = ''; + + if (items.length == 0) { + label = _('Default Profile'); + } else { + label = items.join(' · '); + } + + return label; } \ No newline at end of file From 6f8300412396eb28573115193ccbd0cacda9f5d0 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Mon, 23 Jan 2023 19:58:51 +0100 Subject: [PATCH 10/67] :wrench: Add TV Glitch options --- ...nsions.burn-my-windows-profile.gschema.xml | 48 +++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/schemas/org.gnome.shell.extensions.burn-my-windows-profile.gschema.xml b/schemas/org.gnome.shell.extensions.burn-my-windows-profile.gschema.xml index a8d86cf..8834a2a 100644 --- a/schemas/org.gnome.shell.extensions.burn-my-windows-profile.gschema.xml +++ b/schemas/org.gnome.shell.extensions.burn-my-windows-profile.gschema.xml @@ -597,6 +597,54 @@ SPDX-License-Identifier: CC0-1.0 The color of the effect. + + + + + + + false + TV Glitch Close Effect + Use the Glitch effect for window closing. + + + + false + TV Glitch Open Effect + Use the Glitch effect for window opening. + + + + 750 + TV Glitch Animation Time + The time the Glitch effect takes. + + + + 1.0 + TV Glitch Scale + The size of the effect. + + + + 2.0 + TV Glitch Strength + The intensity of the effect. + + + + 2.0 + TV Glitch Speed + The speed of the effect. + + + + "rgb(100, 160, 255)" + TV Glitch Color + The color of the effect. + + + From b2f5a930d026f7edce952cbd0cf0b6319c956cc7 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Mon, 23 Jan 2023 19:59:19 +0100 Subject: [PATCH 11/67] :sparkles: Fix indentation --- ...nsions.burn-my-windows-profile.gschema.xml | 1550 ++++++++--------- 1 file changed, 775 insertions(+), 775 deletions(-) diff --git a/schemas/org.gnome.shell.extensions.burn-my-windows-profile.gschema.xml b/schemas/org.gnome.shell.extensions.burn-my-windows-profile.gschema.xml index 8834a2a..695c8c8 100644 --- a/schemas/org.gnome.shell.extensions.burn-my-windows-profile.gschema.xml +++ b/schemas/org.gnome.shell.extensions.burn-my-windows-profile.gschema.xml @@ -7,780 +7,780 @@ SPDX-License-Identifier: CC0-1.0 - - - - - - - - 0 - - Profile Animation Type - The animation types for which the current effect settings should be used. - - - - 0 - - Profile Window Type - The window types for which the current effect settings should be used. - - - - 0 - - Profile Desktop Style - The desktop styles for which the current effect settings should be used. - - - - 0 - - Profile Power Mode - The power mode for which the current effect settings should be used. - - - - 0 - - Profile Power Profile - The power profiles in which the current effect settings should be used. - - - - - - - - false - Apparition Enable Effect - Use the apparition effect. - - - - 300 - Apparition Animation Time - The time the apparition effect takes. - - - - 0.5 - Apparition Randomness - The amount of randomness of the apparition effect. - - - - 5.0 - Apparition Twirl Intensity - The amount of twirling of the apparition effect. - - - - 3.0 - Apparition Shake Intensity - The amount of shaking of the apparition effect. - - - - 0.75 - Apparition Suction Intensity - The amount of suction of the apparition effect. - - - - - - - - - false - Pixelate Enable Effect - Use the Pixelate effect. - - - - 500 - Pixelate Animation Time - The time the Pixelate effect takes. - - - - 40 - Pixelate Noise - The noise of the effect. - - - - 10 - Pixelate Pixel Size - The size of the maximum pixelation. - - - - - - - - - false - Pixel Wipe Enable Effect - Use the Pixel Wipe effect. - - - - 1000 - Pixel Wipe Animation Time - The time the Pixel Wipe effect takes. - - - - 10 - Pixel Wipe Pixel Size - The size of the maximum pixelation. - - - - - - - - false - Pixel Wheel Enable Effect - Use the Pixel Wheel effect. - - - - 300 - Pixel Wheel Animation Time - The time the Pixel Wheel effect takes. - - - - 12 - Pixel Wheel Spoke Count - The number of sections in the wheel. - - - - 10 - Pixel Wheel Pixel Size - The size of the maximum pixelation. - - - - - - - - false - Doom Enable Effect - Use the Doom effect. - - - - 1000 - Doom Animation Time - The time the Doom effect takes. - - - - 10.0 - Doom Horizontal Scale - The X scale of the effect. - - - - 10.0 - Doom Vertical Scale - The Y scale of the effect. - - - - 10 - Doom Pixel Size - The size of the maximum pixelation. - - - - - - - - true - Fire Enable Effect - Use the fire effect. - - - - 1500 - Fire Animation Time - The time the fire effect takes. - - - - 0.5 - Fire Movement Speed - The speed at which the fire moves. - - - - 1.0 - Fire Scale - The size of the fire. - - - - false - Fire 3D Noise - Use a 3D noise for the fire. - - - - "rgba(76, 51, 25, 0.0)" - Fire Color 1 - The first color of the fire gradient. - - - - "rgba(180, 55, 30, 0.7)" - Fire Color 2 - The second color of the fire gradient. - - - - "rgba(255, 76, 38, 0.9)" - Fire Color 3 - The third color of the fire gradient. - - - - "rgba(255, 166, 25, 1)" - Fire Color 4 - The fourth color of the fire gradient. - - - - "rgba(255, 255, 255, 1)" - Fire Color 5 - The fifth color of the fire gradient. - - - - - - - - false - Glide Enable Effect - Use the glide effect. - - - - 250 - Glide Animation Time - The time the glide effect takes. - - - - 0.95 - Glide Scale - The scale of the window. - - - - 0.15 - Glide Squish - The amount of squishing. - - - - -0.3 - Glide Tilt - The amount of tilting. - - - - -0.05 - Glide Shift - The amount of shifting. - - - - - - - - false - Matrix Enable Effect - Use the matrix effect. - - - - 1500 - Matrix Animation Time - The time the matrix effect takes. - - - - 20 - Matrix Scale - The size of the matrix letters. - - - - 1.0 - Matrix Randomness - The randomness of the matrix effect. - - - - "rgb(255, 255, 255)" - Matrix Tip Color - The color of the matrix trail tips. - - - - "rgb(25, 255, 89)" - Matrix Trail Color - The color matrix trails. - - - - 0.25 - Matrix Overshoot - The vertical overshooting of the matrix effect. - - - - - - - - false - TV Enable Effect - Use the tv effect. - - - - 400 - TV Animation Time - The time the tv effect takes. - - - - "rgb(255, 255, 255)" - TV Effect Color - The color of the TV effect. - - - - - - - - false - T-Rex Enable Effect - Use the trex effect. - - - - 1000 - T-Rex Animation Time - The time the trex effect takes. - - - - "rgb(170, 0, 0)" - Claw Scratch Color - The color of the claw scratches. - - - - 1.0 - Claw Scratch Scale - Size of the claw scratches. - - - - 0.15 - Claw Scratch Warp - Intensity of the claw scratch warp effect. - - - - 5 - Claw Scratch Count - Number of claw scratches drawn on top of each other. - - - - - - - - false - Hexagon Enable Effect - Use the Hexagon effect. - - - - 1500 - Hexagon Animation Time - The time the Hexagon effect takes. - - - - 3.0 - Hexagon Scale - The size of the effect. - - - - 2.0 - Hexagon Line Width - The width of the lines. - - - - "rgba(200, 255, 255, 0.5)" - Hexagon Line Color - The color of the lines. - - - - "rgba(20, 80, 255, 0.5)" - Hexagon Glow Color - The color of the glow effect. - - - - true - Hexagon Additive Blending - Use additive blending for the line and the glow. - - - - - - - - false - Incinerate Enable Effect - Use the Incinerate effect. - - - - 2000 - Incinerate Animation Time - The time the Incinerate effect takes. - - - - 1.0 - Incinerate Scale - The scale of the effect. - - - - 0.3 - Incinerate Turbulence - The turbulence of the effect. - - - - "rgb(255, 180, 127)" - Incinerate Color - The color of the effect. - - - - true - Incinerate Use Pointer - Use the pointer location for the incinerate effect. - - - - - - - - false - Energize A Enable Effect - Use the Energize A effect. - - - - 2000 - Energize A Animation Time - The time the Energize A effect takes. - - - - 1.0 - Energize A Scale - The size of the effect. - - - - "rgb(255, 200, 50)" - Energize A Color - The color of the effect. - - - - - - - - false - Energize B Enable Effect - Use the Energize B effect. - - - - 1000 - Energize B Animation Time - The time the Energize B effect takes. - - - - 1.0 - Energize B Scale - The size of the effect. - - - - "rgb(160, 180, 255)" - Energize B Color - The color of the effect. - - - - - - - - - false - Glitch Enable Effect - Use the Glitch effect. - - - - 750 - Glitch Animation Time - The time the Glitch effect takes. - - - - 1.0 - Glitch Scale - The size of the effect. - - - - 2.0 - Glitch Strength - The intensity of the effect. - - - - 2.0 - Glitch Speed - The speed of the effect. - - - - "rgb(100, 160, 255)" - Glitch Color - The color of the effect. - - - - - - - - - false - TV Glitch Close Effect - Use the Glitch effect for window closing. - - - - false - TV Glitch Open Effect - Use the Glitch effect for window opening. - - - - 750 - TV Glitch Animation Time - The time the Glitch effect takes. - - - - 1.0 - TV Glitch Scale - The size of the effect. - - - - 2.0 - TV Glitch Strength - The intensity of the effect. - - - - 2.0 - TV Glitch Speed - The speed of the effect. - - - - "rgb(100, 160, 255)" - TV Glitch Color - The color of the effect. - - - - - - - - - false - Wisps Enable Effect - Use the wisps effect. - - - - 1500 - Wisps Animation Time - The time the wisps effect takes. - - - - 1.0 - Wisps Scale - The size of the wisps. - - - - "rgb(255, 100, 200)" - Wisps Effect Color - The color of the wisps effect. - - - - - - - - false - Broken Glass Enable Effect - Use the broken glass effect. - - - - 1000 - Broken Glass Animation Time - The time the broken glass effect takes. - - - - 1.0 - Broken Glass Scale - The size of the broken glass effect. - - - - -1.0 - Broken Glass Gravity - The gravity of the broken glass effect. - - - - 0.5 - Broken Glass Blow Force - The blow force of the broken glass effect. - - - - false - Broken Glass Use Pointer - Use the pointer location for the broken glass effect. - - - - - - - - false - Portal Enable Effect - Use the Portal effect. - - - - 1250 - Portal Animation Time - The time the Portal effect takes. - - - - "rgb(121, 233, 24)" - Portal Color - The color of the effect. - - - - 0.3 - Portal Rotation Speed - The angular speed of the portal. - - - - 1.0 - Portal Whirling - The amount of distortion. - - - - 15.0 - Portal Details - The amount of details in the portal. - - - - - - - - false - Snap Enable Effect - Use the snap effect. - - - - 1500 - Snap Animation Time - The time the snap effect takes. - - - - 3.0 - Snap Scale - The size of the snap effect. - - - - "rgb(50, 40, 35)" - Snap Effect Color - The color of the dust. - - - + + + + + + + + 0 + + Profile Animation Type + The animation types for which the current effect settings should be used. + + + + 0 + + Profile Window Type + The window types for which the current effect settings should be used. + + + + 0 + + Profile Desktop Style + The desktop styles for which the current effect settings should be used. + + + + 0 + + Profile Power Mode + The power mode for which the current effect settings should be used. + + + + 0 + + Profile Power Profile + The power profiles in which the current effect settings should be used. + + + + + + + + false + Apparition Enable Effect + Use the apparition effect. + + + + 300 + Apparition Animation Time + The time the apparition effect takes. + + + + 0.5 + Apparition Randomness + The amount of randomness of the apparition effect. + + + + 5.0 + Apparition Twirl Intensity + The amount of twirling of the apparition effect. + + + + 3.0 + Apparition Shake Intensity + The amount of shaking of the apparition effect. + + + + 0.75 + Apparition Suction Intensity + The amount of suction of the apparition effect. + + + + + + + + + false + Pixelate Enable Effect + Use the Pixelate effect. + + + + 500 + Pixelate Animation Time + The time the Pixelate effect takes. + + + + 40 + Pixelate Noise + The noise of the effect. + + + + 10 + Pixelate Pixel Size + The size of the maximum pixelation. + + + + + + + + + false + Pixel Wipe Enable Effect + Use the Pixel Wipe effect. + + + + 1000 + Pixel Wipe Animation Time + The time the Pixel Wipe effect takes. + + + + 10 + Pixel Wipe Pixel Size + The size of the maximum pixelation. + + + + + + + + false + Pixel Wheel Enable Effect + Use the Pixel Wheel effect. + + + + 300 + Pixel Wheel Animation Time + The time the Pixel Wheel effect takes. + + + + 12 + Pixel Wheel Spoke Count + The number of sections in the wheel. + + + + 10 + Pixel Wheel Pixel Size + The size of the maximum pixelation. + + + + + + + + false + Doom Enable Effect + Use the Doom effect. + + + + 1000 + Doom Animation Time + The time the Doom effect takes. + + + + 10.0 + Doom Horizontal Scale + The X scale of the effect. + + + + 10.0 + Doom Vertical Scale + The Y scale of the effect. + + + + 10 + Doom Pixel Size + The size of the maximum pixelation. + + + + + + + + true + Fire Enable Effect + Use the fire effect. + + + + 1500 + Fire Animation Time + The time the fire effect takes. + + + + 0.5 + Fire Movement Speed + The speed at which the fire moves. + + + + 1.0 + Fire Scale + The size of the fire. + + + + false + Fire 3D Noise + Use a 3D noise for the fire. + + + + "rgba(76, 51, 25, 0.0)" + Fire Color 1 + The first color of the fire gradient. + + + + "rgba(180, 55, 30, 0.7)" + Fire Color 2 + The second color of the fire gradient. + + + + "rgba(255, 76, 38, 0.9)" + Fire Color 3 + The third color of the fire gradient. + + + + "rgba(255, 166, 25, 1)" + Fire Color 4 + The fourth color of the fire gradient. + + + + "rgba(255, 255, 255, 1)" + Fire Color 5 + The fifth color of the fire gradient. + + + + + + + + false + Glide Enable Effect + Use the glide effect. + + + + 250 + Glide Animation Time + The time the glide effect takes. + + + + 0.95 + Glide Scale + The scale of the window. + + + + 0.15 + Glide Squish + The amount of squishing. + + + + -0.3 + Glide Tilt + The amount of tilting. + + + + -0.05 + Glide Shift + The amount of shifting. + + + + + + + + false + Matrix Enable Effect + Use the matrix effect. + + + + 1500 + Matrix Animation Time + The time the matrix effect takes. + + + + 20 + Matrix Scale + The size of the matrix letters. + + + + 1.0 + Matrix Randomness + The randomness of the matrix effect. + + + + "rgb(255, 255, 255)" + Matrix Tip Color + The color of the matrix trail tips. + + + + "rgb(25, 255, 89)" + Matrix Trail Color + The color matrix trails. + + + + 0.25 + Matrix Overshoot + The vertical overshooting of the matrix effect. + + + + + + + + false + TV Enable Effect + Use the tv effect. + + + + 400 + TV Animation Time + The time the tv effect takes. + + + + "rgb(255, 255, 255)" + TV Effect Color + The color of the TV effect. + + + + + + + + false + T-Rex Enable Effect + Use the trex effect. + + + + 1000 + T-Rex Animation Time + The time the trex effect takes. + + + + "rgb(170, 0, 0)" + Claw Scratch Color + The color of the claw scratches. + + + + 1.0 + Claw Scratch Scale + Size of the claw scratches. + + + + 0.15 + Claw Scratch Warp + Intensity of the claw scratch warp effect. + + + + 5 + Claw Scratch Count + Number of claw scratches drawn on top of each other. + + + + + + + + false + Hexagon Enable Effect + Use the Hexagon effect. + + + + 1500 + Hexagon Animation Time + The time the Hexagon effect takes. + + + + 3.0 + Hexagon Scale + The size of the effect. + + + + 2.0 + Hexagon Line Width + The width of the lines. + + + + "rgba(200, 255, 255, 0.5)" + Hexagon Line Color + The color of the lines. + + + + "rgba(20, 80, 255, 0.5)" + Hexagon Glow Color + The color of the glow effect. + + + + true + Hexagon Additive Blending + Use additive blending for the line and the glow. + + + + + + + + false + Incinerate Enable Effect + Use the Incinerate effect. + + + + 2000 + Incinerate Animation Time + The time the Incinerate effect takes. + + + + 1.0 + Incinerate Scale + The scale of the effect. + + + + 0.3 + Incinerate Turbulence + The turbulence of the effect. + + + + "rgb(255, 180, 127)" + Incinerate Color + The color of the effect. + + + + true + Incinerate Use Pointer + Use the pointer location for the incinerate effect. + + + + + + + + false + Energize A Enable Effect + Use the Energize A effect. + + + + 2000 + Energize A Animation Time + The time the Energize A effect takes. + + + + 1.0 + Energize A Scale + The size of the effect. + + + + "rgb(255, 200, 50)" + Energize A Color + The color of the effect. + + + + + + + + false + Energize B Enable Effect + Use the Energize B effect. + + + + 1000 + Energize B Animation Time + The time the Energize B effect takes. + + + + 1.0 + Energize B Scale + The size of the effect. + + + + "rgb(160, 180, 255)" + Energize B Color + The color of the effect. + + + + + + + + + false + Glitch Enable Effect + Use the Glitch effect. + + + + 750 + Glitch Animation Time + The time the Glitch effect takes. + + + + 1.0 + Glitch Scale + The size of the effect. + + + + 2.0 + Glitch Strength + The intensity of the effect. + + + + 2.0 + Glitch Speed + The speed of the effect. + + + + "rgb(100, 160, 255)" + Glitch Color + The color of the effect. + + + + + + + + + false + TV Glitch Close Effect + Use the Glitch effect for window closing. + + + + false + TV Glitch Open Effect + Use the Glitch effect for window opening. + + + + 750 + TV Glitch Animation Time + The time the Glitch effect takes. + + + + 1.0 + TV Glitch Scale + The size of the effect. + + + + 2.0 + TV Glitch Strength + The intensity of the effect. + + + + 2.0 + TV Glitch Speed + The speed of the effect. + + + + "rgb(100, 160, 255)" + TV Glitch Color + The color of the effect. + + + + + + + + + false + Wisps Enable Effect + Use the wisps effect. + + + + 1500 + Wisps Animation Time + The time the wisps effect takes. + + + + 1.0 + Wisps Scale + The size of the wisps. + + + + "rgb(255, 100, 200)" + Wisps Effect Color + The color of the wisps effect. + + + + + + + + false + Broken Glass Enable Effect + Use the broken glass effect. + + + + 1000 + Broken Glass Animation Time + The time the broken glass effect takes. + + + + 1.0 + Broken Glass Scale + The size of the broken glass effect. + + + + -1.0 + Broken Glass Gravity + The gravity of the broken glass effect. + + + + 0.5 + Broken Glass Blow Force + The blow force of the broken glass effect. + + + + false + Broken Glass Use Pointer + Use the pointer location for the broken glass effect. + + + + + + + + false + Portal Enable Effect + Use the Portal effect. + + + + 1250 + Portal Animation Time + The time the Portal effect takes. + + + + "rgb(121, 233, 24)" + Portal Color + The color of the effect. + + + + 0.3 + Portal Rotation Speed + The angular speed of the portal. + + + + 1.0 + Portal Whirling + The amount of distortion. + + + + 15.0 + Portal Details + The amount of details in the portal. + + + + + + + + false + Snap Enable Effect + Use the snap effect. + + + + 1500 + Snap Animation Time + The time the snap effect takes. + + + + 3.0 + Snap Scale + The size of the snap effect. + + + + "rgb(50, 40, 35)" + Snap Effect Color + The color of the dust. + + + \ No newline at end of file From 6bdb1b07ff1cc143364501ab5875c064163efde6 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Wed, 25 Jan 2023 05:50:46 +0100 Subject: [PATCH 12/67] :wrench: Implicitely load effect preferences --- docs/how-to-create-new-effects.md | 25 ++-- prefs.js | 119 ++++++++++-------- .../ui/adw/{Apparition.ui => apparition.ui} | 0 .../adw/{BrokenGlass.ui => broken-glass.ui} | 0 resources/ui/adw/{Doom.ui => doom.ui} | 0 .../ui/adw/{EnergizeA.ui => energize-a.ui} | 0 .../ui/adw/{EnergizeB.ui => energize-b.ui} | 0 resources/ui/adw/{Fire.ui => fire.ui} | 0 resources/ui/adw/{Glide.ui => glide.ui} | 0 resources/ui/adw/{Glitch.ui => glitch.ui} | 0 resources/ui/adw/{Hexagon.ui => hexagon.ui} | 0 .../ui/adw/{Incinerate.ui => incinerate.ui} | 0 resources/ui/adw/{Matrix.ui => matrix.ui} | 0 .../ui/adw/{PixelWheel.ui => pixel-wheel.ui} | 0 .../ui/adw/{PixelWipe.ui => pixel-wipe.ui} | 0 resources/ui/adw/{Pixelate.ui => pixelate.ui} | 0 resources/ui/adw/{Portal.ui => portal.ui} | 0 .../adw/{SnapOfDisintegration.ui => snap.ui} | 0 resources/ui/adw/{TRexAttack.ui => trex.ui} | 0 .../ui/adw/{TVGlitch.ui => tv-glitch.ui} | 0 resources/ui/adw/{TVEffect.ui => tv.ui} | 0 resources/ui/adw/{Wisps.ui => wisps.ui} | 0 .../ui/gtk3/{Apparition.ui => apparition.ui} | 0 resources/ui/gtk3/{Doom.ui => doom.ui} | 0 .../ui/gtk3/{EnergizeA.ui => energize-a.ui} | 0 .../ui/gtk3/{EnergizeB.ui => energize-b.ui} | 0 resources/ui/gtk3/{Fire.ui => fire.ui} | 0 resources/ui/gtk3/{Glide.ui => glide.ui} | 0 resources/ui/gtk3/{Glitch.ui => glitch.ui} | 0 resources/ui/gtk3/{Hexagon.ui => hexagon.ui} | 0 .../ui/gtk3/{Incinerate.ui => incinerate.ui} | 0 .../ui/gtk3/{PixelWheel.ui => pixel-wheel.ui} | 0 .../ui/gtk3/{PixelWipe.ui => pixel-wipe.ui} | 0 .../ui/gtk3/{Pixelate.ui => pixelate.ui} | 0 resources/ui/gtk3/{Portal.ui => portal.ui} | 0 .../ui/gtk3/{TVGlitch.ui => tv-glitch.ui} | 0 resources/ui/gtk3/{TVEffect.ui => tv.ui} | 0 resources/ui/gtk3/{Wisps.ui => wisps.ui} | 0 .../ui/gtk4/{Apparition.ui => apparition.ui} | 0 .../gtk4/{BrokenGlass.ui => broken-glass.ui} | 0 resources/ui/gtk4/{Doom.ui => doom.ui} | 0 .../ui/gtk4/{EnergizeA.ui => energize-a.ui} | 0 .../ui/gtk4/{EnergizeB.ui => energize-b.ui} | 0 resources/ui/gtk4/{Fire.ui => fire.ui} | 0 resources/ui/gtk4/{Glide.ui => glide.ui} | 0 resources/ui/gtk4/{Glitch.ui => glitch.ui} | 0 resources/ui/gtk4/{Hexagon.ui => hexagon.ui} | 0 .../ui/gtk4/{Incinerate.ui => incinerate.ui} | 0 resources/ui/gtk4/{Matrix.ui => matrix.ui} | 0 .../ui/gtk4/{PixelWheel.ui => pixel-wheel.ui} | 0 .../ui/gtk4/{PixelWipe.ui => pixel-wipe.ui} | 0 .../ui/gtk4/{Pixelate.ui => pixelate.ui} | 0 resources/ui/gtk4/{Portal.ui => portal.ui} | 0 .../gtk4/{SnapOfDisintegration.ui => snap.ui} | 0 resources/ui/gtk4/{TRexAttack.ui => trex.ui} | 0 .../ui/gtk4/{TVGlitch.ui => tv-glitch.ui} | 0 resources/ui/gtk4/{TVEffect.ui => tv.ui} | 0 resources/ui/gtk4/{Wisps.ui => wisps.ui} | 0 ...nsions.burn-my-windows-profile.gschema.xml | 14 +-- src/Apparition.js | 14 +-- src/BrokenGlass.js | 17 +-- src/Doom.js | 14 +-- src/EnergizeA.js | 14 +-- src/EnergizeB.js | 14 +-- src/Fire.js | 12 +- src/Glide.js | 14 +-- src/Glitch.js | 14 +-- src/Hexagon.js | 14 +-- src/Incinerate.js | 14 +-- src/Matrix.js | 14 +-- src/PixelWheel.js | 14 +-- src/PixelWipe.js | 14 +-- src/Pixelate.js | 14 +-- src/Portal.js | 14 +-- src/SnapOfDisintegration.js | 15 +-- src/TRexAttack.js | 14 +-- src/TVEffect.js | 14 +-- src/TVGlitch.js | 14 +-- src/Wisps.js | 14 +-- 79 files changed, 141 insertions(+), 299 deletions(-) rename resources/ui/adw/{Apparition.ui => apparition.ui} (100%) rename resources/ui/adw/{BrokenGlass.ui => broken-glass.ui} (100%) rename resources/ui/adw/{Doom.ui => doom.ui} (100%) rename resources/ui/adw/{EnergizeA.ui => energize-a.ui} (100%) rename resources/ui/adw/{EnergizeB.ui => energize-b.ui} (100%) rename resources/ui/adw/{Fire.ui => fire.ui} (100%) rename resources/ui/adw/{Glide.ui => glide.ui} (100%) rename resources/ui/adw/{Glitch.ui => glitch.ui} (100%) rename resources/ui/adw/{Hexagon.ui => hexagon.ui} (100%) rename resources/ui/adw/{Incinerate.ui => incinerate.ui} (100%) rename resources/ui/adw/{Matrix.ui => matrix.ui} (100%) rename resources/ui/adw/{PixelWheel.ui => pixel-wheel.ui} (100%) rename resources/ui/adw/{PixelWipe.ui => pixel-wipe.ui} (100%) rename resources/ui/adw/{Pixelate.ui => pixelate.ui} (100%) rename resources/ui/adw/{Portal.ui => portal.ui} (100%) rename resources/ui/adw/{SnapOfDisintegration.ui => snap.ui} (100%) rename resources/ui/adw/{TRexAttack.ui => trex.ui} (100%) rename resources/ui/adw/{TVGlitch.ui => tv-glitch.ui} (100%) rename resources/ui/adw/{TVEffect.ui => tv.ui} (100%) rename resources/ui/adw/{Wisps.ui => wisps.ui} (100%) rename resources/ui/gtk3/{Apparition.ui => apparition.ui} (100%) rename resources/ui/gtk3/{Doom.ui => doom.ui} (100%) rename resources/ui/gtk3/{EnergizeA.ui => energize-a.ui} (100%) rename resources/ui/gtk3/{EnergizeB.ui => energize-b.ui} (100%) rename resources/ui/gtk3/{Fire.ui => fire.ui} (100%) rename resources/ui/gtk3/{Glide.ui => glide.ui} (100%) rename resources/ui/gtk3/{Glitch.ui => glitch.ui} (100%) rename resources/ui/gtk3/{Hexagon.ui => hexagon.ui} (100%) rename resources/ui/gtk3/{Incinerate.ui => incinerate.ui} (100%) rename resources/ui/gtk3/{PixelWheel.ui => pixel-wheel.ui} (100%) rename resources/ui/gtk3/{PixelWipe.ui => pixel-wipe.ui} (100%) rename resources/ui/gtk3/{Pixelate.ui => pixelate.ui} (100%) rename resources/ui/gtk3/{Portal.ui => portal.ui} (100%) rename resources/ui/gtk3/{TVGlitch.ui => tv-glitch.ui} (100%) rename resources/ui/gtk3/{TVEffect.ui => tv.ui} (100%) rename resources/ui/gtk3/{Wisps.ui => wisps.ui} (100%) rename resources/ui/gtk4/{Apparition.ui => apparition.ui} (100%) rename resources/ui/gtk4/{BrokenGlass.ui => broken-glass.ui} (100%) rename resources/ui/gtk4/{Doom.ui => doom.ui} (100%) rename resources/ui/gtk4/{EnergizeA.ui => energize-a.ui} (100%) rename resources/ui/gtk4/{EnergizeB.ui => energize-b.ui} (100%) rename resources/ui/gtk4/{Fire.ui => fire.ui} (100%) rename resources/ui/gtk4/{Glide.ui => glide.ui} (100%) rename resources/ui/gtk4/{Glitch.ui => glitch.ui} (100%) rename resources/ui/gtk4/{Hexagon.ui => hexagon.ui} (100%) rename resources/ui/gtk4/{Incinerate.ui => incinerate.ui} (100%) rename resources/ui/gtk4/{Matrix.ui => matrix.ui} (100%) rename resources/ui/gtk4/{PixelWheel.ui => pixel-wheel.ui} (100%) rename resources/ui/gtk4/{PixelWipe.ui => pixel-wipe.ui} (100%) rename resources/ui/gtk4/{Pixelate.ui => pixelate.ui} (100%) rename resources/ui/gtk4/{Portal.ui => portal.ui} (100%) rename resources/ui/gtk4/{SnapOfDisintegration.ui => snap.ui} (100%) rename resources/ui/gtk4/{TRexAttack.ui => trex.ui} (100%) rename resources/ui/gtk4/{TVGlitch.ui => tv-glitch.ui} (100%) rename resources/ui/gtk4/{TVEffect.ui => tv.ui} (100%) rename resources/ui/gtk4/{Wisps.ui => wisps.ui} (100%) diff --git a/docs/how-to-create-new-effects.md b/docs/how-to-create-new-effects.md index 624d5fe..24b923f 100644 --- a/docs/how-to-create-new-effects.md +++ b/docs/how-to-create-new-effects.md @@ -196,7 +196,8 @@ var SimpleFade = class { // This will be called in various places where a unique identifier for this effect is // required. It should match the prefix of the settings keys which store whether the // effect is enabled currently (e.g. '*-enable-effect'), and its animation time - // (e.g. '*-animation-time'). + // (e.g. '*-animation-time'). Also, the shader file and the settings UI files should be + // named likes this. getNick() { return 'simple-fade'; } @@ -209,10 +210,9 @@ var SimpleFade = class { // -------------------------------------------------------------------- API for prefs.js - // This is called by the preferences dialog. It loads the settings page for this effect, - // binds all properties to the settings and appends the page to the main stack of the - // preferences dialog. - getPreferences(dialog) { + // This is called by the preferences dialog whenever a new effect profile is loaded. It + // binds all user interface elements to the respective settings keys of the profile. + bindPreferences(dialog) { // Empty for now... Code is added here later in the tutorial! return null; } @@ -265,9 +265,9 @@ There should be two sliders in this example: The animation duration and the widt If your effect supports GNOME Shell 3.3x _and_ GNOME Shell 40+, you will have to provide three `*.ui` files for this. This is because starting with GNOME Shell 40, the preference dialog uses GTK4, before it used to use GTK3. Starting with GNOME Shell 42, it uses `libadwaita` which requires different UI files again. -We will load the respective file in the `getPreferences()` method of your new effect class. +We will load the respective file in the `bindPreferences()` method of your new effect class. -Just save the code below to `resources/ui/gtk3/SimpleFade.ui`, `resources/ui/gtk4/SimpleFade.ui`, and `resources/ui/adw/SimpleFade.ui` respectively. +Just save the code below to `resources/ui/gtk3/simple-fade.ui`, `resources/ui/gtk4/simple-fade.ui`, and `resources/ui/adw/simple-fade.ui` respectively. Remember to replace any occurrence of `simple-fade` with your effect's nick-name!
@@ -641,21 +641,14 @@ SPDX-License-Identifier: GPL-3.0-or-later ### Loading the Preferences Page -In order to load the above `*.ui` files, add the following code to your effect's `getPreferences()` method. +In order to load the above `*.ui` files, add the following code to your effect's `bindPreferences()` method. ```javascript -static getPreferences(dialog) { - - // Add the settings page to the builder. - dialog.getBuilder().add_from_resource(`/ui/${utils.getUIDir()}/SimpleFade.ui`); - +bindPreferences(dialog) { // These connect the settings to the UI elements. Have a look at prefs.js // on how to bind other types of UI elements. dialog.bindAdjustment('simple-fade-animation-time'); dialog.bindAdjustment('simple-fade-width'); - - // Finally, return the new settings page. - return dialog.getBuilder().get_object('simple-fade-prefs'); } ``` diff --git a/prefs.js b/prefs.js index 1bcc442..ce04dbb 100644 --- a/prefs.js +++ b/prefs.js @@ -107,8 +107,6 @@ var PreferencesDialog = class PreferencesDialog { this._loadActiveProfile(); this._updateProfileButton(); }); - this._loadActiveProfile(); - this._updateProfileButton(); // Check whether the power profiles daemon is available - if not, we hide the // corresponding settings row. @@ -144,7 +142,20 @@ var PreferencesDialog = class PreferencesDialog { this._ALL_EFFECTS.forEach(effect => { const [minMajor, minMinor] = effect.getMinShellVersion(); if (utils.shellVersionIsAtLeast(minMajor, minMinor)) { - const row = effect.getPreferences(this); + + const uiFile = `/ui/${utils.getUIDir()}/${effect.getNick()}.ui`; + const [hasPrefs] = Gio.resources_get_info(uiFile, 0); + + let row; + if (hasPrefs) { + // Add the settings page to the builder. + this._builder.add_from_resource(uiFile); + + // Add the effect's preferences (if any). + row = this._builder.get_object(`${effect.getNick()}-prefs`); + } else { + row = Adw.ActionRow.new(); + } // On older versions of Adw (e.g. on GNOME Shell <43), the set_use_markup() does // not yet exist. @@ -157,15 +168,17 @@ var PreferencesDialog = class PreferencesDialog { // Un-expand any previously expanded effect row. This way we ensure that there // is only one expanded row at any time. - row.connect('notify::expanded', currentRow => { - if (currentRow.get_expanded()) { - this._effectRows.forEach(row => { - if (row != currentRow) { - row.set_expanded(false); - } - }); - } - }); + if (hasPrefs) { + row.connect('notify::expanded', currentRow => { + if (currentRow.get_expanded()) { + this._effectRows.forEach(row => { + if (row != currentRow && row.set_expanded) { + row.set_expanded(false); + } + }); + } + }); + } // The preview button. const previewButton = Gtk.Button.new_from_icon_name('bmw-preview-symbolic'); @@ -179,11 +192,11 @@ var PreferencesDialog = class PreferencesDialog { this._previewEffect(effect); }); - // Now add the two toggle buttons for enabling and disabling the effect. + // Now add the toggle button for enabling and disabling the effect. const button = Gtk.Switch.new(); - button.set_action_name(`prefs.${effect.getNick()}-enable-effect`); button.set_tooltip_text(_('Use this effect')); button.set_valign(Gtk.Align.CENTER); + this._builder.expose_object(`${effect.getNick()}-enable-effect`, button); row.add_prefix(button); group.add(row); @@ -225,10 +238,18 @@ var PreferencesDialog = class PreferencesDialog { page.margin_top = 60; page.margin_bottom = 60; - // Add the effect's preferences (if any). - const preferences = effect.getPreferences(this); - if (preferences) { - this.gtkBoxAppend(page, preferences); + const uiFile = `/ui/${utils.getUIDir()}/${effect.getNick()}.ui`; + const [hasPrefs] = Gio.resources_get_info(uiFile); + if (hasPrefs) { + + // Add the settings page to the builder. + this._builder.add_from_resource(uiFile); + + // Add the effect's preferences (if any). + const prefs = this._builder.get_object(`${effect.getNick()}-prefs`); + if (prefs) { + this.gtkBoxAppend(page, prefs); + } } stack.add_titled(page, effect.getNick(), effect.getLabel()); @@ -244,6 +265,9 @@ var PreferencesDialog = class PreferencesDialog { // Show the version number in the title bar. window.set_title(`Burn-My-Windows ${Me.metadata.version}`); + this._loadActiveProfile(); + this._updateProfileButton(); + // Populate the menu with actions. const group = Gio.SimpleActionGroup.new(); window.insert_action_group('prefs', group); @@ -391,21 +415,8 @@ var PreferencesDialog = class PreferencesDialog { group.add_action(aboutAction); } - // Bind all the profile-related actions. + // Setup all the profile-related actions. { - const setupProfileOption = (settingsKey) => { - this.bindComboRow(settingsKey); - this._profileSettings.connect('changed::' + settingsKey, - () => this._updateProfileButton()); - }; - - setupProfileOption('profile-animation-type'); - setupProfileOption('profile-window-type'); - setupProfileOption('profile-desktop-style'); - setupProfileOption('profile-power-mode'); - setupProfileOption('profile-power-profile'); - - const profileAction = this._settings.create_action('active-profile'); group.add_action(profileAction); @@ -415,7 +426,6 @@ var PreferencesDialog = class PreferencesDialog { this._settings.set_string('active-profile', profile); this._builder.get_object('edit-profile-button').active = true; }); - group.add_action(newProfileAction); const deleteProfileAction = Gio.SimpleAction.new('profile-delete', null); @@ -437,26 +447,6 @@ var PreferencesDialog = class PreferencesDialog { group.add_action(deleteProfileAction); } - - // Populate the enabled-effects drop-down menu. - { - this._ALL_EFFECTS.forEach(effect => { - const [minMajor, minMinor] = effect.getMinShellVersion(); - if (utils.shellVersionIsAtLeast(minMajor, minMinor)) { - const actionName = effect.getNick() + '-enable-effect'; - const action = this._profileSettings.create_action(actionName); - group.add_action(action); - - // The menu only exists if not using libadwaita. With libadwaita, individual - // ToggleButtons are used for triggering the above actions. - if (!utils.isADW()) { - const menu = this._builder.get_object('enabled-effects-menu'); - const label = effect.getLabel(); - menu.append_item(Gio.MenuItem.new(label, 'prefs.' + actionName)); - } - } - }); - } }); // As we do not have something like a destructor, we just listen for the destroy @@ -567,6 +557,29 @@ var PreferencesDialog = class PreferencesDialog { utils.debug('loading ' + activeProfile); this._profileSettings = utils.getProfileSettings(activeProfile); + + // Bind all the profile-related settings. + { + const setupProfileOption = (settingsKey) => { + this.bindComboRow(settingsKey); + this._profileSettings.connect('changed::' + settingsKey, + () => this._updateProfileButton()); + }; + + setupProfileOption('profile-animation-type'); + setupProfileOption('profile-window-type'); + setupProfileOption('profile-desktop-style'); + setupProfileOption('profile-power-mode'); + setupProfileOption('profile-power-profile'); + } + + this._ALL_EFFECTS.forEach(effect => { + const [minMajor, minMinor] = effect.getMinShellVersion(); + if (utils.shellVersionIsAtLeast(minMajor, minMinor)) { + this.bindSwitch(`${effect.getNick()}-enable-effect`); + effect.bindPreferences(this); + } + }); } _updateProfileButton() { diff --git a/resources/ui/adw/Apparition.ui b/resources/ui/adw/apparition.ui similarity index 100% rename from resources/ui/adw/Apparition.ui rename to resources/ui/adw/apparition.ui diff --git a/resources/ui/adw/BrokenGlass.ui b/resources/ui/adw/broken-glass.ui similarity index 100% rename from resources/ui/adw/BrokenGlass.ui rename to resources/ui/adw/broken-glass.ui diff --git a/resources/ui/adw/Doom.ui b/resources/ui/adw/doom.ui similarity index 100% rename from resources/ui/adw/Doom.ui rename to resources/ui/adw/doom.ui diff --git a/resources/ui/adw/EnergizeA.ui b/resources/ui/adw/energize-a.ui similarity index 100% rename from resources/ui/adw/EnergizeA.ui rename to resources/ui/adw/energize-a.ui diff --git a/resources/ui/adw/EnergizeB.ui b/resources/ui/adw/energize-b.ui similarity index 100% rename from resources/ui/adw/EnergizeB.ui rename to resources/ui/adw/energize-b.ui diff --git a/resources/ui/adw/Fire.ui b/resources/ui/adw/fire.ui similarity index 100% rename from resources/ui/adw/Fire.ui rename to resources/ui/adw/fire.ui diff --git a/resources/ui/adw/Glide.ui b/resources/ui/adw/glide.ui similarity index 100% rename from resources/ui/adw/Glide.ui rename to resources/ui/adw/glide.ui diff --git a/resources/ui/adw/Glitch.ui b/resources/ui/adw/glitch.ui similarity index 100% rename from resources/ui/adw/Glitch.ui rename to resources/ui/adw/glitch.ui diff --git a/resources/ui/adw/Hexagon.ui b/resources/ui/adw/hexagon.ui similarity index 100% rename from resources/ui/adw/Hexagon.ui rename to resources/ui/adw/hexagon.ui diff --git a/resources/ui/adw/Incinerate.ui b/resources/ui/adw/incinerate.ui similarity index 100% rename from resources/ui/adw/Incinerate.ui rename to resources/ui/adw/incinerate.ui diff --git a/resources/ui/adw/Matrix.ui b/resources/ui/adw/matrix.ui similarity index 100% rename from resources/ui/adw/Matrix.ui rename to resources/ui/adw/matrix.ui diff --git a/resources/ui/adw/PixelWheel.ui b/resources/ui/adw/pixel-wheel.ui similarity index 100% rename from resources/ui/adw/PixelWheel.ui rename to resources/ui/adw/pixel-wheel.ui diff --git a/resources/ui/adw/PixelWipe.ui b/resources/ui/adw/pixel-wipe.ui similarity index 100% rename from resources/ui/adw/PixelWipe.ui rename to resources/ui/adw/pixel-wipe.ui diff --git a/resources/ui/adw/Pixelate.ui b/resources/ui/adw/pixelate.ui similarity index 100% rename from resources/ui/adw/Pixelate.ui rename to resources/ui/adw/pixelate.ui diff --git a/resources/ui/adw/Portal.ui b/resources/ui/adw/portal.ui similarity index 100% rename from resources/ui/adw/Portal.ui rename to resources/ui/adw/portal.ui diff --git a/resources/ui/adw/SnapOfDisintegration.ui b/resources/ui/adw/snap.ui similarity index 100% rename from resources/ui/adw/SnapOfDisintegration.ui rename to resources/ui/adw/snap.ui diff --git a/resources/ui/adw/TRexAttack.ui b/resources/ui/adw/trex.ui similarity index 100% rename from resources/ui/adw/TRexAttack.ui rename to resources/ui/adw/trex.ui diff --git a/resources/ui/adw/TVGlitch.ui b/resources/ui/adw/tv-glitch.ui similarity index 100% rename from resources/ui/adw/TVGlitch.ui rename to resources/ui/adw/tv-glitch.ui diff --git a/resources/ui/adw/TVEffect.ui b/resources/ui/adw/tv.ui similarity index 100% rename from resources/ui/adw/TVEffect.ui rename to resources/ui/adw/tv.ui diff --git a/resources/ui/adw/Wisps.ui b/resources/ui/adw/wisps.ui similarity index 100% rename from resources/ui/adw/Wisps.ui rename to resources/ui/adw/wisps.ui diff --git a/resources/ui/gtk3/Apparition.ui b/resources/ui/gtk3/apparition.ui similarity index 100% rename from resources/ui/gtk3/Apparition.ui rename to resources/ui/gtk3/apparition.ui diff --git a/resources/ui/gtk3/Doom.ui b/resources/ui/gtk3/doom.ui similarity index 100% rename from resources/ui/gtk3/Doom.ui rename to resources/ui/gtk3/doom.ui diff --git a/resources/ui/gtk3/EnergizeA.ui b/resources/ui/gtk3/energize-a.ui similarity index 100% rename from resources/ui/gtk3/EnergizeA.ui rename to resources/ui/gtk3/energize-a.ui diff --git a/resources/ui/gtk3/EnergizeB.ui b/resources/ui/gtk3/energize-b.ui similarity index 100% rename from resources/ui/gtk3/EnergizeB.ui rename to resources/ui/gtk3/energize-b.ui diff --git a/resources/ui/gtk3/Fire.ui b/resources/ui/gtk3/fire.ui similarity index 100% rename from resources/ui/gtk3/Fire.ui rename to resources/ui/gtk3/fire.ui diff --git a/resources/ui/gtk3/Glide.ui b/resources/ui/gtk3/glide.ui similarity index 100% rename from resources/ui/gtk3/Glide.ui rename to resources/ui/gtk3/glide.ui diff --git a/resources/ui/gtk3/Glitch.ui b/resources/ui/gtk3/glitch.ui similarity index 100% rename from resources/ui/gtk3/Glitch.ui rename to resources/ui/gtk3/glitch.ui diff --git a/resources/ui/gtk3/Hexagon.ui b/resources/ui/gtk3/hexagon.ui similarity index 100% rename from resources/ui/gtk3/Hexagon.ui rename to resources/ui/gtk3/hexagon.ui diff --git a/resources/ui/gtk3/Incinerate.ui b/resources/ui/gtk3/incinerate.ui similarity index 100% rename from resources/ui/gtk3/Incinerate.ui rename to resources/ui/gtk3/incinerate.ui diff --git a/resources/ui/gtk3/PixelWheel.ui b/resources/ui/gtk3/pixel-wheel.ui similarity index 100% rename from resources/ui/gtk3/PixelWheel.ui rename to resources/ui/gtk3/pixel-wheel.ui diff --git a/resources/ui/gtk3/PixelWipe.ui b/resources/ui/gtk3/pixel-wipe.ui similarity index 100% rename from resources/ui/gtk3/PixelWipe.ui rename to resources/ui/gtk3/pixel-wipe.ui diff --git a/resources/ui/gtk3/Pixelate.ui b/resources/ui/gtk3/pixelate.ui similarity index 100% rename from resources/ui/gtk3/Pixelate.ui rename to resources/ui/gtk3/pixelate.ui diff --git a/resources/ui/gtk3/Portal.ui b/resources/ui/gtk3/portal.ui similarity index 100% rename from resources/ui/gtk3/Portal.ui rename to resources/ui/gtk3/portal.ui diff --git a/resources/ui/gtk3/TVGlitch.ui b/resources/ui/gtk3/tv-glitch.ui similarity index 100% rename from resources/ui/gtk3/TVGlitch.ui rename to resources/ui/gtk3/tv-glitch.ui diff --git a/resources/ui/gtk3/TVEffect.ui b/resources/ui/gtk3/tv.ui similarity index 100% rename from resources/ui/gtk3/TVEffect.ui rename to resources/ui/gtk3/tv.ui diff --git a/resources/ui/gtk3/Wisps.ui b/resources/ui/gtk3/wisps.ui similarity index 100% rename from resources/ui/gtk3/Wisps.ui rename to resources/ui/gtk3/wisps.ui diff --git a/resources/ui/gtk4/Apparition.ui b/resources/ui/gtk4/apparition.ui similarity index 100% rename from resources/ui/gtk4/Apparition.ui rename to resources/ui/gtk4/apparition.ui diff --git a/resources/ui/gtk4/BrokenGlass.ui b/resources/ui/gtk4/broken-glass.ui similarity index 100% rename from resources/ui/gtk4/BrokenGlass.ui rename to resources/ui/gtk4/broken-glass.ui diff --git a/resources/ui/gtk4/Doom.ui b/resources/ui/gtk4/doom.ui similarity index 100% rename from resources/ui/gtk4/Doom.ui rename to resources/ui/gtk4/doom.ui diff --git a/resources/ui/gtk4/EnergizeA.ui b/resources/ui/gtk4/energize-a.ui similarity index 100% rename from resources/ui/gtk4/EnergizeA.ui rename to resources/ui/gtk4/energize-a.ui diff --git a/resources/ui/gtk4/EnergizeB.ui b/resources/ui/gtk4/energize-b.ui similarity index 100% rename from resources/ui/gtk4/EnergizeB.ui rename to resources/ui/gtk4/energize-b.ui diff --git a/resources/ui/gtk4/Fire.ui b/resources/ui/gtk4/fire.ui similarity index 100% rename from resources/ui/gtk4/Fire.ui rename to resources/ui/gtk4/fire.ui diff --git a/resources/ui/gtk4/Glide.ui b/resources/ui/gtk4/glide.ui similarity index 100% rename from resources/ui/gtk4/Glide.ui rename to resources/ui/gtk4/glide.ui diff --git a/resources/ui/gtk4/Glitch.ui b/resources/ui/gtk4/glitch.ui similarity index 100% rename from resources/ui/gtk4/Glitch.ui rename to resources/ui/gtk4/glitch.ui diff --git a/resources/ui/gtk4/Hexagon.ui b/resources/ui/gtk4/hexagon.ui similarity index 100% rename from resources/ui/gtk4/Hexagon.ui rename to resources/ui/gtk4/hexagon.ui diff --git a/resources/ui/gtk4/Incinerate.ui b/resources/ui/gtk4/incinerate.ui similarity index 100% rename from resources/ui/gtk4/Incinerate.ui rename to resources/ui/gtk4/incinerate.ui diff --git a/resources/ui/gtk4/Matrix.ui b/resources/ui/gtk4/matrix.ui similarity index 100% rename from resources/ui/gtk4/Matrix.ui rename to resources/ui/gtk4/matrix.ui diff --git a/resources/ui/gtk4/PixelWheel.ui b/resources/ui/gtk4/pixel-wheel.ui similarity index 100% rename from resources/ui/gtk4/PixelWheel.ui rename to resources/ui/gtk4/pixel-wheel.ui diff --git a/resources/ui/gtk4/PixelWipe.ui b/resources/ui/gtk4/pixel-wipe.ui similarity index 100% rename from resources/ui/gtk4/PixelWipe.ui rename to resources/ui/gtk4/pixel-wipe.ui diff --git a/resources/ui/gtk4/Pixelate.ui b/resources/ui/gtk4/pixelate.ui similarity index 100% rename from resources/ui/gtk4/Pixelate.ui rename to resources/ui/gtk4/pixelate.ui diff --git a/resources/ui/gtk4/Portal.ui b/resources/ui/gtk4/portal.ui similarity index 100% rename from resources/ui/gtk4/Portal.ui rename to resources/ui/gtk4/portal.ui diff --git a/resources/ui/gtk4/SnapOfDisintegration.ui b/resources/ui/gtk4/snap.ui similarity index 100% rename from resources/ui/gtk4/SnapOfDisintegration.ui rename to resources/ui/gtk4/snap.ui diff --git a/resources/ui/gtk4/TRexAttack.ui b/resources/ui/gtk4/trex.ui similarity index 100% rename from resources/ui/gtk4/TRexAttack.ui rename to resources/ui/gtk4/trex.ui diff --git a/resources/ui/gtk4/TVGlitch.ui b/resources/ui/gtk4/tv-glitch.ui similarity index 100% rename from resources/ui/gtk4/TVGlitch.ui rename to resources/ui/gtk4/tv-glitch.ui diff --git a/resources/ui/gtk4/TVEffect.ui b/resources/ui/gtk4/tv.ui similarity index 100% rename from resources/ui/gtk4/TVEffect.ui rename to resources/ui/gtk4/tv.ui diff --git a/resources/ui/gtk4/Wisps.ui b/resources/ui/gtk4/wisps.ui similarity index 100% rename from resources/ui/gtk4/Wisps.ui rename to resources/ui/gtk4/wisps.ui diff --git a/schemas/org.gnome.shell.extensions.burn-my-windows-profile.gschema.xml b/schemas/org.gnome.shell.extensions.burn-my-windows-profile.gschema.xml index 695c8c8..917cc36 100644 --- a/schemas/org.gnome.shell.extensions.burn-my-windows-profile.gschema.xml +++ b/schemas/org.gnome.shell.extensions.burn-my-windows-profile.gschema.xml @@ -602,22 +602,16 @@ SPDX-License-Identifier: CC0-1.0 - + false - TV Glitch Close Effect - Use the Glitch effect for window closing. - - - - false - TV Glitch Open Effect - Use the Glitch effect for window opening. + TV Glitch Enable Effect + Use the TV Glitch effect. 750 TV Glitch Animation Time - The time the Glitch effect takes. + The time the TV Glitch effect takes. diff --git a/src/Apparition.js b/src/Apparition.js index 101fce0..067389e 100644 --- a/src/Apparition.js +++ b/src/Apparition.js @@ -83,22 +83,14 @@ var Apparition = class { // -------------------------------------------------------------------- API for prefs.js - // This is called by the preferences dialog. It loads the settings page for this effect, - // and binds all properties to the settings. - getPreferences(dialog) { - - // Add the settings page to the builder. - dialog.getBuilder().add_from_resource(`/ui/${utils.getUIDir()}/Apparition.ui`); - - // Bind all properties. + // This is called by the preferences dialog whenever a new effect profile is loaded. It + // binds all user interface elements to the respective settings keys of the profile. + bindPreferences(dialog) { dialog.bindAdjustment('apparition-randomness'); dialog.bindAdjustment('apparition-animation-time'); dialog.bindAdjustment('apparition-twirl-intensity'); dialog.bindAdjustment('apparition-shake-intensity'); dialog.bindAdjustment('apparition-suction-intensity'); - - // Finally, return the new settings page. - return dialog.getBuilder().get_object('apparition-prefs'); } // ---------------------------------------------------------------- API for extension.js diff --git a/src/BrokenGlass.js b/src/BrokenGlass.js index 8eaf49e..2ad3773 100644 --- a/src/BrokenGlass.js +++ b/src/BrokenGlass.js @@ -128,7 +128,8 @@ var BrokenGlass = class { // This will be called in various places where a unique identifier for this effect is // required. It should match the prefix of the settings keys which store whether the // effect is enabled currently (e.g. '*-enable-effect'), and its animation time - // (e.g. '*-animation-time'). + // (e.g. '*-animation-time'). Also, the shader file and the settings UI files should be + // named likes this. getNick() { return 'broken-glass'; } @@ -141,22 +142,14 @@ var BrokenGlass = class { // -------------------------------------------------------------------- API for prefs.js - // This is called by the preferences dialog. It loads the settings page for this effect, - // and binds all properties to the settings. - getPreferences(dialog) { - - // Add the settings page to the builder. - dialog.getBuilder().add_from_resource(`/ui/${utils.getUIDir()}/BrokenGlass.ui`); - - // Bind all properties. + // This is called by the preferences dialog whenever a new effect profile is loaded. It + // binds all user interface elements to the respective settings keys of the profile. + bindPreferences(dialog) { dialog.bindAdjustment('broken-glass-animation-time'); dialog.bindAdjustment('broken-glass-scale'); dialog.bindAdjustment('broken-glass-gravity'); dialog.bindAdjustment('broken-glass-blow-force'); dialog.bindSwitch('broken-glass-use-pointer'); - - // Finally, return the new settings page. - return dialog.getBuilder().get_object('broken-glass-prefs'); } // ---------------------------------------------------------------- API for extension.js diff --git a/src/Doom.js b/src/Doom.js index 4345ff5..b457faa 100644 --- a/src/Doom.js +++ b/src/Doom.js @@ -90,21 +90,13 @@ var Doom = class { // -------------------------------------------------------------------- API for prefs.js - // This is called by the preferences dialog. It loads the settings page for this effect, - // and binds all properties to the settings. - getPreferences(dialog) { - - // Add the settings page to the builder. - dialog.getBuilder().add_from_resource(`/ui/${utils.getUIDir()}/Doom.ui`); - - // Bind all properties. + // This is called by the preferences dialog whenever a new effect profile is loaded. It + // binds all user interface elements to the respective settings keys of the profile. + bindPreferences(dialog) { dialog.bindAdjustment('doom-animation-time'); dialog.bindAdjustment('doom-horizontal-scale'); dialog.bindAdjustment('doom-vertical-scale'); dialog.bindAdjustment('doom-pixel-size'); - - // Finally, return the new settings page. - return dialog.getBuilder().get_object('doom-prefs'); } // ---------------------------------------------------------------- API for extension.js diff --git a/src/EnergizeA.js b/src/EnergizeA.js index 10d2e67..cb8c2a7 100644 --- a/src/EnergizeA.js +++ b/src/EnergizeA.js @@ -82,20 +82,12 @@ var EnergizeA = class { // -------------------------------------------------------------------- API for prefs.js - // This is called by the preferences dialog. It loads the settings page for this effect, - // and binds all properties to the settings. - getPreferences(dialog) { - - // Add the settings page to the builder. - dialog.getBuilder().add_from_resource(`/ui/${utils.getUIDir()}/EnergizeA.ui`); - - // Bind all properties. + // This is called by the preferences dialog whenever a new effect profile is loaded. It + // binds all user interface elements to the respective settings keys of the profile. + bindPreferences(dialog) { dialog.bindAdjustment('energize-a-animation-time'); dialog.bindAdjustment('energize-a-scale'); dialog.bindColorButton('energize-a-color'); - - // Finally, return the new settings page. - return dialog.getBuilder().get_object('energize-a-prefs'); } // ---------------------------------------------------------------- API for extension.js diff --git a/src/EnergizeB.js b/src/EnergizeB.js index edd2472..2b31c3a 100644 --- a/src/EnergizeB.js +++ b/src/EnergizeB.js @@ -83,20 +83,12 @@ var EnergizeB = class { // -------------------------------------------------------------------- API for prefs.js - // This is called by the preferences dialog. It loads the settings page for this effect, - // and binds all properties to the settings. - getPreferences(dialog) { - - // Add the settings page to the builder. - dialog.getBuilder().add_from_resource(`/ui/${utils.getUIDir()}/EnergizeB.ui`); - - // Bind all properties. + // This is called by the preferences dialog whenever a new effect profile is loaded. It + // binds all user interface elements to the respective settings keys of the profile. + bindPreferences(dialog) { dialog.bindAdjustment('energize-b-animation-time'); dialog.bindAdjustment('energize-b-scale'); dialog.bindColorButton('energize-b-color'); - - // Finally, return the new settings page. - return dialog.getBuilder().get_object('energize-b-prefs'); } // ---------------------------------------------------------------- API for extension.js diff --git a/src/Fire.js b/src/Fire.js index 523189c..96e543c 100644 --- a/src/Fire.js +++ b/src/Fire.js @@ -102,12 +102,9 @@ var Fire = class { // -------------------------------------------------------------------- API for prefs.js - // This is called by the preferences dialog. It loads the settings page for this effect, - // and binds all properties to the settings. - getPreferences(dialog) { - - // Add the settings page to the builder. - dialog.getBuilder().add_from_resource(`/ui/${utils.getUIDir()}/Fire.ui`); + // This is called by the preferences dialog whenever a new effect profile is loaded. It + // binds all user interface elements to the respective settings keys of the profile. + bindPreferences(dialog) { // Bind all properties. dialog.bindAdjustment('fire-animation-time'); @@ -131,9 +128,6 @@ var Fire = class { // Initialize the fire-preset dropdown. this._createFirePresets(dialog); - - // Finally, return the new settings page. - return dialog.getBuilder().get_object('fire-prefs'); } // ---------------------------------------------------------------- API for extension.js diff --git a/src/Glide.js b/src/Glide.js index 1dcc68e..14cfe4d 100644 --- a/src/Glide.js +++ b/src/Glide.js @@ -80,22 +80,14 @@ var Glide = class { // -------------------------------------------------------------------- API for prefs.js - // This is called by the preferences dialog. It loads the settings page for this effect, - // and binds all properties to the settings. - getPreferences(dialog) { - - // Add the settings page to the builder. - dialog.getBuilder().add_from_resource(`/ui/${utils.getUIDir()}/Glide.ui`); - - // Bind all properties. + // This is called by the preferences dialog whenever a new effect profile is loaded. It + // binds all user interface elements to the respective settings keys of the profile. + bindPreferences(dialog) { dialog.bindAdjustment('glide-animation-time'); dialog.bindAdjustment('glide-scale'); dialog.bindAdjustment('glide-squish'); dialog.bindAdjustment('glide-tilt'); dialog.bindAdjustment('glide-shift'); - - // Finally, return the new settings page. - return dialog.getBuilder().get_object('glide-prefs'); } // ---------------------------------------------------------------- API for extension.js diff --git a/src/Glitch.js b/src/Glitch.js index 356e336..cef768c 100644 --- a/src/Glitch.js +++ b/src/Glitch.js @@ -91,22 +91,14 @@ var Glitch = class { // -------------------------------------------------------------------- API for prefs.js - // This is called by the preferences dialog. It loads the settings page for this effect, - // and binds all properties to the settings. - getPreferences(dialog) { - - // Add the settings page to the builder. - dialog.getBuilder().add_from_resource(`/ui/${utils.getUIDir()}/Glitch.ui`); - - // Bind all properties. + // This is called by the preferences dialog whenever a new effect profile is loaded. It + // binds all user interface elements to the respective settings keys of the profile. + bindPreferences(dialog) { dialog.bindAdjustment('glitch-animation-time'); dialog.bindAdjustment('glitch-scale'); dialog.bindAdjustment('glitch-speed'); dialog.bindAdjustment('glitch-strength'); dialog.bindColorButton('glitch-color'); - - // Finally, return the new settings page. - return dialog.getBuilder().get_object('glitch-prefs'); } // ---------------------------------------------------------------- API for extension.js diff --git a/src/Hexagon.js b/src/Hexagon.js index 678d126..d702741 100644 --- a/src/Hexagon.js +++ b/src/Hexagon.js @@ -100,23 +100,15 @@ var Hexagon = class { // -------------------------------------------------------------------- API for prefs.js - // This is called by the preferences dialog. It loads the settings page for this effect, - // and binds all properties to the settings. - getPreferences(dialog) { - - // Add the settings page to the builder. - dialog.getBuilder().add_from_resource(`/ui/${utils.getUIDir()}/Hexagon.ui`); - - // Bind all properties. + // This is called by the preferences dialog whenever a new effect profile is loaded. It + // binds all user interface elements to the respective settings keys of the profile. + bindPreferences(dialog) { dialog.bindAdjustment('hexagon-animation-time'); dialog.bindAdjustment('hexagon-scale'); dialog.bindAdjustment('hexagon-line-width'); dialog.bindColorButton('hexagon-line-color'); dialog.bindColorButton('hexagon-glow-color'); dialog.bindSwitch('hexagon-additive-blending'); - - // Finally, return the new settings page. - return dialog.getBuilder().get_object('hexagon-prefs'); } // ---------------------------------------------------------------- API for extension.js diff --git a/src/Incinerate.js b/src/Incinerate.js index 242ea03..48cb4cd 100644 --- a/src/Incinerate.js +++ b/src/Incinerate.js @@ -133,22 +133,14 @@ var Incinerate = class { // -------------------------------------------------------------------- API for prefs.js - // This is called by the preferences dialog. It loads the settings page for this effect, - // and binds all properties to the settings. - getPreferences(dialog) { - - // Add the settings page to the builder. - dialog.getBuilder().add_from_resource(`/ui/${utils.getUIDir()}/Incinerate.ui`); - - // Bind all properties. + // This is called by the preferences dialog whenever a new effect profile is loaded. It + // binds all user interface elements to the respective settings keys of the profile. + bindPreferences(dialog) { dialog.bindAdjustment('incinerate-animation-time'); dialog.bindAdjustment('incinerate-scale'); dialog.bindAdjustment('incinerate-turbulence'); dialog.bindSwitch('incinerate-use-pointer'); dialog.bindColorButton('incinerate-color'); - - // Finally, return the new settings page. - return dialog.getBuilder().get_object('incinerate-prefs'); } // ---------------------------------------------------------------- API for extension.js diff --git a/src/Matrix.js b/src/Matrix.js index fb3103b..56690a3 100644 --- a/src/Matrix.js +++ b/src/Matrix.js @@ -116,23 +116,15 @@ var Matrix = class { // -------------------------------------------------------------------- API for prefs.js - // This is called by the preferences dialog. It loads the settings page for this effect, - // and binds all properties to the settings. - getPreferences(dialog) { - - // Add the settings page to the builder. - dialog.getBuilder().add_from_resource(`/ui/${utils.getUIDir()}/Matrix.ui`); - - // Bind all properties. + // This is called by the preferences dialog whenever a new effect profile is loaded. It + // binds all user interface elements to the respective settings keys of the profile. + bindPreferences(dialog) { dialog.bindAdjustment('matrix-animation-time'); dialog.bindAdjustment('matrix-scale'); dialog.bindAdjustment('matrix-randomness'); dialog.bindAdjustment('matrix-overshoot'); dialog.bindColorButton('matrix-trail-color'); dialog.bindColorButton('matrix-tip-color'); - - // Finally, return the new settings page. - return dialog.getBuilder().get_object('matrix-prefs'); } // ---------------------------------------------------------------- API for extension.js diff --git a/src/PixelWheel.js b/src/PixelWheel.js index f878c73..60955ec 100644 --- a/src/PixelWheel.js +++ b/src/PixelWheel.js @@ -76,20 +76,12 @@ var PixelWheel = class { // -------------------------------------------------------------------- API for prefs.js - // This is called by the preferences dialog. It loads the settings page for this effect, - // and binds all properties to the settings. - getPreferences(dialog) { - - // Add the settings page to the builder. - dialog.getBuilder().add_from_resource(`/ui/${utils.getUIDir()}/PixelWheel.ui`); - - // Bind all properties. + // This is called by the preferences dialog whenever a new effect profile is loaded. It + // binds all user interface elements to the respective settings keys of the profile. + bindPreferences(dialog) { dialog.bindAdjustment('pixel-wheel-animation-time'); dialog.bindAdjustment('pixel-wheel-pixel-size'); dialog.bindAdjustment('pixel-wheel-spoke-count'); - - // Finally, return the new settings page. - return dialog.getBuilder().get_object('pixel-wheel-prefs'); } // ---------------------------------------------------------------- API for extension.js diff --git a/src/PixelWipe.js b/src/PixelWipe.js index 08745f0..79f5f4a 100644 --- a/src/PixelWipe.js +++ b/src/PixelWipe.js @@ -102,19 +102,11 @@ var PixelWipe = class { // -------------------------------------------------------------------- API for prefs.js - // This is called by the preferences dialog. It loads the settings page for this effect, - // and binds all properties to the settings. - getPreferences(dialog) { - - // Add the settings page to the builder. - dialog.getBuilder().add_from_resource(`/ui/${utils.getUIDir()}/PixelWipe.ui`); - - // Bind all properties. + // This is called by the preferences dialog whenever a new effect profile is loaded. It + // binds all user interface elements to the respective settings keys of the profile. + bindPreferences(dialog) { dialog.bindAdjustment('pixel-wipe-animation-time'); dialog.bindAdjustment('pixel-wipe-pixel-size'); - - // Finally, return the new settings page. - return dialog.getBuilder().get_object('pixel-wipe-prefs'); } // ---------------------------------------------------------------- API for extension.js diff --git a/src/Pixelate.js b/src/Pixelate.js index 3d7ccee..a91285e 100644 --- a/src/Pixelate.js +++ b/src/Pixelate.js @@ -76,20 +76,12 @@ var Pixelate = class { // -------------------------------------------------------------------- API for prefs.js - // This is called by the preferences dialog. It loads the settings page for this effect, - // and binds all properties to the settings. - getPreferences(dialog) { - - // Add the settings page to the builder. - dialog.getBuilder().add_from_resource(`/ui/${utils.getUIDir()}/Pixelate.ui`); - - // Bind all properties. + // This is called by the preferences dialog whenever a new effect profile is loaded. It + // binds all user interface elements to the respective settings keys of the profile. + bindPreferences(dialog) { dialog.bindAdjustment('pixelate-animation-time'); dialog.bindAdjustment('pixelate-noise'); dialog.bindAdjustment('pixelate-pixel-size'); - - // Finally, return the new settings page. - return dialog.getBuilder().get_object('pixelate-prefs'); } // ---------------------------------------------------------------- API for extension.js diff --git a/src/Portal.js b/src/Portal.js index 55709e7..aa76261 100644 --- a/src/Portal.js +++ b/src/Portal.js @@ -93,22 +93,14 @@ var Portal = class { // -------------------------------------------------------------------- API for prefs.js - // This is called by the preferences dialog. It loads the settings page for this effect, - // and binds all properties to the settings. - getPreferences(dialog) { - - // Add the settings page to the builder. - dialog.getBuilder().add_from_resource(`/ui/${utils.getUIDir()}/Portal.ui`); - - // Bind all properties. + // This is called by the preferences dialog whenever a new effect profile is loaded. It + // binds all user interface elements to the respective settings keys of the profile. + bindPreferences(dialog) { dialog.bindAdjustment('portal-animation-time'); dialog.bindAdjustment('portal-rotation-speed'); dialog.bindAdjustment('portal-whirling'); dialog.bindAdjustment('portal-details'); dialog.bindColorButton('portal-color'); - - // Finally, return the new settings page. - return dialog.getBuilder().get_object('portal-prefs'); } // ---------------------------------------------------------------- API for extension.js diff --git a/src/SnapOfDisintegration.js b/src/SnapOfDisintegration.js index f05ca67..985a39c 100644 --- a/src/SnapOfDisintegration.js +++ b/src/SnapOfDisintegration.js @@ -120,21 +120,12 @@ var SnapOfDisintegration = class { // -------------------------------------------------------------------- API for prefs.js - // This is called by the preferences dialog. It loads the settings page for this effect, - // and binds all properties to the settings. - getPreferences(dialog) { - - // Add the settings page to the builder. - dialog.getBuilder().add_from_resource( - `/ui/${utils.getUIDir()}/SnapOfDisintegration.ui`); - - // Bind all properties. + // This is called by the preferences dialog whenever a new effect profile is loaded. It + // binds all user interface elements to the respective settings keys of the profile. + bindPreferences(dialog) { dialog.bindAdjustment('snap-animation-time'); dialog.bindAdjustment('snap-scale'); dialog.bindColorButton('snap-color'); - - // Finally, return the new settings page. - return dialog.getBuilder().get_object('snap-prefs'); } // ---------------------------------------------------------------- API for extension.js diff --git a/src/TRexAttack.js b/src/TRexAttack.js index ae25713..6507a9a 100644 --- a/src/TRexAttack.js +++ b/src/TRexAttack.js @@ -118,22 +118,14 @@ var TRexAttack = class { // -------------------------------------------------------------------- API for prefs.js - // This is called by the preferences dialog. It loads the settings page for this effect, - // and binds all properties to the settings. - getPreferences(dialog) { - - // Add the settings page to the builder. - dialog.getBuilder().add_from_resource(`/ui/${utils.getUIDir()}/TRexAttack.ui`); - - // Bind all properties. + // This is called by the preferences dialog whenever a new effect profile is loaded. It + // binds all user interface elements to the respective settings keys of the profile. + bindPreferences(dialog) { dialog.bindAdjustment('trex-animation-time'); dialog.bindColorButton('claw-scratch-color'); dialog.bindAdjustment('claw-scratch-scale'); dialog.bindAdjustment('claw-scratch-count'); dialog.bindAdjustment('claw-scratch-warp'); - - // Finally, return the new settings page. - return dialog.getBuilder().get_object('trex-prefs'); } // ---------------------------------------------------------------- API for extension.js diff --git a/src/TVEffect.js b/src/TVEffect.js index b4dd4f4..578f9a1 100644 --- a/src/TVEffect.js +++ b/src/TVEffect.js @@ -80,19 +80,11 @@ var TVEffect = class { // -------------------------------------------------------------------- API for prefs.js - // This is called by the preferences dialog. It loads the settings page for this effect, - // and binds all properties to the settings. - getPreferences(dialog) { - - // Add the settings page to the builder. - dialog.getBuilder().add_from_resource(`/ui/${utils.getUIDir()}/TVEffect.ui`); - - // Bind all properties. + // This is called by the preferences dialog whenever a new effect profile is loaded. It + // binds all user interface elements to the respective settings keys of the profile. + bindPreferences(dialog) { dialog.bindAdjustment('tv-animation-time'); dialog.bindColorButton('tv-effect-color'); - - // Finally, return the new settings page. - return dialog.getBuilder().get_object('tv-prefs'); } // ---------------------------------------------------------------- API for extension.js diff --git a/src/TVGlitch.js b/src/TVGlitch.js index 4faebf9..c3bfc9f 100644 --- a/src/TVGlitch.js +++ b/src/TVGlitch.js @@ -92,22 +92,14 @@ var TVGlitch = class { // -------------------------------------------------------------------- API for prefs.js - // This is called by the preferences dialog. It loads the settings page for this effect, - // and binds all properties to the settings. - getPreferences(dialog) { - - // Add the settings page to the builder. - dialog.getBuilder().add_from_resource(`/ui/${utils.getUIDir()}/TVGlitch.ui`); - - // Bind all properties. + // This is called by the preferences dialog whenever a new effect profile is loaded. It + // binds all user interface elements to the respective settings keys of the profile. + bindPreferences(dialog) { dialog.bindAdjustment('tv-glitch-animation-time'); dialog.bindAdjustment('tv-glitch-scale'); dialog.bindAdjustment('tv-glitch-speed'); dialog.bindAdjustment('tv-glitch-strength'); dialog.bindColorButton('tv-glitch-color'); - - // Finally, return the new settings page. - return dialog.getBuilder().get_object('tv-glitch-prefs'); } // ---------------------------------------------------------------- API for extension.js diff --git a/src/Wisps.js b/src/Wisps.js index 1743e5b..b8e173f 100644 --- a/src/Wisps.js +++ b/src/Wisps.js @@ -88,20 +88,12 @@ var Wisps = class { // -------------------------------------------------------------------- API for prefs.js - // This is called by the preferences dialog. It loads the settings page for this effect, - // and binds all properties to the settings. - getPreferences(dialog) { - - // Add the settings page to the builder. - dialog.getBuilder().add_from_resource(`/ui/${utils.getUIDir()}/Wisps.ui`); - - // Bind all properties. + // This is called by the preferences dialog whenever a new effect profile is loaded. It + // binds all user interface elements to the respective settings keys of the profile. + bindPreferences(dialog) { dialog.bindAdjustment('wisps-animation-time'); dialog.bindAdjustment('wisps-scale'); dialog.bindColorButton('wisps-color'); - - // Finally, return the new settings page. - return dialog.getBuilder().get_object('wisps-prefs'); } // ---------------------------------------------------------------- API for extension.js From 3f6d55994a3e67d73fa7230bbe1d85128d2dcccf Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Thu, 26 Jan 2023 05:46:37 +0100 Subject: [PATCH 13/67] :wrench: Include profile edit icon --- resources/img/scalable/actions/bmw-edit-profile-symbolic.svg | 2 ++ resources/ui/adw/prefs.ui | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 resources/img/scalable/actions/bmw-edit-profile-symbolic.svg diff --git a/resources/img/scalable/actions/bmw-edit-profile-symbolic.svg b/resources/img/scalable/actions/bmw-edit-profile-symbolic.svg new file mode 100644 index 0000000..2bf9968 --- /dev/null +++ b/resources/img/scalable/actions/bmw-edit-profile-symbolic.svg @@ -0,0 +1,2 @@ + + diff --git a/resources/ui/adw/prefs.ui b/resources/ui/adw/prefs.ui index e708eba..10d4333 100644 --- a/resources/ui/adw/prefs.ui +++ b/resources/ui/adw/prefs.ui @@ -32,7 +32,7 @@ SPDX-License-Identifier: GPL-3.0-or-later - edit-symbolic + bmw-edit-profile-symbolic center From 524345606c46f27713b5a4205263329e5aa34928 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Thu, 26 Jan 2023 05:54:58 +0100 Subject: [PATCH 14/67] :wrench: Sort profiles --- src/utils.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/utils.js b/src/utils.js index 5150f68..6c1e0c8 100644 --- a/src/utils.js +++ b/src/utils.js @@ -163,7 +163,8 @@ function listProfiles() { } } - return profiles; + + return profiles.sort(); } // Based on From 53e738b87b97fad44b2291d49d04e53e871c0a7d Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Thu, 26 Jan 2023 05:55:18 +0100 Subject: [PATCH 15/67] :beetle: Fix rebinding of properties --- prefs.js | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/prefs.js b/prefs.js index ce04dbb..37e6c68 100644 --- a/prefs.js +++ b/prefs.js @@ -552,26 +552,24 @@ var PreferencesDialog = class PreferencesDialog { if (!profiles.includes(activeProfile)) { activeProfile = profiles[0]; this._settings.set_string('active-profile', activeProfile); + return; } utils.debug('loading ' + activeProfile); this._profileSettings = utils.getProfileSettings(activeProfile); - // Bind all the profile-related settings. - { - const setupProfileOption = (settingsKey) => { - this.bindComboRow(settingsKey); - this._profileSettings.connect('changed::' + settingsKey, - () => this._updateProfileButton()); - }; + const setupProfileOption = (settingsKey) => { + this.bindComboRow(settingsKey); + this._profileSettings.connect('changed::' + settingsKey, + () => this._updateProfileButton()); + }; - setupProfileOption('profile-animation-type'); - setupProfileOption('profile-window-type'); - setupProfileOption('profile-desktop-style'); - setupProfileOption('profile-power-mode'); - setupProfileOption('profile-power-profile'); - } + setupProfileOption('profile-animation-type'); + setupProfileOption('profile-window-type'); + setupProfileOption('profile-desktop-style'); + setupProfileOption('profile-power-mode'); + setupProfileOption('profile-power-profile'); this._ALL_EFFECTS.forEach(effect => { const [minMajor, minMinor] = effect.getMinShellVersion(); @@ -580,6 +578,8 @@ var PreferencesDialog = class PreferencesDialog { effect.bindPreferences(this); } }); + + utils.debug('loading done'); } _updateProfileButton() { @@ -606,10 +606,11 @@ var PreferencesDialog = class PreferencesDialog { // key when clicked. _bindResetButton(settingsKey) { const resetButton = this._builder.get_object('reset-' + settingsKey); - if (resetButton) { + if (resetButton && !resetButton._isConnected) { resetButton.connect('clicked', () => { this._profileSettings.reset(settingsKey); }); + resetButton._isConnected = true; } } @@ -619,6 +620,7 @@ var PreferencesDialog = class PreferencesDialog { const object = this._builder.get_object(settingsKey); if (object) { + Gio.Settings.unbind(object, property); this._profileSettings.bind(settingsKey, object, property, Gio.SettingsBindFlags.DEFAULT); } From 764b8b9ffaba5b2e2e98deaff95a441924f54f79 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Sat, 28 Jan 2023 20:38:58 +0100 Subject: [PATCH 16/67] :wrench: Profile configuration start working --- prefs.js | 116 +++++++---- ...ell.extensions.burn-my-windows.gschema.xml | 2 +- src/ProfileManager.js | 190 ++++++++++++++++++ src/utils.js | 122 +---------- 4 files changed, 271 insertions(+), 159 deletions(-) create mode 100644 src/ProfileManager.js diff --git a/prefs.js b/prefs.js index 37e6c68..7154ce5 100644 --- a/prefs.js +++ b/prefs.js @@ -29,6 +29,7 @@ const _ = imports.gettext.domain('burn-my-windows').gettext; const ExtensionUtils = imports.misc.extensionUtils; const Me = imports.misc.extensionUtils.getCurrentExtension(); const utils = Me.imports.src.utils; +const ProfileManager = Me.imports.src.ProfileManager.ProfileManager; // This template widget class is defined at the bottom of this file. var BurnMyWindowsEffectPage = null; @@ -102,10 +103,13 @@ var PreferencesDialog = class PreferencesDialog { // Store a reference to the general settings object. this._settings = ExtensionUtils.getSettings(); + // This tracks all available effect profiles. + this._profileManager = new ProfileManager(); + this._profileSettingsConnections = []; + // Load the current effect profile. If there is none, we create a default profile. this._settings.connect('changed::active-profile', () => { this._loadActiveProfile(); - this._updateProfileButton(); }); // Check whether the power profiles daemon is available - if not, we hide the @@ -266,7 +270,7 @@ var PreferencesDialog = class PreferencesDialog { window.set_title(`Burn-My-Windows ${Me.metadata.version}`); this._loadActiveProfile(); - this._updateProfileButton(); + this._updateProfileMenu(); // Populate the menu with actions. const group = Gio.SimpleActionGroup.new(); @@ -417,14 +421,21 @@ var PreferencesDialog = class PreferencesDialog { // Setup all the profile-related actions. { - const profileAction = this._settings.create_action('active-profile'); - group.add_action(profileAction); + const activeProfileAction = this._settings.create_action('active-profile'); + group.add_action(activeProfileAction); const newProfileAction = Gio.SimpleAction.new('profile-new', null); newProfileAction.connect('activate', () => { - const profile = utils.createProfile(); - this._settings.set_string('active-profile', profile); + // Create a new profile and make it the active one. + const profile = this._profileManager.createProfile(); + this._settings.set_string('active-profile', profile.path); + + // Start editing the profile. this._builder.get_object('edit-profile-button').active = true; + + // The number of profiles has changed, so we have to update the profile + // selection menu. + this._updateProfileMenu(); }); group.add_action(newProfileAction); @@ -437,11 +448,19 @@ var PreferencesDialog = class PreferencesDialog { deleteProfileDialog.set_transient_for(window); deleteProfileDialog.connect('response', (d, response) => { if (response == 'delete') { + // Stop editing the current profile. this._builder.get_object('edit-profile-button').active = false; - const profile = this._settings.get_string('active-profile'); - utils.deleteProfile(profile); - this._loadActiveProfile(); - this._updateProfileButton(); + + // Delete the currently active profile. + this._profileManager.deleteProfile(this._activeProfile.path); + + // Select another one. + this._settings.set_string('active-profile', + this._profileManager.getProfiles()[0].path); + + // The number of profiles has changed, so we have to update the profile + // selection menu. + this._updateProfileMenu(); } }); @@ -472,7 +491,7 @@ var PreferencesDialog = class PreferencesDialog { // Returns a Gio.Settings object for the current effect profile. getProfileSettings() { - return this._profileSettings; + return this._activeProfile.settings; } // Returns the widget used for the settings of this extension. @@ -508,18 +527,23 @@ var PreferencesDialog = class PreferencesDialog { if (button) { // Update the settings when the color is modified. - button.connect('color-set', () => { - this._profileSettings.set_string(settingsKey, button.get_rgba().to_string()); - }); + if (!button._isConnected) { + button.connect('color-set', () => { + this.getProfileSettings().set_string(settingsKey, + button.get_rgba().to_string()); + }); + + button._isConnected = true; + } // Update the button state when the settings change. const settingSignalHandler = () => { const rgba = new Gdk.RGBA(); - rgba.parse(this._profileSettings.get_string(settingsKey)); + rgba.parse(this.getProfileSettings().get_string(settingsKey)); button.rgba = rgba; }; - this._profileSettings.connect('changed::' + settingsKey, settingSignalHandler); + this._connectProfileSetting('changed::' + settingsKey, settingSignalHandler); // Initialize the button with the state in the settings. settingSignalHandler(); @@ -543,26 +567,27 @@ var PreferencesDialog = class PreferencesDialog { _loadActiveProfile() { - let profiles = utils.listProfiles(); - if (profiles.length == 0) { - profiles = [utils.createProfile()]; - } + this._disconnectProfileSettings(); - let activeProfile = this._settings.get_string('active-profile'); - if (!profiles.includes(activeProfile)) { - activeProfile = profiles[0]; - this._settings.set_string('active-profile', activeProfile); + const allProfiles = this._profileManager.getProfiles(); + const path = this._settings.get_string('active-profile'); + this._activeProfile = allProfiles.find(p => p.path == path); + + if (!this._activeProfile) { + utils.debug('active profile not found!!!'); + this._activeProfile = allProfiles[0]; + this._settings.set_string('active-profile', this._activeProfile.path); return; } - utils.debug('loading ' + activeProfile); - - this._profileSettings = utils.getProfileSettings(activeProfile); + utils.debug('loading ' + this._activeProfile.path); const setupProfileOption = (settingsKey) => { this.bindComboRow(settingsKey); - this._profileSettings.connect('changed::' + settingsKey, - () => this._updateProfileButton()); + this._connectProfileSetting('changed::' + settingsKey, () => { + this._updateProfileButton(); + this._updateProfileMenu(); + }); }; setupProfileOption('profile-animation-type'); @@ -579,36 +604,51 @@ var PreferencesDialog = class PreferencesDialog { } }); + this._updateProfileButton(); + utils.debug('loading done'); } _updateProfileButton() { - const activeProfile = this._settings.get_string('active-profile'); - + utils.debug('updating profile button'); this._builder.get_object('choose-profile-button').label = - utils.getProfileName(activeProfile); + this._profileManager.getProfileName(this.getProfileSettings()); + } + _updateProfileMenu() { + utils.debug('updating profile menu'); const profileSection = this._builder.get_object('profile-section'); profileSection.remove_all(); - const profiles = utils.listProfiles(); + const profiles = this._profileManager.getProfiles(); profiles.forEach(profile => { - const label = utils.getProfileName(profile); + const label = this._profileManager.getProfileName(profile.settings); const item = Gio.MenuItem.new(label, 'prefs.active-profile'); item.set_action_and_target_value('prefs.active-profile', - GLib.Variant.new_string(profile)); + GLib.Variant.new_string(profile.path)); profileSection.append_item(item); }); } + _connectProfileSetting(key, callback) { + this._profileSettingsConnections.push( + this.getProfileSettings().connect(key, callback)); + } + + _disconnectProfileSettings() { + this._profileSettingsConnections.forEach(c => + this.getProfileSettings().disconnect(c)); + this._profileSettingsConnections = []; + } + // Searches for a reset button for the given settings key and make it reset the settings // key when clicked. _bindResetButton(settingsKey) { const resetButton = this._builder.get_object('reset-' + settingsKey); if (resetButton && !resetButton._isConnected) { resetButton.connect('clicked', () => { - this._profileSettings.reset(settingsKey); + this.getProfileSettings().reset(settingsKey); }); resetButton._isConnected = true; } @@ -621,8 +661,8 @@ var PreferencesDialog = class PreferencesDialog { if (object) { Gio.Settings.unbind(object, property); - this._profileSettings.bind(settingsKey, object, property, - Gio.SettingsBindFlags.DEFAULT); + this.getProfileSettings().bind(settingsKey, object, property, + Gio.SettingsBindFlags.DEFAULT); } this._bindResetButton(settingsKey); 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 de978d0..c8a7593 100644 --- a/schemas/org.gnome.shell.extensions.burn-my-windows.gschema.xml +++ b/schemas/org.gnome.shell.extensions.burn-my-windows.gschema.xml @@ -15,7 +15,7 @@ SPDX-License-Identifier: CC0-1.0 "" - Profile + Active Profile The currently active effect profile. diff --git a/src/ProfileManager.js b/src/ProfileManager.js new file mode 100644 index 0000000..ce1ea3f --- /dev/null +++ b/src/ProfileManager.js @@ -0,0 +1,190 @@ +////////////////////////////////////////////////////////////////////////////////////////// +// ) ( // +// ( /( ( ( ) ( ( ( ( )\ ) ( ( // +// )\()) ))\ )( ( ( )\ ) )\))( )\ ( (()/( ( )\))( ( // +// ((_)\ /((_|()\ )\ ) )\ '(()/( ((_)()((_) )\ ) ((_)))\((_)()\ )\ // +// | |(_|_))( ((_)_(_/( _((_)) )(_)) _(()((_|_)_(_/( _| |((_)(()((_|(_) // +// | '_ \ || | '_| ' \)) | ' \()| || | \ V V / | ' \)) _` / _ \ V V (_-< // +// |_.__/\_,_|_| |_||_| |_|_|_| \_, | \_/\_/|_|_||_|\__,_\___/\_/\_//__/ // +// |__/ // +////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: Simon Schneegans +// SPDX-License-Identifier: GPL-3.0-or-later + +'use strict'; + +const {Gio, 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; + +// extension.js: +// - get a list of profile settings objects + +// prefs.js: +// - get a (sorted) list of profile settings objects +// - add a new profile +// - delete a profile +// - create a name for a given profile + +var ProfileManager = class { + // ------------------------------------------------------------ constructor / destructor + + constructor() { + this._makeProfilesDir(); + this._loadProfiles(); + } + + // -------------------------------------------------------------------- public interface + + // Returns an array of effect profiles. Each effect profile is an object with two + // properties: The 'path' points to the file which contains the effect profile + // settings. The 'settings' property contains a Gio.Settings object for the profile. + // The former can be used to uniquely identify the profile, the latter can be used to + // access the profile's settings. + // This method will always return at least one profile. If none is configured, a default + // profile will be created. + getProfiles() { + if (this._profiles.length == 0) { + this._profiles.push(this._createProfile()); + } + + return this._profiles; + } + + // This will create a new profile with all values initialized to their defaults. The + // method will return a effect profile object (as described above). It will also + // trigger an emission of the 'profiles-updated' signal. + createProfile() { + const path = `${GLib.get_user_config_dir()}/burn-my-windows/profiles/${ + GLib.get_real_time()}.conf`; + const file = Gio.File.new_for_path(path); + file.create(Gio.FileCreateFlags.NONE, null); + + const profile = {'path': path, 'settings': this._getProfileSettings(path)}; + + this._profiles.push(profile); + + return profile; + } + + deleteProfile(profilePath) { + const profileDir = `${GLib.get_user_config_dir()}/burn-my-windows/profiles`; + const file = Gio.File.new_for_path(profilePath); + if (file.has_prefix(Gio.File.new_for_path(profileDir)) && file.query_exists(null)) { + file.delete(null); + } + + this._profiles = this._profiles.filter(p => p.path != profilePath); + } + + getProfileName(settings) { + let items = []; + + const addComponent = (settingsKey, options) => { + const option = settings.get_int(settingsKey); + if (option > 0) { + items.push(options[option - 1]); + } + }; + + // clang-format off + addComponent('profile-animation-type', [_('Opening Windows'), + _('Closing Windows')]); + addComponent('profile-window-type', [_('Normal Windows'), + _('Dialog Windows')]); + addComponent('profile-desktop-style', [_('Bright Mode'), + _('Dark Mode')]); + addComponent('profile-power-mode', [_('On Battery'), + _('Plugged In')]); + addComponent('profile-power-profile', [_('Power-Saver Mode'), + _('Balanced Mode'), + _('Performance Mode'), + _('Power Saver or Balanced'), + _('Balanced or Performance')]); + // clang-format on + + let label = ''; + + if (items.length == 0) { + label = _('Default Profile'); + } else { + label = items.join(' · '); + } + + return label; + } + + // ----------------------------------------------------------------------- private stuff + + _makeProfilesDir() { + const path = `${GLib.get_user_config_dir()}/burn-my-windows/profiles`; + const dir = Gio.File.new_for_path(path); + + if (!dir.query_exists(null)) { + dir.make_directory_with_parents(null); + } + } + + _loadProfiles() { + const dir = + Gio.File.new_for_path(GLib.get_user_config_dir() + '/burn-my-windows/profiles'); + + const files = + dir.enumerate_children('standard::*', Gio.FileQueryInfoFlags.NONE, null); + + let profilePaths = []; + + while (true) { + const presetInfo = files.next_file(null); + + if (presetInfo == null) { + break; + } + + if (presetInfo.get_file_type() == Gio.FileType.REGULAR) { + const suffixPos = presetInfo.get_display_name().indexOf('.conf'); + if (suffixPos > 0) { + profilePaths.push(dir.get_child(presetInfo.get_name()).get_path()); + } + } + } + + + profilePaths.sort(); + + this._profiles = []; + + profilePaths.forEach(path => { + this._profiles.push({'path': path, 'settings': this._getProfileSettings(path)}); + }); + } + + // Based on + // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/misc/extensionUtils.js#L213 + _getProfileSettings(profilePath) { + + // Expect USER extensions to have a schemas/ subfolder, otherwise assume a + // SYSTEM extension that has been installed in the same prefix as the shell + const schemaDir = Me.dir.get_child('schemas'); + let source; + if (schemaDir.query_exists(null)) { + source = Gio.SettingsSchemaSource.new_from_directory( + schemaDir.get_path(), Gio.SettingsSchemaSource.get_default(), false); + } else { + source = Gio.SettingsSchemaSource.get_default(); + } + + const schema = + source.lookup('org.gnome.shell.extensions.burn-my-windows-profile', true); + + const backend = + Gio.keyfile_settings_backend_new(profilePath, '/org/gnome/shell/extensions/', null); + + return new Gio.Settings({settings_schema: schema, backend: backend}); + } +} \ No newline at end of file diff --git a/src/utils.js b/src/utils.js index 6c1e0c8..01853af 100644 --- a/src/utils.js +++ b/src/utils.js @@ -14,8 +14,8 @@ 'use strict'; -const {Gtk, Gio, GLib} = imports.gi; -const ByteArray = imports.byteArray; +const {Gtk, Gio} = imports.gi; +const ByteArray = imports.byteArray; // libadwaita is available starting with GNOME Shell 42. let Adw = null; @@ -110,121 +110,3 @@ function getStringResource(path) { const data = Gio.resources_lookup_data(path, 0); return ByteArray.toString(ByteArray.fromGBytes(data)); } - -function createProfile() { - const path = - GLib.get_user_config_dir() + `/burn-my-windows/profiles/${GLib.get_real_time()}.conf`; - const file = Gio.File.new_for_path(path); - - if (!file.get_parent().query_exists(null)) { - file.get_parent().make_directory_with_parents(null); - } - - file.create(Gio.FileCreateFlags.NONE, null); - - return path; -} - -function deleteProfile(profilePath) { - const profileDir = GLib.get_user_config_dir() + `/burn-my-windows/profiles`; - const file = Gio.File.new_for_path(profilePath); - if (file.has_prefix(Gio.File.new_for_path(profileDir)) && file.query_exists(null)) { - file.delete(null); - } -} - - -function listProfiles() { - - const profileDir = - Gio.File.new_for_path(GLib.get_user_config_dir() + '/burn-my-windows/profiles'); - - if (!profileDir.query_exists(null)) { - return []; - } - - const files = - profileDir.enumerate_children('standard::*', Gio.FileQueryInfoFlags.NONE, null); - - let profiles = []; - - while (true) { - const presetInfo = files.next_file(null); - - if (presetInfo == null) { - break; - } - - if (presetInfo.get_file_type() == Gio.FileType.REGULAR) { - const suffixPos = presetInfo.get_display_name().indexOf('.conf'); - if (suffixPos > 0) { - profiles.push(profileDir.get_child(presetInfo.get_name()).get_path()); - } - } - } - - - return profiles.sort(); -} - -// Based on -// https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/misc/extensionUtils.js#L213 -function getProfileSettings(profilePath) { - - // Expect USER extensions to have a schemas/ subfolder, otherwise assume a - // SYSTEM extension that has been installed in the same prefix as the shell - const schemaDir = Me.dir.get_child('schemas'); - let source; - if (schemaDir.query_exists(null)) { - source = Gio.SettingsSchemaSource.new_from_directory( - schemaDir.get_path(), Gio.SettingsSchemaSource.get_default(), false); - } else { - source = Gio.SettingsSchemaSource.get_default(); - } - - const schema = - source.lookup('org.gnome.shell.extensions.burn-my-windows-profile', true); - - const backend = - Gio.keyfile_settings_backend_new(profilePath, '/org/gnome/shell/extensions/', null); - - return new Gio.Settings({settings_schema: schema, backend: backend}); -} - -function getProfileName(profilePath) { - let items = []; - const settings = getProfileSettings(profilePath); - - const addItems = (settingsKey, options) => { - const option = settings.get_int(settingsKey); - if (option > 0) { - items.push(options[option - 1]); - } - }; - - // clang-format off - addItems('profile-animation-type', [_('Opening Windows'), - _('Closing Windows')]); - addItems('profile-window-type', [_('Normal Windows'), - _('Dialog Windows')]); - addItems('profile-desktop-style', [_('Bright Mode'), - _('Dark Mode')]); - addItems('profile-power-mode', [_('On Battery'), - _('Plugged In')]); - addItems('profile-power-profile', [_('Power-Saver Mode'), - _('Balanced Mode'), - _('Performance Mode'), - _('Power Saver or Balanced'), - _('Balanced or Performance')]); - // clang-format on - - let label = ''; - - if (items.length == 0) { - label = _('Default Profile'); - } else { - label = items.join(' · '); - } - - return label; -} \ No newline at end of file From 6904762590533918f475e54bc7704186b2668328 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Sun, 29 Jan 2023 12:42:06 +0100 Subject: [PATCH 17/67] :truck: Move effect sources to separate directory --- Makefile | 2 +- docs/how-to-create-new-effects.md | 4 +-- extension.js | 40 +++++++++++------------ prefs.js | 40 +++++++++++------------ src/{ => effects}/Apparition.js | 0 src/{ => effects}/BrokenGlass.js | 0 src/{ => effects}/Doom.js | 0 src/{ => effects}/EnergizeA.js | 0 src/{ => effects}/EnergizeB.js | 0 src/{ => effects}/Fire.js | 0 src/{ => effects}/Glide.js | 0 src/{ => effects}/Glitch.js | 0 src/{ => effects}/Hexagon.js | 0 src/{ => effects}/Incinerate.js | 0 src/{ => effects}/Matrix.js | 0 src/{ => effects}/PixelWheel.js | 0 src/{ => effects}/PixelWipe.js | 0 src/{ => effects}/Pixelate.js | 0 src/{ => effects}/Portal.js | 0 src/{ => effects}/SnapOfDisintegration.js | 0 src/{ => effects}/TRexAttack.js | 0 src/{ => effects}/TVEffect.js | 0 src/{ => effects}/TVGlitch.js | 0 src/{ => effects}/Wisps.js | 0 24 files changed, 43 insertions(+), 43 deletions(-) rename src/{ => effects}/Apparition.js (100%) rename src/{ => effects}/BrokenGlass.js (100%) rename src/{ => effects}/Doom.js (100%) rename src/{ => effects}/EnergizeA.js (100%) rename src/{ => effects}/EnergizeB.js (100%) rename src/{ => effects}/Fire.js (100%) rename src/{ => effects}/Glide.js (100%) rename src/{ => effects}/Glitch.js (100%) rename src/{ => effects}/Hexagon.js (100%) rename src/{ => effects}/Incinerate.js (100%) rename src/{ => effects}/Matrix.js (100%) rename src/{ => effects}/PixelWheel.js (100%) rename src/{ => effects}/PixelWipe.js (100%) rename src/{ => effects}/Pixelate.js (100%) rename src/{ => effects}/Portal.js (100%) rename src/{ => effects}/SnapOfDisintegration.js (100%) rename src/{ => effects}/TRexAttack.js (100%) rename src/{ => effects}/TVEffect.js (100%) rename src/{ => effects}/TVGlitch.js (100%) rename src/{ => effects}/Wisps.js (100%) diff --git a/Makefile b/Makefile index ba8fdbc..3cd3957 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ DOMAIN := schneegans.github.com ZIP_NAME := $(NAME)@$(DOMAIN).zip # Some of the recipes below depend on some of these files. -JS_FILES = $(wildcard src/*.js extension.js prefs.js) +JS_FILES = $(wildcard src/*.js src/*/*.js extension.js prefs.js) UI_FILES = $(shell find resources -type f -and \( -name "*.ui" \)) RESOURCE_FILES = $(shell find resources -mindepth 2 -type f) LOCALES_PO = $(wildcard po/*.po) diff --git a/docs/how-to-create-new-effects.md b/docs/how-to-create-new-effects.md index 24b923f..c30da07 100644 --- a/docs/how-to-create-new-effects.md +++ b/docs/how-to-create-new-effects.md @@ -78,7 +78,7 @@ Just remember to replace `simple-fade` with your custom name! ### 2. Creating the Effect Class -You will have to create a new GLSL file called `resources/shaders/simple-fade.frag` and a new JavaScript source file called `src/SimpleFade.js`. +You will have to create a new GLSL file called `resources/shaders/simple-fade.frag` and a new JavaScript source file called `src/effects/SimpleFade.js`. Simply paste the following source code to the respective file. Please study this code carefully, all of it is explained with inline comments. @@ -239,7 +239,7 @@ Like this: ```javascript const ALL_EFFECTS = [ ... - new Me.imports.src.SimpleFade.SimpleFade(), + new Me.imports.src.effects.SimpleFade.SimpleFade(), ... ]; ``` diff --git a/extension.js b/extension.js index d1697a7..1660712 100644 --- a/extension.js +++ b/extension.js @@ -51,26 +51,26 @@ class Extension { // New effects must be registered here and in prefs.js. this._ALL_EFFECTS = [ - new Me.imports.src.Apparition.Apparition(), - new Me.imports.src.BrokenGlass.BrokenGlass(), - new Me.imports.src.Doom.Doom(), - new Me.imports.src.EnergizeA.EnergizeA(), - new Me.imports.src.EnergizeB.EnergizeB(), - new Me.imports.src.Fire.Fire(), - new Me.imports.src.Glide.Glide(), - new Me.imports.src.Glitch.Glitch(), - new Me.imports.src.Hexagon.Hexagon(), - new Me.imports.src.Incinerate.Incinerate(), - new Me.imports.src.Matrix.Matrix(), - new Me.imports.src.Pixelate.Pixelate(), - new Me.imports.src.PixelWheel.PixelWheel(), - new Me.imports.src.PixelWipe.PixelWipe(), - new Me.imports.src.Portal.Portal(), - new Me.imports.src.SnapOfDisintegration.SnapOfDisintegration(), - new Me.imports.src.TRexAttack.TRexAttack(), - new Me.imports.src.TVEffect.TVEffect(), - new Me.imports.src.TVGlitch.TVGlitch(), - new Me.imports.src.Wisps.Wisps(), + new Me.imports.src.effects.Apparition.Apparition(), + new Me.imports.src.effects.BrokenGlass.BrokenGlass(), + new Me.imports.src.effects.Doom.Doom(), + new Me.imports.src.effects.EnergizeA.EnergizeA(), + new Me.imports.src.effects.EnergizeB.EnergizeB(), + new Me.imports.src.effects.Fire.Fire(), + new Me.imports.src.effects.Glide.Glide(), + new Me.imports.src.effects.Glitch.Glitch(), + new Me.imports.src.effects.Hexagon.Hexagon(), + new Me.imports.src.effects.Incinerate.Incinerate(), + new Me.imports.src.effects.Matrix.Matrix(), + new Me.imports.src.effects.Pixelate.Pixelate(), + new Me.imports.src.effects.PixelWheel.PixelWheel(), + new Me.imports.src.effects.PixelWipe.PixelWipe(), + new Me.imports.src.effects.Portal.Portal(), + new Me.imports.src.effects.SnapOfDisintegration.SnapOfDisintegration(), + new Me.imports.src.effects.TRexAttack.TRexAttack(), + new Me.imports.src.effects.TVEffect.TVEffect(), + new Me.imports.src.effects.TVGlitch.TVGlitch(), + new Me.imports.src.effects.Wisps.Wisps(), ]; // Load all of our resources. diff --git a/prefs.js b/prefs.js index 7154ce5..98881bf 100644 --- a/prefs.js +++ b/prefs.js @@ -48,26 +48,26 @@ var PreferencesDialog = class PreferencesDialog { // New effects must be registered here and in extension.js. this._ALL_EFFECTS = [ - new Me.imports.src.Apparition.Apparition(), - new Me.imports.src.BrokenGlass.BrokenGlass(), - new Me.imports.src.Doom.Doom(), - new Me.imports.src.EnergizeA.EnergizeA(), - new Me.imports.src.EnergizeB.EnergizeB(), - new Me.imports.src.Fire.Fire(), - new Me.imports.src.Glide.Glide(), - new Me.imports.src.Glitch.Glitch(), - new Me.imports.src.Hexagon.Hexagon(), - new Me.imports.src.Incinerate.Incinerate(), - new Me.imports.src.Matrix.Matrix(), - new Me.imports.src.Pixelate.Pixelate(), - new Me.imports.src.PixelWheel.PixelWheel(), - new Me.imports.src.PixelWipe.PixelWipe(), - new Me.imports.src.Portal.Portal(), - new Me.imports.src.SnapOfDisintegration.SnapOfDisintegration(), - new Me.imports.src.TRexAttack.TRexAttack(), - new Me.imports.src.TVEffect.TVEffect(), - new Me.imports.src.TVGlitch.TVGlitch(), - new Me.imports.src.Wisps.Wisps(), + new Me.imports.src.effects.Apparition.Apparition(), + new Me.imports.src.effects.BrokenGlass.BrokenGlass(), + new Me.imports.src.effects.Doom.Doom(), + new Me.imports.src.effects.EnergizeA.EnergizeA(), + new Me.imports.src.effects.EnergizeB.EnergizeB(), + new Me.imports.src.effects.Fire.Fire(), + new Me.imports.src.effects.Glide.Glide(), + new Me.imports.src.effects.Glitch.Glitch(), + new Me.imports.src.effects.Hexagon.Hexagon(), + new Me.imports.src.effects.Incinerate.Incinerate(), + new Me.imports.src.effects.Matrix.Matrix(), + new Me.imports.src.effects.Pixelate.Pixelate(), + new Me.imports.src.effects.PixelWheel.PixelWheel(), + new Me.imports.src.effects.PixelWipe.PixelWipe(), + new Me.imports.src.effects.Portal.Portal(), + new Me.imports.src.effects.SnapOfDisintegration.SnapOfDisintegration(), + new Me.imports.src.effects.TRexAttack.TRexAttack(), + new Me.imports.src.effects.TVEffect.TVEffect(), + new Me.imports.src.effects.TVGlitch.TVGlitch(), + new Me.imports.src.effects.Wisps.Wisps(), ]; // Load all of our resources. diff --git a/src/Apparition.js b/src/effects/Apparition.js similarity index 100% rename from src/Apparition.js rename to src/effects/Apparition.js diff --git a/src/BrokenGlass.js b/src/effects/BrokenGlass.js similarity index 100% rename from src/BrokenGlass.js rename to src/effects/BrokenGlass.js diff --git a/src/Doom.js b/src/effects/Doom.js similarity index 100% rename from src/Doom.js rename to src/effects/Doom.js diff --git a/src/EnergizeA.js b/src/effects/EnergizeA.js similarity index 100% rename from src/EnergizeA.js rename to src/effects/EnergizeA.js diff --git a/src/EnergizeB.js b/src/effects/EnergizeB.js similarity index 100% rename from src/EnergizeB.js rename to src/effects/EnergizeB.js diff --git a/src/Fire.js b/src/effects/Fire.js similarity index 100% rename from src/Fire.js rename to src/effects/Fire.js diff --git a/src/Glide.js b/src/effects/Glide.js similarity index 100% rename from src/Glide.js rename to src/effects/Glide.js diff --git a/src/Glitch.js b/src/effects/Glitch.js similarity index 100% rename from src/Glitch.js rename to src/effects/Glitch.js diff --git a/src/Hexagon.js b/src/effects/Hexagon.js similarity index 100% rename from src/Hexagon.js rename to src/effects/Hexagon.js diff --git a/src/Incinerate.js b/src/effects/Incinerate.js similarity index 100% rename from src/Incinerate.js rename to src/effects/Incinerate.js diff --git a/src/Matrix.js b/src/effects/Matrix.js similarity index 100% rename from src/Matrix.js rename to src/effects/Matrix.js diff --git a/src/PixelWheel.js b/src/effects/PixelWheel.js similarity index 100% rename from src/PixelWheel.js rename to src/effects/PixelWheel.js diff --git a/src/PixelWipe.js b/src/effects/PixelWipe.js similarity index 100% rename from src/PixelWipe.js rename to src/effects/PixelWipe.js diff --git a/src/Pixelate.js b/src/effects/Pixelate.js similarity index 100% rename from src/Pixelate.js rename to src/effects/Pixelate.js diff --git a/src/Portal.js b/src/effects/Portal.js similarity index 100% rename from src/Portal.js rename to src/effects/Portal.js diff --git a/src/SnapOfDisintegration.js b/src/effects/SnapOfDisintegration.js similarity index 100% rename from src/SnapOfDisintegration.js rename to src/effects/SnapOfDisintegration.js diff --git a/src/TRexAttack.js b/src/effects/TRexAttack.js similarity index 100% rename from src/TRexAttack.js rename to src/effects/TRexAttack.js diff --git a/src/TVEffect.js b/src/effects/TVEffect.js similarity index 100% rename from src/TVEffect.js rename to src/effects/TVEffect.js diff --git a/src/TVGlitch.js b/src/effects/TVGlitch.js similarity index 100% rename from src/TVGlitch.js rename to src/effects/TVGlitch.js diff --git a/src/Wisps.js b/src/effects/Wisps.js similarity index 100% rename from src/Wisps.js rename to src/effects/Wisps.js From 374b8c98b6d58db2a764817a40b0e026f85b38e1 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Sun, 29 Jan 2023 13:15:58 +0100 Subject: [PATCH 18/67] :memo: Add plenty of comments --- src/ProfileManager.js | 119 +++++++++++++++++++++++------------------- 1 file changed, 65 insertions(+), 54 deletions(-) diff --git a/src/ProfileManager.js b/src/ProfileManager.js index ce1ea3f..8fbcea6 100644 --- a/src/ProfileManager.js +++ b/src/ProfileManager.js @@ -22,31 +22,31 @@ const ExtensionUtils = imports.misc.extensionUtils; const Me = imports.misc.extensionUtils.getCurrentExtension(); const utils = Me.imports.src.utils; -// extension.js: -// - get a list of profile settings objects - -// prefs.js: -// - get a (sorted) list of profile settings objects -// - add a new profile -// - delete a profile -// - create a name for a given profile +////////////////////////////////////////////////////////////////////////////////////////// +// Burn-My-Windows allows applying different sets of effect settings under specific // +// circumstances. These settings are called "effect profiles". The ProfileManager // +// provides access to all currently configured effect profiles. It can be used in both // +// the settings dialog and the in the actual extension. // +// The profiles are stored in ~/.config/burn-my-windows/profiles and can be accessed // +// via Gio.Settings objects. // +////////////////////////////////////////////////////////////////////////////////////////// var ProfileManager = class { // ------------------------------------------------------------ constructor / destructor constructor() { this._makeProfilesDir(); - this._loadProfiles(); + this.reloadProfiles(); } // -------------------------------------------------------------------- public interface // Returns an array of effect profiles. Each effect profile is an object with two // properties: The 'path' points to the file which contains the effect profile - // settings. The 'settings' property contains a Gio.Settings object for the profile. - // The former can be used to uniquely identify the profile, the latter can be used to - // access the profile's settings. - // This method will always return at least one profile. If none is configured, a default + // settings (located in ~/.config/burn-my-windows/profiles). The 'settings' property + // contains a Gio.Settings object for the profile. The former can be used to uniquely + // identify the profile, the latter can be used to access the profile's settings. This + // method will always return at least one profile. If none is configured, a default // profile will be created. getProfiles() { if (this._profiles.length == 0) { @@ -57,8 +57,9 @@ var ProfileManager = class { } // This will create a new profile with all values initialized to their defaults. The - // method will return a effect profile object (as described above). It will also - // trigger an emission of the 'profiles-updated' signal. + // method will return an effect profile object (as described above). We will use the + // current system time in microseconds as profile name. This ensures that they are + // always sorted according to their creation date. createProfile() { const path = `${GLib.get_user_config_dir()}/burn-my-windows/profiles/${ GLib.get_real_time()}.conf`; @@ -67,11 +68,14 @@ var ProfileManager = class { const profile = {'path': path, 'settings': this._getProfileSettings(path)}; + // Add the profile to our internal list of profiles. this._profiles.push(profile); return profile; } + // Removes a profile defined by its file path. This will actually remove the file from + // the disk, so there's no going back. deleteProfile(profilePath) { const profileDir = `${GLib.get_user_config_dir()}/burn-my-windows/profiles`; const file = Gio.File.new_for_path(profilePath); @@ -79,9 +83,49 @@ var ProfileManager = class { file.delete(null); } + // Remove the profile from our internal list of profiles. this._profiles = this._profiles.filter(p => p.path != profilePath); } + // Reloads all profiles from ~/.config/burn-my-windows/profiles. If you called the + // createProfile() and deleteProfile() methods above, there is no need to reload the + // profiles. + reloadProfiles() { + const dir = + Gio.File.new_for_path(GLib.get_user_config_dir() + '/burn-my-windows/profiles'); + + const files = + dir.enumerate_children('standard::*', Gio.FileQueryInfoFlags.NONE, null); + + let profilePaths = []; + + while (true) { + const presetInfo = files.next_file(null); + + if (presetInfo == null) { + break; + } + + if (presetInfo.get_file_type() == Gio.FileType.REGULAR) { + const suffixPos = presetInfo.get_display_name().indexOf('.conf'); + if (suffixPos > 0) { + profilePaths.push(dir.get_child(presetInfo.get_name()).get_path()); + } + } + } + + // Sort profiles alphabetically, that is by their creation time. + profilePaths.sort(); + + this._profiles = []; + + profilePaths.forEach(path => { + this._profiles.push({'path': path, 'settings': this._getProfileSettings(path)}); + }); + } + + // Profiles are named according to their configuration. This method returns a localized + // string describing the settings of the profile. getProfileName(settings) { let items = []; @@ -108,19 +152,20 @@ var ProfileManager = class { _('Balanced or Performance')]); // clang-format on - let label = ''; + let name = ''; if (items.length == 0) { - label = _('Default Profile'); + name = _('Default Profile'); } else { - label = items.join(' · '); + name = items.join(' · '); } - return label; + return name; } // ----------------------------------------------------------------------- private stuff + // Creates the directory ~/.config/burn-my-windows/profiles if it does not yet exist. _makeProfilesDir() { const path = `${GLib.get_user_config_dir()}/burn-my-windows/profiles`; const dir = Gio.File.new_for_path(path); @@ -130,41 +175,7 @@ var ProfileManager = class { } } - _loadProfiles() { - const dir = - Gio.File.new_for_path(GLib.get_user_config_dir() + '/burn-my-windows/profiles'); - - const files = - dir.enumerate_children('standard::*', Gio.FileQueryInfoFlags.NONE, null); - - let profilePaths = []; - - while (true) { - const presetInfo = files.next_file(null); - - if (presetInfo == null) { - break; - } - - if (presetInfo.get_file_type() == Gio.FileType.REGULAR) { - const suffixPos = presetInfo.get_display_name().indexOf('.conf'); - if (suffixPos > 0) { - profilePaths.push(dir.get_child(presetInfo.get_name()).get_path()); - } - } - } - - - profilePaths.sort(); - - this._profiles = []; - - profilePaths.forEach(path => { - this._profiles.push({'path': path, 'settings': this._getProfileSettings(path)}); - }); - } - - // Based on + // Creates a Gio.Settings object for the given effect profile path. Based on // https://gitlab.gnome.org/GNOME/gnome-shell/-/blob/main/js/misc/extensionUtils.js#L213 _getProfileSettings(profilePath) { From 8bb0ee26db12741a0472dfe849947fabb5c49608 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Sun, 29 Jan 2023 13:49:41 +0100 Subject: [PATCH 19/67] :memo: Add more comments --- prefs.js | 54 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 18 deletions(-) diff --git a/prefs.js b/prefs.js index 98881bf..2021052 100644 --- a/prefs.js +++ b/prefs.js @@ -104,8 +104,11 @@ var PreferencesDialog = class PreferencesDialog { this._settings = ExtensionUtils.getSettings(); // This tracks all available effect profiles. - this._profileManager = new ProfileManager(); - this._profileSettingsConnections = []; + this._profileManager = new ProfileManager(); + + // This is used to track all connections to properties of the current effect profile. + // Whenever the current effect profile changes, all connections are disconnected. + this._profileConnections = []; // Load the current effect profile. If there is none, we create a default profile. this._settings.connect('changed::active-profile', () => { @@ -421,12 +424,13 @@ var PreferencesDialog = class PreferencesDialog { // Setup all the profile-related actions. { + // Allow switching the current profile. const activeProfileAction = this._settings.create_action('active-profile'); group.add_action(activeProfileAction); + // This action creates a new profile and makes it the active one. const newProfileAction = Gio.SimpleAction.new('profile-new', null); newProfileAction.connect('activate', () => { - // Create a new profile and make it the active one. const profile = this._profileManager.createProfile(); this._settings.set_string('active-profile', profile.path); @@ -439,6 +443,8 @@ var PreferencesDialog = class PreferencesDialog { }); group.add_action(newProfileAction); + // This action shows a confirmation dialog. Upon user approval, the currently + // active profile is deleted. const deleteProfileAction = Gio.SimpleAction.new('profile-delete', null); deleteProfileAction.connect('activate', () => { this._builder.get_object('profile-delete-dialog').show(); @@ -565,23 +571,26 @@ var PreferencesDialog = class PreferencesDialog { // ----------------------------------------------------------------------- private stuff + // This loads all settings from the profile given in the settings key 'active-profile'. _loadActiveProfile() { + // Disconnect any connection to the previously active profile. this._disconnectProfileSettings(); + // Find the active profile in the list of all profiles. const allProfiles = this._profileManager.getProfiles(); const path = this._settings.get_string('active-profile'); this._activeProfile = allProfiles.find(p => p.path == path); + // If, for whatever reason, it is not found, select the first one. Setting the + // settings key will trigger this method again. if (!this._activeProfile) { - utils.debug('active profile not found!!!'); this._activeProfile = allProfiles[0]; this._settings.set_string('active-profile', this._activeProfile.path); return; } - utils.debug('loading ' + this._activeProfile.path); - + // Connect all profile options. const setupProfileOption = (settingsKey) => { this.bindComboRow(settingsKey); this._connectProfileSetting('changed::' + settingsKey, () => { @@ -596,6 +605,7 @@ var PreferencesDialog = class PreferencesDialog { setupProfileOption('profile-power-mode'); setupProfileOption('profile-power-profile'); + // Connect all effect settings. this._ALL_EFFECTS.forEach(effect => { const [minMajor, minMinor] = effect.getMinShellVersion(); if (utils.shellVersionIsAtLeast(minMajor, minMinor)) { @@ -604,25 +614,29 @@ var PreferencesDialog = class PreferencesDialog { } }); + // Update the label in the profile-select button. this._updateProfileButton(); - - utils.debug('loading done'); } + // This updates the label of the profile-selection button according to the currently + // active profile. It's called whenever the active profile is changed or whenever a + // configuration option of the profile is changed. _updateProfileButton() { - utils.debug('updating profile button'); this._builder.get_object('choose-profile-button').label = this._profileManager.getProfileName(this.getProfileSettings()); } + // This updates the list of available profiles in the dropdown of the profile-selection + // button. It's called whenever one of the configuration option of the currently active + // profile is changed, or whenever a profile is added / removed. _updateProfileMenu() { - utils.debug('updating profile menu'); + + // First, clear the menu section. const profileSection = this._builder.get_object('profile-section'); profileSection.remove_all(); - const profiles = this._profileManager.getProfiles(); - - profiles.forEach(profile => { + // Then add an entry for each available profile. + this._profileManager.getProfiles().forEach(profile => { const label = this._profileManager.getProfileName(profile.settings); const item = Gio.MenuItem.new(label, 'prefs.active-profile'); item.set_action_and_target_value('prefs.active-profile', @@ -631,15 +645,18 @@ var PreferencesDialog = class PreferencesDialog { }); } + // This wrapper connects a given callback to a profile settings key. Use this instead of + // the direct connect() call on the profile settings to make sure that the callback is + // disconnected when the active profile changes. _connectProfileSetting(key, callback) { - this._profileSettingsConnections.push( - this.getProfileSettings().connect(key, callback)); + this._profileConnections.push(this.getProfileSettings().connect(key, callback)); } + // This is called whenever the currently edited effect profile changes. It unbinds all + // callbacks bound with the above method before. _disconnectProfileSettings() { - this._profileSettingsConnections.forEach(c => - this.getProfileSettings().disconnect(c)); - this._profileSettingsConnections = []; + this._profileConnections.forEach(c => this.getProfileSettings().disconnect(c)); + this._profileConnections = []; } // Searches for a reset button for the given settings key and make it reset the settings @@ -660,6 +677,7 @@ var PreferencesDialog = class PreferencesDialog { const object = this._builder.get_object(settingsKey); if (object) { + // Unbind any previous binding (potentially to a previously edited profile). Gio.Settings.unbind(object, property); this.getProfileSettings().bind(settingsKey, object, property, Gio.SettingsBindFlags.DEFAULT); From da9bd8818d736044b33d115b157d492752aaee6e Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Sun, 29 Jan 2023 13:55:29 +0100 Subject: [PATCH 20/67] :beetle: Fix double-profile --- src/ProfileManager.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ProfileManager.js b/src/ProfileManager.js index 8fbcea6..740bd81 100644 --- a/src/ProfileManager.js +++ b/src/ProfileManager.js @@ -50,7 +50,7 @@ var ProfileManager = class { // profile will be created. getProfiles() { if (this._profiles.length == 0) { - this._profiles.push(this._createProfile()); + this.createProfile(); } return this._profiles; From b9a8071dd135a1ebc8229ca3bde789b28cd53bfb Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Sun, 29 Jan 2023 14:01:43 +0100 Subject: [PATCH 21/67] :wrench: Increase default window size --- prefs.js | 1 + 1 file changed, 1 insertion(+) diff --git a/prefs.js b/prefs.js index 2021052..40f889a 100644 --- a/prefs.js +++ b/prefs.js @@ -805,6 +805,7 @@ function buildPrefsWidget() { } function fillPreferencesWindow(window) { + window.set_default_size(700, 700); var dialog = new PreferencesDialog(); window.add(dialog.getWidget()); } \ No newline at end of file From 776cfa97365f23880f6bc5ac8715dcdb13922ca8 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Sun, 29 Jan 2023 14:01:54 +0100 Subject: [PATCH 22/67] :wrench: Hide copy-paste buttons --- resources/ui/adw/prefs.ui | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/ui/adw/prefs.ui b/resources/ui/adw/prefs.ui index 10d4333..f56fd50 100644 --- a/resources/ui/adw/prefs.ui +++ b/resources/ui/adw/prefs.ui @@ -200,7 +200,7 @@ SPDX-License-Identifier: GPL-3.0-or-later Effect Settings If multiple are selected, one is chosen randomly. - +
From 96d098daba2c4ca4614fefe6dbd4de399b9e2813 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Sun, 29 Jan 2023 14:06:43 +0100 Subject: [PATCH 23/67] :wrench: Connect fire buttons only once --- src/effects/Fire.js | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/src/effects/Fire.js b/src/effects/Fire.js index 96e543c..151fc36 100644 --- a/src/effects/Fire.js +++ b/src/effects/Fire.js @@ -117,17 +117,22 @@ var Fire = class { dialog.bindColorButton('fire-color-4'); dialog.bindColorButton('fire-color-5'); - // The fire-gradient-reset button needs to be bound explicitly. - dialog.getBuilder().get_object('reset-fire-colors').connect('clicked', () => { - dialog.getProfileSettings().reset('fire-color-1'); - dialog.getProfileSettings().reset('fire-color-2'); - dialog.getProfileSettings().reset('fire-color-3'); - dialog.getProfileSettings().reset('fire-color-4'); - dialog.getProfileSettings().reset('fire-color-5'); - }); + // Connect the buttons only once. The bindPreferences can be called multiple times... + if (!this._isConnected) { + this._isConnected = true; - // Initialize the fire-preset dropdown. - this._createFirePresets(dialog); + // The fire-gradient-reset button needs to be bound explicitly. + dialog.getBuilder().get_object('reset-fire-colors').connect('clicked', () => { + dialog.getProfileSettings().reset('fire-color-1'); + dialog.getProfileSettings().reset('fire-color-2'); + dialog.getProfileSettings().reset('fire-color-3'); + dialog.getProfileSettings().reset('fire-color-4'); + dialog.getProfileSettings().reset('fire-color-5'); + }); + + // Initialize the fire-preset dropdown. + this._createFirePresets(dialog); + } } // ---------------------------------------------------------------- API for extension.js From 72f9c8eefc16cbd26618fa2d4dca17832e67fd5e Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Sun, 29 Jan 2023 20:41:40 +0100 Subject: [PATCH 24/67] :wrench: Pass testMode flag to shaders --- extension.js | 3 +- src/Shader.js | 14 +++++--- src/effects/Apparition.js | 5 +-- src/effects/BrokenGlass.js | 45 +++++++++++------------- src/effects/Doom.js | 32 ++++++++--------- src/effects/Glitch.js | 5 +-- src/effects/Hexagon.js | 6 +--- src/effects/Incinerate.js | 54 ++++++++++++++--------------- src/effects/Portal.js | 5 +-- src/effects/SnapOfDisintegration.js | 6 +--- src/effects/TRexAttack.js | 6 +--- src/effects/TVGlitch.js | 5 +-- src/effects/Wisps.js | 6 +--- 13 files changed, 83 insertions(+), 109 deletions(-) diff --git a/extension.js b/extension.js index 1660712..fecbb60 100644 --- a/extension.js +++ b/extension.js @@ -521,7 +521,8 @@ class Extension { actor.add_effect_with_name('burn-my-windows-effect', shader); // Set one-time uniforms. - shader.beginAnimation(this._settings, forOpening, duration * 0.001, actor); + shader.beginAnimation(profile.settings, forOpening, testMode, duration * 0.001, + actor); // Set other uniforms each frame. transition.connect('new-frame', (t) => { diff --git a/src/Shader.js b/src/Shader.js index 6f897a4..bbd9b67 100644 --- a/src/Shader.js +++ b/src/Shader.js @@ -29,7 +29,7 @@ const utils = Me.imports.src.utils; // main benefit when compared to Clutter.ShaderEffect is that setting uniforms of types // // vec2, vec3 or vec4 is supported via the API (with Clutter.ShaderEffect the GJS // // binding does not work properly). However, there are two drawbacks: On the one hand, // -// the shader source code is cached statically - this mean if we want to have a // +// the shader source code is cached statically - this means if we want to have a // // different shader, we have to derive a new class. Therefore, each effect has to // // derive its own class from the class below. This is encapsulated in the // // ShaderFactory, however it is some really awkward code. The other drawback is the // @@ -47,8 +47,12 @@ const utils = Me.imports.src.utils; var Shader = GObject.registerClass( { Signals: { - 'begin-animation': - {param_types: [Gio.Settings.$gtype, GObject.TYPE_BOOLEAN, Clutter.Actor.$gtype]}, + 'begin-animation': { + param_types: [ + Gio.Settings.$gtype, GObject.TYPE_BOOLEAN, GObject.TYPE_BOOLEAN, + Clutter.Actor.$gtype + ] + }, 'update-animation': {param_types: [GObject.TYPE_DOUBLE]}, 'end-animation': {} } @@ -76,7 +80,7 @@ var Shader = GObject.registerClass( } // This is called once each time the shader is used. - beginAnimation(settings, forOpening, duration, actor) { + beginAnimation(settings, forOpening, testMode, duration, actor) { // Reset progress value. this._progress = 0; @@ -90,7 +94,7 @@ var Shader = GObject.registerClass( this.set_uniform_float(this._uDuration, 1, [duration]); this.set_uniform_float(this._uSize, 2, [actor.width, actor.height]); - this.emit('begin-animation', settings, forOpening, actor); + this.emit('begin-animation', settings, forOpening, testMode, actor); } // This is called at each frame during the animation. diff --git a/src/effects/Apparition.js b/src/effects/Apparition.js index 067389e..a1051fd 100644 --- a/src/effects/Apparition.js +++ b/src/effects/Apparition.js @@ -44,10 +44,7 @@ var Apparition = class { shader._uRandomness = shader.get_uniform_location('uRandomness'); // Write all uniform values at the start of each animation. - shader.connect('begin-animation', (shader, settings) => { - // If we are performing an integration tests, we use a fixed seed. - const testMode = settings.get_boolean('test-mode'); - + shader.connect('begin-animation', (shader, settings, forOpening, testMode) => { // clang-format off shader.set_uniform_float(shader._uSeed, 2, [testMode ? 0 : Math.random(), testMode ? 0 : Math.random()]); shader.set_uniform_float(shader._uShake, 1, [settings.get_double('apparition-shake-intensity')]); diff --git a/src/effects/BrokenGlass.js b/src/effects/BrokenGlass.js index 2ad3773..43c099d 100644 --- a/src/effects/BrokenGlass.js +++ b/src/effects/BrokenGlass.js @@ -70,34 +70,31 @@ var BrokenGlass = class { shader._uGravity = shader.get_uniform_location('uGravity'); // And update all uniforms at the start of each animation. - shader.connect('begin-animation', (shader, settings, forOpening, actor) => { - // Usually, the shards fly away from the center of the window. - let epicenterX = 0.5; - let epicenterY = 0.5; + shader.connect( + 'begin-animation', (shader, settings, forOpening, testMode, actor) => { + // Usually, the shards fly away from the center of the window. + let epicenterX = 0.5; + let epicenterY = 0.5; - // However, if this option is set, we use the mouse pointer position. - if (!forOpening && settings.get_boolean('broken-glass-use-pointer')) { - const [x, y] = global.get_pointer(); - const [ok, localX, localY] = actor.transform_stage_point(x, y); + // However, if this option is set, we use the mouse pointer position. + if (!forOpening && settings.get_boolean('broken-glass-use-pointer')) { + const [x, y] = global.get_pointer(); + const [ok, localX, localY] = actor.transform_stage_point(x, y); - if (ok) { - epicenterX = localX / actor.width; - epicenterY = localY / actor.height; + if (ok) { + epicenterX = localX / actor.width; + epicenterY = localY / actor.height; + } } - } - // If we are currently performing integration test, the animation uses a fixed - // seed. - const testMode = settings.get_boolean('test-mode'); - - // clang-format off - shader.set_uniform_float(shader._uSeed, 2, [testMode ? 0 : Math.random(), testMode ? 0 : Math.random()]); - shader.set_uniform_float(shader._uEpicenter, 2, [epicenterX, epicenterY]); - shader.set_uniform_float(shader._uShardScale, 1, [settings.get_double('broken-glass-scale')]); - shader.set_uniform_float(shader._uBlowForce, 1, [settings.get_double('broken-glass-blow-force')]); - shader.set_uniform_float(shader._uGravity, 1, [settings.get_double('broken-glass-gravity')]); - // clang-format on - }); + // clang-format off + shader.set_uniform_float(shader._uSeed, 2, [testMode ? 0 : Math.random(), testMode ? 0 : Math.random()]); + shader.set_uniform_float(shader._uEpicenter, 2, [epicenterX, epicenterY]); + shader.set_uniform_float(shader._uShardScale, 1, [settings.get_double('broken-glass-scale')]); + shader.set_uniform_float(shader._uBlowForce, 1, [settings.get_double('broken-glass-blow-force')]); + shader.set_uniform_float(shader._uGravity, 1, [settings.get_double('broken-glass-gravity')]); + // clang-format on + }); // This is required to bind the shard texture for drawing. Sadly, this seems to be // impossible under GNOME 3.3x as this.get_pipeline() is not available. It was diff --git a/src/effects/Doom.js b/src/effects/Doom.js index b457faa..ad77cd9 100644 --- a/src/effects/Doom.js +++ b/src/effects/Doom.js @@ -46,23 +46,23 @@ var Doom = class { shader._uPixelSize = shader.get_uniform_location('uPixelSize'); // Write all uniform values at the start of each animation. - shader.connect('begin-animation', (shader, settings, forOpening, actor) => { - // For this effect, we scale the actor vertically so that it covers the entire - // screen. This ensures that the melted window will not be cut off. - let actorScale = 2.0 * Math.max(1.0, global.stage.height / actor.height); + shader.connect( + 'begin-animation', (shader, settings, forOpening, testMode, actor) => { + // For this effect, we scale the actor vertically so that it covers the entire + // screen. This ensures that the melted window will not be cut off. + let actorScale = 2.0 * Math.max(1.0, global.stage.height / actor.height); - // If we are currently performing integration test, nothing will be visible in the - // test images as the animation has passed the center of the window already. To - // fix this, we set the actor scale to a fixed low value when performing tests. - const testMode = settings.get_boolean('test-mode'); - - // clang-format off - shader.set_uniform_float(shader._uActorScale, 1, [testMode ? 1.0 : actorScale]); - shader.set_uniform_float(shader._uHorizontalScale, 1, [testMode ? 50.0 :settings.get_double('doom-horizontal-scale')]); - shader.set_uniform_float(shader._uVerticalScale, 1, [testMode ? 150.0 : settings.get_double('doom-vertical-scale')]); - shader.set_uniform_float(shader._uPixelSize, 1, [settings.get_int('doom-pixel-size')]); - // clang-format on - }); + // If we are currently performing integration test, nothing will be visible in + // the test images as the animation has passed the center of the window already. + // To fix this, we set the actor scale to a fixed low value when performing + // tests. + // clang-format off + shader.set_uniform_float(shader._uActorScale, 1, [testMode ? 1.0 : actorScale]); + shader.set_uniform_float(shader._uHorizontalScale, 1, [testMode ? 50.0 :settings.get_double('doom-horizontal-scale')]); + shader.set_uniform_float(shader._uVerticalScale, 1, [testMode ? 150.0 : settings.get_double('doom-vertical-scale')]); + shader.set_uniform_float(shader._uPixelSize, 1, [settings.get_int('doom-pixel-size')]); + // clang-format on + }); }); } diff --git a/src/effects/Glitch.js b/src/effects/Glitch.js index cef768c..6003f80 100644 --- a/src/effects/Glitch.js +++ b/src/effects/Glitch.js @@ -51,12 +51,9 @@ var Glitch = class { shader._uSpeed = shader.get_uniform_location('uSpeed'); // Write all uniform values at the start of each animation. - shader.connect('begin-animation', (shader, settings) => { + shader.connect('begin-animation', (shader, settings, forOpening, testMode) => { const c = Clutter.Color.from_string(settings.get_string('glitch-color'))[1]; - // If we are performing an integration tests, we use a fixed seed. - const testMode = settings.get_boolean('test-mode'); - // clang-format off shader.set_uniform_float(shader._uSeed, 1, [testMode ? 0 : Math.random()]); shader.set_uniform_float(shader._uColor, 4, [c.red / 255, c.green / 255, c.blue / 255, c.alpha / 255]); diff --git a/src/effects/Hexagon.js b/src/effects/Hexagon.js index d702741..75c74d1 100644 --- a/src/effects/Hexagon.js +++ b/src/effects/Hexagon.js @@ -53,7 +53,7 @@ var Hexagon = class { shader._uLineColor = shader.get_uniform_location('uLineColor'); // Write all uniform values at the start of each animation. - shader.connect('begin-animation', (shader, settings) => { + shader.connect('begin-animation', (shader, settings, forOpening, testMode) => { // Get the two configurable colors. They are directly injected into the shader // code below. const gc = @@ -61,10 +61,6 @@ var Hexagon = class { const lc = Clutter.Color.from_string(settings.get_string('hexagon-line-color'))[1]; - // If we are currently performing integration test, the animation uses a fixed - // seed. - const testMode = settings.get_boolean('test-mode'); - // clang-format off shader.set_uniform_float(shader._uAdditiveBlending, 1, [settings.get_boolean('hexagon-additive-blending')]); shader.set_uniform_float(shader._uSeed, 2, [testMode ? 0 : Math.random(), testMode ? 0 : Math.random()]); diff --git a/src/effects/Incinerate.js b/src/effects/Incinerate.js index 48cb4cd..da5821e 100644 --- a/src/effects/Incinerate.js +++ b/src/effects/Incinerate.js @@ -51,39 +51,39 @@ var Incinerate = class { shader._uStartPos = shader.get_uniform_location('uStartPos'); // Write all uniform values at the start of each animation. - shader.connect('begin-animation', (shader, settings, forOpening, actor) => { - // If we are currently performing integration test, the animation uses a fixed - // seed. - const testMode = settings.get_boolean('test-mode'); - let seed = [testMode ? 0 : Math.random(), testMode ? 0 : Math.random()]; + shader.connect( + 'begin-animation', (shader, settings, forOpening, testMode, actor) => { + // If we are currently performing integration test, the animation uses a fixed + // seed. + let seed = [testMode ? 0 : Math.random(), testMode ? 0 : Math.random()]; - // If this option is set, we use the mouse pointer position. Because the actor - // position may change after the begin-animation signal is called, we set the - // uStartPos uniform during the update callback. - if (settings.get_boolean('incinerate-use-pointer')) { - this._startPointerPos = global.get_pointer(); - this._actor = actor; + // If this option is set, we use the mouse pointer position. Because the actor + // position may change after the begin-animation signal is called, we set the + // uStartPos uniform during the update callback. + if (settings.get_boolean('incinerate-use-pointer')) { + this._startPointerPos = global.get_pointer(); + this._actor = actor; - } else { - // Else, a random position along the window boundary is used as start position - // for the incinerate effect. - let startPos = seed[0] > seed[1] ? [seed[0], Math.floor(seed[1] + 0.5)] : - [Math.floor(seed[0] + 0.5), seed[1]]; + } else { + // Else, a random position along the window boundary is used as start position + // for the incinerate effect. + let startPos = seed[0] > seed[1] ? [seed[0], Math.floor(seed[1] + 0.5)] : + [Math.floor(seed[0] + 0.5), seed[1]]; - shader.set_uniform_float(shader._uStartPos, 2, startPos); + shader.set_uniform_float(shader._uStartPos, 2, startPos); - this._startPointerPos = null; - } + this._startPointerPos = null; + } - const c = Clutter.Color.from_string(settings.get_string('incinerate-color'))[1]; + const c = Clutter.Color.from_string(settings.get_string('incinerate-color'))[1]; - // clang-format off - shader.set_uniform_float(shader._uSeed, 2, seed); - shader.set_uniform_float(shader._uColor, 3, [c.red / 255, c.green / 255, c.blue / 255]); - shader.set_uniform_float(shader._uScale, 1, [settings.get_double('incinerate-scale')]); - shader.set_uniform_float(shader._uTurbulence, 1, [settings.get_double('incinerate-turbulence')]); - // clang-format on - }); + // clang-format off + shader.set_uniform_float(shader._uSeed, 2, seed); + shader.set_uniform_float(shader._uColor, 3, [c.red / 255, c.green / 255, c.blue / 255]); + shader.set_uniform_float(shader._uScale, 1, [settings.get_double('incinerate-scale')]); + shader.set_uniform_float(shader._uTurbulence, 1, [settings.get_double('incinerate-turbulence')]); + // clang-format on + }); // If the mouse pointer position is used as start position, we set the uStartPos // uniform during the update callback as the actor position may not be set up diff --git a/src/effects/Portal.js b/src/effects/Portal.js index aa76261..f17d46f 100644 --- a/src/effects/Portal.js +++ b/src/effects/Portal.js @@ -52,12 +52,9 @@ var Portal = class { shader._uWhirling = shader.get_uniform_location('uWhirling'); // Write all uniform values at the start of each animation. - shader.connect('begin-animation', (shader, settings) => { + shader.connect('begin-animation', (shader, settings, forOpening, testMode) => { const c = Clutter.Color.from_string(settings.get_string('portal-color'))[1]; - // If we are performing an integration tests, we use a fixed seed. - const testMode = settings.get_boolean('test-mode'); - // clang-format off shader.set_uniform_float(shader._uSeed, 2, [testMode ? 0 : Math.random(), testMode ? 0 : Math.random()]); shader.set_uniform_float(shader._uColor, 3, [c.red / 255, c.green / 255, c.blue / 255]); diff --git a/src/effects/SnapOfDisintegration.js b/src/effects/SnapOfDisintegration.js index 985a39c..3b2b724 100644 --- a/src/effects/SnapOfDisintegration.js +++ b/src/effects/SnapOfDisintegration.js @@ -63,14 +63,10 @@ var SnapOfDisintegration = class { shader._uDustScale = shader.get_uniform_location('uDustScale'); // Write all uniform values at the start of each animation. - shader.connect('begin-animation', (shader, settings) => { + shader.connect('begin-animation', (shader, settings, forOpening, testMode) => { // The dust particles will fade to this color over time. const c = Clutter.Color.from_string(settings.get_string('snap-color'))[1]; - // If we are currently performing integration test, the animation uses a fixed - // seed. - const testMode = settings.get_boolean('test-mode'); - // clang-format off shader.set_uniform_float(shader._uDustColor, 4, [c.red / 255, c.green / 255, c.blue / 255, c.alpha / 255]); shader.set_uniform_float(shader._uSeed, 2, [testMode ? 0 : Math.random(), testMode ? 0 : Math.random()]); diff --git a/src/effects/TRexAttack.js b/src/effects/TRexAttack.js index 6507a9a..80dd9af 100644 --- a/src/effects/TRexAttack.js +++ b/src/effects/TRexAttack.js @@ -61,13 +61,9 @@ var TRexAttack = class { shader._uWarpIntensity = shader.get_uniform_location('uWarpIntensity'); // Write all uniform values at the start of each animation. - shader.connect('begin-animation', (shader, settings) => { + shader.connect('begin-animation', (shader, settings, forOpening, testMode) => { const c = Clutter.Color.from_string(settings.get_string('claw-scratch-color'))[1]; - // If we are currently performing integration test, the animation uses a fixed - // seed. - const testMode = settings.get_boolean('test-mode'); - // clang-format off shader.set_uniform_float(shader._uFlashColor, 4, [c.red / 255, c.green / 255, c.blue / 255, c.alpha / 255]); shader.set_uniform_float(shader._uSeed, 2, [testMode ? 0 : Math.random(), testMode ? 0 : Math.random()]); diff --git a/src/effects/TVGlitch.js b/src/effects/TVGlitch.js index c3bfc9f..155f97d 100644 --- a/src/effects/TVGlitch.js +++ b/src/effects/TVGlitch.js @@ -52,12 +52,9 @@ var TVGlitch = class { shader._uSpeed = shader.get_uniform_location('uSpeed'); // Write all uniform values at the start of each animation. - shader.connect('begin-animation', (shader, settings) => { + shader.connect('begin-animation', (shader, settings, forOpening, testMode) => { const c = Clutter.Color.from_string(settings.get_string('tv-glitch-color'))[1]; - // If we are performing an integration tests, we use a fixed seed. - const testMode = settings.get_boolean('test-mode'); - // clang-format off shader.set_uniform_float(shader._uSeed, 1, [testMode ? 0 : Math.random()]); shader.set_uniform_float(shader._uColor, 4, [c.red / 255, c.green / 255, c.blue / 255, c.alpha / 255]); diff --git a/src/effects/Wisps.js b/src/effects/Wisps.js index b8e173f..48078ba 100644 --- a/src/effects/Wisps.js +++ b/src/effects/Wisps.js @@ -50,13 +50,9 @@ var Wisps = class { shader._uScale = shader.get_uniform_location('uScale'); // Write all uniform values at the start of each animation. - shader.connect('begin-animation', (shader, settings) => { + shader.connect('begin-animation', (shader, settings, forOpening, testMode) => { const c = Clutter.Color.from_string(settings.get_string('wisps-color'))[1]; - // If we are currently performing integration test, the animation uses a fixed - // seed. - const testMode = settings.get_boolean('test-mode'); - // clang-format off shader.set_uniform_float(shader._uSeed, 2, [testMode ? 0 : Math.random(), testMode ? 0 : Math.random()]); shader.set_uniform_float(shader._uColor, 3, [c.red / 255, c.green / 255, c.blue / 255]); From 1bc146164ea19bf04c3051aefc05dcb942194e72 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Sun, 29 Jan 2023 20:42:38 +0100 Subject: [PATCH 25/67] :wrench: Previewing effects works again --- extension.js | 87 ++++++++++++++++++++++++++++++++++--------- src/ProfileManager.js | 13 +++++++ 2 files changed, 83 insertions(+), 17 deletions(-) diff --git a/extension.js b/extension.js index fecbb60..2aab160 100644 --- a/extension.js +++ b/extension.js @@ -31,6 +31,7 @@ try { const ExtensionUtils = imports.misc.extensionUtils; const Me = imports.misc.extensionUtils.getCurrentExtension(); const utils = Me.imports.src.utils; +const ProfileManager = Me.imports.src.ProfileManager.ProfileManager; ////////////////////////////////////////////////////////////////////////////////////////// // This extensions modifies the window-close and window-open animations with all kinds // @@ -80,6 +81,15 @@ class Extension { // Store a reference to the settings object. this._settings = ExtensionUtils.getSettings(); + // We reload all effect profiles whenever the currently edited profile in the + // preferences dialog changes. This is most likely a bit too often, but it will also + // happen whenever a new profile is created and whenever an old profile is deleted. + this._settings.connect('changed::active-profile', () => { + this._loadProfiles(); + }); + + this._loadProfiles(); + // We will use extensionThis to refer to the extension inside the patched methods. const extensionThis = this; @@ -363,6 +373,32 @@ class Extension { // ----------------------------------------------------------------------- private stuff + _loadProfiles() { + const profileManager = new ProfileManager(); + + utils.debug('load profiles!'); + + const updatePriority = (p) => { + utils.debug('sort profiles!'); + p.priority = profileManager.getProfilePriority(p.settings); + this._profiles.sort((a, b) => b.priority - a.priority); + }; + + this._profiles = profileManager.getProfiles(); + this._profiles.forEach(p => { + p.settings.connect('changed::profile-animation-type', () => updatePriority(p)); + p.settings.connect('changed::profile-window-type', () => updatePriority(p)); + p.settings.connect('changed::profile-desktop-style', () => updatePriority(p)); + p.settings.connect('changed::profile-power-mode', () => updatePriority(p)); + p.settings.connect('changed::profile-power-profile', () => updatePriority(p)); + + p.priority = profileManager.getProfilePriority(p.settings); + }); + + utils.debug('sort profiles!'); + this._profiles.sort((a, b) => b.priority - a.priority); + } + // 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 @@ -379,7 +415,6 @@ class Extension { return; } - const previewNick = this._settings.get_string('preview-effect'); // TODO!. // We may have to do nothing if running on battery power or if in power-save mode. @@ -407,34 +442,52 @@ class Extension { // ------------------------------------------------------------------ choose an effect - // Now we chose a random effect from all enabled effects. - let effect = null; + // Usually, we use the effect profile with the highest priority which matches the + // current circumstances. From this profile, we choose a random effect. However, if an + // effect is to be previewed, we choose the currently edited profile regardless of the + // circumstances. + let profile = null; + let effect = null; + + // Hence, we first check if an effect is to be previewed. + const previewNick = this._settings.get_string('preview-effect'); - // First we check if an effect is to be previewed. if (previewNick != '') { - effect = this._ALL_EFFECTS.find(effect => effect.getNick() == previewNick); + const activeProfile = this._settings.get_string('active-profile'); + effect = this._ALL_EFFECTS.find(effect => effect.getNick() == previewNick); + profile = this._profiles.find(p => p.path == activeProfile); - // Only preview the effect once. - if (!forOpening) { + // Only preview the effect until the preview window is closed. + if (!profile || !forOpening) { this._settings.set_string('preview-effect', ''); } } - // Else we choose a random effect from all enabled effects. + // If no effect is previewed, we use the effect profile with the highest priority + // which matches the current circumstances. From this profile, we choose a random + // effect. else { - // Therefore, we first create a list of all currently enabled effects. - const enabled = this._ALL_EFFECTS.filter(effect => { - return this._settings.get_boolean(`${effect.getNick()}-enable-effect`); + const profile = this._profiles.find(p => { + utils.debug('PRIO: ' + p.priority); + return true; }); - // And then choose a random effect. - if (enabled.length > 0) { - effect = enabled[Math.floor(Math.random() * enabled.length)]; + if (profile) { + + // Create a list of all enabled effects of this profile. + const enabled = this._ALL_EFFECTS.filter(effect => { + return profile.settings.get_boolean(`${effect.getNick()}-enable-effect`); + }); + + // And then choose a random effect. + if (enabled.length > 0) { + effect = enabled[Math.floor(Math.random() * enabled.length)]; + } } } // If nothing was enabled, we have to do nothing :) - if (effect == null) { + if (!effect || !profile) { this._fixAnimationTimes(isDialogWindow, forOpening, null); return; } @@ -449,12 +502,12 @@ class Extension { // windows are faded in / out scaled up / down slightly by GNOME Shell. Here, we tweak // the transitions so that nothing changes. The window stays opaque and is scaled to // actorScale. - const actorScale = effect.getActorScale(this._settings, forOpening, actor); + const actorScale = effect.getActorScale(profile.settings, forOpening, actor); // To make things deterministic during testing, we set the effect duration to 5 // seconds. const duration = - testMode ? 5000 : this._settings.get_int(effect.getNick() + '-animation-time'); + testMode ? 5000 : profile.settings.get_int(effect.getNick() + '-animation-time'); // All animations are relative to the window's center. actor.set_pivot_point(0.5, 0.5); diff --git a/src/ProfileManager.js b/src/ProfileManager.js index 740bd81..3152386 100644 --- a/src/ProfileManager.js +++ b/src/ProfileManager.js @@ -124,6 +124,19 @@ var ProfileManager = class { }); } + // Each profile has a priority. It is higher, the more specific it is. + getProfilePriority(settings) { + let priority = 0; + + if (settings.get_int('profile-animation-type') > 0) ++priority; + if (settings.get_int('profile-window-type') > 0) ++priority; + if (settings.get_int('profile-desktop-style') > 0) ++priority; + if (settings.get_int('profile-power-mode') > 0) ++priority; + if (settings.get_int('profile-power-profile') > 0) ++priority; + + return priority; + } + // Profiles are named according to their configuration. This method returns a localized // string describing the settings of the profile. getProfileName(settings) { From ddf54c215e8dcfba08b56d741969d67d22a84850 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Mon, 30 Jan 2023 05:51:36 +0100 Subject: [PATCH 26/67] :beetle: Fix tests --- tests/generate-references.sh | 3 +-- tests/run-test.sh | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/tests/generate-references.sh b/tests/generate-references.sh index 6c2d5bd..7544885 100755 --- a/tests/generate-references.sh +++ b/tests/generate-references.sh @@ -109,8 +109,7 @@ capture() { capture_effect() { echo "Capturing ${1} effect." - set_setting "open-preview-effect" "${1}" - set_setting "close-preview-effect" "${1}" + set_setting "preview-effect" "${1}" sleep 1 do_in_pod gnome-terminal diff --git a/tests/run-test.sh b/tests/run-test.sh index 0599323..8d79d1b 100755 --- a/tests/run-test.sh +++ b/tests/run-test.sh @@ -134,8 +134,7 @@ set_setting() { test_effect() { echo "Testing ${1} effect." - set_setting "open-preview-effect" "${1}" - set_setting "close-preview-effect" "${1}" + set_setting "preview-effect" "${1}" sleep 1 do_in_pod gnome-terminal From 269c5a1355619a895660bf9b5f2e25d163e28aff Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Mon, 30 Jan 2023 05:52:49 +0100 Subject: [PATCH 27/67] :wrench: Add some initial profile evaluation --- extension.js | 38 ++++++++++++++++++++++---------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/extension.js b/extension.js index 2aab160..7ab215f 100644 --- a/extension.js +++ b/extension.js @@ -404,6 +404,8 @@ class Extension { // 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) { + // In case we return early, make sure that the animation times are reset properly. + this._fixAnimationTimes(forOpening, null); // Only add effects to normal windows and dialog windows. const isNormalWindow = actor.meta_window.window_type == Meta.WindowType.NORMAL; @@ -425,7 +427,6 @@ class Extension { // 'power-saver'; // if (!skip! && previewNick == '') { - // this._fixAnimationTimes(isDialogWindow, forOpening, null); // return; // } @@ -467,9 +468,20 @@ class Extension { // effect. else { - const profile = this._profiles.find(p => { - utils.debug('PRIO: ' + p.priority); - return true; + const animationType = forOpening ? 1 : 2; + const windowType = isNormalWindow ? 1 : 2; + const powerMode = this._upowerProxy.OnBattery ? 1 : 2; + + profile = this._profiles.find(p => { + const profileAnimationType = p.settings.get_int('profile-animation-type'); + const profileWindowType = p.settings.get_int('profile-window-type'); + const profileDesktopStyle = p.settings.get_int('profile-desktop-style'); + const profilePowerMode = p.settings.get_int('profile-power-mode'); + const profilePowerProfile = p.settings.get_int('profile-power-profile'); + + return (profileAnimationType == 0 || profileAnimationType == animationType) && + (profileWindowType == 0 || profileWindowType == windowType) && + (profilePowerMode == 0 || profilePowerMode == powerMode); }); if (profile) { @@ -488,7 +500,6 @@ class Extension { // If nothing was enabled, we have to do nothing :) if (!effect || !profile) { - this._fixAnimationTimes(isDialogWindow, forOpening, null); return; } @@ -512,7 +523,6 @@ class Extension { // All animations are relative to the window's center. actor.set_pivot_point(0.5, 0.5); - // We tweak the opacity and scale of the actor. If there is no ongoing transition for // a property, a new one is set up. const config = {'opacity': 255, 'scale-x': actorScale.x, 'scale-y': actorScale.y}; @@ -565,7 +575,6 @@ class Extension { const transition = actor.get_transition('opacity'); if (!transition) { - this._fixAnimationTimes(isDialogWindow, forOpening, null); utils.debug('Cannot setup shader without opacity transition.') return; } @@ -600,7 +609,7 @@ 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); + this._fixAnimationTimes(forOpening, duration); } // The code below is not necessary for Burn-My-Windows to function. However, there @@ -610,15 +619,12 @@ class Extension { // 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) { + _fixAnimationTimes(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; - } + imports.ui.windowManager.DIALOG_DESTROY_WINDOW_ANIMATION_TIME = + duration != null ? duration : this._origDialogTime; + imports.ui.windowManager.DESTROY_WINDOW_ANIMATION_TIME = + duration != null ? duration : this._origWindowTime; } } From 792be167a4ab3bcf44e65a7fad85459e1bd9c163 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Mon, 30 Jan 2023 13:56:56 +0100 Subject: [PATCH 28/67] :tada: Add WindowPicker --- ...gnome.shell.extensions.burn-my-windows.xml | 13 +++ src/WindowPicker.js | 88 +++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 resources/interfaces/org.gnome.shell.extensions.burn-my-windows.xml create mode 100644 src/WindowPicker.js diff --git a/resources/interfaces/org.gnome.shell.extensions.burn-my-windows.xml b/resources/interfaces/org.gnome.shell.extensions.burn-my-windows.xml new file mode 100644 index 0000000..22b6fd3 --- /dev/null +++ b/resources/interfaces/org.gnome.shell.extensions.burn-my-windows.xml @@ -0,0 +1,13 @@ + + + + + + + + + + \ No newline at end of file diff --git a/src/WindowPicker.js b/src/WindowPicker.js new file mode 100644 index 0000000..0342573 --- /dev/null +++ b/src/WindowPicker.js @@ -0,0 +1,88 @@ +////////////////////////////////////////////////////////////////////////////////////////// +// ) ( // +// ( /( ( ( ) ( ( ( ( )\ ) ( ( // +// )\()) ))\ )( ( ( )\ ) )\))( )\ ( (()/( ( )\))( ( // +// ((_)\ /((_|()\ )\ ) )\ '(()/( ((_)()((_) )\ ) ((_)))\((_)()\ )\ // +// | |(_|_))( ((_)_(_/( _((_)) )(_)) _(()((_|_)_(_/( _| |((_)(()((_|(_) // +// | '_ \ || | '_| ' \)) | ' \()| || | \ V V / | ' \)) _` / _ \ V V (_-< // +// |_.__/\_,_|_| |_||_| |_|_|_| \_, | \_/\_/|_|_||_|\__,_\___/\_/\_//__/ // +// |__/ // +////////////////////////////////////////////////////////////////////////////////////////// + +// SPDX-FileCopyrightText: Simon Schneegans +// SPDX-FileCopyrightText: Aurélien Hamy +// SPDX-License-Identifier: GPL-3.0-or-later + +'use strict'; + +const {Gio, GLib} = imports.gi; +const Main = imports.ui.main; +const LookingGlass = imports.ui.lookingGlass; + +const Me = imports.misc.extensionUtils.getCurrentExtension(); +const utils = Me.imports.src.utils; + +////////////////////////////////////////////////////////////////////////////////////////// +// This is based on the window-picking functionality of the Blur-My-Shell extension. // +// The PickWindow() method is exposed via the D-Bus and can be called by the // +// preferences dialog of the Burn-My-Windows extensions in order to initiate the window // +// picking. // +////////////////////////////////////////////////////////////////////////////////////////// + +var WindowPicker = class WindowPicker { + // ------------------------------------------------------------------------- constructor + + constructor() { + const iFace = utils.getStringResource( + '/interfaces/org.gnome.shell.extensions.burn-my-windows.xml'); + this._dbus = Gio.DBusExportedObject.wrapJSObject(iFace, this); + } + + // --------------------------------------------------------------------- D-Bus interface + + // This method is exposed via the D-Bus. It is called by the preferences dialog of the + // Burn-My-Windows extensions in order to initiate the window picking. + PickWindow() { + + // We use the actor picking from LookingGlass. This seems a bit hacky and also allows + // selecting things of the Shell which are not windows, but it does the trick :) + const lookingGlass = Main.createLookingGlass(); + lookingGlass.open(); + lookingGlass.hide(); + + const inspector = new LookingGlass.Inspector(Main.createLookingGlass()); + inspector.connect('target', (me, target, x, y) => { + // Remove border effect when window is picked. + target.get_effects() + .filter(e => e.toString().includes('lookingGlass_RedBorderEffect')) + .forEach(e => target.remove_effect(e)); + + let actor = target; + if (target.toString().includes('MetaSurfaceActor')) { + actor = target.get_parent(); + } + + let wmClass = 'window-not-found'; + if (actor.toString().includes('WindowActor')) { + wmClass = actor.meta_window.get_wm_class() ?? 'window-not-found'; + } + + this._dbus.emit_signal('WindowPicked', new GLib.Variant('(s)', [wmClass])); + }); + + // Close LookingGlass when we're done. + inspector.connect('closed', _ => lookingGlass.close()); + } + + // -------------------------------------------------------------------- public interface + + // Call this to make the window-picking API available on the D-Bus. + export() { + this._dbus.export(Gio.DBus.session, '/org/gnome/shell/extensions/BurnMyWindows'); + } + + // Call this to stop this D-Bus again. + unexport() { + this._dbus.unexport(); + } +}; From 35860c7b2d0fb989ed7a1bd5dcba856eef6d838d Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Mon, 30 Jan 2023 13:57:07 +0100 Subject: [PATCH 29/67] :beetle: Fix makefile --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 3cd3957..dc44ed1 100644 --- a/Makefile +++ b/Makefile @@ -91,7 +91,7 @@ $(ZIP_NAME): $(ZIP_CONTENT) fi # Compiles the gschemas.compiled file from the gschema.xml file. -schemas/gschemas.compiled: schemas/org.gnome.shell.extensions.$(NAME).gschema.xml +schemas/gschemas.compiled: schemas/org.gnome.shell.extensions.$(NAME).gschema.xml schemas/org.gnome.shell.extensions.$(NAME)-profile.gschema.xml @echo "Compiling schemas..." @glib-compile-schemas schemas From 99b90377c553bea6af0cb9493251263e7288302e Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Mon, 30 Jan 2023 13:57:33 +0100 Subject: [PATCH 30/67] :tada: Implement profile selection --- extension.js | 107 +++++++++++++----- prefs.js | 56 +++++++-- resources/ui/adw/prefs.ui | 35 ++++-- ...nsions.burn-my-windows-profile.gschema.xml | 18 ++- src/ProfileManager.js | 21 +++- 5 files changed, 185 insertions(+), 52 deletions(-) diff --git a/extension.js b/extension.js index 7ab215f..431c11c 100644 --- a/extension.js +++ b/extension.js @@ -32,6 +32,7 @@ const ExtensionUtils = imports.misc.extensionUtils; const Me = imports.misc.extensionUtils.getCurrentExtension(); const utils = Me.imports.src.utils; const ProfileManager = Me.imports.src.ProfileManager.ProfileManager; +const WindowPicker = Me.imports.src.WindowPicker.WindowPicker; ////////////////////////////////////////////////////////////////////////////////////////// // This extensions modifies the window-close and window-open animations with all kinds // @@ -90,6 +91,13 @@ class Extension { this._loadProfiles(); + // This is used to get the desktop's color scheme. + this._shellSettings = new Gio.Settings({schema: 'org.gnome.desktop.interface'}); + + // Enable the window-picking D-Bus API for the preferences dialog. + this._windowPicker = new WindowPicker(); + this._windowPicker.export(); + // We will use extensionThis to refer to the extension inside the patched methods. const extensionThis = this; @@ -348,6 +356,9 @@ class Extension { // Unregister our resources. Gio.resources_unregister(this._resources); + // Disable the window-picking D-Bus API. + this._windowPicker.unexport(); + // Restore the original window-open and window-close animations. global.window_manager.disconnect(this._destroyConnection); global.display.disconnect(this._windowCreatedConnection); @@ -373,41 +384,50 @@ class Extension { // ----------------------------------------------------------------------- private stuff + // This loads all effect profiles and assigns a priority to each profile. Whenever a + // window is opened or closed, the matching effect profile with the highest priority + // will be chosen. + // This method is called whenever the currently edited profile in the/ preferences + // dialog changes. This is most likely a bit too often, but it will also happen whenever + // a new profile is created and whenever an old profile is deleted. _loadProfiles() { + + // Get all currently available profiles. const profileManager = new ProfileManager(); + this._profiles = profileManager.getProfiles(); - utils.debug('load profiles!'); - + // Whenever the properties of a profile is changed in the settings, we may have to + // resort all profiles according to their priority. const updatePriority = (p) => { - utils.debug('sort profiles!'); p.priority = profileManager.getProfilePriority(p.settings); this._profiles.sort((a, b) => b.priority - a.priority); }; - this._profiles = profileManager.getProfiles(); + // For each profile, assign an initial priority and update the priority whenever a + // related setting changes. this._profiles.forEach(p => { + p.priority = profileManager.getProfilePriority(p.settings); + p.settings.connect('changed::profile-app', () => updatePriority(p)); p.settings.connect('changed::profile-animation-type', () => updatePriority(p)); p.settings.connect('changed::profile-window-type', () => updatePriority(p)); - p.settings.connect('changed::profile-desktop-style', () => updatePriority(p)); + p.settings.connect('changed::profile-color-scheme', () => updatePriority(p)); p.settings.connect('changed::profile-power-mode', () => updatePriority(p)); p.settings.connect('changed::profile-power-profile', () => updatePriority(p)); - - p.priority = profileManager.getProfilePriority(p.settings); }); - utils.debug('sort profiles!'); + // Sort all profiles initially according to their initial priority. this._profiles.sort((a, b) => b.priority - a.priority); } - // 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). + // This method adds one of the configured effects to the given actor. First, a profile + // matching the current circumstances is chosen. Then a random effect from its enabled + // effects will be selected. This will also tweak the transitions of the given actor + // (e.g. scale it up if required). _setupEffect(actor, forOpening) { // In case we return early, make sure that the animation times are reset properly. this._fixAnimationTimes(forOpening, null); - // Only add effects to normal windows and dialog windows. + // For now, we only add effects to normal windows and dialog windows. const isNormalWindow = actor.meta_window.window_type == Meta.WindowType.NORMAL; const isDialogWindow = actor.meta_window.window_type == Meta.WindowType.MODAL_DIALOG || @@ -417,20 +437,6 @@ class Extension { return; } - - // TODO!. - // We may have to do nothing if running on battery power or if in power-save mode. - // let disableOnBattery = - // this._settings.get_boolean('disable-on-battery') && this._upowerProxy.OnBattery; - // let disableOnPowerSave = this._settings.get_boolean('disable-on-power-save') && - // this._powerProfilesProxy && this._powerProfilesProxy.ActiveProfile == - // 'power-saver'; - - // if (!skip! && previewNick == '') { - // return; - // } - - // There is the weird case where an animation is already ongoing. This happens when a // window is closed which has been created before the session was started (e.g. when // GNOME Shell has been restarted in the meantime). @@ -441,7 +447,7 @@ class Extension { oldShader.returnToFactory(); } - // ------------------------------------------------------------------ choose an effect + // ----------------------------------------------- choose a profile and then an effect // Usually, we use the effect profile with the highest priority which matches the // current circumstances. From this profile, we choose a random effect. However, if an @@ -468,22 +474,62 @@ class Extension { // effect. else { + // These numbers match the indices in the Gtk.StringLists defined in the UI files + // (e.g. resources/ui/adw/prefs.ui). const animationType = forOpening ? 1 : 2; const windowType = isNormalWindow ? 1 : 2; const powerMode = this._upowerProxy.OnBattery ? 1 : 2; + // Get the first profile whose constraints match the circumstances. The list is + // sorted by priority, so we are good to take the first match. profile = this._profiles.find(p => { + const profileApp = p.settings.get_string('profile-app'); const profileAnimationType = p.settings.get_int('profile-animation-type'); const profileWindowType = p.settings.get_int('profile-window-type'); - const profileDesktopStyle = p.settings.get_int('profile-desktop-style'); const profilePowerMode = p.settings.get_int('profile-power-mode'); + const profileColorScheme = p.settings.get_int('profile-color-scheme'); const profilePowerProfile = p.settings.get_int('profile-power-profile'); - return (profileAnimationType == 0 || profileAnimationType == animationType) && + // First we check whether the animation type, window type, and power mode are + // matching. + let matches = + (profileAnimationType == 0 || profileAnimationType == animationType) && (profileWindowType == 0 || profileWindowType == windowType) && (profilePowerMode == 0 || profilePowerMode == powerMode); + + // If that was the case, we also check the application name. + if (matches && profileApp != '') { + const app = actor.meta_window.get_wm_class().toLowerCase(); + matches = app == profileApp.toLowerCase(); + } + + // If the profile is still matching, we also check the color scheme. + if (matches && profileColorScheme != 0 && utils.shellVersionIsAtLeast(42, 0)) { + const colorScheme = this._shellSettings.get_string('color-scheme'); + matches &= (profileColorScheme == 1 && colorScheme == 'default') || + (profileColorScheme == 2 && colorScheme == 'prefer-dark'); + } + + // Finally, we may also have to check the power profile. + if (matches && profilePowerProfile != 0 && this._powerProfilesProxy) { + const powerProfile = this._powerProfilesProxy.ActiveProfile; + + // To understand the numbers, please refer to the indices in the Gtk.StringList + // of the profile-power-profile Adw.ComboRow in resources/ui/adw/prefs.ui. + if (powerProfile == 'power-saver') { + matches &= profilePowerProfile == 1 || profilePowerProfile == 4; + } else if (powerProfile == 'balanced') { + matches &= profilePowerProfile == 2 || profilePowerProfile == 4 || + profilePowerProfile == 5; + } else { + matches &= profilePowerProfile == 3 || profilePowerProfile == 5; + } + } + + return matches; }); + // If we found a matching profile, choose a random effect from it. if (profile) { // Create a list of all enabled effects of this profile. @@ -503,6 +549,7 @@ class Extension { return; } + // ----------------------------------------------------------- tweak actor transitions // If we are currently performing integration test, all animations are set to a fixed diff --git a/prefs.js b/prefs.js index 40f889a..61d2ac0 100644 --- a/prefs.js +++ b/prefs.js @@ -131,6 +131,29 @@ var PreferencesDialog = class PreferencesDialog { this._builder.get_object('profile-power-profile').set_visible(hasPowerProfiles); + // The global color scheme is only available starting with GNOME Shell 42. We hide the + // corresponding settings row on older versions. + this._builder.get_object('profile-color-scheme') + .set_visible(utils.shellVersionIsAtLeast(42, 0)); + + this._builder.get_object('profile-choose-app-button').connect('clicked', () => { + Gio.DBus.session.call('org.gnome.Shell', + '/org/gnome/shell/extensions/BurnMyWindows', + 'org.gnome.shell.extensions.BurnMyWindows', 'PickWindow', + null, null, Gio.DBusCallFlags.NO_AUTO_START, -1, null, null); + }); + + this._dbusConnection = Gio.DBus.session.signal_subscribe( + 'org.gnome.Shell', 'org.gnome.shell.extensions.BurnMyWindows', 'WindowPicked', + '/org/gnome/shell/extensions/BurnMyWindows', null, Gio.DBusSignalFlags.NONE, + (conn, sender, obj_path, iface, signal, params) => { + const val = params.get_child_value(0).get_string()[0]; + + if (val != 'window-not-found') { + this._builder.get_object('profile-app').text = val; + } + }); + // Starting with GNOME Shell 42, the settings dialog uses libadwaita. We use this to // create a completely different layout for the settings dialog. if (utils.isADW()) { @@ -479,6 +502,9 @@ var PreferencesDialog = class PreferencesDialog { this._widget.connect('destroy', () => { // Unregister our resources. Gio.resources_unregister(this._resources); + + // Disconnect from the window-picker API. + Gio.DBus.session.signal_unsubscribe(this._dbusConnection); }); // Show the widgets on GTK3. @@ -507,10 +533,16 @@ var PreferencesDialog = class PreferencesDialog { // Connects a Gtk.ComboBox (or anything else which has an 'selected' property) to a // settings key. It also binds the corresponding reset button. - bindComboRow(settingsKey) { + bindComboBox(settingsKey) { this._bind(settingsKey, 'selected'); } + // Connects a Gtk.Entry (or anything else which has an 'text' property) to a + // settings key. It also binds the corresponding reset button. + bindEntry(settingsKey) { + this._bind(settingsKey, 'text'); + } + // Connects a Gtk.Adjustment (or anything else which has a 'value' property) to a // settings key. It also binds the corresponding reset button. bindAdjustment(settingsKey) { @@ -591,19 +623,27 @@ var PreferencesDialog = class PreferencesDialog { } // Connect all profile options. - const setupProfileOption = (settingsKey) => { - this.bindComboRow(settingsKey); + const updateProfileButtonMenuIfChanged = (settingsKey) => { this._connectProfileSetting('changed::' + settingsKey, () => { this._updateProfileButton(); this._updateProfileMenu(); }); }; - setupProfileOption('profile-animation-type'); - setupProfileOption('profile-window-type'); - setupProfileOption('profile-desktop-style'); - setupProfileOption('profile-power-mode'); - setupProfileOption('profile-power-profile'); + updateProfileButtonMenuIfChanged('profile-app'); + updateProfileButtonMenuIfChanged('profile-animation-type'); + updateProfileButtonMenuIfChanged('profile-window-type'); + updateProfileButtonMenuIfChanged('profile-color-scheme'); + updateProfileButtonMenuIfChanged('profile-power-mode'); + updateProfileButtonMenuIfChanged('profile-power-profile'); + + this.bindEntry('profile-app'); + this.bindComboBox('profile-animation-type'); + this.bindComboBox('profile-window-type'); + this.bindComboBox('profile-color-scheme'); + this.bindComboBox('profile-power-mode'); + this.bindComboBox('profile-power-profile'); + this.bindSwitch('profile-high-priority'); // Connect all effect settings. this._ALL_EFFECTS.forEach(effect => { diff --git a/resources/ui/adw/prefs.ui b/resources/ui/adw/prefs.ui index f56fd50..c16d58c 100644 --- a/resources/ui/adw/prefs.ui +++ b/resources/ui/adw/prefs.ui @@ -70,12 +70,12 @@ SPDX-License-Identifier: GPL-3.0-or-later - Edit Effect Profile - Here you can specify under which circumstances the current effect settings should be applied. + Effect Profile Constraints + Define when the current effect settings should be used. - Choose an Application + Application Name bmw-select-app-symbolic @@ -116,14 +116,14 @@ SPDX-License-Identifier: GPL-3.0-or-later - - Desktop Style + + Color Scheme Any - Bright Mode - Dark Mode + Default Color Scheme + Dark Color Scheme @@ -166,6 +166,27 @@ SPDX-License-Identifier: GPL-3.0-or-later + + + Advanced Profile Options + + + + High Priority + Force using this profile even if it has less constraints than another matching profile. + 1 + profile-high-priority + + + center + + + + + + + + prefs.profile-delete diff --git a/schemas/org.gnome.shell.extensions.burn-my-windows-profile.gschema.xml b/schemas/org.gnome.shell.extensions.burn-my-windows-profile.gschema.xml index 917cc36..639191d 100644 --- a/schemas/org.gnome.shell.extensions.burn-my-windows-profile.gschema.xml +++ b/schemas/org.gnome.shell.extensions.burn-my-windows-profile.gschema.xml @@ -13,6 +13,12 @@ SPDX-License-Identifier: CC0-1.0 + + "" + Profile App + The application name for which the current effect settings should be used. + + 0 @@ -27,11 +33,11 @@ SPDX-License-Identifier: CC0-1.0 The window types for which the current effect settings should be used. - + 0 - Profile Desktop Style - The desktop styles for which the current effect settings should be used. + Profile Color Scheme + The desktop color schemes for which the current effect settings should be used. @@ -48,6 +54,12 @@ SPDX-License-Identifier: CC0-1.0 The power profiles in which the current effect settings should be used. + + false + Profile High Priority + Force using this profile even if it has less constraints than another matching profile. + + diff --git a/src/ProfileManager.js b/src/ProfileManager.js index 3152386..6801df7 100644 --- a/src/ProfileManager.js +++ b/src/ProfileManager.js @@ -32,7 +32,7 @@ const utils = Me.imports.src.utils; ////////////////////////////////////////////////////////////////////////////////////////// var ProfileManager = class { - // ------------------------------------------------------------ constructor / destructor + // ------------------------------------------------------------------------- constructor constructor() { this._makeProfilesDir(); @@ -128,12 +128,17 @@ var ProfileManager = class { getProfilePriority(settings) { let priority = 0; + // Each setting which is not set to its default value increases the priority by one. + if (settings.get_string('profile-app') != '') ++priority; if (settings.get_int('profile-animation-type') > 0) ++priority; if (settings.get_int('profile-window-type') > 0) ++priority; - if (settings.get_int('profile-desktop-style') > 0) ++priority; + if (settings.get_int('profile-color-scheme') > 0) ++priority; if (settings.get_int('profile-power-mode') > 0) ++priority; if (settings.get_int('profile-power-profile') > 0) ++priority; + // Increase the priority significantly for high-priority profiles. + if (settings.get_boolean('profile-high-priority')) priority += 100; + return priority; } @@ -142,6 +147,14 @@ var ProfileManager = class { getProfileName(settings) { let items = []; + // If an app is configured, use it as first component for the profile's name. + const app = settings.get_string('profile-app'); + if (app != '') { + items.push(app); + } + + // Now add components to the name for each non-default profile option. Make sure that + // these are the same strings as used in the UI files! const addComponent = (settingsKey, options) => { const option = settings.get_int(settingsKey); if (option > 0) { @@ -154,8 +167,8 @@ var ProfileManager = class { _('Closing Windows')]); addComponent('profile-window-type', [_('Normal Windows'), _('Dialog Windows')]); - addComponent('profile-desktop-style', [_('Bright Mode'), - _('Dark Mode')]); + addComponent('profile-color-scheme', [_('Default Color Scheme'), + _('Dark Color Scheme')]); addComponent('profile-power-mode', [_('On Battery'), _('Plugged In')]); addComponent('profile-power-profile', [_('Power-Saver Mode'), From 88168553f8d7a094a826d3d53d3bca82cfb4c449 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Mon, 30 Jan 2023 14:50:25 +0100 Subject: [PATCH 31/67] :wrench: Port effect profiles to GS 42 --- prefs.js | 40 ++++++++++++++++++++++++++++++++------- resources/ui/adw/prefs.ui | 33 ++++++++++++++++---------------- 2 files changed, 49 insertions(+), 24 deletions(-) diff --git a/prefs.js b/prefs.js index 61d2ac0..74a03be 100644 --- a/prefs.js +++ b/prefs.js @@ -467,16 +467,36 @@ var PreferencesDialog = class PreferencesDialog { group.add_action(newProfileAction); // This action shows a confirmation dialog. Upon user approval, the currently - // active profile is deleted. - const deleteProfileAction = Gio.SimpleAction.new('profile-delete', null); - deleteProfileAction.connect('activate', () => { - this._builder.get_object('profile-delete-dialog').show(); - }); + // active profile is deleted. We use the more beautiful Adw.MessageDialog if it is + // available (usually on GNOME 43 and beyond). + let deleteProfileDialog; + const dialogTitle = _('Delete this Profile?'); + const dialogSubtitle = _('The current effect profile will be permanently lost.'); - const deleteProfileDialog = this._builder.get_object('profile-delete-dialog'); + if (Adw.MessageDialog) { + deleteProfileDialog = + new Adw.MessageDialog({heading: dialogTitle, body: dialogSubtitle}); + deleteProfileDialog.add_response('cancel', _('Cancel')); + deleteProfileDialog.add_response('delete', _('Delete')); + deleteProfileDialog.set_response_appearance('delete', + Adw.ResponseAppearance.DESTRUCTIVE); + deleteProfileDialog.set_default_response('cancel'); + deleteProfileDialog.set_close_response('cancel'); + } else { + deleteProfileDialog = new Gtk.MessageDialog({ + text: dialogTitle, + secondary_text: dialogSubtitle, + modal: true, + title: '', + buttons: Gtk.ButtonsType.OK_CANCEL + }); + } + + deleteProfileDialog.set_hide_on_close(true); deleteProfileDialog.set_transient_for(window); + deleteProfileDialog.connect('response', (d, response) => { - if (response == 'delete') { + if (response == 'delete' || response == Gtk.ResponseType.OK) { // Stop editing the current profile. this._builder.get_object('edit-profile-button').active = false; @@ -491,8 +511,14 @@ var PreferencesDialog = class PreferencesDialog { // selection menu. this._updateProfileMenu(); } + + d.hide(); }); + const deleteProfileAction = Gio.SimpleAction.new('profile-delete', null); + deleteProfileAction.connect('activate', () => { + deleteProfileDialog.show(); + }); group.add_action(deleteProfileAction); } }); diff --git a/resources/ui/adw/prefs.ui b/resources/ui/adw/prefs.ui index c16d58c..428c1a0 100644 --- a/resources/ui/adw/prefs.ui +++ b/resources/ui/adw/prefs.ui @@ -8,20 +8,6 @@ SPDX-License-Identifier: GPL-3.0-or-later - - - true - true - Delete this Profile? - The current effect profile will be permanently lost. - cancel - cancel - - Cancel - Delete - - - center @@ -74,12 +60,25 @@ SPDX-License-Identifier: GPL-3.0-or-later Define when the current effect settings should be used. - + Application Name - - bmw-select-app-symbolic + center + + + + + + + + + bmw-select-app-symbolic + center + + From d6c89cd79bace547007077b6b8e0da4c18a3a462 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Mon, 30 Jan 2023 19:09:46 +0100 Subject: [PATCH 32/67] :wrench: Reorder UI file --- resources/ui/adw/prefs.ui | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/resources/ui/adw/prefs.ui b/resources/ui/adw/prefs.ui index 428c1a0..540bffa 100644 --- a/resources/ui/adw/prefs.ui +++ b/resources/ui/adw/prefs.ui @@ -8,6 +8,12 @@ SPDX-License-Identifier: GPL-3.0-or-later + + + main-menu + heart-filled-symbolic + + center @@ -205,11 +211,6 @@ SPDX-License-Identifier: GPL-3.0-or-later - - main-menu - heart-filled-symbolic - - From 956cef56b4f12995884cabd781dd5b3188e55ed6 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Wed, 1 Feb 2023 05:36:50 +0100 Subject: [PATCH 33/67] :wrench: Start porting to GTK4 --- prefs.js | 311 ++++++++----------- resources/ui/gtk4/effectPage.ui | 59 ---- resources/ui/gtk4/prefs.ui | 528 ++++++++++++++++++++++---------- 3 files changed, 483 insertions(+), 415 deletions(-) delete mode 100644 resources/ui/gtk4/effectPage.ui diff --git a/prefs.js b/prefs.js index 74a03be..933837c 100644 --- a/prefs.js +++ b/prefs.js @@ -31,9 +31,6 @@ const Me = imports.misc.extensionUtils.getCurrentExtension(); const utils = Me.imports.src.utils; const ProfileManager = Me.imports.src.ProfileManager.ProfileManager; -// This template widget class is defined at the bottom of this file. -var BurnMyWindowsEffectPage = null; - ////////////////////////////////////////////////////////////////////////////////////////// // The preferences dialog is organized in pages, each of which is loaded from a // // separate ui file. There's one page with general options, all other paged are loaded // @@ -48,26 +45,26 @@ var PreferencesDialog = class PreferencesDialog { // New effects must be registered here and in extension.js. this._ALL_EFFECTS = [ - new Me.imports.src.effects.Apparition.Apparition(), - new Me.imports.src.effects.BrokenGlass.BrokenGlass(), - new Me.imports.src.effects.Doom.Doom(), - new Me.imports.src.effects.EnergizeA.EnergizeA(), - new Me.imports.src.effects.EnergizeB.EnergizeB(), - new Me.imports.src.effects.Fire.Fire(), - new Me.imports.src.effects.Glide.Glide(), - new Me.imports.src.effects.Glitch.Glitch(), - new Me.imports.src.effects.Hexagon.Hexagon(), - new Me.imports.src.effects.Incinerate.Incinerate(), - new Me.imports.src.effects.Matrix.Matrix(), - new Me.imports.src.effects.Pixelate.Pixelate(), - new Me.imports.src.effects.PixelWheel.PixelWheel(), - new Me.imports.src.effects.PixelWipe.PixelWipe(), - new Me.imports.src.effects.Portal.Portal(), - new Me.imports.src.effects.SnapOfDisintegration.SnapOfDisintegration(), - new Me.imports.src.effects.TRexAttack.TRexAttack(), - new Me.imports.src.effects.TVEffect.TVEffect(), - new Me.imports.src.effects.TVGlitch.TVGlitch(), - new Me.imports.src.effects.Wisps.Wisps(), + // new Me.imports.src.effects.Apparition.Apparition(), + // new Me.imports.src.effects.BrokenGlass.BrokenGlass(), + // new Me.imports.src.effects.Doom.Doom(), + // new Me.imports.src.effects.EnergizeA.EnergizeA(), + // new Me.imports.src.effects.EnergizeB.EnergizeB(), + // new Me.imports.src.effects.Fire.Fire(), + // new Me.imports.src.effects.Glide.Glide(), + // new Me.imports.src.effects.Glitch.Glitch(), + // new Me.imports.src.effects.Hexagon.Hexagon(), + // new Me.imports.src.effects.Incinerate.Incinerate(), + // new Me.imports.src.effects.Matrix.Matrix(), + // new Me.imports.src.effects.Pixelate.Pixelate(), + // new Me.imports.src.effects.PixelWheel.PixelWheel(), + // new Me.imports.src.effects.PixelWipe.PixelWipe(), + // new Me.imports.src.effects.Portal.Portal(), + // new Me.imports.src.effects.SnapOfDisintegration.SnapOfDisintegration(), + // new Me.imports.src.effects.TRexAttack.TRexAttack(), + // new Me.imports.src.effects.TVEffect.TVEffect(), + // new Me.imports.src.effects.TVGlitch.TVGlitch(), + // new Me.imports.src.effects.Wisps.Wisps(), ]; // Load all of our resources. @@ -92,9 +89,6 @@ var PreferencesDialog = class PreferencesDialog { Gtk.IconTheme.get_default().add_resource_path('/img'); } - // Register the template widgets used in the settings dialog. - this._registerCustomClasses(); - // Load the general user interface files. this._builder = new Gtk.Builder(); this._builder.add_from_resource(`/ui/common/menus.ui`); @@ -129,12 +123,19 @@ var PreferencesDialog = class PreferencesDialog { // Maybe the service is masked... } - this._builder.get_object('profile-power-profile').set_visible(hasPowerProfiles); + let powerProfileRow = this._builder.get_object('profile-power-profile'); + if (!utils.isADW()) { + powerProfileRow = powerProfileRow.get_parent().get_parent(); + } + powerProfileRow.set_visible(hasPowerProfiles); // The global color scheme is only available starting with GNOME Shell 42. We hide the // corresponding settings row on older versions. - this._builder.get_object('profile-color-scheme') - .set_visible(utils.shellVersionIsAtLeast(42, 0)); + let colorSchemeRow = this._builder.get_object('profile-color-scheme'); + if (!utils.isADW()) { + colorSchemeRow = colorSchemeRow.get_parent().get_parent(); + } + colorSchemeRow.set_visible(utils.shellVersionIsAtLeast(42, 0)); this._builder.get_object('profile-choose-app-button').connect('clicked', () => { Gio.DBus.session.call('org.gnome.Shell', @@ -154,138 +155,82 @@ var PreferencesDialog = class PreferencesDialog { } }); - // Starting with GNOME Shell 42, the settings dialog uses libadwaita. We use this to - // create a completely different layout for the settings dialog. - if (utils.isADW()) { + // This is our top-level widget which we will return later. + this._widget = this._builder.get_object('general-prefs'); - // This is our top-level widget which we will return later. - this._widget = this._builder.get_object('general-prefs'); + // Then add a preferences group for the effect expander rows. + const group = this._builder.get_object('effects-group'); - // Then add a preferences group for the effect expander rows. - const group = this._builder.get_object('effects-group'); + // This stores all expander rows for the effects. We use this to implement the + // accordion-like behavior of the effect settings. + this._effectRows = []; - // This stores all expander rows for the effects. We use this to implement the - // accordion-functionality of the effect settings. - this._effectRows = []; + // Now add all the rows. + this._ALL_EFFECTS.forEach(effect => { + const [minMajor, minMinor] = effect.getMinShellVersion(); + if (utils.shellVersionIsAtLeast(minMajor, minMinor)) { - // Now add all the rows. - this._ALL_EFFECTS.forEach(effect => { - const [minMajor, minMinor] = effect.getMinShellVersion(); - if (utils.shellVersionIsAtLeast(minMajor, minMinor)) { + const uiFile = `/ui/${utils.getUIDir()}/${effect.getNick()}.ui`; + const [hasPrefs] = Gio.resources_get_info(uiFile, 0); - const uiFile = `/ui/${utils.getUIDir()}/${effect.getNick()}.ui`; - const [hasPrefs] = Gio.resources_get_info(uiFile, 0); + let row; + if (hasPrefs) { + // Add the settings page to the builder. + this._builder.add_from_resource(uiFile); - let row; - if (hasPrefs) { - // Add the settings page to the builder. - this._builder.add_from_resource(uiFile); - - // Add the effect's preferences (if any). - row = this._builder.get_object(`${effect.getNick()}-prefs`); - } else { - row = Adw.ActionRow.new(); - } - - // On older versions of Adw (e.g. on GNOME Shell <43), the set_use_markup() does - // not yet exist. - if (row.set_use_markup) { - row.set_title('' + effect.getLabel() + ''); - row.set_use_markup(true); - } else { - row.set_title(effect.getLabel()); - } - - // Un-expand any previously expanded effect row. This way we ensure that there - // is only one expanded row at any time. - if (hasPrefs) { - row.connect('notify::expanded', currentRow => { - if (currentRow.get_expanded()) { - this._effectRows.forEach(row => { - if (row != currentRow && row.set_expanded) { - row.set_expanded(false); - } - }); - } - }); - } - - // The preview button. - const previewButton = Gtk.Button.new_from_icon_name('bmw-preview-symbolic'); - previewButton.add_css_class('circular'); - previewButton.add_css_class('flat'); - previewButton.set_tooltip_text(_('Preview this effect')); - previewButton.set_valign(Gtk.Align.CENTER); - row.add_action(previewButton); - - previewButton.connect('clicked', () => { - this._previewEffect(effect); - }); - - // Now add the toggle button for enabling and disabling the effect. - const button = Gtk.Switch.new(); - button.set_tooltip_text(_('Use this effect')); - button.set_valign(Gtk.Align.CENTER); - this._builder.expose_object(`${effect.getNick()}-enable-effect`, button); - - row.add_prefix(button); - group.add(row); - - this._effectRows.push(row); + // Add the effect's preferences (if any). + row = this._builder.get_object(`${effect.getNick()}-prefs`); + } else { + row = Adw.ActionRow.new(); } - }); - } - // On older GNOME versions, we use a StackSidebar. The code below works on GTK3 and - // GTK4. - else { - // This is our top-level widget which we will return later. - this._widget = new Gtk.Box({ - orientation: Gtk.Orientation.HORIZONTAL, - }); + // On older versions of Adw (e.g. on GNOME Shell <43), the set_use_markup() does + // not yet exist. + if (row.set_use_markup) { + row.set_title('' + effect.getLabel() + ''); + row.set_use_markup(true); + } else { + row.set_title(effect.getLabel()); + } - const stack = new Gtk.Stack({ - transition_type: Gtk.StackTransitionType.SLIDE_UP_DOWN, - }); - - // Add the general options page. - const generalPage = this._builder.get_object('general-prefs'); - generalPage.margin_start = 60; - generalPage.margin_end = 60; - stack.add_titled(generalPage, 'general', _('General Options')); - - this.gtkBoxAppend(this._widget, new Gtk.StackSidebar({stack: stack})); - this.gtkBoxAppend(this._widget, stack); - - // Add all other effect pages. - this._ALL_EFFECTS.forEach(effect => { - const [minMajor, minMinor] = effect.getMinShellVersion(); - if (utils.shellVersionIsAtLeast(minMajor, minMinor)) { - - const page = new BurnMyWindowsEffectPage(effect, this); - page.margin_start = 60; - page.margin_end = 60; - page.margin_top = 60; - page.margin_bottom = 60; - - const uiFile = `/ui/${utils.getUIDir()}/${effect.getNick()}.ui`; - const [hasPrefs] = Gio.resources_get_info(uiFile); - if (hasPrefs) { - - // Add the settings page to the builder. - this._builder.add_from_resource(uiFile); - - // Add the effect's preferences (if any). - const prefs = this._builder.get_object(`${effect.getNick()}-prefs`); - if (prefs) { - this.gtkBoxAppend(page, prefs); + // Un-expand any previously expanded effect row. This way we ensure that there + // is only one expanded row at any time. + if (hasPrefs) { + row.connect('notify::expanded', currentRow => { + if (currentRow.get_expanded()) { + this._effectRows.forEach(row => { + if (row != currentRow && row.set_expanded) { + row.set_expanded(false); + } + }); } - } - - stack.add_titled(page, effect.getNick(), effect.getLabel()); + }); } - }); - } + + // The preview button. + const previewButton = Gtk.Button.new_from_icon_name('bmw-preview-symbolic'); + previewButton.add_css_class('circular'); + previewButton.add_css_class('flat'); + previewButton.set_tooltip_text(_('Preview this effect')); + previewButton.set_valign(Gtk.Align.CENTER); + row.add_action(previewButton); + + previewButton.connect('clicked', () => { + this._previewEffect(effect); + }); + + // Now add the toggle button for enabling and disabling the effect. + const button = Gtk.Switch.new(); + button.set_tooltip_text(_('Use this effect')); + button.set_valign(Gtk.Align.CENTER); + this._builder.expose_object(`${effect.getNick()}-enable-effect`, button); + + row.add_prefix(button); + group.add(row); + + this._effectRows.push(row); + } + }); // Some things can only be done once the widget is shown as we do not have access to // the toplevel widget before. @@ -309,7 +254,7 @@ var PreferencesDialog = class PreferencesDialog { // Starting with GNOME Shell 42, we have to hack our way through the widget tree // of the Adw.PreferencesWindow... - if (Adw && utils.shellVersionIsAtLeast(42, 'beta')) { + if (utils.isADW()) { const header = this._findWidgetByType(window.get_content(), Adw.HeaderBar); header.pack_start(menu); header.set_title_widget(this._builder.get_object('profile-button')); @@ -330,6 +275,7 @@ var PreferencesDialog = class PreferencesDialog { } else { window.get_titlebar().pack_start(menu); + window.get_titlebar().set_title_widget(this._builder.get_object('profile-button')); } const addURIAction = (name, uri) => { @@ -473,7 +419,7 @@ var PreferencesDialog = class PreferencesDialog { const dialogTitle = _('Delete this Profile?'); const dialogSubtitle = _('The current effect profile will be permanently lost.'); - if (Adw.MessageDialog) { + if (utils.isADW() && Adw.MessageDialog) { deleteProfileDialog = new Adw.MessageDialog({heading: dialogTitle, body: dialogSubtitle}); deleteProfileDialog.add_response('cancel', _('Cancel')); @@ -495,7 +441,7 @@ var PreferencesDialog = class PreferencesDialog { deleteProfileDialog.set_hide_on_close(true); deleteProfileDialog.set_transient_for(window); - deleteProfileDialog.connect('response', (d, response) => { + deleteProfileDialog.connect('response', (dialog, response) => { if (response == 'delete' || response == Gtk.ResponseType.OK) { // Stop editing the current profile. this._builder.get_object('edit-profile-button').active = false; @@ -512,7 +458,7 @@ var PreferencesDialog = class PreferencesDialog { this._updateProfileMenu(); } - d.hide(); + dialog.hide(); }); const deleteProfileAction = Gio.SimpleAction.new('profile-delete', null); @@ -557,10 +503,16 @@ var PreferencesDialog = class PreferencesDialog { return this._widget; } - // Connects a Gtk.ComboBox (or anything else which has an 'selected' property) to a + // Connects an Adw.ComboRow (or anything else which has an 'selected' property) to a + // settings key. It also binds the corresponding reset button. + bindComboRow(settingsKey) { + this._bind(settingsKey, 'selected'); + } + + // Connects a Gtk.ComboBox (or anything else which has an 'active' property) to a // settings key. It also binds the corresponding reset button. bindComboBox(settingsKey) { - this._bind(settingsKey, 'selected'); + this._bind(settingsKey, 'active'); } // Connects a Gtk.Entry (or anything else which has an 'text' property) to a @@ -664,11 +616,20 @@ var PreferencesDialog = class PreferencesDialog { updateProfileButtonMenuIfChanged('profile-power-profile'); this.bindEntry('profile-app'); - this.bindComboBox('profile-animation-type'); - this.bindComboBox('profile-window-type'); - this.bindComboBox('profile-color-scheme'); - this.bindComboBox('profile-power-mode'); - this.bindComboBox('profile-power-profile'); + + if (utils.isADW()) { + this.bindComboRow('profile-animation-type'); + this.bindComboRow('profile-window-type'); + this.bindComboRow('profile-color-scheme'); + this.bindComboRow('profile-power-mode'); + this.bindComboRow('profile-power-profile'); + } else { + this.bindComboBox('profile-animation-type'); + this.bindComboBox('profile-window-type'); + this.bindComboBox('profile-color-scheme'); + this.bindComboBox('profile-power-mode'); + this.bindComboBox('profile-power-profile'); + } this.bindSwitch('profile-high-priority'); // Connect all effect settings. @@ -826,34 +787,6 @@ var PreferencesDialog = class PreferencesDialog { window.show_all(); } } - - // Initializes template widgets used by the preferences dialog. - _registerCustomClasses() { - - // If we are not using libadwaita, each effect page is based on a template widget. - // This template contains the title and the preview button. - if (!utils.isADW() && GObject.type_from_name('BurnMyWindowsEffectPage') == null) { - BurnMyWindowsEffectPage = GObject.registerClass( - { - GTypeName: 'BurnMyWindowsEffectPage', - Template: `resource:///ui/${utils.getUIDir()}/effectPage.ui`, - InternalChildren: ['label', 'button'], - }, - class BurnMyWindowsEffectPage extends Gtk.Box { // ------------------------------ - _init(effect, dialog) { - super._init(); - - // Set the effect's name as label. - this._label.label = effect.getLabel(); - - // Open the preview window once the preview button is clicked. - this._button.connect('clicked', () => { - dialog._previewEffect(effect); - }); - } - }); - } - } } // This is used for setting up the translations. diff --git a/resources/ui/gtk4/effectPage.ui b/resources/ui/gtk4/effectPage.ui deleted file mode 100644 index 6241b13..0000000 --- a/resources/ui/gtk4/effectPage.ui +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/resources/ui/gtk4/prefs.ui b/resources/ui/gtk4/prefs.ui index a20ade9..6836ff0 100644 --- a/resources/ui/gtk4/prefs.ui +++ b/resources/ui/gtk4/prefs.ui @@ -8,201 +8,395 @@ SPDX-License-Identifier: GPL-3.0-or-later - - + main-menu heart-filled-symbolic + + + center + + + profile-menu + + + + + bmw-edit-profile-symbolic + center + + + profile-editor-revealer + + + + + + vertical - 60 - 60 - + + + + edit-profile-button + + + + + vertical + 20 + 20 + 20 + 20 + 5 + + + + Effect Profile Constraints + start + + + + + + + Define when the current effect settings should be used. + start + + + + + + 5 + 15 + + + none + 1 + + + + + 0 + + + + + Application Name + 0 + start + center + 1 + + + + + + center + + + + + 200 + + + + + + bmw-select-app-symbolic + center + + + + + + + + + + + + 0 + + + + + Animation Type + 0 + start + center + 1 + + + + + 200 + + Any + Opening Windows + Closing Windows + + + + + + + + + + + 0 + + + + + Window Type + 0 + start + center + 1 + + + + + 200 + + Any + Normal Windows + Dialog Windows + + + + + + + + + + + 0 + + + + + Color Scheme + 0 + start + center + 1 + + + + + 200 + + Any + Default Color Scheme + Dark Color Scheme + + + + + + + + + + + 0 + + + + + Power Mode + 0 + start + center + 1 + + + + + 200 + + Any + On Battery + Plugged In + + + + + + + + + + + 0 + + + + + Power Profile + 0 + start + center + 1 + + + + + 200 + + Any + Power-Saver Mode + Balanced Mode + Performance Mode + Power Saver or Balanced + Balanced or Performance + + + + + + + + + + + + + + + + Advanced Profile Options + start + + + + + + + 5 + 15 + + + none + 1 + + + + + 0 + + + + + vertical + 3 + + + High Priority + 0 + start + center + 1 + + + + + Force using this profile even if it has less constraints than another matching profile. + 0 + start + center + 1 + end + + + + + + + + center + + + + + + + + + + + + + + + prefs.profile-delete + Delete this Profile... + start + + + + + + + + + + + + Effect Settings + 0 + start center - burn-my-windows-symbolic - 128 + 1 - - Welcome to Burn-My-Windows! - 8 - 6 + If multiple are selected, one is chosen randomly. + 0 + start + center + 1 - - - If you like this extension, recommend it to your friends :) - 36 - - - - + none 1 - - - - 0 - - - - - vertical - 3 - - - Enabled Effects - 0 - start - center - 1 - - - - - If multiple are selected, one is chosen randomly. - 0 - start - center - 1 - - - - - - - - Choose Effects - enabled-effects-menu - - - - - - - - - - 0 - - - - - Also Add Effects to Dialogs - 0 - start - center - 1 - - - - - end - center - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - Disable on Battery Power - 0 - start - center - 1 - - - - - end - center - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - Disable in Power-Save Mode - 0 - start - center - 1 - - - - - end - center - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - From 33e96278018b2fc394ea75f96fe73993786bec50 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Thu, 2 Feb 2023 10:37:11 +0100 Subject: [PATCH 34/67] :wrench: Port effect profiles to GTK4 --- prefs.js | 184 ++++++--- resources/css/gtk.css | 22 ++ resources/ui/gtk4/apparition.ui | 460 +++++++++++----------- resources/ui/gtk4/broken-glass.ui | 478 +++++++++++----------- resources/ui/gtk4/doom.ui | 368 +++++++++-------- resources/ui/gtk4/energize-a.ui | 253 ++++++------ resources/ui/gtk4/energize-b.ui | 253 ++++++------ resources/ui/gtk4/fire.ui | 550 +++++++++++++------------- resources/ui/gtk4/glide.ui | 457 +++++++++++----------- resources/ui/gtk4/glitch.ui | 437 ++++++++++----------- resources/ui/gtk4/hexagon.ui | 524 ++++++++++++------------- resources/ui/gtk4/incinerate.ui | 453 +++++++++++---------- resources/ui/gtk4/matrix.ui | 509 ++++++++++++------------ resources/ui/gtk4/pixel-wheel.ui | 274 +++++++------ resources/ui/gtk4/pixel-wipe.ui | 182 ++++----- resources/ui/gtk4/pixelate.ui | 274 +++++++------ resources/ui/gtk4/portal.ui | 437 ++++++++++----------- resources/ui/gtk4/prefs.ui | 631 +++++++++++++++--------------- resources/ui/gtk4/snap.ui | 253 ++++++------ resources/ui/gtk4/trex.ui | 436 ++++++++++----------- resources/ui/gtk4/tv-glitch.ui | 437 ++++++++++----------- resources/ui/gtk4/tv.ui | 161 ++++---- resources/ui/gtk4/wisps.ui | 253 ++++++------ 23 files changed, 4112 insertions(+), 4174 deletions(-) diff --git a/prefs.js b/prefs.js index 933837c..c4fa9d2 100644 --- a/prefs.js +++ b/prefs.js @@ -45,26 +45,26 @@ var PreferencesDialog = class PreferencesDialog { // New effects must be registered here and in extension.js. this._ALL_EFFECTS = [ - // new Me.imports.src.effects.Apparition.Apparition(), - // new Me.imports.src.effects.BrokenGlass.BrokenGlass(), - // new Me.imports.src.effects.Doom.Doom(), - // new Me.imports.src.effects.EnergizeA.EnergizeA(), - // new Me.imports.src.effects.EnergizeB.EnergizeB(), - // new Me.imports.src.effects.Fire.Fire(), - // new Me.imports.src.effects.Glide.Glide(), - // new Me.imports.src.effects.Glitch.Glitch(), - // new Me.imports.src.effects.Hexagon.Hexagon(), - // new Me.imports.src.effects.Incinerate.Incinerate(), - // new Me.imports.src.effects.Matrix.Matrix(), - // new Me.imports.src.effects.Pixelate.Pixelate(), - // new Me.imports.src.effects.PixelWheel.PixelWheel(), - // new Me.imports.src.effects.PixelWipe.PixelWipe(), - // new Me.imports.src.effects.Portal.Portal(), - // new Me.imports.src.effects.SnapOfDisintegration.SnapOfDisintegration(), - // new Me.imports.src.effects.TRexAttack.TRexAttack(), - // new Me.imports.src.effects.TVEffect.TVEffect(), - // new Me.imports.src.effects.TVGlitch.TVGlitch(), - // new Me.imports.src.effects.Wisps.Wisps(), + new Me.imports.src.effects.Apparition.Apparition(), + new Me.imports.src.effects.BrokenGlass.BrokenGlass(), + new Me.imports.src.effects.Doom.Doom(), + new Me.imports.src.effects.EnergizeA.EnergizeA(), + new Me.imports.src.effects.EnergizeB.EnergizeB(), + new Me.imports.src.effects.Fire.Fire(), + new Me.imports.src.effects.Glide.Glide(), + new Me.imports.src.effects.Glitch.Glitch(), + new Me.imports.src.effects.Hexagon.Hexagon(), + new Me.imports.src.effects.Incinerate.Incinerate(), + new Me.imports.src.effects.Matrix.Matrix(), + new Me.imports.src.effects.Pixelate.Pixelate(), + new Me.imports.src.effects.PixelWheel.PixelWheel(), + new Me.imports.src.effects.PixelWipe.PixelWipe(), + new Me.imports.src.effects.Portal.Portal(), + new Me.imports.src.effects.SnapOfDisintegration.SnapOfDisintegration(), + new Me.imports.src.effects.TRexAttack.TRexAttack(), + new Me.imports.src.effects.TVEffect.TVEffect(), + new Me.imports.src.effects.TVGlitch.TVGlitch(), + new Me.imports.src.effects.Wisps.Wisps(), ]; // Load all of our resources. @@ -137,6 +137,7 @@ var PreferencesDialog = class PreferencesDialog { } colorSchemeRow.set_visible(utils.shellVersionIsAtLeast(42, 0)); + // Wire up the window picker of the profile editor. this._builder.get_object('profile-choose-app-button').connect('clicked', () => { Gio.DBus.session.call('org.gnome.Shell', '/org/gnome/shell/extensions/BurnMyWindows', @@ -155,6 +156,17 @@ var PreferencesDialog = class PreferencesDialog { } }); + if (!utils.isADW()) { + const profileEditorButton = this._builder.get_object("edit-profile-button"); + profileEditorButton.connect("toggled", b => { + if (b.active) { + this._builder.get_object("general-prefs").set_visible_child(this._builder.get_object("profile-editor")); + } else { + this._builder.get_object("general-prefs").set_visible_child(this._builder.get_object("effect-editor")); + } + }); + } + // This is our top-level widget which we will return later. this._widget = this._builder.get_object('general-prefs'); @@ -165,6 +177,26 @@ var PreferencesDialog = class PreferencesDialog { // accordion-like behavior of the effect settings. this._effectRows = []; + if (!utils.isADW()) { + group.connect("row-activated", (g, row) => { + this._effectRows.forEach(r => { + if (r == row) { + if (r._revealer.get_reveal_child()) { + r._revealer.set_reveal_child(false); + r._arrow.remove_css_class("revealed"); + } else { + r._revealer.set_reveal_child(true); + r._arrow.add_css_class("revealed"); + } + } else { + r._revealer.set_reveal_child(false); + r._arrow.remove_css_class("revealed"); + } + } + ); + }); + } + // Now add all the rows. this._ALL_EFFECTS.forEach(effect => { const [minMajor, minMinor] = effect.getMinShellVersion(); @@ -173,38 +205,9 @@ var PreferencesDialog = class PreferencesDialog { const uiFile = `/ui/${utils.getUIDir()}/${effect.getNick()}.ui`; const [hasPrefs] = Gio.resources_get_info(uiFile, 0); - let row; + // Add the settings page to the builder. if (hasPrefs) { - // Add the settings page to the builder. this._builder.add_from_resource(uiFile); - - // Add the effect's preferences (if any). - row = this._builder.get_object(`${effect.getNick()}-prefs`); - } else { - row = Adw.ActionRow.new(); - } - - // On older versions of Adw (e.g. on GNOME Shell <43), the set_use_markup() does - // not yet exist. - if (row.set_use_markup) { - row.set_title('' + effect.getLabel() + ''); - row.set_use_markup(true); - } else { - row.set_title(effect.getLabel()); - } - - // Un-expand any previously expanded effect row. This way we ensure that there - // is only one expanded row at any time. - if (hasPrefs) { - row.connect('notify::expanded', currentRow => { - if (currentRow.get_expanded()) { - this._effectRows.forEach(row => { - if (row != currentRow && row.set_expanded) { - row.set_expanded(false); - } - }); - } - }); } // The preview button. @@ -213,22 +216,89 @@ var PreferencesDialog = class PreferencesDialog { previewButton.add_css_class('flat'); previewButton.set_tooltip_text(_('Preview this effect')); previewButton.set_valign(Gtk.Align.CENTER); - row.add_action(previewButton); - previewButton.connect('clicked', () => { this._previewEffect(effect); }); - - // Now add the toggle button for enabling and disabling the effect. + + // The toggle button for enabling and disabling the effect. const button = Gtk.Switch.new(); button.set_tooltip_text(_('Use this effect')); button.set_valign(Gtk.Align.CENTER); this._builder.expose_object(`${effect.getNick()}-enable-effect`, button); + + if (utils.isADW()) { - row.add_prefix(button); - group.add(row); + let row; + if (hasPrefs) { + + // Add the effect's preferences (if any). + row = this._builder.get_object(`${effect.getNick()}-prefs`); + } else if(utils.isADW()) { + row = Adw.ActionRow.new(); + } + + // On older versions of Adw (e.g. on GNOME Shell <43), the set_use_markup() does + // not yet exist. + if (row.set_use_markup) { + row.set_title('' + effect.getLabel() + ''); + row.set_use_markup(true); + } else { + row.set_title(effect.getLabel()); + } + + // Un-expand any previously expanded effect row. This way we ensure that there + // is only one expanded row at any time. + if (hasPrefs) { + row.connect('notify::expanded', currentRow => { + if (currentRow.get_expanded()) { + this._effectRows.forEach(row => { + if (row != currentRow) { + row.set_expanded(false); + } + }); + } + }); + this._effectRows.push(row); + } + + row.add_action(previewButton); + row.add_prefix(button); + + group.add(row); + + + } else { + + const row = new Gtk.ListBoxRow({css_classes:["effect-row"]}); + const container = new Gtk.Box({orientation:Gtk.Orientation.VERTICAL}); + const header = new Gtk.Box({css_classes:["effect-row-header"], spacing:12}); + const label = new Gtk.Label({label:effect.getLabel(), css_classes:["heading"], hexpand:true, halign: Gtk.Align.START}); + + this.gtkBoxAppend(header, button); + this.gtkBoxAppend(header, label); + this.gtkBoxAppend(header, previewButton); + this.gtkBoxAppend(container, header); + + if (hasPrefs) { + const revealer = this._builder.get_object(`${effect.getNick()}-prefs`); + const arrow = new Gtk.Image({css_classes:["revealer-arrow"], icon_name:"go-down-symbolic"}); + this.gtkBoxAppend(header, arrow); + this.gtkBoxAppend(container, revealer); + row._revealer = revealer; + row._arrow = arrow; + + row.set_activatable(true); + this._effectRows.push(row); + } else { + row.set_activatable(false); + } + + row.set_child(container); + + group.append(row); + + } - this._effectRows.push(row); } }); diff --git a/resources/css/gtk.css b/resources/css/gtk.css index 198fbef..64285d3 100644 --- a/resources/css/gtk.css +++ b/resources/css/gtk.css @@ -5,4 +5,26 @@ SPDX-License-Identifier: CC0-1.0 .pill-button { border-radius: 9999px; +} + +/* These are only used if not using libadwaita */ + +.effect-row { + padding: 0; +} + +.effect-row-header, +.effect-row list { + padding: 8px; + border: 0 solid @borders; + border-bottom-width: 1px; +} + +.revealer-arrow { + margin-right: 6px; + transition: transform 250ms; +} + +.revealer-arrow.revealed { + transform: rotate(180deg); } \ No newline at end of file diff --git a/resources/ui/gtk4/apparition.ui b/resources/ui/gtk4/apparition.ui index dccb962..87da821 100644 --- a/resources/ui/gtk4/apparition.ui +++ b/resources/ui/gtk4/apparition.ui @@ -7,255 +7,243 @@ SPDX-License-Identifier: GPL-3.0-or-later - - vertical - + - + + none + - - none - 1 - - + + 0 - - 0 + - - - - Animation Time [ms] - 0 - start - center - 1 + + Animation Time [ms] + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + + + 2000 + 100 + 10 + 100 - - - - end - center - 1 - 0 - left - 300 - - - 2000 - 100 - 10 - 100 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - + + + + + + edit-clear-symbolic + Reset to Default Value + - - - - 0 - - - - - Randomness - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - - - 1 - 0 - 0.01 - 0.1 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - Twirl Intensity - 0 - start - center - 1 - - - - - end - center - 1 - 1 - left - 300 - - - 10 - -10 - 0.1 - 1 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - Shake Intensity - 0 - start - center - 1 - - - - - end - center - 1 - 1 - left - 300 - - - 10 - 0 - 0.1 - 1 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - Suction Intensity - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - - - 1 - 0 - 0.01 - 0.1 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - + + + + 0 + + + + + Randomness + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + + + 1 + 0 + 0.01 + 0.1 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Twirl Intensity + 0 + start + center + 1 + + + + + end + center + 1 + 1 + left + 300 + + + 10 + -10 + 0.1 + 1 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Shake Intensity + 0 + start + center + 1 + + + + + end + center + 1 + 1 + left + 300 + + + 10 + 0 + 0.1 + 1 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Suction Intensity + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + + + 1 + 0 + 0.01 + 0.1 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + - - \ No newline at end of file diff --git a/resources/ui/gtk4/broken-glass.ui b/resources/ui/gtk4/broken-glass.ui index a17c8af..ab57fa4 100644 --- a/resources/ui/gtk4/broken-glass.ui +++ b/resources/ui/gtk4/broken-glass.ui @@ -7,263 +7,253 @@ SPDX-License-Identifier: GPL-3.0-or-later - - vertical - + - + + none + - - none - 1 - - + + 0 - - 0 + - - - - Animation Time [ms] - 0 - start - center - 1 + + Animation Time [ms] + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + + + 10000 + 100 + 1 + 100 - - - - end - center - 1 - 0 - left - 300 - - - 10000 - 100 - 1 - 100 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - + + + + + + edit-clear-symbolic + Reset to Default Value + - - - - 0 - - - - - Scale - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - - - 5 - 0.2 - 0.01 - 0.1 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - Gravity - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - - - 2.0 - -2.0 - 0.01 - 0.1 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - Blow Force - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - - - 2.0 - -2.0 - 0.01 - 0.1 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - vertical - 3 - - - Shatter From Pointer Location - 0 - start - center - 1 - - - - - The shards will fly away from where your mouse pointer was when closing the window. - 0 - start - center - 1 - 1 - - - - - - - - end - center - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - + + + + 0 + + + + + Scale + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + + + 5 + 0.2 + 0.01 + 0.1 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Gravity + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + + + 2.0 + -2.0 + 0.01 + 0.1 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Blow Force + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + + + 2.0 + -2.0 + 0.01 + 0.1 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + vertical + 3 + + + Shatter From Pointer Location + 0 + start + center + 1 + + + + + The shards will fly away from where your mouse pointer was when closing the window. + 0 + start + center + 1 + 1 + + + + + + + + end + center + 8 + 8 + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + - - \ No newline at end of file diff --git a/resources/ui/gtk4/doom.ui b/resources/ui/gtk4/doom.ui index 13401c5..eca1717 100644 --- a/resources/ui/gtk4/doom.ui +++ b/resources/ui/gtk4/doom.ui @@ -7,209 +7,197 @@ SPDX-License-Identifier: GPL-3.0-or-later - - vertical - + - + + none + - - none - 1 - - + + 0 - - 0 + - - - - Animation Time [ms] - 0 - start - center - 1 + + Animation Time [ms] + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + + + 10000 + 100 + 1 + 100 - - - - end - center - 1 - 0 - left - 300 - - - 10000 - 100 - 1 - 100 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - + + + + + + edit-clear-symbolic + Reset to Default Value + - - - - 0 - - - - - Horizontal Scale - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - - - 50 - 1 - 1 - 10 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - Vertical Scale - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - - - 50 - 1 - 1 - 10 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - Pixel Size - 0 - start - center - 1 - - - - - end - center - 1 - 0 - left - 300 - - - 50 - 1 - 1 - 10 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - + + + + 0 + + + + + Horizontal Scale + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + + + 50 + 1 + 1 + 10 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Vertical Scale + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + + + 50 + 1 + 1 + 10 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Pixel Size + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + + + 50 + 1 + 1 + 10 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + - - \ No newline at end of file diff --git a/resources/ui/gtk4/energize-a.ui b/resources/ui/gtk4/energize-a.ui index 166f493..19e1ee6 100644 --- a/resources/ui/gtk4/energize-a.ui +++ b/resources/ui/gtk4/energize-a.ui @@ -7,151 +7,144 @@ SPDX-License-Identifier: GPL-3.0-or-later - - vertical + - + + none + - - none - 1 - - + + 0 - - 0 + - - - - Animation Time [ms] - 0 - start - center - 1 + + Animation Time [ms] + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + + + 10000 + 100 + 1 + 100 - - - - end - center - 1 - 0 - left - 300 - - - 10000 - 100 - 1 - 100 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - + + + + + + edit-clear-symbolic + Reset to Default Value + - - - - 0 - - - - - Scale - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - - - 10 - 0.1 - 0.01 - 0.1 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - Color - 0 - start - center - 1 - - - - - 0 - 1 - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - + + + + 0 + + + + + Scale + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + + + 10 + 0.1 + 0.01 + 0.1 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Color + 0 + start + center + 1 + + + + + 0 + 1 + 8 + 8 + 250 + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + - \ No newline at end of file diff --git a/resources/ui/gtk4/energize-b.ui b/resources/ui/gtk4/energize-b.ui index 1e6e296..ae77456 100644 --- a/resources/ui/gtk4/energize-b.ui +++ b/resources/ui/gtk4/energize-b.ui @@ -7,151 +7,144 @@ SPDX-License-Identifier: GPL-3.0-or-later - - vertical + - + + none + - - none - 1 - - + + 0 - - 0 + - - - - Animation Time [ms] - 0 - start - center - 1 + + Animation Time [ms] + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + + + 10000 + 100 + 1 + 100 - - - - end - center - 1 - 0 - left - 300 - - - 10000 - 100 - 1 - 100 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - + + + + + + edit-clear-symbolic + Reset to Default Value + - - - - 0 - - - - - Scale - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - - - 10 - 0.1 - 0.01 - 0.1 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - Color - 0 - start - center - 1 - - - - - 0 - 1 - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - + + + + 0 + + + + + Scale + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + + + 10 + 0.1 + 0.01 + 0.1 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Color + 0 + start + center + 1 + + + + + 0 + 1 + 8 + 8 + 250 + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + - \ No newline at end of file diff --git a/resources/ui/gtk4/fire.ui b/resources/ui/gtk4/fire.ui index 724c882..2f1564c 100644 --- a/resources/ui/gtk4/fire.ui +++ b/resources/ui/gtk4/fire.ui @@ -7,295 +7,287 @@ SPDX-License-Identifier: GPL-3.0-or-later - - vertical - + - - 20 + + none + - - none - 1 - - + + 0 - - 0 + - - - - Presets - 0 - start - center - 1 - - - - - Choose a Preset - - + + Presets + 0 + start + center + 1 + + + + + Choose a Preset - - - - 0 - - - - - Animation Time [ms] - 0 - start - center - 1 - - - - - end - center - 1 - 0 - left - 300 - - - 10000 - 100 - 1 - 100 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - Scale - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - - - 3 - 0.1 - 0.01 - 0.1 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - Speed - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - - - 2.0 - -2.0 - 0.01 - 0.1 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - vertical - 3 - - - 3D Noise - 0 - start - center - 1 - - - - - Creates a more dynamic fire but requires more GPU power. - 0 - start - center - 1 - - - - - - - - end - center - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - Gradient - 0 - start - center - 1 - - - - - 1 - 1 - - - - - 1 - 1 - - - - - 1 - 1 - - - - - 1 - 1 - - - - - 1 - 1 - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - + + + + 0 + + + + + Animation Time [ms] + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + + + 10000 + 100 + 1 + 100 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Scale + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + + + 3 + 0.1 + 0.01 + 0.1 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Speed + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + + + 2.0 + -2.0 + 0.01 + 0.1 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + vertical + 3 + + + 3D Noise + 0 + start + center + 1 + + + + + Creates a more dynamic fire but requires more GPU power. + 0 + start + center + 1 + + + + + + + + end + center + 8 + 8 + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Gradient + 0 + start + center + 1 + + + + + 1 + 1 + + + + + 1 + 1 + + + + + 1 + 1 + + + + + 1 + 1 + + + + + 1 + 1 + 8 + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + diff --git a/resources/ui/gtk4/glide.ui b/resources/ui/gtk4/glide.ui index e52edb0..24d998e 100644 --- a/resources/ui/gtk4/glide.ui +++ b/resources/ui/gtk4/glide.ui @@ -7,251 +7,242 @@ SPDX-License-Identifier: GPL-3.0-or-later - - vertical + - + + none + - - none - 1 - - + + 0 - - 0 + - - - - Animation Time [ms] - 0 - start - center - 1 + + Animation Time [ms] + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + + + 2000 + 100 + 1 + 100 - - - - end - center - 1 - 0 - left - 300 - - - 2000 - 100 - 1 - 100 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - + + + + + + edit-clear-symbolic + Reset to Default Value + - - - - 0 - - - - - Scale - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - - - 1 - 0.1 - 0.01 - 0.1 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - Squish - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - - - 1 - 0 - 0.01 - 0.1 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - Tilt - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - - - 1 - -1 - 0.01 - 0.1 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - Shift - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - - - 1 - -1 - 0.01 - 0.1 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - + + + + 0 + + + + + Scale + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + + + 1 + 0.1 + 0.01 + 0.1 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Squish + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + + + 1 + 0 + 0.01 + 0.1 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Tilt + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + + + 1 + -1 + 0.01 + 0.1 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Shift + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + + + 1 + -1 + 0.01 + 0.1 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + diff --git a/resources/ui/gtk4/glitch.ui b/resources/ui/gtk4/glitch.ui index ae0553e..7701849 100644 --- a/resources/ui/gtk4/glitch.ui +++ b/resources/ui/gtk4/glitch.ui @@ -7,243 +7,236 @@ SPDX-License-Identifier: GPL-3.0-or-later - - vertical + - + + none + - - none - 1 - - + + 0 - - 0 + - - - - Animation Time [ms] - 0 - start - center - 1 + + Animation Time [ms] + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + + + 2000 + 100 + 1 + 100 - - - - end - center - 1 - 0 - left - 300 - - - 2000 - 100 - 1 - 100 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - + + + + + + edit-clear-symbolic + Reset to Default Value + - - - - 0 - - - - - Scale - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - - - 10 - 0.1 - 0.01 - 0.1 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - Strength - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - - - 10 - 0.1 - 0.01 - 0.1 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - Speed - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - - - 10 - 0.1 - 0.01 - 0.1 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - Color - 0 - start - center - 1 - - - - - 1 - 1 - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - + + + + 0 + + + + + Scale + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + + + 10 + 0.1 + 0.01 + 0.1 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Strength + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + + + 10 + 0.1 + 0.01 + 0.1 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Speed + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + + + 10 + 0.1 + 0.01 + 0.1 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Color + 0 + start + center + 1 + + + + + 1 + 1 + 8 + 8 + 250 + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + - \ No newline at end of file diff --git a/resources/ui/gtk4/hexagon.ui b/resources/ui/gtk4/hexagon.ui index f0507bc..8469298 100644 --- a/resources/ui/gtk4/hexagon.ui +++ b/resources/ui/gtk4/hexagon.ui @@ -7,284 +7,282 @@ SPDX-License-Identifier: GPL-3.0-or-later - - vertical + - + + none + - - none - 1 - - + + 0 - - 0 + - - - - Animation Time [ms] - 0 - start - center - 1 + + Animation Time [ms] + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + + + 10000 + 100 + 1 + 100 - - - - end - center - 1 - 0 - left - 300 - - - 10000 - 100 - 1 - 100 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - + + + + + + edit-clear-symbolic + Reset to Default Value + - - - - 0 - - - - - Scale - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - - - 10 - 0.1 - 0.01 - 0.1 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - Mesh Line Width - 0 - start - center - 1 - - - - - end - center - 1 - 1 - left - 300 - - - 10 - 0 - 0.1 - 1 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - Line Color - 0 - start - center - 1 - - - - - 1 - 1 - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - Glow Color - 0 - start - center - 1 - - - - - 1 - 1 - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - vertical - 3 - - - Additive Blending - 0 - start - center - 1 - - - - - You may want to enable this for dark window themes. - 0 - start - center - 1 - - - - - - - - end - center - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - + + + + 0 + + + + + Scale + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + + + 10 + 0.1 + 0.01 + 0.1 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Mesh Line Width + 0 + start + center + 1 + + + + + end + center + 1 + 1 + left + 300 + + + 10 + 0 + 0.1 + 1 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Line Color + 0 + start + center + 1 + + + + + 1 + 1 + 8 + 8 + 250 + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Glow Color + 0 + start + center + 1 + + + + + 1 + 1 + 8 + 8 + 250 + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + vertical + 3 + + + Additive Blending + 0 + start + center + 1 + + + + + You may want to enable this for dark window themes. + 0 + start + center + 1 + + + + + + + + end + center + 8 + 8 + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + - \ No newline at end of file diff --git a/resources/ui/gtk4/incinerate.ui b/resources/ui/gtk4/incinerate.ui index 4d847cb..88a6136 100644 --- a/resources/ui/gtk4/incinerate.ui +++ b/resources/ui/gtk4/incinerate.ui @@ -7,250 +7,245 @@ SPDX-License-Identifier: GPL-3.0-or-later - - vertical + - + + none + - - none - 1 - - + + 0 - - 0 + - - - - Animation Time [ms] - 0 - start - center - 1 + + Animation Time [ms] + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + + + 10000 + 100 + 1 + 100 - - - - end - center - 1 - 0 - left - 300 - - - 10000 - 100 - 1 - 100 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - + + + + + + edit-clear-symbolic + Reset to Default Value + - - - - 0 - - - - - Scale - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - - - 10 - 0.1 - 0.01 - 0.1 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - Turbulence - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - - - 1 - 0 - 0.01 - 0.1 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - vertical - 3 - - - Start at Pointer - 0 - start - center - 1 - - - - - If disabled, a random location will be chosen. - 0 - start - center - 1 - - - - - - - - end - center - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - Color - 0 - start - center - 1 - - - - - 0 - 1 - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - + + + + 0 + + + + + Scale + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + + + 10 + 0.1 + 0.01 + 0.1 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Turbulence + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + + + 1 + 0 + 0.01 + 0.1 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + vertical + 3 + + + Start at Pointer + 0 + start + center + 1 + + + + + If disabled, a random location will be chosen. + 0 + start + center + 1 + + + + + + + + end + center + 8 + 8 + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Color + 0 + start + center + 1 + + + + + 0 + 1 + 8 + 8 + 250 + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + - \ No newline at end of file diff --git a/resources/ui/gtk4/matrix.ui b/resources/ui/gtk4/matrix.ui index 22bbc78..f441d5e 100644 --- a/resources/ui/gtk4/matrix.ui +++ b/resources/ui/gtk4/matrix.ui @@ -7,274 +7,271 @@ SPDX-License-Identifier: GPL-3.0-or-later - - vertical + - + + none + - - none - 1 - - + + 0 - - 0 + - - - - Animation Time [ms] - 0 - start - center - 1 + + Animation Time [ms] + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + + + 10000 + 100 + 1 + 100 - - - - end - center - 1 - 0 - left - 300 - - - 10000 - 100 - 1 - 100 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - + + + + + + edit-clear-symbolic + Reset to Default Value + - - - - 0 - - - - - Scale - 0 - start - center - 1 - - - - - end - center - 1 - 0 - left - 300 - - - 50 - 5 - 1 - 5 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - Randomness - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - - - 1.0 - 0.0 - 0.01 - 0.1 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - Vertical Overshooting - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - - - 1.0 - 0.0 - 0.01 - 0.1 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - Trail Color - 0 - start - center - 1 - - - - - 0 - 1 - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - Tip Color - 0 - start - center - 1 - - - - - 0 - 1 - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - + + + + 0 + + + + + Scale + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + + + 50 + 5 + 1 + 5 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Randomness + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + + + 1.0 + 0.0 + 0.01 + 0.1 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Vertical Overshooting + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + + + 1.0 + 0.0 + 0.01 + 0.1 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Trail Color + 0 + start + center + 1 + + + + + 0 + 1 + 8 + 8 + 250 + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Tip Color + 0 + start + center + 1 + + + + + 0 + 1 + 8 + 8 + 250 + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + diff --git a/resources/ui/gtk4/pixel-wheel.ui b/resources/ui/gtk4/pixel-wheel.ui index 32b9a77..4dcdd4a 100644 --- a/resources/ui/gtk4/pixel-wheel.ui +++ b/resources/ui/gtk4/pixel-wheel.ui @@ -7,163 +7,153 @@ SPDX-License-Identifier: GPL-3.0-or-later - - vertical + - + + none + - - none - 1 - - + + 0 - - 0 + - - - - Animation Time [ms] - 0 - start - center - 1 + + Animation Time [ms] + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + + + 2000 + 100 + 1 + 100 - - - - end - center - 1 - 0 - left - 300 - - - 2000 - 100 - 1 - 100 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - + + + + + + edit-clear-symbolic + Reset to Default Value + - - - - 0 - - - - - Spoke Count - 0 - start - center - 1 - - - - - end - center - 1 - 0 - left - 300 - - - 50 - 1 - 1 - 10 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - Pixel Size - 0 - start - center - 1 - - - - - end - center - 1 - 0 - left - 300 - - - 50 - 1 - 1 - 10 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - + + + + 0 + + + + + Spoke Count + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + + + 50 + 1 + 1 + 10 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Pixel Size + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + + + 50 + 1 + 1 + 10 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + - \ No newline at end of file diff --git a/resources/ui/gtk4/pixel-wipe.ui b/resources/ui/gtk4/pixel-wipe.ui index 10e01aa..67549cc 100644 --- a/resources/ui/gtk4/pixel-wipe.ui +++ b/resources/ui/gtk4/pixel-wipe.ui @@ -7,117 +7,107 @@ SPDX-License-Identifier: GPL-3.0-or-later - - vertical + - + + none + - - none - 1 - - + + 0 - - 0 + - - - - Animation Time [ms] - 0 - start - center - 1 + + Animation Time [ms] + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + + + 5000 + 100 + 1 + 100 - - - - end - center - 1 - 0 - left - 300 - - - 5000 - 100 - 1 - 100 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - + + + + + + edit-clear-symbolic + Reset to Default Value + - - - - 0 - - - - - Pixel Size - 0 - start - center - 1 - - - - - end - center - 1 - 0 - left - 300 - - - 50 - 1 - 1 - 10 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - + + + + 0 + + + + + Pixel Size + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + + + 50 + 1 + 1 + 10 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + - \ No newline at end of file diff --git a/resources/ui/gtk4/pixelate.ui b/resources/ui/gtk4/pixelate.ui index 53d070a..6dc5d58 100644 --- a/resources/ui/gtk4/pixelate.ui +++ b/resources/ui/gtk4/pixelate.ui @@ -7,163 +7,153 @@ SPDX-License-Identifier: GPL-3.0-or-later - - vertical + - + + none + - - none - 1 - - + + 0 - - 0 + - - - - Animation Time [ms] - 0 - start - center - 1 + + Animation Time [ms] + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + + + 10000 + 100 + 1 + 100 - - - - end - center - 1 - 0 - left - 300 - - - 10000 - 100 - 1 - 100 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - + + + + + + edit-clear-symbolic + Reset to Default Value + - - - - 0 - - - - - Noise - 0 - start - center - 1 - - - - - end - center - 1 - 0 - left - 300 - - - 100 - 1 - 1 - 10 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - Pixel Size - 0 - start - center - 1 - - - - - end - center - 1 - 0 - left - 300 - - - 50 - 1 - 1 - 10 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - + + + + 0 + + + + + Noise + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + + + 100 + 1 + 1 + 10 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Pixel Size + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + + + 50 + 1 + 1 + 10 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + - \ No newline at end of file diff --git a/resources/ui/gtk4/portal.ui b/resources/ui/gtk4/portal.ui index 66c2c6a..f339557 100644 --- a/resources/ui/gtk4/portal.ui +++ b/resources/ui/gtk4/portal.ui @@ -7,243 +7,236 @@ SPDX-License-Identifier: GPL-3.0-or-later - - vertical + - + + none + - - none - 1 - - + + 0 - - 0 + - - - - Animation Time [ms] - 0 - start - center - 1 + + Animation Time [ms] + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + + + 5000 + 500 + 1 + 100 - - - - end - center - 1 - 0 - left - 300 - - - 5000 - 500 - 1 - 100 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - + + + + + + edit-clear-symbolic + Reset to Default Value + - - - - 0 - - - - - Whirling - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - - - 2 - -2 - 0.1 - 1 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - Rotation Speed - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - - - 2 - -2 - 0.1 - 1 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - Details - 0 - start - center - 1 - - - - - end - center - 1 - 1 - left - 300 - - - 100 - 1 - 1 - 10 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - Color - 0 - start - center - 1 - - - - - 0 - 1 - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - + + + + 0 + + + + + Whirling + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + + + 2 + -2 + 0.1 + 1 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Rotation Speed + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + + + 2 + -2 + 0.1 + 1 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Details + 0 + start + center + 1 + + + + + end + center + 1 + 1 + left + 300 + + + 100 + 1 + 1 + 10 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Color + 0 + start + center + 1 + + + + + 0 + 1 + 8 + 8 + 250 + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + - \ No newline at end of file diff --git a/resources/ui/gtk4/prefs.ui b/resources/ui/gtk4/prefs.ui index 6836ff0..b4bf182 100644 --- a/resources/ui/gtk4/prefs.ui +++ b/resources/ui/gtk4/prefs.ui @@ -26,10 +26,6 @@ SPDX-License-Identifier: GPL-3.0-or-later bmw-edit-profile-symbolic center - - - profile-editor-revealer - - - vertical + + over-down-up - - - - edit-profile-button - - + + never + vertical 20 @@ -58,7 +51,7 @@ SPDX-License-Identifier: GPL-3.0-or-later - Effect Profile Constraints + Effect Settings start - - - - 0 - - - - - Application Name - 0 - start - center - 1 - - - - - - center - - - - - 200 - - - - - - bmw-select-app-symbolic - center - - - - - - - - - - - - 0 - - - - - Animation Type - 0 - start - center - 1 - - - - - 200 - - Any - Opening Windows - Closing Windows - - - - - - - - - - - 0 - - - - - Window Type - 0 - start - center - 1 - - - - - 200 - - Any - Normal Windows - Dialog Windows - - - - - - - - - - - 0 - - - - - Color Scheme - 0 - start - center - 1 - - - - - 200 - - Any - Default Color Scheme - Dark Color Scheme - - - - - - - - - - - 0 - - - - - Power Mode - 0 - start - center - 1 - - - - - 200 - - Any - On Battery - Plugged In - - - - - - - - - - - 0 - - - - - Power Profile - 0 - start - center - 1 - - - - - 200 - - Any - Power-Saver Mode - Balanced Mode - Performance Mode - Power Saver or Balanced - Balanced or Performance - - - - - - - - - - - Advanced Profile Options - start - - - - - - - 5 - 15 - - - none - 1 - - - - - 0 - - - - - vertical - 3 - - - High Priority - 0 - start - center - 1 - - - - - Force using this profile even if it has less constraints than another matching profile. - 0 - start - center - 1 - end - - - - - - - - center - - - - - - - - - - - - - - - prefs.profile-delete - Delete this Profile... - start - - - + - - Effect Settings - 0 - start - center - 1 - - - - - If multiple are selected, one is chosen randomly. - 0 - start - center - 1 + + vertical + 20 + 20 + 20 + 20 + 5 - - - - - - none - 1 + + Effect Profile Constraints + start - + + + + Define when the current effect settings should be used. + start + + + + + + 5 + 15 + + + none + 1 + + + + + 0 + + + + + Application Name + 0 + start + center + 1 + + + + + + center + + + + + 200 + + + + + + bmw-select-app-symbolic + center + + + + + + + + + + + + 0 + + + + + Animation Type + 0 + start + center + 1 + + + + + 200 + + Any + Opening Windows + Closing Windows + + + + + + + + + + + 0 + + + + + Window Type + 0 + start + center + 1 + + + + + 200 + + Any + Normal Windows + Dialog Windows + + + + + + + + + + + 0 + + + + + Color Scheme + 0 + start + center + 1 + + + + + 200 + + Any + Default Color Scheme + Dark Color Scheme + + + + + + + + + + + 0 + + + + + Power Mode + 0 + start + center + 1 + + + + + 200 + + Any + On Battery + Plugged In + + + + + + + + + + + 0 + + + + + Power Profile + 0 + start + center + 1 + + + + + 200 + + Any + Power-Saver Mode + Balanced Mode + Performance Mode + Power Saver or Balanced + Balanced or Performance + + + + + + + + + + + + + + + + Advanced Profile Options + start + + + + + + + 5 + 15 + + + none + 1 + + + + + 0 + + + + + vertical + 3 + + + High Priority + 0 + start + center + 1 + + + + + Force using this profile even if it has less constraints than another matching profile. + 0 + start + center + 1 + end + + + + + + + + center + + + + + + + + + + + + + + + prefs.profile-delete + Delete this Profile... + start + + + + \ No newline at end of file diff --git a/resources/ui/gtk4/snap.ui b/resources/ui/gtk4/snap.ui index 7d5e79f..707b0a9 100644 --- a/resources/ui/gtk4/snap.ui +++ b/resources/ui/gtk4/snap.ui @@ -7,151 +7,144 @@ SPDX-License-Identifier: GPL-3.0-or-later - - vertical + - + + none + - - none - 1 - - + + 0 - - 0 + - - - - Animation Time [ms] - 0 - start - center - 1 + + Animation Time [ms] + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + + + 10000 + 500 + 10 + 100 - - - - end - center - 1 - 0 - left - 300 - - - 10000 - 500 - 10 - 100 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - + + + + + + edit-clear-symbolic + Reset to Default Value + - - - - 0 - - - - - Scale - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - - - 20 - 0.1 - 0.01 - 0.1 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - Color - 0 - start - center - 1 - - - - - 1 - 1 - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - + + + + 0 + + + + + Scale + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + + + 20 + 0.1 + 0.01 + 0.1 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Color + 0 + start + center + 1 + + + + + 1 + 1 + 8 + 8 + 250 + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + - \ No newline at end of file diff --git a/resources/ui/gtk4/trex.ui b/resources/ui/gtk4/trex.ui index 30cd0b5..86bd878 100644 --- a/resources/ui/gtk4/trex.ui +++ b/resources/ui/gtk4/trex.ui @@ -7,239 +7,233 @@ SPDX-License-Identifier: GPL-3.0-or-later - - vertical + - + + none + - - none - 1 - - + + 0 - - 0 + - - - - Animation Time [ms] - 0 - start - center - 1 + + Animation Time [ms] + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + + + 10000 + 100 + 1 + 100 - - - - end - center - 1 - 0 - left - 300 - - - 10000 - 100 - 1 - 100 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - + + + + + + edit-clear-symbolic + Reset to Default Value + - - - - 0 - - - - - Claw Scratch Scale - 0 - start - center - 1 - - - - - end - center - 1 - 1 - left - 300 - - - 10 - 0.1 - 0.1 - 1 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - Claw Scratch Count - 0 - start - center - 1 - - - - - end - center - 1 - 0 - left - 300 - - - 50 - 1 - 1 - 10 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - Warp Effect - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - - - 1 - 0 - 0.01 - 0.1 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - Flash Color - 0 - start - center - 1 - - - - - 1 - 1 - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - + + + + 0 + + + + + Claw Scratch Scale + 0 + start + center + 1 + + + + + end + center + 1 + 1 + left + 300 + + + 10 + 0.1 + 0.1 + 1 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Claw Scratch Count + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + + + 50 + 1 + 1 + 10 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Warp Effect + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + + + 1 + 0 + 0.01 + 0.1 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Flash Color + 0 + start + center + 1 + + + + + 1 + 1 + 8 + 8 + 250 + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + diff --git a/resources/ui/gtk4/tv-glitch.ui b/resources/ui/gtk4/tv-glitch.ui index dc12bf8..858bec1 100644 --- a/resources/ui/gtk4/tv-glitch.ui +++ b/resources/ui/gtk4/tv-glitch.ui @@ -7,243 +7,236 @@ SPDX-License-Identifier: GPL-3.0-or-later - - vertical + - + + none + - - none - 1 - - + + 0 - - 0 + - - - - Animation Time [ms] - 0 - start - center - 1 + + Animation Time [ms] + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + + + 2000 + 100 + 1 + 100 - - - - end - center - 1 - 0 - left - 300 - - - 2000 - 100 - 1 - 100 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - + + + + + + edit-clear-symbolic + Reset to Default Value + - - - - 0 - - - - - Scale - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - - - 10 - 0.1 - 0.01 - 0.1 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - Strength - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - - - 10 - 0.1 - 0.01 - 0.1 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - Speed - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - - - 10 - 0.1 - 0.01 - 0.1 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - Color - 0 - start - center - 1 - - - - - 1 - 1 - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - + + + + 0 + + + + + Scale + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + + + 10 + 0.1 + 0.01 + 0.1 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Strength + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + + + 10 + 0.1 + 0.01 + 0.1 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Speed + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + + + 10 + 0.1 + 0.01 + 0.1 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Color + 0 + start + center + 1 + + + + + 1 + 1 + 8 + 8 + 250 + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + - \ No newline at end of file diff --git a/resources/ui/gtk4/tv.ui b/resources/ui/gtk4/tv.ui index 6e0b7f3..f345a4a 100644 --- a/resources/ui/gtk4/tv.ui +++ b/resources/ui/gtk4/tv.ui @@ -7,105 +7,98 @@ SPDX-License-Identifier: GPL-3.0-or-later - - vertical + - + + none + - - none - 1 - - + + 0 - - 0 + - - - - Animation Time [ms] - 0 - start - center - 1 + + Animation Time [ms] + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + + + 10000 + 100 + 1 + 100 - - - - end - center - 1 - 0 - left - 300 - - - 10000 - 100 - 1 - 100 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - + + + + + + edit-clear-symbolic + Reset to Default Value + - - - - 0 - - - - - Color - 0 - start - center - 1 - - - - - 1 - 1 - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - + + + + 0 + + + + + Color + 0 + start + center + 1 + + + + + 1 + 1 + 8 + 8 + 250 + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + - \ No newline at end of file diff --git a/resources/ui/gtk4/wisps.ui b/resources/ui/gtk4/wisps.ui index 6acd526..e5d3a37 100644 --- a/resources/ui/gtk4/wisps.ui +++ b/resources/ui/gtk4/wisps.ui @@ -7,151 +7,144 @@ SPDX-License-Identifier: GPL-3.0-or-later - - vertical + - + + none + - - none - 1 - - + + 0 - - 0 + - - - - Animation Time [ms] - 0 - start - center - 1 + + Animation Time [ms] + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + + + 10000 + 100 + 1 + 100 - - - - end - center - 1 - 0 - left - 300 - - - 10000 - 100 - 1 - 100 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - + + + + + + edit-clear-symbolic + Reset to Default Value + - - - - 0 - - - - - Scale - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - - - 10 - 0.1 - 0.01 - 0.1 - - - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - - - - 0 - - - - - Color - 0 - start - center - 1 - - - - - 0 - 1 - - - - - edit-clear-symbolic - Reset to Default Value - - - - - - - - + + + + 0 + + + + + Scale + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + + + 10 + 0.1 + 0.01 + 0.1 + + + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + + + + 0 + + + + + Color + 0 + start + center + 1 + + + + + 0 + 1 + 8 + 8 + 250 + + + + + edit-clear-symbolic + Reset to Default Value + + + + + + + + - \ No newline at end of file From cc6a4d83318f97b4d5a360bafc72700fa84e5043 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Thu, 2 Feb 2023 10:40:16 +0100 Subject: [PATCH 35/67] :beetle: Fix pixel wipe effect --- src/effects/PixelWipe.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/effects/PixelWipe.js b/src/effects/PixelWipe.js index 79f5f4a..88fcdb9 100644 --- a/src/effects/PixelWipe.js +++ b/src/effects/PixelWipe.js @@ -44,16 +44,17 @@ var PixelWipe = class { shader._uStartPos = shader.get_uniform_location('uStartPos'); // Write all uniform values at the start of each animation. - shader.connect('begin-animation', (shader, settings, forOpening, actor) => { - // Because the actor position may change after the begin-animation signal is - // called, we set the uStartPos uniform during the update callback. - this._startPointerPos = global.get_pointer(); - this._actor = actor; + shader.connect( + 'begin-animation', (shader, settings, forOpening, testMode, actor) => { + // Because the actor position may change after the begin-animation signal is + // called, we set the uStartPos uniform during the update callback. + this._startPointerPos = global.get_pointer(); + this._actor = actor; - // clang-format off + // clang-format off shader.set_uniform_float(shader._uPixelSize, 1, [settings.get_int('pixel-wipe-pixel-size')]); - // clang-format on - }); + // clang-format on + }); // We set the uStartPos uniform during the update callback as the actor position // may not be set up properly before the begin animation callback. From 9539a9fa13886ef12cbfdbedbfe2cbb7b614efbd Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Sun, 5 Feb 2023 13:04:45 +0100 Subject: [PATCH 36/67] :wrench: Port effect profiles to GNOME Shell 3.38 --- docs/how-to-create-new-effects.md | 8 - prefs.js | 53 ++- resources/css/gtk3.css | 33 ++ resources/css/{gtk.css => gtk4.css} | 4 - resources/ui/gtk3/apparition.ui | 463 ++++++++++------------ resources/ui/gtk3/doom.ui | 369 ++++++++--------- resources/ui/gtk3/effectPage.ui | 59 --- resources/ui/gtk3/energize-a.ui | 266 ++++++------- resources/ui/gtk3/energize-b.ui | 265 ++++++------- resources/ui/gtk3/fire.ui | 539 ++++++++++++------------- resources/ui/gtk3/glide.ui | 463 ++++++++++------------ resources/ui/gtk3/glitch.ui | 454 ++++++++++----------- resources/ui/gtk3/hexagon.ui | 566 +++++++++++++------------- resources/ui/gtk3/incinerate.ui | 481 +++++++++++----------- resources/ui/gtk3/pixel-wheel.ui | 275 ++++++------- resources/ui/gtk3/pixel-wipe.ui | 181 ++++----- resources/ui/gtk3/pixelate.ui | 275 ++++++------- resources/ui/gtk3/portal.ui | 458 ++++++++++----------- resources/ui/gtk3/prefs.ui | 595 ++++++++++++++++++---------- resources/ui/gtk3/tv-glitch.ui | 454 ++++++++++----------- resources/ui/gtk3/tv.ui | 172 ++++---- resources/ui/gtk3/wisps.ui | 266 ++++++------- 22 files changed, 3234 insertions(+), 3465 deletions(-) create mode 100644 resources/css/gtk3.css rename resources/css/{gtk.css => gtk4.css} (90%) delete mode 100644 resources/ui/gtk3/effectPage.ui diff --git a/docs/how-to-create-new-effects.md b/docs/how-to-create-new-effects.md index c30da07..36314f4 100644 --- a/docs/how-to-create-new-effects.md +++ b/docs/how-to-create-new-effects.md @@ -311,10 +311,6 @@ SPDX-License-Identifier: GPL-3.0-or-later - 10 - 10 - 10 - 10 0 @@ -359,10 +355,6 @@ SPDX-License-Identifier: GPL-3.0-or-later - 10 - 10 - 10 - 10 0 diff --git a/prefs.js b/prefs.js index c4fa9d2..e9c15cf 100644 --- a/prefs.js +++ b/prefs.js @@ -73,11 +73,12 @@ var PreferencesDialog = class PreferencesDialog { // Load the CSS file for the settings dialog. const styleProvider = Gtk.CssProvider.new(); - styleProvider.load_from_resource('/css/gtk.css'); - if (utils.isGTK4()) { + if (utils.isGTK4() && !utils.isADW()) { + styleProvider.load_from_resource('/css/gtk4.css'); Gtk.StyleContext.add_provider_for_display(Gdk.Display.get_default(), styleProvider, - Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); + Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); } else { + styleProvider.load_from_resource('/css/gtk3.css'); Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(), styleProvider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); } @@ -183,14 +184,14 @@ var PreferencesDialog = class PreferencesDialog { if (r == row) { if (r._revealer.get_reveal_child()) { r._revealer.set_reveal_child(false); - r._arrow.remove_css_class("revealed"); + r._arrow.get_style_context().remove_class("revealed"); } else { r._revealer.set_reveal_child(true); - r._arrow.add_css_class("revealed"); + r._arrow.get_style_context().add_class("revealed"); } } else { r._revealer.set_reveal_child(false); - r._arrow.remove_css_class("revealed"); + r._arrow.get_style_context().remove_class("revealed"); } } ); @@ -211,9 +212,9 @@ var PreferencesDialog = class PreferencesDialog { } // The preview button. - const previewButton = Gtk.Button.new_from_icon_name('bmw-preview-symbolic'); - previewButton.add_css_class('circular'); - previewButton.add_css_class('flat'); + const previewButton = Gtk.Button.new_from_icon_name('bmw-preview-symbolic', 1); + previewButton.get_style_context().add_class('circular'); + previewButton.get_style_context().add_class('flat'); previewButton.set_tooltip_text(_('Preview this effect')); previewButton.set_valign(Gtk.Align.CENTER); previewButton.connect('clicked', () => { @@ -269,10 +270,16 @@ var PreferencesDialog = class PreferencesDialog { } else { - const row = new Gtk.ListBoxRow({css_classes:["effect-row"]}); + const row = new Gtk.ListBoxRow(); + row.get_style_context().add_class("effect-row"); + const container = new Gtk.Box({orientation:Gtk.Orientation.VERTICAL}); - const header = new Gtk.Box({css_classes:["effect-row-header"], spacing:12}); - const label = new Gtk.Label({label:effect.getLabel(), css_classes:["heading"], hexpand:true, halign: Gtk.Align.START}); + + const header = new Gtk.Box({ spacing:12}); + header.get_style_context().add_class("effect-row-header"); + + const label = new Gtk.Label({label:effect.getLabel(), hexpand:true, halign: Gtk.Align.START}); + label.get_style_context().add_class("heading"); this.gtkBoxAppend(header, button); this.gtkBoxAppend(header, label); @@ -281,7 +288,8 @@ var PreferencesDialog = class PreferencesDialog { if (hasPrefs) { const revealer = this._builder.get_object(`${effect.getNick()}-prefs`); - const arrow = new Gtk.Image({css_classes:["revealer-arrow"], icon_name:"go-down-symbolic"}); + const arrow = new Gtk.Image({icon_name:"go-down-symbolic"}); + arrow.get_style_context().add_class("revealer-arrow"); this.gtkBoxAppend(header, arrow); this.gtkBoxAppend(container, revealer); row._revealer = revealer; @@ -293,9 +301,14 @@ var PreferencesDialog = class PreferencesDialog { row.set_activatable(false); } - row.set_child(container); + if (utils.isGTK4()) { + row.set_child(container); + group.append(row); + } else { + row.add(container); + group.add(row); + } - group.append(row); } @@ -343,9 +356,12 @@ var PreferencesDialog = class PreferencesDialog { flap.set_content(scrolledWindow); - } else { + } else if (utils.isGTK4()) { window.get_titlebar().pack_start(menu); window.get_titlebar().set_title_widget(this._builder.get_object('profile-button')); + } else { + window.get_titlebar().pack_start(menu); + window.get_titlebar().set_custom_title(this._builder.get_object('profile-button')); } const addURIAction = (name, uri) => { @@ -508,7 +524,10 @@ var PreferencesDialog = class PreferencesDialog { }); } - deleteProfileDialog.set_hide_on_close(true); + if (utils.isGTK4()) { + deleteProfileDialog.set_hide_on_close(true); + } + deleteProfileDialog.set_transient_for(window); deleteProfileDialog.connect('response', (dialog, response) => { diff --git a/resources/css/gtk3.css b/resources/css/gtk3.css new file mode 100644 index 0000000..289e791 --- /dev/null +++ b/resources/css/gtk3.css @@ -0,0 +1,33 @@ +/* +SPDX-FileCopyrightText: Simon Schneegans +SPDX-License-Identifier: CC0-1.0 +*/ + +row { + padding: 8px; +} + +.effect-row { + padding: 0; +} + +.effect-row-header, +.effect-row list { + padding: 8px; + border: 0 solid @borders; + border-bottom-width: 1px; +} + +.revealer-arrow { + margin-right: 6px; +} + +/* .revealer-arrow.revealed {} */ + +/* row { + padding: 10px; +} + +.effect-row { + padding: 0px; +} */ \ No newline at end of file diff --git a/resources/css/gtk.css b/resources/css/gtk4.css similarity index 90% rename from resources/css/gtk.css rename to resources/css/gtk4.css index 64285d3..dece072 100644 --- a/resources/css/gtk.css +++ b/resources/css/gtk4.css @@ -3,10 +3,6 @@ SPDX-FileCopyrightText: Simon Schneegans SPDX-License-Identifier: CC0-1.0 */ -.pill-button { - border-radius: 9999px; -} - /* These are only used if not using libadwaita */ .effect-row { diff --git a/resources/ui/gtk3/apparition.ui b/resources/ui/gtk3/apparition.ui index 48124d3..d217042 100644 --- a/resources/ui/gtk3/apparition.ui +++ b/resources/ui/gtk3/apparition.ui @@ -42,269 +42,240 @@ SPDX-License-Identifier: GPL-3.0-or-later 0.1 - - vertical + - + + none + - - none - - + + 0 - - 10 - 10 - 10 - 10 - 0 + + 8 - - 8 + + Animation Time [ms] + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + apparition-animation-time + + + + - - Animation Time [ms] - 0 - start - center - 1 - - - - - end - center - 1 - 0 - left - 300 - apparition-animation-time - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - + + edit-clear-symbolic + 1 + Reset to Default Value + - - - - 10 - 10 - 10 - 10 - 0 - - - 8 - - - Randomness - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - apparition-randomness - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - - - - 10 - 10 - 10 - 10 - 0 - - - 8 - - - Twirl Intensity - 0 - start - center - 1 - - - - - end - center - 1 - 1 - left - 300 - apparition-twirl-intensity - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - - - - 10 - 10 - 10 - 10 - 0 - - - 8 - - - Shake Intensity - 0 - start - center - 1 - - - - - end - center - 1 - 1 - left - 300 - apparition-shake-intensity - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - - - - 10 - 10 - 10 - 10 - 0 - - - 8 - - - Suction Intensity - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - apparition-suction-intensity - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - + + + + 0 + + + 8 + + + Randomness + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + apparition-randomness + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + + + + 0 + + + 8 + + + Twirl Intensity + 0 + start + center + 1 + + + + + end + center + 1 + 1 + left + 300 + apparition-twirl-intensity + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + + + + 0 + + + 8 + + + Shake Intensity + 0 + start + center + 1 + + + + + end + center + 1 + 1 + left + 300 + apparition-shake-intensity + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + + + + 0 + + + 8 + + + Suction Intensity + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + apparition-suction-intensity + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + - \ No newline at end of file diff --git a/resources/ui/gtk3/doom.ui b/resources/ui/gtk3/doom.ui index 754aee0..2bf8fc3 100644 --- a/resources/ui/gtk3/doom.ui +++ b/resources/ui/gtk3/doom.ui @@ -35,220 +35,195 @@ SPDX-License-Identifier: GPL-3.0-or-later 10 - - vertical + - + + none + - - none - - + + 0 - - 10 - 10 - 10 - 10 - 0 + + 8 - - 8 + + Animation Time [ms] + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + doom-animation-time + + + + - - Animation Time [ms] - 0 - start - center - 1 - - - - - end - center - 1 - 0 - left - 300 - doom-animation-time - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - + + edit-clear-symbolic + 1 + Reset to Default Value + - - - - 10 - 10 - 10 - 10 - 0 - - - 8 - - - Horizontal Scale - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - doom-horizontal-scale - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - - - - 10 - 10 - 10 - 10 - 0 - - - 8 - - - Vertical Scale - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - doom-vertical-scale - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - - - - 10 - 10 - 10 - 10 - 0 - - - 8 - - - Pixel Size - 0 - start - center - 1 - - - - - end - center - 1 - 0 - left - 300 - doom-pixel-size - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - + + + + 0 + + + 8 + + + Horizontal Scale + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + doom-horizontal-scale + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + + + + 0 + + + 8 + + + Vertical Scale + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + doom-vertical-scale + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + + + + 0 + + + 8 + + + Pixel Size + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + doom-pixel-size + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + - \ No newline at end of file diff --git a/resources/ui/gtk3/effectPage.ui b/resources/ui/gtk3/effectPage.ui deleted file mode 100644 index 927a8d2..0000000 --- a/resources/ui/gtk3/effectPage.ui +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/resources/ui/gtk3/energize-a.ui b/resources/ui/gtk3/energize-a.ui index b1cd157..10ffe58 100644 --- a/resources/ui/gtk3/energize-a.ui +++ b/resources/ui/gtk3/energize-a.ui @@ -21,165 +21,147 @@ SPDX-License-Identifier: GPL-3.0-or-later 0.1 - - vertical + - + + none + - - none - - + + 0 - - 10 - 10 - 10 - 10 - 0 + + 8 - - 8 + + Animation Time [ms] + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + energize-a-animation-time + + + + - - Animation Time [ms] - 0 - start - center - 1 - - - - - end - center - 1 - 0 - left - 300 - energize-a-animation-time - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - + + edit-clear-symbolic + 1 + Reset to Default Value + - - - - 10 - 10 - 10 - 10 - 0 - - - 8 - - - Scale - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - energize-a-scale - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - - - - 10 - 10 - 10 - 10 - 0 - - - - - Color - 0 - start - center - 1 - - - - - 0 - 1 - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - + + + + 0 + + + 8 + + + Scale + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + energize-a-scale + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + + + + 0 + + + + + Color + 0 + start + center + 1 + + + + + 0 + 1 + 8 + 8 + 250 + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + - \ No newline at end of file diff --git a/resources/ui/gtk3/energize-b.ui b/resources/ui/gtk3/energize-b.ui index cfb6188..8e8709f 100644 --- a/resources/ui/gtk3/energize-b.ui +++ b/resources/ui/gtk3/energize-b.ui @@ -21,161 +21,144 @@ SPDX-License-Identifier: GPL-3.0-or-later 0.1 - - vertical + - + + none + - - none - - + + 0 - - 10 - 10 - 10 - 10 - 0 + + 8 - - 8 + + Animation Time [ms] + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + energize-b-animation-time + + + + - - Animation Time [ms] - 0 - start - center - 1 - - - - - end - center - 1 - 0 - left - 300 - energize-b-animation-time - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - + + edit-clear-symbolic + 1 + Reset to Default Value + - - - - 10 - 10 - 10 - 10 - 0 - - - 8 - - - Scale - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - energize-b-scale - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - - - - 10 - 10 - 10 - 10 - 0 - - - - - Color - 0 - start - center - 1 - - - - - 0 - 1 - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - + + + + 0 + + + 8 + + + Scale + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + energize-b-scale + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + + + + 0 + + + + + Color + 0 + start + center + 1 + + + + + 0 + 1 + 8 + 8 + 250 + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + diff --git a/resources/ui/gtk3/fire.ui b/resources/ui/gtk3/fire.ui index 4cecc10..a047ffe 100644 --- a/resources/ui/gtk3/fire.ui +++ b/resources/ui/gtk3/fire.ui @@ -28,282 +28,196 @@ SPDX-License-Identifier: GPL-3.0-or-later 0.1 - - vertical + - - 20 + + none + - - none - - + + 0 - - 10 - 10 - 10 - 10 - 0 + - - - - Presets - 0 - start - center - 1 - - - - - - - 8 - - - Choose a Preset - - - - - pan-down-symbolic - 1 - - - - - - + + Presets + 0 + start + center + 1 - - - - - - 10 - 10 - 10 - 10 - 0 - - 8 - - - Animation Time [ms] - 0 - start - center - 1 - - - - - end - center - 1 - 0 - left - 300 - fire-animation-time - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - - - - 10 - 10 - 10 - 10 - 0 - - - - - Scale - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - flame-scale - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - - - - 10 - 10 - 10 - 10 - 0 - - - - - Speed - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - flame-movement-speed - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - - - - 10 - 10 - 10 - 10 - 0 - - + - vertical - 3 + 8 - 3D Noise - 0 - start - center - 1 + Choose a Preset - - - Creates a more dynamic fire but requires more GPU power. - 0 - start - center - 1 - - - - - - - - end - center - - - - - edit-clear-symbolic + pan-down-symbolic 1 - Reset to Default Value - + + + + + 0 - - 10 - 10 - 10 - 10 - 0 + + 8 + + + Animation Time [ms] + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + fire-animation-time + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + + + + 0 + + + + + Scale + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + flame-scale + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + + + + 0 + + + + + Speed + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + flame-movement-speed + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + + + + 0 + + - 8 + vertical + 3 - Gradient + 3D Noise 0 start center @@ -311,58 +225,113 @@ SPDX-License-Identifier: GPL-3.0-or-later - - 1 - 1 - - - - - 1 - 1 - - - - - 1 - 1 - - - - - 1 - 1 - - - - - 1 - 1 - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value + + Creates a more dynamic fire but requires more GPU power. + 0 + start + center + 1 + + + end + center + 8 + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + - + + + + 0 + + + 8 + + + Gradient + 0 + start + center + 1 + + + + + 1 + 1 + + + + + 1 + 1 + + + + + 1 + 1 + + + + + 1 + 1 + + + + + 1 + 1 + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + + \ No newline at end of file diff --git a/resources/ui/gtk3/glide.ui b/resources/ui/gtk3/glide.ui index 7029422..57a259c 100644 --- a/resources/ui/gtk3/glide.ui +++ b/resources/ui/gtk3/glide.ui @@ -42,269 +42,240 @@ SPDX-License-Identifier: GPL-3.0-or-later 0.1 - - vertical + - + + none + - - none - - + + 0 - - 10 - 10 - 10 - 10 - 0 + + 8 - - 8 + + Animation Time [ms] + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + glide-animation-time + + + + - - Animation Time [ms] - 0 - start - center - 1 - - - - - end - center - 1 - 0 - left - 300 - glide-animation-time - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - + + edit-clear-symbolic + 1 + Reset to Default Value + - - - - 10 - 10 - 10 - 10 - 0 - - - 8 - - - Scale - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - glide-scale - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - - - - 10 - 10 - 10 - 10 - 0 - - - 8 - - - Squish - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - glide-squish - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - - - - 10 - 10 - 10 - 10 - 0 - - - 8 - - - Tilt - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - glide-tilt - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - - - - 10 - 10 - 10 - 10 - 0 - - - 8 - - - Shift - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - glide-shift - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - + + + + 0 + + + 8 + + + Scale + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + glide-scale + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + + + + 0 + + + 8 + + + Squish + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + glide-squish + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + + + + 0 + + + 8 + + + Tilt + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + glide-tilt + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + + + + 0 + + + 8 + + + Shift + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + glide-shift + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + - \ No newline at end of file diff --git a/resources/ui/gtk3/glitch.ui b/resources/ui/gtk3/glitch.ui index ab45f1b..a8c45c3 100644 --- a/resources/ui/gtk3/glitch.ui +++ b/resources/ui/gtk3/glitch.ui @@ -35,263 +35,237 @@ SPDX-License-Identifier: GPL-3.0-or-later 0.1 - - vertical + - + + none + - - none - - + + 0 - - 10 - 10 - 10 - 10 - 0 + + 8 - - 8 + + Animation Time [ms] + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + glitch-animation-time + + + + - - Animation Time [ms] - 0 - start - center - 1 - - - - - end - center - 1 - 0 - left - 300 - glitch-animation-time - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - + + edit-clear-symbolic + 1 + Reset to Default Value + - - - - 10 - 10 - 10 - 10 - 0 - - - 8 - - - Scale - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - glitch-scale - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - - - - 10 - 10 - 10 - 10 - 0 - - - 8 - - - Strength - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - glitch-strength - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - - - - 10 - 10 - 10 - 10 - 0 - - - 8 - - - Speed - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - glitch-speed - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - - - - 10 - 10 - 10 - 10 - 0 - - - - - Color - 0 - start - center - 1 - - - - - 1 - 1 - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - + + + + 0 + + + 8 + + + Scale + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + glitch-scale + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + + + + 0 + + + 8 + + + Strength + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + glitch-strength + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + + + + 0 + + + 8 + + + Speed + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + glitch-speed + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + + + + 0 + + + + + Color + 0 + start + center + 1 + + + + + 1 + 1 + 8 + 8 + 250 + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + - \ No newline at end of file diff --git a/resources/ui/gtk3/hexagon.ui b/resources/ui/gtk3/hexagon.ui index db77118..5b4bd68 100644 --- a/resources/ui/gtk3/hexagon.ui +++ b/resources/ui/gtk3/hexagon.ui @@ -28,319 +28,293 @@ SPDX-License-Identifier: GPL-3.0-or-later 1 - - vertical + - + + none + - - none - - + + 0 - - 10 - 10 - 10 - 10 - 0 + + 8 - - 8 + + Animation Time [ms] + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + hexagon-animation-time + + + + - - Animation Time [ms] - 0 - start - center - 1 - - - - - end - center - 1 - 0 - left - 300 - hexagon-animation-time - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - + + edit-clear-symbolic + 1 + Reset to Default Value + - - - - 10 - 10 - 10 - 10 - 0 - - - 8 - - - Scale - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - hexagon-scale - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - - - - 10 - 10 - 10 - 10 - 0 - - - 8 - - - Mesh Line Width - 0 - start - center - 1 - - - - - end - center - 1 - 1 - left - 300 - hexagon-line-width - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - - - - 10 - 10 - 10 - 10 - 0 - - - - - Line Color - 0 - start - center - 1 - - - - - 1 - 1 - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - - - - 10 - 10 - 10 - 10 - 0 - - - - - Glow Color - 0 - start - center - 1 - - - - - 1 - 1 - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - - - - 10 - 10 - 10 - 10 - 0 - - - - - vertical - 3 - - - Additive Blending - 0 - start - center - 1 - - - - - You may want to enable this for dark window themes. - 0 - start - center - 1 - - - - - - - - end - center - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - + + + + 0 + + + 8 + + + Scale + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + hexagon-scale + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + + + + 0 + + + 8 + + + Mesh Line Width + 0 + start + center + 1 + + + + + end + center + 1 + 1 + left + 300 + hexagon-line-width + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + + + + 0 + + + + + Line Color + 0 + start + center + 1 + + + + + 1 + 1 + 8 + 8 + 250 + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + + + + 0 + + + + + Glow Color + 0 + start + center + 1 + + + + + 1 + 1 + 8 + 8 + 250 + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + + + + 0 + + + + + vertical + 3 + + + Additive Blending + 0 + start + center + 1 + + + + + You may want to enable this for dark window themes. + 0 + start + center + 1 + + + + + + + + end + center + 8 + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + - \ No newline at end of file diff --git a/resources/ui/gtk3/incinerate.ui b/resources/ui/gtk3/incinerate.ui index 51c0a8a..c31d869 100644 --- a/resources/ui/gtk3/incinerate.ui +++ b/resources/ui/gtk3/incinerate.ui @@ -28,276 +28,251 @@ SPDX-License-Identifier: GPL-3.0-or-later 0.1 - - vertical + - + + none + - - none - - + + 0 - - 10 - 10 - 10 - 10 - 0 + + 8 - - 8 + + Animation Time [ms] + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + incinerate-animation-time + + + + - - Animation Time [ms] - 0 - start - center - 1 - - - - - end - center - 1 - 0 - left - 300 - incinerate-animation-time - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - + + edit-clear-symbolic + 1 + Reset to Default Value + - - - - 10 - 10 - 10 - 10 - 0 - - - 8 - - - Scale - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - incinerate-scale - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - - - - 10 - 10 - 10 - 10 - 0 - - - 8 - - - Turbulence - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - incinerate-turbulence - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - - - - 10 - 10 - 10 - 10 - 0 - - - - - vertical - 3 - - - Start at Pointer - 0 - start - center - 1 - - - - - If disabled, a random location will be chosen. - 0 - start - center - 1 - - - - - - - - end - center - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - - - - 10 - 10 - 10 - 10 - 0 - - - - - Color - 0 - start - center - 1 - - - - - 0 - 1 - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - + + + + 0 + + + 8 + + + Scale + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + incinerate-scale + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + + + + 0 + + + 8 + + + Turbulence + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + incinerate-turbulence + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + + + + 0 + + + + + vertical + 3 + + + Start at Pointer + 0 + start + center + 1 + + + + + If disabled, a random location will be chosen. + 0 + start + center + 1 + + + + + + + + end + center + 8 + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + + + + 0 + + + + + Color + 0 + start + center + 1 + + + + + 0 + 1 + 8 + 8 + 250 + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + - \ No newline at end of file diff --git a/resources/ui/gtk3/pixel-wheel.ui b/resources/ui/gtk3/pixel-wheel.ui index 16c6008..90866dc 100644 --- a/resources/ui/gtk3/pixel-wheel.ui +++ b/resources/ui/gtk3/pixel-wheel.ui @@ -28,171 +28,150 @@ SPDX-License-Identifier: GPL-3.0-or-later 10 - - vertical + - + + none + - - none - - + + 0 - - 10 - 10 - 10 - 10 - 0 + + 8 - - 8 + + Animation Time [ms] + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + pixel-wheel-animation-time + + + + - - Animation Time [ms] - 0 - start - center - 1 - - - - - end - center - 1 - 0 - left - 300 - pixel-wheel-animation-time - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - + + edit-clear-symbolic + 1 + Reset to Default Value + - - - - 10 - 10 - 10 - 10 - 0 - - - 8 - - - Spoke Count - 0 - start - center - 1 - - - - - end - center - 1 - 0 - left - 300 - pixel-wheel-spoke-count - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - - - - 10 - 10 - 10 - 10 - 0 - - - 8 - - - Pixel Size - 0 - start - center - 1 - - - - - end - center - 1 - 0 - left - 300 - pixel-wheel-pixel-size - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - + + + + 0 + + + 8 + + + Spoke Count + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + pixel-wheel-spoke-count + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + + + + 0 + + + 8 + + + Pixel Size + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + pixel-wheel-pixel-size + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + - \ No newline at end of file diff --git a/resources/ui/gtk3/pixel-wipe.ui b/resources/ui/gtk3/pixel-wipe.ui index 6ef7f40..297fbe5 100644 --- a/resources/ui/gtk3/pixel-wipe.ui +++ b/resources/ui/gtk3/pixel-wipe.ui @@ -28,122 +28,105 @@ SPDX-License-Identifier: GPL-3.0-or-later 10 - - vertical + - + + none + - - none - - + + 0 - - 10 - 10 - 10 - 10 - 0 + + 8 - - 8 + + Animation Time [ms] + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + pixel-wipe-animation-time + + + + - - Animation Time [ms] - 0 - start - center - 1 - - - - - end - center - 1 - 0 - left - 300 - pixel-wipe-animation-time - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - + + edit-clear-symbolic + 1 + Reset to Default Value + - - - - 10 - 10 - 10 - 10 - 0 - - - 8 - - - Pixel Size - 0 - start - center - 1 - - - - - end - center - 1 - 0 - left - 300 - pixel-wipe-pixel-size - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - + + + + 0 + + + 8 + + + Pixel Size + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + pixel-wipe-pixel-size + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + - \ No newline at end of file diff --git a/resources/ui/gtk3/pixelate.ui b/resources/ui/gtk3/pixelate.ui index a81d514..1deacb5 100644 --- a/resources/ui/gtk3/pixelate.ui +++ b/resources/ui/gtk3/pixelate.ui @@ -28,171 +28,150 @@ SPDX-License-Identifier: GPL-3.0-or-later 10 - - vertical + - + + none + - - none - - + + 0 - - 10 - 10 - 10 - 10 - 0 + + 8 - - 8 + + Animation Time [ms] + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + pixelate-animation-time + + + + - - Animation Time [ms] - 0 - start - center - 1 - - - - - end - center - 1 - 0 - left - 300 - pixelate-animation-time - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - + + edit-clear-symbolic + 1 + Reset to Default Value + - - - - 10 - 10 - 10 - 10 - 0 - - - 8 - - - Noise - 0 - start - center - 1 - - - - - end - center - 1 - 0 - left - 300 - pixelate-noise - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - - - - 10 - 10 - 10 - 10 - 0 - - - 8 - - - Pixel Size - 0 - start - center - 1 - - - - - end - center - 1 - 0 - left - 300 - pixelate-pixel-size - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - + + + + 0 + + + 8 + + + Noise + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + pixelate-noise + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + + + + 0 + + + 8 + + + Pixel Size + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + pixelate-pixel-size + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + - \ No newline at end of file diff --git a/resources/ui/gtk3/portal.ui b/resources/ui/gtk3/portal.ui index 2b8fd9f..128347f 100644 --- a/resources/ui/gtk3/portal.ui +++ b/resources/ui/gtk3/portal.ui @@ -35,267 +35,237 @@ SPDX-License-Identifier: GPL-3.0-or-later 10 - - vertical + - + + none + - - none - - + + 0 - - 10 - 10 - 10 - 10 - 0 + + 8 - - 8 + + Animation Time [ms] + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + portal-animation-time + + + + - - Animation Time [ms] - 0 - start - center - 1 - - - - - end - center - 1 - 0 - left - 300 - portal-animation-time - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - + + edit-clear-symbolic + 1 + Reset to Default Value + - - - - 10 - 10 - 10 - 10 - 0 - - - 8 - - - Rotation Speed - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - portal-rotation-speed - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - - - - 10 - 10 - 10 - 10 - 0 - - - 8 - - - Whirling - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - portal-whirling - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - - - - 10 - 10 - 10 - 10 - 0 - - - 8 - - - Details - 0 - start - center - 1 - - - - - end - center - 1 - 1 - left - 300 - portal-details - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - - - - 10 - 10 - 10 - 10 - 0 - - - - - Color - 0 - start - center - 1 - - - - - 0 - 1 - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - + + + + 0 + + + 8 + + + Rotation Speed + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + portal-rotation-speed + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + + + + 0 + + + 8 + + + Whirling + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + portal-whirling + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + + + + 0 + + + 8 + + + Details + 0 + start + center + 1 + + + + + end + center + 1 + 1 + left + 300 + portal-details + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + + + + 0 + + + + + Color + 0 + start + center + 1 + + + + + 0 + 1 + 8 + 8 + 250 + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + - \ No newline at end of file diff --git a/resources/ui/gtk3/prefs.ui b/resources/ui/gtk3/prefs.ui index 4b88998..b9366c5 100644 --- a/resources/ui/gtk3/prefs.ui +++ b/resources/ui/gtk3/prefs.ui @@ -8,8 +8,7 @@ SPDX-License-Identifier: GPL-3.0-or-later - - + main-menu 1 @@ -22,244 +21,406 @@ SPDX-License-Identifier: GPL-3.0-or-later - - vertical - 30 - 30 - + + + center + 1 - + + profile-menu + 1 + + + + center - burn-my-windows-symbolic - 128 - - - - - - Welcome to Burn-My-Windows! - 8 - 6 - - - - - - - If you like this extension, recommend it to your friends :) - 36 - - - - - - + 1 - - none + + bmw-edit-profile-symbolic + 1 + 1 + + + + + + + + + over-down-up + + + + never + + + + vertical + 20 + 20 + 20 + 20 + 5 - - 10 - 10 - 10 - 10 - 0 - - - 8 - - - vertical - 3 - - - Enabled Effects - 0 - start - center - 1 - - - - - If multiple are selected, one is chosen randomly. - 0 - start - center - 1 - - - - - - - - enabled-effects-menu - - - 8 - - - Choose Effects - - - - - pan-down-symbolic - 1 - - - - - - - - + + Effect Settings + start + - - 10 - 10 - 10 - 10 - 0 - - - 8 - - - Also Add Effects to Dialogs - 0 - start - center - 1 - - - - - end - center - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - + + If multiple are selected, one is chosen randomly. + start - - 10 - 10 - 10 - 10 - 0 + - - 8 - - - Disable on Battery Power - 0 - start - center - 1 - - - - - end - center - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - - - - 10 - 10 - 10 - 10 - 0 - - - 8 - - - Disable in Power-Save Mode - 0 - start - center - 1 - - - - - end - center - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - + + none + + + + + + vertical + 20 + 20 + 20 + 20 + 5 + + + + + Effect Profile Constraints + start + + + + + + + Define when the current effect settings should be used. + start + + + + + + 5 + 15 + + + none + + + + + + 0 + + + + + Application Name + 0 + start + center + 1 + + + + + + center + + + + + 200 + + + + + + center + + + bmw-select-app-symbolic + 1 + + + + + + + + + + + + + + 0 + + + + + Animation Type + 0 + start + center + 1 + + + + + 200 + + Any + Opening Windows + Closing Windows + + + + + + + + + + + 0 + + + + + Window Type + 0 + start + center + 1 + + + + + 200 + + Any + Normal Windows + Dialog Windows + + + + + + + + + + + 0 + + + + + Color Scheme + 0 + start + center + 1 + + + + + 200 + + Any + Default Color Scheme + Dark Color Scheme + + + + + + + + + + + 0 + + + + + Power Mode + 0 + start + center + 1 + + + + + 200 + + Any + On Battery + Plugged In + + + + + + + + + + + 0 + + + + + Power Profile + 0 + start + center + 1 + + + + + 200 + + Any + Power-Saver Mode + Balanced Mode + Performance Mode + Power Saver or Balanced + Balanced or Performance + + + + + + + + + + + + + + + + Advanced Profile Options + start + + + + + + + 5 + 15 + + + none + + + + + + 0 + + + + + vertical + 3 + + + High Priority + 0 + start + center + 1 + + + + + Force using this profile even if it has less constraints than another matching profile. + 0 + start + center + 1 + end + + + + + + + + center + + + + + + + + + + + + + + + prefs.profile-delete + Delete this Profile... + start + + + + + + \ No newline at end of file diff --git a/resources/ui/gtk3/tv-glitch.ui b/resources/ui/gtk3/tv-glitch.ui index 144d48e..c2a8518 100644 --- a/resources/ui/gtk3/tv-glitch.ui +++ b/resources/ui/gtk3/tv-glitch.ui @@ -35,263 +35,237 @@ SPDX-License-Identifier: GPL-3.0-or-later 0.1 - - vertical + - + + none + - - none - - + + 0 - - 10 - 10 - 10 - 10 - 0 + + 8 - - 8 + + Animation Time [ms] + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + tv-glitch-animation-time + + + + - - Animation Time [ms] - 0 - start - center - 1 - - - - - end - center - 1 - 0 - left - 300 - tv-glitch-animation-time - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - + + edit-clear-symbolic + 1 + Reset to Default Value + - - - - 10 - 10 - 10 - 10 - 0 - - - 8 - - - Scale - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - tv-glitch-scale - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - - - - 10 - 10 - 10 - 10 - 0 - - - 8 - - - Strength - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - tv-glitch-strength - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - - - - 10 - 10 - 10 - 10 - 0 - - - 8 - - - Speed - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - tv-glitch-speed - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - - - - 10 - 10 - 10 - 10 - 0 - - - - - Color - 0 - start - center - 1 - - - - - 1 - 1 - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - + + + + 0 + + + 8 + + + Scale + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + tv-glitch-scale + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + + + + 0 + + + 8 + + + Strength + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + tv-glitch-strength + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + + + + 0 + + + 8 + + + Speed + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + tv-glitch-speed + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + + + + 0 + + + + + Color + 0 + start + center + 1 + + + + + 1 + 1 + 8 + 8 + 250 + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + - \ No newline at end of file diff --git a/resources/ui/gtk3/tv.ui b/resources/ui/gtk3/tv.ui index 7b8902a..66edc99 100644 --- a/resources/ui/gtk3/tv.ui +++ b/resources/ui/gtk3/tv.ui @@ -14,116 +14,102 @@ SPDX-License-Identifier: GPL-3.0-or-later 100 - - vertical + - + + none + - - none - - + + 0 - - 10 - 10 - 10 - 10 - 0 + + 8 - - 8 + + Animation Time [ms] + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + tv-animation-time + + + + - - Animation Time [ms] - 0 - start - center - 1 - - - - - end - center - 1 - 0 - left - 300 - tv-animation-time - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - + + edit-clear-symbolic + 1 + Reset to Default Value + - - - - 10 - 10 - 10 - 10 - 0 - - - - - Color - 0 - start - center - 1 - - - - - 1 - 1 - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - + + + + 0 + + + + + Color + 0 + start + center + 1 + + + + + 1 + 1 + 8 + 8 + 250 + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + - \ No newline at end of file diff --git a/resources/ui/gtk3/wisps.ui b/resources/ui/gtk3/wisps.ui index 694549f..5029d44 100644 --- a/resources/ui/gtk3/wisps.ui +++ b/resources/ui/gtk3/wisps.ui @@ -21,165 +21,147 @@ SPDX-License-Identifier: GPL-3.0-or-later 0.1 - - vertical + - + + none + - - none - - + + 0 - - 10 - 10 - 10 - 10 - 0 + + 8 - - 8 + + Animation Time [ms] + 0 + start + center + 1 + + + + + end + center + 1 + 0 + left + 300 + wisps-animation-time + + + + - - Animation Time [ms] - 0 - start - center - 1 - - - - - end - center - 1 - 0 - left - 300 - wisps-animation-time - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - + + edit-clear-symbolic + 1 + Reset to Default Value + - - - - 10 - 10 - 10 - 10 - 0 - - - 8 - - - Scale - 0 - start - center - 1 - - - - - end - center - 1 - 2 - left - 300 - wisps-scale - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - - - - 10 - 10 - 10 - 10 - 0 - - - - - Color - 0 - start - center - 1 - - - - - 0 - 1 - - - - - - - edit-clear-symbolic - 1 - - - Reset to Default Value - - - - - - - - + + + + 0 + + + 8 + + + Scale + 0 + start + center + 1 + + + + + end + center + 1 + 2 + left + 300 + wisps-scale + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + + + + 0 + + + + + Color + 0 + start + center + 1 + + + + + 0 + 1 + 8 + 8 + 250 + + + + + + + edit-clear-symbolic + 1 + + + Reset to Default Value + + + + + + + + - \ No newline at end of file From f149ee4cf3bc7a1f7ef92e714468aad599a9587e Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Sun, 5 Feb 2023 13:09:36 +0100 Subject: [PATCH 37/67] :wrench: Some libadwaita fixes --- prefs.js | 105 ++++++++++++++++++++++++++++++------------------------- 1 file changed, 57 insertions(+), 48 deletions(-) diff --git a/prefs.js b/prefs.js index e9c15cf..846c0db 100644 --- a/prefs.js +++ b/prefs.js @@ -72,15 +72,18 @@ var PreferencesDialog = class PreferencesDialog { Gio.resources_register(this._resources); // Load the CSS file for the settings dialog. - const styleProvider = Gtk.CssProvider.new(); - if (utils.isGTK4() && !utils.isADW()) { - styleProvider.load_from_resource('/css/gtk4.css'); - Gtk.StyleContext.add_provider_for_display(Gdk.Display.get_default(), styleProvider, - Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); - } else { - styleProvider.load_from_resource('/css/gtk3.css'); - Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(), styleProvider, - Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); + if (!utils.isADW()) { + const styleProvider = Gtk.CssProvider.new(); + if (utils.isGTK4()) { + styleProvider.load_from_resource('/css/gtk4.css'); + Gtk.StyleContext.add_provider_for_display( + Gdk.Display.get_default(), styleProvider, + Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); + } else { + styleProvider.load_from_resource('/css/gtk3.css'); + Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(), styleProvider, + Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); + } } // Make sure custom icons are found. @@ -158,12 +161,14 @@ var PreferencesDialog = class PreferencesDialog { }); if (!utils.isADW()) { - const profileEditorButton = this._builder.get_object("edit-profile-button"); - profileEditorButton.connect("toggled", b => { + const profileEditorButton = this._builder.get_object('edit-profile-button'); + profileEditorButton.connect('toggled', b => { if (b.active) { - this._builder.get_object("general-prefs").set_visible_child(this._builder.get_object("profile-editor")); + this._builder.get_object('general-prefs') + .set_visible_child(this._builder.get_object('profile-editor')); } else { - this._builder.get_object("general-prefs").set_visible_child(this._builder.get_object("effect-editor")); + this._builder.get_object('general-prefs') + .set_visible_child(this._builder.get_object('effect-editor')); } }); } @@ -179,22 +184,21 @@ var PreferencesDialog = class PreferencesDialog { this._effectRows = []; if (!utils.isADW()) { - group.connect("row-activated", (g, row) => { + group.connect('row-activated', (g, row) => { this._effectRows.forEach(r => { if (r == row) { if (r._revealer.get_reveal_child()) { r._revealer.set_reveal_child(false); - r._arrow.get_style_context().remove_class("revealed"); + r._arrow.get_style_context().remove_class('revealed'); } else { r._revealer.set_reveal_child(true); - r._arrow.get_style_context().add_class("revealed"); + r._arrow.get_style_context().add_class('revealed'); } } else { r._revealer.set_reveal_child(false); - r._arrow.get_style_context().remove_class("revealed"); + r._arrow.get_style_context().remove_class('revealed'); } - } - ); + }); }); } @@ -212,7 +216,12 @@ var PreferencesDialog = class PreferencesDialog { } // The preview button. - const previewButton = Gtk.Button.new_from_icon_name('bmw-preview-symbolic', 1); + let previewButton; + if (utils.isGTK4()) { + previewButton = Gtk.Button.new_from_icon_name('bmw-preview-symbolic'); + } else { + previewButton = Gtk.Button.new_from_icon_name('bmw-preview-symbolic', 1); + } previewButton.get_style_context().add_class('circular'); previewButton.get_style_context().add_class('flat'); previewButton.set_tooltip_text(_('Preview this effect')); @@ -220,13 +229,13 @@ var PreferencesDialog = class PreferencesDialog { previewButton.connect('clicked', () => { this._previewEffect(effect); }); - + // The toggle button for enabling and disabling the effect. const button = Gtk.Switch.new(); button.set_tooltip_text(_('Use this effect')); button.set_valign(Gtk.Align.CENTER); this._builder.expose_object(`${effect.getNick()}-enable-effect`, button); - + if (utils.isADW()) { let row; @@ -234,7 +243,7 @@ var PreferencesDialog = class PreferencesDialog { // Add the effect's preferences (if any). row = this._builder.get_object(`${effect.getNick()}-prefs`); - } else if(utils.isADW()) { + } else if (utils.isADW()) { row = Adw.ActionRow.new(); } @@ -266,34 +275,35 @@ var PreferencesDialog = class PreferencesDialog { row.add_prefix(button); group.add(row); - + } else { const row = new Gtk.ListBoxRow(); - row.get_style_context().add_class("effect-row"); - - const container = new Gtk.Box({orientation:Gtk.Orientation.VERTICAL}); + row.get_style_context().add_class('effect-row'); - const header = new Gtk.Box({ spacing:12}); - header.get_style_context().add_class("effect-row-header"); - - const label = new Gtk.Label({label:effect.getLabel(), hexpand:true, halign: Gtk.Align.START}); - label.get_style_context().add_class("heading"); + const container = new Gtk.Box({orientation: Gtk.Orientation.VERTICAL}); + + const header = new Gtk.Box({spacing: 12}); + header.get_style_context().add_class('effect-row-header'); + + const label = new Gtk.Label( + {label: effect.getLabel(), hexpand: true, halign: Gtk.Align.START}); + label.get_style_context().add_class('heading'); this.gtkBoxAppend(header, button); this.gtkBoxAppend(header, label); this.gtkBoxAppend(header, previewButton); this.gtkBoxAppend(container, header); - + if (hasPrefs) { const revealer = this._builder.get_object(`${effect.getNick()}-prefs`); - const arrow = new Gtk.Image({icon_name:"go-down-symbolic"}); - arrow.get_style_context().add_class("revealer-arrow"); + const arrow = new Gtk.Image({icon_name: 'go-down-symbolic'}); + arrow.get_style_context().add_class('revealer-arrow'); this.gtkBoxAppend(header, arrow); this.gtkBoxAppend(container, revealer); row._revealer = revealer; - row._arrow = arrow; + row._arrow = arrow; row.set_activatable(true); this._effectRows.push(row); @@ -301,17 +311,14 @@ var PreferencesDialog = class PreferencesDialog { row.set_activatable(false); } - if (utils.isGTK4()) { - row.set_child(container); - group.append(row); - } else { - row.add(container); - group.add(row); - } - - + if (utils.isGTK4()) { + row.set_child(container); + group.append(row); + } else { + row.add(container); + group.add(row); + } } - } }); @@ -358,10 +365,12 @@ var PreferencesDialog = class PreferencesDialog { } else if (utils.isGTK4()) { window.get_titlebar().pack_start(menu); - window.get_titlebar().set_title_widget(this._builder.get_object('profile-button')); + window.get_titlebar().set_title_widget( + this._builder.get_object('profile-button')); } else { window.get_titlebar().pack_start(menu); - window.get_titlebar().set_custom_title(this._builder.get_object('profile-button')); + window.get_titlebar().set_custom_title( + this._builder.get_object('profile-button')); } const addURIAction = (name, uri) => { From e62a0454c67d7b029b66200d004a31d282801fcf Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Sun, 5 Feb 2023 13:25:14 +0100 Subject: [PATCH 38/67] :wrench: Fix GTK3 label alignment --- prefs.js | 2 +- resources/css/gtk3.css | 12 +----------- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/prefs.js b/prefs.js index 846c0db..0b6ef17 100644 --- a/prefs.js +++ b/prefs.js @@ -673,7 +673,7 @@ var PreferencesDialog = class PreferencesDialog { if (utils.isGTK4()) { box.append(child); } else { - box.pack_start(child, false, false, 0); + box.pack_start(child, false, true, 0); } } diff --git a/resources/css/gtk3.css b/resources/css/gtk3.css index 289e791..6a69c48 100644 --- a/resources/css/gtk3.css +++ b/resources/css/gtk3.css @@ -20,14 +20,4 @@ row { .revealer-arrow { margin-right: 6px; -} - -/* .revealer-arrow.revealed {} */ - -/* row { - padding: 10px; -} - -.effect-row { - padding: 0px; -} */ \ No newline at end of file +} \ No newline at end of file From 44ccb41f908085d42bb0b4ebdd7b1b99fb6d8e32 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Sun, 5 Feb 2023 13:25:26 +0100 Subject: [PATCH 39/67] :wrench: Tweak application entry --- resources/ui/adw/prefs.ui | 7 +++++-- resources/ui/gtk3/prefs.ui | 5 +++-- resources/ui/gtk4/prefs.ui | 5 +++-- 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/resources/ui/adw/prefs.ui b/resources/ui/adw/prefs.ui index 540bffa..69f500f 100644 --- a/resources/ui/adw/prefs.ui +++ b/resources/ui/adw/prefs.ui @@ -67,7 +67,7 @@ SPDX-License-Identifier: GPL-3.0-or-later - Application Name + Application center @@ -76,7 +76,10 @@ SPDX-License-Identifier: GPL-3.0-or-later - + + 300 + Any + diff --git a/resources/ui/gtk3/prefs.ui b/resources/ui/gtk3/prefs.ui index b9366c5..5c4c3cd 100644 --- a/resources/ui/gtk3/prefs.ui +++ b/resources/ui/gtk3/prefs.ui @@ -147,7 +147,7 @@ SPDX-License-Identifier: GPL-3.0-or-later - Application Name + Application 0 start center @@ -164,7 +164,8 @@ SPDX-License-Identifier: GPL-3.0-or-later - 200 + 300 + Any diff --git a/resources/ui/gtk4/prefs.ui b/resources/ui/gtk4/prefs.ui index b4bf182..19b6aa7 100644 --- a/resources/ui/gtk4/prefs.ui +++ b/resources/ui/gtk4/prefs.ui @@ -131,7 +131,7 @@ SPDX-License-Identifier: GPL-3.0-or-later - Application Name + Application 0 start center @@ -148,7 +148,8 @@ SPDX-License-Identifier: GPL-3.0-or-later - 200 + 300 + Any From fbaa04082c160b50f557849629be9c01d4d1c95c Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Sun, 5 Feb 2023 19:54:25 +0100 Subject: [PATCH 40/67] :beetle: Fix syntax error on GNOME 3.36 --- src/WindowPicker.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/WindowPicker.js b/src/WindowPicker.js index 0342573..07ebdb8 100644 --- a/src/WindowPicker.js +++ b/src/WindowPicker.js @@ -63,8 +63,8 @@ var WindowPicker = class WindowPicker { } let wmClass = 'window-not-found'; - if (actor.toString().includes('WindowActor')) { - wmClass = actor.meta_window.get_wm_class() ?? 'window-not-found'; + if (actor.toString().includes('WindowActor') && actor.meta_window.get_wm_class() != "") { + wmClass = actor.meta_window.get_wm_class(); } this._dbus.emit_signal('WindowPicked', new GLib.Variant('(s)', [wmClass])); From fa7b118dc39bfbd63219f31713ae94fa63f5bccc Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Sun, 5 Feb 2023 20:03:51 +0100 Subject: [PATCH 41/67] :wrench: Do not capture preference window reference in center of the screen --- tests/generate-references.sh | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/tests/generate-references.sh b/tests/generate-references.sh index 7544885..ac6b819 100755 --- a/tests/generate-references.sh +++ b/tests/generate-references.sh @@ -60,7 +60,8 @@ EXTENSION="burn-my-windows@schneegans.github.com" # All references images of the effects are captured at & cropped to this region # in the center of the screen. This is kind of arbitrary, but has been choosen so that # something is visible from each effect. -CROP="100x100+900+500" +EFFECT_CROP="100x100+900+500" +PREFS_CROP="100x100+700+300" # Run the container. For more info, visit https://github.com/Schneegans/gnome-shell-pod. POD=$(podman run --rm --cap-add=SYS_NICE --cap-add=IPC_LOCK -td "${IMAGE}") @@ -95,10 +96,11 @@ set_setting() { set org.gnome.shell.extensions.burn-my-windows "${1}" "${2}" } -# This makes a screen capture (cropped to $CROP) inside the container and stores it -# on the host relative to this script with the given file name. +# This makes a screen capture (cropped to either $EFFECT_CROP or P$REFS_CROP as given through the +# second parameter) inside the container and stores it on the host relative to this script with the +# given file name. capture() { - podman cp "${POD}:/opt/Xvfb_screen0" - | tar xf - --to-command "convert xwd:- -crop ${CROP} ${1}" + podman cp "${POD}:/opt/Xvfb_screen0" - | tar xf - --to-command "convert xwd:- -crop ${2} ${1}" } # This opens the extensions preferences dialog and captures two images: One during the @@ -114,10 +116,10 @@ capture_effect() { sleep 1 do_in_pod gnome-terminal sleep 3 - capture "tests/references/${1}-open-${SESSION}-${FEDORA_VERSION}.png" + capture "tests/references/${1}-open-${SESSION}-${FEDORA_VERSION}.png" "${EFFECT_CROP}" send_keystroke "Alt+F4" sleep 3 - capture "tests/references/${1}-close-${SESSION}-${FEDORA_VERSION}.png" + capture "tests/references/${1}-close-${SESSION}-${FEDORA_VERSION}.png" "${EFFECT_CROP}" } # ----------------------------------------------------- wait for the container to start up @@ -170,7 +172,7 @@ sleep 3 echo "Opening Preferences." do_in_pod gnome-extensions prefs "${EXTENSION}" sleep 3 -capture "tests/references/preferences-${SESSION}-${FEDORA_VERSION}.png" +capture "tests/references/preferences-${SESSION}-${FEDORA_VERSION}.png" "${PREFS_CROP}" send_keystroke "Alt+F4" # The test mode ensures that the animations are "frozen" and do not change in time. From ab851d81139c52c92a6b84b3f33efc5b7b421437 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Sun, 5 Feb 2023 20:04:03 +0100 Subject: [PATCH 42/67] :wrench: Update references --- .../preferences-gnome-wayland-nested-32.png | Bin 2296 -> 4633 bytes .../preferences-gnome-wayland-nested-33.png | Bin 2579 -> 4298 bytes .../preferences-gnome-wayland-nested-34.png | Bin 1980 -> 355 bytes .../preferences-gnome-wayland-nested-35.png | Bin 1980 -> 4044 bytes .../preferences-gnome-wayland-nested-36.png | Bin 1934 -> 1894 bytes .../preferences-gnome-wayland-nested-37.png | Bin 1870 -> 1629 bytes .../preferences-gnome-xsession-32.png | Bin 2296 -> 4631 bytes .../preferences-gnome-xsession-33.png | Bin 2579 -> 4301 bytes .../preferences-gnome-xsession-34.png | Bin 3082 -> 2351 bytes .../preferences-gnome-xsession-35.png | Bin 3082 -> 4129 bytes .../preferences-gnome-xsession-36.png | Bin 1048 -> 1894 bytes .../preferences-gnome-xsession-37.png | Bin 1870 -> 1629 bytes 12 files changed, 0 insertions(+), 0 deletions(-) diff --git a/tests/references/preferences-gnome-wayland-nested-32.png b/tests/references/preferences-gnome-wayland-nested-32.png index 2c7169d39aebee7f4313b85c0e16dbae38c423c8..c7114161adf71c8098cd9486c6e3e2f9eee6af7e 100755 GIT binary patch literal 4633 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 diff --git a/tests/references/preferences-gnome-wayland-nested-33.png b/tests/references/preferences-gnome-wayland-nested-33.png index f8ea6124bd360b834b747f11ebd56e6648174723..ff6aec1226e7ce56243dd0cffc79757404d9149e 100755 GIT binary patch literal 4298 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 jY|YHfBoc{?sHqxu3(Ubzk|l|j2M&&Gw diff --git a/tests/references/preferences-gnome-wayland-nested-34.png b/tests/references/preferences-gnome-wayland-nested-34.png index db2b185e41ee8fff23c7707b8ed3d921205fa074..74aae27bbc191f16a963e9261f7bdfcd7d25bf7e 100755 GIT binary patch delta 282 zcmdnP|Cnil1Scai0|SGX4!ih7MZ0^mS!_&crIrAe0{Dw-P8MkeujO29#-FU|_LeU|`w<)S|O$DTawj zmgXi_mX>-30q@zHfl5_DN>dU`QmvAUQh^kMk%5u1u7Q!RfoX`LrImq!m7#?;kTfv3 jcWtW?iiX_$l+3hB+#1$*^Y#HXFnGGM`MIofN@xNA;fYKS delta 1919 zcmV-_2Y~qF0=y597zqdi0000-JY{B)AwGWsols0vMfUadjgOFVb#;S=hGb`H)z#Ff zsi~Kmnx&?u&CSg9^z*g0x9jZdy1TlbprMBQ?df__$H9I{^P*8z{h41g~ zud%UzgM?31Rzpcj;^E=S%F2g}i|+00;o;zAXlXb;KDW5HJV8U}=H-ToiHC}cTVG+u z#>cdG^z-t7goNnm=P))n$jHcS zaB;!I!o9w|Oi@ykmX_=4={-Y5?Cb15MMgC`JcNjd@$m1nw6!)oKIiA=ij0k1U}1cJ zfMscFR$E-q(9hl7+&)A`rl+S+Rac>-q`$$zzQ4XfMo5K-h(JY0r>UsJ#KeD^ot?+W z$g#4s)z;R|&d$%z&#JAgIzU2lc6amg@tB&LgNKJ-V`O=JeMU=7XKQU&TwZs2dpA8l z!o$Pd+}lS?PDV^k#m2_V%gZu2I;^g)PEu6S(a`1OFDzD@LghJM<>u&V`FY|bBvFW)6;*`dwzeoxw(9R zfs2ifQC3%NadOGZ$(EU!t*@`QxVYou;myaw|Ns94XQwFu0004EOGiZB>2Bhi0000G zV_{Bq000Mo000Cy000Ao0005>YpMxz000DaNkl+NrEyVF3R$v@D3G;GLNih_&;DcDMWG zZ|Pjeo!O!3c}jk$^L?J(Ip;m!c|SWd=giEz00{jjb=~z70J&k({|7QT#x%ujQF>DW zm^R&dW2}vIXV~MW&Wv==xXBbhOP#s=1#`pe33XvOV!Fz=mr`P0y*;_j7|QkLm`1`7P>dET&ArcypNhP z<7mKp|C(_iYaf4z(IkviO|73o>UhKqD|pjgPd4`Kbu6%cLxVnK<0frFm8`k48d99I ziZ>e{B%6m^JYcB{>OyL&R%jEd)C4!HA)qQV6%YxI7zmA)&{j5~@|&Y5+0AB1zHXx{$V&Q3-!lN(-zvfK8xF=Ws4Jui^P-gx!(+^78N-a1V}qWyuE z^wgwHFM@x+0Rb;HCKY7m9q{b8s}H5Gs_dZiWzsyPNl5Qx)rU1# zPYE80wYCjJPn$iRuawv5CKM795)u-+25N0W55}Y5*sJ=(TUagdTFgIzB%%j*sUJ9w zM~w`=j=oNuWSzjN@pBNT5u{;A4>BBzfXJu+BFBGlXuOd(suc)2Wf*c=LbX}Rn}=z2 z_*T~$X)=Orv)a*1J3gJVqwQ^0y--*GUi4o2&K&Awv7tfRqW&fLXJOx&5e0%i2;z0` z0N`xF>c;T9Amp{m?|L`2yiMa+nULd(;>SQq+{Akz5qw&bC z2eE%_|3n6|2VLOS?ugU%sRb+?9l((G0IzhpOP(zq3!kS>9<#wQ04{un+A&Ssf8d5l0h(92>_??{^JzCeHT3?FRN>|ziAHs|?pnXR}Ao4Z<>lgAVY znn>szP)K)(U--^_Xi|LnmGZB`q|0iE1&z#tC3uLtvc3+63z?I}I0U&{wz@MY#Gl&B zAmHHf1n|xLVd>ioWaLt~=(|WrN6(e-f1njHb9JUvf|EZoCyQ}NM-Q-Dn|`9}q_}H0 z7OxY$4%YpQO65}nBfl)8hcdn2Om8b_N#XIazL8&9wLo1~v`!N6zbn|uVnfmq0DeR7 z)??z9EhHo)BqSsxBqSsxBqa3j==TW__+tVjAOdpj^d}!(CJ3(jFMa?3002ovPDHLk FV1gPA*1P}! diff --git a/tests/references/preferences-gnome-wayland-nested-35.png b/tests/references/preferences-gnome-wayland-nested-35.png index db2b185e41ee8fff23c7707b8ed3d921205fa074..8060d9d108ab4581086055fd2315b307d6c606bf 100755 GIT binary patch literal 4044 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 Av;Y7A delta 1918 zcmV-^2Z8v^AG{Bc83+Ra002ikWoD5fK7Rt8P)t-s_Vx6QkC1V7b%Tb6WM^sB)zqk| zsh66XrKYCM&CK=m^R>3O>+I{gySkpBp_`tbwzs$K?Ca9f(y6PfnVg*3+S;b5sHm!{ z+uPc_yu6Z?l~`S0NlsAa<>XgeT`@N~Q&?JUadSvbPcAezR9Rct*x0hOvtVRp@PF^_ zm6(`0JwI7qUvYJIJ3&HEQ&mMuOlWOxOHffSH8*~Ng6r$*+C;8Mm0J-goudo@b9yQr>9U=SD~Y%zrn%2zrI06NQH=qKt)HVsi?!m#DAKdoyW(> zv9hz(*4EC>&d<-!s;#U#KtghMck}Y`n3|e{hlgKdWO;mjMoUd+Yi(CtUUzzXH$6YX z!^7O%+eb`JModk`#>UIb%Q84Rtgfz3QdH5=(B5ODdwerFJ7#KZ zWom2J*w@X@&5VwZPg7Kol9Q{gt(~5qkCBq1q@`YCV{USDjE|7h(|^-@et)>RxqN_u zi;a#^R#$Cta>>fcmYJEYudlbbxZ~pC&Bwz3|NjJMrzrpc00Cl4M?~J~ZsMB&000nU zVNP}c00)2o00cMy00V>o00H!CstI!d00ebOL_t(&-tCzCTNG6o$4{lKyXwZe815Jl z9CTS15YSjw0fAO@!GA6!GPbm(aZynUS+a~MkhM%gGg2%uMbeT~u(Gi1Mv0|%xBKO9 z>0HO1*`euqN`9#GeV*Mp=RMzfKRYw$%*?w02>mB@-Srayxna`(2QoRvG{tODdQ$Us#V%*05QWNNzvoFkhYak34c{e3#>PQRKO>UR{WD0Q3+LQ zhaCnGThbIG$TrxZO{h|5ST=xwvh7BYnn0{JVWghQei|4-964rv$c|@tYiGW!Nf;?p zm)8&ip6y<%3$fPn)FrtlO+unwct2a??&p9pWY6f`7jO0WUQs6=dZd@a(s%52dfF?4a{y(mbR|Nbh9ThfOixL;uXMRfo-G{%PRCJZ6KaI6s?<+&YljlyuY^gO^bmGNOSXE52qy zCmbe~@m1H(W|=v8j6gcj%VJRPNSf-tK!5WLA8gd@Vh{i}=lO7%t+)!CyIPr(#}o*f zNa!3;NOy=|_|AQ3QhfQ9@~^_A%W8-Pjm&~2c!;~Qz7B>9nUlph1i4$bx-%%mpW4eH z;NbBD@Xh>T>DvorMAzbvDNGQHnSZ!2g?;qkG)kzZN0KwVa}P7?6HE7-|mL(&ldenaop zW8#)ABqSsxBqSsxBqSsxB=qm-_X!aAV*(@~0&?y2Cm&rV2(J1segFUf07*qoM6N<$ Ef(XObx&QzG diff --git a/tests/references/preferences-gnome-wayland-nested-36.png b/tests/references/preferences-gnome-wayland-nested-36.png index f3e8eeeefaa1ac4a1369b9c25b3d65cf31fdab4b..17d30964be403c1fdc9c1cafb938ba9c4e1db830 100755 GIT binary patch delta 1832 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 KMNUMnLSTY~OrpI2 diff --git a/tests/references/preferences-gnome-wayland-nested-37.png b/tests/references/preferences-gnome-wayland-nested-37.png index 93e98e30c612f23c24ddb6fd8afc38a88a27ee89..6cb7837c2e7ee4e4d7e3e880f3d7296d8bfd21fb 100644 GIT binary patch delta 1528 zcmV5GN0!h8JRDd@=g!voSsx-+b{!qYoxvD1Sa^ z5Q$02a6l%6!2^up#$b-Ig;m?puIt}>&+(yKdv|+EM>|09{vMj&{r%28pZtF3+~4`# zTav|t7y1wwXEO9 zTHHWiU}uxTkvSe%lhBMqDX_NLu@M_x?)6jU!tGemu+uRD0NJZs91UA<=6|hTS6AaS zfUPe)B^w+G_N?k{F%HeIi3b|s$=xHZr1dTU%iBC2F|P7nCf3uonOtZDR|@ zaB7FwRv2q=0KV7WxsfnfOn;CSL-E-`0QNZGoQlsU@cdZneD*omcY|^%Bt88|_&)ezR};1+gFx zPGnyD9RCrBUi%!CA+rwwLLNrCo}4XgK`e*`u^`JVhF6D7GLzGR`B$#RA}MN}S~a9l z>XY#l2M0hvh=>DwV_j_!9*r}p!J$gfGs%Qb#Tcij7Kk2BF|WH|oQY6EguygdwT6TP z;CGTrtIc4|-pNrhrGKRw2nE0+N!e#)z~++~7ah#$=+dSwf$(HZZTsh>!ZId9NX4njk<2ld$m3#6c!w!pxBq;* zv9CghD1)c<29c*BB5~0MGer`@uE=kfHUokEch9&E?k_4c-+!D7d-i;2Lx6IgWx|4? zGI734-;zSEjzB(NhlV!a`Mj^FsC~XY`l0Xg>C%`af=FdnesOAUjqIS?q*EM#_lGY& z#nGbTIPukIUz7fPy2|7pj4h#s4PoSCsDEGS08|;>WE@51@{z&2JO)4pB(94>(aRtt z6J&H0z^M)ZKz|DJnNLB*tq-%*7K~K$0YKqOKNTo|sOC!O#uIFYW zbDGWp5PwOQ6-6#()YuYn&U8(iOQfmSM`2&pJJ623t~Ymhy{6+ zkSFJp?Y~~U5;7bP4KDxy03LKjSaf4=ZEa<4bQ=Izc4lHAG-NX}I5A{7G-WtuIypHm zFf%{W43ppn7aB7yFfuJLHB>P9MbdwY9NPftutOoD=fi;IiJ#l^wF!HSBCGcz;r@bGzgc~etU&VSC% ztE;P>ot=7mdinYJy}i9#TU$;}PN=A;@9*#6;Na=$>8-7;G&D3{Uth+?#!t(O+?(XijwY76|bEc-I$;rvTzrU)gs$E@O&(F`=+S+9?B@$uBu)adBwv9Yns%ga4IJ&cTuP*6~9ZEZX}Jd%=<-{0Ro00H!CstI!d00ZVpL_t(&-tF1>TN6hZ2k^Jj34dCT*2XqOi7Am3 z6|zQPv4ns$goYqmVnnTh1OziCUC;~xSRxKW_-~|?IJzKTyKiJvXWW#C(H^~Mc zALsi6*_nA~KhMtQm;`{d`Cw5&LBWRzAzk6zEC!WXf~TU7mM)vWYWa%Xk&oY4_Q}dm zb4Bzj3Riu$00?}(5Pyh)Aq-&%Lm2Xwk)rGnV@Am8HCZ9Wsu7b|xz_weDr-tq#j>tc zoN85re2H>OnW}4EUz!uLLEXx3%*80LP?@Qy%)Ela6eZC!`Kf|LCG2 z(N~bfaz(tojl4Z0B!=8H1kOkrZ3qsu07Hs)R9LE zlHSD5U2N3|@mwMqwHYr5oQcj~_^`!cJ8PP_q7foJ{Yr~!8m^|^C9Yi$hBoc3gEQJ7 zEG#T6EG+L(%6?q{L+LvA!^?O}qiBc|pjzBi*LivAXAX=+2QfDC z=rIBDkc{->Kb!dn0E>%Y`;+xzpQ3gKJq36c0Dnb;Ob`*69B>T@T_qB7q*dH@wpYX=@D^)idT}SB>%5gH(tfOr|Lldjdv#h0}7c*ojy@AI{*Lx z9&|-mbYpLAZDnqB09bZrVjyB>Wo2VIG!8U2W-&H8IXNyc>v<=NlkWu=8Zs?0GA%PP zR4_C;G&DLjF)J`IIxsL<@#JokAO;sEGA%JOEi*AxFf=+eG&(ggD=;uRFfb^rT+#pl N002ovPDHLkV1jTYVIu$l diff --git a/tests/references/preferences-gnome-xsession-32.png b/tests/references/preferences-gnome-xsession-32.png index 2c7169d39aebee7f4313b85c0e16dbae38c423c8..bb3167adcef1fe9b7404240b768fd6284b1784bd 100755 GIT binary patch delta 4559 zcmZu!c{J4D`+pOmgzS9~N=%Gx>|{%J!emRb?=to+##;&@$tYttvW_i`En|>1do&bf z$-ZQ#tm8M|-}!$3_@3YIo_p@=p7T7fbMC#*eO~vuhgZ=8Z~Q=-09`{(nq^9AX2t7z zN%aE&05Cb)-wy%+nn(bkk_Q0FW&ogoe*EAcOg4?_-cvUXncT<vqxwd5a|9Ly{{H10EMqBO+Nvv)C#WeJv zmBIJV{y+F6;${9Ai6nOrJx5JjvHIFn*bHmR%|N61qX~-AVYsdsPMYhQEDnshcyTB^ zf|!-wqN38IUq^Qp)D^IQP?QhJK%UCUW=_p$QGBU*xZd(ZUI99%?(CfD6UApXb7Tdegnws_K=;@AFFT-Ox zbtd4AjsTRsOeg~qU*u)9>J8dZqICowJqWhx9ptF5e;O7FB9DhdxI8@pK3a#ZXU~g= zv&uev2o4H57C4@t!QqB;T4@23J$5_J)Zky`R)sBj6hHwy-8#=sG9769KwI4)!P zR-5d>O9`ah?ck&zUw!3BJm~bDzd|q1;aAD@!sDsaLR9DoQS=_O?r7?Q$k7obUNa_| zbo?VZY5E-G`;)>6eEx{aOl|p4+SL8!OQiQ!)gRlL?N^C-@A1-e{bnm4<&aS-?vCNC z*6pr7p;aYN-DLlyU{E{B_4}0?9v0R^OwDLpq?G&V3mP^?5n+*H!?;>$xv!?a!Tyfb zmbVI>rCf%ux2A!8cj@V{fBKBgB#R9RX|6_ z8l9QD1q-Q4tUGAYXccC?Bz!hMIr)z693~?Z>aAB`!0(MfY{oqRBA0Cm?3}Z?jmMtA zo4x`LvB#AW`=28_6moX(geeRX50}Bex~zZ}CNIh;&c`=s+_bv3>M-K0X;9Uha6bEq z1llt4%Aan{>awVuETdwI1S^hNdXl_uj;RzVYiVh<7HzpmaEATm)tN}P3c*3X%zS8C zGC@R;)I`c^H*U+n=2ZxqJIO_r>?d9SR%$Bjs@=2t;3jryRKo}Od_G@#eyF>KaUFhP zlyirlwtYCbb~Af@CHdyx&7Zy-#|ICJhr!3q;YYuZ5+G5p>F9~2GlUuk&TcyipzUkN z1%N7w9SE^BqXzPkT66LYz>&CJNoB#1CLcaxp@#Q$_ND>zE%FR{E0I4|7s zUE}i_NyxLf<)v>5`+e#}hdwYbc+nakgLnoS$d_O)c z9tI+d@nJ>-?XV9{%B9okaLCww_+G-Z(X*lakZ}@ zGD~I(ACG|9g#{vq+* zmu#4n%-Jl#J%N2-E1!$tjx^8R72JOaay`YlVdN4n{vU{}u&RUi6i8P4LgE>G11W%X z>q=8dNtZ5=cC>S++EV(bXWHut+lPwcPI8{(Is0d1fh{5VpQd5>!OF_BvjXJ(t$`~X zqK5^oybD`Ewt}3CpUxq=%=|JHr7$FX^5om)%h+|)Xw8mybZu`+#I~{3af?5P7`5S3 z&-o->fQf|*?F&nYPmD`c3SV%0a*FEZ|Fy^7H6wD{9khtPTYby<2l1MeMv=jJ&^)6< zb*;Dk?JfKo1 zj~K~AhQ)+7ijwvd#>eaZ4-7NG%F@uc^~m*U;znIvUGERD!Lu92`AWUMo@=~Pp(@NZ z#O-s2x18x1vBVMl-n^I{9MvG?eQk4fr0}ir_onbMxvTbh>Dmln17fh#*D>I>nzp+! z`TYpPt6$CIZ$L~H*-F;!ecH#8gPO|Du0MZn@6x9fMv8JN*MSZlo-LfNd@L#wyZ{w- zT<%#|SOV)!LcG^lg;Zw7yO-uCa8Jr-g*yzVslGS*$OWrz5|9?_dXTT3@oY>+hDyEsP>_Ox3V5qm zXbJU5G2vs%QV7mF9Li2jOV^5bsTg_m376{|1{?LMm*25tuYntdQz45Ac~uOq-*_F*d( ze7noTBjZ>>!yvKX-k1T$PFxH_v7) z{;zd!KL;%pdGhksT-E2`H8DSJY_p->EK==ZokiZ?>P)tIWOkP;z#m+h z8F!SG>jlqr2pCMdvY-b;X4kQ#d;izti&781mZbAGUAgvtXw%M>qZJaQJ-Jzd#kS;! zhawcmZN{4$sDGAZ*+ff<3>lvQ;R=l zYO2Xa|0&-hX5L&p&d|I-03S+!$t2@L>9(yY;on=ZW?4Q$W7~FjzIV)jEdO@+Z)lUz z-qsPq-+wxprim(;6esv@eA*LpVtH{1V4~7AX6^9d?lED_A9(M1EegZ=+Fl;fx%iNQ z)6K4PV~gguA(Khjo314w5;PD_*6TF9V#Kw+{+*j)n3z@bD%Dm%msyxC58mqxPdDhc zlcZ6Q-!T{nun2iKQnRLpT1e>`Gg~a|E^>*{>Ygfd0MsZy3piBkxOFZn;G1r)c%Ivj z{$fsqW1EB5W8hc`Nt_zfTLjw!4OD^gwop`F<)#gNcbT8Do_MAvsO%crn?3GInUj7i z#(rvZR~N-f7cHRM$oMz3LRC)D^B>wM`s-_PQfctGmwYb~;w(349X>Cj1WZhxHniq8 zXa|fW@zKsL$YmoQaTEA@#4=OGw@xL>orLSs!@hyodW#bzf6~+HDc&}{ry=Ix-x#ruh@N3dvsD7 z4=cR;43_@o`HpaZo7zuHAq3m#KcMEldu};m(eB(FquQLDoFPx2zK2XMy^*r+nRGxX z7(+drB@DtwHEse>L44jX>;)d&=;-Lc;NZz5pP>Z32n6EBI}HX(6-eMX`QE*J+H$qi z4yQSsb8s5kXpIO6*hk&cfAZu>d3iZAGc(cTMzY)LXkoa@43Q`egVpSQ$e%8O($Ue? z*VjAtyru^7jO9U6xQK`d7gy$oR#Ha)Vx4LZEI}YW+y@3F^9O#PtvCP|2Cj1{Kzj`F$BP%lEE{QQcr4PVxrXvlpE~9 zb|5J!DFI9#`D?K`g{J|?@DGEY6GRPKwr6vMQ{N(zATMBC9}^qvJz1;EvvRnLUt~4SpZCL)N|O5*B_$=P z)G=yNVyev5mdf+1x^-~uTlsM?R_b1Ga4>xb>2RL$^5q16Fz>)x-@?KI_}tfr>U9G6 zSc5_k77h+`Q}|#GG3ye~!DAdY=hNH@s>YuchUHJ1z8#&xa|if6O~9vUD0_K%k-gGT zC}#4FWMeaX{P>I<5sg@eIwOVf!)*)()7;!_lCKpS8tUxi@NTqNa=%I zO_b9E4P~_J#i_?(A(a>SQgnHstH{I$xaTyHL?Us>NX<}BuLg(HH!`wqjUeD~dn+UP zN^4F@+zK^rBkvP9#D!Vo-M9kj+B%`au*o6s%g61V^QENvQN0zS$ zr>&bon?KVtGS;@Xz~!OrtgNir+1a+Xw)>;O_4hPD)I!HDyb!JnbUVSqY7T|iRWu|z z-F1?NgnkD?p-?B-MCD_AX=!OH^r7GW%E-{y;KS?9dWBH&k7cI9SF`NfrPNJo!w77; z%y-o<$LEP{cG&!Nb{3sCKnbkp6310arKMpMtiP`9H7&E!k<o zLEW||laQqQB$_TBiw~>a?BoOlt_NsZ1~__qc{w8j0Lvg32R?Zxd1(hp8A+JDqr9Sm zf|vx(fRUQ)dFx-EPWA!LijIEHWB_0iFey<9n5cw|sieH3jJ%?hj)aJWgrbB5)1_Xn h|6+J~JGr}r{y&U=6YMQ~i^&8)SM&b8%DZ+^{{vXP#ytQ4 delta 2206 zcmY+Ec{tRI8plT=4IMPLCWkPIY0g-p8B5A`Ft(a3!;p1S4JHXu{3J`VB{cRC&6Pcg z%2pZ-S3|OnEs|~Q#V}(#I``cBJoo$8=Xt;Xz0do8$goY($F~3x4>zko5a>`i2*is9 zfeuE3Ks;;2;=}$Rkbte3k-p8Hp~W2H#T4c-de`v-YSBt2gobOUWz>tWu+HhpxhKZc) z*%9vUwJ(LWR+oUi?&pSkVm6zbcM3hXjj32s!`9a4?L~9LHIcS^J5b6Nry`7VzsaY) zlQF+|*A9CpH{GwRTq?mabWzqtA@UIh2?W1Y`C1!Xa#_S@JXaAiKiM;4{ zomnR9OVLdZem5JDP`$nk5uPV|=uW^8t>0Q?>GaV?fBHAY5eb>;7I)_G@FG+EoQCeU z1x!8>!+#Q99kQ6YF?V}-%GdWwZf^6X45wYj8_m_b0Fgv8`EXJHy9>wL;*xLYN|8@v*vpAfR(^ME5icXX@ z@A@DTEh2w)?Wc3)b&s~>)X6zOxqZ2Q(lxu&qSVa(N-pAzm54$9uH=ns$31szDmL_9 z{oP!)qmv?MzJ&BcqeZoB!XwQ{o9sW`MC;GYs-|Om4j$a*jC8FR)M#iM%zlZAFlMt` ztF&}IZh;kqul*6rh&24;y%_ul+^f4 z7JKGp(-mj^x!E0IWI}c z$j>x(pfiN-=SGJJqfl}FPi{&}3Jd8j&8kYds!Hs=sorT3T;1HBd}dbSH$ zTKWRrFM56OH7iyAGJ;Vw1qH2{9}9~Mb`@atGhQE`HOG-L?Z@AE<2^~T#~G{cl@Dod z&$5=r>SQ63Gs`oS&?iLE{=vaPz;{4g>`H3KcXMZF>)f`yL10is*j&X18e zo>)DPmOkPw&K-;IBoPCXqkB?SDCAl}f4gHUEjK| z@73k$CUtd}AB}iLAJ6(Sr*xahyJ5tC?{Q7(%+3zHdWg)3&LKFcxHK-X=8mlV5h02$BCnIN#siVmRRTorNUNXL+C9>Mgnq>UjOuX=!&SWqn*;Uj9Hla0AJ(WxSr2 zC3oaNr2kd;^y$;=Y-tjSq@5!pDypWcn%8$D4MV_UpTxu*+6VOv0)gOIW>?a8l|XQl ziguIAu+Y1+l4n>gSPm)b~^ymv6 z;zp%X`FMF>S62rF1}+U&(ijZOA{$mY^QD`ixp^E8p?7mUyr7_<9AGyY2*eu6J1gku z4EOZ(Y{~}(1?@~{f}a{ZOFs{Ud3Y3*yTH@5(P*dlVZbQpT2K(mV79x!q)JrcnA~%f zQ`3u!WfcjE$)>yq^bHMZ@SqFx%qkS_JgToHcEZ%G}=MhOD;FW`Eo(G1`1Vyt8_=66SAZ^zVd7@v9IW) zoL5OUg`Yl+$K%%x%gf6H0sbi7g(`l-RiKVc$! z-Y>1Kt=ZVycX+;v5|msTd6&}UI*#s~`I(cGV=SMXmIjE&&>U)SD;t<9iS_sPDy3m0 zCCP1VraN!;g;_|Y`n_|Krk4~K=jsN#69_F=t7soTK8)pZxxOQB<;WdAK0cF^lkJ|b z{wz>dQCXg!S4e5+A{2L|tck9z`+4rwV5mpwa<3d38bV7arlh1?IPusN22HrS!(Eq? dlWUbU-<6%9epk~PsPY8u$IRHusNBFc;xAhPJ30UW diff --git a/tests/references/preferences-gnome-xsession-33.png b/tests/references/preferences-gnome-xsession-33.png index f8ea6124bd360b834b747f11ebd56e6648174723..63cca045058804ee41c0d0015c03468b435572e3 100755 GIT binary patch literal 4301 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 delta 2491 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 HA3XgJZbfEO delta 3029 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 delta 2998 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 P&`kTDfkycq+wlJYJEGoP diff --git a/tests/references/preferences-gnome-xsession-36.png b/tests/references/preferences-gnome-xsession-36.png index 77522f3d185e41732f1cd9ffb75283a4d63ca080..48cfa936aa89a1c4f50832fe48bd2f71e90faba8 100755 GIT binary patch delta 1805 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 N002ovPDHLkV1iF{Uwr@o From 89e056084a65b809f25292818d141b27b624076b Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Sun, 5 Feb 2023 20:19:19 +0100 Subject: [PATCH 43/67] :wrench: Do not fiddle with animation times --- extension.js | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/extension.js b/extension.js index 431c11c..70da150 100644 --- a/extension.js +++ b/extension.js @@ -125,11 +125,6 @@ class Extension { this._origWaitForOverviewToHide = WindowManager.prototype._waitForOverviewToHide; this._origDestroyWindowDone = WindowManager.prototype._destroyWindowDone; - // 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; - - // ------------------------------------------------ patching the window-open animation // Here we add an effect to the window-open animation. This is done whenever a new @@ -370,9 +365,6 @@ class Extension { WindowManager.prototype._waitForOverviewToHide = this._origWaitForOverviewToHide; WindowManager.prototype._destroyWindowDone = this._origDestroyWindowDone; - imports.ui.windowManager.DESTROY_WINDOW_ANIMATION_TIME = this._origWindowTime; - imports.ui.windowManager.DIALOG_DESTROY_WINDOW_ANIMATION_TIME = this._origDialogTime; - if (WindowPreview) { WindowPreview.prototype._deleteAll = this._origDeleteAll; WindowPreview.prototype._restack = this._origRestack; @@ -424,8 +416,6 @@ class Extension { // effects will be selected. This will also tweak the transitions of the given actor // (e.g. scale it up if required). _setupEffect(actor, forOpening) { - // In case we return early, make sure that the animation times are reset properly. - this._fixAnimationTimes(forOpening, null); // For now, we only add effects to normal windows and dialog windows. const isNormalWindow = actor.meta_window.window_type == Meta.WindowType.NORMAL; @@ -653,26 +643,6 @@ 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(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(forOpening, duration) { - if (!forOpening) { - imports.ui.windowManager.DIALOG_DESTROY_WINDOW_ANIMATION_TIME = - duration != null ? duration : this._origDialogTime; - 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 From 142f6e9e3c119d82d3f02b428c4a6de53a5655ca Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Sun, 5 Feb 2023 20:19:51 +0100 Subject: [PATCH 44/67] :sparkles: Apply clang-format --- src/WindowPicker.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/WindowPicker.js b/src/WindowPicker.js index 07ebdb8..61cbc7d 100644 --- a/src/WindowPicker.js +++ b/src/WindowPicker.js @@ -63,7 +63,8 @@ var WindowPicker = class WindowPicker { } let wmClass = 'window-not-found'; - if (actor.toString().includes('WindowActor') && actor.meta_window.get_wm_class() != "") { + if (actor.toString().includes('WindowActor') && + actor.meta_window.get_wm_class() != '') { wmClass = actor.meta_window.get_wm_class(); } From 1c8ed8df9226624b6659b0b8aec9d5b9c0ff91b2 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Sun, 5 Feb 2023 20:29:29 +0100 Subject: [PATCH 45/67] :memo: Add some comments --- prefs.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/prefs.js b/prefs.js index 0b6ef17..4867aad 100644 --- a/prefs.js +++ b/prefs.js @@ -349,6 +349,11 @@ var PreferencesDialog = class PreferencesDialog { header.pack_start(menu); header.set_title_widget(this._builder.get_object('profile-button')); + // GNOME Shell extensions are forced to use a AdwPreferencesWindow. This already + // includes a Gtk.ScrolledWindow as well as an Adw.Clamp. For the profile + // editing, we want to use an Adw.Flap which reveals itself from the top. This + // needs to be inserted in the widget hierarchy above the Adw.Clamp, else it + // would look ugly. Therefore, we fiddle around with the internal widgets... const flap = this._builder.get_object('profile-editor-flap'); const clamp = this._findWidgetByType(window.get_content(), Adw.Clamp); const viewport = clamp.get_parent(); @@ -901,6 +906,8 @@ function buildPrefsWidget() { return dialog.getWidget(); } +// If using libadwaita, this method is called. In this case, the primary widget of the +// preferences dialog is an Adw.PreferencesPage, which we directly add to the window. function fillPreferencesWindow(window) { window.set_default_size(700, 700); var dialog = new PreferencesDialog(); From 33f4410a5b73afdfe428115397512eeb99a86aff Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Mon, 6 Feb 2023 20:25:26 +0100 Subject: [PATCH 46/67] :memo: Add some comments --- prefs.js | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/prefs.js b/prefs.js index 4867aad..5146c91 100644 --- a/prefs.js +++ b/prefs.js @@ -71,17 +71,17 @@ var PreferencesDialog = class PreferencesDialog { this._resources = Gio.Resource.load(Me.path + '/resources/burn-my-windows.gresource'); Gio.resources_register(this._resources); - // Load the CSS file for the settings dialog. + // Load the CSS file for the settings dialog. If using libadwaita, we do not need an + // additional style sheet. if (!utils.isADW()) { - const styleProvider = Gtk.CssProvider.new(); + const provider = Gtk.CssProvider.new(); if (utils.isGTK4()) { - styleProvider.load_from_resource('/css/gtk4.css'); + provider.load_from_resource('/css/gtk4.css'); Gtk.StyleContext.add_provider_for_display( - Gdk.Display.get_default(), styleProvider, - Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); + Gdk.Display.get_default(), provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); } else { - styleProvider.load_from_resource('/css/gtk3.css'); - Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(), styleProvider, + provider.load_from_resource('/css/gtk3.css'); + Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(), provider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); } } @@ -141,7 +141,8 @@ var PreferencesDialog = class PreferencesDialog { } colorSchemeRow.set_visible(utils.shellVersionIsAtLeast(42, 0)); - // Wire up the window picker of the profile editor. + // Wire up the window picker of the profile editor. Whenever the app-chooser button is + // clicked, we call a method of the extension which will initiate the window picking. this._builder.get_object('profile-choose-app-button').connect('clicked', () => { Gio.DBus.session.call('org.gnome.Shell', '/org/gnome/shell/extensions/BurnMyWindows', @@ -149,17 +150,20 @@ var PreferencesDialog = class PreferencesDialog { null, null, Gio.DBusCallFlags.NO_AUTO_START, -1, null, null); }); + // If the window picking was successful, this D-Bus signal will be emitted. this._dbusConnection = Gio.DBus.session.signal_subscribe( 'org.gnome.Shell', 'org.gnome.shell.extensions.BurnMyWindows', 'WindowPicked', '/org/gnome/shell/extensions/BurnMyWindows', null, Gio.DBusSignalFlags.NONE, (conn, sender, obj_path, iface, signal, params) => { const val = params.get_child_value(0).get_string()[0]; - if (val != 'window-not-found') { this._builder.get_object('profile-app').text = val; } }); + // If using libadwaita, the visibility of the profile-editor Adw.Flap is controlled + // using bindings in the ui file. On GTK3 and GTK4 we have to wire up this toggling + // here since we are using a Gtk.Stack instead of an Adw.Flap. if (!utils.isADW()) { const profileEditorButton = this._builder.get_object('edit-profile-button'); profileEditorButton.connect('toggled', b => { From 26e7f6bb00bacdacb5deefb2842428d90046ec2c Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Wed, 8 Feb 2023 05:33:06 +0100 Subject: [PATCH 47/67] :wrench: Show toast if BMW got updated --- prefs.js | 44 ++++++++++++++++++- ...ell.extensions.burn-my-windows.gschema.xml | 6 +++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/prefs.js b/prefs.js index 5146c91..e483e47 100644 --- a/prefs.js +++ b/prefs.js @@ -337,6 +337,29 @@ var PreferencesDialog = class PreferencesDialog { this._loadActiveProfile(); this._updateProfileMenu(); + // Show an Adw.Toast or a Gtk.InfoBar whenever Burn-My-Windows was updated. We use a + // small timeout so that it is not shown instantaneously. + const lastVersion = this._settings.get_int('last-version'); + if (lastVersion < Me.metadata.version) { + this._showUpdateInfoTimeout = + GLib.timeout_add(GLib.PRIORITY_DEFAULT, 2000, () => { + this._showUpdateInfoTimeout = 0; + + const toast = Adw.Toast.new(_('Burn-My-Windows has been updated!')); + toast.set_button_label(_('View Changelog')); + toast.set_action_name('prefs.changelog'); + toast.set_timeout(0); + + toast.connect( + 'dismissed', + () => this._settings.set_int('last-version', Me.metadata.version)); + + window.add_toast(toast); + + return false; + }); + } + // Populate the menu with actions. const group = Gio.SimpleActionGroup.new(); window.insert_action_group('prefs', group); @@ -390,7 +413,6 @@ var PreferencesDialog = class PreferencesDialog { // clang-format off addURIAction('homepage', 'https://github.com/Schneegans/Burn-My-Windows'); - addURIAction('changelog', 'https://github.com/Schneegans/Burn-My-Windows/blob/main/docs/changelog.md'); addURIAction('bugs', 'https://github.com/Schneegans/Burn-My-Windows/issues'); addURIAction('new-effect', 'https://github.com/Schneegans/Burn-My-Windows/blob/main/docs/how-to-create-new-effects.md'); addURIAction('translate', 'https://hosted.weblate.org/engage/burn-my-windows/'); @@ -398,6 +420,21 @@ var PreferencesDialog = class PreferencesDialog { addURIAction('donate-github', 'https://github.com/sponsors/Schneegans'); // clang-format on + // The changelog action is a bit different, as it may get activated when the + // view-changelog button is pressed which is shown in an Adw.Toast or a + // Gtk.InfoBar whenever Burn-My-Windows gets updated. To ensure that the + // notification is shown only once, we have to store the current version of + // Burn-My-Windows in the settings. + const changelogAction = Gio.SimpleAction.new('changelog', null); + changelogAction.connect('activate', () => { + Gtk.show_uri( + null, + 'https://github.com/Schneegans/Burn-My-Windows/blob/main/docs/changelog.md', + Gdk.CURRENT_TIME); + this._settings.set_int('last-version', Me.metadata.version) + }); + group.add_action(changelogAction); + // Add the about dialog. const aboutAction = Gio.SimpleAction.new('about', null); aboutAction.connect('activate', () => { @@ -584,6 +621,11 @@ var PreferencesDialog = class PreferencesDialog { // Disconnect from the window-picker API. Gio.DBus.session.signal_unsubscribe(this._dbusConnection); + + // If the settings dialog got closed too quickly, this may not have been shown. + if (this._showUpdateInfoTimeout > 0) { + GLib.source_remove(this._showUpdateInfoTimeout); + } }); // Show the widgets on GTK3. 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 c8a7593..8739d9c 100644 --- a/schemas/org.gnome.shell.extensions.burn-my-windows.gschema.xml +++ b/schemas/org.gnome.shell.extensions.burn-my-windows.gschema.xml @@ -31,6 +31,12 @@ SPDX-License-Identifier: CC0-1.0 If set to true, all animations will show only one still frame to allow for continuous integration tests. + + 0 + Last Version + Used to check whether the extension got updated. + + \ No newline at end of file From 3c7849cc1abed7dee8ede222ae05cfdc33103ae2 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Wed, 8 Feb 2023 06:14:57 +0100 Subject: [PATCH 48/67] :wrench: Port update notification to GTK4 --- prefs.js | 29 +++++++----- resources/ui/gtk4/prefs.ui | 90 ++++++++++++++++++++++++++------------ 2 files changed, 80 insertions(+), 39 deletions(-) diff --git a/prefs.js b/prefs.js index e483e47..a510476 100644 --- a/prefs.js +++ b/prefs.js @@ -345,16 +345,25 @@ var PreferencesDialog = class PreferencesDialog { GLib.timeout_add(GLib.PRIORITY_DEFAULT, 2000, () => { this._showUpdateInfoTimeout = 0; - const toast = Adw.Toast.new(_('Burn-My-Windows has been updated!')); - toast.set_button_label(_('View Changelog')); - toast.set_action_name('prefs.changelog'); - toast.set_timeout(0); - - toast.connect( - 'dismissed', - () => this._settings.set_int('last-version', Me.metadata.version)); - - window.add_toast(toast); + if (utils.isADW()) { + const toast = Adw.Toast.new(_('Burn-My-Windows has been updated!')); + toast.set_button_label(_('View Changelog')); + toast.set_action_name('prefs.changelog'); + toast.set_timeout(0); + + toast.connect( + 'dismissed', + () => this._settings.set_int('last-version', Me.metadata.version)); + + window.add_toast(toast); + }else { + const infoBar = this._builder.get_object("update-info"); + infoBar.connect("response", i => { + this._settings.set_int('last-version', Me.metadata.version); + i.set_revealed(false); + }); + infoBar.set_revealed(true); + } return false; }); diff --git a/resources/ui/gtk4/prefs.ui b/resources/ui/gtk4/prefs.ui index 19b6aa7..1f54c70 100644 --- a/resources/ui/gtk4/prefs.ui +++ b/resources/ui/gtk4/prefs.ui @@ -37,50 +37,82 @@ SPDX-License-Identifier: GPL-3.0-or-later over-down-up - - never - - - - vertical - 20 - 20 - 20 - 20 - 5 + + vertical + + + info + false + true - Effect Settings - start - + Burn-My-Windows has been updated! + 6 - - - - If multiple are selected, one is chosen randomly. - start + + + View Changelog + prefs.changelog + + update-info-button + + + + + + + never + true + + + + vertical + 20 + 20 + 20 + 20 + 5 - - - - none + + Effect Settings + start + + + + + If multiple are selected, one is chosen randomly. + start + + + + + + 6 + + + none + + + + + - + + - - - + + From 2dd771aac464f81c6c91ec2ff927d61502be610d Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Wed, 8 Feb 2023 07:50:05 +0100 Subject: [PATCH 49/67] :wrench: Port version check to GTK3 --- resources/ui/gtk3/prefs.ui | 104 +++++++++++++++++++++++++------------ 1 file changed, 71 insertions(+), 33 deletions(-) diff --git a/resources/ui/gtk3/prefs.ui b/resources/ui/gtk3/prefs.ui index 5c4c3cd..9c6e750 100644 --- a/resources/ui/gtk3/prefs.ui +++ b/resources/ui/gtk3/prefs.ui @@ -53,47 +53,85 @@ SPDX-License-Identifier: GPL-3.0-or-later over-down-up - - never + + vertical + - - - vertical - 20 - 20 - 20 - 20 - 5 - - - - Effect Settings - start - - - - - - - If multiple are selected, one is chosen randomly. - start - - - - - + + info + false + true + + - - none + + Burn-My-Windows has been updated! + 6 - + + + + + View Changelog + prefs.changelog + + + + + + update-info-button + + + + + never + true + + + + vertical + 20 + 20 + 20 + 20 + 5 + + + + Effect Settings + start + + + + + + + If multiple are selected, one is chosen randomly. + start + + + + + + + + none + + + + + + + + + From 3020fec2bc3999f0e10057b1fde9cadf909eb8b9 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Wed, 8 Feb 2023 09:03:03 +0100 Subject: [PATCH 50/67] :wrench: Add arrow to profile chooser button on GTK3 --- resources/ui/gtk3/prefs.ui | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/resources/ui/gtk3/prefs.ui b/resources/ui/gtk3/prefs.ui index 9c6e750..f7999fd 100644 --- a/resources/ui/gtk3/prefs.ui +++ b/resources/ui/gtk3/prefs.ui @@ -26,9 +26,27 @@ SPDX-License-Identifier: GPL-3.0-or-later center 1 - + profile-menu 1 + + + 1 + 6 + + + 1 + + + + + pan-down-symbolic + 1 + 1 + + + + From dd5801c0f7aabc6a0e2cf136555142f5c154e8bd Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Wed, 8 Feb 2023 10:33:03 +0100 Subject: [PATCH 51/67] :wrench: Support multiple apps per profile --- extension.js | 6 +++++- prefs.js | 30 +++++++++++++++++++++++------- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/extension.js b/extension.js index 70da150..d34bdac 100644 --- a/extension.js +++ b/extension.js @@ -490,7 +490,11 @@ class Extension { // If that was the case, we also check the application name. if (matches && profileApp != '') { const app = actor.meta_window.get_wm_class().toLowerCase(); - matches = app == profileApp.toLowerCase(); + + // Split app names at |, remove any whitespace, and transform to lower case. + const profileApps = + profileApp.split('|').map(item => item.trim().toLowerCase()); + matches = profileApps.includes(app); } // If the profile is still matching, we also check the color scheme. diff --git a/prefs.js b/prefs.js index a510476..8575c18 100644 --- a/prefs.js +++ b/prefs.js @@ -150,14 +150,30 @@ var PreferencesDialog = class PreferencesDialog { null, null, Gio.DBusCallFlags.NO_AUTO_START, -1, null, null); }); - // If the window picking was successful, this D-Bus signal will be emitted. + // If the window picking was successful, this D-Bus signal will be emitted. If a + // window was picked, we add it to the list of window name. this._dbusConnection = Gio.DBus.session.signal_subscribe( 'org.gnome.Shell', 'org.gnome.shell.extensions.BurnMyWindows', 'WindowPicked', '/org/gnome/shell/extensions/BurnMyWindows', null, Gio.DBusSignalFlags.NONE, (conn, sender, obj_path, iface, signal, params) => { const val = params.get_child_value(0).get_string()[0]; if (val != 'window-not-found') { - this._builder.get_object('profile-app').text = val; + const entry = this._builder.get_object('profile-app'); + + // Split the current value at each |, trim spaces, and remove empty components. + let apps = entry.text.split('|').map(item => item.trim()).filter(v => v != ''); + + // If the list is empty, we simply use the name of the picked window. + if (apps.length == 0) { + entry.text = val; + } else { + + // Else we append the new application name, remove any duplicates, and sort + // the resulting list alphabetically. + apps.push(val); + apps = [...new Set(apps)].sort(); + entry.text = apps.join(' | '); + } } }); @@ -350,15 +366,15 @@ var PreferencesDialog = class PreferencesDialog { toast.set_button_label(_('View Changelog')); toast.set_action_name('prefs.changelog'); toast.set_timeout(0); - + toast.connect( 'dismissed', () => this._settings.set_int('last-version', Me.metadata.version)); - + window.add_toast(toast); - }else { - const infoBar = this._builder.get_object("update-info"); - infoBar.connect("response", i => { + } else { + const infoBar = this._builder.get_object('update-info'); + infoBar.connect('response', i => { this._settings.set_int('last-version', Me.metadata.version); i.set_revealed(false); }); From 8c163f3a383c005c0c14a7c6d73e04fd6ea7a961 Mon Sep 17 00:00:00 2001 From: Simon Schneegans Date: Wed, 8 Feb 2023 16:31:13 +0100 Subject: [PATCH 52/67] :wrench: Unify fire settings keys --- resources/ui/adw/fire.ui | 14 +++++++------- resources/ui/gtk3/fire.ui | 16 ++++++++-------- resources/ui/gtk4/fire.ui | 12 ++++++------ ...xtensions.burn-my-windows-profile.gschema.xml | 6 +++--- src/effects/Fire.js | 16 ++++++++-------- 5 files changed, 32 insertions(+), 32 deletions(-) diff --git a/resources/ui/adw/fire.ui b/resources/ui/adw/fire.ui index b424437..f278814 100644 --- a/resources/ui/adw/fire.ui +++ b/resources/ui/adw/fire.ui @@ -69,7 +69,7 @@ SPDX-License-Identifier: GPL-3.0-or-later left 300 - + 3 0.1 0.01 @@ -79,7 +79,7 @@ SPDX-License-Identifier: GPL-3.0-or-later - + edit-clear-symbolic center Reset to Default Value @@ -102,7 +102,7 @@ SPDX-License-Identifier: GPL-3.0-or-later left 300 - + 2.0 -2.0 0.01 @@ -112,7 +112,7 @@ SPDX-License-Identifier: GPL-3.0-or-later - + edit-clear-symbolic center Reset to Default Value @@ -128,14 +128,14 @@ SPDX-License-Identifier: GPL-3.0-or-later 3D Noise Creates a more dynamic fire but requires more GPU power. - flame-3d-noise + fire-3d-noise - + center - + edit-clear-symbolic center Reset to Default Value diff --git a/resources/ui/gtk3/fire.ui b/resources/ui/gtk3/fire.ui index a047ffe..010fb6a 100644 --- a/resources/ui/gtk3/fire.ui +++ b/resources/ui/gtk3/fire.ui @@ -14,14 +14,14 @@ SPDX-License-Identifier: GPL-3.0-or-later 100 - + 3 0.1 0.01 0.1 - + 2.0 -2.0 0.01 @@ -140,11 +140,11 @@ SPDX-License-Identifier: GPL-3.0-or-later 2 left 300 - flame-scale + fire-scale - + edit-clear-symbolic @@ -184,11 +184,11 @@ SPDX-License-Identifier: GPL-3.0-or-later 2 left 300 - flame-movement-speed + fire-movement-speed - + edit-clear-symbolic @@ -240,14 +240,14 @@ SPDX-License-Identifier: GPL-3.0-or-later - + end center 8 - + edit-clear-symbolic diff --git a/resources/ui/gtk4/fire.ui b/resources/ui/gtk4/fire.ui index 2f1564c..9b77741 100644 --- a/resources/ui/gtk4/fire.ui +++ b/resources/ui/gtk4/fire.ui @@ -105,7 +105,7 @@ SPDX-License-Identifier: GPL-3.0-or-later left 300 - + 3 0.1 0.01 @@ -115,7 +115,7 @@ SPDX-License-Identifier: GPL-3.0-or-later - + edit-clear-symbolic Reset to Default Value