How to Set Up Wayland on FreeBSD with Sway
Wayland is the modern replacement for the X Window System. It eliminates the security issues of X11's permissive client model, reduces input latency, and simplifies the display stack. On FreeBSD, Wayland support has matured significantly. Sway, a tiling compositor that is a drop-in replacement for i3, is the most stable and feature-complete Wayland compositor available on FreeBSD today.
This guide covers a complete Wayland desktop setup on FreeBSD 14.x with Sway: driver prerequisites, package installation, configuration, screen sharing, clipboard integration, running X11 applications under XWayland, and troubleshooting common issues.
Prerequisites
Before installing Sway, your system needs working graphics drivers and a few kernel features enabled.
Graphics Drivers
Wayland compositors talk directly to the kernel's DRM (Direct Rendering Manager) subsystem. You need the drm-kmod package for your GPU.
For Intel and AMD GPUs:
shpkg install drm-kmod
Load the appropriate kernel module at boot. For Intel:
shsysrc kld_list+="i915kms"
For AMD:
shsysrc kld_list+="amdgpu"
For NVIDIA GPUs:
NVIDIA Wayland support on FreeBSD is limited. The proprietary nvidia-driver package does not yet support the GBM backend that Sway requires. If you have an NVIDIA GPU, you may need to use X11 instead, or check if the nvidia-drm module has gained GBM support in the latest driver version.
Kernel Configuration
Sway requires the evdev input subsystem. Load it:
shkldload evdev sysrc kld_list+="evdev"
Verify DRM is working:
shkldstat | grep drm ls /dev/dri/
You should see card0 and renderD128 (or similar) in /dev/dri/.
User Permissions
Your user must be in the video group to access the GPU:
shpw groupmod video -m your_username
Also add to the input group for input device access:
shpw groupmod input -m your_username
Log out and log back in for group changes to take effect.
Installing Sway and Supporting Packages
Install the Sway compositor and essential Wayland utilities:
shpkg install sway swaylock swayidle swaybg waybar \ foot wofi grim slurp wl-clipboard \ xwayland dbus
What each package provides:
sway-- the tiling Wayland compositorswaylock-- screen lockerswayidle-- idle management (lock screen after inactivity, suspend)swaybg-- wallpaper setterwaybar-- status bar (clock, workspaces, system tray, battery, etc.)foot-- Wayland-native terminal emulator (fast and lightweight)wofi-- application launcher (like dmenu/rofi for Wayland)grim-- screenshot toolslurp-- region selection tool (for partial screenshots)wl-clipboard-- command-line clipboard (wl-copy, wl-paste)xwayland-- compatibility layer for running X11 applications
Enable D-Bus, which Sway and many desktop applications require:
shsysrc dbus_enable="YES" service dbus start
Environment Variables
Set the required environment variables. Add these to your shell profile:
shvi ~/.profile
sh# Wayland/Sway environment export XDG_RUNTIME_DIR=/tmp/$(id -u)-runtime-dir if [ ! -d "$XDG_RUNTIME_DIR" ]; then mkdir -p "$XDG_RUNTIME_DIR" chmod 0700 "$XDG_RUNTIME_DIR" fi export XDG_SESSION_TYPE=wayland export XDG_CURRENT_DESKTOP=sway export MOZ_ENABLE_WAYLAND=1 export QT_QPA_PLATFORM=wayland export SDL_VIDEODRIVER=wayland export _JAVA_AWT_WM_NONREPARENTING=1 export ELECTRON_OZONE_PLATFORM_HINT=wayland
The XDG_RUNTIME_DIR is critical. Sway will refuse to start without it. The other variables tell applications to prefer Wayland backends.
If you use ~/.shrc or ~/.bashrc instead, add the same lines there.
Starting Sway
From a TTY console (not from within X11), log in and run:
shsway
Sway reads its configuration from ~/.config/sway/config. If no config file exists, Sway uses defaults and opens a terminal with Mod4+Return (the Super/Windows key plus Enter).
If Sway starts and you see a blank screen with a cursor, it is working. Press Mod4+Return to open a terminal.
Configuring Sway
Create the configuration directory and file:
shmkdir -p ~/.config/sway cp /usr/local/etc/sway/config ~/.config/sway/config
Edit the configuration:
shvi ~/.config/sway/config
Key Bindings
The default modifier is Mod4 (Super key). Core bindings:
shellset $mod Mod4 set $term foot set $menu wofi --show drun # Start terminal bindsym $mod+Return exec $term # Kill focused window bindsym $mod+Shift+q kill # Application launcher bindsym $mod+d exec $menu # Screenshot (full screen) bindsym Print exec grim ~/screenshots/$(date +%Y%m%d-%H%M%S).png # Screenshot (selected region) bindsym $mod+Shift+s exec grim -g "$(slurp)" ~/screenshots/$(date +%Y%m%d-%H%M%S).png # Lock screen bindsym $mod+l exec swaylock -c 000000 # Reload config bindsym $mod+Shift+c reload # Exit Sway bindsym $mod+Shift+e exec swaynag -t warning -m 'Exit Sway?' -b 'Yes' 'swaymsg exit'
Output Configuration
List connected displays:
shswaymsg -t get_outputs
Configure displays in your Sway config:
shell# Set resolution and position output HDMI-A-1 resolution 1920x1080 position 0,0 output DP-1 resolution 2560x1440 position 1920,0 # Set wallpaper output * bg ~/wallpaper.jpg fill
Input Configuration
List input devices:
shswaymsg -t get_inputs
Configure keyboard layout and touchpad:
shellinput type:keyboard { xkb_layout us xkb_options caps:escape repeat_delay 200 repeat_rate 40 } input type:touchpad { tap enabled natural_scroll enabled scroll_method two_finger }
Idle and Lock
Configure automatic screen locking:
shellexec swayidle -w \ timeout 300 'swaylock -f -c 000000' \ timeout 600 'swaymsg "output * dpms off"' \ resume 'swaymsg "output * dpms on"' \ before-sleep 'swaylock -f -c 000000'
This locks the screen after 5 minutes of inactivity and turns off displays after 10 minutes.
Configuring Waybar
Waybar is the status bar for Sway. Create its configuration:
shmkdir -p ~/.config/waybar vi ~/.config/waybar/config
json{ "layer": "top", "position": "top", "height": 30, "modules-left": ["sway/workspaces", "sway/mode"], "modules-center": ["clock"], "modules-right": ["cpu", "memory", "disk", "network", "pulseaudio", "tray"], "clock": { "format": "{:%Y-%m-%d %H:%M}", "tooltip-format": "{:%A, %B %d, %Y}" }, "cpu": { "format": "CPU {usage}%", "interval": 5 }, "memory": { "format": "MEM {}%", "interval": 5 }, "disk": { "format": "DISK {percentage_used}%", "path": "/" }, "network": { "format-wifi": "{essid} ({signalStrength}%)", "format-ethernet": "{ifname}: {ipaddr}", "format-disconnected": "disconnected" }, "tray": { "spacing": 10 } }
Add to your Sway config:
shellbar { swaybar_command waybar }
Style Waybar with CSS:
shvi ~/.config/waybar/style.css
css* { font-family: monospace; font-size: 13px; } window#waybar { background-color: rgba(0, 0, 0, 0.9); color: #cccccc; } #workspaces button.focused { background-color: #333333; color: #ffffff; } #cpu, #memory, #disk, #network, #clock { padding: 0 10px; }
Running X11 Applications
XWayland provides backward compatibility for X11 applications that do not yet support Wayland natively. It is enabled by default in Sway.
Verify XWayland is enabled in your Sway config:
shellxwayland enable
Most X11 applications work transparently under XWayland. To check if an application is running natively on Wayland or through XWayland:
shxprop
Click on a window. If xprop can read its properties, it is running under XWayland. Wayland-native windows will not respond to xprop.
Applications with known Wayland support on FreeBSD:
- Firefox: native with
MOZ_ENABLE_WAYLAND=1 - Chromium: native with
--ozone-platform=wayland - foot, alacritty: native terminal emulators
- LibreOffice: native since 7.x
- mpv: native with
--gpu-context=waylandvk - GIMP: XWayland (Wayland support in progress)
Clipboard
The wl-clipboard package provides wl-copy and wl-paste for command-line clipboard operations:
sh# Copy text to clipboard echo "hello" | wl-copy # Paste from clipboard wl-paste # Copy file contents wl-copy < /etc/motd # Copy screenshot to clipboard grim - | wl-copy -t image/png
Clipboard works between Wayland-native applications and XWayland applications seamlessly.
Screen Sharing
Screen sharing on Wayland requires PipeWire and the xdg-desktop-portal stack.
Install the required packages:
shpkg install pipewire xdg-desktop-portal xdg-desktop-portal-wlr
Enable PipeWire. Add to your Sway config or shell profile:
shvi ~/.config/sway/config
shellexec pipewire exec pipewire-pulse exec wireplumber
Ensure the portal environment variable is set (already in our .profile if XDG_CURRENT_DESKTOP=sway is set).
Test screen sharing in Firefox by joining a test video call or using a screen sharing test page. Firefox uses xdg-desktop-portal-wlr to capture the Sway output.
For OBS Studio, install it and configure it to use the PipeWire source:
shpkg install obs-studio
Notifications
Install mako, a Wayland notification daemon:
shpkg install mako
Add to your Sway config:
shellexec mako
Configure mako:
shmkdir -p ~/.config/mako vi ~/.config/mako/config
inidefault-timeout=5000 font=monospace 12 background-color=#1a1a1aee text-color=#cccccc border-color=#333333 border-size=2
Test notifications:
shnotify-send "Test" "This is a test notification"
File Manager and GTK Theming
Install a file manager and set GTK themes for a consistent look:
shpkg install thunar adwaita-icon-theme
Configure GTK for Wayland:
shmkdir -p ~/.config/gtk-3.0 vi ~/.config/gtk-3.0/settings.ini
ini[Settings] gtk-theme-name=Adwaita gtk-icon-theme-name=Adwaita gtk-font-name=Sans 11 gtk-cursor-theme-name=Adwaita gtk-cursor-theme-size=24
For cursor theme in Sway, add to your config:
shellseat * xcursor_theme Adwaita 24
Auto-Starting Sway on Login
To start Sway automatically when you log into TTY1, add to the end of your ~/.profile:
sh# Auto-start Sway on TTY1 if [ "$(tty)" = "/dev/ttyv0" ]; then exec sway fi
Performance Tuning
Reduce compositor latency. Add to Sway config:
shell# Disable vsync for lower input latency (may cause tearing) # output * adaptive_sync on
Hardware video acceleration. Install VA-API support:
shpkg install libva-intel-driver
Or for AMD:
shpkg install libva-mesa-driver mesa-gallium-va
Verify VA-API:
shvainfo
Font rendering. Install good fonts:
shpkg install noto dejavu sourcecodepro-ttf
Configure fontconfig:
shmkdir -p ~/.config/fontconfig vi ~/.config/fontconfig/fonts.conf
xml<?xml version="1.0"?> <!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd"> <fontconfig> <match target="font"> <edit name="antialias" mode="assign"><bool>true</bool></edit> <edit name="hinting" mode="assign"><bool>true</bool></edit> <edit name="hintstyle" mode="assign"><const>hintslight</const></edit> <edit name="rgba" mode="assign"><const>rgb</const></edit> <edit name="lcdfilter" mode="assign"><const>lcddefault</const></edit> </match> </fontconfig>
Troubleshooting
Sway fails to start with "Failed to open DRM device":
Check GPU driver is loaded:
shkldstat | grep -E "(i915|amdgpu|radeon)"
Check device permissions:
shls -la /dev/dri/
Ensure your user is in the video group:
shgroups your_username
Black screen after starting Sway:
Press Mod4+Return to open a terminal. If nothing happens, check the Sway log:
shsway -d 2> /tmp/sway.log
Review /tmp/sway.log for errors.
XWayland applications look blurry on HiDPI:
XWayland does not handle fractional scaling well. Force integer scaling in Sway:
shelloutput * scale 2
Or set per-application scaling with GDK_SCALE=2 or QT_SCALE_FACTOR=2.
No sound:
Install and configure PipeWire:
shpkg install pipewire wireplumber
Ensure PipeWire is started in your Sway config:
shellexec pipewire exec wireplumber
Check audio devices:
shpw-cli list-objects | grep -i audio
Firefox does not use Wayland natively:
Verify the environment variable:
shecho $MOZ_ENABLE_WAYLAND
It must be 1. Check with:
shMOZ_ENABLE_WAYLAND=1 firefox &
In about:support, the "Window Protocol" field should say "wayland".
FAQ
Is Wayland stable enough for daily use on FreeBSD?
Yes, for most workflows. Sway is production-quality. The main gaps are in application support (some older GTK2 and Qt4 apps need XWayland) and in screen recording/sharing (which requires PipeWire). If you run a tiling workflow with terminals, a browser, and standard productivity tools, Wayland on FreeBSD works well.
Can I run GNOME or KDE on Wayland on FreeBSD?
GNOME on Wayland has experimental support on FreeBSD but is less stable than Sway. KDE Plasma Wayland support is in progress. Sway is the most mature Wayland compositor on FreeBSD currently.
Does multi-monitor work?
Yes. Sway handles multi-monitor setups natively. Use swaymsg -t get_outputs to list displays and configure them in your Sway config with resolution, position, and scale settings.
Can I use Sway with a floating window layout instead of tiling?
Yes. Sway supports floating windows. Press Mod4+Shift+Space to toggle a window between tiled and floating. You can set specific applications to always float with window rules in the config.
How do I switch back to X11 if Wayland does not work?
Install Xorg and a window manager, then start X11 from the console instead of Sway. Both can coexist. You choose which to start at login.
What about gaming on Wayland?
Games using SDL2 or Vulkan generally work. OpenGL games may need XWayland. Steam runs under XWayland. Performance is comparable to X11 for most titles. Set SDL_VIDEODRIVER=wayland for native Wayland support in SDL2 games.