Sway: Difference between revisions
imported>Svrana m add i3-ratiosplit info (works for i3 and sway) |
m nix->NixOS |
||
(68 intermediate revisions by 37 users not shown) | |||
Line 1: | Line 1: | ||
Sway is a tiling | Sway is a tiling Wayland compositor and a drop-in replacement for the i3 window manager for X11. It works with your existing i3 configuration and supports most of i3's features, plus a few extras. | ||
[https://github.com/swaywm/sway/wiki/i3-Migration-Guide i3 migration guide] | [https://github.com/swaywm/sway/wiki/i3-Migration-Guide i3 migration guide] | ||
== | == Setup == | ||
You can install Sway by enabling it in NixOS directly, or by using [[Home Manager]], or both. | |||
[ | |||
=== Using NixOS === | |||
Here is a minimal configuration: | |||
<syntaxhighlight lang="nix"> | <syntaxhighlight lang="nix"> | ||
{ config, pkgs, lib, ... }: | |||
{ | |||
environment.systemPackages = with pkgs; [ | |||
grim # screenshot functionality | |||
slurp # screenshot functionality | |||
wl-clipboard # wl-copy and wl-paste for copy/paste from stdin / stdout | |||
wl-clipboard | mako # notification system developed by swaywm maintainer | ||
mako # notification | |||
]; | ]; | ||
# Enable the gnome-keyring secrets vault. | |||
# Will be exposed through DBus to programs willing to store secrets. | |||
services.gnome.gnome-keyring.enable = true; | |||
# enable Sway window manager | |||
programs.sway = { | |||
enable = true; | |||
wrapperFeatures.gtk = true; | |||
}; | |||
} | |||
</syntaxhighlight>By default, the Sway module in NixOS comes with a set of extra packages, including the <code>foot</code> terminal, <code>swayidle</code>, <code>swaylock</code>, and <code>wmenu</code>, which can be configured under <code>[https://search.nixos.org/options?show=programs.sway.extraPackages programs.sway.extraPackages]</code> option. You may also want to include <code>wl-clipboard</code> for clipboard functionality and <code>slurp</code> for screenshot region selection. Additionally, for a more customizable bar implementation than <code>sway-bar</code>, <code>waybar</code> can be enabled with <code>programs.waybar.enable</code>. | |||
The default Sway configuration is simlinked to <code>/etc/sway/config</code> and <code>/etc/sway/config.d/nixos.conf</code>. The latter file contains dbus and systemd configuration that is critical to using apps that depend on XDG desktop portals with Sway, and should be included in any custom configuration files. | |||
A few general comments: | |||
* There is some friction between GTK theming and Sway. Currently the Sway developers suggest using gsettings to set gtk theme attributes as described here [https://github.com/swaywm/sway/wiki/GTK-3-settings-on-Wayland]. There is currently a plan to allow GTK theme attributes to be set directly in the Sway config. | |||
* Running Sway as a systemd user service is not recommended [https://github.com/swaywm/sway/wiki/Systemd-integration#running-sway-itself-as-a---user-service] [https://github.com/swaywm/sway/issues/5160] | |||
=== Using Home Manager === | |||
To set up Sway using [[Home Manager]], first you must enable [[Polkit]] in your NixOS configuration: | |||
{{file|/etc/nixos/configuration.nix|nix|<nowiki> | |||
security.polkit.enable = true; | |||
</nowiki>}} | |||
Then you can enable Sway in your home manager configuration. Here is a minimal example: | |||
<syntaxhighlight lang="nix> | |||
wayland.windowManager.sway = { | |||
enable = true; | |||
wrapperFeatures.gtk = true; # Fixes common issues with GTK 3 apps | |||
config = rec { | |||
modifier = "Mod4"; | |||
# Use kitty as default terminal | |||
terminal = "kitty"; | |||
startup = [ | |||
# Launch Firefox on start | |||
{command = "firefox";} | |||
]; | |||
}; | |||
}; | |||
</syntaxhighlight> | </syntaxhighlight> | ||
See [https://nix-community.github.io/home-manager/options.xhtml#opt-wayland.windowManager.sway.enable Home Manager's Options for Sway] for a complete list of configuration options. | |||
[https:// | |||
You might need to active dbus manually from .zshrc to use i.e: dunst, see [https://discourse.nixos.org/t/dunst-crashes-if-run-as-service/27671/2 Dunst crashes if run as service] | |||
{{Note| | |||
It's recommended to enable a [[Secret Service]] provider, like GNOME Keyring: | |||
{{file|home.nix|nix|<nowiki> | |||
services.gnome-keyring.enable = true; | |||
</nowiki>}} | |||
}} | |||
=== Systemd services === | |||
Kanshi is an output configuration daemon. As explained above, we don't run Sway itself as a systemd service. There are auxiliary daemons that we do want to run as systemd services, for example Kanshi [https://sr.ht/~emersion/kanshi/], which implements monitor hot swapping. It would be enabled as follows: | |||
{{file|/etc/nixos/configuration.nix|nix|<nowiki> | |||
# kanshi systemd service | |||
}; | systemd.user.services.kanshi = { | ||
description = "kanshi daemon"; | |||
environment = { | |||
WAYLAND_DISPLAY="wayland-1"; | |||
DISPLAY = ":0"; | |||
}; | |||
serviceConfig = { | |||
Type = "simple"; | |||
ExecStart = ''${pkgs.kanshi}/bin/kanshi -c kanshi_config_file''; | |||
}; | |||
}; | |||
</nowiki>}} | |||
{{file|sway config|bash| | |||
# give Sway a little time to startup before starting kanshi. | |||
exec sleep 5; systemctl --user start kanshi.service | |||
}} | |||
When you launch Sway, the systemd service is started. | |||
=== Using greeter === | |||
Installing a greeter based on [https://search.nixos.org/options?channel=unstable&show=services.greetd.settings&from=0&size=50&sort=relevance&type=packages&query=greetd greetd] is the most straightforward way to launch Sway. | |||
Tuigreet does not even need a separate compositor to launch. | |||
== | {{file|/etc/nixos/configuration.nix|nix|<nowiki> | ||
services.greetd = { | |||
enable = true; | |||
settings = { | |||
default_session = { | |||
command = "${pkgs.greetd.tuigreet}/bin/tuigreet --time --cmd sway"; | |||
user = "greeter"; | |||
}; | |||
}; | |||
}; | |||
</nowiki>}} | |||
== | == Configuration == | ||
Sway can be configured for specific users using Home-Manager or manually through configuration files. Default is <code>/etc/sway/config</code> and custom user configuration in <code>~/.config/sway/config</code>. | |||
=== Keyboard layout === | |||
<syntaxhighlight lang=" | Changing layout for all keyboards to German (de)<syntaxhighlight lang="console"> | ||
input * xkb_layout "de" | |||
</syntaxhighlight> | </syntaxhighlight> | ||
=== High-DPI scaling === | |||
Changing scale for all screens to factor 1.5<syntaxhighlight lang="console"> | |||
output * scale 1.5 | |||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Brightness and volume === | === Brightness and volume === | ||
You can set up brightness and volume function keys as follows by binding the key codes to their corresponding commands in your sway config. The following configurations accomplish this using <code>light</code> and <code>pulseaudio</code>: | |||
{{file|/etc/nixos/configuration.nix|nix|<nowiki> | {{file|/etc/nixos/configuration.nix|nix|<nowiki> | ||
users.users.yourusername.extraGroups = [ "video" ]; | users.users.yourusername.extraGroups = [ "video" ]; | ||
programs.light.enable = true; | programs.light.enable = true; | ||
environment.systemPackages = [ pkgs.pulseaudio ]; | |||
environment.systemPackages = | |||
</nowiki>}} | </nowiki>}} | ||
Line 94: | Line 133: | ||
# Brightness | # Brightness | ||
bindsym XF86MonBrightnessDown exec | bindsym XF86MonBrightnessDown exec light -U 10 | ||
bindsym XF86MonBrightnessUp exec | bindsym XF86MonBrightnessUp exec light -A 10 | ||
# Volume | # Volume | ||
Line 103: | Line 142: | ||
}} | }} | ||
=== | == Troubleshooting == | ||
=== Cursor is too tiny on HiDPI displays === | |||
Using [[Home Manager]] try configuring a general mouse cursor size and theme | |||
<syntaxhighlight lang="nix | |||
<syntaxhighlight lang="nix> | |||
home-manager.users.myUser = { | |||
home.pointerCursor = { | |||
name = "Adwaita"; | |||
package = pkgs.gnome.adwaita-icon-theme; | |||
size = 24; | |||
x11 = { | |||
enable = true; | |||
defaultCursor = "Adwaita"; | |||
}; | |||
}; | |||
}; | |||
</syntaxhighlight> | </syntaxhighlight> | ||
< | Replace <code>myUser</code> with your user running the graphical environment. | ||
</ | |||
=== Missing fonts on Xorg applications === | |||
If fonts for certain languages are missing in Xorg applications (e.g. Japanese fonts don't appear in Discord) even though they're in the system, you can set them as default fonts in your configuration file. | |||
= | <syntaxhighlight lang="nix> | ||
==== | fonts = { | ||
packages = with pkgs; [ | |||
noto-fonts | |||
noto-fonts-cjk | |||
noto-fonts-emoji | |||
font-awesome | |||
source-han-sans | |||
source-han-sans-japanese | |||
source-han-serif-japanese | |||
]; | |||
fontconfig.defaultFonts = { | |||
serif = [ "Noto Serif" "Source Han Serif" ]; | |||
sansSerif = [ "Noto Sans" "Source Han Sans" ]; | |||
}; | |||
}; | |||
</syntaxhighlight> | </syntaxhighlight> | ||
=== Swaylock cannot be unlocked with the correct password === | |||
Add the following to your NixOS configuration. | |||
<syntaxhighlight lang="nix | <syntaxhighlight lang="nix> | ||
security.pam.services.swaylock = {}; | |||
</syntaxhighlight> | </syntaxhighlight> | ||
The <code>programs.sway.enable</code> option does this automatically. | |||
=== Inferior performance compared to other distributions === | |||
Enabling realtime may improve latency and reduce stuttering, specially in high load scenarios. | |||
<syntaxhighlight lang="nix"> | |||
security.pam.loginLimits = [ | |||
{ domain = "@users"; item = "rtprio"; type = "-"; value = 1; } | |||
]; | |||
</syntaxhighlight> | |||
Enabling this option allows any program run by the "users" group to request real-time priority. | |||
=== | === WLR Error when trying to launch Sway === | ||
When this happens on a new nixos system, enabling opengl in configuration.nix may fix this issue. | |||
<syntaxhighlight lang="nix"> | <syntaxhighlight lang="nix"> | ||
hardware.opengl.enable = true; | |||
</syntaxhighlight> | |||
=== Touchscreen input bound to the wrong monitor in multi-monitor setups === | |||
See this [https://github.com/swaywm/sway/issues/6590#issue-1021207180 GitHub issue for Sway] and the solution give in [https://github.com/swaywm/sway/issues/6590#issuecomment-938724355 this response]. | |||
Using [[Home Manager]] add the following to your Sway configuration: | |||
<syntaxhighlight lang="nix"> | |||
wayland.windowManager.sway = { | |||
[...] | |||
config = { | |||
[...] | |||
input = { | |||
[...] | |||
"type:touch" = { | |||
# Replace touchscreen_output_identifier with the identifier of your touchscreen. | |||
map_to_output = touchscreen_output_identifier; | |||
}; | |||
}; | |||
}; | |||
}; | |||
</syntaxhighlight> | |||
=== GTK apps take an exceptionally long time to start === | |||
This occurs because GTK apps make blocking calls to freedesktop portals to be displayed. If Sway is not integrated with dbus and systemd, it will not be able to communicate via the <code>org.freedesktop.portal.Desktop</code> portal. To fix this, see the [[Sway#Using NixOS|description]] of default Sway configurations earlier. Adding the following to your sway configuration, if it is not already present, may resolve the issue: | |||
include /etc/sway/config.d/* | |||
== Tips and tricks == | |||
=== Toggle monitor modes script === | |||
Following script toggles screen / monitor modes if executed. It can also be mapped to a specific key in Sway. | |||
First add the Flake input required for the script<syntaxhighlight lang="nix"> | |||
{ | |||
inputs = { | |||
[...] | |||
wl-togglescreens.url = "git+https://git.project-insanity.org/onny/wl-togglescreens.git?ref=main"; | |||
}; | }; | ||
} | outputs = {self, nixpkgs, ...}@inputs: { | ||
nixosConfigurations.myhost = inputs.nixpkgs.lib.nixosSystem { | |||
</syntaxhighlight> | system = "x86_64-linux"; | ||
specialArgs.inputs = inputs; | |||
[...] | |||
</syntaxhighlight>Map the script binary to a specific key<syntaxhighlight lang="nix"> | |||
<syntaxhighlight lang="nix"> | { config, pkgs, lib, inputs, ... }:{ | ||
home-manager.users.onny = { | |||
programs = { | |||
[...] | |||
wayland.windowManager.sway = { | |||
enable = true; | |||
config = { | |||
[...] | |||
keybindings = lib.mkOptionDefault{ | |||
[...] | |||
"XF86Display" = "exec ${inputs.wl-togglescreens.packages.x86_64-linux.wl-togglescreens}/bin/wl-togglescreens"; | |||
}; | |||
}; | |||
}; | |||
}; | }; | ||
</syntaxhighlight> | </syntaxhighlight> | ||
[[Category:Window managers]] | [[Category:Window managers]] | ||
[[Category:Applications]] |
Latest revision as of 18:21, 25 January 2025
Sway is a tiling Wayland compositor and a drop-in replacement for the i3 window manager for X11. It works with your existing i3 configuration and supports most of i3's features, plus a few extras. i3 migration guide
Setup
You can install Sway by enabling it in NixOS directly, or by using Home Manager, or both.
Using NixOS
Here is a minimal configuration:
{ config, pkgs, lib, ... }:
{
environment.systemPackages = with pkgs; [
grim # screenshot functionality
slurp # screenshot functionality
wl-clipboard # wl-copy and wl-paste for copy/paste from stdin / stdout
mako # notification system developed by swaywm maintainer
];
# Enable the gnome-keyring secrets vault.
# Will be exposed through DBus to programs willing to store secrets.
services.gnome.gnome-keyring.enable = true;
# enable Sway window manager
programs.sway = {
enable = true;
wrapperFeatures.gtk = true;
};
}
By default, the Sway module in NixOS comes with a set of extra packages, including the foot
terminal, swayidle
, swaylock
, and wmenu
, which can be configured under programs.sway.extraPackages
option. You may also want to include wl-clipboard
for clipboard functionality and slurp
for screenshot region selection. Additionally, for a more customizable bar implementation than sway-bar
, waybar
can be enabled with programs.waybar.enable
.
The default Sway configuration is simlinked to /etc/sway/config
and /etc/sway/config.d/nixos.conf
. The latter file contains dbus and systemd configuration that is critical to using apps that depend on XDG desktop portals with Sway, and should be included in any custom configuration files.
A few general comments:
- There is some friction between GTK theming and Sway. Currently the Sway developers suggest using gsettings to set gtk theme attributes as described here [1]. There is currently a plan to allow GTK theme attributes to be set directly in the Sway config.
- Running Sway as a systemd user service is not recommended [2] [3]
Using Home Manager
To set up Sway using Home Manager, first you must enable Polkit in your NixOS configuration:

/etc/nixos/configuration.nix
security.polkit.enable = true;
Then you can enable Sway in your home manager configuration. Here is a minimal example:
wayland.windowManager.sway = {
enable = true;
wrapperFeatures.gtk = true; # Fixes common issues with GTK 3 apps
config = rec {
modifier = "Mod4";
# Use kitty as default terminal
terminal = "kitty";
startup = [
# Launch Firefox on start
{command = "firefox";}
];
};
};
See Home Manager's Options for Sway for a complete list of configuration options.
You might need to active dbus manually from .zshrc to use i.e: dunst, see Dunst crashes if run as service
Systemd services
Kanshi is an output configuration daemon. As explained above, we don't run Sway itself as a systemd service. There are auxiliary daemons that we do want to run as systemd services, for example Kanshi [4], which implements monitor hot swapping. It would be enabled as follows:

/etc/nixos/configuration.nix
# kanshi systemd service
systemd.user.services.kanshi = {
description = "kanshi daemon";
environment = {
WAYLAND_DISPLAY="wayland-1";
DISPLAY = ":0";
};
serviceConfig = {
Type = "simple";
ExecStart = ''${pkgs.kanshi}/bin/kanshi -c kanshi_config_file'';
};
};

sway config
# give Sway a little time to startup before starting kanshi.
exec sleep 5; systemctl --user start kanshi.service
When you launch Sway, the systemd service is started.
Using greeter
Installing a greeter based on greetd is the most straightforward way to launch Sway.
Tuigreet does not even need a separate compositor to launch.

/etc/nixos/configuration.nix
services.greetd = {
enable = true;
settings = {
default_session = {
command = "${pkgs.greetd.tuigreet}/bin/tuigreet --time --cmd sway";
user = "greeter";
};
};
};
Configuration
Sway can be configured for specific users using Home-Manager or manually through configuration files. Default is /etc/sway/config
and custom user configuration in ~/.config/sway/config
.
Keyboard layout
Changing layout for all keyboards to German (de)
input * xkb_layout "de"
High-DPI scaling
Changing scale for all screens to factor 1.5
output * scale 1.5
Brightness and volume
You can set up brightness and volume function keys as follows by binding the key codes to their corresponding commands in your sway config. The following configurations accomplish this using light
and pulseaudio
:

/etc/nixos/configuration.nix
users.users.yourusername.extraGroups = [ "video" ];
programs.light.enable = true;
environment.systemPackages = [ pkgs.pulseaudio ];

sway config
# Brightness
bindsym XF86MonBrightnessDown exec light -U 10
bindsym XF86MonBrightnessUp exec light -A 10
# Volume
bindsym XF86AudioRaiseVolume exec 'pactl set-sink-volume @DEFAULT_SINK@ +1%'
bindsym XF86AudioLowerVolume exec 'pactl set-sink-volume @DEFAULT_SINK@ -1%'
bindsym XF86AudioMute exec 'pactl set-sink-mute @DEFAULT_SINK@ toggle'
Troubleshooting
Cursor is too tiny on HiDPI displays
Using Home Manager try configuring a general mouse cursor size and theme
home-manager.users.myUser = {
home.pointerCursor = {
name = "Adwaita";
package = pkgs.gnome.adwaita-icon-theme;
size = 24;
x11 = {
enable = true;
defaultCursor = "Adwaita";
};
};
};
Replace myUser
with your user running the graphical environment.
Missing fonts on Xorg applications
If fonts for certain languages are missing in Xorg applications (e.g. Japanese fonts don't appear in Discord) even though they're in the system, you can set them as default fonts in your configuration file.
fonts = {
packages = with pkgs; [
noto-fonts
noto-fonts-cjk
noto-fonts-emoji
font-awesome
source-han-sans
source-han-sans-japanese
source-han-serif-japanese
];
fontconfig.defaultFonts = {
serif = [ "Noto Serif" "Source Han Serif" ];
sansSerif = [ "Noto Sans" "Source Han Sans" ];
};
};
Swaylock cannot be unlocked with the correct password
Add the following to your NixOS configuration.
security.pam.services.swaylock = {};
The programs.sway.enable
option does this automatically.
Inferior performance compared to other distributions
Enabling realtime may improve latency and reduce stuttering, specially in high load scenarios.
security.pam.loginLimits = [
{ domain = "@users"; item = "rtprio"; type = "-"; value = 1; }
];
Enabling this option allows any program run by the "users" group to request real-time priority.
WLR Error when trying to launch Sway
When this happens on a new nixos system, enabling opengl in configuration.nix may fix this issue.
hardware.opengl.enable = true;
Touchscreen input bound to the wrong monitor in multi-monitor setups
See this GitHub issue for Sway and the solution give in this response.
Using Home Manager add the following to your Sway configuration:
wayland.windowManager.sway = {
[...]
config = {
[...]
input = {
[...]
"type:touch" = {
# Replace touchscreen_output_identifier with the identifier of your touchscreen.
map_to_output = touchscreen_output_identifier;
};
};
};
};
GTK apps take an exceptionally long time to start
This occurs because GTK apps make blocking calls to freedesktop portals to be displayed. If Sway is not integrated with dbus and systemd, it will not be able to communicate via the org.freedesktop.portal.Desktop
portal. To fix this, see the description of default Sway configurations earlier. Adding the following to your sway configuration, if it is not already present, may resolve the issue:
include /etc/sway/config.d/*
Tips and tricks
Toggle monitor modes script
Following script toggles screen / monitor modes if executed. It can also be mapped to a specific key in Sway.
First add the Flake input required for the script
{
inputs = {
[...]
wl-togglescreens.url = "git+https://git.project-insanity.org/onny/wl-togglescreens.git?ref=main";
};
outputs = {self, nixpkgs, ...}@inputs: {
nixosConfigurations.myhost = inputs.nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
specialArgs.inputs = inputs;
[...]
Map the script binary to a specific key
{ config, pkgs, lib, inputs, ... }:{
home-manager.users.onny = {
programs = {
[...]
wayland.windowManager.sway = {
enable = true;
config = {
[...]
keybindings = lib.mkOptionDefault{
[...]
"XF86Display" = "exec ${inputs.wl-togglescreens.packages.x86_64-linux.wl-togglescreens}/bin/wl-togglescreens";
};
};
};
};