1 ;;; GNU Guix --- Functional package management for GNU
2 ;;; Copyright © 2014-2022 Ludovic Courtès <ludo@gnu.org>
3 ;;; Copyright © 2015 Andy Wingo <wingo@igalia.com>
4 ;;; Copyright © 2015 Mark H Weaver <mhw@netris.org>
5 ;;; Copyright © 2016 Sou Bunnbu <iyzsong@gmail.com>
6 ;;; Copyright © 2017, 2020 Maxim Cournoyer <maxim.cournoyer@gmail.com>
7 ;;; Copyright © 2017 Nikita <nikita@n0.is>
8 ;;; Copyright © 2018, 2020 Efraim Flashner <efraim@flashner.co.il>
9 ;;; Copyright © 2018 Ricardo Wurmus <rekado@elephly.net>
10 ;;; Copyright © 2017, 2019 Christopher Baines <mail@cbaines.net>
11 ;;; Copyright © 2019 Tim Gesthuizen <tim.gesthuizen@yahoo.de>
12 ;;; Copyright © 2019 David Wilson <david@daviwil.com>
13 ;;; Copyright © 2020 Tobias Geerinckx-Rice <me@tobias.gr>
14 ;;; Copyright © 2020 Reza Alizadeh Majd <r.majd@pantherx.org>
15 ;;; Copyright © 2021 Brice Waegeneire <brice@waegenei.re>
16 ;;; Copyright © 2021 muradm <mail@muradm.net>
18 ;;; This file is part of GNU Guix.
20 ;;; GNU Guix is free software; you can redistribute it and/or modify it
21 ;;; under the terms of the GNU General Public License as published by
22 ;;; the Free Software Foundation; either version 3 of the License, or (at
23 ;;; your option) any later version.
25 ;;; GNU Guix is distributed in the hope that it will be useful, but
26 ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
27 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 ;;; GNU General Public License for more details.
30 ;;; You should have received a copy of the GNU General Public License
31 ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
33 (define-module (gnu services desktop)
34 #:use-module (gnu services)
35 #:use-module (gnu services shepherd)
36 #:use-module (gnu services base)
37 #:use-module (gnu services dbus)
38 #:use-module (gnu services avahi)
39 #:use-module (gnu services xorg)
40 #:use-module (gnu services networking)
41 #:use-module (gnu services sound)
42 #:use-module ((gnu system file-systems)
43 #:select (%control-groups
46 #:autoload (gnu services sddm) (sddm-service-type)
47 #:use-module (gnu system)
48 #:use-module (gnu system setuid)
49 #:use-module (gnu system shadow)
50 #:use-module (gnu system uuid)
51 #:use-module (gnu system pam)
52 #:use-module (gnu packages glib)
53 #:use-module (gnu packages admin)
54 #:use-module (gnu packages cups)
55 #:use-module (gnu packages freedesktop)
56 #:use-module (gnu packages gnome)
57 #:use-module (gnu packages xfce)
58 #:use-module (gnu packages avahi)
59 #:use-module (gnu packages xdisorg)
60 #:use-module (gnu packages scanner)
61 #:use-module (gnu packages suckless)
62 #:use-module (gnu packages linux)
63 #:use-module (gnu packages libusb)
64 #:use-module (gnu packages lxqt)
65 #:use-module (gnu packages mate)
66 #:use-module (gnu packages nfs)
67 #:use-module (gnu packages enlightenment)
68 #:use-module (guix deprecation)
69 #:use-module (guix records)
70 #:use-module (guix packages)
71 #:use-module (guix store)
72 #:use-module (guix utils)
73 #:use-module (guix gexp)
74 #:use-module (srfi srfi-1)
75 #:use-module (ice-9 format)
76 #:use-module (ice-9 match)
77 #:export (<upower-configuration>
80 upower-configuration-upower
81 upower-configuration-watts-up-pro?
82 upower-configuration-poll-batteries?
83 upower-configuration-ignore-lid?
84 upower-configuration-use-percentage-for-policy?
85 upower-configuration-percentage-low
86 upower-configuration-percentage-critical
87 upower-configuration-percentage-action
88 upower-configuration-time-low
89 upower-configuration-time-critical
90 upower-configuration-time-action
91 upower-configuration-critical-power-action
103 geoclue-configuration
104 geoclue-configuration?
105 %standard-geoclue-applications
109 bluetooth-service-type
110 bluetooth-configuration
111 bluetooth-configuration?
114 elogind-configuration
115 elogind-configuration?
119 %fontconfig-file-system
120 fontconfig-file-system-service
122 accountsservice-service-type
123 accountsservice-service
125 cups-pk-helper-service-type
128 gnome-desktop-configuration
129 gnome-desktop-configuration?
130 gnome-desktop-service
131 gnome-desktop-service-type
133 mate-desktop-configuration
134 mate-desktop-configuration?
136 mate-desktop-service-type
138 lxqt-desktop-configuration
139 lxqt-desktop-configuration?
140 lxqt-desktop-service-type
142 xfce-desktop-configuration
143 xfce-desktop-configuration?
145 xfce-desktop-service-type
147 x11-socket-directory-service
149 enlightenment-desktop-configuration
150 enlightenment-desktop-configuration?
151 enlightenment-desktop-service-type
153 inputattach-configuration
154 inputattach-configuration?
155 inputattach-service-type
159 gnome-keyring-configuration
160 gnome-keyring-configuration?
161 gnome-keyring-service-type
170 ;;; This module contains service definitions for a "desktop" environment.
180 (if value "true\n" "false\n"))
182 (define (package-direct-input-selector input)
184 (match (assoc-ref (package-direct-inputs package) input)
185 ((package . _) package))))
190 ;;; Upower D-Bus service.
193 (define-record-type* <upower-configuration>
194 upower-configuration make-upower-configuration
195 upower-configuration?
196 (upower upower-configuration-upower
198 (watts-up-pro? upower-configuration-watts-up-pro?
200 (poll-batteries? upower-configuration-poll-batteries?
202 (ignore-lid? upower-configuration-ignore-lid?
204 (use-percentage-for-policy? upower-configuration-use-percentage-for-policy?
206 (percentage-low upower-configuration-percentage-low
208 (percentage-critical upower-configuration-percentage-critical
210 (percentage-action upower-configuration-percentage-action
212 (time-low upower-configuration-time-low
214 (time-critical upower-configuration-time-critical
216 (time-action upower-configuration-time-action
218 (critical-power-action upower-configuration-critical-power-action
219 (default 'hybrid-sleep)))
221 (define* upower-configuration-file
222 ;; Return an upower-daemon configuration file.
224 (($ <upower-configuration> upower
225 watts-up-pro? poll-batteries? ignore-lid? use-percentage-for-policy?
226 percentage-low percentage-critical percentage-action time-low
227 time-critical time-action critical-power-action)
228 (plain-file "UPower.conf"
231 "EnableWattsUpPro=" (bool watts-up-pro?)
232 "NoPollBatteries=" (bool (not poll-batteries?))
233 "IgnoreLid=" (bool ignore-lid?)
234 "UsePercentageForPolicy=" (bool use-percentage-for-policy?)
235 "PercentageLow=" (number->string percentage-low) "\n"
236 "PercentageCritical=" (number->string percentage-critical) "\n"
237 "PercentageAction=" (number->string percentage-action) "\n"
238 "TimeLow=" (number->string time-low) "\n"
239 "TimeCritical=" (number->string time-critical) "\n"
240 "TimeAction=" (number->string time-action) "\n"
241 "CriticalPowerAction=" (match critical-power-action
242 ('hybrid-sleep "HybridSleep")
243 ('hibernate "Hibernate")
244 ('power-off "PowerOff"))
247 (define %upower-activation
249 (use-modules (guix build utils))
250 (mkdir-p "/var/lib/upower")))
252 (define (upower-dbus-service config)
253 (list (wrapped-dbus-service (upower-configuration-upower config)
255 `(("UPOWER_CONF_FILE_NAME"
256 ,(upower-configuration-file config))))))
258 (define (upower-shepherd-service config)
259 "Return a shepherd service for UPower with CONFIG."
260 (let ((upower (upower-configuration-upower config))
261 (config (upower-configuration-file config)))
262 (list (shepherd-service
263 (documentation "Run the UPower power and battery monitor.")
264 (provision '(upower-daemon))
265 (requirement '(dbus-system udev))
267 (start #~(make-forkexec-constructor
268 (list (string-append #$upower "/libexec/upowerd"))
269 #:environment-variables
270 (list (string-append "UPOWER_CONF_FILE_NAME="
272 (stop #~(make-kill-destructor))))))
274 (define upower-service-type
275 (let ((upower-package (compose list upower-configuration-upower)))
276 (service-type (name 'upower)
278 "Run @command{upowerd}}, a system-wide monitor for power
279 consumption and battery levels, with the given configuration settings. It
280 implements the @code{org.freedesktop.UPower} D-Bus interface, and is notably
283 (list (service-extension dbus-root-service-type
285 (service-extension shepherd-root-service-type
286 upower-shepherd-service)
287 (service-extension activation-service-type
288 (const %upower-activation))
289 (service-extension udev-service-type
292 ;; Make the 'upower' command visible.
293 (service-extension profile-service-type
295 (default-value (upower-configuration)))))
299 ;;; GeoClue D-Bus service.
303 (define-record-type* <geoclue-configuration>
304 geoclue-configuration make-geoclue-configuration
305 geoclue-configuration?
306 (geoclue geoclue-configuration-geoclue
308 (whitelist geoclue-configuration-whitelist)
309 (wifi-geolocation-url geoclue-configuration-wifi-geolocation-url)
310 (submit-data? geoclue-configuration-submit-data?)
311 (wifi-submission-url geoclue-configuration-wifi-submission-url)
312 (submission-nick geoclue-configuration-submission-nick)
313 (applications geoclue-configuration-applications))
315 (define* (geoclue-application name #:key (allowed? #t) system? (users '()))
316 "Configure default GeoClue access permissions for an application. NAME is
317 the Desktop ID of the application, without the .desktop part. If ALLOWED? is
318 true, the application will have access to location information by default.
319 The boolean SYSTEM? value indicates that an application is a system component
320 or not. Finally USERS is a list of UIDs of all users for which this
321 application is allowed location info access. An empty users list means all
325 "allowed=" (bool allowed?)
326 "system=" (bool system?)
327 "users=" (string-join users ";") "\n"))
329 (define %standard-geoclue-applications
330 (list (geoclue-application "gnome-datetime-panel" #:system? #t)
331 (geoclue-application "epiphany" #:system? #f)
332 (geoclue-application "firefox" #:system? #f)))
334 (define* (geoclue-configuration-file config)
335 "Return a geoclue configuration file."
336 (plain-file "geoclue.conf"
340 (string-join (geoclue-configuration-whitelist config)
343 "url=" (geoclue-configuration-wifi-geolocation-url config) "\n"
344 "submit-data=" (bool (geoclue-configuration-submit-data? config))
346 (geoclue-configuration-wifi-submission-url config) "\n"
348 (geoclue-configuration-submission-nick config)
350 (string-join (geoclue-configuration-applications config)
353 (define (geoclue-dbus-service config)
354 (list (wrapped-dbus-service (geoclue-configuration-geoclue config)
356 `(("GEOCLUE_CONFIG_FILE"
357 ,(geoclue-configuration-file config))))))
359 (define %geoclue-accounts
360 (list (user-group (name "geoclue") (system? #t))
365 (comment "GeoClue daemon user")
366 (home-directory "/var/empty")
367 (shell "/run/current-system/profile/sbin/nologin"))))
369 (define geoclue-service-type
370 (service-type (name 'geoclue)
372 (list (service-extension dbus-root-service-type
373 geoclue-dbus-service)
374 (service-extension account-service-type
375 (const %geoclue-accounts))))
376 (description "Run the @command{geoclue} location service.
377 This service provides a D-Bus interface to allow applications to request
378 access to a user's physical location, and optionally to add information to
379 online location databases.")))
381 (define* (geoclue-service #:key (geoclue geoclue)
383 (wifi-geolocation-url
384 ;; Mozilla geolocation service:
385 "https://location.services.mozilla.com/v1/geolocate?key=geoclue")
388 "https://location.services.mozilla.com/v1/submit?key=geoclue")
389 (submission-nick "geoclue")
390 (applications %standard-geoclue-applications))
391 "Return a service that runs the @command{geoclue} location service. This
392 service provides a D-Bus interface to allow applications to request access to
393 a user's physical location, and optionally to add information to online
394 location databases. By default, only the GNOME date-time panel and the Icecat
395 and Epiphany web browsers are able to ask for the user's location, and in the
396 case of Icecat and Epiphany, both will ask the user for permission first. See
397 @uref{https://wiki.freedesktop.org/www/Software/GeoClue/, the geoclue web
398 site} for more information."
399 (service geoclue-service-type
400 (geoclue-configuration
402 (whitelist whitelist)
403 (wifi-geolocation-url wifi-geolocation-url)
404 (submit-data? submit-data?)
405 (wifi-submission-url wifi-submission-url)
406 (submission-nick submission-nick)
407 (applications applications))))
414 (define-record-type* <bluetooth-configuration>
415 bluetooth-configuration make-bluetooth-configuration
416 bluetooth-configuration?
417 (bluez bluetooth-configuration-bluez (default bluez))
420 (name bluetooth-configuration-name (default "BlueZ"))
421 (class bluetooth-configuration-class (default #x000000))
422 (discoverable-timeout
423 bluetooth-configuration-discoverable-timeout (default 180))
424 (always-pairable? bluetooth-configuration-always-pairable? (default #f))
425 (pairable-timeout bluetooth-configuration-pairable-timeout (default 0))
427 ;;; MAYBE: Exclude into separate <device-id> record-type?
428 (device-id bluetooth-configuration-device-id (default #f))
429 (reverse-service-discovery?
430 bluetooth-configuration-reverse-service-discovery (default #t))
431 (name-resolving? bluetooth-configuration-name-resolving? (default #t))
432 (debug-keys? bluetooth-configuration-debug-keys? (default #f))
435 ;;; 'dual, 'bredr, 'le
436 (controller-mode bluetooth-configuration-controller-mode (default 'dual))
439 ;;; 'off, 'single, 'multiple
440 (multi-profile bluetooth-configuration-multi-profile (default 'off))
441 (fast-connectable? bluetooth-configuration-fast-connectable? (default #f))
444 ;;; for LE mode: 'off, 'network/on, 'device
445 ;;; for Dual mode: 'off, 'network/on', 'device, 'limited-network, 'limited-device
446 ;;; Source: https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/src/main.conf#n68
447 (privacy bluetooth-configuration-privacy (default 'off))
450 ;;; 'never, 'confirm, 'always
451 (just-works-repairing
452 bluetooth-configuration-just-works-repairing (default 'never))
453 (temporary-timeout bluetooth-configuration-temporary-timeout (default 30))
454 (refresh-discovery? bluetooth-configuration-refresh-discovery (default #t))
456 ;;; Possible values: #t, #f, (uuid <uuid>)
458 ;;; d4992530-b9ec-469f-ab01-6c481c47da1c (BlueZ Experimental Debug)
459 ;;; 671b10b5-42c0-4696-9227-eb28d1b049d6 (BlueZ Experimental Simultaneous Central and Peripheral)
460 ;;; 15c0a148-c273-11ea-b3de-0242ac130004 (BlueZ Experimental LL privacy)
461 ;;; 330859bc-7506-492d-9370-9a6f0614037f (BlueZ Experimental Bluetooth Quality Report)
462 ;;; a6695ace-ee7f-4fb9-881a-5fac66c629af (BlueZ Experimental Offload Codecs)
463 ;;; Source: https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/src/main.conf#n110
464 (experimental bluetooth-configuration-experimental (default #f))
465 (remote-name-request-retry-delay
466 bluetooth-configuration-remote-name-request-retry-delay (default 300))
469 (page-scan-type bluetooth-configuration-page-scan-type (default #f))
470 (page-scan-interval bluetooth-configuration-page-scan-interval (default #f))
471 (page-scan-window bluetooth-configuration-page-scan-window (default #f))
472 (inquiry-scan-type bluetooth-configuration-inquiry-scan-type (default #f))
473 (inquiry-scan-interval bluetooth-configuration-inquiry-scan-interval (default #f))
474 (inquiry-scan-window bluetooth-configuration-inquiry-scan-window (default #f))
475 (link-supervision-timeout bluetooth-configuration-link-supervision-timeout (default #f))
476 (page-timeout bluetooth-configuration-page-timeout (default #f))
477 (min-sniff-interval bluetooth-configuration-min-sniff-interval (default #f))
478 (max-sniff-interval bluetooth-configuration-max-sniff-interval (default #f))
481 (min-advertisement-interval
482 bluetooth-configuration-min-advertisement-interval (default #f))
483 (max-advertisement-interval
484 bluetooth-configuration-max-advertisement-interval (default #f))
485 (multi-advertisement-rotation-interval
486 bluetooth-configuration-multi-advertisement-rotation-interval (default #f))
487 (scan-interval-auto-connect
488 bluetooth-configuration-scan-interval-auto-connect (default #f))
489 (scan-window-auto-connect
490 bluetooth-configuration-scan-window-auto-connect (default #f))
491 (scan-interval-suspend
492 bluetooth-configuration-scan-interval-suspend (default #f))
494 bluetooth-configuration-scan-window-suspend (default #f))
495 (scan-interval-discovery
496 bluetooth-configuration-scan-interval-discovery (default #f))
497 (scan-window-discovery
498 bluetooth-configuration-scan-window-discovery (default #f))
499 (scan-interval-adv-monitor
500 bluetooth-configuration-scan-interval-adv-monitor (default #f))
501 (scan-window-adv-monitor
502 bluetooth-configuration-scan-window-adv-monitor (default #f))
503 (scan-interval-connect
504 bluetooth-configuration-scan-interval-connect (default #f))
506 bluetooth-configuration-scan-window-connect (default #f))
507 (min-connection-interval
508 bluetooth-configuration-min-connection-interval (default #f))
509 (max-connection-interval
510 bluetooth-configuration-max-connection-interval (default #f))
512 bluetooth-configuration-connection-latency (default #f))
513 (connection-supervision-timeout
514 bluetooth-configuration-connection-supervision-timeout (default #f))
516 bluetooth-configuration-autoconnect-timeout (default #f))
517 (adv-mon-allowlist-scan-duration
518 bluetooth-configuration-adv-mon-allowlist-scan-duration (default 300))
519 (adv-mon-no-filter-scan-duration
520 bluetooth-configuration-adv-mon-no-filter-scan-duration (default 500))
521 (enable-adv-mon-interleave-scan?
522 bluetooth-configuration-enable-adv-mon-interleave-scan (default #t))
525 ;;; Possible values: 'yes, 'no, 'always
526 (cache bluetooth-configuration-cache (default 'always))
528 ;;; Possible values: 7 ... 16, 0 (don't care)
529 (key-size bluetooth-configuration-key-size (default 0))
531 ;;; Possible values: 23 ... 517
532 (exchange-mtu bluetooth-configuration-exchange-mtu (default 517))
534 ;;; Possible values: 1 ... 5
535 (att-channels bluetooth-configuration-att-channels (default 3))
538 ;;; Possible values: 'basic, 'ertm
539 (session-mode bluetooth-configuration-session-mode (default 'basic))
541 ;;; Possible values: 'basic, 'streaming
542 (stream-mode bluetooth-configuration-stream-mode (default 'basic))
545 (reconnect-uuids bluetooth-configuration-reconnect-uuids (default '()))
546 (reconnect-attempts bluetooth-configuration-reconnect-attempts (default 7))
547 (reconnect-intervals bluetooth-configuration-reconnect-intervals
548 (default (list 1 2 4 8 16 32 64)))
549 (auto-enable? bluetooth-configuration-auto-enable? (default #f))
550 (resume-delay bluetooth-configuration-resume-delay (default 2))
555 ;;; "N = 0x00" ... "N = 0xFF"
556 ;;; Source: https://git.kernel.org/pub/scm/bluetooth/bluez.git/tree/src/main.conf#n286
557 (rssi-sampling-period bluetooth-configuration-rssi-sampling-period
560 (define (bluetooth-configuration-file config)
561 "Return a configuration file for the systemd bluetooth service, as a string."
564 "\nName = " (bluetooth-configuration-name config)
565 "\nClass = " (string-append
567 (format #f "~6,'0x" (bluetooth-configuration-class config)))
568 "\nDiscoverableTimeout = " (number->string
569 (bluetooth-configuration-discoverable-timeout
571 "\nAlwaysPairable = " (bool (bluetooth-configuration-always-pairable?
573 "\nPairableTimeout = " (number->string
574 (bluetooth-configuration-pairable-timeout
576 (if (bluetooth-configuration-device-id config)
577 (string-append "\nDeviceID = " (bluetooth-configuration-device-id config))
579 "\nReverseServiceDiscovery = " (bool
580 (bluetooth-configuration-reverse-service-discovery
582 "\nNameResolving = " (bool (bluetooth-configuration-name-resolving? config))
583 "\nDebugKeys = " (bool (bluetooth-configuration-debug-keys? config))
584 "\nControllerMode = " (symbol->string
585 (bluetooth-configuration-controller-mode config))
586 "\nMultiProfile = " (symbol->string (bluetooth-configuration-multi-profile
588 "\nFastConnectable = " (bool (bluetooth-configuration-fast-connectable? config))
589 "\nPrivacy = " (symbol->string (bluetooth-configuration-privacy config))
590 "\nJustWorksRepairing = " (symbol->string
591 (bluetooth-configuration-just-works-repairing config))
592 "\nTemporaryTimeout = " (number->string
593 (bluetooth-configuration-temporary-timeout config))
594 "\nRefreshDiscovery = " (bool (bluetooth-configuration-refresh-discovery config))
595 "\nExperimental = " (let ((experimental (bluetooth-configuration-experimental config)))
596 (cond ((or (eq? experimental #t)
597 (eq? experimental #f)) (bool experimental))
598 ((list? experimental)
599 (string-join (map uuid->string experimental) ","))))
600 "\nRemoteNameRequestRetryDelay = " (number->string
601 (bluetooth-configuration-remote-name-request-retry-delay
604 (if (bluetooth-configuration-page-scan-type config)
607 (number->string (bluetooth-configuration-page-scan-type config)))
609 (if (bluetooth-configuration-page-scan-interval config)
611 "\nPageScanInterval = "
612 (number->string (bluetooth-configuration-page-scan-interval config)))
614 (if (bluetooth-configuration-page-scan-window config)
616 "\nPageScanWindow = "
617 (number->string (bluetooth-configuration-page-scan-window config)))
619 (if (bluetooth-configuration-inquiry-scan-type config)
621 "\nInquiryScanType = "
622 (number->string (bluetooth-configuration-inquiry-scan-type config)))
624 (if (bluetooth-configuration-inquiry-scan-interval config)
626 "\nInquiryScanInterval = "
627 (number->string (bluetooth-configuration-inquiry-scan-interval config)))
629 (if (bluetooth-configuration-inquiry-scan-window config)
631 "\nInquiryScanWindow = "
632 (number->string (bluetooth-configuration-inquiry-scan-window config)))
634 (if (bluetooth-configuration-link-supervision-timeout config)
636 "\nLinkSupervisionTimeout = "
637 (number->string (bluetooth-configuration-link-supervision-timeout config)))
639 (if (bluetooth-configuration-page-timeout config)
642 (number->string (bluetooth-configuration-page-timeout config)))
644 (if (bluetooth-configuration-min-sniff-interval config)
646 "\nMinSniffInterval = "
647 (number->string (bluetooth-configuration-min-sniff-interval config)))
649 (if (bluetooth-configuration-max-sniff-interval config)
651 "\nMaxSniffInterval = "
652 (number->string (bluetooth-configuration-max-sniff-interval config)))
656 (if (bluetooth-configuration-min-advertisement-interval config)
658 "\nMinAdvertisementInterval = "
659 (number->string (bluetooth-configuration-min-advertisement-interval config)))
661 (if (bluetooth-configuration-max-advertisement-interval config)
663 "\nMaxAdvertisementInterval = "
664 (number->string (bluetooth-configuration-max-advertisement-interval config)))
666 (if (bluetooth-configuration-multi-advertisement-rotation-interval config)
668 "\nMultiAdvertisementRotationInterval = "
670 (bluetooth-configuration-multi-advertisement-rotation-interval config)))
672 (if (bluetooth-configuration-scan-interval-auto-connect config)
674 "\nScanIntervalAutoConnect = "
675 (number->string (bluetooth-configuration-scan-interval-auto-connect config)))
677 (if (bluetooth-configuration-scan-window-auto-connect config)
679 "\nScanWindowAutoConnect = "
680 (number->string (bluetooth-configuration-scan-window-auto-connect config)))
682 (if (bluetooth-configuration-scan-interval-suspend config)
684 "\nScanIntervalSuspend = "
685 (number->string (bluetooth-configuration-scan-interval-suspend config)))
687 (if (bluetooth-configuration-scan-window-suspend config)
689 "\nScanWindowSuspend = "
690 (number->string (bluetooth-configuration-scan-window-suspend config)))
692 (if (bluetooth-configuration-scan-interval-discovery config)
694 "\nScanIntervalDiscovery = "
695 (number->string (bluetooth-configuration-scan-interval-discovery config)))
697 (if (bluetooth-configuration-scan-window-discovery config)
699 "\nScanWindowDiscovery = "
700 (number->string (bluetooth-configuration-scan-window-discovery config)))
702 (if (bluetooth-configuration-scan-interval-adv-monitor config)
704 "\nScanIntervalAdvMonitor = "
705 (number->string (bluetooth-configuration-scan-interval-adv-monitor config)))
707 (if (bluetooth-configuration-scan-window-adv-monitor config)
709 "\nScanWindowAdvMonitor = "
710 (number->string (bluetooth-configuration-scan-window-adv-monitor config)))
712 (if (bluetooth-configuration-scan-interval-connect config)
714 "\nScanIntervalConnect = "
715 (number->string (bluetooth-configuration-scan-interval-connect config)))
717 (if (bluetooth-configuration-scan-window-connect config)
719 "\nScanWindowConnect = "
720 (number->string (bluetooth-configuration-scan-window-connect config)))
722 (if (bluetooth-configuration-min-connection-interval config)
724 "\nMinConnectionInterval = "
725 (number->string (bluetooth-configuration-min-connection-interval config)))
727 (if (bluetooth-configuration-max-connection-interval config)
729 "\nMaxConnectionInterval = "
730 (number->string (bluetooth-configuration-max-connection-interval config)))
732 (if (bluetooth-configuration-connection-latency config)
734 "\nConnectionLatency = "
735 (number->string (bluetooth-configuration-connection-latency config)))
737 (if (bluetooth-configuration-connection-supervision-timeout config)
739 "\nConnectionSupervisionTimeout = "
740 (number->string (bluetooth-configuration-connection-supervision-timeout config)))
742 (if (bluetooth-configuration-autoconnect-timeout config)
744 "\nAutoconnecttimeout = "
745 (number->string (bluetooth-configuration-autoconnect-timeout config)))
747 "\nAdvMonAllowlistScanDuration = " (number->string
748 (bluetooth-configuration-adv-mon-allowlist-scan-duration
750 "\nAdvMonNoFilterScanDuration = " (number->string
751 (bluetooth-configuration-adv-mon-no-filter-scan-duration
753 "\nEnableAdvMonInterleaveScan = " (number->string
755 (bluetooth-configuration-enable-adv-mon-interleave-scan
760 "\nCache = " (symbol->string (bluetooth-configuration-cache config))
761 "\nKeySize = " (number->string (bluetooth-configuration-key-size config))
762 "\nExchangeMTU = " (number->string (bluetooth-configuration-exchange-mtu config))
763 "\nChannels = " (number->string (bluetooth-configuration-att-channels config))
766 "\nSessionMode = " (symbol->string (bluetooth-configuration-session-mode config))
767 "\nStreamMode = " (symbol->string (bluetooth-configuration-stream-mode config))
770 (let ((uuids (bluetooth-configuration-reconnect-uuids config)))
771 (if (not (eq? '() uuids))
773 "\nReconnectUUIDs = "
774 (string-join (map uuid->string uuids) ","))
776 "\nReconnectAttempts = " (number->string
777 (bluetooth-configuration-reconnect-attempts config))
778 "\nReconnectIntervals = " (string-join
780 (bluetooth-configuration-reconnect-intervals
783 "\nAutoEnable = " (bool (bluetooth-configuration-auto-enable?
785 "\nResumeDelay = " (number->string (bluetooth-configuration-resume-delay config))
788 "\nRSSISamplingPeriod = " (string-append
791 (bluetooth-configuration-rssi-sampling-period config)))))
793 (define (bluetooth-directory config)
794 (computed-file "etc-bluetooth"
798 (call-with-output-file "main.conf"
800 (display #$(bluetooth-configuration-file config)
803 (define (bluetooth-shepherd-service config)
804 "Return a shepherd service for @command{bluetoothd}."
806 (provision '(bluetooth))
807 (requirement '(dbus-system udev))
808 (documentation "Run the bluetoothd daemon.")
809 (start #~(make-forkexec-constructor
810 (list #$(file-append (bluetooth-configuration-bluez config)
811 "/libexec/bluetooth/bluetoothd"))))
812 (stop #~(make-kill-destructor))))
814 (define bluetooth-service-type
818 (list (service-extension dbus-root-service-type
819 (compose list bluetooth-configuration-bluez))
820 (service-extension udev-service-type
821 (compose list bluetooth-configuration-bluez))
822 (service-extension etc-service-type
825 ,(bluetooth-directory config)))))
826 (service-extension shepherd-root-service-type
827 (compose list bluetooth-shepherd-service))))
828 (default-value (bluetooth-configuration))
829 (description "Run the @command{bluetoothd} daemon, which manages all the
830 Bluetooth devices and provides a number of D-Bus interfaces.")))
832 (define* (bluetooth-service #:key (bluez bluez) (auto-enable? #f))
833 "Return a service that runs the @command{bluetoothd} daemon, which manages
834 all the Bluetooth devices and provides a number of D-Bus interfaces. When
835 AUTO-ENABLE? is true, the bluetooth controller is powered automatically at
838 Users need to be in the @code{lp} group to access the D-Bus service.
840 (service bluetooth-service-type
841 (bluetooth-configuration
843 (auto-enable? auto-enable?))))
847 ;;; Colord D-Bus service.
850 (define %colord-activation
852 (use-modules (guix build utils))
853 (mkdir-p "/var/lib/colord")
854 (let ((user (getpwnam "colord")))
855 (chown "/var/lib/colord"
856 (passwd:uid user) (passwd:gid user)))))
858 (define %colord-accounts
859 (list (user-group (name "colord") (system? #t))
864 (comment "colord daemon user")
865 (home-directory "/var/empty")
866 (shell (file-append shadow "/sbin/nologin")))))
868 (define colord-service-type
869 (service-type (name 'colord)
871 (list (service-extension account-service-type
872 (const %colord-accounts))
873 (service-extension activation-service-type
874 (const %colord-activation))
876 ;; Colord is a D-Bus service that dbus-daemon can
878 (service-extension dbus-root-service-type list)
880 ;; Colord provides "color device" rules for udev.
881 (service-extension udev-service-type list)
883 ;; It provides polkit "actions".
884 (service-extension polkit-service-type list)))
885 (default-value colord)
887 "Run @command{colord}, a system service with a D-Bus
888 interface to manage the color profiles of input and output devices such as
889 screens and scanners.")))
896 (define-record-type* <udisks-configuration>
897 udisks-configuration make-udisks-configuration
898 udisks-configuration?
899 (udisks udisks-configuration-udisks
902 (define %udisks-activation
903 (with-imported-modules '((guix build utils))
905 (use-modules (guix build utils))
907 (let ((run-dir "/var/run/udisks2"))
909 (chmod run-dir #o700)))))
911 (define udisks-service-type
912 (let ((udisks-package (lambda (config)
913 (list (udisks-configuration-udisks config)))))
914 (service-type (name 'udisks)
916 (list (service-extension polkit-service-type
918 (service-extension dbus-root-service-type
920 (service-extension udev-service-type
922 (service-extension activation-service-type
923 (const %udisks-activation))
925 ;; Profile 'udisksctl' & co. in the system profile.
926 (service-extension profile-service-type
928 (description "Run UDisks, a @dfn{disk management} daemon
929 that provides user interfaces with notifications and ways to mount/unmount
930 disks. Programs that talk to UDisks include the @command{udisksctl} command,
931 part of UDisks, and GNOME Disks."))))
933 (define* (udisks-service #:key (udisks udisks))
934 "Return a service for @uref{http://udisks.freedesktop.org/docs/latest/,
935 UDisks}, a @dfn{disk management} daemon that provides user interfaces with
936 notifications and ways to mount/unmount disks. Programs that talk to UDisks
937 include the @command{udisksctl} command, part of UDisks, and GNOME Disks."
938 (service udisks-service-type
939 (udisks-configuration (udisks udisks))))
943 ;;; Elogind login and seat management service.
946 (define-record-type* <elogind-configuration> elogind-configuration
947 make-elogind-configuration
948 elogind-configuration?
949 (elogind elogind-package
951 (kill-user-processes? elogind-kill-user-processes?
953 (kill-only-users elogind-kill-only-users
955 (kill-exclude-users elogind-kill-exclude-users
957 (inhibit-delay-max-seconds elogind-inhibit-delay-max-seconds
959 (handle-power-key elogind-handle-power-key
961 (handle-suspend-key elogind-handle-suspend-key
963 (handle-hibernate-key elogind-handle-hibernate-key
964 ;; (default 'hibernate)
965 ;; XXX Ignore it for now, since we don't
966 ;; yet handle resume-from-hibernation in
969 (handle-lid-switch elogind-handle-lid-switch
971 (handle-lid-switch-docked elogind-handle-lid-switch-docked
973 (handle-lid-switch-external-power elogind-handle-lid-switch-external-power
975 (power-key-ignore-inhibited? elogind-power-key-ignore-inhibited?
977 (suspend-key-ignore-inhibited? elogind-suspend-key-ignore-inhibited?
979 (hibernate-key-ignore-inhibited? elogind-hibernate-key-ignore-inhibited?
981 (lid-switch-ignore-inhibited? elogind-lid-switch-ignore-inhibited?
983 (holdoff-timeout-seconds elogind-holdoff-timeout-seconds
985 (idle-action elogind-idle-action
987 (idle-action-seconds elogind-idle-action-seconds
989 (runtime-directory-size-percent elogind-runtime-directory-size-percent
991 (runtime-directory-size elogind-runtime-directory-size
993 (remove-ipc? elogind-remove-ipc?
996 (suspend-state elogind-suspend-state
997 (default '("mem" "standby" "freeze")))
998 (suspend-mode elogind-suspend-mode
1000 (hibernate-state elogind-hibernate-state
1001 (default '("disk")))
1002 (hibernate-mode elogind-hibernate-mode
1003 (default '("platform" "shutdown")))
1004 (hybrid-sleep-state elogind-hybrid-sleep-state
1005 (default '("disk")))
1006 (hybrid-sleep-mode elogind-hybrid-sleep-mode
1008 '("suspend" "platform" "shutdown"))))
1010 (define (elogind-configuration-file config)
1015 (_ (error "expected #t or #f, instead got:" x))))
1016 (define char-set:user-name
1017 (string->char-set "abcdefghijklmnopqrstuvwxyz0123456789_-"))
1018 (define (valid-list? l pred)
1019 (and-map (lambda (x) (string-every pred x)) l))
1020 (define (user-name-list users)
1021 (unless (valid-list? users char-set:user-name)
1022 (error "invalid user list" users))
1023 (string-join users " "))
1024 (define (enum val allowed)
1025 (unless (memq val allowed)
1026 (error "invalid value" val allowed))
1027 (symbol->string val))
1028 (define (non-negative-integer x)
1029 (unless (exact-integer? x) (error "not an integer" x))
1030 (when (negative? x) (error "negative number not allowed" x))
1032 (define handle-actions
1033 '(ignore poweroff reboot halt kexec suspend hibernate hybrid-sleep lock))
1034 (define (handle-action x)
1035 (enum x handle-actions))
1036 (define (sleep-list tokens)
1037 (unless (valid-list? tokens char-set:user-name)
1038 (error "invalid sleep list" tokens))
1039 (string-join tokens " "))
1040 (define-syntax ini-file-clause
1042 ((_ config (prop (parser getter)))
1043 (string-append prop "=" (parser (getter config)) "\n"))
1045 (string-append str "\n"))))
1046 (define-syntax-rule (ini-file config file clause ...)
1047 (plain-file file (string-append (ini-file-clause config clause) ...)))
1049 config "logind.conf"
1051 ("KillUserProcesses" (yesno elogind-kill-user-processes?))
1052 ("KillOnlyUsers" (user-name-list elogind-kill-only-users))
1053 ("KillExcludeUsers" (user-name-list elogind-kill-exclude-users))
1054 ("InhibitDelayMaxSec" (non-negative-integer elogind-inhibit-delay-max-seconds))
1055 ("HandlePowerKey" (handle-action elogind-handle-power-key))
1056 ("HandleSuspendKey" (handle-action elogind-handle-suspend-key))
1057 ("HandleHibernateKey" (handle-action elogind-handle-hibernate-key))
1058 ("HandleLidSwitch" (handle-action elogind-handle-lid-switch))
1059 ("HandleLidSwitchDocked" (handle-action elogind-handle-lid-switch-docked))
1060 ("HandleLidSwitchExternalPower" (handle-action elogind-handle-lid-switch-external-power))
1061 ("PowerKeyIgnoreInhibited" (yesno elogind-power-key-ignore-inhibited?))
1062 ("SuspendKeyIgnoreInhibited" (yesno elogind-suspend-key-ignore-inhibited?))
1063 ("HibernateKeyIgnoreInhibited" (yesno elogind-hibernate-key-ignore-inhibited?))
1064 ("LidSwitchIgnoreInhibited" (yesno elogind-lid-switch-ignore-inhibited?))
1065 ("HoldoffTimeoutSec" (non-negative-integer elogind-holdoff-timeout-seconds))
1066 ("IdleAction" (handle-action elogind-idle-action))
1067 ("IdleActionSec" (non-negative-integer elogind-idle-action-seconds))
1068 ("RuntimeDirectorySize"
1071 (match (elogind-runtime-directory-size-percent config)
1072 (#f (non-negative-integer (elogind-runtime-directory-size config)))
1073 (percent (string-append (non-negative-integer percent) "%"))))))
1074 ("RemoveIPC" (yesno elogind-remove-ipc?))
1076 ("SuspendState" (sleep-list elogind-suspend-state))
1077 ("SuspendMode" (sleep-list elogind-suspend-mode))
1078 ("HibernateState" (sleep-list elogind-hibernate-state))
1079 ("HibernateMode" (sleep-list elogind-hibernate-mode))
1080 ("HybridSleepState" (sleep-list elogind-hybrid-sleep-state))
1081 ("HybridSleepMode" (sleep-list elogind-hybrid-sleep-mode))))
1083 (define (elogind-dbus-service config)
1084 "Return a @file{org.freedesktop.login1.service} file that tells D-Bus how to
1085 \"start\" elogind. In practice though, our elogind is started when booting by
1086 shepherd. Thus, the @code{Exec} line of this @file{.service} file does not
1087 explain how to start elogind; instead, it spawns a wrapper that waits for the
1088 @code{elogind} shepherd service. This avoids a race condition where both
1089 @command{shepherd} and @command{dbus-daemon} would attempt to start elogind."
1090 ;; For more info on the elogind startup race, see
1091 ;; <https://issues.guix.gnu.org/55444>.
1094 (elogind-package config))
1097 (program-file "elogind-dbus-shepherd-sync"
1098 (with-imported-modules '((gnu services herd))
1100 (use-modules (gnu services herd)
1103 (guard (c ((service-not-found-error? c)
1104 (format (current-error-port)
1105 "no elogind shepherd service~%")
1107 ((shepherd-error? c)
1108 (format (current-error-port)
1109 "elogind shepherd service not \
1112 (wait-for-service 'elogind))))))
1115 (with-imported-modules '((guix build utils))
1117 (use-modules (guix build utils)
1120 (define service-directory
1121 "/share/dbus-1/system-services")
1123 (mkdir-p (dirname (string-append #$output service-directory)))
1124 (copy-recursively (string-append #$elogind service-directory)
1125 (string-append #$output service-directory))
1126 (symlink (string-append #$elogind "/etc") ;for etc/dbus-1
1127 (string-append #$output "/etc"))
1129 ;; Replace the "Exec=" line of the 'org.freedesktop.login1.service'
1130 ;; file with one that refers to WRAPPER instead of elogind.
1131 (match (find-files #$output "\\.service$")
1134 (("Exec[[:blank:]]*=.*" _)
1135 (string-append "Exec=" #$wrapper "\n"))))))))
1137 (list (computed-file "elogind-dbus-service-wrapper" build)))
1139 (define (pam-extension-procedure config)
1140 "Return an extension for PAM-ROOT-SERVICE-TYPE that ensures that all the PAM
1141 services use 'pam_elogind.so', a module that allows elogind to keep track of
1142 logged-in users (run 'loginctl' to see elogind's world view of users and
1146 (control "required")
1147 (module (file-append (elogind-package config)
1148 "/lib/security/pam_elogind.so"))))
1153 (session (cons pam-elogind (pam-service-session pam)))))))
1155 (define (elogind-shepherd-service config)
1156 "Return a Shepherd service to start elogind according to @var{config}."
1157 (list (shepherd-service
1158 (requirement '(dbus-system))
1159 (provision '(elogind))
1160 (start #~(make-forkexec-constructor
1161 (list #$(file-append (elogind-package config)
1162 "/libexec/elogind/elogind"))
1163 #:environment-variables
1164 (list (string-append "ELOGIND_CONF_FILE="
1165 #$(elogind-configuration-file
1167 (stop #~(make-kill-destructor)))))
1169 (define elogind-service-type
1170 (service-type (name 'elogind)
1172 (list (service-extension dbus-root-service-type
1173 elogind-dbus-service)
1174 (service-extension udev-service-type
1175 (compose list elogind-package))
1176 (service-extension polkit-service-type
1177 (compose list elogind-package))
1179 ;; Start elogind from the Shepherd rather than waiting
1180 ;; for bus activation. This ensures that it can handle
1181 ;; events like lid close, etc.
1182 (service-extension shepherd-root-service-type
1183 elogind-shepherd-service)
1185 ;; Provide the 'loginctl' command.
1186 (service-extension profile-service-type
1187 (compose list elogind-package))
1189 ;; Extend PAM with pam_elogind.so.
1190 (service-extension pam-root-service-type
1191 pam-extension-procedure)
1193 ;; We need /run/user, /run/systemd, etc.
1194 (service-extension file-system-service-type
1195 (const %elogind-file-systems))))
1196 (default-value (elogind-configuration))
1197 (description "Run the @command{elogind} login and seat
1198 management service. The @command{elogind} service integrates with PAM to
1199 allow other system components to know the set of logged-in users as well as
1200 their session types (graphical, console, remote, etc.). It can also clean up
1201 after users when they log out.")))
1203 (define* (elogind-service #:key (config (elogind-configuration)))
1204 "Return a service that runs the @command{elogind} login and seat management
1205 service. The @command{elogind} service integrates with PAM to allow other
1206 system components to know the set of logged-in users as well as their session
1207 types (graphical, console, remote, etc.). It can also clean up after users
1209 (service elogind-service-type config))
1213 ;;; Fontconfig and other desktop file-systems.
1216 (define %fontconfig-file-system
1219 (mount-point "/var/cache/fontconfig")
1221 (flags '(read-only))
1224 ;; The global fontconfig cache directory can sometimes contain stale entries,
1225 ;; possibly referencing fonts that have been GC'd, so mount it read-only.
1226 ;; As mentioned https://debbugs.gnu.org/cgi/bugreport.cgi?bug=36924#8 and
1227 ;; https://debbugs.gnu.org/cgi/bugreport.cgi?bug=38046#10 and elsewhere.
1228 (define fontconfig-file-system-service
1229 (simple-service 'fontconfig-file-system
1230 file-system-service-type
1231 (list %fontconfig-file-system)))
1234 ;;; AccountsService service.
1237 (define %accountsservice-activation
1239 (use-modules (guix build utils))
1240 (mkdir-p "/var/lib/AccountsService")))
1242 (define accountsservice-service-type
1243 (service-type (name 'accountsservice)
1245 (list (service-extension activation-service-type
1246 (const %accountsservice-activation))
1247 (service-extension dbus-root-service-type list)
1248 (service-extension polkit-service-type list)))
1249 (default-value accountsservice)
1250 (description "Run AccountsService, a system service available
1251 over D-Bus that can list available accounts, change their passwords, and so
1252 on. AccountsService integrates with PolicyKit to enable unprivileged users to
1253 acquire the capability to modify their system configuration.")))
1255 (define* (accountsservice-service #:key (accountsservice accountsservice))
1256 "Return a service that runs AccountsService, a system service that
1257 can list available accounts, change their passwords, and so on.
1258 AccountsService integrates with PolicyKit to enable unprivileged users to
1259 acquire the capability to modify their system configuration.
1260 @uref{https://www.freedesktop.org/wiki/Software/AccountsService/, the
1261 accountsservice web site} for more information."
1262 (service accountsservice-service-type accountsservice))
1266 ;;; cups-pk-helper service.
1269 (define cups-pk-helper-service-type
1271 (name 'cups-pk-helper)
1273 "PolicyKit helper to configure CUPS with fine-grained privileges.")
1275 (list (service-extension dbus-root-service-type list)
1276 (service-extension polkit-service-type list)))
1277 (default-value cups-pk-helper)))
1281 ;;; Scanner access via SANE.
1284 (define %sane-accounts
1285 ;; The '60-libsane.rules' udev rules refers to the "scanner" group.
1286 (list (user-group (name "scanner") (system? #t))))
1288 (define sane-service-type
1292 "This service provides access to scanners @i{via}
1293 @uref{http://www.sane-project.org, SANE} by installing the necessary udev
1295 (default-value sane-backends-minimal)
1297 (list (service-extension udev-service-type list)
1298 (service-extension account-service-type
1299 (const %sane-accounts))))))
1304 ;;; GNOME desktop service.
1307 (define-record-type* <gnome-desktop-configuration> gnome-desktop-configuration
1308 make-gnome-desktop-configuration
1309 gnome-desktop-configuration?
1310 (gnome gnome-package (default gnome)))
1312 (define (gnome-packages config packages)
1313 "Return the list of GNOME dependencies from CONFIG which names are part of
1314 the given PACKAGES list."
1315 (let ((gnome (gnome-package config)))
1317 ((package-direct-input-selector name) gnome))
1320 (define (gnome-udev-rules config)
1321 "Return the list of GNOME dependencies that provide udev rules."
1322 (gnome-packages config '("gnome-settings-daemon")))
1324 (define (gnome-polkit-settings config)
1325 "Return the list of GNOME dependencies that provide polkit actions and
1327 (gnome-packages config
1328 '("gnome-settings-daemon"
1329 "gnome-control-center"
1330 "gnome-system-monitor"
1333 (define gnome-desktop-service-type
1335 (name 'gnome-desktop)
1337 (list (service-extension udev-service-type
1339 (service-extension polkit-service-type
1340 gnome-polkit-settings)
1341 (service-extension profile-service-type
1344 (default-value (gnome-desktop-configuration))
1345 (description "Run the GNOME desktop environment.")))
1347 (define-deprecated (gnome-desktop-service #:key (config
1348 (gnome-desktop-configuration)))
1349 gnome-desktop-service-type
1350 "Return a service that adds the @code{gnome} package to the system profile,
1351 and extends polkit with the actions from @code{gnome-settings-daemon}."
1352 (service gnome-desktop-service-type config))
1354 ;; MATE Desktop service.
1355 ;; TODO: Add mate-screensaver.
1357 (define-record-type* <mate-desktop-configuration> mate-desktop-configuration
1358 make-mate-desktop-configuration
1359 mate-desktop-configuration?
1360 (mate-package mate-package (default mate)))
1362 (define (mate-polkit-extension config)
1363 "Return the list of packages for CONFIG's MATE package that extend polkit."
1364 (let ((mate (mate-package config)))
1365 (map (lambda (input)
1366 ((package-direct-input-selector input) mate))
1367 '("mate-system-monitor" ;kill, renice processes
1368 "mate-settings-daemon" ;date/time settings
1369 "mate-power-manager" ;modify brightness
1370 "mate-control-center" ;RandR, display properties FIXME
1371 "mate-applets")))) ;CPU frequency scaling
1373 (define mate-desktop-service-type
1375 (name 'mate-desktop)
1377 (list (service-extension polkit-service-type
1378 mate-polkit-extension)
1379 (service-extension profile-service-type
1382 (default-value (mate-desktop-configuration))
1383 (description "Run the MATE desktop environment.")))
1385 (define-deprecated (mate-desktop-service #:key
1387 (mate-desktop-configuration)))
1388 mate-desktop-service-type
1389 "Return a service that adds the @code{mate} package to the system profile,
1390 and extends polkit with the actions from @code{mate-settings-daemon}."
1391 (service mate-desktop-service-type config))
1395 ;;; XFCE desktop service.
1398 (define-record-type* <xfce-desktop-configuration> xfce-desktop-configuration
1399 make-xfce-desktop-configuration
1400 xfce-desktop-configuration?
1401 (xfce xfce-package (default xfce)))
1403 (define (xfce-polkit-settings config)
1404 "Return the list of XFCE dependencies that provide polkit actions and
1406 (let ((xfce (xfce-package config)))
1408 ((package-direct-input-selector name) xfce))
1410 "xfce4-power-manager"))))
1412 (define xfce-desktop-service-type
1414 (name 'xfce-desktop)
1416 (list (service-extension polkit-service-type
1417 xfce-polkit-settings)
1418 (service-extension profile-service-type
1419 (compose list xfce-package))))
1420 (default-value (xfce-desktop-configuration))
1421 (description "Run the Xfce desktop environment.")))
1423 (define-deprecated (xfce-desktop-service #:key (config
1424 (xfce-desktop-configuration)))
1425 xfce-desktop-service-type
1426 "Return a service that adds the @code{xfce} package to the system profile,
1427 and extends polkit with the ability for @code{thunar} to manipulate the file
1428 system as root from within a user session, after the user has authenticated
1429 with the administrator's password."
1430 (service xfce-desktop-service-type config))
1434 ;;; Lxqt desktop service.
1437 (define-record-type* <lxqt-desktop-configuration> lxqt-desktop-configuration
1438 make-lxqt-desktop-configuration
1439 lxqt-desktop-configuration?
1443 (define (lxqt-polkit-settings config)
1444 "Return the list of LXQt dependencies that provide polkit actions and
1446 (let ((lxqt (lxqt-package config)))
1448 ((package-direct-input-selector name) lxqt))
1451 (define lxqt-desktop-service-type
1453 (name 'lxqt-desktop)
1455 (list (service-extension polkit-service-type
1456 lxqt-polkit-settings)
1457 (service-extension profile-service-type
1458 (compose list lxqt-package))))
1459 (default-value (lxqt-desktop-configuration))
1460 (description "Run LXQt desktop environment.")))
1464 ;;; X11 socket directory service
1467 (define x11-socket-directory-service
1468 ;; Return a service that creates /tmp/.X11-unix. When using X11, libxcb
1469 ;; takes care of creating that directory. However, when using XWayland, we
1470 ;; need to create beforehand. Thus, create it unconditionally here.
1471 (simple-service 'x11-socket-directory
1472 activation-service-type
1473 (with-imported-modules '((guix build utils))
1475 (use-modules (guix build utils))
1476 (let ((directory "/tmp/.X11-unix"))
1478 (chmod directory #o1777))))))
1481 ;;; Enlightenment desktop service.
1484 (define-record-type* <enlightenment-desktop-configuration>
1485 enlightenment-desktop-configuration make-enlightenment-desktop-configuration
1486 enlightenment-desktop-configuration?
1488 (enlightenment enlightenment-package
1489 (default enlightenment)))
1491 (define (enlightenment-setuid-programs enlightenment-desktop-configuration)
1492 (match-record enlightenment-desktop-configuration
1493 <enlightenment-desktop-configuration>
1495 (map file-like->setuid-program
1496 (list (file-append enlightenment
1497 "/lib/enlightenment/utils/enlightenment_sys")
1498 (file-append enlightenment
1499 "/lib/enlightenment/utils/enlightenment_system")
1500 (file-append enlightenment
1501 "/lib/enlightenment/utils/enlightenment_ckpasswd")))))
1503 (define enlightenment-desktop-service-type
1505 (name 'enlightenment-desktop)
1507 (list (service-extension dbus-root-service-type
1509 (package-direct-input-selector
1511 enlightenment-package))
1512 (service-extension setuid-program-service-type
1513 enlightenment-setuid-programs)
1514 (service-extension profile-service-type
1516 enlightenment-package))))
1517 (default-value (enlightenment-desktop-configuration))
1519 "Return a service that adds the @code{enlightenment} package to the system
1520 profile, and extends dbus with the ability for @code{efl} to generate
1521 thumbnails and makes setuid the programs which enlightenment needs to function
1526 ;;; inputattach-service-type
1529 (define-record-type* <inputattach-configuration>
1530 inputattach-configuration
1531 make-inputattach-configuration
1532 inputattach-configuration?
1533 (device-type inputattach-configuration-device-type
1535 (device inputattach-configuration-device
1536 (default "/dev/ttyS0"))
1537 (baud-rate inputattach-configuration-baud-rate
1539 (log-file inputattach-configuration-log-file
1542 (define inputattach-shepherd-service
1544 (($ <inputattach-configuration> type device baud-rate log-file)
1545 (let ((args (append (if baud-rate
1546 (list "--baud" (number->string baud-rate))
1548 (list (string-append "--" type)
1550 (list (shepherd-service
1551 (provision '(inputattach))
1552 (requirement '(udev))
1553 (documentation "inputattach daemon")
1554 (start #~(make-forkexec-constructor
1555 (cons (string-append #$inputattach
1558 #:log-file #$log-file))
1559 (stop #~(make-kill-destructor))))))))
1561 (define inputattach-service-type
1565 (list (service-extension shepherd-root-service-type
1566 inputattach-shepherd-service)))
1567 (default-value (inputattach-configuration))
1568 (description "Return a service that runs inputattach on a device and
1569 dispatches events from it.")))
1573 ;;; gnome-keyring-service-type
1576 (define-record-type* <gnome-keyring-configuration> gnome-keyring-configuration
1577 make-gnome-keyring-configuration
1578 gnome-keyring-configuration?
1579 (keyring gnome-keyring-package (default gnome-keyring))
1580 (pam-services gnome-keyring-pam-services (default '(("gdm-password" . login)
1581 ("passwd" . passwd)))))
1583 (define (pam-gnome-keyring config)
1584 (define (%pam-keyring-entry . arguments)
1586 (control "optional")
1587 (module (file-append (gnome-keyring-package config)
1588 "/lib/security/pam_gnome_keyring.so"))
1589 (arguments arguments)))
1593 (case (assoc-ref (gnome-keyring-pam-services config)
1594 (pam-service-name service))
1598 (auth (append (pam-service-auth service)
1599 (list (%pam-keyring-entry))))
1600 (session (append (pam-service-session service)
1601 (list (%pam-keyring-entry "auto_start"))))))
1605 (password (append (pam-service-password service)
1606 (list (%pam-keyring-entry))))))
1609 (define gnome-keyring-service-type
1611 (name 'gnome-keyring)
1613 (service-extension pam-root-service-type pam-gnome-keyring)))
1614 (default-value (gnome-keyring-configuration))
1615 (description "Return a service, that adds the @code{gnome-keyring} package
1616 to the system profile and extends PAM with entries using
1617 @code{pam_gnome_keyring.so}, unlocking a user's login keyring when they log in
1618 or setting its password with passwd.")))
1622 ;;; polkit-wheel-service -- Allow wheel group to perform admin actions
1625 (define polkit-wheel
1628 `(("share/polkit-1/rules.d/wheel.rules"
1631 "polkit.addAdminRule(function(action, subject) {
1632 return [\"unix-group:wheel\"];
1636 (define polkit-wheel-service
1637 (simple-service 'polkit-wheel polkit-service-type (list polkit-wheel)))
1641 ;;; seatd-service-type -- minimal seat management daemon
1644 (define-record-type* <seatd-configuration> seatd-configuration
1645 make-seatd-configuration
1646 seatd-configuration?
1647 (seatd seatd-package (default seatd))
1648 (user seatd-user (default "root"))
1649 (group seatd-group (default "users"))
1650 (socket seatd-socket (default "/run/seatd.sock"))
1651 (logfile seatd-logfile (default "/var/log/seatd.log"))
1652 (loglevel seatd-loglevel (default "info")))
1654 (define (seatd-shepherd-service config)
1655 (list (shepherd-service
1656 (documentation "Minimal seat management daemon")
1658 ;; TODO: once cgroups is separate dependency
1659 ;; here we should depend on it rather than elogind
1660 (provision '(seatd elogind))
1661 (start #~(make-forkexec-constructor
1662 (list #$(file-append (seatd-package config) "/bin/seatd")
1663 "-u" #$(seatd-user config)
1664 "-g" #$(seatd-group config))
1665 #:environment-variables
1666 (list (string-append "SEATD_LOGLEVEL="
1667 #$(seatd-loglevel config))
1668 (string-append "SEATD_DEFAULTPATH="
1669 #$(seatd-socket config)))
1670 #:log-file #$(seatd-logfile config)))
1671 (stop #~(make-kill-destructor)))))
1673 (define seatd-environment
1675 (($ <seatd-configuration> _ _ _ socket)
1676 `(("SEATD_SOCK" . ,socket)))))
1678 (define seatd-service-type
1681 (description "Seat management takes care of mediating access
1682 to shared devices (graphics, input), without requiring the
1683 applications needing access to be root.")
1686 (service-extension session-environment-service-type seatd-environment)
1687 ;; TODO: once cgroups is separate dependency we should not mount it here
1688 ;; for now it is mounted here, because elogind mounts it
1689 (service-extension file-system-service-type (const %control-groups))
1690 (service-extension shepherd-root-service-type seatd-shepherd-service)))
1691 (default-value (seatd-configuration))))
1695 ;;; The default set of desktop services.
1698 (define* (desktop-services-for-system #:optional
1699 (system (or (%current-target-system)
1700 (%current-system))))
1701 ;; List of services typically useful for a "desktop" use case.
1703 ;; Since GDM depends on Rust (gdm -> gnome-shell -> gjs -> mozjs -> rust)
1704 ;; and Rust is currently unavailable on non-x86_64 platforms, default to
1705 ;; SDDM there (FIXME).
1706 (cons* (if (string-prefix? "x86_64" system)
1707 (service gdm-service-type)
1708 (service sddm-service-type))
1710 ;; Screen lockers are a pretty useful thing and these are small.
1711 (screen-locker-service slock)
1712 (screen-locker-service xlockmore "xlock")
1714 ;; Add udev rules for MTP devices so that non-root users can access
1716 (simple-service 'mtp udev-service-type (list libmtp))
1717 ;; Add udev rules for scanners.
1718 (service sane-service-type)
1719 ;; Add polkit rules, so that non-root users in the wheel group can
1720 ;; perform administrative tasks (similar to "sudo").
1721 polkit-wheel-service
1723 ;; Allow desktop users to also mount NTFS and NFS file systems
1725 (simple-service 'mount-setuid-helpers setuid-program-service-type
1726 (map (lambda (program)
1729 (list (file-append nfs-utils "/sbin/mount.nfs")
1730 (file-append ntfs-3g "/sbin/mount.ntfs-3g"))))
1732 ;; The global fontconfig cache directory can sometimes contain
1733 ;; stale entries, possibly referencing fonts that have been GC'd,
1734 ;; so mount it read-only.
1735 fontconfig-file-system-service
1737 ;; NetworkManager and its applet.
1738 (service network-manager-service-type)
1739 (service wpa-supplicant-service-type) ;needed by NetworkManager
1740 (simple-service 'network-manager-applet
1741 profile-service-type
1742 (list network-manager-applet))
1743 (service modem-manager-service-type)
1744 (service usb-modeswitch-service-type)
1746 ;; The D-Bus clique.
1747 (service avahi-service-type)
1749 (service upower-service-type)
1750 (accountsservice-service)
1751 (service cups-pk-helper-service-type)
1752 (service colord-service-type)
1754 (service polkit-service-type)
1758 (service ntp-service-type)
1760 x11-socket-directory-service
1762 (service pulseaudio-service-type)
1763 (service alsa-service-type)
1767 (define-syntax %desktop-services
1768 (identifier-syntax (desktop-services-for-system)))
1770 ;;; desktop.scm ends here