Skip to content

Commit 165ecda

Browse files
committed
Implement SystemD activation
Closes #369 Closes #433
1 parent c690a59 commit 165ecda

6 files changed

+106
-5
lines changed

Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@ PACK_CONTENT += \
192192
ddterm/com.github.amezin.ddterm.Extension.xml \
193193
ddterm/com.github.amezin.ddterm.desktop.in \
194194
ddterm/com.github.amezin.ddterm.service.in \
195+
ddterm/dbus-com.github.amezin.ddterm.service.in \
195196
LICENSE \
196197

197198
PACK_CONTENT := $(sort $(PACK_CONTENT))

ddterm/app/application.js

+60-2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
'use strict';
2121

22+
const ByteArray = imports.byteArray;
2223
const System = imports.system;
2324

2425
const Me = imports.misc.extensionUtils.getCurrentExtension();
@@ -83,6 +84,14 @@ const Application = GObject.registerClass(
8384
'Ask the extension to launch the app',
8485
null
8586
);
87+
this.add_main_option(
88+
'attach-unit',
89+
0,
90+
GLib.OptionFlags.NONE,
91+
GLib.OptionArg.STRING,
92+
'Attach launched application process to the specified systemd unit',
93+
'UNIT_NAME'
94+
);
8695

8796
this.connect('startup', this.startup.bind(this));
8897
this.connect('handle-local-options', this.handle_local_options.bind(this));
@@ -230,8 +239,7 @@ const Application = GObject.registerClass(
230239
handle_local_options(_, options) {
231240
if (options.lookup('launch-through-extension')) {
232241
try {
233-
const iface = extensiondbus.get();
234-
iface.ServiceSync();
242+
this.launch_through_extension(options);
235243
return 0;
236244
} catch (e) {
237245
logError(e);
@@ -247,6 +255,56 @@ const Application = GObject.registerClass(
247255
return -1;
248256
}
249257

258+
launch_through_extension(options) {
259+
const iface = extensiondbus.get();
260+
const [pid] = iface.ServiceSync();
261+
262+
const attach_unit = options.lookup('attach-unit', 's');
263+
if (attach_unit) {
264+
Gio.DBus.session.call_sync(
265+
'org.freedesktop.systemd1',
266+
'/org/freedesktop/systemd1',
267+
'org.freedesktop.systemd1.Manager',
268+
'AttachProcessesToUnit',
269+
GLib.Variant.new_tuple([
270+
GLib.Variant.new_string(attach_unit),
271+
GLib.Variant.new_string(''),
272+
GLib.Variant.new_array(
273+
new GLib.VariantType('u'),
274+
[GLib.Variant.new_uint32(parseInt(pid, 10))]
275+
),
276+
]),
277+
null,
278+
Gio.DBusCallFlags.NONE,
279+
-1,
280+
null
281+
);
282+
}
283+
284+
const notify_socket_path = GLib.getenv('NOTIFY_SOCKET');
285+
if (notify_socket_path) {
286+
const abstract = notify_socket_path.startsWith('@');
287+
288+
const address = new Gio.UnixSocketAddress({
289+
path: abstract ? notify_socket_path.substr(1) : notify_socket_path,
290+
abstract,
291+
});
292+
293+
const socket = Gio.Socket.new(
294+
Gio.SocketFamily.UNIX,
295+
Gio.SocketType.DATAGRAM,
296+
Gio.SocketProtocol.DEFAULT
297+
);
298+
299+
try {
300+
socket.connect(address, null);
301+
socket.send(ByteArray.fromString(`MAINPID=${pid}`), null);
302+
} finally {
303+
socket.close();
304+
}
305+
}
306+
}
307+
250308
preferences() {
251309
if (this.prefs_dialog === null) {
252310
this.prefs_dialog = new PrefsDialog({

ddterm/com.github.amezin.ddterm.Extension.xml

+3-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
<interface name="com.github.amezin.ddterm.Extension">
66
<method name="Toggle"/>
77
<method name="Activate"/>
8-
<method name="Service"/>
8+
<method name="Service">
9+
<arg type="s" name="pid" direction="out"/>
10+
</method>
911
<method name="GetTargetRect">
1012
<arg type="i" name="x" direction="out"/>
1113
<arg type="i" name="y" direction="out"/>
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
[D-BUS Service]
22
Name=com.github.amezin.ddterm
33
Exec="@LAUNCHER@" --launch-through-extension
4+
SystemdService=dbus-com.github.amezin.ddterm.service
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
[Service]
2+
Type=dbus
3+
BusName=com.github.amezin.ddterm
4+
ExecStart="@LAUNCHER@" --launch-through-extension --attach-unit %n
5+
Delegate=
6+
NotifyAccess=main

ddterm/shell/extension.js

+35-2
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ let window_connections = null;
4444
let dbus_interface = null;
4545

4646
let desktop_entry = null;
47+
let systemd_service = null;
4748
let dbus_service = null;
4849

4950
const APP_ID = 'com.github.amezin.ddterm';
@@ -128,7 +129,7 @@ class ExtensionDBusInterface {
128129
}
129130

130131
Service() {
131-
spawn_app();
132+
return spawn_app();
132133
}
133134

134135
GetTargetRect() {
@@ -266,6 +267,31 @@ function enable() {
266267
);
267268
desktop_entry.install();
268269

270+
systemd_service = new InstallableResource(
271+
Me.dir.get_child('ddterm').get_child('dbus-com.github.amezin.ddterm.service.in'),
272+
Gio.File.new_for_path(GLib.build_filenamev(
273+
[
274+
GLib.get_user_runtime_dir(),
275+
'systemd',
276+
'user',
277+
`dbus-${APP_ID}.service`,
278+
]))
279+
);
280+
systemd_service.install();
281+
282+
Gio.DBus.session.call(
283+
'org.freedesktop.systemd1',
284+
'/org/freedesktop/systemd1',
285+
'org.freedesktop.systemd1.Manager',
286+
'Reload',
287+
null,
288+
null,
289+
Gio.DBusCallFlags.NO_AUTO_START,
290+
-1,
291+
null,
292+
null
293+
);
294+
269295
dbus_service = new InstallableResource(
270296
Me.dir.get_child('ddterm').get_child('com.github.amezin.ddterm.service.in'),
271297
Gio.File.new_for_path(GLib.build_filenamev(
@@ -346,6 +372,11 @@ function disable() {
346372
desktop_entry = null;
347373
}
348374

375+
if (systemd_service) {
376+
systemd_service.uninstall();
377+
systemd_service = null;
378+
}
379+
349380
if (dbus_service) {
350381
dbus_service.uninstall();
351382
dbus_service = null;
@@ -356,7 +387,7 @@ function disable() {
356387

357388
function spawn_app() {
358389
if (subprocess)
359-
return;
390+
return subprocess.get_identifier();
360391

361392
const subprocess_launcher = Gio.SubprocessLauncher.new(Gio.SubprocessFlags.NONE);
362393

@@ -387,6 +418,8 @@ function spawn_app() {
387418
subprocess = subprocess_launcher.spawnv(argv);
388419

389420
subprocess.wait_async(null, subprocess_terminated);
421+
422+
return subprocess.get_identifier();
390423
}
391424

392425
function subprocess_terminated(source) {

0 commit comments

Comments
 (0)