Nixpkgs: services.xserver.libinput: Allow configuration by input type

Created on 5 Dec 2019  路  11Comments  路  Source: NixOS/nixpkgs

Describe the bug
PR https://github.com/NixOS/nixpkgs/pull/73785 broke my setup, since it enabled natural scrolling on my mouse when I only wanted it on touchpad. This was my config before:

xserver = {
  # Enable libinput.
  libinput = {
    enable = true;
    naturalScrolling = true;
  };
};

Since now natural scrolling is applied to all devices, I needed to change my config. To fix it, I had to add the following section in my /etc/nixos/configuration.nix file:

xserver = {
  # Enable libinput.
  libinput = {
    enable = true;
  };

  # Set extra config to libinput devices
  extraConfig = ''
    Section "InputClass"
      Identifier "touchpad"
      Driver "libinput"
      MatchIsTouchpad "on"
      Option "NaturalScrolling" "true"
    EndSection
  '';
};

The solution above is not exactly good, it is verbose, I lose the type checking from Nix, and also I am configuring libinput related things on services.xserver instead of services.xserver.input.

However, the change in the PR actually makes sense, since it makes more sense to apply the configuration to any libinput device instead of only in touchpads. There should be a better solution, though.

My proposal would be to have something like this:

libinput = {
  enable = true;
  # Globally disable natural scrolling
  naturalScrolling = false;
  matchIsTouchpad = {
    # However, enable it in touchpads
    naturalScrolling = true;
  };
  matchIsMouse = {
    # Only for mouse, set accel profile to flat
    accelProfile = "flat";
  };
};

This way, we have much more flexibility, since we can either set a specific configuration to some specific type of device or globally. It also should be backwards compatible with the current configuration files.

To Reproduce
Steps to reproduce the behavior:

  1. Using xserver.libinput, I can't set some configuration that is only applied in touchpads and not mouses, for example

Expected behavior
It would be interesting to have some way to apply libinput configuration to specific device types.

Metadata

 - system: `"x86_64-linux"`
 - host os: `Linux 5.4.1, NixOS, 19.09.1484.84586a4514d (Loris)`
 - multi-user?: `yes`
 - sandbox: `yes`
 - version: `nix-env (Nix) 2.3`
 - channels(root): `"nixos-19.09.1484.84586a4514d"`
 - nixpkgs: `/nix/var/nix/profiles/per-user/root/channels/nixos`

Maintainer information:

# a list of nixos modules affected by the problem
module:
- services.xserver.libinput
bug nixos

Most helpful comment

To make the workaround explicit for anyone else running into this, I added the additionalOptions line to this part of my config:

services.xserver.libinput = {
  enable = true;
  naturalScrolling = true; 
  additionalOptions = ''MatchIsTouchpad "on"'';
};

This was an annoying bug to chase down in my 20.03 upgrade - everything worked perfectly except my mouse scroll wheel was now backwards. As far as I can tell this will affect every user who a) has natural scrolling enabled for their touchpad and b) uses an external mouse with a scroll wheel.

Perhaps cfg.naturalScrolling could be defaulted to null instead of false? That would allow an optionalString check similar to what's done with cfg.scrollButton just one line below. If it's null, then NaturalScrolling wouldn't have a value in the catch-all InputClass, and I could then configure it however I wanted to with custom inputClassSections.

All 11 comments

Thanks for the report, I was thinking what is going on with the natural scrolling lately. I want to enable natural scrolling on touchpad but not on mouse.

Whatever option I use (either inputClassSections or extraConfig), it is not applied to the end of the config file, so last Section "InputClass" (the one comes from libinput option) seems always overriding it.

@seqizz Yeah, workaround the recent changes by loading libinput modules manually: https://github.com/thiagokokada/dotfiles/commit/17057a544dcb8a51e3b9b1ea92c476edd6e2cc46

Seems fixed after revert :+1:

I would rather see a list or set of libinput configurations, that you can match with any of the xorg matching criteria. I have a device with an unusual builtin "mouse". It isn't classified as a touchpad, but it benefits from special configuration that I don't want applied to an external mouse.

Soo... this is broken again after 20.03 release. Or I am doing something wrong.

Could you tell me how can I enable natural scrolling for touchpad but disable for an external mouse? I am OK for either whitelisting or blacklisting.

I am obviously repeating myself but:

Whatever I do, (because of services.xserver.libinput.*'s options are placed at the bottom of the xorg config file) if I set services.xserver.libinput.naturalScrolling, it overrides all other options set via others. I've tested with:

  • services.xserver.extraConfig: Not working / overriden
  • services.xserver.inputClassSections: Not working / overriden
  • services.xserver.libinput.additionalOptions: Couldn't manage to set an exception for a rule or device name

Release notes for 20.03 gives following line as a warning:

When using services.xserver.libinput (enabled by default in GNOME), it now handles all input devices, not just touchpads. As a result, you might need to re-evaluate any custom Xorg configuration. In particular, Option "XkbRules" "base" may result in broken keyboard layout.

But I am not sure if this my setup is possible/supported anymore.

@seqizz As long as you only want to configure a single device with services.xserver.libinput, you can add a MatchProduct (or similar) line to services.xserver.libinput.additionalOptions.

@seqizz As long as you only want to configure a single device with services.xserver.libinput, you can add a MatchProduct (or similar) line to services.xserver.libinput.additionalOptions.

Yeah that looks like a valid option. Thanks for the suggestion :+1:

To make the workaround explicit for anyone else running into this, I added the additionalOptions line to this part of my config:

services.xserver.libinput = {
  enable = true;
  naturalScrolling = true; 
  additionalOptions = ''MatchIsTouchpad "on"'';
};

This was an annoying bug to chase down in my 20.03 upgrade - everything worked perfectly except my mouse scroll wheel was now backwards. As far as I can tell this will affect every user who a) has natural scrolling enabled for their touchpad and b) uses an external mouse with a scroll wheel.

Perhaps cfg.naturalScrolling could be defaulted to null instead of false? That would allow an optionalString check similar to what's done with cfg.scrollButton just one line below. If it's null, then NaturalScrolling wouldn't have a value in the catch-all InputClass, and I could then configure it however I wanted to with custom inputClassSections.

Just to second @zackelan it was quite unusual to boot my 20.03 for the first time and some how my mouse scroller was backwards. I guess 2020 is _alost_ the year of the Linux desktop :+1:

The release has been great so far though :100:

I marked this as stale due to inactivity. → More info

I'm on 20.09 and @zackelan's workaround doesn't seem to work for me. Actually, I'm in this weird spot where I have naturalScrolling enabled regardless of whether I set it to true or not :-(

Was this page helpful?
0 / 5 - 0 ratings

Related issues

retrry picture retrry  路  3Comments

lverns picture lverns  路  3Comments

spacekitteh picture spacekitteh  路  3Comments

copumpkin picture copumpkin  路  3Comments

rzetterberg picture rzetterberg  路  3Comments