Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nixos/libinput: separate settings by mouse/touchpad #108909

Merged
merged 3 commits into from Jan 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion nixos/doc/manual/configuration/x-windows.xml
Expand Up @@ -186,7 +186,7 @@
The driver has many options (see <xref linkend="ch-options"/>). For
instance, the following disables tap-to-click behavior:
<programlisting>
<xref linkend="opt-services.xserver.libinput.tapping"/> = false;
<xref linkend="opt-services.xserver.libinput.touchpad.tapping"/> = false;
</programlisting>
Note: the use of <literal>services.xserver.synaptics</literal> is deprecated
since NixOS 17.09.
Expand Down
11 changes: 11 additions & 0 deletions nixos/doc/manual/release-notes/rl-2103.xml
Expand Up @@ -430,6 +430,17 @@ http://some.json-exporter.host:7979/probe?target=https://example.com/some/json/e
dynamically allocated uid.
</para>
</listitem>
<listitem>
<para>
The libinput module has been updated with the ability to configure mouse and touchpad settings separately.
The options in <literal>services.xserver.libinput</literal> have been renamed to <literal>services.xserver.libinput.touchpad</literal>,
while there is a new <literal>services.xserver.libinput.mouse</literal> for mouse related configuration.
</para>
<para>
Since touchpad options no longer apply to all devices, you may want to replicate your touchpad configuration in
mouse section.
</para>
</listitem>
</itemizedlist>
</section>

Expand Down
96 changes: 59 additions & 37 deletions nixos/modules/services/x11/hardware/libinput.nix
Expand Up @@ -3,23 +3,18 @@
with lib;

let cfg = config.services.xserver.libinput;
xorgBool = v: if v then "on" else "off";
in {

options = {

services.xserver.libinput = {

enable = mkEnableOption "libinput";
xorgBool = v: if v then "on" else "off";

mkConfigForDevice = deviceType: {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not every option makes sense for mouse and touchpad here, so probably we will need some mkIf deviceType == "touchpad" and mkIf deviceType == "mouse". But I think this can be fixed in another PR since there isn't any clear documentation if option X is never applied for Y device.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I'd prefer adding the type-specific options not here but where we use the function, like touchpad = mkConfigForDevice "touchpad" // { tapToClick = mkOption …; };

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this makes sense. Once this PR is merged I will look at it.

dev = mkOption {
type = types.nullOr types.str;
default = null;
example = "/dev/input/event0";
description =
''
Path for touchpad device. Set to null to apply to any
auto-detected touchpad.
Path for ${deviceType} device. Set to null to apply to any
auto-detected ${deviceType}.
'';
};

Expand Down Expand Up @@ -185,14 +180,63 @@ in {
Option "DragLockButtons" "L1 B1 L2 B2"
'';
description = ''
Additional options for libinput touchpad driver. See
Additional options for libinput ${deviceType} driver. See
<citerefentry><refentrytitle>libinput</refentrytitle><manvolnum>4</manvolnum></citerefentry>
for available options.";
'';
};

};

mkX11ConfigForDevice = deviceType: matchIs: ''
Identifier "libinput ${deviceType} configuration"
MatchDriver "libinput"
MatchIs${matchIs} "${xorgBool true}"
thiagokokada marked this conversation as resolved.
Show resolved Hide resolved
${optionalString (cfg.${deviceType}.dev != null) ''MatchDevicePath "${cfg.${deviceType}.dev}"''}
Option "AccelProfile" "${cfg.${deviceType}.accelProfile}"
${optionalString (cfg.${deviceType}.accelSpeed != null) ''Option "AccelSpeed" "${cfg.${deviceType}.accelSpeed}"''}
${optionalString (cfg.${deviceType}.buttonMapping != null) ''Option "ButtonMapping" "${cfg.${deviceType}.buttonMapping}"''}
${optionalString (cfg.${deviceType}.calibrationMatrix != null) ''Option "CalibrationMatrix" "${cfg.${deviceType}.calibrationMatrix}"''}
${optionalString (cfg.${deviceType}.clickMethod != null) ''Option "ClickMethod" "${cfg.${deviceType}.clickMethod}"''}
Option "LeftHanded" "${xorgBool cfg.${deviceType}.leftHanded}"
Option "MiddleEmulation" "${xorgBool cfg.${deviceType}.middleEmulation}"
Option "NaturalScrolling" "${xorgBool cfg.${deviceType}.naturalScrolling}"
${optionalString (cfg.${deviceType}.scrollButton != null) ''Option "ScrollButton" "${toString cfg.${deviceType}.scrollButton}"''}
Option "ScrollMethod" "${cfg.${deviceType}.scrollMethod}"
Option "HorizontalScrolling" "${xorgBool cfg.${deviceType}.horizontalScrolling}"
Option "SendEventsMode" "${cfg.${deviceType}.sendEventsMode}"
Option "Tapping" "${xorgBool cfg.${deviceType}.tapping}"
Option "TappingDragLock" "${xorgBool cfg.${deviceType}.tappingDragLock}"
Option "DisableWhileTyping" "${xorgBool cfg.${deviceType}.disableWhileTyping}"
${cfg.${deviceType}.additionalOptions}
'';
in {

imports =
(map (option: mkRenamedOptionModule ([ "services" "xserver" "libinput" option ]) [ "services" "xserver" "libinput" "touchpad" option ]) [
"accelProfile"
"accelSpeed"
"buttonMapping"
"calibrationMatrix"
"clickMethod"
"leftHanded"
"middleEmulation"
"naturalScrolling"
"scrollButton"
"scrollMethod"
"horizontalScrolling"
"sendEventsMode"
"tapping"
"disableWhileTyping"
"additionalOptions"
]);

options = {

services.xserver.libinput = {
enable = mkEnableOption "libinput";
mouse = mkConfigForDevice "mouse";
touchpad = mkConfigForDevice "touchpad";
};
};


Expand All @@ -212,32 +256,10 @@ in {

services.udev.packages = [ pkgs.libinput.out ];

services.xserver.config =
''
# General libinput configuration.
# See CONFIGURATION DETAILS section of man:libinput(4).
Section "InputClass"
Identifier "libinputConfiguration"
MatchDriver "libinput"
${optionalString (cfg.dev != null) ''MatchDevicePath "${cfg.dev}"''}
Option "AccelProfile" "${cfg.accelProfile}"
${optionalString (cfg.accelSpeed != null) ''Option "AccelSpeed" "${cfg.accelSpeed}"''}
${optionalString (cfg.buttonMapping != null) ''Option "ButtonMapping" "${cfg.buttonMapping}"''}
${optionalString (cfg.calibrationMatrix != null) ''Option "CalibrationMatrix" "${cfg.calibrationMatrix}"''}
${optionalString (cfg.clickMethod != null) ''Option "ClickMethod" "${cfg.clickMethod}"''}
Option "LeftHanded" "${xorgBool cfg.leftHanded}"
Option "MiddleEmulation" "${xorgBool cfg.middleEmulation}"
Option "NaturalScrolling" "${xorgBool cfg.naturalScrolling}"
${optionalString (cfg.scrollButton != null) ''Option "ScrollButton" "${toString cfg.scrollButton}"''}
Option "ScrollMethod" "${cfg.scrollMethod}"
Option "HorizontalScrolling" "${xorgBool cfg.horizontalScrolling}"
Option "SendEventsMode" "${cfg.sendEventsMode}"
Option "Tapping" "${xorgBool cfg.tapping}"
Option "TappingDragLock" "${xorgBool cfg.tappingDragLock}"
Option "DisableWhileTyping" "${xorgBool cfg.disableWhileTyping}"
${cfg.additionalOptions}
EndSection
'';
services.xserver.inputClassSections = [
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As a side effect of using inputClassSections instead of config here, this now works as it should:

{
    xserver = {
      enable = true;
      libinput = {
        enable = true;
        mouse = {
          naturalScrolling = true;
        };
      };
    };

    inputClassSections = [
      ''
        Identifier "natural scrolling"
        MatchIsPointer "on"
        Option "NaturalScrolling" "on"
      ''
    ];
}

You will have Natural Scrolling in a mouse in this case.

And while this may be strange, it is important to cover the cases like PR #90635 (that was reverted later). So even if we set something by default in mouse/touchpad, the user can always overwrite (this is isn't true nowadays since you can't overwrite a config with inputClassSections).

(mkX11ConfigForDevice "mouse" "Pointer")
(mkX11ConfigForDevice "touchpad" "Touchpad")
];

assertions = [
# already present in synaptics.nix
Expand Down