aboutsummaryrefslogtreecommitdiffstats
path: root/modules
diff options
context:
space:
mode:
authorArpit Chakladar <arpitchakladar+git@gmail.com>2026-07-25 11:50:05 +0530
committerArpit Chakladar <arpitchakladar+git@gmail.com>2026-07-25 11:50:05 +0530
commit892b62a3129a6ae30fa6b039e3f88d370d418319 (patch)
tree5a25ed4be60fd2a29548ec1ed65c9b831d2ef4b2 /modules
parent6621b1998e6f02772adb2df2fc19343691b086cf (diff)
downloadhome-manager-config-892b62a3129a6ae30fa6b039e3f88d370d418319.tar.gz
home-manager-config-892b62a3129a6ae30fa6b039e3f88d370d418319.zip
feat(hyprland): migrate config to Lua, fix API calls, switch to hyprpaper
- Set configType = "lua" for Hyprland 0.55+ Lua config format - Rewrite window rules to use hl.window_rule({...}) table API - Convert keybindings to hl.bind() with _args + mkLuaInline - Fix dispatchers: hl.dsp.focus (not window.focus), hl.dsp.focus({workspace=}) (not workspace.switch) - Replace swaybg with services.hyprpaper module for wallpaper - Fix border colors to use base07 (white) / base03 (grey) with rgba() format - Reduce default font size from 16 to 12
Diffstat (limited to 'modules')
-rw-r--r--modules/desktop/default.nix18
-rw-r--r--modules/desktop/hyprland/default.nix126
-rw-r--r--modules/desktop/hyprland/keybindings.nix147
-rw-r--r--modules/desktop/i3/default.nix103
-rw-r--r--modules/desktop/i3/keybindings.nix90
-rw-r--r--modules/desktop/xdg/default.nix25
-rw-r--r--modules/fonts/default.nix2
7 files changed, 294 insertions, 217 deletions
diff --git a/modules/desktop/default.nix b/modules/desktop/default.nix
index eb2eea6..a2fdfc8 100644
--- a/modules/desktop/default.nix
+++ b/modules/desktop/default.nix
@@ -1,4 +1,4 @@
-# Desktop - Desktop environment configuration (i3, GTK, polybar)
+# Desktop - Desktop environment configuration (i3/Hyprland, GTK, polybar)
{
lib,
config,
@@ -6,10 +6,10 @@
}:
{
imports = [
- ./i3
./gtk
./polybar
./xdg
+ ./hyprland
];
options.desktop = {
@@ -18,19 +18,5 @@
config = lib.mkIf config.desktop.enable {
xdg.enable = true;
- xsession.enable = true;
-
- home.file.".xinitrc" = {
- text = ''
- #!/usr/bin/env sh
-
- [ -f ~/.Xresources ] && xrdb -merge ~/.Xresources
- [ -f ~/.profile ] && . ~/.profile
- [ -f ~/.xsession ] && . ~/.xsession
-
- exec ${config.xsession.windowManager.i3.package}/bin/i3
- '';
- executable = true;
- };
};
}
diff --git a/modules/desktop/hyprland/default.nix b/modules/desktop/hyprland/default.nix
new file mode 100644
index 0000000..bd80157
--- /dev/null
+++ b/modules/desktop/hyprland/default.nix
@@ -0,0 +1,126 @@
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+let
+ toHyprColor = hex: "rgba(${lib.removePrefix "#" hex}ff)";
+in
+{
+ imports = [
+ ./keybindings.nix
+ ];
+
+ options.desktop.hyprland = {
+ enable = lib.mkEnableOption "Hyprland Wayland compositor";
+ };
+
+ config = lib.mkIf config.desktop.hyprland.enable {
+ wayland.windowManager.hyprland = {
+ enable = true;
+ configType = "lua";
+ xwayland.enable = true;
+ systemd.enable = true;
+
+ settings = {
+ mainMod = {
+ _var = "SUPER";
+ };
+
+ config = {
+ general = with config.scheme.withHashtag; {
+ gaps_in = 5;
+ gaps_out = 5;
+ border_size = 1;
+ col = {
+ active_border = {
+ colors = [ (toHyprColor base07) ];
+ angle = 45;
+ };
+ inactive_border = toHyprColor base03;
+ };
+ layout = "dwindle";
+ };
+
+ decoration = {
+ rounding = 0;
+ };
+
+ input = {
+ follow_mouse = 1;
+ kb_layout = "us";
+ };
+
+ dwindle = {
+ preserve_split = true;
+ };
+ };
+
+ window_rule = [
+ {
+ name = "float-file-explorer";
+ match.class = "^(file-explorer)$";
+ float = true;
+ }
+ {
+ name = "size-file-explorer";
+ match.class = "^(file-explorer)$";
+ size = "1280 720";
+ }
+ {
+ name = "center-file-explorer";
+ match.class = "^(file-explorer)$";
+ center = true;
+ }
+
+ {
+ name = "float-application-launcher";
+ match.class = "^(application-launcher)$";
+ float = true;
+ }
+ {
+ name = "size-application-launcher";
+ match.class = "^(application-launcher)$";
+ size = "800 600";
+ }
+ {
+ name = "center-application-launcher";
+ match.class = "^(application-launcher)$";
+ center = true;
+ }
+
+ {
+ name = "float-keybindings-viewer";
+ match.class = "^(keybindings-viewer)$";
+ float = true;
+ }
+ {
+ name = "size-keybindings-viewer";
+ match.class = "^(keybindings-viewer)$";
+ size = "1280 720";
+ }
+ {
+ name = "center-keybindings-viewer";
+ match.class = "^(keybindings-viewer)$";
+ center = true;
+ }
+ ];
+ };
+ };
+
+ services.hyprpaper = lib.mkIf config.media.feh.enable {
+ enable = true;
+ settings = {
+ preload = [ "${../../../assets/sapling.png}" ];
+ wallpaper = [ ",${../../../assets/sapling.png}" ];
+ };
+ };
+
+ home.packages = with pkgs; [
+ grim
+ slurp
+ wl-clipboard
+ ];
+ };
+}
diff --git a/modules/desktop/hyprland/keybindings.nix b/modules/desktop/hyprland/keybindings.nix
new file mode 100644
index 0000000..09ba822
--- /dev/null
+++ b/modules/desktop/hyprland/keybindings.nix
@@ -0,0 +1,147 @@
+{
+ config,
+ lib,
+ ...
+}:
+let
+ lua = lib.generators.mkLuaInline;
+
+ bind = key: dispatcher: {
+ _args = [
+ (lua "mainMod .. \" + ${key}\"")
+ (lua dispatcher)
+ ];
+ };
+
+ bindRawFlags = key: dispatcher: flags: {
+ _args = [
+ key
+ (lua dispatcher)
+ flags
+ ];
+ };
+
+ execLua = cmd: "hl.dsp.exec_cmd(\"${cmd}\")";
+
+ execLuaSingle = cmd: "hl.dsp.exec_cmd('${cmd}')";
+in
+{
+ config.wayland.windowManager.hyprland.settings.bind = lib.flatten [
+ # --- General Applications ---
+ (lib.optionals (config.terminal.fzf.enable && config.terminal.kitty.enable) [
+ (bind "R" (
+ execLua "${lib.getExe config.terminal.kitty.package} --class application-launcher -e ${lib.getExe config.scripts.fzf-launcher.package}"
+ ))
+ ])
+ (lib.optionals config.terminal.kitty.enable [
+ (bind "Return" (execLua "${lib.getExe config.terminal.kitty.package}"))
+ (bind "S" (
+ execLua "${lib.getExe config.terminal.kitty.package} --title 'Keybindings' --class keybindings-viewer -e ${lib.getExe config.scripts.i3-keybindings.package}"
+ ))
+ ])
+ (lib.optionals (config.terminal.kitty.enable && config.file-management.yazi.enable) [
+ (bind "F" (
+ execLua "${lib.getExe config.terminal.kitty.package} --class file-explorer --title 'Yazi' -e ${lib.getExe config.file-management.yazi.package}"
+ ))
+ ])
+ (bind "Q" "hl.dsp.window.close()")
+
+ # --- Media / Hardware Keys ---
+ (lib.optionals config.system.brightnessctl.enable [
+ (bindRawFlags "XF86MonBrightnessDown"
+ (execLuaSingle "${lib.getExe config.system.brightnessctl.package} set 5%-")
+ {
+ locked = true;
+ repeating = true;
+ }
+ )
+ (bindRawFlags "XF86MonBrightnessUp"
+ (execLuaSingle "${lib.getExe config.system.brightnessctl.package} set +5%")
+ {
+ locked = true;
+ repeating = true;
+ }
+ )
+ ])
+ (lib.optionals config.media.pamixer.enable [
+ (bindRawFlags "XF86AudioLowerVolume"
+ (execLuaSingle "${lib.getExe config.media.pamixer.package} --decrease 5")
+ {
+ locked = true;
+ repeating = true;
+ }
+ )
+ (bindRawFlags "XF86AudioRaiseVolume"
+ (execLuaSingle "${lib.getExe config.media.pamixer.package} --increase 5")
+ {
+ locked = true;
+ repeating = true;
+ }
+ )
+ (bindRawFlags "XF86AudioMute"
+ (execLuaSingle "${lib.getExe config.media.pamixer.package} --toggle-mute")
+ {
+ locked = true;
+ repeating = true;
+ }
+ )
+ ])
+ (lib.optionals config.media.playerctl.enable [
+ (bindRawFlags "XF86AudioPlay"
+ (execLuaSingle "${lib.getExe config.media.playerctl.package} play-pause")
+ {
+ locked = true;
+ repeating = true;
+ }
+ )
+ ])
+
+ # --- Window Management (Vim-style) ---
+ (bind "H" "hl.dsp.focus({ direction = \"l\" })")
+ (bind "J" "hl.dsp.focus({ direction = \"d\" })")
+ (bind "K" "hl.dsp.focus({ direction = \"u\" })")
+ (bind "L" "hl.dsp.focus({ direction = \"r\" })")
+
+ (bind "SHIFT + H" "hl.dsp.window.move({ direction = \"l\" })")
+ (bind "SHIFT + J" "hl.dsp.window.move({ direction = \"d\" })")
+ (bind "SHIFT + K" "hl.dsp.window.move({ direction = \"u\" })")
+ (bind "SHIFT + L" "hl.dsp.window.move({ direction = \"r\" })")
+
+ (bind "CTRL + H" "hl.dsp.window.resize({ x = -20, y = 0 })")
+ (bind "CTRL + J" "hl.dsp.window.resize({ x = 0, y = 20 })")
+ (bind "CTRL + K" "hl.dsp.window.resize({ x = 0, y = -20 })")
+ (bind "CTRL + L" "hl.dsp.window.resize({ x = 20, y = 0 })")
+
+ (bind "D" "hl.dsp.window.float({ action = \"toggle\" })")
+ (bind "M" "hl.dsp.window.fullscreen()")
+
+ # --- Workspaces ---
+ (bind "1" "hl.dsp.focus({ workspace = 1 })")
+ (bind "2" "hl.dsp.focus({ workspace = 2 })")
+ (bind "3" "hl.dsp.focus({ workspace = 3 })")
+ (bind "4" "hl.dsp.focus({ workspace = 4 })")
+ (bind "5" "hl.dsp.focus({ workspace = 5 })")
+ (bind "6" "hl.dsp.focus({ workspace = 6 })")
+ (bind "7" "hl.dsp.focus({ workspace = 7 })")
+ (bind "8" "hl.dsp.focus({ workspace = 8 })")
+ (bind "9" "hl.dsp.focus({ workspace = 9 })")
+ (bind "0" "hl.dsp.focus({ workspace = 10 })")
+
+ (bind "SHIFT + 1" "hl.dsp.window.move({ workspace = 1 })")
+ (bind "SHIFT + 2" "hl.dsp.window.move({ workspace = 2 })")
+ (bind "SHIFT + 3" "hl.dsp.window.move({ workspace = 3 })")
+ (bind "SHIFT + 4" "hl.dsp.window.move({ workspace = 4 })")
+ (bind "SHIFT + 5" "hl.dsp.window.move({ workspace = 5 })")
+ (bind "SHIFT + 6" "hl.dsp.window.move({ workspace = 6 })")
+ (bind "SHIFT + 7" "hl.dsp.window.move({ workspace = 7 })")
+ (bind "SHIFT + 8" "hl.dsp.window.move({ workspace = 8 })")
+ (bind "SHIFT + 9" "hl.dsp.window.move({ workspace = 9 })")
+ (bind "SHIFT + 0" "hl.dsp.window.move({ workspace = 10 })")
+
+ # --- Screenshots ---
+ (bind "P" (execLuaSingle "grim -g \"$(slurp)\" - | wl-copy"))
+ (bind "SHIFT + P" (
+ execLuaSingle "mkdir -p ~/Pictures/Screenshots && grim -g \"$(slurp)\" ~/Pictures/Screenshots/screenshot-$(date +%Y%m%d-%H%M%S).png"
+ ))
+ ];
+}
diff --git a/modules/desktop/i3/default.nix b/modules/desktop/i3/default.nix
deleted file mode 100644
index b3d0672..0000000
--- a/modules/desktop/i3/default.nix
+++ /dev/null
@@ -1,103 +0,0 @@
-# i3 - Window manager configuration (gaps, colors, startup, keybindings)
-{
- config,
- lib,
- pkgs,
- ...
-}:
-{
- config = lib.mkIf config.desktop.enable {
- xsession.windowManager.i3 = {
- enable = true;
- config = with config.scheme.withHashtag; {
- modifier = "Mod4"; # Super
-
- bars = [ ];
-
- gaps = {
- inner = 10;
- top = 50; # NOTE: Based on height of polybar
- outer = 0;
- };
-
- window = {
- border = 1;
- titlebar = false;
- };
-
- colors = {
- focused = {
- border = base03;
- background = base03;
- text = base07;
- indicator = base03;
- childBorder = base03;
- };
- focusedInactive = {
- border = base02;
- background = base02;
- text = base05;
- indicator = base02;
- childBorder = base02;
- };
- unfocused = {
- border = base02;
- background = base02;
- text = base05;
- indicator = base02;
- childBorder = base02;
- };
- };
-
- defaultWorkspace = "workspace number 1";
-
- window.commands = [
- {
- command = "floating enable, resize set 1280 720, move position center";
- criteria.class = "file-explorer";
- }
- {
- command = "floating enable, resize set 800 600, move position center";
- criteria.class = "application-launcher";
- }
- {
- command = "floating enable, resize set 1280 720, move position center";
- criteria.class = "keybindings-viewer";
- }
- ];
-
- focus.followMouse = true;
-
- startup = [
- {
- command = "xrandr -q | grep -w 'connected' | cut -d' ' -f1 | xargs -I{} i3-msg \"workspace 1 output {}\"";
- always = false;
- notification = false;
- }
- {
- command =
- if config.media.feh.enable then
- "${lib.getExe pkgs.feh} --bg-scale ${../../../assets/sapling.png}"
- else
- "xsetroot -solid \"${config.scheme.withHashtag.base00}\"";
- always = true;
- notification = false;
- }
- ];
-
- keybindings = lib.mkOptionDefault (
- import ./keybindings.nix {
- inherit
- lib
- config
- ;
- }
- );
- };
- extraConfig = ''
- exec_always --no-startup-id xrandr -q | grep -w 'connected' | cut -d' ' -f1 | xargs -I{} i3-msg "workspace 1 output {}"
- exec_always --no-startup-id "polybar-msg cmd restart"
- '';
- };
- };
-}
diff --git a/modules/desktop/i3/keybindings.nix b/modules/desktop/i3/keybindings.nix
deleted file mode 100644
index 8857e7d..0000000
--- a/modules/desktop/i3/keybindings.nix
+++ /dev/null
@@ -1,90 +0,0 @@
-# Keybindings - i3 keyboard shortcuts (app launchers, vim directions, workspaces)
-{
- lib,
- config,
-}:
-let
- mod = "Mod4";
-in
-{
- # --- General Applications ---
- "${mod}+r" =
- lib.mkIf (config.terminal.fzf.enable && config.terminal.kitty.enable)
- "exec ${lib.getExe config.terminal.kitty.package} --class application-launcher -e ${lib.getExe config.scripts.fzf-launcher.package}";
- "${mod}+Return" =
- lib.mkIf config.terminal.kitty.enable "exec ${lib.getExe config.terminal.kitty.package}";
- "${mod}+f" =
- lib.mkIf (config.terminal.kitty.enable && config.file-management.yazi.enable)
- "exec ${lib.getExe config.terminal.kitty.package} --class file-explorer --title 'Yazi' -e ${lib.getExe config.file-management.yazi.package}";
- "${mod}+s" =
- lib.mkIf config.terminal.kitty.enable "exec ${lib.getExe config.terminal.kitty.package} --title 'Keybindings' --class keybindings-viewer -e ${lib.getExe config.scripts.i3-keybindings.package}";
- "${mod}+q" = "kill";
-
- # --- Media / Hardware Keys ---
- "XF86MonBrightnessDown" =
- lib.mkIf config.system.brightnessctl.enable "exec ${lib.getExe config.system.brightnessctl.package} set 5%-";
- "XF86MonBrightnessUp" =
- lib.mkIf config.system.brightnessctl.enable "exec ${lib.getExe config.system.brightnessctl.package} set +5%";
- "XF86AudioLowerVolume" =
- lib.mkIf config.media.pamixer.enable "exec ${lib.getExe config.media.pamixer.package} --decrease 5";
- "XF86AudioRaiseVolume" =
- lib.mkIf config.media.pamixer.enable "exec ${lib.getExe config.media.pamixer.package} --increase 5";
- "XF86AudioMute" =
- lib.mkIf config.media.pamixer.enable "exec ${lib.getExe config.media.pamixer.package} --toggle-mute";
- "XF86AudioPlay" =
- lib.mkIf config.media.playerctl.enable "exec ${lib.getExe config.media.playerctl.package} play-pause";
-
- # --- Window Management (Vim-style) ---
- # Focus
- "${mod}+h" = "focus left";
- "${mod}+j" = "focus down";
- "${mod}+k" = "focus up";
- "${mod}+l" = "focus right";
-
- # Move/Swap
- "${mod}+Shift+h" = "move left";
- "${mod}+Shift+j" = "move down";
- "${mod}+Shift+k" = "move up";
- "${mod}+Shift+l" = "move right";
-
- # Resize
- "${mod}+Control+h" = "resize shrink width 20 px or 20 ppt";
- "${mod}+Control+j" = "resize grow height 20 px or 20 ppt";
- "${mod}+Control+k" = "resize shrink height 20 px or 20 ppt";
- "${mod}+Control+l" = "resize grow width 20 px or 20 ppt";
-
- # Layout Modes
- "${mod}+d" = "floating toggle, resize set 1280 720, move position center";
- "${mod}+m" = "fullscreen toggle";
-
- # --- Workspaces ---
- # Switch to workspace
- "${mod}+1" = "workspace number 1";
- "${mod}+2" = "workspace number 2";
- "${mod}+3" = "workspace number 3";
- "${mod}+4" = "workspace number 4";
- "${mod}+5" = "workspace number 5";
- "${mod}+6" = "workspace number 6";
- "${mod}+7" = "workspace number 7";
- "${mod}+8" = "workspace number 8";
- "${mod}+9" = "workspace number 9";
- "${mod}+0" = "workspace number 10";
-
- # Move window to workspace
- "${mod}+Shift+1" = "move container to workspace number 1; workspace number 1";
- "${mod}+Shift+2" = "move container to workspace number 2; workspace number 2";
- "${mod}+Shift+3" = "move container to workspace number 3; workspace number 3";
- "${mod}+Shift+4" = "move container to workspace number 4; workspace number 4";
- "${mod}+Shift+5" = "move container to workspace number 5; workspace number 5";
- "${mod}+Shift+6" = "move container to workspace number 6; workspace number 6";
- "${mod}+Shift+7" = "move container to workspace number 7; workspace number 7";
- "${mod}+Shift+8" = "move container to workspace number 8; workspace number 8";
- "${mod}+Shift+9" = "move container to workspace number 9; workspace number 9";
- "${mod}+Shift+0" = "move container to workspace number 10; workspace number 10";
-
- # --- Screenshots ---
- "${mod}+p" =
- lib.mkIf config.media.maim.enable "exec \"${lib.getExe config.media.maim.package} -s | xclip -selection clipboard -t image/png\"";
- "${mod}+Shift+p" =
- lib.mkIf config.media.maim.enable "exec \"mkdir -p ~/Pictures/Screenshots && ${lib.getExe config.media.maim.package} -s ~/Pictures/Screenshots/screenshot-$(date +%Y%m%d-%H%M%S).png\"";
-}
diff --git a/modules/desktop/xdg/default.nix b/modules/desktop/xdg/default.nix
index bf5ac02..5edaf03 100644
--- a/modules/desktop/xdg/default.nix
+++ b/modules/desktop/xdg/default.nix
@@ -5,19 +5,30 @@
pkgs,
...
}:
+let
+ # Hyprland ships its own portal for screensharing/screencasting
+ portalPkgs =
+ with pkgs;
+ [
+ xdg-desktop-portal-termfilechooser
+ ]
+ ++ lib.optionals config.desktop.hyprland.enable [
+ xdg-desktop-portal-hyprland
+ ]
+ ++ lib.optionals (!config.desktop.hyprland.enable) [
+ xdg-desktop-portal-gtk
+ ];
+
+ defaultPortal = if config.desktop.hyprland.enable then "hyprland" else "gtk";
+in
{
config = lib.mkIf config.desktop.enable {
xdg.portal = {
enable = true;
- extraPortals = with pkgs; [
- xdg-desktop-portal-termfilechooser
- xdg-desktop-portal-gtk
- ];
+ extraPortals = portalPkgs;
config.common = {
"org.freedesktop.impl.portal.FileChooser" = [ "termfilechooser" ];
- default = [
- "gtk"
- ];
+ default = [ defaultPortal ];
};
xdgOpenUsePortal = true;
};
diff --git a/modules/fonts/default.nix b/modules/fonts/default.nix
index 89e1318..2f77b2a 100644
--- a/modules/fonts/default.nix
+++ b/modules/fonts/default.nix
@@ -27,7 +27,7 @@
size = lib.mkOption {
type = lib.types.int;
description = "Default font size.";
- default = 16;
+ default = 12;
};
};