blob: dd436d1ae6b5a699c5635e9569a54072cdefb58a [file] [log] [blame]
Skyler Grey69a999e2024-05-23 00:09:10 +00001{
2 pkgs,
3 config,
4 inputs,
5 system,
6 lib,
7 ...
8}: {
9
10 options.chimera.niri = {
11 enable = lib.mkEnableOption "Use Niri as your window manager";
12 monitors = lib.mkOption {
13 type = lib.types.attrsOf (lib.types.submodule {
14 options = {
15 enable = lib.mkOption {
16 type = lib.types.bool;
17 default = true;
18 description = "Enable this monitor";
19 };
20 mode = lib.mkOption {
21 type = lib.types.nullOr (lib.types.submodule {
22 options = {
23 width = lib.mkOption {
24 type = lib.types.int;
25 };
26 height = lib.mkOption {
27 type = lib.types.int;
28 };
29 refresh = lib.mkOption {
30 type = lib.types.nullOr lib.types.float;
31 default = null;
32 };
33 };
34 });
35 default = null;
36 };
37 position = lib.mkOption {
38 type = lib.types.nullOr (lib.types.submodule {
39 options = {
40 x = lib.mkOption {
41 type = lib.types.int;
42 };
43 y = lib.mkOption {
44 type = lib.types.int;
45 };
46 };
47 });
48 default = null;
49 };
50 scale = lib.mkOption {
51 type = lib.types.float;
52 default = 1.;
53 };
54 transform = {
55 flipped = lib.mkOption {
56 type = lib.types.bool;
57 default = false;
58 };
59 rotation = lib.mkOption {
60 type = lib.types.enum [ 0 90 180 270 ];
61 default = 0;
62 };
63 };
64 variable-refresh-rate = lib.mkEnableOption "Enable Variable Refresh Rate (AMD FreeSync / Nvidia G-Sync)";
65 };
66 });
67 description = "Atribute set of monitors";
68 default = { };
69 };
Samuel Shuert35d5f652024-07-01 13:09:28 -040070 startupCommands = lib.mkOption {
71 type = lib.types.listOf (lib.types.submodule {
72 options = {
73 command = lib.mkOption {
74 type = lib.types.listOf lib.types.str;
75 description = "Command to run";
76 };
77 };
78 });
79 description = "List of commands to run at startup";
80 default = [ ];
81 };
Skyler Grey69a999e2024-05-23 00:09:10 +000082 };
83
84 config = lib.mkIf config.chimera.niri.enable {
85 chimera.wayland.enable = true;
86
87 programs.bash.profileExtra = lib.mkIf config.chimera.shell.bash.enable (lib.mkBefore ''
88 if [ -z $WAYLAND_DISPLAY ] && [ "$(tty)" = "/dev/tty1" ]; then
89 exec ${pkgs.systemd}/bin/systemd-cat -t niri ${pkgs.dbus}/bin/dbus-run-session ${config.programs.niri.package}/bin/niri --session
90 fi
91 '');
92
93 programs.zsh.profileExtra = lib.mkIf config.chimera.shell.zsh.enable (lib.mkBefore ''
94 if [ -z $WAYLAND_DISPLAY ] && [ "$(tty)" = "/dev/tty1" ]; then
95 exec ${pkgs.systemd}/bin/systemd-cat -t niri ${pkgs.dbus}/bin/dbus-run-session ${config.programs.niri.package}/bin/niri --session
96 fi
97 '');
98
99 home.sessionVariables.NIXOS_OZONE_WL = "1";
100
101 programs.niri = let
102 mod = "Super";
103 mod1 = "Alt";
104 terminal = "${pkgs.kitty}/bin/kitty";
105 menu = (if config.chimera.runner.anyrun.enable then "${inputs.anyrun.packages.${system}.anyrun}/bin/anyrun" else "");
106
107 lock = ''${pkgs.swaylock}/bin/swaylock -i ${config.chimera.theme.wallpaper} -s fill'';
108 in {
109 enable = true;
110 package = pkgs.niri-stable;
111 settings = {
112 input.keyboard = {
113 track-layout = "window";
114 repeat-delay = 200;
115 repeat-rate = 25;
116 xkb = {
117 layout = config.chimera.input.keyboard.layout;
118 variant = config.chimera.input.keyboard.variant;
119 };
120 };
121
122 input.mouse.natural-scroll = config.chimera.input.mouse.scrolling.natural;
123 input.touchpad.natural-scroll = config.chimera.input.touchpad.scrolling.natural;
124
125 input.warp-mouse-to-focus = true;
126 input.focus-follows-mouse = true;
127
128 input.power-key-handling.enable = false;
129
130 binds = let
131 inherit (config.lib.niri) actions;
132
133 generateWorkspaceBindings = workspaceNumber: {
134 "${mod}+${builtins.toString (lib.mod workspaceNumber 10)}".action = actions.focus-workspace workspaceNumber;
135 "${mod}+Shift+${builtins.toString (lib.mod workspaceNumber 10)}".action = actions.move-column-to-workspace workspaceNumber;
136 };
137 joinAttrsetList = listOfAttrsets: lib.fold (a: b: a // b) {} listOfAttrsets;
138 in { # General Keybinds
139 "${mod}+Q".action = actions.close-window;
140 "${mod}+Return".action = actions.spawn "${terminal}";
141 "${mod}+L".action = actions.spawn ["sh" "-c" "${config.programs.niri.package}/bin/niri msg action do-screen-transition && ${lock}"];
142 "${mod}+P".action = actions.power-off-monitors;
143
144 "${mod}+R".action = actions.screenshot;
145 "${mod}+Ctrl+R".action = actions.screenshot-screen;
146 "${mod}+Shift+R".action = actions.screenshot-window;
147 "Print".action = actions.screenshot;
148 "Ctrl+Print".action = actions.screenshot-screen;
149 "Shift+Print".action = actions.screenshot-window;
150
151 "${mod}+Space".action = actions."switch-layout" "next";
152 "${mod}+Shift+Space".action = actions."switch-layout" "prev";
153
154 "${mod}+D" = lib.mkIf config.chimera.runner.enable { action = actions.spawn "${menu}"; };
155 "Alt+Space" = lib.mkIf (
156 config.chimera.runner.enable
157 && config.chimera.input.keybinds.alternativeSearch.enable
158 ) { action = actions.spawn "${menu}"; };
159 "${mod}+Shift+Slash".action = actions.show-hotkey-overlay;
160 } // ( # Workspace Keybinds
161 lib.pipe (lib.range 1 10) [
162 (map generateWorkspaceBindings)
163 joinAttrsetList
164 ]
165 ) // ( # Window Manipulation Bindings
166 {
167 "${mod}+BracketLeft".action = actions."consume-or-expel-window-left";
168 "${mod}+BracketRight".action = actions."consume-or-expel-window-right";
169 "${mod}+Shift+BracketLeft".action = actions."consume-window-into-column";
170 "${mod}+Shift+BracketRight".action = actions."expel-window-from-column";
171 "${mod}+Slash".action = actions."switch-preset-column-width";
172 "${mod}+${mod1}+F".action = actions."fullscreen-window";
173
174 # Focus
175 "${mod}+Up".action = actions."focus-window-or-workspace-up";
176 "${mod}+Down".action = actions."focus-window-or-workspace-down";
177
178 # Non Jump Movement
179 "${mod}+Shift+Up".action = actions."move-window-up-or-to-workspace-up";
180 "${mod}+Shift+Down".action = actions."move-window-down-or-to-workspace-down";
181 "${mod}+Shift+Left".action = actions."consume-or-expel-window-left";
182 "${mod}+Shift+Right".action = actions."consume-or-expel-window-right";
183
184 # To Monitor
185 "${mod}+Shift+Ctrl+Up".action = actions."move-window-to-monitor-up";
186 "${mod}+Shift+Ctrl+Down".action = actions."move-window-to-monitor-down";
187 "${mod}+Shift+Ctrl+Left".action = actions."move-window-to-monitor-left";
188 "${mod}+Shift+Ctrl+Right".action = actions."move-window-to-monitor-right";
189
190 # To Workspace
191 "${mod}+Ctrl+Up".action = actions."move-window-to-workspace-up";
192 "${mod}+Ctrl+Down".action = actions."move-window-to-workspace-down";
193
194 # Sizing
195 "${mod}+Equal".action = actions."set-window-height" "+5%";
196 "${mod}+Minus".action = actions."set-window-height" "-5%";
197 }) // ( # Column Manipulation Bindings
198 {
199 # Focus
200 "${mod}+Left".action = actions."focus-column-left";
201 "${mod}+Right".action = actions."focus-column-right";
202 "${mod}+${mod1}+C".action = actions."center-column";
203 "${mod}+F".action = actions."maximize-column";
204
205 # Non Monitor Movement
206 "${mod}+${mod1}+Shift+Up".action = actions."move-column-to-workspace-up";
207 "${mod}+${mod1}+Shift+Down".action = actions."move-column-to-workspace-down";
208 "${mod}+${mod1}+Shift+Left".action = actions."move-column-left";
209 "${mod}+${mod1}+Shift+Right".action = actions."move-column-right";
210
211 # To Monitor
212 "${mod}+${mod1}+Shift+Ctrl+Up".action = actions."move-column-to-monitor-up";
213 "${mod}+${mod1}+Shift+Ctrl+Down".action = actions."move-column-to-monitor-down";
214 "${mod}+${mod1}+Shift+Ctrl+Left".action = actions."move-column-to-monitor-left";
215 "${mod}+${mod1}+Shift+Ctrl+Right".action = actions."move-column-to-monitor-right";
216
217 # Sizing
218 "${mod}+${mod1}+Equal".action = actions."set-column-width" "+5%";
219 "${mod}+${mod1}+Minus".action = actions."set-column-width" "-5%";
220 }) // ( # Workspace Manipulation Bindings
221 {
222 # Focus
223 "${mod}+Page_Up".action = actions."focus-workspace-up";
224 "${mod}+Page_Down".action = actions."focus-workspace-down";
225
226 # Within Itself
227 "${mod}+Shift+Page_Up".action = actions."move-workspace-up";
228 "${mod}+Shift+Page_Down".action = actions."move-workspace-down";
229
230 # To Monitor
231 "${mod}+Shift+Ctrl+Page_Up".action = actions."move-workspace-to-monitor-up";
232 "${mod}+Shift+Ctrl+Page_Down".action = actions."move-workspace-to-monitor-down";
233 "${mod}+Shift+Ctrl+Home".action = actions."move-workspace-to-monitor-left";
234 "${mod}+Shift+Ctrl+End".action = actions."move-workspace-to-monitor-right";
235 }) // { # Audio
236 "XF86AudioRaiseVolume" = {
237 allow-when-locked = true;
238 action = actions.spawn "${pkgs.wireplumber}/bin/wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.05+";
239 };
240 "XF86AudioLowerVolume" = {
241 allow-when-locked = true;
242 action = actions.spawn "${pkgs.wireplumber}/bin/wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.05-";
243 };
244 "XF86AudioMute" = {
245 allow-when-locked = true;
246 action = actions.spawn "${pkgs.wireplumber}/bin/wpctl" "set-mute" "@DEFAULT_AUDIO_SINK@" "toggle";
247 };
248 "XF86AudioMicMute" = {
249 allow-when-locked = true;
250 action = actions.spawn "${pkgs.wireplumber}/bin/wpctl" "set-mute" "@DEFAULT_AUDIO_SOURCE@" "toggle";
251 };
252 };
253
254 outputs = config.chimera.niri.monitors;
255
256 cursor = {
257 size = config.chimera.theme.cursor.size;
258 theme = config.chimera.theme.cursor.name;
259 };
260
261 layout = {
262 gaps = 16;
263
264 center-focused-column = "on-overflow";
265
266 preset-column-widths = [
267 { proportion = 1. / 4.; }
268 { proportion = 1. / 3.; }
269 { proportion = 1. / 2.; }
270 { proportion = 2. / 3.; }
Samuel Shuert4d5c5fb2024-06-09 09:39:11 -0400271 { proportion = 9. / 10.; }
Skyler Grey69a999e2024-05-23 00:09:10 +0000272 ]; # TODO: clicks to PR a docs update for niri-flake
273 };
274
275 prefer-no-csd = true; # No "client-side-decorations" (i.e. client-side window open/close buttons)
276 hotkey-overlay.skip-at-startup = true;
277 screenshot-path = null;
278
279 spawn-at-startup = [
280 {
281 command = [ "${pkgs.waybar}/bin/waybar" ];
282 }
283 {
284 command = [ "${pkgs.swaybg}/bin/swaybg" "-i" "${config.chimera.theme.wallpaper}" "-m" "fill" ];
285 }
Samuel Shuert35d5f652024-07-01 13:09:28 -0400286 ] ++ config.chimera.niri.startupCommands;
Skyler Grey69a999e2024-05-23 00:09:10 +0000287 };
288 };
289 };
290}