Rosenthal/modules/rosenthal/services/desktop.scm
Hilton Chain 8967007a20
services: Inherit graphical session environment from Shepherd.
This will be utilized by an upcoming home-graphical-session-service-type.

* 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): Use environment variables from the running environment.
2026-04-10 16:29:34 +08:00

818 lines
26 KiB
Scheme
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

;;; SPDX-License-Identifier: GPL-3.0-or-later
;;; Copyright © 2025 Hilton Chain <hako@ultrarare.space>
(define-module (rosenthal services desktop)
;; Utilities
#:use-module (guix deprecation)
#:use-module (guix diagnostics)
#:use-module (guix gexp)
#:use-module (guix i18n)
#:use-module (guix modules)
#:use-module (guix packages)
#:use-module (guix records)
#:use-module (guix utils)
#:use-module (rosenthal utils file)
#:use-module (rosenthal utils packages)
;; Guix build systems
#:use-module (guix build-system copy)
;; Guix System
#:use-module (gnu system)
#:use-module (gnu system shadow)
;; Guix System - services
#:use-module (gnu services)
#:use-module (gnu services base)
#:use-module (gnu services configuration)
#:use-module (gnu services desktop)
#:use-module (gnu services pm)
#:use-module (gnu services sddm)
#:use-module (gnu services xorg)
#:use-module (rosenthal services base)
#:use-module (rosenthal services networking)
;; Guix Home - services
#:use-module (gnu home)
#:use-module (gnu home services)
#:use-module (gnu home services desktop)
#:use-module (gnu home services shepherd)
#:use-module (gnu home services sound)
#:use-module (rosenthal home services gtk)
;; Guix packages
#:use-module (gnu packages fcitx5)
#:use-module (gnu packages fonts)
#:use-module (gnu packages gnome)
#:use-module (gnu packages guile)
#:use-module (gnu packages hardware)
#:use-module (gnu packages linux)
#:use-module (gnu packages networking)
#:use-module (gnu packages polkit)
#:use-module (gnu packages qt)
#:use-module (gnu packages wm)
#:use-module (gnu packages xorg)
#:use-module (rosenthal packages authentication)
#:use-module (rosenthal packages wm)
#:export (home-blueman-applet-configuration
home-blueman-applet-service-type
home-fcitx5-configuration
home-fcitx5-service-type
home-mako-configuration
home-mako-service-type
home-network-manager-applet-configuration
home-network-manager-applet-service-type
home-niri-configuration
home-niri-service-type
home-noctalia-shell-configuration
home-noctalia-shell-service-type
home-bb-auth-service-type
home-polkit-gnome-service-type
home-rofi-configuration
home-rofi-service-type
home-swaybg-configuration
home-swaybg-service-type
home-theme-configuration
home-theme-service-type
home-waybar-configuration
home-waybar-service-type
%rosenthal-skeletons
%rosenthal-skeletons-installer
%rosenthal-desktop-services/base
%rosenthal-desktop-services/gdm
%rosenthal-desktop-services/tuigreet
%rosenthal-desktop-services-gdm ;deprecated
%rosenthal-desktop-services ;deprecated
%rosenthal-desktop-home-services))
;;;
;;; Blueman
;;;
(define-configuration/no-serialization home-blueman-applet-configuration
(blueman
(file-like blueman)
""))
(define %home-blueman-applet-shepherd
(match-record-lambda <home-blueman-applet-configuration>
(blueman)
(list (shepherd-service
(documentation "Start blueman applet.")
(provision '(blueman-applet))
(start
#~(lambda args
((make-forkexec-constructor
(list #$(file-append blueman "/bin/blueman-applet"))
;; Inherit graphical session environment.
#:environment-variables (environ))
args)))
(stop #~(make-kill-destructor))))))
(define home-blueman-applet-service-type
(service-type
(name 'home-blueman-applet)
(extensions
(list (service-extension home-profile-service-type
(compose list home-blueman-applet-configuration-blueman))
(service-extension home-shepherd-service-type
%home-blueman-applet-shepherd)))
(default-value (home-blueman-applet-configuration))
(description "Run blueman applet, a tray applet for managing bluetooth.")))
;;;
;;; Fcitx5
;;;
(define list-of-file-likes?
(list-of file-like?))
(define-maybe file-like)
(define-maybe boolean)
(define-configuration/no-serialization home-fcitx5-configuration
(fcitx5
(file-like fcitx5)
"")
(utilities
(list-of-file-likes (list fcitx5-configtool))
"")
(themes
(list-of-file-likes '())
"")
(input-method-editors
(list-of-file-likes '())
"")
(wayland-frontend?
(boolean #f)
"")
;; deprecated
(gtk-im-module?
maybe-boolean
""
(sanitizer
(lambda (config)
(if (maybe-value-set? config)
(warning
(G_ "'~a': option '~a' is deprecated, please use '~a' instead.~%")
"home-fcitx5-configuration"
"gtk-im-module?"
"wayland-frontend?")))))
(qt-im-module?
maybe-boolean
""
(sanitizer
(lambda (config)
(if (maybe-value-set? config)
(warning
(G_ "'~a': option '~a' is deprecated, please use '~a' instead.~%")
"home-fcitx5-configuration"
"qt-im-module?"
"wayland-frontend?")))))
(xim?
maybe-boolean
""
(sanitizer
(lambda (config)
(if (maybe-value-set? config)
(warning
(G_ "'~a': option '~a' is deprecated.~%")
"home-fcitx5-configuration"
"xim?"))))))
;; https://fcitx-im.org/wiki/Using_Fcitx_5_on_Wayland
(define %home-fcitx5-environment-variables
(match-record-lambda <home-fcitx5-configuration>
(wayland-frontend?)
`(("XMODIFIERS" . "@im=fcitx")
("QT_IM_MODULE" . "fcitx")
,@(if wayland-frontend?
'(("QT_IM_MODULES" . "wayland;fcitx"))
'(("GTK_IM_MODULE" . "fcitx"))))))
(define home-fcitx5-gtk2
(match-record-lambda <home-fcitx5-configuration>
(wayland-frontend?)
(if wayland-frontend?
`(("gtk-im-module" . ,(format #f "~s" "fcitx")))
'())))
(define home-fcitx5-gtk3
(match-record-lambda <home-fcitx5-configuration>
(wayland-frontend?)
(if wayland-frontend?
`(("gtk-im-module" . "fcitx"))
'())))
(define %home-fcitx5-profile
(match-record-lambda <home-fcitx5-configuration>
(fcitx5 utilities themes input-method-editors wayland-frontend?)
(append (list fcitx5 fcitx5-gtk fcitx5-qt)
utilities
themes
input-method-editors)))
(define %home-fcitx5-shepherd
(match-record-lambda <home-fcitx5-configuration>
(fcitx5)
(list (shepherd-service
(documentation "Start fcitx5.")
(provision '(fcitx5))
(requirement '(dbus))
(start
#~(lambda args
((make-forkexec-constructor
(list #$(file-append fcitx5 "/bin/fcitx5"))
;; Inherit graphical session environment.
#:environment-variables (environ))
args)))
(stop #~(make-kill-destructor))))))
(define home-fcitx5-service-type
(service-type
(name 'home-fcitx5)
(extensions
(list (service-extension home-environment-variables-service-type
%home-fcitx5-environment-variables)
(service-extension home-gtk2-service-type
home-fcitx5-gtk2)
(service-extension home-gtk3-service-type
home-fcitx5-gtk3)
(service-extension home-gtk4-service-type
home-fcitx5-gtk3)
(service-extension home-profile-service-type
%home-fcitx5-profile)
(service-extension home-shepherd-service-type
%home-fcitx5-shepherd)))
(default-value (home-fcitx5-configuration))
(description "Run fcitx5, an input method framework.")))
;;;
;;; mako
;;;
(define-configuration/no-serialization home-mako-configuration
(mako
(file-like mako)
"")
(config
maybe-file-like
"")
)
(define %home-mako-xdg-config
(match-record-lambda <home-mako-configuration>
(config)
(if (maybe-value-set? config)
`(("mako/config" ,config))
'())))
(define %home-mako-shepherd
(match-record-lambda <home-mako-configuration>
(mako)
(list (shepherd-service
(documentation "Start mako.")
(provision '(mako))
(start
#~(lambda args
((make-forkexec-constructor
(list #$(file-append mako "/bin/mako"))
;; Inherit graphical session environment.
#:environment-variables (environ))
args)))
(stop #~(make-kill-destructor))))))
(define home-mako-service-type
(service-type
(name 'home-mako)
(extensions
(list (service-extension home-xdg-configuration-files-service-type
%home-mako-xdg-config)
(service-extension home-shepherd-service-type
%home-mako-shepherd)))
(default-value (home-mako-configuration))
(description "Run mako, a notification daemon.")))
;;;
;;; network-manager-applet
;;;
(define-configuration/no-serialization home-network-manager-applet-configuration
(network-manager-applet
(file-like network-manager-applet)
""))
(define %home-network-manager-applet-shepherd
(match-record-lambda <home-network-manager-applet-configuration>
(network-manager-applet)
(list (shepherd-service
(documentation "Start network manager applet.")
(provision '(network-manager-applet))
(start
#~(lambda args
((make-forkexec-constructor
(list #$(file-append network-manager-applet "/bin/nm-applet"))
;; Inherit graphical session environment.
#:environment-variables (environ))
args)))
(stop #~(make-kill-destructor))))))
(define home-network-manager-applet-service-type
(service-type
(name 'home-network-manager-applet)
(extensions
(list (service-extension home-profile-service-type
(compose list home-network-manager-applet-configuration-network-manager-applet))
(service-extension home-shepherd-service-type
%home-network-manager-applet-shepherd)))
(default-value (home-network-manager-applet-configuration))
(description "Run nm-applet, a tray applet for managing networks.")))
;;;
;;; niri
;;;
(define-configuration/no-serialization home-niri-configuration
(config
maybe-file-like
""))
(define %home-niri-xdg-config
(match-record-lambda <home-niri-configuration>
(config)
(if (maybe-value-set? config)
`(("niri/config.kdl" ,config))
'())))
(define home-niri-service-type
(service-type
(name 'home-niri)
(extensions
(list (service-extension home-xdg-configuration-files-service-type
%home-niri-xdg-config)))
(default-value (home-niri-configuration))
(description
"Set up configuration file for niri, a scrollable-tiling Wayland
compositor.")))
;;;
;;; Noctalia
;;;
(define-configuration/no-serialization home-noctalia-shell-configuration
(noctalia-shell
(file-like noctalia-shell)
"File-like object to provide @command{/bin/noctalia-shell}."))
;; Create ~/.config/noctalia directory, otherwise Noctalia shell won't show up
;; on initial startup.
(define (%home-noctalia-shell-activation _)
(with-imported-modules (source-module-closure '((guix build utils)))
#~(begin
(use-modules (guix build utils))
(let ((xdg-config-home
(or (getenv "XDG_CONFIG_HOME")
(in-vicinity (getenv "HOME") ".config"))))
(mkdir-p (in-vicinity xdg-config-home "noctalia"))))))
(define %home-noctalia-shell-shepherd
(match-record-lambda <home-noctalia-shell-configuration>
(noctalia-shell)
(list (shepherd-service
(documentation "Start noctalia-shell.")
(provision '(noctalia-shell))
(modules '((shepherd support)))
(start
#~(lambda args
((make-forkexec-constructor
(list #$(file-append noctalia-shell "/bin/noctalia-shell"))
#:log-file (in-vicinity %user-log-dir "noctalia-shell.log")
;; Inherit graphical session environment.
#:environment-variables (environ))
args)))
(stop #~(make-kill-destructor))))))
(define home-noctalia-shell-service-type
(service-type
(name 'home-noctalia-shell)
(extensions
(list (service-extension home-profile-service-type
(compose list home-noctalia-shell-configuration-noctalia-shell))
(service-extension home-activation-service-type
%home-noctalia-shell-activation)
(service-extension home-shepherd-service-type
%home-noctalia-shell-shepherd)))
(default-value (home-noctalia-shell-configuration))
(description "")))
;;;
;;; bb-auth
;;;
(define (%home-bb-auth-shepherd _)
(list (shepherd-service
(provision '(bb-auth))
(start
#~(lambda args
((make-forkexec-constructor
(list #$(file-append bb-auth "/libexec/bb-auth") "--daemon")
;; Inherit graphical session environment.
#:environment-variables (environ))
args)))
(stop #~(make-kill-destructor)))))
(define home-bb-auth-service-type
(service-type
(name 'home-bb-auth)
(extensions
(list (service-extension home-shepherd-service-type
%home-bb-auth-shepherd)))
(default-value #f)
(description "Run @command{bb-auth} daemon.")))
;;;
;;; polkit-gnome
;;;
(define (%home-polkit-gnome-shepherd _)
(list (shepherd-service
(provision '(polkit-gnome))
(start
#~(lambda args
((make-forkexec-constructor
(list #$(file-append polkit-gnome "/libexec/polkit-gnome-authentication-agent-1"))
;; Inherit graphical session environment.
#:environment-variables (environ))
args)))
(stop #~(make-kill-destructor)))))
(define home-polkit-gnome-service-type
(service-type
(name 'home-polkit-gnome)
(extensions
(list (service-extension home-shepherd-service-type
%home-polkit-gnome-shepherd)))
(default-value #f)
(description "")))
;;;
;;; rofi
;;;
(define-configuration/no-serialization home-rofi-configuration
(config
maybe-file-like
""))
(define %home-rofi-xdg-config
(match-record-lambda <home-rofi-configuration>
(config)
(if (maybe-value-set? config)
`(("rofi/config.rasi" ,config))
'())))
(define home-rofi-service-type
(service-type
(name 'home-rofi)
(extensions
(list (service-extension home-xdg-configuration-files-service-type
%home-rofi-xdg-config)))
(default-value (home-rofi-configuration))
(description
"Set up configuration file for rofi, an application launcher.")))
;;;
;;; swaybg
;;;
(define-configuration/no-serialization home-swaybg-configuration
(swaybg
(file-like swaybg)
"")
(background
(file-like (local-file "../examples/wallpaper.jpg"))
""))
(define %home-swaybg-shepherd
(match-record-lambda <home-swaybg-configuration>
(swaybg background)
(list (shepherd-service
(documentation "Start swaybg.")
(provision '(swaybg))
(start
#~(lambda args
((make-forkexec-constructor
(list #$(file-append swaybg "/bin/swaybg") "--mode" "fill"
"--image" #$background)
;; Inherit graphical session environment.
#:environment-variables (environ))
args)))
(stop #~(make-kill-destructor))))))
(define home-swaybg-service-type
(service-type
(name 'home-swaybg)
(extensions
(list (service-extension home-shepherd-service-type
%home-swaybg-shepherd)))
(default-value (home-swaybg-configuration))
(description
"Run swaybg, a screen wallpaper utility for Wayland compositors.")))
;;;
;;; theme
;;;
(define-configuration/no-serialization home-theme-configuration
(packages
(list-of-file-likes '())
"")
(icon-theme
(string "Adwaita")
"")
(font
(string "Sans")
"")
(cursor-theme
(string "Adwaita")
"")
(cursor-size
(number 24)
"")
(key-theme
(string "Default")
""))
(define (%home-theme-environment-variables _)
'(("QT_QPA_PLATFORMTHEME" . "gtk3")
("QT_WAYLAND_DECORATION" . "adwaita")))
(define %home-theme-profile
(match-record-lambda <home-theme-configuration>
(packages)
(cons* adwaita-icon-theme
hicolor-icon-theme
packages)))
(define %home-theme-files
(match-record-lambda <home-theme-configuration>
(icon-theme)
`((".icons/default/index.theme"
,(ini-file "index.theme"
#~'(("icon theme"
("Inherits" . #$icon-theme))))))))
(define home-theme-gtk2
(match-record-lambda <home-theme-configuration>
(icon-theme font cursor-theme cursor-size key-theme)
`(("gtk-theme-name" . ,(format #f "~s" "Adwaita"))
("gtk-icon-theme-name" . ,(format #f "~s" icon-theme))
("gtk-font-name" . ,(format #f "~s" font))
("gtk-cursor-theme-name" . ,(format #f "~s" cursor-theme))
("gtk-cursor-theme-size" . ,cursor-size)
("gtk-key-theme-name" . ,(format #f "~s" key-theme)))))
(define home-theme-gtk3
(match-record-lambda <home-theme-configuration>
(icon-theme font cursor-theme cursor-size key-theme)
`(("gtk-theme-name" . "Adwaita")
("gtk-icon-theme-name" . ,icon-theme)
("gtk-font-name" . ,font)
("gtk-cursor-theme-name" . ,cursor-theme)
("gtk-cursor-theme-size" . ,cursor-size)
("gtk-key-theme-name" . ,key-theme))))
(define home-theme-service-type
(service-type
(name 'home-theme)
(extensions
(list (service-extension home-environment-variables-service-type
%home-theme-environment-variables)
(service-extension home-profile-service-type
%home-theme-profile)
(service-extension home-files-service-type
%home-theme-files)
(service-extension home-gtk2-service-type
home-theme-gtk2)
(service-extension home-gtk3-service-type
home-theme-gtk3)
(service-extension home-gtk4-service-type
home-theme-gtk3)))
(default-value (home-theme-configuration))
(description "Set up desktop themes.")))
;;;
;;; waybar
;;;
(define-configuration/no-serialization home-waybar-configuration
(waybar
(file-like waybar)
"")
(config
maybe-file-like
"")
(style
maybe-file-like
""))
(define %home-waybar-xdg-config
(match-record-lambda <home-waybar-configuration>
(config style)
`(,@(if (maybe-value-set? config)
`(("waybar/config.jsonc" ,config))
'())
,@(if (maybe-value-set? style)
`(("waybar/style.css" ,style))
'()))))
(define %home-waybar-shepherd
(match-record-lambda <home-waybar-configuration>
(waybar)
(list (shepherd-service
(documentation "Start waybar.")
(provision '(waybar))
(start
#~(lambda args
((make-forkexec-constructor
(list #$(file-append waybar "/bin/waybar"))
;; Inherit graphical session environment.
#:environment-variables (environ))
args)))
(stop #~(make-kill-destructor))))))
(define home-waybar-service-type
(service-type
(name 'home-waybar)
(extensions
(list (service-extension home-xdg-configuration-files-service-type
%home-waybar-xdg-config)
(service-extension home-shepherd-service-type
%home-waybar-shepherd)))
(default-value (home-waybar-configuration))
(description "Run waybar, a status bar for Wayland compositors.")))
;;;
;;; Configuration file presets.
;;;
(define %rosenthal-skeletons
`((".config/emacs/init.el"
,(local-file "../examples/emacs/init.el"))
(".config/emacs/init-fonts.el"
,(local-file "../examples/emacs/init-fonts.el"))
(".config/emacs/init-interface.el"
,(local-file "../examples/emacs/init-interface.el"))
(".config/emacs/init-editing.el"
,(local-file "../examples/emacs/init-editing.el"))
(".config/emacs/init-miscellaneous.el"
,(local-file "../examples/emacs/init-miscellaneous.el"))
(".config/fcitx5/config"
,(local-file "../examples/dot-config/fcitx5/config"))
(".config/htop/htoprc"
,(local-file "../examples/dot-config/htop/htoprc"))
(".config/niri/config.kdl"
,(local-file "../examples/dot-config/niri/config.kdl"))
(".config/xfce4/helpers.rc"
,(local-file "../examples/dot-config/xfce4/helpers.rc"))
,@(default-skeletons)))
(define %rosenthal-skeletons-installer
`((".config/noctalia/settings.json"
,(local-file "../examples/dot-config/noctalia/settings.json"))
(".config/wezterm/wezterm.lua"
,(local-file "../examples/dot-config/wezterm/wezterm.lua"))
;; Prevent Noctalia shell initial screen.
(".cache/noctalia/shell-state.json"
,(json-file "noctalia-shell-state.json"
#~'(("changelogState"
("lastSeenVersion"
. #$(string-append "v" (package-version noctalia-shell))))
("telemetry"
("instanceId" . "")))))
,@%rosenthal-skeletons))
;;;
;;; Service presets.
;;;
(define* (base-rosenthal-desktop-services
#:optional (system (or (%current-target-system)
(%current-system))))
(define %display-manager-service-type
(if (target-64bit? system)
gdm-service-type
sddm-service-type))
(cons* (service bluetooth-service-type
(bluetooth-configuration
(auto-enable? #t)))
(service gvfs-service-type)
(service power-profiles-daemon-service-type)
;; Screen lockers for Wayland environment. No dependencies are pulled
;; in since we're using empty files.
(service screen-locker-service-type
(screen-locker-configuration
(name "swaylock")
(program (plain-file "empty" "")) ;Not used.
(using-setuid? #f)))
(service screen-locker-service-type
(screen-locker-configuration
(name "waylock")
(program (plain-file "empty" "")) ;Not used.
(using-setuid? #f)))
;; Add udev rules for backlight control.
(simple-service 'backlight udev-service-type (list ddcutil light))
(modify-services %desktop-services
(delete %display-manager-service-type)
;; Use a font suitable for HiDPI monitors.
(console-font-service-type
_ => (map (lambda (num)
(cons (string-append "tty" (number->string num))
(file-append font-terminus
"/share/consolefonts/ter-132n")))
(iota 6 1))))))
(define-syntax %rosenthal-desktop-services/base
(identifier-syntax (base-rosenthal-desktop-services)))
(define %rosenthal-desktop-services/gdm
(cons* (service gdm-service-type)
%rosenthal-desktop-services/base))
(define %rosenthal-desktop-services/tuigreet
(cons* (service greetd-service-type
(greetd-configuration
(greeter-supplementary-groups '("video" "input"))
(terminals
(map (lambda (x)
(greetd-terminal-configuration
(terminal-vt (number->string x))
(terminal-switch (eqv? 1 x))
(default-session-command
(cond
((eqv? 1 x)
(greetd-tuigreet-session))
(else
(greetd-agreety-session
(command
(greetd-user-session
(command #~(getenv "SHELL"))))))))))
(iota 6 1)))))
(modify-services %rosenthal-desktop-services/base
(delete mingetty-service-type))))
(define-deprecated %rosenthal-desktop-services-gdm %rosenthal-desktop-services/gdm)
(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)))))
(service home-pipewire-service-type)
%base-home-services))