Files
dotfiles/dotfiles/config/hypr/hyprland.conf
Ivan Malison feaca43946 Set IMALISON_SESSION_TYPE env var for reliable X11/Wayland detection
systemd user environment persists across login sessions, so
XDG_SESSION_TYPE can be stale. Proactively set a custom variable
on each session start so ConditionEnvironment checks are reliable.

Use it for xsettingsd and random-background (X11-only services).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-18 19:05:35 -07:00

594 lines
24 KiB
Plaintext

# Hyprland Configuration
# XMonad-like dynamic tiling using hy3 plugin
# Based on XMonad configuration from xmonad.hs
# =============================================================================
# PLUGINS (Hyprland pinned to 0.53.0 to match hy3)
# =============================================================================
# Load the plugin before parsing keybinds/layouts that depend on it
plugin = /run/current-system/sw/lib/libhy3.so
plugin = /run/current-system/sw/lib/libhyprexpo.so
# =============================================================================
# MONITORS
# =============================================================================
monitor=,preferred,auto,1
# =============================================================================
# PROGRAMS
# =============================================================================
$terminal = ghostty
$fileManager = dolphin
$menu = rofi -show drun -show-icons
$runMenu = rofi -show run
# =============================================================================
# ENVIRONMENT VARIABLES
# =============================================================================
env = XCURSOR_SIZE,24
env = QT_QPA_PLATFORMTHEME,qt5ct
# Used by ~/.config/hypr/scripts/* to keep workspace IDs bounded.
env = HYPR_MAX_WORKSPACE,9
# =============================================================================
# INPUT CONFIGURATION
# =============================================================================
input {
kb_layout = us
kb_variant =
kb_model =
kb_options =
kb_rules =
follow_mouse = 1
touchpad {
natural_scroll = no
}
sensitivity = 0
}
# Cursor warping behavior
cursor {
persistent_warps = true
}
# =============================================================================
# GENERAL SETTINGS
# =============================================================================
general {
gaps_in = 5
gaps_out = 10
border_size = 2
col.active_border = rgba(edb443ee) rgba(33ccffee) 45deg
col.inactive_border = rgba(595959aa)
# Use hy3 layout for XMonad-like dynamic tiling
layout = hy3
allow_tearing = false
}
# =============================================================================
# DECORATION
# =============================================================================
decoration {
rounding = 5
blur {
enabled = true
size = 3
passes = 1
}
# Fade inactive windows (like XMonad's fadeInactive)
active_opacity = 1.0
inactive_opacity = 0.9
}
# =============================================================================
# ANIMATIONS
# =============================================================================
animations {
enabled = yes
bezier = myBezier, 0.05, 0.9, 0.1, 1.05
bezier = linear, 0, 0, 1, 1
animation = windows, 1, 4, myBezier
animation = windowsOut, 1, 4, default, popin 80%
animation = border, 1, 10, default
animation = borderangle, 1, 8, default
animation = fade, 1, 4, default
animation = workspaces, 1, 4, default
}
# =============================================================================
# MASTER LAYOUT CONFIGURATION
# =============================================================================
master {
new_status = slave
mfact = 0.5
orientation = left
}
# Dwindle layout (alternative - binary tree like i3)
dwindle {
pseudotile = yes
preserve_split = yes
}
# =============================================================================
# WORKSPACE RULES (SMART GAPS)
# =============================================================================
# Replace no_gaps_when_only (removed in newer Hyprland)
# Remove gaps when there's only one visible tiled window (ignore special workspaces)
workspace = w[tv1]s[false], gapsout:0, gapsin:0
workspace = f[1]s[false], gapsout:0, gapsin:0
# Group/tabbed window configuration (built-in alternative to hy3 tabs)
group {
col.border_active = rgba(edb443ff)
col.border_inactive = rgba(091f2eff)
groupbar {
enabled = true
font_size = 12
height = 22
col.active = rgba(edb443ff)
col.inactive = rgba(091f2eff)
text_color = rgba(091f2eff)
}
}
# =============================================================================
# HY3/HYPREXPO PLUGIN CONFIG
# =============================================================================
plugin {
hy3 {
# Disable autotile to get XMonad-like manual control
autotile {
enable = false
}
# Tab configuration
tabs {
height = 22
padding = 6
render_text = true
text_font = "Sans"
text_height = 10
text_padding = 3
col.active = rgba(edb443ff)
col.inactive = rgba(091f2eff)
col.urgent = rgba(ff0000ff)
col.text.active = rgba(091f2eff)
col.text.inactive = rgba(ffffffff)
col.text.urgent = rgba(ffffffff)
}
}
hyprexpo {
# Always include workspace 1 in the overview grid
workspace_method = first 1
# Only show workspaces with windows
skip_empty = true
# 3 columns -> 3x3 grid when 9 workspaces are visible
columns = 3
}
}
# =============================================================================
# MISC
# =============================================================================
misc {
force_default_wallpaper = 0
disable_hyprland_logo = true
}
# =============================================================================
# BINDS OPTIONS
# =============================================================================
binds {
# Keep workspace history so "previous" can toggle back reliably.
allow_workspace_cycles = true
workspace_back_and_forth = true
}
# =============================================================================
# WINDOW RULES
# =============================================================================
# Float dialogs
windowrulev2 = float, class:^()$,title:^()$
windowrulev2 = float, title:^(Picture-in-Picture)$
windowrulev2 = float, title:^(Open File)$
windowrulev2 = float, title:^(Save File)$
windowrulev2 = float, title:^(Confirm)$
# Scratchpad windows - float and size
windowrulev2 = workspace special:htop silent, class:^(htop-scratch)$
windowrulev2 = float, class:^(htop-scratch)$
windowrulev2 = size 90% 90%, class:^(htop-scratch)$
windowrulev2 = center, class:^(htop-scratch)$
windowrulev2 = workspace special:volume silent, class:^(?i)(pavucontrol|pavucontrol-qt|org\.pulseaudio\.pavucontrol)$
windowrulev2 = float, class:^(?i)(pavucontrol|pavucontrol-qt|org\.pulseaudio\.pavucontrol)$
windowrulev2 = size 90% 90%, class:^(?i)(pavucontrol|pavucontrol-qt|org\.pulseaudio\.pavucontrol)$
windowrulev2 = center, class:^(?i)(pavucontrol|pavucontrol-qt|org\.pulseaudio\.pavucontrol)$
windowrulev2 = workspace special:spotify silent, class:^(spotify)$
windowrulev2 = float, class:^(spotify)$
windowrulev2 = size 90% 90%, class:^(spotify)$
windowrulev2 = center, class:^(spotify)$
windowrulev2 = workspace special:element silent, class:^(Element)$
windowrulev2 = float, class:^(Element)$
windowrulev2 = size 90% 90%, class:^(Element)$
windowrulev2 = center, class:^(Element)$
windowrulev2 = workspace special:slack silent, class:^(Slack)$
windowrulev2 = float, class:^(Slack)$
windowrulev2 = size 90% 90%, class:^(Slack)$
windowrulev2 = center, class:^(Slack)$
windowrulev2 = workspace special:transmission silent, class:^(transmission-gtk)$
windowrulev2 = float, class:^(transmission-gtk)$
windowrulev2 = size 90% 90%, class:^(transmission-gtk)$
windowrulev2 = center, class:^(transmission-gtk)$
# Gmail and Messages (Chrome windows)
windowrulev2 = workspace special:gmail silent, class:^(google-chrome)$,title:^(.*@gmail.com.*Gmail.*)$
windowrulev2 = float, class:^(google-chrome)$,title:^(.*@gmail.com.*Gmail.*)$
windowrulev2 = size 90% 90%, class:^(google-chrome)$,title:^(.*@gmail.com.*Gmail.*)$
windowrulev2 = center, class:^(google-chrome)$,title:^(.*@gmail.com.*Gmail.*)$
windowrulev2 = workspace special:messages silent, class:^(google-chrome)$,title:^(Messages.*)$
windowrulev2 = float, class:^(google-chrome)$,title:^(Messages.*)$
windowrulev2 = size 90% 90%, class:^(google-chrome)$,title:^(Messages.*)$
windowrulev2 = center, class:^(google-chrome)$,title:^(Messages.*)$
# =============================================================================
# KEY BINDINGS
# =============================================================================
# Modifier keys
$mainMod = SUPER
$modAlt = SUPER ALT
$hyper = SUPER CTRL ALT
# -----------------------------------------------------------------------------
# Program Launching
# -----------------------------------------------------------------------------
bind = $mainMod, P, exec, $menu
bind = $mainMod SHIFT, P, exec, $runMenu
bind = $mainMod SHIFT, Return, exec, $terminal
# -----------------------------------------------------------------------------
# Overview (Hyprexpo)
# -----------------------------------------------------------------------------
bind = $mainMod, TAB, hyprexpo:expo, toggle
bind = $mainMod, Q, killactive,
bind = $mainMod SHIFT, C, killactive,
bind = $mainMod SHIFT, Q, exit,
# Emacs-everywhere (like XMonad's emacs-everywhere)
bind = $mainMod, E, exec, emacsclient --eval '(emacs-everywhere)'
bind = $mainMod, V, exec, wl-paste | xdotool type --file -
# Chrome/Browser (raise or spawn like XMonad's bindBringAndRaise)
bind = $modAlt, C, exec, ~/.config/hypr/scripts/raise-or-run.sh google-chrome google-chrome-stable
# -----------------------------------------------------------------------------
# SCRATCHPADS (Special Workspaces)
# -----------------------------------------------------------------------------
# Toggle scratchpads
bind = $modAlt, E, exec, ~/.config/hypr/scripts/toggle-scratchpad.sh element '^Element$' - element-desktop
bind = $modAlt, G, exec, ~/.config/hypr/scripts/toggle-scratchpad.sh gmail '^google-chrome$' '.*@gmail.com.*Gmail.*' google-chrome-stable --new-window https://mail.google.com/mail/u/0/#inbox
bind = $modAlt, H, exec, ~/.config/hypr/scripts/toggle-scratchpad.sh htop '^htop-scratch$' - alacritty --class htop-scratch --title htop -e htop
bind = $modAlt, M, exec, ~/.config/hypr/scripts/toggle-scratchpad.sh messages '^google-chrome$' '^Messages.*' google-chrome-stable --new-window https://messages.google.com/web/conversations
bind = $modAlt, K, exec, ~/.config/hypr/scripts/toggle-scratchpad.sh slack '^Slack$' - slack
bind = $modAlt, S, exec, ~/.config/hypr/scripts/toggle-scratchpad.sh spotify '^spotify$' - spotify
bind = $modAlt, T, exec, ~/.config/hypr/scripts/toggle-scratchpad.sh transmission '^transmission-gtk$' - transmission-gtk
bind = $modAlt, V, exec, ~/.config/hypr/scripts/toggle-scratchpad.sh volume '^(pavucontrol|pavucontrol-qt|org\.pulseaudio\.pavucontrol)$' - pavucontrol
# Move windows to scratchpads
bind = $modAlt SHIFT, E, movetoworkspace, special:element
bind = $modAlt SHIFT, G, movetoworkspace, special:gmail
bind = $modAlt SHIFT, H, movetoworkspace, special:htop
bind = $modAlt SHIFT, M, movetoworkspace, special:messages
bind = $modAlt SHIFT, K, movetoworkspace, special:slack
bind = $modAlt SHIFT, S, movetoworkspace, special:spotify
bind = $modAlt SHIFT, T, movetoworkspace, special:transmission
bind = $modAlt SHIFT, V, movetoworkspace, special:volume
# Hidden workspace (like XMonad's NSP)
bind = $mainMod, X, movetoworkspace, special:NSP
bind = $mainMod SHIFT, X, togglespecialworkspace, NSP
# -----------------------------------------------------------------------------
# DIRECTIONAL NAVIGATION (WASD - like XMonad Navigation2D)
# Using hy3 dispatchers for proper tree-based navigation
# -----------------------------------------------------------------------------
# Focus movement (Mod + WASD) - hy3:movefocus navigates the tree
bind = $mainMod, W, hy3:movefocus, u
bind = $mainMod, S, hy3:movefocus, d
bind = $mainMod, A, hy3:movefocus, l
bind = $mainMod, D, hy3:movefocus, r
# Move windows (Mod + Shift + WASD) - hy3:movewindow with once=true for swapping
bind = $mainMod SHIFT, W, exec, ~/.config/hypr/scripts/movewindow-follow-cursor.sh u once
bind = $mainMod SHIFT, S, exec, ~/.config/hypr/scripts/movewindow-follow-cursor.sh d once
bind = $mainMod SHIFT, A, exec, ~/.config/hypr/scripts/movewindow-follow-cursor.sh l once
bind = $mainMod SHIFT, D, exec, ~/.config/hypr/scripts/movewindow-follow-cursor.sh r once
# Resize windows (Mod + Ctrl + WASD)
binde = $mainMod CTRL, W, resizeactive, 0 -50
binde = $mainMod CTRL, S, resizeactive, 0 50
binde = $mainMod CTRL, A, resizeactive, -50 0
binde = $mainMod CTRL, D, resizeactive, 50 0
# Screen/Monitor focus (Hyper + WASD)
bind = $hyper, W, focusmonitor, u
bind = $hyper, S, focusmonitor, d
bind = $hyper, A, focusmonitor, l
bind = $hyper, D, focusmonitor, r
# Move window to monitor and follow (Hyper + Shift + WASD)
bind = $hyper SHIFT, W, movewindow, mon:u
bind = $hyper SHIFT, S, movewindow, mon:d
bind = $hyper SHIFT, A, movewindow, mon:l
bind = $hyper SHIFT, D, movewindow, mon:r
# Shift to empty workspace on screen direction (Hyper + Ctrl + WASD)
# Like XMonad's shiftToEmptyOnScreen
bind = $hyper CTRL, W, exec, ~/.config/hypr/scripts/shift-to-empty-on-screen.sh u
bind = $hyper CTRL, S, exec, ~/.config/hypr/scripts/shift-to-empty-on-screen.sh d
bind = $hyper CTRL, A, exec, ~/.config/hypr/scripts/shift-to-empty-on-screen.sh l
bind = $hyper CTRL, D, exec, ~/.config/hypr/scripts/shift-to-empty-on-screen.sh r
# -----------------------------------------------------------------------------
# LAYOUT CONTROL (XMonad-like with hy3)
# -----------------------------------------------------------------------------
# Create groups with different orientations (like XMonad layouts)
# hy3:makegroup creates a split/tab group from focused window
bind = $mainMod, Space, hy3:changegroup, toggletab
bind = $mainMod SHIFT, Space, hy3:changegroup, opposite
# Create specific group types
bind = $mainMod, H, hy3:makegroup, h
bind = $mainMod SHIFT, V, hy3:makegroup, v
# Mod+Ctrl+Space mirrors Mod+Space (tabs instead of fullscreen)
bind = $mainMod CTRL, Space, hy3:changegroup, toggletab
# Change group type (cycle h -> v -> tab)
bind = $mainMod, slash, hy3:changegroup, h
bind = $mainMod SHIFT, slash, hy3:changegroup, v
# Tab navigation (like XMonad's focus next/prev in tabbed)
bind = $mainMod, bracketright, hy3:focustab, r, wrap
bind = $mainMod, bracketleft, hy3:focustab, l, wrap
# Move window within tab group (hy3 has no movetab dispatcher)
bind = $mainMod SHIFT, bracketright, hy3:movewindow, r, visible
bind = $mainMod SHIFT, bracketleft, hy3:movewindow, l, visible
# Expand focus to parent group (like XMonad's focus parent)
bind = $mainMod, grave, hy3:expand, expand
bind = $mainMod SHIFT, grave, hy3:expand, base
# Fullscreen (like XMonad's NBFULL toggle)
bind = $mainMod, F, fullscreen, 0
bind = $mainMod SHIFT, F, fullscreen, 1
# Toggle floating
bind = $mainMod, T, togglefloating,
# Resize split ratio (hy3 uses resizeactive for splits)
binde = $mainMod, comma, resizeactive, -50 0
binde = $mainMod, period, resizeactive, 50 0
# Equalize window sizes on workspace (hy3)
bind = $mainMod SHIFT, equal, hy3:equalize, workspace
# Kill group - removes the focused window from its group
bind = $mainMod, N, hy3:killactive
# hy3:setswallow - set a window to swallow newly spawned windows
bind = $mainMod CTRL, M, hy3:setswallow, toggle
# Minimize/unminimize (via special workspace)
bind = $mainMod, M, exec, ~/.config/hypr/scripts/minimize-active.sh minimized
bind = $mainMod SHIFT, M, exec, ~/.config/hypr/scripts/unminimize-last.sh minimized
# Minimized "picker" mode:
# Open the minimized special workspace, focus a window, press Enter to restore it.
bind = $modAlt, Return, exec, ~/.config/hypr/scripts/minimized-mode.sh minimized
submap = minimized
bind = , Return, exec, ~/.config/hypr/scripts/unminimize-last.sh minimized; hyprctl dispatch submap reset
bind = , Escape, exec, ~/.config/hypr/scripts/minimized-cancel.sh minimized
bind = $modAlt, Return, exec, ~/.config/hypr/scripts/minimized-cancel.sh minimized
# Optional: basic focus navigation inside the picker.
bind = , H, movefocus, l
bind = , J, movefocus, d
bind = , K, movefocus, u
bind = , L, movefocus, r
bind = , left, movefocus, l
bind = , down, movefocus, d
bind = , up, movefocus, u
bind = , right, movefocus, r
submap = reset
# -----------------------------------------------------------------------------
# WORKSPACE CONTROL
# -----------------------------------------------------------------------------
# Switch workspaces (1-9 only)
bind = $mainMod, 1, workspace, 1
bind = $mainMod, 2, workspace, 2
bind = $mainMod, 3, workspace, 3
bind = $mainMod, 4, workspace, 4
bind = $mainMod, 5, workspace, 5
bind = $mainMod, 6, workspace, 6
bind = $mainMod, 7, workspace, 7
bind = $mainMod, 8, workspace, 8
bind = $mainMod, 9, workspace, 9
# Move window to workspace
bind = $mainMod SHIFT, 1, movetoworkspace, 1
bind = $mainMod SHIFT, 2, movetoworkspace, 2
bind = $mainMod SHIFT, 3, movetoworkspace, 3
bind = $mainMod SHIFT, 4, movetoworkspace, 4
bind = $mainMod SHIFT, 5, movetoworkspace, 5
bind = $mainMod SHIFT, 6, movetoworkspace, 6
bind = $mainMod SHIFT, 7, movetoworkspace, 7
bind = $mainMod SHIFT, 8, movetoworkspace, 8
bind = $mainMod SHIFT, 9, movetoworkspace, 9
# Move and follow to workspace (like XMonad's shiftThenView)
bind = $mainMod CTRL, 1, movetoworkspacesilent, 1
bind = $mainMod CTRL, 1, workspace, 1
bind = $mainMod CTRL, 2, movetoworkspacesilent, 2
bind = $mainMod CTRL, 2, workspace, 2
bind = $mainMod CTRL, 3, movetoworkspacesilent, 3
bind = $mainMod CTRL, 3, workspace, 3
bind = $mainMod CTRL, 4, movetoworkspacesilent, 4
bind = $mainMod CTRL, 4, workspace, 4
bind = $mainMod CTRL, 5, movetoworkspacesilent, 5
bind = $mainMod CTRL, 5, workspace, 5
bind = $mainMod CTRL, 6, movetoworkspacesilent, 6
bind = $mainMod CTRL, 6, workspace, 6
bind = $mainMod CTRL, 7, movetoworkspacesilent, 7
bind = $mainMod CTRL, 7, workspace, 7
bind = $mainMod CTRL, 8, movetoworkspacesilent, 8
bind = $mainMod CTRL, 8, workspace, 8
bind = $mainMod CTRL, 9, movetoworkspacesilent, 9
bind = $mainMod CTRL, 9, workspace, 9
# Workspace cycling (like XMonad's cycleWorkspaceOnCurrentScreen)
bind = $mainMod, backslash, exec, ~/.config/hypr/scripts/workspace-back.sh
# Swap current workspace with another (like XMonad's swapWithCurrent)
bind = $hyper, 5, exec, ~/.config/hypr/scripts/swap-workspaces.sh
# Go to next empty workspace (like XMonad's moveTo Next emptyWS)
bind = $hyper, E, exec, ~/.config/hypr/scripts/workspace-goto-empty.sh
# Move to next screen (like XMonad's shiftToNextScreenX)
bind = $mainMod, Z, focusmonitor, +1
bind = $mainMod SHIFT, Z, movewindow, mon:+1
# Shift to empty workspace and view (like XMonad's shiftToEmptyAndView)
bind = $mainMod SHIFT, H, exec, ~/.config/hypr/scripts/workspace-move-to-empty.sh
# -----------------------------------------------------------------------------
# WINDOW MANAGEMENT
# -----------------------------------------------------------------------------
# Go to window (rofi window switcher with icons)
bind = $mainMod, G, exec, ~/.config/hypr/scripts/go-to-window.sh
# Bring window (move to current workspace)
bind = $mainMod, B, exec, ~/.config/hypr/scripts/bring-window.sh
# Replace window (swap focused with selected - like XMonad's myReplaceWindow)
bind = $mainMod SHIFT, B, exec, ~/.config/hypr/scripts/replace-window.sh
# Gather windows of same class (like XMonad's gatherThisClass)
bind = $hyper, G, exec, ~/.config/hypr/scripts/gather-class.sh
# Focus next window of different class (like XMonad's focusNextClass)
bind = $mainMod, apostrophe, exec, ~/.config/hypr/scripts/focus-next-class.sh
# -----------------------------------------------------------------------------
# MEDIA KEYS
# -----------------------------------------------------------------------------
# Volume control (matching XMonad: Mod+I=up, Mod+K=down, Mod+U=mute)
binde = , XF86AudioRaiseVolume, exec, set_volume --unmute --change-volume +5
binde = , XF86AudioLowerVolume, exec, set_volume --unmute --change-volume -5
bind = , XF86AudioMute, exec, set_volume --toggle-mute
binde = $mainMod, I, exec, set_volume --unmute --change-volume +5
binde = $mainMod, K, exec, set_volume --unmute --change-volume -5
bind = $mainMod, U, exec, set_volume --toggle-mute
# Media player controls (matching XMonad: Mod+;=play, Mod+L=next, Mod+J=prev)
bind = $mainMod, semicolon, exec, playerctl play-pause
bind = , XF86AudioPlay, exec, playerctl play-pause
bind = , XF86AudioPause, exec, playerctl play-pause
bind = $mainMod, L, exec, playerctl next
bind = , XF86AudioNext, exec, playerctl next
bind = $mainMod, J, exec, playerctl previous
bind = , XF86AudioPrev, exec, playerctl previous
# Mute current window (like XMonad's toggle_mute_current_window)
bind = $hyper SHIFT, Q, exec, toggle_mute_current_window.sh
bind = $hyper CTRL, Q, exec, toggle_mute_current_window.sh only
# Brightness control
binde = , XF86MonBrightnessUp, exec, brightness.sh up
binde = , XF86MonBrightnessDown, exec, brightness.sh down
# -----------------------------------------------------------------------------
# UTILITY BINDINGS
# -----------------------------------------------------------------------------
bind = $hyper, V, exec, cliphist list | rofi -dmenu -p "Clipboard" | cliphist decode | wl-copy
bind = $hyper, P, exec, rofi-pass
bind = $hyper, H, exec, grim -g "$(slurp)" - | swappy -f -
bind = $hyper, C, exec, shell_command.sh
bind = $hyper, X, exec, rofi_command.sh
bind = $hyper SHIFT, L, exec, hyprlock
bind = $hyper, K, exec, rofi_kill_process.sh
bind = $hyper SHIFT, K, exec, rofi_kill_all.sh
bind = $hyper, R, exec, rofi-systemd
bind = $hyper, slash, exec, toggle_taffybar
bind = $hyper, 9, exec, start_synergy.sh
bind = $hyper, I, exec, rofi_select_input.hs
bind = $hyper, O, exec, rofi_paswitch
# Reload config
bind = $mainMod, R, exec, hyprctl reload
# -----------------------------------------------------------------------------
# MOUSE BINDINGS
# -----------------------------------------------------------------------------
bindm = $mainMod, mouse:272, movewindow
bindm = $mainMod, mouse:273, resizewindow
# Scroll through workspaces
bind = $mainMod, mouse_down, exec, ~/.config/hypr/scripts/workspace-scroll.sh +1
bind = $mainMod, mouse_up, exec, ~/.config/hypr/scripts/workspace-scroll.sh -1
# =============================================================================
# AUTOSTART
# =============================================================================
# Start Hyprland session target for systemd user services (e.g., waybar)
exec-once = systemctl --user set-environment IMALISON_SESSION_TYPE=wayland
exec-once = systemctl --user import-environment WAYLAND_DISPLAY XDG_CURRENT_DESKTOP HYPRLAND_INSTANCE_SIGNATURE
exec-once = systemctl --user start hyprland-session.target
exec-once = ~/.config/hypr/scripts/workspace-history.sh
# Scratchpad applications (spawn on demand via keybinds)
# exec-once = [workspace special:element silent] element-desktop
# exec-once = [workspace special:gmail silent] google-chrome-stable --new-window https://mail.google.com/mail/u/0/#inbox
# exec-once = [workspace special:htop silent] ghostty --class=htop-scratch --title=htop -e htop
# exec-once = [workspace special:messages silent] google-chrome-stable --new-window https://messages.google.com/web/conversations
# exec-once = [workspace special:slack silent] slack
# exec-once = [workspace special:spotify silent] spotify
# exec-once = [workspace special:transmission silent] transmission-gtk
# exec-once = [workspace special:volume silent] pavucontrol
# Clipboard history daemon
exec-once = wl-paste --type text --watch cliphist store
exec-once = wl-paste --type image --watch cliphist store
# Night light (optional - comment out if not needed)
# exec-once = wlsunset -l 37.7 -L -122.4