summaryrefslogtreecommitdiff
path: root/accounts/gkleen@sif/niri
diff options
context:
space:
mode:
authorGregor Kleen <gkleen@yggdrasil.li>2025-01-14 11:30:32 +0100
committerGregor Kleen <gkleen@yggdrasil.li>2025-01-14 11:30:32 +0100
commit21b52a31e1eff5c8142f26e091fde083c21db55f (patch)
tree650eb693d91b353c866c42dfae49b7c5daee5ca9 /accounts/gkleen@sif/niri
parentbef130240c10b90d912aa06239402a6ad98867fe (diff)
downloadnixos-21b52a31e1eff5c8142f26e091fde083c21db55f.tar
nixos-21b52a31e1eff5c8142f26e091fde083c21db55f.tar.gz
nixos-21b52a31e1eff5c8142f26e091fde083c21db55f.tar.bz2
nixos-21b52a31e1eff5c8142f26e091fde083c21db55f.tar.xz
nixos-21b52a31e1eff5c8142f26e091fde083c21db55f.zip
niri
Diffstat (limited to 'accounts/gkleen@sif/niri')
-rw-r--r--accounts/gkleen@sif/niri/default.nix139
-rw-r--r--accounts/gkleen@sif/niri/waybar.nix288
2 files changed, 427 insertions, 0 deletions
diff --git a/accounts/gkleen@sif/niri/default.nix b/accounts/gkleen@sif/niri/default.nix
new file mode 100644
index 00000000..6a8d10a0
--- /dev/null
+++ b/accounts/gkleen@sif/niri/default.nix
@@ -0,0 +1,139 @@
1{ config, 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";
8in {
9 imports = [
10 ./waybar.nix
11 ];
12
13 config = {
14 systemd.user.services.xwayland-satellite = {
15 Unit = {
16 BindsTo = [ "graphical-session.target" ];
17 PartOf = [ "graphical-session.target" ];
18 After = [ "graphical-session.target" ];
19 Requisite = [ "graphical-session.target" ];
20 };
21 Service = {
22 Type = "notify";
23 NotifyAccess = "all";
24 ExecStart = lib.getExe pkgs.xwayland-satellite-unstable;
25 StandardOutput = "journal";
26 };
27 Install = {
28 WantedBy = [ "graphical-session.target" ];
29 };
30 };
31
32 programs.niri.settings = {
33 prefer-no-csd = true;
34 screenshot-path = "${config.home.homeDirectory}/screenshots";
35
36 input = {
37 keyboard.xkb = {
38 layout = "us,";
39 variant = "dvp,";
40 options = "compose:caps,grp:win_space_toggle";
41 };
42 };
43
44 environment = {
45 NIXOS_OZONE_WL = "1";
46 QT_QPA_PLATFORM = "wayland";
47 GDK_BACKEND = "wayland";
48 SDL_VIDEODRIVER = "wayland";
49 };
50
51 cursor.hide-when-typing = true;
52
53 binds = with config.lib.niri.actions; {
54 "Mod+Return".action = spawn terminal;
55 "Mod+Q".action = close-window;
56 "Mod+D".action = spawn (lib.getExe config.programs.fuzzel.package);
57 "Mod+Shift+D".action = spawn (lib.getExe config.programs.fuzzel.package) "--list-executables-in-path";
58
59 "Mod+H".action = focus-column-left;
60 "Mod+T".action = focus-window-down;
61 "Mod+N".action = focus-window-up;
62 "Mod+S".action = focus-column-right;
63
64 "Mod+Shift+H".action = move-column-left;
65 "Mod+Shift+T".action = move-window-down;
66 "Mod+Shift+N".action = move-window-up;
67 "Mod+Shift+S".action = move-column-right;
68
69 "Mod+Control+H".action = focus-monitor-left;
70 "Mod+Control+T".action = focus-monitor-down;
71 "Mod+Control+N".action = focus-monitor-up;
72 "Mod+Control+S".action = focus-monitor-right;
73
74 "Mod+Shift+Control+H".action = move-workspace-to-monitor-left;
75 "Mod+Shift+Control+T".action = move-workspace-to-monitor-down;
76 "Mod+Shift+Control+N".action = move-workspace-to-monitor-up;
77 "Mod+Shift+Control+S".action = move-workspace-to-monitor-right;
78
79 "Mod+G".action = focus-workspace-down;
80 "Mod+C".action = focus-workspace-up;
81
82 "Mod+Control+G".action = move-column-to-workspace-down;
83 "Mod+Control+C".action = move-column-to-workspace-up;
84
85 "Mod+Shift+G".action = move-workspace-down;
86 "Mod+Shift+C".action = move-workspace-up;
87
88 "Mod+M".action = consume-window-into-column;
89 "Mod+W".action = expel-window-from-column;
90
91 "Mod+F".action = maximize-column;
92 "Mod+Shift+F".action = fullscreen-window;
93
94 "Mod+Space".action = switch-focus-between-floating-and-tiling;
95 "Mod+Shift+Space".action = toggle-window-floating;
96
97 "Mod+Left".action = set-column-width "-10%";
98 "Mod+Down".action = set-window-height "-10%";
99 "Mod+Up".action = set-window-height "+10%";
100 "Mod+Right".action = set-column-width "+10%";
101
102 "Mod+Shift+Z" = {
103 action = spawn (lib.getExe niri) "msg" "action" "power-off-monitors";
104 allow-when-locked = true;
105 };
106
107 "XF86MonBrightnessUp" = {
108 action = spawn lightctl "-d" "-e4" "-n1" "up";
109 allow-when-locked = true;
110 };
111 "XF86MonBrightnessDown" = {
112 action = spawn lightctl "-d" "-e4" "-n1" "down";
113 allow-when-locked = true;
114 };
115 "XF86AudioRaiseVolume" = {
116 action = spawn volumectl "-d" "-u" "up";
117 allow-when-locked = true;
118 };
119 "XF86AudioLowerVolume" = {
120 action = spawn volumectl "-d" "-u" "down";
121 allow-when-locked = true;
122 };
123 "XF86AudioMute" = {
124 action = spawn volumectl "-d" "toggle-mute";
125 allow-when-locked = true;
126 };
127 "XF86AudioMicMute" = {
128 action = spawn volumectl "-d" "-m" "toggle-mute";
129 allow-when-locked = true;
130 };
131
132 "Mod+Semicolon".action = spawn dunstctl "close";
133 "Mod+Shift+Semicolon".action = spawn dunstctl "close-all";
134 "Mod+Period".action = spawn dunstctl "context";
135 "Mod+Comma".action = spawn dunstctl "history-pop";
136 };
137 };
138 };
139}
diff --git a/accounts/gkleen@sif/niri/waybar.nix b/accounts/gkleen@sif/niri/waybar.nix
new file mode 100644
index 00000000..1a25b581
--- /dev/null
+++ b/accounts/gkleen@sif/niri/waybar.nix
@@ -0,0 +1,288 @@
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 all-outputs = true;
85 };
86 "niri/window" = {
87 separate-outputs = true;
88 icon = true;
89 icon-size = 14;
90 rewrite = windowRewrites;
91 };
92 clock = {
93 interval = 1;
94 # timezone = "Europe/Berlin";
95 format = "W{:%V-%u %F %H:%M:%S%Ez}";
96 tooltip-format = "<tt><small>{calendar}</small></tt>";
97 calendar = {
98 mode = "year";
99 mode-mon-col = 3;
100 weeks-pos = "left";
101 on-scroll = 1;
102 format = {
103 months = "<span color='#ffead3'><b>{}</b></span>";
104 days = "{}";
105 weeks = "<span color='#99ffdd'><b>{}</b></span>";
106 weekdays = "<span color='#ffcc66'><b>{}</b></span>";
107 today = "<span color='#ff6699'><b>{}</b></span>";
108 };
109 };
110 };
111 battery = {
112 format = "<span font=\"Symbols Nerd Font Mono\" size=\"90%\">{icon}</span>";
113 icon-size = iconSize - 2;
114 states = { warning = 30; critical = 15; };
115 format-icons = ["&#xf008e;" "&#xf007a;" "&#xf007b;" "&#xf007c;" "&#xf007d;" "&#xf007e;" "&#xf007f;" "&#xf0080;" "&#xf0081;" "&#xf0082;" "&#xf0079;" ];
116 format-charging = "&#xf0084;";
117 format-plugged = "&#xf06a5;";
118 tooltip-format = "{capacity}% {timeTo}";
119 interval = 20;
120 };
121 tray = {
122 icon-size = 16;
123 # show-passive-items = true;
124 spacing = 1;
125 };
126 privacy = {
127 icon-spacing = 7;
128 icon-size = iconSize;
129 modules = [
130 { type = "screenshare"; }
131 { type = "audio-in"; }
132 ];
133 };
134 idle_inhibitor = {
135 format = "<span font=\"Symbols Nerd Font Mono\" size=\"90%\">{icon}</span>";
136 icon-size = iconSize;
137 format-icons = { activated = "&#xf0208;"; deactivated = "&#xf0209;"; };
138 timeout = 120;
139 };
140 backlight = {
141 format = "<span font=\"Symbols Nerd Font Mono\" size=\"90%\">{icon}</span>";
142 icon-size = iconSize;
143 tooltip-format = "{percent}%";
144 format-icons = ["&#xf00da;" "&#xf00db;" "&#xf00dc;" "&#xf00dd;" "&#xf00de;" "&#xf00df;" "&#xf00e0;"];
145 on-scroll-up = "lightctl -d -e4 -n1 up";
146 on-scroll-down = "lightctl -d -e4 -n1 down";
147 };
148 wireplumber = {
149 format = "<span font=\"Symbols Nerd Font Mono\" size=\"90%\">{icon}</span>";
150 icon-size = iconSize;
151 tooltip-format = "{volume}% {node_name}";
152 format-icons = ["&#xf057f;" "&#xf0580;" "&#xf057e;"];
153 format-muted = "<span font=\"Symbols Nerd Font Mono\" size=\"90%\">&#xf075f;</span>";
154 # ignored-sinks = ["Easy Effects Sink"];
155 on-scroll-up = "volumectl -d -u up";
156 on-scroll-down = "volumectl -d -u down";
157 on-click = "volumectl -d toggle-mute";
158 };
159 }
160 {
161 layer = "top";
162 position = "top";
163 height = 14;
164 output = [ "!eDP-1" "!DP-2" "!DP-3" ];
165 modules-left = [ "niri/workspaces" ];
166 modules-center = [ "niri/window" ];
167 modules-right = [ "clock" ];
168
169 "niri/workspaces" = {
170 all-outputs = false;
171 };
172 "niri/window" = {
173 separate-outputs = true;
174 icon = true;
175 icon-size = 14;
176 rewrite = windowRewrites;
177 };
178 clock = {
179 interval = 1;
180 # timezone = "Europe/Berlin";
181 format = "{:%H:%M}";
182 tooltip-format = "W{:%V-%u %F %H:%M:%S%Ez}";
183 };
184 }
185 ];
186 style = ''
187 @define-color white #ffffff;
188 @define-color grey #555555;
189 @define-color blue #1a8fff;
190 @define-color green #23fd00;
191 @define-color orange #f28a21;
192 @define-color red #f2201f;
193
194 * {
195 border: none;
196 font-family: "Fira Sans Nerd Font";
197 font-size: 10pt;
198 min-height: 0;
199 }
200
201 window#waybar {
202 background-color: rgba(0, 0, 0, 0.66);
203 color: @white;
204 }
205
206 .modules-left {
207 margin-left: 9px;
208 }
209 .modules-right {
210 margin-right: 9px;
211 }
212
213 .module {
214 margin: 0 5px;
215 }
216
217 #workspaces button {
218 color: @grey;
219 }
220 #workspaces button.hosting-monitor {
221 color: @white;
222 }
223 #workspaces button.visible {
224 color: @blue;
225 }
226 #workspaces button.active {
227 color: @green;
228 }
229 #workspaces button.urgent {
230 color: @red;
231 }
232
233 #custom-weather, #custom-keymap, #custom-worktime, #custom-worktime-today {
234 color: @grey;
235 margin: 0 5px;
236 }
237 #custom-weather, #custom-worktime-today {
238 margin-right: 3px;
239 }
240 #custom-keymap, #custom-weather {
241 margin-left: 3px;
242 }
243
244 #tray {
245 margin: 0;
246 }
247 #battery, #idle_inhibitor, #backlight, #wireplumber {
248 color: @grey;
249 margin: 0 5px 0 2px;
250 }
251 #idle_inhibitor {
252 margin-right: 2px;
253 margin-left: 3px;
254 }
255 #battery {
256 margin-right: 3px;
257 }
258 #battery.discharging {
259 color: @white;
260 }
261 #battery.warning {
262 color: @orange;
263 }
264 #battery.critical {
265 color: @red;
266 }
267 #battery.charging {
268 color: @white;
269 }
270 #idle_inhibitor.activated {
271 color: @white;
272 }
273
274 #idle_inhibitor {
275 padding-top: 1px;
276 }
277
278 #privacy {
279 color: @red;
280 margin: -1px 2px 0px 5px;
281 }
282 #clock {
283 /* margin-right: 5px; */
284 }
285 '';
286 };
287 };
288}