summaryrefslogtreecommitdiff
path: root/accounts/gkleen@sif/niri
diff options
context:
space:
mode:
Diffstat (limited to 'accounts/gkleen@sif/niri')
-rw-r--r--accounts/gkleen@sif/niri/default.nix289
-rw-r--r--accounts/gkleen@sif/niri/waybar.nix282
2 files changed, 0 insertions, 571 deletions
diff --git a/accounts/gkleen@sif/niri/default.nix b/accounts/gkleen@sif/niri/default.nix
deleted file mode 100644
index 6aa4391c..00000000
--- a/accounts/gkleen@sif/niri/default.nix
+++ /dev/null
@@ -1,289 +0,0 @@
1{ config, hostConfig, pkgs, lib, ... }:
2let
3 niri = config.programs.niri.package;
4 terminal = lib.getExe config.programs.kitty.package;
5 lightctl = lib.getExe' config.services.avizo.package "lightctl";
6 volumectl = lib.getExe' config.services.avizo.package "volumectl";
7 dunstctl = lib.getExe' config.services.dunst.package "dunstctl";
8 loginctl = lib.getExe' hostConfig.systemd.package "loginctl";
9 systemctl = lib.getExe' hostConfig.systemd.package "systemctl";
10
11 focus-or-spawn = pkgs.writeShellApplication {
12 name = "focus-or-spawn";
13 runtimeInputs = [ niri pkgs.gojq pkgs.gnugrep pkgs.socat ];
14 text = ''
15 app_id="$1"
16 shift
17 workspace_name="$1"
18 shift
19
20 workspaces_json="$(niri msg -j workspaces)"
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")"
23 niri msg action move-workspace-to-monitor --output "$(jq -r '.[] | select(.is_focused) | .output' <<<"$workspaces_json")" "$workspace_name"
24 socat STDIO "$NIRI_SOCKET" <<<'{"Action":{"FocusWorkspace":{"reference":{"Id":'"''${active_workspace}"'}}}}'
25 niri msg action move-workspace-to-index --index 1 "$workspace_name"
26
27 while IFS=$'\n' read -r window_json; do
28 if jq -r '.app_id' <<<"$window_json" | grep -q "$app_id"; then
29 niri msg action focus-window --id "$(jq -r '.id' <<<"$window_json")"
30 exit 0
31 fi
32 done < <(niri msg -j windows | jq -c '.[]')
33
34 exec "$@"
35 '';
36 };
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);
38in {
39 imports = [
40 ./waybar.nix
41 ];
42
43 config = {
44 systemd.user.services.xwayland-satellite = {
45 Unit = {
46 BindsTo = [ "graphical-session.target" ];
47 PartOf = [ "graphical-session.target" ];
48 After = [ "graphical-session.target" ];
49 Requisite = [ "graphical-session.target" ];
50 };
51 Service = {
52 Type = "notify";
53 NotifyAccess = "all";
54 Environment = [ "DISPLAY=:0" ];
55 ExecStart = ''${lib.getExe pkgs.xwayland-satellite-unstable} ''${DISPLAY}'';
56 ExecStartPre = "${systemctl} --user import-environment DISPLAY";
57 StandardOutput = "journal";
58 };
59 Install = {
60 WantedBy = [ "graphical-session.target" ];
61 };
62 };
63
64 services.swayidle = {
65 events = [
66 { event = "after-resume"; command = "${lib.getExe niri} msg action power-on-monitors"; }
67 ];
68 timeouts = [
69 { timeout = 300;
70 command = "${lib.getExe niri} msg action power-off-monitors";
71 }
72 ];
73 };
74
75 programs.niri.settings = {
76 prefer-no-csd = true;
77 screenshot-path = "${config.home.homeDirectory}/screenshots";
78
79 hotkey-overlay.skip-at-startup = true;
80
81 input = {
82 keyboard.xkb = {
83 layout = "us,us";
84 variant = "dvp,";
85 options = "compose:caps,grp:win_space_toggle";
86 };
87
88 workspace-auto-back-and-forth = true;
89 # focus-follows-mouse.enable = true;
90 warp-mouse-to-focus = true;
91 };
92
93 outputs = {
94 "Samsung Display Corp. 0x4141 Unknown" = {
95 scale = 1.5;
96 position = { x = 0; y = 0; };
97 };
98 "Ancor Communications Inc ASUS PB287Q 0x0000DD9B" = {
99 scale = 1.5;
100 position = { x = 2560; y = 0; };
101 };
102 };
103
104 environment = {
105 NIXOS_OZONE_WL = "1";
106 QT_QPA_PLATFORM = "wayland";
107 GDK_BACKEND = "wayland";
108 SDL_VIDEODRIVER = "wayland";
109 };
110
111 layout = {
112 gaps = 8;
113 struts = { left = 8; right = 8; top = 0; bottom = 0; };
114 focus-ring = {
115 width = 2;
116 };
117 };
118
119 cursor.hide-when-typing = true;
120
121 workspaces = {
122 "001".name = "pwctl";
123 "002".name = "kpxc";
124 "003".name = "bmgr";
125 "101".name = "comm";
126 "102".name = "web";
127 "104".name = "read";
128 "105".name = "mon";
129 "110".name = "vid";
130 };
131
132 window-rules = [
133 {
134 geometry-corner-radius =
135 let
136 allCorners = r: { bottom-left = r; bottom-right = r; top-left = r; top-right = r; };
137 in allCorners 8.;
138 clip-to-geometry = true;
139 }
140 {
141 matches = [ { app-id = "^com\.saivert\.pwvucontrol$"; } ];
142 open-on-workspace = "pwctl";
143 }
144 {
145 matches = [ { app-id = "^\.blueman-manager-wrapped$"; } ];
146 open-on-workspace = "bmgr";
147 }
148 {
149 matches = [ { app-id = "^org\.keepassxc\.KeePassXC$"; } ];
150 excludes = [
151 { title = "^Unlock Database"; }
152 { title = "^Access Request"; }
153 { title = "^Passkey credentials"; }
154 ];
155 open-on-workspace = "kpxc";
156 open-focused = false;
157 }
158 {
159 matches = [
160 { app-id = "^thunderbird$"; }
161 { app-id = "^Element$"; }
162 ];
163 open-on-workspace = "comm";
164 }
165 {
166 matches = [ { app-id = "^firefox$"; } ];
167 open-on-workspace = "web";
168 }
169 {
170 matches = [
171 { app-id = "^evince$"; }
172 { app-id = "^imv$"; }
173 { app-id = "^org\.pwmt\.zathura$"; }
174 ];
175 open-on-workspace = "read";
176 }
177 {
178 matches = [ { app-id = "^mpv$"; } ];
179 open-on-workspace = "vid";
180 }
181 {
182 matches = [
183 { app-id = "^qemu$"; }
184 { app-id = "^virt-manager$"; }
185 ];
186 open-on-workspace = "mon";
187 }
188 ];
189
190 binds = with config.lib.niri.actions; {
191 "Mod+Slash".action = show-hotkey-overlay;
192
193 "Mod+Return".action = spawn terminal;
194 "Mod+Q".action = close-window;
195 "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";
197
198 "Mod+H".action = focus-column-left;
199 "Mod+T".action = focus-window-down;
200 "Mod+N".action = focus-window-up;
201 "Mod+S".action = focus-column-right;
202
203 "Mod+Shift+H".action = move-column-left;
204 "Mod+Shift+T".action = move-window-down;
205 "Mod+Shift+N".action = move-window-up;
206 "Mod+Shift+S".action = move-column-right;
207
208 "Mod+Control+H".action = focus-monitor-left;
209 "Mod+Control+T".action = focus-monitor-down;
210 "Mod+Control+N".action = focus-monitor-up;
211 "Mod+Control+S".action = focus-monitor-right;
212
213 "Mod+Shift+Control+H".action = move-workspace-to-monitor-left;
214 "Mod+Shift+Control+T".action = move-workspace-to-monitor-down;
215 "Mod+Shift+Control+N".action = move-workspace-to-monitor-up;
216 "Mod+Shift+Control+S".action = move-workspace-to-monitor-right;
217
218 "Mod+G".action = focus-workspace-down;
219 "Mod+C".action = focus-workspace-up;
220
221 "Mod+Shift+G".action = move-column-to-workspace-down;
222 "Mod+Shift+C".action = move-column-to-workspace-up;
223
224 "Mod+Shift+Control+G".action = move-workspace-down;
225 "Mod+Shift+Control+C".action = move-workspace-up;
226
227 "Mod+M".action = consume-or-expel-window-left;
228 "Mod+W".action = consume-or-expel-window-right;
229
230 "Mod+R".action = switch-preset-column-width;
231 "Mod+Shift+R".action = switch-preset-window-height;
232 "Mod+F".action = center-column;
233 "Mod+Shift+F".action = maximize-column;
234 "Mod+Shift+Ctrl+F".action = fullscreen-window;
235
236 "Mod+B".action = switch-focus-between-floating-and-tiling;
237 "Mod+Shift+B".action = toggle-window-floating;
238
239 "Mod+Left".action = set-column-width "-10%";
240 "Mod+Down".action = set-window-height "-10%";
241 "Mod+Up".action = set-window-height "+10%";
242 "Mod+Right".action = set-column-width "+10%";
243
244 "Mod+Shift+Z" = {
245 action = spawn (lib.getExe niri) "msg" "action" "power-off-monitors";
246 allow-when-locked = true;
247 };
248 "Mod+Shift+L" = {
249 action = spawn loginctl "lock-session";
250 };
251 "Mod+Shift+E".action = quit;
252
253 "XF86MonBrightnessUp" = {
254 action = spawn lightctl "-d" "-e4" "-n1" "up";
255 allow-when-locked = true;
256 };
257 "XF86MonBrightnessDown" = {
258 action = spawn lightctl "-d" "-e4" "-n1" "down";
259 allow-when-locked = true;
260 };
261 "XF86AudioRaiseVolume" = {
262 action = spawn volumectl "-d" "-u" "up";
263 allow-when-locked = true;
264 };
265 "XF86AudioLowerVolume" = {
266 action = spawn volumectl "-d" "-u" "down";
267 allow-when-locked = true;
268 };
269 "XF86AudioMute" = {
270 action = spawn volumectl "-d" "toggle-mute";
271 allow-when-locked = true;
272 };
273 "XF86AudioMicMute" = {
274 action = spawn volumectl "-d" "-m" "toggle-mute";
275 allow-when-locked = true;
276 };
277
278 "Mod+Semicolon".action = spawn dunstctl "close";
279 "Mod+Shift+Semicolon".action = spawn dunstctl "close-all";
280 "Mod+Period".action = spawn dunstctl "context";
281 "Mod+Comma".action = spawn dunstctl "history-pop";
282
283 "Mod+Alt+A".action = focus-or-spawn-action "^com\.saivert\.pwvucontrol$" "pwctl" "pwvucontrol";
284 "Mod+Alt+P".action = focus-or-spawn-action "^org\.keepassxc\.KeePassXC$" "kpxc" "keepassxc";
285 "Mod+Alt+B".action = focus-or-spawn-action "^\.blueman-manager-wrapped$" "bmgr" "blueman-manager";
286 };
287 };
288 };
289}
diff --git a/accounts/gkleen@sif/niri/waybar.nix b/accounts/gkleen@sif/niri/waybar.nix
deleted file mode 100644
index 2d00c6d8..00000000
--- a/accounts/gkleen@sif/niri/waybar.nix
+++ /dev/null
@@ -1,282 +0,0 @@
1{ lib, pkgs, ... }:
2{
3 config = {
4 programs.waybar = {
5 enable = true;
6 systemd = {
7 enable = true;
8 target = "graphical-session.target";
9 };
10 settings = let
11 windowRewrites = {
12 "(.*) — Mozilla Firefox" = "$1";
13 "(.*) - Mozilla Thunderbird" = "$1";
14 "(.*) - mpv" = "$1";
15 };
16 iconSize = 11;
17 in [
18 {
19 layer = "top";
20 position = "top";
21 height = 14;
22 output = [ "eDP-1" "DP-2" "DP-3" ];
23 modules-left = [ "niri/workspaces" ];
24 modules-center = [ "niri/window" ];
25 modules-right = [ # "custom/worktime" "custom/worktime-today"
26 "custom/weather"
27 # "custom/keymap"
28 "privacy" "tray" "wireplumber" "backlight" "battery" "idle_inhibitor" "clock" ];
29
30 "custom/weather" = {
31 format = "{}";
32 tooltip = true;
33 interval = 3600;
34 exec = "${lib.getExe pkgs.wttrbar} --hide-conditions --nerd --custom-indicator \"<span font=\\\"Symbols Nerd Font Mono\\\" size=\\\"120%\\\">{ICON}</span> {FeelsLikeC}°\"";
35 return-type = "json";
36 };
37 "custom/keymap" = {
38 format = "{}";
39 tooltip = true;
40 return-type = "json";
41 exec = pkgs.writers.writePython3 "keymap" {} ''
42 import os
43 import socket
44 import re
45 import subprocess
46 import json
47
48
49 def output(keymap):
50 short = keymap
51 if keymap == "English (programmer Dvorak)":
52 short = "dvp"
53 elif keymap == "English (US)":
54 short = "<span color=\"#ffffff\">us</span>"
55 print(json.dumps({'text': short, 'tooltip': keymap}, separators=(',', ':')), flush=True) # noqa: E501
56
57
58 r = subprocess.run(["hyprctl", "devices", "-j"], check=True, stdout=subprocess.PIPE, text=True) # noqa: E501
59 for keyboard in json.loads(r.stdout)['keyboards']:
60 if keyboard['name'] != "at-translated-set-2-keyboard":
61 continue
62 output(keyboard['active_keymap'])
63
64 sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
65 sock.connect(os.environ["XDG_RUNTIME_DIR"] + "/hypr/" + os.environ["HYPRLAND_INSTANCE_SIGNATURE"] + "/.socket2.sock") # noqa: E501
66 expected = re.compile(r'^activelayout>>at-translated-set-2-keyboard,(?P<keymap>.+)$') # noqa: E501
67 for line in sock.makefile(buffering=1, encoding='utf-8'):
68 if match := expected.match(line):
69 output(match.group("keymap"))
70 '';
71 on-click = "hyprctl switchxkblayout at-translated-set-2-keyboard next";
72 };
73 "custom/worktime" = {
74 interval = 60;
75 exec = lib.getExe pkgs.worktime;
76 tooltip = false;
77 };
78 "custom/worktime-today" = {
79 interval = 60;
80 exec = "${lib.getExe pkgs.worktime} today";
81 tooltip = false;
82 };
83 "niri/workspaces" = {};
84 "niri/window" = {
85 separate-outputs = true;
86 icon = true;
87 icon-size = 14;
88 rewrite = windowRewrites;
89 };
90 clock = {
91 interval = 1;
92 # timezone = "Europe/Berlin";
93 format = "W{:%V-%u %F %H:%M:%S%Ez}";
94 tooltip-format = "<tt><small>{calendar}</small></tt>";
95 calendar = {
96 mode = "year";
97 mode-mon-col = 3;
98 weeks-pos = "left";
99 on-scroll = 1;
100 format = {
101 months = "<span color='#ffead3'><b>{}</b></span>";
102 days = "{}";
103 weeks = "<span color='#99ffdd'><b>{}</b></span>";
104 weekdays = "<span color='#ffcc66'><b>{}</b></span>";
105 today = "<span color='#ff6699'><b>{}</b></span>";
106 };
107 };
108 };
109 battery = {
110 format = "<span font=\"Symbols Nerd Font Mono\" size=\"90%\">{icon}</span>";
111 icon-size = iconSize - 2;
112 states = { warning = 30; critical = 15; };
113 format-icons = ["&#xf008e;" "&#xf007a;" "&#xf007b;" "&#xf007c;" "&#xf007d;" "&#xf007e;" "&#xf007f;" "&#xf0080;" "&#xf0081;" "&#xf0082;" "&#xf0079;" ];
114 format-charging = "&#xf0084;";
115 format-plugged = "&#xf06a5;";
116 tooltip-format = "{capacity}% {timeTo}";
117 interval = 20;
118 };
119 tray = {
120 icon-size = 16;
121 # show-passive-items = true;
122 spacing = 1;
123 };
124 privacy = {
125 icon-spacing = 7;
126 icon-size = iconSize;
127 modules = [
128 { type = "screenshare"; }
129 { type = "audio-in"; }
130 ];
131 };
132 idle_inhibitor = {
133 format = "<span font=\"Symbols Nerd Font Mono\" size=\"90%\">{icon}</span>";
134 icon-size = iconSize;
135 format-icons = { activated = "&#xf0208;"; deactivated = "&#xf0209;"; };
136 timeout = 120;
137 };
138 backlight = {
139 format = "<span font=\"Symbols Nerd Font Mono\" size=\"90%\">{icon}</span>";
140 icon-size = iconSize;
141 tooltip-format = "{percent}%";
142 format-icons = ["&#xf00da;" "&#xf00db;" "&#xf00dc;" "&#xf00dd;" "&#xf00de;" "&#xf00df;" "&#xf00e0;"];
143 on-scroll-up = "lightctl -d -e4 -n1 up";
144 on-scroll-down = "lightctl -d -e4 -n1 down";
145 };
146 wireplumber = {
147 format = "<span font=\"Symbols Nerd Font Mono\" size=\"90%\">{icon}</span>";
148 icon-size = iconSize;
149 tooltip-format = "{volume}% {node_name}";
150 format-icons = ["&#xf057f;" "&#xf0580;" "&#xf057e;"];
151 format-muted = "<span font=\"Symbols Nerd Font Mono\" size=\"90%\">&#xf075f;</span>";
152 # ignored-sinks = ["Easy Effects Sink"];
153 on-scroll-up = "volumectl -d -u up";
154 on-scroll-down = "volumectl -d -u down";
155 on-click = "volumectl -d toggle-mute";
156 };
157 }
158 {
159 layer = "top";
160 position = "top";
161 height = 14;
162 output = [ "!eDP-1" "!DP-2" "!DP-3" ];
163 modules-left = [ "niri/workspaces" ];
164 modules-center = [ "niri/window" ];
165 modules-right = [ "clock" ];
166
167 "niri/workspaces" = {};
168 "niri/window" = {
169 separate-outputs = true;
170 icon = true;
171 icon-size = 14;
172 rewrite = windowRewrites;
173 };
174 clock = {
175 interval = 1;
176 # timezone = "Europe/Berlin";
177 format = "{:%H:%M}";
178 tooltip-format = "W{:%V-%u %F %H:%M:%S%Ez}";
179 };
180 }
181 ];
182 style = ''
183 @define-color white #ffffff;
184 @define-color grey #555555;
185 @define-color blue #1a8fff;
186 @define-color green #23fd00;
187 @define-color orange #f28a21;
188 @define-color red #f2201f;
189
190 * {
191 border: none;
192 font-family: "Fira Sans Nerd Font";
193 font-size: 10pt;
194 min-height: 0;
195 }
196
197 window#waybar {
198 background-color: rgba(0, 0, 0, 0.66);
199 color: @white;
200 }
201
202 .modules-left {
203 margin-left: 9px;
204 }
205 .modules-right {
206 margin-right: 9px;
207 }
208
209 .module {
210 margin: 0 5px;
211 }
212
213 #workspaces button {
214 color: @white;
215 padding: 2px 5px;
216 }
217 #workspaces button.empty {
218 color: @grey;
219 }
220 #workspaces button.active {
221 color: @green;
222 }
223 #workspaces button.urgent {
224 color: @red;
225 }
226
227 #custom-weather, #custom-keymap, #custom-worktime, #custom-worktime-today {
228 color: @grey;
229 margin: 0 5px;
230 }
231 #custom-weather, #custom-worktime-today {
232 margin-right: 3px;
233 }
234 #custom-keymap, #custom-weather {
235 margin-left: 3px;
236 }
237
238 #tray {
239 margin: 0;
240 }
241 #battery, #idle_inhibitor, #backlight, #wireplumber {
242 color: @grey;
243 margin: 0 5px 0 2px;
244 }
245 #idle_inhibitor {
246 margin-right: 2px;
247 margin-left: 3px;
248 }
249 #battery {
250 margin-right: 3px;
251 }
252 #battery.discharging {
253 color: @white;
254 }
255 #battery.warning {
256 color: @orange;
257 }
258 #battery.critical {
259 color: @red;
260 }
261 #battery.charging {
262 color: @white;
263 }
264 #idle_inhibitor.activated {
265 color: @white;
266 }
267
268 #idle_inhibitor {
269 padding-top: 1px;
270 }
271
272 #privacy {
273 color: @red;
274 margin: -1px 2px 0px 5px;
275 }
276 #clock {
277 /* margin-right: 5px; */
278 }
279 '';
280 };
281 };
282}