diff --git a/add-power-profiles-menu.patch b/add-power-profiles-menu.patch new file mode 100644 index 0000000..289a80b --- /dev/null +++ b/add-power-profiles-menu.patch @@ -0,0 +1,333 @@ +From 2103c5fcf994bb6aebd978553b338436e85fa7ed Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Wed, 7 Jul 2021 22:05:25 +0200 +Subject: [PATCH 1/2] status/powerProfiles: Add power mode selection + +Settings' power panel gained support for switchable power profiles +in GNOME 40. It's useful to have that functionality more readily +available, so expose it in the system status menu as well. + +https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/3944 + +Part-of: +--- + .../net.hadess.PowerProfiles.xml | 76 ++++++++++++ + .../gnome-shell-dbus-interfaces.gresource.xml | 1 + + js/js-resources.gresource.xml | 1 + + js/ui/panel.js | 4 + + js/ui/status/powerProfiles.js | 111 ++++++++++++++++++ + po/POTFILES.in | 1 + + 6 files changed, 194 insertions(+) + create mode 100644 data/dbus-interfaces/net.hadess.PowerProfiles.xml + create mode 100644 js/ui/status/powerProfiles.js + +diff --git a/data/dbus-interfaces/net.hadess.PowerProfiles.xml b/data/dbus-interfaces/net.hadess.PowerProfiles.xml +new file mode 100644 +index 000000000..fce04a86d +--- /dev/null ++++ b/data/dbus-interfaces/net.hadess.PowerProfiles.xml +@@ -0,0 +1,76 @@ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +diff --git a/data/gnome-shell-dbus-interfaces.gresource.xml b/data/gnome-shell-dbus-interfaces.gresource.xml +index e7972f6cb..6682c462d 100644 +--- a/data/gnome-shell-dbus-interfaces.gresource.xml ++++ b/data/gnome-shell-dbus-interfaces.gresource.xml +@@ -1,6 +1,7 @@ + + + ++ net.hadess.PowerProfiles.xml + net.hadess.SensorProxy.xml + net.reactivated.Fprint.Device.xml + net.reactivated.Fprint.Manager.xml +diff --git a/js/js-resources.gresource.xml b/js/js-resources.gresource.xml +index b2c603a55..7a94e2ff1 100644 +--- a/js/js-resources.gresource.xml ++++ b/js/js-resources.gresource.xml +@@ -134,6 +134,7 @@ + ui/status/nightLight.js + ui/status/network.js + ui/status/power.js ++ ui/status/powerProfiles.js + ui/status/rfkill.js + ui/status/volume.js + ui/status/bluetooth.js +diff --git a/js/ui/panel.js b/js/ui/panel.js +index ad11f4ba2..84668e96e 100644 +--- a/js/ui/panel.js ++++ b/js/ui/panel.js +@@ -693,6 +693,7 @@ class AggregateMenu extends PanelMenu.Button { + + this._remoteAccess = new imports.ui.status.remoteAccess.RemoteAccessApplet(); + this._power = new imports.ui.status.power.Indicator(); ++ this._powerProfiles = new imports.ui.status.powerProfiles.Indicator(); + this._rfkill = new imports.ui.status.rfkill.Indicator(); + this._volume = new imports.ui.status.volume.Indicator(); + this._brightness = new imports.ui.status.brightness.Indicator(); +@@ -712,6 +713,7 @@ class AggregateMenu extends PanelMenu.Button { + this._indicators.add_child(this._rfkill); + this._indicators.add_child(this._volume); + this._indicators.add_child(this._power); ++ this._indicators.add_child(this._powerProfiles); + + this.menu.addMenuItem(this._volume.menu); + this.menu.addMenuItem(this._brightness.menu); +@@ -726,6 +728,7 @@ class AggregateMenu extends PanelMenu.Button { + this.menu.addMenuItem(this._location.menu); + this.menu.addMenuItem(this._rfkill.menu); + this.menu.addMenuItem(this._power.menu); ++ this.menu.addMenuItem(this._powerProfiles.menu); + this.menu.addMenuItem(this._nightLight.menu); + this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem()); + this.menu.addMenuItem(this._system.menu); +@@ -733,6 +736,7 @@ class AggregateMenu extends PanelMenu.Button { + menuLayout.addSizeChild(this._location.menu.actor); + menuLayout.addSizeChild(this._rfkill.menu.actor); + menuLayout.addSizeChild(this._power.menu.actor); ++ menuLayout.addSizeChild(this._powerProfiles.menu.actor); + menuLayout.addSizeChild(this._system.menu.actor); + } + }); +diff --git a/js/ui/status/powerProfiles.js b/js/ui/status/powerProfiles.js +new file mode 100644 +index 000000000..f6bc5835b +--- /dev/null ++++ b/js/ui/status/powerProfiles.js +@@ -0,0 +1,111 @@ ++// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- ++/* exported Indicator */ ++ ++const { Gio, GObject } = imports.gi; ++ ++const Main = imports.ui.main; ++const PanelMenu = imports.ui.panelMenu; ++const PopupMenu = imports.ui.popupMenu; ++ ++const { loadInterfaceXML } = imports.misc.fileUtils; ++ ++const BUS_NAME = 'net.hadess.PowerProfiles'; ++const OBJECT_PATH = '/net/hadess/PowerProfiles'; ++ ++const PowerProfilesIface = loadInterfaceXML('net.hadess.PowerProfiles'); ++const PowerProfilesProxy = Gio.DBusProxy.makeProxyWrapper(PowerProfilesIface); ++ ++const PROFILE_LABELS = { ++ 'performance': _('Performance Mode'), ++ 'balanced': _('Balanced Power'), ++ 'power-saver': _('Power Saver'), ++}; ++const PROFILE_ICONS = { ++ 'performance': 'power-profile-performance-symbolic', ++ 'balanced': 'power-profile-balanced-symbolic', ++ 'power-saver': 'power-profile-power-saver-symbolic', ++}; ++ ++var Indicator = GObject.registerClass( ++class Indicator extends PanelMenu.SystemIndicator { ++ _init() { ++ super._init(); ++ ++ this._profileItems = new Map(); ++ this._updateProfiles = true; ++ ++ this._proxy = new PowerProfilesProxy(Gio.DBus.system, BUS_NAME, OBJECT_PATH, ++ (proxy, error) => { ++ if (error) { ++ log(error.message); ++ } else { ++ this._proxy.connect('g-properties-changed', ++ (p, properties) => { ++ const propertyNames = properties.deep_unpack(); ++ this._updateProfiles = 'Profiles' in propertyNames; ++ this._sync(); ++ }); ++ } ++ this._sync(); ++ }); ++ ++ this._item = new PopupMenu.PopupSubMenuMenuItem('', true); ++ ++ this._profileSection = new PopupMenu.PopupMenuSection(); ++ this._item.menu.addMenuItem(this._profileSection); ++ this._item.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem()); ++ this._item.menu.addSettingsAction(_('Power Settings'), ++ 'gnome-power-panel.desktop'); ++ this.menu.addMenuItem(this._item); ++ ++ Main.sessionMode.connect('updated', this._sessionUpdated.bind(this)); ++ this._sessionUpdated(); ++ this._sync(); ++ } ++ ++ _sessionUpdated() { ++ const sensitive = !Main.sessionMode.isLocked && !Main.sessionMode.isGreeter; ++ this.menu.setSensitive(sensitive); ++ } ++ ++ _sync() { ++ this._item.visible = this._proxy.g_name_owner !== null; ++ ++ if (!this._item.visible) ++ return; ++ ++ if (this._updateProfiles) { ++ this._profileSection.removeAll(); ++ this._profileItems.clear(); ++ ++ const profiles = this._proxy.Profiles ++ .map(p => p.Profile.unpack()) ++ .reverse(); ++ for (const profile of profiles) { ++ const label = PROFILE_LABELS[profile]; ++ if (!label) ++ continue; ++ ++ const item = new PopupMenu.PopupMenuItem(label); ++ item.connect('activate', ++ () => (this._proxy.ActiveProfile = profile)); ++ this._profileItems.set(profile, item); ++ this._profileSection.addMenuItem(item); ++ } ++ this._updateProfiles = false; ++ } ++ ++ for (const [profile, item] of this._profileItems) { ++ item.setOrnament(profile === this._proxy.ActiveProfile ++ ? PopupMenu.Ornament.DOT ++ : PopupMenu.Ornament.NONE); ++ } ++ ++ const perfItem = this._profileItems.get('performance'); ++ if (perfItem) ++ perfItem.sensitive = this._proxy.PerformanceInhibited === ''; ++ ++ this._item.label.text = PROFILE_LABELS[this._proxy.ActiveProfile]; ++ this._item.icon.icon_name = PROFILE_ICONS[this._proxy.ActiveProfile]; ++ } ++}); +diff --git a/po/POTFILES.in b/po/POTFILES.in +index cb279c1ee..727cb01a8 100644 +--- a/po/POTFILES.in ++++ b/po/POTFILES.in +@@ -61,6 +61,7 @@ js/ui/status/location.js + js/ui/status/network.js + js/ui/status/nightLight.js + js/ui/status/power.js ++js/ui/status/powerProfiles.js + js/ui/status/remoteAccess.js + js/ui/status/rfkill.js + js/ui/status/system.js +-- +2.31.1 + + +From 0f8a2e2c6c3119492670efce5aff1224f2c3c47f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Florian=20M=C3=BCllner?= +Date: Fri, 6 Aug 2021 21:04:24 +0200 +Subject: [PATCH 2/2] powerProfiles: Tweak profile names + +After some more discussion, we settled on slightly different +profile names. + +https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/4530 + +Part-of: +--- + js/ui/status/powerProfiles.js | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/js/ui/status/powerProfiles.js b/js/ui/status/powerProfiles.js +index f6bc5835b..61205bbc6 100644 +--- a/js/ui/status/powerProfiles.js ++++ b/js/ui/status/powerProfiles.js +@@ -16,9 +16,9 @@ const PowerProfilesIface = loadInterfaceXML('net.hadess.PowerProfiles'); + const PowerProfilesProxy = Gio.DBusProxy.makeProxyWrapper(PowerProfilesIface); + + const PROFILE_LABELS = { +- 'performance': _('Performance Mode'), +- 'balanced': _('Balanced Power'), +- 'power-saver': _('Power Saver'), ++ 'performance': C_('Power profile', 'Performance'), ++ 'balanced': C_('Power profile', 'Balanced'), ++ 'power-saver': C_('Power profile', 'Power Saver'), + }; + const PROFILE_ICONS = { + 'performance': 'power-profile-performance-symbolic', +-- +2.31.1 + diff --git a/gnome-shell.spec b/gnome-shell.spec index 8cd6b04..cc4d699 100644 --- a/gnome-shell.spec +++ b/gnome-shell.spec @@ -2,7 +2,7 @@ Name: gnome-shell Version: 40.3 -Release: 3%{?dist} +Release: 4%{?dist} Summary: Window management and application launching for GNOME License: GPLv2+ @@ -32,6 +32,7 @@ Patch35: fix-some-js-warnings.patch Patch36: 0001-st-texture-cache-purge-on-resume.patch Patch37: 0001-Update-generated-stylesheets.patch Patch38: 0001-appDisplay-Avoid-a-warning.patch +Patch39: add-power-profiles-menu.patch %define eds_version 3.33.1 %define gnome_desktop_version 3.35.91 @@ -250,6 +251,10 @@ desktop-file-validate %{buildroot}%{_datadir}/applications/evolution-calendar.de %{_mandir}/man1/gnome-shell.1* %changelog +* Wed Aug 18 2021 Florian Müllner - 40.3-4 +- Add power profiles menu + Resolves: #1994471 + * Mon Aug 09 2021 Mohan Boddu - 40.3-3 - Rebuilt for IMA sigs, glibc 2.34, aarch64 flags Related: rhbz#1991688