dbusServices: Port to ESM

We want to replace gjs' custom (and now legacy) imports system
with standard EcmaScript modules: JS developers are already
familiar with them, they have better tooling support and using
standard features over non-standard ones is generally the right
thing to do.

Our D-Bus services are separate from the main process, and thus
can be ported separately (except for the few imports that are
shared with the main process' code base).

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2786>
This commit is contained in:
Florian Müllner 2023-05-25 20:31:22 +02:00
parent eacabbf443
commit 612e04165e
13 changed files with 70 additions and 70 deletions

View File

@ -4,5 +4,6 @@ extends:
overrides: overrides:
- files: - files:
- js/ui/init.js - js/ui/init.js
- js/dbusServices/**
parserOptions: parserOptions:
sourceType: module sourceType: module

View File

@ -1,5 +1,9 @@
imports.package.start({ import {programInvocationName, programArgs} from 'system';
imports.package.init({
name: '@PACKAGE_NAME@', name: '@PACKAGE_NAME@',
prefix: '@prefix@', prefix: '@prefix@',
libdir: '@libdir@', libdir: '@libdir@',
}); });
const {main} = await import(`${imports.package.moduledir}/main.js`);
await main([programInvocationName, ...programArgs]);

View File

@ -1,3 +1,3 @@
[D-BUS Service] [D-BUS Service]
Name=@service@ Name=@service@
Exec=@gjs@ @pkgdatadir@/@service@ Exec=@gjs@ -m @pkgdatadir@/@service@

View File

@ -1,14 +1,13 @@
/* exported DBusService, ServiceImplementation */ import Gio from 'gi://Gio';
import GLib from 'gi://GLib';
const { Gio, GLib } = imports.gi; import {programArgs} from 'system';
const Signals = imports.signals; const Signals = imports.signals;
const IDLE_SHUTDOWN_TIME = 2; // s const IDLE_SHUTDOWN_TIME = 2; // s
const { programArgs } = imports.system; export class ServiceImplementation {
var ServiceImplementation = class {
constructor(info, objectPath) { constructor(info, objectPath) {
this._objectPath = objectPath; this._objectPath = objectPath;
this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(info, this); this._dbusImpl = Gio.DBusExportedObject.wrapJSObject(info, this);
@ -150,10 +149,10 @@ var ServiceImplementation = class {
that._queueShutdownCheck(); that._queueShutdownCheck();
}; };
} }
}; }
Signals.addSignalMethods(ServiceImplementation.prototype); Signals.addSignalMethods(ServiceImplementation.prototype);
var DBusService = class { export class DBusService {
constructor(name, service) { constructor(name, service) {
this._name = name; this._name = name;
this._service = service; this._service = service;
@ -162,7 +161,7 @@ var DBusService = class {
this._service.connect('shutdown', () => this._loop.quit()); this._service.connect('shutdown', () => this._loop.quit());
} }
run() { async runAsync() {
// Bail out when not running under gnome-shell // Bail out when not running under gnome-shell
Gio.DBus.watch_name(Gio.BusType.SESSION, Gio.DBus.watch_name(Gio.BusType.SESSION,
'org.gnome.Shell', 'org.gnome.Shell',
@ -183,6 +182,6 @@ var DBusService = class {
null, null,
() => this._loop.quit()); () => this._loop.quit());
this._loop.run(); await this._loop.runAsync();
}
} }
};

View File

@ -1,11 +1,15 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported ExtensionPrefsDialog */
const { Adw, Gdk, Gio, GLib, GObject, Gtk } = imports.gi; import Adw from 'gi://Adw?version=1';
import Gdk from 'gi://Gdk?version=4.0';
import Gio from 'gi://Gio';
import GLib from 'gi://GLib';
import GObject from 'gi://GObject';
import Gtk from 'gi://Gtk?version=4.0';
const ExtensionUtils = imports.misc.extensionUtils; const ExtensionUtils = imports.misc.extensionUtils;
var ExtensionPrefsDialog = GObject.registerClass({ export const ExtensionPrefsDialog = GObject.registerClass({
GTypeName: 'ExtensionPrefsDialog', GTypeName: 'ExtensionPrefsDialog',
}, class ExtensionPrefsDialog extends Adw.PreferencesWindow { }, class ExtensionPrefsDialog extends Adw.PreferencesWindow {
_init(extension) { _init(extension) {

View File

@ -1,18 +1,18 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported ExtensionsService */ import Gio from 'gi://Gio';
import GLib from 'gi://GLib';
import Shew from 'gi://Shew';
const { Gio, GLib, Shew } = imports.gi; import {ExtensionPrefsDialog} from './extensionPrefsDialog.js';
import {ServiceImplementation} from './dbusService.js';
const ExtensionUtils = imports.misc.extensionUtils; const ExtensionUtils = imports.misc.extensionUtils;
const {loadInterfaceXML} = imports.misc.dbusUtils; const {loadInterfaceXML} = imports.misc.dbusUtils;
const { ExtensionPrefsDialog } = imports.extensionPrefsDialog;
const { ServiceImplementation } = imports.dbusService;
const ExtensionsIface = loadInterfaceXML('org.gnome.Shell.Extensions'); const ExtensionsIface = loadInterfaceXML('org.gnome.Shell.Extensions');
const ExtensionsProxy = Gio.DBusProxy.makeProxyWrapper(ExtensionsIface); const ExtensionsProxy = Gio.DBusProxy.makeProxyWrapper(ExtensionsIface);
var ExtensionsService = class extends ServiceImplementation { export const ExtensionsService = class extends ServiceImplementation {
constructor() { constructor() {
super(ExtensionsIface, '/org/gnome/Shell/Extensions'); super(ExtensionsIface, '/org/gnome/Shell/Extensions');

View File

@ -1,16 +1,12 @@
/* exported main */ import Adw from 'gi://Adw?version=1';
import GObject from 'gi://GObject';
imports.gi.versions.Adw = '1';
imports.gi.versions.Gdk = '4.0';
imports.gi.versions.Gtk = '4.0';
const { Adw, GObject } = imports.gi;
const pkg = imports.package; const pkg = imports.package;
const { DBusService } = imports.dbusService; import {DBusService} from './dbusService.js';
const { ExtensionsService } = imports.extensionsService; import {ExtensionsService} from './extensionsService.js';
function main() { /** @returns {void} */
export async function main() {
Adw.init(); Adw.init();
pkg.initFormat(); pkg.initFormat();
@ -19,5 +15,5 @@ function main() {
const service = new DBusService( const service = new DBusService(
'org.gnome.Shell.Extensions', 'org.gnome.Shell.Extensions',
new ExtensionsService()); new ExtensionsService());
service.run(); await service.runAsync();
} }

View File

@ -1,11 +1,10 @@
/* exported main */ import {DBusService} from './dbusService.js';
import {NotificationDaemon} from './notificationDaemon.js';
const { DBusService } = imports.dbusService; /** @returns {void} */
const { NotificationDaemon } = imports.notificationDaemon; export async function main() {
function main() {
const service = new DBusService( const service = new DBusService(
'org.gnome.Shell.Notifications', 'org.gnome.Shell.Notifications',
new NotificationDaemon()); new NotificationDaemon());
service.run(); await service.runAsync();
} }

View File

@ -1,17 +1,17 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported NotificationDaemon */ import Gio from 'gi://Gio';
import GLib from 'gi://GLib';
const { Gio, GLib } = imports.gi; import {ServiceImplementation} from './dbusService.js';
const {loadInterfaceXML} = imports.misc.dbusUtils; const {loadInterfaceXML} = imports.misc.dbusUtils;
const { ServiceImplementation } = imports.dbusService;
const NotificationsIface = loadInterfaceXML('org.freedesktop.Notifications'); const NotificationsIface = loadInterfaceXML('org.freedesktop.Notifications');
const NotificationsProxy = Gio.DBusProxy.makeProxyWrapper(NotificationsIface); const NotificationsProxy = Gio.DBusProxy.makeProxyWrapper(NotificationsIface);
Gio._promisify(Gio.DBusConnection.prototype, 'call'); Gio._promisify(Gio.DBusConnection.prototype, 'call');
var NotificationDaemon = class extends ServiceImplementation { export const NotificationDaemon = class extends ServiceImplementation {
constructor() { constructor() {
super(NotificationsIface, '/org/freedesktop/Notifications'); super(NotificationsIface, '/org/freedesktop/Notifications');

View File

@ -1,14 +1,13 @@
/* exported main */ import {DBusService} from './dbusService.js';
import {ScreencastService} from './screencastService.js';
const {DBusService} = imports.dbusService; /** @returns {void} */
export async function main() {
function main() {
const {ScreencastService} = imports.screencastService;
if (!ScreencastService.canScreencast()) if (!ScreencastService.canScreencast())
return; return;
const service = new DBusService( const service = new DBusService(
'org.gnome.Shell.Screencast', 'org.gnome.Shell.Screencast',
new ScreencastService()); new ScreencastService());
service.run(); await service.runAsync();
} }

View File

@ -1,14 +1,13 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported ScreencastService */ import Gio from 'gi://Gio';
import GLib from 'gi://GLib';
import Gst from 'gi://Gst?version=1.0';
import Gtk from 'gi://Gtk?version=4.0';
imports.gi.versions.Gst = '1.0'; import {ServiceImplementation} from './dbusService.js';
imports.gi.versions.Gtk = '4.0';
const { Gio, GLib, Gst, Gtk } = imports.gi;
const {loadInterfaceXML, loadSubInterfaceXML} = imports.misc.dbusUtils; const {loadInterfaceXML, loadSubInterfaceXML} = imports.misc.dbusUtils;
const Signals = imports.misc.signals; const Signals = imports.misc.signals;
const { ServiceImplementation } = imports.dbusService;
const ScreencastIface = loadInterfaceXML('org.gnome.Shell.Screencast'); const ScreencastIface = loadInterfaceXML('org.gnome.Shell.Screencast');
@ -400,7 +399,7 @@ var Recorder = class extends Signals.EventEmitter {
} }
}; };
var ScreencastService = class extends ServiceImplementation { export const ScreencastService = class extends ServiceImplementation {
static canScreencast() { static canScreencast() {
if (!Gst.init_check(null)) if (!Gst.init_check(null))
return false; return false;

View File

@ -1,11 +1,10 @@
/* exported main */ import {DBusService} from './dbusService.js';
import {ScreenSaverService} from './screenSaverService.js';
const { DBusService } = imports.dbusService; /** @returns {void} */
const { ScreenSaverService } = imports.screenSaverService; export async function main() {
function main() {
const service = new DBusService( const service = new DBusService(
'org.gnome.ScreenSaver', 'org.gnome.ScreenSaver',
new ScreenSaverService()); new ScreenSaverService());
service.run(); await service.runAsync();
} }

View File

@ -1,15 +1,15 @@
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*- // -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported ScreenSaverService */ import Gio from 'gi://Gio';
import GLib from 'gi://GLib';
const { Gio, GLib } = imports.gi; import {ServiceImplementation} from './dbusService.js';
const {loadInterfaceXML} = imports.misc.dbusUtils; const {loadInterfaceXML} = imports.misc.dbusUtils;
const { ServiceImplementation } = imports.dbusService;
const ScreenSaverIface = loadInterfaceXML('org.gnome.ScreenSaver'); const ScreenSaverIface = loadInterfaceXML('org.gnome.ScreenSaver');
const ScreenSaverProxy = Gio.DBusProxy.makeProxyWrapper(ScreenSaverIface); const ScreenSaverProxy = Gio.DBusProxy.makeProxyWrapper(ScreenSaverIface);
var ScreenSaverService = class extends ServiceImplementation { export const ScreenSaverService = class extends ServiceImplementation {
constructor() { constructor() {
super(ScreenSaverIface, '/org/gnome/ScreenSaver'); super(ScreenSaverIface, '/org/gnome/ScreenSaver');