diff options
Diffstat (limited to 'accounts/gkleen@sif/niri')
-rw-r--r-- | accounts/gkleen@sif/niri/default.nix | 143 |
1 files changed, 127 insertions, 16 deletions
diff --git a/accounts/gkleen@sif/niri/default.nix b/accounts/gkleen@sif/niri/default.nix index 6aa4391c..fa39fdd4 100644 --- a/accounts/gkleen@sif/niri/default.nix +++ b/accounts/gkleen@sif/niri/default.nix | |||
@@ -8,11 +8,11 @@ let | |||
8 | loginctl = lib.getExe' hostConfig.systemd.package "loginctl"; | 8 | loginctl = lib.getExe' hostConfig.systemd.package "loginctl"; |
9 | systemctl = lib.getExe' hostConfig.systemd.package "systemctl"; | 9 | systemctl = lib.getExe' hostConfig.systemd.package "systemctl"; |
10 | 10 | ||
11 | focus-or-spawn = pkgs.writeShellApplication { | 11 | focus_or_spawn = pkgs.writeShellApplication { |
12 | name = "focus-or-spawn"; | 12 | name = "focus-or-spawn"; |
13 | runtimeInputs = [ niri pkgs.gojq pkgs.gnugrep pkgs.socat ]; | 13 | runtimeInputs = [ niri pkgs.gojq pkgs.gnugrep pkgs.socat ]; |
14 | text = '' | 14 | text = '' |
15 | app_id="$1" | 15 | window_select="$1" |
16 | shift | 16 | shift |
17 | workspace_name="$1" | 17 | workspace_name="$1" |
18 | shift | 18 | shift |
@@ -20,12 +20,15 @@ let | |||
20 | workspaces_json="$(niri msg -j workspaces)" | 20 | workspaces_json="$(niri msg -j workspaces)" |
21 | workspace_output="$(jq -r --arg workspace_name "$workspace_name" '.[] | select(.name == $workspace_name) | .output' <<<"$workspaces_json")" | 21 | 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")" | 22 | active_workspace="$(jq -r --arg workspace_output "$workspace_output" '.[] | select(.output == $workspace_output and .is_active) | .id' <<<"$workspaces_json")" |
23 | niri msg action move-workspace-to-monitor --output "$(jq -r '.[] | select(.is_focused) | .output' <<<"$workspaces_json")" "$workspace_name" | 23 | active_output="$(jq -r '.[] | select(.is_focused) | .output' <<<"$workspaces_json")" |
24 | socat STDIO "$NIRI_SOCKET" <<<'{"Action":{"FocusWorkspace":{"reference":{"Id":'"''${active_workspace}"'}}}}' | 24 | if [[ $workspace_output != "$active_output" ]]; then |
25 | niri msg action move-workspace-to-index --index 1 "$workspace_name" | 25 | niri msg action move-workspace-to-monitor --output "$active_output" "$workspace_name" |
26 | socat STDIO "$NIRI_SOCKET" <<<'{"Action":{"FocusWorkspace":{"reference":{"Id":'"''${active_workspace}"'}}}}' | ||
27 | niri msg action move-workspace-to-index --index 1 "$workspace_name" | ||
28 | fi | ||
26 | 29 | ||
27 | while IFS=$'\n' read -r window_json; do | 30 | while IFS=$'\n' read -r window_json; do |
28 | if jq -r '.app_id' <<<"$window_json" | grep -q "$app_id"; then | 31 | if [[ -n $(jq -c "$window_select" <<<"$window_json") ]]; then |
29 | niri msg action focus-window --id "$(jq -r '.id' <<<"$window_json")" | 32 | niri msg action focus-window --id "$(jq -r '.id' <<<"$window_json")" |
30 | exit 0 | 33 | exit 0 |
31 | fi | 34 | fi |
@@ -34,7 +37,65 @@ let | |||
34 | exec "$@" | 37 | exec "$@" |
35 | ''; | 38 | ''; |
36 | }; | 39 | }; |
37 | focus-or-spawn-action = app_id: workspace_name: config.lib.niri.actions.spawn (lib.getExe focus-or-spawn) (lib.escapeShellArg app_id) (lib.escapeShellArg workspace_name); | 40 | focus-or-spawn-action = config.lib.niri.actions.spawn (lib.getExe focus_or_spawn); |
41 | focus-or-spawn-action-app_id = app_id: focus-or-spawn-action ''select(.app_id == "${app_id}")''; | ||
42 | |||
43 | with_adjacent_workspace = pkgs.writeShellApplication { | ||
44 | name = "with-adjacent-workspace"; | ||
45 | runtimeInputs = [ niri pkgs.gojq pkgs.socat ]; | ||
46 | text = '' | ||
47 | blacklist="$1" | ||
48 | shift | ||
49 | direction="$1" | ||
50 | shift | ||
51 | action="$1" | ||
52 | shift | ||
53 | |||
54 | workspaces_json="$(niri msg -j workspaces)" | ||
55 | active_workspace="$(jq -r '.[] | select(.is_focused) | .id' <<<"$workspaces_json")" | ||
56 | workspace_output="$(jq -r --arg active_workspace "$active_workspace" '.[] | select(.id == ($active_workspace | tonumber)) | .output' <<<"$workspaces_json")" | ||
57 | workspace_idx="$(jq -r '.[] | select(.is_focused) | .idx' <<<"$workspaces_json")" | ||
58 | |||
59 | jq_script='map(select(' | ||
60 | case "$direction" in | ||
61 | down) | ||
62 | # shellcheck disable=SC2016 | ||
63 | jq_script=''${jq_script}'.idx > ($workspace_idx | tonumber)';; | ||
64 | up) | ||
65 | # shellcheck disable=SC2016 | ||
66 | jq_script=''${jq_script}'.idx < ($workspace_idx | tonumber)';; | ||
67 | esac | ||
68 | # shellcheck disable=SC2016 | ||
69 | jq_script=''${jq_script}' and .output == $workspace_output and ((.name == null) or (.name | test($blacklist) | not)))) | sort_by(.idx)' | ||
70 | [[ $direction == "up" ]] && jq_script=''${jq_script}' | reverse' | ||
71 | jq_script=''${jq_script}' | .[0]' | ||
72 | |||
73 | workspace_json=$(jq -c --arg blacklist "$blacklist" --arg workspace_output "$workspace_output" --arg workspace_idx "$workspace_idx" "$jq_script" <<<"$workspaces_json") | ||
74 | [[ -n $workspace_json && $workspace_json != null ]] || exit 0 | ||
75 | jq --arg active_workspace "$active_workspace" -c "$action" <<<"$workspace_json" | tee /dev/stderr | socat STDIO "$NIRI_SOCKET" | ||
76 | ''; | ||
77 | }; | ||
78 | with-adjacent-workspace-action = config.lib.niri.actions.spawn (lib.getExe with_adjacent_workspace) "^pwctl|kpxc|bmgr|edit|term$"; | ||
79 | 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}}}}''; | ||
81 | |||
82 | with_unnamed_workspace = pkgs.writeShellApplication { | ||
83 | name = "with-unnamed-workspace"; | ||
84 | runtimeInputs = [ niri pkgs.gojq pkgs.socat ]; | ||
85 | text = '' | ||
86 | action="$1" | ||
87 | shift | ||
88 | |||
89 | workspaces_json="$(niri msg -j workspaces)" | ||
90 | active_output="$(jq -r '.[] | select(.is_focused) | .output' <<<"$workspaces_json")" | ||
91 | active_workspace="$(jq -r '.[] | select(.is_focused) | .id' <<<"$workspaces_json")" | ||
92 | |||
93 | workspace_json="$(jq -c --arg active_output "$active_output" 'map(select(.output == $active_output and .name == null)) | sort_by(.idx) | .[0]' <<<"$workspaces_json")" | ||
94 | [[ -n $workspace_json && $workspace_json != null && $active_workspace != "$(jq -r '.id' <<<"$workspace_json")" ]] || exit 0 | ||
95 | jq --arg active_workspace "$active_workspace" -c "$action" <<<"$workspace_json" | tee /dev/stderr | socat STDIO "$NIRI_SOCKET" | ||
96 | ''; | ||
97 | }; | ||
98 | with-unnamed-workspace-action = config.lib.niri.actions.spawn (lib.getExe with_unnamed_workspace); | ||
38 | in { | 99 | in { |
39 | imports = [ | 100 | imports = [ |
40 | ./waybar.nix | 101 | ./waybar.nix |
@@ -110,10 +171,27 @@ in { | |||
110 | 171 | ||
111 | layout = { | 172 | layout = { |
112 | gaps = 8; | 173 | gaps = 8; |
113 | struts = { left = 8; right = 8; top = 0; bottom = 0; }; | 174 | struts = { left = 0; right = 0; top = 0; bottom = 0; }; |
114 | focus-ring = { | 175 | focus-ring = { |
115 | width = 2; | 176 | width = 2; |
116 | }; | 177 | }; |
178 | |||
179 | preset-column-widths = [ | ||
180 | { proportion = 1. / 4.; } | ||
181 | { proportion = 1. / 3.; } | ||
182 | { proportion = 1. / 2.; } | ||
183 | { proportion = 2. / 3.; } | ||
184 | { proportion = 3. / 4.; } | ||
185 | ]; | ||
186 | default-column-width.proportion = 1. / 2.; | ||
187 | preset-window-heights = [ | ||
188 | { proportion = 1. / 3.; } | ||
189 | { proportion = 1. / 2.; } | ||
190 | { proportion = 2. / 3.; } | ||
191 | { proportion = 1.; } | ||
192 | ]; | ||
193 | |||
194 | always-center-single-column = true; | ||
117 | }; | 195 | }; |
118 | 196 | ||
119 | cursor.hide-when-typing = true; | 197 | cursor.hide-when-typing = true; |
@@ -122,6 +200,8 @@ in { | |||
122 | "001".name = "pwctl"; | 200 | "001".name = "pwctl"; |
123 | "002".name = "kpxc"; | 201 | "002".name = "kpxc"; |
124 | "003".name = "bmgr"; | 202 | "003".name = "bmgr"; |
203 | "004".name = "term"; | ||
204 | "005".name = "edit"; | ||
125 | "101".name = "comm"; | 205 | "101".name = "comm"; |
126 | "102".name = "web"; | 206 | "102".name = "web"; |
127 | "104".name = "read"; | 207 | "104".name = "read"; |
@@ -134,8 +214,9 @@ in { | |||
134 | geometry-corner-radius = | 214 | geometry-corner-radius = |
135 | let | 215 | let |
136 | allCorners = r: { bottom-left = r; bottom-right = r; top-left = r; top-right = r; }; | 216 | allCorners = r: { bottom-left = r; bottom-right = r; top-left = r; top-right = r; }; |
137 | in allCorners 8.; | 217 | in allCorners 4.; |
138 | clip-to-geometry = true; | 218 | clip-to-geometry = true; |
219 | open-focused = true; | ||
139 | } | 220 | } |
140 | { | 221 | { |
141 | matches = [ { app-id = "^com\.saivert\.pwvucontrol$"; } ]; | 222 | matches = [ { app-id = "^com\.saivert\.pwvucontrol$"; } ]; |
@@ -156,6 +237,14 @@ in { | |||
156 | open-focused = false; | 237 | open-focused = false; |
157 | } | 238 | } |
158 | { | 239 | { |
240 | matches = [ { app-id = "^kitty-scratch$"; } ]; | ||
241 | open-on-workspace = "term"; | ||
242 | } | ||
243 | { | ||
244 | matches = [ { title = "^scratch$"; app-id = "^emacs$"; } ]; | ||
245 | open-on-workspace = "edit"; | ||
246 | } | ||
247 | { | ||
159 | matches = [ | 248 | matches = [ |
160 | { app-id = "^thunderbird$"; } | 249 | { app-id = "^thunderbird$"; } |
161 | { app-id = "^Element$"; } | 250 | { app-id = "^Element$"; } |
@@ -195,6 +284,8 @@ in { | |||
195 | "Mod+D".action = spawn (lib.getExe config.programs.fuzzel.package); | 284 | "Mod+D".action = spawn (lib.getExe config.programs.fuzzel.package); |
196 | "Mod+Shift+D".action = spawn (lib.getExe config.programs.fuzzel.package) "--list-executables-in-path"; | 285 | "Mod+Shift+D".action = spawn (lib.getExe config.programs.fuzzel.package) "--list-executables-in-path"; |
197 | 286 | ||
287 | "Mod+Alt+E".action = spawn (lib.getExe' config.services.emacs.package "emacsclient") "-c"; | ||
288 | |||
198 | "Mod+H".action = focus-column-left; | 289 | "Mod+H".action = focus-column-left; |
199 | "Mod+T".action = focus-window-down; | 290 | "Mod+T".action = focus-window-down; |
200 | "Mod+N".action = focus-window-up; | 291 | "Mod+N".action = focus-window-up; |
@@ -215,15 +306,33 @@ in { | |||
215 | "Mod+Shift+Control+N".action = move-workspace-to-monitor-up; | 306 | "Mod+Shift+Control+N".action = move-workspace-to-monitor-up; |
216 | "Mod+Shift+Control+S".action = move-workspace-to-monitor-right; | 307 | "Mod+Shift+Control+S".action = move-workspace-to-monitor-right; |
217 | 308 | ||
218 | "Mod+G".action = focus-workspace-down; | 309 | "Mod+G".action = focus-adjacent-workspace "down"; |
219 | "Mod+C".action = focus-workspace-up; | 310 | "Mod+C".action = focus-adjacent-workspace "up"; |
220 | 311 | ||
221 | "Mod+Shift+G".action = move-column-to-workspace-down; | 312 | "Mod+Shift+G".action = move-column-to-adjacent-workspace "down"; |
222 | "Mod+Shift+C".action = move-column-to-workspace-up; | 313 | "Mod+Shift+C".action = move-column-to-adjacent-workspace "up"; |
223 | 314 | ||
224 | "Mod+Shift+Control+G".action = move-workspace-down; | 315 | "Mod+Shift+Control+G".action = move-workspace-down; |
225 | "Mod+Shift+Control+C".action = move-workspace-up; | 316 | "Mod+Shift+Control+C".action = move-workspace-up; |
226 | 317 | ||
318 | "Mod+ParenLeft".action = focus-workspace "comm"; | ||
319 | "Mod+Shift+ParenLeft".action = move-column-to-workspace "comm"; | ||
320 | |||
321 | "Mod+ParenRight".action = focus-workspace "web"; | ||
322 | "Mod+Shift+ParenRight".action = move-column-to-workspace "web"; | ||
323 | |||
324 | "Mod+BraceRight".action = focus-workspace "read"; | ||
325 | "Mod+Shift+BraceRight".action = move-column-to-workspace "read"; | ||
326 | |||
327 | "Mod+BraceLeft".action = focus-workspace "mon"; | ||
328 | "Mod+Shift+BraceLeft".action = move-column-to-workspace "mon"; | ||
329 | |||
330 | "Mod+Asterisk".action = focus-workspace "vid"; | ||
331 | "Mod+Shift+Asterisk".action = move-column-to-workspace "vid"; | ||
332 | |||
333 | "Mod+Plus".action = with-unnamed-workspace-action ''{"Action":{"FocusWorkspace":{"reference":{"Id": .id}}}}''; | ||
334 | "Mod+Shift+Plus".action = with-unnamed-workspace-action ''{"Action":{"MoveColumnToWorkspace":{"reference":{"Id": .id}}}}''; | ||
335 | |||
227 | "Mod+M".action = consume-or-expel-window-left; | 336 | "Mod+M".action = consume-or-expel-window-left; |
228 | "Mod+W".action = consume-or-expel-window-right; | 337 | "Mod+W".action = consume-or-expel-window-right; |
229 | 338 | ||
@@ -280,9 +389,11 @@ in { | |||
280 | "Mod+Period".action = spawn dunstctl "context"; | 389 | "Mod+Period".action = spawn dunstctl "context"; |
281 | "Mod+Comma".action = spawn dunstctl "history-pop"; | 390 | "Mod+Comma".action = spawn dunstctl "history-pop"; |
282 | 391 | ||
283 | "Mod+Alt+A".action = focus-or-spawn-action "^com\.saivert\.pwvucontrol$" "pwctl" "pwvucontrol"; | 392 | "Mod+Control+A".action = focus-or-spawn-action-app_id "com.saivert.pwvucontrol" "pwctl" "pwvucontrol"; |
284 | "Mod+Alt+P".action = focus-or-spawn-action "^org\.keepassxc\.KeePassXC$" "kpxc" "keepassxc"; | 393 | "Mod+Control+P".action = focus-or-spawn-action-app_id "org.keepassxc.KeePassXC" "kpxc" "keepassxc"; |
285 | "Mod+Alt+B".action = focus-or-spawn-action "^\.blueman-manager-wrapped$" "bmgr" "blueman-manager"; | 394 | "Mod+Control+B".action = focus-or-spawn-action-app_id ".blueman-manager-wrapped" "bmgr" "blueman-manager"; |
395 | "Mod+Control+Return".action = focus-or-spawn-action-app_id "kitty-scratch" "term" "kitty" "--app-id" "kitty-scratch"; | ||
396 | "Mod+Control+E".action = focus-or-spawn-action "select(.app_id == \"emacs\" and .title == \"scratch\")" "edit" "emacsclient" "-c" "--frame-parameters=(quote (name . \"scratch\"))"; | ||
286 | }; | 397 | }; |
287 | }; | 398 | }; |
288 | }; | 399 | }; |