aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.dir-locals.el1
-rw-r--r--tw/gexp.scm9
-rw-r--r--tw/home/btl.scm3
-rw-r--r--tw/home/cern.scm33
-rw-r--r--tw/home/files/zshrc24
-rw-r--r--tw/home/frm.scm3
-rw-r--r--tw/home/lap.scm3
-rw-r--r--tw/packages/catppuccin.scm26
-rw-r--r--tw/packages/zoom.scm141
-rw-r--r--tw/services/desktop.scm547
-rw-r--r--tw/services/dev-env.scm5
-rw-r--r--tw/services/files/foot.ini20
-rwxr-xr-xtw/services/files/passmenu12
-rw-r--r--tw/services/files/rofi.rasi2
-rwxr-xr-xtw/services/files/sessionmenu34
-rw-r--r--tw/services/files/sway.conf275
-rw-r--r--tw/services/files/waybar.css77
-rw-r--r--tw/system.scm119
-rw-r--r--tw/system/cern.scm25
-rw-r--r--tw/theme.scm15
20 files changed, 1185 insertions, 189 deletions
diff --git a/.dir-locals.el b/.dir-locals.el
index 9761ff20..ac9c7edd 100644
--- a/.dir-locals.el
+++ b/.dir-locals.el
@@ -123,6 +123,7 @@
(eval . (put 'scheme-file 'scheme-indent-function 1))
(eval . (put 'plain-file 'scheme-indent-function 1))
(eval . (put 'mixed-text-file 'scheme-indent-function 1))
+ (eval . (put 'json-file 'scheme-indent-function 1))
;; My own functions.
(eval . (put 'combined-text-file 'scheme-indent-function 1))
diff --git a/tw/gexp.scm b/tw/gexp.scm
index 2f1705b7..0770f250 100644
--- a/tw/gexp.scm
+++ b/tw/gexp.scm
@@ -1,4 +1,5 @@
(define-module (tw gexp)
+ #:use-module (gnu packages guile)
#:use-module (guix gexp)
#:use-module (guix modules))
@@ -19,3 +20,11 @@
(lambda (iport)
(dump-port iport oport))))
'#$files)))))))
+
+(define-public (json-file name value)
+ (computed-file name
+ (with-extensions (list guile-json-4)
+ #~(begin
+ (use-modules (json) (srfi srfi-26))
+ (call-with-output-file #$output
+ (cut scm->json '#$value <> #:unicode #t))))))
diff --git a/tw/home/btl.scm b/tw/home/btl.scm
index 200153ea..3c370eef 100644
--- a/tw/home/btl.scm
+++ b/tw/home/btl.scm
@@ -12,7 +12,6 @@
#:use-module (gnu home services pm)
#:use-module (gnu home services ssh)
#:use-module (gnu packages finance)
- #:use-module (gnu packages networking)
#:use-module (gnu services)
#:use-module (guix gexp)
#:use-module (tw home)
@@ -27,7 +26,7 @@
(packages
;; These packages will show up in the home profile, under ~/.guix-home/profile.
;; Graphical applications
- (list blueman electrum))
+ (list electrum))
;; To search for available home services, run 'guix home search KEYWORD'.
(services
diff --git a/tw/home/cern.scm b/tw/home/cern.scm
index d86ef727..9b79c3b1 100644
--- a/tw/home/cern.scm
+++ b/tw/home/cern.scm
@@ -11,17 +11,10 @@
#:use-module (gnu home services guix)
#:use-module (gnu home services pm)
#:use-module (gnu home services ssh)
- #:use-module (gnu packages)
- #:use-module (gnu packages calendar)
- #:use-module (gnu packages dav)
- #:use-module (gnu packages mail)
- #:use-module (gnu packages networking)
- #:use-module (gnu packages web-browsers)
#:use-module (gnu services)
#:use-module (guix gexp)
#:use-module (tw home)
#:use-module (tw gexp)
- #:use-module ((tw packages mail) #:select (mutt_oauth2.py))
#:use-module (tw services desktop)
#:use-module (tw services dev-env)
#:use-module (tw services git)
@@ -29,39 +22,19 @@
(define-public %cern-home
(home-environment
- ;; These packages will show up in the home profile, under ~/.guix-home/profile.
- (packages (list blueman))
;; To search for available home services, run 'guix home search KEYWORD'.
(services
(list
(simple-service 'remote-desktop-config home-files-service-type
`((".local/share/vinagre/vinagre-bookmarks.xml" ,(local-file "files/vinagre-bookmarks.xml"))))
- ;; Redshift: make the screen turn redder at night.
- (service home-redshift-service-type
- (home-redshift-configuration
- (location-provider 'manual)
- ;; Approximate location
- (latitude 46.0)
- (longitude 6.0)
- ;; (location-provider 'geoclue2) ; TODO: currently waits forever for a location -- not sure why geoclue doesn't work
- (daytime-brightness 1.0)
- (nighttime-brightness 0.7)
- (extra-content "fade=0"))) ; with fade=1, restarting redshift causes flickering for a few secs
-
(service home-dbus-service-type)
(service tw-home-service-type)
- (service home-desktop-service-type
- (home-desktop-configuration
- (battery-name "BAT0")
- (ac-adapter-name "AC")
- (thermal-zone "0")
- (monitors
- (list (home-monitor-configuration
- (name "eDP-1")
- (xrandr-options '("--primary" "--auto")))))))
+ (service home-wayland-desktop-service-type
+ (home-wayland-desktop-configuration
+ (num-cores 12)))
(service home-full-dev-env-service-type)
diff --git a/tw/home/files/zshrc b/tw/home/files/zshrc
index ca4481e2..8a658173 100644
--- a/tw/home/files/zshrc
+++ b/tw/home/files/zshrc
@@ -189,3 +189,27 @@ fi
load_plugin fast-syntax-highlighting ||
load_plugin zsh-syntax-highlighting
+
+## Terminal integration with foot
+# https://codeberg.org/dnkl/foot/wiki#shell-integration
+if [ "$TERM" = foot ]; then
+ function foot-osc7-pwd () {
+ (( ZSH_SUBSHELL )) && return 0
+ emulate -L zsh # also sets localoptions for us
+ setopt extendedglob
+ local LC_ALL=C
+ printf '\e]7;file://%s%s\e\' "$HOST" "${PWD//(#m)([^@-Za-z&-;_~])/%${(l:2::0:)$(([##16]#MATCH))}}"
+ }
+ function foot-precmd () {
+ print -Pn '\e]133;A\e\'
+ if ! builtin zle; then
+ print -n '\e]133;D\e\'
+ fi
+ }
+ function foot-preexec () {
+ print -n '\e]133;C\e\'
+ }
+ add-zsh-hook -Uz chpwd foot-osc7-pwd
+ add-zsh-hook -Uz precmd foot-precmd
+ add-zsh-hook -Uz preexec foot-preexec
+fi
diff --git a/tw/home/frm.scm b/tw/home/frm.scm
index 2a0e5481..27b0ccbb 100644
--- a/tw/home/frm.scm
+++ b/tw/home/frm.scm
@@ -12,7 +12,6 @@
#:use-module (gnu home services pm)
#:use-module (gnu home services ssh)
#:use-module (gnu packages finance)
- #:use-module (gnu packages networking)
#:use-module (gnu services)
#:use-module (guix gexp)
#:use-module (tw home)
@@ -27,7 +26,7 @@
(packages
;; These packages will show up in the home profile, under ~/.guix-home/profile.
;; Graphical applications
- (list blueman electrum))
+ (list electrum))
;; To search for available home services, run 'guix home search KEYWORD'.
(services
diff --git a/tw/home/lap.scm b/tw/home/lap.scm
index e0ee5980..1ece6f19 100644
--- a/tw/home/lap.scm
+++ b/tw/home/lap.scm
@@ -12,7 +12,6 @@
#:use-module (gnu home services pm)
#:use-module (gnu home services ssh)
#:use-module (gnu packages finance)
- #:use-module (gnu packages networking)
#:use-module (gnu services)
#:use-module (guix gexp)
#:use-module (tw home)
@@ -27,7 +26,7 @@
(packages
;; These packages will show up in the home profile, under ~/.guix-home/profile.
;; Graphical applications
- (list blueman electrum))
+ (list electrum))
;; To search for available home services, run 'guix home search KEYWORD'.
(services
diff --git a/tw/packages/catppuccin.scm b/tw/packages/catppuccin.scm
index e79c6be2..85a92630 100644
--- a/tw/packages/catppuccin.scm
+++ b/tw/packages/catppuccin.scm
@@ -137,7 +137,7 @@ Cursors with a Catppuccin palettes.")
(package
(name (string-append "catppuccin-" program "-theme"))
;; See info '(guix)Version Numbers' for advice.
- (version (git-version "0.0.0" revision commit))
+ (version (git-version version revision commit))
(home-page (string-append "https://github.com/catppuccin/" program))
(source
(origin
@@ -178,6 +178,14 @@ Catppuccin color palette."))
#:repo-hash "1cv46rqdd159plnqdkl74zwcgmbndq81d02g41a327hdwbpahp6v"
#:install-plan '(("catppuccin-theme.el" "share/catppuccin/emacs/"))))
+(define-public catppuccin-foot-theme
+ (catppuccin-theme-package
+ #:program "foot"
+ #:commit "307611230661b7b1787feb7f9d122e851bae97e9"
+ #:revision "44" ; total number of commits since repo beginning
+ #:repo-hash "0ki01m4r3rxsx0vqjylwa3i6f6k8lf1xbsx2kv1xfzbd68fdhhws"
+ #:install-plan '(("themes/" "share/catppuccin/foot/"))))
+
(define-public catppuccin-kde-theme
(catppuccin-theme-package
#:program "kde"
@@ -221,6 +229,14 @@ Catppuccin color palette."))
#:repo-hash "15phrl9qlbzjxmp29hak3a5k015x60w2hxjif90q82vp55zjpnhc"
#:install-plan '(("basic/.local/share/rofi/themes/" "share/catppuccin/rofi/"))))
+(define-public catppuccin-swaylock-theme
+ (catppuccin-theme-package
+ #:program "swaylock"
+ #:revision "41"
+ #:commit "77246bbbbf8926bdb8962cffab6616bc2b9e8a06"
+ #:repo-hash "02nql7ry71fxlhj0vsbsxi3jrmfajxmapr9gg0mzp0k0bxwqxa00"
+ #:install-plan '(("themes/" "share/catppuccin/swaylock/"))))
+
(define-public catppuccin-vim-theme
(catppuccin-theme-package
#:program "vim"
@@ -230,6 +246,14 @@ Catppuccin color palette."))
#:install-plan '(("colors/" "share/catppuccin/vim/colors/")
("autoload/" "share/catppuccin/vim/autoload/"))))
+(define-public catppuccin-waybar-theme
+ (catppuccin-theme-package
+ #:program "waybar"
+ #:version "1.1"
+ #:commit "0830796af6aa64ce8bc7453d42876a628777ac68"
+ #:repo-hash "0np88b9zi6zk21fy5w4kmgjg1clqp4ggw1hijlv9qvlka2zkwmpn"
+ #:install-plan '(("themes/" "share/catppuccin/waybar/"))))
+
(define-public catppuccin-zathura-theme
(catppuccin-theme-package
#:program "zathura"
diff --git a/tw/packages/zoom.scm b/tw/packages/zoom.scm
new file mode 100644
index 00000000..be64d4d2
--- /dev/null
+++ b/tw/packages/zoom.scm
@@ -0,0 +1,141 @@
+(define-module (tw packages zoom)
+ #:use-module (ice-9 match)
+ #:use-module (nongnu packages messaging)
+ #:use-module (guix gexp)
+ #:use-module (guix packages))
+
+;; One Wayland, Zoom needs two extra environment variables to be set:
+;; - XDG_CURRENT_DESKTOP=GNOME (to get past the refusal to try sharing the screen)
+;; - QT_QPA_PLATFORM= (since QT_QPA_PLATFORM=wayland makes zoom fail to start)
+;; The following package definition patches it to set those variables.
+
+(define plist-delete
+ (match-lambda*
+ ((() _) '())
+ (((unpaired-item) _)
+ (error "Found unpaired item in plist" unpaired-item))
+ (((key-to-delete _ . rest) key-to-delete)
+ (plist-delete rest key-to-delete))
+ (((key value . rest) key-to-delete)
+ (cons* key value (plist-delete rest key-to-delete)))))
+
+(define-public zoom/wayland
+ (package
+ (inherit zoom)
+ (arguments
+ (apply
+ (lambda* (#:key phases #:allow-other-keys . args)
+ (cons*
+ #:phases
+ #~(modify-phases #$phases
+ (replace 'wrap-where-patchelf-does-not-work
+ (lambda _
+ (wrap-program (string-append #$output "/lib/zoom/zopen")
+ `("LD_LIBRARY_PATH" prefix
+ ,(list #$@(map (lambda (pkg)
+ (file-append (this-package-input pkg) "/lib"))
+ '("fontconfig-minimal"
+ "freetype"
+ "gcc"
+ "glib"
+ "libxcomposite"
+ "libxdamage"
+ "libxkbcommon"
+ "libxkbfile"
+ "libxrandr"
+ "libxrender"
+ "zlib")))))
+ (wrap-program (string-append #$output "/lib/zoom/zoom")
+ '("XDG_CURRENT_DESKTOP" = ("GNOME")) ; tw: added
+ '("QT_QPA_PLATFORM" = ()) ; tw: added
+ '("QML2_IMPORT_PATH" = ())
+ '("QT_PLUGIN_PATH" = ())
+ '("QT_SCREEN_SCALE_FACTORS" = ())
+ `("FONTCONFIG_PATH" ":" prefix
+ (,(string-join
+ (list
+ (string-append #$(this-package-input "fontconfig-minimal") "/etc/fonts")
+ #$output)
+ ":")))
+ `("LD_LIBRARY_PATH" prefix
+ ,(list (string-append #$(this-package-input "nss") "/lib/nss")
+ #$@(map (lambda (pkg)
+ (file-append (this-package-input pkg) "/lib"))
+ ;; TODO: Reuse this long list as it is
+ ;; needed for aomhost. Or perhaps
+ ;; aomhost has a shorter needed list,
+ ;; but untested.
+ '("alsa-lib"
+ "atk"
+ "at-spi2-atk"
+ "at-spi2-core"
+ "cairo"
+ "cups"
+ "dbus"
+ "eudev"
+ "expat"
+ "gcc"
+ "glib"
+ "mesa"
+ "mit-krb5"
+ "nspr"
+ "libxcb"
+ "libxcomposite"
+ "libxdamage"
+ "libxext"
+ "libxkbcommon"
+ "libxkbfile"
+ "libxrandr"
+ "libxshmfence"
+ "pango"
+ "pulseaudio"
+ "xcb-util"
+ "xcb-util-image"
+ "xcb-util-keysyms"
+ "xcb-util-wm"
+ "xcb-util-renderutil"
+ "zlib")))))
+ (wrap-program (string-append #$output "/lib/zoom/aomhost")
+ `("FONTCONFIG_PATH" ":" prefix
+ (,(string-join
+ (list
+ (string-append #$(this-package-input "fontconfig-minimal") "/etc/fonts")
+ #$output)
+ ":")))
+ `("LD_LIBRARY_PATH" prefix
+ ,(list (string-append #$(this-package-input "nss") "/lib/nss")
+ #$@(map (lambda (pkg)
+ (file-append (this-package-input pkg) "/lib"))
+ '("alsa-lib"
+ "atk"
+ "at-spi2-atk"
+ "at-spi2-core"
+ "cairo"
+ "cups"
+ "dbus"
+ "eudev"
+ "expat"
+ "gcc"
+ "glib"
+ "mesa"
+ "mit-krb5"
+ "nspr"
+ "libxcb"
+ "libxcomposite"
+ "libxdamage"
+ "libxext"
+ "libxkbcommon"
+ "libxkbfile"
+ "libxrandr"
+ "libxshmfence"
+ "pango"
+ "pulseaudio"
+ "xcb-util"
+ "xcb-util-image"
+ "xcb-util-keysyms"
+ "xcb-util-wm"
+ "xcb-util-renderutil"
+ "zlib"))))))))
+ ;; ARGS still contains the old "#:phases ..." entry, so delete it.
+ (plist-delete args #:phases)))
+ (package-arguments zoom)))))
diff --git a/tw/services/desktop.scm b/tw/services/desktop.scm
index 6d9edfa8..a602fdf3 100644
--- a/tw/services/desktop.scm
+++ b/tw/services/desktop.scm
@@ -4,7 +4,8 @@
#:use-module (gnu home services mail)
#:use-module (gnu home services mcron)
#:use-module (gnu home services shepherd)
- #:use-module ((gnu packages admin) #:select (ansible))
+ #:use-module (gnu home services sound)
+ #:use-module ((gnu packages admin) #:select (ansible shepherd))
#:use-module ((gnu packages aidc) #:select (qrencode))
#:use-module ((gnu packages bittorrent) #:select (transmission-remote-gtk))
#:use-module ((gnu packages calendar) #:select (khal))
@@ -13,7 +14,7 @@
#:use-module ((gnu packages compton) #:select (picom))
#:use-module ((gnu packages dav) #:select (vdirsyncer))
#:use-module ((gnu packages fonts) #:select (font-fira-code font-fira-sans font-google-noto font-google-noto-emoji font-google-noto-sans-cjk font-google-noto-serif-cjk font-hermit font-inconsolata font-libertinus font-openmoji))
- #:use-module ((gnu packages freedesktop) #:select (xdg-utils))
+ #:use-module ((gnu packages freedesktop) #:select (elogind wev wtype xdg-utils xdg-desktop-portal xdg-desktop-portal-wlr))
#:use-module ((gnu packages games) #:select (bsd-games))
#:use-module ((gnu packages gimp) #:select (gimp))
#:use-module ((gnu packages gl) #:select (mesa))
@@ -21,10 +22,11 @@
#:use-module ((gnu packages gnome-xyz) #:select (papirus-icon-theme))
#:use-module ((gnu packages gnuzilla) #:select (icecat))
#:use-module ((gnu packages graphviz) #:select (xdot))
+ #:use-module ((gnu packages image) #:select (grim slurp))
#:use-module ((gnu packages image-viewers) #:select (imv))
#:use-module ((gnu packages inkscape) #:select (inkscape))
#:use-module ((gnu packages libreoffice) #:select (libreoffice))
- #:use-module ((gnu packages linux) #:select (acpilight powertop radeontop))
+ #:use-module ((gnu packages linux) #:select (acpilight procps powertop radeontop))
#:use-module ((gnu packages mail) #:select (aerc khard))
#:use-module ((gnu packages messaging) #:select (nheko))
#:use-module ((gnu packages networking) #:select (blueman))
@@ -37,25 +39,24 @@
#:use-module ((gnu packages ssh) #:select (pdsh))
#:use-module ((gnu packages syndication) #:select (newsboat))
#:use-module ((gnu packages tcl) #:select (tk))
- #:use-module ((gnu packages terminals) #:select (kitty))
+ #:use-module ((gnu packages terminals) #:select (foot kitty))
#:use-module ((gnu packages tex) #:select (texlive-scheme-small texlive-latexmk texlive-moderncv texlive-fontawesome5 texlive-multirow texlive-arydshln texlive-libertine texlive-inconsolata texlive-newtx texlive-babel texlive-csquotes texlive-siunitx texlive-minted texlive-svg texlive-hyperref texlive-capt-of texlive-ulem texlive-trimspaces texlive-transparent texlive-graphics texlive-tools texlive-wrapfig texlive-amsmath texlive-amsfonts texlive-txfonts))
#:use-module ((gnu packages version-control) #:select (git))
- #:use-module ((gnu packages video) #:select (mpv))
+ #:use-module ((gnu packages video) #:select (mpv obs obs-pipewire-audio-capture))
#:use-module ((gnu packages web-browsers) #:select (lynx))
- #:use-module ((gnu packages wm) #:select (dunst polybar))
- #:use-module ((gnu packages xdisorg) #:select (arandr numlockx hsetroot rofi rofi-calc xclip xdotool xsel))
+ #:use-module ((gnu packages wm) #:select (dunst polybar swaybg swayfx swayidle swaylock waybar))
+ #:use-module ((gnu packages xdisorg) #:select (arandr numlockx hsetroot rofi rofi-calc rofi-wayland wl-clipboard wob xclip xdotool xsel))
#:use-module ((gnu packages xfce) #:select (xfce4-screenshooter))
#:use-module ((gnu packages xorg) #:select (xdpyinfo xev xfd xfontsel xinput xkill xprop xrandr xset xrdb xwininfo setxkbmap))
#:use-module ((games packages minecraft) #:select (prismlauncher))
#:use-module ((nongnu packages nvidia) #:select (nvda))
- #:use-module ((nongnu packages messaging) #:select (zoom))
#:use-module ((nongnu packages nvidia) #:select (nvidia-system-monitor))
#:use-module (gnu services configuration)
#:use-module (guix gexp)
#:use-module (guix packages)
#:use-module ((guix records) #:select (match-record))
#:use-module ((nongnu packages game-client) #:select (steam steam-nvidia))
- #:use-module ((nongnu packages messaging) #:select (zoom signal-desktop))
+ #:use-module ((nongnu packages messaging) #:select (signal-desktop))
#:use-module ((nongnu packages nvidia) #:select (nvda nvidia-system-monitor))
#:use-module (srfi srfi-1)
#:use-module (srfi srfi-26)
@@ -67,15 +68,76 @@
#:use-module ((tw packages mail) #:select (mutt_oauth2.py))
#:use-module ((tw packages scanner) #:select (simple-scan/airscan))
#:use-module ((tw packages xorg) #:select (xcwd))
+ #:use-module ((tw packages zoom) #:select (zoom/wayland))
#:use-module (tw theme)
#:export (home-desktop-configuration
home-monitor-configuration
home-desktop-service-type
+ home-wayland-desktop-configuration
+ home-wayland-desktop-service-type
home-gaming-configuration
home-gaming-service-type
home-pim-configuration
home-pim-service-type))
+(define common-desktop-packages
+ (list
+ ;; CLI tools
+ bsd-games powertop (list git "send-email") pdsh qrencode
+ texlive-scheme-small texlive-latexmk
+ ;; For CV:
+ texlive-moderncv texlive-fontawesome5 texlive-multirow texlive-arydshln
+ texlive-libertine texlive-inconsolata texlive-newtx texlive-babel
+ texlive-csquotes texlive-siunitx
+ ;; For org-mode export:
+ texlive-minted texlive-svg texlive-hyperref texlive-capt-of texlive-ulem
+ texlive-trimspaces texlive-transparent texlive-graphics texlive-tools
+ texlive-wrapfig texlive-amsmath texlive-amsfonts texlive-libertine
+ texlive-newtx texlive-txfonts texlive-inconsolata
+
+ ;; Work
+ s3cmd python-alibuild python-alidistlint actionlint modules
+ python-tox python-setuptools-scm python-mypy
+ hashicorp-levant-bin hashicorp-nomad-bin
+ hashicorp-consul-bin hashicorp-vault-bin hashicorp-packer-bin
+ ansible vinagre
+
+ ;; Fonts
+ font-hermit font-inconsolata font-fira-code font-fira-sans font-libertinus
+ ;; Base Noto doesn't include CJK, so install those separately.
+ font-google-noto font-google-noto-sans-cjk font-google-noto-serif-cjk
+ font-google-noto-emoji font-openmoji ; for polybar
+ ;; Theming
+ papirus-icon-theme catppuccin-gtk-theme catppuccin-mocha-dark-cursors
+ ;; Games (larger games installed in ~/.guix-profile to avoid frequent huge downloads).
+ szio-solitaire prismlauncher
+ ;; 0ad flightgear freeciv simutrans/pak128 warzone2100 widelands pioneer
+
+ ;; GUI applications common to X11 and Wayland
+ ;; acpilight is a drop-in xbacklight replacement, as xbacklight doesn't work on my system.
+ acpilight blueman gimp inkscape icecat imv libreoffice mpv pulsemixer
+ simple-scan/airscan transmission-remote-gtk tk xdg-utils xdot zoom/wayland
+ zathura zathura-ps zathura-pdf-poppler
+ ungoogled-chromium ; needed e.g. for Interrail site & DRM video
+ dconf dconf-editor)) ; required for config by blueman, cozy, ...
+
+(define common-xdg-configs
+ `(("alibuild/disable-analytics" ; All alibuild needs is an empty file.
+ ,(plain-file "alibuild-disable-analytics" ""))
+ ("gtk-2.0/gtkrc" ,(local-file "files/gtk2.ini"))
+ ("gtk-3.0/settings.ini" ,(local-file "files/gtk3.ini"))
+ ("kdeglobals" ,catppuccin-kdeglobals)
+ ("mimeapps.list" ,(local-file "files/mimeapps.list"))
+ ("zathura/zathurarc" ,(local-file "files/zathurarc"))
+ ("zathura/catppuccin" ,catppuccin-zathura)))
+
+(define common-home-files
+ `((".icons/default/index.theme" ,(local-file "files/cursors.ini"))
+ ;; With #:recursive? #t, Guix keeps the files' permission bits, i.e. makes them executable.
+ (".local/bin/sessionmenu" ,(local-file "files/sessionmenu" #:recursive? #t))
+ (".local/bin/passmenu" ,(local-file "files/passmenu" #:recursive? #t))
+ (".local/bin/volume" ,(local-file "files/volume" #:recursive? #t))))
+
;; Desktop services, including monitor layout
@@ -145,48 +207,13 @@ to list zones and their types.")
(define (home-packages config)
"Install packages I use frequently."
- (list
- ;; CLI tools
- bsd-games powertop (list git "send-email") pdsh qrencode
- texlive-scheme-small texlive-latexmk
- ;; For CV:
- texlive-moderncv texlive-fontawesome5 texlive-multirow texlive-arydshln
- texlive-libertine texlive-inconsolata texlive-newtx texlive-babel
- texlive-csquotes texlive-siunitx
- ;; For org-mode export:
- texlive-minted texlive-svg texlive-hyperref texlive-capt-of texlive-ulem
- texlive-trimspaces texlive-transparent texlive-graphics texlive-tools
- texlive-wrapfig texlive-amsmath texlive-amsfonts texlive-libertine
- texlive-newtx texlive-txfonts texlive-inconsolata
-
- ;; Work
- s3cmd python-alibuild python-alidistlint actionlint modules
- python-tox python-setuptools-scm python-mypy
- hashicorp-levant-bin hashicorp-nomad-bin
- hashicorp-consul-bin hashicorp-vault-bin hashicorp-packer-bin
- ansible vinagre
-
+ (cons*
;; 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 simple-scan/airscan
- transmission-remote-gtk tk xdg-utils xdot xclip xcwd xdotool
+ arandr dunst hsetroot kitty polybar rofi rofi-calc xclip xcwd xdotool
xdpyinfo xev xfd xfontsel xinput xkill xprop xrandr xrdb xsel xset xwininfo
- xfce4-screenshooter zoom zathura zathura-ps zathura-pdf-poppler
- ungoogled-chromium ; needed e.g. for Interrail site & DRM video
- 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
- ;; Base Noto doesn't include CJK, so install those separately.
- font-google-noto font-google-noto-sans-cjk font-google-noto-serif-cjk
- font-google-noto-emoji font-openmoji ; for polybar
- ;; Theming
- papirus-icon-theme catppuccin-gtk-theme catppuccin-mocha-dark-cursors
- ;; Games (larger games installed in ~/.guix-profile to avoid frequent huge downloads).
- ;; 0ad flightgear freeciv simutrans/pak128 warzone2100 widelands pioneer
- szio-solitaire prismlauncher))
+ xfce4-screenshooter ; only supports X11 for now: https://gitlab.xfce.org/apps/xfce4-screenshooter/-/merge_requests/52
+
+ common-desktop-packages))
(define xfce4-screenshooter.conf
(mixed-text-file "xfce4-screenshooter.conf" "\
@@ -206,20 +233,15 @@ show_border=1
(define (home-xdg-configs config)
"Configuration files that follow the XDG basedir spec."
- `(("alibuild/disable-analytics" ; All alibuild needs is an empty file.
- ,(plain-file "alibuild-disable-analytics" ""))
- ;; X11 environment configuration.
- ("X11/XCompose" ,(local-file "files/XCompose")) ; see also: $XCOMPOSEFILE variable
+ `(;; X11 environment configuration.
+ ("X11/XCompose" ,(local-file "files/XCompose")) ; see also: $XCOMPOSEFILE variable
;; Configuration files for GUI programs in $XDG_CONFIG_HOME. Some
;; of these may also work under Wayland, but some are X11-specific.
("dunst/dunstrc" ,(local-file "files/dunstrc"))
("dunst/dunstrc.d/50-catppuccin.conf" ,catppuccin-dunstrc)
- ("gtk-2.0/gtkrc" ,(local-file "files/gtk2.ini"))
- ("gtk-3.0/settings.ini" ,(local-file "files/gtk3.ini"))
("i3/config" ,(local-file "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"
@@ -229,19 +251,16 @@ show_border=1
,(combined-text-file "kitty.conf"
(local-file "files/kitty.conf")
catppuccin-kitty))
- ("mimeapps.list" ,(local-file "files/mimeapps.list"))
("polybar/config.ini" ,(local-file "files/polybar.ini"))
("polybar/catppuccin.ini" ,catppuccin-polybar)
("rofi/config.rasi" ,(local-file "files/rofi.rasi"))
("rofi/themes/catppuccin.rasi" ,catppuccin-rofi)
("xfce4/xfce4-screenshooter" ,xfce4-screenshooter.conf)
- ("zathura/zathurarc" ,(local-file "files/zathurarc"))
- ("zathura/catppuccin" ,catppuccin-zathura)))
+ ,@common-xdg-configs))
(define (home-files config)
"Extra configuration files and binaries that don't follow the XDG spec."
- `((".icons/default/index.theme" ,(local-file "files/cursors.ini"))
- ;; https://sw.kovidgoyal.net/kitty/kittens/diff/
+ `(;; https://sw.kovidgoyal.net/kitty/kittens/diff/
(".local/bin/kdiff" ; show a diff
,(program-file "kdiff"
#~(apply execl #$(file-append kitty "/bin/kitty") "kitty"
@@ -259,21 +278,7 @@ show_border=1
;; 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 "files/sessionmenu" #:recursive? #t))
- (".local/bin/passmenu" ,(local-file "files/passmenu" #:recursive? #t))
- (".local/bin/volume" ,(local-file "files/volume" #:recursive? #t))
- (".local/bin/alienv.guix"
- ,(program-file "alienv.guix"
- #~(begin
- (setenv "TERM" "xterm-256color") ; "modules" gets confused if this is unset
- (apply execlp "guix" "guix" "shell" "--pure" "--container" "--emulate-fhs" "--preserve=^TERM$"
- "bash" "util-linux" "coreutils" ; basic shell utilities (also needed by alienv)
- "which" "sed" "grep" "findutils" "procps" "gawk" "modules" ; alienv requirements
- "openssl@3" ; some packages need openssl
- "xz" ; XRootD needs liblzma
- "python-alibuild" "--" "alienv" (cdr (command-line))))))))
+ (system* #$(file-append dunst "/bin/dunstctl") "set-paused" "false"))))))
(define (home-environment config)
`(("TERMINAL" . "kitty")
@@ -303,6 +308,7 @@ show_border=1
,(shepherd-service
(documentation "Blueman applet; provides a GUI for connection to bluetooth devices.")
(provision '(blueman-applet))
+ (requirement '(x11-display))
(start #~(make-forkexec-constructor
(list #$(file-append blueman "/bin/blueman-applet"))))
(stop #~(make-kill-destructor)))
@@ -400,6 +406,395 @@ show_border=1
(service-extension home-shepherd-service-type home-shepherd-services)))))
+;;; Wayland-based desktop services
+
+(define-configuration/no-serialization home-wayland-desktop-configuration
+ (num-cores integer "Number of cores on the system. Used for waybar CPU
+display."))
+
+(define (home-wayland-packages config)
+ "Install packages I use frequently."
+ ;; Wayland-specific desktop tools
+ (cons* swayfx dunst foot grim rofi-wayland slurp swaybg wev wob wtype wl-clipboard
+ obs obs-pipewire-audio-capture ; to hack screen sharing
+ xdg-desktop-portal xdg-desktop-portal-wlr ; to set XDG_DESKTOP_PORTAL_DIR search path
+ common-desktop-packages))
+
+(define %waybar-dunst-signal 13)
+
+(define (waybar-configuration num-cores)
+ ;; For documentation, see:
+ ;; https://github.com/Alexays/Waybar/wiki/Configuration
+ (json-file "waybar.json"
+ `((reload_style_on_change . #t)
+ (layer . "top") ; put top bar above other windows' shadows
+
+ (modules-left . #("sway/mode" "sway/workspaces" "sway/window"))
+ (modules-center . #())
+ (modules-right . #("network" "memory" "cpu" "temperature"
+ "keyboard-state" "privacy" "pulseaudio" "battery"
+ "clock" "custom/dunst" "tray"))
+
+ (sway/workspaces (all-outputs . #t) (format . "{name}"))
+ (sway/window (max-length . 80) (icon . #t) (icon-size . 16))
+
+ (network
+ (interval . 10)
+ (icons . #("<span face='OpenMoji' fallback='false' color='#f38ba8'>๐Ÿ“ถ</span>"
+ "<span face='OpenMoji' fallback='false' color='#f9e2af'>๐Ÿ“ถ</span>"
+ "<span face='OpenMoji' fallback='false' color='#a6e3a1'>๐Ÿ“ถ</span>"))
+ (format . "{ifname}")
+ (format-ethernet . "<span face='OpenMoji' fallback='false'>๐ŸŒ</span> โ†“ {bandwidthDownBytes} โ†‘ {bandwidthUpBytes}")
+ (format-wifi . "{icon} {essid} โ†“ {bandwidthDownBytes} โ†‘ {bandwidthUpBytes}")
+ (tooltip-format . "{ifname}")
+ (tooltip-format-wifi . "{ifname}: {ipaddr} ({signalStrength}%, {frequency}GHz)")
+ (tooltip-format-ethernet . "{ifname}: {ipaddr} ({bandwidthTotalBytes}B/s)"))
+
+ (cpu
+ (interval . 2)
+ (format . ,(apply string-append (map (cut format #f "{icon~d}" <>)
+ (iota num-cores))))
+ (format-icons . #("<span color='#585b70'>โ–</span>"
+ "<span color='#cdd6f4'>โ–‚</span>"
+ "<span color='#cdd6f4'>โ–ƒ</span>"
+ "<span color='#cdd6f4'>โ–„</span>"
+ "<span color='#cdd6f4'>โ–…</span>"
+ "<span color='#cdd6f4'>โ–†</span>"
+ "<span color='#f9e2af'>โ–‡</span>"
+ "<span color='#f9e2af'>โ–ˆ</span>")))
+
+ (memory
+ (interval . 5)
+ (format . "<span color='#cdd6f4'>RAM</span> {used} GiB"))
+
+ (battery
+ (states (medium . 80) (critical . 20))
+ (format-discharging . "{icon} {capacity}% {power}W {time}")
+ (format-charging . "<span face='OpenMoji' fallback='false'>๐Ÿ”Œ</span> {capacity}% {power}W {time}")
+ (format-full . "")
+ (format-icons . #("<span face='OpenMoji' fallback='false' color='#f38ba8'>๐Ÿ”‹</span>"
+ "<span face='OpenMoji' fallback='false' color='#f9e2af'>๐Ÿ”‹</span>"
+ "<span face='OpenMoji' fallback='false' color='#f9e2af'>๐Ÿ”‹</span>"
+ "<span face='OpenMoji' fallback='false' color='#f9e2af'>๐Ÿ”‹</span>"
+ "<span face='OpenMoji' fallback='false' color='#a6e3a1'>๐Ÿ”‹</span>")))
+
+ (pulseaudio
+ (scroll-step . 1)
+ (format . "{icon} {volume}%")
+ (format-muted . "<span face='OpenMoji' fallback='false'>๐Ÿ”‡</span>")
+ (format-icons (default . #("<span face='OpenMoji' fallback='false'>๐Ÿ”ˆ</span>"
+ "<span face='OpenMoji' fallback='false'>๐Ÿ”‰</span>"
+ "<span face='OpenMoji' fallback='false'>๐Ÿ”Š</span>")))
+ (tooltip-format . "{desc}: {volume}%")
+ (on-click . "volume toggle-mute")
+ (on-click-right . "foot pulsemixer"))
+
+ (keyboard-state (capslock . #t))
+
+ (custom/dunst
+ (exec . "echo '{\"alt\": \"'$(dunstctl is-paused)'\"}'")
+ (return-type . "json")
+ (interval . 10)
+ (signal . ,%waybar-dunst-signal) ; SIGRTMIN + %waybar-dunst-signal
+ (format-icons (true . "<span face='OpenMoji' fallback='false'>๐Ÿ”•</span>") (false . ""))
+ (format . "{icon}"))
+
+ (clock
+ (format . "{:%a, %e %b %H:%M}")
+ (tooltip-format . "<tt><small>{calendar}</small></tt>")
+ (calendar
+ (mode . "year")
+ (mode-mon-col . 3)
+ (on-scroll . 1)
+ (format (months . "<span color='#f9e2af'><b>{}</b></span>")
+ (days . "<span color='#cdd6f4'>{}</span>")
+ (weekdays . "<span color='#fab387'><b>{}</b></span>")
+ (today . "<span color='#f38ba8'><b><u>{}</u></b></span>"))))
+
+ (tray (icon-size . 16) (spacing . 4)))))
+
+(define-public %sway-common-configuration
+ (mixed-text-file "sway-greetd.conf" "\
+font pango:Fira Sans 10
+
+input type:keyboard {
+ xkb_layout \"gb\"
+ xkb_options \"caps:swapescape,parens:swap_brackets,terminate:ctrl_alt_bksp,compose:rctrl,keypad:oss,kpdl:kposs\"
+ xkb_numlock enabled
+}
+
+input type:touchpad {
+ # libinput configuration for touchpad
+ dwt enabled # 'disabled while typing'
+ middle_emulation enabled
+ natural_scroll enabled
+ click_method clickfinger
+ scroll_method two_finger
+ tap enabled
+ tap_button_map lrm
+ drag enabled
+ drag_lock disabled
+}
+
+output * background " tw-background "/share/backgrounds/tw/blobs.png fill
+
+# swayfx effects
+blur enable
+shadows enable
+corner_radius 6
+"))
+
+(define (home-wayland-xdg-configs config)
+ ;; Wayland also uses the XCompose file.
+ (match-record config <home-wayland-desktop-configuration> (num-cores)
+ `(("X11/XCompose" ,(local-file "files/XCompose")) ; see also: $XCOMPOSEFILE variable
+ ("dunst/dunstrc" ,(local-file "files/dunstrc"))
+ ("dunst/dunstrc.d/50-catppuccin.conf" ,catppuccin-dunstrc)
+ ("foot/foot.ini" ,(local-file "files/foot.ini"))
+ ("foot/catppuccin.ini" ,catppuccin-foot)
+ ("rofi/config.rasi" ,(local-file "files/rofi.rasi"))
+ ("rofi/themes/catppuccin.rasi" ,catppuccin-rofi)
+ ("sway/config"
+ ,(combined-text-file "sway.conf"
+ %sway-common-configuration
+ (local-file "files/sway.conf")))
+ ("swaylock/config"
+ ,(combined-text-file "swaylock.conf"
+ (mixed-text-file "swaylock-settings.conf"
+ "image=" tw-background "/share/backgrounds/tw/blobs.png\n"
+ "scaling=fill\n"
+ "font=Fira Sans\n"
+ "font-size=12\n"
+ "indicator-idle-visible\n"
+ "show-keyboard-layout\n"
+ "show-failed-attempts\n")
+ catppuccin-swaylock))
+ ("waybar/config.jsonc" ,(waybar-configuration num-cores))
+ ("waybar/style.css" ,(local-file "files/waybar.css"))
+ ("waybar/catppuccin.css" ,catppuccin-waybar)
+ ,@common-xdg-configs)))
+
+(define (home-wayland-files config)
+ common-home-files)
+
+(define (home-wayland-environment config)
+ `(;; Smooth trackpad scrolling in Firefox/Icecat.
+ ;; https://wiki.archlinux.org/index.php/Firefox/Tweaks#Pixel-perfect_trackpad_scrolling
+ ("MOZ_ENABLE_WAYLAND" . "1")
+ ("TERMINAL" . "foot") ; needed for rofi-sensible-terminal
+ ("QT_QPA_PLATFORM" . "wayland") ; needed for Qt apps, e.g. obs
+ ("XDG_CURRENT_DESKTOP" . "sway") ; not sure why this isn't set by default
+ ("_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"))))
+
+(define wayland-screenlock-program
+ ;; Wrapper around swaylock to turn off the screen and pause notifications.
+ (program-file "wayland-screenlock"
+ ;; If swaylock is already running, don't lock again.
+ #~(unless (zero? (status:exit-val
+ (system* #$(file-append procps "/bin/pgrep")
+ "-xU" (number->string (getuid)) "swaylock")))
+ ;; Rely on swayidle to turn off the screen after a timeout.
+ (system* #$(file-append dunst "/bin/dunstctl") "set-paused" "true")
+ (system* #$(file-append shepherd "/bin/herd") "kick-dunst" "waybar")
+ (system* #$(file-append swaylock "/bin/swaylock"))
+ (system* #$(file-append dunst "/bin/dunstctl") "set-paused" "false")
+ (system* #$(file-append shepherd "/bin/herd") "kick-dunst" "waybar"))))
+
+(define (home-wayland-shepherd-services config)
+ (define wayland-environment-variables
+ (let ((vars '("XDG_RUNTIME_DIR" "WAYLAND_DISPLAY" "SWAYSOCK")))
+ #~(cons*
+ #$@(map (lambda (var) #~(string-append #$var "=" (getenv #$var))) vars)
+ (filter (lambda (assignment)
+ (not (or #$@(map (lambda (var)
+ #~(string-prefix? #$(string-append var "=") assignment))
+ vars))))
+ (default-environment-variables)))))
+
+ (list
+ (shepherd-service ; adjusted from Guix x11-display service
+ (provision '(wayland-display))
+ (modules '((ice-9 ftw)
+ (ice-9 match)
+ (ice-9 receive)
+ (srfi srfi-1)))
+ (start
+ #~(lambda* (#:optional
+ (display (getenv "WAYLAND_DISPLAY"))
+ (swaysock (getenv "SWAYSOCK")))
+ (define runtime-directory
+ (or (getenv "XDG_RUNTIME_DIR")
+ (format #f "/run/user/~d" (getuid))))
+
+ (define (correct-socket? prefix)
+ (lambda (name)
+ (let ((path (in-vicinity runtime-directory name)))
+ (and (string-prefix? prefix name)
+ (eq? 'socket (stat:type (stat path)))
+ (access? path O_RDWR)))))
+
+ (define (find-display delay)
+ ;; Wait for an accessible socket to show up in RUNTIME-DIRECTORY,
+ ;; up to DELAY seconds.
+ (let loop ((attempts delay))
+ (define wayland-socket
+ (find (correct-socket? "wayland-")
+ (or (scandir runtime-directory) '())))
+ (define sway-socket
+ (find (correct-socket? "sway-ipc.")
+ (or (scandir runtime-directory) '())))
+
+ (cond
+ ((and wayland-socket sway-socket)
+ (let ((swaysock (in-vicinity runtime-directory sway-socket)))
+ (format #t "Wayland server found at ~s. Sway socket found at ~s.~%"
+ wayland-socket swaysock)
+ (values wayland-socket swaysock)))
+ ((zero? attempts)
+ (format (current-error-port)
+ "Wayland server or Sway socket did not show up; giving up.~%")
+ (values #f #f))
+ (else (sleep 1) (loop (- attempts 1))))))
+
+ (receive (wayland-socket sway-socket) (find-display 10)
+ (let ((display (or display wayland-socket))
+ (swaysock (or swaysock sway-socket)))
+ (setenv "XDG_RUNTIME_DIR" runtime-directory)
+ (when display
+ (setenv "WAYLAND_DISPLAY" display))
+ (when swaysock
+ (setenv "SWAYSOCK" swaysock))
+ display))))
+ (stop #~(lambda _
+ (unsetenv "WAYLAND_DISPLAY")
+ (unsetenv "SWAYSOCK")
+ #f))
+ (respawn? #f))
+
+ ;; Using `make-forkexec-constructor' does not work because we need to
+ ;; inherit the variables from `wayland-display' at start time, not at
+ ;; definition time.
+ (shepherd-service
+ (documentation "NetworkManager applet; provides a GUI for network connections.")
+ (provision '(nm-applet))
+ (requirement '(wayland-display))
+ (start #~(lambda _
+ (fork+exec-command
+ (list #$(file-append network-manager-applet "/bin/nm-applet"))
+ #:environment-variables #$wayland-environment-variables)))
+ (stop #~(make-kill-destructor)))
+
+ (shepherd-service
+ (documentation "Blueman applet; provides a GUI for connection to bluetooth devices.")
+ (provision '(blueman-applet))
+ (requirement '(wayland-display))
+ (start #~(lambda _
+ (fork+exec-command
+ (list #$(file-append blueman "/bin/blueman-applet"))
+ #:environment-variables #$wayland-environment-variables)))
+ (stop #~(make-kill-destructor)))
+
+ (shepherd-service
+ (documentation "Dunst notification daemon; displays desktop notifications.")
+ (provision '(dunst))
+ (requirement '(wayland-display))
+ (start #~(lambda _
+ (fork+exec-command
+ (list #$(file-append dunst "/bin/dunst"))
+ #:environment-variables #$wayland-environment-variables)))
+ (stop #~(make-kill-destructor)))
+
+ (shepherd-service
+ (documentation "XDG desktop portal dispatcher.")
+ (provision '(xdg-desktop-portal))
+ (requirement '(wayland-display dbus))
+ (start #~(lambda _
+ (fork+exec-command
+ (list #$(file-append xdg-desktop-portal
+ "/libexec/xdg-desktop-portal") "-rv")
+ #:environment-variables
+ (cons* "XDG_CURRENT_DESKTOP=sway"
+ #;(string-append "XDG_DESKTOP_PORTAL_DIR=" #$xdg-desktop-portal-wlr
+ "/share/xdg-desktop-portal/portals")
+ #$wayland-environment-variables))))
+ (stop #~(make-kill-destructor)))
+
+ (shepherd-service
+ (documentation "Screen sharing support for wlroots-based compositors.")
+ (provision '(xdg-desktop-portal-wlr))
+ (requirement '(xdg-desktop-portal wayland-display dbus))
+ (start #~(lambda _
+ (fork+exec-command
+ (list #$(file-append xdg-desktop-portal-wlr
+ "/libexec/xdg-desktop-portal-wlr") "-rl" "DEBUG")
+ #:environment-variables
+ (cons* "XDG_CURRENT_DESKTOP=sway"
+ #$wayland-environment-variables))))
+ (stop #~(make-kill-destructor)))
+
+ (shepherd-service
+ (documentation "Waybar desktop status bar daemon.")
+ (provision '(waybar))
+ (requirement '(wayland-display))
+ (start #~(lambda _
+ (fork+exec-command
+ (list #$(file-append waybar "/bin/waybar"))
+ #:environment-variables #$wayland-environment-variables)))
+ (stop #~(make-kill-destructor))
+ (actions
+ (list (shepherd-action
+ (name 'kick-dunst)
+ (documentation "Tell waybar to update its Dunst status.")
+ (procedure #~(lambda (waybar-pid . args)
+ ;; See magic constant defined in waybar.jsonc.
+ (kill waybar-pid (+ SIGRTMIN #$%waybar-dunst-signal))
+ #t))))))
+
+ (let ((swayidle.conf
+ (mixed-text-file "swayidle.conf"
+ "lock '" wayland-screenlock-program "' \n"
+ "unlock '" procps "/bin/pkill -x -USR1 swaylock'\n"
+ "before-sleep '" elogind "/bin/loginctl lock-session'\n"
+ "timeout 300 '" elogind "/bin/loginctl lock-session && "
+ swayfx "/bin/swaymsg \"output * power off\"' " ; no newline!
+ "resume '" swayfx "/bin/swaymsg \"output * power on\"'\n"
+ "timeout 600 '" elogind "/bin/loginctl suspend'\n")))
+ (shepherd-service
+ (documentation "Manage the screen when idle or locked.")
+ (provision '(swayidle))
+ (requirement '(wayland-display))
+ (start #~(lambda _
+ (fork+exec-command
+ (list #$(file-append swayidle "/bin/swayidle") "-C" #$swayidle.conf)
+ #:environment-variables #$wayland-environment-variables)))
+ (stop #~(make-kill-destructor))
+ (actions
+ (list (shepherd-configuration-action swayidle.conf)
+ (shepherd-action
+ (name 'idle)
+ (documentation "Immediately enter idle state.")
+ (procedure #~(lambda (swayidle-pid . args)
+ (kill swayidle-pid SIGUSR1)
+ #t)))))))))
+
+(define home-wayland-desktop-service-type
+ (service-type
+ (name 'wayland-desktop)
+ (description "Configure a Wayland-based desktop environment.")
+ (extensions
+ (list (service-extension home-profile-service-type home-wayland-packages)
+ (service-extension home-xdg-configuration-files-service-type home-wayland-xdg-configs)
+ (service-extension home-files-service-type home-wayland-files)
+ (service-extension home-environment-variables-service-type home-wayland-environment)
+ (service-extension home-pipewire-service-type (const #t))
+ (service-extension home-shepherd-service-type home-wayland-shepherd-services)))))
+
+
;;; Gaming servicse
(define-configuration/no-serialization home-gaming-configuration
diff --git a/tw/services/dev-env.scm b/tw/services/dev-env.scm
index 8e38ea8f..17c73eee 100644
--- a/tw/services/dev-env.scm
+++ b/tw/services/dev-env.scm
@@ -57,9 +57,8 @@
(list (shepherd-service
(documentation "Emacs server; connect using emacsclient.")
(provision '(emacs))
- (requirement '(x11-display))
(start #~(make-forkexec-constructor
- (list #$(file-append emacs "/bin/emacs") "--fg-daemon")))
+ (list #$(file-append emacs-pgtk "/bin/emacs") "--fg-daemon")))
(stop #~(make-kill-destructor)))))
(define (emacs-packages config)
@@ -70,7 +69,7 @@
glibc ; for ldd
;; Emacs general
- emacs ; for Wayland, switch to emacs-pgtk for better fractional scaling support
+ emacs-pgtk ; for Wayland and better fractional scaling support
emacs-use-package
emacs-gcmh
emacs-eglot
diff --git a/tw/services/files/foot.ini b/tw/services/files/foot.ini
new file mode 100644
index 00000000..f1bc6d54
--- /dev/null
+++ b/tw/services/files/foot.ini
@@ -0,0 +1,20 @@
+[main]
+font=Hermit:size=10, Noto Color Emoji:size=10
+dpi-aware=no
+include=~/.config/foot/catppuccin.ini
+
+[scrollback]
+lines=1000000
+multiplier=10.0
+
+[cursor]
+blink=yes
+
+[mouse]
+hide-when-typing=yes
+
+[text-bindings]
+# Remap Ctrl+Return and Shift+Return to Return, to avoid confusing the shell.
+# These are frequently mistyped, e.g. when typing Ctrl+Space, Return.
+\x0a=Shift+Return
+\x0a=Control+Return
diff --git a/tw/services/files/passmenu b/tw/services/files/passmenu
index 9bf7f7e3..a95fcc7a 100755
--- a/tw/services/files/passmenu
+++ b/tw/services/files/passmenu
@@ -44,7 +44,11 @@ extract_key() {
}
type_stdin() {
- tr -d '\n' | xdotool getactivewindow type --clearmodifiers --file -
+ tr -d '\n' | if [ -n "$WAYLAND_DISPLAY" ]; then
+ wtype -s 50 -
+ else
+ xdotool getactivewindow type --clearmodifiers --file -
+ fi
}
## Command-line arguments
@@ -82,7 +86,11 @@ case "$mode" in
entry=$(pass show "$password_name")
if [ "$mode" = type-all ]; then
echo "$entry" | extract_key username | type_stdin
- xdotool getactivewindow key Tab
+ if [ -n "$WAYLAND_DISPLAY" ]; then
+ wtype -s 50 -k Tab
+ else
+ xdotool getactivewindow key Tab
+ fi
fi
echo "$entry" | head -1 | type_stdin
unset entry;;
diff --git a/tw/services/files/rofi.rasi b/tw/services/files/rofi.rasi
index 83363c14..b01c4c1d 100644
--- a/tw/services/files/rofi.rasi
+++ b/tw/services/files/rofi.rasi
@@ -1,6 +1,6 @@
/* -*- mode: css -*- */
configuration {
- modi: "combi,windowcd,calc";
+ modi: "combi,window";
combi-modi: "window,drun,session:sessionmenu,ssh,run";
terminal: "rofi-sensible-terminal";
icon-theme: "Papirus-Dark";
diff --git a/tw/services/files/sessionmenu b/tw/services/files/sessionmenu
index 91839d8e..4f145d34 100755
--- a/tw/services/files/sessionmenu
+++ b/tw/services/files/sessionmenu
@@ -4,26 +4,34 @@
(ice-9 match)
(ice-9 ports))
+(define wm
+ (cond ((getenv "SWAYSOCK") 'sway)
+ ((getenv "I3SOCK") 'i3)
+ (else #f)))
+
(define (call-command/stderr . command)
"Call COMMAND using `system*', but redirect all output to stderr."
(with-output-to-port (current-error-port)
(lambda () (apply system* command))))
+(define (wm-msg . command)
+ (apply call-command/stderr
+ (match wm
+ (sway "swaymsg")
+ (i3 "i3-msg")
+ (_ (error "No recognised window manager running")))
+ command))
+
(match (command-line)
((_ "quit")
(exit 0))
- ((_ "Reload i3 configuration")
- (call-command/stderr "i3-msg" "reload"))
+ ((_ "Reload WM configuration")
+ (wm-msg "reload"))
((_ "Sleep")
- ;; "screenlock" blocks until unlocked by the user, so run in background.
- ;; TODO: write "mem" to /sys/power/state, but it's owned by root.
- (let ((locker (spawn "screenlock" '("screenlock")))
- (sleepfile (open-file "/sys/power/state" "w")))
- (display "mem" sleepfile)
- (close sleepfile)
- (waitpid locker)))
+ ;; Rely on swayidle to lock the screen before going to sleep.
+ (call-command/stderr "loginctl" "suspend"))
((_ "Log out")
- (call-command/stderr "i3-msg" "exit"))
+ (wm-msg "exit"))
((_ "Shutdown")
(call-command/stderr "sudo" "-n" "/run/current-system/profile/sbin/shutdown"))
((_ "Reboot")
@@ -31,8 +39,10 @@
(_
(format #t "\0~a\x1f~a~%~{~a\0icon\x1f~a~%~}"
"prompt" "Session"
- '("Reload i3 configuration" "reload"
+ `(,@(if wm
+ '("Reload WM configuration" "reload"
+ "Log out" "system-log-out")
+ '())
"Sleep" "system-suspend"
- "Log out" "system-log-out"
"Shutdown" "system-shutdown"
"Reboot" "system-reboot"))))
diff --git a/tw/services/files/sway.conf b/tw/services/files/sway.conf
new file mode 100644
index 00000000..498c8cff
--- /dev/null
+++ b/tw/services/files/sway.conf
@@ -0,0 +1,275 @@
+# sway config file
+# This file is augmented by the default sway configuration in tw/system.scm,
+# which is used for wlgreet's sway session. Common options should go there.
+
+# Appearance and Styling {{{
+title_align center
+default_border pixel 3
+default_floating_border pixel 3
+hide_edge_borders smart
+gaps inner 15
+gaps outer 0
+smart_gaps on
+# TODO: Zoom needs XWayland despite [General]xwayland=false in zoomus.conf
+# xwayland disable
+
+# swayfx effects
+# swaymsg -r -t get_outputs | jq -r '.[0].layer_shell_surfaces | .[] | .namespace'
+layer_effects "waybar" corner_radius 0
+
+# Catppuccin colours
+# Foregrounds
+set $c_fg #cdd6f4
+set $c_inactive #7f849c
+# Backgrounds
+set $c_bg #11111b
+set $c_active #585b70
+set $c_urgent #f9e2af
+
+# class border background text indicator child_border
+client.focused $c_active $c_active $c_fg $c_active $c_active
+client.focused_inactive $c_bg $c_bg $c_fg $c_bg $c_bg
+client.unfocused $c_bg $c_bg $c_inactive $c_bg $c_bg
+client.urgent $c_urgent $c_urgent $c_fg $c_urgent $c_urgent
+client.placeholder $c_bg $c_bg $c_inactive $c_bg $c_bg
+client.background $c_bg
+# }}}
+
+# Output Configuration {{{
+# Laptop screen
+output "AU Optronics 0x4CA3 Unknown" position 0 0
+# Displays at work
+output "HP Inc. HP Z24u G3 CN42322LXZ" position -1920 0
+output "Samsung Electric Company SyncMaster H9XZ110607" position -3840 0
+# }}}
+
+# Basic Configuration {{{
+# use the Super key as $mod
+set $mod Mod4
+
+# Use Mouse+$mod to drag floating windows to their wanted position
+floating_modifier $mod
+
+# essential applications
+bindsym $mod+Return exec foot
+bindsym $mod+i exec icecat --new-window
+bindsym $mod+shift+i exec icecat --new-tab "$(wl-paste -np)"
+bindsym $mod+e exec $ASYNC_EDITOR
+# Use ASYNC_EDITOR so I can continue using ranger while the editor
+# remains open in a separate window.
+bindsym $mod+slash exec EDITOR=$ASYNC_EDITOR foot ranger
+bindsym $mod+semicolon exec --no-startup-id nheko
+bindsym $mod+shift+semicolon exec --no-startup-id foot aerc
+bindsym $mod+y exec foot pulsemixer
+
+# volume
+bindsym XF86AudioRaiseVolume exec --no-startup-id volume +5
+bindsym XF86AudioLowerVolume exec --no-startup-id volume -5
+bindsym XF86AudioMute exec --no-startup-id volume toggle-mute
+
+# screenshots
+bindsym Print exec --no-startup-id slurp -o | grim -g- -l9
+bindsym shift+Print exec --no-startup-id swaymsg -t get_tree | jq -r '.. | select(.pid? and .visible?) | .rect | "\(.x),\(.y) \(.width)x\(.height)"' | slurp | grim -g- -l9
+
+# notifications
+bindsym $mod+n exec dunstctl close
+bindsym $mod+shift+n exec dunstctl history-pop
+bindsym $mod+period exec dunstctl context
+
+# screen locking and sleep handling
+bindsym $mod+shift+slash exec loginctl lock-session
+bindswitch --locked lid:on exec loginctl suspend
+
+# kill focused window
+bindsym $mod+shift+q kill
+
+# rofi menus
+bindsym $mod+d exec rofi -show combi
+bindsym $mod+shift+e exec rofi -show session:sessionmenu
+bindsym $mod+p exec passmenu --type-all
+bindsym $mod+shift+p exec passmenu --type-pass
+bindsym $mod+o exec passmenu --type-otp
+bindsym $mod+shift+Return exec rofi -show ssh
+# }}}
+
+# Basic Movement {{{
+# change focus
+bindsym $mod+h focus left
+bindsym $mod+j focus down
+bindsym $mod+k focus up
+bindsym $mod+l focus right
+bindsym $mod+Left focus left
+bindsym $mod+Down focus down
+bindsym $mod+Up focus up
+bindsym $mod+Right focus right
+
+# move focused window
+bindsym $mod+shift+h move left
+bindsym $mod+shift+j move down
+bindsym $mod+shift+k move up
+bindsym $mod+shift+l move right
+bindsym $mod+shift+Left move left
+bindsym $mod+shift+Down move down
+bindsym $mod+shift+Up move up
+bindsym $mod+shift+Right move right
+
+bindsym $mod+a focus parent
+bindsym $mod+shift+a focus child
+# }}}
+
+# Layout {{{
+bindsym $mod+b split h
+bindsym $mod+v split v
+
+# enter fullscreen mode for the focused container
+bindsym $mod+f fullscreen toggle
+bindsym $mod+shift+f floating enable, resize set 1920 1080, move position 0 0
+
+# change container layout (stacked, tabbed, toggle split)
+bindsym $mod+s layout stacking
+bindsym $mod+w layout tabbed
+bindsym $mod+x layout toggle split
+
+bindsym $mod+shift+space floating toggle
+# change focus between tiling / floating windows
+bindsym $mod+space focus mode_toggle
+
+# scratchpad
+bindsym $mod+numbersign scratchpad show
+bindsym $mod+shift+numbersign move to scratchpad
+bindsym $mod+apostrophe sticky disable, floating disable
+bindsym $mod+shift+apostrophe sticky enable, floating enable
+
+# move workspaces
+bindsym $mod+shift+comma move workspace to output left
+bindsym $mod+shift+period move workspace to output right
+# }}}
+
+# Default Workspaces {{{
+# switch to workspace
+bindsym $mod+Escape workspace back_and_forth
+bindsym $mod+1 workspace 1
+bindsym $mod+2 workspace 2
+bindsym $mod+3 workspace 3
+bindsym $mod+4 workspace 4
+bindsym $mod+5 workspace 5
+bindsym $mod+6 workspace 6
+bindsym $mod+7 workspace 7
+bindsym $mod+8 workspace 8
+bindsym $mod+9 workspace 9
+bindsym $mod+0 workspace 10
+bindsym $mod+parenleft workspace prev
+bindsym $mod+parenright workspace next
+# Swiping with 3 fingers should move workspaces. Emulate "natural scrolling"
+# where swiping right moves the current workspace off to the right, so the
+# previous/left-hand workspace comes into focus.
+bindgesture swipe:3:right workspace prev
+bindgesture swipe:3:left workspace next
+
+# move focused container to workspace
+bindsym $mod+shift+Escape move container to workspace back_and_forth
+bindsym $mod+shift+1 move container to workspace 1
+bindsym $mod+shift+2 move container to workspace 2
+bindsym $mod+shift+3 move container to workspace 3
+bindsym $mod+shift+4 move container to workspace 4
+bindsym $mod+shift+5 move container to workspace 5
+bindsym $mod+shift+6 move container to workspace 6
+bindsym $mod+shift+7 move container to workspace 7
+bindsym $mod+shift+8 move container to workspace 8
+bindsym $mod+shift+9 move container to workspace 9
+bindsym $mod+shift+0 move container to workspace 10
+bindsym $mod+shift+parenleft move container to workspace prev
+bindsym $mod+shift+parenright move container to workspace next
+# }}}
+
+# Custom Workspaces {{{
+set $ws_terminal 0:>_
+bindsym $mod+grave workspace "$ws_terminal"
+bindsym $mod+shift+grave move container to workspace "$ws_terminal"
+
+set $ws_coding 50:๐Ÿ–Š๏ธ
+bindsym $mod+c workspace "$ws_coding"
+bindsym $mod+shift+c move container to workspace "$ws_coding"
+
+set $ws_games 60:๐ŸŽฎ
+bindsym $mod+g workspace "$ws_games"
+bindsym $mod+shift+g move container to workspace "$ws_games"
+
+set $ws_music 80:๐ŸŽต
+bindsym $mod+u workspace "$ws_music"
+bindsym $mod+shift+u move container to workspace "$ws_music"
+
+set $ws_messaging 90:๐Ÿ’ฌ
+bindsym $mod+m workspace "$ws_messaging"
+bindsym $mod+shift+m move container to workspace "$ws_messaging"
+
+# Mark xwayland windows specially.
+for_window [shell="xwayland"] title_format "%title (%shell)"
+
+assign [class="^Franz$"] "$ws_messaging"
+assign [window_role="^weechat$"] "$ws_messaging"
+assign [window_role="^mutt$"] "$ws_messaging"
+assign [class="^evolution-initial$"] "$ws_messaging"
+assign [class="^kontact$"] "$ws_messaging"
+
+# NOTE: no_focus will also be ignored for the first window on a workspace as
+# there shouldnโ€™t be a reason to not focus the window in this case. This allows
+# for better usability in combination with workspace_layout. (From i3 docs)
+#no_focus [class="^Franz$"]
+#no_focus [window_role="^weechat$"]
+#no_focus [window_role="^mutt$"]
+#no_focus [class="^evolution-initial$"]
+
+## PlayOnLinux
+for_window [title="PlayOnLinux"] floating enable
+
+## Plasma/KDE: https://ryanlue.com/posts/2019-06-13-kde-i3
+# Donโ€™t treat Plasma pop-ups as full-sized windows
+for_window [class="plasmashell"] floating enable
+# Donโ€™t spawn an empty window for the Plasma Desktop
+for_window [title="Desktop โ€” Plasma"] move scratchpad
+# Donโ€™t let notifications and non-interactive pop-up windows steal focus
+#no_focus [class="plasmashell" window_type="on_screen_display"]
+# https://github.com/heckelson/i3-and-kde-plasma
+# Move notifications to top-right corner.
+#for_window [class="plasmashell" window_type="notification"] move up 400, move right 750, no_focus
+# Notifications appear in the centre of the screen. According to
+# https://old.reddit.com/r/i3wm/comments/bw1yfs/kde_notifications_appearing_in_the_centre_of/,
+# setting notifications to appear in the top-left corner gets placement right.
+no_focus [class="plasmashell" window_type="notification"]
+
+for_window [class="^Pyneedle$"] floating enable
+for_window [instance="^emacs-initial$"] floating enable
+for_window [class="^Spotify$"] move container to workspace "$ws_music"
+for_window [class="^Pidgin$"] move container to workspace "$ws_messaging"
+for_window [title="^aerc$"] move container to workspace "$ws_messaging"
+# annoying pop-up from Bluetooth network manager
+for_window [class="^.blueman-applet-real$"] kill
+# Zoom popups (e.g. "user has started sharing their screen")
+# "Normal" Zoom windows have titles other than a plain "zoom".
+for_window [class="^zoom$" title="^zoom$"] floating enable
+no_focus [class="^zoom$" title="^zoom$"]
+# }}}
+
+# Modes {{{
+mode "resize" {
+ bindsym h resize shrink width 10 px or 10 ppt
+ bindsym j resize grow height 10 px or 10 ppt
+ bindsym k resize shrink height 10 px or 10 ppt
+ bindsym l resize grow width 10 px or 10 ppt
+
+ bindsym shift+h resize shrink width 5 px or 5 ppt
+ bindsym shift+j resize grow height 5 px or 5 ppt
+ bindsym shift+k resize shrink height 5 px or 5 ppt
+ bindsym shift+l resize grow width 5 px or 5 ppt
+
+ bindsym left resize shrink width 10 px or 10 ppt
+ bindsym down resize grow height 10 px or 10 ppt
+ bindsym up resize shrink height 10 px or 10 ppt
+ bindsym right resize grow width 10 px or 10 ppt
+
+ bindsym Return mode "default"
+ bindsym Escape mode "default"
+}
+bindsym $mod+r mode "resize"
+# }}}
diff --git a/tw/services/files/waybar.css b/tw/services/files/waybar.css
new file mode 100644
index 00000000..c03025fe
--- /dev/null
+++ b/tw/services/files/waybar.css
@@ -0,0 +1,77 @@
+/* See basic example at <https://github.com/catppuccin/waybar>. */
+@import "catppuccin.css";
+
+* {
+ background: @base;
+ color: @text;
+ font-family: Fira Sans, OpenMoji, Hermit;
+ font-size: 1em;
+ border-radius: 0;
+ border: none;
+}
+
+tooltip {
+ background: @surface0;
+ border: 2px solid @surface2;
+}
+
+label.module {
+ padding: 5px;
+ background: transparent;
+ border-top: 3px solid transparent;
+}
+box.module {
+ margin: 0 5px; /* vertical, then horizontal */
+ background: transparent;
+}
+
+#workspaces button {
+ padding: 0;
+ background: transparent;
+ border-top: 3px solid transparent;
+}
+#workspaces button {
+ border-top: 3px solid @base;
+}
+#workspaces button.urgent {
+ border-top: 3px solid @yellow;
+}
+#workspaces button.focused {
+ border-top: 3px solid @blue;
+}
+
+#mode {
+ color: @red;
+ border-top: 3px solid @red;
+}
+
+#temperature {
+ border-top: 3px solid transparent;
+}
+#temperature.critical {
+ border-top: 3px solid @red;
+}
+
+#pulseaudio {
+ border-top: 3px solid @red;
+}
+#pulseaudio.bluetooth {
+ border-top: 3px solid @blue;
+}
+#pulseaudio.muted {
+ border-top: 3px solid transparent;
+}
+
+#battery {
+ border-top: 3px solid @green;
+}
+#battery.discharging.medium {
+ border-top: 3px solid transparent;
+}
+#battery.discharging.critical {
+ border-top: 3px solid @red;
+}
+
+#custom-dunst {
+ border-top: 3px solid @red;
+}
diff --git a/tw/system.scm b/tw/system.scm
index 7e7f8aa8..67dea549 100644
--- a/tw/system.scm
+++ b/tw/system.scm
@@ -1,12 +1,15 @@
(define-module (tw system)
#:use-module (ice-9 string-fun)
+ #:use-module (srfi srfi-26)
#:use-module (gnu)
#:use-module (gnu services)
#:use-module (gnu system)
#:use-module (gnu system keyboard)
#:use-module (guix gexp)
#:use-module (tw channels)
+ #:use-module (tw packages catppuccin)
#:use-module (tw packages scanner)
+ #:use-module (tw services desktop)
#:use-module (tw services wireguard))
(use-package-modules acl admin android avahi backup certs cups curl disk
@@ -32,7 +35,7 @@
(comment "Timo Wilken")
(group "users")
(home-directory "/home/timo")
- (supplementary-groups '("wheel" "netdev" "audio" "video"))
+ (supplementary-groups '("wheel" "input" "netdev" "audio" "video"))
(shell (file-append zsh "/bin/zsh")))
%base-user-accounts))
@@ -90,12 +93,15 @@
(port (format #f "~a:~a" ip port))
(else ip))))
+(define system-base-packages-service
+ (simple-service 'tw-base-packages profile-service-type
+ (list acl acpi age btrfs-progs cpupower curl efibootmgr exfat-utils git
+ glibc-locales hddtemp htop lshw lsof man-db man-pages man-pages-posix
+ mlocate moreutils nss-mdns python restic rsync strace vim wireguard-tools)))
+
(define-public (server-base-services host-name)
(cons*
- (simple-service 'tw-base-packages profile-service-type
- (list acl acpi age btrfs-progs cpupower curl efibootmgr exfat-utils git
- glibc-locales hddtemp htop lshw lsof man-db man-pages man-pages-posix
- mlocate moreutils nss-mdns python restic rsync strace vim wireguard-tools))
+ system-base-packages-service
(tw-openssh-service host-name)
@@ -197,6 +203,7 @@ ACTION!=\"remove\", SUBSYSTEM==\"leds\", GROUP=\"video\", MODE=\"0664\"
(define* (enduser-system-services
#:key
host-name cores wireless-interface backlight-device
+ (wayland? #f)
(work-system? #f)
(xorg-extra-modules '())
(xorg-drivers '()))
@@ -209,18 +216,17 @@ ACTION!=\"remove\", SUBSYSTEM==\"leds\", GROUP=\"video\", MODE=\"0664\"
(list? xorg-drivers))
(error "Invalid argument type"))
- (define xorg-config
- (xorg-configuration
- (keyboard-layout %british-keyboard)
- (extra-config (list touchpad-xorg-config))
- (modules (append xorg-extra-modules %default-xorg-modules))
- (drivers xorg-drivers)))
-
(cons*
+ system-base-packages-service
(simple-service 'tw-enduser-packages profile-service-type
(list cups docker mit-krb5 pulseaudio dosfstools mtools ntfs-3g
;; Install window manager here so gdm can see its xsession file.
- i3-wm))
+ (if wayland? swayfx i3-wm)))
+
+ (simple-service 'screen-locker pam-root-service-type
+ (list (pam-service
+ (name (if wayland? "swaylock" "i3lock"))
+ (auth (list (pam-entry (control "include") (module "login")))))))
(service docker-service-type)
@@ -240,14 +246,6 @@ ACTION!=\"remove\", SUBSYSTEM==\"leds\", GROUP=\"video\", MODE=\"0664\"
(service earlyoom-service-type
(earlyoom-configuration)) ; TODO: configure at least `avoid-regexp'
- (set-xorg-configuration xorg-config)
-
- ;; Install i3lock as a setuid binary, so it can talk to PAM.
- (service screen-locker-service-type
- (screen-locker-configuration
- (name "i3lock")
- (program (file-append i3lock "/bin/i3lock"))))
-
;; Allow anyone in the "video" group to set the display's brightness.
;; Run `udevadm info -q all /sys/class/backlight/*' to see properties.
(udev-rules-service 'backlight backlight-udev-rules #:groups '("video"))
@@ -360,30 +358,73 @@ ACTION!=\"remove\", SUBSYSTEM==\"leds\", GROUP=\"video\", MODE=\"0664\"
(string-append #$(file-append util-linux "/sbin/fstrim")
" --fstab --verbose"))))
- (modify-services (append %system-channel-services %desktop-services)
- (guix-service-type
- config =>
- (guix-configuration
- (inherit config)
- (channels %system-channels)))
+ (if wayland?
+ (wayland-enduser-base-services)
+ (x11-enduser-base-services work-system? xorg-extra-modules xorg-drivers))))
- ;; Let sane find the airscan backend. ipp-usb needs to be running separately.
- (sane-service-type _ => sane-backends/airscan)
+(define enduser-base-services
+ (modify-services (append %system-channel-services %desktop-services)
+ (guix-service-type
+ config =>
+ (guix-configuration
+ (inherit config)
+ (channels %system-channels)))
+ ;; Let sane find the airscan backend. ipp-usb needs to be running separately.
+ (sane-service-type _ => sane-backends/airscan)
+
+ (geoclue-service-type
+ config =>
+ (geoclue-configuration
+ (inherit config)
+ (applications
+ (cons* (geoclue-application "redshift" #:system? #f)
+ %standard-geoclue-applications))))
+
+ (login-service-type config => (tw-login-configuration config))))
+
+(define (x11-enduser-base-services work-system? xorg-extra-modules xorg-drivers)
+ (define xorg-config
+ (xorg-configuration
+ (keyboard-layout %british-keyboard)
+ (extra-config (list touchpad-xorg-config))
+ (modules (append xorg-extra-modules %default-xorg-modules))
+ (drivers xorg-drivers)))
+
+ (cons*
+ (set-xorg-configuration xorg-config)
+ (modify-services enduser-base-services
(gdm-service-type
config =>
(gdm-configuration
(inherit config)
(auto-login? #f)
(default-user (if work-system? "twilken" "timo"))
- (xorg-configuration xorg-config)))
-
- (geoclue-service-type
- config =>
- (geoclue-configuration
- (inherit config)
- (applications
- (cons* (geoclue-application "redshift" #:system? #f)
- %standard-geoclue-applications))))
+ (xorg-configuration xorg-config))))))
- (login-service-type config => (tw-login-configuration config)))))
+(define (wayland-enduser-base-services)
+ (cons*
+ (service greetd-service-type
+ (greetd-configuration
+ (terminals
+ (list (greetd-terminal-configuration
+ (terminal-switch #t)
+ (default-session-command
+ (greetd-wlgreet-sway-session
+ (sway-configuration %sway-common-configuration)
+ (wlgreet-session
+ (greetd-wlgreet-session
+ (command (file-append swayfx "/bin/sway"))
+ (scale 1) ; TODO
+ ;; Catppuccin colours.
+ ;; Note: if these are Guile rationals, they will be written
+ ;; to wlgreet.toml in fractional form and wlgreet will crash.
+ (background '(0.12 0.12 0.18 1.0)) ; base
+ (headline '(0.80 0.84 0.95 1.0)) ; text
+ (prompt '(0.80 0.84 0.95 1.0)) ; text
+ (prompt-error '(0.97 0.88 0.68 1.0)) ; yellow
+ (border '(0.35 0.36 0.44 1.0))))))))))) ; sway window border
+ (modify-services enduser-base-services
+ ;; Not needed for pure Wayland, but Zoom uses xwayland.
+ ;; (delete x11-socket-directory-service-type)
+ (delete gdm-service-type))))
diff --git a/tw/system/cern.scm b/tw/system/cern.scm
index 362ff9e0..1ca01508 100644
--- a/tw/system/cern.scm
+++ b/tw/system/cern.scm
@@ -17,8 +17,8 @@
#:use-module (tw services wireguard)
#:use-module (tw system))
-(use-package-modules certs cups disk docker file-systems gnome kerberos linux
- mtools pulseaudio search shells wm xorg)
+(use-package-modules certs cups disk docker file-systems freedesktop gnome
+ kerberos linux mtools pulseaudio search shells wm xorg)
(use-service-modules admin authentication avahi base cups dbus desktop docker
kerberos linux mcron networking pm shepherd ssh syncthing
@@ -29,10 +29,6 @@
(define guixsd-root-partition ; /dev/nvme0n1p2
(uuid "933d1bec-14ec-4421-aa4d-93846c68f27c" 'btrfs))
-(define custom-xorg-config
- (xorg-configuration
- (keyboard-layout %british-keyboard)))
-
(define-public %cern-system
(operating-system
(host-name "twilkenlaptop.cern.ch")
@@ -48,7 +44,7 @@
;; The MT7921E module is for the card connected via PCIe, which it is
;; (it's in an M.2 slot). Alternatives are S (SDIO) and U (USB).
(kernel nongnu:linux)
- ;; (kernel-loadable-modules (list ddcci-driver-linux)) ; TODO: disabled because the package fails to build
+ (kernel-loadable-modules (list ddcci-driver-linux v4l2loopback-linux-module))
(initrd nongnu:microcode-initrd)
(firmware (cons* nongnu:i915-firmware nongnu:ibt-hw-firmware nongnu:sof-firmware
nongnu:iwlwifi-firmware %base-firmware))
@@ -99,7 +95,8 @@
;; We need to preserve $TERMINFO so that programs under sudo can
;; find kitty's terminfo files. This is possibly unsafe; sudo
;; explicitly deletes this variable by default.
- "Defaults env_keep += \"TERMINFO\"\n"
+ "Defaults env_keep += \"TERMINFO\"\n" ; for kitty
+ "Defaults env_keep += \"TERMINFO_DIRS\"\n" ; for foot
(plain-file-content %sudoers-specification)
;; In addition to the default rules, allow admins to power off
;; the computer. They'll have to use the system binaries, not
@@ -127,17 +124,6 @@
(sched-powersave-on-bat? #t)
(cpu-boost-on-ac? #t)))
- (service unattended-upgrade-service-type
- (unattended-upgrade-configuration
- (schedule "0 22 * * *") ; every night at 22:00
- (maximum-duration (* 40 60)) ; 40 minutes
- (channels #~(@ (tw channels) %system-channels))
- (operating-system-expression
- #~(@ (tw system cern) %cern-system))
- (services-to-restart
- ;; Anything that won't cause disruption when restarting.
- '(mcron earlyoom thermald))))
-
(service openntpd-service-type
(openntpd-configuration
;; Use CERN time servers.
@@ -149,6 +135,7 @@
#:host-name host-name
#:cores 12
#:work-system? #t
+ #:wayland? #t
#:wireless-interface "wlp0s20f3"
#:backlight-device "intel_backlight")
;; openntpd works better.
diff --git a/tw/theme.scm b/tw/theme.scm
index a6837e2d..543504d9 100644
--- a/tw/theme.scm
+++ b/tw/theme.scm
@@ -50,6 +50,11 @@
(file-append catppuccin-emacs-theme
"/share/catppuccin/emacs/catppuccin-theme.el"))
+(define-public catppuccin-foot
+ (file-append catppuccin-foot-theme
+ (string-append "/share/catppuccin/foot/catppuccin-"
+ catppuccin-theme-variant ".ini")))
+
(define-public catppuccin-kdeglobals
(file-append catppuccin-kde-theme
(string-append "/share/color-schemes/Catppuccin"
@@ -86,11 +91,21 @@
(("JetBrainsMono Nerd Font 14") "Fira Sans 12") ; default font
(("border-col: #[0-9a-f]*;") "border-col: #585b70;")))))) ; i3 border colour
+(define-public catppuccin-swaylock
+ (file-append catppuccin-swaylock-theme
+ (string-append "/share/catppuccin/swaylock/"
+ catppuccin-theme-variant ".conf")))
+
(define-public catppuccin-vim
(file-append catppuccin-vim-theme
(string-append "/share/catppuccin/vim/colors/catppuccin_"
catppuccin-theme-variant ".vim")))
+(define-public catppuccin-waybar
+ (file-append catppuccin-waybar-theme
+ (string-append "/share/catppuccin/waybar/"
+ catppuccin-theme-variant ".css")))
+
(define-public catppuccin-zathura
(file-append catppuccin-zathura-theme
(string-append "/share/catppuccin/zathura/catppuccin-"