Add Hyprland configuration and scripts

This commit is contained in:
Chris Toph 2025-03-28 14:29:51 -04:00
parent bd3ccfabb4
commit 5502f71fc1
11 changed files with 277 additions and 87 deletions

View file

@ -106,13 +106,16 @@
# "SUPER_SHIFT, P, exec, ${notify} 'Toggled Pin'" # "SUPER_SHIFT, P, exec, ${notify} 'Toggled Pin'"
"SUPER_SHIFT, S, swapnext" "SUPER_SHIFT, S, swapnext"
# "SUPER_SHIFT, O, toggleopaque" # "SUPER_SHIFT, O, toggleopaque"
"SUPER, G, togglegroup"
# "SUPER, G, exec, ${notify} 'Toggled Group'"
"SUPER, Tab, changegroupactive, f"
# -- Workspaces -- # -- Workspaces --
", Home, overview:toggle" ", Home, overview:toggle"
# "SUPER, A, " # "SUPER, A, "
# TODO: use hycov for alt tab, https://github.com/bighu630/hycov # TODO: use hycov for alt tab, https://github.com/bighu630/hycov
"ALT, Tab, cyclenext," "ALT, Tab, cyclenext,"
"ALT, Tab, bringactivetotop," "ALT, Tab, bringactivetotop,"
]; ];
}; };

View file

@ -31,9 +31,8 @@
]; ];
settings = { settings = {
#
# ========== Environment Vars ========== ## Environment Vars ##
#
env = [ env = [
"NIXOS_OZONE_WL, 1" # for ozone-based and electron apps to run on wayland "NIXOS_OZONE_WL, 1" # for ozone-based and electron apps to run on wayland
"MOZ_ENABLE_WAYLAND, 1" # for firefox to run on wayland "MOZ_ENABLE_WAYLAND, 1" # for firefox to run on wayland
@ -46,120 +45,159 @@
]; ];
## Monitor ## ## Monitor ##
# parse the monitor spec defined in home/<user>/<host>/default.nix
monitor = ( monitor = (
# INFO: parse the monitors defined in home/<user>/<host>/default.nix
map ( map (
m: m:
"${m.name},${ "${m.name},${
if m.enabled then if m.enabled then
"${toString m.width}x${toString m.height}@${toString m.refreshRate},${toString m.x}x${toString m.y},1,transform,${toString m.transform},vrr,${toString m.vrr}" "${toString m.width}x${toString m.height}@${toString m.refreshRate},${toString m.x}x${toString m.y},${toString m.scale},transform,${toString m.transform},vrr,${toString m.vrr}"
else else
"disable" "disable"
}" }"
) (config.monitors) ) (config.monitors)
); );
#FIXME(hyprland): adapt this to work with new monitor module # I love this :)
#FIXME(hyprland): ws1 still appears on both DP-1 and DP-3 on reboot # Creates 5 workspaces for all monitors
# workspace = [ workspace =
# "1, monitor:DP-1, default:true, persistent:true" let
# "2, monitor:DP-1, default:true" json = pkgs.writeTextFile {
# "3, monitor:DP-1, default:true" name = "monitors.json";
# "4, monitor:DP-1, default:true" text = builtins.toJSON config.monitors;
# "5, monitor:DP-1, default:true" };
# "6, monitor:DP-1, default:true" parse = pkgs.runCommand "parse-workspaces" { } ''
# "7, monitor:DP-1, default:true" mkdir "$out"; ${pkgs.jq}/bin/jq -r '
# "8, monitor:DP-2, default:true, persistent:true" [ to_entries[] |
# "9, monitor:HDMI-A-1, default:true, persistent:true" (.key as $i | .value.name as $name |
# "0, monitor:DP-3, default:true, persistent:true" [ range(0;5) | ($i * 5 + .) as $wsnum |
# ]; if . == 0 then "\($wsnum), monitor:\($name), default:true, persistent:true"
else "\($wsnum), monitor:\($name)" end
]
)
] | flatten
' ${json} > "$out/out.json"
'';
output = builtins.fromJSON (builtins.readFile "${parse}/out.json");
in
output;
## Behavior ##
#
# ========== Behavior ==========
#
binds = { binds = {
workspace_center_on = 1; # Whether switching workspaces should center the cursor on the workspace (0) or on the last active window for that workspace (1) workspace_center_on = 1;
movefocus_cycles_fullscreen = false; # If enabled, when on a fullscreen window, movefocus will cycle fullscreen, if not, it will move the focus in a direction. movefocus_cycles_fullscreen = false;
}; };
input = { input = {
follow_mouse = 2; follow_mouse = 2;
# follow_mouse options:
# 0 - Cursor movement will not change focus.
# 1 - Cursor movement will always change focus to the window under the cursor.
# 2 - Cursor focus will be detached from keyboard focus. Clicking on a window will move keyboard focus to that window.
# 3 - Cursor focus will be completely separate from keyboard focus. Clicking on a window will not change keyboard focus.
mouse_refocus = false; mouse_refocus = false;
kb_options = "fkeys:basic_13-24"; kb_options = "fkeys:basic_13-24";
sensitivity = 0.5;
}; };
cursor.inactive_timeout = 10;
cursor = {
inactive_timeout = 10;
};
misc = { misc = {
disable_hyprland_logo = true; disable_hyprland_logo = true;
animate_manual_resizes = true; animate_manual_resizes = true;
animate_mouse_windowdragging = true; animate_mouse_windowdragging = true;
#disable_autoreload = true; #disable_autoreload = true;
new_window_takes_over_fullscreen = 2; # 0 - behind, 1 - takes over, 2 - unfullscreen/unmaxize new_window_takes_over_fullscreen = 2;
middle_click_paste = false; middle_click_paste = false;
}; };
# group = {
# ========== Appearance ========== drag_into_group = 2;
# merge_groups_on_drag = true;
#FIXME-rice colors conflict with stylix # col.border_active = "";
# col.border_inactive = "";
groupbar = {
enabled = true;
height = 12;
};
};
dwindle = {
pseudotile = false;
force_split = 0;
smart_split = true;
split_bias = 1;
};
## Appearance ##
general = { general = {
border_size = 2;
gaps_in = 6; gaps_in = 6;
gaps_out = 6; gaps_out = 6;
border_size = 0; "col.inactive_border" = "0x44e3625e";
#col.inactive-border = "0x00000000"; "col.active_border" = "0x20e3625e";
#col.active-border = "0x0000000";
resize_on_border = true;
hover_icon_on_border = true;
allow_tearing = true; # used to reduce latency and/or jitter in games allow_tearing = true; # used to reduce latency and/or jitter in games
snap = {
enabled = true;
window_gap = 6;
};
}; };
decoration = { decoration = {
active_opacity = 1.0;
inactive_opacity = 0.85;
fullscreen_opacity = 1.0;
rounding = 10; rounding = 10;
rounding_power = 4.0;
active_opacity = 0.90;
inactive_opacity = 0.80;
fullscreen_opacity = 1.0;
blur = { blur = {
enabled = true; enabled = true;
size = 4; size = 15;
passes = 2; passes = 2;
new_optimizations = true; new_optimizations = true;
ignore_opacity = true;
xray = true;
# noise = 0.15;
popups = true; popups = true;
}; };
shadow = { shadow = {
enabled = true; enabled = true;
range = 12; range = 30;
offset = "3 3"; render_power = 3;
#color = "0x88ff9400"; scale = 1.0;
#color_inactive = "0x8818141d"; color = "0x66000000";
color_inactive = "0x66000000";
}; };
}; };
# group = {
#groupbar = {
# };
#};
# animation = [
# ========== Auto Launch ========== "windowsIn, 1, 5 ,default, popin 0%"
# "windowsOut, 1, 5 ,default, popin"
# exec-once = ''${startupScript}/path''; "windowsMove, 1, 5 ,default, slide"
# To determine path, run `which foo` "fadeIn, 1, 8 ,default"
"fadeOut, 1, 8 ,default"
"fadeSwitch, 1, 8 ,default"
"fadeShadow, 1, 8 ,default"
"fadeDim, 1, 8 ,default"
"border, 1, 10 ,default"
"workspaces, 1, 5 ,default, slide"
];
## Auto Launch ##
exec-once = [ exec-once = [
''${pkgs.waypaper}/bin/waypaper --restore'' ''${pkgs.waypaper}/bin/waypaper --restore''
]; ];
#
# ========== Layer Rules ========== ## Layers Rules ##
#
layer = [ layer = [
#"blur, rofi" #"blur, rofi"
#"ignorezero, rofi" #"ignorezero, rofi"
#"ignorezero, logout_dialog" #"ignorezero, logout_dialog"
]; ];
#
# ========== Window Rules ========== ## Window Rules ##
#
windowrule = [ windowrule = [
# Dialogs # Dialogs
"float, title:^(Open File)(.*)$" "float, title:^(Open File)(.*)$"
@ -170,7 +208,11 @@
"float, title:^(Library)(.*)$" "float, title:^(Library)(.*)$"
"float, title:^(Accounts)(.*)$" "float, title:^(Accounts)(.*)$"
]; ];
windowrulev2 = [ windowrulev2 = [
#Zen Extensions
"suppressevent maximize, class:^(zen)$"
"float, class:^(galculator)$" "float, class:^(galculator)$"
"float, class:^(waypaper)$" "float, class:^(waypaper)$"
"float, class:^(keymapp)$" "float, class:^(keymapp)$"
@ -220,14 +262,14 @@
# #
# ========== Workspace Assignments ========== # ========== Workspace Assignments ==========
# #
"workspace 8, class:^(virt-manager)$" # "workspace 8, class:^(virt-manager)$"
"workspace 8, class:^(obsidian)$" # "workspace 8, class:^(obsidian)$"
"workspace 9, class:^(brave-browser)$" # "workspace 9, class:^(brave-browser)$"
"workspace 9, class:^(signal)$" # "workspace 9, class:^(signal)$"
"workspace 9, class:^(org.telegram.desktop)$" # "workspace 9, class:^(org.telegram.desktop)$"
"workspace 9, class:^(discord)$" # "workspace 9, class:^(discord)$"
"workspace 0, title:^([Ss]potify*)$" # "workspace 0, title:^([Ss]potify*)$"
"workspace special, class:^(yubioath-flutter)$" # "workspace special, class:^(yubioath-flutter)$"
]; ];
# load at the end of the hyperland set # load at the end of the hyperland set

View file

@ -27,7 +27,7 @@
font = { font = {
name = "Sans"; name = "Sans";
size = 14; size = 12;
}; };
}; };
} }

View file

@ -1 +1,4 @@
{ } { lib, ... }:
{
imports = lib.custom.scanPaths ./.;
}

View file

@ -0,0 +1,78 @@
{ pkgs, lib, ... }:
let
zen-extensions = {
bitwarden = {
regex = "'*(Bitwarden Password Manager) - Bitwarden*'";
x = 500;
y = 900;
};
authenticator = {
regex = "'*(Authenticator) - Authenticator*'";
x = 335;
y = 525;
};
};
zen-json = pkgs.writeText "zen-extensions.json" (builtins.toJSON zen-extensions);
zen-script = pkgs.writeScript "zen-script" ''
#!/usr/bin/env fish
function handle
set -l line $argv[1]
switch $line
case "windowtitlev2*"
# Expected format: windowtitlev2>><id>,<title>
set -l payload (string replace -r '^windowtitlev2>>' "" $line)
set -l parts (string split "," $payload)
set -l window_id (string trim $parts[1])
set -l title (string join "," $parts[2..-1])
# Debug output
echo "Extracted window_id: [$window_id]"
echo "Extracted title: [$title]"
# Loop over the extensions defined in the JSON file.
for ext in ( ${pkgs.jq}/bin/jq -r 'keys[]' ${zen-json} )
echo "Processing extension: [$ext]"
# Get regex, x and y for the current extension.
set -l reg ( ${pkgs.jq}/bin/jq -r --arg k $ext '.[$k].regex' ${zen-json} )
set -l ext_x ( ${pkgs.jq}/bin/jq -r --arg k $ext '.[$k].x' ${zen-json} )
set -l ext_y ( ${pkgs.jq}/bin/jq -r --arg k $ext '.[$k].y' ${zen-json} )
# Remove any extra surrounding single quotes.
set -l reg (string trim -c "'" $reg)
# Debug: show the extension and regex being used.
echo "Checking extension [$ext] with regex [$reg] against title [$title]"
# If the title matches the regex, dispatch floating commands.
if string match -q -- "*$reg*" "$title"
echo "$ext window id: $window_id -- setting float mode with size $ext_x x $ext_y"
hyprctl --batch "dispatch togglefloating address:0x$window_id; dispatch resizewindowpixel exact $ext_x $ext_y,address:0x$window_id; dispatch movewindowpixel exact 64% 3%,address:0x$window_id"
return
end
end
;;
case "*"
# Do nothing for other events.
;;
end
end
${pkgs.socat}/bin/socat -U - UNIX-CONNECT:/run/user/1000/hypr/$HYPRLAND_INSTANCE_SIGNATURE/.socket2.sock | while read -l line
handle "$line"
end
'';
in
{
wayland.windowManager.hyprland.settings = {
exec-once = [
"${pkgs.fish}/bin/fish ${zen-script}"
];
windowrulev2 = [
# Zen Extensions
"suppressevent maximize, class:^(zen)$"
];
};
}

View file

@ -11,7 +11,8 @@
## Host-specific Optional Configs ## ## Host-specific Optional Configs ##
../common/optional/browsers ../common/optional/browsers
../common/optional/gnome # ../common/optional/gnome
../common/optional/hyprland
../common/optional/development ../common/optional/development
../common/optional/gaming ../common/optional/gaming
../common/optional/xdg.nix # file associations ../common/optional/xdg.nix # file associations
@ -36,7 +37,6 @@
bitwarden-desktop bitwarden-desktop
inspector inspector
remmina remmina
wezterm
vial # KB setup vial # KB setup
## Productivity ## ## Productivity ##
@ -45,6 +45,31 @@
; ;
}; };
monitors = [
{
name = "DP-3";
x = 900;
y = 0;
width = 3840;
height = 2160;
refreshRate = 120;
primary = true;
scale = 1.20;
vrr = 2;
}
{
name = "HDMI-A-2";
x = 0;
y = 0;
width = 1920;
height = 1080;
refreshRate = 60;
primary = false;
transform = 3;
scale = 1.20;
}
];
# home.file = { # home.file = {
# "run-mac.sh".source = config.lib.file.mkOutOfStoreSymlink "${pkgs.macos-ventura-image.runScript}"; # "run-mac.sh".source = config.lib.file.mkOutOfStoreSymlink "${pkgs.macos-ventura-image.runScript}";
# }; # };

View file

@ -35,10 +35,11 @@ in
# System-wide packages, in case we log in as root # System-wide packages, in case we log in as root
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
micro micro
plocate
openssh openssh
plocate
ranger ranger
sshfs sshfs
wget
]; ];
# Enable CUPS to print documents. # Enable CUPS to print documents.
@ -108,7 +109,7 @@ in
]; ];
## NIX NIX NIX ## ## NIX NIX NIX ##
documentation.nixos.enable = false; documentation.nixos.enable = lib.mkForce false;
nix = { nix = {
# This will add each flake input as a registry # This will add each flake input as a registry
# To make nix3 commands consistent with your flake # To make nix3 commands consistent with your flake

View file

@ -0,0 +1,16 @@
{
programs.foot = {
enable = true;
settings = {
main = {
term = "xterm-256color";
font = "monospace:size=10";
dpi-aware = "yes";
};
mouse = {
hide-when-typing = "yes";
};
};
};
}

View file

@ -0,0 +1,22 @@
{ pkgs, ... }:
{
environment.systemPackages = with pkgs; [
file-roller
nautilus
];
services = {
# needed for GNOME services outside of GNOME Desktop
dbus.packages = with pkgs; [
gcr
gnome-keyring
gnome-settings-daemon
gvfs
];
gnome.gnome-keyring.enable = true;
gvfs.enable = true;
};
}

View file

@ -33,7 +33,8 @@ in
"hosts/common/optional/bluetooth.nix" "hosts/common/optional/bluetooth.nix"
"hosts/common/optional/ddcutil.nix" # ddcutil for monitor controls "hosts/common/optional/ddcutil.nix" # ddcutil for monitor controls
"hosts/common/optional/gaming.nix" # steam, gamescope, gamemode, and related hardware "hosts/common/optional/gaming.nix" # steam, gamescope, gamemode, and related hardware
"hosts/common/optional/gnome.nix" # desktop # "hosts/common/optional/gnome.nix" # desktop
"hosts/common/optional/hyprland" # desktop
"hosts/common/optional/libvirt.nix" # vm tools "hosts/common/optional/libvirt.nix" # vm tools
"hosts/common/optional/nvtop.nix" # GPU monitor (not available in home-manager) "hosts/common/optional/nvtop.nix" # GPU monitor (not available in home-manager)
"hosts/common/optional/plymouth.nix" # fancy boot screen "hosts/common/optional/plymouth.nix" # fancy boot screen
@ -67,10 +68,6 @@ in
programs.nix-ld.enable = true; programs.nix-ld.enable = true;
environment.systemPackages = with pkgs; [ environment.systemPackages = with pkgs; [
asdf-vm asdf-vm
openssh
ranger
sshfs
wget
]; ];
# https://wiki.nixos.org/wiki/FAQ/When_do_I_update_stateVersion # https://wiki.nixos.org/wiki/FAQ/When_do_I_update_stateVersion

View file

@ -3,6 +3,7 @@
# to /etc/nixos/configuration.nix instead. # to /etc/nixos/configuration.nix instead.
{ {
pkgs,
config, config,
lib, lib,
modulesPath, modulesPath,
@ -24,6 +25,9 @@
timeout = 3; timeout = 3;
}; };
# use latest kernel
kernelPackages = pkgs.linuxPackages_latest;
initrd = { initrd = {
systemd.enable = true; systemd.enable = true;
verbose = false; verbose = false;
@ -61,8 +65,7 @@
}; };
"/pool" = { "/pool" = {
# FIXME: admin does not work here anymore device = "${config.hostSpec.username}@cloud:/pool";
device = "${config.hostSpec.username}@104.40.4.24:/pool";
fsType = "sshfs"; fsType = "sshfs";
options = [ options = [
"defaults" "defaults"