Hi Abbé,
shepherd doesn't really offer this functionality built-in. Moreover, even if you do setenv in shepherd process, it won't automatically be propagated to the started services, you need to modify their environment parameter. There are a couple of ways to achieve what you want, though. One is to make a service that will set this variable based on the file appearing at XDG_RUNTIME_DIR, ie. /run/user/1000/wayland-X, this is how the home x display service works, so you can check its source in guix channel. Then you can call setenv and set the service's run value to the display name. Then other services depend on this one and are started only after this one starts. There is sort of a timeout of 10 seconds to wait for a display. But I personally don't like this approach of 'guessing' the wayland display and relying on it starting in time. The approach I take is that I make a service called wayland-display, and I start this service with a run value I want, as an argument. In turn it is `herd start wayland-display $WAYLAND_DISPLAY`. This service will keep $WAYLAND_DISPLAY as an argument and I can then use it in other services. Here is the service, it is very simple. ``` (define (wayland-display-shepherd-service config) (list (shepherd-service (documentation "Sets WAYLAND_DISPLAY to argument passed in. This should be called from a wayland compositor like this: `herd start wayland-display $WAYLAND_DISPLAY`") (provision '(wayland-display)) (auto-start? #f) (start #~(lambda (wayland-display) wayland-display)) (stop #~(lambda _ #f))))) ``` Then to use it in another services, here is an example with swayidle: ``` (define (home-swayidle-shepherd-services config) (list (shepherd-service (documentation "Run the swayidle daemon for managing commands executed when idle.") (provision '(swayidle)) (requirement '(wayland-display)) (modules '((srfi srfi-1) (srfi srfi-26) (shepherd service) (shepherd support))) (start #~(lambda _ (fork+exec-command (list #$(file-append (home-swayidle-configuration-swayidle config) "/bin/swayidle") "-wC" #$(serialize-swayidle-configuration (home-swayidle-configuration-config config))) #:environment-variables #$wayland-display-environ))) (stop #~(make-kill-destructor))))) ``` BEWARE of make-fork-exec-command! Then environment will be picked up at wrong time. Also the modules are important, since they are used in the `wayland-display-environ` And here is the symbol to obtain the run value, used in #:environment-variables argument: ``` (define wayland-display-environ #~(begin (use-modules (shepherd service) (shepherd support)) (let* ((display-service (lookup-service 'wayland-display)) (display (or (and display-service (service-running-value display-service)) "FAILED_TO_OBTAIN"))) (cons (string-append "WAYLAND_DISPLAY=" display) (remove (cut string-prefix? "WAYLAND_DISPLAY=" <>) (default-environment-variables)))))) ``` Then the idea is to start a batch of services that depend on this. One problem with this is that shepherd doesn't really have targets, ie. ways to start a group of services, so I made myself a service that will achieve that, it just calls all services that are passed in its configuration ``` (define (wlr-services-shepherd-service services) (list (shepherd-service (documentation "Service for starting WLR services.") (provision '(wlr-services)) (auto-start? #f) (start #~(lambda* (#:optional (wayland-display #f)) (use-modules (shepherd service) (shepherd support)) (let ((display-service (lookup-service 'wayland-display))) (when (and wayland-display (service-stopped? display-service)) (start-service display-service wayland-display)) (if (service-running? display-service) (for-each (lambda (service) (start-service (lookup-service service))) '#$services) (begin ((@ (shepherd support) local-output) ((@ (shepherd support) l10n) "Cannot start wlr-services, because wayland-display is not running and WAYLAND_DISPLAY argument has not been supplied.")) #f))))) (stop #~(lambda* (running-value #:optional (stop-display "yes")) (use-modules (shepherd service) (shepherd support)) (for-each (lambda (service) (stop-service (lookup-service service))) '#$services) (when (equal? stop-display "yes") ((@ (shepherd support) local-output) ((@ (shepherd support) l10n) "Stopping wayland-display as well.")) (stop-service (lookup-service 'wayland-display))) #f))))) (define-public home-wlr-services-service-type (service-type (name 'home-wayland-display) (description "A service to start a list of services, meant for wlr.") (default-value '()) (extensions (list (service-extension home-shepherd-service-type wlr-services-shepherd-service) (service-extension home-wayland-display-service-type (const #f)))))) ``` Config example: ``` (service home-wlr-services-service-type '(waybar kanshi emacs gammastep swayidle blueman-applet network-manager-applet)) ``` You can find more in my channel: https://git.ditigal.xyz/~ruther/guix-exprs/tree/main/item/ruther/home/services/wayland.scm If anyone had any ideas on improvements, I would appreciate that. Regards, Rutherther