AboutServicesProjectsBlog
Blog
Replacing X window system with wayland and sway

Replacing X window system with wayland and sway

SoftwareNixOSWayland
2020-3-20

After a BIOS update my second monitor stopped working, this documents my journey switching to sway+wayland

Darkest before dawn

First let's knock X over and enable sway

configuration.nix

  imports = [
    ./sway.nix
    ...
  ];

  #services.xserver.enable = true;
  programs.sway.enable = true;

At this point my desktop looks like this:

a gray square
But actually (1920x2)x1200

But both monitors are on so that's a plus!

Research

Starting on the exact wiki is a good idea

  • nixos wiki sway

People love blogging about software config, hm

  • Dejà vu - Running Sway and friends with home-manager systemd user services

The best resource for nix is finding publicly hosted examples

  • github search "programs.sway.enable"

Arch is always a good reference for setup and configuration, and maps closely to nixos

  • arch wiki sway

Configuring sway

It was a bit spooky to have no way to start programs, digging out of that was tricky. Remember that ctrl+alt+F2 will switch to TTY2 giving you a chance to log in and tweak with a terminal.

It turns out sway ships with a default config that sets up some basic utility that nixos does not include, because why would it!

The wiki has an example sway.nix file, and the default sway config is on github

Application launcher

I am using an edge version of wofi installed with the following snippet:

sway.nix

{ config, pkgs, lib, ... }:
let
  wofi_edge = pkgs.callPackage (builtins.fetchurl {
    url = "https://raw.githubusercontent.com/NixOS/nixpkgs/master/pkgs/applications/misc/wofi/default.nix";
    sha256 = "0wfigcrxihcdpkwm7ygkqvah0phw0g1g72k6jah51ng1gm0qvsra";
  }) {};
in
{
   programs.sway = {
    enable = true;
    extraPackages = with pkgs; [
      ...
      dmenu
      wofi_edge
    ];
  };
}

sway.config

set $menu dmenu_path | wofi --dmenu | xargs swaymsg exec --
bindsym $mod+Space exec $menu

Next steps are getting wofi to

Application bar

waybar is used with some basic config:

sway.nix

    extraPackages = with pkgs; [
      waybar
    ];

waybar/config

Term

I wanted new terminals to open in the same directory as the currently focused one. I suspected I could use a similar technique to screenshotting, luckily for me someone else has already done this and I just had to tweak to fit

This shell script looks up the currently focused window and grabs its pid, and if it's a terminal uses /proc to determine the working directory

sway/focused-cwd

#!/usr/bin/env sh

terminal=${1:-alacritty}
pid=$(swaymsg -t get_tree | jq '.. | select(.type?) | select(.type=="con") | select(.focused==true).pid')
pname=$(ps -p ${pid} -o comm= | sed 's/-$//')

if [[ $pname == $terminal ]]
then
  ppid=$(pgrep --newest --parent ${pid})
  readlink /proc/${ppid}/cwd || echo $HOME
else
  echo $HOME
fi

sway/config

set $term alacritty --working-directory $(/etc/sway/focused-cwd alacritty)

bindsym $mod+Return exec $term

Notifications

I had an issue with firefox popping up its own tiling notification window. It turns out my mako config had an error and was failing to start, fixing the config allowed mako to run again.

As per usual it was inspecting the strace logs that showed me that the program was failing immediately after reading the config file

strace -c makoctl invoke

Taking screenshots

Requires programs:

  • swaymsg
  • grim
  • jq
  • slurp
grim -g "$(swaymsg -t get_tree | jq -r '.. | select(.pid? and .visible?) | .rect | "\(.x),\(.y) \(.width)x\(.height)"' | slurp)" filename.png

This is actually kinda awesome. swaymsg -t get_tree outputs a big json structure of the layout of all drawable areas on the screen, jq extracts all window regions and formats it in a palatable manner for slurp to select a single one of the regions at which point grim captures it into a png. Terrible. Wonderful.

Featured Projects
GeneratorHandwheel Repair
Company Info
About UsContactAffiliate DisclosurePrivacy Policy
Specific Solutions LLC
Portland, OR