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: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1907>
This commit is contained in:
@ -133,6 +133,7 @@
|
||||
<file>ui/status/nightLight.js</file>
|
||||
<file>ui/status/network.js</file>
|
||||
<file>ui/status/power.js</file>
|
||||
<file>ui/status/powerProfiles.js</file>
|
||||
<file>ui/status/rfkill.js</file>
|
||||
<file>ui/status/volume.js</file>
|
||||
<file>ui/status/bluetooth.js</file>
|
||||
|
@ -684,6 +684,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();
|
||||
@ -703,6 +704,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);
|
||||
@ -717,6 +719,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);
|
||||
@ -724,6 +727,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);
|
||||
}
|
||||
});
|
||||
|
111
js/ui/status/powerProfiles.js
Normal file
111
js/ui/status/powerProfiles.js
Normal file
@ -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];
|
||||
}
|
||||
});
|
Reference in New Issue
Block a user