Sway: Difference between revisions

From NixOS Wiki
imported>Vieta
fonts -> packages
Axka (talk | contribs)
No edit summary
 
(24 intermediate revisions by 14 users not shown)
Line 2: Line 2:
[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 ==
== Setup ==
You can install Sway by enabling it in NixOS directly, or by using [[Home Manager]]. Note that if you enable Sway using NixOS (via <code>programs.sway.enable = true;</code> in <code>configuration.nix</code>), your Home Manager configurations for Sway will be ignored.
You can install Sway by enabling it in NixOS directly, or by using [[Home Manager]], or both.


=== Using NixOS ===
=== Using NixOS ===
Here is a minimal configuration (without [[Home Manager]]) where everything you would expect (like screen sharing and gtk themes) work:
Here is a minimal configuration:
<syntaxhighlight lang="nix">
<syntaxhighlight lang="nix">
{ config, pkgs, lib, ... }:
{ config, pkgs, lib, ... }:
let
  # bash script to let dbus know about important env variables and
  # propagate 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; [
   environment.systemPackages = with pkgs; [
    alacritty # gpu accelerated terminal
    dbus-sway-environment
    configure-gtk
    wayland
    xdg-utils # for opening default programs when clicking links
    glib # gsettings
    dracula-theme # gtk theme
    gnome3.adwaita-icon-theme  # default gnome cursors
    swaylock
    swayidle
     grim # screenshot functionality
     grim # screenshot functionality
     slurp # screenshot functionality
     slurp # screenshot functionality
     wl-clipboard # wl-copy and wl-paste for copy/paste from stdin / stdout
     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
     mako # notification system developed by swaywm maintainer
    wdisplays # tool to configure displays
   ];
   ];


   services.pipewire = {
   # Enable the gnome-keyring secrets vault.  
    enable = true;
  # Will be exposed through DBus to programs willing to store secrets.
    alsa.enable = true;
  services.gnome.gnome-keyring.enable = true;
    pulse.enable = true;
  };


   # xdg-desktop-portal works by exposing a series of D-Bus interfaces
   # enable Sway window manager
  # 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 ];
  };
 
  # enable sway window manager
   programs.sway = {
   programs.sway = {
     enable = true;
     enable = true;
Line 97: Line 28:
}
}
</syntaxhighlight>
</syntaxhighlight>
and here are the relevent things you should add to your sway config:
{{file|sway config|bash|
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
}}


A few general comments:
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.
* 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]
* 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]
* This wiki page was gutted and rewritten in June 2022. See [https://discourse.nixos.org/t/some-lose-ends-for-sway-on-nixos-which-we-should-fix/17728] for the related discussion.


=== Using Home Manager ===
=== Using Home Manager ===
Line 128: Line 43:
   wayland.windowManager.sway = {
   wayland.windowManager.sway = {
     enable = true;
     enable = true;
    wrapperFeatures.gtk = true; # Fixes common issues with GTK 3 apps
     config = rec {
     config = rec {
       modifier = "Mod4";
       modifier = "Mod4";
Line 140: Line 56:
</syntaxhighlight>
</syntaxhighlight>


See [https://rycee.gitlab.io/home-manager/options.html#opt-wayland.windowManager.sway.enable Home Manager's Options for Sway] for a complete list of configuration options.
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.


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]
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 ===
Changing layout for all keyboards to German (de)<syntaxhighlight lang="console">
input * xkb_layout "de"
</syntaxhighlight>
=== High-DPI scaling ===
Changing scale for all screens to factor 1.5<syntaxhighlight lang="console">
output * scale 1.5
</syntaxhighlight>


=== Brightness and volume ===
=== Brightness and volume ===
Line 149: Line 125:
users.users.yourusername.extraGroups = [ "video" ];
users.users.yourusername.extraGroups = [ "video" ];
programs.light.enable = true;
programs.light.enable = true;
 
environment.systemPackages = [ pkgs.pulseaudio ];
</nowiki>}}
</nowiki>}}


Line 163: Line 139:
bindsym XF86AudioMute exec 'pactl set-sink-mute @DEFAULT_SINK@ toggle'
bindsym XF86AudioMute exec 'pactl set-sink-mute @DEFAULT_SINK@ toggle'
}}
}}
=== Systemd services ===
Kanshi is 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";
    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.


== Troubleshooting ==
== Troubleshooting ==
Line 210: Line 167:
=== Missing fonts on Xorg applications ===
=== 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
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>
<syntaxhighlight lang="nix>
Line 254: Line 211:
Enabling this option allows any program run by the "users" group to request real-time priority.
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">
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>
== 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 {
      system = "x86_64-linux";
      specialArgs.inputs = inputs;
      [...]
</syntaxhighlight>Map the script binary to a specific key<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>
[[Category:Window managers]]
[[Category:Window managers]]
[[Category:Applications]]
[[Category:Applications]]

Latest revision as of 14:19, 19 November 2024

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

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 nix 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

Note:

It's recommended to enable a Secret Service provider, like GNOME Keyring:

home.nix
services.gnome-keyring.enable = true;

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

If you are on a laptop, you can set up brightness and volume function keys as follows:

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

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