-
Notifications
You must be signed in to change notification settings - Fork 0
Hyprland
Complete guide to NullOS's Hyprland configuration, keybindings, and customization.
NullOS uses Hyprland, a modern dynamic tiling Wayland compositor. Configuration is split across multiple files for better organization.
Configuration Location: home/hyprland/
Main entry point that imports all other Hyprland configs.
Core Hyprland settings:
- General appearance
- Gaps and borders
- Decoration (shadows, blur, rounding)
- Cursor settings
- Layout rules
All keybindings for:
- Applications
- Window management
- Workspace switching
- Media controls
- System functions
Window-specific rules:
- Floating windows
- Workspace assignments
- Opacity rules
- Size and position
Animation configuration:
- Window animations
- Workspace transitions
- Fade effects
- Bezier curves
Environment variables:
- Wayland settings
- Qt/GTK configuration
- Hardware acceleration
- Cursor theme
Idle management:
- Screen timeout
- Automatic locking
- Suspend rules
Screen lock configuration:
- Lock screen appearance
- Background image
- Input fields
Pyprland scratchpads and extensions:
- Dropdown terminal
- Quick access windows
Press SUPER + K to view all keybindings in a searchable menu!
| Key | Action |
|---|---|
SUPER + Return |
Terminal (Ghostty) |
SUPER + SHIFT + Return |
App launcher (Rofi) |
SUPER (tap twice) |
App launcher |
SUPER + W |
Web browser |
SUPER + E |
File manager (Dolphin) |
SUPER + Y |
Yazi file manager |
SUPER + C |
VSCode |
SUPER + D |
Dolphin file manager |
SUPER + M |
Audio mixer (Pavucontrol) |
SUPER + T |
Scratchpad terminal (dropdown) |
SUPER + # |
VPN scratchpad |
SUPER + S |
Screenshot tool |
F8 |
Display settings (nwg-displays) |
| Key | Action |
|---|---|
SUPER + Q |
Close window |
SUPER + F |
Toggle fullscreen |
SUPER + SHIFT + F |
Toggle floating |
SUPER + ALT + F |
Toggle all float on workspace |
SUPER + P |
Pseudo-tile mode |
SUPER + SHIFT + I |
Toggle split direction |
| Key | Action |
|---|---|
SUPER + H/J/K/L |
Move focus (Vim keys) |
SUPER + Arrow Keys |
Move focus (arrows) |
ALT + Tab |
Cycle windows |
| Key | Action |
|---|---|
SUPER + SHIFT + H/J/K/L |
Move window (Vim) |
SUPER + SHIFT + Arrows |
Move window (arrows) |
| Key | Action |
|---|---|
SUPER + ALT + H/J/K/L |
Swap windows (Vim) |
SUPER + ALT + Arrows |
Swap windows (arrows) |
| Key | Action |
|---|---|
SUPER + 1-9/0 |
Switch to workspace 1-10 |
SUPER + SHIFT + 1-9/0 |
Move window to workspace |
SUPER + CTRL + Left/Right |
Previous/next workspace |
SUPER + Mouse Wheel |
Scroll workspaces |
SUPER + SPACE |
Toggle special workspace |
SUPER + SHIFT + SPACE |
Move to special workspace |
| Key | Action |
|---|---|
SUPER + Left Click |
Move window |
SUPER + Right Click |
Resize window |
| Key | Action |
|---|---|
XF86AudioPlay |
Play/pause |
XF86AudioNext |
Next track |
XF86AudioPrev |
Previous track |
XF86AudioRaiseVolume |
Volume up |
XF86AudioLowerVolume |
Volume down |
XF86AudioMute |
Mute/unmute |
XF86MonBrightnessUp |
Brightness up |
XF86MonBrightnessDown |
Brightness down |
Edit home/hyprland/binds.nix:
bind = [
# Existing bindings...
# Add your custom binding
"SUPER, B, exec, firefox" # Open Firefox
"SUPER, N, exec, nautilus" # Open Nautilus
];bind = [
# Change terminal from ghostty to kitty
"SUPER,Return,exec,kitty" # Instead of ${vars.terminal}
# Change browser key
"SUPER,B,exec,${vars.browser.meta.mainProgram}" # Instead of SUPER+W
];-
SUPER- Windows/Super key -
SHIFT- Shift key -
CTRLorCONTROL- Control key -
ALT- Alt key
Combine with spaces: SUPER SHIFT, CTRL ALT
-
Return- Enter -
SPACE- Spacebar -
Tab- Tab key - Numbers:
1,2,3, etc. - Arrows:
left,right,up,down - Function keys:
F1,F2, etc.
bind = [
"SUPER, T, exec, command-here"
];bind = [
"SUPER, Q, killactive," # Close window
"SUPER, F, fullscreen," # Fullscreen
"SUPER, V, togglefloating," # Toggle floating
"SUPER, P, pseudo," # Pseudo-tile
"SUPER, 1, workspace, 1" # Switch workspace
"SUPER SHIFT, 1, movetoworkspace, 1" # Move to workspace
];Window rules control how specific applications behave.
Edit home/hyprland/windowrules.nix
windowrulev2 = float, class:^(pavucontrol)$
windowrulev2 = float, title:^(Picture-in-Picture)$windowrulev2 = size 800 600, class:^(pavucontrol)$windowrulev2 = center, class:^(pavucontrol)$windowrulev2 = workspace 2, class:^(firefox)$
windowrulev2 = workspace 3, class:^(discord)$windowrulev2 = opacity 0.9 0.9, class:^(code)$windowrulev2 = tile, class:^(Spotify)$windowrulev2 = move 100 100, class:^(pavucontrol)$Run in terminal:
hyprctl clientsOr hover over a window and press SUPER + K to see properties.
# In variables.nix
animationSet = home/hyprland/animations-end4.nix;Create home/hyprland/animations-custom.nix:
{
wayland.windowManager.hyprland.settings = {
animations = {
enabled = true;
bezier = [
"wind, 0.05, 0.9, 0.1, 1.05"
"winIn, 0.1, 1.1, 0.1, 1.1"
"winOut, 0.3, -0.3, 0, 1"
"liner, 1, 1, 1, 1"
];
animation = [
"windows, 1, 6, wind, slide"
"windowsIn, 1, 6, winIn, slide"
"windowsOut, 1, 5, winOut, slide"
"windowsMove, 1, 5, wind, slide"
"border, 1, 1, liner"
"borderangle, 1, 30, liner, loop"
"fade, 1, 10, default"
"workspaces, 1, 5, wind"
];
};
};
}Update variables.nix:
animationSet = home/hyprland/animations-custom.nix;{
wayland.windowManager.hyprland.settings = {
animations = {
enabled = false;
};
};
}Edit home/hyprland/hyprland.nix for core settings:
general = {
gaps_in = 5;
gaps_out = 10;
border_size = 2;
"col.active_border" = "rgba(33ccffee) rgba(00ff99ee) 45deg";
"col.inactive_border" = "rgba(595959aa)";
};decoration = {
rounding = 10;
blur = {
enabled = true;
size = 3;
passes = 1;
};
drop_shadow = true;
shadow_range = 4;
shadow_render_power = 3;
"col.shadow" = "rgba(1a1a1aee)";
};input = {
kb_layout = "us";
kb_variant = "";
kb_options = "";
follow_mouse = 1;
touchpad = {
natural_scroll = true;
tap-to-click = true;
};
sensitivity = 0; # -1.0 to 1.0
};gestures = {
workspace_swipe = true;
workspace_swipe_fingers = 3;
workspace_swipe_distance = 300;
};Leave extraMonitorSettings empty in variables.nix:
extraMonitorSettings = "";extraMonitorSettings = "
monitor = DP-1, 2560x1440@144, 0x0, 1
monitor = HDMI-A-1, 1920x1080@60, 2560x0, 1
";Format: monitor = NAME, RESOLUTION@REFRESH, POSITION, SCALE
Examples:
Laptop screen:
monitor = eDP-1, 1920x1080@60, auto, 1
4K monitor with scaling:
monitor = DP-1, 3840x2160@60, auto, 1.5
Vertical monitor:
monitor = DP-2, 1920x1080@60, 2560x0, 1, transform, 1
Disable monitor:
monitor = HDMI-A-1, disable
hyprctl monitorsTest monitor settings without rebuild:
hyprctl keyword monitor "DP-1,2560x1440@144,0x0,1"Use nwg-displays GUI (press F8).
Edit home/hyprland/env.nix:
env = [
"XCURSOR_SIZE,24"
"XCURSOR_THEME,Adwaita"
"QT_QPA_PLATFORM,wayland"
"QT_QPA_PLATFORMTHEME,qt6ct"
"MOZ_ENABLE_WAYLAND,1"
"GDK_BACKEND,wayland"
];env = [
"LIBVA_DRIVER_NAME,nvidia"
"XDG_SESSION_TYPE,wayland"
"GBM_BACKEND,nvidia-drm"
"__GLX_VENDOR_LIBRARY_NAME,nvidia"
"WLR_NO_HARDWARE_CURSORS,1"
];Edit home/hyprland/pyprland.nix:
scratchpads = {
term = {
command = "ghostty --class scratchpad";
animation = "fromTop";
size = "75% 60%";
margin = 50;
};
};Toggle with SUPER + T
scratchpads = {
music = {
command = "spotify";
animation = "fromRight";
size = "40% 90%";
};
};Add keybind in binds.nix:
bind = [
"SUPER, G, exec, pypr toggle music"
];Edit home/hyprland/hypridle.nix:
services.hypridle = {
enable = true;
settings = {
general = {
lock_cmd = "hyprlock";
before_sleep_cmd = "hyprlock";
};
listener = [
{
timeout = 300; # 5 minutes
on-timeout = "hyprlock";
}
{
timeout = 600; # 10 minutes
on-timeout = "systemctl suspend";
}
];
};
};Edit home/hyprland/hyprlock.nix:
programs.hyprlock = {
enable = true;
settings = {
background = {
path = "screenshot";
blur_passes = 3;
blur_size = 8;
};
input-field = {
size = "300, 50";
position = "0, -80";
outline_thickness = 2;
fade_on_empty = false;
};
};
};Add to home/hyprland/hyprland.nix:
exec-once = [
"waybar"
"swaync"
"swayosd-server"
"hypridle"
"pypr"
# Add custom startup apps
"discord --start-minimized"
"spotify"
"[workspace 1 silent] firefox"
];hyprctl getoption allConfiguration reloads automatically, or:
hyprctl reloadEnable debug logging:
debug = {
overlay = false;
damage_tracking = 2;
};View logs:
journalctl --user -u hyprland -fdecoration = {
blur = {
enabled = false; # Disable blur for performance
};
drop_shadow = false;
};
animations = {
enabled = false; # Disable animations
};Create mode-specific bindings:
bind = [
"SUPER, R, submap, resize"
];
submap = "resize";
binde = [
", right, resizeactive, 10 0"
", left, resizeactive, -10 0"
", up, resizeactive, 0 -10"
", down, resizeactive, 0 10"
", escape, submap, reset"
];
submap = "reset";NullOS doesn't include plugins by default, but you can add them:
# In flake inputs
hyprland-plugins.url = "github:hyprwm/hyprland-plugins";
# In configuration
wayland.windowManager.hyprland = {
plugins = [
inputs.hyprland-plugins.packages.${pkgs.system}.borders-plus-plus
];
};- Check for conflicts:
hyprctl binds - Verify syntax in
binds.nix - Reload:
hyprctl reload
general = {
allow_tearing = false;
};
windowrulev2 = immediate, class:^(game)$ # For specific appsenv = [
"WLR_NO_HARDWARE_CURSORS,1"
];
cursor = {
no_hardware_cursors = true;
};- Waybar - Customize your status bar
- Rofi - Configure application launcher
- Customization Guide - General customization
- Theming - Appearance customization