me like nix
1{ inputs, ... }:
2
3{
4 flake.modules.nixos.desktop =
5 { pkgs, lib, ... }:
6 {
7 programs.niri.enable = true;
8
9 programs.regreet = {
10 enable = true;
11 cageArgs = [
12 "-s"
13 "-d"
14 ];
15 settings.GTK.application_prefer_dark_theme = true;
16 theme = {
17 package = pkgs.catppuccin-gtk.override {
18 variant = "frappe";
19 accents = [ "lavender" ];
20 size = "standard";
21 };
22 name = "catppuccin-frappe-lavender-standard";
23 };
24 iconTheme = {
25 package = pkgs.catppuccin-papirus-folders.override {
26 flavor = "frappe";
27 accent = "lavender";
28 };
29 name = "Papirus-Dark";
30 };
31 cursorTheme = {
32 package = pkgs.catppuccin-cursors.frappeDark;
33 name = "catppuccin-frappe-dark-cursors";
34 };
35 };
36
37 # Scale regreet's greeter for HiDPI displays
38 services.greetd.settings.default_session.command =
39 lib.mkForce "${pkgs.dbus}/bin/dbus-run-session ${lib.getExe pkgs.cage} -s -d -- env GDK_SCALE=2 ${lib.getExe pkgs.regreet}";
40
41 # ZSA Keyboard udev rules for Oryx web flashing and live training
42 services.udev.extraRules = ''
43 # Rules for Oryx web flashing and live training
44 KERNEL=="hidraw*", ATTRS{idVendor}=="16c0", MODE="0664", GROUP="plugdev"
45 KERNEL=="hidraw*", ATTRS{idVendor}=="3297", MODE="0664", GROUP="plugdev"
46
47 # Legacy rules for live training over webusb (Not needed for firmware v21+)
48 # Rule for all ZSA keyboards
49 SUBSYSTEM=="usb", ATTR{idVendor}=="3297", GROUP="plugdev"
50 # Rule for the Moonlander
51 SUBSYSTEM=="usb", ATTR{idVendor}=="3297", ATTR{idProduct}=="1969", GROUP="plugdev"
52 # Rule for the Ergodox EZ
53 SUBSYSTEM=="usb", ATTR{idVendor}=="feed", ATTR{idProduct}=="1307", GROUP="plugdev"
54 # Rule for the Planck EZ
55 SUBSYSTEM=="usb", ATTR{idVendor}=="feed", ATTR{idProduct}=="6060", GROUP="plugdev"
56
57 # Wally Flashing rules for the Ergodox EZ
58 ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789B]?", ENV{ID_MM_DEVICE_IGNORE}="1"
59 ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789A]?", ENV{MTP_NO_PROBE}="1"
60 SUBSYSTEMS=="usb", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789ABCD]?", MODE:="0666"
61 KERNEL=="ttyACM*", ATTRS{idVendor}=="16c0", ATTRS{idProduct}=="04[789B]?", MODE:="0666"
62
63 # Keymapp / Wally Flashing rules for the Moonlander and Planck EZ
64 SUBSYSTEMS=="usb", ATTRS{idVendor}=="0483", ATTRS{idProduct}=="df11", MODE:="0666", SYMLINK+="stm32_dfu"
65 # Keymapp Flashing rules for the Voyager
66 SUBSYSTEMS=="usb", ATTRS{idVendor}=="3297", MODE:="0666", SYMLINK+="ignition_dfu"
67 # USB serial device access via Chrome/Chromium
68 KERNEL=="ttyUSB[0-9]*", MODE:="0666", GROUP="dialout"
69 KERNEL=="ttyACM[0-9]*", MODE:="0666", GROUP="dialout"
70 '';
71 };
72
73 flake.modules.homeManager.desktop =
74 { pkgs, config, ... }:
75 let
76 wallpapers = import ./_data/wallpapers.nix;
77 downloads = builtins.concatStringsSep "\n" (
78 map (wp: ''
79 if [ ! -f "$DIR/${wp.filename}" ]; then
80 echo "Downloading ${wp.filename}..."
81 ${pkgs.curl}/bin/curl -fsSL -o "$DIR/${wp.filename}" ${
82 builtins.replaceStrings [ "\"" ] [ "\\\"" ] wp.url
83 } || echo "WARNING: Failed to download ${wp.filename}, skipping"
84 fi
85 '') wallpapers
86 );
87 in
88 {
89 home.packages = with pkgs; [
90 inputs.fsel.packages.${pkgs.stdenv.hostPlatform.system}.default
91 bemoji
92 (import ../packages/cclip.nix { inherit pkgs; })
93 xwayland-satellite
94 ];
95
96 programs.niri = {
97 enable = true;
98 settings = {
99 window-rules = [
100 {
101 geometry-corner-radius = {
102 top-left = 5.0;
103 top-right = 5.0;
104 bottom-left = 5.0;
105 bottom-right = 5.0;
106 };
107 clip-to-geometry = true;
108 draw-border-with-background = false;
109 }
110 {
111 matches = [ { app-id = "^steam_app_"; } ];
112 border.enable = false;
113 open-fullscreen = true;
114 }
115 {
116 matches = [ { app-id = "^fsel$"; } ];
117 open-floating = true;
118 default-column-width.fixed = 800;
119 default-window-height.fixed = 500;
120 }
121 ];
122 debug = {
123 honor-xdg-activation-with-invalid-serial = { };
124 };
125 layout = {
126 focus-ring = {
127 width = 2;
128 active.color = "#8caaee";
129 inactive.color = "#414559";
130 };
131 struts = {
132 top = -6;
133 bottom = -6;
134 left = 0;
135 right = 0;
136 };
137 gaps = 8;
138 };
139 gestures = {
140 hot-corners = {
141 enable = false;
142 };
143 };
144 binds = {
145 "Mod+d".action.spawn = [
146 "alacritty"
147 "--class"
148 "fsel"
149 "-e"
150 "fsel"
151 "--detach"
152 ];
153 "Mod+c".action.spawn = [
154 "alacritty"
155 "--class"
156 "fsel"
157 "-e"
158 "fsel"
159 "--cclip"
160 ];
161 "Mod+e".action.spawn = "bemoji";
162 "Mod+n".action.spawn = [
163 "noctalia"
164 "msg"
165 "panel-toggle"
166 "notifications"
167 ];
168 "Mod+a".action.spawn = "alacritty";
169 "Mod+h".action = {
170 focus-column-left = { };
171 };
172 "Mod+j".action = {
173 focus-workspace-down = { };
174 };
175 "Mod+k".action = {
176 focus-workspace-up = { };
177 };
178 "Mod+l".action = {
179 focus-column-right = { };
180 };
181 "Mod+Shift+h".action = {
182 move-column-left = { };
183 };
184 "Mod+Shift+j".action = {
185 move-window-down-or-to-workspace-down = { };
186 };
187 "Mod+Shift+k".action = {
188 move-window-up-or-to-workspace-up = { };
189 };
190 "Mod+Shift+l".action = {
191 move-column-right = { };
192 };
193 "Mod+Down".action = {
194 move-workspace-down = { };
195 };
196 "Mod+Up".action = {
197 move-workspace-up = { };
198 };
199 "Mod+p".action = {
200 show-hotkey-overlay = { };
201 };
202 "Mod+o".action = {
203 toggle-overview = { };
204 };
205 "Mod+q".action = {
206 close-window = { };
207 };
208 "Mod+f".action = {
209 toggle-window-floating = { };
210 };
211 "Mod+Shift+f".action = {
212 switch-focus-between-floating-and-tiling = { };
213 };
214 "Mod+m".action = {
215 fullscreen-window = { };
216 };
217 "Mod+s".action = {
218 screenshot = {
219 show-pointer = true;
220 };
221 };
222 "Mod+1".action = {
223 set-column-width = "100%";
224 };
225 "Mod+2".action = {
226 set-column-width = "50%";
227 };
228 "Mod+Minus".action = {
229 set-column-width = "-10%";
230 };
231 "Mod+Equal".action = {
232 set-column-width = "+10%";
233 };
234 "Mod+Shift+q".action = {
235 quit = { };
236 };
237 "Mod+Shift+r".action.spawn = [
238 "systemctl"
239 "--user"
240 "restart"
241 "noctalia.service"
242 ];
243 "XF86AudioPlay".action.spawn = [
244 "noctalia"
245 "msg"
246 "media"
247 "toggle"
248 ];
249 "XF86AudioStop".action.spawn = [
250 "noctalia"
251 "msg"
252 "media"
253 "stop"
254 ];
255 "XF86AudioNext".action.spawn = [
256 "noctalia"
257 "msg"
258 "media"
259 "next"
260 ];
261 "XF86AudioPrev".action.spawn = [
262 "noctalia"
263 "msg"
264 "media"
265 "previous"
266 ];
267 "XF86AudioMute".action.spawn = [
268 "noctalia"
269 "msg"
270 "volume-mute"
271 ];
272 "XF86AudioLowerVolume".action.spawn = [
273 "noctalia"
274 "msg"
275 "volume-down"
276 "5%"
277 ];
278 "XF86AudioRaiseVolume".action.spawn = [
279 "noctalia"
280 "msg"
281 "volume-up"
282 "5%"
283 ];
284 "XF86MonBrightnessDown".action.spawn = [
285 "noctalia"
286 "msg"
287 "brightness-down"
288 "5%"
289 ];
290 "XF86MonBrightnessUp".action.spawn = [
291 "noctalia"
292 "msg"
293 "brightness-up"
294 "5%"
295 ];
296 };
297 outputs = {
298 "DP-5" = {
299 scale = 2.0;
300 mode = {
301 width = 5120;
302 height = 2160;
303 refresh = 120.0;
304 };
305 position = {
306 x = 0;
307 y = 0;
308 };
309 };
310 "DP-1" = {
311 scale = 2.0;
312 mode = {
313 width = 5120;
314 height = 2160;
315 refresh = 120.0;
316 };
317 position = {
318 x = 0;
319 y = 0;
320 };
321 };
322 "DP-2" = {
323 scale = 1.0;
324 mode = {
325 width = 5120;
326 height = 2160;
327 refresh = 120.0;
328 };
329 position = {
330 x = 0;
331 y = 0;
332 };
333 };
334 "DP-6" = {
335 scale = 2.0;
336 mode = {
337 width = 5120;
338 height = 2160;
339 refresh = 120.0;
340 };
341 position = {
342 x = 0;
343 y = 0;
344 };
345 };
346 "DP-7" = {
347 scale = 2.0;
348 mode = {
349 width = 5120;
350 height = 2160;
351 refresh = 120.0;
352 };
353 position = {
354 x = 0;
355 y = 0;
356 };
357 };
358 "eDP-1" = {
359 scale = 1.5;
360 mode = {
361 width = 2560;
362 height = 1600;
363 refresh = 165.0;
364 };
365 position = {
366 x = 0;
367 y = 1080;
368 };
369 };
370 };
371 spawn-at-startup = [
372 { command = [ "xwayland-satellite" ]; }
373 { command = [ "cclipd" ]; }
374 ];
375 environment = {
376 DISPLAY = ":0";
377 };
378 };
379 };
380
381 programs.noctalia = {
382 enable = true;
383 systemd.enable = true;
384 settings = {
385 bar.default = {
386 auto_hide = true;
387 center = [
388 "clock"
389 "weather"
390 ];
391 end = [
392 "media"
393 "notifications"
394 "clipboard"
395 "network"
396 "bluetooth"
397 "volume"
398 "battery"
399 "control-center"
400 "tray"
401 "session"
402 ];
403 margin_edge = 0;
404 reserve_space = false;
405 start = [
406 "wallpaper"
407 "workspaces"
408 ];
409 widget_spacing = 12;
410 };
411
412 location.auto_locate = true;
413
414 lockscreen = {
415 allow_empty_password = true;
416 blurred_desktop = true;
417 };
418
419 lockscreen_widgets = {
420 enabled = true;
421 schema_version = 2;
422 widget_order = [
423 "lockscreen-login-box@DP-7"
424 "lockscreen-login-box@eDP-1"
425 "lockscreen-widget-0000000000000001"
426 "lockscreen-widget-0000000000000002"
427 ];
428 grid = {
429 cell_size = 16;
430 major_interval = 4;
431 visible = true;
432 };
433 widget = {
434 "lockscreen-login-box@DP-7" = {
435 box_height = 0.0;
436 box_width = 0.0;
437 cx = 1280.0;
438 cy = 957.0;
439 output = "DP-7";
440 rotation = 0.0;
441 type = "login_box";
442 settings = {
443 background_color = "surface_variant";
444 background_opacity = 0.88;
445 background_radius = 12.0;
446 input_opacity = 1.0;
447 input_radius = 6.0;
448 show_login_button = true;
449 };
450 };
451 "lockscreen-login-box@eDP-1" = {
452 box_height = 0.0;
453 box_width = 0.0;
454 cx = 854.0;
455 cy = 944.0;
456 output = "eDP-1";
457 rotation = 0.0;
458 type = "login_box";
459 settings = {
460 background_color = "surface_variant";
461 background_opacity = 0.88;
462 background_radius = 12.0;
463 input_opacity = 1.0;
464 input_radius = 6.0;
465 show_login_button = true;
466 };
467 };
468 lockscreen-widget-0000000000000001 = {
469 box_height = 0.0;
470 box_width = 0.0;
471 cx = 723.0;
472 cy = 217.5;
473 output = "eDP-1";
474 rotation = 0.0;
475 type = "clock";
476 settings = {
477 background = true;
478 clock_style = "digital";
479 font_family = "BerkeleyMono Nerd Font";
480 };
481 };
482 lockscreen-widget-0000000000000002 = {
483 box_height = 0.0;
484 box_width = 0.0;
485 cx = 985.5;
486 cy = 219.5;
487 output = "eDP-1";
488 rotation = 0.0;
489 type = "weather";
490 };
491 };
492 };
493
494 notification = {
495 background_opacity = 0.97;
496 enable_daemon = true;
497 layer = "top";
498 offset_x = 20;
499 offset_y = 8;
500 scale = 1.0;
501 show_actions = true;
502 show_app_name = true;
503 };
504
505 osd = {
506 orientation = "vertical";
507 position = "top_right";
508 kinds = {
509 keyboard_layout = false;
510 lock_keys = false;
511 };
512 };
513
514 plugins.enabled = [
515 "noctalia/bongocat"
516 "noctalia/screen_recorder"
517 "noctalia/timer"
518 ];
519
520 shell = {
521 font_family = "BerkeleyMono Nerd Font";
522 launch_apps_as_systemd_services = true;
523 niri_overview_type_to_launch_enabled = true;
524 polkit_agent = true;
525 screen_corners.enabled = true;
526 };
527
528 theme = {
529 mode = "dark";
530 source = "builtin";
531 builtin = "Gruvbox";
532 templates = {
533 builtin_ids = [
534 "alacritty"
535 "btop"
536 "gtk3"
537 "gtk4"
538 "helix"
539 "niri"
540 "qt"
541 "starship"
542 ];
543 community_ids = [
544 "pi-agent"
545 "zen-browser"
546 "discord"
547 "steam"
548 "yazi"
549 ];
550 enable_builtin_templates = false;
551 user = {
552 alacritty = {
553 input_path = "${inputs.noctalia}/assets/templates/alacritty/alacritty.toml";
554 output_path = "$XDG_CONFIG_HOME/alacritty/themes/noctalia.toml";
555 };
556 helix = {
557 input_path = "${inputs.noctalia}/assets/templates/helix/helix.toml";
558 output_path = "$XDG_CONFIG_HOME/helix/themes/noctalia.toml";
559 };
560 starship = {
561 input_path = "${inputs.noctalia}/assets/templates/starship/starship.toml";
562 output_path = "$XDG_CONFIG_HOME/starship/noctalia.toml";
563 post_hook = ''
564 ${pkgs.runtimeShell} -c '
565 file="''${XDG_CONFIG_HOME:-$HOME/.config}/starship/noctalia.toml"
566 ${pkgs.gnugrep}/bin/grep -qE "^palette[[:space:]]*=" "$file" \
567 || ${pkgs.gnused}/bin/sed -i "1ipalette = \"noctalia\"" "$file"
568 '
569 '';
570 };
571 zellij = {
572 input_path = "${inputs.noctalia-template-zellij}/zellij.kdl";
573 output_path = "$XDG_CONFIG_HOME/zellij/themes/noctalia.kdl";
574 };
575 };
576 };
577 };
578
579 wallpaper = {
580 enabled = true;
581 directory = "${config.home.homeDirectory}/Pictures/Wallpapers";
582 automation = {
583 enabled = true;
584 interval_minutes = 15;
585 order = "random";
586 recursive = true;
587 };
588 default.path = "${config.home.homeDirectory}/Pictures/Wallpapers/car.png";
589 last.path = "${config.home.homeDirectory}/Pictures/Wallpapers/car.png";
590 monitors = {
591 DP-7.path = "${config.home.homeDirectory}/Pictures/Wallpapers/car.png";
592 eDP-1.path = "${config.home.homeDirectory}/Pictures/Wallpapers/monogatari.png";
593 };
594 };
595
596 widget = {
597 bluetooth.capsule_padding = 14.0;
598 media.hide_when_no_media = true;
599 network.show_label = false;
600 tray.drawer = true;
601 };
602 };
603 };
604
605 # Wallpaper downloads
606 home.activation.downloadWallpapers = config.lib.dag.entryAfter [ "writeBoundary" ] ''
607 DIR="${config.home.homeDirectory}/Pictures/Wallpapers"
608 mkdir -p "$DIR"
609 ${downloads}
610 '';
611
612 services.udiskie = {
613 enable = true;
614 tray = "never";
615 automount = true;
616 };
617
618 home.pointerCursor = {
619 name = "Adwaita";
620 package = pkgs.adwaita-icon-theme;
621 size = 16;
622 x11.enable = true;
623 gtk.enable = true;
624 };
625 };
626}