Files
NixOS-Configs/home/hypr/hyprland.nix
Anish Govind 367e21ef95 quickshell: replace macOS-style shell with standalone overview module
Swap the illogical-impulse-derived components for the upstream
quickshell-overview standalone module, update Hyprland keybinds
(Super+Tab overview, rofi launcher), refresh foot colors and
starship theme, and adjust related host/module wiring.
2026-09-18 23:25:42 -07:00

403 lines
14 KiB
Nix

{ pkgs, lib, config, ... }:
let
mkLua = lib.generators.mkLuaInline;
in
{
# -------------------------------------------------------------------------
# Per-host monitor configuration.
#
# Hosts declare their displays once, in hosts/<host>/default.nix, via:
# home-manager.users.anish.volt.monitors = [ { ... } ];
# and the setting flows into Hyprland here. The default (empty output +
# preferred mode) works on any machine with any display.
# -------------------------------------------------------------------------
options.volt.monitors = lib.mkOption {
description = "Hyprland monitor rules for this host";
type = lib.types.listOf (lib.types.submodule {
options = {
output = lib.mkOption {
type = lib.types.str;
default = "";
description = "Output name or desc: match. Empty string matches every output.";
};
mode = lib.mkOption {
type = lib.types.str;
default = "preferred";
description = "Resolution@refresh, e.g. \"3840x2160@164.99Hz\" or \"preferred\".";
};
position = lib.mkOption {
type = lib.types.str;
default = "auto";
};
scale = lib.mkOption {
type = lib.types.either lib.types.number lib.types.str;
default = "auto";
};
vrr = lib.mkOption {
type = lib.types.nullOr (lib.types.either lib.types.number lib.types.str);
default = null;
description = "Optional per-monitor VRR setting (0/1/on-demand).";
};
};
});
default = [
{ output = ""; mode = "preferred"; position = "auto"; scale = "auto"; }
];
};
config = {
wayland.windowManager.hyprland.settings.monitor = map (m:
{ inherit (m) output mode position scale; }
// (lib.optionalAttrs (m.vrr != null) { inherit (m) vrr; })
) config.volt.monitors;
wayland.windowManager.hyprland = {
enable = true;
configType = "lua";
package = null; # Hyprland package is managed system-wide via NixOS programs.hyprland
settings = {
# -----------------------------------------------------------------------
# 1. Variables & Modifiers (Rendered as Lua local variables)
# -----------------------------------------------------------------------
mainMod = { _var = "SUPER"; };
terminal = { _var = "foot"; };
browser = { _var = "brave"; };
# -----------------------------------------------------------------------
# 2. Monitors (hl.monitor) - declared per-host via volt.monitors
# (see hosts/<host>/default.nix); defaults to any display @ preferred.
# -----------------------------------------------------------------------
# -----------------------------------------------------------------------
# 3. Environment Variables (hl.env)
# -----------------------------------------------------------------------
env = [
{ _args = [ "XCURSOR_SIZE" "24" ]; }
{ _args = [ "XDG_SESSION_TYPE" "wayland" ]; }
];
# -----------------------------------------------------------------------
# 4. Main Configuration (hl.config) - Strictly validates against Hyprland 0.55+ schema
# -----------------------------------------------------------------------
config = {
input = {
kb_layout = "us";
repeat_delay = 300;
repeat_rate = 50;
follow_mouse = 1;
sensitivity = 0;
touchpad = {
natural_scroll = false;
};
};
cursor = {
inactive_timeout = 3;
# Hardware cursors ON (explicit). Note: this replaces the old
# WLR_NO_HARDWARE_CURSORS=1, which forced software rendering.
no_hardware_cursors = false;
};
general = {
gaps_in = 5;
gaps_out = 10;
border_size = 2;
col = {
# Silicon Volt: electric lime gradient on focus, glass gray at rest
active_border = {
colors = [ "rgba(cffc00ee)" "rgba(e3ff66ee)" ];
angle = 45;
};
inactive_border = "rgba(ffffff14)";
};
layout = "dwindle";
};
group = {
groupbar = {
font_size = 14;
font_family = "JetBrainsMono Nerd Font";
col = {
active = "rgba(cffc0022)";
inactive = "rgba(ffffff08)";
};
};
col = {
border_active = {
colors = [ "rgba(cffc00ee)" "rgba(e3ff66ee)" ];
angle = 45;
};
border_inactive = "rgba(ffffff14)";
};
};
misc = {
disable_hyprland_logo = true;
disable_splash_rendering = true;
};
decoration = {
rounding = 4;
# Subtle glass blur to match the brutalist-glass aesthetic
blur = {
enabled = true;
size = 4;
passes = 2;
new_optimizations = true;
ignore_opacity = true;
contrast = 1.1;
brightness = 0.9;
vibrancy = 0.1;
};
shadow = {
enabled = true;
range = 12;
render_power = 3;
color = "rgba(00000066)";
};
};
animations = {
enabled = true;
};
dwindle = {
preserve_split = true;
};
master = {
new_status = "master";
};
};
# -----------------------------------------------------------------------
# 5. Curves & Animations (hl.curve & hl.animation)
# -----------------------------------------------------------------------
curve = [
{
_args = [
"myBezier"
{
type = "bezier";
points = [ [ 0.05 0.9 ] [ 0.1 1.05 ] ];
}
];
}
];
animation = [
{ leaf = "windows"; enabled = true; speed = 7; bezier = "myBezier"; }
{ leaf = "windowsOut"; enabled = true; speed = 7; bezier = "default"; style = "popin 80%"; }
{ leaf = "border"; enabled = true; speed = 10; bezier = "default"; }
{ leaf = "borderangle"; enabled = true; speed = 8; bezier = "default"; }
{ leaf = "fade"; enabled = true; speed = 7; bezier = "default"; }
{ leaf = "workspaces"; enabled = true; speed = 6; bezier = "default"; }
];
# -----------------------------------------------------------------------
# 6. Autostart Daemons & Apps (hl.on)
# -----------------------------------------------------------------------
on = [
{
_args = [
"hyprland.start"
(mkLua ''function()
hl.exec_cmd("qs")
hl.exec_cmd("hyprpaper")
hl.exec_cmd("mako")
hl.exec_cmd("wl-paste --type text --watch cliphist store")
hl.exec_cmd("wl-paste --type image --watch cliphist store")
hl.exec_cmd("${pkgs.hyprpolkitagent}/libexec/hyprpolkitagent")
end'')
];
}
];
# -----------------------------------------------------------------------
# 7. Keybindings (hl.bind)
# -----------------------------------------------------------------------
bind = [
# Launchers & Window Controls
{ _args = [ (mkLua "mainMod .. \" + Q\"") (mkLua "hl.dsp.exec_cmd(terminal)") ]; }
{ _args = [ (mkLua "mainMod .. \" + C\"") (mkLua "hl.dsp.window.close()") ]; }
{ _args = [ (mkLua "mainMod .. \" + SPACE\"") (mkLua "hl.dsp.exec_cmd(\"rofi -show combi -show-icons\")") ]; }
{ _args = [ (mkLua "mainMod .. \" + N\"") (mkLua "hl.dsp.exec_cmd(\"swaync-client -t -sw\")") ]; }
{ _args = [ (mkLua "mainMod .. \" + TAB\"") (mkLua "hl.dsp.exec_cmd(\"qs ipc call overview toggle\")") ]; }
{ _args = [ (mkLua "mainMod .. \" + V\"") (mkLua "hl.dsp.window.float({ action = \"toggle\" })") ]; }
{ _args = [ (mkLua "mainMod .. \" + R\"") (mkLua "hl.dsp.exec_cmd(\"rofi -show combi\")") ]; }
{ _args = [ (mkLua "mainMod .. \" + G\"") (mkLua "hl.dsp.group.toggle()") ]; }
{ _args = [ (mkLua "mainMod .. \" + F\"") (mkLua "hl.dsp.window.fullscreen({ fullscreen = 0 })") ]; }
# Move focus with mainMod + vim
{ _args = [ (mkLua "mainMod .. \" + h\"") (mkLua "hl.dsp.focus({ direction = \"left\" })") ]; }
{ _args = [ (mkLua "mainMod .. \" + l\"") (mkLua "hl.dsp.focus({ direction = \"right\" })") ]; }
{ _args = [ (mkLua "mainMod .. \" + k\"") (mkLua "hl.dsp.focus({ direction = \"up\" })") ]; }
{ _args = [ (mkLua "mainMod .. \" + j\"") (mkLua "hl.dsp.focus({ direction = \"down\" })") ]; }
# Move focus within a grouped page
{ _args = [ (mkLua "mainMod .. \" + e\"") (mkLua "hl.dsp.group.next()") ]; }
{ _args = [ (mkLua "mainMod .. \" + d\"") (mkLua "hl.dsp.group.prev()") ]; }
# Move window or group with vim keys
{ _args = [ (mkLua "mainMod .. \" + SHIFT + h\"") (mkLua "hl.dsp.window.move({ direction = \"left\" })") ]; }
{ _args = [ (mkLua "mainMod .. \" + SHIFT + l\"") (mkLua "hl.dsp.window.move({ direction = \"right\" })") ]; }
{ _args = [ (mkLua "mainMod .. \" + SHIFT + k\"") (mkLua "hl.dsp.window.move({ direction = \"up\" })") ]; }
{ _args = [ (mkLua "mainMod .. \" + SHIFT + j\"") (mkLua "hl.dsp.window.move({ direction = \"down\" })") ]; }
# Scroll through existing workspaces with mainMod + scroll
{ _args = [ (mkLua "mainMod .. \" + mouse_down\"") (mkLua "hl.dsp.focus({ workspace = \"e+1\" })") ]; }
{ _args = [ (mkLua "mainMod .. \" + mouse_up\"") (mkLua "hl.dsp.focus({ workspace = \"e-1\" })") ]; }
# Lock shortcut
{ _args = [ (mkLua "mainMod .. \" + S\"") (mkLua "hl.dsp.exec_cmd(\"hyprlock\")") ]; }
# Quick access applications
{ _args = [ (mkLua "mainMod .. \" + b\"") (mkLua "hl.dsp.exec_cmd(browser)") ]; }
# Scratch workspace
{ _args = [ (mkLua "mainMod .. \" + RETURN\"") (mkLua "hl.dsp.workspace.toggle_special(\"scratch\")") ]; }
{ _args = [ (mkLua "mainMod .. \" + SHIFT + RETURN\"") (mkLua "hl.dsp.window.move({ workspace = \"special:scratch\" })") ]; }
# Messaging workspace
{ _args = [ (mkLua "mainMod .. \" + M\"") (mkLua "hl.dsp.workspace.toggle_special(\"messaging\")") ]; }
# Move/resize windows with mouse and dragging
{
_args = [
(mkLua "mainMod .. \" + mouse:272\"")
(mkLua "hl.dsp.window.drag()")
{ mouse = true; }
];
}
{
_args = [
(mkLua "mainMod .. \" + mouse:273\"")
(mkLua "hl.dsp.window.resize()")
{ mouse = true; }
];
}
# Function Row Keys
{
_args = [
"XF86AudioRaiseVolume"
(mkLua "hl.dsp.exec_cmd(\"pactl -- set-sink-volume @DEFAULT_SINK@ +5%\")")
{ repeating = true; }
];
}
{
_args = [
"XF86AudioLowerVolume"
(mkLua "hl.dsp.exec_cmd(\"pactl -- set-sink-volume @DEFAULT_SINK@ -5%\")")
{ repeating = true; locked = true; }
];
}
{
_args = [
"XF86AudioMute"
(mkLua "hl.dsp.exec_cmd(\"pactl -- set-sink-mute @DEFAULT_SINK@ toggle\")")
{ repeating = true; locked = true; }
];
}
{
_args = [
"XF86MonBrightnessUp"
(mkLua "hl.dsp.exec_cmd(\"brightnessctl set 5%+\")")
{ repeating = true; locked = true; }
];
}
{
_args = [
"XF86MonBrightnessDown"
(mkLua "hl.dsp.exec_cmd(\"brightnessctl set 5%-\")")
{ repeating = true; locked = true; }
];
}
# Lid switch - generically detects the embedded (eDP*) panel on any laptop
{
_args = [
"switch:off:Lid Switch"
(mkLua "hl.dsp.exec_cmd(\"m=$(hyprctl monitors | awk '$1==\\\"Monitor\\\"{print $2; exit}'); [ -n \\\"$m\\\" ] && hyprctl keyword monitor \\\"$m, preferred, auto, auto\\\"\")")
{ locked = true; }
];
}
{
_args = [
"switch:on:Lid Switch"
(mkLua "hl.dsp.exec_cmd(\"m=$(hyprctl monitors | awk '$1==\\\"Monitor\\\"{print $2; exit}'); [ -n \\\"$m\\\" ] && hyprctl keyword monitor \\\"$m, disable\\\"\")")
{ locked = true; }
];
}
]
# Workspace 1-9 switching and moving
++ (lib.concatMap (i: [
{
_args = [
(mkLua "mainMod .. \" + ${toString i}\"")
(mkLua "hl.dsp.focus({ workspace = ${toString i} })")
];
}
{
_args = [
(mkLua "mainMod .. \" + SHIFT + ${toString i}\"")
(mkLua "hl.dsp.window.move({ workspace = ${toString i} })")
];
}
]) (lib.range 1 9))
# Workspace 10 switching and moving (mapped to key 0)
++ [
{
_args = [
(mkLua "mainMod .. \" + 0\"")
(mkLua "hl.dsp.focus({ workspace = 10 })")
];
}
{
_args = [
(mkLua "mainMod .. \" + SHIFT + 0\"")
(mkLua "hl.dsp.window.move({ workspace = 10 })")
];
}
];
# -----------------------------------------------------------------------
# 8. Workspace Rules (hl.workspace_rule)
# -----------------------------------------------------------------------
workspace_rule = [
{
workspace = "name:messaging";
on_created_empty = "[] togglegroup";
}
];
# -----------------------------------------------------------------------
# 9. Window Rules (hl.window_rule)
# -----------------------------------------------------------------------
window_rule = [
{
name = "signal-messaging";
match = { class = "Signal"; };
workspace = "special:messaging";
}
{
name = "vesktop-messaging";
match = { class = "vesktop"; };
workspace = "special:messaging";
}
{
name = "ghidra-tile";
match = { class = "ghidra-Ghidra"; };
float = false;
}
];
};
};
};
}