{ lib, config, pkgs, ... }: let inherit (lib) mkEnableOption mkIf concatMapAttrs map range listToAttrs getExe ; inherit (lib.marleyos) enabled disabled; cfg = config.marleyos.xorg.i3; isGenericLinux = config.targets.genericLinux.enable; in { options.marleyos.xorg.i3.enable = mkEnableOption "i3"; config = mkIf cfg.enable { marleyos = { programs.rofi = enabled; services = { dunst = enabled; picom = enabled; polybar = enabled; # broken on non-nixOS screen-locker = if isGenericLinux then disabled else enabled; }; }; home.packages = with pkgs; [ networkmanagerapplet feh ]; xsession.windowManager.i3 = { enable = true; package = config.lib.nixGL.wrap pkgs.i3; extraConfig = "tiling_drag modifier titlebar"; config = let directions = { left = "h"; down = "j"; up = "k"; right = "l"; }; in { focus.followMouse = false; window.border = 0; floating.border = 0; window.titlebar = false; floating.titlebar = false; gaps = { smartBorders = "no_gaps"; inner = 10; top = 50; }; bars = [ ]; # Startup - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - startup = with pkgs; [ { command = "${getExe feh} --no-fehbg --bg-fill ${./bg.jpg}"; } { command = "${getExe networkmanagerapplet}"; } ]; # Keybindings - - - - - - - - - - - - - - - - - - - - - - - - - - - - modifier = "Mod4"; keybindings = let mod = config.xsession.windowManager.i3.config.modifier; workspaces = range 1 10; getI = i: if i == 10 then "0" else toString i; inherit (config.xdg) configHome; isGenericLinux = config.targets.genericLinux.enable; in { "${mod}+Shift+c" = "reload"; "${mod}+Shift+r" = "restart"; "${mod}+Shift+e" = "exec i3-nagbar -t warning -m 'Do you want to exit i3?' -b 'Yes' 'i3-msg exit'"; "${mod}+e" = "layout toggle split"; "${mod}+Control+h" = "split -"; "${mod}+Control+v" = "split |"; "${mod}+f" = "fullscreen toggle"; "${mod}+Shift+space" = "floating toggle"; "${mod}+Control+r" = "mode resize"; "${mod}+q" = "kill"; "${mod}+r" = "exec ${configHome}/rofi/launchers/type-1/launcher.sh"; "${mod}+Return" = "exec ${if isGenericLinux then "wezterm" else "${pkgs.wezterm}/bin/wezterm"}"; } # PulseAudio Volume - - - - - - - - - - - - - - - - - - - - - - - - // (concatMapAttrs (key: cmd: { "${key}" = "exec --no-startup-id pactl ${cmd} && killall -SIGUSR1 i3status"; }) { XF86AudioRaiseVolume = "set-sink-volume @DEFAULT_SINK@ +10%"; XF86AudioLowerVolume = "set-sink-volume @DEFAULT_SINK@ -10%"; XF86AudioMute = "set-sink-mute @DEFAULT_SINK@ toggle"; XF86AudioMicMute = "set-source-mute @DEFAULT_SOURCE@ toggle"; } ) # Focus & Movement - - - - - - - - - - - - - - - - - - - - - - - - - // (concatMapAttrs (direction: key: { "${mod}+${key}" = "focus ${direction}"; "${mod}+Shift+${key}" = "move ${direction}"; }) directions) # Switch Workspaces - - - - - - - - - - - - - - - - - - - - - - - - - // (listToAttrs ( (map (i: { name = "${mod}+${getI i}"; value = "workspace number ${toString i}"; })) workspaces )) # Move Windows Between Workspaces - - - - - - - - - - - - - - - - - - // (listToAttrs ( (map (i: { name = "${mod}+Shift+${getI i}"; value = "move container to workspace number ${toString i}"; })) workspaces )); # Resize Windows - - - - - - - - - - - - - - - - - - - - - - - - - - - modes.resize = let mod = config.xsession.windowManager.i3.config.modifier; in { Return = "mode default"; Escape = "mode default"; "${mod}+Control+r" = "mode default"; } // (concatMapAttrs (key: action: { "${key}" = "resize ${action} 10 px or 10 ppt"; }) rec { Left = "shrink width"; Down = "shrink height"; Up = "grow height"; Right = "grow width"; "${directions.left}" = Left; "${directions.down}" = Down; "${directions.up}" = Up; "${directions.right}" = Right; } ); }; }; }; }