diff --git a/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml b/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml index 83f2d1022514..5c29f98b28df 100644 --- a/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml +++ b/nixos/doc/manual/from_md/release-notes/rl-2211.section.xml @@ -62,6 +62,15 @@ services.infnoise. + + + persistent-evdev, + a daemon to add virtual proxy devices that mirror a physical + input device but persist even if the underlying hardware is + hot-plugged. Available as + services.persistent-evdev. + +
diff --git a/nixos/doc/manual/release-notes/rl-2211.section.md b/nixos/doc/manual/release-notes/rl-2211.section.md index 85adae269c31..624bde2c83d7 100644 --- a/nixos/doc/manual/release-notes/rl-2211.section.md +++ b/nixos/doc/manual/release-notes/rl-2211.section.md @@ -29,6 +29,7 @@ In addition to numerous new and upgraded packages, this release has the followin - [infnoise](https://github.com/leetronics/infnoise), a hardware True Random Number Generator dongle. Available as [services.infnoise](options.html#opt-services.infnoise.enable). +- [persistent-evdev](https://github.com/aiberia/persistent-evdev), a daemon to add virtual proxy devices that mirror a physical input device but persist even if the underlying hardware is hot-plugged. Available as [services.persistent-evdev](#opt-services.persistent-evdev.enable). diff --git a/nixos/modules/module-list.nix b/nixos/modules/module-list.nix index 7b1054262f59..d67602a26761 100644 --- a/nixos/modules/module-list.nix +++ b/nixos/modules/module-list.nix @@ -606,6 +606,7 @@ ./services/misc/packagekit.nix ./services/misc/paperless.nix ./services/misc/parsoid.nix + ./services/misc/persistent-evdev.nix ./services/misc/plex.nix ./services/misc/plikd.nix ./services/misc/podgrab.nix diff --git a/nixos/modules/services/misc/persistent-evdev.nix b/nixos/modules/services/misc/persistent-evdev.nix new file mode 100644 index 000000000000..401d20010b12 --- /dev/null +++ b/nixos/modules/services/misc/persistent-evdev.nix @@ -0,0 +1,60 @@ +{ config, lib, pkgs, ... }: + +let + cfg = config.services.persistent-evdev; + settingsFormat = pkgs.formats.json {}; + + configFile = settingsFormat.generate "persistent-evdev-config" { + cache = "/var/cache/persistent-evdev"; + devices = lib.mapAttrs (virt: phys: "/dev/input/by-id/${phys}") cfg.devices; + }; +in +{ + options.services.persistent-evdev = { + enable = lib.mkEnableOption "virtual input devices that persist even if the backing device is hotplugged"; + + devices = lib.mkOption { + default = {}; + type = with lib.types; attrsOf str; + description = '' + A set of virtual proxy device labels with backing physical device ids. + + Physical devices should already exist in /dev/input/by-id/. + Proxy devices will be automatically given a uinput- prefix. + + See the + project page for example configuration of virtual devices with libvirt + and remember to add uinput-* devices to the qemu + cgroup_device_acl list (see ). + ''; + example = lib.literalExpression '' + { + persist-mouse0 = "usb-Logitech_G403_Prodigy_Gaming_Mouse_078738533531-event-if01"; + persist-mouse1 = "usb-Logitech_G403_Prodigy_Gaming_Mouse_078738533531-event-mouse"; + persist-mouse2 = "usb-Logitech_G403_Prodigy_Gaming_Mouse_078738533531-if01-event-kbd"; + persist-keyboard0 = "usb-Microsoft_NaturalĀ®_Ergonomic_Keyboard_4000-event-kbd"; + persist-keyboard1 = "usb-Microsoft_NaturalĀ®_Ergonomic_Keyboard_4000-if01-event-kbd"; + } + ''; + }; + }; + + config = lib.mkIf cfg.enable { + + systemd.services.persistent-evdev = { + documentation = [ "https://github.com/aiberia/persistent-evdev/blob/master/README.md" ]; + description = "Persistent evdev proxy"; + wantedBy = [ "multi-user.target" ]; + + serviceConfig = { + Restart = "on-failure"; + ExecStart = "${pkgs.persistent-evdev}/bin/persistent-evdev.py ${configFile}"; + CacheDirectory = "persistent-evdev"; + }; + }; + + services.udev.packages = [ pkgs.persistent-evdev ]; + }; + + meta.maintainers = with lib.maintainers; [ lodi ]; +} diff --git a/pkgs/servers/persistent-evdev/default.nix b/pkgs/servers/persistent-evdev/default.nix new file mode 100644 index 000000000000..c666e9c8d799 --- /dev/null +++ b/pkgs/servers/persistent-evdev/default.nix @@ -0,0 +1,42 @@ +{ lib, buildPythonPackage, fetchFromGitHub, python3Packages }: + +buildPythonPackage rec { + pname = "persistent-evdev"; + version = "unstable-2022-05-07"; + + src = fetchFromGitHub { + owner = "aiberia"; + repo = pname; + rev = "52bf246464e09ef4e6f2e1877feccc7b9feba164"; + sha256 = "d0i6DL/qgDELet4ew2lyVqzd9TApivRxL3zA3dcsQXY="; + }; + + propagatedBuildInputs = with python3Packages; [ + evdev pyudev + ]; + + postPatch = '' + patchShebangs bin/persistent-evdev.py + ''; + + dontBuild = true; + + installPhase = '' + mkdir -p $out/bin + cp bin/persistent-evdev.py $out/bin + + mkdir -p $out/etc/udev/rules.d + cp udev/60-persistent-input-uinput.rules $out/etc/udev/rules.d + ''; + + # has no tests + doCheck = false; + + meta = with lib; { + homepage = "https://github.com/aiberia/persistent-evdev"; + description = "Persistent virtual input devices for qemu/libvirt/evdev hotplug support"; + license = licenses.mit; + maintainers = [ maintainers.lodi ]; + platforms = platforms.linux; + }; +} diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index bd878b1669ca..4c9ef168932f 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -4757,6 +4757,8 @@ with pkgs; evdevremapkeys = callPackage ../tools/inputmethods/evdevremapkeys { }; + persistent-evdev = python3Packages.callPackage ../servers/persistent-evdev { }; + evscript = callPackage ../tools/inputmethods/evscript { }; gebaar-libinput = callPackage ../tools/inputmethods/gebaar-libinput { stdenv = gcc10StdenvCompat; };