;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2017 Andy Wingo <wingo@igalia.com>
-;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2019 Ludovic Courtès <ludo@gnu.org>
+;;; Copyright © 2013, 2014, 2015, 2016, 2017, 2019, 2020 Ludovic Courtès <ludo@gnu.org>
;;; Copyright © 2015 Sou Bunnbu <iyzsong@gmail.com>
;;; Copyright © 2018, 2019 Timothy Sample <samplet@ngyro.com>
+;;; Copyright © 2019 Jan (janneke) Nieuwenhuizen <janneke@gnu.org>
+;;; Copyright © 2019 Tim Gesthuizen <tim.gesthuizen@yahoo.de>
+;;; Copyright © 2020 shtwzrd <shtwzrd@protonmail.com>
+;;; Copyright © 2020 Jakub Kądziołka <kuba@kadziolka.net>
+;;; Copyright © 2020 Alex Griffin <a@ajgrf.com>
;;;
;;; This file is part of GNU Guix.
;;;
#:use-module (gnu services)
#:use-module (gnu services shepherd)
#:use-module (gnu system pam)
+ #:use-module (gnu system keyboard)
+ #:use-module (gnu services base)
#:use-module (gnu services dbus)
- #:use-module ((gnu packages base) #:select (canonical-package))
+ #:use-module (gnu packages base)
#:use-module (gnu packages guile)
#:use-module (gnu packages xorg)
#:use-module (gnu packages fonts)
#:use-module (gnu packages gl)
#:use-module (gnu packages glib)
#:use-module (gnu packages display-managers)
+ #:use-module (gnu packages freedesktop)
#:use-module (gnu packages gnustep)
#:use-module (gnu packages gnome)
#:use-module (gnu packages admin)
#:use-module (srfi srfi-9)
#:use-module (srfi srfi-26)
#:use-module (ice-9 match)
- #:export (xorg-configuration-file
+ #:export (xorg-configuration
+ xorg-configuration?
+ xorg-configuration-modules
+ xorg-configuration-fonts
+ xorg-configuration-drivers
+ xorg-configuration-resolutions
+ xorg-configuration-extra-config
+ xorg-configuration-server
+ xorg-configuration-server-arguments
+
%default-xorg-modules
%default-xorg-fonts
xorg-wrapper
slim-configuration-xauth
slim-configuration-shepherd
slim-configuration-auto-login-session
- slim-configuration-startx
+ slim-configuration-xorg
+ slim-configuration-display
+ slim-configuration-vt
+ slim-configuration-sessreg
slim-service-type
slim-service
screen-locker-service-type
screen-locker-service
+ localed-configuration
+ localed-configuration?
+ localed-service-type
+
gdm-configuration
gdm-service-type
- gdm-service))
+ gdm-service
+
+ handle-xorg-configuration
+ set-xorg-configuration))
;;; Commentary:
;;;
"/share/fonts/X11/misc")
(file-append font-adobe75dpi "/share/fonts/X11/75dpi")))
-(define* (xorg-configuration-file #:key
- (modules %default-xorg-modules)
- (fonts %default-xorg-fonts)
- (drivers '()) (resolutions '())
- (extra-config '()))
- "Return a configuration file for the Xorg server containing search paths for
-all the common drivers.
-
-@var{modules} must be a list of @dfn{module packages} loaded by the Xorg
-server---e.g., @code{xf86-video-vesa}, @code{xf86-input-keyboard}, and so on.
-@var{fonts} must be a list of font directories to add to the server's
-@dfn{font path}.
-
-@var{drivers} must be either the empty list, in which case Xorg chooses a
-graphics driver automatically, or a list of driver names that will be tried in
-this order---e.g., @code{(\"modesetting\" \"vesa\")}.
-
-Likewise, when @var{resolutions} is the empty list, Xorg chooses an
-appropriate screen resolution; otherwise, it must be a list of
-resolutions---e.g., @code{((1024 768) (640 480))}.
-
-Last, @var{extra-config} is a list of strings or objects appended to the
-configuration file. It is used to pass extra text to be
-added verbatim to the configuration file."
- (define all-modules
- ;; 'xorg-server' provides 'fbdevhw.so' etc.
- (append modules (list xorg-server)))
-
- (define build
- #~(begin
- (use-modules (ice-9 match)
- (srfi srfi-1)
- (srfi srfi-26))
-
- (call-with-output-file #$output
- (lambda (port)
- (define drivers
- '#$drivers)
+(define %default-xorg-server-arguments
+ ;; Default command-line arguments for X.
+ '("-nolisten" "tcp"))
+
+;; Configuration of an Xorg server.
+(define-record-type* <xorg-configuration>
+ xorg-configuration make-xorg-configuration
+ xorg-configuration?
+ (modules xorg-configuration-modules ;list of packages
+ ; filter out modules not supported on current system
+ (default (filter
+ (lambda (p)
+ (member (%current-system)
+ (package-supported-systems p)))
+ %default-xorg-modules)))
+ (fonts xorg-configuration-fonts ;list of packges
+ (default %default-xorg-fonts))
+ (drivers xorg-configuration-drivers ;list of strings
+ (default '()))
+ (resolutions xorg-configuration-resolutions ;list of tuples
+ (default '()))
+ (keyboard-layout xorg-configuration-keyboard-layout ;#f | <keyboard-layout>
+ (default #f))
+ (extra-config xorg-configuration-extra-config ;list of strings
+ (default '()))
+ (server xorg-configuration-server ;package
+ (default xorg-server))
+ (server-arguments xorg-configuration-server-arguments ;list of strings
+ (default %default-xorg-server-arguments)))
+
+(define (xorg-configuration->file config)
+ "Compute an Xorg configuration file corresponding to CONFIG, an
+<xorg-configuration> record."
+ (let ((xorg-server (xorg-configuration-server config)))
+ (define all-modules
+ ;; 'xorg-server' provides 'fbdevhw.so' etc.
+ (append (xorg-configuration-modules config)
+ (list xorg-server)))
+
+ (define build
+ #~(begin
+ (use-modules (ice-9 match)
+ (srfi srfi-1)
+ (srfi srfi-26))
+
+ (call-with-output-file #$output
+ (lambda (port)
+ (define drivers
+ '#$(xorg-configuration-drivers config))
- (define (device-section driver)
- (string-append "
+ (define (device-section driver)
+ (string-append "
Section \"Device\"
Identifier \"device-" driver "\"
Driver \"" driver "\"
EndSection"))
- (define (screen-section driver resolutions)
- (string-append "
+ (define (screen-section driver resolutions)
+ (string-append "
Section \"Screen\"
Identifier \"screen-" driver "\"
Device \"device-" driver "\"
EndSubSection
EndSection"))
- (define (expand modules)
- ;; Append to MODULES the relevant /lib/xorg/modules
- ;; sub-directories.
- (append-map (lambda (module)
- (filter-map (lambda (directory)
- (let ((full (string-append module
- directory)))
- (and (file-exists? full)
- full)))
- '("/lib/xorg/modules/drivers"
- "/lib/xorg/modules/input"
- "/lib/xorg/modules/multimedia"
- "/lib/xorg/modules/extensions")))
- modules))
-
- (display "Section \"Files\"\n" port)
- (for-each (lambda (font)
- (format port " FontPath \"~a\"~%" font))
- '#$fonts)
- (for-each (lambda (module)
- (format port
- " ModulePath \"~a\"~%"
- module))
- (append (expand '#$all-modules)
-
- ;; For fbdevhw.so and so on.
- (list #$(file-append xorg-server
- "/lib/xorg/modules"))))
- (display "EndSection\n" port)
- (display "
+ (define (input-class-section layout variant model options)
+ (string-append "
+Section \"InputClass\"
+ Identifier \"evdev keyboard catchall\"
+ MatchIsKeyboard \"on\"
+ Option \"XkbLayout\" " (object->string layout)
+ (if variant
+ (string-append " Option \"XkbVariant\" \""
+ variant "\"")
+ "")
+ (if model
+ (string-append " Option \"XkbModel\" \""
+ model "\"")
+ "")
+ (match options
+ (()
+ "")
+ (_
+ (string-append " Option \"XkbOptions\" \""
+ (string-join options ",") "\""))) "
+
+ MatchDevicePath \"/dev/input/event*\"
+ Driver \"evdev\"
+EndSection\n"))
+
+ (define (expand modules)
+ ;; Append to MODULES the relevant /lib/xorg/modules
+ ;; sub-directories.
+ (append-map (lambda (module)
+ (filter-map (lambda (directory)
+ (let ((full (string-append module
+ directory)))
+ (and (file-exists? full)
+ full)))
+ '("/lib/xorg/modules/drivers"
+ "/lib/xorg/modules/input"
+ "/lib/xorg/modules/multimedia"
+ "/lib/xorg/modules/extensions")))
+ modules))
+
+ (display "Section \"Files\"\n" port)
+ (for-each (lambda (font)
+ (format port " FontPath \"~a\"~%" font))
+ '#$(xorg-configuration-fonts config))
+ (for-each (lambda (module)
+ (format port
+ " ModulePath \"~a\"~%"
+ module))
+ (append (expand '#$all-modules)
+
+ ;; For fbdevhw.so and so on.
+ (list #$(file-append xorg-server
+ "/lib/xorg/modules"))))
+ (display "EndSection\n" port)
+ (display "
Section \"ServerFlags\"
Option \"AllowMouseOpenFail\" \"on\"
EndSection\n" port)
- (display (string-join (map device-section drivers) "\n")
- port)
- (newline port)
- (display (string-join
- (map (cut screen-section <> '#$resolutions)
- drivers)
- "\n")
- port)
- (newline port)
-
- (for-each (lambda (config)
- (display config port))
- '#$extra-config)))))
-
- (computed-file "xserver.conf" build))
-
+ (display (string-join (map device-section drivers) "\n")
+ port)
+ (newline port)
+ (display (string-join
+ (map (cut screen-section <>
+ '#$(xorg-configuration-resolutions config))
+ drivers)
+ "\n")
+ port)
+ (newline port)
+
+ (let ((layout #$(and=> (xorg-configuration-keyboard-layout config)
+ keyboard-layout-name))
+ (variant #$(and=> (xorg-configuration-keyboard-layout config)
+ keyboard-layout-variant))
+ (model #$(and=> (xorg-configuration-keyboard-layout config)
+ keyboard-layout-model))
+ (options '#$(and=> (xorg-configuration-keyboard-layout config)
+ keyboard-layout-options)))
+ (when layout
+ (display (input-class-section layout variant model options)
+ port)
+ (newline port)))
+
+ (for-each (lambda (config)
+ (display config port))
+ '#$(xorg-configuration-extra-config config))))))
+
+ (computed-file "xserver.conf" build)))
(define (xorg-configuration-directory modules)
"Return a directory that contains the @code{.conf} files for X.org that
files)
#t))))
-(define* (xorg-wrapper #:key
- (guile (canonical-package guile-2.0))
- (modules %default-xorg-modules)
- (configuration-file (xorg-configuration-file
- #:modules modules))
- (xorg-server xorg-server))
- "Return a derivation that builds a @var{guile} script to start the X server
-from @var{xorg-server}. @var{configuration-file} is the server configuration
-file or a derivation that builds it; when omitted, the result of
-@code{xorg-configuration-file} is used. The resulting script should be used
-in place of @code{/usr/bin/X}."
+(define* (xorg-wrapper #:optional (config (xorg-configuration)))
+ "Return a derivation that builds a script to start the X server with the
+given @var{config}. The resulting script should be used in place of
+@code{/usr/bin/X}."
(define exp
;; Write a small wrapper around the X server.
#~(begin
(setenv "XORG_DRI_DRIVER_PATH" (string-append #$mesa "/lib/dri"))
(setenv "XKB_BINDIR" (string-append #$xkbcomp "/bin"))
- (let ((X (string-append #$xorg-server "/bin/X")))
+ (let ((X (string-append #$(xorg-configuration-server config) "/bin/X")))
(apply execl X X
"-xkbdir" (string-append #$xkeyboard-config "/share/X11/xkb")
- "-config" #$configuration-file
- "-configdir" #$(xorg-configuration-directory modules)
+ "-config" #$(xorg-configuration->file config)
+ "-configdir" #$(xorg-configuration-directory
+ (xorg-configuration-modules config))
(cdr (command-line))))))
(program-file "X-wrapper" exp))
-(define* (xorg-start-command #:key
- (guile (canonical-package guile-2.0))
- (modules %default-xorg-modules)
- (fonts %default-xorg-fonts)
- (configuration-file
- (xorg-configuration-file #:modules modules
- #:fonts fonts))
- (xorg-server xorg-server))
- "Return a @code{startx} script in which @var{modules}, a list of X module
-packages, and @var{fonts}, a list of X font directories, are available. See
-@code{xorg-wrapper} for more details on the arguments. The result should be
-used in place of @code{startx}."
+(define* (xorg-start-command #:optional (config (xorg-configuration)))
+ "Return a @code{startx} script in which the modules, fonts, etc. specified
+in @var{config}, are available. The result should be used in place of
+@code{startx}."
(define X
- (xorg-wrapper #:guile guile
- #:configuration-file configuration-file
- #:modules modules
- #:xorg-server xorg-server))
+ (xorg-wrapper config))
+
(define exp
;; Write a small wrapper around the X server.
#~(apply execl #$X #$X ;; Second #$X is for argv[0].
- "-logverbose" "-verbose" "-nolisten" "tcp" "-terminate"
- (cdr (command-line))))
+ "-logverbose" "-verbose" "-terminate"
+ #$@(xorg-configuration-server-arguments config)
+ (cdr (command-line))))
(program-file "startx" exp))
-(define* (xinitrc #:key
- (guile (canonical-package guile-2.0))
- fallback-session)
+(define* (xinitrc #:key fallback-session)
"Return a system-wide xinitrc script that starts the specified X session,
which should be passed to this script as the first argument. If not, the
@var{fallback-session} will be used or, if @var{fallback-session} is false, a
(program-file "xinitrc" builder))
+(define-syntax handle-xorg-configuration
+ (syntax-rules ()
+ "Generate the `compose' and `extend' entries of a login manager
+`service-type' to handle specifying the `xorg-configuration' through
+a `service-extension', as used by `set-xorg-configuration'."
+ ((_ configuration-record service-type-definition)
+ (service-type
+ (inherit service-type-definition)
+ (compose (lambda (extensions)
+ (match extensions
+ (() #f)
+ ((config . _) config))))
+ (extend (lambda (config xorg-configuration)
+ (if xorg-configuration
+ (configuration-record
+ (inherit config)
+ (xorg-configuration xorg-configuration))
+ config)))))))
+
\f
;;;
;;; SLiM log-in manager.
(define %default-slim-theme-name
;; This must be the name of the sub-directory in %DEFAULT-SLIM-THEME that
;; contains the actual theme files.
- "0.x")
+ "1.x")
(define-record-type* <slim-configuration>
slim-configuration make-slim-configuration
(default shepherd))
(auto-login-session slim-configuration-auto-login-session
(default #f))
- (startx slim-configuration-startx
- (default (xorg-start-command)))
+ (xorg-configuration slim-configuration-xorg
+ (default (xorg-configuration)))
+ (display slim-configuration-display
+ (default ":0"))
+ (vt slim-configuration-vt
+ (default "vt7"))
(sessreg slim-configuration-sessreg
(default sessreg)))
"Return a PAM service for @command{slim}."
(list (unix-pam-service
"slim"
+ #:login-uid? #t
#:allow-empty-passwords?
(slim-configuration-allow-empty-passwords? config))))
(define (slim-shepherd-service config)
- (define slim.cfg
- (let ((xinitrc (xinitrc #:fallback-session
- (slim-configuration-auto-login-session config)))
- (slim (slim-configuration-slim config))
- (xauth (slim-configuration-xauth config))
- (startx (slim-configuration-startx config))
- (shepherd (slim-configuration-shepherd config))
- (theme-name (slim-configuration-theme-name config))
- (sessreg (slim-configuration-sessreg config)))
+ (let* ((xinitrc (xinitrc #:fallback-session
+ (slim-configuration-auto-login-session config)))
+ (xauth (slim-configuration-xauth config))
+ (startx (xorg-start-command (slim-configuration-xorg config)))
+ (display (slim-configuration-display config))
+ (vt (slim-configuration-vt config))
+ (shepherd (slim-configuration-shepherd config))
+ (theme-name (slim-configuration-theme-name config))
+ (sessreg (slim-configuration-sessreg config))
+ (lockfile (string-append "/var/run/slim-" vt ".lock")))
+ (define slim.cfg
(mixed-text-file "slim.cfg" "
default_path /run/current-system/profile/bin
default_xserver " startx "
-xserver_arguments :0 vt7
+display_name " display "
+xserver_arguments " vt "
xauth_path " xauth "/bin/xauth
-authfile /var/run/slim.auth
+authfile /var/run/slim-" vt ".auth
+lockfile " lockfile "
+logfile /var/log/slim-" vt ".log
# The login command. '%session' is replaced by the chosen session name, one
# of the names specified in the 'sessions' setting: 'wmaker', 'xfce', etc.
"")
(if theme-name
(string-append "current_theme " theme-name "\n")
- ""))))
-
- (define theme
- (slim-configuration-theme config))
-
- (list (shepherd-service
- (documentation "Xorg display server")
- (provision '(xorg-server))
- (requirement '(user-processes host-name udev))
- (start
- #~(lambda ()
- ;; A stale lock file can prevent SLiM from starting, so remove it to
- ;; be on the safe side.
- (false-if-exception (delete-file "/var/run/slim.lock"))
-
- (fork+exec-command
- (list (string-append #$slim "/bin/slim") "-nodaemon")
- #:environment-variables
- (list (string-append "SLIM_CFGFILE=" #$slim.cfg)
- #$@(if theme
- (list #~(string-append "SLIM_THEMESDIR=" #$theme))
- #~())))))
- (stop #~(make-kill-destructor))
- (respawn? #t))))
+ "")))
+
+ (define theme
+ (slim-configuration-theme config))
+
+ (list (shepherd-service
+ (documentation "Xorg display server")
+ (provision (append
+ ;; For compatibility, also provide 'xorg-server'.
+ (if (string=? vt "vt7")
+ '(xorg-server)
+ '())
+
+ (list (symbol-append 'xorg-server-
+ (string->symbol vt)))))
+ (requirement '(user-processes host-name udev))
+ (start
+ #~(lambda ()
+ ;; A stale lock file can prevent SLiM from starting, so remove it to
+ ;; be on the safe side.
+ (false-if-exception (delete-file lockfile))
+
+ (fork+exec-command
+ (list (string-append #$(slim-configuration-slim config)
+ "/bin/slim")
+ "-nodaemon")
+ #:environment-variables
+ (list (string-append "SLIM_CFGFILE=" #$slim.cfg)
+ #$@(if theme
+ (list #~(string-append "SLIM_THEMESDIR=" #$theme))
+ #~())))))
+ (stop #~(make-kill-destructor))
+ (respawn? #t)))))
(define slim-service-type
- (service-type (name 'slim)
- (extensions
- (list (service-extension shepherd-root-service-type
- slim-shepherd-service)
- (service-extension pam-root-service-type
- slim-pam-service)
-
- ;; Unconditionally add xterm to the system profile, to
- ;; avoid bad surprises.
- (service-extension profile-service-type
- (const (list xterm)))))
- (default-value (slim-configuration))))
+ (handle-xorg-configuration slim-configuration
+ (service-type (name 'slim)
+ (extensions
+ (list (service-extension shepherd-root-service-type
+ slim-shepherd-service)
+ (service-extension pam-root-service-type
+ slim-pam-service)
+
+ ;; Unconditionally add xterm to the system profile, to
+ ;; avoid bad surprises.
+ (service-extension profile-service-type
+ (const (list xterm)))))
+
+ (default-value (slim-configuration))
+ (description
+ "Run the SLiM graphical login manager for X11."))))
(define-deprecated (slim-service #:key (slim slim)
(allow-empty-passwords? #t) auto-login?
(auto-login? auto-login?) (default-user default-user)
(theme theme) (theme-name theme-name)
(xauth xauth) (shepherd shepherd)
- (auto-login-session auto-login-session)
- (startx startx))))
+ (auto-login-session auto-login-session))))
\f
;;;
(list (service-extension pam-root-service-type
screen-locker-pam-services)
(service-extension setuid-program-service-type
- screen-locker-setuid-programs)))))
+ screen-locker-setuid-programs)))
+ (description
+ "Allow the given program to be used as a screen locker for
+the graphical server by making it setuid-root, so it can authenticate users,
+and by creating a PAM service for it.")))
(define* (screen-locker-service package
#:optional
(file-append package "/bin/" program)
allow-empty-passwords?)))
+\f
+;;;
+;;; Locale service.
+;;;
+
+(define-record-type* <localed-configuration>
+ localed-configuration make-localed-configuration
+ localed-configuration?
+ (localed localed-configuration-localed
+ (default localed))
+ (keyboard-layout localed-configuration-keyboard-layout
+ (default #f)))
+
+(define (localed-dbus-service config)
+ "Return the 'localed' D-Bus service for @var{config}, a
+@code{<localed-configuration>} record."
+ (define keyboard-layout
+ (localed-configuration-keyboard-layout config))
+
+ ;; The primary purpose of 'localed' is to tell GDM what the "current" Xorg
+ ;; keyboard layout is. If 'localed' is missing, or if it's unable to
+ ;; determine the current XKB layout, then GDM forcefully installs its
+ ;; default XKB config (US English). Here we communicate the configured
+ ;; layout through environment variables.
+
+ (if keyboard-layout
+ (let* ((layout (keyboard-layout-name keyboard-layout))
+ (variant (keyboard-layout-variant keyboard-layout))
+ (model (keyboard-layout-model keyboard-layout))
+ (options (keyboard-layout-options keyboard-layout)))
+ (list (wrapped-dbus-service
+ (localed-configuration-localed config)
+ "libexec/localed/localed"
+ `(("GUIX_XKB_LAYOUT" ,layout)
+ ,@(if variant
+ `(("GUIX_XKB_VARIANT" ,variant))
+ '())
+ ,@(if model
+ `(("GUIX_XKB_MODEL" ,model))
+ '())
+ ,@(if (null? options)
+ '()
+ `(("GUIX_XKB_OPTIONS"
+ ,(string-join options ","))))))))
+ '()))
+
+(define localed-service-type
+ (let ((package (lambda (config)
+ ;; Don't bother if the user didn't specify any keyboard
+ ;; layout.
+ (if (localed-configuration-keyboard-layout config)
+ (list (localed-configuration-localed config))
+ '()))))
+ (service-type (name 'localed)
+ (extensions
+ (list (service-extension dbus-root-service-type
+ localed-dbus-service)
+ (service-extension udev-service-type package)
+ (service-extension polkit-service-type package)
+
+ ;; Add 'localectl' to the profile.
+ (service-extension profile-service-type package)))
+
+ ;; This service can be extended, typically by the X login
+ ;; manager, to communicate the chosen Xorg keyboard layout.
+ (compose (lambda (extensions)
+ (find keyboard-layout? extensions)))
+ (extend (lambda (config keyboard-layout)
+ (localed-configuration
+ (inherit config)
+ (keyboard-layout keyboard-layout))))
+ (description
+ "Run the locale daemon, @command{localed}, which can be used
+to control the system locale and keyboard mapping from user programs such as
+the GNOME desktop environment.")
+ (default-value (localed-configuration)))))
+
+\f
+;;;
+;;; GNOME Desktop Manager.
+;;;
+
(define %gdm-accounts
(list (user-group (name "gdm") (system? #t))
(user-account
(name "gdm")
(group "gdm")
+ (supplementary-groups '("video"))
(system? #t)
(comment "GNOME Display Manager user")
(home-directory "/var/lib/gdm")
(shell (file-append shadow "/sbin/nologin")))))
+(define %gdm-activation
+ ;; Ensure /var/lib/gdm is owned by the "gdm" user. This is normally the
+ ;; case but could be wrong if the "gdm" user was created, then removed, and
+ ;; then recreated under a different UID/GID: <https://bugs.gnu.org/37423>.
+ (with-imported-modules '((guix build utils))
+ #~(begin
+ (use-modules (guix build utils))
+
+ (let* ((gdm (getpwnam "gdm"))
+ (uid (passwd:uid gdm))
+ (gid (passwd:gid gdm))
+ (st (stat "/var/lib/gdm" #f)))
+ ;; Recurse into /var/lib/gdm only if it has wrong ownership.
+ (when (and st
+ (or (not (= uid (stat:uid st)))
+ (not (= gid (stat:gid st)))))
+ (for-each (lambda (file)
+ (chown file uid gid))
+ (find-files "/var/lib/gdm"
+ #:directories? #t)))))))
+
(define dbus-daemon-wrapper
- (program-file "gdm-dbus-wrapper"
- #~(begin
- (setenv "XDG_CONFIG_DIRS"
- "/run/current-system/profile/etc/xdg")
- (setenv "XDG_DATA_DIRS"
- "/run/current-system/profile/share")
- (apply execl (string-append #$dbus "/bin/dbus-daemon")
- (program-arguments)))))
+ (program-file
+ "gdm-dbus-wrapper"
+ #~(begin
+ (use-modules (srfi srfi-26))
+
+ (define system-profile
+ "/run/current-system/profile")
+
+ (define user-profile
+ (and=> (getpw (getuid))
+ (lambda (pw)
+ (string-append (passwd:dir pw) "/.guix-profile"))))
+
+ ;; If we are able to find the user's profile, we can add it to
+ ;; the search paths set below. We need to do this so that D-Bus
+ ;; can start services installed by the user. This allows
+ ;; applications that require session D-Bus services (e.g,
+ ;; 'evolution') to work even if those services are only available
+ ;; in the user's profile. See <https://bugs.gnu.org/35267>.
+ (define profiles
+ (if user-profile
+ (list user-profile system-profile)
+ (list system-profile)))
+
+ (setenv "XDG_CONFIG_DIRS"
+ (string-join (map (cut string-append <> "/etc/xdg") profiles)
+ ":"))
+ (setenv "XDG_DATA_DIRS"
+ (string-join (map (cut string-append <> "/share") profiles)
+ ":"))
+ (apply execl (string-append #$dbus "/bin/dbus-daemon")
+ (program-arguments)))))
(define-record-type* <gdm-configuration>
gdm-configuration make-gdm-configuration
(allow-empty-passwords? gdm-configuration-allow-empty-passwords? (default #t))
(auto-login? gdm-configuration-auto-login? (default #f))
(dbus-daemon gdm-configuration-dbus-daemon (default dbus-daemon-wrapper))
+ (debug? gdm-configuration-debug? (default #f))
(default-user gdm-configuration-default-user (default #f))
(gnome-shell-assets gdm-configuration-gnome-shell-assets
(default (list adwaita-icon-theme font-cantarell)))
- (x-server gdm-configuration-x-server
- (default (xorg-wrapper))))
+ (xorg-configuration gdm-configuration-xorg
+ (default (xorg-configuration)))
+ (x-session gdm-configuration-x-session
+ (default (xinitrc))))
(define (gdm-configuration-file config)
(mixed-text-file "gdm-custom.conf"
"#TimedLoginEnable=false\n"
"#TimedLogin=\n"
"#TimedLoginDelay=0\n"
- "#InitialSetupEnable=true\n"
+ ;; Disable initial system setup inside GDM.
+ ;; Whatever settings are set there should already be
+ ;; taken care of through `guix system'.
+ ;; See also
+ ;; <https://debbugs.gnu.org/cgi/bugreport.cgi?bug=39281>.
+ "InitialSetupEnable=false\n"
;; Enable me once X is working.
"WaylandEnable=false\n"
"\n"
"[debug]\n"
- "#Enable=true\n"
+ "Enable=" (if (gdm-configuration-debug? config)
+ "true"
+ "false") "\n"
"\n"
"[security]\n"
"#DisallowTCP=true\n"
"Return a PAM service for @command{gdm}."
(list
(pam-service
- (inherit (unix-pam-service "gdm-autologin"))
+ (inherit (unix-pam-service "gdm-autologin"
+ #:login-uid? #t))
(auth (list (pam-entry
- (control "[success=ok default=1]")
+ (control "optional")
(module (file-append (gdm-configuration-gdm config)
"/lib/security/pam_gdm.so")))
(pam-entry
(control "required")
(module "pam_permit.so")))))
(unix-pam-service "gdm-password"
+ #:login-uid? #t
#:allow-empty-passwords?
(gdm-configuration-allow-empty-passwords? config))))
#$(gdm-configuration-dbus-daemon config))
(string-append
"GDM_X_SERVER="
- #$(gdm-configuration-x-server config))
+ #$(xorg-wrapper
+ (gdm-configuration-xorg config)))
+ (string-append
+ "GDM_X_SESSION="
+ #$(gdm-configuration-x-session config))
(string-append
"XDG_DATA_DIRS="
((lambda (ls) (string-join ls ":"))
(respawn? #t))))
(define gdm-service-type
- (service-type (name 'gdm)
- (extensions
- (list (service-extension shepherd-root-service-type
- gdm-shepherd-service)
- (service-extension account-service-type
- (const %gdm-accounts))
- (service-extension pam-root-service-type
- gdm-pam-service)
- (service-extension profile-service-type
- gdm-configuration-gnome-shell-assets)
- (service-extension dbus-root-service-type
- (compose list
- gdm-configuration-gdm))))
- (default-value (gdm-configuration))
- (description
- "Run the GNOME Desktop Manager (GDM), a program that allows
-you to log in in a graphical session, whether or not you use GNOME.")))
+ (handle-xorg-configuration gdm-configuration
+ (service-type (name 'gdm)
+ (extensions
+ (list (service-extension shepherd-root-service-type
+ gdm-shepherd-service)
+ (service-extension activation-service-type
+ (const %gdm-activation))
+ (service-extension account-service-type
+ (const %gdm-accounts))
+ (service-extension pam-root-service-type
+ gdm-pam-service)
+ (service-extension profile-service-type
+ gdm-configuration-gnome-shell-assets)
+ (service-extension dbus-root-service-type
+ (compose list
+ gdm-configuration-gdm))
+ (service-extension localed-service-type
+ (compose
+ xorg-configuration-keyboard-layout
+ gdm-configuration-xorg))))
+ (default-value (gdm-configuration))
+ (description
+ "Run the GNOME Desktop Manager (GDM), a program that allows
+you to log in in a graphical session, whether or not you use GNOME."))))
-;; This service isn't working yet; it gets as far as starting to run the
-;; greeter from gnome-shell but doesn't get any further. It is here because
-;; it doesn't hurt anyone and perhaps it inspires someone to fix it :)
(define-deprecated (gdm-service #:key (gdm gdm)
(allow-empty-passwords? #t)
(x-server (xorg-wrapper)))
(service gdm-service-type
(gdm-configuration
(gdm gdm)
- (allow-empty-passwords? allow-empty-passwords?)
- (x-server x-server))))
+ (allow-empty-passwords? allow-empty-passwords?))))
+
+(define* (set-xorg-configuration config
+ #:optional
+ (login-manager-service-type
+ gdm-service-type))
+ "Tell the log-in manager (of type @var{login-manager-service-type}) to use
+@var{config}, an <xorg-configuration> record."
+ (simple-service 'set-xorg-configuration
+ login-manager-service-type
+ config))
;;; xorg.scm ends here