Nixpkgs: sway: Optimal NixOS integration

Created on 13 Mar 2019  路  54Comments  路  Source: NixOS/nixpkgs

This is intended as an issue to collect and track possible improvements and feedback in general. Feedback form users is welcome (what is difficult, does not work, could be improved, are packages missing, etc.).

Possible improvements (WIP):

  • [x] Read all configurations from /etc and fallback to /nix/store for non NixOS systems (#60319)
  • Should we install the default wallpaper? (see https://github.com/NixOS/nixpkgs/pull/57414#discussion_r265056873)

    • We could e.g. install them into another output and introduce an option to enable/disable them.

    • /run/current-system/backgrounds/sway or /run/current-system/wallpapers/sway would probably work well, but unfortunately only on NixOS

  • systemd integration (user units) - WIP: https://github.com/NixOS/nixpkgs/pull/54627#issuecomment-462736971
  • [x] Login manager integration (e.g. SDDM) - https://github.com/swaywm/sway/issues/100
  • Copying /etc/sway/config is not optimal because the file in the Nix store is read-only (-> the configuration in ~/.config/sway/config will be read-only). We could consider copying the example configuration file to /etc (instead of symlinking it) and change the permissions.
  • Track sway-security
  • Compare the setup script (D-Bus, etc.) to the ones for X11

    • Unify these for X11 and Wayland?

  • [ ] Enable a few extraSessionCommands by default?

Useful software (for Wayland in general) in nixpkgs:

  • [x] swayidle: idle management daemon
  • [x] swaylock: lock screen
  • [x] mako: notification daemon
  • [x] grim: screenshot tool
  • [x] slurp: interactive region selection
  • [x] wf-recorder: video capture tool (https://github.com/NixOS/nixpkgs/pull/57662)
  • [x] waybar: alternative panel (https://github.com/NixOS/nixpkgs/pull/54627)
  • [ ] virtboard: on-screen keyboard (https://github.com/NixOS/nixpkgs/pull/57614)
  • [x] wl-clipboard: xclip replacement
  • [x] wallutils: fancy wallpaper manager (https://github.com/NixOS/nixpkgs/pull/59878)
  • [x] light / brightnessctl: backlight management
  • [x] bemenu: Dynamic menu library and client program inspired by dmenu (Wayland, ncurses, and X11)
  • [x] wdisplays: Basically an ARandR equivalent for Wayland (see https://github.com/NixOS/nixpkgs/issues/81825)
  • [ ] sgtk-menu: GTK launcher for sway & other WMs w/ menu, dmenu, application grid and button bar (see https://github.com/NixOS/nixpkgs/issues/78370)
  • [ ] wshowkeys (WIP: #83687)
  • [x] sway-contrib (grimshot, etc.): #88577
enhancement

Most helpful comment

If I recreate that configuration I could share the errors I got here.

Alright, I tried again to adapt some instructions from the Arch Wiki to use wf-recorder to create a virtual webcam, and (good news!) this time I succeeded. Still feels a little hacky, but this is what I did.

In my NixOS config:

  # Obviously omitting all my non-screen-sharing-related packages:
  programs.sway.extraPackages = with pkgs; [
    v4l-utils
    wf-recorder
  ];
  boot.extraModulePackages = with config.boot.kernelPackages; [
    v4l2loopback
  ];

Then when I'm ready to start screen-sharing I do

# modprobe v4l2loopback exclusive_caps=1 card_label=WfRecorder
$ v4l2-ctl --list-devices

On my system this results in /dev/video4 being allocated with the WfRecorder label, so then I do

$ wf-recorder --muxer=v4l2 --codec=rawvideo --file=/dev/video4 -x yuv420p

I had two displays active when I first tried this, so wf-recorder asked me to specify which one I wanted to capture. I left this command running while I opened Firefox, opened a webcam-sharing test, and easily shared the "webcam" that was capturing my screen.

Now that I have this working I guess it's my solution for the time being. Would have preferred to just select applications or displays from within Firefox on the fly instead of setting up a virtual webcam first, but this is a pretty cool workaround.

All 54 comments

light / brightnessctl: backlight management

Could actkbd or acpid used instead? For brightness control locally I use

  brightness = pkgs.writeShellScriptBin "brightness.sh" ''
    bl_dev=`echo /sys/class/backlight/*`
    echo $(($(< $bl_dev/brightness) $1 $2)) >$bl_dev/brightness
  '';
  services.actkbd = {
    bindings = [
      { keys = [ 224 ]; events = [ "key" "rep" ]; command = "${brightness}/bin/brightness.sh - 10"; }
      { keys = [ 225 ]; events = [ "key" "rep" ]; command = "${brightness}/bin/brightness.sh + 10"; }
    ];
  };

Will this work for all videocards? If so, I would like to add brightness control defaults to actkbd, like we already have for sound control sound.mediaKeys.enable = true;

Useful software (for Wayland in general) in nixpkgs:
wallutils

Don't see it in nixpkgs.

systemd integration (user units) - WIP: #54627 (comment)

What benefits it brings? sway is capable to run applications on start by itself.

What benefits it brings?

Starting sway itself, presumably.

Could actkbd or acpid used instead?

I do not have any preference here, it was simply meant as a list of software that could be useful (I took if from Drew's blog post). I also didn't plan to integrate this into the sway module if that was your concern (not sure if I'm interpreting your comment correctly).

If so, I would like to add brightness control defaults to actkbd, like we already have for sound control sound.mediaKeys.enable = true;

Might be a good idea if we already have this for sound. But since this is a generic solution that should work with both Wayland and X11 we should not put it in the sway module (but that was probably not your intention anyway).

Don't see it in nixpkgs.

Only the checked entries (checkbox) are already in nixpkgs.

What benefits it brings? sway is capable to run applications on start by itself.

That's a valid concern.
I'm not using user units - it's mainly useful for people who already use them. I assume the main advantages are to automatically launch sway on a TTY (like with .bashrc), "dependency management" (other systemd user units) and we could better integrate it into nixpkgs than via the sway configuration (though I'm not sure how useful it would actually be - but it could be implemented in a generic and standardized way I guess).

(Edit: Also, please note that this is only a collection of possible improvements (that often require further discussion).)

Home-manager provided a nice way to set i3 declaratively [0].
Could be nice to have that in-tree and shared with i3 or add sway support to home-manager's dingy.

[0] https://github.com/rycee/home-manager/blob/master/modules/services/window-managers/i3.nix

@t184256

Starting sway itself, presumably.

Looks like we have a blocker for user services: https://github.com/NixOS/nixpkgs/issues/21460

@primeos

But since this is a generic solution that should work with both Wayland and X11 we should not put it in the sway module (but that was probably not your intention anyway).

Right, I'm just interesting whether it will work with different video cards. I only have Intel there.

Only the checked entries (checkbox) are already in nixpkgs.

Sorry. With sway 1.0-rc5, firefox and breeze dark theme they are not visible by some reason.

wf-recorder has been merged! #57662 :tada:

Right, I'm just interesting whether it will work with different video cards. I only have Intel there.

I also only have Intel but according to the Arch Wiki:

All methods are exposed to the user through /sys/class/backlight

it sounds like a good method that should work in most cases.

But we would have to modify the script to consider max_brightness.

According to the Arch Wiki:

The maximum brightness can be found by reading from max_brightness, which is often 15.

and on my system max_brightness has the value 7500. So the step size of 10 is either too high or too low in these cases. Using something like 10% would be better.

With sway 1.0-rc5, firefox and breeze dark theme they are not visible by some reason.

As long as it works with 1.0 :)

Home-manager provided a nice way to set i3 declaratively [0].
Could be nice to have that in-tree and shared with i3 or add sway support to home-manager's dingy.

@amazari interesting. I don't think that we can/should move it in-tree (too many configuration options IMO) but I'm assuming that adding a module for sway to home-manager would be fine - any volunteers? :)

Waybar has been merged. #54627

@primeos Would be nice to add environment setup like that https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/x11/display-managers/default.nix does
For e.g. currently without doing
exec dbus-update-activation-environment DISPLAY
in sway config I get an error when trying to send notification
gi.repository.GLib.Error: g-dbus-error-quark: 袨褕懈斜泻邪 胁褘蟹芯胁邪 StartServiceByName 写谢褟 org.freedesktop.Notifications: GDBus.Error:org.freedesktop.DBus.Error.Spawn.ChildExited: Process org.freedesktop.Notifications exited with status 1 (25)

What about bemenu?

@NilsIrl good idea, I added it to the list - it's already packaged in nixpkgs (pkgs/applications/misc/bemenu/default.nix)

@gnidorah seems like I forgot to reply :o

Regarding the environment setup: Yes, that would be nice. I think there is already an issue to unify this for X11 and Wayland (I'll try to look it up and reference it).

Regarding the notification: Can this be reproduced (e.g. with notify-send and mako)? I don't use notifications but I could have a look at it if it doesn't work.

@primeos
No, mako works. Looks like this is only needed for X11 programs. Thanks, I will switch to mako from now.
Though with mako I see an issue that it can't be launched automatically

gi.repository.GLib.Error: g-dbus-error-quark: GDBus.Error:org.freedesktop.DBus.Error.ServiceUnknown: The name org.freedesktop.Notifications was not provided by any .service files (2)

If I start mako manually, everything works fine

@gnidorah great :) Just realized that I missed the exec dbus-update-activation-environment DISPLAY part...


gi.repository.GLib.Error: g-dbus-error-quark: GDBus.Error:org.freedesktop.DBus.Error.ServiceUnknown: The name org.freedesktop.Notifications was not provided by any .service files (2)

Seems like mako didn't provide a .service file but it should work after the next release:
https://github.com/emersion/mako/commit/ca8e763f06756136c534b1bbd2e5b536be6b1995 (cc @dywedir maybe you could you test if it works after the next release)

@NilsIrl

How to make it work under sway? This doesn't show anything for me

nix-build -A bemenu
./result/bin/bemenu

@NilsIrl

How to make it work under sway? This doesn't show anything for me

nix-build -A bemenu
./result/bin/bemenu

I had the same problem. Bemenu is only in the master branch.

git clone [email protected]:NixOS/nixpkgs.git
nix-build -A bemenu -I nixpkgs=nixpkgs/
# OR
nix-build -A bemenu -I nixpkgs/

The part after the = is the path to your local copy of the nixpkgs repository
I am not sure if you need nixpkgs=

@NilsIrl I've tried it from master branch, but when I run bemenu under sway it doesn't draw anything on the screen.

@NilsIrl I've tried it from master branch, but when I run bemenu under sway it doesn't draw anything on the screen.

Have you tried to run bemenu from a terminal?

Have you tried to run bemenu from a terminal?

That is. And nothing on the screen. Sway version is 1.1.1

Have you tried to run bemenu from a terminal?

That is. And nothing on the screen. Sway version is 1.1.1

If you can open a terminal, you could see what bemenu outputs when it is run. If you don't have access to a terminal, you can try to redirect the output from bemenu into a file and then view the file.

I personally had a problem where I couldn't even run a terminal. What I did is that I redirected stdout and stderr from the command launching the terminal in sway into a file.

I then viewed the file from the tty. And guess what... The file had an error message saying my version of opengl was too outdated for the terminal emulator, alacritty to work.

@NilsIrl Looks like my mistake was in that I've tried to run bemenu instead of bemenu-run. bemenu-run works just fine. My sorry :disappointed:
BTW I hope they introduce something akin to i3-dmenu-desktop some day

@gnidorah
https://github.com/i3/i3/blob/6339427f017e1265a022e6537e16a8b4a921e52f/i3-dmenu-desktop
You can modify this script for it to use bemenu instead of dmenu.

Actually you don't even need to do that.
Just run $ i3-dmenu-desktop --demenu=bemenu and it should work

If you don't want to install i3 just to have i3-dmenu-desktop you can download it from https://github.com/i3/i3/blob/6339427f017e1265a022e6537e16a8b4a921e52f/i3-dmenu-desktop

i'd like to suggest redshift to adjust the color temperature:
https://aur.archlinux.org/packages/redshift-wlr-gamma-control-git/

optimally there could be a switch in services.redshift

Regarding systemd user service integration: I started to document my setup in https://nixos.wiki/wiki/Sway. Atm I have no time to integrate these changes into NixOS, but maybe somebody else has?

Hello @erictapen, I've been trying to integrate Sway with systemd the way you proposed, but I had multiple issues doing so :

  • I could not find a way to autostart correctly the session (I use full disk encryption and I do not want to enter passwords twice)
  • I could not find a way bind it with a displaymanager properly at all

Have you been able to achieve this ?

The approach i' m currently following is to start Sway as the display-manager itself. I have the feeling the way you're doing it might be cleaner. Here is my setup :

  systemd.defaultUnit = "graphical.target";
  systemd.services.sway = {
    enable = true;
    wants = [ "systemd-machined.service" ];
    aliases = [ "display-manager.service" ];
    after =  [
      "rc-local.service"
      "systemd-machined.service"
      "systemd-user-sessions.service"
      "plymouth-quit.service"
      "plymouth-start.service"
    ];
    serviceConfig = {
      ExecStartPre = "${config.system.path}/bin/chvt ${sway.tty}";
      ExecStart = "${pkgs.dbus}/bin/dbus-launch --exit-with-session ${pkgs.sway}/bin/sway";
      TTYPath = "/dev/tty${sway.tty}";
      TTYReset = "yes";
      TTYVHangup = "yes";
      TTYVTDisallocate = "yes";
      PAMName = "login";
      User = sway.username;
      WorkingDirectory = "/home/${sway.username}";
      StandardInput = "tty";
      StandardError = "journal";
      StandardOutput = "journal";
      Restart = "no";
    };
  };

It still has one issue though.

Regarding systemd user service integration: I started to document my setup in https://nixos.wiki/wiki/Sway. Atm I have no time to integrate these changes into NixOS, but maybe somebody else has?

I tried your config, but had to make some changes (due to redshift):
Remove

    package = pkgs.redshift-wlr;

Add (top level)

location = {
 latitude = 40.7;
 longitude = -74.0;
}

Also, not relevant to redshift, but

    environment.PATH = lib.mkForce null;

had to be changed to

    environment.PATH = pkgs.lib.mkForce null;

because lib does not exist (not sure if I did this one right).

I am sorry if this is not a right place to drop my idea, or this is something to create a separate issue for, but I would personally love if the Sway package in the option programs.sway was exposed so that it could be overridden with a package from the nixos-unstable.

Since the Wayland ecosystem and Sway are still in work in progress adoption-wise; many Wayland tools, and the newest releases of Wlroots and Sway themselves rarely make it into releases of Linux distributions, which follow the fixed 6 months release schedule model, in time. While using NixOS Unstable may be an option, having the latest Wayland stack is all I need.

My lack of understanding of the basic knowledge about Nix and/or NixOS'es Sway wrapper may make obvious limitations of implementing this feature inapparent to me, but I would like to hear from you what you think about it, and why it could/should (not) be implemented, nonetheless.

https://functor.tokyo/blog/2018-02-18-install-packages-from-nixos-unstable

@Bryophyllum that's a valid idea and feel free to add such comments to this issue ;)

That said, I'm not sure if having such a package option is worth it. I don't have any strong feelings on this, but AFAIK the consensus is to avoid such an option in cases like this (see https://github.com/NixOS/nixpkgs/issues/50476). Also: Mixing Sway from nixos-unstable with a system based on nixos-stable can result im problems like https://github.com/NixOS/nixpkgs/pull/76787#issuecomment-578461880.

Therefore I would avoid adding such an option. However, you should still be able to realise your use-case by using overlays. It should be sufficient to override the sway package with the one from nixos-unstable. Here is an example: https://gist.github.com/LnL7/58d687c58948e71acd7fd4d410f3cdd1 (instead of unstable = ... the following should be sufficient: sway = unstable.sway).

For users interested in Grimshot or other scripts in contrib/: In #87979 we're currently discussing how to best package these in Nixpkgs.

I'm still missing some documentation / configuration examples on how to actually /enable/ sway.

While testing pipewire support in a VM, I hacked together the following:

      programs.sway.enable = true;

      services.xserver.enable = true; #??
      services.xserver.displayManager.sddm = {
        enable = true;
        autoLogin = {
          enable = true;
          user = "alice";
        };
      };
      services.xserver.displayManager.defaultSession = "sway";

      xdg.portal = {
        enable = true;
        extraPortals = with pkgs; [ xdg-desktop-portal-wlr ];
        gtkUsePortal = true;
      };

      services.pipewire.enable = true;

However, this is using Xwayland, and this is probably not right, i don't know.

We should also have some tests that ensure stuff doesn't break - I tried automating something with ydotool, but couldn't get it to work.

I'm still missing some documentation / configuration examples on how to actually /enable/ sway.

Where would you suggest to document this? E.g. there's a page on the NixOS wiki but that is currently only focused on systemd. Alternatively we could document it in the NixOS manual, but unfortunately there are many Wayland compositors and we don't have a general abstraction for them in Nixpkgs (i.e. documenting Sway there might be too specific).

But basically programs.sway.enable = true; is already enough and the most relevant things should already be documented via the NixOS module.

However, this is using Xwayland, and this is probably not right, i don't know.

I guess this is regarding Chromium? Unfortunately Ozone still isn't considered stable / enabled by default so you have to recompile Chromium for native Wayland support: chromium.override { useOzone = true; }. You can also disable XWayland by removing it from programs.sway.extraPackages or via the Sway config (IIRC).

We should also have some tests that ensure stuff doesn't break - I tried automating something with ydotool, but couldn't get it to work.

A NixOS VM test for Sway sounds like a good idea :)

Where would you suggest to document this? E.g. there's a page on the NixOS wiki but that is currently only focused on systemd. Alternatively we could document it in the NixOS manual, but unfortunately there are many Wayland compositors and we don't have a general abstraction for them in Nixpkgs (i.e. documenting Sway there might be too specific).

Yeah, I'd prefer having more complicated things documented in the NixOS manual via meta.doc - those hopefully are more likely to be up-to-date with the code than a page in the wiki.
A Sway-specific documentation is probably better than no documentation at all :-)

Also note the Wiki Page is more a configuration dump that shows a way to get it working with systemd (and probably outdated, see https://github.com/NixOS/nixpkgs/pull/85334#issuecomment-615495925 as discussed with @Ma27)

These parts should really just end up in the sway module, and once we want to abstract that to support more wayland compositors, can be done as a follow-up.

I guess this is regarding Chromium? Unfortunately Ozone still isn't considered stable / enabled by default so you have to recompile Chromium for native Wayland support [鈥

Once compiled with Ozone support, is this a flag/environment variable? Could we enable this during compilation, while still having users opting in (similar to https://github.com/NixOS/nixpkgs/pull/89565)?

A NixOS VM test for Sway sounds like a good idea :)

As I posted in my previous comment, I didn't get the ydotool parts to work, so we can't really do anything in it. I'd assume for the test, we'd at least want to open a terminal and do some OCR (like in nixosTests.cage)

A Sway-specific documentation is probably better than no documentation at all :-)

Ok, I'll try to look into that then (but it might take me some time). Help is obviously welcome, if someone else who follows this issue is interested in that.

Once compiled with Ozone support, is this a flag/environment variable?

You need to run chromium --ozone-platform=wayland to select the Wayland backend (by default X11 is used).

Could we enable this during compilation, while still having users opting in (similar to #89565)?

Unfortunately not :o See https://github.com/NixOS/nixpkgs/issues/82443 and https://github.com/NixOS/nixpkgs/pull/85197 for related discussions. I'm hoping that Ozone will become stable in 2020 and current news look promising (e.g. Chrome Is Reaching The Point Of Good X11 + Wayland Support In Same Build - the X11 stability was lacking behind Wayland, which is the main focus).

As I posted in my previous comment, I didn't get the ydotool parts to work, so we can't really do anything in it. I'd assume for the test, we'd at least want to open a terminal and do some OCR (like in nixosTests.cage)

Why don't we just send the key combinations via send_keys to launch a terminal, etc.?

services.xserver.enable = true; #??

I was curious about that myself as I'd rather not have everything else that brings in.

To have just a display manager that launches sway and other wayland window managers all that is needed from xserver.nix is settingsystemd.defaultUnit and creating the display manager service. I pulled those out manually on my local machine to verify.

I'm wondering if extracting that config into display manager specific config might be a good idea. Maybe something where if services.xserver.enabled is true, then the display manager is automatically enabled, but it could be enabled without enabling the xserver.

I'd appreciate any feedback and opinions on that idea, and then I could potentially put together a PR.

Has anyone gotten a different login manager than sddm working with sway? I am currently trying lightdm with the mini greeter, but I only get a black sceen with a cursor.

Maybe something like https://git.sr.ht/~kennylevinsen/gtkgreet would be perfect since it seems to be made specifically for sway?

Has anyone gotten a different login manager than sddm working with sway? I am currently trying lightdm with the mini greeter, but I only get a black sceen with a cursor.

I've been using gdm with sway, as it's the only one that I'm aware of that will render with wayland and not have to start an Xserver. I did it with the proposed method above where just the display manager is enabled without enabling all of Xorg.

In my configuration.nix:

  services.xserver.displayManager.gdm = {
    enable = true;
    wayland = true;
  };

  # Extracted from nixos/modules/services/x11/xserver.nix
  systemd.defaultUnit = "graphical.target";
  systemd.services.display-manager =
    let
      cfg = config.services.xserver.displayManager;
    in
    {
      description = "Display Manager";

      after = [ "acpid.service" "systemd-logind.service" ];

      restartIfChanged = false;

      environment =
        lib.optionalAttrs
          config.hardware.opengl.setLdLibraryPath {
          LD_LIBRARY_PATH = pkgs.addOpenGLRunpath.driverLink;
        } // cfg.job.environment;

      preStart =
        ''
          ${cfg.job.preStart}

          rm -f /tmp/.X0-lock
        '';

      script = "${cfg.job.execCmd}";

      serviceConfig = {
        Restart = "always";
        RestartSec = "200ms";
        SyslogIdentifier = "display-manager";
        # Stop restarting if the display manager stops (crashes) 2 times
        # in one minute. Starting X typically takes 3-4s.
        StartLimitInterval = "30s";
        StartLimitBurst = "3";
      };
    };

I previously checked out gtkgreet, it's one of the greeters that are part of greetd. That project seems really promising but still in early phases. Maybe some progress has been made since I last looked. Also since it involves login, hopefully there will be some security minded folks looking over it.

Has anyone gotten a different login manager than sddm working with sway? I am currently trying lightdm with the mini greeter, but I only get a black sceen with a cursor.

I have been using lightdm with Sway successfully on nixpkgs-unstable and 20.03 channel with no problems whatsoever.
I use the enso greeter if it's relevant.
My keyring (gnome-keyring) gets automatically unlocked too.

Excerpt from my config:

{
  services.xserver.enable = true;
  services.xserver.displayManager.defaultSession = "sway";
  services.xserver.displayManager.lightdm = {
    enable = true;
    greeters.enso.enable = true;
  };
  services.xserver.libinput.enable = true;
  services.xserver.layout = "us";

  services.gnome3.gnome-keyring.enable = true;
}

I am using sway on NixOS unstable right now (last upgraded from the nixos-unstable channel today, 20 August 2020) and overall it's pretty smooth -- the one reason I feel I still need to keep XFCE installed alongside sway is that I still don't have screen-sharing working under sway. Here's some excerpts from my system configuration:

  programs.sway.extraSessionCommands = ''
    export GTK_THEME=Blackbird
    export GTK_ICON_THEME=Tango
    export MOZ_ENABLE_WAYLAND=1
    export MOZ_USE_XINPUT2=1
    export XDG_SESSION_TYPE=wayland
    export XDG_CURRENT_DESKTOP=sway
  '';
  services.pipewire.enable = true;
  xdg.portal = {
    enable = true;
    gtkUsePortal = true;
    extraPortals = with pkgs; [
      xdg-desktop-portal-gtk
      xdg-desktop-portal-wlr
    ];
  };

In Firefox, I have widget.use-xdg-desktop-portal set to true. In google-chrome-stable, I have #enable-webrtc-pipewire-capturer set to enabled.

I've been using Mozilla's WebRTC gUM test to test screensharing. In Firefox, I can share either the entire screen -- which only comes through as a an empty black frame -- or individual applications that are running in XWayland, but not native Wayland applications. In Google Chrome I can only share Chrome tabs.

The above configuration excerpts are based on various snippets I've found across different GitHub issues &c, but they don't seem to do the trick with the most recent versions of everything. I'm trying to figure out what options I might be missing.

I've never tried screen sharing myself but for Firefox #84233 might fix your issues and for Chromium #89565 and linked issues/PRs might contain valuable information (configuration examples, etc.).

Meanwhile, wf-recoder might or might not save you from relogging into XFCE.

Meanwhile, wf-recoder might or might not save you from relogging into XFCE.

I did try an alternate configuration involving the v4l2loopback kernel module and wf-recorder but when I tried to initialize a "webcam" feed from wf-recorder I ran into some errors. If I recreate that configuration I could share the errors I got here. It feels like kind of a hack to begin with though; if I could get one of these solutions to work I'd prefer it to be pipewire.

If I recreate that configuration I could share the errors I got here.

Alright, I tried again to adapt some instructions from the Arch Wiki to use wf-recorder to create a virtual webcam, and (good news!) this time I succeeded. Still feels a little hacky, but this is what I did.

In my NixOS config:

  # Obviously omitting all my non-screen-sharing-related packages:
  programs.sway.extraPackages = with pkgs; [
    v4l-utils
    wf-recorder
  ];
  boot.extraModulePackages = with config.boot.kernelPackages; [
    v4l2loopback
  ];

Then when I'm ready to start screen-sharing I do

# modprobe v4l2loopback exclusive_caps=1 card_label=WfRecorder
$ v4l2-ctl --list-devices

On my system this results in /dev/video4 being allocated with the WfRecorder label, so then I do

$ wf-recorder --muxer=v4l2 --codec=rawvideo --file=/dev/video4 -x yuv420p

I had two displays active when I first tried this, so wf-recorder asked me to specify which one I wanted to capture. I left this command running while I opened Firefox, opened a webcam-sharing test, and easily shared the "webcam" that was capturing my screen.

Now that I have this working I guess it's my solution for the time being. Would have preferred to just select applications or displays from within Firefox on the fly instead of setting up a virtual webcam first, but this is a pretty cool workaround.

As someone who is relatively new to NixOS and configuring this kind of thing I still found it fairly difficult to pull together all of the required pieces from different places to get a working setup with sway as the window manager and gdm as the display manager (to avoid having to enable xserver - not sure how much sway users care about this).

I'm still having trouble with kanshi, other than that I have a working config, which I wanted to share in case others find it useful:
https://gist.github.com/mschwaig/195fe93ed85dea7aaceaf8e1fc6c0e99

I also added a warning in the wiki because I forgot to start the sway-session.target and this gave me trouble for a long time. If kanshi was working and I knew that GDM was a good choice for most people (SDDM is mentioned originally in this issue) I'd be happy to extend the wiki with a few lines on display manager integration..

There is a blogpost by Ongy who pulled out more stuff than just kanshi into individual units. I don't know if that would be a good idea.

@mschwaig yeah, the current module is focused on running Sway from a virtual terminal so using login/display managers (especially without X11) and/or systemd user units is unfortunately a bit tricky. For the login/display managers we'd likely need better NixOS abstractions that aren't so much X11 focused (not sure how well this is currently possible though). I'm also not sure what to do about the systemd user unit integration. Upstream doesn't officially support it (e.g. noted in the wiki and there should be a few issues/PRs IIRC) but AFAIK there are many(?) NixOS users that want/use it. I think if there are NixOS users interested in maintaining that it might make sense to add an option to the module (e.g. programs.sway.systemdIntegration) that is disabled by default but can be quickly enabled (and should then work with the Sway/Wayland related Nixpkgs packages - not sure if they can install systemd user units without a module though) (edit: this is probably too difficult to get right atm and some units (e.g. swayidle) probably even need to be configurable). But given that it's not officially supported and we likely add systemd user units that integrate with the sway unit it's likely better suited for home-manager(?).

If kanshi was working and I knew that GDM was a good choice for most people (SDDM is mentioned originally in this issue) I'd be happy to extend the wiki with a few lines on display manager integration.

That seems like a good idea. The Wiki is community maintained and the current version of the Sway page is AFAIK only a draft to document the systemd integration. So it would be good to extend it. And if there's e.g. an example for GDM that might be easily portable to other login/display managers as well.

@primeos, thank you for the reply it was really helpful to me to understand what I can expect to work.

About getting a nice default sway setup to work:
@primeos's post makes me think it might be better to not use a display manager at all or get a really minimal one working instead of GDM. I have the suspicion that configuring GDM to not do any power-managment would help, but it looks like right now that would also still be quite complicated to configure, I am not sure (does #54150 apply when I try to disable GDM's power manamgent?). I will also try to run kanshi directly from sway and see if that fixes it.

About using systemd units:
I have not used home-manager at all yet (I'm going one step at a time), but it seems like home-manager would be a way better fit to optinally integrate specific services as systemd user units instead of starting them from the sway config. Probably having options that move individual parts ot the desktop into user units directly in NixOS is prone to leave you with one foot inside of your configuration.nix file and the other one inside your ~/.config/sway/config file, because things you change in configuration.nix will mean you always also have make the corresponding changes in your sway config file correctly. So maybe home-manager would be a better place to do that kind of thing and maybe to do heavier customization in general.

Probably having options that move individual parts ot the desktop into user units directly in NixOS is prone to leave you with one foot inside of your configuration.nix file and the other one inside your ~/.config/sway/config file

To avoid this situation I declare the content of global /etc/sway/config via environment.etc."sway/config" and intentionally have no file in ~/.config/sway/. Works only for single user setups of course.

Regarding the discussion wether to put sway logic into home-manager I'd like to add that this would leave us without the possibility to test sway integration via NixOS tests, like pretty much all X display-manager do and also cage.

Half a year ago I started bringing my Sway systemd user modules upstream, but never finished it. Here is my progress: https://github.com/erictapen/nixpkgs/tree/sway-systemd-integration (heavily WiP). My goal was to make the proposed systemd user integration described in the Wiki article I wrote easier for the end user. I'm still using this setup, but felt that it'd be better to wait with the PR until the discussion about where to put sway and how to integrate it into NixOS is solved.

Regarding the discussion wether to put sway logic into home-manager I'd like to add that this would leave us without the possibility to test sway integration via NixOS tests, like pretty much all X display-manager do and also cage.

Not sure about that one, what wouldn't we be able to do? Sway should be fully functional without systemd user units.

I'm still using this setup, but felt that it'd be better to wait with the PR until the discussion about where to put sway and how to integrate it into NixOS is solved.

I think it would be best to open a dedicated Nixpkgs issue regarding this (with e.g. the "0.kind: question" and "9.needs: community feedback" labels for better visibility and since this will require some discussion). I'm not too optimistic that it will be easy to nicely integrate this into Nixpkgs tbh but I guess it should be possible. I think the main problems are:

  • Wayland is very modular and flexible by design which resulted in a very diverse ecosystem (software wise)
  • We don't have any abstractions for Wayland compositors in Nixpkgs (like services.xserver for X11) and the previous problem makes this more difficult
  • AFAIK there's no real consensus if and how we want to handle systemd user units in Nixpkgs

I have updated my config (also linked above) to use SDDM instead of GDM. Kanshi still doesn't pick up when outputs are changed on the fly, but this is now a workable setup for me, because I can recover from being left with a black screen easily and every time.

I also wanted to highlight that when I was using GDM I used the snippet that @wkral posted and that itself was working well for avoiding xserver.enable = true and looks promising to me.

Was this page helpful?
0 / 5 - 0 ratings