// derivatives
Hyprland on Arch: NVIDIA + Dank Material Shell + Modular Config
A complete Hyprland setup guide for NVIDIA users with modular config structure
# Hyprland Installation Guide
NVIDIA | Dank Material Shell | Modular Configuration
Prerequisites: A working Arch Linux base installation. This guide assumes you have completed the Arch Linux installation guide and have a functional system with NVIDIA drivers, iwd, and NetworkManager already set up.
—
Table of Contents
1. [What is Hyprland?](#1-what-is-hyprland) 2. [The Hypr Ecosystem](#2-the-hypr-ecosystem) 3. [Install Hyprland and Dependencies](#3-install-hyprland-and-dependencies) 4. [NVIDIA Configuration](#4-nvidia-configuration) 5. [Install Recommended Applications](#5-install-recommended-applications) 6. [Modular Configuration Structure](#6-modular-configuration-structure) 7. [hyprland.conf — Main Entry Point](#7-hyprlandconf–main-entry-point) 8. [env.conf — Environment Variables](#8-envconf–environment-variables) 9. [monitor.conf](#9-monitorconf) 10. [autostart.conf](#10-autostartconf) 11. [input.conf](#11-inputconf) 12. [decorations.conf](#12-decorationsconf) 13. [animations.conf](#13-animationsconf) 14. [keybinds.conf](#14-keybindsconf) 15. [windowrules.conf](#15-windowrulesconf) 16. [workspaces.conf](#16-workspacesconf) 17. [hyprpaper.conf](#17-hyprpaperconf) 18. [hypridle.conf](#18-hypridleconf) 19. [hyprlock.conf](#19-hyprlockconf) 20. [Waybar](#20-waybar) 21. [Dank Material Shell](#21-dank-material-shell) 22. [Setting Default Applications](#22-setting-default-applications) 23. [Enable Services](#23-enable-services) 24. [NVIDIA Troubleshooting](#24-nvidia-troubleshooting)
—
1. What is Hyprland?
Hyprland is a dynamic tiling Wayland compositor with first-class support for animations, blur, rounded corners, and per-window rules. Unlike traditional tiling window managers it is a full Wayland compositor — no separate X11 server is involved for native Wayland apps.
Key concepts:
– Compositor — Hyprland replaces both the window manager and the display server
– Workspaces — numbered virtual desktops; windows can be pinned or moved between them
– Layouts — dwindle (spiral tiling) and master are built in; floating windows are also supported
– IPC — Hyprland exposes a socket for scripting via hyprctl
– Config language — hyprlang, a structured key = value format with hot reload on save
—
2. The Hypr Ecosystem
The Hyprland project maintains a full suite of companion tools. All are available in the Arch extra repository unless noted.
hyprland | The Wayland compositor |
| hyprpaper | Wallpaper daemon — IPC-controlled, fast, supports per-monitor wallpapers |
| hypridle | Idle management — triggers actions (lock, suspend, dim) after configurable timeouts |
| hyprlock | GPU-accelerated screen locker — configured separately in hyprlock.conf |
| hyprshot | Screenshot tool — region, window, and output modes from the CLI |
| hyprpicker | On-screen color picker — outputs hex, rgb, or hsl to stdout |
| hyprlauncher | Official Hyprland application launcher |
| hyprsunset | Night light / blue light filter — adjustable color temperature |
| hyprsysteminfo | System info display (for bug reports or status scripts) |
| hyprpolkitagent | Polkit authentication agent — replaces polkit-gnome for Hyprland |
| xdg-desktop-portal-hyprland | XDG portal — enables screen sharing, window picking, global shortcuts |
| hyprland-qt-support | Qt platform integration for Hyprland |
| hyprcursor | Cursor theme library (dependency, handles cursor rendering) |
| hyprlang | Config language parser (dependency) |
| aquamarine | DRM/KMS rendering backend (dependency) |
—
3. Install Hyprland and Dependencies
Core packages
sudo pacman -S hyprland \
hyprpaper hypridle hyprlock hyprshot hyprpicker \
hyprlauncher hyprpolkitagent hyprsunset \
xdg-desktop-portal-hyprland xdg-desktop-portal-gtk \
qt5-wayland qt6-wayland \
xorg-xwayland
Audio stack
sudo pacman -S pipewire pipewire-alsa pipewire-pulse pipewire-jack \
wireplumber pavucontrol playerctl
Enable PipeWire immediately:
systemctl --user enable --now pipewire pipewire-pulse wireplumber
Fonts
sudo pacman -S noto-fonts noto-fonts-emoji noto-fonts-cjk \
ttf-jetbrains-mono-nerd ttf-font-awesome
XDG and theming tools
sudo pacman -S xdg-utils xdg-user-dirs nwg-look qt6ct
Create standard user directories:
xdg-user-dirs-update
—
4. NVIDIA Configuration
Hyprland does not officially support NVIDIA, but works well with the correct setup. These steps build on the NVIDIA driver installation from the Arch guide — the drivers and kernel parameters should already be in place.
modprobe options
Create /etc/modprobe.d/nvidia.conf:
sudo nano /etc/modprobe.d/nvidia.conf
options nvidia-drm modeset=1
options nvidia NVreg_PreserveVideoMemoryAllocations=1
NVreg_PreserveVideoMemoryAllocations=1 is required for proper suspend and resume on laptops. Rebuild initramfs to apply:
sudo mkinitcpio -P
Verify kernel parameters
Confirm nvidia-drm.modeset=1 and nvidia-drm.fbdev=1 are already in your GRUB cmdline from the Arch install guide:
cat /proc/cmdline | grep nvidia
If they are missing, add them to /etc/default/grub and run sudo grub-mkconfig -o /boot/grub/grub.cfg.
NVIDIA environment variables
All NVIDIA-specific environment variables are set in env.conf (section 8). They are not set system-wide here — Hyprland loads them at compositor startup so they apply to every child process.
—
5. Install Recommended Applications
Terminal — kitty
sudo pacman -S kitty
kitty is GPU-accelerated, supports Wayland natively, and is the most widely used terminal in the Hyprland community. Config lives at ~/.config/kitty/kitty.conf.
File manager — Thunar
sudo pacman -S thunar thunar-archive-plugin thunar-volman gvfs
gvfs provides mount support (USB drives, MTP devices). thunar-volman enables automatic device handling.
App launcher — wofi
sudo pacman -S wofi
wofi is a Wayland-native GTK launcher. Style it with ~/.config/wofi/style.css. Invoke with wofi --show drun for applications or wofi --show run for executables.
Status bar — Waybar
sudo pacman -S waybar
Copy the default config as a starting point:
mkdir -p ~/.config/waybar
cp /etc/xdg/waybar/config.jsonc ~/.config/waybar/
cp /etc/xdg/waybar/style.css ~/.config/waybar/
Important: The default config referencessway/workspaces. Change it tohyprland/workspacesfor Hyprland workspace integration.
Notification daemon — dunst
sudo pacman -S dunst
Config lives at ~/.config/dunst/dunstrc. Copy the default:
mkdir -p ~/.config/dunst
cp /etc/dunst/dunstrc ~/.config/dunst/dunstrc
Clipboard — wl-clipboard and cliphist
sudo pacman -S wl-clipboard cliphist
cliphist stores clipboard history. Watchers are started in autostart.conf and a keybind opens the history picker through wofi.
Image viewer — imv
sudo pacman -S imv
Lightweight Wayland-native image viewer. Used as the default for image MIME types.
Video player — mpv
sudo pacman -S mpv
Supports hardware-accelerated video decode via VA-API. Create ~/.config/mpv/mpv.conf:
hwdec=vaapi
gpu-api=vulkan
PDF viewer — zathura
sudo pacman -S zathura zathura-pdf-mupdf
Browser — Firefox
sudo pacman -S firefox
Firefox has full native Wayland support. No extra flags needed on modern versions.
AUR helper — yay
Some packages (handlr, kvantum) are AUR-only. Install yay:
sudo pacman -S --needed git base-devel
git clone https://aur.archlinux.org/yay.git /tmp/yay
cd /tmp/yay && makepkg -si
GTK/Qt theming
# GTK theme switcher (Wayland-native GUI)
sudo pacman -S nwg-look
# Qt6 appearance tool
sudo pacman -S qt6ct
# Qt Kvantum theme engine (AUR)
yay -S kvantum
Set Qt platform theme in env.conf:
env = QT_QPA_PLATFORMTHEME,qt6ct
Then open qt6ct and nwg-look to configure themes after your first Hyprland login.
—
6. Modular Configuration Structure
Hyprland’s config language supports the source = directive which includes another file at that point. All changes are hot-reloaded — edit a file, save it, and Hyprland picks up the changes immediately without restarting.
Directory layout
~/.config/hypr/
├── hyprland.conf # Main entry point — sources all conf files below
├── conf/
│ ├── env.conf # Environment variables (NVIDIA, Qt, XDG, cursor)
│ ├── monitor.conf # Monitor layout, resolution, refresh rate, scaling
│ ├── autostart.conf # exec-once lines for services and daemons
│ ├── input.conf # Keyboard, touchpad, mouse settings
│ ├── decorations.conf # Blur, shadows, rounding, opacity
│ ├── animations.conf # Animation curves and durations
│ ├── keybinds.conf # All keybindings
│ ├── windowrules.conf # Per-app window rules
│ └── workspaces.conf # Workspace rules and assignments
├── hyprpaper.conf
├── hypridle.conf
└── hyprlock.conf
Create the directory structure:
mkdir -p ~/.config/hypr/conf
—
7. hyprland.conf — Main Entry Point
~/.config/hypr/hyprland.conf
# ============================================================
# HYPRLAND MAIN CONFIG
# Sources all modular conf files
# ============================================================
# Load environment variables first — everything else depends on them
source = ~/.config/hypr/conf/env.conf
# Hardware and layout
source = ~/.config/hypr/conf/monitor.conf
source = ~/.config/hypr/conf/input.conf
# Visuals
source = ~/.config/hypr/conf/decorations.conf
source = ~/.config/hypr/conf/animations.conf
# Behaviour
source = ~/.config/hypr/conf/keybinds.conf
source = ~/.config/hypr/conf/windowrules.conf
source = ~/.config/hypr/conf/workspaces.conf
# Startup
source = ~/.config/hypr/conf/autostart.conf
# ============================================================
# GENERAL SETTINGS
# ============================================================
general {
gaps_in = 5
gaps_out = 10
border_size = 2
col.active_border = rgba(88c0d0ff) rgba(81a1c1ff) 45deg
col.inactive_border = rgba(4c566aff)
resize_on_border = true
layout = dwindle
}
dwindle {
pseudotile = true
preserve_split = true
}
master {
new_status = master
}
misc {
force_default_wallpaper = 0
disable_hyprland_logo = true
disable_splash_rendering = true
vfr = true
vrr = 2
}
—
8. env.conf — Environment Variables
~/.config/hypr/conf/env.conf
# ============================================================
# NVIDIA — required for Wayland/Hyprland on NVIDIA hardware
# ============================================================
env = LIBVA_DRIVER_NAME,nvidia
env = GBM_BACKEND,nvidia-drm
env = __GLX_VENDOR_LIBRARY_NAME,nvidia
env = WLR_NO_HARDWARE_CURSORS,1
env = AQ_NO_MODIFIERS,1
# ============================================================
# WAYLAND SESSION
# ============================================================
env = XDG_SESSION_TYPE,wayland
env = XDG_CURRENT_DESKTOP,Hyprland
env = XDG_SESSION_DESKTOP,Hyprland
# ============================================================
# QT — force Wayland and set theme tool
# ============================================================
env = QT_QPA_PLATFORM,wayland
env = QT_QPA_PLATFORMTHEME,qt6ct
env = QT_WAYLAND_DISABLE_WINDOWDECORATION,1
env = QT_AUTO_SCREEN_SCALE_FACTOR,1
# ============================================================
# ELECTRON / CHROMIUM — force native Wayland
# ============================================================
env = ELECTRON_OZONE_PLATFORM_HINT,auto
env = NIXOS_OZONE_WL,1
# ============================================================
# CURSOR
# ============================================================
env = XCURSOR_THEME,Adwaita
env = XCURSOR_SIZE,24
env = HYPRCURSOR_THEME,Adwaita
env = HYPRCURSOR_SIZE,24
# ============================================================
# TOOLKIT — prefer Wayland over XWayland where possible
# ============================================================
env = GDK_BACKEND,wayland,x11,*
env = SDL_VIDEODRIVER,wayland
env = CLUTTER_BACKEND,wayland
# ============================================================
# DEFAULT TERMINAL (used by some launchers and scripts)
# ============================================================
env = TERMINAL,kitty
env = TERM,kitty
—
9. monitor.conf
~/.config/hypr/conf/monitor.conf
# ============================================================
# MONITOR CONFIGURATION
# Format: monitor = name, resolution@refreshrate, position, scale
# ============================================================
# Laptop built-in display
# Replace 1920x1080@144 with your actual resolution and refresh rate
# Run: hyprctl monitors — to see available monitors and their names
monitor = eDP-1, 1920x1080@144, 0x0, 1
# External monitor examples (uncomment and adjust as needed):
# monitor = HDMI-A-1, 2560x1440@60, 1920x0, 1
# monitor = DP-1, 3840x2160@60, 1920x0, 1.5
# Fallback: any unrecognised monitor uses preferred mode
monitor = , preferred, auto, 1
Run hyprctl monitors from a running Hyprland session to see exact monitor names and available modes.
—
10. autostart.conf
~/.config/hypr/conf/autostart.conf
# ============================================================
# AUTOSTART
# exec-once — runs once at Hyprland startup
# exec — runs every time the config is reloaded
# ============================================================
# D-Bus environment — required for screen sharing and portals
exec-once = dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP XDG_SESSION_TYPE
# Polkit agent — handles privilege escalation dialogs
exec-once = systemctl --user start hyprpolkitagent
# XDG portals — screen sharing, file pickers, global shortcuts
exec-once = /usr/lib/xdg-desktop-portal-hyprland
exec-once = /usr/lib/xdg-desktop-portal -r
# Wallpaper
exec-once = hyprpaper
# Idle management and screen lock
exec-once = hypridle
# Status bar
exec-once = waybar
# Notification daemon
exec-once = dunst
# Clipboard history watchers
exec-once = wl-paste --type text --watch cliphist store
exec-once = wl-paste --type image --watch cliphist store
# GTK dark mode
exec-once = gsettings set org.gnome.desktop.interface color-scheme prefer-dark
exec-once = gsettings set org.gnome.desktop.interface gtk-theme Adwaita-dark
—
11. input.conf
~/.config/hypr/conf/input.conf
# ============================================================
# INPUT — keyboard, touchpad, mouse
# ============================================================
input {
kb_layout = us
kb_variant =
kb_model =
kb_options =
kb_rules =
follow_mouse = 1
sensitivity = 0
accel_profile = flat
touchpad {
natural_scroll = true
disable_while_typing = true
tap-to-click = true
scroll_factor = 0.8
}
}
gestures {
workspace_swipe = true
workspace_swipe_fingers = 3
workspace_swipe_distance = 300
workspace_swipe_cancel_ratio = 0.5
}
—
12. decorations.conf
~/.config/hypr/conf/decorations.conf
# ============================================================
# DECORATIONS — blur, shadows, rounding, opacity
# ============================================================
decoration {
rounding = 10
active_opacity = 1.0
inactive_opacity = 0.95
shadow {
enabled = true
range = 15
render_power = 3
color = rgba(0, 0, 0, 0.4)
}
blur {
enabled = true
size = 8
passes = 2
new_optimizations = true
xray = false
ignore_opacity = false
}
}
—
13. animations.conf
~/.config/hypr/conf/animations.conf
# ============================================================
# ANIMATIONS — bezier curves and animation rules
# ============================================================
animations {
enabled = true
# Custom bezier curves
bezier = overshot, 0.05, 0.9, 0.1, 1.1
bezier = smoothOut, 0.36, 0, 0.66, -0.56
bezier = smoothIn, 0.25, 1, 0.5, 1
bezier = linear, 0, 0, 1, 1
# Window animations
animation = windows, 1, 5, overshot, slide
animation = windowsOut, 1, 4, smoothOut, slide
animation = windowsMove, 1, 4, smoothIn
# Border
animation = border, 1, 10, default
# Fade
animation = fade, 1, 5, smoothIn
animation = fadeOut, 1, 5, smoothOut
# Workspaces
animation = workspaces, 1, 6, overshot, slidevert
}
—
14. keybinds.conf
~/.config/hypr/conf/keybinds.conf
# ============================================================
# KEYBINDS
# bind = MODS, key, dispatcher, params
# ============================================================
$mod = SUPER
# ---- Applications ----
bind = $mod, Return, exec, kitty
bind = $mod, E, exec, thunar
bind = $mod, B, exec, firefox
bind = $mod, D, exec, wofi --show drun
# ---- Window management ----
bind = $mod, Q, killactive
bind = $mod, F, fullscreen
bind = $mod SHIFT, F, togglefloating
bind = $mod, P, pseudo
bind = $mod, J, togglesplit
# ---- Focus movement ----
bind = $mod, left, movefocus, l
bind = $mod, right, movefocus, r
bind = $mod, up, movefocus, u
bind = $mod, down, movefocus, d
bind = $mod, H, movefocus, l
bind = $mod, L, movefocus, r
bind = $mod, K, movefocus, u
bind = $mod, J, movefocus, d
# ---- Move windows ----
bind = $mod SHIFT, left, movewindow, l
bind = $mod SHIFT, right, movewindow, r
bind = $mod SHIFT, up, movewindow, u
bind = $mod SHIFT, down, movewindow, d
# ---- Resize windows (submap) ----
bind = $mod, R, submap, resize
submap = resize
binde = , right, resizeactive, 30 0
binde = , left, resizeactive, -30 0
binde = , up, resizeactive, 0 -30
binde = , down, resizeactive, 0 30
bind = , escape, submap, reset
bind = , Return, submap, reset
submap = reset
# ---- Workspaces ----
bind = $mod, 1, workspace, 1
bind = $mod, 2, workspace, 2
bind = $mod, 3, workspace, 3
bind = $mod, 4, workspace, 4
bind = $mod, 5, workspace, 5
bind = $mod, 6, workspace, 6
bind = $mod, 7, workspace, 7
bind = $mod, 8, workspace, 8
bind = $mod, 9, workspace, 9
bind = $mod, 0, workspace, 10
# Move window to workspace
bind = $mod SHIFT, 1, movetoworkspace, 1
bind = $mod SHIFT, 2, movetoworkspace, 2
bind = $mod SHIFT, 3, movetoworkspace, 3
bind = $mod SHIFT, 4, movetoworkspace, 4
bind = $mod SHIFT, 5, movetoworkspace, 5
bind = $mod SHIFT, 6, movetoworkspace, 6
bind = $mod SHIFT, 7, movetoworkspace, 7
bind = $mod SHIFT, 8, movetoworkspace, 8
bind = $mod SHIFT, 9, movetoworkspace, 9
bind = $mod SHIFT, 0, movetoworkspace, 10
# Scroll through workspaces
bind = $mod, mouse_down, workspace, e+1
bind = $mod, mouse_up, workspace, e-1
# ---- Special workspace (scratchpad) ----
bind = $mod, S, togglespecialworkspace, magic
bind = $mod SHIFT, S, movetoworkspace, special:magic
# ---- Mouse binds ----
bindm = $mod, mouse:272, movewindow
bindm = $mod, mouse:273, resizewindow
# ---- Screenshots ----
bind = , Print, exec, hyprshot -m region
bind = SHIFT, Print, exec, hyprshot -m window
bind = $mod, Print, exec, hyprshot -m output
# ---- Clipboard history ----
bind = $mod, V, exec, cliphist list | wofi --dmenu | cliphist decode | wl-copy
# ---- Color picker ----
bind = $mod SHIFT, C, exec, hyprpicker -a
# ---- Audio (requires playerctl + pipewire) ----
bind = , XF86AudioPlay, exec, playerctl play-pause
bind = , XF86AudioNext, exec, playerctl next
bind = , XF86AudioPrev, exec, playerctl previous
bind = , XF86AudioRaiseVolume, exec, wpctl set-volume -l 1.5 @DEFAULT_AUDIO_SINK@ 5%+
bind = , XF86AudioLowerVolume, exec, wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-
bind = , XF86AudioMute, exec, wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle
# ---- Brightness (requires brightnessctl) ----
bind = , XF86MonBrightnessUp, exec, brightnessctl set 10%+
bind = , XF86MonBrightnessDown, exec, brightnessctl set 10%-
# ---- Hyprland ----
bind = $mod SHIFT, R, exec, hyprctl reload
bind = $mod SHIFT, M, exit
bind = $mod, L, exec, hyprlock
Installbrightnessctl(sudo pacman -S brightnessctl) for the brightness keybinds to work.
—
15. windowrules.conf
~/.config/hypr/conf/windowrules.conf
# ============================================================
# WINDOW RULES
# windowrulev2 = rule, matcher
# Matchers: class, title, xwayland, floating, fullscreen, etc.
# ============================================================
# Float common utility windows
windowrulev2 = float, class:(pavucontrol)
windowrulev2 = float, class:(nm-connection-editor)
windowrulev2 = float, class:(blueman-manager)
windowrulev2 = float, class:(nwg-look)
windowrulev2 = float, class:(qt6ct)
windowrulev2 = float, class:(kvantum)
# Size floating windows
windowrulev2 = size 800 600, class:(pavucontrol)
windowrulev2 = size 900 650, class:(thunar), floating:1
# File manager opens floating
windowrulev2 = float, class:(thunar), title:(File Operation Progress)
# Firefox picture-in-picture
windowrulev2 = float, title:(Picture-in-Picture)
windowrulev2 = pin, title:(Picture-in-Picture)
windowrulev2 = size 480 270, title:(Picture-in-Picture)
windowrulev2 = move 100%-490 100%-290, title:(Picture-in-Picture)
# Fix XWayland apps
windowrulev2 = rounding 0, xwayland:1, floating:1
windowrulev2 = center, xwayland:1, floating:1
# Idle inhibit when fullscreen (prevents screen lock during video)
windowrulev2 = idleinhibit fullscreen, class:(.*)
# Workspace assignments
windowrulev2 = workspace 2, class:(firefox)
windowrulev2 = workspace 3, class:(thunar)
—
16. workspaces.conf
~/.config/hypr/conf/workspaces.conf
# ============================================================
# WORKSPACE RULES
# ============================================================
# Persistent workspaces on the laptop screen
workspace = 1, monitor:eDP-1, default:true
workspace = 2, monitor:eDP-1
workspace = 3, monitor:eDP-1
workspace = 4, monitor:eDP-1
workspace = 5, monitor:eDP-1
# If an external monitor is connected, assign workspaces 6-10 to it
# workspace = 6, monitor:HDMI-A-1
# workspace = 7, monitor:HDMI-A-1
—
17. hyprpaper.conf
~/.config/hypr/hyprpaper.conf
# ============================================================
# HYPRPAPER — wallpaper daemon
# ============================================================
# Preload wallpapers into memory (do this for every wallpaper you use)
preload = ~/Pictures/Wallpapers/wallpaper.jpg
# Set wallpaper per monitor
# Format: wallpaper = monitor, path (leave monitor blank for all)
wallpaper = eDP-1, ~/Pictures/Wallpapers/wallpaper.jpg
# Show splash text (false = disable Hyprland splash)
splash = false
Place a wallpaper at ~/Pictures/Wallpapers/wallpaper.jpg before starting Hyprland, or adjust the path. You can also set a different image per monitor.
—
18. hypridle.conf
~/.config/hypr/hypridle.conf
# ============================================================
# HYPRIDLE — idle daemon
# Triggers actions after periods of inactivity
# ============================================================
general {
lock_cmd = pidof hyprlock || hyprlock # lock only if not already locked
before_sleep_cmd = loginctl lock-session # lock before suspend
after_sleep_cmd = hyprctl dispatch dpms on # turn screen on after resume
ignore_dbus_inhibit = false
}
# Dim screen at 2.5 minutes
listener {
timeout = 150
on-timeout = brightnessctl -s set 20%
on-resume = brightnessctl -r
}
# Lock screen at 5 minutes
listener {
timeout = 300
on-timeout = loginctl lock-session
}
# Turn off display at 5.5 minutes (30s after lock)
listener {
timeout = 330
on-timeout = hyprctl dispatch dpms off
on-resume = hyprctl dispatch dpms on
}
# Suspend at 30 minutes
listener {
timeout = 1800
on-timeout = systemctl suspend
}
—
19. hyprlock.conf
~/.config/hypr/hyprlock.conf
# ============================================================
# HYPRLOCK — screen locker
# Without a config hyprlock renders a blank screen
# ============================================================
general {
disable_loading_bar = false
hide_cursor = true
grace = 0
no_fade_in = false
}
background {
monitor =
path = ~/Pictures/Wallpapers/wallpaper.jpg
blur_size = 7
blur_passes = 3
brightness = 0.6
contrast = 0.9
vibrancy = 0.2
}
input-field {
monitor =
size = 300, 50
outline_thickness = 2
dots_size = 0.25
dots_spacing = 0.3
outer_color = rgba(88c0d0ff)
inner_color = rgba(2e344080)
font_color = rgba(eceff4ff)
fade_on_empty = true
placeholder_text = Password...
hide_input = false
check_color = rgba(a3be8cff)
fail_color = rgba(bf616aff)
fail_text = $FAIL ($ATTEMPTS)
position = 0, -100
halign = center
valign = center
}
label {
monitor =
text = $TIME
color = rgba(eceff4ff)
font_size = 64
font_family = JetBrains Mono Nerd Font
position = 0, 200
halign = center
valign = center
}
label {
monitor =
text = $USER
color = rgba(d8dee9cc)
font_size = 16
font_family = JetBrains Mono Nerd Font
position = 0, -40
halign = center
valign = center
}
—
20. Waybar
Waybar is the most widely used status bar for Hyprland. The key change from the default config is replacing the sway workspace module with the Hyprland one.
Edit ~/.config/waybar/config.jsonc and find the modules-left section:
"modules-left": ["hyprland/workspaces", "hyprland/submap", "hyprland/window"],
"modules-center": ["clock"],
"modules-right": ["pulseaudio", "network", "battery", "tray"],
Add the Hyprland workspace module configuration:
"hyprland/workspaces": {
"format": "{icon}",
"on-click": "activate",
"format-icons": {
"1": "1", "2": "2", "3": "3", "4": "4", "5": "5",
"active": "",
"default": ""
},
"sort-by-number": true
},
"hyprland/window": {
"max-length": 80,
"separate-outputs": true
},
"clock": {
"format": " {:%H:%M}",
"format-alt": " {:%Y-%m-%d}",
"tooltip-format": "{:%B %Y}\n{calendar}"
},
"battery": {
"states": { "warning": 30, "critical": 15 },
"format": "{icon} {capacity}%",
"format-charging": " {capacity}%",
"format-icons": ["", "", "", "", ""]
},
"network": {
"format-wifi": " {signalStrength}%",
"format-ethernet": " {ipaddr}",
"format-disconnected": "⚠ Disconnected",
"tooltip-format": "{ifname}: {ipaddr}\n{essid}"
},
"pulseaudio": {
"format": "{icon} {volume}%",
"format-muted": " Muted",
"format-icons": { "default": ["", "", ""] },
"on-click": "pavucontrol"
}
—
21. Dank Material Shell
Dank Material Shell (DMS) is a full desktop shell built with Quickshell (QML) and Go. It replaces waybar, dunst, wofi, hyprlock, hypridle, and the polkit agent with a unified system that applies dynamic Material You color theming driven by your wallpaper via matugen.
What DMS provides: – Taskbar/panel with workspace indicators, system tray, clock, and media controls – Spotlight-style launcher (apps, files, emojis, calculations, open windows) – Notification center with grouped notifications and keyboard navigation – Control center (network, Bluetooth, audio, display, night mode) – Lock screen with idle detection and auto-suspend – Clipboard history with previews – Dynamic color theming — changing your wallpaper recolors the entire shell, GTK, Qt, and terminal automatically
Note: If you install DMS, you do not need to separately run waybar, dunst, wofi, or hypridle — DMS handles all of these. You can keep them installed as fallbacks.
Installation
# From official Arch repos
sudo pacman -S dms-shell
# Or using the one-command installer
curl -fsSL https://install.danklinux.com | sh
Dependencies
sudo pacman -S quickshell matugen wl-clipboard cliphist
Hyprland integration
Add to autostart.conf (replaces or supplements the waybar/dunst/hypridle lines):
# D-Bus environment (required)
exec-once = dbus-update-activation-environment --systemd --all
# Start Hyprland systemd session target
exec-once = systemctl --user start hyprland-session.target
Create a systemd user target at ~/.config/systemd/user/hyprland-session.target:
[Unit]
Description=Hyprland session
BindsTo=graphical-session.target
After=graphical-session.target
[Install]
WantedBy=graphical-session.target
Bind DMS to the session target and enable it:
systemctl --user add-wants hyprland-session.target dms
systemctl --user enable dms
Run first-time setup (generates Hyprland-specific configuration):
dms setup
Dynamic theming with matugen
DMS uses matugen to extract a Material You color palette from your wallpaper and apply it to GTK, Qt, terminal configs, and the shell itself. When you change your wallpaper through DMS, theming updates automatically.
To manually trigger a theme update with a specific wallpaper:
matugen image ~/Pictures/Wallpapers/wallpaper.jpg
kitty — Dynamic Colors with DMS
DMS automatically generates two kitty theme files via its matugen pipeline whenever the wallpaper changes:
| File | Purpose | |——|———| |~/.config/kitty/dank-theme.conf | Window colors (background, foreground, cursor, 16 ANSI colors) |
| ~/.config/kitty/dank-tabs.conf | Tab bar colors |
These files are regenerated every time you change your wallpaper or theme through DMS. To activate them, kitty must be told to include them.
Step 1 — Include the DMS theme files in kitty.conf
echo "include dank-tabs.conf" >> ~/.config/kitty/kitty.conf
echo "include dank-theme.conf" >> ~/.config/kitty/kitty.conf
Or edit ~/.config/kitty/kitty.conf manually and add these two lines at the bottom:
# DMS dynamic theme (generated by matugen on wallpaper change)
include dank-tabs.conf
include dank-theme.conf
Step 2 — Remove conflicting auto-saved theme files
If you have ever used kitty’s built-in theme chooser (kitty +kitten themes), kitty saves override files that will prevent DMS colors from applying:
rm -f ~/.config/kitty/current-theme.conf
rm -f ~/.config/kitty/dark-theme.auto.conf
rm -f ~/.config/kitty/light-theme.auto.conf
rm -f ~/.config/kitty/no-preference-theme.auto.conf
Step 3 — Generate the initial theme
Run matugen once to create the dank-theme.conf and dank-tabs.conf files before launching kitty:
matugen image ~/Pictures/Wallpapers/wallpaper.jpg
After this, kitty will use the DMS color palette. Every subsequent wallpaper change through DMS regenerates these files automatically — no further action is needed.
Always use Dark Theme (optional)
By default, DMS uses mode-aware colors (.default variant) — the terminal background follows the light/dark mode setting of the shell. If you want kitty to always use the dark variant of the palette regardless of shell mode, enable this in DMS settings:
DMS Settings → Terminals → Always use Dark Theme
When enabled, DMS substitutes .default with .dark at build time when generating dank-theme.conf.
Verify
Open kitty from within Hyprland (not a bare TTY) and confirm the colors match the shell:
# The background and accent colors should match the DMS panel
echo $TERM # should be: xterm-kitty
cat ~/.config/kitty/dank-theme.conf # should contain color0–color15 values
If kitty still shows old colors, reload it:
kill -SIGUSR1 $(pgrep kitty)
—
22. Setting Default Applications
Default application associations are controlled by ~/.config/mimeapps.list and the xdg-mime command from xdg-utils.
Create mimeapps.list
nano ~/.config/mimeapps.list
[Default Applications]
# Browser
x-scheme-handler/http=firefox.desktop
x-scheme-handler/https=firefox.desktop
text/html=firefox.desktop
application/xhtml+xml=firefox.desktop
# File manager
inode/directory=thunar.desktop
# Text editor
text/plain=nvim.desktop
# Images
image/jpeg=imv.desktop
image/png=imv.desktop
image/gif=imv.desktop
image/webp=imv.desktop
image/svg+xml=imv.desktop
# Video
video/mp4=mpv.desktop
video/x-matroska=mpv.desktop
video/webm=mpv.desktop
video/avi=mpv.desktop
# Audio
audio/mpeg=mpv.desktop
audio/flac=mpv.desktop
audio/ogg=mpv.desktop
audio/x-wav=mpv.desktop
# Documents
application/pdf=org.pwmt.zathura.desktop
# Archives (open with Thunar file manager)
application/zip=thunar.desktop
application/x-tar=thunar.desktop
application/x-compressed-tar=thunar.desktop
Set defaults with xdg-mime
# Browser
xdg-mime default firefox.desktop x-scheme-handler/http
xdg-mime default firefox.desktop x-scheme-handler/https
# File manager
xdg-mime default thunar.desktop inode/directory
# Image viewer
xdg-mime default imv.desktop image/jpeg
xdg-mime default imv.desktop image/png
# Video player
xdg-mime default mpv.desktop video/mp4
xdg-mime default mpv.desktop video/x-matroska
# Query a current default at any time
xdg-mime query default image/jpeg
handlr — better xdg-open (AUR)
handlr is a Rust replacement for xdg-open that handles MIME types more cleanly and supports glob patterns:
yay -S handlr-bin
# Set by file extension
handlr set .pdf zathura.desktop
handlr set .png imv.desktop
handlr set .mp4 mpv.desktop
# Set by MIME type
handlr set x-scheme-handler/https firefox.desktop
handlr set inode/directory thunar.desktop
# Open a file (respects all defaults)
handlr open ~/document.pdf
# List all current defaults
handlr list
xdg-user-dirs
Confirm standard user directories are created:
xdg-user-dirs-update
cat ~/.config/user-dirs.dirs
If you want to customise them:
nano ~/.config/user-dirs.dirs
XDG_DESKTOP_DIR="$HOME/Desktop"
XDG_DOWNLOAD_DIR="$HOME/Downloads"
XDG_DOCUMENTS_DIR="$HOME/Documents"
XDG_MUSIC_DIR="$HOME/Music"
XDG_PICTURES_DIR="$HOME/Pictures"
XDG_VIDEOS_DIR="$HOME/Videos"
—
23. Enable Services
These services need to be enabled to start automatically:
# PipeWire audio (if not already done in step 3)
systemctl --user enable --now pipewire pipewire-pulse wireplumber
# Hyprpolkit agent (started via autostart.conf — no separate enable needed)
# DMS (if installed)
systemctl --user enable dms
Verify all running:
systemctl --user status pipewire pipewire-pulse wireplumber
Start Hyprland
From a TTY (not inside another desktop session):
Hyprland
To start Hyprland automatically on TTY login, add to~/.bash_profileor~/.zprofile:
> if [ -z "$DISPLAY" ] && [ "$XDG_VTNR" = "1" ]; then
exec Hyprland
fi
—
24. NVIDIA Troubleshooting
| Symptom | Fix | |—|—| | Blank or flickering screen on start | Addenv = AQ_NO_MODIFIERS,1 to env.conf — resolves ~80% of NVIDIA rendering issues |
| Invisible or corrupted cursor | Ensure WLR_NO_HARDWARE_CURSORS,1 is in env.conf |
| External monitor not detected | Try AQ_NO_MODIFIERS,1; or set BIOS to Discrete GPU only; or AQ_DRM_DEVICES,/dev/dri/card1 |
| Screen freezes after suspend/resume | Confirm NVreg_PreserveVideoMemoryAllocations=1 is in /etc/modprobe.d/nvidia.conf |
| Electron apps (VS Code, Discord) not Wayland native | Confirm ELECTRON_OZONE_PLATFORM_HINT,auto is in env.conf |
| Screen tearing in games | Enable VRR: set vrr = 2 in misc {} block in hyprland.conf |
| VA-API fails | Run LIBVA_DRIVER_NAME=nvidia vainfo --display drm --device /dev/dri/renderD128 and try renderD129 if it fails |
| Symbol lookup errors on Hyprland start | Library version mismatch — run sudo pacman -Syu to sync all hypr* packages together |
| hyprctl returns socket error | Hyprland isn’t running, or $HYPRLAND_INSTANCE_SIGNATURE is unset — check with echo $HYPRLAND_INSTANCE_SIGNATURE |
Verify NVIDIA is active
These environment variables are set by Hyprland when it reads env.conf at startup. They only exist inside processes that Hyprland spawns. Running them from a bare TTY before Hyprland starts will always produce empty output. Open a terminal inside a running Hyprland session to verify them.
# Run these from inside kitty (or any terminal) within Hyprland — NOT from a bare TTY
echo $GBM_BACKEND # should be: nvidia-drm
echo $__GLX_VENDOR_LIBRARY_NAME # should be: nvidia
echo $LIBVA_DRIVER_NAME # should be: nvidia
echo $WLR_NO_HARDWARE_CURSORS # should be: 1
echo $XDG_SESSION_TYPE # should be: wayland
nvidia-smi # shows driver version and GPU usage
hyprctl monitors # confirms Hyprland sees your displays
If any variable is empty inside Hyprland, check that env.conf exists and is being sourced:
cat ~/.config/hypr/conf/env.conf
grep "source.*env" ~/.config/hypr/hyprland.conf
// categories
// recent posts