From e9a8d16ecef24d9031b95c34af352359b7a4d95b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Geoffrey=20=E2=80=9CFrogeye=E2=80=9D=20Preud=27homme?= Date: Sat, 13 Jan 2024 22:58:45 +0100 Subject: [PATCH] i3: Add config to easily create modes With their associated "switch-to" keybinding. --- hm/desktop/i3.nix | 193 ++++++++++++++++++++++++++++------------------ 1 file changed, 117 insertions(+), 76 deletions(-) diff --git a/hm/desktop/i3.nix b/hm/desktop/i3.nix index 15f13f7..4633fc8 100644 --- a/hm/desktop/i3.nix +++ b/hm/desktop/i3.nix @@ -10,14 +10,11 @@ let '' }"; - # MODES - mode_system = "[L] Vérouillage [E] Déconnexion [S] Veille [H] Hibernation [R] Redémarrage [P] Extinction"; - mode_resize = "Resize"; - mode_pres_main = "Presentation (main display)"; - mode_pres_sec = "Presentation (secondary display)"; - mode_screen = "Screen setup [A] Auto [L] Load [S] Save [R] Remove [D] Default"; - mode_temp = "Temperature [R] Red [D] Dust storm [C] Campfire [O] Normal [A] All nighter [B] Blue"; + # MISC + mod = config.xsession.windowManager.i3.config.modifier; fonts = config.stylix.fonts; + rofi = "exec --no-startup-id ${config.programs.rofi.package}/bin/rofi"; + modes = config.frogeye.desktop.i3.bindmodes; in { config = lib.mkIf config.xsession.windowManager.i3.enable { @@ -40,10 +37,6 @@ in }; focus.followMouse = false; keybindings = - let - mod = config.xsession.windowManager.i3.config.modifier; - rofi = "exec --no-startup-id ${config.programs.rofi.package}/bin/rofi"; - in { # Compatibility layer for people coming from other backgrounds "Mod1+Tab" = "${rofi} -modi window -show window"; @@ -157,71 +150,13 @@ in "${mod}+Shift+c" = "reload"; "${mod}+Shift+r" = "restart"; "${mod}+Shift+e" = "exit"; - # Modes - "${mod}+Escape" = "mode ${mode_system}"; - "${mod}+r" = "mode ${mode_resize}"; - "${mod}+Shift+p" = "mode ${mode_pres_main}"; - "${mod}+t" = "mode ${mode_screen}"; - "${mod}+y" = "mode ${mode_temp}"; - }; - # TOOD Config option so we don't have to separate name and binding - modes = let return_bindings = { - "Return" = "mode default"; - "Escape" = "mode default"; - }; in - { - "${mode_system}" = { - "l" = "exec --no-startup-id exec xlock, mode default"; - "e" = "exit, mode default"; - "s" = "exec --no-startup-id exec xlock & ${pkgs.systemd}/bin/systemctl suspend --check-inhibitors=no, mode default"; - "h" = "exec --no-startup-id exec xlock & ${pkgs.systemd}/bin/systemctl hibernate, mode default"; - "r" = "exec --no-startup-id ${pkgs.systemd}/bin/systemctl reboot, mode default"; - "p" = "exec --no-startup-id ${pkgs.systemd}/bin/systemctl poweroff -i, mode default"; - } // return_bindings; - "${mode_resize}" = { - "h" = "resize shrink width 10 px or 10 ppt; ${focus}"; - "j" = "resize grow height 10 px or 10 ppt; ${focus}"; - "k" = "resize shrink height 10 px or 10 ppt; ${focus}"; - "l" = "resize grow width 10 px or 10 ppt; ${focus}"; - } // return_bindings; - "${mode_pres_main}" = { - "b" = "workspace 3, workspace 4, mode ${mode_pres_sec}"; - "q" = "mode default"; - "Return" = "mode default"; - }; - "${mode_pres_sec}" = { - "b" = "workspace 1, workspace 2, mode ${mode_pres_main}"; - "q" = "mode default"; - "Return" = "mode default"; - }; - "${mode_screen}" = - let - builtin_configs = [ "off" "common" "clone-largest" "horizontal" "vertical" "horizontal-reverse" "vertical-reverse" ]; - autorandrmenu = { title, option, builtin ? false }: pkgs.writeShellScript "autorandrmenu" - '' - shopt -s nullglob globstar - profiles="${if builtin then lib.strings.concatLines builtin_configs else ""}$(${pkgs.autorandr}/bin/autorandr | ${pkgs.gawk}/bin/awk '{ print $1 }')" - profile="$(echo "$profiles" | ${config.programs.rofi.package}/bin/rofi -dmenu -p "${title}")" - [[ -n "$profile" ]] || exit - ${pkgs.autorandr}/bin/autorandr ${option} "$profile" - ''; - in - { - "a" = "exec ${pkgs.autorandr}/bin/autorandr --change --force, mode default"; - "l" = "exec ${autorandrmenu {title="Load profile"; option="--load"; builtin = true;}}, mode default"; - "s" = "exec ${autorandrmenu {title="Save profile"; option="--save";}}, mode default"; - "r" = "exec ${autorandrmenu {title="Remove profile"; option="--remove";}}, mode default"; - "d" = "exec ${autorandrmenu {title="Default profile"; option="--default"; builtin = true;}}, mode default"; - } // return_bindings; - "${mode_temp}" = { - "r" = "exec ${pkgs.sct}/bin/sct 1000"; - "d" = "exec ${pkgs.sct}/bin/sct 2000"; - "c" = "exec ${pkgs.sct}/bin/sct 4500"; - "o" = "exec ${pkgs.sct}/bin/sct"; - "a" = "exec ${pkgs.sct}/bin/sct 8000"; - "b" = "exec ${pkgs.sct}/bin/sct 10000"; - } // return_bindings; - }; + } // lib.mapAttrs' (k: v: lib.nameValuePair v.enter "mode ${v.name}") modes; + modes = lib.mapAttrs' + (k: v: lib.nameValuePair v.name (v.bindings // lib.optionalAttrs v.return_bindings { + "Return" = "mode default"; + "Escape" = "mode default"; + })) + modes; window = { hideEdgeBorders = "both"; titlebar = false; # So that single-container screens are basically almost fullscreen @@ -261,5 +196,111 @@ in in forEachWorkspace ({ w, workspace }: { output = builtins.elemAt x11_screens (lib.mod w (builtins.length x11_screens)); workspace = workspace.name; }); }; + frogeye.desktop.i3.bindmodes = + let + mode_pres_main = "Presentation (main display)"; + mode_pres_sec = "Presentation (secondary display)"; + in + { + "Resize" = { + bindings = { + "h" = "resize shrink width 10 px or 10 ppt; ${focus}"; + "j" = "resize grow height 10 px or 10 ppt; ${focus}"; + "k" = "resize shrink height 10 px or 10 ppt; ${focus}"; + "l" = "resize grow width 10 px or 10 ppt; ${focus}"; + }; + mod_enter = "r"; + }; + "[L] Vérouillage [E] Déconnexion [S] Veille [H] Hibernation [R] Redémarrage [P] Extinction" = { + bindings = { + "l" = "exec --no-startup-id exec xlock, mode default"; + "e" = "exit, mode default"; + "s" = "exec --no-startup-id exec xlock & ${pkgs.systemd}/bin/systemctl suspend --check-inhibitors=no, mode default"; + "h" = "exec --no-startup-id exec xlock & ${pkgs.systemd}/bin/systemctl hibernate, mode default"; + "r" = "exec --no-startup-id ${pkgs.systemd}/bin/systemctl reboot, mode default"; + "p" = "exec --no-startup-id ${pkgs.systemd}/bin/systemctl poweroff -i, mode default"; + }; + mod_enter = "Escape"; + }; + "${mode_pres_main}" = { + mod_enter = "Shift+p"; + bindings = { + "b" = "workspace 3, workspace 4, mode ${mode_pres_sec}"; + "q" = "mode default"; + "Return" = "mode default"; + }; + return_bindings = false; + }; + "${mode_pres_sec}" = { + mod_enter = "Shift+p+2"; + bindings = { + "b" = "workspace 1, workspace 2, mode ${mode_pres_main}"; + "q" = "mode default"; + "Return" = "mode default"; + }; + return_bindings = false; + }; + "Screen setup [A] Auto [L] Load [S] Save [R] Remove [D] Default" = + let + builtin_configs = [ "off" "common" "clone-largest" "horizontal" "vertical" "horizontal-reverse" "vertical-reverse" ]; + autorandrmenu = { title, option, builtin ? false }: pkgs.writeShellScript "autorandrmenu" + '' + shopt -s nullglob globstar + profiles="${if builtin then lib.strings.concatLines builtin_configs else ""}$(${pkgs.autorandr}/bin/autorandr | ${pkgs.gawk}/bin/awk '{ print $1 }')" + profile="$(echo "$profiles" | ${config.programs.rofi.package}/bin/rofi -dmenu -p "${title}")" + [[ -n "$profile" ]] || exit + ${pkgs.autorandr}/bin/autorandr ${option} "$profile" + ''; + in + { + bindings = { + "a" = "exec ${pkgs.autorandr}/bin/autorandr --change --force, mode default"; + "l" = "exec ${autorandrmenu {title="Load profile"; option="--load"; builtin = true;}}, mode default"; + "s" = "exec ${autorandrmenu {title="Save profile"; option="--save";}}, mode default"; + "r" = "exec ${autorandrmenu {title="Remove profile"; option="--remove";}}, mode default"; + "d" = "exec ${autorandrmenu {title="Default profile"; option="--default"; builtin = true;}}, mode default"; + }; + mod_enter = "t"; + }; + "Temperature [R] Red [D] Dust storm [C] Campfire [O] Normal [A] All nighter [B] Blue" = { + bindings = { + "r" = "exec ${pkgs.sct}/bin/sct 1000"; + "d" = "exec ${pkgs.sct}/bin/sct 2000"; + "c" = "exec ${pkgs.sct}/bin/sct 4500"; + "o" = "exec ${pkgs.sct}/bin/sct"; + "a" = "exec ${pkgs.sct}/bin/sct 8000"; + "b" = "exec ${pkgs.sct}/bin/sct 10000"; + }; + mod_enter = "y"; + }; + }; + }; + options = { + frogeye.desktop.i3.bindmodes = lib.mkOption { + default = { }; + type = lib.types.attrsOf (lib.types.submodule ({ config, name, ... }: { + options = { + name = lib.mkOption { + type = lib.types.str; + default = name; + }; + bindings = lib.mkOption { + type = lib.types.attrsOf lib.types.str; + default = { }; + }; + enter = lib.mkOption { + type = lib.types.str; + default = "${mod}+${config.mod_enter}"; + }; + mod_enter = lib.mkOption { + type = lib.types.str; + }; + return_bindings = lib.mkOption { + type = lib.types.bool; + default = true; + }; + }; + })); + }; }; }