1{ config, lib, ... }:
2
3with lib;
4
5{
6 ###### interface
7
8 options = {
9
10 hardware.trackpoint = {
11
12 enable = mkOption {
13 default = false;
14 type = types.bool;
15 description = ''
16 Enable sensitivity and speed configuration for trackpoints.
17 '';
18 };
19
20 sensitivity = mkOption {
21 default = 128;
22 example = 255;
23 type = types.int;
24 description = ''
25 Configure the trackpoint sensitivity. By default, the kernel
26 configures 128.
27 '';
28 };
29
30 speed = mkOption {
31 default = 97;
32 example = 255;
33 type = types.int;
34 description = ''
35 Configure the trackpoint speed. By default, the kernel
36 configures 97.
37 '';
38 };
39
40 emulateWheel = mkOption {
41 default = false;
42 type = types.bool;
43 description = ''
44 Enable scrolling while holding the middle mouse button.
45 '';
46 };
47
48 fakeButtons = mkOption {
49 default = false;
50 type = types.bool;
51 description = ''
52 Switch to "bare" PS/2 mouse support in case Trackpoint buttons are not recognized
53 properly. This can happen for example on models like the L430, T450, T450s, on
54 which the Trackpoint buttons are actually a part of the Synaptics touchpad.
55 '';
56 };
57
58 device = mkOption {
59 default = "TPPS/2 IBM TrackPoint";
60 type = types.str;
61 description = ''
62 The device name of the trackpoint. You can check with xinput.
63 Some newer devices (example x1c6) use "TPPS/2 Elan TrackPoint".
64 '';
65 };
66
67 };
68
69 };
70
71 ###### implementation
72
73 config =
74 let
75 cfg = config.hardware.trackpoint;
76 in
77 mkMerge [
78 (mkIf cfg.enable {
79 services.udev.extraRules = ''
80 ACTION=="add|change", SUBSYSTEM=="input", ATTR{name}=="${cfg.device}", ATTR{device/speed}="${toString cfg.speed}", ATTR{device/sensitivity}="${toString cfg.sensitivity}"
81 '';
82
83 systemd.services.trackpoint = {
84 wantedBy = [ "sysinit.target" ];
85 before = [
86 "sysinit.target"
87 "shutdown.target"
88 ];
89 conflicts = [ "shutdown.target" ];
90 unitConfig.DefaultDependencies = false;
91 serviceConfig.Type = "oneshot";
92 serviceConfig.RemainAfterExit = true;
93 serviceConfig.ExecStart = ''
94 ${config.systemd.package}/bin/udevadm trigger --attr-match=name="${cfg.device}"
95 '';
96 };
97 })
98
99 (mkIf (cfg.emulateWheel) {
100 services.xserver.inputClassSections = [
101 ''
102 Identifier "Trackpoint Wheel Emulation"
103 MatchProduct "${
104 if cfg.fakeButtons then
105 "PS/2 Generic Mouse"
106 else
107 "ETPS/2 Elantech TrackPoint|Elantech PS/2 TrackPoint|TPPS/2 IBM TrackPoint|DualPoint Stick|Synaptics Inc. Composite TouchPad / TrackPoint|ThinkPad USB Keyboard with TrackPoint|USB Trackpoint pointing device|Composite TouchPad / TrackPoint|${cfg.device}"
108 }"
109 MatchDevicePath "/dev/input/event*"
110 Option "EmulateWheel" "true"
111 Option "EmulateWheelButton" "2"
112 Option "Emulate3Buttons" "false"
113 Option "XAxisMapping" "6 7"
114 Option "YAxisMapping" "4 5"
115 ''
116 ];
117 })
118
119 (mkIf cfg.fakeButtons {
120 boot.extraModprobeConfig = "options psmouse proto=bare";
121 })
122 ];
123}