diff options
Diffstat (limited to 'accounts/gkleen@sif/niri')
-rw-r--r-- | accounts/gkleen@sif/niri/default.nix | 231 | ||||
-rw-r--r-- | accounts/gkleen@sif/niri/mako.nix | 56 | ||||
-rw-r--r-- | accounts/gkleen@sif/niri/swayosd.nix | 7 | ||||
-rw-r--r-- | accounts/gkleen@sif/niri/waybar.nix | 21 |
4 files changed, 248 insertions, 67 deletions
diff --git a/accounts/gkleen@sif/niri/default.nix b/accounts/gkleen@sif/niri/default.nix index dc993d66..8752f3e3 100644 --- a/accounts/gkleen@sif/niri/default.nix +++ b/accounts/gkleen@sif/niri/default.nix | |||
@@ -35,7 +35,11 @@ let | |||
35 | if jq -e '.is_focused' <<<"$window_json" >/dev/null; then | 35 | if jq -e '.is_focused' <<<"$window_json" >/dev/null; then |
36 | niri msg action focus-workspace-previous | 36 | niri msg action focus-workspace-previous |
37 | else | 37 | else |
38 | niri msg action focus-window --id "$(jq -r '.id' <<<"$window_json")" | 38 | 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 |
39 | niri msg action focus-workspace "$workspace_name" | ||
40 | else | ||
41 | niri msg action focus-window --id "$(jq -r '.id' <<<"$window_json")" | ||
42 | fi | ||
39 | fi | 43 | fi |
40 | exit 0 | 44 | exit 0 |
41 | fi | 45 | fi |
@@ -45,7 +49,6 @@ let | |||
45 | ''; | 49 | ''; |
46 | }; | 50 | }; |
47 | focus-or-spawn-action = config.lib.niri.actions.spawn (lib.getExe focus_or_spawn); | 51 | 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 | 52 | ||
50 | with_adjacent_workspace = pkgs.writeShellApplication { | 53 | with_adjacent_workspace = pkgs.writeShellApplication { |
51 | name = "with-adjacent-workspace"; | 54 | name = "with-adjacent-workspace"; |
@@ -84,7 +87,7 @@ let | |||
84 | }; | 87 | }; |
85 | with-adjacent-workspace-action = config.lib.niri.actions.spawn (lib.getExe with_adjacent_workspace) "^${lib.concatMapStringsSep "|" ({ name, ...}: name) cfg.scratchspaces}$"; | 88 | 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}}}}''; | 89 | 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}}}}''; | 90 | move-column-to-adjacent-workspace = direction: with-adjacent-workspace-action direction ''{"Action":{"MoveColumnToWorkspace":{"reference":{"Id": .id}, "focus": true}}}''; |
88 | 91 | ||
89 | with_unnamed_workspace = pkgs.writeShellApplication { | 92 | with_unnamed_workspace = pkgs.writeShellApplication { |
90 | name = "with-unnamed-workspace"; | 93 | name = "with-unnamed-workspace"; |
@@ -131,7 +134,7 @@ let | |||
131 | 134 | ||
132 | windows_json="$(niri msg -j windows)" | 135 | windows_json="$(niri msg -j windows)" |
133 | active_workspace="$(jq -r '.[] | select(.is_focused) | .workspace_id' <<<"$windows_json")" | 136 | 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)" | 137 | 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 | 138 | # 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")" | 139 | window_json="$(gojq -rc --arg active_workspace "$active_workspace" --arg window_ix "$window_ix" 'map(select('"$window_select"')) | .[($window_ix | tonumber)]' <<<"$windows_json")" |
137 | 140 | ||
@@ -141,6 +144,25 @@ let | |||
141 | ''; | 144 | ''; |
142 | }; | 145 | }; |
143 | with-select-window-action = config.lib.niri.actions.spawn (lib.getExe with_select_window); | 146 | with-select-window-action = config.lib.niri.actions.spawn (lib.getExe with_select_window); |
147 | |||
148 | with_predicate_window = pred: pkgs.writeShellApplication { | ||
149 | name = "with-predicate-window"; | ||
150 | runtimeInputs = [ niri pkgs.gojq pkgs.socat ]; | ||
151 | text = '' | ||
152 | action="$1" | ||
153 | shift | ||
154 | |||
155 | windows_json="$(niri msg -j windows)" | ||
156 | window_json="$(gojq -rc 'map(select(${pred})) | .[0]' <<<"$windows_json")" | ||
157 | |||
158 | [[ -z "$window_json" || $window_json = "null" ]] && exit 1 | ||
159 | |||
160 | jq -c "$action" <<<"$window_json" | socat STDIO "$NIRI_SOCKET" | ||
161 | ''; | ||
162 | }; | ||
163 | |||
164 | with-urgent-window-action = config.lib.niri.actions.spawn (lib.getExe (with_predicate_window ".is_urgent")); | ||
165 | with-focused-window-action = config.lib.niri.actions.spawn (lib.getExe (with_predicate_window ".is_focused")); | ||
144 | in { | 166 | in { |
145 | imports = [ | 167 | imports = [ |
146 | ./waybar.nix | 168 | ./waybar.nix |
@@ -171,6 +193,17 @@ in { | |||
171 | type = lib.types.nullOr lib.types.str; | 193 | type = lib.types.nullOr lib.types.str; |
172 | default = null; | 194 | default = null; |
173 | }; | 195 | }; |
196 | moveKey = lib.mkOption { | ||
197 | type = lib.types.nullOr lib.types.str; | ||
198 | default = let | ||
199 | keys = lib.splitString "+" config.key; | ||
200 | defMoveKey = lib.concatStringsSep "+" (lib.flatten [ | ||
201 | (lib.take (lib.length keys - 1) keys) | ||
202 | ["Shift"] | ||
203 | (lib.takeEnd 1 keys) | ||
204 | ]); | ||
205 | in if config.key == null then null else defMoveKey; | ||
206 | }; | ||
174 | spawn = lib.mkOption { | 207 | spawn = lib.mkOption { |
175 | type = lib.types.nullOr (lib.types.listOf lib.types.str); | 208 | type = lib.types.nullOr (lib.types.listOf lib.types.str); |
176 | default = null; | 209 | default = null; |
@@ -245,11 +278,11 @@ in { | |||
245 | Service = { | 278 | Service = { |
246 | Type = "simple"; | 279 | Type = "simple"; |
247 | Sockets = [ "niri-workspace-history.socket" ]; | 280 | Sockets = [ "niri-workspace-history.socket" ]; |
248 | ExecStart = pkgs.writers.writePython3 "niri-workspace-history" {} '' | 281 | ExecStart = pkgs.writers.writePython3 "niri-workspace-history" { flakeIgnore = ["E501"]; } '' |
249 | import os | 282 | import os |
250 | import socket | 283 | import socket |
251 | import json | 284 | import json |
252 | import sys | 285 | # import sys |
253 | from collections import defaultdict | 286 | from collections import defaultdict |
254 | from threading import Thread, Lock | 287 | from threading import Thread, Lock |
255 | from socketserver import StreamRequestHandler, ThreadingTCPServer | 288 | from socketserver import StreamRequestHandler, ThreadingTCPServer |
@@ -274,8 +307,8 @@ in { | |||
274 | 307 | ||
275 | def focus_workspace(output, workspace): | 308 | def focus_workspace(output, workspace): |
276 | with history_lock: | 309 | with history_lock: |
277 | workspace_history[output] = [workspace] + [ws for ws in workspace_history[output] if ws != workspace] # noqa: E501 | 310 | workspace_history[output] = [workspace] + [ws for ws in workspace_history[output] if ws != workspace] |
278 | print(json.dumps(workspace_history), file=sys.stderr) | 311 | # print(json.dumps(workspace_history), file=sys.stderr) |
279 | 312 | ||
280 | sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) | 313 | sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) |
281 | sock.connect(os.environ["NIRI_SOCKET"]) | 314 | sock.connect(os.environ["NIRI_SOCKET"]) |
@@ -297,14 +330,14 @@ in { | |||
297 | 330 | ||
298 | class RequestHandler(StreamRequestHandler): | 331 | class RequestHandler(StreamRequestHandler): |
299 | def handle(self): | 332 | def handle(self): |
300 | with detaching(TextIOWrapper(self.wfile, encoding='utf-8', write_through=True)) as out: # noqa: E501 | 333 | with detaching(TextIOWrapper(self.wfile, encoding='utf-8', write_through=True)) as out: |
301 | with history_lock: | 334 | with history_lock: |
302 | json.dump(workspace_history, out) | 335 | json.dump(workspace_history, out) |
303 | 336 | ||
304 | 337 | ||
305 | class Server(ThreadingTCPServer): | 338 | class Server(ThreadingTCPServer): |
306 | def __init__(self): | 339 | def __init__(self): |
307 | ThreadingTCPServer.__init__(self, ("", 8000), RequestHandler, bind_and_activate=False) # noqa: E501 | 340 | ThreadingTCPServer.__init__(self, ("", 8000), RequestHandler, bind_and_activate=False) |
308 | self.socket = socket.fromfd(3, self.address_family, self.socket_type) | 341 | self.socket = socket.fromfd(3, self.address_family, self.socket_type) |
309 | 342 | ||
310 | 343 | ||
@@ -330,6 +363,79 @@ in { | |||
330 | ''; | 363 | ''; |
331 | }; | 364 | }; |
332 | }; | 365 | }; |
366 | systemd.user.services.niri-workspace-sort = { | ||
367 | Unit = { | ||
368 | BindsTo = [ "niri.service" ]; | ||
369 | After = [ "niri.service" ]; | ||
370 | }; | ||
371 | Install = { | ||
372 | WantedBy = [ "niri.service" ]; | ||
373 | }; | ||
374 | Service = { | ||
375 | Type = "simple"; | ||
376 | ExecStart = pkgs.writers.writePython3 "niri-workspace-sort" { flakeIgnore = ["E501"]; } '' | ||
377 | import os | ||
378 | import sys | ||
379 | import socket | ||
380 | import json | ||
381 | |||
382 | outputs = None | ||
383 | only = {'HDMI-A-1': {'bmr'}, 'eDP-1': {'vid'}} | ||
384 | |||
385 | |||
386 | class Niri(socket.socket): | ||
387 | def __init__(self): | ||
388 | super().__init__(socket.AF_UNIX, socket.SOCK_STREAM) | ||
389 | super().connect(os.environ["NIRI_SOCKET"]) | ||
390 | self.fh = super().makefile(mode='rw', buffering=1, encoding='utf-8') | ||
391 | |||
392 | def cmd(self, obj): | ||
393 | print(json.dumps(obj, separators=(',', ':')), flush=True, file=self.fh) | ||
394 | |||
395 | def event_stream(self): | ||
396 | self.cmd("EventStream") | ||
397 | return self.fh | ||
398 | |||
399 | |||
400 | with Niri() as niri, Niri().event_stream() as niri_stream: | ||
401 | for line in niri_stream: | ||
402 | workspaces = None | ||
403 | if line_json := json.loads(line): | ||
404 | if "WorkspacesChanged" in line_json: | ||
405 | workspaces = line_json["WorkspacesChanged"]["workspaces"] | ||
406 | |||
407 | if workspaces is None: | ||
408 | continue | ||
409 | |||
410 | old_outputs = outputs | ||
411 | outputs = {ws["output"] for ws in workspaces} | ||
412 | if old_outputs is None: | ||
413 | print("Initial outputs: {}".format(outputs), file=sys.stderr) | ||
414 | continue | ||
415 | |||
416 | new_outputs = outputs - old_outputs | ||
417 | if not new_outputs: | ||
418 | continue | ||
419 | print("New outputs: {}".format(new_outputs), file=sys.stderr) | ||
420 | |||
421 | relevant_workspaces = list(filter(lambda ws: (ws["name"] is not None) or (ws["active_window_id"] is not None), workspaces)) | ||
422 | target_output = next(iter(outputs - set(only.keys()))) | ||
423 | if not target_output: | ||
424 | continue | ||
425 | for ws in relevant_workspaces: | ||
426 | ws_ident = ws["name"] if ws["name"] is not None else (ws["output"], ws["idx"]) | ||
427 | if ws["output"] not in set(only.keys()): | ||
428 | continue | ||
429 | if ws_ident in only[ws["output"]]: | ||
430 | continue | ||
431 | |||
432 | print("{} -> {}".format(ws_ident, target_output), file=sys.stderr) | ||
433 | niri.cmd({"Action": {"MoveWorkspaceToMonitor": {"reference": {"Id": ws["id"]}, "output": target_output}}}) | ||
434 | ''; | ||
435 | Restart = "on-failure"; | ||
436 | RestartSec = 10; | ||
437 | }; | ||
438 | }; | ||
333 | 439 | ||
334 | programs.niri.scratchspaces = [ | 440 | programs.niri.scratchspaces = [ |
335 | { name = "pwctl"; | 441 | { name = "pwctl"; |
@@ -343,7 +449,7 @@ in { | |||
343 | { title = "^Access Request.*"; } | 449 | { title = "^Access Request.*"; } |
344 | { title = ".*Passkey credentials$"; } | 450 | { title = ".*Passkey credentials$"; } |
345 | ]; | 451 | ]; |
346 | windowRuleExtra = [ | 452 | windowRuleExtra = with kdl; [ |
347 | (kdl.leaf "open-focused" false) | 453 | (kdl.leaf "open-focused" false) |
348 | ]; | 454 | ]; |
349 | key = "Mod+Control+P"; | 455 | key = "Mod+Control+P"; |
@@ -371,6 +477,20 @@ in { | |||
371 | app-id = "com.github.wwmm.easyeffects"; | 477 | app-id = "com.github.wwmm.easyeffects"; |
372 | spawn = [ "easyeffects" ]; | 478 | spawn = [ "easyeffects" ]; |
373 | } | 479 | } |
480 | { name = "time"; | ||
481 | key = "Mod+Control+K"; | ||
482 | app-id = "chrome-kimai.yggdrasil.li__-Default"; | ||
483 | spawn = [ (toString (pkgs.resholve.writeScript "kimai" { | ||
484 | interpreter = pkgs.runtimeShell; | ||
485 | inputs = [ pkgs.dex ]; | ||
486 | execer = [ "cannot:${lib.getExe pkgs.dex}" ]; | ||
487 | } '' | ||
488 | exec dex $HOME/.local/state/nix/profile/share/applications/kimai.desktop | ||
489 | '')) ]; | ||
490 | windowRuleExtra = with kdl; [ | ||
491 | (leaf "block-out-from" "screencast") | ||
492 | ]; | ||
493 | } | ||
374 | ]; | 494 | ]; |
375 | programs.niri.config = | 495 | programs.niri.config = |
376 | let | 496 | let |
@@ -415,6 +535,10 @@ in { | |||
415 | ]) | 535 | ]) |
416 | ]) | 536 | ]) |
417 | 537 | ||
538 | (plain "gestures" [ | ||
539 | (plain "hot-corners" [(flag "off")]) | ||
540 | ]) | ||
541 | |||
418 | (plain "environment" (lib.mapAttrsToList leaf { | 542 | (plain "environment" (lib.mapAttrsToList leaf { |
419 | NIXOS_OZONE_WL = "1"; | 543 | NIXOS_OZONE_WL = "1"; |
420 | QT_QPA_PLATFORM = "wayland"; | 544 | QT_QPA_PLATFORM = "wayland"; |
@@ -422,6 +546,10 @@ in { | |||
422 | GDK_BACKEND = "wayland"; | 546 | GDK_BACKEND = "wayland"; |
423 | SDL_VIDEODRIVER = "wayland"; | 547 | SDL_VIDEODRIVER = "wayland"; |
424 | DISPLAY = ":0"; | 548 | DISPLAY = ":0"; |
549 | ELECTRON_OZONE_PLATFORM_HINT = "auto"; | ||
550 | SSH_ASKPASS_REQUIRE = "prefer"; | ||
551 | SSH_ASKPASS = lib.getExe pkgs.kdePackages.ksshaskpass; | ||
552 | SUDO_ASKPASS = lib.getExe pkgs.kdePackages.ksshaskpass; | ||
425 | })) | 553 | })) |
426 | 554 | ||
427 | (node "output" "eDP-1" [ | 555 | (node "output" "eDP-1" [ |
@@ -536,7 +664,7 @@ in { | |||
536 | (plain "window-rule" [ | 664 | (plain "window-rule" [ |
537 | (map (title: | 665 | (map (title: |
538 | (leaf "match" { app-id = "^org\\.keepassxc\\.KeePassXC$"; inherit title; }) | 666 | (leaf "match" { app-id = "^org\\.keepassxc\\.KeePassXC$"; inherit title; }) |
539 | ) ["^Unlock Database.*" "^Access Request.*" ".*Passkey credentials$"]) | 667 | ) ["^Unlock Database.*" "^Access Request.*" ".*Passkey credentials$" "Browser Access Request$"]) |
540 | (leaf "open-focused" true) | 668 | (leaf "open-focused" true) |
541 | (leaf "open-floating" true) | 669 | (leaf "open-floating" true) |
542 | ]) | 670 | ]) |
@@ -565,7 +693,7 @@ in { | |||
565 | (plain "window-rule" [ | 693 | (plain "window-rule" [ |
566 | (leaf "match" { app-id = "^thunderbird$"; }) | 694 | (leaf "match" { app-id = "^thunderbird$"; }) |
567 | (leaf "match" { app-id = "^Element$"; }) | 695 | (leaf "match" { app-id = "^Element$"; }) |
568 | (leaf "match" { app-id = "^Rainbow$"; }) | 696 | (leaf "match" { app-id = "^chrome-web\.openrainbow\.com__-Default$"; }) |
569 | (leaf "open-on-workspace" "comm") | 697 | (leaf "open-on-workspace" "comm") |
570 | ]) | 698 | ]) |
571 | (plain "window-rule" [ | 699 | (plain "window-rule" [ |
@@ -584,6 +712,11 @@ in { | |||
584 | (leaf "open-focused" false) | 712 | (leaf "open-focused" false) |
585 | ]) | 713 | ]) |
586 | (plain "window-rule" [ | 714 | (plain "window-rule" [ |
715 | (leaf "match" { app-id = "^chrome-audiobookshelf\.yggdrasil\.li__-Default$"; }) | ||
716 | (leaf "match" { app-id = "^YouTube Music Desktop App$"; }) | ||
717 | (leaf "open-on-workspace" "vid") | ||
718 | ]) | ||
719 | (plain "window-rule" [ | ||
587 | (leaf "match" { app-id = "^pdfpc$"; }) | 720 | (leaf "match" { app-id = "^pdfpc$"; }) |
588 | (plain "default-column-width" [(leaf "proportion" 1.)]) | 721 | (plain "default-column-width" [(leaf "proportion" 1.)]) |
589 | ]) | 722 | ]) |
@@ -633,6 +766,21 @@ in { | |||
633 | "Mod+Slash".action = show-hotkey-overlay; | 766 | "Mod+Slash".action = show-hotkey-overlay; |
634 | 767 | ||
635 | "Mod+Return".action = spawn terminal; | 768 | "Mod+Return".action = spawn terminal; |
769 | "Mod+Shift+Return".action = | ||
770 | let | ||
771 | nushellKitty = pkgs.symlinkJoin { | ||
772 | name = "nushell-kitty"; | ||
773 | paths = [ config.programs.kitty.package ]; | ||
774 | buildInputs = [ pkgs.makeWrapper ]; | ||
775 | postBuild = '' | ||
776 | wrapProgram $out/bin/kitty \ | ||
777 | --add-flags "--config ${pkgs.writeText "kitty.conf" '' | ||
778 | include $HOME/${config.xdg.configFile."kitty/kitty.conf".target} | ||
779 | shell ${lib.getExe config.programs.nushell.package} | ||
780 | ''}" | ||
781 | ''; | ||
782 | }; | ||
783 | in spawn (lib.getExe' nushellKitty "kitty"); | ||
636 | "Mod+Q".action = close-window; | 784 | "Mod+Q".action = close-window; |
637 | "Mod+O".action = spawn (lib.getExe config.programs.fuzzel.package); | 785 | "Mod+O".action = spawn (lib.getExe config.programs.fuzzel.package); |
638 | "Mod+Shift+O".action = spawn (lib.getExe config.programs.fuzzel.package) "--list-executables-in-path"; | 786 | "Mod+Shift+O".action = spawn (lib.getExe config.programs.fuzzel.package) "--list-executables-in-path"; |
@@ -668,12 +816,12 @@ in { | |||
668 | 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) | 816 | 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) |
669 | $FOUND || echo | 817 | $FOUND || echo |
670 | } | 818 | } |
671 | FUZZEL_RES=$(prev | fuzzel --dmenu --prompt "qalc> ") || exit $? | 819 | FUZZEL_RES=$(prev | fuzzel --dmenu --prompt "qalc> " --width=60) || exit $? |
672 | if [[ "$FUZZEL_RES" =~ .*\ =\ .* ]]; then | 820 | if [[ "$FUZZEL_RES" =~ .*\ =\ .* ]]; then |
673 | QALC_RES="$FUZZEL_RES" | 821 | QALC_RES="$FUZZEL_RES" |
674 | QALC_RET=0 | 822 | QALC_RET=0 |
675 | else | 823 | else |
676 | QALC_RES=$(qalc "$FUZZEL_RES" 2>&1) | 824 | QALC_RES=$(qalc -set "autocalc off" "$FUZZEL_RES" 2>&1) |
677 | QALC_RET=$? | 825 | QALC_RET=$? |
678 | fi | 826 | fi |
679 | [[ -n "$QALC_RES" ]] || exit 1 | 827 | [[ -n "$QALC_RES" ]] || exit 1 |
@@ -693,18 +841,33 @@ in { | |||
693 | notify-send "$QALC_RES" | 841 | notify-send "$QALC_RES" |
694 | ''; | 842 | ''; |
695 | })); | 843 | })); |
844 | "Mod+Shift+U".action = | ||
845 | let | ||
846 | qalcKitty = pkgs.symlinkJoin { | ||
847 | name = "qalc-kitty"; | ||
848 | paths = [ config.programs.kitty.package ]; | ||
849 | buildInputs = [ pkgs.makeWrapper ]; | ||
850 | postBuild = '' | ||
851 | wrapProgram $out/bin/kitty \ | ||
852 | --add-flags "--config ${pkgs.writeText "kitty.conf" '' | ||
853 | include $HOME/${config.xdg.configFile."kitty/kitty.conf".target} | ||
854 | shell ${lib.getExe pkgs.libqalculate} | ||
855 | ''}" | ||
856 | ''; | ||
857 | }; | ||
858 | in spawn (lib.getExe' qalcKitty "kitty"); | ||
696 | "Mod+E".action = spawn (lib.getExe (pkgs.writeShellApplication { | 859 | "Mod+E".action = spawn (lib.getExe (pkgs.writeShellApplication { |
697 | name = "emoji-fuzzel"; | 860 | name = "emoji-fuzzel"; |
698 | runtimeInputs = with pkgs; [ config.programs.fuzzel.package wtype wl-clipboard-rs ]; | 861 | runtimeInputs = with pkgs; [ config.programs.fuzzel.package wtype wl-clipboard-rs ]; |
699 | text = '' | 862 | text = '' |
700 | FUZZEL_RES=$(fuzzel --dmenu --prompt "emoji> " <"$HOME"/.local/share/emoji-data/list.txt) || exit $? | 863 | FUZZEL_RES=$(fuzzel --dmenu --prompt "emoji> " --cache "$HOME"/.cache/fuzzel-emoji --width=60 <"$HOME"/.local/share/emoji-data/list.txt) || exit $? |
701 | [[ -n "$FUZZEL_RES" ]] || exit 1 | 864 | [[ -n "$FUZZEL_RES" ]] || exit 1 |
702 | wl-copy "$(cut -d ':' -f 1 <<<"$FUZZEL_RES" | tr -d '\n')" && wtype -k XF86Paste | 865 | wl-copy "$(cut -d ':' -f 1 <<<"$FUZZEL_RES" | tr -d '\n')" && wtype -k XF86Paste |
703 | ''; | 866 | ''; |
704 | })); | 867 | })); |
705 | "Print".action = screenshot; | 868 | "Print".action = screenshot; |
706 | "Control+Print".action = screenshot-window; | 869 | "Control+Print".action = screenshot-window; |
707 | # "Shift+Print".action = screenshot-screen; | 870 | "Shift+Print".action = kdl.magic-leaf "screenshot-screen"; |
708 | "Mod+B".action = with-select-window-action ".workspace_id == ($active_workspace | tonumber)" "{\"Action\":{\"FocusWindow\":{\"id\": .id}}}"; | 871 | "Mod+B".action = with-select-window-action ".workspace_id == ($active_workspace | tonumber)" "{\"Action\":{\"FocusWindow\":{\"id\": .id}}}"; |
709 | "Mod+Shift+B".action = with-select-window-action "true" "{\"Action\":{\"FocusWindow\":{\"id\": .id}}}"; | 872 | "Mod+Shift+B".action = with-select-window-action "true" "{\"Action\":{\"FocusWindow\":{\"id\": .id}}}"; |
710 | 873 | ||
@@ -743,22 +906,22 @@ in { | |||
743 | "Mod+Shift+Control+C".action = move-workspace-up; | 906 | "Mod+Shift+Control+C".action = move-workspace-up; |
744 | 907 | ||
745 | "Mod+ParenLeft".action = focus-workspace "comm"; | 908 | "Mod+ParenLeft".action = focus-workspace "comm"; |
746 | "Mod+Shift+ParenLeft".action = move-column-to-workspace "comm"; | 909 | "Mod+Shift+ParenLeft".action = kdl.magic-leaf "move-column-to-workspace" "comm"; |
747 | 910 | ||
748 | "Mod+ParenRight".action = focus-workspace "web"; | 911 | "Mod+ParenRight".action = focus-workspace "web"; |
749 | "Mod+Shift+ParenRight".action = move-column-to-workspace "web"; | 912 | "Mod+Shift+ParenRight".action = kdl.magic-leaf "move-column-to-workspace" "web"; |
750 | 913 | ||
751 | "Mod+BraceRight".action = focus-workspace "read"; | 914 | "Mod+BraceRight".action = focus-workspace "read"; |
752 | "Mod+Shift+BraceRight".action = move-column-to-workspace "read"; | 915 | "Mod+Shift+BraceRight".action = kdl.magic-leaf "move-column-to-workspace" "read"; |
753 | 916 | ||
754 | "Mod+BraceLeft".action = focus-workspace "mon"; | 917 | "Mod+BraceLeft".action = focus-workspace "mon"; |
755 | "Mod+Shift+BraceLeft".action = move-column-to-workspace "mon"; | 918 | "Mod+Shift+BraceLeft".action = kdl.magic-leaf "move-column-to-workspace" "mon"; |
756 | 919 | ||
757 | "Mod+Asterisk".action = focus-workspace "vid"; | 920 | "Mod+Asterisk".action = focus-workspace "vid"; |
758 | "Mod+Shift+Asterisk".action = move-column-to-workspace "vid"; | 921 | "Mod+Shift+Asterisk".action = kdl.magic-leaf "move-column-to-workspace" "vid"; |
759 | 922 | ||
760 | "Mod+Plus".action = with-unnamed-workspace-action ''{"Action":{"FocusWorkspace":{"reference":{"Id": .id}}}}''; | 923 | "Mod+Plus".action = with-unnamed-workspace-action ''{"Action":{"FocusWorkspace":{"reference":{"Id": .id}}}}''; |
761 | "Mod+Shift+Plus".action = with-unnamed-workspace-action ''{"Action":{"MoveColumnToWorkspace":{"reference":{"Id": .id}}}}''; | 924 | "Mod+Shift+Plus".action = with-unnamed-workspace-action ''{"Action":{"MoveColumnToWorkspace":{"reference":{"Id": .id}, "focus": true}}}''; |
762 | 925 | ||
763 | "Mod+M".action = consume-or-expel-window-left; | 926 | "Mod+M".action = consume-or-expel-window-left; |
764 | "Mod+W".action = consume-or-expel-window-right; | 927 | "Mod+W".action = consume-or-expel-window-right; |
@@ -766,10 +929,11 @@ in { | |||
766 | "Mod+Shift+M".action = toggle-column-tabbed-display; | 929 | "Mod+Shift+M".action = toggle-column-tabbed-display; |
767 | 930 | ||
768 | "Mod+R".action = switch-preset-column-width; | 931 | "Mod+R".action = switch-preset-column-width; |
769 | "Mod+Shift+R".action = switch-preset-window-height; | 932 | "Mod+Shift+R".action = maximize-column; |
933 | "Mod+Shift+Ctrl+R".action = switch-preset-window-height; | ||
770 | "Mod+F".action = center-column; | 934 | "Mod+F".action = center-column; |
771 | "Mod+Shift+F".action = maximize-column; | 935 | "Mod+Shift+F".action = toggle-windowed-fullscreen; |
772 | "Mod+Shift+Ctrl+F".action = fullscreen-window; | 936 | "Mod+Ctrl+Shift+F".action = fullscreen-window; |
773 | 937 | ||
774 | "Mod+V".action = switch-focus-between-floating-and-tiling; | 938 | "Mod+V".action = switch-focus-between-floating-and-tiling; |
775 | "Mod+Shift+V".action = toggle-window-floating; | 939 | "Mod+Shift+V".action = toggle-window-floating; |
@@ -825,13 +989,24 @@ in { | |||
825 | 989 | ||
826 | "Mod+Semicolon".action = spawn makoctl "dismiss" "--group"; | 990 | "Mod+Semicolon".action = spawn makoctl "dismiss" "--group"; |
827 | "Mod+Shift+Semicolon".action = spawn makoctl "dismiss" "--all"; | 991 | "Mod+Shift+Semicolon".action = spawn makoctl "dismiss" "--all"; |
828 | "Mod+Period".action = spawn makoctl "menu" (lib.getExe config.programs.fuzzel.package) "--dmenu"; | 992 | "Mod+Period".action = spawn makoctl "menu" "--" (lib.getExe config.programs.fuzzel.package) "--dmenu"; |
829 | "Mod+Comma".action = spawn makoctl "restore"; | 993 | "Mod+Comma".action = spawn makoctl "restore"; |
830 | 994 | ||
831 | "Mod+Control+W".action = with-empty-unnamed-workspace-action "{\"Action\":{\"FocusWorkspace\":{\"reference\":{\"Id\": $workspace_id}}}}"; | 995 | "Mod+Control+W".action = with-empty-unnamed-workspace-action "{\"Action\":{\"FocusWorkspace\":{\"reference\":{\"Id\": $workspace_id}}}}"; |
832 | "Mod+Control+Shift+W".action = with-empty-unnamed-workspace-action "{\"Action\":{\"MoveColumnToWorkspace\":{\"reference\":{\"Id\": $workspace_id}}}}"; | 996 | "Mod+Control+Shift+W".action = with-empty-unnamed-workspace-action "{\"Action\":{\"MoveColumnToWorkspace\":{\"reference\":{\"Id\": $workspace_id}, \"focus\": true}}}"; |
997 | |||
998 | "Mod+X".action = set-dynamic-cast-window; | ||
999 | "Mod+Shift+X".action = set-dynamic-cast-monitor; | ||
1000 | "Mod+Control+Shift+X".action = clear-dynamic-cast-target; | ||
1001 | |||
1002 | "Mod+D".action = with-urgent-window-action "{\"Action\":{\"FocusWindow\":{\"id\": .id}}}"; | ||
1003 | "Mod+Shift+D".action = with-focused-window-action "{\"Action\":{\"UnsetUrgent\":{\"id\": .id}}}"; | ||
1004 | |||
1005 | "Mod+K".action = spawn (lib.getExe' pkgs.worktime "worktime-ui"); | ||
1006 | "Mod+Shift+K".action = spawn (lib.getExe' pkgs.worktime "worktime-stop"); | ||
833 | })) | 1007 | })) |
834 | (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) | 1008 | (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) |
1009 | (map ({ name, moveKey, ...}: if moveKey != null then bind moveKey { action = kdl.magic-leaf "move-column-to-workspace" name; } else null) cfg.scratchspaces) | ||
835 | ] | 1010 | ] |
836 | )) | 1011 | )) |
837 | ]; | 1012 | ]; |
diff --git a/accounts/gkleen@sif/niri/mako.nix b/accounts/gkleen@sif/niri/mako.nix index 2788fb82..eba26caa 100644 --- a/accounts/gkleen@sif/niri/mako.nix +++ b/accounts/gkleen@sif/niri/mako.nix | |||
@@ -3,37 +3,31 @@ | |||
3 | config = { | 3 | config = { |
4 | services.mako = { | 4 | services.mako = { |
5 | enable = true; | 5 | enable = true; |
6 | font = "Fira Sans 10"; | 6 | settings = { |
7 | format = "<i>%s</i>\\n%b"; | 7 | font = "Fira Sans 10"; |
8 | margin = "2"; | 8 | format = "<i>%s</i>\\n%b"; |
9 | maxVisible = -1; | 9 | margin = "2"; |
10 | backgroundColor = "#000000dd"; | 10 | max-visible = -1; |
11 | progressColor = "source #223544ff"; | 11 | background-color = "#000000dd"; |
12 | width = 384; | 12 | progress-color = "source #223544ff"; |
13 | extraConfig = '' | 13 | width = 384; |
14 | outer-margin=1 | 14 | outer-margin = 1; |
15 | max-history=100 | 15 | max-history = 100; |
16 | max-icon-size=48 | 16 | max-icon-size = 48; |
17 | 17 | }; | |
18 | [grouped] | 18 | criteria = { |
19 | format=<b>(%g)</b> <i>%s</i>\n%b | 19 | grouped.format = "<b>(%g)</b> <i>%s</i>\\n%b"; |
20 | 20 | "urgency=low".text-color = "#999999ff"; | |
21 | [urgency=low] | 21 | "urgency=critical".background-color = "#900000dd"; |
22 | text-color=#999999ff | 22 | "app-name=Element".group-by = "summary"; |
23 | 23 | "app-name=poweralertd" = { | |
24 | [urgency=critical] | 24 | history = false; |
25 | background-color=#900000dd | 25 | ignore-timeout = true; |
26 | 26 | default-timeout = 2000; | |
27 | [app-name=Element] | 27 | }; |
28 | group-by=summary | 28 | "app-name=worktime".history = false; |
29 | 29 | "mode=silent".invisible = true; | |
30 | [app-name=poweralertd] | 30 | }; |
31 | ignore-timeout=1 | ||
32 | default-timeout=2000 | ||
33 | |||
34 | [mode=silent] | ||
35 | invisible=1 | ||
36 | ''; | ||
37 | package = pkgs.symlinkJoin { | 31 | package = pkgs.symlinkJoin { |
38 | name = "${pkgs.mako.name}-wrapped"; | 32 | name = "${pkgs.mako.name}-wrapped"; |
39 | paths = with pkgs; [ mako ]; | 33 | paths = with pkgs; [ mako ]; |
diff --git a/accounts/gkleen@sif/niri/swayosd.nix b/accounts/gkleen@sif/niri/swayosd.nix index 984927c2..54ebb302 100644 --- a/accounts/gkleen@sif/niri/swayosd.nix +++ b/accounts/gkleen@sif/niri/swayosd.nix | |||
@@ -3,9 +3,10 @@ | |||
3 | config = { | 3 | config = { |
4 | services.swayosd = { | 4 | services.swayosd = { |
5 | enable = true; | 5 | enable = true; |
6 | topMargin = 0.946154; | 6 | topMargin = 0.4769706078; |
7 | stylePath = pkgs.runCommand "style.css" { | 7 | stylePath = pkgs.runCommand "style.css" { |
8 | src = pkgs.writeText "style.scss" '' | 8 | passAsFile = [ "src" ]; |
9 | src = '' | ||
9 | window#osd { | 10 | window#osd { |
10 | padding: 12px 20px; | 11 | padding: 12px 20px; |
11 | border-radius: 999px; | 12 | border-radius: 999px; |
@@ -59,7 +60,7 @@ | |||
59 | } | 60 | } |
60 | ''; | 61 | ''; |
61 | buildInputs = with pkgs; [sass]; | 62 | buildInputs = with pkgs; [sass]; |
62 | } "scss -C --sourcemap=none --style=compact $src $out"; | 63 | } "scss -C --sourcemap=none --style=compact $srcPath $out"; |
63 | }; | 64 | }; |
64 | }; | 65 | }; |
65 | } | 66 | } |
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 | }; |