cbbc066d6f
GDBusProxy transparently handles the remote object appearing and vanishing. It is therefore not an error if the service is not running at the time the proxy is initialized, so we proceed and try to read the list of profiles which is null in that case, resulting in (harmless but annoying) warnings. Avoid this by only reading the initial list of profiles if the service has a name owner. https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/5992 Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2518>
127 lines
3.8 KiB
JavaScript
127 lines
3.8 KiB
JavaScript
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
|
/* exported Indicator */
|
|
|
|
const {Gio, GObject} = imports.gi;
|
|
|
|
const {QuickMenuToggle, SystemIndicator} = imports.ui.quickSettings;
|
|
|
|
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_PARAMS = {
|
|
'performance': {
|
|
label: C_('Power profile', 'Performance'),
|
|
iconName: 'power-profile-performance-symbolic',
|
|
},
|
|
|
|
'balanced': {
|
|
label: C_('Power profile', 'Balanced'),
|
|
iconName: 'power-profile-balanced-symbolic',
|
|
},
|
|
|
|
'power-saver': {
|
|
label: C_('Power profile', 'Power Saver'),
|
|
iconName: 'power-profile-power-saver-symbolic',
|
|
},
|
|
};
|
|
|
|
const LAST_PROFILE_KEY = 'last-selected-power-profile';
|
|
|
|
const PowerProfilesToggle = GObject.registerClass(
|
|
class PowerProfilesToggle extends QuickMenuToggle {
|
|
_init() {
|
|
super._init();
|
|
|
|
this._profileItems = new Map();
|
|
|
|
this.connect('clicked', () => {
|
|
this._proxy.ActiveProfile = this.checked
|
|
? 'balanced'
|
|
: global.settings.get_string(LAST_PROFILE_KEY);
|
|
});
|
|
|
|
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 profilesChanged = !!properties.lookup_value('Profiles', null);
|
|
if (profilesChanged)
|
|
this._syncProfiles();
|
|
this._sync();
|
|
});
|
|
|
|
if (this._proxy.g_name_owner)
|
|
this._syncProfiles();
|
|
}
|
|
this._sync();
|
|
});
|
|
|
|
this._profileSection = new PopupMenu.PopupMenuSection();
|
|
this.menu.addMenuItem(this._profileSection);
|
|
this.menu.setHeader('power-profile-balanced-symbolic', _('Power Profiles'));
|
|
|
|
this._sync();
|
|
}
|
|
|
|
_syncProfiles() {
|
|
this._profileSection.removeAll();
|
|
this._profileItems.clear();
|
|
|
|
const profiles = this._proxy.Profiles
|
|
.map(p => p.Profile.unpack())
|
|
.reverse();
|
|
for (const profile of profiles) {
|
|
const {label, iconName} = PROFILE_PARAMS[profile];
|
|
if (!label)
|
|
continue;
|
|
|
|
const item = new PopupMenu.PopupImageMenuItem(label, iconName);
|
|
item.connect('activate',
|
|
() => (this._proxy.ActiveProfile = profile));
|
|
this._profileItems.set(profile, item);
|
|
this._profileSection.addMenuItem(item);
|
|
}
|
|
|
|
this.menuEnabled = this._profileItems.size > 2;
|
|
}
|
|
|
|
_sync() {
|
|
this.visible = this._proxy.g_name_owner !== null;
|
|
|
|
if (!this.visible)
|
|
return;
|
|
|
|
const {ActiveProfile: activeProfile} = this._proxy;
|
|
|
|
for (const [profile, item] of this._profileItems) {
|
|
item.setOrnament(profile === activeProfile
|
|
? PopupMenu.Ornament.CHECK
|
|
: PopupMenu.Ornament.NONE);
|
|
}
|
|
|
|
this.set(PROFILE_PARAMS[activeProfile]);
|
|
this.checked = activeProfile !== 'balanced';
|
|
|
|
if (this.checked)
|
|
global.settings.set_string(LAST_PROFILE_KEY, activeProfile);
|
|
}
|
|
});
|
|
|
|
var Indicator = GObject.registerClass(
|
|
class Indicator extends SystemIndicator {
|
|
_init() {
|
|
super._init();
|
|
|
|
this.quickSettingsItems.push(new PowerProfilesToggle());
|
|
}
|
|
});
|