aboutsummaryrefslogtreecommitdiff
path: root/tw/home.scm
diff options
context:
space:
mode:
authorTimo Wilken2023-03-07 21:42:07 +0100
committerTimo Wilken2023-03-07 21:42:07 +0100
commit4b8f75543f177b4e469c829d5bea00b5d681fb06 (patch)
tree3507a0f9c99d9e3406dfd16972338adb6b5bd377 /tw/home.scm
parent49da695f2229bf2327350c06bc5f83a23f52d307 (diff)
Unify common laptop and CERN desktop home config
Diffstat (limited to 'tw/home.scm')
-rw-r--r--tw/home.scm482
1 files changed, 403 insertions, 79 deletions
diff --git a/tw/home.scm b/tw/home.scm
index 2d5a7410..6cb67344 100644
--- a/tw/home.scm
+++ b/tw/home.scm
@@ -2,25 +2,38 @@
#:use-module (ice-9 string-fun)
#:use-module (gnu)
#:use-module (gnu home services)
+ #:use-module (gnu home services desktop)
#:use-module (gnu home services shells)
#:use-module (gnu home services shepherd)
#:use-module (gnu home services ssh)
#:use-module (guix gexp)
+ #:use-module ((nongnu packages messaging)
+ #:select (zoom))
+ #:use-module (tw gexp)
+ #:use-module (tw packages alice)
+ #:use-module (tw packages catppuccin)
+ #:use-module (tw packages ci)
+ #:use-module (tw packages games)
#:use-module (tw packages shell)
- #:use-module (tw system))
+ #:use-module (tw packages xorg)
+ #:use-module (tw system)
+ #:use-module (tw theme))
-(use-package-modules admin compression curl databases disk dns file finance
- gnupg graphviz imagemagick less linux lisp maths
- password-utils pretty-print pv python python-xyz rsync
- shells shellutils ssh textutils tmux version-control
- video vim web)
+(use-package-modules
+ admin base calendar compression cmake compton curl databases dav disk dns
+ dunst elf emacs emacs-xyz file finance fonts freedesktop games gcc gimp gnome
+ gnome-xyz gnupg gnuzilla graphviz haskell-apps image-viewers imagemagick
+ inkscape less libreoffice linux lisp llvm mail maths password-utils pdf
+ pretty-print pulseaudio pv python python-xyz rsync shells shellutils sqlite
+ ssh syndication terminals tcl tex textutils tmux version-control video vim web
+ web-browsers wm xdisorg xorg)
-(define-public common-packages
+(define-public %common-packages
(list
- curl dos2unix fdupes file git gnupg gnuplot graphviz hledger imagemagick jq
- less lesspipe net-tools openssh password-store pass-otp pv python
- python-ipython recutils rsync sbcl smartmontools source-highlight tmux tree
- xxd zip unzip
+ curl diffstat dos2unix fdupes file git gnupg gnuplot graphviz hledger
+ imagemagick jq less lesspipe net-tools openssh password-store pass-otp pv
+ python python-ipython recutils rsync sbcl smartmontools source-highlight
+ tmux tree xxd zip unzip
get-iplayer ffmpeg atomicparsley yt-dlp
;; Install only bind-utils like dig, not the full suite.
@@ -67,7 +80,81 @@ auto-expand-secmem
(define (make-own-ssh-host host port)
(openssh-host (name host) (port port) (user "timo")))
-(define-public common-services
+(define-public (openssh-service proxy-to-cern?)
+ (service home-openssh-service-type
+ (home-openssh-configuration
+ (hosts
+ ;; Earlier rules take precedence over later ones.
+ `(,(openssh-host (name "*.srcf.net") (user "tw466"))
+ ;; My own machines
+ ,@(map make-own-ssh-host (map car %ssh-ports) (map cdr %ssh-ports))
+ ,@(map make-own-ssh-host (map (compose wireguardify car) %ssh-ports) (map cdr %ssh-ports))
+ ,(openssh-host (name "*.fritz.box") (proxy-command "ssh -W '[%h]:%p' lud.twilken.net"))
+ ;; Git hosts
+ ,@(map (lambda (host) (openssh-host (name host) (user "git")))
+ '("github.com" "ssh.github.com" "bitbucket.org"))
+ ,(openssh-host (name "gitlab.cern.ch") (port 7999) (user "git") (proxy-command "none"))
+ ;; BitBucket apparently only supports ssh-rsa.
+ ,(openssh-host
+ (name "bitbucket.org")
+ (host-key-algorithms '("+ssh-rsa"))
+ (accepted-key-types '("+ssh-rsa")))
+ ;; CERN stuff
+ ,(openssh-host
+ (name "lxplus.cern.ch")
+ (proxy-command "none") ; avoid ProxyJump loops
+ (extra-content "GSSAPIDelegateCredentials yes")) ; needed for EOS home mount
+ ,(openssh-host
+ (name "aiadm.cern.ch")
+ (extra-content "GSSAPIDelegateCredentials yes")) ; needed for EOS home mount
+ ,(openssh-host
+ (name "cvmfs-alice.cern.ch")
+ (extra-content "GSSAPIDelegateCredentials yes")) ; needed for EOS home mount
+ ,(openssh-host
+ (name "tw-mailproc.cern.ch")
+ (user "root")
+ (identity-file "~/.local/share/ssh-keys/openstack_personal_id_rsa"))
+ ,(openssh-host
+ (name "twilkendesktop.cern.ch")
+ (port 22022)
+ (forward-x11? #t)
+ (extra-content "GSSAPIDelegateCredentials yes"))
+ ,@(map (lambda (spec)
+ (openssh-host (name (car spec)) (user (cdr spec))
+ (identity-file "~/.local/share/ssh-keys/alicern_id_rsa")))
+ '(("alimonitor.cern.ch" . "alibuild")
+ ("alinsure.cern.ch" . "alibuild")
+ ("alibuildmac*.cern.ch" . "alibuild")
+ ("aido*osx*.cern.ch" . "alibuild")
+ ("alibuild*.cern.ch" . "root")
+ ("alissandra*.cern.ch" . "root")
+ ("alimesos*.cern.ch" . "root")
+ ("alientest*.cern.ch" . "root")
+ ("aliflow*.cern.ch" . "root")
+ ("alijenkins*.cern.ch" . "root")
+ ("arm-builder-*" . "centos")))
+ ,(openssh-host
+ (name "*.cern.ch")
+ (user "twilken")
+ (identity-file "~/.local/share/ssh-keys/cern_id_rsa")
+ (proxy-command (if proxy-to-cern?
+ "ssh -W '[%h]:%p' -l twilken lxplus.cern.ch"
+ "none"))
+ (extra-content "\
+ # Kerberos authentication
+ GSSAPIAuthentication yes
+ GSSAPIDelegateCredentials no
+ PreferredAuthentications gssapi-keyex,gssapi-with-mic,publickey,password,keyboard-interactive
+"))
+ ;; Default SSH key. This isn't in ~/.ssh as `home-openssh-service-type'
+ ;; manages that and might delete keys there.
+ ,(openssh-host
+ (name "*")
+ (identity-file "~/.local/share/ssh-keys/id_rsa")
+ ;; Remote servers probably don't know about xterm-kitty.
+ (extra-content "SetEnv TERM=xterm-256color")))))))
+
+(define-public %common-services
(list
(service home-zsh-service-type
(home-zsh-configuration
@@ -180,70 +267,307 @@ auto-expand-secmem
("XCOMPOSEFILE" . "$XDG_CONFIG_HOME/X11/XCompose")
("ZDOTDIR" . "$XDG_CONFIG_HOME/zsh")
("_JAVA_OPTIONS" .
- "$_JAVA_OPTIONS${_JAVA_OPTIONS:+ }-Djava.util.prefs.userRoot=$XDG_CONFIG_HOME/java")))
-
- (service home-openssh-service-type
- (home-openssh-configuration
- (hosts
- ;; Earlier rules take precedence over later ones.
- `(,(openssh-host (name "*.srcf.net") (user "tw466"))
- ;; My own machines
- ,@(map make-own-ssh-host (map car %ssh-ports) (map cdr %ssh-ports))
- ,@(map make-own-ssh-host (map (compose wireguardify car) %ssh-ports) (map cdr %ssh-ports))
- ,(openssh-host (name "*.fritz.box") (proxy-command "ssh -W '[%h]:%p' lud.twilken.net"))
- ;; Git hosts
- ,@(map (lambda (host) (openssh-host (name host) (user "git")))
- '("github.com" "ssh.github.com" "bitbucket.org"))
- ,(openssh-host (name "gitlab.cern.ch") (port 7999) (user "git") (proxy-command "none"))
- ;; BitBucket apparently only supports ssh-rsa.
- ,(openssh-host
- (name "bitbucket.org")
- (host-key-algorithms '("+ssh-rsa"))
- (accepted-key-types '("+ssh-rsa")))
- ;; CERN stuff
- ,(openssh-host
- (name "lxplus.cern.ch")
- (proxy-command "none") ; avoid ProxyJump loops
- (extra-content "GSSAPIDelegateCredentials yes")) ; needed for EOS home mount
- ,(openssh-host
- (name "aiadm.cern.ch")
- (extra-content "GSSAPIDelegateCredentials yes")) ; needed for EOS home mount
- ,(openssh-host
- (name "cvmfs-alice.cern.ch")
- (extra-content "GSSAPIDelegateCredentials yes")) ; needed for EOS home mount
- ,(openssh-host
- (name "twilkendesktop.cern.ch")
- (port 22022)
- (forward-x11? #t)
- (extra-content "GSSAPIDelegateCredentials yes"))
- ,@(map (lambda (spec)
- (openssh-host (name (car spec)) (user (cdr spec))
- (identity-file "~/.local/share/ssh-keys/alicern_id_rsa")))
- '(("alimonitor.cern.ch" . "alibuild")
- ("alinsure.cern.ch" . "alibuild")
- ("alibuildmac*.cern.ch" . "alibuild")
- ("aido*osx*.cern.ch" . "alibuild")
- ("alibuild*.cern.ch" . "root")
- ("alissandra*.cern.ch" . "root")
- ("alimesos*.cern.ch" . "root")
- ("alientest*.cern.ch" . "root")
- ("aliflow*.cern.ch" . "root")
- ("alijenkins*.cern.ch" . "root")))
- ,(openssh-host
- (name "*.cern.ch")
- (user "twilken")
- (identity-file "~/.local/share/ssh-keys/cern_id_rsa")
- (proxy-command "ssh -W '[%h]:%p' -l twilken lxplus.cern.ch")
- (extra-content "\
- # Kerberos authentication
- GSSAPIAuthentication yes
- GSSAPIDelegateCredentials no
- PreferredAuthentications gssapi-keyex,gssapi-with-mic,publickey,password,keyboard-interactive
-"))
- ;; Default SSH key. This isn't in ~/.ssh as `home-openssh-service-type'
- ;; manages that and might delete keys there.
- ,(openssh-host
- (name "*")
- (identity-file "~/.local/share/ssh-keys/id_rsa")
- ;; Remote servers probably don't know about xterm-kitty.
- (extra-content "SetEnv TERM=xterm-256color"))))))))
+ "$_JAVA_OPTIONS${_JAVA_OPTIONS:+ }-Djava.util.prefs.userRoot=$XDG_CONFIG_HOME/java")))))
+
+(define-public %pim-packages
+ (list newsboat vdirsyncer khal khard aerc lynx)) ; lynx for HTML mail
+
+(define-public %pim-services
+ (list
+ (simple-service 'pim-config home-xdg-configuration-files-service-type
+ `(("khal/config" ,(local-file "home/files/khal.conf"))
+ ("khard/khard.conf" ,(local-file "home/files/khard.conf"))
+ ("aerc" ,(local-file "home/files/aerc" #:recursive? #t))
+ ("newsboat/config" ,(local-file "home/files/newsboat.conf"))
+ ("newsboat/config.catppuccin" ,catppuccin-newsboat)
+ ("vdirsyncer/config" ,(local-file "home/files/vdirsyncer.conf"))))
+
+ ;; These cron jobs are annoying because they pop up a password prompt every time they run.
+ ;; (simple-service 'pim-cronjobs home-mcron-service-type
+ ;; (list #~(job "15 */4 * * *" ; every four hours at HH:15
+ ;; (string-append #$(file-append vdirsyncer "/bin/vdirsyncer") " metasync"))
+ ;; #~(job "0,30 * * * *" ; every half hour
+ ;; (string-append #$(file-append vdirsyncer "/bin/vdirsyncer") " sync"))))
+
+ (simple-service 'mail-files home-files-service-type
+ `(;; The file from git main is newer than the one bundled with the
+ ;; packaged neomutt version and contains a few fixes.
+ (".local/bin/mutt_oauth2.py"
+ ,(local-file "home/files/neomutt/contrib/oauth2/mutt_oauth2.py" #:recursive? #t))))))
+
+(define polybar-wrapper
+ (program-file
+ "polybar-wrapper"
+ #~(begin
+ ;; This wrapper program checks that the monitor we want to start
+ ;; polybar on is actually connected.
+ (use-modules (ice-9 popen)
+ (ice-9 rdelim))
+ (let* ((connected-str (string-append (getenv "POLYBAR_MONITOR") " connected"))
+ (xrandr (open-pipe* OPEN_READ #$(file-append xrandr "/bin/xrandr") "-q"))
+ (monitor-connected?
+ (let loop ((line (read-line xrandr)))
+ (cond
+ ((eof-object? line) #f) ; we didn't find our monitor connected
+ ((string-prefix? connected-str line) #t) ; the monitor we want is connected
+ (else (loop (read-line xrandr))))))) ; keep looking
+ (close-pipe xrandr)
+ (when monitor-connected?
+ (execl #$(file-append polybar "/bin/polybar")))))))
+
+(define-public (polybar-service monitor)
+ (shepherd-service
+ (documentation (string-append "Polybar desktop bar for monitor " monitor "."))
+ (provision (list (symbol-append 'polybar- (string->symbol monitor))))
+ (requirement '(xorg-setup))
+ (start #~(make-forkexec-constructor
+ (list #$polybar-wrapper)
+ #:environment-variables
+ (cons #$(string-append "POLYBAR_MONITOR=" monitor)
+ (default-environment-variables))))
+ (stop #~(make-kill-destructor))))
+
+(define-public %interactive-packages
+ (list
+ ;; CLI tools
+ bsd-games texlive powertop (list git "send-email")
+
+ ;; Work
+ s3cmd python-alibuild python-alidistlint
+ hashicorp-levant-bin hashicorp-nomad-bin
+ hashicorp-consul-bin hashicorp-vault-bin hashicorp-packer-bin
+
+ ;; i3 and Xorg. i3 itself must be installed system-wide for gdm to pick it up.
+ ;; acpilight is a drop-in xbacklight replacement, as xbacklight doesn't work on my system.
+ acpilight arandr dunst gimp hsetroot inkscape icecat imv kitty libreoffice
+ mpv polybar pulsemixer rofi rofi-calc tk xdg-utils xdot xclip xcwd xdotool
+ xdpyinfo xev xfd xfontsel xinput xkill xprop xrandr xrdb xsel xset xwininfo
+ zoom zathura zathura-ps zathura-pdf-poppler
+ dconf dconf-editor ; required for config by blueman, cozy, ...
+ ;; gnome-keyring ; installed system-wide; see system-configuration.scm
+ ;; geoclue ; for redshift -- installed system-wide
+ ;; Fonts
+ font-hermit font-inconsolata font-fira-code font-fira-sans font-libertinus
+ font-google-noto font-google-noto-emoji font-openmoji ; for polybar
+ ;; Theming
+ papirus-icon-theme catppuccin-gtk-theme catppuccin-mocha-dark-cursors
+
+ ;; Development & language servers
+ gnu-make python-lsp-server python-yamllint shellcheck gcc binutils patchelf elfutils
+ clang ; for clangd
+ glibc ; for ldd
+ ;; Supported OotB by eglot, but not packaged by guix:
+ ;; https://github.com/mads-hartmann/bash-language-server
+ ;; https://github.com/regen100/cmake-language-server
+ ;; https://github.com/hrsh7th/vscode-langservers-extracted ; {html,css,json}-languageserver
+ ;; https://github.com/golang/tools/tree/master/gopls ; maybe?
+ ;; https://github.com/artempyanykh/marksman ; Markdown
+ ;; https://github.com/astoff/digestif ; (La)TeX
+ ;; https://github.com/redhat-developer/yaml-language-server
+ ;; Needs eglot config + not packaged (from lsp-mode):
+ ;; https://github.com/graphql/graphiql/tree/main/packages/graphql-language-service-cli#readme
+ ;; https://github.com/haskell/haskell-language-server / https://github.com/haskell/ghcide
+ ;; https://github.com/eclipse/lemminx
+
+ ;; Emacs general
+ emacs
+ emacs-use-package
+ emacs-eglot
+ emacs-counsel
+ emacs-counsel-dash sqlite ; emacs-counsel-dash requires the sqlite3 binary
+ emacs-ivy
+ ;; emacs-company emacs-company-quickhelp emacs-company-posframe
+ emacs-corfu emacs-corfu-doc
+ emacs-autothemer ; for catppuccin/emacs
+ emacs-undo-tree
+ emacs-aggressive-indent
+ emacs-which-key
+ emacs-smart-mode-line
+ emacs-diminish
+ emacs-rainbow-mode
+ emacs-form-feed
+ emacs-guix
+ ;; TODO: emacs-editorconfig emacs-sly emacs-sly-macrostep
+ emacs-org ; emacs-org-modern theme?
+
+ ;; Emacs Evil
+ emacs-evil
+ emacs-evil-collection
+ emacs-evil-expat ; for :reverse, :remove, :rename, :colo, :g*, ... ex commands
+ emacs-evil-surround
+ ;; emacs-evil-owl ; tests failing
+ emacs-evil-args
+ emacs-evil-numbers
+ emacs-evil-multiedit
+ emacs-evil-goggles
+ emacs-evil-traces
+ emacs-evil-commentary
+ emacs-evil-replace-with-register
+ emacs-evil-org
+ emacs-evil-markdown
+ emacs-evil-tex
+ emacs-evil-text-object-python
+
+ ;; Emacs language modes
+ emacs-flymake-collection
+ emacs-geiser emacs-geiser-guile
+ emacs-cmake-mode emacs-gnuplot emacs-graphviz-dot-mode emacs-hcl-mode
+ emacs-ledger-mode emacs-mmm-mode emacs-puppet-mode emacs-rec-mode
+ emacs-web-mode emacs-yaml-mode))
+
+(define-public %interactive-services
+ (cons*
+ ;; Configuration files for terminal-only programs in $XDG_CONFIG_HOME.
+ (simple-service 'interactive-terminal-config home-xdg-configuration-files-service-type
+ `(;; All alibuild needs is an empty file.
+ ("alibuild/disable-analytics"
+ ,(plain-file "alibuild-disable-analytics" ""))
+ ("X11/XCompose" ,(local-file "home/files/XCompose")) ; see also: $XCOMPOSEFILE variable
+ ("X11/Xresources" ,(local-file "home/files/Xresources"))))
+
+ (simple-service 'emacs-config home-xdg-configuration-files-service-type
+ `(("emacs/include" ,(local-file "home/files/emacs-packages" #:recursive? #t))
+ ("emacs/init.el" ,(local-file "home/files/emacs-init.el"))
+ (,(string-append "emacs/" (local-file-name catppuccin-emacs-theme))
+ ,catppuccin-emacs-theme)))
+
+ (simple-service 'emacsclient-is-editor home-environment-variables-service-type
+ `(("EDITOR" . "emacsclient -qc")
+ ;; Tell emacsclient to return immediately after opening the file. I
+ ;; can't put this in $EDITOR as many programs expect $EDITOR to exit
+ ;; only when the user is done editing.
+ ("ASYNC_EDITOR" . "emacsclient -qcn")))
+
+ (simple-service 'emacs-server home-shepherd-service-type
+ (list
+ (shepherd-service
+ (documentation "Emacs server; connect using emacsclient.")
+ (provision '(emacs))
+ (start #~(make-forkexec-constructor
+ (list #$(file-append emacs "/bin/emacs") "--fg-daemon")))
+ (stop #~(make-kill-destructor)))))
+
+ ;; The dbus service doesn't seem to be added automatically.
+ (service home-dbus-service-type
+ (home-dbus-configuration))
+
+ (simple-service 'common-gui-services home-shepherd-service-type
+ (list
+ (shepherd-service
+ (documentation "NetworkManager applet; provides a GUI for network connections.")
+ (provision '(nm-applet))
+ (start #~(make-forkexec-constructor
+ (list #$(file-append network-manager-applet "/bin/nm-applet"))))
+ (stop #~(make-kill-destructor)))
+
+ (shepherd-service
+ (documentation "Dunst notification daemon; displays desktop notifications.")
+ (provision '(dunst))
+ (start #~(make-forkexec-constructor
+ (list #$(file-append dunst "/bin/dunst"))))
+ (stop #~(make-kill-destructor)))
+
+ (shepherd-service
+ (documentation "Picom compositor; enables transparent windows in X.")
+ (provision '(picom))
+ (start #~(make-forkexec-constructor
+ (list #$(file-append picom "/bin/picom")
+ "--config" #$(local-file "home/files/picom.conf"))))
+ (stop #~(make-kill-destructor)))
+
+ (shepherd-service
+ (documentation "Source Xresources on login.")
+ (provision '(xrdb))
+ (one-shot? #t)
+ (start #~(lambda _
+ (invoke #$(file-append xrdb "/bin/xrdb") "-merge"
+ (string-append (getenv "XDG_CONFIG_HOME") "/X11/Xresources")))))
+
+ ;; By default, xdotool gets most of "#@\|~()<>[]{} wrong. Make
+ ;; it use the correct keymap by re-setting the same one again.
+ (shepherd-service
+ (documentation "Fix X keyboard map on login; passmenu needs this.")
+ (provision '(fix-xdotool))
+ (one-shot? #t)
+ (start #~(lambda _
+ (use-modules (ice-9 rdelim)
+ (ice-9 regex)
+ (ice-9 popen))
+ (let ((port (open-pipe* OPEN_READ #$(file-append setxkbmap "/bin/setxkbmap")
+ "-query")))
+ (let loop ((line (read-line port)))
+ (unless (eof-object? line)
+ (let ((mtch (string-match "^layout:[[:space:]]*" line)))
+ (if mtch
+ (system* #$(file-append setxkbmap "/bin/setxkbmap")
+ (match:suffix mtch))
+ (loop (read-line port))))))))))))
+
+ ;; Configuration files for GUI programs in $XDG_CONFIG_HOME.
+ (simple-service 'gui-config home-xdg-configuration-files-service-type
+ `(("dunst/dunstrc" ,(local-file "home/files/dunstrc"))
+ ("dunst/dunstrc.d/50-catppuccin.conf" ,catppuccin-dunstrc)
+ ("gtk-2.0/gtkrc" ,(local-file "home/files/gtk2.ini"))
+ ("gtk-3.0/settings.ini" ,(local-file "home/files/gtk3.ini"))
+ ("i3/config" ,(local-file "home/files/i3.conf"))
+ ;; TODO: "kdeglobals" works for some programs (e.g. kdeconnect-app),
+ ;; but not for others (e.g. nheko, kdeconnect-settings)...
+ ("kdeglobals" ,catppuccin-kdeglobals)
+ ("kitty/diff.conf"
+ ,(combined-text-file "kitty-diff.conf"
+ (plain-file "kitty-diff-custom.conf"
+ "pygments_style bw\n")
+ catppuccin-kitty-diff))
+ ("kitty/kitty.conf"
+ ,(combined-text-file "kitty.conf"
+ (local-file "home/files/kitty.conf")
+ catppuccin-kitty))
+ ("mimeapps.list" ,(local-file "home/files/mimeapps.list"))
+ ("polybar/config.ini" ,(local-file "home/files/polybar.ini"))
+ ("polybar/catppuccin.ini" ,catppuccin-polybar)
+ ("rofi/config.rasi" ,(local-file "home/files/rofi.rasi"))
+ ("rofi/themes/catppuccin.rasi" ,catppuccin-rofi)
+ ("zathura/zathurarc" ,(local-file "home/files/zathurarc"))
+ ("zathura/catppuccin" ,catppuccin-zathura)))
+
+ (simple-service 'cursor-theme home-files-service-type
+ `((".icons/default/index.theme" ,(local-file "home/files/cursors.ini"))))
+
+ (simple-service 'gui-environment home-environment-variables-service-type
+ `(("TERMINAL" . "kitty")
+ ("_JAVA_OPTIONS" .
+ ,(string-append
+ "$_JAVA_OPTIONS${_JAVA_OPTIONS:+ }-Dawt.useSystemAAFontSettings=on -Dswing.aatext=true "
+ "-Dswing.defaultlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel "
+ "-Dswing.crossplatformlaf=com.sun.java.swing.plaf.gtk.GTKLookAndFeel"))
+ ;; Smooth trackpad scrolling in Firefox/Icecat.
+ ;; https://wiki.archlinux.org/index.php/Firefox/Tweaks#Pixel-perfect_trackpad_scrolling
+ ("MOZ_USE_XINPUT2" . "1")))
+
+ (simple-service 'gui-scripts home-files-service-type
+ `(;; https://sw.kovidgoyal.net/kitty/kittens/diff/
+ (".local/bin/kdiff" ; show a diff
+ ,(program-file "kdiff" #~(apply execl #$(file-append kitty "/bin/kitty") "kitty"
+ "+kitten" "diff" (cdr (command-line)))))
+ (".local/bin/icat" ; kitty's "catimg" equivalent
+ ,(program-file "icat" #~(apply execl #$(file-append kitty "/bin/kitty") "kitty"
+ "+kitten" "icat" (cdr (command-line)))))
+ (".local/bin/screenlock"
+ ,(program-file
+ "screenlock"
+ #~(begin ; Wrapper around i3lock to turn off the screen and pause notifications.
+ (system* #$(file-append dunst "/bin/dunstctl") "set-paused" "true")
+ (system* #$(file-append xset "/bin/xset") "dpms" "0" "0" "5")
+ ;; We mustn't use `file-append' here, as we have to pick up the
+ ;; setuid binary for i3lock installed by the system config.
+ (system* "i3lock" "-nc" #$catppuccin-background-color)
+ (system* #$(file-append xset "/bin/xset") "dpms" "600" "600" "600")
+ (system* #$(file-append dunst "/bin/dunstctl") "set-paused" "false"))))
+ ;; With #:recursive? #t, Guix keeps the files' permission bits, i.e. makes them executable.
+ (".local/bin/sessionmenu" ,(local-file "home/files/sessionmenu" #:recursive? #t))
+ (".local/bin/passmenu" ,(local-file "home/files/passmenu" #:recursive? #t))
+ (".local/bin/volume" ,(local-file "home/files/volume" #:recursive? #t))
+ (".local/share/applications/emacsclient.desktop"
+ ,(local-file "home/files/emacsclient.desktop"))))
+
+ (gnupg-services #:gui-pinentry? #t)))