{ config, lib, pkgs, ... }: let ccfg = import ../../config.nix; cfg_path = [ ccfg.custom_config_key "desktopEnvironment" "i3" ]; cfg = lib.attrsets.getAttrFromPath cfg_path config; in { config = lib.mkIf cfg.enable { programs.i3 = { enable = true; package = pkgs.i3; # i3 window manager windowManager.command = "i3"; extraConfig = lib.mkForce ('' # Generated from sway configuration set $mod Mod4 set $term ${cfg.terminalCommand} set $menu rofi -show drun # Input # Caps lock as escape is handled system-wide in NixOS # Focus bindsym $mod+h focus left bindsym $mod+l focus right bindsym $mod+k focus up bindsym $mod+j focus down # Apps bindsym $mod+Return exec $term bindsym $mod+space exec ${cfg.menu} bindsym $mod+q kill bindsym $mod+Shift+Escape exit bindsym $mod+Shift+q exec i3lock bindsym $mod+f floating toggle # Workspaces set $ws1 "1: " set $ws2 "2: " set $ws3 "3: " set $ws4 "4: " set $ws5 "5: " set $ws6 "6" set $ws7 "7" set $ws8 "8" set $ws9 "9" set $ws10 "10" bindsym $mod+1 workspace $ws1 bindsym $mod+n workspace $ws1 bindsym $mod+2 workspace $ws2 bindsym $mod+m workspace $ws2 bindsym $mod+3 workspace $ws3 bindsym $mod+comma workspace $ws3 bindsym $mod+4 workspace $ws4 bindsym $mod+period workspace $ws4 bindsym $mod+5 workspace $ws5 bindsym $mod+slash workspace $ws5 bindsym $mod+6 workspace $ws6 bindsym $mod+7 workspace $ws7 bindsym $mod+8 workspace $ws8 bindsym $mod+9 workspace $ws9 bindsym $mod+0 workspace $ws10 # Move windows bindsym $mod+Shift+h move left bindsym $mod+Shift+l move right bindsym $mod+Shift+k move up bindsym $mod+Shift+j move down bindsym $mod+Shift+1 move container to workspace $ws1 bindsym $mod+Shift+n move container to workspace $ws1 bindsym $mod+Shift+2 move container to workspace $ws2 bindsym $mod+Shift+m move container to workspace $ws2 bindsym $mod+Shift+3 move container to workspace $ws3 bindsym $mod+Shift+comma move container to workspace $ws3 bindsym $mod+Shift+4 move container to workspace $ws4 bindsym $mod+Shift+period move container to workspace $ws4 bindsym $mod+Shift+5 move container to workspace $ws5 bindsym $mod+Shift+slash move container to workspace $ws5 bindsym $mod+Shift+6 move container to workspace $ws6 bindsym $mod+Shift+7 move container to workspace $ws7 bindsym $mod+Shift+8 move container to workspace $ws8 bindsym $mod+Shift+9 move container to workspace $ws9 bindsym $mod+Shift+0 move container to workspace $ws10 # Mouse floating_modifier $mod # Screenshot (uses grim/slurp on Wayland; on X11 use maim) bindsym Print exec --no-startup-id maim -s | xclip -selection clipboard -t image/png # Startup exec --no-startup-id ${pkgs.bash}/bin/sh -c '~/.config/polybar/launch.sh' # gaps, borders handled by i3-gaps if available include ~/.config/i3/custom.conf '') ; }; home.file = { ".config/i3/config" = { text = builtins.toString (config.programs.i3.extraConfig); }; ".config/i3/custom.conf" = { text = let extra = cfg.extraOptions or {}; mkWorkspaceAssign = ws: out: "workspace \"${ws}\" output ${out}\n"; wsAssigns = if extra.workspaceOutputAssign == null then "" else lib.concatStringsSep "" (lib.map (v: mkWorkspaceAssign v.workspace v.output) extra.workspaceOutputAssign); startupLines = if extra.startup == null then "" else lib.concatStringsSep "" (lib.map (s: "exec --no-startup-id ${s.command}\n") extra.startup); in wsAssigns + startupLines; }; }; environment.systemPackages = with pkgs; [ i3 i3status polybar maim xclip i3lock i3-gaps ]; }; }