blob: e60161021371f1bca00a19e68755ca1bc32d130a [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}:
Samuel Shuert291d96b2024-10-14 14:45:24 -04009let
10inherit (inputs) nixpkgs-stable;
11in {
Skyler Grey69a999e2024-05-23 00:09:10 +000012
13 options.chimera.niri = {
14 enable = lib.mkEnableOption "Use Niri as your window manager";
Skyler Grey035c8d12024-05-26 21:23:33 +000015 xwayland.enable = lib.mkOption {
16 type = lib.types.bool;
17 default = true;
18 description = "Enable xwayland-satellite to run X apps in niri";
19 };
Skyler Grey69a999e2024-05-23 00:09:10 +000020 monitors = lib.mkOption {
Skyler Grey035c8d12024-05-26 21:23:33 +000021 type = lib.types.attrsOf (
22 lib.types.submodule {
23 options = {
24 enable = lib.mkOption {
Skyler Grey69a999e2024-05-23 00:09:10 +000025 type = lib.types.bool;
Skyler Grey035c8d12024-05-26 21:23:33 +000026 default = true;
27 description = "Enable this monitor";
Skyler Grey69a999e2024-05-23 00:09:10 +000028 };
Skyler Grey035c8d12024-05-26 21:23:33 +000029 mode = lib.mkOption {
30 type = lib.types.nullOr (
31 lib.types.submodule {
32 options = {
33 width = lib.mkOption { type = lib.types.int; };
34 height = lib.mkOption { type = lib.types.int; };
35 refresh = lib.mkOption {
36 type = lib.types.nullOr lib.types.float;
37 default = null;
38 };
39 };
40 }
41 );
42 default = null;
Skyler Grey69a999e2024-05-23 00:09:10 +000043 };
Skyler Grey035c8d12024-05-26 21:23:33 +000044 position = lib.mkOption {
45 type = lib.types.nullOr (
46 lib.types.submodule {
47 options = {
48 x = lib.mkOption { type = lib.types.int; };
49 y = lib.mkOption { type = lib.types.int; };
50 };
51 }
52 );
53 default = null;
54 };
55 scale = lib.mkOption {
56 type = lib.types.float;
57 default = 1.0;
58 };
59 transform = {
60 flipped = lib.mkOption {
61 type = lib.types.bool;
62 default = false;
63 };
64 rotation = lib.mkOption {
65 type = lib.types.enum [
66 0
67 90
68 180
69 270
70 ];
71 default = 0;
72 };
73 };
74 variable-refresh-rate = lib.mkEnableOption "Enable Variable Refresh Rate (AMD FreeSync / Nvidia G-Sync)";
Skyler Grey69a999e2024-05-23 00:09:10 +000075 };
Skyler Grey035c8d12024-05-26 21:23:33 +000076 }
77 );
Skyler Grey69a999e2024-05-23 00:09:10 +000078 description = "Atribute set of monitors";
79 default = { };
80 };
Samuel Shuert35d5f652024-07-01 13:09:28 -040081 startupCommands = lib.mkOption {
82 type = lib.types.listOf (lib.types.submodule {
83 options = {
84 command = lib.mkOption {
85 type = lib.types.listOf lib.types.str;
86 description = "Command to run";
87 };
88 };
89 });
90 description = "List of commands to run at startup";
91 default = [ ];
92 };
Skyler Grey69a999e2024-05-23 00:09:10 +000093 };
94
95 config = lib.mkIf config.chimera.niri.enable {
96 chimera.wayland.enable = true;
97
Skyler Grey035c8d12024-05-26 21:23:33 +000098 programs.bash.profileExtra = lib.mkIf config.chimera.shell.bash.enable (
99 lib.mkBefore ''
100 if [ -z $WAYLAND_DISPLAY ] && [ "$(tty)" = "/dev/tty1" ]; then
101 exec ${pkgs.systemd}/bin/systemd-cat -t niri ${pkgs.dbus}/bin/dbus-run-session ${config.programs.niri.package}/bin/niri --session
102 fi
103 ''
104 );
Skyler Grey69a999e2024-05-23 00:09:10 +0000105
Skyler Grey035c8d12024-05-26 21:23:33 +0000106 programs.zsh.profileExtra = lib.mkIf config.chimera.shell.zsh.enable (
107 lib.mkBefore ''
108 if [ -z $WAYLAND_DISPLAY ] && [ "$(tty)" = "/dev/tty1" ]; then
Samuel Shuert7f9aba12024-09-15 00:10:13 -0400109 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 +0000110 fi
111 ''
112 );
Skyler Grey69a999e2024-05-23 00:09:10 +0000113
Skyler Grey035c8d12024-05-26 21:23:33 +0000114 programs.niri =
115 let
116 mod = "Super";
117 mod1 = "Alt";
118 terminal = "${pkgs.kitty}/bin/kitty";
119 menu = (
120 if config.chimera.runner.anyrun.enable then
121 "${inputs.anyrun.packages.${system}.anyrun}/bin/anyrun"
122 else
123 ""
124 );
Skyler Grey69a999e2024-05-23 00:09:10 +0000125
Skyler Grey035c8d12024-05-26 21:23:33 +0000126 lock = ''${pkgs.swaylock}/bin/swaylock -i ${config.chimera.theme.wallpaper} -s fill'';
127 in
128 {
129 enable = true;
130 package = pkgs.niri-stable;
131 settings = {
132 environment = {
133 NIXOS_OZONE_WL = "1";
134 DISPLAY = lib.mkIf config.chimera.niri.xwayland.enable ":0";
Skyler Grey69a999e2024-05-23 00:09:10 +0000135 };
Skyler Grey035c8d12024-05-26 21:23:33 +0000136
137 input.keyboard = {
138 track-layout = "window";
139 repeat-delay = 200;
140 repeat-rate = 25;
141 xkb = {
142 layout = config.chimera.input.keyboard.layout;
143 variant = config.chimera.input.keyboard.variant;
Samuel Shuert291d96b2024-10-14 14:45:24 -0400144 options = lib.mkIf (config.chimera.input.keyboard.appleMagic) "apple:alupckeys";
Skyler Grey035c8d12024-05-26 21:23:33 +0000145 };
146 };
Skyler Grey69a999e2024-05-23 00:09:10 +0000147
148 input.mouse.natural-scroll = config.chimera.input.mouse.scrolling.natural;
149 input.touchpad.natural-scroll = config.chimera.input.touchpad.scrolling.natural;
150
151 input.warp-mouse-to-focus = true;
Skyler Grey035c8d12024-05-26 21:23:33 +0000152 input.focus-follows-mouse = {
153 enable = true;
154 max-scroll-amount = "0%";
155 };
Skyler Grey69a999e2024-05-23 00:09:10 +0000156
157 input.power-key-handling.enable = false;
158
159 binds = let
160 inherit (config.lib.niri) actions;
161
162 generateWorkspaceBindings = workspaceNumber: {
Samuel Shuert291d96b2024-10-14 14:45:24 -0400163 "${mod}+${builtins.toString (lib.mod workspaceNumber 10)}".action.focus-workspace = [workspaceNumber];
164 "${mod}+Shift+${builtins.toString (lib.mod workspaceNumber 10)}".action.move-column-to-workspace = [workspaceNumber];
Skyler Grey69a999e2024-05-23 00:09:10 +0000165 };
166 joinAttrsetList = listOfAttrsets: lib.fold (a: b: a // b) {} listOfAttrsets;
167 in { # General Keybinds
Samuel Shuert291d96b2024-10-14 14:45:24 -0400168 "${mod}+Q".action.close-window = [];
169 "${mod}+Shift+Q".action.quit = [];
170 "${mod}+Return".action.spawn = "${terminal}";
171 "${mod}+L".action.spawn = ["sh" "-c" "${config.programs.niri.package}/bin/niri msg action do-screen-transition && ${lock}"];
172 "${mod}+P".action.power-off-monitors = [];
Skyler Grey69a999e2024-05-23 00:09:10 +0000173
Samuel Shuert291d96b2024-10-14 14:45:24 -0400174 "${mod}+R".action.screenshot = [];
175 "${mod}+Ctrl+R".action.screenshot-screen = [];
176 "${mod}+Shift+R".action.screenshot-window = [];
177 "Print".action.screenshot = [];
178 "Ctrl+Print".action.screenshot-screen = [];
179 "Shift+Print".action.screenshot-window = [];
Skyler Grey69a999e2024-05-23 00:09:10 +0000180
Samuel Shuert291d96b2024-10-14 14:45:24 -0400181 "${mod}+Alt+R".action.spawn = ["sh" "-c" ''([ -d Videos ] || mkdir Videos) && ${nixpkgs-stable.legacyPackages.${system}.wl-screenrec}/bin/wl-screenrec --geometry "$(${pkgs.slurp}/bin/slurp)" --filename "Videos/$(date +'%Y-%m-%d-%H-%M-%S').mp4"''];
182 "${mod}+Alt+Shift+R".action.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"];
Samuel Shuert14af78c2024-10-02 16:34:40 -0400183
Samuel Shuert291d96b2024-10-14 14:45:24 -0400184 "${mod}+Space".action.switch-layout = ["next"];
185 "${mod}+Shift+Space".action.switch-layout = ["prev"];
Skyler Grey69a999e2024-05-23 00:09:10 +0000186
Samuel Shuert291d96b2024-10-14 14:45:24 -0400187 "${mod}+D" = lib.mkIf config.chimera.runner.enable { action.spawn = "${menu}"; };
Skyler Grey69a999e2024-05-23 00:09:10 +0000188 "Alt+Space" = lib.mkIf (
189 config.chimera.runner.enable
190 && config.chimera.input.keybinds.alternativeSearch.enable
Samuel Shuert291d96b2024-10-14 14:45:24 -0400191 ) { action.spawn = "${menu}"; };
192 "${mod}+Shift+Slash".action.show-hotkey-overlay = [];
Skyler Grey69a999e2024-05-23 00:09:10 +0000193 } // ( # Workspace Keybinds
194 lib.pipe (lib.range 1 10) [
195 (map generateWorkspaceBindings)
196 joinAttrsetList
197 ]
198 ) // ( # Window Manipulation Bindings
199 {
Samuel Shuert291d96b2024-10-14 14:45:24 -0400200 "${mod}+BracketLeft".action.consume-or-expel-window-left = [];
201 "${mod}+BracketRight".action.consume-or-expel-window-right = [];
202 "${mod}+Shift+BracketLeft".action.consume-window-into-column = [];
203 "${mod}+Shift+BracketRight".action.expel-window-from-column = [];
204 "${mod}+Slash".action.switch-preset-column-width = [];
205 "${mod}+${mod1}+F".action.fullscreen-window = [];
Skyler Grey69a999e2024-05-23 00:09:10 +0000206
207 # Focus
Samuel Shuert291d96b2024-10-14 14:45:24 -0400208 "${mod}+Up".action.focus-window-or-workspace-up = [];
209 "${mod}+Down".action.focus-window-or-workspace-down = [];
Skyler Grey69a999e2024-05-23 00:09:10 +0000210
211 # Non Jump Movement
Samuel Shuert291d96b2024-10-14 14:45:24 -0400212 "${mod}+Shift+Up".action.move-window-up-or-to-workspace-up = [];
213 "${mod}+Shift+Down".action.move-window-down-or-to-workspace-down = [];
214 "${mod}+Shift+Left".action.consume-or-expel-window-left = [];
215 "${mod}+Shift+Right".action.consume-or-expel-window-right = [];
Skyler Grey69a999e2024-05-23 00:09:10 +0000216
217 # To Monitor
Samuel Shuert291d96b2024-10-14 14:45:24 -0400218 "${mod}+Shift+Ctrl+Up".action.move-window-to-monitor-up = [];
219 "${mod}+Shift+Ctrl+Down".action.move-window-to-monitor-down = [];
220 "${mod}+Shift+Ctrl+Left".action.move-window-to-monitor-left = [];
221 "${mod}+Shift+Ctrl+Right".action.move-window-to-monitor-right = [];
Skyler Grey69a999e2024-05-23 00:09:10 +0000222
223 # To Workspace
Samuel Shuert291d96b2024-10-14 14:45:24 -0400224 "${mod}+Ctrl+Up".action.move-window-to-workspace-up = [];
225 "${mod}+Ctrl+Down".action.move-window-to-workspace-down = [];
Skyler Grey69a999e2024-05-23 00:09:10 +0000226
227 # Sizing
Samuel Shuert291d96b2024-10-14 14:45:24 -0400228 "${mod}+Equal".action.set-window-height = ["+5%"];
229 "${mod}+Minus".action.set-window-height = ["-5%"];
Skyler Grey69a999e2024-05-23 00:09:10 +0000230 }) // ( # Column Manipulation Bindings
231 {
232 # Focus
Samuel Shuert291d96b2024-10-14 14:45:24 -0400233 "${mod}+Left".action.focus-column-left = [];
234 "${mod}+Right".action.focus-column-right = [];
235 "${mod}+${mod1}+C".action.center-column = [];
236 "${mod}+F".action.maximize-column = [];
Skyler Grey69a999e2024-05-23 00:09:10 +0000237
238 # Non Monitor Movement
Samuel Shuert291d96b2024-10-14 14:45:24 -0400239 "${mod}+${mod1}+Shift+Up".action.move-column-to-workspace-up = [];
240 "${mod}+${mod1}+Shift+Down".action.move-column-to-workspace-down = [];
241 "${mod}+${mod1}+Shift+Left".action.move-column-left = [];
242 "${mod}+${mod1}+Shift+Right".action.move-column-right = [];
Skyler Grey69a999e2024-05-23 00:09:10 +0000243
244 # To Monitor
Samuel Shuert291d96b2024-10-14 14:45:24 -0400245 "${mod}+${mod1}+Shift+Ctrl+Up".action.move-column-to-monitor-up = [];
246 "${mod}+${mod1}+Shift+Ctrl+Down".action.move-column-to-monitor-down = [];
247 "${mod}+${mod1}+Shift+Ctrl+Left".action.move-column-to-monitor-left = [];
248 "${mod}+${mod1}+Shift+Ctrl+Right".action.move-column-to-monitor-right = [];
Skyler Grey69a999e2024-05-23 00:09:10 +0000249
250 # Sizing
Samuel Shuert291d96b2024-10-14 14:45:24 -0400251 "${mod}+${mod1}+Equal".action.set-column-width = ["+5%"];
252 "${mod}+${mod1}+Minus".action.set-column-width = ["-5%"];
Skyler Grey69a999e2024-05-23 00:09:10 +0000253 }) // ( # Workspace Manipulation Bindings
254 {
255 # Focus
Samuel Shuert291d96b2024-10-14 14:45:24 -0400256 "${mod}+Page_Up".action.focus-workspace-up = [];
257 "${mod}+Page_Down".action.focus-workspace-down = [];
Skyler Grey69a999e2024-05-23 00:09:10 +0000258
259 # Within Itself
Samuel Shuert291d96b2024-10-14 14:45:24 -0400260 "${mod}+Shift+Page_Up".action.move-workspace-up = [];
261 "${mod}+Shift+Page_Down".action.move-workspace-down = [];
Skyler Grey69a999e2024-05-23 00:09:10 +0000262
263 # To Monitor
Samuel Shuert291d96b2024-10-14 14:45:24 -0400264 "${mod}+Shift+Ctrl+Page_Up".action.move-workspace-to-monitor-up = [];
265 "${mod}+Shift+Ctrl+Page_Down".action.move-workspace-to-monitor-down = [];
266 "${mod}+Shift+Ctrl+Home".action.move-workspace-to-monitor-left = [];
267 "${mod}+Shift+Ctrl+End".action.move-workspace-to-monitor-right = [];
Skyler Grey69a999e2024-05-23 00:09:10 +0000268 }) // { # Audio
269 "XF86AudioRaiseVolume" = {
270 allow-when-locked = true;
Samuel Shuert291d96b2024-10-14 14:45:24 -0400271 action.spawn = ["${pkgs.wireplumber}/bin/wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.05+"];
Skyler Grey69a999e2024-05-23 00:09:10 +0000272 };
273 "XF86AudioLowerVolume" = {
274 allow-when-locked = true;
Samuel Shuert291d96b2024-10-14 14:45:24 -0400275 action.spawn = ["${pkgs.wireplumber}/bin/wpctl" "set-volume" "@DEFAULT_AUDIO_SINK@" "0.05-"];
Skyler Grey69a999e2024-05-23 00:09:10 +0000276 };
277 "XF86AudioMute" = {
278 allow-when-locked = true;
Samuel Shuert291d96b2024-10-14 14:45:24 -0400279 action.spawn = ["${pkgs.wireplumber}/bin/wpctl" "set-mute" "@DEFAULT_AUDIO_SINK@" "toggle"];
Skyler Grey69a999e2024-05-23 00:09:10 +0000280 };
281 "XF86AudioMicMute" = {
282 allow-when-locked = true;
Samuel Shuert291d96b2024-10-14 14:45:24 -0400283 action.spawn = ["${pkgs.wireplumber}/bin/wpctl" "set-mute" "@DEFAULT_AUDIO_SOURCE@" "toggle"];
Skyler Grey69a999e2024-05-23 00:09:10 +0000284 };
285 };
286
287 outputs = config.chimera.niri.monitors;
288
289 cursor = {
290 size = config.chimera.theme.cursor.size;
291 theme = config.chimera.theme.cursor.name;
292 };
293
294 layout = {
295 gaps = 16;
296
297 center-focused-column = "on-overflow";
298
299 preset-column-widths = [
300 { proportion = 1. / 4.; }
301 { proportion = 1. / 3.; }
302 { proportion = 1. / 2.; }
303 { proportion = 2. / 3.; }
Samuel Shuert4d5c5fb2024-06-09 09:39:11 -0400304 { proportion = 9. / 10.; }
Skyler Grey69a999e2024-05-23 00:09:10 +0000305 ]; # TODO: clicks to PR a docs update for niri-flake
306 };
307
308 prefer-no-csd = true; # No "client-side-decorations" (i.e. client-side window open/close buttons)
309 hotkey-overlay.skip-at-startup = true;
310 screenshot-path = null;
311
Samuel Shuert291d96b2024-10-14 14:45:24 -0400312 spawn-at-startup = if config.chimera.waybar.enable then [{
Skyler Grey69a999e2024-05-23 00:09:10 +0000313 command = [ "${pkgs.waybar}/bin/waybar" ];
Samuel Shuert291d96b2024-10-14 14:45:24 -0400314 }] else [] ++ [
Skyler Grey69a999e2024-05-23 00:09:10 +0000315 {
316 command = [ "${pkgs.swaybg}/bin/swaybg" "-i" "${config.chimera.theme.wallpaper}" "-m" "fill" ];
317 }
Skyler Grey035c8d12024-05-26 21:23:33 +0000318 {
Skyler Grey44fbdc12024-09-17 21:07:18 +0000319 command = [ "${pkgs.xwayland-satellite-unstable}/bin/xwayland-satellite" ]; # todo: use xwayland-satellite-nixpkgs in the future...
Skyler Grey035c8d12024-05-26 21:23:33 +0000320 }
Samuel Shuert35d5f652024-07-01 13:09:28 -0400321 ] ++ config.chimera.niri.startupCommands;
Skyler Grey69a999e2024-05-23 00:09:10 +0000322 };
323 };
324 };
325}