From 65c77e90aac72706736c1cfb596caa16419e88c2 Mon Sep 17 00:00:00 2001 From: dan Date: Thu, 23 Oct 2025 11:57:14 +0800 Subject: [PATCH] gnu: Add home-darkman-service-type. * gnu/home/services/desktop.scm (home-darkman-configuration) (home-darkman-service-type): New variables. (serialize-number, serialize-boolean, serialize-home-darkman-configuration) (home-darkman-configuration-files, home-darkman-profile-service) (home-darkman-shepherd-service): New procedures. * doc/guix.texi (Desktop Home Services): Document it. Change-Id: I23acb2cae9745e1a76c19c5552bf487539d6a807 Reviewed-by: Sergey Trofimov Signed-off-by: Sharlatan Hellseher --- doc/guix.texi | 44 ++++++++++++++++ gnu/home/services/desktop.scm | 99 ++++++++++++++++++++++++++++++++++- 2 files changed, 141 insertions(+), 2 deletions(-) diff --git a/doc/guix.texi b/doc/guix.texi index 4823197470a..1e4d022e99e 100644 --- a/doc/guix.texi +++ b/doc/guix.texi @@ -51852,6 +51852,50 @@ is passed to the @code{xorg-start-command-xinit} procedure producing the @command{startx} used. Default value is @code{(xorg-configuration)}. @end defvar +@defvar home-darkman-service-type +This is the service type for the +@uref{https://gitlab.com/WhyNotHugo/darkman, Darkman}, a program for +dark-mode and light-mode transitions on Unix-like desktops. It invokes +scripts in @code{$XDG_DATA_DIRS/dark-mode.d} at sundown, and invokes +scripts in @code{$XDG_DATA_DIRS/light-mode.d} at sunrise. Darkman tries +to determine the user's current location from: +@itemize +@item The config file. +@item The cache file from last time it ran. +@item Using the system geoclue. +@end itemize +@end defvar + +@deftp {Data Type} home-darkman-configuration +The configuration record for @code{home-darkman-service-type}. Its +available fields are: + +@table @asis +@item @code{darkman} (default: @code{darkman}) (type: file-like) +The @code{darkman} package to use. + +@item @code{latitude} (type: maybe-number) +Latitude, used at startup or when @code{use-geoclue} is @code{#f}. More +than one decimal point is generally not needed. + +@item @code{longitude} (type: maybe-number) +Longitude, used at startup or when @code{use-geoclue} is @code{#f}. +More than one decimal point is generally not needed. + +@item @code{use-geoclue} (default: @code{#f}) (type: boolean) +Whether to use a local geoclue instance to determine the current +location. Setting this to false without explicitly setting latitude and +longtitude disables automatic transitions entirely. + +@item @code{dbus-server} (default: @code{#t}) (type: boolean) +Whether to expose the current mode via darkman's own D-Bus API. + +@item @code{portal} (default: @code{#t}) (type: boolean) +Whether to expose the current mode via the XDG settings portal D-Bus +API. + +@end table +@end deftp @node Guix Home Services @subsection Guix Home Services diff --git a/gnu/home/services/desktop.scm b/gnu/home/services/desktop.scm index 859dba776a0..2ae50bfb076 100644 --- a/gnu/home/services/desktop.scm +++ b/gnu/home/services/desktop.scm @@ -3,6 +3,7 @@ ;;; Copyright © 2022 ( ;;; Copyright © 2023 conses ;;; Copyright © 2023 Janneke Nieuwenhuizen +;;; Copyright © 2025 dan ;;; ;;; This file is part of GNU Guix. ;;; @@ -25,7 +26,7 @@ #:use-module (gnu services configuration) #:use-module (gnu services xorg) #:autoload (gnu packages glib) (dbus) - #:autoload (gnu packages xdisorg) (redshift unclutter) + #:autoload (gnu packages xdisorg) (darkman redshift unclutter) #:autoload (gnu packages xorg) (setxkbmap xmodmap) #:use-module (guix records) #:use-module (guix gexp) @@ -46,7 +47,11 @@ home-xmodmap-configuration home-xmodmap-service-type - home-startx-command-service-type)) + home-startx-command-service-type + + home-darkman-configuration + home-darkman-configuration? + home-darkman-service-type)) ;;; @@ -447,3 +452,93 @@ buttons under the Xorg display server via user-defined expressions."))) (define-service-type-mapping startx-command-service-type => home-startx-command-service-type) + + +;;; +;;; Darkman. +;;; + +(define-maybe number) + +(define (serialize-number field value) + (string-append (match field + ('latitude "lat") + ('longitude "lng") + (_ (symbol->string field))) + ": " (number->string value) "\n")) + +(define (serialize-boolean field value) + (string-append (match field + ('use-geoclue "usegeoclue") + ('dbus-server "dbusserver") + (_ "portal")) + ": " (if value "true" "false") "\n")) + +(define-configuration home-darkman-configuration + (darkman + (file-like darkman) + "The @code{darkman} package to use.") + + (latitude + maybe-number + "Latitude, used at startup or when @code{use-geoclue} is @code{#f}. More than +one decimal point is generally not needed.") + + (longitude + maybe-number + "Longitude, used at startup or when @code{use-geoclue} is @code{#f}. More than +one decimal point is generally not needed.") + + (use-geoclue + (boolean #f) + "Whether to use a local geoclue instance to determine the current location. +Setting this to false without explicitly setting latitude and longtitude +disables automatic transitions entirely.") + + (dbus-server + (boolean #t) + "Whether to expose the current mode via darkman's own D-Bus API.") + + (portal + (boolean #t) + "Whether to expose the current mode via the XDG settings portal D-Bus API.")) + +(define (serialize-home-darkman-configuration config) + (mixed-text-file + "config.yaml" + (serialize-configuration config home-darkman-configuration-fields))) + +(define (home-darkman-configuration-files config) + `(("darkman/config.yaml" ,(serialize-home-darkman-configuration config)))) + +(define (home-darkman-profile-service config) + (list (home-darkman-configuration-darkman config))) + +(define (home-darkman-shepherd-service config) + (list + (shepherd-service + (provision '(darkman)) + (requirement '(dbus)) + (modules '((shepherd support))) ;for '%user-log-dir' + (start #~(make-forkexec-constructor + (list #$(file-append (home-darkman-configuration-darkman config) + "/bin/darkman") + "run") + #:log-file + (string-append %user-log-dir "/darkman.log"))) + (stop #~(make-kill-destructor))))) + +(define home-darkman-service-type + (service-type + (name 'home-darkman) + (extensions + (list (service-extension home-shepherd-service-type + home-darkman-shepherd-service) + (service-extension home-xdg-configuration-files-service-type + home-darkman-configuration-files) + (service-extension home-profile-service-type + home-darkman-profile-service))) + (default-value (home-darkman-configuration)) + (description "Run the @code{darkman} daemon, which will invoke scripts in +$XDG_DATA_DIRS/dark-mode.d/ when sundown, and invoke scripts in +$XDG_DATA_DIRS/light-mode.d/ when sunrise.")))