A second shell chrome under dotfiles/quickshell/hyprchrome, built around a BarPanel that carries TWO renderings of its data: the default children are the expanded detail view, `summary` the terse one shown while collapsed. Both stay bound to the same sources, so the densities cannot disagree, and the panel cross-fades between them while its height animates. Panels: HostPanel (hostname, user, timezone, clock), VitalsPanel (CPU load and temperature, memory, GPU load and temperature, all metered), TrayPanel (system tray, self-sizing). HyprChromeBar pins them to DP-2 and owns `expanded` for the whole rail — SUPER A, via GlobalShortcut "chrome". GPU busy comes off sysfs rather than the node_exporter scrape VitalsData already does: the hwmon collector carries the card's temps, power and clocks but not its utilisation. The bar's height binds to each panel's `targetHeight` — where it will settle, not where the animation currently is — because the exclusive zone is window-sized by default, and binding to the animated height relayouts every tiled window on the output twelve times per toggle. The zone follows the target immediately so the desktop reflows once, at the start; the surface itself shrinks only after the panels finish, or it would clip them mid-animation. DebugWindow stages a widget in the middle of the secondary monitor (SUPER CTRL D), masked so only the staged widget takes pointer input. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HEtXvseVb5gwAtKNhFx2PU
320 lines
14 KiB
Nix
320 lines
14 KiB
Nix
{ lib, pkgs, config, inputs, ... }:
|
|
|
|
# Hyprland config migrated from github.com/darman96/hyprland-dotfiles (the
|
|
# hyprlang `hypr/*.conf` files) into the home-manager lua-style `settings`
|
|
# (configType defaults to "lua" on stateVersion 26.05). Each top-level
|
|
# `settings` attr becomes an `hl.<name>(...)` call in ~/.config/hypr/hyprland.lua;
|
|
# `_args` lists become multi-arg calls, `_var` locals become `local x = ...`, and
|
|
# `lib.generators.mkLuaInline` values render as raw Lua expressions.
|
|
#
|
|
# Imported by home.nix. System-level Hyprland enable (session entry, portals)
|
|
# lives in ../../services/desktop/desktop-hyprland.nix; this manages the user's
|
|
# own hyprland.lua.
|
|
#
|
|
# Deliberately NOT migrated:
|
|
# - hyprbars.conf: config for the third-party `hyprbevelbars` plugin, which
|
|
# isn't packaged in nixpkgs. Load it via
|
|
# `wayland.windowManager.hyprland.plugins` and re-add its config once
|
|
# available. (hyprredsquare.conf's plugin was renamed hypr-chrome and
|
|
# rewritten since - it's wired in below via the `hypr-chrome` flake
|
|
# input instead, with its own `plugin.hyprchrome` config.)
|
|
# - hyprqt6engine.conf + `QT_QPA_PLATFORMTHEME=hyprqt6engine`: terra themes Qt
|
|
# through qtct/Dracula in home.nix, so that env var is left off to avoid a conflict.
|
|
# - hyprlock.conf: a separate program (use `programs.hyprlock` if wanted).
|
|
# - the duplicate pamixer/amixer + `.wob` volume binds: kept only the clean
|
|
# pipewire `wpctl`/`playerctl` set (no wob overlay is configured here).
|
|
# - `XDG_MENU_PREFIX=arch-` and `VCPKG_ROOT`: Arch-/user-specific.
|
|
# Many binds reference apps/scripts not packaged on terra yet (vivaldi-stable,
|
|
# dolphin, vicinae, grimblast, waypaper, discord, gitkraken, qbz,
|
|
# ~/.config/scripts/start-communications.sh); add them separately.
|
|
|
|
let
|
|
lua = lib.generators.mkLuaInline;
|
|
|
|
# Wallpaper images aren't checked into this repo (binary blobs) — pulled
|
|
# from the existing Wallhaven library on /mnt/hdd_01 instead. Picked once
|
|
# here rather than at runtime, since hyprpaper has no built-in "random"
|
|
# mode; re-pick and rebuild (or swap in real per-monitor selection) when
|
|
# this stops being a placeholder.
|
|
wallpaper = "/mnt/hdd_01/data/Pictures/Wallhaven/wallhaven-ym81rl.png";
|
|
|
|
# Dispatchers → the new hl.dsp.* API (signatures verified against hyprland
|
|
# 0.55's src/config/lua/bindings/LuaBindingsDispatchers.cpp).
|
|
dsp = {
|
|
exec = cmd: lua ''hl.dsp.exec_cmd("${cmd}")'';
|
|
global = name: lua ''hl.dsp.global("${name}")'';
|
|
exit = lua "hl.dsp.exit()";
|
|
killactive = lua "hl.dsp.window.close()";
|
|
togglefloating = lua ''hl.dsp.window.float({ action = "toggle" })'';
|
|
fullscreen = lua "hl.dsp.window.fullscreen()"; # mode 0
|
|
maximize = lua ''hl.dsp.window.fullscreen({ mode = "maximized" })''; # mode 1
|
|
togglegroup = lua "hl.dsp.group.toggle()";
|
|
changegroupactive = lua "hl.dsp.group.next()";
|
|
drag = lua "hl.dsp.window.drag()";
|
|
resizemouse = lua "hl.dsp.window.resize()";
|
|
movefocus = dir: lua ''hl.dsp.focus({ direction = "${dir}" })'';
|
|
movewindow = dir: lua ''hl.dsp.window.move({ direction = "${dir}" })'';
|
|
resizeactive = x: y:
|
|
lua ''hl.dsp.window.resize({ x = ${toString x}, y = ${toString y}, relative = true })'';
|
|
workspace = n: lua ''hl.dsp.focus({ workspace = ${toString n} })'';
|
|
workspaceRef = s: lua ''hl.dsp.focus({ workspace = "${s}" })'';
|
|
movetoworkspace = n: lua ''hl.dsp.window.move({ workspace = ${toString n} })'';
|
|
togglespecial = name: lua ''hl.dsp.workspace.toggle_special("${name}")'';
|
|
};
|
|
|
|
bind = keys: dispatcher: { _args = [ keys dispatcher ]; };
|
|
bindo = keys: dispatcher: opts: { _args = [ keys dispatcher opts ]; };
|
|
|
|
# SUPER + 1..9 → workspaces 1..9, SUPER + 0 → workspace 10.
|
|
wsKeys = [
|
|
{ k = "1"; n = 1; } { k = "2"; n = 2; } { k = "3"; n = 3; }
|
|
{ k = "4"; n = 4; } { k = "5"; n = 5; } { k = "6"; n = 6; }
|
|
{ k = "7"; n = 7; } { k = "8"; n = 8; } { k = "9"; n = 9; }
|
|
{ k = "0"; n = 10; }
|
|
];
|
|
in
|
|
{
|
|
services.hyprpaper = {
|
|
enable = true;
|
|
settings = {
|
|
ipc = "on";
|
|
splash = false;
|
|
preload = [ wallpaper ];
|
|
wallpaper = [
|
|
{ monitor = "DP-2"; path = wallpaper; }
|
|
{ monitor = "HDMI-A-1"; path = wallpaper; }
|
|
];
|
|
};
|
|
};
|
|
|
|
wayland.windowManager.hyprland = {
|
|
enable = true;
|
|
plugins = [ inputs.hypr-chrome.packages.${pkgs.stdenv.hostPlatform.system}.default ];
|
|
settings = {
|
|
# ---- colours (from colors.conf) ----
|
|
fg_color = { _var = "rgba(eeeeeeff)"; };
|
|
fg_accent = { _var = "rgba(ffd063ff)"; };
|
|
fg_accent_alt = { _var = "rgba(ff9d42ff)"; };
|
|
bg_color = { _var = "rgba(0f1012ff)"; };
|
|
bg_accent = { _var = "rgba(963c38ff)"; };
|
|
|
|
# ---- monitors ----
|
|
monitor = [
|
|
{ output = "DP-2"; mode = "2560x1440@144"; position = "1920x0"; scale = 1; }
|
|
{ output = "HDMI-A-1"; mode = "1920x1080@60"; position = "0x360"; scale = 1; }
|
|
];
|
|
|
|
# ---- variables (general/decoration/input/misc/...) ----
|
|
config = {
|
|
input = {
|
|
kb_layout = "de";
|
|
numlock_by_default = true;
|
|
follow_mouse = 1;
|
|
sensitivity = 0;
|
|
};
|
|
|
|
debug.disable_logs = false;
|
|
|
|
general = {
|
|
border_size = 0;
|
|
col = {
|
|
inactive_border = lua "bg_accent";
|
|
active_border = {
|
|
colors = [ (lua "fg_accent") (lua "fg_accent_alt") ];
|
|
angle = 45;
|
|
};
|
|
};
|
|
layout = "dwindle";
|
|
gaps_in = 4;
|
|
gaps_out = 8;
|
|
};
|
|
|
|
decoration = {
|
|
dim_special = 0.3;
|
|
rounding = 10;
|
|
blur = {
|
|
enabled = true;
|
|
special = true; # blur behind the special workspace
|
|
size = 6;
|
|
passes = 2;
|
|
ignore_opacity = true;
|
|
};
|
|
shadow.enabled = false;
|
|
active_opacity = 0.9;
|
|
inactive_opacity = 0.9;
|
|
};
|
|
|
|
animations.enabled = true;
|
|
|
|
misc = {
|
|
close_special_on_empty = true;
|
|
disable_hyprland_logo = true;
|
|
disable_splash_rendering = true;
|
|
};
|
|
|
|
binds = {
|
|
hide_special_on_workspace_change = true;
|
|
workspace_back_and_forth = true;
|
|
allow_workspace_cycles = true;
|
|
};
|
|
|
|
plugin.hyprchrome = {
|
|
enabled = true;
|
|
glow_size = 12;
|
|
glow_strength = 0.85;
|
|
shadow_size = 24;
|
|
shadow_color = lua "bg_color";
|
|
shadow_offset = lua "{ 4, 8 }";
|
|
outline_size = lua "2";
|
|
outline_color = lua "fg_color";
|
|
};
|
|
};
|
|
|
|
# ---- animations ----
|
|
# specialWorkspace, enabled, speed 8, default curve, slidefadevert -50%
|
|
animation = [
|
|
{ leaf = "specialWorkspace"; enabled = true; speed = 8; bezier = "default"; style = "slidefadevert -50%"; }
|
|
];
|
|
|
|
# ---- environment (environment.conf) ----
|
|
env = [
|
|
{ _args = [ "HYPRCURSOR_THEME" "Bibata-Modern-Classic" ]; }
|
|
{ _args = [ "HYPRCURSOR_SIZE" "24" ]; }
|
|
{ _args = [ "XCURSOR_THEME" "Bibata-Modern-Classic" ]; }
|
|
{ _args = [ "XCURSOR_SIZE" "24" ]; }
|
|
{ _args = [ "GDK_BACKEND" "wayland,x11" ]; }
|
|
{ _args = [ "SDL_VIDEODRIVER" "wayland" ]; }
|
|
{ _args = [ "CLUTTER_BACKEND" "wayland" ]; }
|
|
{ _args = [ "XDG_CURRENT_DESKTOP" "Hyprland" ]; }
|
|
{ _args = [ "XDG_SESSION_DESKTOP" "Hyprland" ]; }
|
|
{ _args = [ "XDG_SESSION_TYPE" "wayland" ]; }
|
|
{ _args = [ "QT_QPA_PLATFORMTHEME" "qt6ct" ]; }
|
|
];
|
|
|
|
# ---- keybinds (keybinds.conf) ----
|
|
bind = [
|
|
(bindo "SUPER + SUPER_L" (dsp.exec "bash $HOME/.config/quickshell/open_launcher.sh") { release = true; })
|
|
(bind "SUPER + Return" (dsp.exec "alacritty"))
|
|
|
|
# quickshell app-launcher variants (evaluating — pick one)
|
|
]
|
|
++ (map (n: bind "SUPER + CTRL + ${toString n}" (dsp.global "quickshell:launcher${toString n}")) (lib.range 1 9))
|
|
++ [
|
|
# variant 10 (CTRL+0 is already the quickshell restart binding below)
|
|
(bind "SUPER + CTRL + SHIFT + 0" (dsp.global "quickshell:launcher10"))
|
|
# restart quickshell (also starts it if not running)
|
|
(bind "SUPER + CTRL + 0" (dsp.exec "qs kill; sleep 0.3; qs"))
|
|
# toggle the Slant sidebar
|
|
(bind "SUPER + CTRL + S" (dsp.global "quickshell:sidebar"))
|
|
# toggle the host vitals HUD
|
|
(bind "SUPER + CTRL + V" (dsp.global "quickshell:vitals"))
|
|
# toggle the debug widget stage (centred on the secondary monitor)
|
|
(bind "SUPER + CTRL + D" (dsp.global "quickshell:debug"))
|
|
# expand / collapse the hyprchrome bar as a whole
|
|
(bind "SUPER + A" (dsp.global "quickshell:chrome"))
|
|
|
|
(bind "SUPER + B" (dsp.exec "vivaldi"))
|
|
(bind "SUPER + E" (dsp.exec "cosmic-files"))
|
|
(bind "SUPER + SHIFT + G" (dsp.workspaceRef "game"))
|
|
(bind "SUPER + S" (dsp.exec "grim -o DP-2 ~/screenshot.png"))
|
|
(bind "SUPER + SHIFT + S" (dsp.exec "grimblast copy area --freeze"))
|
|
(bind "Print" (dsp.exec "rishot"))
|
|
(bind "SUPER + L" (dsp.exec "hyprlock"))
|
|
(bind "SUPER + W" (dsp.exec "waypaper --random"))
|
|
|
|
# window management
|
|
(bind "SUPER + Q" dsp.killactive)
|
|
(bind "SUPER + SHIFT + Q" dsp.exit)
|
|
(bind "SUPER + F" dsp.maximize)
|
|
(bind "SUPER + SHIFT + F" dsp.fullscreen)
|
|
(bind "SUPER + Space" dsp.togglefloating)
|
|
|
|
# focus
|
|
(bind "SUPER + left" (dsp.movefocus "left"))
|
|
(bind "SUPER + right" (dsp.movefocus "right"))
|
|
(bind "SUPER + up" (dsp.movefocus "up"))
|
|
(bind "SUPER + down" (dsp.movefocus "down"))
|
|
|
|
# move
|
|
(bind "SUPER + SHIFT + left" (dsp.movewindow "left"))
|
|
(bind "SUPER + SHIFT + right" (dsp.movewindow "right"))
|
|
(bind "SUPER + SHIFT + up" (dsp.movewindow "up"))
|
|
(bind "SUPER + SHIFT + down" (dsp.movewindow "down"))
|
|
|
|
# resize
|
|
(bind "SUPER + CTRL + left" (dsp.resizeactive (-20) 0))
|
|
(bind "SUPER + CTRL + right" (dsp.resizeactive 20 0))
|
|
(bind "SUPER + CTRL + up" (dsp.resizeactive 0 (-20)))
|
|
(bind "SUPER + CTRL + down" (dsp.resizeactive 0 20))
|
|
|
|
# tabbed / group
|
|
(bind "SUPER + g" dsp.togglegroup)
|
|
(bind "SUPER + tab" dsp.changegroupactive)
|
|
|
|
# special workspaces
|
|
(bind "SUPER + T" (dsp.togglespecial "terminal"))
|
|
(bind "SUPER + C" (dsp.togglespecial "communications"))
|
|
(bind "SUPER + M" (dsp.togglespecial "music"))
|
|
(bind "SUPER + V" (dsp.togglespecial "version_control"))
|
|
|
|
# cycle workspaces
|
|
(bind "SUPER + ALT + up" (dsp.workspaceRef "e+1"))
|
|
(bind "SUPER + ALT + down" (dsp.workspaceRef "e-1"))
|
|
|
|
# mouse move / resize
|
|
(bindo "SUPER + mouse:272" dsp.drag { mouse = true; })
|
|
(bindo "SUPER + mouse:273" dsp.resizemouse { mouse = true; })
|
|
|
|
# multimedia (pipewire)
|
|
(bindo "XF86AudioRaiseVolume" (dsp.exec "wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+") { repeating = true; })
|
|
(bindo "XF86AudioLowerVolume" (dsp.exec "wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-") { repeating = true; })
|
|
(bind "XF86AudioMute" (dsp.exec "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"))
|
|
(bind "XF86AudioPlay" (dsp.exec "playerctl play-pause"))
|
|
(bind "XF86AudioPause" (dsp.exec "playerctl play-pause"))
|
|
(bind "XF86AudioNext" (dsp.exec "playerctl next"))
|
|
(bind "XF86AudioPrev" (dsp.exec "playerctl previous"))
|
|
]
|
|
++ (map (w: bind "SUPER + ${w.k}" (dsp.workspace w.n)) wsKeys)
|
|
++ (map (w: bind "SUPER + SHIFT + ${w.k}" (dsp.movetoworkspace w.n)) wsKeys);
|
|
|
|
# ---- window rules (windowrules.conf) ----
|
|
window_rule = [
|
|
{ name = "games"; match.class = "gamescope"; workspace = "name:game"; opacity = "1 1 override"; }
|
|
{ name = "vivaldi"; match.title = "(.*)(- YouTube - Vivaldi)"; opacity = "1 1 override"; }
|
|
{ name = "jetbrains"; match.class = "(jetbrains-)(.*)"; no_initial_focus = true; float = true; center = true; }
|
|
{ name = "jetbrains-toolbox"; match.class = "jetbrains-toolbox"; move = "1933 21"; }
|
|
{ name = "comms"; match.class = "discord|org.telegram.desktop"; workspace = "special:communications"; }
|
|
{ name = "music"; match.class = "qbz"; workspace = "special:music"; }
|
|
{ name = "vicinae"; match.class = "vicinae"; stay_focused = true; }
|
|
{ name = "gitkraken"; match.class = "gitkraken"; workspace = "special:version_control"; }
|
|
];
|
|
|
|
# ---- workspace rules (workspacerules.conf) ----
|
|
workspace_rule = [
|
|
{ workspace = "name:game"; monitor = "DP-2"; decorate = false; }
|
|
{ workspace = "special:terminal"; on_created_empty = "alacritty"; gaps_out = 256; }
|
|
{ workspace = "special:communications"; on_created_empty = "${config.home.homeDirectory}/.config/scripts/start-communications.sh"; gaps_out = 128; }
|
|
{ workspace = "special:music"; on_created_empty = "com.blitzfc.qbz"; gaps_out = 128; }
|
|
{ workspace = "special:version_control"; on_created_empty = "com.axosoft.GitKraken"; gaps_out = 128; }
|
|
];
|
|
|
|
# ---- autostart (autostart.conf) ----
|
|
on = {
|
|
_args = [
|
|
"hyprland.start"
|
|
(lua ''
|
|
function()
|
|
hl.exec_cmd("systemctl --user start hyprpolkitagent")
|
|
hl.exec_cmd("cosmic-settings-daemon")
|
|
hl.exec_cmd("quickshell")
|
|
hl.exec_cmd("alacritty", { workspace = "special:terminal silent" })
|
|
hl.exec_cmd("kbuildsycoca6 --noincremental")
|
|
end'')
|
|
];
|
|
};
|
|
};
|
|
};
|
|
|
|
xdg.portal.extraPortals = [ pkgs.xdg-desktop-portal-cosmic ];
|
|
}
|