589 lines
18 KiB
Nix
589 lines
18 KiB
Nix
# Hyprland window manager with keybindings, window rules, idle/lock, and hyprpaper.
|
|
{
|
|
config,
|
|
lib,
|
|
...
|
|
}:
|
|
with lib; let
|
|
cfg = config.desktop.wm.hyprland;
|
|
lua = lib.generators.mkLuaInline;
|
|
luaString = builtins.toJSON;
|
|
|
|
mkEnvVar = name: value: {
|
|
_args = [
|
|
name
|
|
value
|
|
];
|
|
};
|
|
|
|
modKey = key: lua ''mainMod .. " + ${key}"'';
|
|
mkDispatcher = expression: lua expression;
|
|
execCmd = command: "hl.dsp.exec_cmd(${luaString command})";
|
|
execExpr = expression: "hl.dsp.exec_cmd(${expression})";
|
|
|
|
mkBinding = keys: dispatcher: {
|
|
_args = [
|
|
keys
|
|
(mkDispatcher dispatcher)
|
|
];
|
|
};
|
|
mkBindingWithOptions = keys: dispatcher: options: {
|
|
_args = [
|
|
keys
|
|
(mkDispatcher dispatcher)
|
|
options
|
|
];
|
|
};
|
|
|
|
startupCommand = command: {
|
|
_args = [
|
|
"hyprland.start"
|
|
(lua ''
|
|
function()
|
|
hl.exec_cmd(${luaString command})
|
|
end
|
|
'')
|
|
];
|
|
};
|
|
|
|
focusWorkspace = workspace: "hl.dsp.focus({ workspace = ${luaString workspace} })";
|
|
moveToWorkspace = workspace: "hl.dsp.window.move({ workspace = ${luaString workspace} })";
|
|
in {
|
|
options.desktop.wm.hyprland.enable = mkEnableOption "Hyprland window manager";
|
|
|
|
config = mkIf cfg.enable {
|
|
wayland.windowManager.hyprland = {
|
|
configType = "lua";
|
|
extraLuaFiles."00-dms" = {
|
|
autoLoad = true;
|
|
content = ''
|
|
-- DMS setup/runtime owns these modules. Load only the Lua equivalents
|
|
-- of the pre-migration active sources, before local Home Manager
|
|
-- settings, preserving the old source-first order without enabling new
|
|
-- DMS default binds or rules.
|
|
--
|
|
-- Keep fresh Home Manager generations usable before DMS has written
|
|
-- ~/.config/hypr/dms/*.lua.
|
|
local function require_if_present(module)
|
|
if package.searchpath(module, package.path) ~= nil then
|
|
require(module)
|
|
end
|
|
end
|
|
|
|
require_if_present("dms.colors")
|
|
require_if_present("dms.layout")
|
|
require_if_present("dms.outputs")
|
|
'';
|
|
};
|
|
settings = {
|
|
mainMod = {
|
|
_var = "SUPER";
|
|
};
|
|
terminal = {
|
|
_var = "ghostty";
|
|
};
|
|
|
|
config = {
|
|
xwayland = {
|
|
force_zero_scaling = true;
|
|
};
|
|
input = {
|
|
kb_layout = "us";
|
|
kb_variant = "";
|
|
kb_model = "";
|
|
kb_rules = "";
|
|
kb_options = "ctrl:nocaps";
|
|
follow_mouse = 1;
|
|
};
|
|
general = {
|
|
gaps_in = 5;
|
|
gaps_out = 5;
|
|
border_size = 1;
|
|
layout = "dwindle";
|
|
};
|
|
decoration = {
|
|
shadow = {
|
|
enabled = true;
|
|
range = 60;
|
|
render_power = 3;
|
|
# color = "rgba(${config.colorScheme.palette.base00}66)";
|
|
offset = "1 2";
|
|
scale = 0.97;
|
|
};
|
|
rounding = 8;
|
|
blur = {
|
|
enabled = true;
|
|
size = 3;
|
|
passes = 3;
|
|
};
|
|
active_opacity = 0.9;
|
|
inactive_opacity = 0.5;
|
|
};
|
|
animations = {
|
|
enabled = true;
|
|
};
|
|
dwindle = {
|
|
# pseudotile = true; # TODO
|
|
preserve_split = true;
|
|
};
|
|
master = {
|
|
new_status = "master";
|
|
};
|
|
};
|
|
|
|
on = [
|
|
(startupCommand "vibetyper")
|
|
];
|
|
|
|
"env" = [
|
|
(mkEnvVar "XCURSOR_SIZE" "32")
|
|
(mkEnvVar "HYPRCURSOR_THEME" "Bibata-Modern-Ice")
|
|
(mkEnvVar "WLR_NO_HARDWARE_CURSORS" "1")
|
|
(mkEnvVar "XDG_CURRENT_DESKTOP" "Hyprland")
|
|
(mkEnvVar "XDG_SESSION_TYPE" "wayland")
|
|
(mkEnvVar "XDG_SESSION_DESKTOP" "Hyprland")
|
|
(mkEnvVar "XKB_DEFAULT_LAYOUT" "de")
|
|
(mkEnvVar "NIXOS_OZONE_WL" "1")
|
|
(mkEnvVar "QT_QPA_PLATFORM" "wayland;xcb")
|
|
(mkEnvVar "QT_QPA_PLATFORMTHEME" "gtk3")
|
|
(mkEnvVar "QT_QPA_PLATFORMTHEME_QT6" "gtk3")
|
|
];
|
|
|
|
device = [
|
|
# Alle normalen Keyboards explizit auf de setzen:
|
|
{
|
|
name = "video-bus";
|
|
kb_layout = "de,us";
|
|
kb_options = "ctrl:nocaps";
|
|
}
|
|
{
|
|
name = "razer-razer-pro-click-v2-vertical-edition-keyboard";
|
|
kb_layout = "de,us";
|
|
kb_options = "ctrl:nocaps";
|
|
}
|
|
{
|
|
name = "razer-razer-pro-click-v2-vertical-edition-1";
|
|
kb_layout = "de,us";
|
|
kb_options = "ctrl:nocaps";
|
|
}
|
|
{
|
|
name = "vibe-typer-virtual-keyboard";
|
|
kb_layout = "de";
|
|
kb_options = "ctrl:nocaps";
|
|
}
|
|
{
|
|
name = "keychron-keychron-k7";
|
|
kb_layout = "us";
|
|
kb_options = "ctrl:nocaps";
|
|
}
|
|
# Moonlander Sub-Devices bleiben us (erben global)
|
|
{
|
|
name = "zsa-technology-labs-moonlander-mark-i-consumer-control";
|
|
kb_layout = "us";
|
|
kb_options = "ctrl:nocaps";
|
|
}
|
|
{
|
|
name = "zsa-technology-labs-moonlander-mark-i-keyboard";
|
|
kb_layout = "us";
|
|
kb_options = "ctrl:nocaps";
|
|
}
|
|
{
|
|
name = "zsa-technology-labs-moonlander-mark-i-system-control";
|
|
kb_layout = "us";
|
|
kb_options = "ctrl:nocaps";
|
|
}
|
|
];
|
|
|
|
curve = {
|
|
_args = [
|
|
"myBezier"
|
|
(lua ''{ 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";
|
|
}
|
|
];
|
|
|
|
window_rule = [
|
|
{
|
|
match.class = "file_progress";
|
|
float = true;
|
|
}
|
|
{
|
|
match.class = "confirm";
|
|
float = true;
|
|
}
|
|
{
|
|
match.class = "dialog";
|
|
float = true;
|
|
}
|
|
{
|
|
match.class = "download";
|
|
float = true;
|
|
}
|
|
{
|
|
match.class = "notification";
|
|
float = true;
|
|
}
|
|
{
|
|
match.class = "error";
|
|
float = true;
|
|
}
|
|
{
|
|
match.class = "splash";
|
|
float = true;
|
|
}
|
|
{
|
|
match.class = "confirmreset";
|
|
float = true;
|
|
}
|
|
{
|
|
match.title = "Open File";
|
|
float = true;
|
|
}
|
|
{
|
|
match.title = "branchdialog";
|
|
float = true;
|
|
}
|
|
{
|
|
match.class = "pavucontrol-qt";
|
|
float = true;
|
|
}
|
|
{
|
|
match.class = "pavucontrol";
|
|
float = true;
|
|
}
|
|
{
|
|
match.class = "class:^(espanso)$";
|
|
float = true;
|
|
}
|
|
{
|
|
match.class = "wlogout";
|
|
fullscreen = true;
|
|
}
|
|
{
|
|
match.title = "wlogout";
|
|
float = true;
|
|
}
|
|
{
|
|
match.title = "wlogout";
|
|
fullscreen = true;
|
|
}
|
|
{
|
|
match.class = "mpv";
|
|
float = true;
|
|
}
|
|
{
|
|
match.class = "mpv";
|
|
idle_inhibit = "focus";
|
|
}
|
|
{
|
|
match.class = "mpv";
|
|
opacity = "1.0 override";
|
|
}
|
|
{
|
|
match.title = "^(Media viewer)$";
|
|
float = true;
|
|
}
|
|
{
|
|
match.title = "^(Volume Control)$";
|
|
float = true;
|
|
}
|
|
{
|
|
match.title = "^(Picture-in-Picture)$";
|
|
float = true;
|
|
}
|
|
{
|
|
match.title = "^(floating-pomodoro)$";
|
|
float = true;
|
|
}
|
|
{
|
|
match.title = "^(floating-pomodoro)$";
|
|
size = "250 50";
|
|
}
|
|
{
|
|
match.title = "^(floating-pomodoro)$";
|
|
move = "12 (monitor_h-150)";
|
|
}
|
|
{
|
|
match.title = "^(floating-pomodoro)$";
|
|
pin = true;
|
|
}
|
|
{
|
|
match.initial_title = ".*streamlabs.com.*";
|
|
float = true;
|
|
}
|
|
{
|
|
match.initial_title = ".*streamlabs.com.*";
|
|
pin = true;
|
|
}
|
|
{
|
|
match.initial_title = ".*streamlabs.com.*";
|
|
size = "800 400";
|
|
}
|
|
{
|
|
match.initial_title = ".*alert-box.*";
|
|
move = "100%-820 102";
|
|
}
|
|
{
|
|
match.initial_title = ".*chat-box.*";
|
|
move = "100%-820 512";
|
|
}
|
|
{
|
|
match.initial_title = ".*streamlabs.com.*";
|
|
opacity = "0.5 override";
|
|
}
|
|
{
|
|
match.initial_title = ".*streamlabs.com.*";
|
|
idle_inhibit = "focus";
|
|
}
|
|
{
|
|
match.initial_title = ".*streamlabs.com.*";
|
|
no_anim = true;
|
|
}
|
|
{
|
|
match.initial_title = ".*streamlabs.com.*";
|
|
decorate = false;
|
|
}
|
|
{
|
|
match.initial_title = ".*streamlabs.com.*";
|
|
no_shadow = true;
|
|
}
|
|
{
|
|
match.initial_title = ".*streamlabs.com.*";
|
|
no_blur = true;
|
|
}
|
|
{
|
|
match = {
|
|
class = "^vibe-typer$";
|
|
title = "^Recording Indicator$";
|
|
};
|
|
no_blur = true;
|
|
}
|
|
{
|
|
match = {
|
|
class = "^vibe-typer$";
|
|
title = "^Recording Indicator$";
|
|
};
|
|
no_shadow = true;
|
|
}
|
|
{
|
|
match = {
|
|
class = "^vibe-typer$";
|
|
title = "^Recording Indicator$";
|
|
};
|
|
no_anim = true;
|
|
}
|
|
{
|
|
match = {
|
|
class = "^vibe-typer$";
|
|
title = "^Recording Indicator$";
|
|
};
|
|
border_size = 0;
|
|
}
|
|
{
|
|
match = {
|
|
class = "^vibe-typer$";
|
|
title = "^Recording Indicator$";
|
|
};
|
|
no_focus = true;
|
|
}
|
|
{
|
|
match.xwayland = true;
|
|
border_color = "rgb(ffffff)";
|
|
}
|
|
];
|
|
|
|
"bind" = [
|
|
# mainMod + return intentionally remains disabled from the previous config.
|
|
(mkBinding (modKey "t") (execExpr ''terminal .. " -e nu -c 'nitch; exec nu'"''))
|
|
(mkBinding (modKey "SHIFT + t") (execCmd "launch-timer"))
|
|
(mkBinding (modKey "n") (execExpr ''terminal .. " -e nvim"''))
|
|
(mkBinding (modKey "z") (execCmd "uwsm app -- zeditor"))
|
|
(mkBinding (modKey "o") ''hl.dsp.window.set_prop({ prop = "opaque", value = "toggle" })'')
|
|
(mkBinding (modKey "r") (
|
|
execCmd ''hyprctl dispatch focuswindow "initialtitle:.*alert-box.*" && hyprctl dispatch moveactive exact 4300 102 && hyprctl dispatch focuswindow "initialtitle:.*chat-box.*" && hyprctl dispatch moveactive exact 4300 512''
|
|
))
|
|
(mkBinding (modKey "b") (execCmd "uwsm app -- thunar"))
|
|
(mkBinding (modKey "SHIFT + B") (execCmd "uwsm app -- vivaldi"))
|
|
(mkBinding (modKey "Escape") (execCmd "uwsm app -- dms ipc call powermenu toggle"))
|
|
(mkBinding (modKey "q") "hl.dsp.window.close()")
|
|
(mkBinding (modKey "M") "hl.dsp.exit()")
|
|
(mkBinding (modKey "F") "hl.dsp.window.fullscreen({})")
|
|
(mkBinding (modKey "SHIFT + V") ''hl.dsp.window.float({ action = "toggle" })'')
|
|
(mkBinding (modKey "D") (execCmd "uwsm app -- dms ipc call spotlight toggle"))
|
|
(mkBinding (modKey "V") (execCmd "uwsm app -- dms ipc call clipboard toggle"))
|
|
(mkBinding (modKey "C") (
|
|
execCmd "bash -c 'FILE=/tmp/screenshot_$(date +%s).png; grim -g \"$(slurp)\" \"$FILE\" && ksnip \"$FILE\"'"
|
|
))
|
|
(mkBinding (modKey "SHIFT + S") (execCmd "uwsm app -- rofi -show emoji"))
|
|
(mkBinding (modKey "P") (execCmd "uwsm app -- rofi-pass"))
|
|
(mkBinding (modKey "SHIFT + P") "hl.dsp.window.pseudo({})")
|
|
(mkBinding (modKey "R") (execCmd "stt-ptt start"))
|
|
(mkBinding (modKey "S") (execCmd "stt-ptt start"))
|
|
(mkBinding (modKey "h") ''hl.dsp.focus({ direction = "l" })'')
|
|
(mkBinding (modKey "l") ''hl.dsp.focus({ direction = "r" })'')
|
|
(mkBinding (modKey "k") ''hl.dsp.focus({ direction = "u" })'')
|
|
(mkBinding (modKey "j") ''hl.dsp.focus({ direction = "d" })'')
|
|
(mkBinding (modKey "1") (focusWorkspace "1"))
|
|
(mkBinding (modKey "2") (focusWorkspace "2"))
|
|
(mkBinding (modKey "3") (focusWorkspace "3"))
|
|
(mkBinding (modKey "4") (focusWorkspace "4"))
|
|
(mkBinding (modKey "5") (focusWorkspace "5"))
|
|
(mkBinding (modKey "6") (focusWorkspace "6"))
|
|
(mkBinding (modKey "7") (focusWorkspace "7"))
|
|
(mkBinding (modKey "8") (focusWorkspace "8"))
|
|
(mkBinding (modKey "9") (focusWorkspace "9"))
|
|
(mkBinding (modKey "0") (focusWorkspace "10"))
|
|
(mkBinding (modKey "SHIFT + 1") (moveToWorkspace "1"))
|
|
(mkBinding (modKey "SHIFT + 2") (moveToWorkspace "2"))
|
|
(mkBinding (modKey "SHIFT + 3") (moveToWorkspace "3"))
|
|
(mkBinding (modKey "SHIFT + 4") (moveToWorkspace "4"))
|
|
(mkBinding (modKey "SHIFT + 5") (moveToWorkspace "5"))
|
|
(mkBinding (modKey "SHIFT + 6") (moveToWorkspace "6"))
|
|
(mkBinding (modKey "SHIFT + 7") (moveToWorkspace "7"))
|
|
(mkBinding (modKey "SHIFT + 8") (moveToWorkspace "8"))
|
|
(mkBinding (modKey "SHIFT + 9") (moveToWorkspace "9"))
|
|
(mkBinding (modKey "SHIFT + 0") (moveToWorkspace "10"))
|
|
(mkBinding (modKey "mouse_down") (focusWorkspace "e+1"))
|
|
(mkBinding (modKey "mouse_up") (focusWorkspace "e-1"))
|
|
(mkBindingWithOptions (modKey "mouse:272") "hl.dsp.window.drag()" {mouse = true;})
|
|
(mkBindingWithOptions (modKey "mouse:273") "hl.dsp.window.resize()" {mouse = true;})
|
|
];
|
|
};
|
|
};
|
|
|
|
# services.hypridle = {
|
|
# enable = true;
|
|
# settings = {
|
|
# general = {
|
|
# before_sleep_cmd = "hyprlock";
|
|
# after_sleep_cmd = "hyprctl dispatch dpms on";
|
|
# inhibit_sleep = 3;
|
|
# };
|
|
# listener = [
|
|
# {
|
|
# timeout = 300;
|
|
# on-timeout = "hyprlock";
|
|
# }
|
|
# {
|
|
# timeout = 420;
|
|
# on-timeout = "hyprctl dispatch dpms off";
|
|
# on-resume = "hyprctl dispatch dpms on";
|
|
# }
|
|
# ];
|
|
# };
|
|
# };
|
|
|
|
# services.hyprpaper.enable = true;
|
|
|
|
# programs.hyprlock = {
|
|
# enable = true;
|
|
# settings = {
|
|
# "$font" = "JetBrainsMono Nerd Font";
|
|
# "$base" = "rgb(${config.colorScheme.palette.base00})";
|
|
# "$text" = "rgb(${config.colorScheme.palette.base05})";
|
|
# "$textAlpha" = "${config.colorScheme.palette.base05}";
|
|
# "$accentAlpha" = "${config.colorScheme.palette.base0D}";
|
|
# "$red" = "rgb(${config.colorScheme.palette.base08})";
|
|
# "$yellow" = "rgb(${config.colorScheme.palette.base0A})";
|
|
|
|
# general = {
|
|
# hide_cursor = true;
|
|
# };
|
|
|
|
# background = {
|
|
# monitor = "";
|
|
# path = "${config.home.homeDirectory}/.config/hypr/wallpapers/wallhaven-lmmo8r.jpg";
|
|
# blur_passes = 0;
|
|
# color = "rgb(${config.colorScheme.palette.base00})";
|
|
# };
|
|
|
|
# label = [
|
|
# {
|
|
# monitor = "";
|
|
# text = "$TIME";
|
|
# color = "$text";
|
|
# font_size = 90;
|
|
# font_family = "$font";
|
|
# position = "30, 0";
|
|
# halign = "left";
|
|
# valign = "top";
|
|
# }
|
|
# {
|
|
# monitor = "";
|
|
# text = ''cmd[update:43200000] echo "$(date +"%A, %d %B %Y")"'';
|
|
# color = "$text";
|
|
# font_size = 25;
|
|
# font_family = "$font";
|
|
# position = "30, -150";
|
|
# halign = "left";
|
|
# valign = "top";
|
|
# }
|
|
# ];
|
|
|
|
# input-field = [
|
|
# {
|
|
# monitor = "";
|
|
# size = "300, 60";
|
|
# outline_thickness = 4;
|
|
# dots_size = 0.2;
|
|
# dots_spacing = 0.2;
|
|
# dots_center = true;
|
|
# outer_color = "rgb(${config.colorScheme.palette.base0D})";
|
|
# inner_color = "rgb(${config.colorScheme.palette.base00})";
|
|
# font_color = "rgb(${config.colorScheme.palette.base05})";
|
|
# fade_on_empty = false;
|
|
# placeholder_text = ''<span foreground="##${config.colorScheme.palette.base05}"> Logged in as <span foreground="##${config.colorScheme.palette.base0D}">$USER</span></span>'';
|
|
# hide_input = false;
|
|
# check_color = "rgb(${config.colorScheme.palette.base0D})";
|
|
# fail_color = "rgb(${config.colorScheme.palette.base08})";
|
|
# fail_text = ''<i>$FAIL <b>($ATTEMPTS)</b></i>'';
|
|
# capslock_color = "rgb(${config.colorScheme.palette.base0A})";
|
|
# position = "0, -35";
|
|
# halign = "center";
|
|
# valign = "center";
|
|
# }
|
|
# ];
|
|
# };
|
|
# };
|
|
};
|
|
}
|