i3 is one of the many tiling window managers available for the X11 display server. I’ve been using i3 for some time, in fact it was the one and only tiling wm I had used before switching over to Sway.

In this post I’ll go over the differences I’ve experienced as a former i3 user switching to Sway.

X11 and Wayland

First and foremost, let’s address the biggest difference between i3 and Sway. i3 is a window manager for X11, while Sway is a Wayland window manager and compositor.

X11 (or X Window System, Xorg, or simply X) is a legendary display server for Unix-like operating systems. It controls displays and input devices, but it does not organize windows. X11 is often used together with a window manager, be it tiling (like i3) or stacking (like Openbox, KDE or Gnome). Most often X11 is used with a compositor, which uses GPU rendering to composite the windows into buffers and allow more sophisticated graphic APIs to draw the screen, with the ability to add effects and vsync. WMs and compositors can be interchanged and mixed together in X11, as long as a base X11 server is running.

Wayland is a newer display server, aimed to become a replacement and successor of X11. Like X11, it also controls displays and inputs, but it is rather a more complete system, for better or worse. A Wayland server is a full implementation of the Wayland protocols with a compositor and a window manager. This means that, unlike X11, window managers and compositors are tightly coupled and cannot be interchanged or mixed. This is a design decision made to reduce the codebase and complexity of the protocols.

Switching from i3 to Sway means that we are changing displays servers as well.

Scaling

Scaling in X11 is generally done via font-size DPI, or changing the underlying render resolution and scaling to the display’s resolution.

Sway scales all the UI elements without changing the underlying render resolution, which avoids aliasing issues or UI elements to look out of place with their texts enlarged as you normally with X11.

Setting 150% scale is as easy as running swaymsg output <output> scale 1.5, or setting the same in .config/sway/config.

Mixed framerates and adaptive sync (variable refresh rate)

I’ve had better luck with mixed framerates and Adaptive Sync (variable refresh rate – VRR) in Sway. Having multiple framerates in X11 for some reason always ran the displays at the lowest rate set between all of them for me.

Vsync and latency

With Sway you don’t really need to think about screen tearing, as sway is also the compositor which handles vsync. In i3, if you want vsync, you need to run a compositor or use TearFree directly in X11, which introduces some performance and latency penalty.

Sway allows you to set max_render_time per output, which allows you to have the best of both worlds: No screen tearing and low-latency.

Automatic display switching

If you want workspaces in i3 to be moved around to other displays when you plug/unplug an output, you need something like xrandr --auto, autorandr or dockd. With Sway this isn’t necessary, Sway remembers what outputs the workspaces were before being unplugged and moves them back when the display is reconnected.

Configuration changes

Sway config is compatible with the i3 config file, so you can literally copy your i3 config as a starting point. Obviously with Sway you can’t use .xinitrc, so you need to add anything you started with startx with exec statements in .config/sway/config.

Basic commands

X11 has a lot of tools developed that interface directly with the X11 server, which means they work regardless of window manager.

With Sway you will find that a lot of the commands need to be executed through swaymsg.

i3 Sway
xrandr swaymsg -t get_outputs
xrandr --output DP-1 --mode 1920x1080 swaymsg output DP-1 mode 1920x1080
xinput swaymsg -t get_inputs
setxkbmap -layout us swaymsg input xkb_layout us

As can be seen, input and output configuration is done directly in Sway.

If you pipe swaymsg -t you will get JSON output, which is handy for scripting. Anything that you set via swaymsg can be place directly in .config/sway/config as well to have it applied when Sway boots up. For example, to set resolutions and input configuration you can simply add this to the config file and Sway will apply it.

output * {
    bg ~/.wallpaper fill #000000
}

output DP-1 {
    mode 3440x1440@120.000Hz
    adaptive_sync on
    render_bit_depth 10
    pos 0 0
}

output eDP-1 {
    max_render_time 8
    pos 760 1440
}

input * {
    xkb_layout "us"
    repeat_delay 300
    repeat_rate 60
    natural_scroll enabled
}

There is no equivalent for /etc/X11/xorg.conf, everything is configured in .config/sway/config, using the same syntax as swaymsg which is nice.

Everything else is compatible with existing i3 configuration, like keybindings.

Wayland native apps

X11 clients work in Wayland through XWayland, but they lack some features like native scaling. So, in order to maximize the Sway functionality, using native Wayland clients is recommended.

X11 Wayland
Firefox Firefox (native)
Chromium Chromium (needs custom flags)
Electron based apps Most of them work with custom flags
OBS OBS (native)
dunst dunst (native)
clipmenud clipman
flameshot grim + slurp + swappy
arandr wdisplays
rofi rofi (through XWayland, haven’t found a worthy native replacement)

Sandboxing solutions like Flatpak or Sandman (my own project) help a lot with setting custom flags or environment variables for Wayland.

The Archlinux Wayland wiki also has a lot of useful information, workarounds and Wayland native alternatives.

Shortcomings

Screen capture

Screen capturing works differently in Wayland. Clients do not have permissions to capture screen or the input. All screen capture is done through Pipewire and Desktop portals. OBS has native support for Wayland screen capture, but most apps haven’t been updated to use it.

This can be seen as an advantage in some cases, because no rogue apps can record your screen without going through your explicit approval through a portal.

X11 forwarding via SSH

X11 is notorious for being able to run seamlessly through an SSH connection. Wayland has some alternatives to that but they’re not as transparent as X11.

Global shortcuts

All input is handled by the Wayland compositor. The compositor routes input to the focused window, so applications cannot arbitrarily read keyboard input to implement shortcuts if they are not in focus, so Global Shortcuts do not work as well as they do in X11.

Again, this can be seen as an advantage in some cases, where this makes keyloggers way harder to be implemented, requiring priviledge escalation where in X11 it’s not the case by default (some window managers work around this behavior, but it’s not native in X11)

The bottom line

Overall I’m very satisfied with Sway and I’ve been daily driving it for about 6 months at the time of writing. I still have i3 installed as a backup, but I’ve found that I didn’t miss anything or needed to go back due to a crash or bug. A lot of the small annoyances I had with i3 and X11, like random crashes, inconsistent framerates and display tearing, were gone with Sway.

Big distros are also using the Wayland session as their default, like Ubuntu, Fedora and SteamOS, which is a testament to the maturity of the Wayland project overall.

I recommend giving Sway a go, even if i3 works just fine for you. It has been a nice ride re-learning and discovering how to configure my system with Wayland, kind of the same way I felt when I first started using Linux about 13 years ago… but that’s a story for another article.

References

https://artemis.sh/2022/09/18/wayland-from-an-x-apologist.html

https://wiki.archlinux.org/title/Wayland

https://github.com/swaywm/sway/wiki

https://i3wm.org/