me like nix
1{ inputs, ... }:
2
3{
4 flake.modules.nixos.desktop =
5 { pkgs, lib, ... }:
6 let
7 niriPackage = inputs.niri.packages.${pkgs.stdenv.hostPlatform.system}.niri-unstable;
8 in
9 {
10 programs.niri = {
11 enable = true;
12 package = niriPackage;
13 };
14
15 programs.regreet = {
16 enable = true;
17 cageArgs = [
18 "-s"
19 "-d"
20 ];
21 settings.GTK.application_prefer_dark_theme = true;
22 theme = {
23 package = pkgs.catppuccin-gtk.override {
24 variant = "frappe";
25 accents = [ "lavender" ];
26 size = "standard";
27 };
28 name = "catppuccin-frappe-lavender-standard";
29 };
30 iconTheme = {
31 package = pkgs.catppuccin-papirus-folders.override {
32 flavor = "frappe";
33 accent = "lavender";
34 };
35 name = "Papirus-Dark";
36 };
37 cursorTheme = {
38 package = pkgs.catppuccin-cursors.frappeDark;
39 name = "catppuccin-frappe-dark-cursors";
40 };
41 };
42
43 # Scale regreet's greeter for HiDPI displays
44 services.greetd.settings.default_session.command =
45 lib.mkForce "${pkgs.dbus}/bin/dbus-run-session ${lib.getExe pkgs.cage} -s -d -- env GDK_SCALE=2 ${lib.getExe pkgs.regreet}";
46
47 # ZSA Keyboard udev rules for Oryx web flashing and live training
48 services.udev.extraRules = ''
49 # Rules for Oryx web flashing and live training
50 KERNEL=="hidraw*", ATTRS{idVendor}=="16c0", MODE="0664", GROUP="plugdev"
51 KERNEL=="hidraw*", ATTRS{idVendor}=="3297", MODE="0664", GROUP="plugdev"
52
53 # Legacy rules for live training over webusb (Not needed for firmware v21+)
54 # Rule for all ZSA keyboards
55 SUBSYSTEM=="usb", ATTR{idVendor}=="3297", GROUP="plugdev"
56 # Rule for the Moonlander
57 SUBSYSTEM=="usb", ATTR{idVendor}=="3297", ATTR{idProduct}=="1969", GROUP="plugdev"
58 # Rule for the Ergodox EZ
59 SUBSYSTEM=="usb", ATTR{idVendor}=="feed", ATTR{idProduct}=="1307", GROUP="plugdev"
60 # Rule for the Planck EZ
61 SUBSYSTEM=="usb", ATTR{idVendor}=="feed", ATTR{idProduct}=="6060", GROUP="plugdev"
62
63 # Wally Flashing rules for the Ergodox EZ
64 ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789B]?", ENV{ID_MM_DEVICE_IGNORE}="1"
65 ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789A]?", ENV{MTP_NO_PROBE}="1"
66 SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789ABCD]?", MODE:="0666"
67 KERNEL=="ttyACM*", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789B]?", MODE:="0666"
68
69 # Keymapp / Wally Flashing rules for the Moonlander and Planck EZ
70 SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="df11", MODE:="0666", SYMLINK+="stm32_dfu"
71 # Keymapp Flashing rules for the Voyager
72 SUBSYSTEMS=="usb", ATTRS{idVendor}=="3297", MODE:="0666", SYMLINK+="ignition_dfu"
73 # USB serial device access via Chrome/Chromium
74 KERNEL=="ttyUSB[0-9]*", MODE:="0666", GROUP="dialout"
75 KERNEL=="ttyACM[0-9]*", MODE:="0666", GROUP="dialout"
76 '';
77 };
78
79 flake.modules.homeManager.desktop =
80 { pkgs, lib, config, ... }:
81 let
82 niriPackage = inputs.niri.packages.${pkgs.stdenv.hostPlatform.system}.niri-unstable;
83 wallpapers = import ./_data/wallpapers.nix;
84 downloads = builtins.concatStringsSep "\n" (
85 map (wp: ''
86 if [ ! -f "$DIR/${wp.filename}" ]; then
87 echo "Downloading ${wp.filename}..."
88 ${pkgs.curl}/bin/curl -fsSL -o "$DIR/${wp.filename}" ${
89 builtins.replaceStrings [ "\"" ] [ "\\\"" ] wp.url
90 } || echo "WARNING: Failed to download ${wp.filename}, skipping"
91 fi
92 '') wallpapers
93 );
94 in
95 {
96 home.packages = with pkgs; [
97 inputs.fsel.packages.${pkgs.stdenv.hostPlatform.system}.default
98 bemoji
99 (import ../packages/cclip.nix { inherit pkgs; })
100 xwayland-satellite
101 ];
102
103 programs.niri = {
104 enable = true;
105 package = niriPackage;
106 settings = {
107 window-rules = [
108 {
109 geometry-corner-radius = {
110 top-left = 5.0;
111 top-right = 5.0;
112 bottom-left = 5.0;
113 bottom-right = 5.0;
114 };
115 clip-to-geometry = true;
116 draw-border-with-background = false;
117 }
118 {
119 matches = [ { app-id = "^steam_app_"; } ];
120 border.enable = false;
121 open-fullscreen = true;
122 }
123 {
124 matches = [ { app-id = "^fsel$"; } ];
125 open-floating = true;
126 default-column-width.fixed = 800;
127 default-window-height.fixed = 500;
128 }
129 ];
130 debug = {
131 honor-xdg-activation-with-invalid-serial = { };
132 };
133 layout = {
134 focus-ring = {
135 width = 2;
136 };
137 struts = {
138 top = -6;
139 bottom = -6;
140 left = 0;
141 right = 0;
142 };
143 gaps = 8;
144 };
145 gestures = {
146 hot-corners = {
147 enable = false;
148 };
149 };
150 binds = {
151 "Mod+d".action.spawn = [
152 "alacritty"
153 "--class"
154 "fsel"
155 "-e"
156 "fsel"
157 "--detach"
158 ];
159 "Mod+c".action.spawn = [
160 "alacritty"
161 "--class"
162 "fsel"
163 "-e"
164 "fsel"
165 "--cclip"
166 ];
167 "Mod+e".action.spawn = "bemoji";
168 "Mod+n".action.spawn = [
169 "noctalia"
170 "msg"
171 "panel-toggle"
172 "notifications"
173 ];
174 "Mod+a".action.spawn = "alacritty";
175 "Mod+h".action = {
176 focus-column-left = { };
177 };
178 "Mod+j".action = {
179 focus-workspace-down = { };
180 };
181 "Mod+k".action = {
182 focus-workspace-up = { };
183 };
184 "Mod+l".action = {
185 focus-column-right = { };
186 };
187 "Mod+Shift+h".action = {
188 move-column-left = { };
189 };
190 "Mod+Shift+j".action = {
191 move-window-down-or-to-workspace-down = { };
192 };
193 "Mod+Shift+k".action = {
194 move-window-up-or-to-workspace-up = { };
195 };
196 "Mod+Shift+l".action = {
197 move-column-right = { };
198 };
199 "Mod+Down".action = {
200 move-workspace-down = { };
201 };
202 "Mod+Up".action = {
203 move-workspace-up = { };
204 };
205 "Mod+p".action = {
206 show-hotkey-overlay = { };
207 };
208 "Mod+o".action = {
209 toggle-overview = { };
210 };
211 "Mod+q".action = {
212 close-window = { };
213 };
214 "Mod+f".action = {
215 toggle-window-floating = { };
216 };
217 "Mod+Shift+f".action = {
218 switch-focus-between-floating-and-tiling = { };
219 };
220 "Mod+m".action = {
221 fullscreen-window = { };
222 };
223 "Mod+s".action = {
224 screenshot = {
225 show-pointer = true;
226 };
227 };
228 "Mod+1".action = {
229 set-column-width = "100%";
230 };
231 "Mod+2".action = {
232 set-column-width = "50%";
233 };
234 "Mod+Minus".action = {
235 set-column-width = "-10%";
236 };
237 "Mod+Equal".action = {
238 set-column-width = "+10%";
239 };
240 "Mod+Shift+q".action = {
241 quit = { };
242 };
243 "Mod+Shift+r".action.spawn = [
244 "systemctl"
245 "--user"
246 "restart"
247 "noctalia.service"
248 ];
249 "XF86AudioPlay".action.spawn = [
250 "noctalia"
251 "msg"
252 "media"
253 "toggle"
254 ];
255 "XF86AudioStop".action.spawn = [
256 "noctalia"
257 "msg"
258 "media"
259 "stop"
260 ];
261 "XF86AudioNext".action.spawn = [
262 "noctalia"
263 "msg"
264 "media"
265 "next"
266 ];
267 "XF86AudioPrev".action.spawn = [
268 "noctalia"
269 "msg"
270 "media"
271 "previous"
272 ];
273 "XF86AudioMute".action.spawn = [
274 "noctalia"
275 "msg"
276 "volume-mute"
277 ];
278 "XF86AudioLowerVolume".action.spawn = [
279 "noctalia"
280 "msg"
281 "volume-down"
282 "5%"
283 ];
284 "XF86AudioRaiseVolume".action.spawn = [
285 "noctalia"
286 "msg"
287 "volume-up"
288 "5%"
289 ];
290 "XF86MonBrightnessDown".action.spawn = [
291 "noctalia"
292 "msg"
293 "brightness-down"
294 "5%"
295 ];
296 "XF86MonBrightnessUp".action.spawn = [
297 "noctalia"
298 "msg"
299 "brightness-up"
300 "5%"
301 ];
302 };
303 outputs = {
304 "DP-5" = {
305 scale = 2.0;
306 mode = {
307 width = 5120;
308 height = 2160;
309 refresh = 120.0;
310 };
311 position = {
312 x = 0;
313 y = 0;
314 };
315 };
316 "DP-1" = {
317 scale = 2.0;
318 mode = {
319 width = 5120;
320 height = 2160;
321 refresh = 120.0;
322 };
323 position = {
324 x = 0;
325 y = 0;
326 };
327 };
328 "DP-2" = {
329 scale = 1.0;
330 mode = {
331 width = 5120;
332 height = 2160;
333 refresh = 120.0;
334 };
335 position = {
336 x = 0;
337 y = 0;
338 };
339 };
340 "DP-6" = {
341 scale = 2.0;
342 mode = {
343 width = 5120;
344 height = 2160;
345 refresh = 120.0;
346 };
347 position = {
348 x = 0;
349 y = 0;
350 };
351 };
352 "DP-7" = {
353 scale = 2.0;
354 mode = {
355 width = 5120;
356 height = 2160;
357 refresh = 120.0;
358 };
359 position = {
360 x = 0;
361 y = 0;
362 };
363 };
364 "eDP-1" = {
365 scale = 1.5;
366 mode = {
367 width = 2560;
368 height = 1600;
369 refresh = 165.0;
370 };
371 position = {
372 x = 0;
373 y = 1080;
374 };
375 };
376 };
377 spawn-at-startup = [
378 { command = [ "xwayland-satellite" ]; }
379 { command = [ "cclipd" ]; }
380 ];
381 environment = {
382 DISPLAY = ":0";
383 };
384 };
385 };
386
387 xdg.configFile.niri-config.source = lib.mkForce (
388 pkgs.runCommand "niri-config-with-noctalia-include"
389 {
390 config = ''
391 include "noctalia.kdl"
392 ${config.programs.niri.finalConfig}
393 '';
394 passAsFile = [ "config" ];
395 buildInputs = [ config.programs.niri.package ];
396 }
397 ''
398 work="$TMPDIR/niri-config"
399 mkdir -p "$work"
400 cp "$configPath" "$work/config.kdl"
401 : > "$work/noctalia.kdl"
402 niri validate -c "$work/config.kdl"
403 cp "$work/config.kdl" "$out"
404 ''
405 );
406
407 home.activation.ensureNiriNoctaliaConfig = config.lib.dag.entryAfter [ "writeBoundary" ] ''
408 config_home="''${XDG_CONFIG_HOME:-$HOME/.config}"
409 mkdir -p "$config_home/niri"
410 if [ ! -e "$config_home/niri/noctalia.kdl" ]; then
411 : > "$config_home/niri/noctalia.kdl"
412 fi
413 '';
414
415 # Wallpaper downloads
416 home.activation.downloadWallpapers = config.lib.dag.entryAfter [ "writeBoundary" ] ''
417 DIR="${config.home.homeDirectory}/Pictures/Wallpapers"
418 mkdir -p "$DIR"
419 ${downloads}
420 '';
421
422 services.udiskie = {
423 enable = true;
424 tray = "never";
425 automount = true;
426 };
427
428 home.pointerCursor = {
429 name = "Adwaita";
430 package = pkgs.adwaita-icon-theme;
431 size = 16;
432 x11.enable = true;
433 gtk.enable = true;
434 };
435 };
436}