Difference between revisions of "Sway"

From NixOS Wiki
Jump to: navigation, search
m (pactl is not in the nixpkgs, enable pulseaudio instead)
Line 1: Line 1:
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.  
+
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]
  
 
== Installation ==
 
== Installation ==
  
=== NixOS ===
+
Here is a minimal configuration where everything you would expect (like screen sharing and gtk themes) work:
[https://search.nixos.org/options?query=sway NixOS options for sway]
+
<syntaxhighlight lang="nix">
 +
{ config, pkgs, lib, ... }:
 +
 
 +
let
 +
  # bash script to let dbus know about important env variables and
 +
  # propogate them to relevent services run at the end of sway config
 +
  # see
 +
  # https://github.com/emersion/xdg-desktop-portal-wlr/wiki/"It-doesn't-work"-Troubleshooting-Checklist
 +
  # note: this is pretty much the same as  /etc/sway/config.d/nixos.conf but also restarts 
 +
  # some user services to make sure they have the correct environment variables
 +
  dbus-sway-environment = pkgs.writeTextFile {
 +
    name = "dbus-sway-environment";
 +
    destination = "/bin/dbus-sway-environment";
 +
    executable = true;
 +
 
 +
    text = ''
 +
  dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP=sway
 +
  systemctl --user stop pipewire pipewire-media-session xdg-desktop-portal xdg-desktop-portal-wlr
 +
  systemctl --user start pipewire pipewire-media-session xdg-desktop-portal xdg-desktop-portal-wlr
 +
      '';
 +
  };
 +
 
 +
  # currently, there is some friction between sway and gtk:
 +
  # https://github.com/swaywm/sway/wiki/GTK-3-settings-on-Wayland
 +
  # the suggested way to set gtk settings is with gsettings
 +
  # for gsettings to work, we need to tell it where the schemas are
 +
  # using the XDG_DATA_DIR environment variable
 +
  # run at the end of sway config
 +
  configure-gtk = pkgs.writeTextFile {
 +
      name = "configure-gtk";
 +
      destination = "/bin/configure-gtk";
 +
      executable = true;
 +
      text = let
 +
        schema = pkgs.gsettings-desktop-schemas;
 +
        datadir = "${schema}/share/gsettings-schemas/${schema.name}";
 +
      in ''
 +
        export XDG_DATA_DIRS=${datadir}:$XDG_DATA_DIRS
 +
        gnome_schema=org.gnome.desktop.interface
 +
        gsettings set $gnome_schema gtk-theme 'Dracula'
 +
        '';
 +
  };
  
<syntaxhighlight lang="nix">
+
 
programs.sway = {
+
in
   enable = true;
+
{
  wrapperFeatures.gtk = true; # so that gtk works properly
+
   environment.systemPackages = with pkgs; [
  extraPackages = with pkgs; [
+
    alacritty # gpu accelerated terminal
 +
    sway
 +
    dbus-sway-environment
 +
    configure-gtk
 +
    wayland
 +
    glib # gsettings
 +
    dracula-theme # gtk theme
 +
    gnome3.adwaita-icon-theme  # default gnome cursors
 
     swaylock
 
     swaylock
 
     swayidle
 
     swayidle
     wl-clipboard
+
    grim # screenshot functionality
    mako # notification daemon
+
    slurp # screenshot functionality
     alacritty # Alacritty is the default terminal in the config
+
     wl-clipboard # wl-copy and wl-paste for copy/paste from stdin / stdout
     dmenu # Dmenu is the default in the config but i recommend wofi since its wayland native
+
     bemenu # wayland clone of dmenu
 +
     mako # notification system developed by swaywm maintainer
 
   ];
 
   ];
};
 
  
 +
 +
  services.pipewire = {
 +
    enable = true;
 +
    alsa.enable = true;
 +
    pulse.enable = true;
 +
  };
 +
 +
 +
  # xdg-desktop-portal works by exposing a series of D-Bus interfaces
 +
  # known as portals under a well-known name
 +
  # (org.freedesktop.portal.Desktop) and object path
 +
  # (/org/freedesktop/portal/desktop).
 +
  # The portal interfaces include APIs for file access, opening URIs,
 +
  # printing and others.
 +
  services.dbus.enable = true;
 +
  xdg.portal = {
 +
    enable = true;
 +
    wlr.enable = true;
 +
    # gtk portal needed to make gtk apps happy
 +
    extraPortals = [ pkgs.xdg-desktop-portal-gtk ];
 +
    gtkUsePortal = true;
 +
  };
 +
 +
  # enable sway window manager
 +
  programs.sway = {
 +
    enable = true;
 +
    wrapperFeatures.gtk = true;
 +
  };
 
</syntaxhighlight>
 
</syntaxhighlight>
  
=== Home Manager ===
+
and here are the relevent things you should add to your sway config:
[https://rycee.gitlab.io/home-manager/options.html#opt-wayland.windowManager.sway.enable Home Manager options for sway]
 
  
<syntaxhighlight lang="nix">
+
{{file|sway config|bash|
wayland.windowManager.sway = {
+
 
  enable = true;
+
set $menu bemenu-run
  wrapperFeatures.gtk = true ;
+
 
};
+
# screenshots
home.packages = with pkgs; [
+
bindsym $mod+c exec grim  -g "$(slurp)" /tmp/$(date +'%H:%M:%S.png')
  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
 
];
 
</syntaxhighlight>
 
  
== Info ==
 
  
=== Clipboard ===
+
exec dbus-sway-environment
 +
exec configure-gtk
  
For clipboard support
+
}}
<syntaxhighlight lang="nix">
 
environment.systemPackages = with pkgs; [ wl-clipboard ];
 
</syntaxhighlight>
 
  
to use [https://github.com/brunelli/wl-clipboard-x11/ wl-clipboard-x11] which is a wrapper to use wl-clipboard as a drop-in replacement to X11 clipboard tools
 
  
<syntaxhighlight lang="nix">
 
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;
 
  })
 
];
 
</syntaxhighlight>
 
{{Note|This will recompile all packages that have xclip or xsel in their dependencies|warn}}
 
  
 
=== Brightness and volume ===
 
=== Brightness and volume ===
  
Brightnessctl has worked better for me than light
 
 
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
 
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
environment.systemPackages = with pkgs; [ brightnessctl ];
 
 
users.users.yourusername.extraGroups = [ "video" ];
 
users.users.yourusername.extraGroups = [ "video" ];
 
# or
 
# or
Line 94: Line 128:
  
 
# Brightness
 
# Brightness
bindsym XF86MonBrightnessDown exec "brightnessctl set 2%-"
+
bindsym XF86MonBrightnessDown exec light -U 10
bindsym XF86MonBrightnessUp exec "brightnessctl set +2%"
+
bindsym XF86MonBrightnessUp exec light -A 10
  
 
# Volume
 
# Volume
Line 103: Line 137:
 
}}
 
}}
  
=== Autostart Sway ===
 
It is possible to use [[greetd]], a minimal login manager, to autostart Sway. In this example, <code>myuser</code> needs to be replaced with the username which should execute Sway:
 
 
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
 
services.greetd = {
 
  enable = true;
 
  settings = rec {
 
    initial_session = {
 
      command = "${pkgs.sway}/bin/sway";
 
      user = "myuser";
 
    };
 
    default_session = initial_session;
 
  };
 
};
 
</nowiki>}}
 
 
Note that this approach starts Sway without asking for a user password. See [[greetd]] for alternative configuration examples.
 
 
Alternatively, using <code>loginShellInit</code> Sway will automatically get started after user login. Use <code>getty</code> if you also want to skip the login and automatically get into <code>tty1</code> with <code>myuser</code>:
 
 
{{file|/etc/nixos/configuration.nix|nix|<nowiki>
 
services.getty.autologinUser = "myuser";
 
 
environment.loginShellInit = ''
 
  if [ -z $DISPLAY ] && [ "$(tty)" = "/dev/tty1" ]; then
 
    exec sway
 
  fi
 
'';
 
</nowiki>}}
 
 
=== Polkit ===
 
 
nix generated sway config
 
<syntaxhighlight lang="nix">
 
${pkgs.polkit_gnome}/libexec/polkit-gnome-authentication-agent-1
 
</syntaxhighlight>
 
 
normal sway config
 
<syntaxhighlight lang="nix">
 
environment.systemPackages = with pkgs; [ polkit_gnome ];
 
environment.pathsToLink = [ "/libexec" ];
 
</syntaxhighlight>
 
 
<syntaxhighlight lang="bash">
 
# 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
 
</syntaxhighlight>
 
 
 
 
=== Theming ===
 
 
==== Gtk ====
 
 
<syntaxhighlight lang="nix">
 
environment.systemPackages = with pkgs; [
 
  gtk-engine-murrine
 
  gtk_engines
 
  gsettings-desktop-schemas
 
  lxappearance
 
];
 
</syntaxhighlight>
 
open lxappearance and pick your themes
 
 
read [https://github.com/swaywm/sway/wiki/GTK-3-settings-on-Wayland GTK3 settings on Wayland]
 
 
==== Qt ====
 
 
<syntaxhighlight lang="nix">
 
programs.qt5ct.enable = true;
 
</syntaxhighlight>
 
open qt5ct and pick your theme
 
  
 
=== Additional packages ===
 
=== Additional packages ===
Line 187: Line 147:
 
{{app|wofi|Launcher/menu program for wlroots based wayland compositors such as sway|https://hg.sr.ht/~scoopta/wofi|wofi}}
 
{{app|wofi|Launcher/menu program for wlroots based wayland compositors such as sway|https://hg.sr.ht/~scoopta/wofi|wofi}}
 
{{app|flashfocus|Simple focus animations for tiling window managers|https://github.com/fennerm/flashfocus|flashfocus}}
 
{{app|flashfocus|Simple focus animations for tiling window managers|https://github.com/fennerm/flashfocus|flashfocus}}
{{app|wf-recorder|Screen recorder for wlroots-based compositors such as sway|https://github.com/ammen99/wf-recorder|wf-recorder}}
 
 
{{app|i3-ratiosplit|Configurable window size on creation|https://github.com/333fred/i3-ratiosplit|i3-ratiosplit}}
 
{{app|i3-ratiosplit|Configurable window size on creation|https://github.com/333fred/i3-ratiosplit|i3-ratiosplit}}
  
Line 193: Line 152:
  
  
=== Systemd integration ===
 
 
In an article on the sway wiki [https://github.com/swaywm/sway/wiki/Systemd-integration], 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 <code>graphical-session.target</code> and can therefore be started as their own user service, including convenient service management and logging.
 
 
<syntaxhighlight lang="nix">
 
{ 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";
 
    };
 
  };
 
 
}
 
</syntaxhighlight>
 
 
And then simply add the following to the ''end'' of your sway configuration
 
<syntaxhighlight>
 
exec "systemctl --user import-environment; systemctl --user start sway-session.target"
 
</syntaxhighlight>
 
  
Note: swayidle will fail cryptically if it cannot find {{ic|sh}} in {{ic|PATH}}, so you must provide this if you create a service file for it. An example is below:
 
 
<syntaxhighlight lang="nix">
 
  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"'
 
      '';
 
    };
 
  };
 
</syntaxhighlight>
 
 
[[Category:Window managers]]
 
[[Category:Window managers]]

Revision as of 15:54, 4 June 2022

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

Here is a minimal configuration where everything you would expect (like screen sharing and gtk themes) work:

{ config, pkgs, lib, ... }:

let
  # bash script to let dbus know about important env variables and
  # propogate them to relevent services run at the end of sway config
  # see
  # https://github.com/emersion/xdg-desktop-portal-wlr/wiki/"It-doesn't-work"-Troubleshooting-Checklist
  # note: this is pretty much the same as  /etc/sway/config.d/nixos.conf but also restarts  
  # some user services to make sure they have the correct environment variables
  dbus-sway-environment = pkgs.writeTextFile {
    name = "dbus-sway-environment";
    destination = "/bin/dbus-sway-environment";
    executable = true;

    text = ''
  dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP=sway
  systemctl --user stop pipewire pipewire-media-session xdg-desktop-portal xdg-desktop-portal-wlr
  systemctl --user start pipewire pipewire-media-session xdg-desktop-portal xdg-desktop-portal-wlr
      '';
  };

  # currently, there is some friction between sway and gtk:
  # https://github.com/swaywm/sway/wiki/GTK-3-settings-on-Wayland
  # the suggested way to set gtk settings is with gsettings
  # for gsettings to work, we need to tell it where the schemas are
  # using the XDG_DATA_DIR environment variable
  # run at the end of sway config
  configure-gtk = pkgs.writeTextFile {
      name = "configure-gtk";
      destination = "/bin/configure-gtk";
      executable = true;
      text = let
        schema = pkgs.gsettings-desktop-schemas;
        datadir = "${schema}/share/gsettings-schemas/${schema.name}";
      in ''
        export XDG_DATA_DIRS=${datadir}:$XDG_DATA_DIRS
        gnome_schema=org.gnome.desktop.interface
        gsettings set $gnome_schema gtk-theme 'Dracula'
        '';
  };


in
{
  environment.systemPackages = with pkgs; [
    alacritty # gpu accelerated terminal
    sway
    dbus-sway-environment
    configure-gtk
    wayland
    glib # gsettings
    dracula-theme # gtk theme
    gnome3.adwaita-icon-theme  # default gnome cursors
    swaylock
    swayidle
    grim # screenshot functionality
    slurp # screenshot functionality
    wl-clipboard # wl-copy and wl-paste for copy/paste from stdin / stdout
    bemenu # wayland clone of dmenu
    mako # notification system developed by swaywm maintainer
  ];


  services.pipewire = {
    enable = true;
    alsa.enable = true;
    pulse.enable = true;
  };


  # xdg-desktop-portal works by exposing a series of D-Bus interfaces
  # known as portals under a well-known name
  # (org.freedesktop.portal.Desktop) and object path
  # (/org/freedesktop/portal/desktop).
  # The portal interfaces include APIs for file access, opening URIs,
  # printing and others.
  services.dbus.enable = true;
  xdg.portal = {
    enable = true;
    wlr.enable = true;
    # gtk portal needed to make gtk apps happy
    extraPortals = [ pkgs.xdg-desktop-portal-gtk ];
    gtkUsePortal = true;
  };

  # enable sway window manager
  programs.sway = {
    enable = true;
    wrapperFeatures.gtk = true;
  };

and here are the relevent things you should add to your sway config:

Breeze-text-x-plain.png
sway config
set $menu bemenu-run

# screenshots
bindsym $mod+c exec grim  -g "$(slurp)" /tmp/$(date +'%H:%M:%S.png')


exec dbus-sway-environment
exec configure-gtk



Brightness and volume

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

hardware.pulseaudio.enable = true;


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


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
  • i3-ratiosplit — Configurable window size on creation
https://github.com/333fred/i3-ratiosplit || i3-ratiosplit

more packages here i3 migration guide