Skip to content

Commit c14e69a

Browse files
committed
Implement SystemD activation
Closes #369 Closes #433
1 parent c7af06d commit c14e69a

6 files changed

+108
-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

+62-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,22 @@ 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+
);
95+
this.add_main_option(
96+
'pid-file',
97+
0,
98+
GLib.OptionFlags.NONE,
99+
GLib.OptionArg.FILENAME,
100+
'Write launched application process id to the specified file',
101+
'FILE_NAME'
102+
);
86103

87104
this.connect('startup', this.startup.bind(this));
88105
this.connect('handle-local-options', this.handle_local_options.bind(this));
@@ -230,8 +247,7 @@ const Application = GObject.registerClass(
230247
handle_local_options(_, options) {
231248
if (options.lookup('launch-through-extension')) {
232249
try {
233-
const iface = extensiondbus.get();
234-
iface.ServiceSync();
250+
this.launch_through_extension(options);
235251
return 0;
236252
} catch (e) {
237253
logError(e);
@@ -247,6 +263,50 @@ const Application = GObject.registerClass(
247263
return -1;
248264
}
249265

266+
launch_through_extension(options) {
267+
const iface = extensiondbus.get();
268+
const [pid] = iface.ServiceSync();
269+
270+
const attach_unit = options.lookup('attach-unit', 's');
271+
if (attach_unit) {
272+
Gio.DBus.session.call_sync(
273+
'org.freedesktop.systemd1',
274+
'/org/freedesktop/systemd1',
275+
'org.freedesktop.systemd1.Manager',
276+
'AttachProcessesToUnit',
277+
GLib.Variant.new_tuple([
278+
GLib.Variant.new_string(attach_unit),
279+
GLib.Variant.new_string(''),
280+
GLib.Variant.new_array(
281+
new GLib.VariantType('u'),
282+
[GLib.Variant.new_uint32(parseInt(pid, 10))]
283+
),
284+
]),
285+
null,
286+
Gio.DBusCallFlags.NONE,
287+
-1,
288+
null
289+
);
290+
}
291+
292+
const pid_file_path = options.lookup('pid-file', 'ay');
293+
if (pid_file_path) {
294+
const pid_file = Gio.File.new_for_commandline_arg(
295+
ByteArray.toString(pid_file_path)
296+
);
297+
298+
GLib.mkdir_with_parents(pid_file.get_parent().get_path(), 0o700);
299+
300+
pid_file.replace_contents(
301+
ByteArray.fromString(`${pid}`),
302+
null,
303+
false,
304+
Gio.FileCreateFlags.PRIVATE | Gio.FileCreateFlags.REPLACE_DESTINATION,
305+
null
306+
);
307+
}
308+
}
309+
250310
preferences() {
251311
if (this.prefs_dialog === null) {
252312
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=forking
3+
BusName=com.github.amezin.ddterm
4+
ExecStart="@LAUNCHER@" --launch-through-extension --attach-unit "%n" --pid-file "%t/%n.pid"
5+
PIDFile=%t/%n.pid
6+
Delegate=

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)