(define-module (sigils home services wayland) #:use-module (gnu home services) #:use-module (gnu home services shepherd) #:use-module (gnu packages wm) #:use-module (gnu services configuration) #:use-module (guix packages) #:use-module (guix gexp) #:use-module (guix diagnostics) #:use-module (guix ui) #:use-module (sigils home services desktop) #:use-module (srfi srfi-1) #:use-module (srfi srfi-26) #:use-module (srfi srfi-43) #:use-module (ice-9 match) #:export (home-kanshi-service-type home-kanshi-configuration)) ;;; ;;; kanshi. ;;; (define kanshi-config? list?) (define (serialize-kanshi-config config) (define serialize-term (match-lambda ((? symbol? e) `(" " ,(symbol->string e))) ((? number? e) `(" " ,(number->string e))) ((? string? e) `(" " ,(format #f "~s" e))) (e `(" " ,e)))) (define serialize-statement (match-lambda ((cmd . lst) `(,(symbol->string cmd) ,@(append-map serialize-term lst))))) (define serialize-profile (match-lambda ((name ((expressions ...) ...)) `("profile " ,(symbol->string name) " {\n" ,@(append-map (lambda (expr) `(" " ,@(serialize-statement expr) "\n")) expressions) "}\n")))) (append-map serialize-profile config)) (define-configuration home-kanshi-configuration (kanshi (file-like kanshi) "kanshi package to use.") (config (kanshi-config `()) "The kanshi configuration is a list of profiles with output and exec fields. @lisp '((static ((output LVDS-1 disable) (output \"Some Company ASDF 4242\" mode 1600x900 position 0,0))) (portable ((output LVDS-1 enable scale 2)))) @end lisp serializes to @code profile static { output LVDS-1 disable output \"Some Company ASDF 4242\" mode 1600x900 position 0,0 } profile portable { output LVDS-1 enable scale 2 } @end code ")) (define (add-kanshi-packages config) (list (home-kanshi-configuration-kanshi config))) (define (add-kanshi-configuration config) `(("kanshi/config" ,(apply mixed-text-file "kanshi-config" (serialize-kanshi-config (home-kanshi-configuration-config config)))))) (define (home-kanshi-shepherd-service config) (let ((kanshi (home-kanshi-configuration-kanshi config))) (list (shepherd-service (provision '(kanshi)) (requirement '(wayland-display)) (modules '((srfi srfi-1) (srfi srfi-26))) (start #~(lambda _ ;; This is not optimal. (fork+exec-command (list #$(file-append kanshi "/bin/kanshi")) #:log-file (string-append (getenv "XDG_STATE_HOME") "/log" "/kanshi.log") #:environment-variables (cons (string-append "WAYLAND_DISPLAY=" (getenv "WAYLAND_DISPLAY")) (remove (cut string-prefix? "WAYLAND_DISPLAY=" <>) (default-environment-variables)))))) (stop #~(make-kill-destructor)) (documentation "Run Kanshi"))))) (define (home-kanshi-extensions cfg extensions) (home-kanshi-configuration (inherit cfg) (config (append (home-kanshi-configuration-config cfg) (append-map identity (reverse extensions)))))) (define home-kanshi-service-type (service-type (name 'home-kanshi) (extensions (list (service-extension home-profile-service-type add-kanshi-packages) (service-extension home-shepherd-service-type home-kanshi-shepherd-service) (service-extension home-xdg-configuration-files-service-type add-kanshi-configuration))) (compose identity) (extend home-kanshi-extensions) (default-value (home-kanshi-configuration)) (description "\ Install and configure kanshi, output profile manager.")))