327 lines
9.9 KiB
Nix
327 lines
9.9 KiB
Nix
{
|
|
config,
|
|
pkgs,
|
|
lib,
|
|
makeEnable,
|
|
inputs,
|
|
...
|
|
}: let
|
|
system = pkgs.stdenv.hostPlatform.system;
|
|
hyprlandInput = inputs.hyprland;
|
|
baseHyprlandPackage = hyprlandInput.packages.${system}.hyprland;
|
|
cleanupStaleGraphicalSession = pkgs.writeShellScript "cleanup-stale-graphical-session" ''
|
|
set -u
|
|
|
|
# Only clean targets that are plainly stale. If a compositor is still
|
|
# running, let the active session own its own shutdown path.
|
|
if ${pkgs.procps}/bin/pgrep -u "$(${pkgs.coreutils}/bin/id -u)" -f '(^|/)(Hyprland|\.Hyprland-wrapped|river|kwin_wayland)( |$)' >/dev/null 2>&1; then
|
|
exit 0
|
|
fi
|
|
|
|
${pkgs.systemd}/bin/systemctl --user stop \
|
|
hyprland-session.target \
|
|
river-xmonad-session.target \
|
|
graphical-session.target \
|
|
graphical-session-pre.target \
|
|
tray.target \
|
|
2>/dev/null || true
|
|
|
|
${pkgs.systemd}/bin/systemctl --user unset-environment \
|
|
WAYLAND_DISPLAY \
|
|
DISPLAY \
|
|
XAUTHORITY \
|
|
HYPRLAND_INSTANCE_SIGNATURE \
|
|
XDG_CURRENT_DESKTOP \
|
|
XDG_SESSION_DESKTOP \
|
|
XDG_SESSION_TYPE \
|
|
IMALISON_SESSION_TYPE \
|
|
IMALISON_WINDOW_MANAGER \
|
|
2>/dev/null || true
|
|
|
|
${pkgs.systemd}/bin/systemctl --user reset-failed 2>/dev/null || true
|
|
'';
|
|
makeHyprlandLuaPackage = package:
|
|
(pkgs.symlinkJoin {
|
|
name = "${package.name}-lua-config";
|
|
inherit (package) version;
|
|
paths = [package];
|
|
passthru =
|
|
(package.passthru or {})
|
|
// {
|
|
providedSessions = package.passthru.providedSessions or ["hyprland"];
|
|
};
|
|
postBuild = ''
|
|
mkdir -p "$out/bin" "$out/share/wayland-sessions"
|
|
printf '%s\n' \
|
|
'#!${pkgs.runtimeShell}' \
|
|
'config_path="''${XDG_CONFIG_HOME:-$HOME/.config}/hypr/hyprland.lua"' \
|
|
'exec "${package}/bin/start-hyprland" --path "${package}/bin/Hyprland" -- --config "$config_path" "$@"' \
|
|
> "$out/bin/start-hyprland-lua"
|
|
chmod +x "$out/bin/start-hyprland-lua"
|
|
|
|
printf '%s\n' \
|
|
'#!${pkgs.runtimeShell}' \
|
|
'${cleanupStaleGraphicalSession}' \
|
|
'exec ${pkgs.uwsm}/bin/uwsm start -g -1 -e -D Hyprland hyprland.desktop' \
|
|
> "$out/bin/start-hyprland-uwsm-clean"
|
|
chmod +x "$out/bin/start-hyprland-uwsm-clean"
|
|
|
|
rm -f "$out/share/wayland-sessions/hyprland.desktop"
|
|
substitute \
|
|
"${package}/share/wayland-sessions/hyprland.desktop" \
|
|
"$out/share/wayland-sessions/hyprland.desktop" \
|
|
--replace-fail \
|
|
"Exec=${package}/bin/start-hyprland" \
|
|
"Exec=$out/bin/start-hyprland-lua"
|
|
|
|
rm -f "$out/share/wayland-sessions/hyprland-uwsm.desktop"
|
|
substitute \
|
|
"${package}/share/wayland-sessions/hyprland-uwsm.desktop" \
|
|
"$out/share/wayland-sessions/hyprland-uwsm.desktop" \
|
|
--replace-fail \
|
|
"Exec=uwsm start -e -D Hyprland hyprland.desktop" \
|
|
"Exec=$out/bin/start-hyprland-uwsm-clean"
|
|
'';
|
|
})
|
|
// {
|
|
override = {enableXWayland ? true, ...} @ args:
|
|
makeHyprlandLuaPackage (package.override args);
|
|
overrideAttrs = f: makeHyprlandLuaPackage (package.overrideAttrs f);
|
|
};
|
|
hyprlandPackage = makeHyprlandLuaPackage baseHyprlandPackage;
|
|
enableHyprglass = false;
|
|
hyprglass = pkgs.callPackage ./packages/hyprglass {
|
|
src = inputs.hyprglass;
|
|
hyprland = baseHyprlandPackage;
|
|
aquamarine = inputs.aquamarine.packages.${system}.aquamarine;
|
|
hyprcursor = inputs.hyprcursor.packages.${system}.hyprcursor;
|
|
hyprgraphics = inputs.hyprgraphics.packages.${system}.hyprgraphics;
|
|
hyprlang = inputs.hyprlang.packages.${system}.hyprlang;
|
|
hyprutils = inputs.hyprutils.packages.${system}.hyprutils;
|
|
};
|
|
hyprwobbly = inputs.hyprwobbly.packages.${system}.hyprwobbly.overrideAttrs (old: {
|
|
patches =
|
|
(old.patches or [])
|
|
++ [
|
|
./packages/hyprwobbly-safe-geometry-and-idle-timer.patch
|
|
];
|
|
});
|
|
hyprexpo = inputs.hyprexpo.packages.${system}.hyprexpo;
|
|
hyprlandPluginPackages =
|
|
[
|
|
inputs.hyprNStack.packages.${system}.hyprNStack
|
|
hyprexpo
|
|
inputs.hyprwinview.packages.${system}.hyprwinview
|
|
inputs.hypr-workspace-history.packages.${system}.hypr-workspace-history
|
|
hyprwobbly
|
|
]
|
|
++ lib.optionals enableHyprglass [hyprglass];
|
|
hyprRofiWindow = pkgs.writeShellApplication {
|
|
name = "hypr_rofi_window";
|
|
runtimeInputs = [
|
|
pkgs.python3
|
|
pkgs.rofi
|
|
hyprlandPackage
|
|
];
|
|
text = ''
|
|
exec python3 ${../dotfiles/lib/bin/hypr_rofi_window} "$@"
|
|
'';
|
|
};
|
|
hyprShellUi = pkgs.writeShellApplication {
|
|
name = "hypr_shell_ui";
|
|
runtimeInputs = [
|
|
pkgs.rofi
|
|
hyprRofiWindow
|
|
];
|
|
text = ''
|
|
exec ${../dotfiles/lib/bin/hypr_shell_ui} "$@"
|
|
'';
|
|
};
|
|
hyprRofiLayout = pkgs.writeShellApplication {
|
|
name = "hypr_rofi_layout";
|
|
runtimeInputs = [
|
|
pkgs.coreutils
|
|
pkgs.findutils
|
|
pkgs.gawk
|
|
pkgs.rofi
|
|
hyprlandPackage
|
|
];
|
|
text = ''
|
|
exec ${../dotfiles/lib/bin/hypr_rofi_layout} "$@"
|
|
'';
|
|
};
|
|
hyprRofiAction = pkgs.writeShellApplication {
|
|
name = "hypr_rofi_action";
|
|
runtimeInputs = [
|
|
pkgs.libnotify
|
|
pkgs.python3
|
|
pkgs.rofi
|
|
hyprlandPackage
|
|
];
|
|
text = ''
|
|
exec python3 ${../dotfiles/lib/bin/hypr_rofi_action} "$@"
|
|
'';
|
|
};
|
|
hyprscratchSettings = {
|
|
daemon_options = "clean";
|
|
global_options = "";
|
|
global_rules = "float;size monitor_w*0.95 monitor_h*0.95;center";
|
|
|
|
htop = {
|
|
command = "alacritty --class htop-scratch --title htop -e htop";
|
|
class = "htop-scratch";
|
|
};
|
|
|
|
volume = {
|
|
command = "pavucontrol";
|
|
class = "org.pulseaudio.pavucontrol";
|
|
};
|
|
|
|
spotify = {
|
|
command = "spotify";
|
|
class = "spotify";
|
|
};
|
|
|
|
element = {
|
|
command = "element-desktop";
|
|
class = "Element";
|
|
};
|
|
|
|
slack = {
|
|
command = "slack";
|
|
class = "Slack";
|
|
};
|
|
|
|
transmission = {
|
|
command = "transmission-gtk";
|
|
class = "transmission-gtk";
|
|
};
|
|
|
|
dropdown = {
|
|
command = "ghostty --config-file=/home/imalison/.config/ghostty/dropdown";
|
|
class = "com.mitchellh.ghostty.dropdown";
|
|
options = "persist";
|
|
rules = "float;size monitor_w monitor_h*0.5;move 0 60;noborder;noshadow;animation slide";
|
|
};
|
|
};
|
|
enabledModule = makeEnable config "myModules.hyprland" true {
|
|
myModules.taffybar.enable = lib.mkDefault true;
|
|
|
|
# Needed for hyprlock authentication without PAM fallback warnings.
|
|
security.pam.services.hyprlock = {};
|
|
|
|
# DDC/CI monitor control for keyboard-driven input switching.
|
|
hardware.i2c = {
|
|
enable = true;
|
|
group = "video";
|
|
};
|
|
|
|
programs.hyprland = {
|
|
enable = true;
|
|
# Keep Hyprland and plugins on a matched flake input for ABI compatibility.
|
|
package = hyprlandPackage;
|
|
# Let UWSM manage the Hyprland session targets
|
|
withUWSM = true;
|
|
};
|
|
|
|
home-manager.sharedModules = [
|
|
inputs.hyprscratch.homeModules.default
|
|
(
|
|
{
|
|
config,
|
|
lib,
|
|
...
|
|
}: {
|
|
services.kanshi = {
|
|
enable = true;
|
|
systemdTarget = "graphical-session.target";
|
|
settings = [
|
|
{
|
|
# USB-C connector names can move between DP-* ports across docks/reboots.
|
|
# Match the ultrawide by make/model and allow the serial field to vary.
|
|
profile.name = "ultrawide-usbc-desk";
|
|
profile.outputs = [
|
|
{
|
|
criteria = "eDP-1";
|
|
status = "enable";
|
|
mode = "2560x1600@240Hz";
|
|
position = "0,0";
|
|
scale = 1.0;
|
|
}
|
|
{
|
|
criteria = "Microstep MPG341CX OLED *";
|
|
status = "enable";
|
|
mode = "3440x1440@240Hz";
|
|
position = "2560,0";
|
|
scale = 1.0;
|
|
}
|
|
];
|
|
}
|
|
{
|
|
# When the laptop panel is unavailable (e.g. lid-closed docked use),
|
|
# still drive the ultrawide at its full refresh rate.
|
|
profile.name = "ultrawide-only";
|
|
profile.outputs = [
|
|
{
|
|
criteria = "Microstep MPG341CX OLED *";
|
|
status = "enable";
|
|
mode = "3440x1440@240Hz";
|
|
position = "0,0";
|
|
scale = 1.0;
|
|
}
|
|
];
|
|
}
|
|
];
|
|
};
|
|
|
|
programs.hyprscratch = {
|
|
enable = false;
|
|
settings = {};
|
|
};
|
|
|
|
xdg.configFile."hyprscratch/config.conf" = lib.mkIf false {
|
|
text = lib.hm.generators.toHyprconf {
|
|
attrs = hyprscratchSettings;
|
|
};
|
|
};
|
|
|
|
xdg.configFile."systemd/user/wayland-wm@hyprland.desktop.service.d/10-cleanup-stale-session.conf".text = ''
|
|
[Service]
|
|
ExecStopPost=${cleanupStaleGraphicalSession}
|
|
'';
|
|
}
|
|
)
|
|
];
|
|
|
|
# Hyprland-specific packages
|
|
environment.systemPackages = with pkgs;
|
|
[
|
|
# Hyprland utilities
|
|
hyprpaper # Wallpaper
|
|
neowall # Shader wallpaper
|
|
hypridle # Idle daemon
|
|
hyprlock # Screen locker
|
|
hyprcursor # Cursor themes
|
|
wl-clipboard # Clipboard for Wayland
|
|
wtype # Wayland input typing
|
|
cliphist # Clipboard history
|
|
grim # Screenshot utility
|
|
slurp # Region selection
|
|
swappy # Screenshot annotation
|
|
nwg-displays # GUI monitor arrangement
|
|
mpvpaper # Layer-shell video screensaver payload
|
|
ddcutil # Monitor input switching over DDC/CI
|
|
|
|
# For scripts
|
|
hyprRofiLayout
|
|
hyprRofiAction
|
|
hyprRofiWindow
|
|
hyprShellUi
|
|
jq
|
|
lua5_4 # lua/luac for validating Hyprland Lua config
|
|
]
|
|
++ hyprlandPluginPackages;
|
|
};
|
|
in
|
|
enabledModule
|