summaryrefslogtreecommitdiff
path: root/accounts
diff options
context:
space:
mode:
Diffstat (limited to 'accounts')
-rw-r--r--accounts/gkleen@sif/default.nix90
-rw-r--r--accounts/gkleen@sif/emacs.el2
-rw-r--r--accounts/gkleen@sif/niri/default.nix326
-rw-r--r--accounts/gkleen@sif/niri/mako.nix2
-rw-r--r--accounts/gkleen@sif/niri/waybar.nix21
-rw-r--r--accounts/gkleen@sif/synadm/default.nix9
-rw-r--r--accounts/gkleen@sif/synadm/synadm_yaml15
-rw-r--r--accounts/gkleen@sif/systemd.nix2
-rw-r--r--accounts/gkleen@sif/utils/async-yt-dlp.nix57
-rw-r--r--accounts/gkleen@sif/zshrc4
10 files changed, 390 insertions, 138 deletions
diff --git a/accounts/gkleen@sif/default.nix b/accounts/gkleen@sif/default.nix
index e07362fc..a1a694ea 100644
--- a/accounts/gkleen@sif/default.nix
+++ b/accounts/gkleen@sif/default.nix
@@ -71,6 +71,7 @@ in {
71 imports = [ 71 imports = [
72 ./libvirt 72 ./libvirt
73 ./niri 73 ./niri
74 ./synadm
74 flakeInputs.nix-index-database.hmModules.nix-index 75 flakeInputs.nix-index-database.hmModules.nix-index
75 flakeInputs.impermanence.nixosModules.home-manager.impermanence 76 flakeInputs.impermanence.nixosModules.home-manager.impermanence
76 ]; 77 ];
@@ -171,6 +172,7 @@ in {
171 }; 172 };
172 }; 173 };
173 }; 174 };
175 chromium.enable = true;
174 176
175 zathura = { 177 zathura = {
176 enable = true; 178 enable = true;
@@ -282,6 +284,16 @@ in {
282 pro = "$HOME/projects/pro"; 284 pro = "$HOME/projects/pro";
283 media = "$HOME/media"; 285 media = "$HOME/media";
284 }; 286 };
287 jq.colors = {
288 arrays = "1;37";
289 "false" = "0;37";
290 "null" = "2;37";
291 numbers = "0;37";
292 objectKeys = "1;34";
293 objects = "1;37";
294 strings = "0;32";
295 "true" = "0;37";
296 };
285 297
286 obs-studio = { 298 obs-studio = {
287 enable = true; 299 enable = true;
@@ -317,8 +329,10 @@ in {
317 # notify_on_cmd_finish = "invisible 120"; 329 # notify_on_cmd_finish = "invisible 120";
318 }; 330 };
319 keybindings = { 331 keybindings = {
320 "kitty_mod+n" = "detach_window"; 332 "kitty_mod+n" = "new_os_window_with_cwd";
321 "kitty_mod+m" = "detach_window ask"; 333 "kitty_mod+m" = "detach_window ask";
334 "kitty_mod+enter" = "new_window_with_cwd";
335 "kitty_mod+t" = "new_tab_with_cwd";
322 }; 336 };
323 }; 337 };
324 fuzzel = { 338 fuzzel = {
@@ -331,7 +345,7 @@ in {
331 font = "Fira Sans"; 345 font = "Fira Sans";
332 }; 346 };
333 colors = { 347 colors = {
334 background = "000000aa"; 348 background = "000000cc";
335 text = "cdd6f4ff"; 349 text = "cdd6f4ff";
336 match = "94e2d5ff"; 350 match = "94e2d5ff";
337 selection = "585b70ff"; 351 selection = "585b70ff";
@@ -352,6 +366,7 @@ in {
352 enable = true; 366 enable = true;
353 settings.show_banner = false; 367 settings.show_banner = false;
354 }; 368 };
369 fd.enable = true;
355 }; 370 };
356 371
357 services = { 372 services = {
@@ -477,6 +492,13 @@ in {
477 }; 492 };
478 }; 493 };
479 494
495 qt.kde.settings = {
496 kwalletrc = {
497 KSecretD.Enabled = false;
498 Wallet."Default Wallet" = "store";
499 };
500 };
501
480 xsession.preferStatusNotifierItems = true; 502 xsession.preferStatusNotifierItems = true;
481 503
482 xresources.properties = import ./xresources.nix; 504 xresources.properties = import ./xresources.nix;
@@ -488,16 +510,15 @@ in {
488 wrappedYTMDesktop libsForQt5.qt5ct playerctl evince papers 510 wrappedYTMDesktop libsForQt5.qt5ct playerctl evince papers
489 thunderbird zoom-us xdg-desktop-portal steam steam-run 511 thunderbird zoom-us xdg-desktop-portal steam steam-run
490 wireshark virt-manager rclone cached-nix-shell worktime 512 wireshark virt-manager rclone cached-nix-shell worktime
491 fira-code-symbols libreoffice xournalpp google-chrome 513 fira-code-symbols libreoffice xournalpp
492 nixos-shell virt-viewer freerdp gnome-icon-theme 514 nixos-shell virt-viewer freerdp gnome-icon-theme
493 paper-icon-theme sshpassSecret weechat element-desktop 515 paper-icon-theme sshpassSecret weechat element-desktop
494 sieve-connect gimp3 inkscape udiskie glab nitrokey-app 516 sieve-connect gimp3 inkscape udiskie glab nitrokey-app
495 pynitrokey gtklock wlrctl remmina openscad spice-record 517 pynitrokey gtklock wlrctl remmina openscad spice-record
496 libguestfs-with-appliance nerd-fonts.fira-mono 518 libguestfs-with-appliance nerd-fonts.fira-mono
497 nerd-fonts.symbols-only nerd-fonts.fira-code powerline-fonts 519 nerd-fonts.symbols-only nerd-fonts.fira-code powerline-fonts
498 swtpm (hunspellWithDicts (with hunspellDicts; [en_GB-large de_DE])) 520 swtpm (hunspell.withDicts (dicts: with dicts; [en_GB-large de_DE]))
499 libation 521 libation libqalculate
500 # synadm
501 ] ++ mapAttrsToList (_name: pkg: pkgs.callPackage pkg {}) (customUtils.nixImport { dir = ./utils; }); 522 ] ++ mapAttrsToList (_name: pkg: pkgs.callPackage pkg {}) (customUtils.nixImport { dir = ./utils; });
502 523
503 file = { 524 file = {
@@ -520,6 +541,7 @@ in {
520 STACK_XDG = 1; 541 STACK_XDG = 1;
521 EDITOR = lib.getExe' editor "emacsclient"; 542 EDITOR = lib.getExe' editor "emacsclient";
522 RCLONE_PASSWORD_COMMAND = "${lib.getExe' pkgs.libsecret "secret-tool"} lookup service rclone"; 543 RCLONE_PASSWORD_COMMAND = "${lib.getExe' pkgs.libsecret "secret-tool"} lookup service rclone";
544 SYSTEMD_TINT_BACKGROUND = "false";
523 }; 545 };
524 546
525 extraProfileCommands = '' 547 extraProfileCommands = ''
@@ -556,9 +578,17 @@ in {
556 General = { 578 General = {
557 dot_as_separator = 0; 579 dot_as_separator = 0;
558 }; 580 };
581 Mode = {
582 calculate_as_you_type = 1;
583 };
559 }; 584 };
560 }; 585 };
561 "emacs/init.el".source = ./emacs.el; 586 "emacs/init.el".source = pkgs.substitute {
587 src = ./emacs.el;
588 substitutions = [
589 "--subst-var-by" "ksshaskpass" (lib.getExe pkgs.kdePackages.ksshaskpass)
590 ];
591 };
562 "systemd/user/xdg-desktop-portal.service.d/after-graphical-session.conf".text = '' 592 "systemd/user/xdg-desktop-portal.service.d/after-graphical-session.conf".text = ''
563 [Unit] 593 [Unit]
564 After=graphical-session.target 594 After=graphical-session.target
@@ -576,6 +606,8 @@ in {
576 xdg.dataFile = { 606 xdg.dataFile = {
577 "dbus-1/services/org.keepassxc.KeePassXC.service".source = "${wrappedKeepassxc}/share/dbus-1/services/org.keepassxc.KeePassXC.service"; 607 "dbus-1/services/org.keepassxc.KeePassXC.service".source = "${wrappedKeepassxc}/share/dbus-1/services/org.keepassxc.KeePassXC.service";
578 "dbus-1/services/org.freedesktop.secrets.service.service".source = "${wrappedKeepassxc}/share/dbus-1/services/org.freedesktop.secrets.service.service"; 608 "dbus-1/services/org.freedesktop.secrets.service.service".source = "${wrappedKeepassxc}/share/dbus-1/services/org.freedesktop.secrets.service.service";
609 "dbus-1/services/org.kde.kwalletd6.service".source = "${pkgs.kdePackages.kwallet}/share/dbus-1/services/org.kde.kwalletd6.service";
610 "dbus-1/services/org.kde.kwalletd5.service".source = "${pkgs.kdePackages.kwallet}/share/dbus-1/services/org.kde.kwalletd5.service";
579 "emoji-data/list.txt".source = pkgs.stdenv.mkDerivation { 611 "emoji-data/list.txt".source = pkgs.stdenv.mkDerivation {
580 inherit (sources.emoji-data) pname src; 612 inherit (sources.emoji-data) pname src;
581 version = lib.removePrefix "v" sources.emoji-data.version; 613 version = lib.removePrefix "v" sources.emoji-data.version;
@@ -663,11 +695,11 @@ in {
663 exec -- \ 695 exec -- \
664 ${lib.getExe' config.systemd.package "systemd-run"} --wait --user --slice-inherit \ 696 ${lib.getExe' config.systemd.package "systemd-run"} --wait --user --slice-inherit \
665 --property 'CPUAccounting=yes' --property 'CPUQuotaPeriodSec=50ms' \ 697 --property 'CPUAccounting=yes' --property 'CPUQuotaPeriodSec=50ms' \
666 --property 'Environment=DSCP=46' \ 698 -E DSCP=46 -E NIXOS_OZONE_WL \
667 -- ${lib.getExe pkgs.dscp} ${lib.getExe' pkgs.google-chrome "google-chrome-stable"} \ 699 -- ${lib.getExe pkgs.dscp} ${lib.getExe cfg.programs.chromium.package} \
668 --class=Rainbow \ 700 --class=Rainbow \
669 --kiosk "https://web.openrainbow.com" \ 701 --app="https://web.openrainbow.com" \
670 --user-data-dir=''${HOME}/.config/google-chrome-rainbow 702 --user-data-dir=''${HOME}/.config/chromium-rainbow
671 ''); 703 '');
672 icon = pkgs.fetchurl { 704 icon = pkgs.fetchurl {
673 url = "https://web.openrainbow.com/rb/2.139.17/assets/skins/rainbow/images/homepage/logo__rainbow.svg"; 705 url = "https://web.openrainbow.com/rb/2.139.17/assets/skins/rainbow/images/homepage/logo__rainbow.svg";
@@ -677,6 +709,42 @@ in {
677 StartupWMClass = "Rainbow"; 709 StartupWMClass = "Rainbow";
678 }; 710 };
679 }; 711 };
712 kimai = {
713 name = "Kimai";
714 exec = toString (pkgs.writeShellScript "kimai" ''
715 exec -- \
716 ${lib.getExe cfg.programs.chromium.package} \
717 --class=Kimai \
718 --app="https://kimai.yggdrasil.li" \
719 --user-data-dir=''${HOME}/.config/chromium-kimai
720 '');
721 icon = pkgs.fetchurl {
722 url = "https://www.kimai.org/images/kimai_logo.png";
723 hash = "sha256-lnlOttzR2SwXA70R+egJUkeKr4U5V0avqTk8uX4bqfs=";
724 };
725 settings = {
726 StartupWMClass = "Kimai";
727 StartupNotify = "true";
728 };
729 };
730 audiobookshelf = {
731 name = "Audiobookshelf";
732 exec = toString (pkgs.writeShellScript "audiobookshelf" ''
733 exec -- \
734 ${lib.getExe cfg.programs.chromium.package} \
735 --class=Audiobookshelf \
736 --app="https://audiobookshelf.yggdrasil.li" \
737 --user-data-dir=''${HOME}/.config/chromium-audiobookshelf
738 '');
739 icon = pkgs.fetchurl {
740 url = "https://www.audiobookshelf.org/Logo.png";
741 hash = "sha256-JGPk+WNT1C4DC4lSMb0K0YmAMT5LvmSOeO0QRzkc7Lk=";
742 };
743 settings = {
744 StartupWMClass = "Audiobookshelf";
745 StartupNotify = "true";
746 };
747 };
680 thunderbird-lmu = { 748 thunderbird-lmu = {
681 name = "Thunderbird (LMU)"; 749 name = "Thunderbird (LMU)";
682 exec = "thunderbird --name thunderbird -P lmu %U"; 750 exec = "thunderbird --name thunderbird -P lmu %U";
diff --git a/accounts/gkleen@sif/emacs.el b/accounts/gkleen@sif/emacs.el
index 563c5d0b..3beefba6 100644
--- a/accounts/gkleen@sif/emacs.el
+++ b/accounts/gkleen@sif/emacs.el
@@ -254,3 +254,5 @@ necessarily running."
254(bind-key "C-x C-m" #'move-file) 254(bind-key "C-x C-m" #'move-file)
255 255
256(let ((ssh_auth_sock (string-chop-newline (shell-command-to-string "gpgconf --list-dirs agent-ssh-socket")))) (setenv "SSH_AUTH_SOCK" ssh_auth_sock)) 256(let ((ssh_auth_sock (string-chop-newline (shell-command-to-string "gpgconf --list-dirs agent-ssh-socket")))) (setenv "SSH_AUTH_SOCK" ssh_auth_sock))
257(setenv "SSH_ASKPASS_REQUIRE" "prefer")
258(setenv "SSH_ASKPASS" "@ksshaskpass@")
diff --git a/accounts/gkleen@sif/niri/default.nix b/accounts/gkleen@sif/niri/default.nix
index 924d3843..35a3d799 100644
--- a/accounts/gkleen@sif/niri/default.nix
+++ b/accounts/gkleen@sif/niri/default.nix
@@ -3,6 +3,7 @@ let
3 cfg = config.programs.niri; 3 cfg = config.programs.niri;
4 4
5 kdl = flakeInputs.niri-flake.lib.kdl; 5 kdl = flakeInputs.niri-flake.lib.kdl;
6 sleaf = name: arg: kdl.node name [arg] [];
6 7
7 niri = cfg.package; 8 niri = cfg.package;
8 terminal = lib.getExe config.programs.kitty.package; 9 terminal = lib.getExe config.programs.kitty.package;
@@ -35,7 +36,11 @@ let
35 if jq -e '.is_focused' <<<"$window_json" >/dev/null; then 36 if jq -e '.is_focused' <<<"$window_json" >/dev/null; then
36 niri msg action focus-workspace-previous 37 niri msg action focus-workspace-previous
37 else 38 else
38 niri msg action focus-window --id "$(jq -r '.id' <<<"$window_json")" 39 if [[ $(jq -r --arg workspace_name "$workspace_name" 'map(select(.name == $workspace_name)) | .[0].is_focused' <<<"$workspaces_json") != "true" ]] && [[ $(jq -r --arg workspace_name "$workspace_name" 'map(select(.name == $workspace_name)) | .[0].id' <<<"$workspaces_json") = $(jq -r '.workspace_id' <<<"$window_json") ]]; then
40 niri msg action focus-workspace "$workspace_name"
41 else
42 niri msg action focus-window --id "$(jq -r '.id' <<<"$window_json")"
43 fi
39 fi 44 fi
40 exit 0 45 exit 0
41 fi 46 fi
@@ -45,7 +50,6 @@ let
45 ''; 50 '';
46 }; 51 };
47 focus-or-spawn-action = config.lib.niri.actions.spawn (lib.getExe focus_or_spawn); 52 focus-or-spawn-action = config.lib.niri.actions.spawn (lib.getExe focus_or_spawn);
48 focus-or-spawn-action-app_id = app_id: focus-or-spawn-action ''select(.app_id == "${app_id}")'';
49 53
50 with_adjacent_workspace = pkgs.writeShellApplication { 54 with_adjacent_workspace = pkgs.writeShellApplication {
51 name = "with-adjacent-workspace"; 55 name = "with-adjacent-workspace";
@@ -84,7 +88,7 @@ let
84 }; 88 };
85 with-adjacent-workspace-action = config.lib.niri.actions.spawn (lib.getExe with_adjacent_workspace) "^${lib.concatMapStringsSep "|" ({ name, ...}: name) cfg.scratchspaces}$"; 89 with-adjacent-workspace-action = config.lib.niri.actions.spawn (lib.getExe with_adjacent_workspace) "^${lib.concatMapStringsSep "|" ({ name, ...}: name) cfg.scratchspaces}$";
86 focus-adjacent-workspace = direction: with-adjacent-workspace-action direction ''{"Action":{"FocusWorkspace":{"reference":{"Id": .id}}}}''; 90 focus-adjacent-workspace = direction: with-adjacent-workspace-action direction ''{"Action":{"FocusWorkspace":{"reference":{"Id": .id}}}}'';
87 move-column-to-adjacent-workspace = direction: with-adjacent-workspace-action direction ''{"Action":{"MoveColumnToWorkspace":{"reference":{"Id": .id}}}}''; 91 move-column-to-adjacent-workspace = direction: with-adjacent-workspace-action direction ''{"Action":{"MoveColumnToWorkspace":{"reference":{"Id": .id}, "focus": true}}}'';
88 92
89 with_unnamed_workspace = pkgs.writeShellApplication { 93 with_unnamed_workspace = pkgs.writeShellApplication {
90 name = "with-unnamed-workspace"; 94 name = "with-unnamed-workspace";
@@ -131,7 +135,7 @@ let
131 135
132 windows_json="$(niri msg -j windows)" 136 windows_json="$(niri msg -j windows)"
133 active_workspace="$(jq -r '.[] | select(.is_focused) | .workspace_id' <<<"$windows_json")" 137 active_workspace="$(jq -r '.[] | select(.is_focused) | .workspace_id' <<<"$windows_json")"
134 window_ix="$(gojq -r --arg active_workspace "$active_workspace" '.[] | select('"$window_select"') | "\(.title)\u0000icon\u001f\(.app_id)"' <<<"$windows_json" | fuzzel --log-level=warning --dmenu --index)" 138 window_ix="$(gojq -r --arg active_workspace "$active_workspace" '.[] | select('"$window_select"') | "\(.title)\u0000icon\u001f\(.app_id)"' <<<"$windows_json" | fuzzel --width=60 --log-level=warning --dmenu --index)"
135 # shellcheck disable=SC2016 139 # shellcheck disable=SC2016
136 window_json="$(gojq -rc --arg active_workspace "$active_workspace" --arg window_ix "$window_ix" 'map(select('"$window_select"')) | .[($window_ix | tonumber)]' <<<"$windows_json")" 140 window_json="$(gojq -rc --arg active_workspace "$active_workspace" --arg window_ix "$window_ix" 'map(select('"$window_select"')) | .[($window_ix | tonumber)]' <<<"$windows_json")"
137 141
@@ -141,6 +145,25 @@ let
141 ''; 145 '';
142 }; 146 };
143 with-select-window-action = config.lib.niri.actions.spawn (lib.getExe with_select_window); 147 with-select-window-action = config.lib.niri.actions.spawn (lib.getExe with_select_window);
148
149 with_predicate_window = pred: pkgs.writeShellApplication {
150 name = "with-predicate-window";
151 runtimeInputs = [ niri pkgs.gojq pkgs.socat ];
152 text = ''
153 action="$1"
154 shift
155
156 windows_json="$(niri msg -j windows)"
157 window_json="$(gojq -rc 'map(select(${pred})) | .[0]' <<<"$windows_json")"
158
159 [[ -z "$window_json" || $window_json = "null" ]] && exit 1
160
161 jq -c "$action" <<<"$window_json" | socat STDIO "$NIRI_SOCKET"
162 '';
163 };
164
165 with-urgent-window-action = config.lib.niri.actions.spawn (lib.getExe (with_predicate_window ".is_urgent"));
166 with-focused-window-action = config.lib.niri.actions.spawn (lib.getExe (with_predicate_window ".is_focused"));
144in { 167in {
145 imports = [ 168 imports = [
146 ./waybar.nix 169 ./waybar.nix
@@ -171,6 +194,17 @@ in {
171 type = lib.types.nullOr lib.types.str; 194 type = lib.types.nullOr lib.types.str;
172 default = null; 195 default = null;
173 }; 196 };
197 moveKey = lib.mkOption {
198 type = lib.types.nullOr lib.types.str;
199 default = let
200 keys = lib.splitString "+" config.key;
201 defMoveKey = lib.concatStringsSep "+" (lib.flatten [
202 (lib.take (lib.length keys - 1) keys)
203 ["Shift"]
204 (lib.takeEnd 1 keys)
205 ]);
206 in if config.key == null then null else defMoveKey;
207 };
174 spawn = lib.mkOption { 208 spawn = lib.mkOption {
175 type = lib.types.nullOr (lib.types.listOf lib.types.str); 209 type = lib.types.nullOr (lib.types.listOf lib.types.str);
176 default = null; 210 default = null;
@@ -416,8 +450,8 @@ in {
416 { title = "^Access Request.*"; } 450 { title = "^Access Request.*"; }
417 { title = ".*Passkey credentials$"; } 451 { title = ".*Passkey credentials$"; }
418 ]; 452 ];
419 windowRuleExtra = [ 453 windowRuleExtra = with kdl; [
420 (kdl.leaf "open-focused" false) 454 (sleaf "open-focused" false)
421 ]; 455 ];
422 key = "Mod+Control+P"; 456 key = "Mod+Control+P";
423 app-id = "org.keepassxc.KeePassXC"; 457 app-id = "org.keepassxc.KeePassXC";
@@ -444,6 +478,20 @@ in {
444 app-id = "com.github.wwmm.easyeffects"; 478 app-id = "com.github.wwmm.easyeffects";
445 spawn = [ "easyeffects" ]; 479 spawn = [ "easyeffects" ];
446 } 480 }
481 { name = "time";
482 key = "Mod+Control+K";
483 app-id = "chrome-kimai.yggdrasil.li__-Default";
484 spawn = [ (toString (pkgs.resholve.writeScript "kimai" {
485 interpreter = pkgs.runtimeShell;
486 inputs = [ pkgs.dex ];
487 execer = [ "cannot:${lib.getExe pkgs.dex}" ];
488 } ''
489 exec dex $HOME/.local/state/nix/profile/share/applications/kimai.desktop
490 '')) ];
491 windowRuleExtra = with kdl; [
492 (sleaf "block-out-from" "screencast")
493 ];
494 }
447 ]; 495 ];
448 programs.niri.config = 496 programs.niri.config =
449 let 497 let
@@ -453,10 +501,12 @@ in {
453 then v 501 then v
454 else null; 502 else null;
455 opt-props = lib.filterAttrs (lib.const (value: value != null)); 503 opt-props = lib.filterAttrs (lib.const (value: value != null));
504 normalize-nodes = nodes: lib.remove null (lib.flatten nodes);
456 in 505 in
457 [ (flag "prefer-no-csd") 506 normalize-nodes [
507 (flag "prefer-no-csd")
458 508
459 (leaf "screenshot-path" "~/screenshots/%Y-%m-%dT%H:%M:%S.png") 509 (sleaf "screenshot-path" "~/screenshots/%Y-%m-%dT%H:%M:%S.png")
460 510
461 (plain "hotkey-overlay" [ 511 (plain "hotkey-overlay" [
462 (flag "skip-at-startup") 512 (flag "skip-at-startup")
@@ -464,27 +514,27 @@ in {
464 514
465 (plain "input" [ 515 (plain "input" [
466 (plain "keyboard" [ 516 (plain "keyboard" [
467 (leaf "repeat-delay" 300) 517 (sleaf "repeat-delay" 300)
468 (leaf "repeat-rate" 50) 518 (sleaf "repeat-rate" 50)
469 519
470 (plain "xkb" [ 520 (plain "xkb" [
471 (leaf "layout" "us,us") 521 (sleaf "layout" "us,us")
472 (leaf "variant" "dvp,") 522 (sleaf "variant" "dvp,")
473 (leaf "options" "compose:caps,grp:win_space_toggle") 523 (sleaf "options" "compose:caps,grp:win_space_toggle")
474 ]) 524 ])
475 ]) 525 ])
476 526
477 (flag "workspace-auto-back-and-forth") 527 (flag "workspace-auto-back-and-forth")
478 # (leaf "focus-follows-mouse" {}) 528 # (sleaf "focus-follows-mouse" {})
479 # (flag "warp-mouse-to-focus") 529 # (flag "warp-mouse-to-focus")
480 530
481 # (plain "touchpad" [ (flag "off") ]) 531 # (plain "touchpad" [ (flag "off") ])
482 (plain "trackball" [ 532 (plain "trackball" [
483 (leaf "scroll-method" "on-button-down") 533 (sleaf "scroll-method" "on-button-down")
484 (leaf "scroll-button" 278) 534 (sleaf "scroll-button" 278)
485 ]) 535 ])
486 (plain "touch" [ 536 (plain "touch" [
487 (leaf "map-to-output" "eDP-1") 537 (sleaf "map-to-output" "eDP-1")
488 ]) 538 ])
489 ]) 539 ])
490 540
@@ -492,7 +542,7 @@ in {
492 (plain "hot-corners" [(flag "off")]) 542 (plain "hot-corners" [(flag "off")])
493 ]) 543 ])
494 544
495 (plain "environment" (lib.mapAttrsToList leaf { 545 (plain "environment" (lib.mapAttrsToList sleaf {
496 NIXOS_OZONE_WL = "1"; 546 NIXOS_OZONE_WL = "1";
497 QT_QPA_PLATFORM = "wayland"; 547 QT_QPA_PLATFORM = "wayland";
498 QT_WAYLAND_DISABLE_WINDOWDECORATION = "1"; 548 QT_WAYLAND_DISABLE_WINDOWDECORATION = "1";
@@ -500,49 +550,52 @@ in {
500 SDL_VIDEODRIVER = "wayland"; 550 SDL_VIDEODRIVER = "wayland";
501 DISPLAY = ":0"; 551 DISPLAY = ":0";
502 ELECTRON_OZONE_PLATFORM_HINT = "auto"; 552 ELECTRON_OZONE_PLATFORM_HINT = "auto";
553 SSH_ASKPASS_REQUIRE = "prefer";
554 SSH_ASKPASS = lib.getExe pkgs.kdePackages.ksshaskpass;
555 SUDO_ASKPASS = lib.getExe pkgs.kdePackages.ksshaskpass;
503 })) 556 }))
504 557
505 (node "output" "eDP-1" [ 558 (node "output" ["eDP-1"] [
506 (leaf "scale" 1.5) 559 (sleaf "scale" 1.5)
507 (leaf "position" { x = 0; y = 0; }) 560 (sleaf "position" { x = 0; y = 0; })
508 ]) 561 ])
509 (node "output" "Ancor Communications Inc ASUS PB287Q 0x0000DD9B" [ 562 (node "output" ["Ancor Communications Inc ASUS PB287Q 0x0000DD9B"] [
510 (leaf "scale" 1.5) 563 (sleaf "scale" 1.5)
511 (leaf "position" { x = 2560; y = 0; }) 564 (sleaf "position" { x = 2560; y = 0; })
512 ]) 565 ])
513 (node "output" "HP Inc. HP 727pu CN4417143K" [ 566 (node "output" ["HP Inc. HP 727pu CN4417143K"] [
514 (leaf "mode" "2560x1440@119.998") 567 (sleaf "mode" "2560x1440@119.998")
515 (leaf "scale" 1) 568 (sleaf "scale" 1)
516 (leaf "position" { x = 2560; y = 0; }) 569 (sleaf "position" { x = 2560; y = 0; })
517 (flag "variable-refresh-rate") 570 (flag "variable-refresh-rate")
518 ]) 571 ])
519 572
520 (plain "debug" [ 573 (plain "debug" [
521 (leaf "render-drm-device" "/dev/dri/by-path/pci-0000:00:02.0-render") 574 (sleaf "render-drm-device" "/dev/dri/by-path/pci-0000:00:02.0-render")
522 ]) 575 ])
523 576
524 (plain "animations" [ 577 (plain "animations" [
525 (leaf "slowdown" 0.5) 578 (sleaf "slowdown" 0.5)
526 (plain "workspace-switch" [(flag "off")]) 579 (plain "workspace-switch" [(flag "off")])
527 ]) 580 ])
528 581
529 (plain "layout" [ 582 (plain "layout" [
530 (leaf "gaps" 8) 583 (sleaf "gaps" 8)
531 (plain "struts" [ 584 (plain "struts" [
532 (leaf "left" 26) 585 (sleaf "left" 26)
533 (leaf "right" 26) 586 (sleaf "right" 26)
534 (leaf "top" 0) 587 (sleaf "top" 0)
535 (leaf "bottom" 0) 588 (sleaf "bottom" 0)
536 ]) 589 ])
537 (plain "border" [ 590 (plain "border" [
538 (leaf "width" 2) 591 (sleaf "width" 2)
539 (leaf "active-gradient" { 592 (sleaf "active-gradient" {
540 from = "hsla(195 100% 45% 1)"; 593 from = "hsla(195 100% 45% 1)";
541 to = "hsla(155 100% 37.5% 1)"; 594 to = "hsla(155 100% 37.5% 1)";
542 angle = 29; 595 angle = 29;
543 relative-to = "workspace-view"; 596 relative-to = "workspace-view";
544 }) 597 })
545 (leaf "inactive-gradient" { 598 (sleaf "inactive-gradient" {
546 from = "hsla(0 0% 27.7% 1)"; 599 from = "hsla(0 0% 27.7% 1)";
547 to = "hsla(0 0% 23% 1)"; 600 to = "hsla(0 0% 23% 1)";
548 angle = 29; 601 angle = 29;
@@ -553,29 +606,29 @@ in {
553 (flag "off") 606 (flag "off")
554 ]) 607 ])
555 608
556 (plain "preset-column-widths" (map (prop: leaf "proportion" prop) [ 609 (plain "preset-column-widths" (map (prop: sleaf "proportion" prop) [
557 (1. / 4.) (1. / 3.) (1. / 2.) (2. / 3.) (3. / 4.) (1.) 610 (1. / 4.) (1. / 3.) (1. / 2.) (2. / 3.) (3. / 4.) (1.)
558 ])) 611 ]))
559 (plain "default-column-width" [ (leaf "proportion" (1. / 2.)) ]) 612 (plain "default-column-width" [ (sleaf "proportion" (1. / 2.)) ])
560 (plain "preset-window-heights" (map (prop: leaf "proportion" prop) [ 613 (plain "preset-window-heights" (map (prop: sleaf "proportion" prop) [
561 (1. / 3.) (1. / 2.) (2. / 3.) (1.) 614 (1. / 3.) (1. / 2.) (2. / 3.) (1.)
562 ])) 615 ]))
563 616
564 (flag "always-center-single-column") 617 (flag "always-center-single-column")
565 618
566 (plain "tab-indicator" [ 619 (plain "tab-indicator" [
567 (leaf "gap" 4) 620 (sleaf "gap" 4)
568 (leaf "width" 8) 621 (sleaf "width" 8)
569 (leaf "gaps-between-tabs" 4) 622 (sleaf "gaps-between-tabs" 4)
570 (flag "place-within-column") 623 (flag "place-within-column")
571 (leaf "length" { total-proportion = 1.; }) 624 (sleaf "length" { total-proportion = 1.; })
572 (leaf "active-gradient" { 625 (sleaf "active-gradient" {
573 from = "hsla(195 100% 60% 0.75)"; 626 from = "hsla(195 100% 60% 0.75)";
574 to = "hsla(155 100% 50% 0.75)"; 627 to = "hsla(155 100% 50% 0.75)";
575 angle = 29; 628 angle = 29;
576 relative-to = "workspace-view"; 629 relative-to = "workspace-view";
577 }) 630 })
578 (leaf "inactive-gradient" { 631 (sleaf "inactive-gradient" {
579 from = "hsla(0 0% 42% 0.66)"; 632 from = "hsla(0 0% 42% 0.66)";
580 to = "hsla(0 0% 35% 0.66)"; 633 to = "hsla(0 0% 35% 0.66)";
581 angle = 29; 634 angle = 29;
@@ -589,129 +642,140 @@ in {
589 ]) 642 ])
590 643
591 (map (name: 644 (map (name:
592 (node "workspace" name [ 645 (node "workspace" [name] [
593 (leaf "open-on-output" "eDP-1") 646 (sleaf "open-on-output" "eDP-1")
594 ]) 647 ])
595 ) (map ({name, ...}: name) cfg.scratchspaces)) 648 ) (map ({name, ...}: name) cfg.scratchspaces))
596 (map (name: 649 (map (name:
597 (leaf "workspace" name) 650 (sleaf "workspace" name)
598 ) ["comm" "web" "vid" "bmr"]) 651 ) ["comm" "web" "vid" "bmr"])
599 652
600 (plain "window-rule" [ 653 (plain "window-rule" [
601 (leaf "clip-to-geometry" true) 654 (sleaf "clip-to-geometry" true)
602 ]) 655 ])
603 656
604 (plain "window-rule" [ 657 (plain "window-rule" [
605 (leaf "match" { is-floating = true; }) 658 (sleaf "match" { is-floating = true; })
606 (leaf "geometry-corner-radius" 8) 659 (sleaf "geometry-corner-radius" 8)
607 (plain "shadow" [ (flag "on") ]) 660 (plain "shadow" [ (flag "on") ])
608 ]) 661 ])
609 662
610 (plain "window-rule" [ 663 (plain "window-rule" [
611 (leaf "match" { app-id = "^org\\.keepassxc\\.KeePassXC$"; }) 664 (sleaf "match" { app-id = "^org\\.keepassxc\\.KeePassXC$"; })
612 (leaf "block-out-from" "screencast") 665 (sleaf "block-out-from" "screencast")
613 ]) 666 ])
614 (plain "window-rule" [ 667 (plain "window-rule" (normalize-nodes [
615 (map (title: 668 (map (title:
616 (leaf "match" { app-id = "^org\\.keepassxc\\.KeePassXC$"; inherit title; }) 669 (sleaf "match" { app-id = "^org\\.keepassxc\\.KeePassXC$"; inherit title; })
617 ) ["^Unlock Database.*" "^Access Request.*" ".*Passkey credentials$"]) 670 ) ["^Unlock Database.*" "^Access Request.*" ".*Passkey credentials$" "Browser Access Request$"])
618 (leaf "open-focused" true) 671 (sleaf "open-focused" true)
619 (leaf "open-floating" true) 672 (sleaf "open-floating" true)
620 ]) 673 ]))
621 674
622 (map ({ name, match, exclude, windowRuleExtra, ... }: 675 (map ({ name, match, exclude, windowRuleExtra, ... }:
623 (optional-node (match != []) (plain "window-rule" [ 676 (optional-node (match != []) (plain "window-rule" (normalize-nodes [
624 (map (leaf "match") match) 677 (map (sleaf "match") match)
625 (map (leaf "exclude") exclude) 678 (map (sleaf "exclude") exclude)
626 (leaf "open-on-workspace" name) 679 (sleaf "open-on-workspace" name)
627 (leaf "open-maximized" true) 680 (sleaf "open-maximized" true)
628 windowRuleExtra 681 windowRuleExtra
629 ])) 682 ])))
630 ) cfg.scratchspaces) 683 ) cfg.scratchspaces)
631 684
632 (plain "window-rule" [ 685 (plain "window-rule" [
633 (leaf "match" { app-id = "^emacs$"; }) 686 (sleaf "match" { app-id = "^emacs$"; })
634 (leaf "match" { app-id = "^firefox$"; }) 687 (sleaf "match" { app-id = "^firefox$"; })
635 (plain "default-column-width" [(leaf "proportion" (2. / 3.))]) 688 (plain "default-column-width" [(sleaf "proportion" (2. / 3.))])
636 ]) 689 ])
637 (plain "window-rule" [ 690 (plain "window-rule" [
638 (leaf "match" { app-id = "^kitty$"; }) 691 (sleaf "match" { app-id = "^kitty$"; })
639 (leaf "match" { app-id = "^kitty-play$"; }) 692 (sleaf "match" { app-id = "^kitty-play$"; })
640 (plain "default-column-width" [(leaf "proportion" (1. / 3.))]) 693 (plain "default-column-width" [(sleaf "proportion" (1. / 3.))])
641 ]) 694 ])
642 695
643 (plain "window-rule" [ 696 (plain "window-rule" [
644 (leaf "match" { app-id = "^thunderbird$"; }) 697 (sleaf "match" { app-id = "^thunderbird$"; })
645 (leaf "match" { app-id = "^Element$"; }) 698 (sleaf "match" { app-id = "^Element$"; })
646 (leaf "match" { app-id = "^Rainbow$"; }) 699 (sleaf "match" { app-id = "^chrome-web\.openrainbow\.com__-Default$"; })
647 (leaf "open-on-workspace" "comm") 700 (sleaf "open-on-workspace" "comm")
648 ]) 701 ])
649 (plain "window-rule" [ 702 (plain "window-rule" [
650 (leaf "match" { app-id = "^firefox$"; }) 703 (sleaf "match" { app-id = "^firefox$"; })
651 (leaf "open-on-workspace" "web") 704 (sleaf "open-on-workspace" "web")
652 (leaf "open-maximized" true) 705 (sleaf "open-maximized" true)
653 ]) 706 ])
654 (plain "window-rule" [ 707 (plain "window-rule" [
655 (leaf "match" { app-id = "^mpv$"; }) 708 (sleaf "match" { app-id = "^mpv$"; })
656 (leaf "open-on-workspace" "vid") 709 (sleaf "open-on-workspace" "vid")
657 (plain "default-column-width" [(leaf "proportion" 1.)]) 710 (plain "default-column-width" [(sleaf "proportion" 1.)])
658 ]) 711 ])
659 (plain "window-rule" [ 712 (plain "window-rule" [
660 (leaf "match" { app-id = "^kitty-play$"; }) 713 (sleaf "match" { app-id = "^kitty-play$"; })
661 (leaf "open-on-workspace" "vid") 714 (sleaf "open-on-workspace" "vid")
662 (leaf "open-focused" false) 715 (sleaf "open-focused" false)
663 ]) 716 ])
664 (plain "window-rule" [ 717 (plain "window-rule" [
665 (leaf "match" { app-id = "^pdfpc$"; }) 718 (sleaf "match" { app-id = "^chrome-audiobookshelf\.yggdrasil\.li__-Default$"; })
666 (plain "default-column-width" [(leaf "proportion" 1.)]) 719 (sleaf "match" { app-id = "^YouTube Music Desktop App$"; })
720 (sleaf "open-on-workspace" "vid")
667 ]) 721 ])
668 (plain "window-rule" [ 722 (plain "window-rule" [
669 (leaf "match" { app-id = "^pdfpc$"; title = "^.*presentation.*$"; }) 723 (sleaf "match" { app-id = "^pdfpc$"; })
670 (plain "default-column-width" [(leaf "proportion" 1.)]) 724 (plain "default-column-width" [(sleaf "proportion" 1.)])
671 (leaf "open-fullscreen" true)
672 (leaf "open-on-workspace" "bmr")
673 (leaf "open-focused" false)
674 ]) 725 ])
675 (plain "window-rule" [ 726 (plain "window-rule" [
676 (map (leaf "match") [ 727 (sleaf "match" { app-id = "^pdfpc$"; title = "^.*presentation.*$"; })
728 (plain "default-column-width" [(sleaf "proportion" 1.)])
729 (sleaf "open-fullscreen" true)
730 (sleaf "open-on-workspace" "bmr")
731 (sleaf "open-focused" false)
732 ])
733 (plain "window-rule" (normalize-nodes [
734 (map (sleaf "match") [
677 { app-id = "^Gimp-"; title = "^Quit GIMP$"; } 735 { app-id = "^Gimp-"; title = "^Quit GIMP$"; }
678 { app-id = "^org\\.kde\\.polkit-kde-authentication-agent-1$"; } 736 { app-id = "^org\\.kde\\.polkit-kde-authentication-agent-1$"; }
679 { app-id = "^xdg-desktop-portal-gtk$"; } 737 { app-id = "^xdg-desktop-portal-gtk$"; }
680 ]) 738 ])
681 (leaf "open-floating" true) 739 (sleaf "open-floating" true)
682 ]) 740 ]))
683 (plain "window-rule" [ 741 (plain "window-rule" [
684 (leaf "match" { app-id = "^org\\.pwmt\\.zathura$"; }) 742 (sleaf "match" { app-id = "^org\\.pwmt\\.zathura$"; })
685 (leaf "match" { app-id = "^evince$"; }) 743 (sleaf "match" { app-id = "^evince$"; })
686 (leaf "match" { app-id = "^org\\.gnome\\.Papers$"; }) 744 (sleaf "match" { app-id = "^org\\.gnome\\.Papers$"; })
687 (leaf "default-column-display" "tabbed") 745 (sleaf "default-column-display" "tabbed")
688 ]) 746 ])
689 747
690 (plain "layer-rule" [ 748 (plain "layer-rule" [
691 (leaf "match" { namespace = "^notifications$"; }) 749 (sleaf "match" { namespace = "^notifications$"; })
692 (leaf "match" { namespace = "^waybar$"; }) 750 (sleaf "match" { namespace = "^waybar$"; })
693 (leaf "match" { namespace = "^launcher$"; }) 751 (sleaf "match" { namespace = "^launcher$"; })
694 (leaf "block-out-from" "screencast") 752 (sleaf "block-out-from" "screencast")
695 ]) 753 ])
696 754
697 (plain "binds" 755 (plain "binds"
698 (let 756 (let
699 bind = name: cfg: node name (opt-props { 757 bind = name: cfg: node name [(lib.removeAttrs cfg ["action"])] (lib.mapAttrsToList leaf (lib.removeAttrs cfg.action ["__functor"]));
700 cooldown-ms = cfg.cooldown-ms or null;
701 }
702 // (lib.optionalAttrs (!(cfg.repeat or true)) {
703 repeat = false;
704 })
705 // (lib.optionalAttrs (cfg.allow-when-locked or false) {
706 allow-when-locked = true;
707 })) (lib.mapAttrsToList leaf (lib.removeAttrs cfg.action ["__functor"]));
708 in 758 in
709 [ 759 normalize-nodes [
710 (lib.mapAttrsToList bind (with config.lib.niri.actions; { 760 (lib.mapAttrsToList bind (with config.lib.niri.actions; {
711 "Mod+Slash".action = show-hotkey-overlay; 761 "Mod+Slash".action = show-hotkey-overlay;
712 762
713 "Mod+Return".action = spawn terminal; 763 "Mod+Return".action = spawn terminal;
714 "Mod+Shift+Return".action = spawn terminal (lib.getExe config.programs.nushell.package); 764 "Mod+Shift+Return".action =
765 let
766 nushellKitty = pkgs.symlinkJoin {
767 name = "nushell-kitty";
768 paths = [ config.programs.kitty.package ];
769 buildInputs = [ pkgs.makeWrapper ];
770 postBuild = ''
771 wrapProgram $out/bin/kitty \
772 --add-flags "--config ${pkgs.writeText "kitty.conf" ''
773 include $HOME/${config.xdg.configFile."kitty/kitty.conf".target}
774 shell ${lib.getExe config.programs.nushell.package}
775 ''}"
776 '';
777 };
778 in spawn (lib.getExe' nushellKitty "kitty");
715 "Mod+Q".action = close-window; 779 "Mod+Q".action = close-window;
716 "Mod+O".action = spawn (lib.getExe config.programs.fuzzel.package); 780 "Mod+O".action = spawn (lib.getExe config.programs.fuzzel.package);
717 "Mod+Shift+O".action = spawn (lib.getExe config.programs.fuzzel.package) "--list-executables-in-path"; 781 "Mod+Shift+O".action = spawn (lib.getExe config.programs.fuzzel.package) "--list-executables-in-path";
@@ -747,12 +811,12 @@ in {
747 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) 811 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)
748 $FOUND || echo 812 $FOUND || echo
749 } 813 }
750 FUZZEL_RES=$(prev | fuzzel --dmenu --prompt "qalc> ") || exit $? 814 FUZZEL_RES=$(prev | fuzzel --dmenu --prompt "qalc> " --width=60) || exit $?
751 if [[ "$FUZZEL_RES" =~ .*\ =\ .* ]]; then 815 if [[ "$FUZZEL_RES" =~ .*\ =\ .* ]]; then
752 QALC_RES="$FUZZEL_RES" 816 QALC_RES="$FUZZEL_RES"
753 QALC_RET=0 817 QALC_RET=0
754 else 818 else
755 QALC_RES=$(qalc "$FUZZEL_RES" 2>&1) 819 QALC_RES=$(qalc -set "autocalc off" "$FUZZEL_RES" 2>&1)
756 QALC_RET=$? 820 QALC_RET=$?
757 fi 821 fi
758 [[ -n "$QALC_RES" ]] || exit 1 822 [[ -n "$QALC_RES" ]] || exit 1
@@ -772,11 +836,26 @@ in {
772 notify-send "$QALC_RES" 836 notify-send "$QALC_RES"
773 ''; 837 '';
774 })); 838 }));
839 "Mod+Shift+U".action =
840 let
841 qalcKitty = pkgs.symlinkJoin {
842 name = "qalc-kitty";
843 paths = [ config.programs.kitty.package ];
844 buildInputs = [ pkgs.makeWrapper ];
845 postBuild = ''
846 wrapProgram $out/bin/kitty \
847 --add-flags "--config ${pkgs.writeText "kitty.conf" ''
848 include $HOME/${config.xdg.configFile."kitty/kitty.conf".target}
849 shell ${lib.getExe pkgs.libqalculate}
850 ''}"
851 '';
852 };
853 in spawn (lib.getExe' qalcKitty "kitty");
775 "Mod+E".action = spawn (lib.getExe (pkgs.writeShellApplication { 854 "Mod+E".action = spawn (lib.getExe (pkgs.writeShellApplication {
776 name = "emoji-fuzzel"; 855 name = "emoji-fuzzel";
777 runtimeInputs = with pkgs; [ config.programs.fuzzel.package wtype wl-clipboard-rs ]; 856 runtimeInputs = with pkgs; [ config.programs.fuzzel.package wtype wl-clipboard-rs ];
778 text = '' 857 text = ''
779 FUZZEL_RES=$(fuzzel --dmenu --prompt "emoji> " <"$HOME"/.local/share/emoji-data/list.txt) || exit $? 858 FUZZEL_RES=$(fuzzel --dmenu --prompt "emoji> " --cache "$HOME"/.cache/fuzzel-emoji --width=60 <"$HOME"/.local/share/emoji-data/list.txt) || exit $?
780 [[ -n "$FUZZEL_RES" ]] || exit 1 859 [[ -n "$FUZZEL_RES" ]] || exit 1
781 wl-copy "$(cut -d ':' -f 1 <<<"$FUZZEL_RES" | tr -d '\n')" && wtype -k XF86Paste 860 wl-copy "$(cut -d ':' -f 1 <<<"$FUZZEL_RES" | tr -d '\n')" && wtype -k XF86Paste
782 ''; 861 '';
@@ -837,7 +916,7 @@ in {
837 "Mod+Shift+Asterisk".action = kdl.magic-leaf "move-column-to-workspace" "vid"; 916 "Mod+Shift+Asterisk".action = kdl.magic-leaf "move-column-to-workspace" "vid";
838 917
839 "Mod+Plus".action = with-unnamed-workspace-action ''{"Action":{"FocusWorkspace":{"reference":{"Id": .id}}}}''; 918 "Mod+Plus".action = with-unnamed-workspace-action ''{"Action":{"FocusWorkspace":{"reference":{"Id": .id}}}}'';
840 "Mod+Shift+Plus".action = with-unnamed-workspace-action ''{"Action":{"MoveColumnToWorkspace":{"reference":{"Id": .id}}}}''; 919 "Mod+Shift+Plus".action = with-unnamed-workspace-action ''{"Action":{"MoveColumnToWorkspace":{"reference":{"Id": .id}, "focus": true}}}'';
841 920
842 "Mod+M".action = consume-or-expel-window-left; 921 "Mod+M".action = consume-or-expel-window-left;
843 "Mod+W".action = consume-or-expel-window-right; 922 "Mod+W".action = consume-or-expel-window-right;
@@ -909,13 +988,20 @@ in {
909 "Mod+Comma".action = spawn makoctl "restore"; 988 "Mod+Comma".action = spawn makoctl "restore";
910 989
911 "Mod+Control+W".action = with-empty-unnamed-workspace-action "{\"Action\":{\"FocusWorkspace\":{\"reference\":{\"Id\": $workspace_id}}}}"; 990 "Mod+Control+W".action = with-empty-unnamed-workspace-action "{\"Action\":{\"FocusWorkspace\":{\"reference\":{\"Id\": $workspace_id}}}}";
912 "Mod+Control+Shift+W".action = with-empty-unnamed-workspace-action "{\"Action\":{\"MoveColumnToWorkspace\":{\"reference\":{\"Id\": $workspace_id}}}}"; 991 "Mod+Control+Shift+W".action = with-empty-unnamed-workspace-action "{\"Action\":{\"MoveColumnToWorkspace\":{\"reference\":{\"Id\": $workspace_id}, \"focus\": true}}}";
913 992
914 "Mod+X".action = set-dynamic-cast-window; 993 "Mod+X".action = set-dynamic-cast-window;
915 "Mod+Shift+X".action = set-dynamic-cast-monitor; 994 "Mod+Shift+X".action = set-dynamic-cast-monitor;
916 "Mod+Control+Shift+X".action = clear-dynamic-cast-target; 995 "Mod+Control+Shift+X".action = clear-dynamic-cast-target;
996
997 "Mod+D".action = with-urgent-window-action "{\"Action\":{\"FocusWindow\":{\"id\": .id}}}";
998 "Mod+Shift+D".action = with-focused-window-action "{\"Action\":{\"UnsetUrgent\":{\"id\": .id}}}";
999
1000 "Mod+K".action = spawn (lib.getExe' pkgs.worktime "worktime-ui");
1001 "Mod+Shift+K".action = spawn (lib.getExe' pkgs.worktime "worktime-stop");
917 })) 1002 }))
918 (map ({ name, selector, spawn, key, ...}: if key != null && selector != null && spawn != null then bind key { action = focus-or-spawn-action selector name spawn; } else null) cfg.scratchspaces) 1003 (map ({ name, selector, spawn, key, ...}: if key != null && selector != null && spawn != null then bind key { action = focus-or-spawn-action selector name spawn; } else null) cfg.scratchspaces)
1004 (map ({ name, moveKey, ...}: if moveKey != null then bind moveKey { action = kdl.magic-leaf "move-column-to-workspace" name; } else null) cfg.scratchspaces)
919 ] 1005 ]
920 )) 1006 ))
921 ]; 1007 ];
diff --git a/accounts/gkleen@sif/niri/mako.nix b/accounts/gkleen@sif/niri/mako.nix
index 274441ab..eba26caa 100644
--- a/accounts/gkleen@sif/niri/mako.nix
+++ b/accounts/gkleen@sif/niri/mako.nix
@@ -21,9 +21,11 @@
21 "urgency=critical".background-color = "#900000dd"; 21 "urgency=critical".background-color = "#900000dd";
22 "app-name=Element".group-by = "summary"; 22 "app-name=Element".group-by = "summary";
23 "app-name=poweralertd" = { 23 "app-name=poweralertd" = {
24 history = false;
24 ignore-timeout = true; 25 ignore-timeout = true;
25 default-timeout = 2000; 26 default-timeout = 2000;
26 }; 27 };
28 "app-name=worktime".history = false;
27 "mode=silent".invisible = true; 29 "mode=silent".invisible = true;
28 }; 30 };
29 package = pkgs.symlinkJoin { 31 package = pkgs.symlinkJoin {
diff --git a/accounts/gkleen@sif/niri/waybar.nix b/accounts/gkleen@sif/niri/waybar.nix
index cc131c08..c02a9a76 100644
--- a/accounts/gkleen@sif/niri/waybar.nix
+++ b/accounts/gkleen@sif/niri/waybar.nix
@@ -27,8 +27,14 @@ in {
27 modules-right = [ "custom/worktime" "custom/worktime-today" 27 modules-right = [ "custom/worktime" "custom/worktime-today"
28 "custom/weather" 28 "custom/weather"
29 "custom/keymap" 29 "custom/keymap"
30 "privacy" "tray" "wireplumber" "backlight" "battery" "idle_inhibitor" "custom/mako" "clock" ]; 30 "privacy" "tray" "wireplumber" "backlight" "battery" "idle_inhibitor" "custom/mako" "custom/lid_inhibitor" "clock" ];
31 31
32 "custom/lid_inhibitor" = {
33 format = "{}";
34 return-type = "json";
35 exec = lib.getExe pkgs.waybar-systemd-inhibit;
36 on-click = lib.getExe' pkgs.waybar-systemd-inhibit "waybar-systemd-inhibit-toggle";
37 };
32 "custom/mako" = { 38 "custom/mako" = {
33 format = "{}"; 39 format = "{}";
34 return-type = "json"; 40 return-type = "json";
@@ -211,7 +217,7 @@ in {
211 layer = "top"; 217 layer = "top";
212 position = "top"; 218 position = "top";
213 height = 14; 219 height = 14;
214 output = [ "!eDP-1" "!DP-2" "!DP-3" ]; 220 output = [ "!eDP-1" "!DP-2" "!DP-3" "*" ];
215 modules-left = [ "niri/workspaces" ]; 221 modules-left = [ "niri/workspaces" ];
216 modules-center = [ "niri/window" ]; 222 modules-center = [ "niri/window" ];
217 modules-right = [ "clock" ]; 223 modules-right = [ "clock" ];
@@ -293,7 +299,7 @@ in {
293 #tray { 299 #tray {
294 margin: 0; 300 margin: 0;
295 } 301 }
296 #battery, #idle_inhibitor, #backlight, #wireplumber, #custom-mako { 302 #battery, #idle_inhibitor, #backlight, #wireplumber, #custom-mako, #custom-lid_inhibitor {
297 color: @grey; 303 color: @grey;
298 margin: 0 5px 0 2px; 304 margin: 0 5px 0 2px;
299 } 305 }
@@ -302,7 +308,11 @@ in {
302 margin-left: 6px; 308 margin-left: 6px;
303 } 309 }
304 #custom-mako { 310 #custom-mako {
305 margin-right: 2px; 311 margin-right: 4px;
312 margin-left: 3px;
313 }
314 #custom-lid_inhibitor {
315 margin-right: 3px;
306 margin-left: 3px; 316 margin-left: 3px;
307 } 317 }
308 #battery { 318 #battery {
@@ -330,7 +340,7 @@ in {
330 color: @orange; 340 color: @orange;
331 } 341 }
332 342
333 #idle_inhibitor { 343 #idle_inhibitor, #custom-lid_inhibitor {
334 padding-top: 1px; 344 padding-top: 1px;
335 } 345 }
336 346
@@ -340,6 +350,7 @@ in {
340 } 350 }
341 #clock { 351 #clock {
342 /* margin-right: 5px; */ 352 /* margin-right: 5px; */
353 font-feature-settings: "tnum";
343 } 354 }
344 ''; 355 '';
345 }; 356 };
diff --git a/accounts/gkleen@sif/synadm/default.nix b/accounts/gkleen@sif/synadm/default.nix
new file mode 100644
index 00000000..0a8e0d4c
--- /dev/null
+++ b/accounts/gkleen@sif/synadm/default.nix
@@ -0,0 +1,9 @@
1{ config, pkgs, ... }:
2{
3 home.packages = with pkgs; [ synadm ];
4 sops.secrets."synadm.yaml" = {
5 format = "binary";
6 sopsFile = ./synadm_yaml;
7 path = config.xdg.configHome + "/synadm.yaml";
8 };
9}
diff --git a/accounts/gkleen@sif/synadm/synadm_yaml b/accounts/gkleen@sif/synadm/synadm_yaml
new file mode 100644
index 00000000..8d951ccc
--- /dev/null
+++ b/accounts/gkleen@sif/synadm/synadm_yaml
@@ -0,0 +1,15 @@
1{
2 "data": "ENC[AES256_GCM,data:qJy4Pmbbxja4jmW7OaHsD0mQZ7anZwLhiVmAgkavb+CqwWGDnUBXdz22/MHCbxng5NshcFSpBoCBhgY6B9V2bUiES6bH9AtMlDcs9ebKGMArBTUTnQ2MjWQGfQTqraWdNgy+n327uj9swwCH8EZXdYH/Hlv0t/re470W+VOHeXhGghQ3Y9IGz2sgfvMGr8QxaJNydZz85rgs5QUP/PglCwWIOw2mY1EX2vYwnmiAo49LmIEaxWvRi++KHaeBveDt0nlkJwzUlipL2VOKWxkgpK3yGucQn2mz+FRe1btp+4KGm8H17eUI9FO9sBwq,iv:kgM921ovwCgDYHQj3c5Rupy/8JxHehxUD2jb1k9Ik2Y=,tag:3TLQkJbv679VWy8V2TMugw==,type:str]",
3 "sops": {
4 "age": [
5 {
6 "recipient": "age1rmmhetcmllq0ahl5qznlr0eya2zdxwl9h6y5wnl97d2wtyx5t99sm2u866",
7 "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6bzVHUGNxZTF2WC9MYmZr\neGdVVzJXN3lGdEk3cTBER3J6UTFtcUJna2d3CjdNQmRXd2haZW1MYlJzNkk1dWVD\nVTFQc2gvS0JrejJ6SFh2MXpPWDZpRE0KLS0tIE0wTC85bEpvSnlGdGFkZVFhNjFZ\nbzRiZkxMWUg2ODNVUlBmNFlPNGRrZlkK1VXLJWcssv3ETyZSSM/Hhn5VIaI9iov9\nzShZA9Zx/FX6PYTuUMC29pJ57gKourcIxa/7HwSv/xYn1A6WcYfgSg==\n-----END AGE ENCRYPTED FILE-----\n"
8 }
9 ],
10 "lastmodified": "2025-05-18T11:03:42Z",
11 "mac": "ENC[AES256_GCM,data:yonJC68PhilAgEHNNJQ8nO53Qo3rx/LnfiOWfuMm24bOUIH9QM3WZZxpigd7bHI4eC4TqRb4LvcSi0nEURTRAhwiTqGNrWbpw2Iv3n5dhLEN9aTcetG5ZuhaXqfVUoML45/ovdBZG/0l8+XIHqxN2M/g/h4JwKoR/6lqzcrVhgo=,iv:xvxBJwy+E5zUdjhGPdZPdy7tnBIEj50hfiDJFsS3wNg=,tag:L4Fas36ZOg4h0QQwC4gjNA==,type:str]",
12 "unencrypted_suffix": "_unencrypted",
13 "version": "3.10.2"
14 }
15}
diff --git a/accounts/gkleen@sif/systemd.nix b/accounts/gkleen@sif/systemd.nix
index 90cccc58..18c2315f 100644
--- a/accounts/gkleen@sif/systemd.nix
+++ b/accounts/gkleen@sif/systemd.nix
@@ -385,6 +385,8 @@ in {
385 }; 385 };
386 Service = { 386 Service = {
387 ExecStart = "${config.systemd.package}/lib/systemd/systemd-socket-proxyd --exit-idle-time=60s 127.0.0.1:${toString (port + 1)}"; 387 ExecStart = "${config.systemd.package}/lib/systemd/systemd-socket-proxyd --exit-idle-time=60s 127.0.0.1:${toString (port + 1)}";
388 Restart = "always";
389 RestartSec = "23s";
388 }; 390 };
389 }) [{ host = "proxy.ssh.math.lmu.de"; port = 8118; } { host = "proxy.vidhar"; port = 8120; } { host = "proxy.mathw0h"; port = 8122; } { host = "proxy.mathw0e"; port = 8124; }]); 391 }) [{ host = "proxy.ssh.math.lmu.de"; port = 8118; } { host = "proxy.vidhar"; port = 8120; } { host = "proxy.mathw0h"; port = 8122; } { host = "proxy.mathw0e"; port = 8124; }]);
390 sockets = listToAttrs (map (port: nameValuePair "proxy-to-autossh-socks@${toString port}" { 392 sockets = listToAttrs (map (port: nameValuePair "proxy-to-autossh-socks@${toString port}" {
diff --git a/accounts/gkleen@sif/utils/async-yt-dlp.nix b/accounts/gkleen@sif/utils/async-yt-dlp.nix
new file mode 100644
index 00000000..c3b82ec5
--- /dev/null
+++ b/accounts/gkleen@sif/utils/async-yt-dlp.nix
@@ -0,0 +1,57 @@
1{ writers, python3Packages, ... }:
2
3writers.writePython3Bin "async-yt-dlp" {
4 libraries = with python3Packages; [ yt-dlp ];
5 flakeIgnore = ["E501"];
6} ''
7import sys
8import os
9
10import yt_dlp
11import yt_dlp.options
12from collections import namedtuple
13import socket
14from pathlib import Path
15import json
16
17create_parser = yt_dlp.options.create_parser
18
19
20def parse_patched_options(opts):
21 patched_parser = create_parser()
22 patched_parser.defaults.update({
23 'ignoreerrors': False,
24 'retries': 0,
25 'fragment_retries': 0,
26 'extract_flat': False,
27 'concat_playlist': 'never',
28 })
29 yt_dlp.options.create_parser = lambda: patched_parser
30 try:
31 return yt_dlp.parse_options(opts)
32 finally:
33 yt_dlp.options.create_parser = create_parser
34
35
36default_opts = parse_patched_options([]).ydl_opts
37
38
39def cli_to_api(opts):
40 opts = parse_patched_options(opts)
41 urls = opts.urls
42 opts = opts.ydl_opts
43
44 diff = {k: v for k, v in opts.items() if default_opts[k] != v}
45 if 'postprocessors' in diff:
46 diff['postprocessors'] = [pp for pp in diff['postprocessors']
47 if pp not in default_opts['postprocessors']]
48 return namedtuple('Options', ('params', 'urls'))(diff, urls)
49
50
51if __name__ == '__main__':
52 opts = cli_to_api(sys.argv[1:])
53 with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as sock:
54 sock.connect(str(Path(os.environ["XDG_RUNTIME_DIR"]) / "yt-dlp.sock").encode('utf-8'))
55 with sock.makefile(mode='w', buffering=1, encoding='utf-8') as fh:
56 json.dump(opts._asdict(), fh)
57''
diff --git a/accounts/gkleen@sif/zshrc b/accounts/gkleen@sif/zshrc
index abc200c6..b24ff257 100644
--- a/accounts/gkleen@sif/zshrc
+++ b/accounts/gkleen@sif/zshrc
@@ -93,7 +93,7 @@ dir() {
93 if [[ $curlArchive = "true" ]]; then 93 if [[ $curlArchive = "true" ]]; then
94 archiveFile=$(mktemp -t "archive.XXXXXXXXXX.${templateArchive:t}") 94 archiveFile=$(mktemp -t "archive.XXXXXXXXXX.${templateArchive:t}")
95 95
96 curl -L -o ${archiveFile} ${templateArchive} 96 curl -SfL -o ${archiveFile} ${templateArchive}
97 97
98 templateArchive=${archiveFile} 98 templateArchive=${archiveFile}
99 fi 99 fi
@@ -231,7 +231,7 @@ clock() {
231} 231}
232 232
233public-ip() { 233public-ip() {
234 curl -s -H 'Accept: application/json' $@ ifconfig.co | jq -r '.ip' 234 curl -sSf -H 'Accept: application/json' $@ ifconfig.co | jq -r '.ip'
235} 235}
236 236
237swap() { 237swap() {