summaryrefslogtreecommitdiff
path: root/sigils/home/services/desktop.scm
blob: 388e1fa7ffe1d5efe692beea398a7cbbb226a050 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
(define-module (sigils home services desktop)
  #:use-module (guix gexp)
  #:use-module (gnu home services)
  #:use-module (gnu home services shepherd))

(define (wayland-shepherd-service delay)
  (list (shepherd-service
         (provision '(wayland-display))
         (modules '((ice-9 ftw)
                    (ice-9 match)
                    (ice-9 regex)
                    (srfi srfi-1)))
         (start
          #~(lambda* (#:optional (display (getenv "WAYLAND_DISPLAY")))
              (define xdg-runtime-directory
                (or (getenv "XDG_RUNTIME_DIR")
                    (string-append "/run/user" (getuid))))

              (define (find-display delay)
                ;; Wait for an accessible socket to show up in
                ;; XDG-RUNTIME-DIRECTORY, up to DELAY seconds.
                (let loop ((attempts delay))
                  (define socket
                    (find (match-lambda
                            ((or "." "..") #f)
                            (name
                             (let ((name (in-vicinity xdg-runtime-directory
                                                      name)))
                               (and (string-match "wayland-[0-9]+" name)
                                    (access? name O_RDWR)))))
                          (or (scandir xdg-runtime-directory) '())))

                  (if socket
                      (begin
                        (format #t "Wayland server found at ~s.~%" socket)
                        socket)
                      (if (zero? attempts)
                          (begin
                            (format (current-error-port)
                                    "Wayland server did not show up; \
giving up.\n")
                            #f)
                          (begin
                            (sleep 1)
                            (loop (- attempts 1)))))))

              (let ((display (or display (find-display #$delay))))
                (when display
                  ;; Note: 'make-forkexec-constructor' calls take their
                  ;; default #:environment-variables value before this service
                  ;; is started and are thus unaffected by the 'setenv' call
                  ;; below.  Users of this service have to explicitly query
                  ;; its value.
                  (setenv "WAYLAND_DISPLAY" display))
                display)))
         (stop #~(lambda (_)
                   (unsetenv "WAYLAND_DISPLAY")
                   #f))
         (respawn? #f))))

(define-public home-wayland-service-type
  (service-type
   (name 'home-wayland-display)
   (extensions (list (service-extension home-shepherd-service-type
                                        wayland-shepherd-service)))
   (default-value 10)
   (description
    "Create a @code{wayland-display} Shepherd service that waits for a Wayland
compositor to be up and running, up to a configurable delay, and sets the
@code{WAYLAND_DISPLAY} environment variable of @command{shepherd} itself
accordingly.  If no accessible Wayland server shows up during that time, the
@code{wayland-display} service is marked as failing to start.")))