283 lines
11 KiB
Lua
283 lines
11 KiB
Lua
-- ~/.config/hypr/hyprland.luaA
|
|
|
|
-----------------------------------------------------
|
|
-- Variables (from variables.conf)
|
|
-----------------------------------------------------
|
|
local copy = "wl-copy --trim-newline"
|
|
local paste = "wl-paste"
|
|
local launcher = "rofi -show run -p 'launch'"
|
|
-- local clear = "cliphist list | head -n1 | cliphist delete"
|
|
|
|
|
|
-----------------------------------------------------
|
|
-- Monitors (from monitors.conf)
|
|
-----------------------------------------------------
|
|
hl.monitor({ output = "desc:Ancor Communications Inc ASUS VS228 E3LMTF071438", mode = "preferred", position = "0x0", scale = "1" }) -- DP-7, left
|
|
hl.monitor({ output = "desc:Samsung Display Corp. 0x4193", mode = "preferred", position = "1920x0", scale = "2" }) -- eDP-1, center
|
|
hl.monitor({ output = "desc:Ancor Communications Inc ASUS VS228 E3LMTF071391", mode = "preferred", position = "3360x0", scale = "1" }) -- DP-8, right
|
|
hl.monitor({ output = "desc:Stargate Technology FHD", mode = "preferred", position = "auto", scale = "auto" }) -- portable monitor
|
|
|
|
|
|
-----------------------------------------------------
|
|
-- Environment Variables (from env.conf)
|
|
-----------------------------------------------------
|
|
hl.env("GDK_BACKEND", "wayland,x11,*")
|
|
hl.env("GUI_ENABLE_WAYLAND", "1")
|
|
hl.env("HYPRCURSOR_SIZE", "18")
|
|
hl.env("QT_QPA_PLATFORM", "wayland;xcb")
|
|
hl.env("QT_QPA_PLATFORMTHEME", "qt6ct")
|
|
hl.env("QT_AUTO_SCREEN_SCALE_FACTOR", "1")
|
|
hl.env("QT_WAYLAND_DISABLE_WINDOWDECORATION", "1")
|
|
hl.env("XCURSOR_SIZE", "18")
|
|
hl.env("XDG_CURRENT_DESKTOP", "Hyprland")
|
|
hl.env("XDG_SESSION_TYPE", "wayland")
|
|
hl.env("XDG_SESSION_DESKTOP", "Hyprland")
|
|
|
|
|
|
-----------------------------------------------------
|
|
-- Appearance & Input (from appearance.conf & input.conf)
|
|
-----------------------------------------------------
|
|
hl.config({
|
|
general = {
|
|
gaps_in = 1,
|
|
gaps_out = 2,
|
|
border_size = 2,
|
|
col = {
|
|
active_border = "rgba(fabd2f99)",
|
|
inactive_border = "rgba(595959aa)",
|
|
},
|
|
resize_on_border = false,
|
|
allow_tearing = false,
|
|
layout = "dwindle"
|
|
},
|
|
|
|
decoration = {
|
|
rounding = 10,
|
|
rounding_power = 2,
|
|
active_opacity = 1.0,
|
|
inactive_opacity = 1.0,
|
|
shadow = {
|
|
enabled = true,
|
|
range = 4,
|
|
render_power = 3,
|
|
color = "rgba(1a1a1aee)"
|
|
},
|
|
blur = {
|
|
enabled = true,
|
|
size = 3,
|
|
passes = 1,
|
|
vibrancy = 0.1696
|
|
}
|
|
},
|
|
|
|
animations = {
|
|
enabled = true,
|
|
bezier = {
|
|
"easeOutQuint,0.23,1,0.32,1",
|
|
"easeInOutCubic,0.65,0.05,0.36,1",
|
|
"linear,0,0,1,1",
|
|
"almostLinear,0.5,0.5,0.75,1.0",
|
|
"quick,0.15,0,0.1,1"
|
|
},
|
|
animation = {
|
|
"global, 1, 10, default",
|
|
"border, 1, 5.39, easeOutQuint",
|
|
"windows, 1, 4.79, easeOutQuint",
|
|
"windowsIn, 1, 4.1, easeOutQuint, popin 87%",
|
|
"windowsOut, 1, 1.49, linear, popin 87%",
|
|
"fadeIn, 1, 1.73, almostLinear",
|
|
"fadeOut, 1, 1.46, almostLinear",
|
|
"fade, 1, 3.03, quick",
|
|
"layers, 1, 3.81, easeOutQuint",
|
|
"layersIn, 1, 4, easeOutQuint, fade",
|
|
"layersOut, 1, 1.5, linear, fade",
|
|
"fadeLayersIn, 1, 1.79, almostLinear",
|
|
"fadeLayersOut, 1, 1.39, almostLinear",
|
|
"workspaces, 1, 1.94, almostLinear, fade",
|
|
"workspacesIn, 1, 1.21, almostLinear, fade",
|
|
"workspacesOut, 1, 1.94, almostLinear, fade"
|
|
}
|
|
},
|
|
|
|
dwindle = { preserve_split = true },
|
|
master = { new_status = "master" },
|
|
misc = {
|
|
on_focus_under_fullscreen = 1,
|
|
force_default_wallpaper = 0,
|
|
disable_hyprland_logo = true
|
|
},
|
|
|
|
input = {
|
|
resolve_binds_by_sym = 1,
|
|
kb_layout = "us, us",
|
|
kb_variant = "colemak,",
|
|
kb_options = "ctrl:nocaps, compose:ralt, grp:ctrls_toggle",
|
|
follow_mouse = 1,
|
|
sensitivity = 0,
|
|
touchpad = { natural_scroll = false }
|
|
}})
|
|
|
|
hl.device({
|
|
name = "epic-mouse-v1",
|
|
sensitivity = -0.5
|
|
})
|
|
|
|
|
|
-----------------------------------------------------
|
|
-- Window Rules (from windowrules.conf)
|
|
-----------------------------------------------------
|
|
-- XWayland dragging
|
|
hl.window_rule({
|
|
no_focus = true,
|
|
match = { xwayland = true, float = true, fullscreen = false, pin = false }
|
|
})
|
|
|
|
-- Floating rules
|
|
local float_class_regex = "(gcr-prompter|qt5ct|qt6ct|simple-scan|espanso|nm-applet)"
|
|
local float_title_regex = "(\"HP Device Manager - Plug-in Installer\")"
|
|
local float_regex = "(" .. float_class_regex .. "|" .. float_title_regex .. ")"
|
|
|
|
hl.window_rule({ float = true, match = { class = float_class_regex } })
|
|
hl.window_rule({ float = true, match = { title = float_title_regex } })
|
|
|
|
-- Pin rules
|
|
local pin_regex = "(gcr-prompter|nm-applet)"
|
|
hl.window_rule({ pin = true, match = { class = pin_regex } })
|
|
|
|
-- Maximize everything else (fixed typo fioat_regex -> float_regex)
|
|
hl.window_rule({
|
|
maximize = true,
|
|
match = { class = "negative:" .. float_regex }
|
|
})
|
|
|
|
-- Espanso on special
|
|
hl.window_rule({
|
|
workspace = "special",
|
|
match = { title = "Espanso Sync Tool" }
|
|
})
|
|
|
|
-- App-specific workspaces
|
|
local browsers = "(.*qutebrowser.*|.*[Ff]irefox.*)"
|
|
local meeting = "(.*[Zz]oom.*)"
|
|
|
|
hl.window_rule({ workspace = "name:shell", match = { class = ".*[Aa]lacritty.*" } })
|
|
hl.window_rule({ workspace = "name:browser silent", match = { class = browsers } })
|
|
hl.window_rule({ workspace = "name:jobs silent", match = { class = ".*[Vv]ivaldi-stable.*" } })
|
|
hl.window_rule({ workspace = "name:meeting silent", match = { class = meeting } })
|
|
|
|
|
|
-----------------------------------------------------
|
|
-- Workspaces (from workspaces.conf)
|
|
-----------------------------------------------------
|
|
require("workspaces")
|
|
|
|
|
|
-----------------------------------------------------
|
|
-- Keybindings & Macros (from keybindings.conf & macros.conf)
|
|
-----------------------------------------------------
|
|
local bind = hl.bind
|
|
local dsp = hl.dsp
|
|
local fn = require("functions")
|
|
|
|
bind("SUPER + Q", dsp.exec_cmd("hyprctl reload && killall -SIGUSR2 waybar && notify-send 'Hyprland' 'Config Reloaded' -u low -t 2000"))
|
|
-- BUG FIX: SUPER + SHIFT + Q was bound to both tmux kill and uwsm stop.
|
|
-- bind("SUPER + SHIFT + Q", dsp.exec_cmd("tmux kill-server"))
|
|
bind("SUPER + SHIFT + Q", dsp.exec_cmd("killall -q signal-desktop; uwsm stop"))
|
|
|
|
bind("SUPER + L", dsp.exec_cmd("hyprlock"))
|
|
bind("switch:Lid Switch", dsp.exec_cmd("hyprlock"))
|
|
|
|
-- Screenshots (evaluated natively in Lua at keypress time)
|
|
bind("CTRL + SHIFT + 3", function()
|
|
local cmd = string.format("grim 'images/screenshots/%s_screenshot.png' && paplay ~/wav/camera.wav", os.date("%FT%H%M%S"))
|
|
hl.dispatch(hl.dsp.exec_cmd(cmd))
|
|
end)
|
|
bind("CTRL + SHIFT + 4", function()
|
|
local cmd = string.format("slurp | grim -g - '%s_screenshot.png' && paplay ~/wav/camera.wav", os.date("%FT%H%M%S"))
|
|
hl.dispatch(hl.dsp.exec_cmd(cmd))
|
|
end)
|
|
|
|
-- App launchers using our custom Lua focusOrLaunch function
|
|
bind("SUPER + return", function() fn.focusOrLaunch("alacritty", "Alacritty") end)
|
|
bind("SUPER + A", function() fn.focusOrLaunch("slack", "Slack", "Slack") end)
|
|
bind("SUPER + D", function() fn.focusOrLaunch("gnome-dictionary", "org.gnome.Dictionary", "org.gnome.Dictionary") end)
|
|
bind("SUPER + G", function() fn.focusOrLaunch("vivaldi-stable", "vivaldi-stable", "vivaldi-stable") end)
|
|
bind("SUPER + ALT + H", function() fn.focusOrLaunch("qutebrowser", "org.qutebrowser.qutebrowser") end)
|
|
bind("SUPER + P", dsp.exec_cmd(launcher))
|
|
bind("SUPER + S", function() fn.focusOrLaunch("pavucontrol", "org.pulseaudio.pavucontrol", "org.pulseaudio.pavucontrol") end)
|
|
bind("SUPER + V", function() fn.focusOrLaunch("alacritty", "Alacritty") end)
|
|
|
|
-- Window control
|
|
bind("SUPER + C", dsp.window.close())
|
|
bind("SUPER + T", dsp.window.float({ action = "toggle" }))
|
|
bind("SUPER + space", dsp.window.fullscreen({ mode = 1 }))
|
|
|
|
-- BUG FIX: H/J/K were redundantly bound to move_focus AND fullscreen.
|
|
bind("SUPER + H", dsp.focus({ direction = "l" }))
|
|
bind("SUPER + K", dsp.focus({ direction = "u" }))
|
|
bind("SUPER + J", dsp.focus({ direction = "d" }))
|
|
|
|
bind("SUPER + X", dsp.exec_cmd("dunstctl close"))
|
|
bind("SUPER + Y", dsp.exec_cmd("dunstctl close-all"))
|
|
|
|
-- Workspace control
|
|
bind("SUPER + right", function() hl.dispatch(hl.dsp.focus({ workspace = "m+1" })) end)
|
|
bind("SUPER + left", function() hl.dispatch(hl.dsp.focus({ workspace = "m-1" })) end)
|
|
bind("SUPER + SHIFT + H", function() hl.dispatch(hl.dsp.focus({ workspace = "m-1" })) end)
|
|
bind("SUPER + SHIFT + L", function() hl.dispatch(hl.dsp.focus({ workspace = "m+1" })) end)
|
|
bind("SUPER + SHIFT + M", function() fn.mv2workspace() end)
|
|
bind("SUPER + SHIFT + N", function() fn.createWorkspace() end)
|
|
bind("SUPER + SHIFT + X", function() fn.deleteWorkspace() end)
|
|
bind("SUPER + SHIFT + Z", function() fn.createWorkspace(fn.getActiveWorkspaceName()) end)
|
|
bind("SUPER + SHIFT + left", function() fn.moveWorkspace(-1) end)
|
|
bind("SUPER + SHIFT + right", function() fn.moveWorkspace(1) end)
|
|
bind("SUPER + ALT + DOWN", function() fn.moveWorkspace(nil, "DP-8") end)
|
|
|
|
-- Cliphist
|
|
bind("ALT + V", dsp.exec_cmd("cliphist list | rofi -dmenu -p 'paste' | cliphist decode | " .. copy .. " && " .. paste))
|
|
|
|
-- Laptop keys
|
|
bind("XF86MonBrightnessUp", dsp.exec_cmd("brightnessctl -- set +10%"))
|
|
bind("XF86MonBrightnessDown", dsp.exec_cmd("brightnessctl -- set -10%"))
|
|
|
|
-- Macros (uses fn.pasteText and native Lua os.time/os.date instead of bash scripts)
|
|
bind("SUPER + CTRL + S", function() fn.pasteText(os.date("%F")) end)
|
|
bind("SUPER + CTRL + N", function() fn.pasteText(os.date("%FT%T %z")) end)
|
|
bind("SUPER + CTRL + Y", function() fn.pasteText(os.date("%F", os.time() - 86400)) end)
|
|
bind("SUPER + CTRL + T", function() fn.pasteText(os.date("%F", os.time() + 86400)) end)
|
|
|
|
-- Timetracker Macro
|
|
bind("CTRL + SHIFT + S", function() fn.timetracker() end)
|
|
|
|
-- Bitwarden Macro
|
|
bind("SUPER + CTRL + 1", function() fn.pasteMacro("secret-tool lookup app bw") end)
|
|
|
|
|
|
-----------------------------------------------------
|
|
-- Autostart (from autostart.conf)
|
|
-----------------------------------------------------
|
|
hl.on("hyprland.start", function()
|
|
hl.exec_cmd("dbus-update-activation-environment --systemd WAYLAND_DISPLAY XDG_CURRENT_DESKTOP")
|
|
hl.exec_cmd("hyprpolkitagent")
|
|
hl.exec_cmd("uwsm app -- hypridle")
|
|
hl.exec_cmd("uwsm app -- hyprpaper")
|
|
hl.exec_cmd("uwsm app -- waybar")
|
|
hl.exec_cmd("uwsm app -- espanso start")
|
|
hl.exec_cmd("uwsm app -- dunst")
|
|
hl.exec_cmd("nm-applet")
|
|
hl.exec_cmd("signal-desktop")
|
|
hl.exec_cmd("hp-systray")
|
|
hl.exec_cmd("blueman-applet")
|
|
hl.exec_cmd("wl-paste --watch cliphist store")
|
|
hl.exec_cmd("wl-clip-persist --clipboard regular")
|
|
hl.exec_cmd("qutebrowser")
|
|
hl.exec_cmd("vivaldi-stable")
|
|
hl.exec_cmd("alacritty")
|
|
|
|
-- Start the battery low-level notifier
|
|
hl.exec_cmd("bash ~/.config/hypr/scripts/battery-notify.sh")
|
|
|
|
-- Randomize wallpapers after hyprpaper has time to start
|
|
hl.exec_cmd("sleep 2 && hyprctl eval 'require(\"functions\").randomizeWallpaper()'")
|
|
end)
|