lol
1{
2 lib,
3 buildPythonApplication,
4 fetchFromGitHub,
5 pkgconfig,
6 wrapGAppsHook3,
7 gettext,
8 gtk3,
9 glib,
10 dbus,
11 gobject-introspection,
12 xmodmap,
13 pygobject3,
14 setuptools,
15 evdev,
16 pydantic,
17 pydbus,
18 psutil,
19 procps,
20 gtksourceview4,
21 bash,
22 nixosTests,
23 # Change the default log level to debug for easier debugging of package issues
24 withDebugLogLevel ? false,
25 # Xmodmap is an optional dependency
26 # If you use Xmodmap to set keyboard mappings (or your DE does)
27 # it is required to correctly map keys
28 withXmodmap ? true,
29 # Some tests are flakey under high CPU load and could cause intermittent
30 # failures when building. Override this to true to run tests anyway
31 # See upstream issue: https://github.com/sezanzeb/input-remapper/issues/306
32 withDoCheck ? false,
33}:
34
35let
36 maybeXmodmap = lib.optional withXmodmap xmodmap;
37in
38(buildPythonApplication rec {
39 pname = "input-remapper";
40 version = "2.1.1";
41
42 src = fetchFromGitHub {
43 owner = "sezanzeb";
44 repo = "input-remapper";
45 tag = version;
46 hash = "sha256-GMKcs2UK1yegGT/TBsLGgTBJROQ38M6WwnLbJIuAZwg=";
47 };
48
49 postPatch =
50 ''
51 # fix FHS paths
52 substituteInPlace inputremapper/configs/data.py \
53 --replace-fail "/usr/share" "$out/usr/share"
54 ''
55 + lib.optionalString withDebugLogLevel ''
56 # if debugging
57 substituteInPlace inputremapper/logger.py \
58 --replace-fail "logger.setLevel(logging.INFO)" "logger.setLevel(logging.DEBUG)"
59 '';
60
61 nativeBuildInputs = [
62 wrapGAppsHook3
63 gettext # needed to build translations
64 gtk3
65 glib
66 gobject-introspection
67 pygobject3
68 ] ++ maybeXmodmap;
69
70 dependencies = [
71 setuptools # needs pkg_resources
72 pygobject3
73 evdev
74 pkgconfig
75 pydantic
76 pydbus
77 gtksourceview4
78 psutil
79 ];
80
81 doCheck = withDoCheck;
82
83 nativeCheckInputs = [ psutil ];
84
85 pythonImportsCheck = [
86 "evdev"
87 "inputremapper"
88 ];
89
90 postInstall = ''
91 substituteInPlace data/99-input-remapper.rules \
92 --replace-fail 'RUN+="/bin/input-remapper-control' "RUN+=\"$out/bin/input-remapper-control"
93 substituteInPlace data/input-remapper.service \
94 --replace-fail "ExecStart=/usr/bin/input-remapper-service" "ExecStart=$out/bin/input-remapper-service"
95 substituteInPlace data/input-remapper-autoload.desktop \
96 --replace-fail "bash" "${lib.getExe bash}"
97
98 install -m644 -D -t $out/share/applications/ data/*.desktop
99 install -m644 -D -t $out/share/polkit-1/actions/ data/input-remapper.policy
100 install -m644 -D data/99-input-remapper.rules $out/etc/udev/rules.d/99-input-remapper.rules
101 install -m644 -D data/input-remapper.service $out/lib/systemd/system/input-remapper.service
102 install -m644 -D data/input-remapper.policy $out/share/polkit-1/actions/input-remapper.policy
103 install -m644 -D data/inputremapper.Control.conf $out/etc/dbus-1/system.d/inputremapper.Control.conf
104 install -m644 -D data/input-remapper.svg $out/share/icons/hicolor/scalable/apps/input-remapper.svg
105 install -m644 -D -t $out/usr/share/input-remapper/ data/*
106
107 # Only install input-remapper prefixed binaries, we don't care about deprecated key-mapper ones
108 install -m755 -D -t $out/bin/ bin/input-remapper*
109 '';
110
111 # Custom test script, can't use plain pytest / pytestCheckHook
112 # We only run tests in the unit folder, integration tests require UI
113 # To allow tests which access the system and session DBUS to run, we start a dbus session
114 # and bind it to both the system and session buses
115 installCheckPhase = ''
116 runHook preInstallCheck
117
118 echo "<busconfig>
119 <type>session</type>
120 <listen>unix:tmpdir=$TMPDIR</listen>
121 <listen>unix:path=/build/system_bus_socket</listen>
122 <standard_session_servicedirs/>
123 <policy context=\"default\">
124 <!-- Allow everything to be sent -->
125 <allow send_destination=\"*\" eavesdrop=\"true\"/>
126 <!-- Allow everything to be received -->
127 <allow eavesdrop=\"true\"/>
128 <!-- Allow anyone to own anything -->
129 <allow own=\"*\"/>
130 </policy>
131 </busconfig>" > dbus.cfg
132 PATH=${
133 lib.makeBinPath (
134 [
135 dbus
136 procps
137 ]
138 ++ maybeXmodmap
139 )
140 }:$PATH \
141 USER="$(id -u -n)" \
142 DBUS_SYSTEM_BUS_ADDRESS=unix:path=/build/system_bus_socket \
143 ${dbus}/bin/dbus-run-session --config-file dbus.cfg \
144 python tests/test.py --start-dir unit
145
146 runHook postInstallCheck
147 '';
148
149 # Nixpkgs 15.9.4.3. When using wrapGAppsHook3 with special derivers you can end up with double wrapped binaries.
150 dontWrapGApps = true;
151
152 preFixup = ''
153 makeWrapperArgs+=(
154 "''${gappsWrapperArgs[@]}"
155 --prefix PATH : "${lib.makeBinPath maybeXmodmap}"
156 )
157 '';
158
159 passthru.tests = nixosTests.input-remapper;
160
161 meta = {
162 description = "Easy to use tool to change the mapping of your input device buttons";
163 homepage = "https://github.com/sezanzeb/input-remapper";
164 license = lib.licenses.gpl3Plus;
165 platforms = lib.platforms.linux;
166 maintainers = with lib.maintainers; [ LunNova ];
167 mainProgram = "input-remapper-gtk";
168 };
169}).overrideAttrs
170 (
171 final: prev: {
172 # Set in an override as buildPythonApplication doesn't yet support
173 # the `final:` arg yet from #119942 'overlay style overridable recursive attributes'
174 # this ensures the rev matches the input src's rev after overriding
175 # See https://discourse.nixos.org/t/avoid-rec-expresions-in-nixpkgs/8293/7 for more
176 # discussion
177 postPatch =
178 prev.postPatch or ""
179 + ''
180 # set revision for --version output
181 echo "COMMIT_HASH = '${final.src.rev}'" > inputremapper/commit_hash.py
182 '';
183 }
184 )