Sway

From NixOS Wiki
Revision as of 13:48, 30 May 2022 by Onny (talk | contribs) (Clarify autologin without password)
Jump to: navigation, search

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

NixOS options for sway

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

Home Manager options for sway

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;
  })
];
Note: This will recompile all packages that have xclip or xsel in their dependencies

Brightness and volume

Brightnessctl has worked better for me than light

Breeze-text-x-plain.png
/etc/nixos/configuration.nix
environment.systemPackages = with pkgs; [ brightnessctl ];
users.users.yourusername.extraGroups = [ "video" ];
# or
programs.light.enable = true;

environment.systemPackages = with pkgs; [ pactl ];


Breeze-text-x-plain.png
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'


Autostart Sway

It is possible to use greetd, a minimal login manager, to autostart Sway. Where myuser needs to be replaced with the username which should execute Sway:

Breeze-text-x-plain.png
/etc/nixos/configuration.nix
services.greetd = {
  enable = true;
  settings = rec {
    initial_session = {
      command = "${pkgs.sway}/bin/sway";
      user = "myuser";
    };
    default_session = initial_session;
  };
};


Note that this approach starts Sway without asking for a user password. See greetd for alternative configuration examples.

Alternatively, using loginShellInit Sway will automatically get started after user login. Use getty if you also want to skip the login and automatically get into tty1 with myuser:

Breeze-text-x-plain.png
/etc/nixos/configuration.nix
services.getty.autologinUser = "myuser";

environment.loginShellInit = ''
  if [ -z $DISPLAY ] && [ "$(tty)" = "/dev/tty1" ]; then
    exec sway
  fi
'';


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

read GTK3 settings on Wayland

Qt

programs.qt5ct.enable = true;

open qt5ct and pick your theme

Additional packages

  • waybar — Highly customizable Wayland bar for Sway and Wlroots based compositors
https://github.com/Alexays/Waybar || waybar
  • autotiling — Script for sway and i3 to automatically switch the horizontal / vertical window split orientation
https://github.com/nwg-piotr/autotiling || autotiling
  • gammastep — Reduces bluelight and saves your eyes
https://gitlab.com/chinstrap/gammastep || gammastep
  • clipman — Simple clipboard manager for Wayland
https://github.com/yory8/clipman/ || clipman
  • wofi — Launcher/menu program for wlroots based wayland compositors such as sway
https://hg.sr.ht/~scoopta/wofi || wofi
  • flashfocus — Simple focus animations for tiling window managers
https://github.com/fennerm/flashfocus || flashfocus
  • wf-recorder — Screen recorder for wlroots-based compositors such as sway
https://github.com/ammen99/wf-recorder || wf-recorder
  • i3-ratiosplit — Configurable window size on creation
https://github.com/333fred/i3-ratiosplit || i3-ratiosplit

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:

  • 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.
{ 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;
    };
  };

  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" ];
  };

  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";
    };
  };

}

And then simply add the following to the end of your sway configuration

exec "systemctl --user import-environment; systemctl --user start sway-session.target"

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"'
      '';
    };
  };