From b6b9e755c7b3730263f6139aac37f97aec28b3e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=BCllner?= Date: Tue, 26 Oct 2021 19:40:08 +0200 Subject: [PATCH] dbusServices/extensions: Only allow one dialog at a time Showing multiple preference dialogs at the same time (for instance by repeated `gnome-extensions prefs` calls) may or may not work as expected, depending on whether any of the dialogs is modal or not (read: opened via the Extensions app). The easiest way to address this is to disallow more than a single dialog at the time. It's arguably also the more predictable behavior, and means extensions don't have to deal with inconsistent state caused by multiple dialogs. https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/4564 Part-of: (cherry picked from commit b93342f72e871dc8472a9e92b23b45e0e7ded282) --- .../extensions/extensionsService.js | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/js/dbusServices/extensions/extensionsService.js b/js/dbusServices/extensions/extensionsService.js index 7fa32fe80..10743d4cc 100644 --- a/js/dbusServices/extensions/extensionsService.js +++ b/js/dbusServices/extensions/extensionsService.js @@ -116,30 +116,37 @@ var ExtensionsService = class extends ServiceImplementation { if (this._handleError(invocation, error)) return; + if (this._prefsDialog) { + this._handleError(invocation, + new Error('Already showing a prefs dialog')); + return; + } + const [serialized] = res; const extension = ExtensionUtils.deserializeExtension(serialized); - const window = new ExtensionPrefsDialog(extension); - window.connect('realize', () => { + this._prefsDialog = new ExtensionPrefsDialog(extension); + this._prefsDialog.connect('realize', () => { let externalWindow = null; if (parentWindow) externalWindow = Shew.ExternalWindow.new_from_handle(parentWindow); if (externalWindow) - externalWindow.set_parent_of(window.get_surface()); + externalWindow.set_parent_of(this._prefsDialog.get_surface()); }); if (options.modal) - window.modal = options.modal.get_boolean(); + this._prefsDialog.modal = options.modal.get_boolean(); - window.connect('close-request', () => { + this._prefsDialog.connect('close-request', () => { + delete this._prefsDialog; this.release(); return false; }); this.hold(); - window.show(); + this._prefsDialog.show(); invocation.return_value(null); });