diff --git a/data/theme/gnome-shell-sass/widgets/_quick-settings.scss b/data/theme/gnome-shell-sass/widgets/_quick-settings.scss index 82d88b4b3..53325fa50 100644 --- a/data/theme/gnome-shell-sass/widgets/_quick-settings.scss +++ b/data/theme/gnome-shell-sass/widgets/_quick-settings.scss @@ -86,4 +86,14 @@ .quick-settings-system-item { & > StBoxLayout { spacing: 2 * $base_padding; } + + & .power-item { + min-height: 0; + min-width: 0; + + &:insensitive { + @include button(normal); + background-color: transparent; + } + } } diff --git a/js/js-resources.gresource.xml b/js/js-resources.gresource.xml index d6508a2ee..76b5f9553 100644 --- a/js/js-resources.gresource.xml +++ b/js/js-resources.gresource.xml @@ -141,7 +141,6 @@ ui/status/keyboard.js ui/status/nightLight.js ui/status/network.js - ui/status/power.js ui/status/powerProfiles.js ui/status/rfkill.js ui/status/volume.js diff --git a/js/ui/panel.js b/js/ui/panel.js index f43955781..6337ca0f1 100644 --- a/js/ui/panel.js +++ b/js/ui/panel.js @@ -415,7 +415,6 @@ class QuickSettings extends PanelMenu.Button { this._rfkill = new imports.ui.status.rfkill.Indicator(); this._autoRotate = new imports.ui.status.autoRotate.Indicator(); this._unsafeMode = new UnsafeModeIndicator(); - this._power = new imports.ui.status.power.Indicator(); this._indicators.add_child(this._brightness); this._indicators.add_child(this._remoteAccess); @@ -430,7 +429,6 @@ class QuickSettings extends PanelMenu.Button { this._indicators.add_child(this._autoRotate); this._indicators.add_child(this._volume); this._indicators.add_child(this._unsafeMode); - this._indicators.add_child(this._power); this._indicators.add_child(this._system); this._addItems(this._system.quickSettingsItems, N_QUICK_SETTINGS_COLUMNS); @@ -448,7 +446,6 @@ class QuickSettings extends PanelMenu.Button { this._addItems(this._rfkill.quickSettingsItems); this._addItems(this._autoRotate.quickSettingsItems); this._addItems(this._unsafeMode.quickSettingsItems); - this._addItems(this._power.quickSettingsItems); } _addItems(items, colSpan = 1) { diff --git a/js/ui/status/power.js b/js/ui/status/power.js deleted file mode 100644 index de363d0ce..000000000 --- a/js/ui/status/power.js +++ /dev/null @@ -1,142 +0,0 @@ -// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- -/* exported Indicator */ - -const {Atk, Clutter, Gio, GObject, Shell, St, UPowerGlib: UPower} = imports.gi; - -const Main = imports.ui.main; -const {QuickToggle, SystemIndicator} = imports.ui.quickSettings; - -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'; - -const PowerToggle = GObject.registerClass({ - Properties: { - 'fallback-icon-name': GObject.ParamSpec.string('fallback-icon-name', '', '', - GObject.ParamFlags.READWRITE, - ''), - }, -}, class PowerToggle extends QuickToggle { - _init() { - super._init({ - accessible_role: Atk.Role.PUSH_BUTTON, - }); - - this._proxy = new PowerManagerProxy(Gio.DBus.system, BUS_NAME, OBJECT_PATH, - (proxy, error) => { - if (error) - console.error(error.message); - else - this._proxy.connect('g-properties-changed', () => this._sync()); - this._sync(); - }); - - this.bind_property('fallback-icon-name', - this._icon, 'fallback-icon-name', - GObject.BindingFlags.SYNC_CREATE); - - this.connect('clicked', () => { - const app = Shell.AppSystem.get_default().lookup_app('gnome-power-panel.desktop'); - Main.overview.hide(); - Main.panel.closeQuickSettings(); - app.activate(); - }); - - Main.sessionMode.connect('updated', () => this._sessionUpdated()); - this._sessionUpdated(); - this._sync(); - } - - _sessionUpdated() { - this.reactive = Main.sessionMode.allowSettings; - } - - _sync() { - // Do we have batteries or a UPS? - this.visible = this._proxy.IsPresent; - if (!this.visible) - return; - - // The icons - let chargingState = this._proxy.State === UPower.DeviceState.CHARGING - ? '-charging' : ''; - let fillLevel = 10 * Math.floor(this._proxy.Percentage / 10); - const charged = - this._proxy.State === UPower.DeviceState.FULLY_CHARGED || - (this._proxy.State === UPower.DeviceState.CHARGING && fillLevel === 100); - const icon = charged - ? 'battery-level-100-charged-symbolic' - : `battery-level-${fillLevel}${chargingState}-symbolic`; - - // Make sure we fall back to fallback-icon-name and not GThemedIcon's - // default fallbacks - const gicon = new Gio.ThemedIcon({ - name: icon, - use_default_fallbacks: false, - }); - - this.set({ - label: _('%d\u2009%%').format(this._proxy.Percentage), - fallback_icon_name: this._proxy.IconName, - gicon, - }); - } -}); - -var Indicator = GObject.registerClass( -class Indicator extends SystemIndicator { - _init() { - super._init(); - - this._desktopSettings = new Gio.Settings({ - schema_id: 'org.gnome.desktop.interface', - }); - this._desktopSettings.connect( - `changed::${SHOW_BATTERY_PERCENTAGE}`, () => this._sync()); - - 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._powerToggle = new PowerToggle(); - - this._powerToggle.bind_property('label', - this._percentageLabel, 'text', - GObject.BindingFlags.SYNC_CREATE); - - this._powerToggle.connectObject( - 'notify::visible', () => this._sync(), - 'notify::gicon', () => this._sync(), - 'notify::fallback-icon-name', () => this._sync(), - this); - - this.quickSettingsItems.push(this._powerToggle); - - this._sync(); - } - - _sync() { - if (this._powerToggle.visible) { - this._indicator.set({ - gicon: this._powerToggle.gicon, - fallback_icon_name: this._powerToggle.fallback_icon_name, - }); - this._percentageLabel.visible = - this._desktopSettings.get_boolean(SHOW_BATTERY_PERCENTAGE); - } else { - // If there's no battery, then we use the power icon. - this._indicator.icon_name = 'system-shutdown-symbolic'; - this._percentageLabel.hide(); - } - } -}); diff --git a/js/ui/status/system.js b/js/ui/status/system.js index ed9e3cf7e..d4607d519 100644 --- a/js/ui/status/system.js +++ b/js/ui/status/system.js @@ -1,13 +1,97 @@ // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- /* exported Indicator */ -const {Clutter, GObject, Shell, St} = imports.gi; +const {Atk, Clutter, Gio, GObject, Shell, St, UPowerGlib: UPower} = imports.gi; const SystemActions = imports.misc.systemActions; const Main = imports.ui.main; const PopupMenu = imports.ui.popupMenu; -const {QuickSettingsItem, SystemIndicator} = imports.ui.quickSettings; +const {QuickSettingsItem, QuickToggle, SystemIndicator} = imports.ui.quickSettings; +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'; + +const PowerToggle = GObject.registerClass({ + Properties: { + 'fallback-icon-name': GObject.ParamSpec.string('fallback-icon-name', '', '', + GObject.ParamFlags.READWRITE, + ''), + }, +}, class PowerToggle extends QuickToggle { + _init() { + super._init({ + accessible_role: Atk.Role.PUSH_BUTTON, + }); + + this.add_style_class_name('power-item'); + + this._proxy = new PowerManagerProxy(Gio.DBus.system, BUS_NAME, OBJECT_PATH, + (proxy, error) => { + if (error) + console.error(error.message); + else + this._proxy.connect('g-properties-changed', () => this._sync()); + this._sync(); + }); + + this.bind_property('fallback-icon-name', + this._icon, 'fallback-icon-name', + GObject.BindingFlags.SYNC_CREATE); + + this.connect('clicked', () => { + const app = Shell.AppSystem.get_default().lookup_app('gnome-power-panel.desktop'); + Main.overview.hide(); + Main.panel.closeQuickSettings(); + app.activate(); + }); + + Main.sessionMode.connect('updated', () => this._sessionUpdated()); + this._sessionUpdated(); + this._sync(); + } + + _sessionUpdated() { + this.reactive = Main.sessionMode.allowSettings; + } + + _sync() { + // Do we have batteries or a UPS? + this.visible = this._proxy.IsPresent; + if (!this.visible) + return; + + // The icons + let chargingState = this._proxy.State === UPower.DeviceState.CHARGING + ? '-charging' : ''; + let fillLevel = 10 * Math.floor(this._proxy.Percentage / 10); + const charged = + this._proxy.State === UPower.DeviceState.FULLY_CHARGED || + (this._proxy.State === UPower.DeviceState.CHARGING && fillLevel === 100); + const icon = charged + ? 'battery-level-100-charged-symbolic' + : `battery-level-${fillLevel}${chargingState}-symbolic`; + + // Make sure we fall back to fallback-icon-name and not GThemedIcon's + // default fallbacks + const gicon = new Gio.ThemedIcon({ + name: icon, + use_default_fallbacks: false, + }); + + this.set({ + label: _('%d\u2009%%').format(this._proxy.Percentage), + fallback_icon_name: this._proxy.IconName, + gicon, + }); + } +}); const SettingsItem = GObject.registerClass( class SettingsItem extends QuickSettingsItem { @@ -153,6 +237,9 @@ class SystemItem extends QuickSettingsItem { this.child = new St.BoxLayout(); + this._powerToggle = new PowerToggle(); + this.child.add_child(this._powerToggle); + // spacer this.child.add_child(new Clutter.Actor({x_expand: true})); @@ -167,6 +254,10 @@ class SystemItem extends QuickSettingsItem { this.menu = shutdownItem.menu; } + + get powerToggle() { + return this._powerToggle; + } }); var Indicator = GObject.registerClass( @@ -174,8 +265,52 @@ class Indicator extends SystemIndicator { _init() { super._init(); - const item = new SystemItem(); + this._desktopSettings = new Gio.Settings({ + schema_id: 'org.gnome.desktop.interface', + }); + this._desktopSettings.connectObject( + `changed::${SHOW_BATTERY_PERCENTAGE}`, () => this._sync(), this); - this.quickSettingsItems.push(item); + 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._systemItem = new SystemItem(); + + const {powerToggle} = this._systemItem; + + powerToggle.bind_property('label', + this._percentageLabel, 'text', + GObject.BindingFlags.SYNC_CREATE); + + powerToggle.connectObject( + 'notify::visible', () => this._sync(), + 'notify::gicon', () => this._sync(), + 'notify::fallback-icon-name', () => this._sync(), + this); + + this.quickSettingsItems.push(this._systemItem); + + this._sync(); + } + + _sync() { + const {powerToggle} = this._systemItem; + if (powerToggle.visible) { + this._indicator.set({ + gicon: powerToggle.gicon, + fallback_icon_name: powerToggle.fallback_icon_name, + }); + this._percentageLabel.visible = + this._desktopSettings.get_boolean(SHOW_BATTERY_PERCENTAGE); + } else { + // If there's no battery, then we use the power icon. + this._indicator.icon_name = 'system-shutdown-symbolic'; + this._percentageLabel.hide(); + } } });