home: services: Add home-graphical-session-service-type.

* modules/rosenthal/home/services/desktop.scm
(<home-graphical-session-configuration>): New data type.
(home-graphical-session-find-socket)
(home-graphical-session-shepherd-service): New procedures.
(home-graphical-session-service-type): New variable.
* modules/rosenthal/services/desktop.scm (%home-blueman-applet-shepherd)
(%home-fcitx5-shepherd, %home-mako-shepherd)
(%home-network-manager-applet-shepherd, %home-noctalia-shell-shepherd)
(%home-bb-auth-shepherd, %home-polkit-gnome-shepherd, %home-swaybg-shepherd)
(%home-waybar-shepherd): Depend on its shepherd service.
(home-mako-service-type, home-noctalia-shell-service-type)
(home-swaybg-service-type, home-waybar-service-type): Extend it.
(%rosenthal-desktop-home-services): No longer manually start Shepherd.
* modules/rosenthal/examples/dot-config/niri/config.kdl: Add screencasting
workaround and import environment variables into Shepherd.
This commit is contained in:
Hilton Chain 2026-04-09 13:25:44 +08:00
parent 1ada96ae7a
commit 5b3539c882
No known key found for this signature in database
GPG Key ID: ACC66D09CA528292
3 changed files with 208 additions and 26 deletions

View File

@ -3,6 +3,14 @@
// Check the wiki for a full description of the configuration:
// https://yalter.github.io/niri/Configuration:-Introduction
environment {
// Workaround for screencasting.
XDG_CURRENT_DESKTOP "niri:GNOME"
}
// See also `import_environment' in niri source (src/main.rs).
spawn-sh-at-startup "herd set-environment graphical-session XDG_CURRENT_DESKTOP=niri XDG_SESSION_TYPE=$XDG_SESSION_TYPE NIRI_SOCKET=$NIRI_SOCKET"
// Input device configuration.
// Find the full list of options on the wiki:
// https://yalter.github.io/niri/Configuration:-Input
@ -268,9 +276,6 @@ layout {
// Add lines like this to spawn processes at startup.
// See the binds section below for more spawn examples.
// Start user Shepherd for Guix Home.
spawn-at-startup "shepherd"
// To run a shell command (with variables, pipes, etc.), use spawn-sh-at-startup:
// spawn-sh-at-startup "qs -c ~/source/qs/MyAwesomeShell"

View File

@ -0,0 +1,177 @@
;;; SPDX-License-Identifier: GPL-3.0-or-later
;;; Copyright © 2023 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2026 Hilton Chain <hako@ultrarare.space>
(define-module (rosenthal home services desktop)
;; Guile builtins
#:use-module (ice-9 match)
#:use-module (srfi srfi-1)
;; Utilities
#:use-module (guix gexp)
#:use-module (guix records)
;; Guix System - services
#:use-module (gnu services)
#:use-module (gnu services configuration)
;; Guix Home - services
#:use-module (gnu home services shepherd)
#:export (home-graphical-session-service-type
home-graphical-session-configuration))
(define-configuration/no-serialization home-graphical-session-configuration
(timeout
(integer 10)
"Time in seconds to wait before a graphical session is found.")
(wayland?
(boolean #f)
"Wait and require Wayland environment to be available, providing a
@code{wayland-display} Shepherd service.")
(x11?
(boolean #f)
"Wait and require X11 environment to be available, providing a
@code{x11-display} Shepherd service."))
(define (home-graphical-session-find-socket)
#~(lambda* (timeout directory pattern #:key wayland?)
;; Wait for an accessible socket matching PATTERN to show up in
;; DIRECTORY, up to TIMEOUT seconds.
(let loop ((attempts timeout))
(define socket
(find (match-lambda
((or "." "..") #f)
(name
(let ((name (in-vicinity directory name)))
(and (string-match pattern name)
(access? name O_RDWR)))))
(or (reverse (scandir directory))
'())))
(if socket
(let ((display
(if wayland?
socket
(string-append ":" (string-drop socket 1)))))
(format #t "Display server found at ~s.~%" display)
display)
(if (zero? attempts)
(error
(format #f "Can't find ~a environment; giving up."
(if wayland? "Wayland" "X11")))
(begin
(sleep 1)
(loop (- attempts 1))))))))
(define home-graphical-session-shepherd-service
(match-record-lambda <home-graphical-session-configuration>
(timeout wayland? x11?)
(append
(if (or wayland? x11?)
(list (shepherd-service
(documentation
"Service target to indicate a graphical session is ready.")
(provision '(graphical-session))
(requirement
(append
(if wayland?
'(wayland-display)
'())
(if x11?
'(x11-display)
'())))
(respawn? #f)
(start #~(const #t))
(stop #~(const #f))
(actions
(list (shepherd-action
(name 'set-environment)
(documentation
"Set environment variables in Shepherd.")
(procedure
#~(lambda (_ . args)
(for-each putenv args))))))))
'())
(if wayland?
(list (shepherd-service
(documentation "Find Wayland socket.")
(provision '(wayland-display))
(modules
'((ice-9 ftw)
(ice-9 match)
(ice-9 regex)
(srfi srfi-1)
(shepherd support)))
(respawn? #f)
(start
#~(lambda* (#:optional (wayland-display (getenv "WAYLAND_DISPLAY")))
(let ((wayland-display
(or wayland-display
(#$(home-graphical-session-find-socket)
#$timeout
%user-runtime-dir
"wayland-[0-9]+$"
#:wayland? #t))))
(when wayland-display
(setenv "WAYLAND_DISPLAY" wayland-display))
wayland-display)))
(stop
#~(lambda (_)
(unsetenv "WAYLAND_DISPLAY")
#f))))
'())
(if x11?
(list (shepherd-service
(documentation "Find X11 display server.")
(provision '(x11-display))
(requirement
;; XWayland starts later than the compositor.
(if wayland?
'(wayland-display)
'()))
(modules
'((ice-9 ftw)
(ice-9 match)
(ice-9 regex)
(srfi srfi-1)))
(respawn? #f)
(start
#~(lambda* (#:optional (x11-display (getenv "DISPLAY")))
(let ((x11-display
(and #$x11?
(or x11-display
(#$(home-graphical-session-find-socket)
#$timeout
"/tmp/.X11-unix"
"X[0-9]+$")))))
(when x11-display
(setenv "DISPLAY" x11-display))
x11-display)))
(stop
#~(lambda (_)
(unsetenv "DISPLAY")
#f))))
'()))))
(define home-graphical-session-service-type
(service-type
(name 'home-graphical-session)
(extensions
(list (service-extension home-shepherd-service-type
home-graphical-session-shepherd-service)))
(compose identity)
(extend
(lambda (config extensions)
(match-record config <home-graphical-session-configuration>
(wayland? x11?)
(home-graphical-session-configuration
(inherit config)
(wayland?
(if (or wayland?
(member 'wayland extensions))
#t
#f))
(x11?
(if (or x11?
(member 'x11 extensions))
#t
#f))))))
(default-value (home-graphical-session-configuration))
(description "")))

View File

@ -34,6 +34,7 @@
#:use-module (gnu home services desktop)
#:use-module (gnu home services shepherd)
#:use-module (gnu home services sound)
#:use-module (rosenthal home services desktop)
#:use-module (rosenthal home services gtk)
;; Guix packages
#:use-module (gnu packages fcitx5)
@ -109,6 +110,7 @@
(list (shepherd-service
(documentation "Start blueman applet.")
(provision '(blueman-applet))
(requirement '(graphical-session))
(start
#~(lambda args
((make-forkexec-constructor
@ -227,7 +229,7 @@
(list (shepherd-service
(documentation "Start fcitx5.")
(provision '(fcitx5))
(requirement '(dbus))
(requirement '(dbus graphical-session))
(start
#~(lambda args
((make-forkexec-constructor
@ -283,6 +285,7 @@
(list (shepherd-service
(documentation "Start mako.")
(provision '(mako))
(requirement '(graphical-session))
(start
#~(lambda args
((make-forkexec-constructor
@ -299,7 +302,9 @@
(list (service-extension home-xdg-configuration-files-service-type
%home-mako-xdg-config)
(service-extension home-shepherd-service-type
%home-mako-shepherd)))
%home-mako-shepherd)
(service-extension home-graphical-session-service-type
(const 'wayland))))
(default-value (home-mako-configuration))
(description "Run mako, a notification daemon.")))
@ -319,6 +324,7 @@
(list (shepherd-service
(documentation "Start network manager applet.")
(provision '(network-manager-applet))
(requirement '(graphical-session))
(start
#~(lambda args
((make-forkexec-constructor
@ -394,6 +400,7 @@ compositor.")))
(list (shepherd-service
(documentation "Start noctalia-shell.")
(provision '(noctalia-shell))
(requirement '(graphical-session))
(modules '((shepherd support)))
(start
#~(lambda args
@ -414,7 +421,9 @@ compositor.")))
(service-extension home-activation-service-type
%home-noctalia-shell-activation)
(service-extension home-shepherd-service-type
%home-noctalia-shell-shepherd)))
%home-noctalia-shell-shepherd)
(service-extension home-graphical-session-service-type
(const 'wayland))))
(default-value (home-noctalia-shell-configuration))
(description "")))
@ -426,6 +435,7 @@ compositor.")))
(define (%home-bb-auth-shepherd _)
(list (shepherd-service
(provision '(bb-auth))
(requirement '(graphical-session))
(start
#~(lambda args
((make-forkexec-constructor
@ -452,6 +462,7 @@ compositor.")))
(define (%home-polkit-gnome-shepherd _)
(list (shepherd-service
(provision '(polkit-gnome))
(requirement '(graphical-session))
(start
#~(lambda args
((make-forkexec-constructor
@ -516,6 +527,7 @@ compositor.")))
(list (shepherd-service
(documentation "Start swaybg.")
(provision '(swaybg))
(requirement '(graphical-session))
(start
#~(lambda args
((make-forkexec-constructor
@ -531,7 +543,9 @@ compositor.")))
(name 'home-swaybg)
(extensions
(list (service-extension home-shepherd-service-type
%home-swaybg-shepherd)))
%home-swaybg-shepherd)
(service-extension home-graphical-session-service-type
(const 'wayland))))
(default-value (home-swaybg-configuration))
(description
"Run swaybg, a screen wallpaper utility for Wayland compositors.")))
@ -651,6 +665,7 @@ compositor.")))
(list (shepherd-service
(documentation "Start waybar.")
(provision '(waybar))
(requirement '(graphical-session))
(start
#~(lambda args
((make-forkexec-constructor
@ -667,7 +682,9 @@ compositor.")))
(list (service-extension home-xdg-configuration-files-service-type
%home-waybar-xdg-config)
(service-extension home-shepherd-service-type
%home-waybar-shepherd)))
%home-waybar-shepherd)
(service-extension home-graphical-session-service-type
(const 'wayland))))
(default-value (home-waybar-configuration))
(description "Run waybar, a status bar for Wayland compositors.")))
@ -795,23 +812,6 @@ compositor.")))
(define-deprecated %rosenthal-desktop-services %rosenthal-desktop-services/tuigreet)
(define %rosenthal-desktop-home-services
(cons* (service home-shepherd-service-type
(home-shepherd-configuration
;; Start by WM to inherit environment variables for graphical session.
(auto-start? #f)
(daemonize? #f)))
;; NOTE: The environment variable set by home-dbus-service-type will
;; prevent GNOME from starting when using above Shepherd configuration.
;; Replace home-dbus-service-type, expecting the session bus will be
;; started elsewhere. See also:
;; https://codeberg.org/guix/guix/issues/5899#issuecomment-10208485
(simple-service 'dbus home-shepherd-service-type
(list (shepherd-service
(provision '(dbus))
(start #~(const #t))
(stop #~(const #f)))))
(cons* (service home-dbus-service-type)
(service home-pipewire-service-type)
%base-home-services))