feat(configs): introduce layout‑specific bind helper and extend keybindings with window controls, audio, and brightness

The changes add helper functions, new keybindings for layout manipulation, mouse drag/resize, and system controls while cleaning up old configurations.

New Features:
- Added `layout_bind` helper for layout‑specific key actions.
- Introduced mouse drag/resize via SUPER + LMB/RMB.
- Added audio volume/mute/mic mute and brightness controls bound to XF86 keys.
- Added playerctl media key handling.

Enhancements:
- Consolidated power‑off, reboot, and lock bindings under Ctrl‑L/P/R.
- Refactored keybindings layout for better readability.
- Updated window rules to properly float VSCodium and terminal windows.

Bug Fixes:
- Removed obsolete test notifications and redundant bindings.
- Fixed workspace cycle indexing to use keys 1‑9.
- Corrected ordering of special window rules.
This commit is contained in:
sankalp committed 2026-05-12 00:19:18 +05:45
1 parent efd38683cf
commit 602dc3cd24
2 files changed
+110 -94

No files matched your search

+106 -86
View File
@@ -1,114 +1,134 @@
-- Keybinds
local mainMod = "SUPER"
local terminal = "kitty"
local filemanager = "thunar"
local telegram = "materialgram"
local browser = "zen-browser"
local file_manager = "thunar"
local mainMod = "SUPER"
-- Generates layout specific binds to avoid error warnings
local function layout_bind(bind_table)
return function()
local layout = hl.get_active_workspace().tiled_layout
if bind_table[layout] then
hl.dispatch(bind_table[layout])
end
end
end
-- apps launch
hl.bind(mainMod .. " + return", hl.dsp.exec_cmd("uwsm app -- " .. terminal))
hl.bind("ALT + SHIFT + return", hl.dsp.exec_cmd("uwsm app -- " .. terminal), { float = true })
hl.bind("ALT + E", hl.dsp.exec_cmd("uwsm app -- " .. file_manager))
hl.bind(mainMod .. " + B", hl.dsp.exec_cmd("uwsm app -- " .. browser))
-- Increases / Decreases active window by x, y relatively
hl.bind("ALT + SHIFT + Z", hl.dsp.window.resize({ x = -80, y = -75, relative = true }))
hl.bind("ALT + SHIFT + C", hl.dsp.window.resize({ x = 80, y = 75, relative = true }))
hl.bind(mainMod .. " + C", hl.dsp.window.close())
hl.bind(mainMod .. " + SHIFT + C", hl.dsp.window.kill())
-- Toggle fullscreen and center floating window
hl.bind(mainMod .. " + SHIFT + F", hl.dsp.window.fullscreen({ action = "toggle" }))
hl.bind(mainMod .. " + F", function()
hl.dispatch(hl.dsp.window.float({ action = "toggle" }))
hl.dispatch(hl.dsp.window.center())
end)
-- Testing
hl.bind(
"ALT + F12",
hl.dsp.exec_cmd(
'notify-send \'Test notification\' "Here\'s a really long message to test truncation and wrapping\\nYou can middle click or flick this notification to dismiss it!" -a \'terminal\' -A "Test1=I got it!" -A "Test2=Another action"'
hl.bind(mainMod .. " + CTRL + L", hl.dsp.exec_cmd("pidof hyprlock || hyprlock -q")) -- hyprlock
hl.bind(mainMod .. " + CTRL + P", hl.dsp.exec_cmd("systemctl poweroff")) -- poweroff
hl.bind(mainMod .. " + CTRL + R", hl.dsp.exec_cmd("systemctl reboot")) -- reboot
hl.bind(mainMod .. " + P", hl.dsp.window.pseudo()) -- pseudo tiling
-- Layout column resize
for key, dir in pairs({
["ALT + SHIFT + F"] = "+conf", -- If scrolling layout, set next column width from config
[mainMod .. " + SHIFT + W"] = "-conf", -- Scrolling: set previous column width from config
}) do
hl.bind(key, layout_bind({ scrolling = hl.dsp.layout("colresize " .. dir) }))
end
-- Multi-layout specific binds
for key, val in pairs({
H = { "swapcol l", "swapsplit", "cycleprev" },
L = { "swapcol r", "togglesplit", "cyclenext" },
}) do
hl.bind(
mainMod .. " + SHIFT + " .. key,
layout_bind({
scrolling = hl.dsp.layout(val[1]),
dwindle = hl.dsp.layout(val[2]),
monocle = hl.dsp.layout(val[3]),
master = hl.dsp.layout(val[3]),
})
)
)
hl.bind("ALT + Equal", hl.dsp.exec_cmd("notify-send 'hmm' ${SLURP_ARGS}"))
end
local message_cmd =
'notify-send "Hello" "FIRE IN THE HOLE‼️🗣️🔥🕳️" -i "/home/sankalp/.face.icon" -A "🗣️" -A "🔥" -A "🕳️" -a "Source Code"'
hl.bind(mainMod .. "+ ALT + N", hl.dsp.exec_cmd(message_cmd))
-- Minimize active window
hl.bind("SUPER + Q", function()
hl.dispatch(hl.dsp.workspace.toggle_special("minimize"))
hl.dispatch(hl.dsp.window.move({ workspace = "+0" }))
hl.dispatch(hl.dsp.workspace.toggle_special("minimize"))
hl.dispatch(hl.dsp.window.move({ workspace = "special:minimize" }))
hl.dispatch(hl.dsp.workspace.toggle_special("minimize"))
end)
hl.bind(mainMod .. " + return", hl.dsp.exec_cmd(terminal))
hl.bind("ALT + SHIFT + return", hl.dsp.exec_cmd(terminal .. " --title float_kitty --single-instance"))
hl.bind("ALT + E", hl.dsp.exec_cmd("uwsm app -- " .. filemanager))
hl.bind(mainMod .. " + B", hl.dsp.exec_cmd("uwsm app -- " .. browser))
hl.bind("ALT + T", hl.dsp.exec_cmd("uwsm app -- " .. telegram))
-- Cycle workspaces and Scrolling / Layout
for key, val in pairs({
D = { "e+1", "+col" },
A = { "e-1", "-col" },
}) do
hl.bind("ALT + SHIFT + " .. key, hl.dsp.focus({ workspace = val[1] })) -- Cycle workspace
hl.bind("ALT + " .. key, hl.dsp.layout("move " .. val[2])) -- Scrolling
end
hl.bind(mainMod .. " + SHIFT + Y", hl.dsp.exec_cmd("grimblast save active ~/Pictures/Screenshots/"))
hl.bind(mainMod .. " + CTRL + L", hl.dsp.exec_cmd("pidof hyprlock || hyprlock -q"))
hl.bind(mainMod .. " + CTRL + P", hl.dsp.exec_cmd("systemctl poweroff"))
hl.bind(mainMod .. " + CTRL + R", hl.dsp.exec_cmd("systemctl reboot"))
hl.bind(mainMod .. " + P", hl.dsp.window.pseudo())
hl.bind(mainMod .. " + SHIFT + P", hl.dsp.layout("togglesplit"))
-- Cycle through existing workspaces
hl.bind("ALT + SHIFT + D", hl.dsp.focus({ workspace = "e+1" }))
hl.bind("ALT + SHIFT + A", hl.dsp.focus({ workspace = "e-1" }))
-- Scrolling / Layout
hl.bind("ALT + D", hl.dsp.layout("move +col"))
hl.bind("ALT + A", hl.dsp.layout("move -col"))
hl.bind(mainMod .. " + SHIFT + period", hl.dsp.layout("swapcol r"))
hl.bind(mainMod .. " + SHIFT + comma", hl.dsp.layout("swapcol l"))
-- Scroll through existing workspaces with mainMod + scroll
hl.bind(mainMod .. " + mouse_down", hl.dsp.focus({ workspace = "e+1" }))
hl.bind(mainMod .. " + mouse_up", hl.dsp.focus({ workspace = "e-1" }))
-- Move window --
hl.bind(mainMod .. " + SHIFT + H", hl.dsp.window.move({ direction = "left" }))
hl.bind(mainMod .. " + SHIFT + L", hl.dsp.window.move({ direction = "right" }))
hl.bind(mainMod .. " + SHIFT + K", hl.dsp.window.move({ direction = "up" }))
hl.bind(mainMod .. " + SHIFT + J", hl.dsp.window.move({ direction = "down" }))
-- Focus to different window --
hl.bind(mainMod .. " + H", hl.dsp.focus({ direction = "left" }))
hl.bind(mainMod .. " + L", hl.dsp.focus({ direction = "right" }))
hl.bind(mainMod .. " + K", hl.dsp.focus({ direction = "up" }))
hl.bind(mainMod .. " + J", hl.dsp.focus({ direction = "down" }))
-- Move, Focus and Resize windows
for key, val in pairs({
H = { "left", 70, 0 },
L = { "right", -70, 0 },
K = { "up", 0, -70 },
J = { "down", 0, 70 },
}) do
hl.bind(mainMod .. " + SHIFT + " .. key, hl.dsp.window.move({ direction = val[1] })) -- Move
hl.bind(mainMod .. " + " .. key, hl.dsp.focus({ direction = val[1] })) -- Focus
hl.bind("ALT + SHIFT + " .. key, hl.dsp.window.resize({ x = val[2], y = val[3], relative = true })) -- Resize
end
-- Switch workspaces with mainMod + [0-9]
-- Move active window to a workspace with mainMod + SHIFT + [0-9]
for i = 1, 10 do
local key = i % 10 -- 10 maps to key 0
hl.bind(mainMod .. " + " .. key, hl.dsp.focus({ workspace = i }))
hl.bind(mainMod .. " + SHIFT + " .. key, hl.dsp.window.move({ workspace = i }))
hl.bind("SHIFT + ALT + " .. key, hl.dsp.window.move({ workspace = i, follow = false }))
for i = 1, 9 do
hl.bind(mainMod .. "+" .. i, hl.dsp.focus({ workspace = i }))
hl.bind("ALT + SHIFT + " .. i, hl.dsp.window.move({ workspace = i, follow = false }))
hl.bind(mainMod .. "+ SHIFT + " .. i, hl.dsp.window.move({ workspace = i }))
end
-- Move/resize windows with mainMod + LMB/RMB and dragging
hl.bind(mainMod .. " + mouse:272", hl.dsp.window.drag(), { mouse = true })
hl.bind(mainMod .. " + mouse:273", hl.dsp.window.resize(), { mouse = true })
-- Move/resize windows with SUPER + LMB/RMB and dragging
hl.bind("SUPER + mouse:272", hl.dsp.window.drag(), { mouse = true })
hl.bind("SUPER + mouse:273", hl.dsp.window.resize(), { mouse = true })
-- Laptop keys
hl.bind(
"XF86AudioRaiseVolume",
hl.dsp.exec_cmd("wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+"),
{ locked = true, repeating = true }
)
hl.bind(
"XF86AudioLowerVolume",
hl.dsp.exec_cmd("wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-"),
{ locked = true, repeating = true }
)
hl.bind(
"XF86AudioMute",
hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"),
{ locked = true, repeating = true }
)
hl.bind(
"XF86AudioMicMute",
hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle"),
{ locked = true, repeating = true }
)
-- Audio keys
for key, cmd in pairs({
AudioRaiseVolume = "wpctl set-volume -l 1 @DEFAULT_AUDIO_SINK@ 5%+",
AudioLowerVolume = "wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-",
AudioMute = "wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle",
AudioMicMute = "wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle",
}) do
hl.bind("XF86" .. key, hl.dsp.exec_cmd(cmd), { locked = true, repeating = true })
end
-- brightness
hl.bind("XF86MonBrightnessUp", hl.dsp.exec_cmd("brightnessctl -e4 -n2 set 5%+"), { locked = true, repeating = true })
hl.bind("XF86MonBrightnessDown", hl.dsp.exec_cmd("brightnessctl -e4 -n2 set 5%-"), { locked = true, repeating = true })
hl.bind("xf86Sleep", hl.dsp.exec_cmd("systemctl suspend"), { locked = true })
-- Playerctl
hl.bind("XF86AudioNext", hl.dsp.exec_cmd("playerctl next"), { locked = true })
hl.bind("XF86AudioPause", hl.dsp.exec_cmd("playerctl play-pause"), { locked = true })
hl.bind("XF86AudioPlay", hl.dsp.exec_cmd("playerctl play-pause"), { locked = true })
hl.bind("XF86AudioPrev", hl.dsp.exec_cmd("playerctl previous"), { locked = true })
for key, cmd in pairs({
AudioNext = "next",
AudioPause = "play-pause",
AudioPlay = "play-pause",
AudioPrev = "previous",
}) do
hl.bind("XF86" .. key, hl.dsp.exec_cmd("playerctl " .. cmd), { locked = true })
end
+4 -8
View File
@@ -92,7 +92,10 @@ local simple_rules = {
center = true,
size = "(monitor_w*0.35) (monitor_h*0.35)",
},
{ match = { class = "(codium|codium-url-handler|VSCodium)", title = "negative:(.*codium.*|.*VSCodium.*)" }, float = true },
{
match = { class = "(codium|codium-url-handler|VSCodium)", title = "negative:(.*codium.*|.*VSCodium.*)" },
float = true,
},
{ match = { class = "^(com.heroicgameslauncher.hgl)$", title = "negative:(Heroic Games Launcher)" }, float = true },
{ match = { class = "^([Ss]team)$", title = "negative:^([Ss]team)$" }, float = true },
{
@@ -205,13 +208,6 @@ local special_rules = {
center = true,
size = "(monitor_w*0.6) (monitor_h*0.65)",
},
{
name = "Floating Terminal",
match = { title = "^(float_kitty)$" },
float = true,
center = true,
size = "(monitor_w*0.6) (monitor_h*0.6)",
},
}
for _, rule in ipairs(special_rules) do