diff options
-rw-r--r-- | .sops.yaml | 3 | ||||
-rw-r--r-- | _sources/generated.json | 40 | ||||
-rw-r--r-- | _sources/generated.nix | 28 | ||||
-rw-r--r-- | accounts/gkleen@sif/default.nix | 38 | ||||
-rw-r--r-- | accounts/gkleen@sif/emacs.el | 1 | ||||
-rw-r--r-- | accounts/gkleen@sif/niri/default.nix | 185 | ||||
-rw-r--r-- | accounts/gkleen@sif/niri/mako.nix | 10 | ||||
-rw-r--r-- | accounts/gkleen@sif/niri/swayosd.nix | 65 | ||||
-rw-r--r-- | accounts/gkleen@sif/niri/waybar.nix | 49 | ||||
-rw-r--r-- | accounts/gkleen@sif/systemd.nix | 3 | ||||
-rw-r--r-- | flake.lock | 66 | ||||
-rw-r--r-- | hosts/sif/default.nix | 12 | ||||
-rw-r--r-- | hosts/sif/greetd/wallpaper.png | bin | 132 -> 6073128 bytes | |||
-rw-r--r-- | modules/nix-access-tokens/default.nix | 24 | ||||
-rw-r--r-- | modules/nix-access-tokens/nix.conf | 32 | ||||
-rw-r--r-- | nvfetcher.toml | 18 | ||||
-rw-r--r-- | overlays/batman-adv.nix | 15 | ||||
-rw-r--r-- | overlays/keepassxc/database-open-dialog.patch | 126 | ||||
-rw-r--r-- | overlays/keepassxc/default.nix | 8 | ||||
-rw-r--r-- | overlays/swayosd/default.nix | 30 | ||||
-rw-r--r-- | overlays/swayosd/exponential.patch | 57 | ||||
-rwxr-xr-x | overlays/worktime/worktime/__main__.py | 119 |
22 files changed, 755 insertions, 174 deletions
@@ -26,3 +26,6 @@ creation_rules: | |||
26 | - path_regex: ^hosts/sif/ | 26 | - path_regex: ^hosts/sif/ |
27 | key_groups: | 27 | key_groups: |
28 | - age: [ *admin_gkleen, *machine_sif ] | 28 | - age: [ *admin_gkleen, *machine_sif ] |
29 | - path_regex: ^modules/nix-access-tokens/ | ||
30 | key_groups: | ||
31 | - age: [ *admin_gkleen, *machine_sif, *machine_surtr, *machine_vidhar ] | ||
diff --git a/_sources/generated.json b/_sources/generated.json index f73b8190..72f913ec 100644 --- a/_sources/generated.json +++ b/_sources/generated.json | |||
@@ -20,20 +20,6 @@ | |||
20 | }, | 20 | }, |
21 | "version": "8ef9a5b73e5d1063cf912c70027c655fb19d1109" | 21 | "version": "8ef9a5b73e5d1063cf912c70027c655fb19d1109" |
22 | }, | 22 | }, |
23 | "batman-adv": { | ||
24 | "cargoLocks": null, | ||
25 | "date": null, | ||
26 | "extract": null, | ||
27 | "name": "batman-adv", | ||
28 | "passthru": null, | ||
29 | "pinned": false, | ||
30 | "src": { | ||
31 | "sha256": "sha256-VYyIkH5IFfKN6EOHZxSx6AaepD3a22/hhmLhqkle5Z0=", | ||
32 | "type": "tarball", | ||
33 | "url": "https://downloads.open-mesh.org/batman/stable/sources/batman-adv/batman-adv-2024.4.tar.gz" | ||
34 | }, | ||
35 | "version": "2024.4" | ||
36 | }, | ||
37 | "bpf-examples": { | 23 | "bpf-examples": { |
38 | "cargoLocks": null, | 24 | "cargoLocks": null, |
39 | "date": "2025-01-03", | 25 | "date": "2025-01-03", |
@@ -379,6 +365,26 @@ | |||
379 | }, | 365 | }, |
380 | "version": "0.2.1" | 366 | "version": "0.2.1" |
381 | }, | 367 | }, |
368 | "swayosd": { | ||
369 | "cargoLocks": null, | ||
370 | "date": "2025-01-27", | ||
371 | "extract": null, | ||
372 | "name": "swayosd", | ||
373 | "passthru": null, | ||
374 | "pinned": false, | ||
375 | "src": { | ||
376 | "deepClone": false, | ||
377 | "fetchSubmodules": false, | ||
378 | "leaveDotGit": false, | ||
379 | "name": null, | ||
380 | "rev": "993180b5e7db1dfc453a556bf208f05b04283c8f", | ||
381 | "sha256": "sha256-qwtGkRJlCYu+dO3xCmnRexX+E4QvXRAHXUslLO7mrAI=", | ||
382 | "sparseCheckout": [], | ||
383 | "type": "git", | ||
384 | "url": "https://github.com/ErikReider/SwayOSD" | ||
385 | }, | ||
386 | "version": "993180b5e7db1dfc453a556bf208f05b04283c8f" | ||
387 | }, | ||
382 | "tomorrow-night-paradise-theme": { | 388 | "tomorrow-night-paradise-theme": { |
383 | "cargoLocks": null, | 389 | "cargoLocks": null, |
384 | "date": "2012-06-04", | 390 | "date": "2012-06-04", |
@@ -450,10 +456,10 @@ | |||
450 | "pinned": false, | 456 | "pinned": false, |
451 | "src": { | 457 | "src": { |
452 | "name": null, | 458 | "name": null, |
453 | "sha256": "sha256-6OxRXUm7YnBJFdE6Iu5v4DpWWNZR5OZFdOOhfuAfbjs=", | 459 | "sha256": "sha256-HJc4JmkhrUPFaK0BrDNi+3x69Uknb77JK9cvFA2hYkA=", |
454 | "type": "url", | 460 | "type": "url", |
455 | "url": "https://pypi.org/packages/source/y/yt_dlp/yt_dlp-2025.1.15.tar.gz" | 461 | "url": "https://pypi.org/packages/source/y/yt_dlp/yt_dlp-2025.1.26.tar.gz" |
456 | }, | 462 | }, |
457 | "version": "2025.1.15" | 463 | "version": "2025.1.26" |
458 | } | 464 | } |
459 | } \ No newline at end of file | 465 | } \ No newline at end of file |
diff --git a/_sources/generated.nix b/_sources/generated.nix index fb57de83..e25f1bda 100644 --- a/_sources/generated.nix +++ b/_sources/generated.nix | |||
@@ -16,14 +16,6 @@ | |||
16 | }; | 16 | }; |
17 | date = "2021-05-30"; | 17 | date = "2021-05-30"; |
18 | }; | 18 | }; |
19 | batman-adv = { | ||
20 | pname = "batman-adv"; | ||
21 | version = "2024.4"; | ||
22 | src = fetchTarball { | ||
23 | url = "https://downloads.open-mesh.org/batman/stable/sources/batman-adv/batman-adv-2024.4.tar.gz"; | ||
24 | sha256 = "sha256-VYyIkH5IFfKN6EOHZxSx6AaepD3a22/hhmLhqkle5Z0="; | ||
25 | }; | ||
26 | }; | ||
27 | bpf-examples = { | 19 | bpf-examples = { |
28 | pname = "bpf-examples"; | 20 | pname = "bpf-examples"; |
29 | version = "8d53e6fc46ae625bd16b38eb1007ece99460eada"; | 21 | version = "8d53e6fc46ae625bd16b38eb1007ece99460eada"; |
@@ -232,6 +224,20 @@ | |||
232 | sha256 = "sha256-7d/0fepOvdswuBGJCCMULB2kXOFBLP78yqX4NmByCF8="; | 224 | sha256 = "sha256-7d/0fepOvdswuBGJCCMULB2kXOFBLP78yqX4NmByCF8="; |
233 | }; | 225 | }; |
234 | }; | 226 | }; |
227 | swayosd = { | ||
228 | pname = "swayosd"; | ||
229 | version = "993180b5e7db1dfc453a556bf208f05b04283c8f"; | ||
230 | src = fetchgit { | ||
231 | url = "https://github.com/ErikReider/SwayOSD"; | ||
232 | rev = "993180b5e7db1dfc453a556bf208f05b04283c8f"; | ||
233 | fetchSubmodules = false; | ||
234 | deepClone = false; | ||
235 | leaveDotGit = false; | ||
236 | sparseCheckout = [ ]; | ||
237 | sha256 = "sha256-qwtGkRJlCYu+dO3xCmnRexX+E4QvXRAHXUslLO7mrAI="; | ||
238 | }; | ||
239 | date = "2025-01-27"; | ||
240 | }; | ||
235 | tomorrow-night-paradise-theme = { | 241 | tomorrow-night-paradise-theme = { |
236 | pname = "tomorrow-night-paradise-theme"; | 242 | pname = "tomorrow-night-paradise-theme"; |
237 | version = "70225a5bf90d495e13a9260bfdc268632ece0801"; | 243 | version = "70225a5bf90d495e13a9260bfdc268632ece0801"; |
@@ -272,10 +278,10 @@ | |||
272 | }; | 278 | }; |
273 | yt-dlp = { | 279 | yt-dlp = { |
274 | pname = "yt-dlp"; | 280 | pname = "yt-dlp"; |
275 | version = "2025.1.15"; | 281 | version = "2025.1.26"; |
276 | src = fetchurl { | 282 | src = fetchurl { |
277 | url = "https://pypi.org/packages/source/y/yt_dlp/yt_dlp-2025.1.15.tar.gz"; | 283 | url = "https://pypi.org/packages/source/y/yt_dlp/yt_dlp-2025.1.26.tar.gz"; |
278 | sha256 = "sha256-6OxRXUm7YnBJFdE6Iu5v4DpWWNZR5OZFdOOhfuAfbjs="; | 284 | sha256 = "sha256-HJc4JmkhrUPFaK0BrDNi+3x69Uknb77JK9cvFA2hYkA="; |
279 | }; | 285 | }; |
280 | }; | 286 | }; |
281 | } | 287 | } |
diff --git a/accounts/gkleen@sif/default.nix b/accounts/gkleen@sif/default.nix index 0c0872cc..58cfb425 100644 --- a/accounts/gkleen@sif/default.nix +++ b/accounts/gkleen@sif/default.nix | |||
@@ -80,7 +80,7 @@ let | |||
80 | ]; | 80 | ]; |
81 | }; | 81 | }; |
82 | 82 | ||
83 | lockCommand = "${config.systemd.package}/bin/systemctl --user start gtklock.service"; | 83 | lockCommand = "${lib.getExe' config.systemd.package "systemctl"} --user start gtklock.service"; |
84 | in { | 84 | in { |
85 | imports = with flake.nixosModules.userProfiles.${userName}; [ | 85 | imports = with flake.nixosModules.userProfiles.${userName}; [ |
86 | mpv yt-dlp (args: import ./xcompose.nix (inputs // args)) | 86 | mpv yt-dlp (args: import ./xcompose.nix (inputs // args)) |
@@ -185,7 +185,12 @@ in { | |||
185 | }; | 185 | }; |
186 | }; | 186 | }; |
187 | 187 | ||
188 | zathura.enable = true; | 188 | zathura = { |
189 | enable = true; | ||
190 | options = { | ||
191 | scroll-page-aware = true; | ||
192 | }; | ||
193 | }; | ||
189 | imv.enable = true; | 194 | imv.enable = true; |
190 | 195 | ||
191 | mpv.config = { | 196 | mpv.config = { |
@@ -314,6 +319,7 @@ in { | |||
314 | }; | 319 | }; |
315 | device_config = [ | 320 | device_config = [ |
316 | { loop_file = "/nix/store/*-etc-metadata.erofs"; is_mounted = false; ignore = true; } | 321 | { loop_file = "/nix/store/*-etc-metadata.erofs"; is_mounted = false; ignore = true; } |
322 | { mount_path = "/run/nixos-etc-metadata"; ignore = true; } | ||
317 | { mount_path = "/run/nixos-etc-metadata.*"; ignore = true; } | 323 | { mount_path = "/run/nixos-etc-metadata.*"; ignore = true; } |
318 | ]; | 324 | ]; |
319 | icon_names.media = ["drive-removable-media-symbolic"]; | 325 | icon_names.media = ["drive-removable-media-symbolic"]; |
@@ -353,31 +359,17 @@ in { | |||
353 | enable = true; | 359 | enable = true; |
354 | events = [ | 360 | events = [ |
355 | { event = "before-sleep"; command = lockCommand; } | 361 | { event = "before-sleep"; command = lockCommand; } |
356 | # { event = "after-resume"; command = "${cfg.wayland.windowManager.hyprland.package}/bin/hyprctl dispatch dpms on"; } | ||
357 | { event = "lock"; command = lockCommand; } | 362 | { event = "lock"; command = lockCommand; } |
358 | ]; | 363 | ]; |
359 | timeouts = [ | 364 | timeouts = [ |
360 | # { timeout = 300; | ||
361 | # command = "${cfg.wayland.windowManager.hyprland.package}/bin/hyprctl dispatch dpms off"; | ||
362 | # } | ||
363 | { timeout = 330; command = lockCommand; } | 365 | { timeout = 330; command = lockCommand; } |
364 | ]; | 366 | ]; |
365 | extraArgs = [ | 367 | extraArgs = [ |
368 | "-w" | ||
366 | "idlehint" "30" | 369 | "idlehint" "30" |
367 | ]; | 370 | ]; |
368 | }; | 371 | }; |
369 | poweralertd.enable = true; | 372 | poweralertd.enable = true; |
370 | avizo = { | ||
371 | enable = true; | ||
372 | settings.default = { | ||
373 | time = "1.0"; | ||
374 | background = "rgba(0, 0, 0, 0.8)"; | ||
375 | border-color = "rgba(0, 0, 0, 1)"; | ||
376 | bar-fg-color = "rgba(160, 160, 160, 1)"; | ||
377 | bar-bg-color = "rgba(32, 32, 32, 0.96)"; | ||
378 | # y-offset = "0.25"; | ||
379 | }; | ||
380 | }; | ||
381 | }; | 373 | }; |
382 | 374 | ||
383 | home.pointerCursor = { | 375 | home.pointerCursor = { |
@@ -499,6 +491,14 @@ in { | |||
499 | [Unit] | 491 | [Unit] |
500 | After=graphical-session.target | 492 | After=graphical-session.target |
501 | ''; | 493 | ''; |
494 | "systemd/user/home-manager.service.d/before-graphical-session.conf".text = '' | ||
495 | [Unit] | ||
496 | Before=graphical-session-pre.target | ||
497 | ''; | ||
498 | "pdfpc/pdfpcrc".text = '' | ||
499 | mouse 8 prev | ||
500 | mouse 9 next | ||
501 | ''; | ||
502 | }; | 502 | }; |
503 | 503 | ||
504 | xdg.dataFile = { | 504 | xdg.dataFile = { |
@@ -616,7 +616,6 @@ in { | |||
616 | --property 'CPUAccounting=yes' --property 'CPUQuotaPeriodSec=50ms' \ | 616 | --property 'CPUAccounting=yes' --property 'CPUQuotaPeriodSec=50ms' \ |
617 | --property 'Environment=DSCP=46' \ | 617 | --property 'Environment=DSCP=46' \ |
618 | -- ${pkgs.dscp}/bin/dscp ${pkgs.google-chrome}/bin/google-chrome-stable \ | 618 | -- ${pkgs.dscp}/bin/dscp ${pkgs.google-chrome}/bin/google-chrome-stable \ |
619 | --force-device-scale-factor=1.5 \ | ||
620 | --class=Rainbow \ | 619 | --class=Rainbow \ |
621 | --kiosk "https://web.openrainbow.com" \ | 620 | --kiosk "https://web.openrainbow.com" \ |
622 | --user-data-dir=''${HOME}/.config/google-chrome-rainbow | 621 | --user-data-dir=''${HOME}/.config/google-chrome-rainbow |
@@ -625,6 +624,9 @@ in { | |||
625 | url = "https://web.openrainbow.com/rb/2.139.17/assets/skins/rainbow/images/homepage/logo__rainbow.svg"; | 624 | url = "https://web.openrainbow.com/rb/2.139.17/assets/skins/rainbow/images/homepage/logo__rainbow.svg"; |
626 | hash = "sha256-5fmo8rDqVDpzkGaPjk4Y+SsSZpAsY7VUQSFW6WdHwuU="; | 625 | hash = "sha256-5fmo8rDqVDpzkGaPjk4Y+SsSZpAsY7VUQSFW6WdHwuU="; |
627 | }; | 626 | }; |
627 | settings = { | ||
628 | StartupWMClass = "Rainbow"; | ||
629 | }; | ||
628 | }; | 630 | }; |
629 | }; | 631 | }; |
630 | 632 | ||
diff --git a/accounts/gkleen@sif/emacs.el b/accounts/gkleen@sif/emacs.el index 183cb322..5cee16b0 100644 --- a/accounts/gkleen@sif/emacs.el +++ b/accounts/gkleen@sif/emacs.el | |||
@@ -228,6 +228,7 @@ necessarily running." | |||
228 | (global-set-key (kbd "C-x k") 'kill-buffer-with-special-emacsclient-handling)) | 228 | (global-set-key (kbd "C-x k") 'kill-buffer-with-special-emacsclient-handling)) |
229 | 229 | ||
230 | (add-hook 'server-switch-hook 'install-emacsclient-wrapped-kill-buffer) | 230 | (add-hook 'server-switch-hook 'install-emacsclient-wrapped-kill-buffer) |
231 | (add-hook 'server-switch-hook #'raise-frame) | ||
231 | 232 | ||
232 | (defun move-file (new-location) | 233 | (defun move-file (new-location) |
233 | "Write this file to NEW-LOCATION, and delete the old one." | 234 | "Write this file to NEW-LOCATION, and delete the old one." |
diff --git a/accounts/gkleen@sif/niri/default.nix b/accounts/gkleen@sif/niri/default.nix index 2e9b6909..7e187c84 100644 --- a/accounts/gkleen@sif/niri/default.nix +++ b/accounts/gkleen@sif/niri/default.nix | |||
@@ -2,11 +2,10 @@ | |||
2 | let | 2 | let |
3 | niri = config.programs.niri.package; | 3 | niri = config.programs.niri.package; |
4 | terminal = lib.getExe config.programs.kitty.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 | makoctl = lib.getExe' config.services.mako.package "makoctl"; | 5 | makoctl = lib.getExe' config.services.mako.package "makoctl"; |
8 | loginctl = lib.getExe' hostConfig.systemd.package "loginctl"; | 6 | loginctl = lib.getExe' hostConfig.systemd.package "loginctl"; |
9 | systemctl = lib.getExe' hostConfig.systemd.package "systemctl"; | 7 | systemctl = lib.getExe' hostConfig.systemd.package "systemctl"; |
8 | swayosd-client = lib.getExe' config.services.swayosd.package "swayosd-client"; | ||
10 | 9 | ||
11 | focus_or_spawn = pkgs.writeShellApplication { | 10 | focus_or_spawn = pkgs.writeShellApplication { |
12 | name = "focus-or-spawn"; | 11 | name = "focus-or-spawn"; |
@@ -19,17 +18,21 @@ let | |||
19 | 18 | ||
20 | workspaces_json="$(niri msg -j workspaces)" | 19 | workspaces_json="$(niri msg -j workspaces)" |
21 | workspace_output="$(jq -r --arg workspace_name "$workspace_name" '.[] | select(.name == $workspace_name) | .output' <<<"$workspaces_json")" | 20 | workspace_output="$(jq -r --arg workspace_name "$workspace_name" '.[] | select(.name == $workspace_name) | .output' <<<"$workspaces_json")" |
22 | active_workspace="$(jq -r --arg workspace_output "$workspace_output" '.[] | select(.output == $workspace_output and .is_active) | .id' <<<"$workspaces_json")" | 21 | # active_workspace="$(jq -r --arg workspace_output "$workspace_output" '.[] | select(.output == $workspace_output and .is_active) | .id' <<<"$workspaces_json")" |
23 | active_output="$(jq -r '.[] | select(.is_focused) | .output' <<<"$workspaces_json")" | 22 | active_output="$(jq -r '.[] | select(.is_focused) | .output' <<<"$workspaces_json")" |
24 | if [[ $workspace_output != "$active_output" ]]; then | 23 | if [[ $workspace_output != "$active_output" ]]; then |
25 | niri msg action move-workspace-to-monitor --output "$active_output" "$workspace_name" | 24 | niri msg action move-workspace-to-monitor --reference "$workspace_name" "$active_output" |
26 | socat STDIO "$NIRI_SOCKET" <<<'{"Action":{"FocusWorkspace":{"reference":{"Id":'"''${active_workspace}"'}}}}' | 25 | # socat STDIO "$NIRI_SOCKET" <<<'{"Action":{"FocusWorkspace":{"reference":{"Id":'"''${active_workspace}"'}}}}' |
27 | niri msg action move-workspace-to-index --index 1 "$workspace_name" | 26 | # niri msg action move-workspace-to-index --reference "$workspace_name" 1 |
28 | fi | 27 | fi |
29 | 28 | ||
30 | while IFS=$'\n' read -r window_json; do | 29 | while IFS=$'\n' read -r window_json; do |
31 | if [[ -n $(jq -c "$window_select" <<<"$window_json") ]]; then | 30 | if [[ -n $(jq -c "$window_select" <<<"$window_json") ]]; then |
32 | niri msg action focus-window --id "$(jq -r '.id' <<<"$window_json")" | 31 | if jq -e '.is_focused' <<<"$window_json" >/dev/null; then |
32 | niri msg action focus-workspace-previous | ||
33 | else | ||
34 | niri msg action focus-window --id "$(jq -r '.id' <<<"$window_json")" | ||
35 | fi | ||
33 | exit 0 | 36 | exit 0 |
34 | fi | 37 | fi |
35 | done < <(niri msg -j windows | jq -c '.[]') | 38 | done < <(niri msg -j windows | jq -c '.[]') |
@@ -75,7 +78,7 @@ let | |||
75 | jq --arg active_workspace "$active_workspace" -c "$action" <<<"$workspace_json" | tee /dev/stderr | socat STDIO "$NIRI_SOCKET" | 78 | jq --arg active_workspace "$active_workspace" -c "$action" <<<"$workspace_json" | tee /dev/stderr | socat STDIO "$NIRI_SOCKET" |
76 | ''; | 79 | ''; |
77 | }; | 80 | }; |
78 | with-adjacent-workspace-action = config.lib.niri.actions.spawn (lib.getExe with_adjacent_workspace) "^pwctl|kpxc|bmgr|edit|term$"; | 81 | with-adjacent-workspace-action = config.lib.niri.actions.spawn (lib.getExe with_adjacent_workspace) "^pwctl|eff|kpxc|bmgr|edit|term$"; |
79 | focus-adjacent-workspace = direction: with-adjacent-workspace-action direction ''{"Action":{"FocusWorkspace":{"reference":{"Id": .id}}}}''; | 82 | focus-adjacent-workspace = direction: with-adjacent-workspace-action direction ''{"Action":{"FocusWorkspace":{"reference":{"Id": .id}}}}''; |
80 | move-column-to-adjacent-workspace = direction: with-adjacent-workspace-action direction ''{"Action":{"MoveColumnToWorkspace":{"reference":{"Id": .id}}}}''; | 83 | move-column-to-adjacent-workspace = direction: with-adjacent-workspace-action direction ''{"Action":{"MoveColumnToWorkspace":{"reference":{"Id": .id}}}}''; |
81 | 84 | ||
@@ -90,7 +93,8 @@ let | |||
90 | active_output="$(jq -r '.[] | select(.is_focused) | .output' <<<"$workspaces_json")" | 93 | active_output="$(jq -r '.[] | select(.is_focused) | .output' <<<"$workspaces_json")" |
91 | active_workspace="$(jq -r '.[] | select(.is_focused) | .id' <<<"$workspaces_json")" | 94 | active_workspace="$(jq -r '.[] | select(.is_focused) | .id' <<<"$workspaces_json")" |
92 | 95 | ||
93 | workspace_json="$(jq -c --arg active_output "$active_output" 'map(select(.output == $active_output and .name == null)) | sort_by(.idx) | .[0]' <<<"$workspaces_json")" | 96 | history_json="$(socat STDIO UNIX-CONNECT:"$XDG_RUNTIME_DIR"/niri-workspace-history.sock)" |
97 | workspace_json="$(jq -c --arg active_output "$active_output" --argjson history "$history_json" 'map(select(.output == $active_output and .name == null)) | map({"value": ., "history_idx": ((. as $workspace | ($history[$active_output] | index($workspace | .id))) as $active_idx | if $active_idx then $active_idx else ($history[$active_output] | length) + 1 end)}) | sort_by(.history_idx, .value.idx) | map(.value) | .[0]' <<<"$workspaces_json")" | ||
94 | [[ -n $workspace_json && $workspace_json != null ]] || exit 0 | 98 | [[ -n $workspace_json && $workspace_json != null ]] || exit 0 |
95 | jq --arg active_workspace "$active_workspace" -c "$action" <<<"$workspace_json" | tee /dev/stderr | socat STDIO "$NIRI_SOCKET" | 99 | jq --arg active_workspace "$active_workspace" -c "$action" <<<"$workspace_json" | tee /dev/stderr | socat STDIO "$NIRI_SOCKET" |
96 | ''; | 100 | ''; |
@@ -122,6 +126,7 @@ in { | |||
122 | imports = [ | 126 | imports = [ |
123 | ./waybar.nix | 127 | ./waybar.nix |
124 | ./mako.nix | 128 | ./mako.nix |
129 | ./swayosd.nix | ||
125 | ]; | 130 | ]; |
126 | 131 | ||
127 | config = { | 132 | config = { |
@@ -156,6 +161,113 @@ in { | |||
156 | ]; | 161 | ]; |
157 | }; | 162 | }; |
158 | 163 | ||
164 | systemd.user.sockets.niri-workspace-history = { | ||
165 | Socket = { | ||
166 | ListenStream = "%t/niri-workspace-history.sock"; | ||
167 | SocketMode = "0600"; | ||
168 | }; | ||
169 | }; | ||
170 | systemd.user.services.niri-workspace-history = { | ||
171 | Unit = { | ||
172 | BindsTo = [ "niri.service" ]; | ||
173 | After = [ "niri.service" ]; | ||
174 | }; | ||
175 | Install = { | ||
176 | WantedBy = [ "niri.service" ]; | ||
177 | }; | ||
178 | Service = { | ||
179 | Type = "simple"; | ||
180 | Sockets = [ "niri-workspace-history.socket" ]; | ||
181 | ExecStart = pkgs.writers.writePython3 "niri-workspace-history" {} '' | ||
182 | import os | ||
183 | import socket | ||
184 | import json | ||
185 | import sys | ||
186 | from collections import defaultdict | ||
187 | from threading import Thread, Lock | ||
188 | from socketserver import StreamRequestHandler, ThreadingTCPServer | ||
189 | from contextlib import contextmanager | ||
190 | from io import TextIOWrapper | ||
191 | |||
192 | |||
193 | @contextmanager | ||
194 | def detaching(thing): | ||
195 | try: | ||
196 | yield thing | ||
197 | finally: | ||
198 | thing.detach() | ||
199 | |||
200 | |||
201 | workspace_history = defaultdict(list) | ||
202 | history_lock = Lock() | ||
203 | |||
204 | |||
205 | def monitor_niri(): | ||
206 | workspaces = list() | ||
207 | |||
208 | def focus_workspace(output, workspace): | ||
209 | global workspace_history, history_lock | ||
210 | |||
211 | with history_lock: | ||
212 | workspace_history[output] = [workspace] + [ws for ws in workspace_history[output] if ws != workspace] # noqa: E501 | ||
213 | print(json.dumps(workspace_history), file=sys.stderr) | ||
214 | |||
215 | sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) | ||
216 | sock.connect(os.environ["NIRI_SOCKET"]) | ||
217 | sock.send(b"\"EventStream\"\n") | ||
218 | for line in sock.makefile(buffering=1, encoding='utf-8'): | ||
219 | if line_json := json.loads(line): | ||
220 | if "WorkspacesChanged" in line_json: | ||
221 | workspaces = line_json["WorkspacesChanged"]["workspaces"] | ||
222 | for ws in workspaces: | ||
223 | if ws["is_focused"]: | ||
224 | focus_workspace(ws["output"], ws["id"]) | ||
225 | if "WorkspaceActivated" in line_json: | ||
226 | for ws in workspaces: | ||
227 | if ws["id"] != line_json["WorkspaceActivated"]["id"]: | ||
228 | continue | ||
229 | focus_workspace(ws["output"], ws["id"]) | ||
230 | break | ||
231 | |||
232 | |||
233 | class RequestHandler(StreamRequestHandler): | ||
234 | def handle(self): | ||
235 | global workspace_history, history_lock | ||
236 | |||
237 | with detaching(TextIOWrapper(self.wfile, encoding='utf-8', write_through=True)) as out: # noqa: E501 | ||
238 | with history_lock: | ||
239 | json.dump(workspace_history, out) | ||
240 | |||
241 | |||
242 | class Server(ThreadingTCPServer): | ||
243 | def __init__(self): | ||
244 | ThreadingTCPServer.__init__(self, ("", 8000), RequestHandler, bind_and_activate=False) # noqa: E501 | ||
245 | self.socket = socket.fromfd(3, self.address_family, self.socket_type) | ||
246 | |||
247 | |||
248 | def run_server(): | ||
249 | with Server() as server: | ||
250 | server.serve_forever() | ||
251 | |||
252 | |||
253 | niri = Thread(target=monitor_niri) | ||
254 | niri.daemon = True | ||
255 | niri.start() | ||
256 | |||
257 | server_thread = Thread(target=run_server) | ||
258 | server_thread.daemon = True | ||
259 | server_thread.start() | ||
260 | |||
261 | while True: | ||
262 | server_thread.join(timeout=0.5) | ||
263 | niri.join(timeout=0.5) | ||
264 | |||
265 | if not (niri.is_alive() and server_thread.is_alive()): | ||
266 | break | ||
267 | ''; | ||
268 | }; | ||
269 | }; | ||
270 | |||
159 | programs.niri.settings = { | 271 | programs.niri.settings = { |
160 | prefer-no-csd = true; | 272 | prefer-no-csd = true; |
161 | screenshot-path = "${config.home.homeDirectory}/screenshots"; | 273 | screenshot-path = "${config.home.homeDirectory}/screenshots"; |
@@ -163,10 +275,15 @@ in { | |||
163 | hotkey-overlay.skip-at-startup = true; | 275 | hotkey-overlay.skip-at-startup = true; |
164 | 276 | ||
165 | input = { | 277 | input = { |
166 | keyboard.xkb = { | 278 | keyboard = { |
167 | layout = "us,us"; | 279 | repeat-delay = 300; |
168 | variant = "dvp,"; | 280 | repeat-rate = 50; |
169 | options = "compose:caps,grp:win_space_toggle"; | 281 | |
282 | xkb = { | ||
283 | layout = "us,us"; | ||
284 | variant = "dvp,"; | ||
285 | options = "compose:caps,grp:win_space_toggle"; | ||
286 | }; | ||
170 | }; | 287 | }; |
171 | 288 | ||
172 | workspace-auto-back-and-forth = true; | 289 | workspace-auto-back-and-forth = true; |
@@ -202,6 +319,11 @@ in { | |||
202 | 319 | ||
203 | debug.render-drm-device = "/dev/dri/by-path/pci-0000:00:02.0-render"; | 320 | debug.render-drm-device = "/dev/dri/by-path/pci-0000:00:02.0-render"; |
204 | 321 | ||
322 | animations = { | ||
323 | slowdown = 0.5; | ||
324 | workspace-switch = null; | ||
325 | }; | ||
326 | |||
205 | layout = { | 327 | layout = { |
206 | gaps = 8; | 328 | gaps = 8; |
207 | struts = { left = 0; right = 0; top = 0; bottom = 0; }; | 329 | struts = { left = 0; right = 0; top = 0; bottom = 0; }; |
@@ -255,6 +377,7 @@ in { | |||
255 | "003" = { name = "bmgr"; open-on-output = "eDP-1"; }; | 377 | "003" = { name = "bmgr"; open-on-output = "eDP-1"; }; |
256 | "004" = { name = "term"; open-on-output = "eDP-1"; }; | 378 | "004" = { name = "term"; open-on-output = "eDP-1"; }; |
257 | "005" = { name = "edit"; open-on-output = "eDP-1"; }; | 379 | "005" = { name = "edit"; open-on-output = "eDP-1"; }; |
380 | "006" = { name = "eff"; open-on-output = "eDP-1"; }; | ||
258 | "101".name = "comm"; | 381 | "101".name = "comm"; |
259 | "102".name = "web"; | 382 | "102".name = "web"; |
260 | # "104".name = "read"; | 383 | # "104".name = "read"; |
@@ -264,19 +387,25 @@ in { | |||
264 | }; | 387 | }; |
265 | 388 | ||
266 | window-rules = [ | 389 | window-rules = [ |
267 | # { | 390 | { |
268 | # geometry-corner-radius = | 391 | matches = [ { is-floating = true; } ]; |
269 | # let | 392 | geometry-corner-radius = |
270 | # allCorners = r: { bottom-left = r; bottom-right = r; top-left = r; top-right = r; }; | 393 | let |
271 | # in allCorners 4.; | 394 | allCorners = r: { bottom-left = r; bottom-right = r; top-left = r; top-right = r; }; |
272 | # clip-to-geometry = true; | 395 | in allCorners 8.; |
273 | # } | 396 | clip-to-geometry = true; |
397 | } | ||
274 | { | 398 | { |
275 | matches = [ { app-id = "^com\.saivert\.pwvucontrol$"; } ]; | 399 | matches = [ { app-id = "^com\.saivert\.pwvucontrol$"; } ]; |
276 | open-on-workspace = "pwctl"; | 400 | open-on-workspace = "pwctl"; |
277 | open-maximized = true; | 401 | open-maximized = true; |
278 | } | 402 | } |
279 | { | 403 | { |
404 | matches = [ { app-id = "^com\.github\.wwmm\.easyeffects$"; } ]; | ||
405 | open-on-workspace = "eff"; | ||
406 | open-maximized = true; | ||
407 | } | ||
408 | { | ||
280 | matches = [ { app-id = "^\.blueman-manager-wrapped$"; } ]; | 409 | matches = [ { app-id = "^\.blueman-manager-wrapped$"; } ]; |
281 | open-on-workspace = "bmgr"; | 410 | open-on-workspace = "bmgr"; |
282 | open-maximized = true; | 411 | open-maximized = true; |
@@ -303,6 +432,7 @@ in { | |||
303 | { app-id = "^org\.keepassxc\.KeePassXC$"; title = ".*Passkey credentials$"; } | 432 | { app-id = "^org\.keepassxc\.KeePassXC$"; title = ".*Passkey credentials$"; } |
304 | ]; | 433 | ]; |
305 | open-focused = true; | 434 | open-focused = true; |
435 | open-floating = true; | ||
306 | } | 436 | } |
307 | { | 437 | { |
308 | matches = [ { app-id = "^kitty-scratch$"; } ]; | 438 | matches = [ { app-id = "^kitty-scratch$"; } ]; |
@@ -332,6 +462,7 @@ in { | |||
332 | matches = [ | 462 | matches = [ |
333 | { app-id = "^thunderbird$"; } | 463 | { app-id = "^thunderbird$"; } |
334 | { app-id = "^Element$"; } | 464 | { app-id = "^Element$"; } |
465 | { app-id = "^Rainbow$"; } | ||
335 | ]; | 466 | ]; |
336 | open-on-workspace = "comm"; | 467 | open-on-workspace = "comm"; |
337 | } | 468 | } |
@@ -380,6 +511,7 @@ in { | |||
380 | matches = [ | 511 | matches = [ |
381 | { app-id = "^Gimp-"; title = "^Quit GIMP$"; } | 512 | { app-id = "^Gimp-"; title = "^Quit GIMP$"; } |
382 | { app-id = "^org\.kde\.polkit-kde-authentication-agent-1$"; } | 513 | { app-id = "^org\.kde\.polkit-kde-authentication-agent-1$"; } |
514 | { app-id = "^xdg-desktop-portal-gtk$"; } | ||
383 | ]; | 515 | ]; |
384 | open-floating = true; | 516 | open-floating = true; |
385 | } | 517 | } |
@@ -570,27 +702,27 @@ in { | |||
570 | }; | 702 | }; |
571 | 703 | ||
572 | "XF86MonBrightnessUp" = { | 704 | "XF86MonBrightnessUp" = { |
573 | action = spawn lightctl "-d" "-e4" "-n1" "up"; | 705 | action = spawn swayosd-client "--brightness" "raise"; |
574 | allow-when-locked = true; | 706 | allow-when-locked = true; |
575 | }; | 707 | }; |
576 | "XF86MonBrightnessDown" = { | 708 | "XF86MonBrightnessDown" = { |
577 | action = spawn lightctl "-d" "-e4" "-n1" "down"; | 709 | action = spawn swayosd-client "--brightness" "lower"; |
578 | allow-when-locked = true; | 710 | allow-when-locked = true; |
579 | }; | 711 | }; |
580 | "XF86AudioRaiseVolume" = { | 712 | "XF86AudioRaiseVolume" = { |
581 | action = spawn volumectl "-d" "-u" "up"; | 713 | action = spawn swayosd-client "--output-volume" "raise"; |
582 | allow-when-locked = true; | 714 | allow-when-locked = true; |
583 | }; | 715 | }; |
584 | "XF86AudioLowerVolume" = { | 716 | "XF86AudioLowerVolume" = { |
585 | action = spawn volumectl "-d" "-u" "down"; | 717 | action = spawn swayosd-client "--output-volume" "lower"; |
586 | allow-when-locked = true; | 718 | allow-when-locked = true; |
587 | }; | 719 | }; |
588 | "XF86AudioMute" = { | 720 | "XF86AudioMute" = { |
589 | action = spawn volumectl "-d" "toggle-mute"; | 721 | action = spawn swayosd-client "--output-volume" "mute-toggle"; |
590 | allow-when-locked = true; | 722 | allow-when-locked = true; |
591 | }; | 723 | }; |
592 | "XF86AudioMicMute" = { | 724 | "XF86AudioMicMute" = { |
593 | action = spawn volumectl "-d" "-m" "toggle-mute"; | 725 | action = spawn swayosd-client "--input-volume" "mute-toggle"; |
594 | allow-when-locked = true; | 726 | allow-when-locked = true; |
595 | }; | 727 | }; |
596 | 728 | ||
@@ -600,6 +732,7 @@ in { | |||
600 | "Mod+Comma".action = spawn makoctl "restore"; | 732 | "Mod+Comma".action = spawn makoctl "restore"; |
601 | 733 | ||
602 | "Mod+Control+A".action = focus-or-spawn-action-app_id "com.saivert.pwvucontrol" "pwctl" "pwvucontrol"; | 734 | "Mod+Control+A".action = focus-or-spawn-action-app_id "com.saivert.pwvucontrol" "pwctl" "pwvucontrol"; |
735 | "Mod+Control+O".action = focus-or-spawn-action-app_id "com.github.wwmm.easyeffects" "eff" "easyeffects"; | ||
603 | "Mod+Control+P".action = focus-or-spawn-action-app_id "org.keepassxc.KeePassXC" "kpxc" "keepassxc"; | 736 | "Mod+Control+P".action = focus-or-spawn-action-app_id "org.keepassxc.KeePassXC" "kpxc" "keepassxc"; |
604 | "Mod+Control+B".action = focus-or-spawn-action-app_id ".blueman-manager-wrapped" "bmgr" "blueman-manager"; | 737 | "Mod+Control+B".action = focus-or-spawn-action-app_id ".blueman-manager-wrapped" "bmgr" "blueman-manager"; |
605 | "Mod+Control+Return".action = focus-or-spawn-action-app_id "kitty-scratch" "term" "kitty" "--app-id" "kitty-scratch"; | 738 | "Mod+Control+Return".action = focus-or-spawn-action-app_id "kitty-scratch" "term" "kitty" "--app-id" "kitty-scratch"; |
diff --git a/accounts/gkleen@sif/niri/mako.nix b/accounts/gkleen@sif/niri/mako.nix index e06d3b3a..0a10555a 100644 --- a/accounts/gkleen@sif/niri/mako.nix +++ b/accounts/gkleen@sif/niri/mako.nix | |||
@@ -1,4 +1,4 @@ | |||
1 | { config, lib, ... }: | 1 | { config, lib, pkgs, ... }: |
2 | { | 2 | { |
3 | config = { | 3 | config = { |
4 | services.mako = { | 4 | services.mako = { |
@@ -30,6 +30,14 @@ | |||
30 | [mode=silent] | 30 | [mode=silent] |
31 | invisible=1 | 31 | invisible=1 |
32 | ''; | 32 | ''; |
33 | package = pkgs.symlinkJoin { | ||
34 | name = "${pkgs.mako.name}-wrapped"; | ||
35 | paths = with pkgs; [ mako ]; | ||
36 | inherit (pkgs.mako) meta; | ||
37 | postBuild = '' | ||
38 | rm -r $out/share/dbus-1 | ||
39 | ''; | ||
40 | }; | ||
33 | }; | 41 | }; |
34 | systemd.user.services.mako = { | 42 | systemd.user.services.mako = { |
35 | Unit = { | 43 | Unit = { |
diff --git a/accounts/gkleen@sif/niri/swayosd.nix b/accounts/gkleen@sif/niri/swayosd.nix new file mode 100644 index 00000000..984927c2 --- /dev/null +++ b/accounts/gkleen@sif/niri/swayosd.nix | |||
@@ -0,0 +1,65 @@ | |||
1 | { pkgs, ... }: | ||
2 | { | ||
3 | config = { | ||
4 | services.swayosd = { | ||
5 | enable = true; | ||
6 | topMargin = 0.946154; | ||
7 | stylePath = pkgs.runCommand "style.css" { | ||
8 | src = pkgs.writeText "style.scss" '' | ||
9 | window#osd { | ||
10 | padding: 12px 20px; | ||
11 | border-radius: 999px; | ||
12 | border: none; | ||
13 | background: rgba(0, 0, 0, 0.87); | ||
14 | |||
15 | #container { | ||
16 | margin: 16px; | ||
17 | } | ||
18 | |||
19 | image, | ||
20 | label { | ||
21 | color: rgb(255, 255, 255); | ||
22 | |||
23 | &:disabled { | ||
24 | opacity: 1; | ||
25 | color: rgb(84, 84, 84); | ||
26 | } | ||
27 | } | ||
28 | |||
29 | progressbar { | ||
30 | min-height: 6px; | ||
31 | border-radius: 999px; | ||
32 | background: transparent; | ||
33 | border: none; | ||
34 | |||
35 | trough, progress { | ||
36 | min-height: inherit; | ||
37 | border-radius: inherit; | ||
38 | border: none; | ||
39 | } | ||
40 | |||
41 | trough { | ||
42 | background: rgb(127, 127, 127); | ||
43 | } | ||
44 | progress { | ||
45 | background: rgb(255, 255, 255); | ||
46 | } | ||
47 | |||
48 | &:disabled { | ||
49 | opacity: 1; | ||
50 | |||
51 | trough { | ||
52 | background: rgb(19, 19, 19); | ||
53 | } | ||
54 | progress { | ||
55 | background: rgb(38, 38, 38); | ||
56 | } | ||
57 | } | ||
58 | } | ||
59 | } | ||
60 | ''; | ||
61 | buildInputs = with pkgs; [sass]; | ||
62 | } "scss -C --sourcemap=none --style=compact $src $out"; | ||
63 | }; | ||
64 | }; | ||
65 | } | ||
diff --git a/accounts/gkleen@sif/niri/waybar.nix b/accounts/gkleen@sif/niri/waybar.nix index 79c429f8..3f1f8119 100644 --- a/accounts/gkleen@sif/niri/waybar.nix +++ b/accounts/gkleen@sif/niri/waybar.nix | |||
@@ -1,5 +1,7 @@ | |||
1 | { lib, pkgs, ... }: | 1 | { lib, config, pkgs, ... }: |
2 | { | 2 | let |
3 | swayosd-client = lib.getExe' config.services.swayosd.package "swayosd-client"; | ||
4 | in { | ||
3 | config = { | 5 | config = { |
4 | programs.waybar = { | 6 | programs.waybar = { |
5 | enable = true; | 7 | enable = true; |
@@ -22,7 +24,7 @@ | |||
22 | output = [ "eDP-1" "DP-2" "DP-3" ]; | 24 | output = [ "eDP-1" "DP-2" "DP-3" ]; |
23 | modules-left = [ "niri/workspaces" ]; | 25 | modules-left = [ "niri/workspaces" ]; |
24 | modules-center = [ "niri/window" ]; | 26 | modules-center = [ "niri/window" ]; |
25 | modules-right = [ # "custom/worktime" "custom/worktime-today" | 27 | modules-right = [ "custom/worktime" "custom/worktime-today" |
26 | "custom/weather" | 28 | "custom/weather" |
27 | "custom/keymap" | 29 | "custom/keymap" |
28 | "privacy" "tray" "wireplumber" "backlight" "battery" "idle_inhibitor" "custom/mako" "clock" ]; | 30 | "privacy" "tray" "wireplumber" "backlight" "battery" "idle_inhibitor" "custom/mako" "clock" ]; |
@@ -59,7 +61,7 @@ | |||
59 | text = f"<span font=\"Symbols Nerd Font Mono\" size=\"90%\">{icon}</span>" # noqa: E501 | 61 | text = f"<span font=\"Symbols Nerd Font Mono\" size=\"90%\">{icon}</span>" # noqa: E501 |
60 | if is_silent: | 62 | if is_silent: |
61 | text = f"<span color=\"#ffffff\">{text}</span>" | 63 | text = f"<span color=\"#ffffff\">{text}</span>" |
62 | print(json.dumps({'text': text}, separators=(',', ':')), flush=True) # noqa: E501 | 64 | print(json.dumps({'text': text, 'tooltip': ', '.join(modes)}, separators=(',', ':')), flush=True) # noqa: E501 |
63 | 65 | ||
64 | async def on_properties_changed(interface_name, changed_properties, invalidated_properties): # noqa: E501 | 66 | async def on_properties_changed(interface_name, changed_properties, invalidated_properties): # noqa: E501 |
65 | if "Modes" not in invalidated_properties: | 67 | if "Modes" not in invalidated_properties: |
@@ -120,16 +122,16 @@ | |||
120 | }; | 122 | }; |
121 | "custom/worktime" = { | 123 | "custom/worktime" = { |
122 | interval = 60; | 124 | interval = 60; |
123 | exec = lib.getExe pkgs.worktime; | 125 | exec = "${lib.getExe pkgs.worktime} time --waybar"; |
124 | tooltip = false; | 126 | return-type = "json"; |
125 | }; | 127 | }; |
126 | "custom/worktime-today" = { | 128 | "custom/worktime-today" = { |
127 | interval = 60; | 129 | interval = 60; |
128 | exec = "${lib.getExe pkgs.worktime} today"; | 130 | exec = "${lib.getExe pkgs.worktime} today --waybar"; |
129 | tooltip = false; | 131 | return-type = "json"; |
130 | }; | 132 | }; |
131 | "niri/workspaces" = { | 133 | "niri/workspaces" = { |
132 | ignore = ["pwctl" "kpxc" "bmgr" "edit" "term"]; | 134 | ignore = ["eff" "pwctl" "kpxc" "bmgr" "edit" "term"]; |
133 | }; | 135 | }; |
134 | "niri/window" = { | 136 | "niri/window" = { |
135 | separate-outputs = true; | 137 | separate-outputs = true; |
@@ -190,8 +192,8 @@ | |||
190 | icon-size = iconSize; | 192 | icon-size = iconSize; |
191 | tooltip-format = "{percent}%"; | 193 | tooltip-format = "{percent}%"; |
192 | format-icons = ["󰃚" "󰃛" "󰃜" "󰃝" "󰃞" "󰃟" "󰃠"]; | 194 | format-icons = ["󰃚" "󰃛" "󰃜" "󰃝" "󰃞" "󰃟" "󰃠"]; |
193 | on-scroll-up = "lightctl -d -e4 -n1 up"; | 195 | on-scroll-up = "${swayosd-client} --brightness raise"; |
194 | on-scroll-down = "lightctl -d -e4 -n1 down"; | 196 | on-scroll-down = "${swayosd-client} --brightness lower"; |
195 | }; | 197 | }; |
196 | wireplumber = { | 198 | wireplumber = { |
197 | format = "<span font=\"Symbols Nerd Font Mono\" size=\"90%\">{icon}</span>"; | 199 | format = "<span font=\"Symbols Nerd Font Mono\" size=\"90%\">{icon}</span>"; |
@@ -200,9 +202,9 @@ | |||
200 | format-icons = ["󰕿" "󰖀" "󰕾"]; | 202 | format-icons = ["󰕿" "󰖀" "󰕾"]; |
201 | format-muted = "<span font=\"Symbols Nerd Font Mono\" size=\"90%\">󰝟</span>"; | 203 | format-muted = "<span font=\"Symbols Nerd Font Mono\" size=\"90%\">󰝟</span>"; |
202 | # ignored-sinks = ["Easy Effects Sink"]; | 204 | # ignored-sinks = ["Easy Effects Sink"]; |
203 | on-scroll-up = "volumectl -d -u up"; | 205 | on-scroll-up = "${swayosd-client} --output-volume raise"; |
204 | on-scroll-down = "volumectl -d -u down"; | 206 | on-scroll-down = "${swayosd-client} --output-volume lower"; |
205 | on-click = "volumectl -d toggle-mute"; | 207 | on-click = "${swayosd-client} --output-volume mute-toggle"; |
206 | }; | 208 | }; |
207 | } | 209 | } |
208 | { | 210 | { |
@@ -241,7 +243,7 @@ | |||
241 | 243 | ||
242 | * { | 244 | * { |
243 | border: none; | 245 | border: none; |
244 | font-family: "Fira Sans Nerd Font"; | 246 | font-family: "Fira Sans"; |
245 | font-size: 10pt; | 247 | font-size: 10pt; |
246 | min-height: 0; | 248 | min-height: 0; |
247 | } | 249 | } |
@@ -252,10 +254,10 @@ | |||
252 | } | 254 | } |
253 | 255 | ||
254 | .modules-left { | 256 | .modules-left { |
255 | margin-left: 8px; | 257 | margin-left: 12px; |
256 | } | 258 | } |
257 | .modules-right { | 259 | .modules-right { |
258 | margin-right: 8px; | 260 | margin-right: 12px; |
259 | } | 261 | } |
260 | 262 | ||
261 | .module { | 263 | .module { |
@@ -280,11 +282,12 @@ | |||
280 | color: @grey; | 282 | color: @grey; |
281 | margin: 0 5px; | 283 | margin: 0 5px; |
282 | } | 284 | } |
283 | #custom-weather, #custom-worktime-today { | 285 | #custom-weather { |
284 | margin-right: 3px; | 286 | margin-right: 3px; |
285 | } | 287 | } |
286 | #custom-keymap, #custom-weather { | 288 | #custom-keymap { |
287 | margin-left: 3px; | 289 | margin-left: 3px; |
290 | margin-right: 3px; | ||
288 | } | 291 | } |
289 | 292 | ||
290 | #tray { | 293 | #tray { |
@@ -320,6 +323,12 @@ | |||
320 | #idle_inhibitor.activated { | 323 | #idle_inhibitor.activated { |
321 | color: @white; | 324 | color: @white; |
322 | } | 325 | } |
326 | #custom-worktime.running, #custom-worktime-today.running { | ||
327 | color: @white; | ||
328 | } | ||
329 | #custom-worktime.over, #custom-worktime-today.over { | ||
330 | color: @orange; | ||
331 | } | ||
323 | 332 | ||
324 | #idle_inhibitor { | 333 | #idle_inhibitor { |
325 | padding-top: 1px; | 334 | padding-top: 1px; |
@@ -327,7 +336,7 @@ | |||
327 | 336 | ||
328 | #privacy { | 337 | #privacy { |
329 | color: @red; | 338 | color: @red; |
330 | margin: -1px 2px 0px 5px; | 339 | margin: -1px 4px 0px 3px; |
331 | } | 340 | } |
332 | #clock { | 341 | #clock { |
333 | /* margin-right: 5px; */ | 342 | /* margin-right: 5px; */ |
diff --git a/accounts/gkleen@sif/systemd.nix b/accounts/gkleen@sif/systemd.nix index d3a1a4c7..a89b46c2 100644 --- a/accounts/gkleen@sif/systemd.nix +++ b/accounts/gkleen@sif/systemd.nix | |||
@@ -344,6 +344,9 @@ in { | |||
344 | Unit = { | 344 | Unit = { |
345 | PartOf = lib.mkForce ["tray.target"]; | 345 | PartOf = lib.mkForce ["tray.target"]; |
346 | }; | 346 | }; |
347 | Install = { | ||
348 | WantedBy = lib.mkForce ["tray.target"]; | ||
349 | }; | ||
347 | }; | 350 | }; |
348 | } // listToAttrs (map ({host, port}: nameValuePair "proxy-to-autossh-socks@${toString port}" { | 351 | } // listToAttrs (map ({host, port}: nameValuePair "proxy-to-autossh-socks@${toString port}" { |
349 | Unit = { | 352 | Unit = { |
@@ -322,11 +322,11 @@ | |||
322 | ] | 322 | ] |
323 | }, | 323 | }, |
324 | "locked": { | 324 | "locked": { |
325 | "lastModified": 1736014120, | 325 | "lastModified": 1737831749, |
326 | "narHash": "sha256-ZrI+mcuQfal5IfT4HsxVEiiFNAgV4qYh+B4/NyXxpAs=", | 326 | "narHash": "sha256-La1xZYZ1yHvT4h5MNl5WC2wxBi2P4vozce2n7V/9+2w=", |
327 | "owner": "gkleen", | 327 | "owner": "gkleen", |
328 | "repo": "home-manager", | 328 | "repo": "home-manager", |
329 | "rev": "99e8412a18eb7e0731aa2b77abeed00d6d1863ad", | 329 | "rev": "8b16ee252e38acc29ba634ab60672a051ebc9f59", |
330 | "type": "github" | 330 | "type": "github" |
331 | }, | 331 | }, |
332 | "original": { | 332 | "original": { |
@@ -359,11 +359,11 @@ | |||
359 | }, | 359 | }, |
360 | "impermanence": { | 360 | "impermanence": { |
361 | "locked": { | 361 | "locked": { |
362 | "lastModified": 1736688610, | 362 | "lastModified": 1737831083, |
363 | "narHash": "sha256-1Zl9xahw399UiZSJ9Vxs1W4WRFjO1SsNdVZQD4nghz0=", | 363 | "narHash": "sha256-LJggUHbpyeDvNagTUrdhe/pRVp4pnS6wVKALS782gRI=", |
364 | "owner": "nix-community", | 364 | "owner": "nix-community", |
365 | "repo": "impermanence", | 365 | "repo": "impermanence", |
366 | "rev": "c64bed13b562fc3bb454b48773d4155023ac31b7", | 366 | "rev": "4b3e914cdf97a5b536a889e939fb2fd2b043a170", |
367 | "type": "github" | 367 | "type": "github" |
368 | }, | 368 | }, |
369 | "original": { | 369 | "original": { |
@@ -397,11 +397,11 @@ | |||
397 | "xwayland-satellite-unstable": "xwayland-satellite-unstable" | 397 | "xwayland-satellite-unstable": "xwayland-satellite-unstable" |
398 | }, | 398 | }, |
399 | "locked": { | 399 | "locked": { |
400 | "lastModified": 1737627930, | 400 | "lastModified": 1737961005, |
401 | "narHash": "sha256-oaAatwNVaX36xmI2AKIVu2oG07XJmHq2T+Y66hEprd8=", | 401 | "narHash": "sha256-b4hqJNgyx8lnngz7NFcJ1W+59xQnMQYF0EK5g0IOy7c=", |
402 | "owner": "sodiboo", | 402 | "owner": "sodiboo", |
403 | "repo": "niri-flake", | 403 | "repo": "niri-flake", |
404 | "rev": "f79aa307f4bc0bfbabee404e6354fd2a1edfcb01", | 404 | "rev": "e98ae62893568dd31e7a7e4e75e1dbbf23f759a0", |
405 | "type": "github" | 405 | "type": "github" |
406 | }, | 406 | }, |
407 | "original": { | 407 | "original": { |
@@ -431,11 +431,11 @@ | |||
431 | "niri-unstable": { | 431 | "niri-unstable": { |
432 | "flake": false, | 432 | "flake": false, |
433 | "locked": { | 433 | "locked": { |
434 | "lastModified": 1736861309, | 434 | "lastModified": 1737795105, |
435 | "narHash": "sha256-RSCoXyngYF+7apD5pRq6lZfRbl8vHIUVI57bbihA5Ew=", | 435 | "narHash": "sha256-OsrjQ8O9t9NjDCwfG/EY8MT+K3lb+A5U6SZZ+4PyKzk=", |
436 | "owner": "gkleen", | 436 | "owner": "gkleen", |
437 | "repo": "niri", | 437 | "repo": "niri", |
438 | "rev": "80a7ee2971b2d43622f68dcdc3233ae8365338f6", | 438 | "rev": "78697d1cea20e6b53013e820999b0403c45d9f00", |
439 | "type": "github" | 439 | "type": "github" |
440 | }, | 440 | }, |
441 | "original": { | 441 | "original": { |
@@ -472,11 +472,11 @@ | |||
472 | ] | 472 | ] |
473 | }, | 473 | }, |
474 | "locked": { | 474 | "locked": { |
475 | "lastModified": 1736652904, | 475 | "lastModified": 1737861961, |
476 | "narHash": "sha256-8uolHABgroXqzs03QdulHp8H9e5kWQZnnhcda1MKbBM=", | 476 | "narHash": "sha256-LIRtMvAwLGb8pBoamzgEF67oKlNPz4LuXiRPVZf+TpE=", |
477 | "owner": "Mic92", | 477 | "owner": "Mic92", |
478 | "repo": "nix-index-database", | 478 | "repo": "nix-index-database", |
479 | "rev": "271e5bd7c57e1f001693799518b10a02d1123b12", | 479 | "rev": "79b7b8eae3243fc5aa9aad34ba6b9bbb2266f523", |
480 | "type": "github" | 480 | "type": "github" |
481 | }, | 481 | }, |
482 | "original": { | 482 | "original": { |
@@ -508,11 +508,11 @@ | |||
508 | }, | 508 | }, |
509 | "nixos-hardware": { | 509 | "nixos-hardware": { |
510 | "locked": { | 510 | "locked": { |
511 | "lastModified": 1736441705, | 511 | "lastModified": 1737751639, |
512 | "narHash": "sha256-OL7leZ6KBhcDF3nEKe4aZVfIm6xQpb1Kb+mxySIP93o=", | 512 | "narHash": "sha256-ZEbOJ9iT72iwqXsiEMbEa8wWjyFvRA9Ugx8utmYbpz4=", |
513 | "owner": "NixOS", | 513 | "owner": "NixOS", |
514 | "repo": "nixos-hardware", | 514 | "repo": "nixos-hardware", |
515 | "rev": "8870dcaff63dfc6647fb10648b827e9d40b0a337", | 515 | "rev": "dfad538f751a5aa5d4436d9781ab27a6128ec9d4", |
516 | "type": "github" | 516 | "type": "github" |
517 | }, | 517 | }, |
518 | "original": { | 518 | "original": { |
@@ -630,11 +630,11 @@ | |||
630 | }, | 630 | }, |
631 | "nixpkgs-stable_2": { | 631 | "nixpkgs-stable_2": { |
632 | "locked": { | 632 | "locked": { |
633 | "lastModified": 1737569578, | 633 | "lastModified": 1737885640, |
634 | "narHash": "sha256-6qY0pk2QmUtBT9Mywdvif0i/CLVgpCjMUn6g9vB+f3M=", | 634 | "narHash": "sha256-GFzPxJzTd1rPIVD4IW+GwJlyGwBDV1Tj5FLYwDQQ9sM=", |
635 | "owner": "NixOS", | 635 | "owner": "NixOS", |
636 | "repo": "nixpkgs", | 636 | "repo": "nixpkgs", |
637 | "rev": "47addd76727f42d351590c905d9d1905ca895b82", | 637 | "rev": "4e96537f163fad24ed9eb317798a79afc85b51b7", |
638 | "type": "github" | 638 | "type": "github" |
639 | }, | 639 | }, |
640 | "original": { | 640 | "original": { |
@@ -678,11 +678,11 @@ | |||
678 | }, | 678 | }, |
679 | "nixpkgs_2": { | 679 | "nixpkgs_2": { |
680 | "locked": { | 680 | "locked": { |
681 | "lastModified": 1736798957, | 681 | "lastModified": 1737885589, |
682 | "narHash": "sha256-qwpCtZhSsSNQtK4xYGzMiyEDhkNzOCz/Vfu4oL2ETsQ=", | 682 | "narHash": "sha256-Zf0hSrtzaM1DEz8//+Xs51k/wdSajticVrATqDrfQjg=", |
683 | "owner": "NixOS", | 683 | "owner": "NixOS", |
684 | "repo": "nixpkgs", | 684 | "repo": "nixpkgs", |
685 | "rev": "9abb87b552b7f55ac8916b6fc9e5cb486656a2f3", | 685 | "rev": "852ff1d9e153d8875a83602e03fdef8a63f0ecf8", |
686 | "type": "github" | 686 | "type": "github" |
687 | }, | 687 | }, |
688 | "original": { | 688 | "original": { |
@@ -748,11 +748,11 @@ | |||
748 | "treefmt-nix": "treefmt-nix" | 748 | "treefmt-nix": "treefmt-nix" |
749 | }, | 749 | }, |
750 | "locked": { | 750 | "locked": { |
751 | "lastModified": 1736774291, | 751 | "lastModified": 1736884309, |
752 | "narHash": "sha256-1rEUm7R93L8rltgyBzon2/lzIN2udC/Kd8nyvuDN6ps=", | 752 | "narHash": "sha256-eiCqmKl0BIRiYk5/ZhZozwn4/7Km9CWTbc15Cv+VX5k=", |
753 | "owner": "nix-community", | 753 | "owner": "nix-community", |
754 | "repo": "poetry2nix", | 754 | "repo": "poetry2nix", |
755 | "rev": "499221030113adc5dea05886a1d7aa1cc3a315d1", | 755 | "rev": "75d0515332b7ca269f6d7abfd2c44c47a7cbca7b", |
756 | "type": "github" | 756 | "type": "github" |
757 | }, | 757 | }, |
758 | "original": { | 758 | "original": { |
@@ -891,11 +891,11 @@ | |||
891 | ] | 891 | ] |
892 | }, | 892 | }, |
893 | "locked": { | 893 | "locked": { |
894 | "lastModified": 1736808430, | 894 | "lastModified": 1737411508, |
895 | "narHash": "sha256-wlgdf/n7bJMLBheqt1jmPoxJFrUP6FByKQFXuM9YvIk=", | 895 | "narHash": "sha256-j9IdflJwRtqo9WpM0OfAZml47eBblUHGNQTe62OUqTw=", |
896 | "owner": "Mic92", | 896 | "owner": "Mic92", |
897 | "repo": "sops-nix", | 897 | "repo": "sops-nix", |
898 | "rev": "553c7cb22fed19fd60eb310423fdc93045c51ba8", | 898 | "rev": "015d461c16678fc02a2f405eb453abb509d4e1d4", |
899 | "type": "github" | 899 | "type": "github" |
900 | }, | 900 | }, |
901 | "original": { | 901 | "original": { |
@@ -1000,11 +1000,11 @@ | |||
1000 | "xwayland-satellite-unstable": { | 1000 | "xwayland-satellite-unstable": { |
1001 | "flake": false, | 1001 | "flake": false, |
1002 | "locked": { | 1002 | "locked": { |
1003 | "lastModified": 1736487362, | 1003 | "lastModified": 1737837494, |
1004 | "narHash": "sha256-4kGoOA7FgK9N2mzS+TFEn41kUUNY6KwdiA/0rqlr868=", | 1004 | "narHash": "sha256-wIMowP8Juas4ZwMRcpc+58sZ0kKTDu8fm13THPmv/F8=", |
1005 | "owner": "Supreeeme", | 1005 | "owner": "Supreeeme", |
1006 | "repo": "xwayland-satellite", | 1006 | "repo": "xwayland-satellite", |
1007 | "rev": "8f55e27f63a749881c4bbfbb6b1da028342a91d1", | 1007 | "rev": "3944c9a0e40e5629f16ad023bbc90dac80d35a0f", |
1008 | "type": "github" | 1008 | "type": "github" |
1009 | }, | 1009 | }, |
1010 | "original": { | 1010 | "original": { |
diff --git a/hosts/sif/default.nix b/hosts/sif/default.nix index 9de16de3..32651e14 100644 --- a/hosts/sif/default.nix +++ b/hosts/sif/default.nix | |||
@@ -470,16 +470,16 @@ in { | |||
470 | exportConfiguration = true; | 470 | exportConfiguration = true; |
471 | }; | 471 | }; |
472 | libinput.enable = true; | 472 | libinput.enable = true; |
473 | }; | ||
474 | 473 | ||
475 | programs.niri.enable = true; | 474 | envfs.enable = false; |
475 | }; | ||
476 | 476 | ||
477 | systemd.tmpfiles.settings = { | 477 | systemd.tmpfiles.settings = { |
478 | "10-localtime"."/etc/localtime".L.argument = "/.bcachefs/etc/localtime"; | 478 | "10-localtime"."/etc/localtime".L.argument = "/.bcachefs/etc/localtime"; |
479 | 479 | ||
480 | "10-regreet"."/var/cache/regreet/cache.toml".C.argument = toString ((pkgs.formats.toml {}).generate "cache.toml" { | 480 | "10-regreet"."/var/cache/regreet/cache.toml".C.argument = toString ((pkgs.formats.toml {}).generate "cache.toml" { |
481 | last_user = "gkleen"; | 481 | last_user = "gkleen"; |
482 | user_to_last_sess.gkleen = "Niri"; | 482 | user_to_last_sess.gkleen = "niri"; |
483 | }); | 483 | }); |
484 | }; | 484 | }; |
485 | 485 | ||
@@ -589,7 +589,7 @@ in { | |||
589 | }; | 589 | }; |
590 | 590 | ||
591 | nvidia = { | 591 | nvidia = { |
592 | open = true; | 592 | open = false; |
593 | modesetting.enable = true; | 593 | modesetting.enable = true; |
594 | powerManagement.enable = true; | 594 | powerManagement.enable = true; |
595 | # prime = { | 595 | # prime = { |
@@ -680,6 +680,8 @@ in { | |||
680 | light.enable = true; | 680 | light.enable = true; |
681 | wireshark.enable = true; | 681 | wireshark.enable = true; |
682 | dconf.enable = true; | 682 | dconf.enable = true; |
683 | niri.enable = true; | ||
684 | fuse.userAllowOther = true; | ||
683 | }; | 685 | }; |
684 | 686 | ||
685 | services.pcscd.enable = true; | 687 | services.pcscd.enable = true; |
@@ -716,11 +718,11 @@ in { | |||
716 | directories = [ | 718 | directories = [ |
717 | "/nix" | 719 | "/nix" |
718 | "/root" | 720 | "/root" |
721 | "/home" | ||
719 | "/var/log" | 722 | "/var/log" |
720 | "/var/lib/sops-nix" | 723 | "/var/lib/sops-nix" |
721 | "/var/lib/nixos" | 724 | "/var/lib/nixos" |
722 | "/var/lib/systemd" | 725 | "/var/lib/systemd" |
723 | "/home" | ||
724 | "/var/lib/chrony" | 726 | "/var/lib/chrony" |
725 | "/var/lib/fprint" | 727 | "/var/lib/fprint" |
726 | "/var/lib/bluetooth" | 728 | "/var/lib/bluetooth" |
diff --git a/hosts/sif/greetd/wallpaper.png b/hosts/sif/greetd/wallpaper.png index f6f6c818..20fc761a 100644 --- a/hosts/sif/greetd/wallpaper.png +++ b/hosts/sif/greetd/wallpaper.png | |||
Binary files differ | |||
diff --git a/modules/nix-access-tokens/default.nix b/modules/nix-access-tokens/default.nix new file mode 100644 index 00000000..a3b7abfa --- /dev/null +++ b/modules/nix-access-tokens/default.nix | |||
@@ -0,0 +1,24 @@ | |||
1 | { lib, config, hostName ,... }: | ||
2 | |||
3 | let | ||
4 | cfg = config.nix.includeAccessTokens; | ||
5 | in { | ||
6 | options = { | ||
7 | nix.includeAccessTokens.enable = lib.mkEnableOption "including access tokens in nix.conf" // { default = lib.elem hostName ["sif" "surtr" "vidhar"]; }; | ||
8 | }; | ||
9 | |||
10 | config = lib.mkIf cfg.enable { | ||
11 | nix = { | ||
12 | extraOptions = '' | ||
13 | !include ${config.sops.secrets.nixAccessTokens.path} | ||
14 | ''; | ||
15 | }; | ||
16 | |||
17 | sops.secrets.nixAccessTokens = { | ||
18 | format = "binary"; | ||
19 | sopsFile = ./nix.conf; | ||
20 | mode = "0440"; | ||
21 | group = "wheel"; | ||
22 | }; | ||
23 | }; | ||
24 | } | ||
diff --git a/modules/nix-access-tokens/nix.conf b/modules/nix-access-tokens/nix.conf new file mode 100644 index 00000000..f0b394ef --- /dev/null +++ b/modules/nix-access-tokens/nix.conf | |||
@@ -0,0 +1,32 @@ | |||
1 | { | ||
2 | "data": "ENC[AES256_GCM,data:/cdBpvCAFpgm0YWhy1WYlA09KlU6PzVfBYVLBD0boqGqvP+8wuyDzj5KWbcKsdGhoiklODiKR0ODXNU+fA35y862PFXvSb4xVyfbdKRndYdIA4W6vyobtoC9h7B1yR9pkq9L+1tqlU30Dgy2Gndg9rWHlIo+1lO/1A==,iv:B1Px2+cxCaopHZThkEG5saOib+PNvurPIS6aeAv2uPo=,tag:K3JqRaX3/iIqD3c//YdqSQ==,type:str]", | ||
3 | "sops": { | ||
4 | "kms": null, | ||
5 | "gcp_kms": null, | ||
6 | "azure_kv": null, | ||
7 | "hc_vault": null, | ||
8 | "age": [ | ||
9 | { | ||
10 | "recipient": "age1rmmhetcmllq0ahl5qznlr0eya2zdxwl9h6y5wnl97d2wtyx5t99sm2u866", | ||
11 | "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB5NkZUUGI3M2pQYWVXeFV6\na2h2czRTeUJFekJCS012YlBkL1FDdTd3ekZ3ClJsTVh0R2JQM0Jua1JjL285RVA1\nRHhlbjlLdmNBUXVLelFGY2NGYWpLejQKLS0tIDBUWUhJNm8zWGoyQ0pBYnV1ZjBh\ndktNRkNPS1lpWXFITC81aEZJbXlONk0Km2c1xVKwSankaVs7O/utGJwRRX395upz\ndPbsOElTnbGmkb0esGtvGSPboTvK+gjn9w/GhaPyTnNDoos7GaIfyg==\n-----END AGE ENCRYPTED FILE-----\n" | ||
12 | }, | ||
13 | { | ||
14 | "recipient": "age1fj65apkhfkrwyv5tx6zcs9nkjg8267fy733qph30sc7zfn7vapjqkd5kne", | ||
15 | "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB6bS9iY2lua3U4U3lJa1pK\nSlZNMmFZMEU5M1V2bWRjaXIwajZJVDJPMlM4Cmd3TTNFWjVuSGdtbC9iODltTS91\nOE5XOEVEQkh0SFpVVW5jc3IzbzNpTmMKLS0tIEtrSU54QUVPa2tBZDhLYlRFWitR\nc2x6MFlxL0tobDJTek42dEcyZXpoWDgKXzQfU+o6FkbJBwmm6oaHu4sDPi822uUR\n5VY6gY/h3g2kM4cuS03Q4NJmeRxuh7cx0UqGU3j5Mf8muE1LHpYEPw==\n-----END AGE ENCRYPTED FILE-----\n" | ||
16 | }, | ||
17 | { | ||
18 | "recipient": "age19a7j77w267z04zls7m28a8hj4a0g5af6ltye2d5wypg33c3l89csd4r9zq", | ||
19 | "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBaOVpNZ2lVT0VwbHVZNzFl\nenJsMGpnbkRvU0xOSU5obk5yT2p5ZVNzdXhNCnVlQzZtRjZNVmJLSUpKc3UwVXZs\nWi9EZ3kxZkJNeFJDSjl1L1IweTFNMXcKLS0tIDJUOTBwTldCUmlnU0tWVkZkNzJL\nejM4ajJVbVhvSm1YM2Vxa2JldllYN0UKAzxy2wkzRvCSiTy417AulpCu41z668HG\nto92eGF2ZRFfEG5LGlCKWeDcP3gM8QwKiVlm6wndbOkhMMfc4Sp3wA==\n-----END AGE ENCRYPTED FILE-----\n" | ||
20 | }, | ||
21 | { | ||
22 | "recipient": "age1qffdqvy9arld9zd5a5cylt0n98xhcns5shxhrhwjq5g4qa844ejselaa4l", | ||
23 | "enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB2ejRHcGttNUxYZnFzTU5J\nMTFvY3daQ1VMM2xxYTgvLzZwT1owazVNenhzCktaWFF6K2s5UjI2b20rSHFNSS9E\nMVlJSmZhQm15eUs3U0hGTGpSRndmSDgKLS0tIDVrcjl4eDhwak1pRithbnRWWEZy\nVE9EOEpKdEJoRTFrTXpQVDc1cmsrU1kK/goTdUmpZPeMRbY1QzLXAa6Qpg4YYYYo\n3v3GK1bzdey8szfgIr1dHTtQEzqE2WX1swzZizDXj/RiUWx01Ky3GA==\n-----END AGE ENCRYPTED FILE-----\n" | ||
24 | } | ||
25 | ], | ||
26 | "lastmodified": "2025-01-25T19:58:58Z", | ||
27 | "mac": "ENC[AES256_GCM,data:Oza4XgnTX3vly89nGluLbEytk1dUYAiOhIYewQyDLLLSSlUIpXmWhV+X0HUQ9AX5kUrEhNbVzRdvUG/9YwoWjTJfvd7tw41IYeTqgykMNXJUfGssoutXfeij9YR+t5aJaRhlTkIWcBhUjXSUNyJCl6Z3XmzWstTPZXEU9VmAvuE=,iv:LqVwIiit+WqI5NWSboexWsmPzg7e63nWJYsNFEK1Uog=,tag:ClR6oI62WXEfIYYAY6vL0A==,type:str]", | ||
28 | "pgp": null, | ||
29 | "unencrypted_suffix": "_unencrypted", | ||
30 | "version": "3.9.3" | ||
31 | } | ||
32 | } \ No newline at end of file | ||
diff --git a/nvfetcher.toml b/nvfetcher.toml index d33040c5..ecaebba0 100644 --- a/nvfetcher.toml +++ b/nvfetcher.toml | |||
@@ -78,12 +78,12 @@ git.fetchSubmodules = true | |||
78 | src.git = "https://github.com/jgreco/mpv-youtube-quality" | 78 | src.git = "https://github.com/jgreco/mpv-youtube-quality" |
79 | fetch.git = "https://github.com/jgreco/mpv-youtube-quality" | 79 | fetch.git = "https://github.com/jgreco/mpv-youtube-quality" |
80 | 80 | ||
81 | [batman-adv] | 81 | # [batman-adv] |
82 | src.webpage = "https://www.open-mesh.org/projects/open-mesh/wiki/Download" | 82 | # src.webpage = "https://www.open-mesh.org/projects/open-mesh/wiki/Download" |
83 | src.regex = "The latest version of <a[^\\>]*>batman-adv</a> is <a[^\\>]*>batman-adv-([0-9\\.]+).tar.gz</a>" | 83 | # src.regex = "The latest version of <a[^\\>]*>batman-adv</a> is <a[^\\>]*>batman-adv-([0-9\\.]+).tar.gz</a>" |
84 | src.from_pattern = "^.*batman-adv-([0-9\\.]+).tar.gz.*$" | 84 | # src.from_pattern = "^.*batman-adv-([0-9\\.]+).tar.gz.*$" |
85 | src.to_pattern = "\\1" | 85 | # src.to_pattern = "\\1" |
86 | fetch.tarball = "https://downloads.open-mesh.org/batman/stable/sources/batman-adv/batman-adv-$ver.tar.gz" | 86 | # fetch.tarball = "https://downloads.open-mesh.org/batman/stable/sources/batman-adv/batman-adv-$ver.tar.gz" |
87 | 87 | ||
88 | [scutiger] | 88 | [scutiger] |
89 | src.github_tag = "bk2204/scutiger" | 89 | src.github_tag = "bk2204/scutiger" |
@@ -110,4 +110,8 @@ fetch.pypi = "yt_dlp" | |||
110 | 110 | ||
111 | [mako] | 111 | [mako] |
112 | src.git = "https://github.com/emersion/mako" | 112 | src.git = "https://github.com/emersion/mako" |
113 | fetch.git = "https://github.com/emersion/mako" \ No newline at end of file | 113 | fetch.git = "https://github.com/emersion/mako" |
114 | |||
115 | [swayosd] | ||
116 | src.git = "https://github.com/ErikReider/SwayOSD" | ||
117 | fetch.git = "https://github.com/ErikReider/SwayOSD" | ||
diff --git a/overlays/batman-adv.nix b/overlays/batman-adv.nix deleted file mode 100644 index cce7dc4f..00000000 --- a/overlays/batman-adv.nix +++ /dev/null | |||
@@ -1,15 +0,0 @@ | |||
1 | { final, prev, sources, ... }: { | ||
2 | linuxPackages_latest = prev.linuxPackages_latest.extend (self: super: { | ||
3 | batman_adv = super.batman_adv.overrideAttrs (oldAttrs: { | ||
4 | version = "${sources.batman-adv.version}-${self.kernel.version}"; | ||
5 | inherit (sources.batman-adv) src; | ||
6 | }); | ||
7 | }); | ||
8 | |||
9 | linuxPackages_6_2 = prev.linuxPackages_6_2.extend (self: super: { | ||
10 | batman_adv = super.batman_adv.overrideAttrs (oldAttrs: { | ||
11 | version = "${sources.batman-adv.version}-${self.kernel.version}"; | ||
12 | inherit (sources.batman-adv) src; | ||
13 | }); | ||
14 | }); | ||
15 | } | ||
diff --git a/overlays/keepassxc/database-open-dialog.patch b/overlays/keepassxc/database-open-dialog.patch new file mode 100644 index 00000000..4916dc1b --- /dev/null +++ b/overlays/keepassxc/database-open-dialog.patch | |||
@@ -0,0 +1,126 @@ | |||
1 | diff -u3 -r source.orig/src/browser/BrowserService.cpp source/src/browser/BrowserService.cpp | ||
2 | --- source.orig/src/browser/BrowserService.cpp 2025-01-27 20:55:04.128198171 +0100 | ||
3 | +++ source/src/browser/BrowserService.cpp 2025-01-27 21:16:07.068959077 +0100 | ||
4 | @@ -249,7 +249,7 @@ | ||
5 | return result; | ||
6 | } | ||
7 | |||
8 | - auto dialogResult = MessageBox::warning(m_currentDatabaseWidget, | ||
9 | + auto dialogResult = MessageBox::warning(nullptr, | ||
10 | tr("KeePassXC - Create a new group"), | ||
11 | tr("A request for creating a new group \"%1\" has been received.\n" | ||
12 | "Do you want to create this group?\n") | ||
13 | @@ -422,7 +422,7 @@ | ||
14 | |||
15 | m_dialogActive = true; | ||
16 | updateWindowState(); | ||
17 | - BrowserAccessControlDialog accessControlDialog(m_currentDatabaseWidget); | ||
18 | + BrowserAccessControlDialog accessControlDialog{}; | ||
19 | |||
20 | connect(m_currentDatabaseWidget, SIGNAL(databaseLockRequested()), &accessControlDialog, SLOT(reject())); | ||
21 | |||
22 | @@ -512,7 +512,7 @@ | ||
23 | QString id; | ||
24 | |||
25 | do { | ||
26 | - QInputDialog keyDialog(m_currentDatabaseWidget); | ||
27 | + QInputDialog keyDialog{}; | ||
28 | connect(m_currentDatabaseWidget, SIGNAL(databaseLockRequested()), &keyDialog, SLOT(reject())); | ||
29 | keyDialog.setWindowTitle(tr("KeePassXC - New key association request")); | ||
30 | keyDialog.setLabelText(tr("You have received an association request for the following database:\n%1\n\n" | ||
31 | @@ -535,7 +535,7 @@ | ||
32 | |||
33 | contains = db->metadata()->customData()->contains(CustomData::BrowserKeyPrefix + id); | ||
34 | if (contains) { | ||
35 | - dialogResult = MessageBox::warning(m_currentDatabaseWidget, | ||
36 | + dialogResult = MessageBox::warning(nullptr, | ||
37 | tr("KeePassXC - Overwrite existing key?"), | ||
38 | tr("A shared encryption key with the name \"%1\" " | ||
39 | "already exists.\nDo you want to overwrite it?") | ||
40 | @@ -595,7 +595,7 @@ | ||
41 | const auto existingEntries = getPasskeyEntriesWithUserHandle(rpId, userId, keyList); | ||
42 | |||
43 | raiseWindow(); | ||
44 | - BrowserPasskeysConfirmationDialog confirmDialog(m_currentDatabaseWidget); | ||
45 | + BrowserPasskeysConfirmationDialog confirmDialog{}; | ||
46 | confirmDialog.registerCredential(username, rpId, existingEntries, timeout); | ||
47 | |||
48 | auto dialogResult = confirmDialog.exec(); | ||
49 | @@ -612,7 +612,7 @@ | ||
50 | // If no entry is selected, show the import dialog for manual entry selection | ||
51 | auto selectedEntry = confirmDialog.getSelectedEntry(); | ||
52 | if (!selectedEntry) { | ||
53 | - PasskeyImporter passkeyImporter(m_currentDatabaseWidget); | ||
54 | + PasskeyImporter passkeyImporter{}; | ||
55 | const auto result = passkeyImporter.showImportDialog(db, | ||
56 | nullptr, | ||
57 | origin, | ||
58 | @@ -683,7 +683,7 @@ | ||
59 | const auto timeout = publicKeyOptions["timeout"].toInt(); | ||
60 | |||
61 | raiseWindow(); | ||
62 | - BrowserPasskeysConfirmationDialog confirmDialog(m_currentDatabaseWidget); | ||
63 | + BrowserPasskeysConfirmationDialog confirmDialog{}; | ||
64 | confirmDialog.authenticateCredential(entries, rpId, timeout); | ||
65 | auto dialogResult = confirmDialog.exec(); | ||
66 | if (dialogResult == QDialog::Accepted) { | ||
67 | @@ -760,7 +760,7 @@ | ||
68 | |||
69 | // Ask confirmation if entry already contains a Passkey | ||
70 | if (entry->hasPasskey()) { | ||
71 | - if (MessageBox::question(m_currentDatabaseWidget, | ||
72 | + if (MessageBox::question(nullptr, | ||
73 | tr("KeePassXC - Update passkey"), | ||
74 | tr("Entry already has a passkey.\nDo you want to overwrite the passkey in %1 - %2?") | ||
75 | .arg(entry->title(), passkeyUtils()->getUsernameFromEntry(entry)), | ||
76 | @@ -873,7 +873,7 @@ | ||
77 | MessageBox::Button dialogResult = MessageBox::No; | ||
78 | if (!browserSettings()->alwaysAllowUpdate()) { | ||
79 | raiseWindow(); | ||
80 | - dialogResult = MessageBox::question(m_currentDatabaseWidget, | ||
81 | + dialogResult = MessageBox::question(nullptr, | ||
82 | tr("KeePassXC - Update Entry"), | ||
83 | tr("Do you want to update the information in %1 - %2?") | ||
84 | .arg(QUrl(entryParameters.siteUrl).host(), username), | ||
85 | @@ -909,7 +909,7 @@ | ||
86 | return false; | ||
87 | } | ||
88 | |||
89 | - auto dialogResult = MessageBox::warning(m_currentDatabaseWidget, | ||
90 | + auto dialogResult = MessageBox::warning(nullptr, | ||
91 | tr("KeePassXC - Delete entry"), | ||
92 | tr("A request for deleting entry \"%1\" has been received.\n" | ||
93 | "Do you want to delete the entry?\n") | ||
94 | @@ -1536,7 +1536,7 @@ | ||
95 | } | ||
96 | } | ||
97 | |||
98 | - BrowserEntrySaveDialog browserEntrySaveDialog(m_currentDatabaseWidget); | ||
99 | + BrowserEntrySaveDialog browserEntrySaveDialog{}; | ||
100 | int openDatabaseCount = browserEntrySaveDialog.setItems(databaseWidgets, m_currentDatabaseWidget); | ||
101 | if (openDatabaseCount > 1) { | ||
102 | int res = browserEntrySaveDialog.exec(); | ||
103 | diff -u3 -r source.orig/src/fdosecrets/objects/Prompt.cpp source/src/fdosecrets/objects/Prompt.cpp | ||
104 | --- source.orig/src/fdosecrets/objects/Prompt.cpp 2025-01-27 20:55:04.135942791 +0100 | ||
105 | +++ source/src/fdosecrets/objects/Prompt.cpp 2025-01-27 21:01:37.166710935 +0100 | ||
106 | @@ -313,7 +313,7 @@ | ||
107 | if (!entries.isEmpty()) { | ||
108 | QString app = tr("%1 (PID: %2)").arg(client->name()).arg(client->pid()); | ||
109 | auto ac = new AccessControlDialog( | ||
110 | - findWindow(m_windowId), entries, app, client->processInfo(), AuthOption::Remember); | ||
111 | + nullptr, entries, app, client->processInfo(), AuthOption::Remember); | ||
112 | connect(ac, &AccessControlDialog::finished, this, &UnlockPrompt::itemUnlockFinished); | ||
113 | connect(ac, &AccessControlDialog::finished, ac, &AccessControlDialog::deleteLater); | ||
114 | ac->open(); | ||
115 | diff -u3 -r source.orig/src/gui/DatabaseTabWidget.cpp source/src/gui/DatabaseTabWidget.cpp | ||
116 | --- source.orig/src/gui/DatabaseTabWidget.cpp 2025-01-27 20:55:04.134589500 +0100 | ||
117 | +++ source/src/gui/DatabaseTabWidget.cpp 2025-01-27 21:07:09.785284837 +0100 | ||
118 | @@ -41,7 +41,7 @@ | ||
119 | : QTabWidget(parent) | ||
120 | , m_dbWidgetStateSync(new DatabaseWidgetStateSync(this)) | ||
121 | , m_dbWidgetPendingLock(nullptr) | ||
122 | - , m_databaseOpenDialog(new DatabaseOpenDialog(this)) | ||
123 | + , m_databaseOpenDialog(new DatabaseOpenDialog()) | ||
124 | , m_databaseOpenInProgress(false) | ||
125 | { | ||
126 | auto* tabBar = new QTabBar(this); | ||
diff --git a/overlays/keepassxc/default.nix b/overlays/keepassxc/default.nix new file mode 100644 index 00000000..25429a66 --- /dev/null +++ b/overlays/keepassxc/default.nix | |||
@@ -0,0 +1,8 @@ | |||
1 | { final, prev, ... }: | ||
2 | { | ||
3 | keepassxc = prev.keepassxc.overrideAttrs (oldAttrs: { | ||
4 | patches = (oldAttrs.patches or []) ++ [ | ||
5 | ./database-open-dialog.patch | ||
6 | ]; | ||
7 | }); | ||
8 | } | ||
diff --git a/overlays/swayosd/default.nix b/overlays/swayosd/default.nix new file mode 100644 index 00000000..28c8f1b9 --- /dev/null +++ b/overlays/swayosd/default.nix | |||
@@ -0,0 +1,30 @@ | |||
1 | { final, prev, sources, ... }: { | ||
2 | swayosd = prev.swayosd.overrideAttrs (oldAttrs: rec { | ||
3 | inherit (sources.swayosd) version src; | ||
4 | cargoDeps = prev.rustPlatform.fetchCargoTarball { | ||
5 | inherit (oldAttrs) pname; | ||
6 | inherit version src; | ||
7 | hash = "sha256-Anrk8p76HKZcNavYdi9l1oYahduLrb7Lf7knQK7Hy5E="; | ||
8 | }; | ||
9 | nativeBuildInputs = with final; [ | ||
10 | wrapGAppsHook4 | ||
11 | pkg-config | ||
12 | meson | ||
13 | rustc | ||
14 | cargo | ||
15 | ninja | ||
16 | rustPlatform.cargoSetupHook | ||
17 | ]; | ||
18 | buildInputs = with final; [ | ||
19 | gtk4-layer-shell | ||
20 | libevdev | ||
21 | libinput | ||
22 | libpulseaudio | ||
23 | udev | ||
24 | sassc | ||
25 | ]; | ||
26 | patches = (oldAttrs.patches or []) ++ [ | ||
27 | ./exponential.patch | ||
28 | ]; | ||
29 | }); | ||
30 | } | ||
diff --git a/overlays/swayosd/exponential.patch b/overlays/swayosd/exponential.patch new file mode 100644 index 00000000..eb90d739 --- /dev/null +++ b/overlays/swayosd/exponential.patch | |||
@@ -0,0 +1,57 @@ | |||
1 | diff --git a/src/brightness_backend/brightnessctl.rs b/src/brightness_backend/brightnessctl.rs | ||
2 | index ccb0e11..740fdb6 100644 | ||
3 | --- a/src/brightness_backend/brightnessctl.rs | ||
4 | +++ b/src/brightness_backend/brightnessctl.rs | ||
5 | @@ -107,10 +107,21 @@ impl VirtualDevice { | ||
6 | } | ||
7 | } | ||
8 | |||
9 | - fn set_percent(&mut self, mut val: u32) -> anyhow::Result<()> { | ||
10 | - val = val.clamp(0, 100); | ||
11 | - self.current = self.max.map(|max| val * max / 100); | ||
12 | - let _: String = self.run(("set", &*format!("{val}%")))?; | ||
13 | + fn val_to_percent(&mut self, val: u32) -> u32 { | ||
14 | + return ((val as f64 / self.get_max() as f64).powf(0.25) * 100_f64).round() as u32; | ||
15 | + } | ||
16 | + fn percent_to_val(&mut self, perc: u32) -> u32 { | ||
17 | + return ((perc as f64 / 100_f64).powf(4_f64) * self.get_max() as f64).round() as u32; | ||
18 | + } | ||
19 | + | ||
20 | + fn set_percent(&mut self, val: u32) -> anyhow::Result<()> { | ||
21 | + let new = self.percent_to_val(val); | ||
22 | + self.set_val(new) | ||
23 | + } | ||
24 | + fn set_val(&mut self, val: u32) -> anyhow::Result<()> { | ||
25 | + let curr = val.clamp(0, self.get_max()); | ||
26 | + self.current = Some(curr); | ||
27 | + let _: String = self.run(("set", &*format!("{curr}")))?; | ||
28 | Ok(()) | ||
29 | } | ||
30 | } | ||
31 | @@ -134,20 +145,18 @@ impl BrightnessBackend for BrightnessCtl { | ||
32 | |||
33 | fn lower(&mut self, by: u32) -> anyhow::Result<()> { | ||
34 | let curr = self.get_current(); | ||
35 | - let max = self.get_max(); | ||
36 | - | ||
37 | - let curr = curr * 100 / max; | ||
38 | + let mut new = self.device.val_to_percent(curr).saturating_sub(by); | ||
39 | + new = self.device.percent_to_val(new).min(curr.saturating_sub(1)); | ||
40 | |||
41 | - self.device.set_percent(curr.saturating_sub(by)) | ||
42 | + self.device.set_val(new) | ||
43 | } | ||
44 | |||
45 | fn raise(&mut self, by: u32) -> anyhow::Result<()> { | ||
46 | let curr = self.get_current(); | ||
47 | - let max = self.get_max(); | ||
48 | - | ||
49 | - let curr = curr * 100 / max; | ||
50 | + let mut new = self.device.val_to_percent(curr) + by; | ||
51 | + new = self.device.percent_to_val(new).max(curr + 1); | ||
52 | |||
53 | - self.device.set_percent(curr + by) | ||
54 | + self.device.set_val(new) | ||
55 | } | ||
56 | |||
57 | fn set(&mut self, val: u32) -> anyhow::Result<()> { | ||
diff --git a/overlays/worktime/worktime/__main__.py b/overlays/worktime/worktime/__main__.py index 362c8da4..ba6c5ff6 100755 --- a/overlays/worktime/worktime/__main__.py +++ b/overlays/worktime/worktime/__main__.py | |||
@@ -23,7 +23,7 @@ import argparse | |||
23 | from copy import deepcopy | 23 | from copy import deepcopy |
24 | 24 | ||
25 | import sys | 25 | import sys |
26 | from sys import stderr | 26 | from sys import stderr, stdout |
27 | 27 | ||
28 | from tabulate import tabulate | 28 | from tabulate import tabulate |
29 | 29 | ||
@@ -38,6 +38,7 @@ from collections import defaultdict | |||
38 | 38 | ||
39 | import jsonpickle | 39 | import jsonpickle |
40 | from hashlib import blake2s | 40 | from hashlib import blake2s |
41 | import json | ||
41 | 42 | ||
42 | class TogglAPISection(Enum): | 43 | class TogglAPISection(Enum): |
43 | TOGGL = '/api/v9' | 44 | TOGGL = '/api/v9' |
@@ -223,6 +224,7 @@ class Worktime(object): | |||
223 | leave_budget = dict() | 224 | leave_budget = dict() |
224 | time_per_day = None | 225 | time_per_day = None |
225 | workdays = None | 226 | workdays = None |
227 | pull_forward = dict() | ||
226 | 228 | ||
227 | @staticmethod | 229 | @staticmethod |
228 | @cache | 230 | @cache |
@@ -390,8 +392,6 @@ class Worktime(object): | |||
390 | if e.errno != 2: | 392 | if e.errno != 2: |
391 | raise e | 393 | raise e |
392 | 394 | ||
393 | pull_forward = dict() | ||
394 | |||
395 | start_day = self.start_date.date() | 395 | start_day = self.start_date.date() |
396 | end_day = self.end_date.date() | 396 | end_day = self.end_date.date() |
397 | 397 | ||
@@ -418,15 +418,15 @@ class Worktime(object): | |||
418 | if not d == datetime.strptime(c, date_format).replace(tzinfo=tzlocal()).date(): break | 418 | if not d == datetime.strptime(c, date_format).replace(tzinfo=tzlocal()).date(): break |
419 | else: | 419 | else: |
420 | if d >= self.end_date.date(): | 420 | if d >= self.end_date.date(): |
421 | pull_forward[d] = min(timedelta(hours = float(hours)), self.time_per_day(d) - (holidays[d] if d in holidays else timedelta())) | 421 | self.pull_forward[d] = min(timedelta(hours = float(hours)), self.time_per_day(d) - (holidays[d] if d in holidays else timedelta())) |
422 | except IOError as e: | 422 | except IOError as e: |
423 | if e.errno != 2: | 423 | if e.errno != 2: |
424 | raise e | 424 | raise e |
425 | 425 | ||
426 | self.days_to_work = dict() | 426 | self.days_to_work = dict() |
427 | 427 | ||
428 | if pull_forward: | 428 | if self.pull_forward: |
429 | end_day = max(end_day, max(list(pull_forward))) | 429 | end_day = max(end_day, max(list(self.pull_forward))) |
430 | 430 | ||
431 | for day in [start_day + timedelta(days = x) for x in range(0, (end_day - start_day).days + 1)]: | 431 | for day in [start_day + timedelta(days = x) for x in range(0, (end_day - start_day).days + 1)]: |
432 | if day.isoweekday() in self.workdays: | 432 | if day.isoweekday() in self.workdays: |
@@ -470,17 +470,17 @@ class Worktime(object): | |||
470 | self.extra_days_to_work[self.now.date()] = timedelta() | 470 | self.extra_days_to_work[self.now.date()] = timedelta() |
471 | 471 | ||
472 | self.time_to_work = sum([self.days_to_work[day] for day in self.days_to_work.keys() if day <= self.end_date.date()], timedelta()) | 472 | self.time_to_work = sum([self.days_to_work[day] for day in self.days_to_work.keys() if day <= self.end_date.date()], timedelta()) |
473 | for day in [d for d in list(pull_forward) if d > self.end_date.date()]: | 473 | for day in [d for d in list(self.pull_forward) if d > self.end_date.date()]: |
474 | days_forward = set([d for d in self.days_to_work.keys() if d >= self.end_date.date() and d < day and (not d in pull_forward or d == self.end_date.date())]) | 474 | days_forward = set([d for d in self.days_to_work.keys() if d >= self.end_date.date() and d < day and (not d in self.pull_forward or d == self.end_date.date())]) |
475 | extra_days_forward = set([d for d in self.extra_days_to_work.keys() if d >= self.end_date.date() and d < day and (not d in pull_forward or d == self.end_date.date())]) | 475 | extra_days_forward = set([d for d in self.extra_days_to_work.keys() if d >= self.end_date.date() and d < day and (not d in self.pull_forward or d == self.end_date.date())]) |
476 | days_forward = days_forward.union(extra_days_forward) | 476 | days_forward = days_forward.union(extra_days_forward) |
477 | 477 | ||
478 | extra_day_time_left = timedelta() | 478 | extra_day_time_left = timedelta() |
479 | for extra_day in extra_days_forward: | 479 | for extra_day in extra_days_forward: |
480 | day_time = max(timedelta(), self.time_per_day(extra_day) - self.extra_days_to_work[extra_day]) | 480 | day_time = max(timedelta(), self.time_per_day(extra_day) - self.extra_days_to_work[extra_day]) |
481 | extra_day_time_left += day_time | 481 | extra_day_time_left += day_time |
482 | extra_day_time = min(extra_day_time_left, pull_forward[day]) | 482 | extra_day_time = min(extra_day_time_left, self.pull_forward[day]) |
483 | time_forward = pull_forward[day] - extra_day_time | 483 | time_forward = self.pull_forward[day] - extra_day_time |
484 | if extra_day_time_left > timedelta(): | 484 | if extra_day_time_left > timedelta(): |
485 | for extra_day in extra_days_forward: | 485 | for extra_day in extra_days_forward: |
486 | day_time = max(timedelta(), self.time_per_day(extra_day) - self.extra_days_to_work[extra_day]) | 486 | day_time = max(timedelta(), self.time_per_day(extra_day) - self.extra_days_to_work[extra_day]) |
@@ -518,7 +518,14 @@ def format_days(worktime, days, date_format=None): | |||
518 | return ', '.join(map(lambda group: ','.join(map(format_group, group)), groups)) | 518 | return ', '.join(map(lambda group: ','.join(map(format_group, group)), groups)) |
519 | 519 | ||
520 | 520 | ||
521 | def worktime(**args): | 521 | def tooltip_timedelta(td): |
522 | if td < timedelta(seconds = 0): | ||
523 | return "-" + tooltip_timedelta(-td) | ||
524 | mm, ss = divmod(td.total_seconds(), 60) | ||
525 | hh, mm = divmod(mm, 60) | ||
526 | return "%d:%02d:%02d" % (hh, mm, ss) | ||
527 | |||
528 | def worktime(pull_forward_cutoff, waybar, **args): | ||
522 | worktime = Worktime(**args) | 529 | worktime = Worktime(**args) |
523 | 530 | ||
524 | def format_worktime(worktime): | 531 | def format_worktime(worktime): |
@@ -562,7 +569,12 @@ def worktime(**args): | |||
562 | else: | 569 | else: |
563 | return f"({difference_string})" | 570 | return f"({difference_string})" |
564 | 571 | ||
565 | if worktime.time_pulled_forward >= timedelta(minutes = 15): | 572 | out_class = "running" if worktime.running_entry else "stopped" |
573 | difference = worktime.time_to_work - worktime.time_worked | ||
574 | if worktime.running_entry and -min(timedelta(milliseconds=0), difference) > sum(worktime.pull_forward.values(), start=timedelta(milliseconds=0)) or not worktime.running_entry and max(timedelta(milliseconds=0), difference) > worktime.time_per_day(worktime.now.date()) and worktime.now_is_workday: | ||
575 | out_class = "over" | ||
576 | tooltip = tooltip_timedelta(difference) | ||
577 | if worktime.time_pulled_forward >= min(pull_forward_cutoff, timedelta(seconds = 1)): | ||
566 | worktime_no_pulled_forward = deepcopy(worktime) | 578 | worktime_no_pulled_forward = deepcopy(worktime) |
567 | worktime_no_pulled_forward.time_to_work -= worktime_no_pulled_forward.time_pulled_forward | 579 | worktime_no_pulled_forward.time_to_work -= worktime_no_pulled_forward.time_pulled_forward |
568 | worktime_no_pulled_forward.time_pulled_forward = timedelta() | 580 | worktime_no_pulled_forward.time_pulled_forward = timedelta() |
@@ -570,11 +582,24 @@ def worktime(**args): | |||
570 | difference_string = format_worktime(worktime) | 582 | difference_string = format_worktime(worktime) |
571 | difference_string_no_pulled_forward = format_worktime(worktime_no_pulled_forward) | 583 | difference_string_no_pulled_forward = format_worktime(worktime_no_pulled_forward) |
572 | 584 | ||
573 | print(f"{difference_string_no_pulled_forward}…{difference_string}") | 585 | tooltip = tooltip_timedelta(worktime_no_pulled_forward.time_to_work - worktime_no_pulled_forward.time_worked) + "…" + tooltip |
586 | if worktime.time_pulled_forward >= pull_forward_cutoff: | ||
587 | out_text = f"{difference_string_no_pulled_forward}…{difference_string}" | ||
588 | else: | ||
589 | out_text = format_worktime(worktime) | ||
590 | else: | ||
591 | out_text = format_worktime(worktime) | ||
592 | |||
593 | if waybar: | ||
594 | json.dump({"text": out_text, "class": out_class, "tooltip": tooltip}, stdout) | ||
574 | else: | 595 | else: |
575 | print(format_worktime(worktime)) | 596 | print(out_text) |
597 | |||
598 | def pull_forward(**args): | ||
599 | worktime = Worktime(**args) | ||
600 | print(tooltip_timedelta(sum(worktime.pull_forward.values(), start=timedelta(milliseconds=0)))) | ||
576 | 601 | ||
577 | def time_worked(now, **args): | 602 | def time_worked(now, waybar, **args): |
578 | then = now.replace(hour = 0, minute = 0, second = 0, microsecond = 0) | 603 | then = now.replace(hour = 0, minute = 0, second = 0, microsecond = 0) |
579 | if now.time() == time(): | 604 | if now.time() == time(): |
580 | now = now + timedelta(days = 1) | 605 | now = now + timedelta(days = 1) |
@@ -584,6 +609,9 @@ def time_worked(now, **args): | |||
584 | 609 | ||
585 | worked = now.time_worked - then.time_worked | 610 | worked = now.time_worked - then.time_worked |
586 | 611 | ||
612 | out_text = None | ||
613 | out_class = "stopped" | ||
614 | tooltip = tooltip_timedelta(worked) | ||
587 | if args['do_round']: | 615 | if args['do_round']: |
588 | total_minutes_difference = 5 * ceil(worked / timedelta(minutes = 5)) | 616 | total_minutes_difference = 5 * ceil(worked / timedelta(minutes = 5)) |
589 | (hours_difference, minutes_difference) = divmod(abs(total_minutes_difference), 60) | 617 | (hours_difference, minutes_difference) = divmod(abs(total_minutes_difference), 60) |
@@ -602,15 +630,25 @@ def time_worked(now, **args): | |||
602 | difference = target_time - worked | 630 | difference = target_time - worked |
603 | clockout_difference = 5 * ceil(difference / timedelta(minutes = 5)) | 631 | clockout_difference = 5 * ceil(difference / timedelta(minutes = 5)) |
604 | clockout_time = now.now + difference | 632 | clockout_time = now.now + difference |
633 | exact_clockout_time = clockout_time | ||
605 | clockout_time += (5 - clockout_time.minute % 5) * timedelta(minutes = 1) | 634 | clockout_time += (5 - clockout_time.minute % 5) * timedelta(minutes = 1) |
606 | clockout_time = clockout_time.replace(second = 0, microsecond = 0) | 635 | clockout_time = clockout_time.replace(second = 0, microsecond = 0) |
607 | 636 | ||
608 | if now.running_entry and clockout_time and clockout_difference >= 0: | 637 | if now.running_entry and clockout_time and clockout_difference >= 0: |
609 | print(f"{difference_string}/{clockout_time:%H:%M}") | 638 | out_class = "running" |
639 | out_text = f"{difference_string}/{clockout_time:%H:%M}" | ||
640 | tooltip = f"{tooltip_timedelta(worked)}/{exact_clockout_time:%H:%M}" | ||
610 | else: | 641 | else: |
611 | print(difference_string) | 642 | if now.running_entry: |
643 | out_class = "over" | ||
644 | out_text = difference_string | ||
645 | else: | ||
646 | out_text = str(worked) | ||
647 | |||
648 | if waybar: | ||
649 | json.dump({"text": out_text, "class": out_class, "tooltip": tooltip}, stdout) | ||
612 | else: | 650 | else: |
613 | print(worked) | 651 | print(out_text) |
614 | 652 | ||
615 | def diff(now, **args): | 653 | def diff(now, **args): |
616 | now = now.replace(hour = 0, minute = 0, second = 0, microsecond = 0) | 654 | now = now.replace(hour = 0, minute = 0, second = 0, microsecond = 0) |
@@ -798,6 +836,38 @@ def classification(classification_name, table, table_format, **args): | |||
798 | def main(): | 836 | def main(): |
799 | def isotime(s): | 837 | def isotime(s): |
800 | return datetime.fromisoformat(s).replace(tzinfo=tzlocal()) | 838 | return datetime.fromisoformat(s).replace(tzinfo=tzlocal()) |
839 | def duration_minutes(s): | ||
840 | return timedelta(minutes = float(s)) | ||
841 | |||
842 | def set_default_subparser(self, name, args=None, positional_args=0): | ||
843 | """default subparser selection. Call after setup, just before parse_args() | ||
844 | name: is the name of the subparser to call by default | ||
845 | args: if set is the argument list handed to parse_args() | ||
846 | |||
847 | , tested with 2.7, 3.2, 3.3, 3.4 | ||
848 | it works with 2.6 assuming argparse is installed | ||
849 | """ | ||
850 | subparser_found = False | ||
851 | for arg in sys.argv[1:]: | ||
852 | if arg in ['-h', '--help']: # global help if no subparser | ||
853 | break | ||
854 | else: | ||
855 | for x in self._subparsers._actions: | ||
856 | if not isinstance(x, argparse._SubParsersAction): | ||
857 | continue | ||
858 | for sp_name in x._name_parser_map.keys(): | ||
859 | if sp_name in sys.argv[1:]: | ||
860 | subparser_found = True | ||
861 | if not subparser_found: | ||
862 | # insert default in last position before global positional | ||
863 | # arguments, this implies no global options are specified after | ||
864 | # first positional argument | ||
865 | if args is None: | ||
866 | sys.argv.insert(len(sys.argv) - positional_args, name) | ||
867 | else: | ||
868 | args.insert(len(args) - positional_args, name) | ||
869 | |||
870 | argparse.ArgumentParser.set_default_subparser = set_default_subparser | ||
801 | 871 | ||
802 | config = Worktime.config() | 872 | config = Worktime.config() |
803 | 873 | ||
@@ -807,9 +877,13 @@ def main(): | |||
807 | parser.add_argument('--no-running', dest = 'include_running', action = 'store_false') | 877 | parser.add_argument('--no-running', dest = 'include_running', action = 'store_false') |
808 | parser.add_argument('--no-force-day-to-work', dest = 'force_day_to_work', action = 'store_false') | 878 | parser.add_argument('--no-force-day-to-work', dest = 'force_day_to_work', action = 'store_false') |
809 | subparsers = parser.add_subparsers(help = 'Subcommands') | 879 | subparsers = parser.add_subparsers(help = 'Subcommands') |
810 | parser.set_defaults(cmd = worktime) | 880 | worktime_parser = subparsers.add_parser('time_worked', aliases = ['time', 'worked']) |
811 | time_worked_parser = subparsers.add_parser('time_worked', aliases = ['time', 'worked', 'today']) | 881 | worktime_parser.add_argument('--pull-forward-cutoff', dest = 'pull_forward_cutoff', metavar = 'MINUTES', type = duration_minutes, default = timedelta(minutes = 15)) |
882 | worktime_parser.add_argument('--waybar', action='store_true') | ||
883 | worktime_parser.set_defaults(cmd = worktime) | ||
884 | time_worked_parser = subparsers.add_parser('today') | ||
812 | time_worked_parser.add_argument('--no-round', dest = 'do_round', action = 'store_false') | 885 | time_worked_parser.add_argument('--no-round', dest = 'do_round', action = 'store_false') |
886 | time_worked_parser.add_argument('--waybar', action='store_true') | ||
813 | time_worked_parser.set_defaults(cmd = time_worked) | 887 | time_worked_parser.set_defaults(cmd = time_worked) |
814 | diff_parser = subparsers.add_parser('diff') | 888 | diff_parser = subparsers.add_parser('diff') |
815 | diff_parser.set_defaults(cmd = diff) | 889 | diff_parser.set_defaults(cmd = diff) |
@@ -827,6 +901,9 @@ def main(): | |||
827 | classification_parser.add_argument('--table', action = 'store_true') | 901 | classification_parser.add_argument('--table', action = 'store_true') |
828 | classification_parser.add_argument('--table-format', dest='table_format', type=str, default='fancy_grid') | 902 | classification_parser.add_argument('--table-format', dest='table_format', type=str, default='fancy_grid') |
829 | classification_parser.set_defaults(cmd = partial(classification, classification_name=classification_name)) | 903 | classification_parser.set_defaults(cmd = partial(classification, classification_name=classification_name)) |
904 | pull_forward_parser = subparsers.add_parser('pull-forward') | ||
905 | pull_forward_parser.set_defaults(cmd = pull_forward) | ||
906 | parser.set_default_subparser('time_worked') | ||
830 | args = parser.parse_args() | 907 | args = parser.parse_args() |
831 | 908 | ||
832 | args.cmd(**vars(args)) | 909 | args.cmd(**vars(args)) |