Hyprland on Arch: NVIDIA + Dank Material Shell + Modular Config

// 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 hyprctlConfig 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.

| Package | Role | |—|—| | 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 references sway/workspaces. Change it to hyprland/workspaces for 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

Install brightnessctl (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_profile or ~/.zprofile:
> if [ -z "$DISPLAY" ] && [ "$XDG_VTNR" = "1" ]; then
exec Hyprland
fi

24. NVIDIA Troubleshooting

| Symptom | Fix | |—|—| | Blank or flickering screen on start | Add env = 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

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top