@@ -44,6 +44,7 @@ let window_connections = null;
44
44
let dbus_interface = null ;
45
45
46
46
let desktop_entry = null ;
47
+ let systemd_service = null ;
47
48
let dbus_service = null ;
48
49
49
50
const APP_ID = 'com.github.amezin.ddterm' ;
@@ -127,8 +128,28 @@ class ExtensionDBusInterface {
127
128
activate ( ) ;
128
129
}
129
130
130
- Service ( ) {
131
- spawn_app ( ) ;
131
+ ServiceAsync ( params , invocation ) {
132
+ const return_error = err => {
133
+ logError ( err ) ;
134
+
135
+ if ( err instanceof GLib . Error ) {
136
+ invocation . return_gerror ( err ) ;
137
+ } else {
138
+ let name = err . name ;
139
+ if ( ! name . includes ( '.' ) )
140
+ name = `org.gnome.gjs.JSError.${ name } ` ;
141
+
142
+ invocation . return_dbus_error ( name , err . message ) ;
143
+ }
144
+ } ;
145
+
146
+ try {
147
+ const [ args ] = params ;
148
+
149
+ spawn_app ( args ) . then ( ( ) => invocation . return_value ( null ) ) . catch ( return_error ) ;
150
+ } catch ( err ) {
151
+ return_error ( err ) ;
152
+ }
132
153
}
133
154
134
155
MissingDependenciesNotification ( packages , files ) {
@@ -146,15 +167,7 @@ class ExtensionDBusInterface {
146
167
for ( const filename of files )
147
168
cmd . push ( '--file' , filename ) ;
148
169
149
- const [ _ , pid ] = GLib . spawn_async (
150
- null ,
151
- cmd ,
152
- null ,
153
- GLib . SpawnFlags . DEFAULT ,
154
- null
155
- ) ;
156
-
157
- GLib . spawn_close_pid ( pid ) ;
170
+ Gio . Subprocess . new ( cmd , Gio . SubprocessFlags . NONE ) ;
158
171
}
159
172
160
173
GetTargetRect ( ) {
@@ -292,6 +305,31 @@ function enable() {
292
305
) ;
293
306
desktop_entry . install ( ) ;
294
307
308
+ systemd_service = new InstallableResource (
309
+ Me . dir . get_child ( 'ddterm' ) . get_child ( 'dbus-com.github.amezin.ddterm.service.in' ) ,
310
+ Gio . File . new_for_path ( GLib . build_filenamev (
311
+ [
312
+ GLib . get_user_runtime_dir ( ) ,
313
+ 'systemd' ,
314
+ 'user' ,
315
+ `dbus-${ APP_ID } .service` ,
316
+ ] ) )
317
+ ) ;
318
+ systemd_service . install ( ) ;
319
+
320
+ Gio . DBus . session . call (
321
+ 'org.freedesktop.systemd1' ,
322
+ '/org/freedesktop/systemd1' ,
323
+ 'org.freedesktop.systemd1.Manager' ,
324
+ 'Reload' ,
325
+ null ,
326
+ null ,
327
+ Gio . DBusCallFlags . NO_AUTO_START ,
328
+ - 1 ,
329
+ null ,
330
+ null
331
+ ) ;
332
+
295
333
dbus_service = new InstallableResource (
296
334
Me . dir . get_child ( 'ddterm' ) . get_child ( 'com.github.amezin.ddterm.service.in' ) ,
297
335
Gio . File . new_for_path ( GLib . build_filenamev (
@@ -372,6 +410,11 @@ function disable() {
372
410
desktop_entry = null ;
373
411
}
374
412
413
+ if ( systemd_service ) {
414
+ systemd_service . uninstall ( ) ;
415
+ systemd_service = null ;
416
+ }
417
+
375
418
if ( dbus_service ) {
376
419
dbus_service . uninstall ( ) ;
377
420
dbus_service = null ;
@@ -380,7 +423,7 @@ function disable() {
380
423
settings = null ;
381
424
}
382
425
383
- function spawn_app ( ) {
426
+ async function spawn_app ( args ) {
384
427
if ( subprocess )
385
428
return ;
386
429
@@ -393,6 +436,7 @@ function spawn_app() {
393
436
Me . dir . get_child ( APP_ID ) . get_path ( ) ,
394
437
'--undecorated' ,
395
438
'--gapplication-service' ,
439
+ ...args ,
396
440
] ;
397
441
398
442
if ( Meta . is_wayland_compositor ( ) ) {
@@ -407,12 +451,35 @@ function spawn_app() {
407
451
408
452
printerr ( `Starting ddterm app: ${ JSON . stringify ( argv ) } ` ) ;
409
453
410
- if ( wayland_client )
411
- subprocess = wayland_client . spawnv ( global . display , argv ) ;
412
- else
413
- subprocess = subprocess_launcher . spawnv ( argv ) ;
454
+ let available_handler = null ;
455
+
456
+ const registered = new Promise ( resolve => {
457
+ available_handler = app_dbus . connect ( 'notify::available' , source => {
458
+ if ( source . available )
459
+ resolve ( ) ;
460
+ } ) ;
461
+ } ) ;
462
+
463
+ try {
464
+ if ( wayland_client )
465
+ subprocess = wayland_client . spawnv ( global . display , argv ) ;
466
+ else
467
+ subprocess = subprocess_launcher . spawnv ( argv ) ;
468
+
469
+ const terminated = new Promise ( resolve => {
470
+ subprocess . wait_async ( null , source => {
471
+ subprocess_terminated ( source ) ;
472
+ resolve ( ) ;
473
+ } ) ;
474
+ } ) ;
475
+
476
+ await Promise . race ( [ terminated , registered ] ) ;
477
+ } finally {
478
+ app_dbus . disconnect ( available_handler ) ;
479
+ }
414
480
415
- subprocess . wait_async ( null , subprocess_terminated ) ;
481
+ if ( ! subprocess )
482
+ throw new Error ( 'ddterm app exited without acquiring bus name' ) ;
416
483
}
417
484
418
485
function subprocess_terminated ( source ) {
0 commit comments