1

Modules/Hyprland: Deprecate hyprland module

This commit is contained in:
2026-03-20 14:04:16 +01:00
parent 6e999ffa02
commit e83c1df409
23 changed files with 436 additions and 1165 deletions

View File

@ -0,0 +1,31 @@
{
lib,
pkgs,
config,
hyprland,
}:
builtins.concatLists [
(lib.optionals hyprland.dunst.enable ["dunst"]) # Notifications
(lib.optionals hyprland.hyprpanel.enable ["hyprpanel"]) # Panel
(lib.optionals hyprland.caelestia.enable ["caelestia shell"]) # Panel/Shell # TODO: Crashes on startup
[
# Start clipboard management
"wl-paste -t text --watch clipman store --no-persist"
"wl-paste -p -t text --watch clipman store -P --histpath=\"~/.local/share/clipman-primary.json\""
"hyprctl setcursor ${config.home.pointerCursor.name} ${builtins.toString config.home.pointerCursor.size}"
"hyprsunset --identity"
# HACK: Hyprland doesn't set the xwayland/x11 keymap correctly
"setxkbmap -layout ${hyprland.keyboard.layout} -variant ${hyprland.keyboard.variant} -option ${hyprland.keyboard.option} -model pc104"
# HACK: Flatpak doesn't find applications in the system PATH
"systemctl --user import-environment PATH && systemctl --user restart xdg-desktop-portal.service"
# Provide a polkit authentication UI.
# This is used for example when running systemd commands without root.
# "systemctl --user start hyprpolkitagent.service"
# "${pkgs.kdePackages.polkit-kde-agent-1}/libexec/polkit-kde-authentication-agent-1"
"${pkgs.polkit_gnome}/libexec/polkit-gnome-authentication-agent-1"
]
]

View File

@ -0,0 +1,516 @@
{
config,
hyprland,
color,
}: {
enable = hyprland.caelestia.enable;
systemd = {
enable = false; # Start from hyprland autostart
target = "graphical-session.target";
environment = [];
};
settings = {
appearance = {
anim = {durations = {scale = 1;};};
font = {
family = {
clock = "Rubik";
material = "Material Symbols Rounded";
mono = color.font;
sans = color.font;
};
size = {scale = 1;};
};
padding = {scale = 1;};
rounding = {scale = 1;};
spacing = {scale = 1;};
transparency = {
base = 0.85;
enabled = false;
layers = 0.4;
};
};
background = {
desktopClock = {enabled = false;};
enabled = true;
# Lags when visible on both monitors (different refresh rates?)
visualiser = {
autoHide = true;
blur = true;
enabled = false;
rounding = 1;
spacing = 1;
};
};
bar = {
clock = {showIcon = true;};
dragThreshold = 20;
entries = [
{
enabled = true;
id = "logo";
}
{
enabled = true;
id = "workspaces";
}
{
enabled = true;
id = "spacer";
}
{
enabled = true;
id = "activeWindow";
}
{
enabled = true;
id = "spacer";
}
{
enabled = true;
id = "clock";
}
{
enabled = true;
id = "tray";
}
{
enabled = true;
id = "statusIcons";
}
{
enabled = true;
id = "power";
}
];
persistent = true;
popouts = {
activeWindow = true;
statusIcons = true;
tray = true;
};
scrollActions = {
brightness = false;
volume = true;
workspaces = true;
};
showOnHover = true;
status = {
showAudio = true;
showBattery = false;
showBluetooth = true;
showKbLayout = false;
showLockStatus = true;
showMicrophone = false;
showNetwork = true;
};
tray = {
background = true;
compact = false;
iconSubs = [];
recolour = false;
};
workspaces = {
activeIndicator = true;
activeLabel = "󰮯";
activeTrail = true;
label = " ";
occupiedBg = false;
occupiedLabel = "󰮯";
perMonitorWorkspaces = false;
showWindows = false;
shown = 10;
# Pick them here: https://fonts.google.com/icons
specialWorkspaceIcons = [
{
icon = "music_note";
name = "rmpc";
}
{
icon = "memory";
name = "btop";
}
{
icon = "mark_chat_unread";
name = "ferdium";
}
{
icon = "network_intelligence";
name = "msty";
}
];
};
};
border = {
rounding = 25;
thickness = 10;
};
dashboard = {
dragThreshold = 50;
enabled = true;
mediaUpdateInterval = 500;
showOnHover = true;
};
general = {
apps = {
audio = ["kitty" "--title=NcpaMixer" "-e" "ncpamixer"];
explorer = ["kitty" "--title=Yazi" "-e" "yazi"];
playback = ["mpv"];
terminal = ["kitty"];
};
battery = {
criticalLevel = 3;
warnLevels = [
{
icon = "battery_android_frame_2";
level = 20;
message = "You might want to plug in a charger";
title = "Low battery";
}
{
icon = "battery_android_frame_1";
level = 10;
message = "You should probably plug in a charger <b>now</b>";
title = "Did you see the previous message?";
}
{
critical = true;
icon = "battery_android_alert";
level = 5;
message = "PLUG THE CHARGER RIGHT NOW!!";
title = "Critical battery level";
}
];
};
idle = {
inhibitWhenAudio = true;
lockBeforeSleep = true;
timeouts = [
{
idleAction = "lock";
timeout = 600;
}
{
# idleAction = "dpms off";
# returnAction = "dpms on";
idleAction = "echo 'idle'";
returnAction = "echo 'return'";
timeout = 10000;
}
{
# idleAction = ["systemctl" "suspend-then-hibernate"];
idleAction = ["echo" "'idle'"];
timeout = 20000;
}
];
};
};
launcher = {
actionPrefix = ">";
actions = [
{
command = ["autocomplete" "calc"];
dangerous = false;
description = "Do simple math equations (powered by Qalc)";
enabled = true;
icon = "calculate";
name = "Calculator";
}
{
command = ["autocomplete" "scheme"];
dangerous = false;
description = "Change the current colour scheme";
enabled = true;
icon = "palette";
name = "Scheme";
}
{
command = ["autocomplete" "wallpaper"];
dangerous = false;
description = "Change the current wallpaper";
enabled = true;
icon = "image";
name = "Wallpaper";
}
{
command = ["autocomplete" "variant"];
dangerous = false;
description = "Change the current scheme variant";
enabled = true;
icon = "colors";
name = "Variant";
}
{
command = ["autocomplete" "transparency"];
dangerous = false;
description = "Change shell transparency";
enabled = false;
icon = "opacity";
name = "Transparency";
}
{
command = ["caelestia" "wallpaper" "-r"];
dangerous = false;
description = "Switch to a random wallpaper";
enabled = false;
icon = "casino";
name = "Random";
}
{
command = ["setMode" "light"];
dangerous = false;
description = "Change the scheme to light mode";
enabled = true;
icon = "light_mode";
name = "Light";
}
{
command = ["setMode" "dark"];
dangerous = false;
description = "Change the scheme to dark mode";
enabled = true;
icon = "dark_mode";
name = "Dark";
}
{
command = ["systemctl" "poweroff"];
dangerous = true;
description = "Shutdown the system";
enabled = true;
icon = "power_settings_new";
name = "Shutdown";
}
{
command = ["systemctl" "reboot"];
dangerous = true;
description = "Reboot the system";
enabled = true;
icon = "cached";
name = "Reboot";
}
{
command = ["loginctl" "terminate-user" ""];
dangerous = true;
description = "Log out of the current session";
enabled = true;
icon = "exit_to_app";
name = "Logout";
}
{
command = ["loginctl" "lock-session"];
dangerous = false;
description = "Lock the current session";
enabled = true;
icon = "lock";
name = "Lock";
}
{
command = ["systemctl" "suspend-then-hibernate"];
dangerous = false;
description = "Suspend then hibernate";
enabled = false;
icon = "bedtime";
name = "Sleep";
}
];
dragThreshold = 50;
enableDangerousActions = true;
hiddenApps = [];
maxShown = 7;
maxWallpapers = 9;
showOnHover = false;
specialPrefix = "@";
useFuzzy = {
actions = false;
apps = false;
schemes = false;
variants = false;
wallpapers = false;
};
vimKeybinds = false;
};
lock = {recolourLogo = false;};
notifs = {
actionOnClick = false;
clearThreshold = 0.3;
defaultExpireTimeout = 5000;
expandThreshold = 20;
expire = true;
};
osd = {
enableBrightness = false;
enableMicrophone = true;
enabled = true;
hideDelay = 2000;
};
paths = {
mediaGif = "root:/assets/bongocat.gif";
sessionGif = "root:/assets/kurukuru.gif";
wallpaperDir = "~/NixFlake/wallpapers";
};
services = {
audioIncrement = 0.1;
defaultPlayer = "MPD";
gpuType = "";
maxVolume = 1;
playerAliases = [
{
from = "com.github.th_ch.youtube_music";
to = "YT Music";
}
];
smartScheme = true;
useFahrenheit = false;
useTwelveHourClock = false;
visualiserBars = 45;
weatherLocation = "Dortmund, Germany";
};
session = {
commands = {
hibernate = ["systemctl" "hibernate"];
logout = ["loginctl" "terminate-user" ""];
reboot = ["systemctl" "reboot"];
shutdown = ["systemctl" "poweroff"];
};
dragThreshold = 30;
enabled = true;
vimKeybinds = false;
};
sidebar = {
dragThreshold = 80;
enabled = true;
};
utilities = {
enabled = true;
maxToasts = 4;
toasts = {
audioInputChanged = true;
audioOutputChanged = true;
capsLockChanged = true;
chargingChanged = true;
configLoaded = true;
dndChanged = true;
gameModeChanged = true;
kbLayoutChanged = false;
nowPlaying = false;
numLockChanged = true;
vpnChanged = true;
};
vpn = {
enabled = false;
provider = [
{
displayName = "Wireguard (Your VPN)";
interface = "your-connection-name";
name = "wireguard";
}
];
};
};
};
cli = {
enable = hyprland.caelestia.enable;
settings = {
record = {extraArgs = [];};
theme = {
enableBtop = false;
enableDiscord = false;
enableFuzzel = false;
enableGtk = false;
enableHypr = false;
enableQt = false;
enableSpicetify = false;
enableTerm = false;
};
toggles = {
communication = {
discord = {
command = ["discord"];
enable = false;
match = [{class = "discord";}];
move = true;
};
whatsapp = {
enable = false;
match = [{class = "whatsapp";}];
move = true;
};
};
music = {
feishin = {
enable = false;
match = [{class = "feishin";}];
move = true;
};
spotify = {
command = ["spicetify" "watch" "-s"];
enable = false;
match = [{class = "Spotify";} {initialTitle = "Spotify";} {initialTitle = "Spotify Free";}];
move = true;
};
};
sysmon = {
btop = {
command = ["kitty" "--title" "Btop" "-e" "btop"];
enable = false;
match = [
{
class = "btop";
title = "Btop";
workspace = {name = "special:sysmon";};
}
];
};
};
todo = {
todoist = {
command = ["todoist"];
enable = false;
match = [{class = "Todoist";}];
move = true;
};
};
};
wallpaper = {postHook = "echo $WALLPAPER_PATH";};
};
};
}

View File

@ -0,0 +1,180 @@
{
inputs,
config,
lib,
mylib,
pkgs,
nixosConfig,
username,
...
}: let
inherit (config.homemodules) hyprland color;
# Autostart programs
always-exec = import ./autostart.nix {inherit lib pkgs config hyprland;};
# Keybindings
always-bind = import ./mappings.nix {inherit lib config hyprland;};
# Mousebindings
always-bindm = {
"$mainMod, mouse:272" = ["movewindow"];
"$mainMod, mouse:273" = ["resizewindow"];
};
in {
options.homemodules.hyprland = import ./options.nix {inherit lib mylib;};
config = lib.mkIf hyprland.enable {
assertions = [
{
assertion = nixosConfig.programs.hyprland.enable;
message = "Can't enable Hyprland module with Hyprland disabled!";
}
{
assertion = builtins.hasAttr "hyprlock" nixosConfig.security.pam.services;
message = "Can't enable Hyprland module without Hyprlock PAM service!";
}
{
assertion = hyprland.hyprpanel.enable != hyprland.caelestia.enable;
message = "Can't enable Hyprpanel and Caelestia at the same time!";
}
];
gtk = {
enable = true;
iconTheme.package = lib.mkDefault color.iconPackage;
iconTheme.name = color.iconTheme;
};
homemodules = {
hyprpanel.enable = hyprland.hyprpanel.enable;
};
home = {
pointerCursor = {
gtk.enable = lib.mkDefault true;
x11.enable = lib.mkDefault true;
package = lib.mkDefault color.cursorPackage;
name = color.cursor;
size = color.cursorSize;
};
packages = with pkgs; [
hyprpaper # Wallpaper setter
hyprpicker # Color picker
# hyprpolkitagent # Ugly polkit authentication GUI
hyprland-qt-support
hyprsunset # Blue light filter
wl-clipboard
clipman # Clipboard manager (wl-paste)
libnotify
inotify-tools # Includes inotifywait
ncpamixer # Audio control
slurp # Region selector for screensharing
grim # Grab images from compositor
# Deps for Qt5 and Qt6 apps (e.g., Nextcloud)
qt5.qtwayland
qt6.qtwayland
];
file = {
".config/hypr/keybindings.info".text = let
fixupHomeDir = key:
builtins.replaceStrings ["/home/${username}"] ["~"] key;
fixupNixStore = key: let
# The pattern has to match the entire string, otherwise it won't work
matches = builtins.match ".*/nix/store/(.*)/.*" key;
in
if (matches == null)
then key
else builtins.replaceStrings matches ["..."] key;
fixupNoMod = key:
builtins.replaceStrings ["<-"] ["<"] key;
mkBindHelpKey = key:
builtins.replaceStrings ["$mainMod" " " ","] ["${hyprland.keybindings.main-mod}" "-" ""] key;
mkBindHelpAction = action:
builtins.replaceStrings [","] [""] action;
mkBindHelp = key: action: "<${mkBindHelpKey key}>: ${mkBindHelpAction action}";
mkBindsHelp = key: actions:
actions
|> builtins.map (mkBindHelp key)
|> builtins.map fixupNoMod
|> builtins.map fixupNixStore
|> builtins.map fixupHomeDir;
in
(hyprland.keybindings.bindings // always-bind)
|> builtins.mapAttrs mkBindsHelp
|> builtins.attrValues
|> builtins.concatLists
|> builtins.concatStringsSep "\n";
};
};
programs = {
hyprlock = import ./hyprlock.nix {inherit config hyprland color;};
caelestia = import ./caelestia.nix {inherit config hyprland color;};
};
services = {
dunst = import ./dunst.nix {inherit pkgs config hyprland color;};
hypridle = import ./hypridle.nix {inherit config hyprland color;};
hyprpaper = import ./hyprpaper.nix {inherit config hyprland color;};
};
# Make sure the units only start when using Hyprland
systemd.user.services.dunst.Unit.After = lib.mkIf hyprland.dunst.enable (lib.mkForce ["hyprland-session.target"]);
systemd.user.services.dunst.Unit.PartOf = lib.mkIf hyprland.dunst.enable (lib.mkForce ["hyprland-session.target"]);
systemd.user.services.hypridle.Install.WantedBy = lib.mkIf (!hyprland.caelestia.enable) (lib.mkForce ["hyprland-session.target"]);
systemd.user.services.hypridle.Unit.After = lib.mkIf (!hyprland.caelestia.enable) (lib.mkForce ["hyprland-session.target"]);
systemd.user.services.hypridle.Unit.PartOf = lib.mkIf (!hyprland.caelestia.enable) (lib.mkForce ["hyprland-session.target"]);
systemd.user.services.hyprpaper.Install.WantedBy = lib.mkIf (!hyprland.caelestia.enable) (lib.mkForce ["hyprland-session.target"]);
systemd.user.services.hyprpaper.Unit.After = lib.mkIf (!hyprland.caelestia.enable) (lib.mkForce ["hyprland-session.target"]);
systemd.user.services.hyprpaper.Unit.PartOf = lib.mkIf (!hyprland.caelestia.enable) (lib.mkForce ["hyprland-session.target"]);
wayland.windowManager.hyprland = {
enable = true;
package = inputs.hyprland.packages.${pkgs.stdenv.hostPlatform.system}.hyprland;
portalPackage = inputs.hyprland.packages.${pkgs.stdenv.hostPlatform.system}.xdg-desktop-portal-hyprland;
systemd.enable = true; # Enable hyprland-session.target
systemd.variables = ["--all"]; # Import PATH into systemd
xwayland.enable = true;
plugins = builtins.concatLists [
(lib.optionals
hyprland.bars.enable
[inputs.hyprland-plugins.packages.${pkgs.stdenv.hostPlatform.system}.hyprbars])
(lib.optionals
hyprland.dynamicCursor.enable
[inputs.hypr-dynamic-cursors.packages.${pkgs.stdenv.hostPlatform.system}.hypr-dynamic-cursors])
(lib.optionals
hyprland.trails.enable
[inputs.hyprland-plugins.packages.${pkgs.stdenv.hostPlatform.system}.hyprtrails])
(lib.optionals
hyprland.hyprspace.enable
[inputs.hyprspace.packages.${pkgs.stdenv.hostPlatform.system}.Hyprspace])
];
settings = import ./settings.nix {
inherit
lib
config
hyprland
color
always-exec
always-bind
always-bindm
;
};
};
};
}

View File

@ -0,0 +1,36 @@
{
pkgs,
config,
hyprland,
color,
}: {
enable = hyprland.dunst.enable;
iconTheme.package = color.iconPackage;
iconTheme.name = color.iconTheme;
settings = {
global = {
monitor = config.homemodules.waybar.monitor;
font = "${color.font} 11";
offset = "10x10";
background = color.hexS.base;
foreground = color.hexS.text;
frame_width = 2;
corner_radius = 6;
separator_color = "frame";
};
urgency_low = {
frame_color = color.hexS.green;
};
urgency_normal = {
frame_color = color.hexS.green;
};
urgency_critical = {
frame_color = color.hexS.red;
};
};
}

View File

@ -0,0 +1,28 @@
{
config,
hyprland,
color,
}: {
enable = !hyprland.caelestia.enable;
settings = {
general = {
# DPMS - Display Powermanagement Signaling. "On" means the monitor is on.
after_sleep_cmd = "hyprctl dispatch dpms on";
ignore_dbus_inhibit = false;
lock_cmd = "hyprlock";
};
listener = [
{
timeout = 900;
on-timeout = "hyprlock";
}
{
timeout = 1200;
on-timeout = "hyprctl dispatch dpms off";
on-resume = "hyprctl dispatch dpms on";
}
];
};
}

View File

@ -0,0 +1,44 @@
{
keyboard = {
layout = "us";
variant = "altgr-intl";
option = "nodeadkeys";
};
monitors = {
"DP-1" = {
width = 3440;
height = 1440;
rate = 165;
x = 1920;
y = 0;
scale = 1;
};
"DP-2" = {
width = 1920;
height = 1080;
rate = 60;
x = 0;
y = 0;
scale = 1;
};
};
workspaces = {
"DP-1" = [1 2 3 4 5 6 7 8 9];
"DP-2" = [10];
};
autostart = {
delayed = [
"fcitx5"
];
};
floating = [
{
class = "fcitx";
}
];
}

View File

@ -0,0 +1,186 @@
{
nixosConfig,
config,
lib,
pkgs,
}: {
enable = nixosConfig.programs.hyprland.enable;
dunst.enable = !config.homemodules.hyprpanel.enable; # Disable for hyprpanel
bars.enable = false;
dynamicCursor.enable = false;
trails.enable = true;
hyprspace.enable = false; # Always broken
hyprpanel.enable = true;
caelestia.enable = false;
keybindings = {
main-mod = "SUPER";
bindings = lib.mergeAttrsList [
# Use Rofi if we don't have caelestia
(lib.optionalAttrs (!config.homemodules.hyprland.caelestia.enable) {
"$mainMod, a" = ["exec, rofi -drun-show-actions -show drun"];
"$mainMod, c" = ["exec, clipman pick --tool=rofi"];
"$mainMod SHIFT, l" = ["exec, loginctl lock-session"];
})
# Caelestia
(lib.optionalAttrs (config.homemodules.hyprland.caelestia.enable) {
"$mainMod, a" = ["exec, caelestia shell drawers toggle launcher"];
# "$mainMod, c" = ["exec, caelestia clipboard"];
"$mainMod SHIFT, l" = ["exec, caelestia shell lock lock"];
"$mainMod, escape" = ["exec, caelestia shell drawers toggle session"];
})
{
# Applications
"$mainMod, t" = ["exec, kitty"];
"$mainMod, e" = ["exec, kitty --title=Yazi yazi"];
"$mainMod, n" = ["exec, neovide"];
# "$mainMod, r" = ["exec, kitty --title=Rmpc rmpc"];
"$mainMod CTRL, n" = ["exec, kitty --title=Navi navi"];
"$mainMod SHIFT, n" = ["exec, neovide ${config.paths.dotfiles}/navi/christoph.cheat"];
"$mainMod SHIFT, f" = ["exec, neovide ${config.paths.dotfiles}/flake.nix"];
# "ALT, tab" = ["exec, rofi -show window"];
# Screenshots
"$mainMod, p" = ["exec, hyprpicker --autocopy --format=hex"];
"$mainMod, s" = ["exec, grim -g \"$(slurp)\""];
"$mainMod SHIFT, s" = ["exec, grim -g \"$(slurp)\" - | wl-copy"];
# Audio
", XF86AudioRaiseVolume" = ["exec, wpctl set-volume -l 1.5 @DEFAULT_AUDIO_SINK@ 5%+"];
", XF86AudioLowerVolume" = ["exec, wpctl set-volume -l 1.5 @DEFAULT_AUDIO_SINK@ 5%-"];
", XF86AudioPlay" = ["exec, playerctl play-pause"];
", XF86AudioPrev" = ["exec, playerctl previous"];
", XF86AudioNext" = ["exec, playerctl next"];
# Brightness
", XF86MonBrightnessDown" = ["exec, hyprctl hyprsunset gamma -10"];
", XF86MonBrightnessUp" = ["exec, hyprctl hyprsunset gamma +10"];
"$mainMod, XF86MonBrightnessDown" = ["exec, hyprctl hyprsunset temperature 5750"];
"$mainMod, XF86MonBrightnessUp" = ["exec, hyprctl hyprsunset identity"];
"CTRL ALT, f" = let
hyprctl = "${config.wayland.windowManager.hyprland.package}/bin/hyprctl";
grep = "${pkgs.gnugrep}/bin/grep";
awk = "${pkgs.gawk}/bin/gawk";
notify = "${pkgs.libnotify}/bin/notify-send";
toggleMouseFocus = pkgs.writeScriptBin "hypr-toggle-mouse-focus" ''
CURRENT=$(${hyprctl} getoption input:follow_mouse | ${grep} int | ${awk} -F' ' '{print $2}')
if [[ "$CURRENT" == "1" ]]; then
${hyprctl} keyword input:follow_mouse 0
${notify} "Disabled Mouse Focus!"
else
${hyprctl} keyword input:follow_mouse 1
${notify} "Enabled Mouse Focus!"
fi
'';
in ["exec, ${toggleMouseFocus}/bin/hypr-toggle-mouse-focus"];
# "CTRL ALT, t" = ["exec, bash -c 'systemctl --user restart hyprpanel.service'"];
}
];
ws-bindings = {
# "<Workspace>" = "<Key>";
"1" = "1";
"2" = "2";
"3" = "3";
"4" = "4";
"5" = "5";
"6" = "6";
"7" = "7";
"8" = "8";
"9" = "9";
"10" = "0";
};
special-ws-bindings = {
"ferdium" = "x";
"msty" = "z";
"btop" = "b";
"rmpc" = "r";
};
};
autostart = {
immediate = [
"kitty --hold fastfetch"
"zeal"
"nextcloud --background"
"protonvpn-app"
# "kdeconnect-indicator" # started by services.kdeconnect.indicator
];
delayed = [
"keepassxc" # The tray doesn't work when started too early
];
special-silent = {
"ferdium" = ["ferdium"];
"msty" = ["msty"];
"btop" = ["kitty --title=Btop btop"];
"rmpc" = ["kitty --title=Rmpc rmpc"];
};
};
windowrules = [
# Fix jetbrains tooltip flicker
"match:class ^(jetbrains-.*)$, match:title ^(win[0-9]+)$, float 1"
"match:class ^(jetbrains-.*)$, match:title ^(win[0-9]+)$, no_initial_focus 1"
];
workspacerules = {
"1" = [];
"2" = ["Zotero" "neovide" "code-url-handler"];
"3" = ["obsidian"];
"4" = ["firefox" "Google-chrome" "chromium-browser" "org.qutebrowser.qutebrowser"];
"5" = ["steam"];
"6" = ["steam_app_(.+)"];
"7" = ["signal"];
"8" = ["tidal-hifi"];
"9" = ["discord"];
"10" = ["python3"];
};
floating = [
{class = "org.kde.polkit-kde-authentication-agent-1";}
{
class = "thunar";
title = "File Operation Progress";
}
{class = "ffplay";}
{class = "Unity";}
];
transparent-opacity = "0.75";
transparent = [
"kitty"
"Alacritty"
"discord"
"signal"
"vesktop"
"Spotify"
"tidal-hifi"
"obsidian"
"firefox"
"org.qutebrowser.qutebrowser"
"jetbrains-clion"
"jetbrains-idea"
"jetbrains-pycharm"
"jetbrains-rustrover"
"jetbrains-rider"
"jetbrains-webstorm"
"code-url-handler"
"neovide"
"steam"
"ferdium"
"Msty"
];
}

View File

@ -0,0 +1,74 @@
{
config,
hyprland,
color,
}: {
enable = true;
settings = {
general = {
disable_loading_bar = true;
grace = 0; # Immediately lock
hide_cursor = true;
no_fade_in = false;
};
# The widgets start here.
background = [
{
path = "${config.paths.nixflake}/wallpapers/${color.wallpaper}.jpg";
blur_passes = 3;
blur_size = 10;
monitor = "";
}
];
input-field = [
# Password input
{
size = "200, 50";
position = "0, 0";
monitor = "";
dots_center = true;
fade_on_empty = false;
font_color = "rgb(${color.hex.accentText})";
font_family = "${color.font}";
inner_color = "rgb(${color.hex.accent})";
outer_color = "rgb(${color.hex.accent})";
outline_thickness = 2;
placeholder_text = "<span foreground='\#\#${color.hex.accentText}'>Password...</span>";
shadow_passes = 0;
rounding = 4;
halign = "center";
valign = "center";
}
];
label = [
# Date
{
position = "0, 300";
monitor = "";
text = ''cmd[update:1000] date -I'';
color = "rgba(${color.hex.text}AA)";
font_size = 22;
font_family = "${color.font}";
halign = "center";
valign = "center";
}
# Time
{
position = "0, 200";
monitor = "";
text = ''cmd[update:1000] date +"%-H:%M"'';
color = "rgba(${color.hex.text}AA)";
font_size = 95;
font_family = "${color.font} Extrabold";
halign = "center";
valign = "center";
}
];
};
}

View File

@ -0,0 +1,28 @@
{
config,
hyprland,
color,
}: {
enable = !hyprland.caelestia.enable;
settings = {
ipc = "on";
splash = false;
splash_offset = 2.0;
# Wallpapers have to be preloaded to be displayed
preload = let
mkPreload = name: "${config.paths.nixflake}/wallpapers/${name}.jpg";
in
color.wallpapers |> builtins.map mkPreload;
wallpaper = let
mkWallpaper = monitor:
"${monitor}, "
+ "${config.paths.nixflake}/wallpapers/${color.wallpaper}.jpg";
in
hyprland.monitors
|> builtins.attrNames
|> builtins.map mkWallpaper;
};
}

View File

@ -0,0 +1,77 @@
{
lib,
config,
hyprland,
}:
lib.mergeAttrsList [
{
# Hyprland control
"$mainMod, q" = ["killactive"];
"$mainMod, v" = ["togglefloating"];
"$mainMod, f" = ["fullscreen"];
"$mainMod, tab" = ["workspace, previous"];
# "$mainMod, g" = ["togglegroup"];
# "ALT, tab" = ["changegroupactive"];
# Move focus with mainMod + arrow keys
"$mainMod, h" = ["movefocus, l"];
"$mainMod, l" = ["movefocus, r"];
"$mainMod, k" = ["movefocus, u"];
"$mainMod, j" = ["movefocus, d"];
# Swap windows
"$mainMod CTRL, h" = ["movewindow, l"];
"$mainMod CTRL, l" = ["movewindow, r"];
"$mainMod CTRL, k" = ["movewindow, u"];
"$mainMod CTRL, d" = ["movewindow, d"];
# Reset workspaces to the defined configuration in hyprland.workspaces:
"CTRL ALT, r" = let
mkWBinding = m: w:
"moveworkspacetomonitor, "
+ "${builtins.toString w} ${builtins.toString m}";
mkWsBindings = m: ws: builtins.map (mkWBinding m) ws;
in
hyprland.workspaces
|> builtins.mapAttrs mkWsBindings
|> builtins.attrValues
|> builtins.concatLists;
}
# Switch to WS: "$mainMod, 1" = ["workspace, 1"];
(let
mkWBinding = w: k: {"$mainMod, ${k}" = ["workspace, ${w}"];};
in
hyprland.keybindings.ws-bindings
|> builtins.mapAttrs mkWBinding
|> builtins.attrValues
|> lib.mergeAttrsList)
# Toggle special WS: "$mainMod, x" = ["togglespecialworkspace, ferdium"];
(let
mkSpecialWBinding = w: k: {"$mainMod, ${k}" = ["togglespecialworkspace, ${w}"];};
in
hyprland.keybindings.special-ws-bindings
|> builtins.mapAttrs mkSpecialWBinding
|> builtins.attrValues
|> lib.mergeAttrsList)
# Move to WS: "$mainMod SHIFT, 1" = ["movetoworkspace, 1"];
(let
mkMoveWBinding = w: k: {"$mainMod SHIFT, ${k}" = ["movetoworkspace, ${w}"];};
in
(hyprland.keybindings.ws-bindings)
|> builtins.mapAttrs mkMoveWBinding
|> builtins.attrValues
|> lib.mergeAttrsList)
# Move to special WS: "$mainMod SHIFT, x" = ["movetoworkspace, special:ferdium"];
(let
mkSpecialMoveWBinding = w: k: {"$mainMod SHIFT, ${k}" = ["movetoworkspace, special:${w}"];};
in
hyprland.keybindings.special-ws-bindings
|> builtins.mapAttrs mkSpecialMoveWBinding
|> builtins.attrValues
|> lib.mergeAttrsList)
]

View File

@ -0,0 +1,206 @@
{
lib,
mylib,
...
}: {
enable = lib.mkEnableOption "Hyprland Window Manager + Compositor";
dunst.enable = lib.mkEnableOption "Enable Dunst notification daemon";
bars.enable = lib.mkEnableOption "Enable window bars";
dynamicCursor.enable = lib.mkEnableOption "Enable dynamic cursors";
trails.enable = lib.mkEnableOption "Enable dynamic window trails";
hyprspace.enable = lib.mkEnableOption "Enable Hyprspace workspace overview";
hyprpanel.enable = lib.mkEnableOption "Enable Hyprpanel";
caelestia.enable = lib.mkEnableOption "Enable Caelestia";
keyboard = {
layout = lib.mkOption {
type = lib.types.str;
example = "us";
description = "Keyboard layout to use";
};
variant = lib.mkOption {
type = lib.types.str;
example = "altgr-intl";
description = "Keyboard layout variant";
};
option = lib.mkOption {
type = lib.types.str;
example = "nodeadkeys";
description = "Keyboard layout options";
};
};
keybindings = {
main-mod = lib.mkOption {
type = lib.types.str;
description = "Main modifier key";
example = ''
"SUPER"
'';
default = "SUPER";
};
bindings = lib.mkOption {
type = lib.types.attrsOf (lib.types.listOf lib.types.str);
description = "Hyprland keyboard shortcuts";
default = {};
example = ''
{
"CTRL ALT, R" = [
"moveworkspacetomonitor, 1 HDMI-A-1"
"moveworkspacetomonitor, 2 HDMI-A-1"
];
}
'';
};
ws-bindings = lib.mkOption {
type = lib.types.attrsOf lib.types.str;
description = "Map keys to workspaces";
default = {};
example = ''
{
# "<Workspace>" = "<Key>";
"1" = "1";
"10" = "0";
}
'';
};
special-ws-bindings = lib.mkOption {
type = lib.types.attrsOf lib.types.str;
description = "Map keys to special (scratchpad) workspaces";
default = {};
example = ''
{
# "<Workspace>" = "<Key>";
"ferdium" = "x";
"btop" = "b";
}
'';
};
};
monitors = lib.mkOption {
type = lib.types.attrs;
description = "Hyprland Monitor Configurations";
example = ''
{
"HDMI-A-1" = {
width = 2560;
height = 1440;
rate = 144;
x = 1920;
y = 0;
scale = 1;
}
}
'';
};
workspaces = lib.mkOption {
type = lib.types.attrs;
description = "How workspaces are distributed to monitors. These monitors will also receive a wallpaper.";
example = ''
{
"HDMI-A-1" = [1 2 3 4 5 6 7 8 9];
"HDMI-A-2" = [0];
}
'';
};
workspacerules = lib.mkOption {
type = lib.types.attrs;
description = "Launch programs on specified workspaces, accepts window class.";
example = ''
{
"2" = [
"jetbrains-clion"
"code-url-handler"
];
}
'';
};
windowrules = lib.mkOption {
type = lib.types.listOf lib.types.str;
description = "Specify specific window rules.";
example = ''
[
"suppressevent activate, class: Unity"
]
'';
};
transparent-opacity = lib.mkOption {
type = lib.types.str;
description = "The opacity transparent windows should have.";
example = "0.8";
};
transparent = lib.mkOption {
type = lib.types.listOf lib.types.str;
description = "What programs should be transparent? Accepts window class.";
example = ''
[
"kitty"
]
'';
};
floating = lib.mkOption {
type = lib.types.listOf lib.types.attrs;
description = "What programs are floating down here?";
example = ''
[
{
class = "thunar";
title = "File Operation Progress";
}
{
class = "org.kde.polkit-kde-authentication-agent-1";
}
]
'';
};
autostart = {
immediate = lib.mkOption {
type = lib.types.listOf lib.types.str;
description = "Programs to launch when Hyprland starts";
example = ''
[
"kitty"
]
'';
default = [];
};
delayed = lib.mkOption {
type = lib.types.listOf lib.types.str;
description = "Programs to launch with a delay when Hyprland starts (e.g. to wait for the waybar tray)";
example = ''
[
"keepassxc"
"nextcloud --background"
]
'';
default = [];
};
special-silent = lib.mkOption {
type = lib.types.attrsOf (lib.types.listOf lib.types.str);
description = "Programs to silently launch on special workspaces";
example = ''
{
"ferdium" = ["ferdium"];
"btop" = ["kitty --title=Btop btop"];
}
'';
default = {};
};
};
}

View File

@ -0,0 +1,359 @@
{
lib,
config,
hyprland,
color,
always-exec,
always-bind,
always-bindm,
}: {
"$mainMod" = "${hyprland.keybindings.main-mod}";
general = {
gaps_in = 5;
gaps_out = 10;
border_size = 2;
"col.active_border" = "rgb(${color.hex.accent})";
"col.inactive_border" = "rgb(${color.hex.base})";
};
group = {
groupbar = {
enabled = true;
render_titles = false;
font_size = 10;
gradients = false;
"col.active" = "rgb(${color.hex.accent})";
"col.inactive" = "rgb(${color.hex.base})";
};
"col.border_active" = "rgb(${color.hex.accent})";
"col.border_inactive" = "rgb(${color.hex.base})";
};
input = {
kb_layout = hyprland.keyboard.layout;
kb_variant = hyprland.keyboard.variant;
kb_options = hyprland.keyboard.option;
kb_model = "pc104";
kb_rules = "";
follow_mouse = true;
touchpad = {
natural_scroll = "no";
};
sensitivity = 0; # -1.0 - 1.0, 0 means no modification.
};
monitor = let
mkMonitor = name: conf:
"${name}, "
+ "${builtins.toString conf.width}x${builtins.toString conf.height}@"
+ "${builtins.toString conf.rate}, "
+ "${builtins.toString conf.x}x${builtins.toString conf.y}, "
+ "${builtins.toString conf.scale}";
in
hyprland.monitors
|> builtins.mapAttrs mkMonitor
|> builtins.attrValues;
workspace = let
mkWorkspace = monitor: workspace:
"${builtins.toString workspace}, "
+ "monitor:${builtins.toString monitor}";
mkWorkspaces = monitor: workspace-list:
builtins.map (mkWorkspace monitor) workspace-list;
in
hyprland.workspaces
|> builtins.mapAttrs mkWorkspaces
|> builtins.attrValues
|> builtins.concatLists;
bind = let
mkBind = key: action: "${key}, ${action}";
mkBinds = key: actions: builtins.map (mkBind key) actions;
in
(hyprland.keybindings.bindings // always-bind)
|> builtins.mapAttrs mkBinds
|> builtins.attrValues
|> builtins.concatLists;
bindm = let
mkBind = key: action: "${key}, ${action}";
mkBinds = key: actions: builtins.map (mkBind key) actions;
in
always-bindm
|> builtins.mapAttrs mkBinds
|> builtins.attrValues
|> builtins.concatLists;
exec-once = let
mkDelayedStart = str: ''hyprctl dispatch exec "sleep 5s && ${str}"'';
mkSpecialSilentStart = w: str: "[workspace special:${w} silent] ${str}";
mkSpecialSilentStarts = w: strs: builtins.map (mkSpecialSilentStart w) strs;
in
lib.mkMerge [
always-exec
hyprland.autostart.immediate
(hyprland.autostart.special-silent
|> builtins.mapAttrs mkSpecialSilentStarts
|> builtins.attrValues
|> builtins.concatLists)
(hyprland.autostart.delayed
|> builtins.map mkDelayedStart)
];
windowrule = let
mkWorkspaceRule = workspace: class:
"match:class ^(${class})$, "
+ "workspace ${workspace}";
mkWorkspaceRules = workspace: class-list:
builtins.map (mkWorkspaceRule workspace) class-list;
mkFloatingRule = attrs:
(lib.optionalString (builtins.hasAttr "class" attrs) "match:class ^(${attrs.class})$, ")
+ (lib.optionalString (builtins.hasAttr "title" attrs) "match:title ^(${attrs.title})$, ")
+ "float 1";
mkTranslucentRule = class:
"match:class ^(${class})$, "
+ "opacity ${hyprland.transparent-opacity} ${hyprland.transparent-opacity}";
in
lib.mkMerge [
(hyprland.workspacerules
|> builtins.mapAttrs mkWorkspaceRules
|> builtins.attrValues
|> builtins.concatLists)
(hyprland.floating
|> builtins.map mkFloatingRule)
(hyprland.transparent
|> builtins.map mkTranslucentRule)
hyprland.windowrules
];
dwindle = {
pseudotile = true;
preserve_split = true;
};
master = {
new_status = "master";
};
gesture = [
"3, horizontal, workspace" # 3 Fingers, horizontal, workspace swipe
];
misc = {
# Say no to the anime girl
disable_hyprland_logo = true;
force_default_wallpaper = 0;
# Say no to the "Application not responding" window
enable_anr_dialog = false;
disable_splash_rendering = true;
font_family = "${color.font}";
};
# Because those are not windows, but layers,
# we have to blur them explicitly
layerrule = [
"match:class rofi, blur 1"
# "match:class rofi, ignore_alpha 0.001" # Fix pixelated corners
# "match:class rofi, xray 0" # Render on top of other windows
# "match:class rofi, dim_around 1"
"match:class waybar, blur 1"
"match:class gtk4-layer-shell, blur 1"
"match:class bar-0, blur 1"
"match:class bar-1, blur 1"
];
decoration = {
rounding = 4;
shadow = {
enabled = false;
};
blur = {
enabled = true;
size = 10;
passes = 3;
new_optimizations = true;
ignore_opacity = true;
xray = true;
};
};
animations = {
enabled = true;
bezier = "myBezier, 0.05, 0.9, 0.1, 1.05";
animation = [
"windows, 1, 7, myBezier"
"windowsOut, 1, 7, default,popin 80%"
"border, 1, 10, default"
"borderangle, 1, 8, default"
"fade, 1, 7, default"
"workspaces, 1, 6, default"
];
};
plugin = lib.mergeAttrsList [
(lib.optionalAttrs hyprland.bars.enable {
hyprbars = {
enabled = true;
bar_height = 25;
bar_blur = true;
bar_color = "rgb(${color.hex.base})";
col.text = "rgb(${color.hex.text})";
bar_title_enabled = true;
bar_text_size = 12;
bar_text_font = color.font;
bar_text_align = "center";
bar_buttons_alignment = "left";
bar_part_of_window = true;
bar_precedence_over_border = false;
# example buttons (R -> L)
# hyprbars-button = color, size, on-click
hyprbars-button = [
"rgb(${color.hex.red}), 10, 󰖭, hyprctl dispatch killactive"
"rgb(${color.hex.green}), 10, , hyprctl dispatch fullscreen 1"
];
# cmd to run on double click of the bar
on_double_click = "hyprctl dispatch fullscreen 1";
};
})
(lib.optionalAttrs hyprland.dynamicCursor.enable {
dynamic-cursors = {
# enables the plugin
enabled = true;
# sets the cursor behaviour, supports these values:
# tilt - tilt the cursor based on x-velocity
# rotate - rotate the cursor based on movement direction
# stretch - stretch the cursor shape based on direction and velocity
# none - do not change the cursors behaviour
mode = "rotate";
# minimum angle difference in degrees after which the shape is changed
# smaller values are smoother, but more expensive for hw cursors
threshold = 2;
# for mode = rotate
rotate = {
# length in px of the simulated stick used to rotate the cursor
# most realistic if this is your actual cursor size
length = 20;
# clockwise offset applied to the angle in degrees
# this will apply to ALL shapes
offset = 0.0;
};
# for mode = tilt
tilt = {
# controls how powerful the tilt is, the lower, the more power
# this value controls at which speed (px/s) the full tilt is reached
# the full tilt being 60° in both directions
limit = 1000;
# relationship between speed and tilt, supports these values:
# linear - a linear function is used
# quadratic - a quadratic function is used (most realistic to actual air drag)
# negative_quadratic - negative version of the quadratic one, feels more aggressive
# see `activation` in `src/mode/utils.cpp` for how exactly the calculation is done
function = "negative_quadratic";
# time window (ms) over which the speed is calculated
# higher values will make slow motions smoother but more delayed
window = 100;
};
# configure shake to find
# magnifies the cursor if its is being shaken
shake = {
# enables shake to find
enabled = false;
# use nearest-neighbour (pixelated) scaling when shaking
# may look weird when effects are enabled
nearest = true;
# controls how soon a shake is detected
# lower values mean sooner
threshold = 3.0;
# magnification level immediately after shake start
base = 1.5;
# magnification increase per second when continuing to shake
speed = 0.0;
# how much the speed is influenced by the current shake intensitiy
influence = 0.0;
# maximal magnification the cursor can reach
# values below 1 disable the limit (e.g. 0)
limit = 0.0;
# time in millseconds the cursor will stay magnified after a shake has ended
timeout = 1000;
# show cursor behaviour `tilt`, `rotate`, etc. while shaking
effects = true;
# enable ipc events for shake
# see the `ipc` section below
ipc = false;
};
# use hyprcursor to get a higher resolution texture when the cursor is magnified
# see the `hyprcursor` section below
hyprcursor = {
# use nearest-neighbour (pixelated) scaling when magnifing beyond texture size
# this will also have effect without hyprcursor support being enabled
# 0 / false - never use pixelated scaling
# 1 / true - use pixelated when no highres image
# 2 - always use pixleated scaling
nearest = true;
# enable dedicated hyprcursor support
enabled = true;
# resolution in pixels to load the magnified shapes at
# be warned that loading a very high-resolution image will take a long time and might impact memory consumption
# -1 means we use [normal cursor size] * [shake:base option]
resolution = -1;
# shape to use when clientside cursors are being magnified
# see the shape-name property of shape rules for possible names
# specifying clientside will use the actual shape, but will be pixelated
fallback = "clientside";
};
};
})
(lib.optionalAttrs hyprland.trails.enable {
hyprtrails = {
color = "rgb(${color.hex.accent})";
};
})
(lib.optionalAttrs hyprland.hyprspace.enable {
overview = {};
})
];
}

View File

@ -0,0 +1,342 @@
{
config,
nixosConfig,
lib,
mylib,
pkgs,
...
}: let
inherit (config.homemodules) hyprpanel color;
in {
options.homemodules.hyprpanel = import ./options.nix {inherit lib mylib;};
config = lib.mkIf hyprpanel.enable {
programs.hyprpanel = {
enable = true;
systemd.enable = hyprpanel.systemd.enable;
settings = {
#
# Bar Config
#
# https://github.com/Jas-SinghFSU/HyprPanel/blob/master/src/configuration/modules/config/index.ts
"scalingPriority" = "hyprland";
"wallpaper.enable" = false;
# https://github.com/Jas-SinghFSU/HyprPanel/blob/master/src/configuration/modules/config/bar/index.ts
"bar.autoHide" = "never";
# https://github.com/Jas-SinghFSU/HyprPanel/blob/master/src/configuration/modules/config/bar/layouts/index.ts
# TODO: To module option
# TODO: This should contain battery etc. for laptop
"bar.layouts" = {
"DP-1" = {
"left" = ["workspaces" "windowtitle"];
"middle" = ["media"]; # "cava"
"right" = ["volume" "network" "cpu" "ram" "storage" "clock" "systray" "notifications"]; # "bluetooth"
};
"DP-2" = {
"left" = ["workspaces" "windowtitle"];
"middle" = ["media"]; # "cava"
"right" = ["volume" "clock" "notifications"];
};
};
# TODO: Expose this as a module option: applicationIcons = {kitty = "󰄛"; ...};
"bar.workspaces.applicationIconMap" = {
"class:^(kitty)$" = "󰄛";
"class:^(org\.keepassxc\.KeePassXC)$" = "󰟵";
"class:^(com\.nextcloud\.desktopclient\.nextcloud)$" = "";
"class:^(neovide)$" = "";
"class:^(jetbrains-clion)$" = "";
"class:^(jetbrains-idea)$" = "";
"class:^(jetbrains-pycharm)$" = "";
"class:^(jetbrains-rustrover)$" = "";
"class:^(jetbrains-rider)$" = "";
"class:^(jetbrains-webstorm)$" = "";
"class:^(obsidian)$" = "";
"class:^(anki)$" = "";
"class:^(blender)$" = "󰂫";
"class:^(unityhub)$" = "";
"class:^(Unity)$" = "";
"class:^(steam)$" = "";
"class:^(steam_app_)(.+)$" = "";
"class:^(signal)$" = "󱋊";
"class:^(Spotify)$" = "";
"class:^(rmpc)$" = "󰝚";
"class:^(discord)$" = "";
"class:^(Zotero)$" = "";
"class:^(org.zealdocs.zeal)$" = "󰞋";
"class:^(navi)$" = "";
"class:^(org.qutebrowser.qutebrowser)$" = "󰖟";
};
# https://github.com/Jas-SinghFSU/HyprPanel/blob/master/src/configuration/modules/theme/bar/index.ts
"theme.bar.background" = "#${color.hex.base}";
"theme.bar.border.color" = "#${color.hex.accent}";
"theme.bar.border.location" = "full";
"theme.bar.border_radius" = "6px";
"theme.bar.border.width" = "2px";
"theme.bar.dropdownGap" = "50px";
"theme.bar.floating" = true;
"theme.bar.label_spacing" = "0px"; # what does this do?
"theme.bar.margin_bottom" = "0px";
"theme.bar.margin_sides" = "10px";
"theme.bar.margin_top" = "10px";
"theme.bar.opacity" = 75;
"theme.bar.outer_spacing" = "0px"; # NOTE: Left/Right bar padding
"theme.bar.transparent" = false;
# https://github.com/Jas-SinghFSU/HyprPanel/blob/master/src/configuration/modules/theme/bar/buttons/index.ts
"theme.bar.buttons.opacity" = 100;
"theme.bar.buttons.padding_x" = "10px";
"theme.bar.buttons.padding_y" = "2px";
"theme.bar.buttons.radius" = "3px";
"theme.bar.buttons.spacing" = "2px"; # NOTE: Horizontal inter-button spacing
"theme.bar.buttons.style" = "default";
"theme.bar.buttons.text" = "#${color.hex.accentText}";
"theme.bar.buttons.y_margins" = "2px"; # NOTE: Top/Bottom bar padding
# https://github.com/Jas-SinghFSU/HyprPanel/blob/master/src/configuration/modules/theme/general/index.ts
"theme.font.label" = color.font;
"theme.font.name" = color.font;
"theme.font.size" = "14px";
"theme.font.weight" = 600;
#
# Modules Config
#
# https://github.com/Jas-SinghFSU/HyprPanel/blob/master/src/configuration/modules/config/bar/workspaces/index.ts
"bar.workspaces.applicationIconEmptyWorkspace" = "";
"bar.workspaces.applicationIconFallback" = "󰣆";
"bar.workspaces.applicationIconOncePerWorkspace" = true;
"bar.workspaces.ignored" = "-\\d+"; # Special workspaces
"bar.workspaces.monitorSpecific" = true;
"bar.workspaces.numbered_active_indicator" = "highlight";
"bar.workspaces.reverse_scroll" = true;
"bar.workspaces.show_icons" = false;
"bar.workspaces.show_numbered" = false;
"bar.workspaces.showAllActive" = true;
"bar.workspaces.showApplicationIcons" = true; # requires showWsIcons
"bar.workspaces.showWsIcons" = true;
# "bar.workspaces.spacing" = 1;
"bar.workspaces.workspaces" = 9;
# https://github.com/Jas-SinghFSU/HyprPanel/blob/master/src/configuration/modules/theme/bar/buttons/workspaces.ts
"theme.bar.buttons.workspaces.active" = "#${color.hex.accentHl}";
"theme.bar.buttons.workspaces.available" = "#${color.hex.accentText}";
"theme.bar.buttons.workspaces.background" = "#${color.hex.accent}";
"theme.bar.buttons.workspaces.border" = "#${color.hex.accent}";
"theme.bar.buttons.workspaces.enableBorder" = false;
"theme.bar.buttons.workspaces.fontSize" = "18px";
"theme.bar.buttons.workspaces.hover" = "#${color.hex.accentHl}";
"theme.bar.buttons.workspaces.numbered_active_highlight_border" = "4px"; # border radius
"theme.bar.buttons.workspaces.numbered_active_highlighted_text_color" = "#${color.hex.accentText}";
"theme.bar.buttons.workspaces.numbered_active_highlight_padding" = "6px";
"theme.bar.buttons.workspaces.numbered_active_underline_color" = "#${color.hex.accentHl}";
"theme.bar.buttons.workspaces.numbered_inactive_padding" = "6px"; # make the same as numbered_active_highlight_padding to avoid layout jumping
"theme.bar.buttons.workspaces.occupied" = "#${color.hex.accentText}";
"theme.bar.buttons.workspaces.smartHighlight" = "false";
"theme.bar.buttons.workspaces.spacing" = "6px"; # no visible difference?
# The pill marks the active workspace when icons are disabled
# "theme.bar.buttons.workspaces.pill" = {
# "active_width" = "12em";
# "height" = "4em";
# "radius" = "4px";
# "width" = "4em";
# };
# https://github.com/Jas-SinghFSU/HyprPanel/blob/master/src/configuration/modules/config/bar/windowtitle/index.ts
"bar.windowtitle.class_name" = true;
"bar.windowtitle.custom_title" = true;
"bar.windowtitle.icon" = true;
"bar.windowtitle.label" = true;
"bar.windowtitle.truncation" = true;
"bar.windowtitle.truncation_size" = 50;
# https://github.com/Jas-SinghFSU/HyprPanel/blob/master/src/configuration/modules/theme/bar/buttons/windowtitle.ts
"theme.bar.buttons.windowtitle.background" = "#${color.hex.pink}";
"theme.bar.buttons.windowtitle.border" = "#${color.hex.accent}";
"theme.bar.buttons.windowtitle.enableBorder" = false;
"theme.bar.buttons.windowtitle.icon_background" = "#${color.hex.pink}";
"theme.bar.buttons.windowtitle.icon" = "#${color.hex.accentText}";
"theme.bar.buttons.windowtitle.spacing" = "6px"; # Spacing between icon and text
"theme.bar.buttons.windowtitle.text" = "#${color.hex.accentText}";
# https://github.com/Jas-SinghFSU/HyprPanel/blob/master/src/configuration/modules/config/bar/media/index.ts
"bar.media.format" = "{artist: - }{title}";
"bar.media.show_active_only" = true;
"bar.media.show_label" = true;
"bar.media.truncation" = true;
"bar.media.truncation_size" = 30;
# https://github.com/Jas-SinghFSU/HyprPanel/blob/master/src/configuration/modules/theme/bar/buttons/media.ts
"theme.bar.buttons.media.background" = "#${color.hex.lavender}";
"theme.bar.buttons.media.border" = "#${color.hex.accent}";
"theme.bar.buttons.media.enableBorder" = false;
"theme.bar.buttons.media.icon_background" = "#${color.hex.lavender}";
"theme.bar.buttons.media.icon" = "#${color.hex.accentText}";
"theme.bar.buttons.media.spacing" = "6px";
"theme.bar.buttons.media.text" = "#${color.hex.accentText}";
# https://github.com/Jas-SinghFSU/HyprPanel/blob/master/src/configuration/modules/config/bar/cava/index.ts
"bar.customModules.cava.showActiveOnly" = true;
"bar.customModules.cava.bars" = 10;
# "bar.customModules.cava.leftClick" = "menu:media";
# https://github.com/Jas-SinghFSU/HyprPanel/blob/master/src/configuration/modules/theme/bar/buttons/cava.ts
"theme.bar.buttons.modules.cava.background" = "#${color.hex.red}";
"theme.bar.buttons.modules.cava.border" = "#${color.hex.accent}";
"theme.bar.buttons.modules.cava.enableBorder" = false;
"theme.bar.buttons.modules.cava.icon" = "#${color.hex.accentText}";
"theme.bar.buttons.modules.cava.icon_background" = "#${color.hex.red}";
"theme.bar.buttons.modules.cava.spacing" = "6px";
"theme.bar.buttons.modules.cava.text" = "#${color.hex.accentText}";
# https://github.com/Jas-SinghFSU/HyprPanel/blob/master/src/configuration/modules/config/bar/volume/index.ts
"bar.volume.middleClick" = "kitty ncpamixer";
# https://github.com/Jas-SinghFSU/HyprPanel/blob/master/src/configuration/modules/theme/bar/buttons/volume.ts
"theme.bar.buttons.volume.background" = "#${color.hex.maroon}";
"theme.bar.buttons.volume.enableBorder" = false;
"theme.bar.buttons.volume.border" = "#${color.hex.accent}";
"theme.bar.buttons.volume.icon_background" = "#${color.hex.maroon}";
"theme.bar.buttons.volume.icon" = "#${color.hex.accentText}";
"theme.bar.buttons.volume.spacing" = "6px";
"theme.bar.buttons.volume.text" = "#${color.hex.accentText}";
# https://github.com/Jas-SinghFSU/HyprPanel/blob/master/src/configuration/modules/config/bar/network/index.ts
# https://github.com/Jas-SinghFSU/HyprPanel/blob/master/src/configuration/modules/theme/bar/buttons/network.ts
"theme.bar.buttons.network.background" = "#${color.hex.peach}";
"theme.bar.buttons.network.enableBorder" = false;
"theme.bar.buttons.network.border" = "#${color.hex.accent}";
"theme.bar.buttons.network.icon_background" = "#${color.hex.peach}";
"theme.bar.buttons.network.icon" = "#${color.hex.accentText}";
"theme.bar.buttons.network.spacing" = "6px";
"theme.bar.buttons.network.text" = "#${color.hex.accentText}";
# https://github.com/Jas-SinghFSU/HyprPanel/blob/master/src/configuration/modules/config/bar/bluetooth/index.ts
# https://github.com/Jas-SinghFSU/HyprPanel/blob/master/src/configuration/modules/theme/bar/buttons/bluetooth.ts
"theme.bar.buttons.bluetooth.background" = "#${color.hex.yellow}";
"theme.bar.buttons.bluetooth.enableBorder" = false;
"theme.bar.buttons.bluetooth.border" = "#${color.hex.accent}";
"theme.bar.buttons.bluetooth.icon_background" = "#${color.hex.yellow}";
"theme.bar.buttons.bluetooth.icon" = "#${color.hex.accentText}";
"theme.bar.buttons.bluetooth.spacing" = "6px";
"theme.bar.buttons.bluetooth.text" = "#${color.hex.accentText}";
# https://github.com/Jas-SinghFSU/HyprPanel/blob/master/src/configuration/modules/config/bar/cpu/index.ts
"bar.customModules.cpu.middleClick" = "kitty btop";
"bar.customModules.cpu.pollingInterval" = 1000;
# https://github.com/Jas-SinghFSU/HyprPanel/blob/master/src/configuration/modules/theme/bar/buttons/cpu.ts
"theme.bar.buttons.modules.cpu.background" = "#${color.hex.green}";
"theme.bar.buttons.modules.cpu.enableBorder" = false;
"theme.bar.buttons.modules.cpu.border" = "#${color.hex.accent}";
"theme.bar.buttons.modules.cpu.icon_background" = "#${color.hex.green}";
"theme.bar.buttons.modules.cpu.icon" = "#${color.hex.accentText}";
"theme.bar.buttons.modules.cpu.spacing" = "6px";
"theme.bar.buttons.modules.cpu.text" = "#${color.hex.accentText}";
# https://github.com/Jas-SinghFSU/HyprPanel/blob/master/src/configuration/modules/config/bar/ram/index.ts
"bar.customModules.ram.labelType" = "percentage"; # "used/total", "percentage"
"bar.customModules.ram.pollingInterval" = 1000;
# https://github.com/Jas-SinghFSU/HyprPanel/blob/master/src/configuration/modules/theme/bar/buttons/ram.ts
"theme.bar.buttons.modules.ram.background" = "#${color.hex.teal}";
"theme.bar.buttons.modules.ram.enableBorder" = false;
"theme.bar.buttons.modules.ram.border" = "#${color.hex.accent}";
"theme.bar.buttons.modules.ram.icon_background" = "#${color.hex.teal}";
"theme.bar.buttons.modules.ram.icon" = "#${color.hex.accentText}";
"theme.bar.buttons.modules.ram.spacing" = "6px";
"theme.bar.buttons.modules.ram.text" = "#${color.hex.accentText}";
# https://github.com/Jas-SinghFSU/HyprPanel/blob/master/src/configuration/modules/config/bar/storage/index.ts
"bar.customModules.storage.labelType" = "percentage"; # "used/total", "percentage"
"bar.customModules.storage.tooltipStyle" = "simple"; # "tree", "percentage-bar", "simple"
"bar.customModules.storage.pollingInterval" = 60000;
# https://github.com/Jas-SinghFSU/HyprPanel/blob/master/src/configuration/modules/theme/bar/buttons/storage.ts
"theme.bar.buttons.modules.storage.background" = "#${color.hex.sky}";
"theme.bar.buttons.modules.storage.enableBorder" = false;
"theme.bar.buttons.modules.storage.border" = "#${color.hex.accent}";
"theme.bar.buttons.modules.storage.icon_background" = "#${color.hex.sky}";
"theme.bar.buttons.modules.storage.icon" = "#${color.hex.accentText}";
"theme.bar.buttons.modules.storage.spacing" = "6px";
"theme.bar.buttons.modules.storage.text" = "#${color.hex.accentText}";
# https://github.com/Jas-SinghFSU/HyprPanel/blob/master/src/configuration/modules/config/bar/clock/index.ts
"bar.clock.format" = "%Y-%m-%d %H:%M";
"bar.clock.showTime" = true;
# https://github.com/Jas-SinghFSU/HyprPanel/blob/master/src/configuration/modules/theme/bar/buttons/clock.ts
"theme.bar.buttons.clock.background" = "#${color.hex.sapphire}";
"theme.bar.buttons.clock.enableBorder" = false;
"theme.bar.buttons.clock.border" = "#${color.hex.accent}";
"theme.bar.buttons.clock.icon_background" = "#${color.hex.sapphire}";
"theme.bar.buttons.clock.icon" = "#${color.hex.accentText}";
"theme.bar.buttons.clock.spacing" = "6px";
"theme.bar.buttons.clock.text" = "#${color.hex.accentText}";
# TODO: To module option
# https://github.com/Jas-SinghFSU/HyprPanel/blob/master/src/configuration/modules/config/bar/systray/index.ts
"bar.systray.ignore" = [
"Fcitx" # Keyboard indicator
]; # Middle click the tray icon to show a notification with the app name :)
"bar.systray.customIcons" = {};
# https://github.com/Jas-SinghFSU/HyprPanel/blob/master/src/configuration/modules/theme/bar/buttons/systray.ts
"theme.bar.buttons.systray.background" = "#${color.hex.blue}";
"theme.bar.buttons.systray.enableBorder" = false;
"theme.bar.buttons.systray.border" = "#${color.hex.accent}";
"theme.bar.buttons.systray.customIcon" = "#${color.hex.accentText}";
"theme.bar.buttons.systray.spacing" = "6px";
# https://github.com/Jas-SinghFSU/HyprPanel/blob/master/src/configuration/modules/config/bar/notifications/index.ts
"bar.notifications.hideCountWhenZero" = true;
"bar.notifications.show_total" = true;
# https://github.com/Jas-SinghFSU/HyprPanel/blob/master/src/configuration/modules/theme/bar/buttons/notifications.ts
"theme.bar.buttons.notifications.background" = "#${color.hex.accent}";
"theme.bar.buttons.notifications.enableBorder" = false;
"theme.bar.buttons.notifications.border" = "#${color.hex.accent}";
"theme.bar.buttons.notifications.icon_background" = "#${color.hex.accent}";
"theme.bar.buttons.notifications.icon" = "#${color.hex.accentText}";
"theme.bar.buttons.notifications.spacing" = "6px";
"theme.bar.buttons.notifications.total" = "#${color.hex.accentText}";
#
# TODO: Menus Config
#
"theme.bar.menus.background" = "#${color.hex.base}";
"theme.bar.menus.border.color" = "#${color.hex.accent}";
"theme.bar.menus.border.radius" = "6px";
"theme.bar.menus.border.size" = "2px";
"theme.bar.menus.buttons.radius" = "0.4em";
"theme.bar.menus.card_radius" = "0.4em";
"menus.clock.time.military" = true;
"menus.clock.weather.location" = "Dortmund";
"menus.clock.weather.key" = "1d22720b9e0848a9b1303412251706"; # Don't care if public
"menus.clock.weather.unit" = "metric";
"menus.transition" = "crossfade";
"menus.transitionTime" = 200;
#
# TODO: Notifications Config
#
"notifications.position" = "top right";
"notifications.showActionsOnHover" = true;
"notifications.timeout" = 5000;
};
};
};
}

View File

@ -0,0 +1,10 @@
{
lib,
mylib,
...
}:
with lib;
with mylib.modules; {
enable = mkEnableOption "Enable Hyprpanel";
systemd.enable = mkEnableOption "Start using systemd";
}

View File

@ -0,0 +1,265 @@
{color}: {
enable = false;
settings = {
# configure noctalia here; defaults will
# be deep merged with these attributes.
colorSchemes.predefinedScheme = "Catppuccin";
general = {
avatarImage = ../../../config/face.jpeg;
radiusRatio = 0.2;
showScreenCorners = false;
forceBlackScreenCorners = false;
dimDesktop = true;
scaleRatio = 1;
screenRadiusRatio = 1;
animationSpeed = 1;
animationDisabled = false;
compactLockScreen = false;
lockOnSuspend = true;
enableShadows = true;
shadowDirection = "bottom_right";
shadowOffsetX = 2;
shadowOffsetY = 3;
language = "";
};
ui = {
fontDefault = color.font;
fontFixed = color.font;
tooltipsEnabled = true;
panelsAttachedToBar = true;
settingsPanelAttachTobar = true;
fontDefaultScale = 1;
fontFixedScale = 1;
settingsPanelAttachToBar = false;
};
location = {
name = "Dortmund, Germany";
monthBeforeDay = true;
weatherEnabled = true;
useFahrenheit = false;
use12hourFormat = false;
showWeekNumberInCalendar = false;
showCalendarEvents = true;
showCalendarWeather = true;
analogClockInCalendar = false;
firstDayOfWeek = -1;
};
screenRecorder = {
directory = "~/Videos/Recordings";
frameRate = 60;
audioCodec = "aac";
videoCodec = "h265";
quality = "very_high";
colorRange = "limited";
showCursor = true;
audioSource = "default_output";
videoSource = "portal";
};
wallpaper = {
enabled = true;
overviewEnabled = true;
directory = "~/NixFlake/wallpapers";
enableMultiMonitorDirectories = false;
recursiveSearch = false;
setWallpaperOnAllMonitors = true;
defaultWallpaper = ../../../wallpapers/Windows.jpg;
fillMode = "crop";
fillColor = "#000000";
randomEnabled = false;
randomIntervalSec = 300;
transitionDuration = 1500;
transitionType = "random";
transitionEdgeSmoothness = 0.05;
monitors = [];
panelPosition = "follow_bar";
};
appLauncher = {
enableClipboardHistory = true;
position = "center";
backgroundOpacity = 1;
pinnedExecs = [];
useApp2Unit = false;
sortByMostUsed = true;
terminalCommand = "kitty -e";
customLaunchPrefixEnabled = false;
customLaunchPrefix = "";
};
dock = {
enabled = false;
};
network = {
wifiEnabled = true;
bluetoothEnabled = true;
};
notifications = {
enabled = true;
monitors = [];
location = "top_right";
overlayLayer = true;
backgroundOpacity = 1;
respectExpireTimeout = false;
lowUrgencyDuration = 3;
normalUrgencyDuration = 8;
criticalUrgencyDuration = 15;
};
osd = {
enabled = true;
location = "top_right";
monitors = [];
autoHideMs = 2000;
overlayLayer = true;
};
audio = {
volumeStep = 5;
volumeOverdrive = true;
cavaFrameRate = 30;
visualizerType = "linear";
visualizerQuality = "high";
mprisBlacklist = [];
preferredPlayer = "";
externalMixer = "kitty --title=Ncpamixer ncpamixer";
};
nightLight = {
enabled = false;
forced = false;
autoSchedule = true;
nightTemp = "5000";
dayTemp = "6500";
manualSunrise = "06:30";
manualSunset = "21:30";
};
sessionMenu = {
countdownDuration = 10000;
enableCountdown = true;
position = "center";
powerOptions = [
{
action = "lock";
enabled = true;
}
{
action = "suspend";
enabled = false;
}
{
action = "reboot";
enabled = true;
}
{
action = "logout";
enabled = true;
}
{
action = "shutdown";
enabled = true;
}
];
showHeader = true;
};
bar = {
density = "default";
position = "top";
showCapsule = false;
outerCorners = false;
exclusive = true;
backgroundOpacity = 1;
monitors = [];
floating = false;
marginVertical = 0.25;
marginHorizontal = 0.25;
widgets = {
left = [
{
id = "SidePanelToggle";
useDistroLogo = true;
}
{
hideUnoccupied = false;
id = "Workspace";
labelMode = "none";
}
{
id = "ActiveWindow";
maxWidth = 250;
}
];
center = [
{
id = "MediaMini";
maxWidth = 250;
showAlbumArt = true;
}
{
id = "AudioVisualizer";
width = 100;
visualizerType = "mirrored";
}
];
right = [
# {
# id = "SystemMonitor";
# usePrimaryColor = true;
# showCpuUsage = true;
# showCpuTemp = false;
# showMemoryUsage = true;
# showMemoryAsPercent = false;
# showNetworkStats = true;
# showDiskUsage = true;
# diskPath = "/";
# }
{
id = "Volume";
# displayMode = "alwaysShow";
}
{
id = "Microphone";
# displayMode = "alwaysShow";
}
{
id = "Bluetooth";
# displayMode = "alwaysShow";
}
{
id = "WiFi";
# displayMode = "alwaysShow";
}
{
id = "VPN";
# displayMode = "alwaysShow";
}
{
id = "Tray";
drawerEnabled = false;
}
{
formatHorizontal = "yyyy-MM-dd HH:mm";
formatVertical = "HH mm";
id = "Clock";
useMonospacedFont = true;
usePrimaryColor = true;
}
{
id = "NotificationHistory";
}
];
};
};
};
}