diff --git a/js/dbusServices/extensions/css/application.css b/js/dbusServices/extensions/css/application.css
new file mode 100644
index 000000000..06914ea3c
--- /dev/null
+++ b/js/dbusServices/extensions/css/application.css
@@ -0,0 +1,2 @@
+.expander-frame > * { border-top-width: 0; }
+.expander-toolbar { border: 0 solid @borders; border-top-width: 1px; }
diff --git a/js/dbusServices/extensions/extensionsService.js b/js/dbusServices/extensions/extensionsService.js
index 9ea07df45..482373846 100644
--- a/js/dbusServices/extensions/extensionsService.js
+++ b/js/dbusServices/extensions/extensionsService.js
@@ -1,7 +1,9 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported ExtensionsService */
-const { Gio, GLib } = imports.gi;
+const { Gdk, Gio, GLib, GObject, Gtk } = imports.gi;
+
+const ExtensionUtils = imports.misc.extensionUtils;
const { loadInterfaceXML } = imports.misc.fileUtils;
const { ServiceImplementation } = imports.dbusService;
@@ -108,10 +110,25 @@ var ExtensionsService = class extends ServiceImplementation {
}
OpenExtensionPrefsAsync(params, invocation) {
- this._proxy.OpenExtensionPrefsRemote(...params, (res, error) => {
+ const [uuid, parentWindow_, options] = params;
+
+ this._proxy.GetExtensionInfoRemote(uuid, (res, error) => {
if (this._handleError(invocation, error))
return;
+ const [serialized] = res;
+ const extension = ExtensionUtils.deserializeExtension(serialized);
+
+ const window = new ExtensionPrefsDialog(extension);
+
+ if (options.modal)
+ window.modal = options.modal.get_boolean();
+
+ window.connect('destroy', () => this.release());
+ this.hold();
+
+ window.show();
+
invocation.return_value(null);
});
}
@@ -125,3 +142,124 @@ var ExtensionsService = class extends ServiceImplementation {
});
}
};
+
+var ExtensionPrefsDialog = GObject.registerClass({
+ GTypeName: 'ExtensionPrefsDialog',
+ Template: 'resource:///org/gnome/Shell/Extensions/ui/extension-prefs-dialog.ui',
+ InternalChildren: [
+ 'headerBar',
+ 'stack',
+ 'expander',
+ 'expanderArrow',
+ 'revealer',
+ 'errorView',
+ ],
+}, class ExtensionPrefsDialog extends Gtk.Window {
+ _init(extension) {
+ super._init();
+
+ this._uuid = extension.uuid;
+ this._url = extension.metadata.url || '';
+
+ this._headerBar.title = extension.metadata.name;
+
+ this._actionGroup = new Gio.SimpleActionGroup();
+ this.insert_action_group('win', this._actionGroup);
+
+ this._initActions();
+ this._addCustomStylesheet();
+
+ this._gesture = new Gtk.GestureMultiPress({
+ widget: this._expander,
+ button: 0,
+ exclusive: true,
+ });
+
+ this._gesture.connect('released', (gesture, nPress) => {
+ if (nPress === 1)
+ this._revealer.reveal_child = !this._revealer.reveal_child;
+ });
+
+ this._revealer.connect('notify::reveal-child', () => {
+ this._expanderArrow.icon_name = this._revealer.reveal_child
+ ? 'pan-down-symbolic'
+ : 'pan-end-symbolic';
+ });
+
+ try {
+ ExtensionUtils.installImporter(extension);
+
+ // give extension prefs access to their own extension object
+ ExtensionUtils.getCurrentExtension = () => extension;
+
+ const prefsModule = extension.imports.prefs;
+ prefsModule.init(extension.metadata);
+
+ const widget = prefsModule.buildPrefsWidget();
+ this._stack.add(widget);
+ this._stack.visible_child = widget;
+ } catch (e) {
+ this._setError(e);
+ }
+ }
+
+ _setError(exc) {
+ this._errorView.buffer.text = `${exc}\n\nStack trace:\n`;
+ // Indent stack trace.
+ this._errorView.buffer.text +=
+ exc.stack.split('\n').map(line => ` ${line}`).join('\n');
+
+ // markdown for pasting in gitlab issues
+ let lines = [
+ `The settings of extension ${this._uuid} had an error:`,
+ '```',
+ `${exc}`,
+ '```',
+ '',
+ 'Stack trace:',
+ '```',
+ exc.stack.replace(/\n$/, ''), // stack without trailing newline
+ '```',
+ '',
+ ];
+ this._errorMarkdown = lines.join('\n');
+ this._actionGroup.lookup('copy-error').enabled = true;
+ }
+
+ _initActions() {
+ let action;
+
+ action = new Gio.SimpleAction({
+ name: 'copy-error',
+ enabled: false,
+ });
+ action.connect('activate', () => {
+ const clipboard = Gtk.Clipboard.get_default(this.get_display());
+ clipboard.set_text(this._errorMarkdown, -1);
+ });
+ this._actionGroup.add_action(action);
+
+ action = new Gio.SimpleAction({
+ name: 'show-url',
+ enabled: this._url !== '',
+ });
+ action.connect('activate', () => {
+ Gio.AppInfo.launch_default_for_uri(this._url,
+ this.get_display().get_app_launch_context());
+ });
+ this._actionGroup.add_action(action);
+ }
+
+ _addCustomStylesheet() {
+ let provider = new Gtk.CssProvider();
+ let uri = 'resource:///org/gnome/Shell/Extensions/css/application.css';
+ try {
+ provider.load_from_file(Gio.File.new_for_uri(uri));
+ } catch (e) {
+ logError(e, 'Failed to add application style');
+ }
+ Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),
+ provider,
+ Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
+ }
+});
diff --git a/js/dbusServices/extensions/main.js b/js/dbusServices/extensions/main.js
index 8f139a64f..9cc4bc5e3 100644
--- a/js/dbusServices/extensions/main.js
+++ b/js/dbusServices/extensions/main.js
@@ -1,9 +1,18 @@
/* exported main */
+imports.gi.versions.Gdk = '3.0';
+imports.gi.versions.Gtk = '3.0';
+
+const { Gtk } = imports.gi;
+const pkg = imports.package;
+
const { DBusService } = imports.dbusService;
const { ExtensionsService } = imports.extensionsService;
function main() {
+ Gtk.init(null);
+ pkg.initFormat();
+
const service = new DBusService(
'org.gnome.Shell.Extensions',
new ExtensionsService());
diff --git a/js/extensionPrefs/data/ui/extension-prefs-dialog.ui b/js/dbusServices/extensions/ui/extension-prefs-dialog.ui
similarity index 100%
rename from js/extensionPrefs/data/ui/extension-prefs-dialog.ui
rename to js/dbusServices/extensions/ui/extension-prefs-dialog.ui
diff --git a/js/dbusServices/org.gnome.Shell.Extensions.src.gresource.xml b/js/dbusServices/org.gnome.Shell.Extensions.src.gresource.xml
index 7bbcdab11..7436f2e89 100644
--- a/js/dbusServices/org.gnome.Shell.Extensions.src.gresource.xml
+++ b/js/dbusServices/org.gnome.Shell.Extensions.src.gresource.xml
@@ -6,6 +6,12 @@
dbusService.js
misc/config.js
+ misc/extensionUtils.js
misc/fileUtils.js
+
+
+ css/application.css
+ ui/extension-prefs-dialog.ui
+
diff --git a/js/extensionPrefs/data/css/application.css b/js/extensionPrefs/data/css/application.css
index 5641c5d23..37105d081 100644
--- a/js/extensionPrefs/data/css/application.css
+++ b/js/extensionPrefs/data/css/application.css
@@ -9,6 +9,3 @@
}
image.warning { color: @warning_color; }
-
-.expander-frame > * { border-top-width: 0; }
-.expander-toolbar { border: 0 solid @borders; border-top-width: 1px; }
diff --git a/js/extensionPrefs/data/org.gnome.Extensions.data.gresource.xml b/js/extensionPrefs/data/org.gnome.Extensions.data.gresource.xml
index de65e0823..659c03ffc 100644
--- a/js/extensionPrefs/data/org.gnome.Extensions.data.gresource.xml
+++ b/js/extensionPrefs/data/org.gnome.Extensions.data.gresource.xml
@@ -5,7 +5,6 @@
dbus-interfaces/org.gnome.Shell.Extensions.xml
- ui/extension-prefs-dialog.ui
ui/extension-row.ui
ui/extensions-window.ui
diff --git a/js/extensionPrefs/js/main.js b/js/extensionPrefs/js/main.js
index b96319c87..fd7605157 100644
--- a/js/extensionPrefs/js/main.js
+++ b/js/extensionPrefs/js/main.js
@@ -85,7 +85,6 @@ var ExtensionsWindow = GObject.registerClass({
_init(params) {
super._init(params);
- this._prefsDialog = null;
this._updatesCheckId = 0;
this._mainBox.set_focus_vadjustment(this._scrolledWindow.vadjustment);
@@ -152,16 +151,9 @@ var ExtensionsWindow = GObject.registerClass({
}
openPrefs(uuid) {
- if (this._prefsDialog)
- return;
-
- let row = this._findExtensionRow(uuid);
- this._prefsDialog = new ExtensionPrefsDialog(row);
- this._prefsDialog.set({ transient_for: this, modal: true });
-
- this._prefsDialog.connect('destroy', () => (this._prefsDialog = null));
-
- this._prefsDialog.show();
+ this._shellProxy.OpenExtensionPrefsRemote(uuid,
+ '',
+ { modal: new GLib.Variant('b', true) });
}
_showAbout() {
@@ -467,119 +459,6 @@ var ExtensionRow = GObject.registerClass({
_canToggle() {
return this._extension.canChange;
}
-
- get prefsModule() {
- // give extension prefs access to their own extension object
- ExtensionUtils.getCurrentExtension = () => this._extension;
-
- if (!this._prefsModule) {
- ExtensionUtils.installImporter(this._extension);
-
- this._prefsModule = this._extension.imports.prefs;
- this._prefsModule.init(this._extension.metadata);
- }
-
- return this._prefsModule;
- }
-});
-
-var ExtensionPrefsDialog = GObject.registerClass({
- GTypeName: 'ExtensionPrefsDialog',
- Template: 'resource:///org/gnome/Extensions/ui/extension-prefs-dialog.ui',
- InternalChildren: [
- 'headerBar',
- 'stack',
- 'expander',
- 'expanderArrow',
- 'revealer',
- 'errorView',
- ],
-}, class ExtensionPrefsDialog extends Gtk.Window {
- _init(extension) {
- super._init();
-
- this._uuid = extension.uuid;
- this._url = extension.url;
-
- this._headerBar.title = extension.name;
-
- this._actionGroup = new Gio.SimpleActionGroup();
- this.insert_action_group('win', this._actionGroup);
-
- this._initActions();
-
- this._gesture = new Gtk.GestureMultiPress({
- widget: this._expander,
- button: 0,
- exclusive: true,
- });
-
- this._gesture.connect('released', (gesture, nPress) => {
- if (nPress === 1)
- this._revealer.reveal_child = !this._revealer.reveal_child;
- });
-
- this._revealer.connect('notify::reveal-child', () => {
- this._expanderArrow.icon_name = this._revealer.reveal_child
- ? 'pan-down-symbolic'
- : 'pan-end-symbolic';
- });
-
- try {
- const widget = extension.prefsModule.buildPrefsWidget();
- this._stack.add(widget);
- this._stack.visible_child = widget;
- } catch (e) {
- this._setError(e);
- }
- }
-
- _setError(exc) {
- this._errorView.buffer.text = '%s\n\nStack trace:\n'.format(exc);
- // Indent stack trace.
- this._errorView.buffer.text +=
- exc.stack.split('\n').map(line => ' %s'.format(line)).join('\n');
-
- // markdown for pasting in gitlab issues
- let lines = [
- 'The settings of extension %s had an error:'.format(this._uuid),
- '```', // '`' (xgettext throws up on odd number of backticks)
- exc.toString(),
- '```', // '`'
- '',
- 'Stack trace:',
- '```', // '`'
- exc.stack.replace(/\n$/, ''), // stack without trailing newline
- '```', // '`'
- '',
- ];
- this._errorMarkdown = lines.join('\n');
- this._actionGroup.lookup('copy-error').enabled = true;
- }
-
- _initActions() {
- let action;
-
- action = new Gio.SimpleAction({
- name: 'copy-error',
- enabled: false,
- });
- action.connect('activate', () => {
- const clipboard = Gtk.Clipboard.get_default(this.get_display());
- clipboard.set_text(this._errorMarkdown, -1);
- });
- this._actionGroup.add_action(action);
-
- action = new Gio.SimpleAction({
- name: 'show-url',
- enabled: this._url !== '',
- });
- action.connect('activate', () => {
- Gio.AppInfo.launch_default_for_uri(this._url,
- this.get_display().get_app_launch_context());
- });
- this._actionGroup.add_action(action);
- }
});
function initEnvironment() {
diff --git a/js/ui/shellDBus.js b/js/ui/shellDBus.js
index 983a88712..2b6b2ae96 100644
--- a/js/ui/shellDBus.js
+++ b/js/ui/shellDBus.js
@@ -1,7 +1,7 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported GnomeShell, ScreenSaverDBus */
-const { Gio, GLib, Meta, Shell } = imports.gi;
+const { Gio, GLib, Meta } = imports.gi;
const Config = imports.misc.config;
const ExtensionDownloader = imports.ui.extensionDownloader;
@@ -315,13 +315,18 @@ var GnomeShellExtensions = class {
this.OpenExtensionPrefs(uuid, '', {});
}
- OpenExtensionPrefs(uuid, _parentWindow, _options) {
- let appSys = Shell.AppSystem.get_default();
- let app = appSys.lookup_app('org.gnome.Extensions.desktop');
- let info = app.get_app_info();
- let timestamp = global.display.get_current_time_roundtrip();
- info.launch_uris([`extension:///${uuid}`],
- global.create_app_launch_context(timestamp, -1));
+ OpenExtensionPrefs(uuid, parentWindow, options) {
+ Gio.DBus.session.call(
+ 'org.gnome.Shell.Extensions',
+ '/org/gnome/Shell/Extensions',
+ 'org.gnome.Shell.Extensions',
+ 'OpenExtensionPrefs',
+ new GLib.Variant('(ssa{sv})', [uuid, parentWindow, options]),
+ null,
+ Gio.DBusCallFlags.NONE,
+ -1,
+ null,
+ (conn, res) => conn.call_finish(res));
}
ReloadExtension(uuid) {
diff --git a/po/POTFILES.in b/po/POTFILES.in
index ba8a5b13b..92cdaf5ce 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -4,10 +4,10 @@ data/50-gnome-shell-system.xml
data/org.gnome.Shell.desktop.in.in
data/org.gnome.shell.gschema.xml.in
data/org.gnome.Shell.PortalHelper.desktop.in.in
+js/dbusServices/extensions/ui/extension-prefs-dialog.ui
js/extensionPrefs/data/metainfo/org.gnome.Extensions.metainfo.xml.in
js/extensionPrefs/data/org.gnome.Extensions.desktop.in.in
js/extensionPrefs/js/main.js
-js/extensionPrefs/data/ui/extension-prefs-dialog.ui
js/extensionPrefs/data/ui/extension-row.ui
js/extensionPrefs/data/ui/extensions-window.ui
js/gdm/authPrompt.js