Roll your own Linux desktop using Sway

Wayland is the future of graphical desktops on Linux.
With the arrival of the latest stable release of Debian I decided that - instead of my usual setup of Xorg + Openbox - I would explore Wayland and a different desktop environment.
The first big change in making the switch is that - whereas Xorg the (graphical) server and the chosen (graphical) desktop client are separate entities - in Wayland they are one and the same thing and are called compositors. You can't simply drop Openbox or GNOME on top of Wayland. Each desktop must be created or re-written for Wayland.
The next big change is what to do about the array of utilities typically used in an X session: either use Wayland-native replacements, or continue to use - if possible - the current apps courtesy of Xwayland (an X server for running X clients under Wayland).
Browsing through the list of Wayland compositors, it appears that Sway is one of most solid implementations currently available. Another point in favour of Sway is that its already packaged in Debian, so I decided to start there.
I've never used i3 window manager (which Sway is modelled on) or a tiling environment (with windows arranged in a grid vs "floating" in Openbox) for any length of time, but after making the switch to Sway and a few weeks of use I find myself liking it very much!
Sway quickly gets you 90% towards a usable desktop. Its that 10% where you're replacing all your X11 tools and crafting your own desktop just the way you like it that takes some experimenting!
This is how I do it, with links to my config files ...
1. Install
My setup: Laptop is a Thinkpad T480s with Intel video, running Debian 12 aka "Bookworm", attached to a 32" 2560x1440 external display.
Install the Sway compositor and a few essentials ...
$ sudo apt install sway swaybg swayidle swaylock xdg-desktop-portal-wlr xwayland
Some extras that I add and use in this HOWTO ...
$ sudo apt install adwaita-qt alsa-utils brightnessctl copyq fonts-dejavu fonts-firacode fonts-font-awesome fonts-ubuntu grimshot gthumb libglib2.0-bin libgtk-3-0 libgtk-4-1 libnotify-bin mako-notifier network-manager network-manager-gnome papirus-icon-theme pipewire-audio qt5-style-plugins qt5ct waybar wob wofi x11-utils
2. Start
I don't use a login manager, so to start Sway from a tty console simply run ...
$ sway
That's it to get started!
There are a few environmental variables that should be set when running sway
. There are a few different methods to accomplish this.
I found it convenient to create a small script - startw
- that includes these variables ...
#!/bin/sh
# Set env variables when starting a wayland session
export ANKI_WAYLAND=1
export MOZ_ENABLE_WAYLAND=1
export WLR_DRM_NO_MODIFIERS=1
# For sway
export XDG_CURRENT_DESKTOP=sway
sway $@
Run ...
$ startw
Source: startw
3. Custom configuration
To begin customizing your own Sway experience there are two possible methods:
- copy the sample configuration installed on the system into $HOME and make changes to a single, unified file
- or copy the sample configuration installed on the system into $HOME and make changes split across several sub-files (my preferred method)
Method 1: Single config
Create a new Sway directory in HOME for the custom configuration ...
$ mkdir -p ~/.config/sway
Create a new config
file by copying the sample configuration /etc/sway/config
to ~/.config/sway/config
...
$ cp /etc/sway/config ~/.config/sway/config
Make any desired modifications. Enable any changes made in the current session by reloading the config with the key combo Super+Shift+c
.
Method 2: Config with sub-files
I favour the modular approach of splitting the configuration into smaller sub-files, finding it easier to modify discrete components of the Sway config vs working with a single large file.
Create a new Sway directory in HOME for the custom configuration ...
$ mkdir -p ~/.config/sway/config.d
Create a new default
configuration file by copying the sample configuration /etc/sway/config
to ~/.config/sway/config.d/default
...
$ cp /etc/sway/config ~/.config/sway/config.d/default
Most of the changes will be made in sub-files that we create from scratch.
Note: Some of those changes stored in sub-files will involve deleting the corresponding entry in default
(otherwise you may have conflicting settings being loaded).
Create a new config
file as ~/.config/sway/config
that will load the sub-files in the config.d
directory ...
# Config for sway
#
# Read `man 5 sway` for a complete reference.
# user config directory
include $HOME/.config/sway/config.d/*
Enable any changes made in the current session by reloading the config with the key combo Super+Shift+c
.
Sources:
3.1 Application defaults
Assign certain applications and windows to open on certain workspaces and/or open in "floating" (non-tiling) mode.
Source: .config/sway/config.d/application_defaults
3.2 Autostart applications
Set certain applications to start when Sway is launched:
- desktop notifications: mako
- network manager: nm-applet
- clipboard: copyq
- terminal: foot
Source: .config/sway/config.d/autostart_applications
3.3 Input
Settings for items such as keyboard layouts (I use colemak
) and mice/touchpads.
Source: .config/sway/config.d/input
3.4 Output
Sway does a good job at automatically detecting system displays at their optimal resolution and (with multiple displays connected) positioning them relative to each other. All of this can be modified by the user.
Example: My laptop display defaults to 1920x1080, but - instead of using fractional scaling - for reading I prefer a resolution of 1600x900 on this device.
Source: .config/sway/config.d/output
3.5 Theme
I use the Adwaita Dark theme paired with Papirus Dark icons. Adwaita is the default GTK theme and has good coverage in QT courtesy of the adwaita-qt
package in Debian.
GTK
GTK settings on Wayland are set in ~/.config/gtk-3.0/settings.ini
...
gtk-theme-name=Adwaita
gtk-application-prefer-dark-theme=true
gtk-icon-theme-name=Papirus-Dark
gtk-cursor-theme-name=Adwaita
Create ~/.config/sway/config.d/theme
with settings ...
set $gnome-schema org.gnome.desktop.interface
exec_always {
gsettings set $gnome-schema gtk-theme Adwaita
gsettings set $gnome-schema gtk-application-prefer-dark-theme true
gsettings set $gnome-schema icon-theme Papirus-Dark
gsettings set $gnome-schema cursor-theme Adwaita
}
Note: Do not put gsettings
selections in double quotes or it will fail to display properly.
Wallpaper
Set a default desktop wallpaper in ~/.config/sway/config.d/theme
...
output * bg /path/to/wallpaper.jpg fill
QT
Use adwaita-qt
as the theme and select it by running qt5ct
.
Set qt5ct
as QT_QPA_PLATFORMTHEME
in ~/.profile
...
export QT_QPA_PLATFORMTHEME=qt5ct
Also export QT_QPA_PLATFORM
as wayland
(included in my startw script) ...
export QT_QPA_PLATFORM=wayland
Sources:
4. Applications
Hint: Run the command xlsclients
in a terminal to view which open applications are running in xwayland
(that is, running as legacy X11 applications) vs Wayland proper.
4.1 Terminal: foot
Set foot
as the default terminal emulator in .config/sway/config.d/default
...
set $term foot
Create a local config ...
$ mkdir ~/.config/foot
$ cp /etc/xdg/foot/foot.ini ~/.config/foot/
To have the terminal behave properly when ssh'ing into remote machines, on the remote machine install the terminfo files for foot
...
$ sudo apt install foot-terminfo
Source: .config/foot/foot.ini
4.2 Application launcher: wofi
Wofi is a Wayland-native dynamic menu/launcher for applications in a user's PATH. Frequently-used applications are positioned near the top of the list.
Set launcher to wofi
in ~/.config/sway/config.d/default
...
set $menu wofi -c ~/.config/wofi/config --show
Activate menu with Super+d
...
bindsym $mod+d exec $menu
Create a local config
and style.css
in ~/.config/wofi
.
Source: .config/wofi
4.3 Status bar: waybar
Sway includes a status bar, but I prefer this highly configurable Wayland bar: waybar
Configure ~/.config/sway/config.d/default
to use this alternative status bar ...
bar {
swaybar_command waybar
}
Create a local config
and style.css
inside ~/.config/waybar
.
Source: .config/waybar
4.4 System idle: swayidle + swaylock
Set a display timeout (in seconds), lock screen, and actions to take on suspend using swayidle
and swaylock
in ~/.config/sway/config.d/default
...
exec swayidle -w \
timeout 1200 'swaylock -C ~/.config/swaylock/config' \
timeout 1500 'swaymsg "output * dpms off"' \
resume 'swaymsg "output * dpms on"' \
before-sleep 'swaylock -C ~/.config/swaylock/config'
Create a local config
for swaylock
in ~/.config/swaylock/config
.
Source: .config/swaylock/config
4.5 Sound: pipewire + alsamixer
Sound is managed by pipewire
and alsamixer
can be used to set audio and enable/mute devices.
4.6 Volume|Backlight: wob + amixer + brightnessctl
Overlay bar wob can be used to display changes in volume|backlight levels.
Configure keybindings in ~/.config/sway/config.d/default
that use amixer
for volume and brightnessctl for the backlight ...
set $WOBSOCK $XDG_RUNTIME_DIR/wob.sock
exec rm -f $WOBSOCK && mkfifo $WOBSOCK && tail -f $WOBSOCK | wob
bindsym XF86AudioRaiseVolume exec amixer sset Master 5%+ | sed -En 's/.*\[([0-9]+)%\].*/\1/p' | head -1 > $WOBSOCK
bindsym XF86AudioLowerVolume exec amixer sset Master 5%- | sed -En 's/.*\[([0-9]+)%\].*/\1/p' | head -1 > $WOBSOCK
bindsym XF86AudioMute exec amixer sset Master toggle | sed -En '/\[on\]/ s/.*\[([0-9]+)%\].*/\1/ p; /\[off\]/ s/.*/0/p' | head -1 > $WOBSOCK
bindsym XF86MonBrightnessDown exec brightnessctl set 5%- | sed -En 's/.*\(([0-9]+)%\).*/\1/p' > $WOBSOCK
bindsym XF86MonBrightnessUp exec brightnessctl set +5% | sed -En 's/.*\(([0-9]+)%\).*/\1/p' > $WOBSOCK
4.7 Screenshots: grimshot
I created a script - swayshot
- that uses grimshot (a wrapper around grim
and slurp
) to capture and save screenshots, and gthumb
to view images.
Source: swayshot
4.8 Clipboard manager: copyq
Modify ~/.config/sway/config.d/autostart_applications
to start copyq when Sway opens up ...
exec copyq
Modify ~/.config/sway/config.d/application_defaults
to display the clipboard as a floating window ...
for_window [app_id="copyq"] floating enable, sticky enable, resize set height 600px width 550px, move position cursor, move down 330
Set a keybinding in ~/.config/sway/config.d/default
to toggle clipboard visibility ...
bindsym $mod+Shift+v exec copyq toggle
Open the clipboard window, select File->Preferences...
and under the General
tab deselect Close When Unfocused
...
Under Layout
check Hide main window
...
4.9 Notifications: mako
Modify ~/.config/sway/config.d/autostart_applications
to start mako
when Sway opens up ...
exec mako
Create a local config
in ~/.config/mako/config
.
Send a test notification ...
$ notify-send -u low|normal|critical "Testing ..."
Source: .config/mako/config
4.10 Web browser: Firefox
Recent versions of Firefox enable Wayland mode by setting an environmental variable at runtime ...
$ MOZ_ENABLE_WAYLAND=1 firefox
Verify it worked by opening about:support
in Firefox, looking for Window Protocol
, and confirm it indicates wayland
.
Make it permanent with export MOZ_ENABLE_WAYLAND=1
(I include this in my startw script).
5. Helpful
- Sway Wiki
- Arch Wiki entries for Sway and Wayland
- Resources for Wayland and some useful add ons and replacements for X11 apps for Sway
- i3 User Guide: Sway is modelled on
i3
and many of the config settings are the same - Full Wayland Setup on Arch Linux
- An interesting take on the whole Wayland experience: An X11 Apologist Tries Wayland
6. Finish
You can like, share, or comment on this post on Mastodon 💬
» Next: #24. Embedded Linux in Space
« Previous: Minimal Debian Bookworm