477011a364
The module is shared between the various D-Bus services and the main gnome-shell process, so it was originally left out to allow porting different bits at their own speed. Now that everything has been ported to ESM, there is no reason to not move that particular module as well. Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2868>
177 lines
5.6 KiB
JavaScript
177 lines
5.6 KiB
JavaScript
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
|
|
import Gio from 'gi://Gio';
|
|
import GLib from 'gi://GLib';
|
|
import Shew from 'gi://Shew';
|
|
|
|
import {ExtensionPrefsDialog} from './extensionPrefsDialog.js';
|
|
import {ServiceImplementation} from './dbusService.js';
|
|
|
|
import {deserializeExtension} from './misc/extensionUtils.js';
|
|
import {loadInterfaceXML} from './misc/dbusUtils.js';
|
|
|
|
const ExtensionsIface = loadInterfaceXML('org.gnome.Shell.Extensions');
|
|
const ExtensionsProxy = Gio.DBusProxy.makeProxyWrapper(ExtensionsIface);
|
|
|
|
class ExtensionManager {
|
|
#extensions = new Map();
|
|
|
|
createExtensionObject(serialized) {
|
|
const extension = deserializeExtension(serialized);
|
|
this.#extensions.set(extension.uuid, extension);
|
|
return extension;
|
|
}
|
|
|
|
lookup(uuid) {
|
|
return this.#extensions.get(uuid);
|
|
}
|
|
}
|
|
|
|
export const extensionManager = new ExtensionManager();
|
|
|
|
export const ExtensionsService = class extends ServiceImplementation {
|
|
constructor() {
|
|
super(ExtensionsIface, '/org/gnome/Shell/Extensions');
|
|
|
|
this._proxy = new ExtensionsProxy(Gio.DBus.session,
|
|
'org.gnome.Shell', '/org/gnome/Shell');
|
|
|
|
this._proxy.connectSignal('ExtensionStateChanged',
|
|
(proxy, sender, params) => {
|
|
this._dbusImpl.emit_signal('ExtensionStateChanged',
|
|
new GLib.Variant('(sa{sv})', params));
|
|
});
|
|
|
|
this._proxy.connect('g-properties-changed', () => {
|
|
this._dbusImpl.emit_property_changed('UserExtensionsEnabled',
|
|
new GLib.Variant('b', this._proxy.UserExtensionsEnabled));
|
|
});
|
|
}
|
|
|
|
get ShellVersion() {
|
|
return this._proxy.ShellVersion;
|
|
}
|
|
|
|
get UserExtensionsEnabled() {
|
|
return this._proxy.UserExtensionsEnabled;
|
|
}
|
|
|
|
set UserExtensionsEnabled(enable) {
|
|
this._proxy.UserExtensionsEnabled = enable;
|
|
}
|
|
|
|
async ListExtensionsAsync(params, invocation) {
|
|
try {
|
|
const res = await this._proxy.ListExtensionsAsync(...params);
|
|
invocation.return_value(new GLib.Variant('(a{sa{sv}})', res));
|
|
} catch (error) {
|
|
this._handleError(invocation, error);
|
|
}
|
|
}
|
|
|
|
async GetExtensionInfoAsync(params, invocation) {
|
|
try {
|
|
const res = await this._proxy.GetExtensionInfoAsync(...params);
|
|
invocation.return_value(new GLib.Variant('(a{sv})', res));
|
|
} catch (error) {
|
|
this._handleError(invocation, error);
|
|
}
|
|
}
|
|
|
|
async GetExtensionErrorsAsync(params, invocation) {
|
|
try {
|
|
const res = await this._proxy.GetExtensionErrorsAsync(...params);
|
|
invocation.return_value(new GLib.Variant('(as)', res));
|
|
} catch (error) {
|
|
this._handleError(invocation, error);
|
|
}
|
|
}
|
|
|
|
async InstallRemoteExtensionAsync(params, invocation) {
|
|
try {
|
|
const res = await this._proxy.InstallRemoteExtensionAsync(...params);
|
|
invocation.return_value(new GLib.Variant('(s)', res));
|
|
} catch (error) {
|
|
this._handleError(invocation, error);
|
|
}
|
|
}
|
|
|
|
async UninstallExtensionAsync(params, invocation) {
|
|
try {
|
|
const res = await this._proxy.UninstallExtensionAsync(...params);
|
|
invocation.return_value(new GLib.Variant('(b)', res));
|
|
} catch (error) {
|
|
this._handleError(invocation, error);
|
|
}
|
|
}
|
|
|
|
async EnableExtensionAsync(params, invocation) {
|
|
try {
|
|
const res = await this._proxy.EnableExtensionAsync(...params);
|
|
invocation.return_value(new GLib.Variant('(b)', res));
|
|
} catch (error) {
|
|
this._handleError(invocation, error);
|
|
}
|
|
}
|
|
|
|
async DisableExtensionAsync(params, invocation) {
|
|
try {
|
|
const res = await this._proxy.DisableExtensionAsync(...params);
|
|
invocation.return_value(new GLib.Variant('(b)', res));
|
|
} catch (error) {
|
|
this._handleError(invocation, error);
|
|
}
|
|
}
|
|
|
|
LaunchExtensionPrefsAsync([uuid], invocation) {
|
|
this.OpenExtensionPrefsAsync([uuid, '', {}], invocation);
|
|
}
|
|
|
|
async OpenExtensionPrefsAsync(params, invocation) {
|
|
const [uuid, parentWindow, options] = params;
|
|
|
|
try {
|
|
if (this._prefsDialog)
|
|
throw new Error('Already showing a prefs dialog');
|
|
|
|
const [serialized] = await this._proxy.GetExtensionInfoAsync(uuid);
|
|
const extension = extensionManager.createExtensionObject(serialized);
|
|
|
|
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(this._prefsDialog.get_surface());
|
|
});
|
|
|
|
if (options.modal)
|
|
this._prefsDialog.modal = options.modal.get_boolean();
|
|
|
|
this._prefsDialog.connect('close-request', () => {
|
|
delete this._prefsDialog;
|
|
this.release();
|
|
return false;
|
|
});
|
|
this.hold();
|
|
|
|
this._prefsDialog.show();
|
|
|
|
invocation.return_value(null);
|
|
} catch (error) {
|
|
this._handleError(invocation, error);
|
|
}
|
|
}
|
|
|
|
async CheckForUpdatesAsync(params, invocation) {
|
|
try {
|
|
await this._proxy.CheckForUpdatesAsync(...params);
|
|
invocation.return_value(null);
|
|
} catch (error) {
|
|
this._handleError(invocation, error);
|
|
}
|
|
}
|
|
};
|