dotfiles/hyprland/default.nix

314 lines
8.3 KiB
Nix

{ inputs
, lib
, config
, pkgs
, ...
}:
{
options =
let
inherit (lib) mkOption types;
in
{
hyprland = {
mod = mkOption {
type = types.str;
default = "SUPER";
};
autoStart = mkOption {
type = types.listOf types.str;
default = [ ];
};
primaryMonitor = mkOption {
type = types.str;
};
monitors = mkOption {
type = types.listOf (types.submodule {
options = {
name = mkOption {
type = types.str;
};
width = mkOption {
type = types.int;
};
height = mkOption {
type = types.int;
};
refreshRate = mkOption {
type = types.int;
default = 60;
};
x = mkOption {
type = types.int;
default = 0;
};
y = mkOption {
type = types.int;
default = 0;
};
transform = mkOption {
type = types.int;
default = 0;
};
vrr = mkOption {
type = types.int;
default = 0;
};
enabled = mkOption {
type = types.bool;
default = true;
};
};
});
default = [ ];
};
environment = mkOption {
type = types.attrsOf types.str;
default = { };
};
sensitivity = mkOption {
type = types.float;
default = 0.0;
};
keyboard = {
layout = mkOption {
type = types.str;
default = "us";
};
variant = mkOption {
type = types.str;
default = "";
};
options = mkOption {
type = types.str;
default = "";
};
};
layout = mkOption { type = types.str; };
layerRules = mkOption {
type = types.attrsOf (types.listOf types.str);
default = { };
};
windowRules = mkOption {
type = types.attrsOf (types.listOf types.str);
default = { };
};
windowRulesV2 = mkOption {
type = types.attrsOf (types.listOf types.str);
default = { };
};
binds = mkOption {
type = types.attrsOf types.str;
default = { };
};
mouseBinds = mkOption {
type = types.attrsOf types.str;
default = { };
};
};
};
config =
let
cfg = config.hyprland;
in
{
home.packages = with pkgs; [
wl-clipboard
cliphist
ulauncher
];
wayland.windowManager.hyprland = {
enable = true;
settings = {
monitor = map
(m:
let
resolution = "${toString m.width}x${toString m.height}@${toString m.refreshRate}";
position = "${toString m.x}x${toString m.y}";
vrr = if m.vrr != 0 then ",vrr,${toString m.vrr}" else "";
transform = if m.transform != 0 then ",transform,${toString m.transform}" else "";
in
"${m.name},${if m.enabled then "${resolution},${position},1${vrr}${transform}" else "disable"}"
)
(cfg.monitors)
# Automatically detect newly connected monitors
++ [ ",preferred,auto,auto" ];
exec-once = [
"${pkgs.wl-clipboard}/bin/wl-paste --watch ${pkgs.cliphist}/bin/cliphist store"
"${pkgs.ulauncher}/bin/ulauncher --no-window-shadow --hide-window"
"${pkgs.libsForQt5.polkit-kde-agent}/libexec/polkit-kde-authentication-agent-1"
# kde-connect (somehow, wasnt working well last time)
] ++ cfg.autoStart;
env = lib.mapAttrsToList (k: v: "${toString k},${v}") cfg.environment;
input = {
kb_layout = cfg.keyboard.layout;
kb_variant = cfg.keyboard.variant;
kb_options = cfg.keyboard.options;
follow_mouse = 1;
touchpad = {
natural_scroll = "yes";
};
sensitivity = cfg.sensitivity;
accel_profile = "flat";
};
general = {
gaps_in = 5;
gaps_out = 10;
border_size = 1;
"col.active_border" = "rgba(33ccffee) rgba(00ff99ee) 45deg";
"col.inactive_border" = "rgba(595959aa)";
layout = cfg.layout;
};
misc = {
force_default_wallpaper = 2;
};
decoration = {
rounding = 5;
blur = {
enabled = "yes";
size = 3;
passes = 1;
new_optimizations = "on";
};
drop_shadow = "yes";
shadow_range = 4;
shadow_render_power = 3;
"col.shadow" = "rgba(1a1a1aee)";
};
gestures = {
workspace_swipe = "on";
};
animations = {
enabled = "yes";
# Some default animations, see https://wiki.hyprland.org/Configuring/Animations/ for more
bezier = [
"myBezier, 0.05, 0.9, 0.1, 1.05"
];
animation = [
"windows, 1, 3, myBezier"
"windowsOut, 1, 3, default, popin 80%"
"border, 1, 5, default"
"borderangle, 1, 4, default"
"fade, 1, 3, default"
"workspaces, 1, 2, default"
];
};
layerrule =
let
y = ident: value: "${value},${ident}";
x = ident: values: map (y ident) values;
in
lib.flatten (lib.mapAttrsToList x cfg.layerRules);
workspace =
let
# Create one work space for each non primary monitor
perMonitorWorkspaces = map
(m: "name:${m.name}, monitor:${m.name}")
(lib.filter
(m: m.name != cfg.primaryMonitor)
cfg.monitors
);
# Create 10 work spaces on the primary monitor
primaryMonitorWorkspaces = map (i: "${toString i}, monitor:${cfg.primaryMonitor}") (lib.range 1 10);
in
primaryMonitorWorkspaces ++ perMonitorWorkspaces;
bind =
let
# Create binds to switch workspaces and move windows between them
workspaceBinds =
lib.flatten
(map
(i:
let
k = if i == 10 then 0 else i;
in
[
"${cfg.mod}, ${toString k}, workspace, ${toString i}"
"${cfg.mod} SHIFT, ${toString k}, movetoworkspace, ${toString i}"
]
)
(lib.range 1 10)
);
# Create binds to manage wiwdows
windowManagementBinds = [
"${cfg.mod} SHIFT, Q, killactive"
"${cfg.mod}, F, togglefloating"
"${cfg.mod} SHIFT, F, fullscreen"
];
configBinds = lib.mapAttrsToList (k: v: "${k}, ${v}") cfg.binds;
in
configBinds ++ workspaceBinds ++ windowManagementBinds;
bindm =
let
windowManagementBinds = [
"${cfg.mod}, mouse:272, movewindow"
"${cfg.mod}, mouse:273, resizewindow"
];
configBinds = lib.mapAttrsToList (k: v: "${k}, ${v}") cfg.mouseBinds;
in
configBinds ++ windowManagementBinds;
windowrule =
let
y = ident: value: "${value},${ident}";
x = ident: values: map (y ident) values;
in
lib.flatten (lib.mapAttrsToList x cfg.windowRules);
windowrulev2 =
let
y = ident: value: "${value},${ident}";
x = ident: values: map (y ident) values;
in
lib.flatten (lib.mapAttrsToList x cfg.windowRulesV2);
};
};
};
}