dotfiles/.config/hypr/hyprland.lua
2026-08-28 15:07:27 +02:00

222 lines
9.5 KiB
Lua

-- Hyprland 0.55+ Lua configuration.
-- https://wiki.hypr.land/Configuring/Start/
hl.config({ autogenerated = false })
-- Environment variables that must be present before the compositor starts.
hl.env("QT_QPA_PLATFORMTHEME", "qt5ct")
hl.env("QT_AUTO_SCREEN_SCALE_FACTOR", "1")
hl.env("QT_ENABLE_HIGHDPI_SCALING", "1")
hl.env("QT_QPA_PLATFORM", "wayland;xcb")
hl.env("XCURSOR_SIZE", "24")
hl.env("LIBVA_DRIVER_NAME", "nvidia")
hl.env("XDG_SESSION_TYPE", "wayland")
hl.env("__GLX_VENDOR_LIBRARY_NAME", "nvidia")
hl.env("WLR_DRM_DEVICES", "/dev/dri/card1:/dev/dri/card0")
hl.env("GDK_SCALE", "1")
hl.env("GDK_BACKEND", "wayland,x11")
hl.env("QT_WAYLAND_DISABLE_WINDOWDECORATION", "1")
hl.env("MOZ_ENABLE_WAYLAND", "1")
hl.env("XDG_SESSION_DESKTOP", "Hyprland")
hl.env("XDG_CURRENT_DESKTOP", "Hyprland")
hl.env("QT_ENABLE_FONTCONFIG_CACHE", "1")
hl.config({
cursor = { no_hardware_cursors = true },
debug = { disable_logs = false },
xwayland = { force_zero_scaling = true },
input = {
kb_layout = "us,cz",
kb_variant = ",qwerty",
kb_model = "",
kb_options = "grp:win_space_toggle",
kb_rules = "",
numlock_by_default = true,
follow_mouse = 1,
float_switch_override_focus = true,
sensitivity = 0,
touchpad = { natural_scroll = true },
touchdevice = { output = "HDMI-A-1", transform = 2 },
},
general = {
gaps_in = 5,
gaps_out = 10,
border_size = 1,
layout = "master",
resize_on_border = true,
},
decoration = {
rounding = 10,
dim_special = 0.3,
blur = {
enabled = true,
size = 2,
passes = 4,
new_optimizations = true,
ignore_opacity = true,
special = true,
},
},
animations = { enabled = true },
misc = {
disable_hyprland_logo = true,
disable_splash_rendering = true,
mouse_move_enables_dpms = true,
},
-- plugin = {
-- hyprtrails = { color = "rgba(ffaa00ff)" },
-- hyprexpo = {
-- columns = 3,
-- gap_size = 5,
-- bg_col = "rgb(111111)",
-- workspace_method = "center current",
-- },
-- },
})
hl.curve("wind", { type = "bezier", points = { { 0.05, 0.9 }, { 0.1, 1.05 } } })
hl.curve("winIn", { type = "bezier", points = { { 0.1, 1 }, { 0.1, 1 } } })
hl.curve("winOut", { type = "bezier", points = { { 0.3, 0 }, { 0, 1 } } })
hl.curve("liner", { type = "bezier", points = { { 1, 1 }, { 1, 1 } } })
hl.animation({ leaf = "windows", enabled = true, speed = 6, bezier = "wind", style = "slide" })
hl.animation({ leaf = "windowsIn", enabled = true, speed = 6, bezier = "winIn", style = "popin 80%" })
hl.animation({ leaf = "windowsOut", enabled = true, speed = 5, bezier = "winOut", style = "popin 80%" })
hl.animation({ leaf = "windowsMove", enabled = true, speed = 5, bezier = "wind", style = "slide" })
hl.animation({ leaf = "border", enabled = true, speed = 1, bezier = "liner" })
hl.animation({ leaf = "borderangle", enabled = true, speed = 30, bezier = "liner", style = "loop" })
hl.animation({ leaf = "fade", enabled = true, speed = 10, bezier = "default" })
hl.animation({ leaf = "workspaces", enabled = true, speed = 5, bezier = "wind" })
hl.gesture({ fingers = 3, direction = "horizontal", action = "workspace" })
hl.gesture({ fingers = 3, direction = "up", action = "fullscreen" })
hl.gesture({ fingers = 3, direction = "down", action = "fullscreen", mode = "maximize" })
-- UWSM imports the session environment before Hyprland starts.
hl.on("hyprland.start", function()
local commands = {
"systemctl --user start hyprpolkitagent",
"otd-daemon",
"lorri daemon",
"blueman-applet",
"udev-block-notify",
"echo us > /tmp/kb_layout",
"nm-applet --indicator",
"kdeconnect-indicator",
"hyprpm reload -n",
"wl-paste --type text --watch cliphist store",
"wl-paste --type image --watch cliphist store",
"fcitx5",
"easyeffects --gapplication-service",
"voxtype daemon",
"openrgb --startminimized",
}
for _, command in ipairs(commands) do hl.exec_cmd(command) end
end)
-- Layer effects for DMS and the older quickshell namespaces still in use.
local blurredNamespaces = {
"^quickshell:bar$", "^quickshell:popup$", "^quickshell:notificationPopup$",
"^quickshell:overview$", "^quickshell:sidebarLeft$", "^quickshell:sidebarRight$",
}
for _, namespace in ipairs(blurredNamespaces) do
hl.layer_rule({ match = { namespace = namespace }, blur = true, ignore_alpha = 0.2 })
end
for _, namespace in ipairs({ "^quickshell:overview$", "^quickshell:sidebarLeft$", "^quickshell:sidebarRight$" }) do
hl.layer_rule({ match = { namespace = namespace }, blur_popups = true })
end
hl.layer_rule({
name = "blur-dms",
match = { namespace = "^dms:(color-picker|clipboard|spotlight|settings)$" },
blur = true,
ignore_alpha = 0,
})
for _, namespace in ipairs({ "^gtk-layer-shell$", "^lockscreen$", "^rofi$" }) do
hl.layer_rule({ match = { namespace = namespace }, blur = true })
end
local function bind(keys, dispatcher, options)
hl.bind(keys, dispatcher, options)
end
-- Launchers and applications.
bind("SUPER + ALT + R", hl.dsp.exec_cmd("pkill rofi || ~/.config/rofi/bin/launcher"), { release = true })
bind("SUPER + ALT + P", hl.dsp.exec_cmd("pkill rofi || ~/.config/rofi/bin/powermenu"))
bind("XF86AudioRecord", hl.dsp.exec_cmd("voxtype record-toggle"))
bind("SUPER + O", hl.dsp.exec_cmd("voxtype record start"))
bind("SUPER + O", hl.dsp.exec_cmd("voxtype record stop"), { release = true })
bind("SUPER + T", hl.dsp.exec_cmd("kitty"))
bind("SUPER + K", hl.dsp.exec_cmd("kitty"))
bind("SUPER + B", hl.dsp.exec_cmd("vivaldi-stable"))
bind("SUPER + CTRL + Q", hl.dsp.exit())
bind("SUPER + E", hl.dsp.exec_cmd("cosmic-files"))
bind("SUPER + SHIFT + E", hl.dsp.exec_cmd("dolphin"))
-- Window and group management.
bind("SUPER + Q", hl.dsp.window.close())
bind("SUPER + G", hl.dsp.group.toggle())
bind("SUPER + V", hl.dsp.window.float({ action = "toggle" }))
bind("SUPER + F", hl.dsp.window.fullscreen({ mode = "fullscreen", action = "toggle" }))
bind("SUPER + A", hl.dsp.workspace.swap_monitors({ monitor1 = "current", monitor2 = "+1" }))
bind("SUPER + ALT + M", hl.dsp.layout("swapwithmaster"))
-- Media keys.
bind("XF86MonBrightnessUp", hl.dsp.exec_cmd("xbacklight -inc 10"), { locked = true, repeating = true })
bind("XF86MonBrightnessDown", hl.dsp.exec_cmd("xbacklight -dec 10"), { locked = true, repeating = true })
bind("XF86AudioMute", hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_SINK@ toggle"), { locked = true })
bind("XF86AudioMicMute", hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_SOURCE@ toggle"), { locked = true })
bind("XF86AudioPlay", hl.dsp.exec_cmd("playerctl play-pause"), { locked = true })
bind("XF86AudioNext", hl.dsp.exec_cmd("playerctl next"), { locked = true })
bind("XF86AudioPrev", hl.dsp.exec_cmd("playerctl previous"), { locked = true })
-- Focus and group navigation.
for key, direction in pairs({ left = "l", right = "r", up = "u", down = "d" }) do
bind("SUPER + ALT + " .. key, hl.dsp.focus({ direction = direction }))
end
bind("SUPER + SHIFT + left", hl.dsp.group.prev())
bind("SUPER + SHIFT + right", hl.dsp.group.next())
-- Workspaces. Lua lets the repeated numeric bindings stay compact.
for i = 1, 10 do
local key = i % 10
bind("SUPER + " .. key, hl.dsp.focus({ workspace = tostring(i) }))
bind("SUPER + SHIFT + " .. key, hl.dsp.window.move({ workspace = tostring(i) }))
end
for key = 0, 9 do
local workspace = key == 0 and 19 or key + 9
bind("SUPER + ALT + " .. key, hl.dsp.focus({ workspace = tostring(workspace) }))
end
bind("SUPER + CTRL + right", hl.dsp.focus({ workspace = "+1" }))
bind("SUPER + CTRL + left", hl.dsp.focus({ workspace = "-1" }))
bind("SUPER + CTRL + SHIFT + left", hl.dsp.window.move({ workspace = "-1" }))
bind("SUPER + CTRL + SHIFT + right", hl.dsp.window.move({ workspace = "+1" }))
bind("SUPER + right", hl.dsp.window.move({ monitor = "+1" }))
bind("SUPER + left", hl.dsp.window.move({ monitor = "-1" }))
bind("ALT + Tab", hl.dsp.window.cycle_next())
bind("ALT + SHIFT + Tab", hl.dsp.window.cycle_next({ next = false }))
-- Screenshots, mouse, and application pass-through.
bind("Print", hl.dsp.exec_cmd("hyprshot --clipboard-only --mode active --mode output"))
bind("SUPER + SHIFT + S", hl.dsp.exec_cmd("hyprshot --freeze --clipboard-only --mode region"))
bind("SUPER + mouse_down", hl.dsp.focus({ workspace = "e+1" }))
bind("SUPER + mouse_up", hl.dsp.focus({ workspace = "e-1" }))
bind("SUPER + mouse:272", hl.dsp.window.drag(), { mouse = true })
bind("SUPER + mouse:273", hl.dsp.window.resize(), { mouse = true })
bind("CTRL + ALT + 1", hl.dsp.pass({ window = "class:^(com\\.obsproject\\.Studio)$" }))
bind("CTRL + ALT + 2", hl.dsp.pass({ window = "class:^(com\\.obsproject\\.Studio)$" }))
-- Apply GTK preferences on each config load, matching the former `exec` keywords.
hl.exec_cmd("gsettings set org.gnome.desktop.interface color-scheme 'prefer-dark'")
hl.exec_cmd("gsettings set org.gnome.desktop.interface font-antialiasing 'rgba'")
hl.exec_cmd("gsettings set org.gnome.desktop.interface font-hinting 'full'")
-- DMS 1.5+ owns these fragments. In particular, Display Settings rewrites outputs.lua.
-- require("dms.colors")
require("dms/outputs")
-- require("dms.layout")
-- require("dms.cursor")
-- require("dms.binds")
-- require("dms.binds-user")
-- require("dms.windowrules")
require("dms/layout")
require("dms/binds-user")
require("dms/windowrules")