1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let cfg = config.services.xserver.libinput; 6 xorgBool = v: if v then "on" else "off"; 7in { 8 9 options = { 10 11 services.xserver.libinput = { 12 13 enable = mkEnableOption "libinput"; 14 15 dev = mkOption { 16 type = types.nullOr types.str; 17 default = null; 18 example = "/dev/input/event0"; 19 description = 20 '' 21 Path for touchpad device. Set to null to apply to any 22 auto-detected touchpad. 23 ''; 24 }; 25 26 accelProfile = mkOption { 27 type = types.enum [ "flat" "adaptive" ]; 28 default = "flat"; 29 example = "adaptive"; 30 description = 31 '' 32 Sets the pointer acceleration profile to the given profile. Permitted values are adaptive, flat. 33 Not all devices support this option or all profiles. If a profile is unsupported, the default profile 34 for this is used. For a description on the profiles and their behavior, see the libinput documentation. 35 ''; 36 }; 37 38 accelSpeed = mkOption { 39 type = types.nullOr types.string; 40 default = null; 41 description = "Cursor acceleration (how fast speed increases from minSpeed to maxSpeed)."; 42 }; 43 44 buttonMapping = mkOption { 45 type = types.nullOr types.string; 46 default = null; 47 description = 48 '' 49 Sets the logical button mapping for this device, see XSetPointerMapping(3). The string must 50 be a space-separated list of button mappings in the order of the logical buttons on the 51 device, starting with button 1. The default mapping is "1 2 3 ... 32". A mapping of 0 deac 52 tivates the button. Multiple buttons can have the same mapping. Invalid mapping strings are 53 discarded and the default mapping is used for all buttons. Buttons not specified in the 54 user's mapping use the default mapping. See section BUTTON MAPPING for more details. 55 ''; 56 }; 57 58 calibrationMatrix = mkOption { 59 type = types.nullOr types.string; 60 default = null; 61 description = 62 '' 63 A string of 9 space-separated floating point numbers. Sets the calibration matrix to the 64 3x3 matrix where the first row is (abc), the second row is (def) and the third row is (ghi). 65 ''; 66 }; 67 68 clickMethod = mkOption { 69 type = types.nullOr (types.enum [ "none" "buttonareas" "clickfinger" ]); 70 default = null; 71 example = "none"; 72 description = 73 '' 74 Enables a click method. Permitted values are none, buttonareas, clickfinger. 75 Not all devices support all methods, if an option is unsupported, 76 the default click method for this device is used. 77 ''; 78 }; 79 80 leftHanded = mkOption { 81 type = types.bool; 82 default = false; 83 example = true; 84 description = "Enables left-handed button orientation, i.e. swapping left and right buttons."; 85 }; 86 87 middleEmulation = mkOption { 88 type = types.bool; 89 default = true; 90 example = false; 91 description = 92 '' 93 Enables middle button emulation. When enabled, pressing the left and right buttons 94 simultaneously produces a middle mouse button click. 95 ''; 96 }; 97 98 naturalScrolling = mkOption { 99 type = types.bool; 100 default = false; 101 example = true; 102 description = "Enables or disables natural scrolling behavior."; 103 }; 104 105 scrollButton = mkOption { 106 type = types.nullOr types.int; 107 default = null; 108 example = 1; 109 description = 110 '' 111 Designates a button as scroll button. If the ScrollMethod is button and the button is logically 112 held down, x/y axis movement is converted into scroll events. 113 ''; 114 }; 115 116 scrollMethod = mkOption { 117 type = types.enum [ "twofinger" "edge" "none" ]; 118 default = "twofinger"; 119 example = "edge"; 120 description = 121 '' 122 Specify the scrolling method. 123 ''; 124 }; 125 126 horizontalScrolling = mkOption { 127 type = types.bool; 128 default = true; 129 example = false; 130 description = 131 '' 132 Disables horizontal scrolling. When disabled, this driver will discard any horizontal scroll 133 events from libinput. Note that this does not disable horizontal scrolling, it merely 134 discards the horizontal axis from any scroll events. 135 ''; 136 }; 137 138 sendEventsMode = mkOption { 139 type = types.enum [ "disabled" "enabled" "disabled-on-external-mouse" ]; 140 default = "enabled"; 141 example = "disabled"; 142 description = 143 '' 144 Sets the send events mode to disabled, enabled, or "disable when an external mouse is connected". 145 ''; 146 }; 147 148 tapping = mkOption { 149 type = types.bool; 150 default = true; 151 example = false; 152 description = 153 '' 154 Enables or disables tap-to-click behavior. 155 ''; 156 }; 157 158 tappingDragLock = mkOption { 159 type = types.bool; 160 default = true; 161 example = false; 162 description = 163 '' 164 Enables or disables drag lock during tapping behavior. When enabled, a finger up during tap- 165 and-drag will not immediately release the button. If the finger is set down again within the 166 timeout, the draging process continues. 167 ''; 168 }; 169 170 disableWhileTyping = mkOption { 171 type = types.bool; 172 default = true; 173 example = false; 174 description = 175 '' 176 Disable input method while typing. 177 ''; 178 }; 179 180 additionalOptions = mkOption { 181 type = types.str; 182 default = ""; 183 example = 184 '' 185 Option "DragLockButtons" "L1 B1 L2 B2" 186 ''; 187 description = "Additional options for libinput touchpad driver."; 188 }; 189 190 }; 191 192 }; 193 194 195 config = mkIf cfg.enable { 196 197 services.xserver.modules = [ pkgs.xorg.xf86inputlibinput ]; 198 199 environment.systemPackages = [ pkgs.xorg.xf86inputlibinput ]; 200 201 services.xserver.config = 202 '' 203 # Automatically enable the libinput driver for all touchpads. 204 Section "InputClass" 205 Identifier "libinputConfiguration" 206 MatchIsTouchpad "on" 207 ${optionalString (cfg.dev != null) ''MatchDevicePath "${cfg.dev}"''} 208 Driver "libinput" 209 Option "AccelProfile" "${cfg.accelProfile}" 210 ${optionalString (cfg.accelSpeed != null) ''Option "AccelSpeed" "${cfg.accelSpeed}"''} 211 ${optionalString (cfg.buttonMapping != null) ''Option "ButtonMapping" "${cfg.buttonMapping}"''} 212 ${optionalString (cfg.calibrationMatrix != null) ''Option "CalibrationMatrix" "${cfg.calibrationMatrix}"''} 213 ${optionalString (cfg.clickMethod != null) ''Option "ClickMethod" "${cfg.clickMethod}"''} 214 Option "LeftHanded" "${xorgBool cfg.leftHanded}" 215 Option "MiddleEmulation" "${xorgBool cfg.middleEmulation}" 216 Option "NaturalScrolling" "${xorgBool cfg.naturalScrolling}" 217 ${optionalString (cfg.scrollButton != null) ''Option "ScrollButton" "${cfg.scrollButton}"''} 218 Option "ScrollMethod" "${cfg.scrollMethod}" 219 Option "HorizontalScrolling" "${xorgBool cfg.horizontalScrolling}" 220 Option "SendEventsMode" "${cfg.sendEventsMode}" 221 Option "Tapping" "${xorgBool cfg.tapping}" 222 Option "TappingDragLock" "${xorgBool cfg.tappingDragLock}" 223 Option "DisableWhileTyping" "${xorgBool cfg.disableWhileTyping}" 224 ${cfg.additionalOptions} 225 EndSection 226 ''; 227 228 }; 229 230}