9d941f8202
xgettext gained some support for template strings, and no longer fails when encountering '/' somewhere between backticks. Unfortunately its support is still buggy as hell, and it is now silently dropping translatable strings, yay. I hate making the code worse, but until xgettext really gets its shit together, the only viable way forward seems to be to not use template strings in any files listed in POTFILES. https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/1014
148 lines
5.7 KiB
JavaScript
148 lines
5.7 KiB
JavaScript
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
|
/* exported Indicator */
|
|
|
|
const { Clutter, Gio, GObject, St, UPowerGlib: UPower } = 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 = 'org.freedesktop.UPower';
|
|
const OBJECT_PATH = '/org/freedesktop/UPower/devices/DisplayDevice';
|
|
|
|
const DisplayDeviceInterface = loadInterfaceXML('org.freedesktop.UPower.Device');
|
|
const PowerManagerProxy = Gio.DBusProxy.makeProxyWrapper(DisplayDeviceInterface);
|
|
|
|
const SHOW_BATTERY_PERCENTAGE = 'show-battery-percentage';
|
|
|
|
var Indicator = GObject.registerClass(
|
|
class Indicator extends PanelMenu.SystemIndicator {
|
|
_init() {
|
|
super._init();
|
|
|
|
this._desktopSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.interface' });
|
|
this._desktopSettings.connect('changed::%s'.format(SHOW_BATTERY_PERCENTAGE),
|
|
this._sync.bind(this));
|
|
|
|
this._indicator = this._addIndicator();
|
|
this._percentageLabel = new St.Label({ y_expand: true,
|
|
y_align: Clutter.ActorAlign.CENTER });
|
|
this.add_child(this._percentageLabel);
|
|
this.add_style_class_name('power-status');
|
|
|
|
this._proxy = new PowerManagerProxy(Gio.DBus.system, BUS_NAME, OBJECT_PATH,
|
|
(proxy, error) => {
|
|
if (error) {
|
|
log(error.message);
|
|
return;
|
|
}
|
|
this._proxy.connect('g-properties-changed',
|
|
this._sync.bind(this));
|
|
this._sync();
|
|
});
|
|
|
|
this._item = new PopupMenu.PopupSubMenuMenuItem("", true);
|
|
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();
|
|
}
|
|
|
|
_sessionUpdated() {
|
|
let sensitive = !Main.sessionMode.isLocked && !Main.sessionMode.isGreeter;
|
|
this.menu.setSensitive(sensitive);
|
|
}
|
|
|
|
_getStatus() {
|
|
let seconds = 0;
|
|
|
|
if (this._proxy.State == UPower.DeviceState.FULLY_CHARGED)
|
|
return _("Fully Charged");
|
|
else if (this._proxy.State == UPower.DeviceState.CHARGING)
|
|
seconds = this._proxy.TimeToFull;
|
|
else if (this._proxy.State == UPower.DeviceState.DISCHARGING)
|
|
seconds = this._proxy.TimeToEmpty;
|
|
else if (this._proxy.State == UPower.DeviceState.PENDING_CHARGE)
|
|
return _("Not Charging");
|
|
// state is PENDING_DISCHARGE
|
|
else
|
|
return _("Estimating…");
|
|
|
|
let time = Math.round(seconds / 60);
|
|
if (time == 0) {
|
|
// 0 is reported when UPower does not have enough data
|
|
// to estimate battery life
|
|
return _("Estimating…");
|
|
}
|
|
|
|
let minutes = time % 60;
|
|
let hours = Math.floor(time / 60);
|
|
|
|
if (this._proxy.State == UPower.DeviceState.DISCHARGING) {
|
|
// Translators: this is <hours>:<minutes> Remaining (<percentage>)
|
|
return _("%d\u2236%02d Remaining (%d\u2009%%)").format(hours, minutes, this._proxy.Percentage);
|
|
}
|
|
|
|
if (this._proxy.State == UPower.DeviceState.CHARGING) {
|
|
// Translators: this is <hours>:<minutes> Until Full (<percentage>)
|
|
return _("%d\u2236%02d Until Full (%d\u2009%%)").format(hours, minutes, this._proxy.Percentage);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
_sync() {
|
|
// Do we have batteries or a UPS?
|
|
let visible = this._proxy.IsPresent;
|
|
if (visible) {
|
|
this._item.show();
|
|
this._percentageLabel.visible = this._desktopSettings.get_boolean(SHOW_BATTERY_PERCENTAGE);
|
|
} else {
|
|
// If there's no battery, then we use the power icon.
|
|
this._item.hide();
|
|
this._indicator.icon_name = 'system-shutdown-symbolic';
|
|
this._percentageLabel.hide();
|
|
return;
|
|
}
|
|
|
|
// The icons
|
|
let chargingState = this._proxy.State == UPower.DeviceState.CHARGING
|
|
? '-charging' : '';
|
|
let fillLevel = 10 * Math.floor(this._proxy.Percentage / 10);
|
|
let icon;
|
|
if (this._proxy.State == UPower.DeviceState.FULLY_CHARGED ||
|
|
fillLevel === 100)
|
|
icon = 'battery-level-100-charged-symbolic';
|
|
else
|
|
icon = 'battery-level-%d%s-symbolic'.format(fillLevel, chargingState);
|
|
|
|
// Make sure we fall back to fallback-icon-name and not GThemedIcon's
|
|
// default fallbacks
|
|
let gicon = new Gio.ThemedIcon({
|
|
name: icon,
|
|
use_default_fallbacks: false,
|
|
});
|
|
|
|
this._indicator.gicon = gicon;
|
|
this._item.icon.gicon = gicon;
|
|
|
|
let fallbackIcon = this._proxy.IconName;
|
|
this._indicator.fallback_icon_name = fallbackIcon;
|
|
this._item.icon.fallback_icon_name = fallbackIcon;
|
|
|
|
// The icon label
|
|
let label;
|
|
if (this._proxy.State == UPower.DeviceState.FULLY_CHARGED)
|
|
label = _("%d\u2009%%").format(100);
|
|
else
|
|
label = _("%d\u2009%%").format(this._proxy.Percentage);
|
|
this._percentageLabel.clutter_text.set_markup('<span size="smaller">' + label + '</span>');
|
|
|
|
// The status label
|
|
this._item.label.text = this._getStatus();
|
|
}
|
|
});
|