[gnome-shell] status/power: Merge with system indicator



commit ce19849c09de9018b7b4f17b11d432b27c34d8cf
Author: Florian Müllner <fmuellner gnome org>
Date:   Sat Jul 30 03:32:05 2022 +0200

    status/power: Merge with system indicator
    
    Now that the old system menu has been ported over, we can move
    the power toggle to its intended place. The main difference to
    the stand-alone toggle is that the button now uses its natural
    size rather than the fixed size of regular quick items.
    
    Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2393>

 .../gnome-shell-sass/widgets/_quick-settings.scss  |  10 ++
 js/js-resources.gresource.xml                      |   1 -
 js/ui/panel.js                                     |   3 -
 js/ui/status/power.js                              | 142 --------------------
 js/ui/status/system.js                             | 143 ++++++++++++++++++++-
 5 files changed, 149 insertions(+), 150 deletions(-)
---
diff --git a/data/theme/gnome-shell-sass/widgets/_quick-settings.scss 
b/data/theme/gnome-shell-sass/widgets/_quick-settings.scss
index 82d88b4b3d..53325fa503 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 d6508a2eee..76b5f95532 100644
--- a/js/js-resources.gresource.xml
+++ b/js/js-resources.gresource.xml
@@ -141,7 +141,6 @@
     <file>ui/status/keyboard.js</file>
     <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>
diff --git a/js/ui/panel.js b/js/ui/panel.js
index f439557819..6337ca0f12 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/system.js b/js/ui/status/system.js
index ed9e3cf7e3..d4607d5193 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._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(item);
+        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();
+        }
     }
 });


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]