How To

Install Sway on Fedora 45 / 44 with Waybar

Fedora is one of the few distributions where installing Sway gives you a working desktop on the first login. The sway-config-fedora package adds a Waybar panel, an idle lock, media and brightness keys, screenshot bindings, and a Rofi launcher. Everything is split into drop-in files you can override one at a time. The catch is that most Sway guides tell you to copy /etc/sway/config into your home directory and edit it, which works but freezes the core bindings and variables at whatever Fedora shipped that day.

Original content from computingforgeeks.com - post 46100

This guide installs Sway on Fedora Workstation next to GNOME, logs in through GDM, and walks through what Fedora’s layered config actually loads. From there it shows how to override single pieces of it and how to build a custom Waybar config. It finishes with the errors that come up along the way. If you are starting from a fresh machine, the Fedora 45 install guide and the post-install checklist cover the base system first. Every command and screenshot below came from a Fedora 45 Workstation running Sway 1.12 and Waybar 0.15.0, with the Fedora 44 package set checked against the same repositories.

Pick how much of the Sway desktop to install

Fedora packages Sway three ways, and the right one depends on what is already on the machine. Two package groups exist in the repositories plus a dedicated spin ISO. The group sizes below are from a dnf5 install --assumeno dry run on a stock Fedora 45 Workstation:

OptionWhat you getPackages on WorkstationUse it when
@swaywm + sway-config-fedoraSway, swaybg, swayidle, swaylock, Waybar, foot, dunst, grim/slurp, Rofi, portals, Fedora’s config52 (25 MiB)Adding Sway to a GNOME or KDE install
@sway-desktop-environmentAll of the above plus SDDM, Thunar, xfce4-panel pieces, Blueman, mpv, NetworkManager applets107 (138 MiB)A minimal or Server install that has no display manager yet
Fedora Sway Spin ISOThe full environment, SDDM as the login screenFresh installA dedicated Sway machine

On a GNOME machine, skip the full environment. It pulls in SDDM alongside GDM, and a second display manager on a GNOME box is just something to disable later. The dry run shows it plainly:

sudo dnf5 install --assumeno @sway-desktop-environment | grep -E '^ (sddm|Thunar|xfce4-panel) '

SDDM, Thunar and xfce4-panel are all in the transaction:

 Thunar                                      x86_64 0:4.20.10-2.fc45    fedora           10.7 MiB
 sddm                                        x86_64 0:0.21.0-16.fc45    fedora            1.6 MiB
 xfce4-panel                                 x86_64 0:4.20.8-4.fc45     fedora            8.4 MiB

Install Sway on Fedora Workstation

One command. The swaywm group brings the compositor and its tools, and sway-config-fedora is the package that turns it into Fedora’s preconfigured desktop. The sway package only requires “a” config package, and sway-config-upstream (the plain upstream sample with swaybar) satisfies that too, so name Fedora’s explicitly:

sudo dnf5 install -y @swaywm sway-config-fedora

If GNOME Software had an update queued, dnf warns that it just invalidated it. It does not affect the Sway install:

Warning: Pending offline transaction has been invalidated.
To reschedule, run: dnf5daemon-server
Complete!

Confirm the versions that landed:

rpm -q sway wlroots waybar sway-config-fedora foot rofi

On Fedora 45 the compositor sits on wlroots 0.20:

sway-1.12-2.fc45.x86_64
wlroots-0.20.2-2.fc45.x86_64
waybar-0.15.0-6.fc45.x86_64
sway-config-fedora-0.4.3-4.fc45.noarch
foot-1.28.0-1.fc45.x86_64
rofi-2.0.0-3.fc45.x86_64

The package also drops a session file at /usr/share/wayland-sessions/sway.desktop. Its Exec line is start-sway, not sway. That wrapper matters later because it sets environment variables before the compositor starts.

Log in to Sway from GDM

Log out of GNOME, click your user, then open the gear icon in the bottom right corner before typing the password. This catches people out: on our Workstation the Session Type menu still listed only GNOME and GNOME Classic after the install. GDM reads the session list when the greeter starts, so a greeter that was already running never sees sway.desktop. Restart it from a terminal (this ends any graphical session on the machine, so save your work) or reboot:

sudo systemctl restart gdm

After the restart, Sway appears as a third choice:

GDM Session Type menu listing Sway on Fedora 45

GDM remembers the choice per user, so later logins go straight back into Sway until you pick GNOME again. Sway comes up on Fedora’s wallpaper with Waybar across the top, and Super+Return opens a foot terminal before you have written any config. This is the packaged bar with two terminals open, one listing the drop-ins:

Sway on Fedora 45 with the default sway-config-fedora Waybar

The default bar shows workspaces on the left and the focused window title in the middle. On the right are the idle inhibitor, volume, network, power profile, CPU, memory, keyboard layout and clock. Temperature, backlight and battery modules switch themselves off when the hardware has no sensor for them, which is why a VM or desktop shows fewer modules than a laptop. The network address is blacked out in this capture.

How Fedora’s Sway config is layered

/etc/sway/config holds only the core i3-style bindings. Its last line hands everything else to a helper script:

include '$(/usr/libexec/sway/layered-include "/usr/share/sway/config.d/*.conf" "/etc/sway/config.d/*.conf" "${XDG_CONFIG_HOME:-$HOME/.config}/sway/config.d/*.conf")'

layered-include collects files from three directories, keyed by file name, and later directories win. A file in ~/.config/sway/config.d/ named 60-bindings-screenshot.conf replaces the packaged one of the same name instead of adding to it. The result is loaded in sorted file-name order. These are the drop-ins Fedora ships in /usr/share/sway/config.d/:

FileWhat it does
50-rules-browser.confMarks Firefox, Chromium and Brave windows and inhibits idle while they are fullscreen
50-rules-pavucontrol.conf, 50-rules-policykit-agent.confFloats the volume mixer and the polkit password prompt
60-bindings-volume.conf, 60-bindings-media.conf, 60-bindings-brightness.confXF86 volume, media and brightness keys (volume and play also work on the lock screen)
60-bindings-screenshot.confPrint, Alt+Print and Ctrl+Print through grimshot
65-mode-passthrough.confSuper+Pause passes every key to the focused window (handy for nested VMs)
90-bar.confStarts Waybar as the bar
90-swayidle.confLocks after 300 seconds and blanks the screen 60 seconds later
95-autostart-policykit-agent.conf, 95-xdg-desktop-autostart.conf, 95-xdg-user-dirs.confPolkit agent, XDG autostart entries, and the XDG user directories

The bindings every new Sway user needs first come straight from /etc/sway/config. Super is the modifier (Mod4):

KeysAction
Super+ReturnOpen a foot terminal
Super+DRofi launcher (apps and commands in one list)
Super+Shift+QClose the focused window
Super+H/J/K/L or arrowsMove focus; add Shift to move the window
Super+1 to Super+0Switch workspace; add Shift to send the window there
Super+B / Super+VSplit the next window horizontally / vertically
Super+S / Super+W / Super+EStacking / tabbed / toggle split layout
Super+FFullscreen
Super+Shift+SpaceToggle floating
Super+RResize mode (Escape to leave)
Super+Shift+CReload the config
Super+Shift+EExit Sway (asks first)

Override Fedora’s defaults with your own drop-ins

Leave /etc/sway/config alone and put your changes in ~/.config/sway/config.d/. Package updates to sway-config-fedora then keep flowing, and your file only carries what you changed. Create the directory:

mkdir -p ~/.config/sway/config.d

Open a local drop-in. The 10- prefix sorts it ahead of Fedora’s 90-swayidle.conf, and that ordering is what lets the timeout variables take effect:

vim ~/.config/sway/config.d/10-local.conf

This is the exact file used on the test machine. It raises the lock timeout, maps Caps Lock to Escape, enables tap-to-click, sets the resolution and wallpaper, and adds thin borders with small gaps:

# Lock after 10 minutes, blank the screen one minute later
set $lock_timeout 600
set $screen_timeout 60

input type:keyboard {
    xkb_layout us
    xkb_options caps:escape
}

input type:touchpad {
    tap enabled
    natural_scroll enabled
}

output Virtual-1 mode 1920x1080 bg /usr/share/backgrounds/f45/default/f45-01-night.jxl fill

default_border pixel 2
gaps inner 6
font pango:Noto Sans 10

Virtual-1 is the output name of the test VM. List your own outputs and their modes with swaymsg -t get_outputs and use that name, or use output * to match every screen. Fedora 45 ships its wallpapers as JPEG XL, and swaybg loaded the .jxl file directly.

Reload with Super+Shift+C or from a terminal inside the session:

swaymsg reload

The input, output and border changes apply immediately. Two things did not. The gaps inner value was not applied to the workspace that was already open, and swayidle kept running with the old timeout, because exec lines run once at login and a reload does not restart them:

ps -o args= -C swayidle

After the reload the process still had the packaged 300 second value:

swayidle -w timeout 300 swaylock -f timeout 360 swaymsg "output * power off" resume swaymsg "output * power on" timeout 60 pgrep -xu "$USER" swaylock >/dev/null && swaymsg "output * power off" resume pgrep -xu "$USER" swaylock >/dev/null && swaymsg "output * power on" before-sleep swaylock -f lock swaylock -f unlock pkill -xu "$USER" -SIGUSR1 swaylock

Log out with Super+Shift+E and back in. The same check on the new session shows timeout 600 swaylock -f timeout 660, and the gaps apply to workspace 1. To see exactly which files Sway loaded and in what order, read the include list the helper generated under the runtime directory:

cat "$(ls -t "$XDG_RUNTIME_DIR"/sway/layered-include-*.conf | head -1)"

Your drop-in sorts first, followed by the systemd pieces from /etc and Fedora’s packaged files:

include '/home/sysadmin/.config/sway/config.d/10-local.conf'
include '/etc/sway/config.d/10-systemd-cgroups.conf'
include '/etc/sway/config.d/10-systemd-session.conf'
include '/usr/share/sway/config.d/50-rules-browser.conf'
include '/usr/share/sway/config.d/50-rules-pavucontrol.conf'
include '/usr/share/sway/config.d/50-rules-policykit-agent.conf'
include '/usr/share/sway/config.d/60-bindings-brightness.conf'
include '/usr/share/sway/config.d/60-bindings-media.conf'
include '/usr/share/sway/config.d/60-bindings-screenshot.conf'
include '/usr/share/sway/config.d/60-bindings-volume.conf'
include '/usr/share/sway/config.d/65-mode-passthrough.conf'
include '/usr/share/sway/config.d/90-bar.conf'
include '/usr/share/sway/config.d/90-swayidle.conf'
include '/usr/share/sway/config.d/95-autostart-policykit-agent.conf'
include '/usr/share/sway/config.d/95-xdg-desktop-autostart.conf'
include '/usr/share/sway/config.d/95-xdg-user-dirs.conf'

Replace one packaged drop-in

To change a packaged file rather than add to it, copy it under the same name and edit the copy. This swaps the Print key from a full-screen capture to an area selection that is saved and copied to the clipboard:

cp /usr/share/sway/config.d/60-bindings-screenshot.conf ~/.config/sway/config.d/
sed -i 's/Print       exec grimshot save output/Print       exec grimshot savecopy area/' ~/.config/sway/config.d/60-bindings-screenshot.conf
swaymsg reload

The regenerated include list now points at /home/sysadmin/.config/sway/config.d/60-bindings-screenshot.conf, and the /usr/share copy is no longer loaded. With the default bindings, grimshot writes to the XDG Pictures directory, so screenshots land in ~/Pictures with a timestamped file name.

Configure Waybar on Fedora

Waybar reads ~/.config/waybar/config.jsonc and style.css when they exist and falls back to /etc/xdg/waybar/. The packaged config carries every example module upstream ships (MPD, a Spotify media script, a power menu that expects files you do not have), so a short config of your own is easier to maintain than an edited copy. Create the directory and the config:

mkdir -p ~/.config/waybar
vim ~/.config/waybar/config.jsonc

This config moves the clock to the centre, keeps the network address in the tooltip instead of on the bar, and adds a disk module. Plain text labels replace the Font Awesome glyphs, which rarely survive a copy from a web page:

{
    "position": "top",
    "height": 32,
    "spacing": 6,
    "reload_style_on_change": true,
    "modules-left": ["sway/workspaces", "sway/mode", "sway/scratchpad"],
    "modules-center": ["clock"],
    "modules-right": ["idle_inhibitor", "pulseaudio", "network", "cpu", "memory", "disk", "sway/language", "tray"],
    "sway/workspaces": {
        "disable-scroll": true,
        "all-outputs": true
    },
    "clock": {
        "format": "{:%a %d %b  %H:%M}",
        "tooltip-format": "<tt><small>{calendar}</small></tt>"
    },
    "idle_inhibitor": {
        "format": "{icon}",
        "format-icons": { "activated": "AWAKE", "deactivated": "IDLE" }
    },
    "pulseaudio": {
        "format": "VOL {volume}%",
        "format-muted": "VOL muted",
        "on-click": "pavucontrol"
    },
    "network": {
        "format-ethernet": "NET {ifname}",
        "format-wifi": "WIFI {essid} {signalStrength}%",
        "format-disconnected": "NET offline",
        "tooltip-format": "{ifname}: {ipaddr}/{cidr} via {gwaddr}"
    },
    "cpu": { "format": "CPU {usage}%", "interval": 5 },
    "memory": { "format": "MEM {used:0.1f}G", "interval": 10 },
    "disk": { "format": "DISK {percentage_used}%", "path": "/" },
    "tray": { "spacing": 8 }
}

Then the stylesheet:

vim ~/.config/waybar/style.css

A dark bar with the focused workspace highlighted and each module drawn as a rounded pill:

* {
    font-family: 'Noto Sans', sans-serif;
    font-size: 13px;
}

window#waybar {
    background-color: rgba(30, 30, 46, 0.92);
    color: #cdd6f4;
}

#workspaces button {
    padding: 0 8px;
    color: #a6adc8;
    border-radius: 0;
}

#workspaces button.focused {
    color: #1e1e2e;
    background-color: #89b4fa;
}

#clock, #pulseaudio, #network, #cpu, #memory, #disk, #language, #idle_inhibitor, #tray {
    padding: 0 10px;
    margin: 4px 0;
    border-radius: 6px;
    background-color: #313244;
}

#network.disconnected {
    color: #f38ba8;
}

Waybar reloads both files on SIGUSR2, so there is no need to reload Sway:

pkill -SIGUSR2 -x waybar
journalctl -b --no-pager | grep waybar | tail -4

The journal confirms Waybar switched from /etc/xdg/waybar to the files in your home directory:

Sep 28 21:15:21 fedora-ws01 waybar[4733]: [2026-09-28 21:15:21.402] [info] Reloading...
Sep 28 21:15:21 fedora-ws01 waybar[4733]: [2026-09-28 21:15:21.408] [info] Using configuration file /home/sysadmin/.config/waybar/config.jsonc
Sep 28 21:15:21 fedora-ws01 waybar[4733]: [2026-09-28 21:15:21.408] [info] Using CSS file /home/sysadmin/.config/waybar/style.css
Sep 28 21:15:21 fedora-ws01 waybar[4733]: [2026-09-28 21:15:21.537] [info] Bar configured (width: 1920, height: 32) for output: Virtual-1

With the drop-in from the previous section active after a fresh login, three terminals tile with 6 pixel gaps under the new bar (fastfetch on the left, btop and the drop-in file stacked on the right):

Tiled foot terminals in Sway with a custom Waybar on Fedora 45

Launch apps and switch layouts

Super+D opens Rofi in combi mode, which merges desktop applications (drun) and every binary on your PATH (run) into one filtered list. Typing a few letters is enough:

Rofi combi launcher opened with Super+D in Sway on Fedora

Layouts apply to the container holding the focused window. Focus the right column and press Super+W, and its two terminals collapse into tabs while the left window keeps its split:

Sway tabbed layout on Fedora 45

Super+E puts it back to a split. Screen sharing requests from browsers go to xdg-desktop-portal-wlr: Fedora’s /usr/share/xdg-desktop-portal/sway-portals.conf assigns it the ScreenCast and Screenshot interfaces, sends Secret to gnome-keyring, disables Inhibit, and leaves the rest to the GTK portal. Both portal services were running on the test session without any setup.

Sway on Fedora 45 vs Fedora 44

The install commands and group names are identical on both releases, and sway-config-fedora is the same 0.4.3 upstream release. The versions below are the newest builds each release’s repositories offered at the time of testing:

PackageFedora 45Fedora 44
sway1.121.11
sway-config-fedora0.4.3-40.4.3-3
waybar0.15.0-60.15.0-2
foot1.28.01.27.0
rofi2.0.0-32.0.0-2
swaylock1.8.61.8.6
xdg-desktop-portal-wlr0.8.40.8.4

Both releases ship the same sway-config-fedora 0.4.3 drop-ins, so the config layout in this guide is identical; the Fedora 44 side was checked against its repositories, not run in a session. One packaging difference: on Fedora 44 the swaywm-extended group lists SDDM as mandatory, while Fedora 45 makes it a default package. If you plan to move a Fedora 44 Sway machine forward, the Fedora 44 to 45 upgrade guide covers the system upgrade itself.

Sway errors on Fedora and their fixes

Each of these came up while building the setup above.

“There are errors in your config file”

A bad line in any drop-in makes Sway draw a red swaynag bar across the top of the screen after a reload. A single typo (gap instead of gaps) was enough. Click Toggle details to see the file and line:

swaynag error bar for an invalid Sway config line

Sway skips only the broken line and loads the rest, so the session keeps working. Fix the file and reload. To check a config before reloading, sway -C validates it, but over SSH or from a TTY it fails with “No backend was able to open a seat” before reading anything. Forcing the headless backend gets around that:

WLR_BACKENDS=headless sway -C 2>&1 | grep -v 'render node'

The broken drop-in is reported with its path:

00:00:00.059 [ERROR] [sway/config.c:814] Error on line 1 'gap inner 10': Unknown/invalid command 'gap' (/home/sysadmin/.config/sway/config.d/20-typo.conf)
00:00:00.059 [ERROR] [sway/config.c:440] Error(s) loading config!

Do not trust the exit code in a script. Sway 1.12 returned 0 from sway -C with that error present, so grep the output for Error instead.

Sway is missing from the GDM session list

Covered above: the greeter was started before the package installed the session file. sudo systemctl restart gdm or a reboot fixes it. If Sway is still missing, check that /usr/share/wayland-sessions/sway.desktop exists. It ships in the config package (sway-config-fedora or sway-config-upstream), not in sway itself.

Sway in a VM: “Failed to find any DRM render node”

Virtual GPUs without 3D acceleration (QXL, virtio without virgl) have no render node, and wlroots’ default GLES2 renderer cannot start without one. Fedora’s start-sway wrapper already handles KVM guests. It detects the hypervisor and exports a software renderer before launching Sway, which the journal records on every login:

journalctl -b --no-pager -t sway | grep 'environment variables'

On the QXL test VM the wrapper chose pixman and the legacy DRM interface:

Sep 28 21:13:11 fedora-ws01 sway[4000]: environment variables for wlroots: WLR_RENDERER=pixman WLR_DRM_NO_ATOMIC=1

This is also why logging in through GDM or SDDM beats running sway directly from a TTY: running sway by hand skips the wrapper and its VM detection. From a TTY, start start-sway instead. On other hypervisors the wrapper only sets WLR_NO_HARDWARE_CURSORS=1. If you run a different VM platform, add your own variables to ~/.config/sway/environment, which start-sway sources at every login.

NVIDIA: “Proprietary Nvidia drivers are in use”

Older Sway releases refused to start on the proprietary NVIDIA driver. Sway 1.12 starts, logs !!! Proprietary Nvidia drivers are in use !!!, and raises a red swaynag error bar that reads “Proprietary GPU drivers are not supported by sway. Do not report issues.” These messages are taken from the Fedora 45 Sway 1.12 binary; we did not run it on NVIDIA hardware. The bar goes away when Sway is launched with --unsupported-gpu. Fedora’s /etc/sway/environment carries that flag commented out. Enable it for your user only by putting this line in ~/.config/sway/environment:

SWAY_EXTRA_ARGS="$SWAY_EXTRA_ARGS --unsupported-gpu"

Setting SWAY_UNSUPPORTED_GPU=true in the same file does the same job. The nouveau driver and AMD and Intel GPUs need neither. The same check also fires for the proprietary DisplayLink driver.

Waybar modules show blank icons

Waybar’s icons are Font Awesome private-use characters. fontawesome-7-free-fonts arrives as a weak dependency of waybar, so the packaged config renders fine, but glyphs copied from a web page or chat usually arrive as empty strings, and the module shows its value with a blank gap. Either paste the glyph from Waybar’s own example config in /etc/xdg/waybar/config.jsonc, or use text labels as in the config above. Temperature, backlight and battery modules that vanish entirely are a different case: the journal logs “Disabling module” (or “No batteries.”) because the machine has no matching sensor.

For other desktops on the same base, the GNOME Tweaks and extensions guide covers the GNOME side of this machine, and LXQt on Fedora is the lighter stacking alternative if a tiling compositor is not for you.

Keep reading

Backup and Restore Linux Systems with Timeshift Debian Backup and Restore Linux Systems with Timeshift Things to Do After Installing CachyOS Arch Linux Things to Do After Installing CachyOS Fix Touchpad Issues on Linux (Ubuntu 24.04 / Fedora / Debian 13) Desktop Fix Touchpad Issues on Linux (Ubuntu 24.04 / Fedora / Debian 13) Things to Do After Installing Fedora 42 Workstation Desktop Things to Do After Installing Fedora 42 Workstation Things to Do After Installing EndeavourOS: 10 Tested Steps Arch Linux Things to Do After Installing EndeavourOS: 10 Tested Steps Move Photos from Google Drive to Google Photos in 4 Simple Steps Storage Move Photos from Google Drive to Google Photos in 4 Simple Steps

Leave a Comment

Press ESC to close