434 lines
11 KiB
Nix
434 lines
11 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 = "qwerty";
|
|
};
|
|
|
|
options = mkOption {
|
|
type = types.str;
|
|
default = "";
|
|
};
|
|
};
|
|
|
|
inner_gaps = mkOption { type = types.int; };
|
|
|
|
outer_gaps = mkOption { type = types.int; };
|
|
|
|
border = {
|
|
size = mkOption { type = types.int; };
|
|
active = mkOption { type = types.str; };
|
|
inactive = mkOption { type = types.str; };
|
|
};
|
|
|
|
animations = {
|
|
enable = mkOption {
|
|
type = types.bool;
|
|
default = true;
|
|
};
|
|
|
|
beziers = mkOption {
|
|
type = types.listOf types.str;
|
|
default = [
|
|
"myBezier, 0.05, 0.9, 0.1, 1.05"
|
|
];
|
|
};
|
|
|
|
windows = mkOption {
|
|
type = types.str;
|
|
default = "1, 3, myBezier";
|
|
};
|
|
|
|
windowsOut = mkOption {
|
|
type = types.str;
|
|
default = "1, 3, default, popin 80%";
|
|
};
|
|
|
|
border = mkOption {
|
|
type = types.str;
|
|
default = "1, 5, default";
|
|
};
|
|
|
|
borderangle = mkOption {
|
|
type = types.str;
|
|
default = "1, 4, default";
|
|
};
|
|
|
|
fade = mkOption {
|
|
type = types.str;
|
|
default = "1, 3, default";
|
|
};
|
|
|
|
workspaces = mkOption {
|
|
type = types.str;
|
|
default = "1, 2, default";
|
|
};
|
|
};
|
|
|
|
layout = mkOption { type = types.str; };
|
|
rounding = mkOption { type = types.int; };
|
|
|
|
blur = {
|
|
enable = mkOption {
|
|
type = types.bool;
|
|
default = true;
|
|
};
|
|
|
|
size = mkOption {
|
|
type = types.int;
|
|
default = 3;
|
|
};
|
|
|
|
passes = mkOption {
|
|
type = types.int;
|
|
default = 1;
|
|
};
|
|
};
|
|
|
|
shadow = {
|
|
enable = mkOption {
|
|
type = types.bool;
|
|
default = true;
|
|
};
|
|
|
|
range = mkOption {
|
|
type = types.int;
|
|
default = 4;
|
|
};
|
|
|
|
strength = mkOption {
|
|
type = types.int;
|
|
default = 3;
|
|
};
|
|
|
|
color = mkOption {
|
|
type = types.str;
|
|
default = "rgba(1a1a1aee)";
|
|
};
|
|
};
|
|
|
|
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 = { };
|
|
};
|
|
|
|
generateWorkspaceBinds = mkOption {
|
|
type = types.bool;
|
|
default = true;
|
|
};
|
|
|
|
generateWindowManagementBinds = mkOption {
|
|
type = types.bool;
|
|
default = true;
|
|
};
|
|
|
|
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 = cfg.inner_gaps;
|
|
gaps_out = cfg.outer_gaps;
|
|
|
|
border_size = cfg.border.size;
|
|
"col.active_border" = cfg.border.active;
|
|
"col.inactive_border" = cfg.border.inactive;
|
|
|
|
layout = cfg.layout;
|
|
};
|
|
|
|
misc = {
|
|
force_default_wallpaper = 2;
|
|
};
|
|
|
|
decoration = {
|
|
rounding = cfg.rounding;
|
|
|
|
blur = {
|
|
enabled = if cfg.blur.enable then "yes" else "no";
|
|
size = cfg.blur.size;
|
|
passes = cfg.blur.passes;
|
|
new_optimizations = "on";
|
|
};
|
|
|
|
drop_shadow = if cfg.shadow.enable then "yes" else "no";
|
|
shadow_range = cfg.shadow.range;
|
|
shadow_render_power = cfg.shadow.strength;
|
|
"col.shadow" = cfg.shadow.color;
|
|
};
|
|
|
|
dwindle = {
|
|
pseudotile = "yes";
|
|
preserve_split = "yes";
|
|
};
|
|
|
|
master = {
|
|
new_is_master = true;
|
|
};
|
|
|
|
gestures = {
|
|
workspace_swipe = "on";
|
|
};
|
|
|
|
animations = {
|
|
enabled = if cfg.animations.enable then "yes" else "no";
|
|
|
|
# Some default animations, see https://wiki.hyprland.org/Configuring/Animations/ for more
|
|
|
|
bezier = cfg.animations.beziers;
|
|
|
|
animation = [
|
|
"windows, ${cfg.animations.windows}"
|
|
"windowsOut, ${cfg.animations.windowsOut}"
|
|
"border, ${cfg.animations.border}"
|
|
"borderangle, ${cfg.animations.borderangle}"
|
|
"fade, ${cfg.animations.fade}"
|
|
"workspaces, ${cfg.animations.workspaces}"
|
|
];
|
|
|
|
};
|
|
|
|
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: "${m.name}, name:${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 =
|
|
if cfg.generateWorkspaceBinds then
|
|
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)
|
|
)
|
|
else
|
|
[ ];
|
|
|
|
# Create binds to manage wiwdows
|
|
windowManagementBinds =
|
|
if cfg.generateWindowManagementBinds then [
|
|
"${cfg.mod} SHIFT, Q, killactive"
|
|
"${cfg.mod}, F, togglefloating"
|
|
"${cfg.mod} SHIFT, F, fullscreen"
|
|
]
|
|
else
|
|
[ ];
|
|
|
|
configBinds = lib.mapAttrsToList (k: v: "${k}, ${v}") cfg.binds;
|
|
in
|
|
configBinds ++ workspaceBinds ++ windowManagementBinds;
|
|
|
|
bindm =
|
|
let
|
|
windowManagementBinds =
|
|
if cfg.generateWindowManagementBinds then [
|
|
"${cfg.mod}, mouse:272, movewindow"
|
|
"${cfg.mod}, mouse:273, resizewindow"
|
|
]
|
|
else
|
|
[ ];
|
|
|
|
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);
|
|
};
|
|
};
|
|
};
|
|
}
|