blob: 6ef06a7d1f3f6a5148632c1ae51166a3fa56b6b1 [file] [log] [blame]
Skyler Grey69a999e2024-05-23 00:09:10 +00001{
2 pkgs,
3 config,
4 inputs,
5 system,
6 lib,
7 ...
Skyler Grey035c8d12024-05-26 21:23:33 +00008}:
9{
Skyler Grey69a999e2024-05-23 00:09:10 +000010
11 options.chimera.niri = {
12 enable = lib.mkEnableOption "Use Niri as your window manager";
Skyler Grey035c8d12024-05-26 21:23:33 +000013 xwayland.enable = lib.mkOption {
14 type = lib.types.bool;
15 default = true;
16 description = "Enable xwayland-satellite to run X apps in niri";
17 };
Skyler Grey69a999e2024-05-23 00:09:10 +000018 monitors = lib.mkOption {
Skyler Grey035c8d12024-05-26 21:23:33 +000019 type = lib.types.attrsOf (
20 lib.types.submodule {
21 options = {
22 enable = lib.mkOption {
Skyler Grey69a999e2024-05-23 00:09:10 +000023 type = lib.types.bool;
Skyler Grey035c8d12024-05-26 21:23:33 +000024 default = true;
25 description = "Enable this monitor";
Skyler Grey69a999e2024-05-23 00:09:10 +000026 };
Skyler Grey035c8d12024-05-26 21:23:33 +000027 mode = lib.mkOption {
28 type = lib.types.nullOr (
29 lib.types.submodule {
30 options = {
31 width = lib.mkOption { type = lib.types.int; };
32 height = lib.mkOption { type = lib.types.int; };
33 refresh = lib.mkOption {
34 type = lib.types.nullOr lib.types.float;
35 default = null;
36 };
37 };
38 }
39 );
40 default = null;
Skyler Grey69a999e2024-05-23 00:09:10 +000041 };
Skyler Grey035c8d12024-05-26 21:23:33 +000042 position = lib.mkOption {
43 type = lib.types.nullOr (
44 lib.types.submodule {
45 options = {
46 x = lib.mkOption { type = lib.types.int; };
47 y = lib.mkOption { type = lib.types.int; };
48 };
49 }
50 );
51 default = null;
52 };
53 scale = lib.mkOption {
54 type = lib.types.float;
55 default = 1.0;
56 };
57 transform = {
58 flipped = lib.mkOption {
59 type = lib.types.bool;
60 default = false;
61 };
62 rotation = lib.mkOption {
63 type = lib.types.enum [
64 0
65 90
66 180
67 270
68 ];
69 default = 0;
70 };
71 };
72 variable-refresh-rate = lib.mkEnableOption "Enable Variable Refresh Rate (AMD FreeSync / Nvidia G-Sync)";
Skyler Grey69a999e2024-05-23 00:09:10 +000073 };
Skyler Grey035c8d12024-05-26 21:23:33 +000074 }
75 );
Skyler Grey69a999e2024-05-23 00:09:10 +000076 description = "Atribute set of monitors";
77 default = { };
78 };
Samuel Shuert35d5f652024-07-01 13:09:28 -040079 startupCommands = lib.mkOption {
80 type = lib.types.listOf (lib.types.submodule {
81 options = {
82 command = lib.mkOption {
83 type = lib.types.listOf lib.types.str;
84 description = "Command to run";
85 };
86 };
87 });
88 description = "List of commands to run at startup";
89 default = [ ];
90 };
Skyler Grey69a999e2024-05-23 00:09:10 +000091 };
92
93 config = lib.mkIf config.chimera.niri.enable {
94 chimera.wayland.enable = true;
95
Skyler Grey035c8d12024-05-26 21:23:33 +000096 programs.bash.profileExtra = lib.mkIf config.chimera.shell.bash.enable (
97 lib.mkBefore ''
98 if [ -z $WAYLAND_DISPLAY ] && [ "$(tty)" = "/dev/tty1" ]; then
99 exec ${pkgs.systemd}/bin/systemd-cat -t niri ${pkgs.dbus}/bin/dbus-run-session ${config.programs.niri.package}/bin/niri --session
100 fi
101 ''
102 );
Skyler Grey69a999e2024-05-23 00:09:10 +0000103
Skyler Grey035c8d12024-05-26 21:23:33 +0000104 programs.zsh.profileExtra = lib.mkIf config.chimera.shell.zsh.enable (
105 lib.mkBefore ''
106 if [ -z $WAYLAND_DISPLAY ] && [ "$(tty)" = "/dev/tty1" ]; then
Samuel Shuert7f9aba12024-09-15 00:10:13 -0400107 exec ${pkgs.systemd}/bin/systemd-cat -t niri ${pkgs.dbus}/bin/dbus-run-session ${config.programs.niri.package}/bin/niri --session
Skyler Grey035c8d12024-05-26 21:23:33 +0000108 fi
109 ''
110 );
Skyler Grey69a999e2024-05-23 00:09:10 +0000111
Skyler Grey035c8d12024-05-26 21:23:33 +0000112 programs.niri =
113 let
114 mod = "Super";
115 mod1 = "Alt";
116 terminal = "${pkgs.kitty}/bin/kitty";
117 menu = (
118 if config.chimera.runner.anyrun.enable then
119 "${inputs.anyrun.packages.${system}.anyrun}/bin/anyrun"
120 else
121 ""
122 );
Skyler Grey69a999e2024-05-23 00:09:10 +0000123
Skyler Grey035c8d12024-05-26 21:23:33 +0000124 lock = ''${pkgs.swaylock}/bin/swaylock -i ${config.chimera.theme.wallpaper} -s fill'';
125 in
126 {
127 enable = true;
128 package = pkgs.niri-stable;
129 settings = {
130 environment = {
131 NIXOS_OZONE_WL = "1";
132 DISPLAY = lib.mkIf config.chimera.niri.xwayland.enable ":0";
Skyler Grey69a999e2024-05-23 00:09:10 +0000133 };
Skyler Grey035c8d12024-05-26 21:23:33 +0000134
135 input.keyboard = {
136 track-layout = "window";
137 repeat-delay = 200;
138 repeat-rate = 25;
139 xkb = {
140 layout = config.chimera.input.keyboard.layout;
141 variant = config.chimera.input.keyboard.variant;
142 };
143 };
Skyler Grey69a999e2024-05-23 00:09:10 +0000144
145 input.mouse.natural-scroll = config.chimera.input.mouse.scrolling.natural;
146 input.touchpad.natural-scroll = config.chimera.input.touchpad.scrolling.natural;
147
148 input.warp-mouse-to-focus = true;
Skyler Grey035c8d12024-05-26 21:23:33 +0000149 input.focus-follows-mouse = {
150 enable = true;
151 max-scroll-amount = "0%";
152 };
Skyler Grey69a999e2024-05-23 00:09:10 +0000153
154 input.power-key-handling.enable = false;
155
156 binds = let
157 inherit (config.lib.niri) actions;
158
159 generateWorkspaceBindings = workspaceNumber: {
160 "${mod}+${builtins.toString (lib.mod workspaceNumber 10)}".action = actions.focus-workspace workspaceNumber;
161 "${mod}+Shift+${builtins.toString (lib.mod workspaceNumber 10)}".action = actions.move-column-to-workspace workspaceNumber;
162 };
163 joinAttrsetList = listOfAttrsets: lib.fold (a: b: a // b) {} listOfAttrsets;
164 in { # General Keybinds
165 "${mod}+Q".action = actions.close-window;
166 "${mod}+Return".action = actions.spawn "${terminal}";
167 "${mod}+L".action = actions.spawn ["sh" "-c" "${config.programs.niri.package}/bin/niri msg action do-screen-transition && ${lock}"];
168 "${mod}+P".action = actions.power-off-monitors;
169
170 "${mod}+R".action = actions.screenshot;
171 "${mod}+Ctrl+R".action = actions.screenshot-screen;
172 "${mod}+Shift+R".action = actions.screenshot-window;
173 "Print".action = actions.screenshot;
174 "Ctrl+Print".action = actions.screenshot-screen;
175 "Shift+Print".action = actions.screenshot-window;
176
Samuel Shuert14af78c2024-10-02 16:34:40 -0400177 "${mod}+Alt+R".action = actions.spawn "sh" "-c" ''([ -d Videos ] || mkdir Videos) && ${pkgs.wl-screenrec}/bin/wl-screenrec --geometry "$(${pkgs.slurp}/bin/slurp)" --filename "Videos/$(date +'%Y-%m-%d-%H-%M-%S').mp4"'';
178 "${mod}+Alt+Shift+R".action = actions.spawn "sh" "-c" "pkill wl-screenrec && cat \"$(${pkgs.coreutils}/bin/ls -t Videos/*.mp4 | ${pkgs.coreutils}/bin/head -n 1)\" | ${pkgs.wl-clipboard}/bin/wl-copy";
179
Skyler Grey69a999e2024-05-23 00:09:10 +0000180 "${mod}+Space".action = actions."switch-layout" "next";
181 "${mod}+Shift+Space".action = actions."switch-layout" "prev";
182
183 "${mod}+D" = lib.mkIf config.chimera.runner.enable { action = actions.spawn "${menu}"; };
184 "Alt+Space" = lib.mkIf (
185 config.chimera.runner.enable
186 && config.chimera.input.keybinds.alternativeSearch.enable
187 ) { action = actions.spawn "${menu}"; };
188 "${mod}+Shift+Slash".action = actions.show-hotkey-overlay;
189 } // ( # Workspace Keybinds
190 lib.pipe (lib.range 1 10) [
191 (map generateWorkspaceBindings)
192 joinAttrsetList
193 ]
194 ) // ( # Window Manipulation Bindings
195 {
196 "${mod}+BracketLeft".action = actions."consume-or-expel-window-left";
197 "${mod}+BracketRight".action = actions."consume-or-expel-window-right";
198 "${mod}+Shift+BracketLeft".action = actions."consume-window-into-column";
199 "${mod}+Shift+BracketRight".action = actions."expel-window-from-column";
200 "${mod}+Slash".action = actions."switch-preset-column-width";
201 "${mod}+${mod1}+F".action = actions."fullscreen-window";
202
203 # Focus
204 "${mod}+Up".action = actions."focus-window-or-workspace-up";
205 "${mod}+Down".action = actions."focus-window-or-workspace-down";
206
207 # Non Jump Movement
208 "${mod}+Shift+Up".action = actions."move-window-up-or-to-workspace-up";
209 "${mod}+Shift+Down".action = actions."move-window-down-or-to-workspace-down";
210 "${mod}+Shift+Left".action = actions."consume-or-expel-window-left";
211 "${mod}+Shift+Right".action = actions."consume-or-expel-window-right";
212
213 # To Monitor
214 "${mod}+Shift+Ctrl+Up".action = actions."move-window-to-monitor-up";
215 "${mod}+Shift+Ctrl+Down".action = actions."move-window-to-monitor-down";
216 "${mod}+Shift+Ctrl+Left".action = actions."move-window-to-monitor-left";
217 "${mod}+Shift+Ctrl+Right".action = actions."move-window-to-monitor-right";
218
219 # To Workspace
220 "${mod}+Ctrl+Up".action = actions."move-window-to-workspace-up";
221 "${mod}+Ctrl+Down".action = actions."move-window-to-workspace-down";
222
223 # Sizing
224 "${mod}+Equal".action = actions."set-window-height" "+5%";
225 "${mod}+Minus".action = actions."set-window-height" "-5%";
226 }) // ( # Column Manipulation Bindings
227 {
228 # Focus
229 "${mod}+Left".action = actions."focus-column-left";
230 "${mod}+Right".action = actions."focus-column-right";
231 "${mod}+${mod1}+C".action = actions."center-column";
232 "${mod}+F".action = actions."maximize-column";
233
234 # Non Monitor Movement
235 "${mod}+${mod1}+Shift+Up".action = actions."move-column-to-workspace-up";
236 "${mod}+${mod1}+Shift+Down".action = actions."move-column-to-workspace-down";
237 "${mod}+${mod1}+Shift+Left".action = actions."move-column-left";
238 "${mod}+${mod1}+Shift+Right".action = actions."move-column-right";
239
240 # To Monitor
241 "${mod}+${mod1}+Shift+Ctrl+Up".action = actions."move-column-to-monitor-up";
242 "${mod}+${mod1}+Shift+Ctrl+Down".action = actions."move-column-to-monitor-down";
243 "${mod}+${mod1}+Shift+Ctrl+Left".action = actions."move-column-to-monitor-left";
244 "${mod}+${mod1}+Shift+Ctrl+Right".action = actions."move-column-to-monitor-right";
245
246 # Sizing
247 "${mod}+${mod1}+Equal".action = actions."set-column-width" "+5%";
248 "${mod}+${mod1}+Minus".action = actions."set-column-width" "-5%";
249 }) // ( # Workspace Manipulation Bindings
250 {
251 # Focus
252 "${mod}+Page_Up".action = actions."focus-workspace-up";
253 "${mod}+Page_Down".action = actions."focus-workspace-down";
254
255 # Within Itself
256 "${mod}+Shift+Page_Up".action = actions."move-workspace-up";
257 "${mod}+Shift+Page_Down".action = actions."move-workspace-down";
258
259 # To Monitor
260 "${mod}+Shift+Ctrl+Page_Up".action = actions."move-workspace-to-monitor-up";
261 "${mod}+Shift+Ctrl+Page_Down".action = actions."move-workspace-to-monitor-down";
262 "${mod}+Shift+Ctrl+Home".action = actions."move-workspace-to-monitor-left";
263 "${mod}+Shift+Ctrl+End".action = actions."move-workspace-to-monitor-right";
264 }) // { # Audio
265 "XF86AudioRaiseVolume" = {
266 allow-when-locked = true;
267 action = actions.spawn "${pkgs.wireplumber}/bin/wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.05+";
268 };
269 "XF86AudioLowerVolume" = {
270 allow-when-locked = true;
271 action = actions.spawn "${pkgs.wireplumber}/bin/wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.05-";
272 };
273 "XF86AudioMute" = {
274 allow-when-locked = true;
275 action = actions.spawn "${pkgs.wireplumber}/bin/wpctl" "set-mute" "@DEFAULT_AUDIO_SINK@" "toggle";
276 };
277 "XF86AudioMicMute" = {
278 allow-when-locked = true;
279 action = actions.spawn "${pkgs.wireplumber}/bin/wpctl" "set-mute" "@DEFAULT_AUDIO_SOURCE@" "toggle";
280 };
281 };
282
283 outputs = config.chimera.niri.monitors;
284
285 cursor = {
286 size = config.chimera.theme.cursor.size;
287 theme = config.chimera.theme.cursor.name;
288 };
289
290 layout = {
291 gaps = 16;
292
293 center-focused-column = "on-overflow";
294
295 preset-column-widths = [
296 { proportion = 1. / 4.; }
297 { proportion = 1. / 3.; }
298 { proportion = 1. / 2.; }
299 { proportion = 2. / 3.; }
Samuel Shuert4d5c5fb2024-06-09 09:39:11 -0400300 { proportion = 9. / 10.; }
Skyler Grey69a999e2024-05-23 00:09:10 +0000301 ]; # TODO: clicks to PR a docs update for niri-flake
302 };
303
304 prefer-no-csd = true; # No "client-side-decorations" (i.e. client-side window open/close buttons)
305 hotkey-overlay.skip-at-startup = true;
306 screenshot-path = null;
307
308 spawn-at-startup = [
309 {
310 command = [ "${pkgs.waybar}/bin/waybar" ];
311 }
312 {
313 command = [ "${pkgs.swaybg}/bin/swaybg" "-i" "${config.chimera.theme.wallpaper}" "-m" "fill" ];
314 }
Skyler Grey035c8d12024-05-26 21:23:33 +0000315 {
Skyler Grey44fbdc12024-09-17 21:07:18 +0000316 command = [ "${pkgs.xwayland-satellite-unstable}/bin/xwayland-satellite" ]; # todo: use xwayland-satellite-nixpkgs in the future...
Skyler Grey035c8d12024-05-26 21:23:33 +0000317 }
Samuel Shuert35d5f652024-07-01 13:09:28 -0400318 ] ++ config.chimera.niri.startupCommands;
Skyler Grey69a999e2024-05-23 00:09:10 +0000319 };
320 };
321 };
322}