[gnome-shell] status/network: Add NMSection:icon-name property



commit f96447079a5056969d58e10b664b16b40fb236b7
Author: Florian Müllner <fmuellner gnome org>
Date:   Wed Aug 3 02:58:21 2022 +0200

    status/network: Add NMSection:icon-name property
    
    Again no big surprise, a property that will soon correspond to the
    quick toggle's icon.
    
    It is more involved than the :checked property though, which is just
    a simple boolean.
    
    To keep it as simple as possible, we set up a binding group and use
    that to bind the :icon-name property.
    
    As state changes, we then update the group's source with the item
    we deem to best represent the section as a whole at the given
    moment.
    
    That is (in that order):
    
     - the first active item
     - the most recently used item
     - the top-most visible item
    
    Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2408>

 js/ui/status/network.js | 43 ++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 40 insertions(+), 3 deletions(-)
---
diff --git a/js/ui/status/network.js b/js/ui/status/network.js
index 20b44da1c3..d382fed8e4 100644
--- a/js/ui/status/network.js
+++ b/js/ui/status/network.js
@@ -1279,10 +1279,12 @@ const NMSection = GObject.registerClass({
         'checked': GObject.ParamSpec.boolean('checked', '', '',
             GObject.ParamFlags.READWRITE,
             false),
+        'icon-name': GObject.ParamSpec.string('icon-name', '', '',
+            GObject.ParamFlags.READWRITE,
+            ''),
     },
     Signals: {
         'activation-failed': {},
-        'icon-changed': {},
     },
 }, class NMSection extends GObject.Object {
     constructor() {
@@ -1297,6 +1299,10 @@ const NMSection = GObject.registerClass({
         this.menu.addMenuItem(this._itemsSection);
 
         this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
+
+        this._itemBinding = new GObject.BindingGroup();
+        this._itemBinding.bind('icon-name',
+            this, 'icon-name', GObject.BindingFlags.DEFAULT);
     }
 
     setClient(client) {
@@ -1342,7 +1348,7 @@ const NMSection = GObject.registerClass({
             `${this} already has an item for ${key}`);
 
         item.connectObject(
-            'notify::is-active', () => this._updateChecked(),
+            'notify::is-active', () => this._sync(),
             'notify::name', () => this._resortItem(item),
             'destroy', () => this._removeItem(key),
             this);
@@ -1365,10 +1371,41 @@ const NMSection = GObject.registerClass({
         this._sync();
     }
 
+    *_getActiveItems() {
+        for (const item of this._itemSorter) {
+            if (item.is_active)
+                yield item;
+        }
+    }
+
+    _getPrimaryItem() {
+        // prefer active items
+        const [firstActive] = this._getActiveItems();
+        if (firstActive)
+            return firstActive;
+
+        // otherwise prefer the most-recently used
+        const [lastUsed] = this._itemSorter.itemsByMru();
+        if (lastUsed?.timestamp > 0)
+            return lastUsed;
+
+        // as a last resort, return the top-most visible item
+        for (const item of this._itemSorter) {
+            if (item.visible)
+                return item;
+        }
+
+        console.assert(!this.visible,
+            `${this} should not be visible when empty`);
+
+        return null;
+    }
+
     _sync() {
         this.visible = this._items.size > 0;
         this._updateItemsVisibility();
         this._updateChecked();
+        this._itemBinding.source = this._getPrimaryItem();
     }
 });
 
@@ -1702,7 +1739,7 @@ class Indicator extends PanelMenu.SystemIndicator {
         this._allSections.forEach(section => {
             section.connectObject(
                 'activation-failed', () => this._onActivationFailed(),
-                'icon-changed', () => this._updateIcon(),
+                'notify::icon-name', () => this._updateIcon(),
                 this);
             this.menu.addMenuItem(section.menu);
         });


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