extensionUtils: Add DISABLING and ENABLING extension states

Extensions can export asynchronous enable() and disable()
functions. To guard against re-entrancy when enabling or
disabling an extension, this commit adds two new states:
ENABLING and DISABLING which are set immediately prior
to calling enable() and disable() respectively.

This commit updates the extensions CLI and Extensions app
with new strings for these states.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2364>
This commit is contained in:
Evan Welsh 2022-07-24 19:25:23 -07:00 committed by Marge Bot
parent b7c097ba79
commit 56beb6ff2b
6 changed files with 25 additions and 5 deletions

View File

@ -77,6 +77,8 @@
<member>4: OUT_OF_DATE</member> <member>4: OUT_OF_DATE</member>
<member>5: DOWNLOADING</member> <member>5: DOWNLOADING</member>
<member>6: INITIALIZED</member> <member>6: INITIALIZED</member>
<member>7: DISABLING</member>
<member>8: ENABLING</member>
<member>99: UNINSTALLED</member> <member>99: UNINSTALLED</member>
</simplelist> </simplelist>
</para></listitem> </para></listitem>

View File

@ -38,6 +38,8 @@ var ExtensionState = {
OUT_OF_DATE: 4, OUT_OF_DATE: 4,
DOWNLOADING: 5, DOWNLOADING: 5,
INITIALIZED: 6, INITIALIZED: 6,
DISABLING: 7,
ENABLING: 8,
// Used as an error state for operations on unknown extensions, // Used as an error state for operations on unknown extensions,
// should never be in a real extensionMeta object. // should never be in a real extensionMeta object.

View File

@ -100,6 +100,9 @@ var ExtensionManager = class extends Signals.EventEmitter {
if (extension.state != ExtensionState.ENABLED) if (extension.state != ExtensionState.ENABLED)
return; return;
extension.state = ExtensionState.DISABLING;
this.emit('extension-state-changed', extension);
// "Rebase" the extension order by disabling and then enabling extensions // "Rebase" the extension order by disabling and then enabling extensions
// in order to help prevent conflicts. // in order to help prevent conflicts.
@ -164,6 +167,9 @@ var ExtensionManager = class extends Signals.EventEmitter {
if (extension.state != ExtensionState.DISABLED) if (extension.state != ExtensionState.DISABLED)
return; return;
extension.state = ExtensionState.ENABLING;
this.emit('extension-state-changed', extension);
let stylesheetNames = [`${global.session_mode}.css`, 'stylesheet.css']; let stylesheetNames = [`${global.session_mode}.css`, 'stylesheet.css'];
let theme = St.ThemeContext.get_for_stage(global.stage).get_theme(); let theme = St.ThemeContext.get_for_stage(global.stage).get_theme();
for (let i = 0; i < stylesheetNames.length; i++) { for (let i = 0; i < stylesheetNames.length; i++) {

View File

@ -790,16 +790,20 @@ var Extensions = GObject.registerClass({
_stateToString(extensionState) { _stateToString(extensionState) {
switch (extensionState) { switch (extensionState) {
case ExtensionState.ENABLED: case ExtensionState.ENABLED:
return _("Enabled"); return _('Enabled');
case ExtensionState.DISABLED: case ExtensionState.DISABLED:
case ExtensionState.INITIALIZED: case ExtensionState.INITIALIZED:
return _("Disabled"); return _('Disabled');
case ExtensionState.ERROR: case ExtensionState.ERROR:
return _("Error"); return _('Error');
case ExtensionState.OUT_OF_DATE: case ExtensionState.OUT_OF_DATE:
return _("Out of date"); return _('Out of date');
case ExtensionState.DOWNLOADING: case ExtensionState.DOWNLOADING:
return _("Downloading"); return _('Downloading');
case ExtensionState.DISABLING:
return _('Disabling');
case ExtensionState.ENABLING:
return _('Enabling');
} }
return 'Unknown'; // Not translated, shouldn't appear return 'Unknown'; // Not translated, shouldn't appear
} }

View File

@ -36,6 +36,8 @@ typedef enum {
STATE_OUT_OF_DATE, STATE_OUT_OF_DATE,
STATE_DOWNLOADING, STATE_DOWNLOADING,
STATE_INITIALIZED, STATE_INITIALIZED,
STATE_DISABLING,
STATE_ENABLING,
STATE_UNINSTALLED = 99 STATE_UNINSTALLED = 99
} ExtensionState; } ExtensionState;

View File

@ -43,6 +43,10 @@ extension_state_to_string (ExtensionState state)
return "DOWNLOADING"; return "DOWNLOADING";
case STATE_INITIALIZED: case STATE_INITIALIZED:
return "INITIALIZED"; return "INITIALIZED";
case STATE_DISABLING:
return "DISABLING";
case STATE_ENABLING:
return "ENABLING";
case STATE_UNINSTALLED: case STATE_UNINSTALLED:
return "UNINSTALLED"; return "UNINSTALLED";
} }