(define-module (ruther home services wayland)
#:use-module (guix gexp)
#:use-module (gnu packages wm)
#:use-module (gnu packages emacs)
#:use-module (gnu packages gnome)
#:use-module (gnu packages networking)
#:use-module (gnu packages xdisorg)
#:use-module (gnu services)
#:use-module (gnu services configuration)
#:use-module (gnu services shepherd)
#:use-module (srfi srfi-26)
#:use-module (srfi srfi-1)
#:use-module (gnu home services)
#:use-module (gnu home services shepherd)
#:export (home-emacs-configuration
home-network-manager-applet-configuration
home-blueman-applet-configuration
home-waybar-configuration
home-gammastep-configuration
%display-environ-modules
%wayland-display-environ
%x-display-environ))
(define %display-environ-modules
'((srfi srfi-1)
(srfi srfi-26)
(shepherd service)
(shepherd support)))
(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))))))
(define %x-display-environ
#~(begin
(use-modules (shepherd service)
(shepherd support))
(let* ((display-service (lookup-service 'x-display))
(display (or (and display-service
(service-running-value display-service))
"FAILED_TO_OBTAIN")))
(cons (string-append "DISPLAY=" display)
(remove (cut string-prefix? "DISPLAY=" <>)
(default-environment-variables))))))
(define %xwayland-display-environ
#~(begin
(use-modules (shepherd service)
(shepherd support))
(let* ((display-service (lookup-service 'x-display))
(wayland-display-service (lookup-service 'wayland-display))
(wayland-display (or (and wayland-display-service
(service-running-value wayland-display-service))
"FAILED_TO_OBTAIN"))
(display (or (and display-service
(service-running-value display-service))
"FAILED_TO_OBTAIN")))
(cons* (string-append "DISPLAY=" display)
(string-append "WAYLAND_DISPLAY=" wayland-display)
(remove (lambda (var) (or (string-prefix? "DISPLAY=" var)
(string-prefix? "WAYLAND_DISPLAY=" var)))
(default-environment-variables))))))
(define (x-display-shepherd-service config)
(list
(shepherd-service
(documentation "Sets X_DISPLAY to argument passed in.
This should be called from a x compositor like this: `herd start x-display $DISPLAY`")
(provision '(x-display))
(auto-start? #f)
(start #~(lambda (x-display) x-display))
(stop #~(lambda _ #f)))))
(define-public home-x-display-service-type
(service-type
(name 'home-x-display)
(description "A service to set DISPLAY environment variable inside of the shepherd process.")
(default-value #f)
(extensions
(list (service-extension home-shepherd-service-type
x-display-shepherd-service)))))
(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)))))
(define-public home-wayland-display-service-type
(service-type
(name 'home-wayland-display)
(description "A service to set WAYLAND_DISPLAY environment variable inside of the shepherd process.")
(default-value #f)
(extensions
(list (service-extension home-shepherd-service-type
wayland-display-shepherd-service)))))
(define-public home-x-display-service-type
(service-type
(name 'home-wayland-display)
(description "A service to set DISPLAY environment variable inside of the shepherd process.")
(default-value #f)
(extensions
(list (service-extension home-shepherd-service-type
x-display-shepherd-service)))))
(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) (x-display #f))
(use-modules (shepherd service)
(shepherd support))
(let ((display-service (lookup-service 'wayland-display))
(x-display-service (lookup-service 'x-display)))
(when (and wayland-display
(service-stopped? display-service))
(start-service display-service
wayland-display))
(when (and x-display
(service-stopped? x-display-service))
(start-service x-display-service
x-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-x-display-service-type
(const #f))
(service-extension home-wayland-display-service-type
(const #f))))))
(define-configuration/no-serialization home-emacs-configuration
(emacs (file-like emacs) "Emacs package to use.")
(extra-arguments (list-of-strings '()) "Extra arguments to emacs daemon command."))
(define (home-emacs-shepherd-service config)
(list
(shepherd-service
(documentation "Emacs daemon")
(requirement '(wayland-display dbus))
(provision '(emacs))
(auto-start? #f)
(modules %display-environ-modules)
(start #~(lambda _
(fork+exec-command
(cons*
#$(file-append (home-emacs-configuration-emacs config) "/bin/emacs")
"--fg-daemon"
'#$(home-emacs-configuration-extra-arguments config))
#:environment-variables #$%xwayland-display-environ)))
(stop #~(make-kill-destructor)))))
(define-public home-emacs-service-type
(service-type
(name 'home-emacs)
(description "A service to start emacs daemon")
(default-value (home-emacs-configuration))
(extensions
(list (service-extension home-shepherd-service-type
home-emacs-shepherd-service)
(service-extension home-wayland-display-service-type
(const #f))))))
(define-configuration/no-serialization home-network-manager-applet-configuration
(network-manager-applet (file-like network-manager-applet) "Network manager applet package to use.")
(extra-arguments (list-of-strings '()) "Extra arguments to nm-applet daemon command."))
(define (home-network-manager-applet-shepherd-service config)
(list
(shepherd-service
(documentation "Network Manager Applet daemon")
(requirement '(dbus))
(provision '(network-manager-applet))
(auto-start? #f)
(start #~(make-forkexec-constructor
(cons* #$(file-append
(home-network-manager-applet-configuration-network-manager-applet config)
"/bin/nm-applet")
'#$(home-network-manager-applet-configuration-extra-arguments config))))
(stop #~(make-kill-destructor)))))
(define-public home-network-manager-applet-service-type
(service-type
(name 'home-network-manager-applet)
(description "A service to start network-manager-applet daemon")
(default-value (home-network-manager-applet-configuration))
(extensions
(list (service-extension home-shepherd-service-type
home-network-manager-applet-shepherd-service)
(service-extension home-wayland-display-service-type
(const #f))))))
(define-configuration/no-serialization home-blueman-applet-configuration
(blueman (file-like blueman) "Blueman package to use, with blueman-applet binary.")
(blueman-in-profile? (boolean #t) "Whether to add blueman to profile.
This is required for the applet to work properly,
ie. to get manager running when applet is clicked on.")
(extra-arguments (list-of-strings '()) "Extra arguments to blueman-applet daemon command."))
(define (home-blueman-applet-shepherd-service config)
(list
(shepherd-service
(documentation "Blueman applet daemon")
(requirement '(dbus))
(provision '(blueman-applet))
(auto-start? #f)
(start #~(make-forkexec-constructor
(cons* #$(file-append
(home-blueman-applet-configuration-blueman config)
"/bin/blueman-applet")
'#$(home-blueman-applet-configuration-extra-arguments config))))
(stop #~(make-kill-destructor)))))
(define (home-blueman-applet-profile config)
(if (home-blueman-applet-configuration-blueman-in-profile? config)
(list blueman)
'()))
(define-public home-blueman-applet-service-type
(service-type
(name 'home-blueman-applet)
(description "A service to start blueman-applet daemon")
(default-value (home-blueman-applet-configuration))
(extensions
(list (service-extension home-shepherd-service-type
home-blueman-applet-shepherd-service)
(service-extension home-profile-service-type
home-blueman-applet-profile)
(service-extension home-wayland-display-service-type
(const #f))))))
(define-configuration/no-serialization home-waybar-configuration
(waybar (file-like waybar) "Waybar package to use, with waybar binary.")
(extra-arguments (list-of-strings '()) "Extra arguments to waybar daemon command."))
(define (home-waybar-shepherd-service config)
(list
(shepherd-service
(documentation "Waybar daemon")
(requirement '(wayland-display dbus))
(provision '(waybar))
(auto-start? #f)
(modules %display-environ-modules)
(start #~(lambda _
(fork+exec-command
(cons* #$(file-append
(home-waybar-configuration-waybar config)
"/bin/waybar")
'#$(home-waybar-configuration-extra-arguments config))
#:environment-variables #$%wayland-display-environ)))
(stop #~(make-kill-destructor)))))
(define-public home-waybar-service-type
(service-type
(name 'home-waybar)
(description "A service to start waybar daemon")
(default-value (home-waybar-configuration))
(extensions
(list (service-extension home-shepherd-service-type
home-waybar-shepherd-service)
(service-extension home-wayland-display-service-type
(const #f))))))
;; TODO configuration
(define-configuration/no-serialization home-gammastep-configuration
(gammastep (file-like gammastep) "Gammastep package to use, with gammastep binary.")
(extra-arguments (list-of-strings '()) "Extra arguments to gammastep daemon command."))
(define (home-gammastep-shepherd-service config)
(list
(shepherd-service
(documentation "Gammastep daemon")
(requirement '(dbus))
(provision '(gammastep))
(auto-start? #f)
(start #~(make-forkexec-constructor
(cons* #$(file-append
(home-gammastep-configuration-gammastep config)
"/bin/gammastep")
'#$(home-gammastep-configuration-extra-arguments config))))
(stop #~(make-kill-destructor)))))
(define-public home-gammastep-service-type
(service-type
(name 'home-gammastep)
(description "A service to start gammastep daemon")
(default-value (home-gammastep-configuration))
(extensions
(list (service-extension home-shepherd-service-type
home-gammastep-shepherd-service)
(service-extension home-wayland-display-service-type
(const #f))))))