extensions-app: Use new 'enabled' property

The switch for enabling/disabling extensions currently bases its
state on the extension's ACTIVE state.

This is problematic in the enabled-but-inactive case, because
activating the switch tries to change the state from off to on,
which leads to enabling an already enabled extension (an obvious
no-op).

The new `enabled` property allows us to do better, and use delayed
state changes where the switch position represents the `enabled`
state, and the trough color whether the extension is ACTIVE.

https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/7004

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3073>
This commit is contained in:
Florian Müllner 2023-09-12 14:25:03 +02:00 committed by Marge Bot
parent f9e81284f8
commit fec523f83f
3 changed files with 39 additions and 32 deletions

View File

@ -86,7 +86,16 @@
<child type="suffix">
<object class="GtkSwitch" id="switch">
<property name="valign">center</property>
<property name="action-name">row.enabled</property>
<binding name="active">
<lookup name="enabled" type="Extension">
<lookup name="extension" type="ExtensionRow"/>
</lookup>
</binding>
<binding name="sensitive">
<lookup name="can-change" type="Extension">
<lookup name="extension" type="ExtensionRow"/>
</lookup>
</binding>
</object>
</child>
<child type="suffix">

View File

@ -44,6 +44,10 @@ const Extension = GObject.registerClass({
'state', null, null,
GObject.ParamFlags.READABLE,
1, 99, ExtensionState.INITIALIZED),
'enabled': GObject.ParamSpec.boolean(
'enabled', null, null,
GObject.ParamFlags.READABLE,
false),
'creator': GObject.ParamSpec.string(
'creator', null, null,
GObject.ParamFlags.READABLE,
@ -95,7 +99,7 @@ const Extension = GObject.registerClass({
const deserialized = deserializeExtension(variant);
const {
uuid, type, state, error, hasPrefs, hasUpdate, canChange, metadata,
uuid, type, state, enabled, error, hasPrefs, hasUpdate, canChange, metadata,
} = deserialized;
if (!this._uuid)
@ -128,6 +132,11 @@ const Extension = GObject.registerClass({
this.notify('error');
}
if (this._enabled !== enabled) {
this._enabled = enabled;
this.notify('enabled');
}
if (this._state !== state) {
const hadError = this.hasError;
this._state = state;
@ -193,6 +202,10 @@ const Extension = GObject.registerClass({
return this._state;
}
get enabled() {
return this._enabled;
}
get creator() {
return this._creator;
}

View File

@ -1,5 +1,4 @@
import Adw from 'gi://Adw?version=1';
import GLib from 'gi://GLib';
import Gio from 'gi://Gio';
import GObject from 'gi://GObject';
@ -54,35 +53,31 @@ export const ExtensionRow = GObject.registerClass({
this.get_root().uninstall(extension);
},
enabledProp: 'is-user',
}, {
name: 'enabled',
state: 'false',
activate: action => {
const state = action.get_state();
action.change_state(new GLib.Variant('b', !state.get_boolean()));
},
change_state: (a, state) => {
const {uuid} = this._extension;
if (state.get_boolean())
this._app.extensionManager.enableExtension(uuid);
else
this._app.extensionManager.disableExtension(uuid);
},
enabledProp: 'can-change',
},
];
this._actionGroup.add_action_entries(actionEntries);
this._bindActionEnabled(actionEntries);
this._switch.connect('state-set', (sw, state) => {
const {uuid} = this._extension;
if (state)
this._app.extensionManager.enableExtension(uuid);
else
this._app.extensionManager.disableExtension(uuid);
return true;
});
this._extension.bind_property_full('state',
this._switch, 'state',
GObject.BindingFlags.SYNC_CREATE,
(bind, source) => [true, source === ExtensionState.ACTIVE],
null);
this._extension.bind_property_full('version',
this._versionLabel, 'label',
GObject.BindingFlags.SYNC_CREATE,
(bind, source) => [true, _('Version %s').format(source)],
null);
this._extension.connect('notify::state',
() => this._updateState());
this._updateState();
}
get extension() {
@ -113,14 +108,4 @@ export const ExtensionRow = GObject.registerClass({
}
}
}
_updateState() {
const state = this._extension.state === ExtensionState.ACTIVE;
const action = this._actionGroup.lookup_action('enabled');
action.set_state(new GLib.Variant('b', state));
if (!action.enabled)
this._switch.active = state;
}
});