diff options
Diffstat (limited to 'tw/services')
-rw-r--r-- | tw/services/desktop.scm | 130 | ||||
-rw-r--r-- | tw/services/files/polybar.ini | 239 |
2 files changed, 369 insertions, 0 deletions
diff --git a/tw/services/desktop.scm b/tw/services/desktop.scm new file mode 100644 index 00000000..b0bb4e8a --- /dev/null +++ b/tw/services/desktop.scm @@ -0,0 +1,130 @@ +(define-module (tw services desktop) + #:use-module (gnu) + #:use-module (gnu home services) + #:use-module (gnu home services shepherd) + #:use-module ((gnu packages networking) #:select (blueman)) + #:use-module ((gnu packages wm) #:select (polybar)) + #:use-module ((gnu packages xdisorg) #:select (numlockx hsetroot)) + #:use-module ((gnu packages xorg) #:select (xrandr xset)) + #:use-module (gnu services configuration) + #:use-module (guix gexp) + #:use-module (guix packages) + #:use-module ((guix records) #:select (match-record)) + #:use-module (srfi srfi-1) + #:use-module ((tw theme) #:select (catppuccin-polybar)) + #:export (home-desktop-layout-configuration + home-monitor-configuration + home-desktop-layout-service-type + home-blueman-service-type)) + + +;; Monitor layout and polybars + +(define (list-of-strings? thing) + (and (list? thing) (every string? thing))) + +(define-configuration/no-serialization home-monitor-configuration + (name string "The monitor's name in X11.") + (xrandr-options (list-of-strings '()) "Options to pass to xrandr to +configure this monitor.")) + +(define (list-of-monitors? thing) + (and (list? thing) (every home-monitor-configuration? thing))) + +(define-configuration/no-serialization home-desktop-layout-configuration + (desktop-background string "Path to an image that will be set as the desktop +background. An initial @code{~/} is replaced with $HOME/.") + (monitors list-of-monitors "List of monitor declarations to apply.")) + +(define (polybar-config monitors) + `(("polybar/config.ini" ,(local-file "files/polybar.ini")) + ("polybar/catppuccin.ini" ,catppuccin-polybar))) + +(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 (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 (desktop-layout-services config) + (match-record config <home-desktop-layout-configuration> + (desktop-background monitors) + (cons* (shepherd-service + (documentation "Set up X displays on login.") + (provision '(xorg-setup)) + (one-shot? #t) + (start #~(lambda _ + (define (replace-home path) + (if (string-prefix? "~/" path) + (string-replace path (getenv "HOME") 0 1) + path)) + (system* #$(file-append numlockx "/bin/numlockx") "on") + ;; Turn off the monitors if there is no input for 10 minutes. + (system* #$(file-append xset "/bin/xset") "dpms" "600" "600" "600") + ;; TODO: may need one xrandr invocation per monitor; this is + ; ;what tw/home/cern.scm had before. + (system* #$(file-append xrandr "/bin/xrandr") + #$@(append-map (lambda (monitor) + (match-record monitor <home-monitor-configuration> + (name xrandr-options) + `("--output" ,name ,@xrandr-options))) + monitors)) + ;; Set the desktop background picture. Hopefully doing this just after + ;; xrandr works and sets it for both screens. + (system* #$(file-append hsetroot "/bin/hsetroot") + "-cover" (replace-home #$desktop-background))))) + (map (compose polybar-service home-monitor-configuration-name) monitors)))) + +(define home-desktop-layout-service-type + (service-type + (name 'desktop-layout) + (extensions + (list (service-extension home-shepherd-service-type desktop-layout-services) + (service-extension home-xdg-configuration-files-service-type polybar-config))) + (description + "Configure the desktop background, monitor layout and polybar."))) + + +;; Blueman + +(define (blueman-services config) + (list (shepherd-service + (documentation "Blueman applet; provides a GUI for connection to bluetooth devices.") + (provision '(blueman-applet)) + (start #~(make-forkexec-constructor + (list #$(file-append blueman "/bin/blueman-applet")))) + (stop #~(make-kill-destructor))))) + +(define home-blueman-service-type + (service-type + (name 'blueman) + (default-value #f) + (extensions + (list (service-extension home-shepherd-service-type blueman-services))) + (description + "Run the Blueman applet for graphical Bluetooth control."))) diff --git a/tw/services/files/polybar.ini b/tw/services/files/polybar.ini new file mode 100644 index 00000000..201c5131 --- /dev/null +++ b/tw/services/files/polybar.ini @@ -0,0 +1,239 @@ +; -*- mode: conf-windows; -*- + +[global/wm] +include-file = catppuccin.ini + +[colors] +background = ${colors.base} +background-alt = ${colors.surface0} +primary = ${colors.blue} +alert = ${colors.yellow} +disabled = ${colors.overlay2} +empty-bar = ${colors.surface2} + +[settings] +screenchange-reload = true + +[bar/primary] +monitor = ${env:POLYBAR_MONITOR} +width = 100% +height = 24pt +radius = 0 +line-size = 3pt +line-color = ${colors.primary} +border-size = 0 +padding-left = 0 +padding-right = 2 +module-margin = 2 + +background = ${colors.background} +foreground = ${colors.text} + +; font-N = <fontconfig pattern>;<vertical offset> +font-0 = Fira Sans:size=11;2 +; Some workspace names have emojis in them. +; Using Noto Emoji means emojis would be much too big and colourful. +font-1 = OpenMoji:style=Black:size=11;3 +; Hermit is needed for Unicode block chars. +font-2 = Hermit:size=10;1 + +separator = ยท +separator-foreground = ${colors.disabled} + +modules-left = i3 xwindow +modules-right = wlan eth memory cpu temp xkeyboard pulseaudio dunst battery date +tray-position = right + +enable-ipc = true + +cursor-click = pointer +cursor-scroll = ns-resize + +[module/i3] +type = internal/i3 +pin-workspaces = false +show-urgent = true +strip-wsnumbers = true +index-sort = true +label-mode-foreground = ${colors.alert} +label-mode-background = ${colors.background-alt} +label-mode-padding = 2 +label-focused-overline = ${colors.primary} +label-focused-padding = 1 +label-urgent-foreground = ${colors.alert} +label-urgent-background = ${colors.background-alt} +label-urgent-padding = 1 +label-unfocused-padding = 1 +label-visible-padding = 1 + +[module/xwindow] +type = internal/xwindow +label = %title% +label-maxlen = 120 + +[module/pulseaudio] +type = internal/pulseaudio +format-volume = <ramp-volume> <label-volume> +label-volume = %percentage%% +label-muted = ๐ +label-muted-foreground = ${colors.disabled} + +ramp-volume-0 = ๐ +ramp-volume-1 = ๐ +ramp-volume-2 = ๐ +ramp-volume-0-foreground = ${colors.primary} +ramp-volume-1-foreground = ${colors.primary} +ramp-volume-2-foreground = ${colors.primary} + +[module/xkeyboard] +type = internal/xkeyboard +blacklist-0 = num lock +; hide xkeyboard module unless Caps Lock is pressed +label-layout = +label-indicator-padding = 1 +label-indicator-margin = 0 +label-indicator-foreground = ${colors.alert} +label-indicator-background = ${colors.background-alt} + +[module/memory] +type = internal/memory +interval = 1 +format = <label> <ramp-used> +format-prefix = "RAM " +format-prefix-foreground = ${colors.primary} +format-warn-prefix = "RAM " +format-warn-prefix-foreground = ${colors.primary} +label = %used% +label-warn = %free% left +label-warn-foreground = ${colors.alert} +label-warn-background = ${colors.background-alt} + +ramp-used-0 = โ +ramp-used-1 = โ +ramp-used-2 = โ +ramp-used-3 = โ +ramp-used-4 = โ
+ramp-used-5 = โ +ramp-used-6 = โ +ramp-used-7 = โ +ramp-used-0-foreground = ${colors.empty-bar} +ramp-used-1-foreground = ${colors.primary} +ramp-used-2-foreground = ${colors.primary} +ramp-used-3-foreground = ${colors.primary} +ramp-used-4-foreground = ${colors.primary} +ramp-used-5-foreground = ${colors.alert} +ramp-used-6-foreground = ${colors.alert} +ramp-used-7-foreground = ${colors.alert} + +[module/cpu] +type = internal/cpu +interval = 1 +format = <ramp-coreload> +format-prefix = "CPU " +format-prefix-foreground = ${colors.primary} + +; Spacing (number of spaces, pixels, points) between individual per-core ramps +ramp-coreload-spacing = 1 +ramp-coreload-0 = โ +ramp-coreload-1 = โ +ramp-coreload-2 = โ +ramp-coreload-3 = โ +ramp-coreload-4 = โ
+ramp-coreload-5 = โ +ramp-coreload-6 = โ +ramp-coreload-7 = โ +ramp-coreload-0-foreground = ${colors.empty-bar} +ramp-coreload-1-foreground = ${colors.primary} +ramp-coreload-2-foreground = ${colors.primary} +ramp-coreload-3-foreground = ${colors.primary} +ramp-coreload-4-foreground = ${colors.primary} +ramp-coreload-5-foreground = ${colors.primary} +ramp-coreload-6-foreground = ${colors.alert} +ramp-coreload-7-foreground = ${colors.alert} + +[module/temp] +type = internal/temperature +; head /sys/class/thermal/thermal_zone*/type +thermal-zone = 1 +format-prefix = "๐ก " +format-prefix-foreground = ${colors.primary} +format-warn-prefix = "๐ก " +format-warn-prefix-foreground = ${colors.primary} +label-warn-foreground = ${colors.alert} +label-warn-background = ${colors.background-alt} + +[network-base] +type = internal/network +interval = 5 +format-connected = <label-connected> +format-packetloss = <animation-packetloss> <label-connected> +; Hide completely if disconnected. +format-disconnected = + +animation-packetloss-0 = โ +animation-packetloss-0-foreground = ${colors.alert} +animation-packetloss-0-background = ${colors.background-alt} +animation-packetloss-1 = ๐ถ +animation-packetloss-1-foreground = ${colors.alert} +animation-packetloss-1-background = ${colors.background-alt} +; Framerate in milliseconds +animation-packetloss-framerate = 500 +; Don't display "B/s" suffix, only e.g. "5 K" for compactness. +speed-unit = + +[module/wlan] +inherit = network-base +interface-type = wireless +format-connected = <ramp-signal> <label-connected> +label-connected = %essid% โ %downspeed% โ %upspeed% +; label-connected-foreground = ${colors.green} + +ramp-signal-0 = ๐ถ +ramp-signal-1 = ๐ถ +ramp-signal-2 = ๐ถ +ramp-signal-0-foreground = ${colors.red} +ramp-signal-1-foreground = ${colors.green} +ramp-signal-2-foreground = ${colors.green} + +[module/eth] +inherit = network-base +interface-type = wired +label-connected = โ %downspeed% โ %upspeed% +format-connected-prefix = "๐ " +format-connected-prefix-foreground = ${colors.green} + +[module/battery] +type = internal/battery +low-at = 25 +time-format = %-Hh%Mm +format-discharging = <ramp-capacity> <label-discharging> +label-discharging = %percentage%% %time% %consumption%W +format-charging = <label-charging> +format-charging-prefix = "๐ " +format-charging-prefix-foreground = ${colors.green} +label-charging = %percentage%% %time% +format-full = + +ramp-capacity-0 = ๐ +ramp-capacity-1 = ๐ +ramp-capacity-2 = ๐ +ramp-capacity-0-foreground = ${colors.red} +ramp-capacity-1-foreground = ${colors.yellow} +ramp-capacity-2-foreground = ${colors.green} + +[module/date] +type = internal/date +interval = 1 +date = %a %e %b +time = %H:%M +date-alt = %Y-%m-%d +time-alt = %H:%M:%S +label = %date%, %time% + +[module/dunst] +type = custom/script +; Only show a "slience" emoji when notifications are paused; nothing otherwise. +exec = "case $(dunstctl is-paused) in false) echo;; true) echo '๐';; esac" +format = <label> +format-foreground = ${colors.alert} +format-background = ${colors.background-alt} |