Sway
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
Installation
NixOS
programs.sway = {
enable = true;
wrapperFeatures.gtk = true; # so that gtk works properly
extraPackages = with pkgs; [
swaylock
swayidle
wl-clipboard
mako # notification daemon
alacritty # Alacritty is the default terminal in the config
dmenu # Dmenu is the default in the config but i recommend wofi since its wayland native
];
};
Home Manager
wayland.windowManager.sway = {
enable = true;
wrapperFeatures.gtk = true ;
};
home.packages = with pkgs; [
swaylock
swayidle
wl-clipboard
mako # notification daemon
alacritty # Alacritty is the default terminal in the config
dmenu # Dmenu is the default in the config but i recommend wofi since its wayland native
];
Info
Clipboard
For clipboard support
environment.systemPackages = with pkgs; [ wl-clipboard ];
to use wl-clipboard-x11 which is a wrapper to use wl-clipboard as a drop-in replacement to X11 clipboard tools
nixpkgs.overlays = [
(self: super: {
wl-clipboard-x11 = super.stdenv.mkDerivation rec {
pname = "wl-clipboard-x11";
version = "5";
src = super.fetchFromGitHub {
owner = "brunelli";
repo = "wl-clipboard-x11";
rev = "v${version}";
sha256 = "1y7jv7rps0sdzmm859wn2l8q4pg2x35smcrm7mbfxn5vrga0bslb";
};
dontBuild = true;
dontConfigure = true;
propagatedBuildInputs = [ super.wl-clipboard ];
makeFlags = [ "PREFIX=$(out)" ];
};
xsel = self.wl-clipboard-x11;
xclip = self.wl-clipboard-x11;
})
];
Brightness and volume
Brightnessctl has worked better for me than light
/etc/nixos/configuration.nix
environment.systemPackages = with pkgs; [ brightnessctl ];
users.users.yourusername.extraGroups = [ "video" ];
# or
programs.light.enable = true;
environment.systemPackages = with pkgs; [ pactl ];
sway config
# Brightness
bindsym XF86MonBrightnessDown exec "brightnessctl set 2%-"
bindsym XF86MonBrightnessUp exec "brightnessctl set +2%"
# 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'
Polkit
nix generated sway config
${pkgs.polkit_gnome}/libexec/polkit-gnome-authentication-agent-1
normal sway config
environment.systemPackages = with pkgs; [ polkit_gnome ];
environment.pathsToLink = [ "/libexec" ];
# NixOS
exec /run/current-system/sw/libexec/polkit-gnome-authentication-agent-1
# Home Manager | pathsToLink is not needed
exec ~/.nix-profile/libexec/polkit-gnome-authentication-agent-1
Theming
Gtk
environment.systemPackages = with pkgs; [
gtk-engine-murrine
gtk_engines
gsettings-desktop-schemas
lxappearance
];
open lxappearance and pick your themes
Qt
programs.qt5ct.enable = true;
open qt5ct and pick your theme
Additional packages
- waybar — Highly customizable Wayland bar for Sway and Wlroots based compositors
- autotiling — Script for sway and i3 to automatically switch the horizontal / vertical window split orientation
- gammastep — Reduces bluelight and saves your eyes
- clipman — Simple clipboard manager for Wayland
- wofi — Launcher/menu program for wlroots based wayland compositors such as sway
- flashfocus — Simple focus animations for tiling window managers
- wf-recorder — Screen recorder for wlroots-based compositors such as sway
more packages here i3 migration guide
Systemd integration
In an article on the sway wiki [1], a way to integrate Sway with systemd user services is proposed. Starting sway that way has some benefits:
- Logging for Sway is done the same way it is done for every other user service.
- Services like Waybar, kanshi, redshift can depend on
graphical-session.target
and can therefore be started as their own user service, including convenient service management and logging.
Don't forget to additionally start sway-session.target
with one of the methods described in the sway wiki.
{ config, pkgs, lib, ... }: {
programs.sway = {
enable = true;
extraPackages = with pkgs; [
swaylock # lockscreen
swayidle
xwayland # for legacy apps
waybar # status bar
mako # notification daemon
kanshi # autorandr
];
};
environment = {
etc = {
# Put config files in /etc. Note that you also can put these in ~/.config, but then you can't manage them with NixOS anymore!
"sway/config".source = ./dotfiles/sway/config;
"xdg/waybar/config".source = ./dotfiles/waybar/config;
"xdg/waybar/style.css".source = ./dotfiles/waybar/style.css;
};
};
# Here we but a shell script into path, which lets us start sway.service (after importing the environment of the login shell).
environment.systemPackages = with pkgs; [
(
pkgs.writeTextFile {
name = "startsway";
destination = "/bin/startsway";
executable = true;
text = ''
#! ${pkgs.bash}/bin/bash
# first import environment variables from the login manager
systemctl --user import-environment
# then start the service
exec systemctl --user start sway.service
'';
}
)
];
systemd.user.targets.sway-session = {
description = "Sway compositor session";
documentation = [ "man:systemd.special(7)" ];
bindsTo = [ "graphical-session.target" ];
wants = [ "graphical-session-pre.target" ];
after = [ "graphical-session-pre.target" ];
};
systemd.user.services.sway = {
description = "Sway - Wayland window manager";
documentation = [ "man:sway(5)" ];
bindsTo = [ "graphical-session.target" ];
wants = [ "graphical-session-pre.target" ];
after = [ "graphical-session-pre.target" ];
# We explicitly unset PATH here, as we want it to be set by
# systemctl --user import-environment in startsway
environment.PATH = lib.mkForce null;
serviceConfig = {
Type = "simple";
ExecStart = ''
${pkgs.dbus}/bin/dbus-run-session ${pkgs.sway}/bin/sway --debug
'';
Restart = "on-failure";
RestartSec = 1;
TimeoutStopSec = 10;
};
};
services.redshift = {
enable = true;
# Redshift with wayland support isn't present in nixos-19.09 atm. You have to cherry-pick the commit from https://github.com/NixOS/nixpkgs/pull/68285 to do that.
package = pkgs.redshift-wlr;
};
programs.waybar.enable = true;
systemd.user.services.kanshi = {
description = "Kanshi output autoconfig ";
wantedBy = [ "graphical-session.target" ];
partOf = [ "graphical-session.target" ];
serviceConfig = {
# kanshi doesn't have an option to specifiy config file yet, so it looks
# at .config/kanshi/config
ExecStart = ''
${pkgs.kanshi}/bin/kanshi
'';
RestartSec = 5;
Restart = "always";
};
};
}
Note: swayidle will fail cryptically if it cannot find sh
in PATH
, so you must provide this if you create a service file for it. An example is below:
systemd.user.services.swayidle = {
description = "Idle Manager for Wayland";
documentation = [ "man:swayidle(1)" ];
wantedBy = [ "sway-session.target" ];
partOf = [ "graphical-session.target" ];
path = [ pkgs.bash ];
serviceConfig = {
ExecStart = '' ${pkgs.swayidle}/bin/swayidle -w -d \
timeout 300 '${pkgs.sway}/bin/swaymsg "output * dpms off"' \
resume '${pkgs.sway}/bin/swaymsg "output * dpms on"'
'';
};
};