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>
This commit is contained in:
parent
b0df35babf
commit
f96447079a
@ -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);
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user