summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGregor Kleen <gkleen@yggdrasil.li>2025-01-14 11:30:32 +0100
committerGregor Kleen <gkleen@yggdrasil.li>2025-01-14 11:30:32 +0100
commit21b52a31e1eff5c8142f26e091fde083c21db55f (patch)
tree650eb693d91b353c866c42dfae49b7c5daee5ca9
parentbef130240c10b90d912aa06239402a6ad98867fe (diff)
downloadnixos-21b52a31e1eff5c8142f26e091fde083c21db55f.tar
nixos-21b52a31e1eff5c8142f26e091fde083c21db55f.tar.gz
nixos-21b52a31e1eff5c8142f26e091fde083c21db55f.tar.bz2
nixos-21b52a31e1eff5c8142f26e091fde083c21db55f.tar.xz
nixos-21b52a31e1eff5c8142f26e091fde083c21db55f.zip
niri
-rw-r--r--accounts/gkleen@sif/default.nix309
-rw-r--r--accounts/gkleen@sif/hyprland.nix425
-rw-r--r--accounts/gkleen@sif/niri/default.nix139
-rw-r--r--accounts/gkleen@sif/niri/waybar.nix288
-rw-r--r--flake.lock186
-rw-r--r--flake.nix18
-rw-r--r--hosts/sif/default.nix7
-rw-r--r--modules/niri.nix6
-rw-r--r--overlays/matrix-synapse.nix4
-rw-r--r--system-profiles/niri-flake.nix4
10 files changed, 615 insertions, 771 deletions
diff --git a/accounts/gkleen@sif/default.nix b/accounts/gkleen@sif/default.nix
index 83dcf989..bcfd1224 100644
--- a/accounts/gkleen@sif/default.nix
+++ b/accounts/gkleen@sif/default.nix
@@ -92,6 +92,7 @@ in {
92 home-manager.users.${userName} = { 92 home-manager.users.${userName} = {
93 imports = [ 93 imports = [
94 ./libvirt 94 ./libvirt
95 ./niri
95 flakeInputs.nix-index-database.hmModules.nix-index 96 flakeInputs.nix-index-database.hmModules.nix-index
96 flakeInputs.impermanence.nixosModules.home-manager.impermanence 97 flakeInputs.impermanence.nixosModules.home-manager.impermanence
97 ]; 98 ];
@@ -250,287 +251,6 @@ in {
250 "kitty_mod+m" = "detach_window ask"; 251 "kitty_mod+m" = "detach_window ask";
251 }; 252 };
252 }; 253 };
253 waybar = {
254 enable = true;
255 systemd = {
256 enable = true;
257 target = "hyprland-session.target";
258 };
259 settings = let
260 windowRewrites = {
261 "(.*) — Mozilla Firefox" = "$1";
262 "(.*) - Mozilla Thunderbird" = "$1";
263 "(.*) - mpv" = "$1";
264 };
265 iconSize = 11;
266 in [
267 {
268 layer = "top";
269 position = "top";
270 height = 14;
271 output = [ "eDP-1" "DP-2" "DP-3" ];
272 modules-left = [ "hyprland/workspaces" ];
273 modules-center = [ "hyprland/window" ];
274 modules-right = [ # "custom/worktime" "custom/worktime-today"
275 "custom/weather" "custom/keymap" "privacy" "tray" "wireplumber" "backlight" "battery" "idle_inhibitor" "clock" ];
276
277 "custom/weather" = {
278 format = "{}";
279 tooltip = true;
280 interval = 3600;
281 exec = "${lib.getExe pkgs.wttrbar} --hide-conditions --nerd --custom-indicator \"<span font=\\\"Symbols Nerd Font Mono\\\" size=\\\"120%\\\">{ICON}</span> {FeelsLikeC}°\"";
282 return-type = "json";
283 };
284 "custom/keymap" = {
285 format = "{}";
286 tooltip = true;
287 return-type = "json";
288 exec = pkgs.writers.writePython3 "keymap" {} ''
289 import os
290 import socket
291 import re
292 import subprocess
293 import json
294
295
296 def output(keymap):
297 short = keymap
298 if keymap == "English (programmer Dvorak)":
299 short = "dvp"
300 elif keymap == "English (US)":
301 short = "<span color=\"#ffffff\">us</span>"
302 print(json.dumps({'text': short, 'tooltip': keymap}, separators=(',', ':')), flush=True) # noqa: E501
303
304
305 r = subprocess.run(["hyprctl", "devices", "-j"], check=True, stdout=subprocess.PIPE, text=True) # noqa: E501
306 for keyboard in json.loads(r.stdout)['keyboards']:
307 if keyboard['name'] != "at-translated-set-2-keyboard":
308 continue
309 output(keyboard['active_keymap'])
310
311 sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
312 sock.connect(os.environ["XDG_RUNTIME_DIR"] + "/hypr/" + os.environ["HYPRLAND_INSTANCE_SIGNATURE"] + "/.socket2.sock") # noqa: E501
313 expected = re.compile(r'^activelayout>>at-translated-set-2-keyboard,(?P<keymap>.+)$') # noqa: E501
314 for line in sock.makefile(buffering=1, encoding='utf-8'):
315 if match := expected.match(line):
316 output(match.group("keymap"))
317 '';
318 on-click = "hyprctl switchxkblayout at-translated-set-2-keyboard next";
319 };
320 "custom/worktime" = {
321 interval = 60;
322 exec = getExe pkgs.worktime;
323 tooltip = false;
324 };
325 "custom/worktime-today" = {
326 interval = 60;
327 exec = "${getExe pkgs.worktime} today";
328 tooltip = false;
329 };
330 "hyprland/workspaces" = {
331 all-outputs = true;
332 };
333 "hyprland/window" = {
334 separate-outputs = true;
335 icon = true;
336 icon-size = 14;
337 rewrite = windowRewrites;
338 };
339 clock = {
340 interval = 1;
341 # timezone = "Europe/Berlin";
342 format = "W{:%V-%u %F %H:%M:%S%Ez}";
343 tooltip-format = "<tt><small>{calendar}</small></tt>";
344 calendar = {
345 mode = "year";
346 mode-mon-col = 3;
347 weeks-pos = "left";
348 on-scroll = 1;
349 format = {
350 months = "<span color='#ffead3'><b>{}</b></span>";
351 days = "{}";
352 weeks = "<span color='#99ffdd'><b>{}</b></span>";
353 weekdays = "<span color='#ffcc66'><b>{}</b></span>";
354 today = "<span color='#ff6699'><b>{}</b></span>";
355 };
356 };
357 };
358 battery = {
359 format = "<span font=\"Symbols Nerd Font Mono\" size=\"90%\">{icon}</span>";
360 icon-size = iconSize - 2;
361 states = { warning = 30; critical = 15; };
362 format-icons = ["&#xf008e;" "&#xf007a;" "&#xf007b;" "&#xf007c;" "&#xf007d;" "&#xf007e;" "&#xf007f;" "&#xf0080;" "&#xf0081;" "&#xf0082;" "&#xf0079;" ];
363 format-charging = "&#xf0084;";
364 format-plugged = "&#xf06a5;";
365 tooltip-format = "{capacity}% {timeTo}";
366 interval = 20;
367 };
368 tray = {
369 icon-size = 16;
370 # show-passive-items = true;
371 spacing = 1;
372 };
373 privacy = {
374 icon-spacing = 7;
375 icon-size = iconSize;
376 modules = [
377 { type = "screenshare"; }
378 { type = "audio-in"; }
379 ];
380 };
381 idle_inhibitor = {
382 format = "<span font=\"Symbols Nerd Font Mono\" size=\"90%\">{icon}</span>";
383 icon-size = iconSize;
384 format-icons = { activated = "&#xf0208;"; deactivated = "&#xf0209;"; };
385 timeout = 120;
386 };
387 backlight = {
388 format = "<span font=\"Symbols Nerd Font Mono\" size=\"90%\">{icon}</span>";
389 icon-size = iconSize;
390 tooltip-format = "{percent}%";
391 format-icons = ["&#xf00da;" "&#xf00db;" "&#xf00dc;" "&#xf00dd;" "&#xf00de;" "&#xf00df;" "&#xf00e0;"];
392 on-scroll-up = "lightctl -d -e4 -n1 up";
393 on-scroll-down = "lightctl -d -e4 -n1 down";
394 };
395 wireplumber = {
396 format = "<span font=\"Symbols Nerd Font Mono\" size=\"90%\">{icon}</span>";
397 icon-size = iconSize;
398 tooltip-format = "{volume}% {node_name}";
399 format-icons = ["&#xf057f;" "&#xf0580;" "&#xf057e;"];
400 format-muted = "<span font=\"Symbols Nerd Font Mono\" size=\"90%\">&#xf075f;</span>";
401 # ignored-sinks = ["Easy Effects Sink"];
402 on-scroll-up = "volumectl -d -u up";
403 on-scroll-down = "volumectl -d -u down";
404 on-click = "volumectl -d toggle-mute";
405 };
406 }
407 {
408 layer = "top";
409 position = "top";
410 height = 14;
411 output = [ "!eDP-1" "!DP-2" "!DP-3" ];
412 modules-left = [ "hyprland/workspaces" ];
413 modules-center = [ "hyprland/window" ];
414 modules-right = [ "clock" ];
415
416 "hyprland/workspaces" = {
417 all-outputs = false;
418 };
419 "hyprland/window" = {
420 separate-outputs = true;
421 icon = true;
422 icon-size = 14;
423 rewrite = windowRewrites;
424 };
425 clock = {
426 interval = 1;
427 # timezone = "Europe/Berlin";
428 format = "{:%H:%M}";
429 tooltip-format = "W{:%V-%u %F %H:%M:%S%Ez}";
430 };
431 }
432 ];
433 style = ''
434 @define-color white #ffffff;
435 @define-color grey #555555;
436 @define-color blue #1a8fff;
437 @define-color green #23fd00;
438 @define-color orange #f28a21;
439 @define-color red #f2201f;
440
441 * {
442 border: none;
443 font-family: "Fira Sans Nerd Font";
444 font-size: 10pt;
445 min-height: 0;
446 }
447
448 window#waybar {
449 background-color: rgba(0, 0, 0, 0.66);
450 color: @white;
451 }
452
453 .modules-left {
454 margin-left: 9px;
455 }
456 .modules-right {
457 margin-right: 9px;
458 }
459
460 .module {
461 margin: 0 5px;
462 }
463
464 #workspaces button {
465 color: @grey;
466 }
467 #workspaces button.hosting-monitor {
468 color: @white;
469 }
470 #workspaces button.visible {
471 color: @blue;
472 }
473 #workspaces button.active {
474 color: @green;
475 }
476 #workspaces button.urgent {
477 color: @red;
478 }
479
480 #custom-weather, #custom-keymap, #custom-worktime, #custom-worktime-today {
481 color: @grey;
482 margin: 0 5px;
483 }
484 #custom-weather, #custom-worktime-today {
485 margin-right: 3px;
486 }
487 #custom-keymap, #custom-weather {
488 margin-left: 3px;
489 }
490
491 #tray {
492 margin: 0;
493 }
494 #battery, #idle_inhibitor, #backlight, #wireplumber {
495 color: @grey;
496 margin: 0 5px 0 2px;
497 }
498 #idle_inhibitor {
499 margin-right: 2px;
500 margin-left: 3px;
501 }
502 #battery {
503 margin-right: 3px;
504 }
505 #battery.discharging {
506 color: @white;
507 }
508 #battery.warning {
509 color: @orange;
510 }
511 #battery.critical {
512 color: @red;
513 }
514 #battery.charging {
515 color: @white;
516 }
517 #idle_inhibitor.activated {
518 color: @white;
519 }
520
521 #idle_inhibitor {
522 padding-top: 1px;
523 }
524
525 #privacy {
526 color: @red;
527 margin: -1px 2px 0px 5px;
528 }
529 #clock {
530 /* margin-right: 5px; */
531 }
532 '';
533 };
534 wpaperd = { 254 wpaperd = {
535 enable = true; 255 enable = true;
536 settings.default = { 256 settings.default = {
@@ -543,7 +263,7 @@ in {
543 enable = true; 263 enable = true;
544 settings = { 264 settings = {
545 main = { 265 main = {
546 terminal = lib.getExe pkgs.kitty; 266 terminal = lib.getExe cfg.programs.kitty.package;
547 layer = "overlay"; 267 layer = "overlay";
548 icon-theme = "Paper"; 268 icon-theme = "Paper";
549 font = "Fira Sans"; 269 font = "Fira Sans";
@@ -639,13 +359,13 @@ in {
639 enable = true; 359 enable = true;
640 events = [ 360 events = [
641 { event = "before-sleep"; command = lockCommand; } 361 { event = "before-sleep"; command = lockCommand; }
642 { event = "after-resume"; command = "${cfg.wayland.windowManager.hyprland.package}/bin/hyprctl dispatch dpms on"; } 362 # { event = "after-resume"; command = "${cfg.wayland.windowManager.hyprland.package}/bin/hyprctl dispatch dpms on"; }
643 { event = "lock"; command = lockCommand; } 363 { event = "lock"; command = lockCommand; }
644 ]; 364 ];
645 timeouts = [ 365 timeouts = [
646 { timeout = 300; 366 # { timeout = 300;
647 command = "${cfg.wayland.windowManager.hyprland.package}/bin/hyprctl dispatch dpms off"; 367 # command = "${cfg.wayland.windowManager.hyprland.package}/bin/hyprctl dispatch dpms off";
648 } 368 # }
649 { timeout = 330; command = lockCommand; } 369 { timeout = 330; command = lockCommand; }
650 ]; 370 ];
651 extraArgs = [ 371 extraArgs = [
@@ -927,23 +647,6 @@ in {
927 color-scheme = "prefer-dark"; 647 color-scheme = "prefer-dark";
928 }; 648 };
929 }; 649 };
930
931 wayland.windowManager.hyprland = {
932 enable = true;
933 settings = import ./hyprland.nix inputs;
934 };
935
936 xdg.portal = {
937 enable = true;
938 xdgOpenUsePortal = true;
939 config = {
940 common.default = [ "gtk" ];
941 hyprland.default = [ "gtk" "kde" "hyprland" ];
942 };
943 extraPortals = with pkgs; [
944 xdg-desktop-portal-kde xdg-desktop-portal-gtk xdg-desktop-portal-wlr xdg-desktop-portal-hyprland
945 ];
946 };
947 }; 650 };
948 }; 651 };
949} 652}
diff --git a/accounts/gkleen@sif/hyprland.nix b/accounts/gkleen@sif/hyprland.nix
deleted file mode 100644
index 90ae689a..00000000
--- a/accounts/gkleen@sif/hyprland.nix
+++ /dev/null
@@ -1,425 +0,0 @@
1{ pkgs, lib, config, userName, ... }:
2let
3 cfg = config.home-manager.users.${userName};
4in {
5 monitor = [
6 ",preferred,auto,auto,bitdepth,8"
7 "eDP-1,3840x2160@60,auto,1.5,bitdepth,8"
8 ];
9
10 "$terminal" = "kitty";
11 "$menu" = "fuzzel";
12
13 env = [
14 "NIXOS_OZONE_WL,1"
15 "QT_QPA_PLATFORM,wayland"
16 "QT_WAYLAND_DISABLE_WINDOWDECORATION,1"
17 "GDK_BACKEND,wayland"
18 "GDK_SCALE,0.66"
19 "QT_AUTO_SCREEN_SCALE_FACTOR,1"
20 "SDL_VIDEODRIVER,wayland"
21 # "AQ_DRM_DEVICES,/dev/dri/by-path/pci-0000:01:00.0-card"
22 "__NV_PRIME_RENDER_OFFLOAD,1"
23 "__NV_PRIME_RENDER_OFFLOAD_PROVIDER,NVIDIA-G0"
24 "__GLX_VENDOR_LIBRARY_NAME,nvidia"
25 "__VK_LAYER_NV_optimus,NVIDIA_only"
26 ];
27
28 xwayland.force_zero_scaling = true;
29
30 general = {
31 gaps_in = 3;
32 gaps_out = 9;
33 "col.active_border" = "rgba(33ccffee) rgba(00ff95ee) 45deg";
34 "col.inactive_border" = "rgba(595959aa)";
35
36 resize_on_border = false;
37
38 allow_tearing = false;
39
40 layout = "dwindle";
41 };
42
43 decoration = {
44 rounding = 5;
45 dim_special = 0.0;
46 };
47
48 animations = {
49 enabled = true;
50 bezier = "myBezier, 0.05, 0.9, 0.1, 1.05";
51 animation = [
52 "windows, 1, 1, default, popin 80%"
53 "windowsMove, 0"
54 # "windows, 1, 7, myBezier"
55 # "windowsOut, 1, 7, myBezier, popin 80%"
56 "border, 1, 10, default"
57 "borderangle, 1, 8, default"
58 "fade, 1, 1, default"
59 "workspaces, 1, 1, default, fade"
60 # "workspaces, 1, 6, default"
61 ];
62 };
63
64 dwindle = {
65 pseudotile = false;
66 preserve_split = true;
67 };
68
69 master = {
70 new_status = "master";
71 };
72
73 misc = {
74 disable_hyprland_logo = true;
75 disable_splash_rendering = true;
76 # focus_on_activate = true;
77 mouse_move_enables_dpms = true;
78 key_press_enables_dpms = true;
79 new_window_takes_over_fullscreen = 1;
80 exit_window_retains_fullscreen = true;
81 };
82
83 cursor = {
84 use_cpu_buffer = true;
85 hide_on_key_press = true;
86 # no_hardware_cursors = 0;
87 };
88
89 input = {
90 kb_layout = "us,us";
91 kb_variant = "dvp,";
92 kb_model = "";
93 kb_options = "compose:caps,grp:win_space_toggle";
94 kb_rules = "";
95
96 follow_mouse = 1;
97
98 sensitivity = 0;
99
100 touchpad = {
101 natural_scroll = false;
102 };
103 };
104
105 device = [
106 { name = "synaptics-tm3512-010";
107 sensitivity = 0.4;
108 }
109 { name = "tpps/2-elan-trackpoint";
110 sensitivity = 0.2;
111 }
112 { name = "logitech-ergo-m575";
113 sensitivity = 1.333;
114 }
115 ];
116
117 gestures = {
118 workspace_swipe = false;
119 };
120
121 dwindle = {
122 # no_gaps_when_only = 1;
123 };
124
125 "$mainMod" = "SUPER";
126
127 bind = [
128 "$mainMod, return, exec, $terminal"
129 "$mainMod, Q, killactive"
130 "$mainMod SHIFT, Q, exec, hyprctl kill"
131 "$mainMod, V, togglefloating"
132 "$mainMod, D, exec, $menu"
133 "$mainMod SHIFT, D, exec, $menu --list-executables-in-path"
134 # "$mainMod, J, togglesplit,"
135
136 "$mainMod SHIFT, L, exec, loginctl lock-session"
137 "$mainMod SHIFT, E, exit"
138
139 "$mainMod, left, movefocus, l"
140 "$mainMod, right, movefocus, r"
141 "$mainMod, up, movefocus, u"
142 "$mainMod, down, movefocus, d"
143 "$mainMod SHIFT, left, swapwindow, l"
144 "$mainMod SHIFT, right, swapwindow, r"
145 "$mainMod SHIFT, up, swapwindow, u"
146 "$mainMod SHIFT, down, swapwindow, d"
147
148 "$mainMod, N, cyclenext, tiled"
149 "$mainMod, T, cyclenext, prev tiled"
150 "$mainMod SHIFT, N, swapnext"
151 "$mainMod SHIFT, T, swapnext, prev"
152
153 "$mainMod, G, focusmonitor, 0"
154 "$mainMod, C, focusmonitor, 1"
155 "$mainMod, R, focusmonitor, 2"
156 "$mainMod, L, focusmonitor, 3"
157
158 "$mainMod CTRL, G, movecurrentworkspacetomonitor, 0"
159 "$mainMod CTRL, C, movecurrentworkspacetomonitor, 1"
160 "$mainMod CTRL, R, movecurrentworkspacetomonitor, 2"
161 "$mainMod CTRL, L, movecurrentworkspacetomonitor, 3"
162
163 "$mainMod, F, fullscreen, 1"
164 "$mainMod SHIFT, F, fullscreen, 0"
165 "$mainMod CTRL SHIFT, F, fullscreenstate, 1, 2"
166
167 "$mainMod, code:14, workspace, 1"
168 "$mainMod, code:17, workspace, 2"
169 "$mainMod, code:13, workspace, 3"
170 "$mainMod, code:18, workspace, 4"
171 "$mainMod, code:12, workspace, 5"
172 "$mainMod, code:19, workspace, 6"
173 "$mainMod, code:11, workspace, 7"
174 "$mainMod, code:20, workspace, 8"
175 "$mainMod, code:15, workspace, 9"
176 "$mainMod, code:16, workspace, 10"
177
178 "$mainMod SHIFT, code:14, movetoworkspacesilent, 1"
179 "$mainMod SHIFT, code:17, movetoworkspacesilent, 2"
180 "$mainMod SHIFT, code:13, movetoworkspacesilent, 3"
181 "$mainMod SHIFT, code:18, movetoworkspacesilent, 4"
182 "$mainMod SHIFT, code:12, movetoworkspacesilent, 5"
183 "$mainMod SHIFT, code:19, movetoworkspacesilent, 6"
184 "$mainMod SHIFT, code:11, movetoworkspacesilent, 7"
185 "$mainMod SHIFT, code:20, movetoworkspacesilent, 8"
186 "$mainMod SHIFT, code:15, movetoworkspacesilent, 9"
187 "$mainMod SHIFT, code:16, movetoworkspacesilent, 10"
188
189 "$mainMod, semicolon, exec, dunstctl close"
190 "$mainMod SHIFT, semicolon, exec, dunstctl close-all"
191 "$mainMod, period, exec, dunstctl context"
192 "$mainMod, comma, exec, dunstctl history-pop"
193
194 "$mainMod ALT, E, exec, emacsclient -c"
195 "$mainMod ALT, Y, exec, ${pkgs.writeShellScript "yt-dlp" ''
196 export PATH="${lib.makeBinPath (with pkgs; [ wl-clipboard-rs socat ])}:$PATH"
197 socat STDIO UNIX-CONNECT:"$XDG_RUNTIME_DIR"/yt-dlp.sock <<<$'{ "urls": ["'"$(wl-paste)"$'"] }'
198 ''}"
199 "$mainMod ALT, L, exec, ${pkgs.writeShellScript "mpv" ''
200 export PATH="${lib.makeBinPath (with pkgs; [ wl-clipboard-rs ])}:$PATH"
201 exec mpv "$(wl-paste)"
202 ''}"
203
204 ", Print, exec, ${pkgs.writeShellScript "screenshot" ''
205 export PATH="${lib.makeBinPath (with pkgs; [ grim slurp wl-clipboard-rs coreutils ])}:$PATH"
206
207 outFile="$HOME/screenshots/$(date +"%Y-%m-%dT%H:%M:%S").png"
208 grim -g "$(slurp -b 00000080 -c FFFFFFFF -s 00000000 -w 1)" "$outFile"
209 wl-copy --type image/png <"$outFile"
210 ''}"
211 "SHIFT, Print, exec, ${pkgs.writeShellScript "screenshot" ''
212 export PATH="${lib.makeBinPath (with pkgs; [ grim jq wl-clipboard-rs coreutils ])}:$PATH"
213
214 outFile="$HOME/screenshots/$(date +"%Y-%m-%dT%H:%M:%S").png"
215 grim -o "$(hyprctl monitors -j | jq -r '.[] | select(.focused) | .name')" "$outFile"
216 wl-copy --type image/png <"$outFile"
217 ''}"
218 "CTRL SHIFT, Print, exec, ${pkgs.runCommand "picker" {
219 buildInputs = [ pkgs.makeWrapper ];
220 } ''
221 makeWrapper ${lib.getExe pkgs.hyprpicker} $out \
222 --prefix PATH : ${lib.makeBinPath [pkgs.wl-clipboard-rs]}
223 ''} -a"
224 "$mainMod, M, exec, ${pkgs.writeShellScript "qalc-fuzzel" ''
225 export PATH="${lib.makeBinPath (with pkgs; [ wl-clipboard-rs libqalculate cfg.programs.fuzzel.package coreutils findutils libnotify gnugrep ])}:$PATH"
226
227 RESULTS_DIR="$HOME/.cache/qalc-fuzzel"
228 prev() {
229 FOUND=false
230 while IFS= read -r line; do
231 [[ -n "$line" ]] || continue
232 FOUND=true
233 echo $line
234 done < <(export LC_ALL=C.UTF-8; echo; find "$RESULTS_DIR" -type f -printf $'%T@ %p\n' | sort -n | cut -d' ' -f2- | xargs -r cat)
235 $FOUND || echo
236 }
237 FUZZEL_RES=$(prev | fuzzel --dmenu --prompt "qalc> ") || exit $?
238 if [[ "$FUZZEL_RES" =~ .*\ =\ .* ]]; then
239 QALC_RES="$FUZZEL_RES"
240 QALC_RET=0
241 else
242 QALC_RES=$(qalc "$FUZZEL_RES" 2>&1)
243 QALC_RET=$?
244 fi
245 [[ -n "$QALC_RES" ]] || exit 1
246 EXISTING=false
247 fgrep -xrl "$QALC_RES" "$RESULTS_DIR" | xargs -r touch
248 [[ ''${PIPESTATUS[0]} -eq 0 ]] && EXISTING=true
249 if [[ $QALC_RET -eq 0 ]] && ! $EXISTING; then
250 RES_FILE="$RESULTS_DIR"/$(date -uIs).$(tr -Cd 'a-zA-Z0-9' </dev/random | head -c 10)
251 cat >"$RES_FILE" <<<"$QALC_RES"
252 fi
253 [[ "$QALC_RES" =~ .*\ =\ (.*) ]] && QALC_RES="''${BASH_REMATCH[1]}"
254 [[ $QALC_RET -eq 0 ]] && wl-copy "$QALC_RES"
255 notify-send "$QALC_RES"
256 ''}"
257 "$mainMod, E, exec, ${pkgs.writeShellScript "emoji-fuzzel" ''
258 export PATH="${lib.makeBinPath (with pkgs; [ cfg.programs.fuzzel.package wtype wl-clipboard-rs ])}:$PATH"
259
260 FUZZEL_RES=$(fuzzel --dmenu --prompt "emoji> " <$HOME/.local/share/emoji-data/list.txt) || exit $?
261 [[ -n "$FUZZEL_RES" ]] || exit 1
262 wl-copy "$(cut -d ':' -f 1 <<<"$FUZZEL_RES" | tr -d '\n')" && wtype -k XF86Paste
263 ''}"
264 "$mainMod, B, exec, ${pkgs.writeShellScript "bring" ''
265 export PATH="${lib.makeBinPath (with pkgs; [ cfg.programs.fuzzel.package gawk gojq cfg.wayland.windowManager.hyprland.package ])}:$PATH"
266
267 state="$(hyprctl -j clients)"
268 active_window="$(hyprctl -j activewindow)"
269 active_workspace="$(hyprctl -j activeworkspace | gojq -r '.id')"
270
271 current_addr="$(echo "$active_window" | gojq -r '.address')"
272
273 window="$(echo "$state" |
274 gojq -r '.[] | select(.workspace.id == '"$active_workspace"') | select(.monitor != -1 ) | "\(.title)\t\(.address)"' |
275 fuzzel --log-level=warning --dmenu)"
276
277 addr="$(echo "$window" | awk -F $'\t' '{print $2}')"
278
279 if [[ "$addr" = "$current_addr" ]]; then
280 exit 0
281 fi
282
283 fullscreen_on_same_ws="$(echo "$state" | gojq -r '.[] | select(.fullscreen == true) | select(.workspace.id == '"$active_workspace"') | .address')"
284
285 if [[ "$window" != "" ]]; then
286 if [[ "$fullscreen_on_same_ws" == "" ]]; then
287 hyprctl dispatch focuswindow address:"''${addr}"
288 else
289 # If we want to focus app_A and app_B is fullscreen on the same workspace,
290 # app_A will get focus, but app_B will remain on top.
291 # This monstrosity is to make sure app_A will end up on top instead.
292 # XXX: doesn't handle fullscreen 0, but I don't care.
293 hyprctl --batch "dispatch focuswindow address:''${fullscreen_on_same_ws}; dispatch fullscreen 1; dispatch focuswindow address:''${addr}; dispatch fullscreen 1"
294 fi
295 fi
296 ''}"
297 "$mainMod SHIFT, B, exec, ${pkgs.writeShellScript "bring" ''
298 export PATH="${lib.makeBinPath (with pkgs; [ cfg.programs.fuzzel.package gawk gojq cfg.wayland.windowManager.hyprland.package ])}:$PATH"
299
300 state="$(hyprctl -j clients)"
301 active_window="$(hyprctl -j activewindow)"
302
303 current_addr="$(echo "$active_window" | gojq -r '.address')"
304
305 window="$(echo "$state" |
306 gojq -r '.[] | select(.monitor != -1 ) | "\(.title)\t\(.workspace.name)\t\(.address)"' |
307 fuzzel --log-level=warning --dmenu)"
308
309 addr="$(echo "$window" | awk -F $'\t' '{print $3}')"
310 ws="$(echo "$window" | awk -F $'\t' '{print $2}')"
311
312 if [[ "$addr" = "$current_addr" ]]; then
313 exit 0
314 fi
315
316 fullscreen_on_same_ws="$(echo "$state" | gojq -r ".[] | select(.fullscreen == true) | select(.workspace.name == \"$ws\") | .address")"
317
318 if [[ "$window" != "" ]]; then
319 if [[ "$fullscreen_on_same_ws" == "" ]]; then
320 hyprctl dispatch focuswindow address:"''${addr}"
321 else
322 # If we want to focus app_A and app_B is fullscreen on the same workspace,
323 # app_A will get focus, but app_B will remain on top.
324 # This monstrosity is to make sure app_A will end up on top instead.
325 # XXX: doesn't handle fullscreen 0, but I don't care.
326 hyprctl --batch "dispatch focuswindow address:''${fullscreen_on_same_ws}; dispatch fullscreen 1; dispatch focuswindow address:''${addr}; dispatch fullscreen 1"
327 fi
328 fi
329 ''}"
330
331 "$mainMod CTRL, return, togglespecialworkspace, term"
332 "$mainMod CTRL, e, togglespecialworkspace, edit"
333 "$mainMod CTRL, a, togglespecialworkspace, pwvucontrol"
334 "$mainMod CTRL, o, togglespecialworkspace, easyeffects"
335 "$mainMod CTRL, b, togglespecialworkspace, blueman"
336 "$mainMod CTRL, p, togglespecialworkspace, keepass"
337 ];
338 bindm = [
339 "$mainMod, mouse:272, movewindow"
340 "$mainMod, mouse:273, resizewindow"
341 ];
342 bindel = [
343 ", XF86MonBrightnessUp, exec, lightctl -d -e4 -n1 up"
344 ", XF86MonBrightnessDown, exec, lightctl -d -e4 -n1 down"
345 ", XF86AudioRaiseVolume, exec, volumectl -d -u up"
346 ", XF86AudioLowerVolume, exec, volumectl -d -u down"
347 ];
348 bindl = [
349 ", XF86AudioMute, exec, volumectl -d toggle-mute"
350 ", XF86AudioMicMute, exec, volumectl -d -m toggle-mute"
351 "$mainMod SHIFT, S, exec, systemctl suspend"
352
353 ", switch:off:Lid Switch,exec,hyprctl dispatch dpms on eDP-1"
354 ", switch:on:Lid Switch,exec,hyprctl dispatch dpms off eDP-1"
355
356 ", switch:off:Lid Switch,exec,${pkgs.writeShellScript "clamshell-off" ''
357 export PATH="${lib.makeBinPath (with pkgs; [ jq ])}:$PATH"
358 [[ $(hyprctl monitors -j | jq '.[] | select(.name == "eDP-1") | .disabled') = "true" ]] || exit 0
359
360 hyprctl keyword monitor "eDP-1,3840x2160@60,auto,1.5"
361 ''}"
362 ", switch:on:Lid Switch,exec,${pkgs.writeShellScript "clamshell-on" ''
363 export PATH="${lib.makeBinPath (with pkgs; [ jq ])}:$PATH"
364
365 [[ $(hyprctl monitors -j | jq 'reduce (.[] | select(.disabled == false)) as $_ (0; .+1)') -gt 1 ]] || exit 0
366
367 hyprctl keyword monitor "eDP-1,disable"
368 ''}"
369 ];
370
371 windowrulev2 = [
372 "suppressevent maximize fullscreen, class:.*"
373
374 # "maximize, class:^(Element|thunderbird)$"
375 "workspace special:pwvucontrol, class:^com\.saivert\.pwvucontrol$"
376 "workspace special:easyeffects, class:^com\.github\.wwmm\.easyeffects$"
377 "workspace special:blueman, class:^\.blueman-manager-wrapped$"
378 "workspace special:keepass silent, class:^org\.keepassxc\.KeePassXC$, title:^(?!Unlock Database.*)(?!.*(Access Request|Passkey credentials)).*$"
379 # "group set always lock invade, class:^Element$"
380 "workspace 2, class:^firefox$"
381 "workspace 4, class:^evince$"
382 "workspace 4, class:^imv$"
383 "workspace 4, class:^org\.pwmt\.zathura$"
384 "workspace 10, class:^mpv$"
385 "workspace 1, class:^Element$"
386 "workspace 1, class:^thunderbird$"
387 "workspace 5, class:^virt-manager$"
388 "workspace 5, class:^qemu$"
389 "float, class:^org\.keepassxc\.KeePassXC$, title:^.*Access Request$"
390 "center, class:^org\.keepassxc\.KeePassXC$, title:^.*Access Request$"
391 "float, class:^org\.keepassxc\.KeePassXC$, title:^.*Passkey credentials$"
392 "center, class:^org\.keepassxc\.KeePassXC$, title:^.*Passkey credentials$"
393 "float, class:^org\.keepassxc\.KeePassXC$, title:^Unlock Database.*$"
394 "center, class:^org\.keepassxc\.KeePassXC$, title:^Unlock Database.*$"
395 "float, class:^xdg-desktop-portal-gtk$"
396 "center, class:^xdg-desktop-portal-gtk$"
397
398 "bordercolor rgba(ffaa33ee) rgba(bfff00ee) 45deg, fullscreen:1"
399 "bordercolor rgba(3366ffee) rgba(6a00ffee) 45deg, xwayland:1"
400 "bordercolor rgba(6633ffee) rgba(ea00ffee) 45deg, xwayland:1, fullscreen:1"
401 ];
402
403 workspace = [
404 "s[true], gapsout:100"
405
406 "special:term, on-created-empty:kitty"
407 "special:edit, on-created-empty:emacsclient -c"
408 "special:pwvucontrol, on-created-empty:pwvucontrol"
409 "special:easyeffects, on-created-empty:easyeffects"
410 "special:blueman, on-created-empty:blueman-manager"
411 "special:keepass, on-created-empty:keepassxc"
412
413 "1, defaultName:comm"
414 "2, defaultName:web"
415 "3, defaultName:work"
416 "4, defaultName:read"
417 ];
418
419 layerrule = [
420 "blur, waybar"
421 "blur, launcher"
422 "noanim, notifications"
423 "blur, notifications"
424 ];
425}
diff --git a/accounts/gkleen@sif/niri/default.nix b/accounts/gkleen@sif/niri/default.nix
new file mode 100644
index 00000000..6a8d10a0
--- /dev/null
+++ b/accounts/gkleen@sif/niri/default.nix
@@ -0,0 +1,139 @@
1{ config, pkgs, lib, ... }:
2let
3 niri = config.programs.niri.package;
4 terminal = lib.getExe config.programs.kitty.package;
5 lightctl = lib.getExe' config.services.avizo.package "lightctl";
6 volumectl = lib.getExe' config.services.avizo.package "volumectl";
7 dunstctl = lib.getExe' config.services.dunst.package "dunstctl";
8in {
9 imports = [
10 ./waybar.nix
11 ];
12
13 config = {
14 systemd.user.services.xwayland-satellite = {
15 Unit = {
16 BindsTo = [ "graphical-session.target" ];
17 PartOf = [ "graphical-session.target" ];
18 After = [ "graphical-session.target" ];
19 Requisite = [ "graphical-session.target" ];
20 };
21 Service = {
22 Type = "notify";
23 NotifyAccess = "all";
24 ExecStart = lib.getExe pkgs.xwayland-satellite-unstable;
25 StandardOutput = "journal";
26 };
27 Install = {
28 WantedBy = [ "graphical-session.target" ];
29 };
30 };
31
32 programs.niri.settings = {
33 prefer-no-csd = true;
34 screenshot-path = "${config.home.homeDirectory}/screenshots";
35
36 input = {
37 keyboard.xkb = {
38 layout = "us,";
39 variant = "dvp,";
40 options = "compose:caps,grp:win_space_toggle";
41 };
42 };
43
44 environment = {
45 NIXOS_OZONE_WL = "1";
46 QT_QPA_PLATFORM = "wayland";
47 GDK_BACKEND = "wayland";
48 SDL_VIDEODRIVER = "wayland";
49 };
50
51 cursor.hide-when-typing = true;
52
53 binds = with config.lib.niri.actions; {
54 "Mod+Return".action = spawn terminal;
55 "Mod+Q".action = close-window;
56 "Mod+D".action = spawn (lib.getExe config.programs.fuzzel.package);
57 "Mod+Shift+D".action = spawn (lib.getExe config.programs.fuzzel.package) "--list-executables-in-path";
58
59 "Mod+H".action = focus-column-left;
60 "Mod+T".action = focus-window-down;
61 "Mod+N".action = focus-window-up;
62 "Mod+S".action = focus-column-right;
63
64 "Mod+Shift+H".action = move-column-left;
65 "Mod+Shift+T".action = move-window-down;
66 "Mod+Shift+N".action = move-window-up;
67 "Mod+Shift+S".action = move-column-right;
68
69 "Mod+Control+H".action = focus-monitor-left;
70 "Mod+Control+T".action = focus-monitor-down;
71 "Mod+Control+N".action = focus-monitor-up;
72 "Mod+Control+S".action = focus-monitor-right;
73
74 "Mod+Shift+Control+H".action = move-workspace-to-monitor-left;
75 "Mod+Shift+Control+T".action = move-workspace-to-monitor-down;
76 "Mod+Shift+Control+N".action = move-workspace-to-monitor-up;
77 "Mod+Shift+Control+S".action = move-workspace-to-monitor-right;
78
79 "Mod+G".action = focus-workspace-down;
80 "Mod+C".action = focus-workspace-up;
81
82 "Mod+Control+G".action = move-column-to-workspace-down;
83 "Mod+Control+C".action = move-column-to-workspace-up;
84
85 "Mod+Shift+G".action = move-workspace-down;
86 "Mod+Shift+C".action = move-workspace-up;
87
88 "Mod+M".action = consume-window-into-column;
89 "Mod+W".action = expel-window-from-column;
90
91 "Mod+F".action = maximize-column;
92 "Mod+Shift+F".action = fullscreen-window;
93
94 "Mod+Space".action = switch-focus-between-floating-and-tiling;
95 "Mod+Shift+Space".action = toggle-window-floating;
96
97 "Mod+Left".action = set-column-width "-10%";
98 "Mod+Down".action = set-window-height "-10%";
99 "Mod+Up".action = set-window-height "+10%";
100 "Mod+Right".action = set-column-width "+10%";
101
102 "Mod+Shift+Z" = {
103 action = spawn (lib.getExe niri) "msg" "action" "power-off-monitors";
104 allow-when-locked = true;
105 };
106
107 "XF86MonBrightnessUp" = {
108 action = spawn lightctl "-d" "-e4" "-n1" "up";
109 allow-when-locked = true;
110 };
111 "XF86MonBrightnessDown" = {
112 action = spawn lightctl "-d" "-e4" "-n1" "down";
113 allow-when-locked = true;
114 };
115 "XF86AudioRaiseVolume" = {
116 action = spawn volumectl "-d" "-u" "up";
117 allow-when-locked = true;
118 };
119 "XF86AudioLowerVolume" = {
120 action = spawn volumectl "-d" "-u" "down";
121 allow-when-locked = true;
122 };
123 "XF86AudioMute" = {
124 action = spawn volumectl "-d" "toggle-mute";
125 allow-when-locked = true;
126 };
127 "XF86AudioMicMute" = {
128 action = spawn volumectl "-d" "-m" "toggle-mute";
129 allow-when-locked = true;
130 };
131
132 "Mod+Semicolon".action = spawn dunstctl "close";
133 "Mod+Shift+Semicolon".action = spawn dunstctl "close-all";
134 "Mod+Period".action = spawn dunstctl "context";
135 "Mod+Comma".action = spawn dunstctl "history-pop";
136 };
137 };
138 };
139}
diff --git a/accounts/gkleen@sif/niri/waybar.nix b/accounts/gkleen@sif/niri/waybar.nix
new file mode 100644
index 00000000..1a25b581
--- /dev/null
+++ b/accounts/gkleen@sif/niri/waybar.nix
@@ -0,0 +1,288 @@
1{ lib, pkgs, ... }:
2{
3 config = {
4 programs.waybar = {
5 enable = true;
6 systemd = {
7 enable = true;
8 target = "graphical-session.target";
9 };
10 settings = let
11 windowRewrites = {
12 "(.*) — Mozilla Firefox" = "$1";
13 "(.*) - Mozilla Thunderbird" = "$1";
14 "(.*) - mpv" = "$1";
15 };
16 iconSize = 11;
17 in [
18 {
19 layer = "top";
20 position = "top";
21 height = 14;
22 output = [ "eDP-1" "DP-2" "DP-3" ];
23 modules-left = [ "niri/workspaces" ];
24 modules-center = [ "niri/window" ];
25 modules-right = [ # "custom/worktime" "custom/worktime-today"
26 "custom/weather"
27 # "custom/keymap"
28 "privacy" "tray" "wireplumber" "backlight" "battery" "idle_inhibitor" "clock" ];
29
30 "custom/weather" = {
31 format = "{}";
32 tooltip = true;
33 interval = 3600;
34 exec = "${lib.getExe pkgs.wttrbar} --hide-conditions --nerd --custom-indicator \"<span font=\\\"Symbols Nerd Font Mono\\\" size=\\\"120%\\\">{ICON}</span> {FeelsLikeC}°\"";
35 return-type = "json";
36 };
37 "custom/keymap" = {
38 format = "{}";
39 tooltip = true;
40 return-type = "json";
41 exec = pkgs.writers.writePython3 "keymap" {} ''
42 import os
43 import socket
44 import re
45 import subprocess
46 import json
47
48
49 def output(keymap):
50 short = keymap
51 if keymap == "English (programmer Dvorak)":
52 short = "dvp"
53 elif keymap == "English (US)":
54 short = "<span color=\"#ffffff\">us</span>"
55 print(json.dumps({'text': short, 'tooltip': keymap}, separators=(',', ':')), flush=True) # noqa: E501
56
57
58 r = subprocess.run(["hyprctl", "devices", "-j"], check=True, stdout=subprocess.PIPE, text=True) # noqa: E501
59 for keyboard in json.loads(r.stdout)['keyboards']:
60 if keyboard['name'] != "at-translated-set-2-keyboard":
61 continue
62 output(keyboard['active_keymap'])
63
64 sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
65 sock.connect(os.environ["XDG_RUNTIME_DIR"] + "/hypr/" + os.environ["HYPRLAND_INSTANCE_SIGNATURE"] + "/.socket2.sock") # noqa: E501
66 expected = re.compile(r'^activelayout>>at-translated-set-2-keyboard,(?P<keymap>.+)$') # noqa: E501
67 for line in sock.makefile(buffering=1, encoding='utf-8'):
68 if match := expected.match(line):
69 output(match.group("keymap"))
70 '';
71 on-click = "hyprctl switchxkblayout at-translated-set-2-keyboard next";
72 };
73 "custom/worktime" = {
74 interval = 60;
75 exec = lib.getExe pkgs.worktime;
76 tooltip = false;
77 };
78 "custom/worktime-today" = {
79 interval = 60;
80 exec = "${lib.getExe pkgs.worktime} today";
81 tooltip = false;
82 };
83 "niri/workspaces" = {
84 all-outputs = true;
85 };
86 "niri/window" = {
87 separate-outputs = true;
88 icon = true;
89 icon-size = 14;
90 rewrite = windowRewrites;
91 };
92 clock = {
93 interval = 1;
94 # timezone = "Europe/Berlin";
95 format = "W{:%V-%u %F %H:%M:%S%Ez}";
96 tooltip-format = "<tt><small>{calendar}</small></tt>";
97 calendar = {
98 mode = "year";
99 mode-mon-col = 3;
100 weeks-pos = "left";
101 on-scroll = 1;
102 format = {
103 months = "<span color='#ffead3'><b>{}</b></span>";
104 days = "{}";
105 weeks = "<span color='#99ffdd'><b>{}</b></span>";
106 weekdays = "<span color='#ffcc66'><b>{}</b></span>";
107 today = "<span color='#ff6699'><b>{}</b></span>";
108 };
109 };
110 };
111 battery = {
112 format = "<span font=\"Symbols Nerd Font Mono\" size=\"90%\">{icon}</span>";
113 icon-size = iconSize - 2;
114 states = { warning = 30; critical = 15; };
115 format-icons = ["&#xf008e;" "&#xf007a;" "&#xf007b;" "&#xf007c;" "&#xf007d;" "&#xf007e;" "&#xf007f;" "&#xf0080;" "&#xf0081;" "&#xf0082;" "&#xf0079;" ];
116 format-charging = "&#xf0084;";
117 format-plugged = "&#xf06a5;";
118 tooltip-format = "{capacity}% {timeTo}";
119 interval = 20;
120 };
121 tray = {
122 icon-size = 16;
123 # show-passive-items = true;
124 spacing = 1;
125 };
126 privacy = {
127 icon-spacing = 7;
128 icon-size = iconSize;
129 modules = [
130 { type = "screenshare"; }
131 { type = "audio-in"; }
132 ];
133 };
134 idle_inhibitor = {
135 format = "<span font=\"Symbols Nerd Font Mono\" size=\"90%\">{icon}</span>";
136 icon-size = iconSize;
137 format-icons = { activated = "&#xf0208;"; deactivated = "&#xf0209;"; };
138 timeout = 120;
139 };
140 backlight = {
141 format = "<span font=\"Symbols Nerd Font Mono\" size=\"90%\">{icon}</span>";
142 icon-size = iconSize;
143 tooltip-format = "{percent}%";
144 format-icons = ["&#xf00da;" "&#xf00db;" "&#xf00dc;" "&#xf00dd;" "&#xf00de;" "&#xf00df;" "&#xf00e0;"];
145 on-scroll-up = "lightctl -d -e4 -n1 up";
146 on-scroll-down = "lightctl -d -e4 -n1 down";
147 };
148 wireplumber = {
149 format = "<span font=\"Symbols Nerd Font Mono\" size=\"90%\">{icon}</span>";
150 icon-size = iconSize;
151 tooltip-format = "{volume}% {node_name}";
152 format-icons = ["&#xf057f;" "&#xf0580;" "&#xf057e;"];
153 format-muted = "<span font=\"Symbols Nerd Font Mono\" size=\"90%\">&#xf075f;</span>";
154 # ignored-sinks = ["Easy Effects Sink"];
155 on-scroll-up = "volumectl -d -u up";
156 on-scroll-down = "volumectl -d -u down";
157 on-click = "volumectl -d toggle-mute";
158 };
159 }
160 {
161 layer = "top";
162 position = "top";
163 height = 14;
164 output = [ "!eDP-1" "!DP-2" "!DP-3" ];
165 modules-left = [ "niri/workspaces" ];
166 modules-center = [ "niri/window" ];
167 modules-right = [ "clock" ];
168
169 "niri/workspaces" = {
170 all-outputs = false;
171 };
172 "niri/window" = {
173 separate-outputs = true;
174 icon = true;
175 icon-size = 14;
176 rewrite = windowRewrites;
177 };
178 clock = {
179 interval = 1;
180 # timezone = "Europe/Berlin";
181 format = "{:%H:%M}";
182 tooltip-format = "W{:%V-%u %F %H:%M:%S%Ez}";
183 };
184 }
185 ];
186 style = ''
187 @define-color white #ffffff;
188 @define-color grey #555555;
189 @define-color blue #1a8fff;
190 @define-color green #23fd00;
191 @define-color orange #f28a21;
192 @define-color red #f2201f;
193
194 * {
195 border: none;
196 font-family: "Fira Sans Nerd Font";
197 font-size: 10pt;
198 min-height: 0;
199 }
200
201 window#waybar {
202 background-color: rgba(0, 0, 0, 0.66);
203 color: @white;
204 }
205
206 .modules-left {
207 margin-left: 9px;
208 }
209 .modules-right {
210 margin-right: 9px;
211 }
212
213 .module {
214 margin: 0 5px;
215 }
216
217 #workspaces button {
218 color: @grey;
219 }
220 #workspaces button.hosting-monitor {
221 color: @white;
222 }
223 #workspaces button.visible {
224 color: @blue;
225 }
226 #workspaces button.active {
227 color: @green;
228 }
229 #workspaces button.urgent {
230 color: @red;
231 }
232
233 #custom-weather, #custom-keymap, #custom-worktime, #custom-worktime-today {
234 color: @grey;
235 margin: 0 5px;
236 }
237 #custom-weather, #custom-worktime-today {
238 margin-right: 3px;
239 }
240 #custom-keymap, #custom-weather {
241 margin-left: 3px;
242 }
243
244 #tray {
245 margin: 0;
246 }
247 #battery, #idle_inhibitor, #backlight, #wireplumber {
248 color: @grey;
249 margin: 0 5px 0 2px;
250 }
251 #idle_inhibitor {
252 margin-right: 2px;
253 margin-left: 3px;
254 }
255 #battery {
256 margin-right: 3px;
257 }
258 #battery.discharging {
259 color: @white;
260 }
261 #battery.warning {
262 color: @orange;
263 }
264 #battery.critical {
265 color: @red;
266 }
267 #battery.charging {
268 color: @white;
269 }
270 #idle_inhibitor.activated {
271 color: @white;
272 }
273
274 #idle_inhibitor {
275 padding-top: 1px;
276 }
277
278 #privacy {
279 color: @red;
280 margin: -1px 2px 0px 5px;
281 }
282 #clock {
283 /* margin-right: 5px; */
284 }
285 '';
286 };
287 };
288}
diff --git a/flake.lock b/flake.lock
index f379dac0..ac52bba4 100644
--- a/flake.lock
+++ b/flake.lock
@@ -359,11 +359,11 @@
359 }, 359 },
360 "impermanence": { 360 "impermanence": {
361 "locked": { 361 "locked": {
362 "lastModified": 1734945620, 362 "lastModified": 1736688610,
363 "narHash": "sha256-olIfsfJK4/GFmPH8mXMmBDAkzVQ1TWJmeGT3wBGfQPY=", 363 "narHash": "sha256-1Zl9xahw399UiZSJ9Vxs1W4WRFjO1SsNdVZQD4nghz0=",
364 "owner": "nix-community", 364 "owner": "nix-community",
365 "repo": "impermanence", 365 "repo": "impermanence",
366 "rev": "d000479f4f41390ff7cf9204979660ad5dd16176", 366 "rev": "c64bed13b562fc3bb454b48773d4155023ac31b7",
367 "type": "github" 367 "type": "github"
368 }, 368 },
369 "original": { 369 "original": {
@@ -385,6 +385,63 @@
385 "url": "https://data.iana.org/time-zones/tzdb/leap-seconds.list" 385 "url": "https://data.iana.org/time-zones/tzdb/leap-seconds.list"
386 } 386 }
387 }, 387 },
388 "niri-flake": {
389 "inputs": {
390 "niri-stable": "niri-stable",
391 "niri-unstable": "niri-unstable",
392 "nixpkgs": "nixpkgs_2",
393 "nixpkgs-stable": "nixpkgs-stable_2",
394 "xwayland-satellite-stable": "xwayland-satellite-stable",
395 "xwayland-satellite-unstable": "xwayland-satellite-unstable"
396 },
397 "locked": {
398 "lastModified": 1736840959,
399 "narHash": "sha256-po6B6ZkwtYI1BNIm5BR+JZ0HHKKNAnB+Dlr6BXCat3U=",
400 "owner": "sodiboo",
401 "repo": "niri-flake",
402 "rev": "d775188e23f94b2f73e939414b808fc2b9ebad73",
403 "type": "github"
404 },
405 "original": {
406 "owner": "sodiboo",
407 "ref": "main",
408 "repo": "niri-flake",
409 "type": "github"
410 }
411 },
412 "niri-stable": {
413 "flake": false,
414 "locked": {
415 "lastModified": 1736614405,
416 "narHash": "sha256-AJ1rlgNOPb3/+DbS5hkhm21t6Oz8IgqLllwmZt0lyzk=",
417 "owner": "YaLTeR",
418 "repo": "niri",
419 "rev": "e05bc269e678ecf828b96ae79c991c13b00b38a5",
420 "type": "github"
421 },
422 "original": {
423 "owner": "YaLTeR",
424 "ref": "v25.01",
425 "repo": "niri",
426 "type": "github"
427 }
428 },
429 "niri-unstable": {
430 "flake": false,
431 "locked": {
432 "lastModified": 1736836910,
433 "narHash": "sha256-jpyL3/lVeqbcXVOHoSPgXgIbJ9vZtiCDMSvZL0UyCgQ=",
434 "owner": "YaLTeR",
435 "repo": "niri",
436 "rev": "36076d5279f349a32814dea91ca8f4dee61d5b08",
437 "type": "github"
438 },
439 "original": {
440 "owner": "YaLTeR",
441 "repo": "niri",
442 "type": "github"
443 }
444 },
388 "nix-github-actions": { 445 "nix-github-actions": {
389 "inputs": { 446 "inputs": {
390 "nixpkgs": [ 447 "nixpkgs": [
@@ -413,11 +470,11 @@
413 ] 470 ]
414 }, 471 },
415 "locked": { 472 "locked": {
416 "lastModified": 1735443188, 473 "lastModified": 1736652904,
417 "narHash": "sha256-AydPpRBh8+NOkrLylG7vTsHrGO2b5L7XkMEL5HlzcA8=", 474 "narHash": "sha256-8uolHABgroXqzs03QdulHp8H9e5kWQZnnhcda1MKbBM=",
418 "owner": "Mic92", 475 "owner": "Mic92",
419 "repo": "nix-index-database", 476 "repo": "nix-index-database",
420 "rev": "55ab1e1df5daf2476e6b826b69a82862dcbd7544", 477 "rev": "271e5bd7c57e1f001693799518b10a02d1123b12",
421 "type": "github" 478 "type": "github"
422 }, 479 },
423 "original": { 480 "original": {
@@ -434,11 +491,11 @@
434 ] 491 ]
435 }, 492 },
436 "locked": { 493 "locked": {
437 "lastModified": 1735412232, 494 "lastModified": 1736736253,
438 "narHash": "sha256-W9wRlNvQLfV21359gTr3DglRBA6Q7NPUSU4RzgAAGsk=", 495 "narHash": "sha256-GrktftEfXmmdKOU0yz3QXckDz1ncZ+f4KLU8XnYKYuA=",
439 "owner": "AshleyYakeley", 496 "owner": "AshleyYakeley",
440 "repo": "NixVirt", 497 "repo": "NixVirt",
441 "rev": "55367360c00bd304042e5ad90841fd399330b77a", 498 "rev": "9063243af5e6674359a0ff7cec57f02eeacf0cea",
442 "type": "github" 499 "type": "github"
443 }, 500 },
444 "original": { 501 "original": {
@@ -449,11 +506,11 @@
449 }, 506 },
450 "nixos-hardware": { 507 "nixos-hardware": {
451 "locked": { 508 "locked": {
452 "lastModified": 1735388221, 509 "lastModified": 1736441705,
453 "narHash": "sha256-e5IOgjQf0SZcFCEV/gMGrsI0gCJyqOKShBQU0iiM3Kg=", 510 "narHash": "sha256-OL7leZ6KBhcDF3nEKe4aZVfIm6xQpb1Kb+mxySIP93o=",
454 "owner": "NixOS", 511 "owner": "NixOS",
455 "repo": "nixos-hardware", 512 "repo": "nixos-hardware",
456 "rev": "7c674c6734f61157e321db595dbfcd8523e04e19", 513 "rev": "8870dcaff63dfc6647fb10648b827e9d40b0a337",
457 "type": "github" 514 "type": "github"
458 }, 515 },
459 "original": { 516 "original": {
@@ -571,6 +628,22 @@
571 }, 628 },
572 "nixpkgs-stable_2": { 629 "nixpkgs-stable_2": {
573 "locked": { 630 "locked": {
631 "lastModified": 1736684107,
632 "narHash": "sha256-vH5mXxEvZeoGNkqKoCluhTGfoeXCZ1seYhC2pbMN0sg=",
633 "owner": "NixOS",
634 "repo": "nixpkgs",
635 "rev": "635e887b48521e912a516625eee7df6cf0eba9c1",
636 "type": "github"
637 },
638 "original": {
639 "owner": "NixOS",
640 "ref": "nixos-24.11",
641 "repo": "nixpkgs",
642 "type": "github"
643 }
644 },
645 "nixpkgs-stable_3": {
646 "locked": {
574 "lastModified": 1717179513, 647 "lastModified": 1717179513,
575 "narHash": "sha256-vboIEwIQojofItm2xGCdZCzW96U85l9nDW3ifMuAIdM=", 648 "narHash": "sha256-vboIEwIQojofItm2xGCdZCzW96U85l9nDW3ifMuAIdM=",
576 "owner": "NixOS", 649 "owner": "NixOS",
@@ -585,7 +658,7 @@
585 "type": "github" 658 "type": "github"
586 } 659 }
587 }, 660 },
588 "nixpkgs-stable_3": { 661 "nixpkgs-stable_4": {
589 "locked": { 662 "locked": {
590 "lastModified": 1678872516, 663 "lastModified": 1678872516,
591 "narHash": "sha256-/E1YwtMtFAu2KUQKV/1+KFuReYPANM2Rzehk84VxVoc=", 664 "narHash": "sha256-/E1YwtMtFAu2KUQKV/1+KFuReYPANM2Rzehk84VxVoc=",
@@ -603,22 +676,38 @@
603 }, 676 },
604 "nixpkgs_2": { 677 "nixpkgs_2": {
605 "locked": { 678 "locked": {
606 "lastModified": 1736167739, 679 "lastModified": 1736701207,
607 "narHash": "sha256-IWir2Srf07xHsdf9WnLtaqPgL+CfS6tiZ9N/I+qbneE=", 680 "narHash": "sha256-jG/+MvjVY7SlTakzZ2fJ5dC3V1PrKKrUEOEE30jrOKA=",
608 "owner": "gkleen", 681 "owner": "NixOS",
609 "repo": "nixpkgs", 682 "repo": "nixpkgs",
610 "rev": "a89c52fb11e656bbef04452a29eb0cd6cb6272c0", 683 "rev": "ed4a395ea001367c1f13d34b1e01aa10290f67d6",
611 "type": "github" 684 "type": "github"
612 }, 685 },
613 "original": { 686 "original": {
614 "owner": "gkleen", 687 "owner": "NixOS",
615 "ref": "fix/matrix-synapse", 688 "ref": "nixos-unstable",
616 "repo": "nixpkgs", 689 "repo": "nixpkgs",
617 "type": "github" 690 "type": "github"
618 } 691 }
619 }, 692 },
620 "nixpkgs_3": { 693 "nixpkgs_3": {
621 "locked": { 694 "locked": {
695 "lastModified": 1736798957,
696 "narHash": "sha256-qwpCtZhSsSNQtK4xYGzMiyEDhkNzOCz/Vfu4oL2ETsQ=",
697 "owner": "NixOS",
698 "repo": "nixpkgs",
699 "rev": "9abb87b552b7f55ac8916b6fc9e5cb486656a2f3",
700 "type": "github"
701 },
702 "original": {
703 "owner": "NixOS",
704 "ref": "nixos-unstable",
705 "repo": "nixpkgs",
706 "type": "github"
707 }
708 },
709 "nixpkgs_4": {
710 "locked": {
622 "lastModified": 1681303793, 711 "lastModified": 1681303793,
623 "narHash": "sha256-JEdQHsYuCfRL2PICHlOiH/2ue3DwoxUX7DJ6zZxZXFk=", 712 "narHash": "sha256-JEdQHsYuCfRL2PICHlOiH/2ue3DwoxUX7DJ6zZxZXFk=",
624 "owner": "NixOS", 713 "owner": "NixOS",
@@ -673,11 +762,11 @@
673 "treefmt-nix": "treefmt-nix" 762 "treefmt-nix": "treefmt-nix"
674 }, 763 },
675 "locked": { 764 "locked": {
676 "lastModified": 1735852239, 765 "lastModified": 1736774291,
677 "narHash": "sha256-Xrg/HahR9SW1UzT5pwtpQR6D12ZIwwHjxav9YzB1q4U=", 766 "narHash": "sha256-1rEUm7R93L8rltgyBzon2/lzIN2udC/Kd8nyvuDN6ps=",
678 "owner": "nix-community", 767 "owner": "nix-community",
679 "repo": "poetry2nix", 768 "repo": "poetry2nix",
680 "rev": "bb182fd661f5f8a7d6c50dd44cf9a6ddca7ccc1a", 769 "rev": "499221030113adc5dea05886a1d7aa1cc3a315d1",
681 "type": "github" 770 "type": "github"
682 }, 771 },
683 "original": { 772 "original": {
@@ -740,8 +829,8 @@
740 "flake-compat": "flake-compat_4", 829 "flake-compat": "flake-compat_4",
741 "flake-utils": "flake-utils_2", 830 "flake-utils": "flake-utils_2",
742 "gitignore": "gitignore_3", 831 "gitignore": "gitignore_3",
743 "nixpkgs": "nixpkgs_3", 832 "nixpkgs": "nixpkgs_4",
744 "nixpkgs-stable": "nixpkgs-stable_3" 833 "nixpkgs-stable": "nixpkgs-stable_4"
745 }, 834 },
746 "locked": { 835 "locked": {
747 "lastModified": 1685361114, 836 "lastModified": 1685361114,
@@ -794,13 +883,14 @@
794 "home-manager": "home-manager", 883 "home-manager": "home-manager",
795 "home-manager-eostre": "home-manager-eostre", 884 "home-manager-eostre": "home-manager-eostre",
796 "impermanence": "impermanence", 885 "impermanence": "impermanence",
886 "niri-flake": "niri-flake",
797 "nix-index-database": "nix-index-database", 887 "nix-index-database": "nix-index-database",
798 "nixVirt": "nixVirt", 888 "nixVirt": "nixVirt",
799 "nixos-hardware": "nixos-hardware", 889 "nixos-hardware": "nixos-hardware",
800 "nixpkgs": "nixpkgs_2", 890 "nixpkgs": "nixpkgs_3",
801 "nixpkgs-eostre": "nixpkgs-eostre", 891 "nixpkgs-eostre": "nixpkgs-eostre",
802 "nixpkgs-pgbackrest": "nixpkgs-pgbackrest", 892 "nixpkgs-pgbackrest": "nixpkgs-pgbackrest",
803 "nixpkgs-stable": "nixpkgs-stable_2", 893 "nixpkgs-stable": "nixpkgs-stable_3",
804 "nvfetcher": "nvfetcher", 894 "nvfetcher": "nvfetcher",
805 "poetry2nix": "poetry2nix", 895 "poetry2nix": "poetry2nix",
806 "prometheus-borg-exporter": "prometheus-borg-exporter", 896 "prometheus-borg-exporter": "prometheus-borg-exporter",
@@ -815,11 +905,11 @@
815 ] 905 ]
816 }, 906 },
817 "locked": { 907 "locked": {
818 "lastModified": 1735844895, 908 "lastModified": 1736808430,
819 "narHash": "sha256-CIRlqX9tBK2awJkmVu2cKuap/0QziDXStQZ/u/+e8Z4=", 909 "narHash": "sha256-wlgdf/n7bJMLBheqt1jmPoxJFrUP6FByKQFXuM9YvIk=",
820 "owner": "Mic92", 910 "owner": "Mic92",
821 "repo": "sops-nix", 911 "repo": "sops-nix",
822 "rev": "24d89184adf76d7ccc99e659dc5f3838efb5ee32", 912 "rev": "553c7cb22fed19fd60eb310423fdc93045c51ba8",
823 "type": "github" 913 "type": "github"
824 }, 914 },
825 "original": { 915 "original": {
@@ -854,8 +944,9 @@
854 "type": "github" 944 "type": "github"
855 }, 945 },
856 "original": { 946 "original": {
857 "id": "systems", 947 "owner": "nix-systems",
858 "type": "indirect" 948 "repo": "default",
949 "type": "github"
859 } 950 }
860 }, 951 },
861 "treefmt-nix": { 952 "treefmt-nix": {
@@ -902,6 +993,39 @@
902 "repo": "Waybar", 993 "repo": "Waybar",
903 "type": "github" 994 "type": "github"
904 } 995 }
996 },
997 "xwayland-satellite-stable": {
998 "flake": false,
999 "locked": {
1000 "lastModified": 1730166465,
1001 "narHash": "sha256-nq7bouXQXaaPPo/E+Jbq+wNHnatD4dY8OxSrRqzvy6s=",
1002 "owner": "Supreeeme",
1003 "repo": "xwayland-satellite",
1004 "rev": "a713cf46cb7db84a0d1b57c3a397c610cad3cf98",
1005 "type": "github"
1006 },
1007 "original": {
1008 "owner": "Supreeeme",
1009 "ref": "v0.5",
1010 "repo": "xwayland-satellite",
1011 "type": "github"
1012 }
1013 },
1014 "xwayland-satellite-unstable": {
1015 "flake": false,
1016 "locked": {
1017 "lastModified": 1736487362,
1018 "narHash": "sha256-4kGoOA7FgK9N2mzS+TFEn41kUUNY6KwdiA/0rqlr868=",
1019 "owner": "Supreeeme",
1020 "repo": "xwayland-satellite",
1021 "rev": "8f55e27f63a749881c4bbfbb6b1da028342a91d1",
1022 "type": "github"
1023 },
1024 "original": {
1025 "owner": "Supreeeme",
1026 "repo": "xwayland-satellite",
1027 "type": "github"
1028 }
905 } 1029 }
906 }, 1030 },
907 "root": "root", 1031 "root": "root",
diff --git a/flake.nix b/flake.nix
index c6eaab47..816fd499 100644
--- a/flake.nix
+++ b/flake.nix
@@ -4,20 +4,20 @@
4 nixConfig = { 4 nixConfig = {
5 extra-substituters = [ 5 extra-substituters = [
6 "https://nix-community.cachix.org" 6 "https://nix-community.cachix.org"
7 "https://niri.cachix.org"
7 ]; 8 ];
8 extra-trusted-public-keys = [ 9 extra-trusted-public-keys = [
9 "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=" 10 "nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs="
11 "niri.cachix.org-1:Wv0OmO7PsuocRKzfDoJ3mulSl7Z6oezYhGhR+3W2964="
10 ]; 12 ];
11 }; 13 };
12 14
13 inputs = { 15 inputs = {
14 nixpkgs = { 16 nixpkgs = {
15 type = "github"; 17 type = "github";
16 # owner = "NixOS"; 18 owner = "NixOS";
17 repo = "nixpkgs"; 19 repo = "nixpkgs";
18 # ref = "nixos-unstable"; 20 ref = "nixos-unstable";
19 owner = "gkleen";
20 ref = "fix/matrix-synapse";
21 }; 21 };
22 nixpkgs-pgbackrest = { 22 nixpkgs-pgbackrest = {
23 type = "github"; 23 type = "github";
@@ -184,9 +184,15 @@
184 repo = "NixVirt"; 184 repo = "NixVirt";
185 inputs.nixpkgs.follows = "nixpkgs"; 185 inputs.nixpkgs.follows = "nixpkgs";
186 }; 186 };
187 niri-flake = {
188 type = "github";
189 owner = "sodiboo";
190 repo = "niri-flake";
191 ref = "main";
192 };
187 }; 193 };
188 194
189 outputs = { self, nixpkgs, home-manager, sops-nix, deploy-rs, nvfetcher, ... }@inputs: 195 outputs = { self, nixpkgs, home-manager, sops-nix, deploy-rs, nvfetcher, niri-flake, ... }@inputs:
190 let 196 let
191 inherit (builtins) attrNames attrValues elemAt toJSON isNull pathExists; 197 inherit (builtins) attrNames attrValues elemAt toJSON isNull pathExists;
192 inherit (nixpkgs) lib; 198 inherit (nixpkgs) lib;
@@ -324,7 +330,7 @@
324 nixosConfigurations = installerNixosConfigurations // nixImport rec { dir = ./hosts; _import = mkNixosConfiguration [] dir; }; 330 nixosConfigurations = installerNixosConfigurations // nixImport rec { dir = ./hosts; _import = mkNixosConfiguration [] dir; };
325 331
326 homeModules = nixImport rec { dir = ./home-modules; }; 332 homeModules = nixImport rec { dir = ./home-modules; };
327 homeConfigurations = listToAttrs (concatLists (mapAttrsToList (hostname: nixosConfig: mapAttrsToList (username: configuration: nameValuePair "${username}@${hostname}" { inherit (configuration.home) activationPackage; }) nixosConfig.config.home-manager.users) self.nixosConfigurations)); 333 homeConfigurations = listToAttrs (concatLists (mapAttrsToList (hostname: nixosConfig: mapAttrsToList (username: configuration: nameValuePair "${username}@${hostname}" { inherit (configuration.home) activationPackage; inherit (configuration) home-files; }) nixosConfig.config.home-manager.users) self.nixosConfigurations));
328 334
329 overlays = mapAttrs (_name: path: mkOverlay path) overlayPaths; 335 overlays = mapAttrs (_name: path: mkOverlay path) overlayPaths;
330 336
diff --git a/hosts/sif/default.nix b/hosts/sif/default.nix
index 088e1022..09d43109 100644
--- a/hosts/sif/default.nix
+++ b/hosts/sif/default.nix
@@ -27,6 +27,9 @@ in {
27 allowUnfree = true; 27 allowUnfree = true;
28 pulseaudio = true; 28 pulseaudio = true;
29 }; 29 };
30 extraOverlays = [
31 flakeInputs.niri-flake.overlays.niri
32 ];
30 }; 33 };
31 34
32 time.timeZone = null; 35 time.timeZone = null;
@@ -496,14 +499,14 @@ in {
496 GTK.application_prefer_dark_theme = true; 499 GTK.application_prefer_dark_theme = true;
497 }; 500 };
498 }; 501 };
499 programs.hyprland.enable = true; 502 programs.niri.enable = true;
500 503
501 systemd.tmpfiles.settings = { 504 systemd.tmpfiles.settings = {
502 "10-localtime"."/etc/localtime".L.argument = "/.bcachefs/etc/localtime"; 505 "10-localtime"."/etc/localtime".L.argument = "/.bcachefs/etc/localtime";
503 506
504 "10-regreet"."/var/cache/regreet/cache.toml".C.argument = toString ((pkgs.formats.toml {}).generate "cache.toml" { 507 "10-regreet"."/var/cache/regreet/cache.toml".C.argument = toString ((pkgs.formats.toml {}).generate "cache.toml" {
505 last_user = "gkleen"; 508 last_user = "gkleen";
506 user_to_last_sess.gkleen = "Hyprland"; 509 user_to_last_sess.gkleen = "niri";
507 }); 510 });
508 }; 511 };
509 512
diff --git a/modules/niri.nix b/modules/niri.nix
new file mode 100644
index 00000000..4e2ddf8b
--- /dev/null
+++ b/modules/niri.nix
@@ -0,0 +1,6 @@
1{ flakeInputs, ... }:
2{
3 imports = [
4 flakeInputs.niri-flake.nixosModules.niri
5 ];
6}
diff --git a/overlays/matrix-synapse.nix b/overlays/matrix-synapse.nix
deleted file mode 100644
index 59b2c6da..00000000
--- a/overlays/matrix-synapse.nix
+++ /dev/null
@@ -1,4 +0,0 @@
1{ final, prev, ... }:
2{
3 matrix-synapse-unwrapped = prev.matrix-synapse-unwrapped.overridePythonAttrs { doCheck = false; };
4}
diff --git a/system-profiles/niri-flake.nix b/system-profiles/niri-flake.nix
new file mode 100644
index 00000000..b28d51ff
--- /dev/null
+++ b/system-profiles/niri-flake.nix
@@ -0,0 +1,4 @@
1{ ... }:
2{
3 config.niri-flake.cache.enable = false;
4}