After using Sway as my daily Wayland compositor for quite some time, I recently made the switch to Hyprland. The decision wasn’t made lightly, as Sway, especially with the SwayFX fork, served me well. However, Hyprland’s growing community and advanced feature set made it an attractive choice.
# Why Hyprland?
The main reasons for switching are:
Community Size: Hyprland has a much larger and more active community. This means more contributions, faster development, and better support.
Advanced Features: Hyprland offers built-in window animations, hybrid tiling and floating layouts, and fine-grained customization that surpass what Sway provides out of the box.
Modern Approach: The configuration syntax is modern and expressive, making it easier to maintain.
Check my latest Lisp based configuration of Hyprland here: https://codeberg.org/jjba23/sss/src/branch/trunk/lib/hyprland.scm
# SwayFX Configuration (For Posterity)
I wanted to archive my custom SwayFX configuration, which was written entirely in Lisp using Guix’s home-services. This setup, part of the Supreme Sexp System (SSS), includes dynamic wallpapers, custom keybindings, and aesthetic tweaks like rounded corners and blur effects.
Here is the full configuration:
;;; SSS - Supreme Sexp System ;; Copyright (C) 2025 - Josep Bigorra, jjba23 <jjbigorra@gmail.com> ;; sss is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. ;; sss is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with sss. If not, see <https://www.gnu.org/licenses/>. (load "./palette.scm") (define-module (sss sway) #:use-module (gnu home) #:use-module (gnu home services) #:use-module (gnu home services shells) #:use-module (gnu packages emacs) #:use-module (gnu packages wm) #:use-module (gnu packages terminals) #:use-module (gnu packages admin) #:use-module (gnu home services shepherd) #:use-module (gnu system keyboard) #:use-module (guix gexp) #:use-module (gnu home services sway) #:use-module (gnu home services sound) #:use-module (gnu home services desktop) #:use-module (sss palette)) (define sss-sway-gestures `((swipe:3:right . "workspace next_on_output") (swipe:3:left . "workspace prev_on_output") (swipe:3:down . "move to scratchpad") (swipe:3:up . "scratchpad show"))) ;; Defines a list of application identifiers for floating windows in Sway. ;; These applications are specified to open as floating windows, ;; ensuring they don't tile with other windows and maintain a distinct ;; appearance for usability. (define sss-sway-floating-windows `("org.kde.kcalc" "org.gnome.Calculator" "pavucontrol" "org.jointhefreeworld.metainfog")) ;; Define diverse wallpapers based on the active color scheme. (begin (define* (sss-sway-wallpaper #:key sss-clone-dir sss-active-palette) (cond ((equal? 'sss-palette-ef-cyprus sss-active-palette) (format #f "~a/resources/wallpapers/some-forest.jpg" sss-clone-dir)) ((equal? 'sss-palette-ef-dream sss-active-palette) (format #f "~a/resources/wallpapers/1362745.png" sss-clone-dir)) ((equal? 'sss-palette-heavy-metal sss-active-palette) (format #f "~a/resources/wallpapers/heavy-wall3.jpg" sss-clone-dir)) ((equal? 'sss-palette-solarized-light sss-active-palette) (format #f "~a/resources/wallpapers/ofcoisp7abfe1.jpeg" sss-clone-dir)) ((equal? 'sss-palette-ef-autumn sss-active-palette) (format #f "~a/resources/wallpapers/0mar2ygf59je1.jpeg" sss-clone-dir)) (else (format #f "~a/resources/wallpapers/some-forest.jpg" sss-clone-dir)))) (export sss-sway-wallpaper)) (define* (sss-sway-startup-programs #:key (wallpaper-setter "") (extra-startups '())) (append extra-startups `("lxsession" "mako" "dbus-update-activation-environment --all" "emacs --daemon" "waybar" "foot -s" "transmission-daemon" ,(format #f "swww-daemon & sleep 1 && ~a" wallpaper-setter) "conky -d" "podman system service --time=0 unix:///tmp/podman.sock"))) (define* (sss-sway-startup-reload-programs #:key sss-active-palette) (let ((gtk-theme-name (cond ((equal? 'sss-palette-ef-cyprus sss-active-palette) "Yaru-sage") ((equal? 'sss-palette-heavy-metal sss-active-palette) "Yaru-red-dark") ((equal? 'sss-palette-ef-dream sss-active-palette) "Yaru-magenta-dark") ((equal? 'sss-palette-ef-autumn sss-active-palette) "Yaru-dark") ((equal? 'sss-palette-solarized-light sss-active-palette) "Yaru") (else "Yaru-sage-dark"))) (icon-theme-name (cond ((equal? 'sss-palette-ef-cyprus sss-active-palette) "Yaru-sage") ((equal? 'sss-palette-heavy-metal sss-active-palette) "Yaru-red-dark") ((equal? 'sss-palette-ef-dream sss-active-palette) "Yaru-magenta-dark") ((equal? 'sss-palette-ef-autumn sss-active-palette) "Yaru-dark") ((equal? 'sss-palette-solarized-light sss-active-palette) "Yaru") (else "Yaru-sage-dark")))) `(,(format #f "gsettings set $gnome-schema gtk-theme '~a'" gtk-theme-name) , (format #f "gsettings set $gnome-schema icon-theme '~a'" icon-theme-name) "gsettings set $gnome-schema cursor-theme 'Yaru'" "gsettings set $gnome-schema cursor-size 24" "gsettings set $gnome-schema font-name 'Inter'"))) (begin (define* (sss-sway-outputs #:key sss-clone-dir) (list (sway-output (identifier '*)))) (export sss-sway-outputs)) (begin (define* (sss-sway-variables #:key sss-clone-dir sss-active-palette) `((mod . "Mod4") (left . "Left") (down . "Down") (up . "Up") (right . "Right") (gnome-schema . "org.gnome.desktop.interface") (editor . "emacsclient -c") (bloated-browser . "google-chrome") (browser . "QT_QPA_PLATFORM=xcb qutebrowser") (term . "footclient") (wallpaper-setter unquote (format #f "swww img ~a --transition-step 10 --transition-fps 30 --transition-type center" (sss-sway-wallpaper #:sss-clone-dir sss-clone-dir #:sss-active-palette sss-active-palette))) (password-manager . "$HOME/.nix-profile/bin/1password") (locker unquote (string-join '("swaylock" "--screenshots" "--clock" "--indicator" "--indicator-radius 100" "--indicator-thickness 7" "--effect-blur 7x5" "--effect-vignette 0.5:0.5" "--ring-color bb00cc" "--key-hl-color 880033" "--line-color 00000000" "--inside-color 00000088" "--separator-color 00000000" "--grace 2" "--fade-in 0.2") " ")) (menu . "rofi -show drun") (runner . "rofi -show run") (windower . "rofi -show window"))) (export sss-sway-variables)) (define sss-sway-modes (list (sway-mode (mode-name "resize") (keybindings '(($left . "resize shrink width 10px") ($down . "resize grow height 10px") ($up . "resize shrink height 10px") ($right . "resize grow width 10px") (Return . "mode \"default\"") (Escape . "mode \"default\"")))))) (define-public sss-sway-keybindings `(($mod+Return . "exec $term") ($mod+t . "exec $term") ($mod+shift+period . "exec grimshot copy screen") ($mod+period . "exec grimshot save screen") ($mod+shift+comma . "exec grimshot copy area") ($mod+comma . "exec grimshot save area") ($mod+k . "kill") ($mod+l . "exec $locker") ($mod+Shift+b . "exec $wallpaper-setter") ($mod+slash . "exec $menu") ($mod+i . "exec $browser") ($mod+Shift+i . "exec $bloated-browser") ($mod+e . "exec $editor") ($mod+minus . "exec $password-manager") ($mod+Shift+c . "reload") ($mod+$left . "focus left") ($mod+$down . "focus down") ($mod+$up . "focus up") ($mod+$right . "focus right") ($mod+Shift+$left . "move left") ($mod+Shift+$down . "move down") ($mod+Shift+$up . "move up") ($mod+Shift+$right . "move right") ($mod+p . "workspace prev_on_output") ($mod+n . "workspace next_on_output") ($mod+1 . "workspace number 1") ($mod+2 . "workspace number 2") ($mod+3 . "workspace number 3") ($mod+4 . "workspace number 4") ($mod+5 . "workspace number 5") ($mod+6 . "workspace number 6") ($mod+7 . "workspace number 7") ($mod+8 . "workspace number 8") ($mod+9 . "workspace number 9") ($mod+0 . "workspace number 10") ($mod+Shift+1 . "move container to workspace number 1") ($mod+Shift+2 . "move container to workspace number 2") ($mod+Shift+3 . "move container to workspace number 3") ($mod+Shift+5 . "move container to workspace number 5") ($mod+Shift+4 . "move container to workspace number 4") ($mod+Shift+6 . "move container to workspace number 6") ($mod+Shift+7 . "move container to workspace number 7") ($mod+Shift+8 . "move container to workspace number 8") ($mod+Shift+9 . "move container to workspace number 9") ($mod+Shift+0 . "move container to workspace number 10") ($mod+b . "splith") ($mod+v . "splitv") ($mod+s . "layout stacking") ($mod+w . "layout tabbed") ($mod+h . "layout toggle split") ($mod+f . "fullscreen") ($mod+Shift+space . "floating toggle") ($mod+space . "focus mode_toggle") ($mod+a . "focus parent") ($mod+Shift+minus . "move scratchpad") ($mod+Shift+m . "sway output Virtual-1 mode 1920x1200") ($mod+Shift+s . "scratchpad show") ($mod+r . "exec $runner") (Alt+tab . "exec $windower") ($mod+Shift+e unquote #~(string-append "exec " #$sway "/bin/swaynag -t warning -m \\\n " "'You pressed the exit shortcut. Do you really want to exit sway?" " This will end your Wayland session.' \\ " "-B 'Yes, exit sway' \\\n '" #$sway "/bin/swaymsg exit'")) (XF86MonBrightnessDown . "exec sudo light -U 3") (XF86MonBrightnessUp . "exec sudo light -A 3") (XF86AudioRaiseVolume . "exec pactl set-sink-volume @DEFAULT_SINK@ +5%") (XF86AudioLowerVolume . "exec pactl set-sink-volume @DEFAULT_SINK@ -5%") (XF86AudioMute . "exec pactl set-sink-mute @DEFAULT_SINK@ toggle") (XF86AudioMicMute . "exec pactl set-source-mute @DEFAULT_SOURCE@ toggle") (XF86AudioPlay . "exec playerctl play-pause") (XF86AudioNext . "exec playerctl next") (XF86AudioPrev . "exec playerctl previous") ($mod+Shift+r . "mode \"resize\""))) (define sss-swayfx-config `("corner_radius 12" "shadows enable" "blur enable" "default_dim_inactive 0.2" "dim_inactive_colors.unfocused #000000FF" "dim_inactive_colors.urgent #900000FF")) (define* (sss-sway-extra-content #:key sss-active-palette) `("gaps inner 12" "gaps outer 8" ;; class border backgr. text indicator child_border ,(format #f "client.focused ~a ~a ~a ~a ~a" (sss-get-color sss-active-palette 'primary) (sss-get-color sss-active-palette 'primary) (sss-get-color sss-active-palette 'text) (sss-get-color sss-active-palette 'primary) (sss-get-color sss-active-palette 'primary)) ,(format #f "client.focused_inactive ~a ~a ~a ~a ~a" (sss-get-color sss-active-palette 'primary) (sss-get-color sss-active-palette 'primary) (sss-get-color sss-active-palette 'text) (sss-get-color sss-active-palette 'primary) (sss-get-color sss-active-palette 'primary)) ,(format #f "client.unfocused ~a ~a #808f80 ~a ~a" (sss-get-color sss-active-palette 'background-l) (sss-get-color sss-active-palette 'background-l) (sss-get-color sss-active-palette 'background-l) (sss-get-color sss-active-palette 'background-l)) "client.urgent #b02930 #b02930 #cfdfd5 #900000 #900000" "client.placeholder #000000 #0c0c0c #cfdfd5 #000000 #0c0c0c" ,(format #f "client.background ~a" (sss-get-color sss-active-palette 'text)) ,(format #f "seat seat0 xcursor_theme ~a ~a" "Yaru" "24"))) (begin (define* (sss-sway-service-type #:key sss-clone-dir sss-keyboard-layout sss-keyboard-caps-to-ctrl sss-active-palette sss-sway-extra-startups) (service home-sway-service-type (sway-configuration (packages (list swayfx)) (gestures sss-sway-gestures) (startup-programs (sss-sway-startup-programs #:wallpaper-setter (format #f "swww img ~a --transition-step 10 --transition-fps 30 --transition-type center" (sss-sway-wallpaper #:sss-active-palette sss-active-palette #:sss-clone-dir sss-clone-dir)) #:extra-startups sss-sway-extra-startups)) (startup+reload-programs (sss-sway-startup-reload-programs #:sss-active-palette sss-active-palette)) (outputs (sss-sway-outputs #:sss-clone-dir sss-clone-dir)) (inputs (list (sway-input (identifier "type:keyboard") (layout (keyboard-layout sss-keyboard-layout #:options (cond (sss-keyboard-caps-to-ctrl ' ("ctrl:nocaps")) (else '()))))) (sway-input (identifier "type:touchpad") (tap #t)))) (variables (sss-sway-variables #:sss-active-palette sss-active-palette #:sss-clone-dir sss-clone-dir)) (modes sss-sway-modes) (keybindings sss-sway-keybindings) (extra-content (append sss-swayfx-config (map (lambda (w) (format #f "for_window [app_id=\"~a\"] floating enable" w)) sss-sway-floating-windows) (sss-sway-extra-content #:sss-active-palette sss-active-palette)))))) (export sss-sway-service-type))
# Final Thoughts
Switching to Hyprland feels like a step forward into a more vibrant ecosystem (and nice and shiny graphics). Sway will always hold a special place in my heart as the first tiling Wayland compositor I customized with Lisp. However, Hyprland’s polish and active development make it the ideal choice for the Supreme Sexp System moving forward.