diff --git a/SOURCES/0001-Add-move-clock-extension.patch b/SOURCES/0001-Add-move-clock-extension.patch deleted file mode 100644 index d57434f..0000000 --- a/SOURCES/0001-Add-move-clock-extension.patch +++ /dev/null @@ -1,101 +0,0 @@ -From 13ea90a5f6f5e73d83a2ab04ea70c6263f6d8f5f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Florian=20M=C3=BCllner?= -Date: Tue, 21 May 2024 19:01:30 +0200 -Subject: [PATCH] Add move-clock extension - ---- - extensions/move-clock/extension.js | 38 ++++++++++++++++++++++++++ - extensions/move-clock/meson.build | 5 ++++ - extensions/move-clock/metadata.json.in | 10 +++++++ - meson.build | 1 + - 4 files changed, 54 insertions(+) - create mode 100644 extensions/move-clock/extension.js - create mode 100644 extensions/move-clock/meson.build - create mode 100644 extensions/move-clock/metadata.json.in - -diff --git a/extensions/move-clock/extension.js b/extensions/move-clock/extension.js -new file mode 100644 -index 00000000..571567f7 ---- /dev/null -+++ b/extensions/move-clock/extension.js -@@ -0,0 +1,38 @@ -+/* exported enable disable */ -+const Main = imports.ui.main; -+const SessionMode = imports.ui.sessionMode; -+ -+class MoveClockExtension { -+ enable() { -+ const panel = SessionMode._modes['user'].panel; -+ -+ const clockIndex = panel.center.indexOf('dateMenu'); -+ this._modified = clockIndex !== -1; -+ -+ if (!this._modified) -+ return; -+ -+ panel.center.splice(clockIndex, 1); -+ panel.right.splice(-1, 0, 'dateMenu'); -+ -+ Main.panel._updatePanel(); -+ } -+ -+ disable() { -+ if (!this._modified) -+ return; -+ -+ const panel = SessionMode._modes['user'].panel; -+ const clockIndex = panel.right.indexOf('dateMenu'); -+ -+ if (clockIndex !== -1) -+ panel.right.splice(clockIndex, 1); -+ panel.center.unshift('dateMenu'); -+ -+ Main.panel._updatePanel(); -+ } -+} -+ -+function init() { -+ return new MoveClockExtension(); -+} -diff --git a/extensions/move-clock/meson.build b/extensions/move-clock/meson.build -new file mode 100644 -index 00000000..48504f63 ---- /dev/null -+++ b/extensions/move-clock/meson.build -@@ -0,0 +1,5 @@ -+extension_data += configure_file( -+ input: metadata_name + '.in', -+ output: metadata_name, -+ configuration: metadata_conf -+) -diff --git a/extensions/move-clock/metadata.json.in b/extensions/move-clock/metadata.json.in -new file mode 100644 -index 00000000..d872ab63 ---- /dev/null -+++ b/extensions/move-clock/metadata.json.in -@@ -0,0 +1,10 @@ -+{ -+"extension-id": "@extension_id@", -+"uuid": "@uuid@", -+"settings-schema": "@gschemaname@", -+"gettext-domain": "@gettext_domain@", -+"name": "Move notification menu", -+"description": "Move the notification menu to the right", -+"shell-version": [ "@shell_current@" ], -+"url": "@url@" -+} -diff --git a/meson.build b/meson.build -index 7e6ed3e8..ea6efb76 100644 ---- a/meson.build -+++ b/meson.build -@@ -53,6 +53,7 @@ all_extensions += [ - 'dash-to-dock', - 'dash-to-panel', - 'gesture-inhibitor', -+ 'move-clock', - 'native-window-placement', - 'panel-favorites', - 'systemMonitor', --- -2.45.1 - diff --git a/SOURCES/0001-Add-move-notifications-extension.patch b/SOURCES/0001-Add-move-notifications-extension.patch new file mode 100644 index 0000000..38dcc86 --- /dev/null +++ b/SOURCES/0001-Add-move-notifications-extension.patch @@ -0,0 +1,231 @@ +From 50c6c0c2137fded5f89be5bbee2292071e464cd2 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Tue, 21 May 2024 19:01:30 +0200 +Subject: [PATCH] Add move-notifications extension + +--- + extensions/move-notifications/extension.js | 49 +++++++++++ + extensions/move-notifications/meson.build | 8 ++ + .../move-notifications/metadata.json.in | 10 +++ + ....extensions.move-notifications.gschema.xml | 14 +++ + extensions/move-notifications/prefs.js | 86 +++++++++++++++++++ + meson.build | 1 + + 6 files changed, 168 insertions(+) + create mode 100644 extensions/move-notifications/extension.js + create mode 100644 extensions/move-notifications/meson.build + create mode 100644 extensions/move-notifications/metadata.json.in + create mode 100644 extensions/move-notifications/org.gnome.shell.extensions.move-notifications.gschema.xml + create mode 100644 extensions/move-notifications/prefs.js + +diff --git a/extensions/move-notifications/extension.js b/extensions/move-notifications/extension.js +new file mode 100644 +index 00000000..0211696d +--- /dev/null ++++ b/extensions/move-notifications/extension.js +@@ -0,0 +1,49 @@ ++/* exported init */ ++const Clutter = imports.gi.Clutter; ++ ++const ExtensionUtils = imports.misc.extensionUtils; ++const Main = imports.ui.main; ++ ++class MoveNotificationsExtension { ++ enable() { ++ const updatePanel = Main.panel._updatePanel; ++ this._updatePanelOrig = updatePanel; ++ ++ Main.panel._updatePanel = () => { ++ updatePanel.call(Main.panel); ++ ++ Main.messageTray.bannerAlignment = this._getAlignment(); ++ }; ++ ++ this._settings = ExtensionUtils.getSettings(); ++ this._changedId = this._settings.connect('changed::position', ++ () => Main.panel._updatePanel()); ++ Main.panel._updatePanel(); ++ } ++ ++ disable() { ++ this._settings.disconnect(this._changedId); ++ this._settings = null; ++ ++ Main.panel._updatePanel = this._updatePanelOrig; ++ delete this._updatePanelOrig; ++ ++ Main.panel._updatePanel(); ++ } ++ ++ _getAlignment() { ++ switch (this._settings.get_string('position')) { ++ case 'top-left': ++ return Clutter.ActorAlign.START; ++ case 'top-right': ++ return Clutter.ActorAlign.END; ++ case 'top-center': ++ default: ++ return Clutter.ActorAlign.CENTER; ++ } ++ } ++} ++ ++function init() { ++ return new MoveNotificationsExtension(); ++} +diff --git a/extensions/move-notifications/meson.build b/extensions/move-notifications/meson.build +new file mode 100644 +index 00000000..c55a7830 +--- /dev/null ++++ b/extensions/move-notifications/meson.build +@@ -0,0 +1,8 @@ ++extension_data += configure_file( ++ input: metadata_name + '.in', ++ output: metadata_name, ++ configuration: metadata_conf ++) ++ ++extension_sources += files('prefs.js') ++extension_schemas += files(metadata_conf.get('gschemaname') + '.gschema.xml') +diff --git a/extensions/move-notifications/metadata.json.in b/extensions/move-notifications/metadata.json.in +new file mode 100644 +index 00000000..cae9352c +--- /dev/null ++++ b/extensions/move-notifications/metadata.json.in +@@ -0,0 +1,10 @@ ++{ ++ "uuid": "@uuid@", ++ "extension-id": "@extension_id@", ++ "settings-schema": "@gschemaname@", ++ "gettext-domain": "@gettext_domain@", ++ "name": "Move notifications", ++ "description": "Move notification banners", ++ "shell-version": [ "@shell_current@" ], ++ "url": "@url@" ++} +diff --git a/extensions/move-notifications/org.gnome.shell.extensions.move-notifications.gschema.xml b/extensions/move-notifications/org.gnome.shell.extensions.move-notifications.gschema.xml +new file mode 100644 +index 00000000..a78d72bb +--- /dev/null ++++ b/extensions/move-notifications/org.gnome.shell.extensions.move-notifications.gschema.xml +@@ -0,0 +1,14 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ "top-right" ++ Notification position ++ ++ ++ +diff --git a/extensions/move-notifications/prefs.js b/extensions/move-notifications/prefs.js +new file mode 100644 +index 00000000..a3ecdacf +--- /dev/null ++++ b/extensions/move-notifications/prefs.js +@@ -0,0 +1,86 @@ ++// -*- mode: js2; indent-tabs-mode: nil; js2-basic-offset: 4 -*- ++/* exported init buildPrefsWidget */ ++ ++const { Gio, GLib, GObject, Gtk } = imports.gi; ++ ++const ExtensionUtils = imports.misc.extensionUtils; ++const Me = ExtensionUtils.getCurrentExtension(); ++ ++const Gettext = imports.gettext.domain(Me.metadata['gettext-domain']); ++const _ = Gettext.gettext; ++ ++/** */ ++function init() { ++ ExtensionUtils.initTranslations(); ++} ++ ++const MoveNotificationsPrefsWidget = GObject.registerClass( ++class MoveNotificationsPrefsWidget extends Gtk.Box { ++ _init() { ++ super._init({ ++ orientation: Gtk.Orientation.VERTICAL, ++ spacing: 6, ++ margin_top: 36, ++ margin_bottom: 36, ++ margin_start: 36, ++ margin_end: 36, ++ halign: Gtk.Align.CENTER, ++ }); ++ ++ this._actionGroup = new Gio.SimpleActionGroup(); ++ this.insert_action_group('move-notifications', this._actionGroup); ++ ++ this._settings = ExtensionUtils.getSettings(); ++ this._actionGroup.add_action( ++ this._settings.create_action('position')); ++ ++ const title = new Gtk.Label({ ++ label: _('Notification Position'), ++ halign: Gtk.Align.START, ++ }); ++ title.add_css_class('heading'); ++ this.append(title); ++ ++ const box = new Gtk.Box({ ++ orientation: Gtk.Orientation.VERTICAL, ++ spacing: 12, ++ margin_bottom: 12, ++ }); ++ this.append(box); ++ ++ const context = box.get_style_context(); ++ const cssProvider = new Gtk.CssProvider(); ++ cssProvider.load_from_data( ++ 'box { padding: 12px; }', -1); ++ ++ context.add_provider(cssProvider, ++ Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); ++ context.add_class('boxed-list'); ++ context.add_class('view'); ++ ++ const positions = [ ++ { pos: 'top-right', label: _('Top–Right') }, ++ { pos: 'top-center', label: _('Top–Center') }, ++ { pos: 'top-left', label: _('Top–Left') }, ++ ]; ++ let group = null; ++ for (const { pos, label } of positions) { ++ const check = new Gtk.CheckButton({ ++ action_name: 'move-notifications.position', ++ action_target: new GLib.Variant('s', pos), ++ label, ++ group, ++ margin_end: 12, ++ }); ++ group = check; ++ box.append(check); ++ } ++ } ++}); ++ ++/** ++ * @returns {Gtk.Widget} - the prefs widget ++ */ ++function buildPrefsWidget() { ++ return new MoveNotificationsPrefsWidget(); ++} +diff --git a/meson.build b/meson.build +index 7e6ed3e8..0a31d2f6 100644 +--- a/meson.build ++++ b/meson.build +@@ -53,6 +53,7 @@ all_extensions += [ + 'dash-to-dock', + 'dash-to-panel', + 'gesture-inhibitor', ++ 'move-notifications', + 'native-window-placement', + 'panel-favorites', + 'systemMonitor', +-- +2.46.0 + diff --git a/SOURCES/0001-dash-to-panel-Remove-faulty-version-check.patch b/SOURCES/0001-dash-to-panel-Remove-faulty-version-check.patch new file mode 100644 index 0000000..ffe277e --- /dev/null +++ b/SOURCES/0001-dash-to-panel-Remove-faulty-version-check.patch @@ -0,0 +1,48 @@ +From 7ed5e50cc978b7fda34aaaf56e8bf4d499f4676d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Mon, 2 Dec 2024 17:34:58 +0100 +Subject: [PATCH] dash-to-panel: Remove faulty version check + +In a string comparison, '40.10' is *smaller* than '40.3', so the +overview ends up being monkey-patched for an older version. + +Unbreak the app grid by removing the check altogether, as we don't +have to care about older versions. +--- + extensions/dash-to-panel/overview.js | 20 ++++++++------------ + 1 file changed, 8 insertions(+), 12 deletions(-) + +diff --git a/extensions/dash-to-panel/overview.js b/extensions/dash-to-panel/overview.js +index 57600a5c..38f04c75 100644 +--- a/extensions/dash-to-panel/overview.js ++++ b/extensions/dash-to-panel/overview.js +@@ -581,18 +581,14 @@ var dtpOverview = Utils.defineClass({ + const workspaceAppGridBox = + this._cachedWorkspaceBoxes.get(OverviewControls.ControlsState.APP_GRID); + +- if (Config.PACKAGE_VERSION > '40.3') { +- const monitor = Main.layoutManager.findMonitorForActor(this._container); +- const workArea = Main.layoutManager.getWorkAreaForMonitor(monitor.index); +- const workAreaBox = new Clutter.ActorBox(); +- +- workAreaBox.set_origin(startX, startY); +- workAreaBox.set_size(workArea.width, workArea.height); +- +- params = [workAreaBox, searchHeight, dashHeight, workspaceAppGridBox] +- } else { +- params = [box, startX, searchHeight, dashHeight, workspaceAppGridBox]; +- } ++ const monitor = Main.layoutManager.findMonitorForActor(this._container); ++ const workArea = Main.layoutManager.getWorkAreaForMonitor(monitor.index); ++ const workAreaBox = new Clutter.ActorBox(); ++ ++ workAreaBox.set_origin(startX, startY); ++ workAreaBox.set_size(workArea.width, workArea.height); ++ ++ params = [workAreaBox, searchHeight, dashHeight, workspaceAppGridBox] + + let appDisplayBox; + if (!transitionParams.transitioning) { +-- +2.47.1 + diff --git a/SOURCES/more-ws-previews.patch b/SOURCES/more-ws-previews.patch index 40a8b74..39e1f5b 100644 --- a/SOURCES/more-ws-previews.patch +++ b/SOURCES/more-ws-previews.patch @@ -1,4 +1,4 @@ -From c4fafbcf01fc3c3846e5fe7d60d9aac623afdd9f Mon Sep 17 00:00:00 2001 +From 2bc8aa48edae1465a5c51be9d864a159b1009bc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Thu, 18 Apr 2024 18:09:40 +0200 Subject: [PATCH 01/29] prefs: Fix loading custom CSS @@ -80,10 +80,10 @@ index 567f3e99..d307dcac 100644 context.add_provider(cssProvider, Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION); -- -2.44.0 +2.47.0 -From a6e988875f52a49289677ca4d883a98b5515033f Mon Sep 17 00:00:00 2001 +From d1380931b47adb23c36e5499cbd931fba4d63bd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 23 Mar 2022 19:59:14 +0100 Subject: [PATCH 02/29] build: Remove unused stylesheets @@ -363,10 +363,10 @@ index 71efa039..19858a39 100644 extension_sources += files('prefs.js') -- -2.44.0 +2.47.0 -From 071226445e95d1a5551378aaf3c83db625fc2422 Mon Sep 17 00:00:00 2001 +From c97c668cf178968d70a9f2de3308e37e0b931acb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 21 Feb 2024 12:38:33 +0100 Subject: [PATCH 03/29] workspace-indicator: Move indicator code into separate @@ -859,7 +859,7 @@ index 19858a39..eb25b9cc 100644 +extension_sources += files('prefs.js', 'workspaceIndicator.js') diff --git a/extensions/workspace-indicator/workspaceIndicator.js b/extensions/workspace-indicator/workspaceIndicator.js new file mode 100644 -index 00000000..b98de047 +index 00000000..c88ffc9c --- /dev/null +++ b/extensions/workspace-indicator/workspaceIndicator.js @@ -0,0 +1,454 @@ @@ -1180,7 +1180,7 @@ index 00000000..b98de047 + } + + _onDestroy() { -+ for (let i = i; i < this._workspaceManagerSignals.length; i++) ++ for (let i = 0; i < this._workspaceManagerSignals.length; i++) + global.workspace_manager.disconnect(this._workspaceManagerSignals[i]); + + if (this._settingsChangedId) { @@ -1329,10 +1329,10 @@ index 10b1d517..bd39ab61 100644 extensions/workspace-indicator/prefs.js +extensions/workspace-indicator/workspaceIndicator.js -- -2.44.0 +2.47.0 -From 4720bf9f69c91c6fa39897534921eb4f2eceb8eb Mon Sep 17 00:00:00 2001 +From 34ba767aa622ac9122463f4649f7a8854a56f25d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 21 Feb 2024 19:09:38 +0100 Subject: [PATCH 04/29] workspace-indicator: Use descendant style selectors @@ -1375,7 +1375,7 @@ index 84aaf454..4e12cce4 100644 } diff --git a/extensions/workspace-indicator/workspaceIndicator.js b/extensions/workspace-indicator/workspaceIndicator.js -index b98de047..101c89c6 100644 +index c88ffc9c..28fc3ea8 100644 --- a/extensions/workspace-indicator/workspaceIndicator.js +++ b/extensions/workspace-indicator/workspaceIndicator.js @@ -263,6 +263,8 @@ class WorkspaceIndicator extends PanelMenu.Button { @@ -1406,10 +1406,10 @@ index b98de047..101c89c6 100644 reactive: true, }); -- -2.44.0 +2.47.0 -From 22f44ae9f21337a11a09447763fbd223e37f3d56 Mon Sep 17 00:00:00 2001 +From c5843b7870e0ce0cbf7b2f587193b93c63062105 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 21 Feb 2024 12:48:43 +0100 Subject: [PATCH 05/29] window-list: Use consistent style class prefix @@ -1473,10 +1473,10 @@ index cdfe5b61..c24f159f 100644 this._delegate = this; -- -2.44.0 +2.47.0 -From c8bb217d2053cf8d7db5f4866f834b6d06250427 Mon Sep 17 00:00:00 2001 +From a81dbea8250c85b950c83048f178c700635a8c38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Fri, 23 Feb 2024 01:59:15 +0100 Subject: [PATCH 06/29] workspace-indicator: Allow overriding base style class @@ -1489,7 +1489,7 @@ to one of the extensions. 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/extensions/workspace-indicator/workspaceIndicator.js b/extensions/workspace-indicator/workspaceIndicator.js -index 101c89c6..ba1e05d7 100644 +index 28fc3ea8..01604b91 100644 --- a/extensions/workspace-indicator/workspaceIndicator.js +++ b/extensions/workspace-indicator/workspaceIndicator.js @@ -25,11 +25,13 @@ const TOOLTIP_ANIMATION_TIME = 150; @@ -1526,10 +1526,10 @@ index 101c89c6..ba1e05d7 100644 let container = new St.Widget({ layout_manager: new Clutter.BinLayout(), -- -2.44.0 +2.47.0 -From fc27a7f0e6da8647380b5bbe901b27ec0e5aa728 Mon Sep 17 00:00:00 2001 +From e1c5b589fca9021b960e19f043ca26735c8b02de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Fri, 23 Feb 2024 01:58:50 +0100 Subject: [PATCH 07/29] window-list: Override base style class @@ -1600,10 +1600,10 @@ index c24f159f..1a1d15cd 100644 this.menu.actor.remove_style_class_name('panel-menu'); -- -2.44.0 +2.47.0 -From 3838a915d953b910aa2d9ec82cd22dcf2e0f7440 Mon Sep 17 00:00:00 2001 +From c673a9d7169cc1a2f6df9c3eeea4b11f8968dc19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 21 Feb 2024 12:48:43 +0100 Subject: [PATCH 08/29] window-list: Externally adjust workspace menu @@ -1688,10 +1688,10 @@ index 1a1d15cd..4290d58a 100644 layout_manager: new Clutter.BinLayout(), x_expand: true, -- -2.44.0 +2.47.0 -From 7d2abee5e5de19bba95e4fb66692e08ace67c972 Mon Sep 17 00:00:00 2001 +From 3271e93695782d06ada9752144c650605ceed76a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Thu, 21 Mar 2024 16:49:35 +0100 Subject: [PATCH 09/29] window-list: Handle changes to workspace menu @@ -1731,10 +1731,10 @@ index c58df434..a011bc90 100644 this.set_position( this._monitor.x, -- -2.44.0 +2.47.0 -From bc71e5e7a21249868a481238193e1ca15eba5699 Mon Sep 17 00:00:00 2001 +From 314072792bba618a85897dc085bb72debe3ec6b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 21 Feb 2024 15:58:39 +0100 Subject: [PATCH 10/29] workspace-indicator: Don't use SCHEMA/KEY constants @@ -1749,7 +1749,7 @@ do the same here. 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/extensions/workspace-indicator/workspaceIndicator.js b/extensions/workspace-indicator/workspaceIndicator.js -index ba1e05d7..60e084e2 100644 +index 01604b91..6e3ad7b5 100644 --- a/extensions/workspace-indicator/workspaceIndicator.js +++ b/extensions/workspace-indicator/workspaceIndicator.js @@ -17,9 +17,6 @@ const Main = imports.ui.main; @@ -1775,10 +1775,10 @@ index ba1e05d7..60e084e2 100644 } -- -2.44.0 +2.47.0 -From 66cf82e0676179a2565a75bbad1c31bb539c065c Mon Sep 17 00:00:00 2001 +From 002a0bb8036a997a70acda017e4016fd9fd51806 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 21 Feb 2024 18:59:23 +0100 Subject: [PATCH 11/29] workspace-indicator: Use existing property @@ -1790,7 +1790,7 @@ instead of getting it from the workspace manager again. 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/workspace-indicator/workspaceIndicator.js b/extensions/workspace-indicator/workspaceIndicator.js -index 60e084e2..4f2188be 100644 +index 6e3ad7b5..60356d74 100644 --- a/extensions/workspace-indicator/workspaceIndicator.js +++ b/extensions/workspace-indicator/workspaceIndicator.js @@ -454,7 +454,7 @@ class WorkspaceIndicator extends PanelMenu.Button { @@ -1803,10 +1803,10 @@ index 60e084e2..4f2188be 100644 } }); -- -2.44.0 +2.47.0 -From c51f0d790c7e4d575d770b63ad7c9632b4af79b1 Mon Sep 17 00:00:00 2001 +From 4e2785910ceccc079305da1b9d0e2c810b1f982a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 21 Feb 2024 16:14:24 +0100 Subject: [PATCH 12/29] workspace-indicator: Don't use menu section @@ -1820,7 +1820,7 @@ This removes another difference with the window-list copy. 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/extensions/workspace-indicator/workspaceIndicator.js b/extensions/workspace-indicator/workspaceIndicator.js -index 4f2188be..66b71cd6 100644 +index 60356d74..39d4e296 100644 --- a/extensions/workspace-indicator/workspaceIndicator.js +++ b/extensions/workspace-indicator/workspaceIndicator.js @@ -296,8 +296,6 @@ class WorkspaceIndicator extends PanelMenu.Button { @@ -1872,10 +1872,10 @@ index 4f2188be..66b71cd6 100644 this._workspacesItems[i].label_actor = this._statusLabel; this._workspacesItems[i].connect('activate', (actor, _event) => { -- -2.44.0 +2.47.0 -From ef3a5860782e67dffcb63c705422102f68bd68ad Mon Sep 17 00:00:00 2001 +From 5f33bc574aee51700c92b940b23df0b7966450d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 21 Feb 2024 13:05:15 +0100 Subject: [PATCH 13/29] workspace-indicator: Support showing tooltips above @@ -1889,7 +1889,7 @@ used in the copy that is included with the window-list extension. 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/extensions/workspace-indicator/workspaceIndicator.js b/extensions/workspace-indicator/workspaceIndicator.js -index 66b71cd6..bc9e222b 100644 +index 39d4e296..83713b6f 100644 --- a/extensions/workspace-indicator/workspaceIndicator.js +++ b/extensions/workspace-indicator/workspaceIndicator.js @@ -227,16 +227,17 @@ class WorkspaceThumbnail extends St.Button { @@ -1915,10 +1915,10 @@ index 66b71cd6..bc9e222b 100644 } -- -2.44.0 +2.47.0 -From 3161d6c59fc8f7dd1b5c5f21082a5fd00cbcf5a9 Mon Sep 17 00:00:00 2001 +From a65fd9e61cf3f3a83116815482843b1b20eef20f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 21 Feb 2024 17:37:16 +0100 Subject: [PATCH 14/29] workspace-indicator: Only change top bar redirect when @@ -1931,7 +1931,7 @@ the check will allow to use the same code in the window list. 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/extensions/workspace-indicator/workspaceIndicator.js b/extensions/workspace-indicator/workspaceIndicator.js -index bc9e222b..ac270d64 100644 +index 83713b6f..fa05a54c 100644 --- a/extensions/workspace-indicator/workspaceIndicator.js +++ b/extensions/workspace-indicator/workspaceIndicator.js @@ -309,6 +309,16 @@ class WorkspaceIndicator extends PanelMenu.Button { @@ -1981,10 +1981,10 @@ index bc9e222b..ac270d64 100644 : Clutter.OffscreenRedirect.AUTOMATIC_FOR_OPACITY); } -- -2.44.0 +2.47.0 -From 3afe55799368e1f899d2949bcc981718c6498623 Mon Sep 17 00:00:00 2001 +From 521b224b17cb15df49a32d5c2dffe5ce65285df4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 21 Feb 2024 16:13:00 +0100 Subject: [PATCH 15/29] workspace-indicator: Small cleanup @@ -1996,7 +1996,7 @@ window-list extension, so use that. 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/extensions/workspace-indicator/workspaceIndicator.js b/extensions/workspace-indicator/workspaceIndicator.js -index ac270d64..9b22102a 100644 +index fa05a54c..bbb51c41 100644 --- a/extensions/workspace-indicator/workspaceIndicator.js +++ b/extensions/workspace-indicator/workspaceIndicator.js @@ -422,19 +422,18 @@ class WorkspaceIndicator extends PanelMenu.Button { @@ -2029,10 +2029,10 @@ index ac270d64..9b22102a 100644 this._statusLabel.set_text(this._labelText()); -- -2.44.0 +2.47.0 -From 2eef4f6dd803021303be7c4f15775a41389debb3 Mon Sep 17 00:00:00 2001 +From 3145e45a2d897b177e7395cec71a1293b6857a36 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 21 Feb 2024 16:13:00 +0100 Subject: [PATCH 16/29] workspace-indicator: Simplify getting status text @@ -2049,7 +2049,7 @@ for menu items. 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/extensions/workspace-indicator/workspaceIndicator.js b/extensions/workspace-indicator/workspaceIndicator.js -index 9b22102a..d8b29f58 100644 +index bbb51c41..d401b6ab 100644 --- a/extensions/workspace-indicator/workspaceIndicator.js +++ b/extensions/workspace-indicator/workspaceIndicator.js @@ -283,7 +283,7 @@ class WorkspaceIndicator extends PanelMenu.Button { @@ -2115,10 +2115,10 @@ index 9b22102a..d8b29f58 100644 _updateThumbnails() { -- -2.44.0 +2.47.0 -From 8785f56bf69272e664c207856bfb7417342550c6 Mon Sep 17 00:00:00 2001 +From 30adbc349b382c69c7592cd674d7837f6c9185c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 21 Feb 2024 16:35:09 +0100 Subject: [PATCH 17/29] workspace-indicator: Include n-workspaces in status @@ -2136,7 +2136,7 @@ bigger click/touch target, so copy the window-list behavior. 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/extensions/workspace-indicator/workspaceIndicator.js b/extensions/workspace-indicator/workspaceIndicator.js -index d8b29f58..756758b3 100644 +index d401b6ab..29b8a671 100644 --- a/extensions/workspace-indicator/workspaceIndicator.js +++ b/extensions/workspace-indicator/workspaceIndicator.js @@ -403,8 +403,9 @@ class WorkspaceIndicator extends PanelMenu.Button { @@ -2151,10 +2151,10 @@ index d8b29f58..756758b3 100644 _updateMenuLabels() { -- -2.44.0 +2.47.0 -From 6e483b472fa4b5a7be8f00b1ef87f28658f815aa Mon Sep 17 00:00:00 2001 +From 675e91b7b521b4c8d7f53a9f3d028ab7300281dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Thu, 22 Feb 2024 04:45:23 +0100 Subject: [PATCH 18/29] workspace-indicator: Tweak preview style @@ -2206,10 +2206,10 @@ index 4e12cce4..f74f7e88 100644 .workspace-indicator-window-preview.active { -- -2.44.0 +2.47.0 -From cf06ac2f9b7e2412fc555721b9c6d34fea7e0b45 Mon Sep 17 00:00:00 2001 +From 011af97ab27a4e7be9dab937754470e890bc131c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 21 Feb 2024 23:22:58 +0100 Subject: [PATCH 19/29] workspace-indicator: Support light style @@ -2344,10 +2344,10 @@ index f74f7e88..b0f7d171 100644 -} +@import url("stylesheet-dark.css"); -- -2.44.0 +2.47.0 -From a5fd131564600f3117f0dbd27a1bb82592ec1132 Mon Sep 17 00:00:00 2001 +From bcb34a3a91a5140b5ecc6f9582dd9f80272c7e32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Wed, 21 Feb 2024 13:08:52 +0100 Subject: [PATCH 20/29] window-list: Use actual copy of workspace-indicator @@ -2905,10 +2905,10 @@ index 4290d58a..00000000 -}); - -- -2.44.0 +2.47.0 -From fbcf6cb317b58dc32c67952b54cec925adfbad34 Mon Sep 17 00:00:00 2001 +From 36e4714c31398b74eb1727197f40bbd81ccfd6f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Tue, 20 Feb 2024 17:39:49 +0100 Subject: [PATCH 21/29] workspace-indicator: Simplify scroll handling @@ -2920,7 +2920,7 @@ via scroll events. Use that instead of implementing our own. 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/extensions/workspace-indicator/workspaceIndicator.js b/extensions/workspace-indicator/workspaceIndicator.js -index 756758b3..8e3fec56 100644 +index 29b8a671..1dd3ed6b 100644 --- a/extensions/workspace-indicator/workspaceIndicator.js +++ b/extensions/workspace-indicator/workspaceIndicator.js @@ -307,8 +307,10 @@ class WorkspaceIndicator extends PanelMenu.Button { @@ -2957,10 +2957,10 @@ index 756758b3..8e3fec56 100644 - } }); -- -2.44.0 +2.47.0 -From 346960098322af549c55a6eaf1628f1743585df1 Mon Sep 17 00:00:00 2001 +From f3154702594a814e5131252ab84b9daf0553ada3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Tue, 27 Feb 2024 21:20:45 +0100 Subject: [PATCH 22/29] workspace-indicator: Handle active indication in @@ -2974,7 +2974,7 @@ workspace ourselves. 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/extensions/workspace-indicator/workspaceIndicator.js b/extensions/workspace-indicator/workspaceIndicator.js -index 8e3fec56..01b831f7 100644 +index 1dd3ed6b..ae526929 100644 --- a/extensions/workspace-indicator/workspaceIndicator.js +++ b/extensions/workspace-indicator/workspaceIndicator.js @@ -116,8 +116,14 @@ class WorkspaceLayout extends Clutter.LayoutManager { @@ -3058,10 +3058,10 @@ index 8e3fec56..01b831f7 100644 _activate(index) { -- -2.44.0 +2.47.0 -From 76ec37876c295b9150e98c04e11189e464af7a94 Mon Sep 17 00:00:00 2001 +From e854ad2e483489952691d5fbede37e3fec63737c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Tue, 20 Feb 2024 17:27:57 +0100 Subject: [PATCH 23/29] workspace-indicator: Split out WorkspacePreviews @@ -3073,7 +3073,7 @@ into a dedicated class. 1 file changed, 49 insertions(+), 25 deletions(-) diff --git a/extensions/workspace-indicator/workspaceIndicator.js b/extensions/workspace-indicator/workspaceIndicator.js -index 01b831f7..a559b8e2 100644 +index ae526929..e5be8081 100644 --- a/extensions/workspace-indicator/workspaceIndicator.js +++ b/extensions/workspace-indicator/workspaceIndicator.js @@ -280,6 +280,51 @@ const WorkspaceThumbnail = GObject.registerClass({ @@ -3209,10 +3209,10 @@ index 01b831f7..a559b8e2 100644 let workspaceManager = global.workspace_manager; -- -2.44.0 +2.47.0 -From 69c5eefbca44f58d10072115dd46ffada862cd48 Mon Sep 17 00:00:00 2001 +From 18b40e7f586d4546bd64745a0b2d617655b87af3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Mon, 19 Feb 2024 14:42:04 +0100 Subject: [PATCH 24/29] workspace-indicator: Handle preview overflow @@ -3246,7 +3246,7 @@ index f74f7e88..61d1e982 100644 padding: 5px; spacing: 3px; diff --git a/extensions/workspace-indicator/workspaceIndicator.js b/extensions/workspace-indicator/workspaceIndicator.js -index a559b8e2..17cf7c89 100644 +index e5be8081..d496d22d 100644 --- a/extensions/workspace-indicator/workspaceIndicator.js +++ b/extensions/workspace-indicator/workspaceIndicator.js @@ -20,6 +20,8 @@ const PopupMenu = imports.ui.popupMenu; @@ -3342,10 +3342,10 @@ index a559b8e2..17cf7c89 100644 _onDestroy() { -- -2.44.0 +2.47.0 -From 609674b2763bfd1536e8854b79d3c1bf265f00b9 Mon Sep 17 00:00:00 2001 +From 422a5e6f67b23c3b9b0764ec313ad0ad864249db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Sun, 3 Mar 2024 15:05:23 +0100 Subject: [PATCH 25/29] workspace-indicator: Support labels in previews @@ -3359,7 +3359,7 @@ names to not lose functionality with regards to the current menu. 1 file changed, 55 insertions(+), 8 deletions(-) diff --git a/extensions/workspace-indicator/workspaceIndicator.js b/extensions/workspace-indicator/workspaceIndicator.js -index 17cf7c89..5e6d6300 100644 +index d496d22d..f5ffdbb7 100644 --- a/extensions/workspace-indicator/workspaceIndicator.js +++ b/extensions/workspace-indicator/workspaceIndicator.js @@ -124,10 +124,23 @@ const WorkspaceThumbnail = GObject.registerClass({ @@ -3504,10 +3504,10 @@ index 17cf7c89..5e6d6300 100644 } -- -2.44.0 +2.47.0 -From 40cfe3a41fa3823fce06824b82e663b8f63f4e6d Mon Sep 17 00:00:00 2001 +From a0985eb24eafee329b6af6c2c2f7db4de7b103e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Tue, 20 Feb 2024 21:43:55 +0100 Subject: [PATCH 26/29] workspace-indicator: Stop handling vertical layouts @@ -3524,7 +3524,7 @@ previews and the actual layout. 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/extensions/workspace-indicator/workspaceIndicator.js b/extensions/workspace-indicator/workspaceIndicator.js -index 5e6d6300..aad2716a 100644 +index f5ffdbb7..362c6372 100644 --- a/extensions/workspace-indicator/workspaceIndicator.js +++ b/extensions/workspace-indicator/workspaceIndicator.js @@ -475,8 +475,6 @@ class WorkspaceIndicator extends PanelMenu.Button { @@ -3548,10 +3548,10 @@ index 5e6d6300..aad2716a 100644 this._statusLabel.visible = useMenu; -- -2.44.0 +2.47.0 -From 1cad76230f8f70a08a8ccbe0970641a7b6a717b5 Mon Sep 17 00:00:00 2001 +From 74b64e860757d56f0d500165ba2e49024ead48d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Sun, 3 Mar 2024 15:05:23 +0100 Subject: [PATCH 27/29] workspace-indicator: Also show previews in menu @@ -3614,7 +3614,7 @@ index 61d1e982..fb0e8b1a 100644 border-color: #9f9f9f; } diff --git a/extensions/workspace-indicator/workspaceIndicator.js b/extensions/workspace-indicator/workspaceIndicator.js -index aad2716a..7b3c6fbe 100644 +index 362c6372..ed5645db 100644 --- a/extensions/workspace-indicator/workspaceIndicator.js +++ b/extensions/workspace-indicator/workspaceIndicator.js @@ -439,7 +439,7 @@ const WorkspacePreviews = GObject.registerClass({ @@ -3649,7 +3649,7 @@ index aad2716a..7b3c6fbe 100644 } _onDestroy() { - for (let i = i; i < this._workspaceManagerSignals.length; i++) + for (let i = 0; i < this._workspaceManagerSignals.length; i++) global.workspace_manager.disconnect(this._workspaceManagerSignals[i]); - if (this._settingsChangedId) { @@ -3748,10 +3748,10 @@ index aad2716a..7b3c6fbe 100644 } }); -- -2.44.0 +2.47.0 -From 20a2122ab7a435cb1a0840747a5d13be0d838a9e Mon Sep 17 00:00:00 2001 +From f810340e1e7ffd7c1964ec950be8b0585afe9e7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Tue, 20 Feb 2024 22:00:57 +0100 Subject: [PATCH 28/29] workspace-indicator: Make previews configurable @@ -3898,7 +3898,7 @@ index 00000000..c7c634ca + + diff --git a/extensions/workspace-indicator/workspaceIndicator.js b/extensions/workspace-indicator/workspaceIndicator.js -index 7b3c6fbe..9d566f41 100644 +index ed5645db..14359a0e 100644 --- a/extensions/workspace-indicator/workspaceIndicator.js +++ b/extensions/workspace-indicator/workspaceIndicator.js @@ -22,8 +22,6 @@ const TOOLTIP_ANIMATION_TIME = 150; @@ -3966,10 +3966,10 @@ index bd39ab61..4d551780 100644 +extensions/workspace-indicator/schemas/org.gnome.shell.extensions.workspace-indicator.gschema.xml extensions/workspace-indicator/workspaceIndicator.js -- -2.44.0 +2.47.0 -From 597ed15f9e4a1fd6eeaaedaae59db30c4d379c3f Mon Sep 17 00:00:00 2001 +From 952d2ca4e3e5b35b3a25336506b06ef0dca734a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Thu, 21 Mar 2024 17:27:09 +0100 Subject: [PATCH 29/29] window-list: Expose workspace preview option @@ -3998,5 +3998,5 @@ index e35990ff..79cd1355 100644 }); -- -2.44.0 +2.47.0 diff --git a/SOURCES/window-list-attention-indicator.patch b/SOURCES/window-list-attention-indicator.patch new file mode 100644 index 0000000..b7bc6ff --- /dev/null +++ b/SOURCES/window-list-attention-indicator.patch @@ -0,0 +1,206 @@ +From 984a2672b4c4c41d9dab85c068f76efa98f81a56 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Tue, 17 Dec 2024 01:09:34 +0100 +Subject: [PATCH] window-list: Add attention indicator + +Some X11 clients still rely on the traditional urgent/demand-attention +hints instead of notifications to request the user's attention. + +Support these by adding a visual indication to the corresponding +buttons, based on the visual indicator in libadwaita's tabs. + +Closes: https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/issues/543 +--- + extensions/window-list/extension.js | 90 +++++++++++++++++++++++++-- + extensions/window-list/stylesheet.css | 9 +++ + 2 files changed, 95 insertions(+), 4 deletions(-) + +diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js +index bb9ca80f..477ed8fe 100644 +--- a/extensions/window-list/extension.js ++++ b/extensions/window-list/extension.js +@@ -160,23 +160,30 @@ const TitleWidget = GObject.registerClass({ + GObject.ParamFlags.READWRITE, + false), + }, +-}, class TitleWidget extends St.BoxLayout { ++}, class TitleWidget extends St.Widget { + _init() { + super._init({ ++ layout_manager: new Clutter.BinLayout(), ++ x_expand: true, ++ y_expand: true, ++ }); ++ ++ const hbox = new St.BoxLayout({ + style_class: 'window-button-box', + x_expand: true, + y_expand: true, + }); ++ this.add_child(hbox); + + this._icon = new St.Bin({ + style_class: 'window-button-icon', + }); +- this.add_child(this._icon); ++ hbox.add_child(this._icon); + + this._label = new St.Label({ + y_align: Clutter.ActorAlign.CENTER, + }); +- this.add_child(this._label); ++ hbox.add_child(this._label); + this.label_actor = this._label; + + this.bind_property('abstract-label', +@@ -189,11 +196,28 @@ const TitleWidget = GObject.registerClass({ + x_expand: true, + y_expand: true, + }); +- this.add_child(this._abstractLabel); ++ hbox.add_child(this._abstractLabel); + + this.bind_property('abstract-label', + this._abstractLabel, 'visible', + GObject.BindingFlags.SYNC_CREATE); ++ ++ this._attentionIndicator = new St.Widget({ ++ style_class: 'window-button-attention-indicator', ++ x_expand: true, ++ y_expand: true, ++ y_align: Clutter.ActorAlign.END, ++ scale_x: 0, ++ }); ++ this._attentionIndicator.set_pivot_point(0.5, 0.5); ++ this.add_child(this._attentionIndicator); ++ } ++ ++ setNeedsAttention(enable) { ++ this._attentionIndicator.ease({ ++ scaleX: enable ? 0.4 : 0, ++ duration: 300, ++ }); + } + }); + +@@ -219,7 +243,12 @@ class WindowTitle extends TitleWidget { + 'notify::title', this._updateTitle.bind(this)); + this._notifyMinimizedId = this._metaWindow.connect( + 'notify::minimized', this._minimizedChanged.bind(this)); ++ this._notifyDemandsAttentionId = this._metaWindow.connect( ++ 'notify::demands-attention', this._updateNeedsAttention.bind(this)); ++ this._notifyUrgentId = this._metaWindow.connect( ++ 'notify::urgent', this._updateNeedsAttention.bind(this)); + this._minimizedChanged(); ++ this._updateNeedsAttention(); + } + + _minimizedChanged() { +@@ -227,6 +256,11 @@ class WindowTitle extends TitleWidget { + this._updateTitle(); + } + ++ _updateNeedsAttention() { ++ const { urgent, demandsAttention } = this._metaWindow; ++ this.setNeedsAttention(urgent || demandsAttention); ++ } ++ + _updateTitle() { + if (!this._metaWindow.title) + return; +@@ -272,6 +306,8 @@ class WindowTitle extends TitleWidget { + this._metaWindow.disconnect(this._notifyMinimizedId); + this._metaWindow.disconnect(this._notifyWmClass); + this._metaWindow.disconnect(this._notifyAppId); ++ this._metaWindow.disconnect(this._notifyDemandsAttentionId); ++ this._metaWindow.disconnect(this._notifyUrgentId); + } + }); + +@@ -281,6 +317,7 @@ class AppTitle extends TitleWidget { + super._init(); + + this._app = app; ++ this._windows = new Map(); + + this._icon.child = app.create_icon_texture(ICON_TEXTURE_SIZE); + this._label.text = app.get_name(); +@@ -291,6 +328,10 @@ class AppTitle extends TitleWidget { + this._icon.child = app.create_icon_texture(ICON_TEXTURE_SIZE); + }); + ++ this._windowsChangedId = this._app.connect( ++ 'windows-changed', this._onWindowsChanged.bind(this)); ++ this._onWindowsChanged(); ++ + this.connect('destroy', this._onDestroy.bind(this)); + } + +@@ -299,6 +340,47 @@ class AppTitle extends TitleWidget { + this._textureCache.disconnect(this._iconThemeChangedId); + this._iconThemeChangedId = 0; + this._textureCache = null; ++ ++ for (const [window, ids] of this._windows) ++ ids.forEach(id => window.disconnect(id)); ++ this._windows.clear(); ++ this._app.disconnect(this._windowsChangedId); ++ } ++ ++ _onWindowsChanged() { ++ const windows = this._app.get_windows(); ++ const removed = [...this._windows].filter(w => !windows.includes(w)); ++ removed.forEach(w => this._untrackWindow(w)); ++ windows.forEach(w => this._trackWindow(w)); ++ this._updateNeedsAttention(); ++ } ++ ++ _trackWindow(window) { ++ if (this._windows.has(window)) ++ return; ++ ++ const signals = [ ++ window.connect('notify::urgent', ++ () => this._updateNeedsAttention()), ++ window.connect('notify::demands-attention', ++ () => this._updateNeedsAttention()), ++ ]; ++ this._windows.set(window, signals); ++ } ++ ++ _untrackWindow(window) { ++ if (!this._windows.has(window)) ++ return; ++ ++ const ids = this._windows.get(window); ++ ids.forEach(id => window.disconnect(id)); ++ this._windows.delete(window); ++ } ++ ++ _updateNeedsAttention() { ++ const needsAttention = ++ [...this._windows.keys()].some(w => w.urgent || w.demandsAttention); ++ this.setNeedsAttention(needsAttention); + } + }); + +diff --git a/extensions/window-list/stylesheet.css b/extensions/window-list/stylesheet.css +index 4c06ebc0..45b42065 100644 +--- a/extensions/window-list/stylesheet.css ++++ b/extensions/window-list/stylesheet.css +@@ -103,3 +103,12 @@ + border-radius: 99px; + margin: 6px; + } ++ ++.window-button-attention-indicator { ++ background-color: rgba(27, 106, 203, 1.0); ++ height: 2px; ++} ++ ++.window-button.minimized .window-button-attention-indicator { ++ background-color: rgba(27, 106, 203, 0.6); ++} +-- +2.47.1 + diff --git a/SOURCES/window-list-reordering.patch b/SOURCES/window-list-reordering.patch new file mode 100644 index 0000000..73ad855 --- /dev/null +++ b/SOURCES/window-list-reordering.patch @@ -0,0 +1,2065 @@ +From 60b46c8d82dfbdcfdf54d3f022318637870a3756 Mon Sep 17 00:00:00 2001 +From: Jakub Steiner +Date: Tue, 16 Jul 2024 09:40:53 +0200 +Subject: [PATCH 01/24] window-list: Update styling + +- Contemporary look. Fewer borders, thinner outlines for workspace indicators +- Lacks the designed unfocused window separators. +- Relies on https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/merge_requests/328 + +Fixes https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/issues/421 + +Part-of: +--- + extensions/window-list/classic.css | 68 ++++++++----- + extensions/window-list/stylesheet.css | 96 +++++++------------ + .../workspace-indicator/stylesheet-dark.css | 4 +- + 3 files changed, 78 insertions(+), 90 deletions(-) + +diff --git a/extensions/window-list/classic.css b/extensions/window-list/classic.css +index d7ceb062..088c9478 100644 +--- a/extensions/window-list/classic.css ++++ b/extensions/window-list/classic.css +@@ -1,22 +1,24 @@ ++/* ++ * SPDX-FileCopyrightText: 2013 Florian Müllner ++ * SPDX-FileCopyrightText: 2015 Jakub Steiner ++ * ++ * SPDX-License-Identifier: GPL-2.0-or-later ++ */ ++ + @import url("stylesheet.css"); + @import url("stylesheet-workspace-switcher-light.css"); + + #panel.bottom-panel { + border-top-width: 1px; + border-bottom-width: 0px; +- height: 2.25em ; +- padding: 2px; ++ height: 2.5em; + } + +- .bottom-panel .window-button > StWidget, +- .bottom-panel .window-picker-toggle > StWidget { +- color: #2e3436; +- background-color: #eee; ++ .bottom-panel .window-button > StWidget { + border-radius: 3px; + padding: 3px 6px 1px; + box-shadow: none; + text-shadow: none; +- border: 1px solid rgba(0,0,0,0.2); + } + + .bottom-panel .window-button > StWidget { +@@ -24,27 +26,43 @@ + max-width: 18.75em; + } + +- .bottom-panel .window-button:hover > StWidget, +- .bottom-panel .window-picker-toggle:hover > StWidget { +- background-color: #f9f9f9; +- } ++ .window-button > StWidget { ++ color: #000; ++ background-color: transparent; ++} + +- .bottom-panel .window-button:active > StWidget, +- .bottom-panel .window-button:focus > StWidget { +- box-shadow: inset 0 1px 3px rgba(0,0,0,0.1); +- } ++.window-button > StWidget { ++ -st-natural-width: 18.75em; ++ max-width: 18.75em; ++} + +- .bottom-panel .window-button.focused > StWidget, +- .bottom-panel .window-picker-toggle:checked > StWidget { +- background-color: #ccc; +- box-shadow: inset 0 1px 3px rgba(0,0,0,0.1); +- } ++.window-button:hover > StWidget { ++ background-color: st-darken(#eee,5%); ++} + +- .bottom-panel .window-button.focused:hover > StWidget { +- background-color: #e9e9e9; ++.window-button:active > StWidget, ++.window-button:focus > StWidget { ++ background-color: st-darken(#eee, 10%); ++} ++ ++.window-button.focused > StWidget { ++ background-color: st-darken(#eee,15%); ++} ++ ++ .window-button.focused:hover > StWidget { ++ background-color: st-darken(#eee, 20%); + } + +- .bottom-panel .window-button.minimized > StWidget { +- color: #888; +- box-shadow: none; ++ .window-button.focused:active > StWidget { ++ background-color: st-darken(#eee, 25%); + } ++ ++.window-button.minimized > StWidget { ++ color: #aaa; ++ background-color: #f9f9f9; ++} ++ ++.window-button.minimized:active > StWidget { ++ color: #aaa; ++ background-color: #f9f9f9; ++} +diff --git a/extensions/window-list/stylesheet.css b/extensions/window-list/stylesheet.css +index 4ba47f07..b9087971 100644 +--- a/extensions/window-list/stylesheet.css ++++ b/extensions/window-list/stylesheet.css +@@ -1,3 +1,9 @@ ++/* ++ * SPDX-FileCopyrightText: 2012 Florian Müllner ++ * SPDX-FileCopyrightText: 2013 Giovanni Campagna ++ * ++ * SPDX-License-Identifier: GPL-2.0-or-later ++ */ + @import url("stylesheet-workspace-switcher-dark.css"); + + .window-list { +@@ -5,8 +11,14 @@ + font-size: 10pt; + } + ++.bottom-panel { ++ background-color: #000000; ++ border-top-width: 0px; ++ height: 2.45em; ++} ++ + .window-button { +- padding: 1px; ++ padding: 4px, 3px; + } + + .window-button:first-child:ltr { +@@ -21,22 +33,12 @@ + spacing: 4px; + } + +-.window-button > StWidget, +-.window-picker-toggle > StWidget { +- color: #bbb; +- background-color: black; +- border-radius: 2px; ++.window-button > StWidget { ++ color: #fff; ++ background-color: transparent; ++ border-radius: 4px; + padding: 3px 6px 1px; +- box-shadow: inset 1px 1px 4px rgba(255,255,255,0.5); +- text-shadow: 1px 1px 4px rgba(0,0,0,0.8); +-} +- +-.window-picker-toggle { +- padding: 3px; +-} +- +-.window-picker-toggle > StWidet { +- border: 1px solid rgba(255,255,255,0.3); ++ transition: 100ms ease; + } + + .window-button > StWidget { +@@ -44,35 +46,35 @@ + max-width: 18.75em; + } + +-.window-button:hover > StWidget, +-.window-picker-toggle:hover > StWidget { +- color: white; +- background-color: #1f1f1f; ++.window-button:hover > StWidget { ++ background-color: #303030; + } + + .window-button:active > StWidget, + .window-button:focus > StWidget { +- box-shadow: inset 2px 2px 4px rgba(255,255,255,0.5); ++ background-color: st-lighten(#303030, 5%); + } + +-.window-button.focused > StWidget, +-.window-picker-toggle:checked > StWidget { +- color: white; +- box-shadow: inset 1px 1px 4px rgba(255,255,255,0.7); ++.window-button.focused > StWidget { ++ background-color: #5b5b5b; + } + +-.window-button.focused:active > StWidget, +-.window-picker-toggle:checked:active > StWidget { +- box-shadow: inset 2px 2px 4px rgba(255,255,255,0.7); +-} ++ .window-button.focused:hover > StWidget { ++ background-color: st-lighten(#5b5b5b, 5%); ++ } ++ ++ .window-button.focused:active > StWidget { ++ background-color: st-lighten(#5b5b5b, 10%); ++ } + + .window-button.minimized > StWidget { + color: #666; +- box-shadow: inset -1px -1px 4px rgba(255,255,255,0.5); ++ background-color: #161616; + } + + .window-button.minimized:active > StWidget { +- box-shadow: inset -2px -2px 4px rgba(255,255,255,0.5); ++ color: #666; ++ background-color: #161616; + } + + .window-button-icon { +@@ -80,38 +82,6 @@ + height: 24px; + } + +-.window-list-workspace-indicator .status-label-bin { +- background-color: rgba(200, 200, 200, .3); +- border: 1px solid #cccccc; +- padding: 0 3px; +- margin: 3px; +-} +- +-.window-list-workspace-indicator .workspaces-box { +- spacing: 3px; +- padding: 3px; +-} +- +-.window-list-workspace-indicator .workspace { +- border: 2px solid #000; +- width: 52px; +- border-radius: 4px; +- background-color: #595959; +-} +- +-.window-list-workspace-indicator .workspace.active { +- border-color: #fff; +-} +- +-.window-list-workspace-indicator-window-preview { +- background-color: #bebebe; +- border: 1px solid #828282; +-} +- +-.window-list-workspace-indicator-window-preview.active { +- background-color: #d4d4d4; +-} +- + .notification { + font-weight: normal; + } +diff --git a/extensions/workspace-indicator/stylesheet-dark.css b/extensions/workspace-indicator/stylesheet-dark.css +index 017d844a..872c6afc 100644 +--- a/extensions/workspace-indicator/stylesheet-dark.css ++++ b/extensions/workspace-indicator/stylesheet-dark.css +@@ -39,7 +39,7 @@ + + .workspace-indicator-menu .workspace, + .workspace-indicator .workspace { +- border: 2px solid transparent; ++ border: 1px solid transparent; + border-radius: 4px; + background-color: #3f3f3f; + } +@@ -55,7 +55,7 @@ + + .workspace-indicator-menu .workspace.active, + .workspace-indicator .workspace.active { +- border-color: #9f9f9f; ++ border-color: #fff; + } + + .workspace-indicator-window-preview { +-- +2.47.0 + + +From b36d05f6d827a9063fb35a5120207718a2f30af1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Wed, 25 Sep 2024 03:36:08 +0200 +Subject: [PATCH 02/24] window-list: Small stylesheet cleanup + +The light stylesheet duplicates some declarations, and the +last occurrence matches what we already inherit from the +dark stylesheet. + +Part-of: +--- + extensions/window-list/classic.css | 10 ---------- + 1 file changed, 10 deletions(-) + +diff --git a/extensions/window-list/classic.css b/extensions/window-list/classic.css +index 088c9478..3a6ffd02 100644 +--- a/extensions/window-list/classic.css ++++ b/extensions/window-list/classic.css +@@ -21,21 +21,11 @@ + text-shadow: none; + } + +- .bottom-panel .window-button > StWidget { +- -st-natural-width: 18.7em; +- max-width: 18.75em; +- } +- + .window-button > StWidget { + color: #000; + background-color: transparent; + } + +-.window-button > StWidget { +- -st-natural-width: 18.75em; +- max-width: 18.75em; +-} +- + .window-button:hover > StWidget { + background-color: st-darken(#eee,5%); + } +-- +2.47.0 + + +From ad30fc0976bface7944beacc276c4ca85961f0d0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Tue, 25 Jun 2024 19:24:35 +0200 +Subject: [PATCH 03/24] window-list: Don't use homogeneous layout + +We want all buttons in the window list to have the same size, +but that's already achieved via max/natural-width in the CSS. + +Not enforcing the equal size via the layout manager will allow +buttons to temporarily have a different size when we start +animating additions and removals. + +Part-of: +--- + extensions/window-list/extension.js | 9 +-------- + 1 file changed, 1 insertion(+), 8 deletions(-) + +diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js +index 688ca761..a59307e2 100644 +--- a/extensions/window-list/extension.js ++++ b/extensions/window-list/extension.js +@@ -753,22 +753,15 @@ class WindowList extends St.Widget { + toggle.connect('notify::checked', + this._updateWindowListVisibility.bind(this)); + +- let layout = new Clutter.BoxLayout({ homogeneous: true }); +- this._windowList = new St.Widget({ ++ this._windowList = new St.BoxLayout({ + style_class: 'window-list', + reactive: true, +- layout_manager: layout, + x_align: Clutter.ActorAlign.START, + x_expand: true, + y_expand: true, + }); + box.add_child(this._windowList); + +- this._windowList.connect('style-changed', () => { +- let node = this._windowList.get_theme_node(); +- let spacing = node.get_length('spacing'); +- this._windowList.layout_manager.spacing = spacing; +- }); + this._windowList.connect('scroll-event', this._onScrollEvent.bind(this)); + + let indicatorsBox = new St.BoxLayout({ x_align: Clutter.ActorAlign.END }); +-- +2.47.0 + + +From 987a526802bae4970cc41c7504f98b5ac568d62d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Tue, 18 Jun 2024 18:55:05 +0200 +Subject: [PATCH 04/24] window-list: Don't hide window button while unmanaging + +This will allow to animate the transition. + +Part-of: +--- + extensions/window-list/extension.js | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js +index a59307e2..8ac59dd0 100644 +--- a/extensions/window-list/extension.js ++++ b/extensions/window-list/extension.js +@@ -417,6 +417,10 @@ class WindowButton extends BaseButton { + }); + this._updateVisibility(); + ++ this._unmanaging = false; ++ this._unmanagingId = metaWindow.connect('unmanaging', ++ () => (this._unmanaging = true)); ++ + this._windowTitle = new WindowTitle(this.metaWindow); + this.set_child(this._windowTitle); + this.label_actor = this._windowTitle.label_actor; +@@ -466,6 +470,9 @@ class WindowButton extends BaseButton { + } + + _updateVisibility() { ++ if (this._unmanaging) ++ return; ++ + this.visible = this._isWindowVisible(this.metaWindow); + } + +@@ -476,6 +483,7 @@ class WindowButton extends BaseButton { + _onDestroy() { + super._onDestroy(); + this.metaWindow.disconnect(this._skipTaskbarId); ++ this.metaWindow.disconnect(this._unmanagingId); + this.metaWindow.disconnect(this._workspaceChangedId); + global.display.disconnect(this._notifyFocusId); + this._contextMenu.destroy(); +-- +2.47.0 + + +From 9d37d880dacb3a29c4976b5442128e7269048d0e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Tue, 18 Jun 2024 18:59:38 +0200 +Subject: [PATCH 05/24] window-list: Animate buttons in and out + +Buttons are currently added and removed from the list without +any transitions, which gives the list a "jumpy" feel. Instead, +do what we do elsewhere and smoothly animate additions and +removals by re-using the dash's ItemContainer class. + +Part-of: +--- + extensions/window-list/extension.js | 34 ++++++++++++++++------------- + 1 file changed, 19 insertions(+), 15 deletions(-) + +diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js +index 8ac59dd0..cb9e7160 100644 +--- a/extensions/window-list/extension.js ++++ b/extensions/window-list/extension.js +@@ -6,6 +6,7 @@ const ExtensionUtils = imports.misc.extensionUtils; + const Main = imports.ui.main; + const Overview = imports.ui.overview; + const PopupMenu = imports.ui.popupMenu; ++const { DashItemContainer } = imports.ui.dash; + + const Me = ExtensionUtils.getCurrentExtension(); + const { WindowPicker, WindowPickerToggle } = Me.imports.windowPicker; +@@ -229,22 +230,25 @@ const BaseButton = GObject.registerClass({ + GObject.ParamFlags.READWRITE, + false), + }, +-}, class BaseButton extends St.Button { ++}, class BaseButton extends DashItemContainer { + _init(perMonitor, monitorIndex) { + this._perMonitor = perMonitor; + this._monitorIndex = monitorIndex; + this._ignoreWorkspace = false; + +- super._init({ ++ super._init(); ++ ++ this._button = new St.Button({ + style_class: 'window-button', + can_focus: true, + x_expand: true, + button_mask: St.ButtonMask.ONE | St.ButtonMask.THREE, + }); ++ this.setChild(this._button); + + this.connect('notify::allocation', + this._updateIconGeometry.bind(this)); +- this.connect('clicked', this._onClicked.bind(this)); ++ this._button.connect('clicked', this._onClicked.bind(this)); + this.connect('destroy', this._onDestroy.bind(this)); + this.connect('popup-menu', this._onPopupMenu.bind(this)); + +@@ -422,7 +426,7 @@ class WindowButton extends BaseButton { + () => (this._unmanaging = true)); + + this._windowTitle = new WindowTitle(this.metaWindow); +- this.set_child(this._windowTitle); ++ this._button.set_child(this._windowTitle); + this.label_actor = this._windowTitle.label_actor; + + this._contextMenu = new WindowContextMenu(this, this.metaWindow); +@@ -558,7 +562,7 @@ class AppButton extends BaseButton { + this._updateVisibility(); + + let stack = new St.Widget({ layout_manager: new Clutter.BinLayout() }); +- this.set_child(stack); ++ this._button.set_child(stack); + + this._singleWindowTitle = new St.Bin({ + x_expand: true, +@@ -851,7 +855,7 @@ class WindowList extends St.Widget { + + this._windowSignals = new Map(); + this._windowCreatedId = global.display.connect( +- 'window-created', (dsp, win) => this._addWindow(win)); ++ 'window-created', (dsp, win) => this._addWindow(win, true)); + + this._dragBeginId = Main.xdndHandler.connect('drag-begin', + this._monitorDrag.bind(this)); +@@ -980,14 +984,14 @@ class WindowList extends St.Widget { + w2.metaWindow.get_stable_sequence(); + }); + for (let i = 0; i < windows.length; i++) +- this._addWindow(windows[i].metaWindow); ++ this._addWindow(windows[i].metaWindow, false); + } else { + let apps = this._appSystem.get_running().sort((a1, a2) => { + return _getAppStableSequence(a1) - + _getAppStableSequence(a2); + }); + for (let i = 0; i < apps.length; i++) +- this._addApp(apps[i]); ++ this._addApp(apps[i], false); + } + } + +@@ -1001,26 +1005,26 @@ class WindowList extends St.Widget { + return; + + if (app.state === Shell.AppState.RUNNING) +- this._addApp(app); ++ this._addApp(app, true); + else if (app.state === Shell.AppState.STOPPED) + this._removeApp(app); + } + +- _addApp(app) { ++ _addApp(app, animate) { + let button = new AppButton(app, this._perMonitor, this._monitor.index); + this._settings.bind('display-all-workspaces', + button, 'ignore-workspace', Gio.SettingsBindFlags.GET); + this._windowList.add_child(button); ++ button.show(animate); + } + + _removeApp(app) { + let children = this._windowList.get_children(); + let child = children.find(c => c.app === app); +- if (child) +- child.destroy(); ++ child?.animateOutAndDestroy(); + } + +- _addWindow(win) { ++ _addWindow(win, animate) { + if (!this._grouped) + this._checkGrouping(); + +@@ -1038,6 +1042,7 @@ class WindowList extends St.Widget { + this._settings.bind('display-all-workspaces', + button, 'ignore-workspace', Gio.SettingsBindFlags.GET); + this._windowList.add_child(button); ++ button.show(animate); + } + + _removeWindow(win) { +@@ -1054,8 +1059,7 @@ class WindowList extends St.Widget { + + let children = this._windowList.get_children(); + let child = children.find(c => c.metaWindow === win); +- if (child) +- child.destroy(); ++ child?.animateOutAndDestroy(); + } + + _monitorDrag() { +-- +2.47.0 + + +From 1f2213658f6d80ab7a9710dd5aa773499747efce Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Tue, 18 Jun 2024 20:08:56 +0200 +Subject: [PATCH 06/24] window-list: Replace custom tooltip implementation + +DashItemContainer already has support for showing a tooltip-like +label, so now that we use that for animating items, we can use +it for tooltips as well. + +Part-of: +--- + extensions/window-list/extension.js | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js +index cb9e7160..0dd3775e 100644 +--- a/extensions/window-list/extension.js ++++ b/extensions/window-list/extension.js +@@ -246,6 +246,13 @@ const BaseButton = GObject.registerClass({ + }); + this.setChild(this._button); + ++ this._button.connect('notify::hover', () => { ++ if (this._button.hover) ++ this.showLabel(); ++ else ++ this.hideLabel(); ++ }); ++ + this.connect('notify::allocation', + this._updateIconGeometry.bind(this)); + this._button.connect('clicked', this._onClicked.bind(this)); +@@ -287,6 +294,18 @@ const BaseButton = GObject.registerClass({ + this._updateVisibility(); + } + ++ showLabel() { ++ const [, , preferredTitleWidth] = this.label_actor.get_preferred_size(); ++ const maxTitleWidth = this.label_actor.allocation.get_width(); ++ const isTitleFullyShown = preferredTitleWidth <= maxTitleWidth; ++ ++ const labelText = isTitleFullyShown ++ ? '' : this.label_actor.text; ++ ++ this.setLabelText(labelText); ++ super.showLabel(); ++ } ++ + _setLongPressTimeout() { + if (this._longPressTimeoutId) + return; +-- +2.47.0 + + +From 59d45cbef4ab701146325c46aea8bc6ffd13ca1f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Sat, 13 Jul 2024 00:11:19 +0200 +Subject: [PATCH 07/24] window-list: Fix .focused styling + +Commit 039c66e7b7c wrapped the button in a container to +animate transitions, but didn't adjust the `.focused` +styling to still apply to the button (where it is +expected) rather than the wrapper. + +Fix that. + +Part-of: +--- + extensions/window-list/extension.js | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js +index 0dd3775e..ec37f50f 100644 +--- a/extensions/window-list/extension.js ++++ b/extensions/window-list/extension.js +@@ -378,9 +378,9 @@ const BaseButton = GObject.registerClass({ + + _updateStyle() { + if (this._isFocused()) +- this.add_style_class_name('focused'); ++ this._button.add_style_class_name('focused'); + else +- this.remove_style_class_name('focused'); ++ this._button.remove_style_class_name('focused'); + } + + _windowEnteredOrLeftMonitor(_metaDisplay, _monitorIndex, _metaWindow) { +-- +2.47.0 + + +From ab1c5fc68916cbc2dff6302cb425f3afb4f4ea68 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Wed, 25 Sep 2024 02:23:41 +0200 +Subject: [PATCH 08/24] window-list: Split out AppTitle class + +Even though it's just a box with icon and label, it's cleaner to +have a dedicated class. + +Part-of: +--- + extensions/window-list/extension.js | 66 ++++++++++++++++++----------- + 1 file changed, 42 insertions(+), 24 deletions(-) + +diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js +index ec37f50f..e778a4d4 100644 +--- a/extensions/window-list/extension.js ++++ b/extensions/window-list/extension.js +@@ -221,6 +221,47 @@ class WindowTitle extends St.BoxLayout { + } + }); + ++const AppTitle = GObject.registerClass( ++class AppTitle extends St.BoxLayout { ++ _init(app) { ++ super._init({ ++ style_class: 'window-button-box', ++ x_expand: true, ++ y_expand: true, ++ }); ++ ++ this._app = app; ++ ++ const icon = new St.Bin({ ++ style_class: 'window-button-icon', ++ child: app.create_icon_texture(ICON_TEXTURE_SIZE), ++ }); ++ this.add_child(icon); ++ ++ let label = new St.Label({ ++ text: app.get_name(), ++ y_align: Clutter.ActorAlign.CENTER, ++ }); ++ this.add_child(label); ++ this.label_actor = label; ++ ++ this._textureCache = St.TextureCache.get_default(); ++ this._iconThemeChangedId = ++ this._textureCache.connect('icon-theme-changed', () => { ++ icon.child = app.create_icon_texture(ICON_TEXTURE_SIZE); ++ }); ++ ++ this.connect('destroy', this._onDestroy.bind(this)); ++ } ++ ++ _onDestroy() { ++ if (this._iconThemeChangedId) ++ this._textureCache.disconnect(this._iconThemeChangedId); ++ this._iconThemeChangedId = 0; ++ this._textureCache = null; ++ } ++}); ++ + + const BaseButton = GObject.registerClass({ + GTypeFlags: GObject.TypeFlags.ABSTRACT, +@@ -588,25 +629,9 @@ class AppButton extends BaseButton { + }); + stack.add_actor(this._singleWindowTitle); + +- this._multiWindowTitle = new St.BoxLayout({ +- style_class: 'window-button-box', +- x_expand: true, +- }); ++ this._multiWindowTitle = new AppTitle(app); + stack.add_actor(this._multiWindowTitle); + +- this._icon = new St.Bin({ +- style_class: 'window-button-icon', +- child: app.create_icon_texture(ICON_TEXTURE_SIZE), +- }); +- this._multiWindowTitle.add(this._icon); +- +- let label = new St.Label({ +- text: app.get_name(), +- y_align: Clutter.ActorAlign.CENTER, +- }); +- this._multiWindowTitle.add(label); +- this._multiWindowTitle.label_actor = label; +- + this._menuManager = new PopupMenu.PopupMenuManager(this); + this._menu = new PopupMenu.PopupMenu(this, 0.5, St.Side.BOTTOM); + this._menu.connect('open-state-changed', _onMenuStateChanged); +@@ -620,12 +645,6 @@ class AppButton extends BaseButton { + this._appContextMenu.actor.hide(); + Main.uiGroup.add_actor(this._appContextMenu.actor); + +- this._textureCache = St.TextureCache.get_default(); +- this._iconThemeChangedId = +- this._textureCache.connect('icon-theme-changed', () => { +- this._icon.child = app.create_icon_texture(ICON_TEXTURE_SIZE); +- }); +- + this._windowsChangedId = this.app.connect( + 'windows-changed', this._windowsChanged.bind(this)); + this._windowsChanged(); +@@ -752,7 +771,6 @@ class AppButton extends BaseButton { + + _onDestroy() { + super._onDestroy(); +- this._textureCache.disconnect(this._iconThemeChangedId); + this._windowTracker.disconnect(this._notifyFocusId); + this.app.disconnect(this._windowsChangedId); + this._menu.destroy(); +-- +2.47.0 + + +From c2cd38942205b33920002d35f347f1051501ccbe Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Wed, 25 Sep 2024 02:55:14 +0200 +Subject: [PATCH 09/24] window-list: Simplify app button + +Depending on the number of windows, the button either shows the +title of the lone window, or the app title for multiple windows. + +While we always recreate the single-window title, we only create +the app title once and hide it as necessary. Avoiding re-creating +a simple actor 50% of mode transitions isn't worth the additional +complexity, so just handle both single- and multi-window titles +the same way. + +Part-of: +--- + extensions/window-list/extension.js | 69 ++++++++++------------------- + 1 file changed, 24 insertions(+), 45 deletions(-) + +diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js +index e778a4d4..f4434afa 100644 +--- a/extensions/window-list/extension.js ++++ b/extensions/window-list/extension.js +@@ -621,17 +621,6 @@ class AppButton extends BaseButton { + this.app = app; + this._updateVisibility(); + +- let stack = new St.Widget({ layout_manager: new Clutter.BinLayout() }); +- this._button.set_child(stack); +- +- this._singleWindowTitle = new St.Bin({ +- x_expand: true, +- }); +- stack.add_actor(this._singleWindowTitle); +- +- this._multiWindowTitle = new AppTitle(app); +- stack.add_actor(this._multiWindowTitle); +- + this._menuManager = new PopupMenu.PopupMenuManager(this); + this._menu = new PopupMenu.PopupMenu(this, 0.5, St.Side.BOTTOM); + this._menu.connect('open-state-changed', _onMenuStateChanged); +@@ -640,11 +629,6 @@ class AppButton extends BaseButton { + this._menuManager.addMenu(this._menu); + Main.uiGroup.add_actor(this._menu.actor); + +- this._appContextMenu = new AppContextMenu(this); +- this._appContextMenu.connect('open-state-changed', _onMenuStateChanged); +- this._appContextMenu.actor.hide(); +- Main.uiGroup.add_actor(this._appContextMenu.actor); +- + this._windowsChangedId = this.app.connect( + 'windows-changed', this._windowsChanged.bind(this)); + this._windowsChanged(); +@@ -691,37 +675,32 @@ class AppButton extends BaseButton { + } + + _windowsChanged() { +- let windows = this.getWindowList(); +- this._singleWindowTitle.visible = windows.length === 1; +- this._multiWindowTitle.visible = !this._singleWindowTitle.visible; +- +- if (this._singleWindowTitle.visible) { +- if (!this._windowTitle) { +- this.metaWindow = windows[0]; +- this._windowTitle = new WindowTitle(this.metaWindow); +- this._singleWindowTitle.child = this._windowTitle; +- this._windowContextMenu = new WindowContextMenu(this, this.metaWindow); +- this._windowContextMenu.connect( +- 'open-state-changed', _onMenuStateChanged); +- Main.uiGroup.add_actor(this._windowContextMenu.actor); +- this._windowContextMenu.actor.hide(); +- this._contextMenuManager.addMenu(this._windowContextMenu); +- } +- this._contextMenuManager.removeMenu(this._appContextMenu); +- this._contextMenu = this._windowContextMenu; +- this.label_actor = this._windowTitle.label_actor; ++ const windows = this.getWindowList(); ++ const singleWindowMode = windows.length === 1; ++ ++ if (this._singleWindowMode === singleWindowMode) ++ return; ++ ++ this._singleWindowMode = singleWindowMode; ++ ++ this._button.child?.destroy(); ++ this._contextMenu?.destroy(); ++ ++ if (this._singleWindowMode) { ++ const [window] = windows; ++ this._button.child = new WindowTitle(window); ++ this._contextMenu = new WindowContextMenu(this, window); + } else { +- if (this._windowTitle) { +- this.metaWindow = null; +- this._singleWindowTitle.child = null; +- this._windowTitle = null; +- this._windowContextMenu.destroy(); +- this._windowContextMenu = null; +- } +- this._contextMenu = this._appContextMenu; +- this._contextMenuManager.addMenu(this._appContextMenu); +- this.label_actor = this._multiWindowTitle.label_actor; ++ this._button.child = new AppTitle(this.app); ++ this._contextMenu = new AppContextMenu(this); + } ++ ++ this.label_actor = this._button.child.label_actor; ++ ++ this._contextMenu.connect('open-state-changed', _onMenuStateChanged); ++ Main.uiGroup.add_child(this._contextMenu.actor); ++ this._contextMenu.actor.hide(); ++ this._contextMenuManager.addMenu(this._contextMenu); + } + + _onClicked(actor, button) { +-- +2.47.0 + + +From beadfe2a6f6a7627096cad5a2161add902edf039 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Mon, 7 Oct 2024 17:22:04 +0200 +Subject: [PATCH 10/24] window-list: Fix minimized styling + +Commit 039c66e7b7c wrapped the button in a container to +animate transitions, but didn't adjust the `.minimized` +styling to still apply to the button (where it is +expected) rather than the wrapper. + +Fix this just like commit c72b8b21 did for the +`.focused` styling. + +Part-of: +--- + extensions/window-list/extension.js | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js +index f4434afa..6c00686c 100644 +--- a/extensions/window-list/extension.js ++++ b/extensions/window-list/extension.js +@@ -523,9 +523,9 @@ class WindowButton extends BaseButton { + super._updateStyle(); + + if (this.metaWindow.minimized) +- this.add_style_class_name('minimized'); ++ this._button.add_style_class_name('minimized'); + else +- this.remove_style_class_name('minimized'); ++ this._button.remove_style_class_name('minimized'); + } + + _windowEnteredOrLeftMonitor(metaDisplay, monitorIndex, metaWindow) { +-- +2.47.0 + + +From 77a1b57678e62ad091e09d5e97299d53999a3521 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Mon, 7 Oct 2024 17:10:43 +0200 +Subject: [PATCH 11/24] window-list: Fix active state + +Commit c72b8b21 fixed the styling of the active window's button, +but missed that the `active` property uses the style information +as well. + +Adjust it to use the correct actor when checking for the style class. + +Closes https://gitlab.gnome.org/GNOME/gnome-shell-extensions/-/issues/529 + +Part-of: +--- + extensions/window-list/extension.js | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js +index 6c00686c..936dd9e4 100644 +--- a/extensions/window-list/extension.js ++++ b/extensions/window-list/extension.js +@@ -316,7 +316,7 @@ const BaseButton = GObject.registerClass({ + } + + get active() { +- return this.has_style_class_name('focused'); ++ return this._button.has_style_class_name('focused'); + } + + // eslint-disable-next-line camelcase +-- +2.47.0 + + +From 8ab9ab5cc43ccea7a3208b72e08f32685584c869 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Tue, 15 Oct 2024 17:48:52 +0200 +Subject: [PATCH 12/24] window-list: Remove outdated style + +A long time ago, the window list used to embed the bottom message +tray, which caused notifications to inherit the window-list's +font style. + +Since that's no longer the case, we have no business in messing +with notification styling, so stop doing that. +--- + extensions/window-list/stylesheet.css | 4 ---- + 1 file changed, 4 deletions(-) + +diff --git a/extensions/window-list/stylesheet.css b/extensions/window-list/stylesheet.css +index b9087971..f02fca60 100644 +--- a/extensions/window-list/stylesheet.css ++++ b/extensions/window-list/stylesheet.css +@@ -81,7 +81,3 @@ + width: 24px; + height: 24px; + } +- +-.notification { +- font-weight: normal; +-} +-- +2.47.0 + + +From 807da4082a3a78789ab4926fd1074a8040f5d794 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Thu, 26 Sep 2024 19:07:11 +0200 +Subject: [PATCH 13/24] window-list: Split out some common code + +Adding an app button and adding a window button involves some +shared steps, move those to a shared `_addButton()` method. +--- + extensions/window-list/extension.js | 15 ++++++++------- + 1 file changed, 8 insertions(+), 7 deletions(-) + +diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js +index 936dd9e4..d92a4155 100644 +--- a/extensions/window-list/extension.js ++++ b/extensions/window-list/extension.js +@@ -1026,14 +1026,18 @@ class WindowList extends St.Widget { + this._removeApp(app); + } + +- _addApp(app, animate) { +- let button = new AppButton(app, this._perMonitor, this._monitor.index); ++ _addButton(button, animate) { + this._settings.bind('display-all-workspaces', + button, 'ignore-workspace', Gio.SettingsBindFlags.GET); + this._windowList.add_child(button); + button.show(animate); + } + ++ _addApp(app, animate) { ++ const button = new AppButton(app, this._perMonitor, this._monitor.index); ++ this._addButton(button, animate); ++ } ++ + _removeApp(app) { + let children = this._windowList.get_children(); + let child = children.find(c => c.app === app); +@@ -1054,11 +1058,8 @@ class WindowList extends St.Widget { + this._windowSignals.set( + win, win.connect('unmanaged', () => this._removeWindow(win))); + +- let button = new WindowButton(win, this._perMonitor, this._monitor.index); +- this._settings.bind('display-all-workspaces', +- button, 'ignore-workspace', Gio.SettingsBindFlags.GET); +- this._windowList.add_child(button); +- button.show(animate); ++ const button = new WindowButton(win, this._perMonitor, this._monitor.index); ++ this._addButton(button, animate); + } + + _removeWindow(win) { +-- +2.47.0 + + +From e10c1fd24bc86c7d980f50efd9e663b42097d2f1 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Thu, 3 Oct 2024 17:19:31 +0200 +Subject: [PATCH 14/24] window-list: Split out common TitleWidget class + +Both app- and window title use the same structure, so add a shared +base class. +--- + extensions/window-list/extension.js | 61 ++++++++++++++--------------- + 1 file changed, 30 insertions(+), 31 deletions(-) + +diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js +index d92a4155..69058fcd 100644 +--- a/extensions/window-list/extension.js ++++ b/extensions/window-list/extension.js +@@ -133,22 +133,35 @@ class WindowContextMenu extends PopupMenu.PopupMenu { + } + } + +-const WindowTitle = GObject.registerClass( +-class WindowTitle extends St.BoxLayout { +- _init(metaWindow) { +- this._metaWindow = metaWindow; +- ++const TitleWidget = GObject.registerClass({ ++ GTypeFlags: GObject.TypeFlags.ABSTRACT, ++}, class TitleWidget extends St.BoxLayout { ++ _init() { + super._init({ + style_class: 'window-button-box', + x_expand: true, + y_expand: true, + }); + +- this._icon = new St.Bin({ style_class: 'window-button-icon' }); +- this.add(this._icon); +- this.label_actor = new St.Label({ y_align: Clutter.ActorAlign.CENTER }); +- this.label_actor.clutter_text.single_line_mode = true; +- this.add(this.label_actor); ++ this._icon = new St.Bin({ ++ style_class: 'window-button-icon', ++ }); ++ this.add_child(this._icon); ++ ++ this._label = new St.Label({ ++ y_align: Clutter.ActorAlign.CENTER, ++ }); ++ this.add_child(this._label); ++ this.label_actor = this._label; ++ } ++}); ++ ++const WindowTitle = GObject.registerClass( ++class WindowTitle extends TitleWidget { ++ _init(metaWindow) { ++ super._init(); ++ ++ this._metaWindow = metaWindow; + + this._textureCache = St.TextureCache.get_default(); + this._iconThemeChangedId = this._textureCache.connect( +@@ -178,9 +191,9 @@ class WindowTitle extends St.BoxLayout { + return; + + if (this._metaWindow.minimized) +- this.label_actor.text = '[%s]'.format(this._metaWindow.title); ++ this._label.text = '[%s]'.format(this._metaWindow.title); + else +- this.label_actor.text = this._metaWindow.title; ++ this._label.text = this._metaWindow.title; + } + + _updateIcon() { +@@ -222,33 +235,19 @@ class WindowTitle extends St.BoxLayout { + }); + + const AppTitle = GObject.registerClass( +-class AppTitle extends St.BoxLayout { ++class AppTitle extends TitleWidget { + _init(app) { +- super._init({ +- style_class: 'window-button-box', +- x_expand: true, +- y_expand: true, +- }); ++ super._init(); + + this._app = app; + +- const icon = new St.Bin({ +- style_class: 'window-button-icon', +- child: app.create_icon_texture(ICON_TEXTURE_SIZE), +- }); +- this.add_child(icon); +- +- let label = new St.Label({ +- text: app.get_name(), +- y_align: Clutter.ActorAlign.CENTER, +- }); +- this.add_child(label); +- this.label_actor = label; ++ this._icon.child = app.create_icon_texture(ICON_TEXTURE_SIZE); ++ this._label.text = app.get_name(); + + this._textureCache = St.TextureCache.get_default(); + this._iconThemeChangedId = + this._textureCache.connect('icon-theme-changed', () => { +- icon.child = app.create_icon_texture(ICON_TEXTURE_SIZE); ++ this._icon.child = app.create_icon_texture(ICON_TEXTURE_SIZE); + }); + + this.connect('destroy', this._onDestroy.bind(this)); +-- +2.47.0 + + +From e29fb2e04541157a6233b702588a3d206ad68615 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Thu, 3 Oct 2024 17:27:57 +0200 +Subject: [PATCH 15/24] window-list: Add TitleWidget:abstract-label property + +When true, the real label is replaced by a more abstract +representation. When used as drag actor, the focus is not +on identifying the window/app, but about picking a drop +location, and the reduced style helps with that. +--- + extensions/window-list/extension.js | 22 ++++++++++++++++++++++ + extensions/window-list/stylesheet.css | 6 ++++++ + 2 files changed, 28 insertions(+) + +diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js +index 69058fcd..fc47d2e6 100644 +--- a/extensions/window-list/extension.js ++++ b/extensions/window-list/extension.js +@@ -135,6 +135,12 @@ class WindowContextMenu extends PopupMenu.PopupMenu { + + const TitleWidget = GObject.registerClass({ + GTypeFlags: GObject.TypeFlags.ABSTRACT, ++ Properties: { ++ 'abstract-label': GObject.ParamSpec.boolean( ++ 'abstract-label', '', '', ++ GObject.ParamFlags.READWRITE, ++ false), ++ }, + }, class TitleWidget extends St.BoxLayout { + _init() { + super._init({ +@@ -153,6 +159,22 @@ const TitleWidget = GObject.registerClass({ + }); + this.add_child(this._label); + this.label_actor = this._label; ++ ++ this.bind_property('abstract-label', ++ this._label, 'visible', ++ GObject.BindingFlags.SYNC_CREATE | ++ GObject.BindingFlags.INVERT_BOOLEAN); ++ ++ this._abstractLabel = new St.Widget({ ++ style_class: 'window-button-abstract-label', ++ x_expand: true, ++ y_expand: true, ++ }); ++ this.add_child(this._abstractLabel); ++ ++ this.bind_property('abstract-label', ++ this._abstractLabel, 'visible', ++ GObject.BindingFlags.SYNC_CREATE); + } + }); + +diff --git a/extensions/window-list/stylesheet.css b/extensions/window-list/stylesheet.css +index f02fca60..fce6bcc5 100644 +--- a/extensions/window-list/stylesheet.css ++++ b/extensions/window-list/stylesheet.css +@@ -81,3 +81,9 @@ + width: 24px; + height: 24px; + } ++ ++.window-button-abstract-label { ++ background-color: #888; ++ border-radius: 99px; ++ margin: 6px; ++} +-- +2.47.0 + + +From e0a5584a79d938d649c17b54267bfb83d547f984 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Wed, 25 Sep 2024 03:20:52 +0200 +Subject: [PATCH 16/24] window-list: Split out `_createTitleActor()` hook + +This will allow creating a suitable drag actor that matches the +current title. In particular this allows for a drag actor that +isn't based on `ClutterClone`, and therefore doesn't inherit +focus/active/minimize/etc. styles that don't make sense outside +the actual window list. +--- + extensions/window-list/extension.js | 23 ++++++++++++++++++++--- + 1 file changed, 20 insertions(+), 3 deletions(-) + +diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js +index fc47d2e6..a65e2108 100644 +--- a/extensions/window-list/extension.js ++++ b/extensions/window-list/extension.js +@@ -418,6 +418,11 @@ const BaseButton = GObject.registerClass({ + this._onClicked(this, 1); + } + ++ _createTitleActor() { ++ throw new GObject.NotImplementedError( ++ `_createTitleActor in ${this.constructor.name}`); ++ } ++ + _onClicked(_actor, _button) { + throw new GObject.NotImplementedError( + `_onClicked in ${this.constructor.name}`); +@@ -506,7 +511,7 @@ class WindowButton extends BaseButton { + this._unmanagingId = metaWindow.connect('unmanaging', + () => (this._unmanaging = true)); + +- this._windowTitle = new WindowTitle(this.metaWindow); ++ this._windowTitle = this._createTitleActor(); + this._button.set_child(this._windowTitle); + this.label_actor = this._windowTitle.label_actor; + +@@ -524,6 +529,10 @@ class WindowButton extends BaseButton { + this._updateStyle(); + } + ++ _createTitleActor() { ++ return new WindowTitle(this.metaWindow); ++ } ++ + _onClicked(actor, button) { + if (this._contextMenu.isOpen) { + this._contextMenu.close(); +@@ -709,13 +718,12 @@ class AppButton extends BaseButton { + + if (this._singleWindowMode) { + const [window] = windows; +- this._button.child = new WindowTitle(window); + this._contextMenu = new WindowContextMenu(this, window); + } else { +- this._button.child = new AppTitle(this.app); + this._contextMenu = new AppContextMenu(this); + } + ++ this._button.child = this._createTitleActor(); + this.label_actor = this._button.child.label_actor; + + this._contextMenu.connect('open-state-changed', _onMenuStateChanged); +@@ -724,6 +732,15 @@ class AppButton extends BaseButton { + this._contextMenuManager.addMenu(this._contextMenu); + } + ++ _createTitleActor() { ++ if (this._singleWindowMode) { ++ const [window] = this.getWindowList(); ++ return new WindowTitle(window); ++ } else { ++ return new AppTitle(this.app); ++ } ++ } ++ + _onClicked(actor, button) { + let menuWasOpen = this._menu.isOpen; + if (menuWasOpen) +-- +2.47.0 + + +From 75e0bbd671101dea9803d3fdcfe10d67e5f71e5d Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Wed, 19 Jun 2024 13:01:37 +0200 +Subject: [PATCH 17/24] window-list: Rename XDND related methods and props + +The window list buttons themselves will become draggable, so +include "xdnd" in the existing drag handling to disambiguate +it. +--- + extensions/window-list/extension.js | 20 ++++++++++---------- + 1 file changed, 10 insertions(+), 10 deletions(-) + +diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js +index a65e2108..263a2af8 100644 +--- a/extensions/window-list/extension.js ++++ b/extensions/window-list/extension.js +@@ -912,11 +912,11 @@ class WindowList extends St.Widget { + 'window-created', (dsp, win) => this._addWindow(win, true)); + + this._dragBeginId = Main.xdndHandler.connect('drag-begin', +- this._monitorDrag.bind(this)); ++ this._monitorXdndDrag.bind(this)); + this._dragEndId = Main.xdndHandler.connect('drag-end', +- this._stopMonitoringDrag.bind(this)); +- this._dragMonitor = { +- dragMotion: this._onDragMotion.bind(this), ++ this._stopMonitoringXdndDrag.bind(this)); ++ this._xdndDragMonitor = { ++ dragMotion: this._onXdndDragMotion.bind(this), + }; + + this._dndTimeoutId = 0; +@@ -1117,16 +1117,16 @@ class WindowList extends St.Widget { + child?.animateOutAndDestroy(); + } + +- _monitorDrag() { +- DND.addDragMonitor(this._dragMonitor); ++ _monitorXdndDrag() { ++ DND.addDragMonitor(this._xdndDragMonitor); + } + +- _stopMonitoringDrag() { +- DND.removeDragMonitor(this._dragMonitor); ++ _stopMonitoringXdndDrag() { ++ DND.removeDragMonitor(this._xdndDragMonitor); + this._removeActivateTimeout(); + } + +- _onDragMotion(dragEvent) { ++ _onXdndDragMotion(dragEvent) { + if (Main.overview.visible || + !this.contains(dragEvent.targetActor)) { + this._removeActivateTimeout(); +@@ -1195,7 +1195,7 @@ class WindowList extends St.Widget { + global.display.disconnect(this._fullscreenChangedId); + global.display.disconnect(this._windowCreatedId); + +- this._stopMonitoringDrag(); ++ this._stopMonitoringXdndDrag(); + Main.xdndHandler.disconnect(this._dragBeginId); + Main.xdndHandler.disconnect(this._dragEndId); + +-- +2.47.0 + + +From 4ae3577e50907cdf0f257fd559475b1decdf4af0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Wed, 25 Sep 2024 04:13:25 +0200 +Subject: [PATCH 18/24] window-list: Allow rearranging window buttons + +We currently sort buttons by the stable sequence to get a persistent +and predictable order. However some users want to customize that +order, and rearrange the buttons as they see fit. + +Support that use case by implementing drag-and-drop behavior based +on the overview's dash. + +Closes https://gitlab.gnome.org/GNOME/gnome-shell-extensions/issues/4 +--- + extensions/window-list/classic.css | 5 + + extensions/window-list/extension.js | 140 ++++++++++++++++++++++++++ + extensions/window-list/stylesheet.css | 14 ++- + 3 files changed, 157 insertions(+), 2 deletions(-) + +diff --git a/extensions/window-list/classic.css b/extensions/window-list/classic.css +index 3a6ffd02..74945657 100644 +--- a/extensions/window-list/classic.css ++++ b/extensions/window-list/classic.css +@@ -56,3 +56,8 @@ + color: #aaa; + background-color: #f9f9f9; + } ++ ++.window-button-drag-actor { ++ background-color: #ddd; ++ border-color: #888; ++} +diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js +index 263a2af8..574c85ac 100644 +--- a/extensions/window-list/extension.js ++++ b/extensions/window-list/extension.js +@@ -18,6 +18,8 @@ const _ = Gettext.gettext; + const ICON_TEXTURE_SIZE = 24; + const DND_ACTIVATE_TIMEOUT = 500; + ++const MIN_DRAG_UPDATE_INTERVAL = 500 * GLib.TIME_SPAN_MILLISECOND; ++ + const GroupingMode = { + NEVER: 0, + AUTO: 1, +@@ -25,6 +27,14 @@ const GroupingMode = { + }; + + ++const DragPlaceholderItem = GObject.registerClass( ++class DragPlaceholderItem extends DashItemContainer { ++ _init() { ++ super._init(); ++ this.setChild(new St.Bin({ style_class: 'placeholder' })); ++ } ++}); ++ + function _minimizeOrActivateWindow(window) { + let focusWindow = global.display.focus_window; + if (focusWindow === window || +@@ -283,6 +293,18 @@ class AppTitle extends TitleWidget { + } + }); + ++const DragActor = GObject.registerClass( ++class DragActor extends St.Bin { ++ _init(source, titleActor) { ++ super._init({ ++ style_class: 'window-button-drag-actor', ++ child: titleActor, ++ width: source.width, ++ }); ++ ++ this.source = source; ++ } ++}); + + const BaseButton = GObject.registerClass({ + GTypeFlags: GObject.TypeFlags.ABSTRACT, +@@ -292,6 +314,10 @@ const BaseButton = GObject.registerClass({ + GObject.ParamFlags.READWRITE, + false), + }, ++ Signals: { ++ 'drag-begin': {}, ++ 'drag-end': {}, ++ }, + }, class BaseButton extends DashItemContainer { + _init(perMonitor, monitorIndex) { + this._perMonitor = perMonitor; +@@ -334,6 +360,15 @@ const BaseButton = GObject.registerClass({ + 'window-left-monitor', + this._windowEnteredOrLeftMonitor.bind(this)); + } ++ ++ this._button._delegate = this; ++ this._draggable = DND.makeDraggable(this._button); ++ this._draggable.connect('drag-begin', () => { ++ this._removeLongPressTimeout(); ++ this.emit('drag-begin'); ++ }); ++ this._draggable.connect('drag-cancelled', () => this.emit('drag-end')); ++ this._draggable.connect('drag-end', () => this.emit('drag-end')); + } + + get active() { +@@ -418,6 +453,17 @@ const BaseButton = GObject.registerClass({ + this._onClicked(this, 1); + } + ++ getDragActor() { ++ const titleActor = this._createTitleActor(); ++ titleActor.set({ abstractLabel: true }); ++ ++ return new DragActor(this, titleActor); ++ } ++ ++ getDragActorSource() { ++ return this; ++ } ++ + _createTitleActor() { + throw new GObject.NotImplementedError( + `_createTitleActor in ${this.constructor.name}`); +@@ -919,9 +965,19 @@ class WindowList extends St.Widget { + dragMotion: this._onXdndDragMotion.bind(this), + }; + ++ this._itemDragMonitor = { ++ dragMotion: this._onItemDragMotion.bind(this), ++ }; ++ + this._dndTimeoutId = 0; + this._dndWindow = null; + ++ this._dragPlaceholder = null; ++ this._dragPlaceholderPos = -1; ++ this._lastPlaceholderUpdate = 0; ++ ++ this._delegate = this; ++ + this._settings = ExtensionUtils.getSettings(); + this._settings.connect('changed::grouping-mode', + () => this._groupingModeChanged()); +@@ -1067,6 +1123,14 @@ class WindowList extends St.Widget { + _addButton(button, animate) { + this._settings.bind('display-all-workspaces', + button, 'ignore-workspace', Gio.SettingsBindFlags.GET); ++ ++ button.connect('drag-begin', ++ () => this._monitorItemDrag()); ++ button.connect('drag-end', () => { ++ this._stopMonitoringItemDrag(); ++ this._clearDragPlaceholder(); ++ }); ++ + this._windowList.add_child(button); + button.show(animate); + } +@@ -1117,6 +1181,82 @@ class WindowList extends St.Widget { + child?.animateOutAndDestroy(); + } + ++ _clearDragPlaceholder() { ++ this._dragPlaceholder?.animateOutAndDestroy(); ++ this._dragPlaceholder = null; ++ this._dragPlaceholderPos = -1; ++ } ++ ++ handleDragOver(source, _actor, x, _y, _time) { ++ if (!(source instanceof BaseButton)) ++ return DND.DragMotionResult.NO_DROP; ++ ++ const buttons = this._windowList.get_children().filter(c => c instanceof BaseButton); ++ const buttonPos = buttons.indexOf(source); ++ const numButtons = buttons.length; ++ let boxWidth = this._windowList.width; ++ ++ // Transform to window list coordinates for index calculation ++ // (mostly relevant for RTL to discard workspace indicator etc.) ++ x -= this._windowList.x; ++ ++ const rtl = this.text_direction === Clutter.TextDirection.RTL; ++ let pos = rtl ++ ? numButtons - Math.round(x * numButtons / boxWidth) ++ : Math.round(x * numButtons / boxWidth); ++ ++ pos = Math.clamp(pos, 0, numButtons); ++ ++ const timeDelta = ++ GLib.get_monotonic_time() - this._lastPlaceholderUpdate; ++ ++ if (pos !== this._dragPlaceholderPos && timeDelta >= MIN_DRAG_UPDATE_INTERVAL) { ++ this._clearDragPlaceholder(); ++ this._dragPlaceholderPos = pos; ++ ++ this._lastPlaceholderUpdate = GLib.get_monotonic_time(); ++ ++ // Don't allow positioning before or after self ++ if (pos === buttonPos || pos === buttonPos + 1) ++ return DND.DragMotionResult.CONTINUE; ++ ++ this._dragPlaceholder = new DragPlaceholderItem(); ++ const sibling = buttons[pos]; ++ if (sibling) ++ this._windowList.insert_child_below(this._dragPlaceholder, sibling); ++ else ++ this._windowList.insert_child_above(this._dragPlaceholder, null); ++ this._dragPlaceholder.show(true); ++ } ++ ++ return this._dragPlaceholder ++ ? DND.DragMotionResult.MOVE_DROP ++ : DND.DragMotionResult.NO_DROP; ++ } ++ ++ acceptDrop(source, _actor, _x, _y, _time) { ++ if (this._dragPlaceholderPos >= 0) ++ this._windowList.set_child_at_index(source, this._dragPlaceholderPos); ++ ++ this._clearDragPlaceholder(); ++ ++ return true; ++ } ++ ++ _monitorItemDrag() { ++ DND.addDragMonitor(this._itemDragMonitor); ++ } ++ ++ _stopMonitoringItemDrag() { ++ DND.removeDragMonitor(this._itemDragMonitor); ++ } ++ ++ _onItemDragMotion(dragEvent) { ++ if (!this._windowList.contains(dragEvent.targetActor)) ++ this._clearDragPlaceholder(); ++ return DND.DragMotionResult.CONTINUE; ++ } ++ + _monitorXdndDrag() { + DND.addDragMonitor(this._xdndDragMonitor); + } +diff --git a/extensions/window-list/stylesheet.css b/extensions/window-list/stylesheet.css +index fce6bcc5..c92081d2 100644 +--- a/extensions/window-list/stylesheet.css ++++ b/extensions/window-list/stylesheet.css +@@ -17,10 +17,19 @@ + height: 2.45em; + } + +-.window-button { ++.window-button, ++.window-button-drag-actor { + padding: 4px, 3px; + } + ++.window-button-drag-actor { ++ background-color: #444; ++ border-radius: 7px; ++ border-width: 2px; ++ border-color: #fff; ++ box-shadow: 0 1px 2px rgba(0,0,0,0.1); ++} ++ + .window-button:first-child:ltr { + padding-left: 2px; + } +@@ -41,7 +50,8 @@ + transition: 100ms ease; + } + +-.window-button > StWidget { ++.window-button > StWidget, ++.window-list .placeholder { + -st-natural-width: 18.75em; + max-width: 18.75em; + } +-- +2.47.0 + + +From 324236e9f4ba7a1ca743c0a432b246dfc9216001 Mon Sep 17 00:00:00 2001 +From: Jakub Steiner +Date: Thu, 3 Oct 2024 14:18:32 +0200 +Subject: [PATCH 19/24] window-list: Indicate drop target more prominently + +The drop target is the main focus of the drag operation, so make +its styling more prominent. +--- + extensions/window-list/classic.css | 5 ++++- + extensions/window-list/stylesheet.css | 6 ++++++ + 2 files changed, 10 insertions(+), 1 deletion(-) + +diff --git a/extensions/window-list/classic.css b/extensions/window-list/classic.css +index 74945657..1147984c 100644 +--- a/extensions/window-list/classic.css ++++ b/extensions/window-list/classic.css +@@ -23,7 +23,6 @@ + + .window-button > StWidget { + color: #000; +- background-color: transparent; + } + + .window-button:hover > StWidget { +@@ -61,3 +60,7 @@ + background-color: #ddd; + border-color: #888; + } ++ ++.window-list .placeholder { ++ border-color: rgba(0,0,0,0.5); ++} +diff --git a/extensions/window-list/stylesheet.css b/extensions/window-list/stylesheet.css +index c92081d2..4c06ebc0 100644 +--- a/extensions/window-list/stylesheet.css ++++ b/extensions/window-list/stylesheet.css +@@ -56,6 +56,12 @@ + max-width: 18.75em; + } + ++.window-list .placeholder { ++ border: 1px solid rgba(255,255,255,0.4); ++ border-radius: 7px; ++ margin: 4px; ++} ++ + .window-button:hover > StWidget { + background-color: #303030; + } +-- +2.47.0 + + +From 5b35516962e6c326f9ae4236a798b6e521d0c850 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Thu, 3 Oct 2024 17:05:42 +0200 +Subject: [PATCH 20/24] window-list: Fade out drag source during drag + +During a drag operation, the focus is on the where to drop the dragged +item, not to identify it or its origin. +--- + extensions/window-list/extension.js | 18 ++++++++++++++++-- + 1 file changed, 16 insertions(+), 2 deletions(-) + +diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js +index 574c85ac..5aca473c 100644 +--- a/extensions/window-list/extension.js ++++ b/extensions/window-list/extension.js +@@ -20,6 +20,9 @@ const DND_ACTIVATE_TIMEOUT = 500; + + const MIN_DRAG_UPDATE_INTERVAL = 500 * GLib.TIME_SPAN_MILLISECOND; + ++const DRAG_OPACITY = 0.3; ++const DRAG_FADE_DURATION = 200; ++ + const GroupingMode = { + NEVER: 0, + AUTO: 1, +@@ -1124,9 +1127,20 @@ class WindowList extends St.Widget { + this._settings.bind('display-all-workspaces', + button, 'ignore-workspace', Gio.SettingsBindFlags.GET); + +- button.connect('drag-begin', +- () => this._monitorItemDrag()); ++ button.connect('drag-begin', () => { ++ button.ease({ ++ opacity: 255 * DRAG_OPACITY, ++ duration: DRAG_FADE_DURATION, ++ }); ++ ++ this._monitorItemDrag(); ++ }); + button.connect('drag-end', () => { ++ button.ease({ ++ opacity: 255, ++ duration: DRAG_FADE_DURATION, ++ }); ++ + this._stopMonitoringItemDrag(); + this._clearDragPlaceholder(); + }); +-- +2.47.0 + + +From bfbb54b4c903ec41f61748868d5f175ad469d811 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Wed, 9 Oct 2024 19:15:16 +0200 +Subject: [PATCH 21/24] window-list: Shrink drag-actor size during drags + +Like the previous commit, this helps with putting the focus on +the target location instead of the dragged item. +--- + extensions/window-list/extension.js | 32 +++++++++++++++++++++++++++-- + 1 file changed, 30 insertions(+), 2 deletions(-) + +diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js +index 5aca473c..2d5ce525 100644 +--- a/extensions/window-list/extension.js ++++ b/extensions/window-list/extension.js +@@ -23,6 +23,8 @@ const MIN_DRAG_UPDATE_INTERVAL = 500 * GLib.TIME_SPAN_MILLISECOND; + const DRAG_OPACITY = 0.3; + const DRAG_FADE_DURATION = 200; + ++const DRAG_RESIZE_DURATION = 400; ++ + const GroupingMode = { + NEVER: 0, + AUTO: 1, +@@ -307,6 +309,23 @@ class DragActor extends St.Bin { + + this.source = source; + } ++ ++ setTargetWidth(width) { ++ const currentWidth = this.width; ++ ++ // set width immediately so shell's DND code uses correct values ++ this.set({ width }); ++ ++ // then transition from the original to the new width ++ Meta.later_add(Meta.LaterType.BEFORE_REDRAW, () => { ++ this.set({ width: currentWidth }); ++ this.ease({ ++ width, ++ duration: DRAG_RESIZE_DURATION, ++ }); ++ return GLib.SOURCE_REMOVE; ++ }); ++ } + }); + + const BaseButton = GObject.registerClass({ +@@ -370,7 +389,10 @@ const BaseButton = GObject.registerClass({ + this._removeLongPressTimeout(); + this.emit('drag-begin'); + }); +- this._draggable.connect('drag-cancelled', () => this.emit('drag-end')); ++ this._draggable.connect('drag-cancelled', () => { ++ this._draggable._dragActor?.setTargetWidth(this.width); ++ this.emit('drag-end'); ++ }); + this._draggable.connect('drag-end', () => this.emit('drag-end')); + } + +@@ -460,7 +482,13 @@ const BaseButton = GObject.registerClass({ + const titleActor = this._createTitleActor(); + titleActor.set({ abstractLabel: true }); + +- return new DragActor(this, titleActor); ++ const dragActor = new DragActor(this, titleActor); ++ ++ const [, natWidth] = this.get_preferred_width(-1); ++ const targetWidth = Math.min(natWidth / 2, this.width); ++ dragActor.setTargetWidth(targetWidth); ++ ++ return dragActor; + } + + getDragActorSource() { +-- +2.47.0 + + +From be721d3fee4faf5060dcf1a83fa5adc8e7ee5f89 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Tue, 8 Oct 2024 19:25:53 +0200 +Subject: [PATCH 22/24] window-list: Handle DND events near the drop target + +Even with the previous change, the dragged actor has the tendency +of obscuring the possible drop target. To alleviate this, handle +DND events near drop targets as if they occurred on the target. +--- + extensions/window-list/extension.js | 26 ++++++++++++++++++++++++-- + 1 file changed, 24 insertions(+), 2 deletions(-) + +diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js +index 2d5ce525..b6c00f8b 100644 +--- a/extensions/window-list/extension.js ++++ b/extensions/window-list/extension.js +@@ -25,6 +25,8 @@ const DRAG_FADE_DURATION = 200; + + const DRAG_RESIZE_DURATION = 400; + ++const DRAG_PROXIMITY_THRESHOLD = 30; ++ + const GroupingMode = { + NEVER: 0, + AUTO: 1, +@@ -998,6 +1000,7 @@ class WindowList extends St.Widget { + + this._itemDragMonitor = { + dragMotion: this._onItemDragMotion.bind(this), ++ dragDrop: this._onItemDragDrop.bind(this), + }; + + this._dndTimeoutId = 0; +@@ -1294,11 +1297,30 @@ class WindowList extends St.Widget { + } + + _onItemDragMotion(dragEvent) { +- if (!this._windowList.contains(dragEvent.targetActor)) +- this._clearDragPlaceholder(); ++ const { source, targetActor, dragActor, x, y } = dragEvent; ++ ++ const hasTarget = this._windowList.contains(targetActor); ++ const isNear = Math.abs(y - this.y) < DRAG_PROXIMITY_THRESHOLD; ++ ++ if (hasTarget || isNear) ++ return this.handleDragOver(source, dragActor, x, y); ++ ++ this._clearDragPlaceholder(); + return DND.DragMotionResult.CONTINUE; + } + ++ _onItemDragDrop(dropEvent) { ++ if (this._dragPlaceholderPos < 0) ++ return DND.DragDropResult.CONTINUE; ++ ++ const { source } = dropEvent.dropActor; ++ this.acceptDrop(source); ++ dropEvent.dropActor.destroy(); ++ // HACK: SUCESS would make more sense, but results in gnome-shell ++ // skipping all drag-end code ++ return DND.DragDropResult.CONTINUE; ++ } ++ + _monitorXdndDrag() { + DND.addDragMonitor(this._xdndDragMonitor); + } +-- +2.47.0 + + +From 66672ca11281deb9326dd164759db749263c143c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Wed, 26 Jun 2024 00:58:18 +0200 +Subject: [PATCH 23/24] window-list: Add `id` property to buttons + +A string ID that uniquely identifies a button will allow to +serialize/deserialize the positions in the next commit. +--- + extensions/window-list/extension.js | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js +index b6c00f8b..feefc66e 100644 +--- a/extensions/window-list/extension.js ++++ b/extensions/window-list/extension.js +@@ -608,6 +608,10 @@ class WindowButton extends BaseButton { + this._updateStyle(); + } + ++ get id() { ++ return `window:${this.metaWindow.get_id()}`; ++ } ++ + _createTitleActor() { + return new WindowTitle(this.metaWindow); + } +@@ -748,6 +752,10 @@ class AppButton extends BaseButton { + this._updateStyle(); + } + ++ get id() { ++ return `app:${this.app.get_id()}`; ++ } ++ + _windowEnteredOrLeftMonitor(metaDisplay, monitorIndex, metaWindow) { + if (this._windowTracker.get_window_app(metaWindow) === this.app && + monitorIndex === this._monitorIndex) { +-- +2.47.0 + + +From 6f11b79c65085a49e6907571ad51f972c1579685 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Tue, 24 Sep 2024 20:31:06 +0200 +Subject: [PATCH 24/24] window-list: Save and restore positions as runtime + state + +While it doesn't make sense for window list positions to be truly +persistent like dash items, some persistence is desirable. + +Otherwise any manually set position is lost when the extension +is disabled, for example when locking the screen. + +To address this, serialize the positions as runtime state on drop, +and restore them when populating the list. +--- + extensions/window-list/extension.js | 28 ++++++++++++++++++++++++++++ + 1 file changed, 28 insertions(+) + +diff --git a/extensions/window-list/extension.js b/extensions/window-list/extension.js +index feefc66e..bb9ca80f 100644 +--- a/extensions/window-list/extension.js ++++ b/extensions/window-list/extension.js +@@ -27,6 +27,8 @@ const DRAG_RESIZE_DURATION = 400; + + const DRAG_PROXIMITY_THRESHOLD = 30; + ++const SAVED_POSITIONS_KEY = 'window-list-positions'; ++ + const GroupingMode = { + NEVER: 0, + AUTO: 1, +@@ -1145,6 +1147,8 @@ class WindowList extends St.Widget { + for (let i = 0; i < apps.length; i++) + this._addApp(apps[i], false); + } ++ ++ this._restorePositions(); + } + + _updateKeyboardAnchor() { +@@ -1293,9 +1297,33 @@ class WindowList extends St.Widget { + + this._clearDragPlaceholder(); + ++ this._savePositions(); ++ + return true; + } + ++ _getPositionStateKey() { ++ return `${SAVED_POSITIONS_KEY}:${this._monitor.index}`; ++ } ++ ++ _savePositions() { ++ const buttons = this._windowList.get_children() ++ .filter(b => b instanceof BaseButton); ++ global.set_runtime_state(this._getPositionStateKey(), ++ new GLib.Variant('as', buttons.map(b => b.id))); ++ } ++ ++ _restorePositions() { ++ const positions = global.get_runtime_state('as', ++ this._getPositionStateKey())?.deepUnpack() ?? []; ++ ++ for (const button of this._windowList.get_children()) { ++ const pos = positions.indexOf(button.id); ++ if (pos > -1) ++ this._windowList.set_child_at_index(button, pos); ++ } ++ } ++ + _monitorItemDrag() { + DND.addDragMonitor(this._itemDragMonitor); + } +-- +2.47.0 + diff --git a/SPECS/gnome-shell-extensions.spec b/SPECS/gnome-shell-extensions.spec index 2b90dcc..2faf43e 100644 --- a/SPECS/gnome-shell-extensions.spec +++ b/SPECS/gnome-shell-extensions.spec @@ -7,7 +7,7 @@ Name: gnome-shell-extensions Version: 40.7 -Release: 19%{?dist} +Release: 25%{?dist} Summary: Modify and extend GNOME Shell functionality and behavior License: GPLv2+ @@ -47,8 +47,11 @@ Patch024: 0001-desktop-icons-Notify-icon-drags.patch Patch025: prefer-window-icon.patch Patch026: 0001-desktop-icons-Handle-touch-events.patch Patch027: more-ws-previews.patch -Patch028: 0001-Add-move-clock-extension.patch +Patch028: 0001-Add-move-notifications-extension.patch Patch029: 0001-workspace-indicator-Re-fittsify-workspace-previews.patch +Patch030: window-list-reordering.patch +Patch031: 0001-dash-to-panel-Remove-faulty-version-check.patch +Patch032: window-list-attention-indicator.patch %description GNOME Shell Extensions is a collection of extensions providing additional and @@ -66,7 +69,7 @@ Enabled extensions: * gesture-inhibitor * launch-new-instance * heads-up-display - * move-clock + * move-notifications * native-window-placement * panel-favorites * places-menu @@ -205,13 +208,13 @@ This GNOME Shell extension modifies the behavior of clicking in the dash and app launcher to always launch a new application instance. -%package -n %{pkg_prefix}-move-clock -Summary: Move GNOME Shell notification menu to the right +%package -n %{pkg_prefix}-move-notifications +Summary: Move GNOME Shell notifications License: GPLv2+ Requires: %{pkg_prefix}-common = %{version}-%{release} -%description -n %{pkg_prefix}-move-clock -This GNOME Shell extension moves the notification menu to the right. +%description -n %{pkg_prefix}-move-notifications +This GNOME Shell extension moves notification banners to a different position %package -n %{pkg_prefix}-heads-up-display @@ -407,8 +410,9 @@ workspaces. %{_datadir}/gnome-shell/extensions/launch-new-instance*/ -%files -n %{pkg_prefix}-move-clock -%{_datadir}/gnome-shell/extensions/move-clock*/ +%files -n %{pkg_prefix}-move-notifications +%{_datadir}/gnome-shell/extensions/move-notifications*/ +%{_datadir}/glib-2.0/schemas/org.gnome.shell.extensions.move-notifications.gschema.xml %files -n %{pkg_prefix}-heads-up-display @@ -467,6 +471,30 @@ workspaces. %changelog +* Wed Jan 08 2025 Florian Müllner - 40.7-25 +- Indicate urgency-hint in window-list + Resolves: RHEL-73146 + +* Wed Dec 18 2024 Florian Müllner - 40.7-24 +- Change "move-clock" to "move-notifications" + Resolves: RHEL-33429 + +* Mon Dec 02 2024 Florian Müllner - 40.7-23 +- Fix app grid with dash-to-panel extension + Resolves: RHEL-69665 + +* Tue Nov 19 2024 Florian Müllner - 40.7-22 +- Fix another bug in window-list reordering backport + Resolves: RHEL-22692 + +* Fri Nov 15 2024 Florian Müllner - 40.7-21 +- Fix bug in window-list reordering backport + Resolves: RHEL-22692 + +* Thu Sep 26 2024 Florian Müllner - 40.7-20 +- Allow reordering items in window-list + Resolves: RHEL-22692 + * Tue Jul 02 2024 Florian Müllner - 40.7-19 - Extend workspace buttons to screen edge Resolves: RHEL-43545