dbusServices/extensions: Only show dialog when loaded

After the port to ESM, an extension's `prefs.js` file is imported
asynchronously. An unintended side effect of that is that we now
show the dialog before anything can be added to the window (either
by the extension, or the fallback error UI).

The delay almost always won't be noticeable to users, but it's
bad practice and prevents extensions from using some API that
only works before the window is realized.

To address the issue, add a `loaded` signal to the dialog that allows
the caller to postpone showing the window until the UI is ready.

Close: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/7201
Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3025>
This commit is contained in:
Florian Müllner 2023-11-21 13:28:30 +01:00 committed by Marge Bot
parent 6ff08fd9bd
commit 7f7ae31fa3
2 changed files with 6 additions and 3 deletions

View File

@ -9,6 +9,9 @@ import Gtk from 'gi://Gtk?version=4.0';
export const ExtensionPrefsDialog = GObject.registerClass({
GTypeName: 'ExtensionPrefsDialog',
Signals: {
'loaded': {},
},
}, class ExtensionPrefsDialog extends Adw.PreferencesWindow {
_init(extension) {
super._init({
@ -21,7 +24,7 @@ export const ExtensionPrefsDialog = GObject.registerClass({
this._loadPrefs().catch(e => {
this._showErrorPage(e);
logError(e, 'Failed to open preferences');
});
}).finally(() => this.emit('loaded'));
}
async _loadPrefs() {

View File

@ -137,6 +137,8 @@ export const ExtensionsService = class extends ServiceImplementation {
const extension = extensionManager.createExtensionObject(serialized);
this._prefsDialog = new ExtensionPrefsDialog(extension);
this._prefsDialog.connect('loaded',
() => this._prefsDialog.show());
this._prefsDialog.connect('realize', () => {
let externalWindow = null;
@ -157,8 +159,6 @@ export const ExtensionsService = class extends ServiceImplementation {
});
this.hold();
this._prefsDialog.show();
invocation.return_value(null);
} catch (error) {
this._handleError(invocation, error);