153 lines
7.5 KiB
Lua
153 lines
7.5 KiB
Lua
-- Shared Hyprland profile. yadm deploys machine.lua for the active class.
|
|
--
|
|
-- Scope: preserve launch, media, directional focus/move, workspace, scratchpad,
|
|
-- floating, fullscreen, and window-placement muscle memory. i3's split-tree,
|
|
-- stacking/tabbed, and resize-mode behavior is intentionally deferred.
|
|
local machine = dofile(os.getenv("HOME") .. "/.config/hypr/machine.lua")
|
|
|
|
for _, monitor in ipairs(machine.monitors or {}) do
|
|
hl.monitor(monitor)
|
|
end
|
|
|
|
local main_mod = "SUPER"
|
|
local terminal = "alacritty"
|
|
|
|
local input = {
|
|
kb_layout = "us",
|
|
kb_variant = "intl",
|
|
numlock_by_default = true,
|
|
}
|
|
for key, value in pairs(machine.input or {}) do
|
|
input[key] = value
|
|
end
|
|
|
|
hl.config({
|
|
input = input,
|
|
general = {
|
|
gaps_in = 4,
|
|
-- Keep a thin black perimeter so the bottom border remains on-screen.
|
|
gaps_out = 2,
|
|
border_size = 2,
|
|
col = {
|
|
-- Muted Ember tones: visible focus without a high-brightness OLED edge.
|
|
active_border = "rgba(c9782ed9)",
|
|
inactive_border = "rgba(2a190fa6)",
|
|
},
|
|
},
|
|
decoration = {
|
|
rounding = 0,
|
|
},
|
|
animations = {
|
|
enabled = false,
|
|
},
|
|
binds = {
|
|
-- Selecting the current workspace again returns to the last workspace.
|
|
workspace_back_and_forth = true,
|
|
},
|
|
})
|
|
|
|
-- Dynamically hide the border when a workspace has exactly one tiled app.
|
|
hl.workspace_rule({
|
|
workspace = "w[t1]",
|
|
no_border = true,
|
|
})
|
|
|
|
-- Application and session bindings.
|
|
local noctalia_ipc = "noctalia msg "
|
|
-- Tap and release Super on its own to open Noctalia's control-center home.
|
|
hl.bind(main_mod .. " + SUPER_L", hl.dsp.exec_cmd(noctalia_ipc .. "panel-toggle control-center"), { release = true })
|
|
hl.bind(main_mod .. " + RETURN", hl.dsp.exec_cmd(terminal))
|
|
hl.bind(main_mod .. " + CTRL + RETURN", hl.dsp.exec_cmd(terminal .. " -e zellij"))
|
|
hl.bind(main_mod .. " + SHIFT + RETURN", hl.dsp.exec_cmd("rofi -show combi"))
|
|
hl.bind(main_mod .. " + SPACE", hl.dsp.exec_cmd(noctalia_ipc .. "panel-toggle launcher"))
|
|
hl.bind(main_mod .. " + S", hl.dsp.exec_cmd(noctalia_ipc .. "panel-toggle control-center"))
|
|
hl.bind(main_mod .. " + SHIFT + F", hl.dsp.exec_cmd(noctalia_ipc .. "bar-toggle main"))
|
|
hl.bind(main_mod .. " + SHIFT + R", hl.dsp.exec_cmd("hyprctl reload"))
|
|
hl.bind(main_mod .. " + CTRL + L", hl.dsp.exec_cmd("command -v hyprlock >/dev/null && hyprlock || loginctl lock-session"))
|
|
hl.bind(main_mod .. " + CTRL + SHIFT + ALT + S", hl.dsp.exec_cmd("systemctl suspend"))
|
|
hl.bind(main_mod .. " + CTRL + SHIFT + ALT + H", hl.dsp.exec_cmd("systemctl hibernate"))
|
|
hl.bind(main_mod .. " + SHIFT + C", hl.dsp.window.close())
|
|
hl.bind(main_mod .. " + CTRL + SHIFT + F", hl.dsp.exec_cmd("env LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8 flameshot gui"))
|
|
|
|
-- Audio, media, brightness, and calculator keys.
|
|
hl.bind("XF86AudioLowerVolume", hl.dsp.exec_cmd("wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%-"), { locked = true })
|
|
hl.bind("XF86AudioRaiseVolume", hl.dsp.exec_cmd("wpctl set-volume @DEFAULT_AUDIO_SINK@ 5%+"), { locked = true })
|
|
hl.bind("XF86AudioMute", hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_AUDIO_SINK@ toggle"), { locked = true })
|
|
hl.bind(main_mod .. " + XF86AudioMute", hl.dsp.exec_cmd("wpctl set-mute @DEFAULT_AUDIO_SOURCE@ toggle"), { locked = true })
|
|
hl.bind("XF86AudioPlay", hl.dsp.exec_cmd("playerctl play-pause"), { locked = true })
|
|
hl.bind("XF86AudioNext", hl.dsp.exec_cmd("playerctl next"), { locked = true })
|
|
hl.bind("XF86AudioPrev", hl.dsp.exec_cmd("playerctl previous"), { locked = true })
|
|
hl.bind(main_mod .. " + XF86AudioRaiseVolume", hl.dsp.exec_cmd("playerctl next"), { locked = true })
|
|
hl.bind(main_mod .. " + XF86AudioLowerVolume", hl.dsp.exec_cmd("playerctl previous"), { locked = true })
|
|
hl.bind("XF86MonBrightnessUp", hl.dsp.exec_cmd('light -A 5'), { locked = true })
|
|
hl.bind("XF86MonBrightnessDown", hl.dsp.exec_cmd('light -U 5'), { locked = true })
|
|
hl.bind(main_mod .. " + XF86MonBrightnessDown", hl.dsp.exec_cmd('light -S 0.0'), { locked = true })
|
|
hl.bind(main_mod .. " + XF86MonBrightnessUp", hl.dsp.exec_cmd('light -S 100'), { locked = true })
|
|
hl.bind("XF86Calculator", hl.dsp.exec_cmd("qalculate-qt"), { locked = true })
|
|
|
|
-- Retain i3's hjkl and arrow-key directional workflow.
|
|
for _, direction in ipairs({ "left", "down", "up", "right" }) do
|
|
local key = ({ left = "H", down = "J", up = "K", right = "L" })[direction]
|
|
hl.bind(main_mod .. " + " .. key, hl.dsp.focus({ direction = direction }))
|
|
hl.bind(main_mod .. " + " .. direction, hl.dsp.focus({ direction = direction }))
|
|
end
|
|
|
|
for key, direction in pairs({ H = "l", J = "d", K = "u", L = "r", LEFT = "l", DOWN = "d", UP = "u", RIGHT = "r" }) do
|
|
hl.bind(main_mod .. " + SHIFT + " .. key, hl.dsp.window.move({ direction = direction }))
|
|
end
|
|
|
|
-- Numbered workspaces match the i3 profile. Shift moves; Ctrl moves and follows.
|
|
for workspace = 1, 9 do
|
|
local key = tostring(workspace)
|
|
hl.bind(main_mod .. " + " .. key, hl.dsp.focus({ workspace = workspace }))
|
|
hl.bind(main_mod .. " + SHIFT + " .. key, hl.dsp.window.move({ workspace = workspace }))
|
|
hl.bind(main_mod .. " + CTRL + " .. key, hl.dsp.window.move({ workspace = workspace, follow = true }))
|
|
end
|
|
-- Match i3's back-and-forth workflow: Super+Tab switches to the last workspace;
|
|
-- selecting the current numbered workspace also returns to it.
|
|
hl.bind(main_mod .. " + TAB", hl.dsp.focus({ workspace = "previous" }))
|
|
hl.bind(main_mod .. " + CTRL + RIGHT", hl.dsp.focus({ workspace = "+1" }))
|
|
hl.bind(main_mod .. " + CTRL + LEFT", hl.dsp.focus({ workspace = "-1" }))
|
|
|
|
-- Hyprland special workspaces are the Wayland analogue of the i3 scratchpad.
|
|
hl.bind(main_mod .. " + MINUS", hl.dsp.workspace.toggle_special("scratchpad"))
|
|
hl.bind(main_mod .. " + SHIFT + MINUS", hl.dsp.window.move({ workspace = "special:scratchpad" }))
|
|
|
|
-- Keep the i3 floating and fullscreen shortcuts. Layout-specific binds are deferred.
|
|
hl.bind(main_mod .. " + F", hl.dsp.window.fullscreen({ action = "toggle" }))
|
|
hl.bind(main_mod .. " + SHIFT + SPACE", hl.dsp.window.float({ action = "toggle" }))
|
|
hl.bind(main_mod .. " + mouse:272", hl.dsp.window.drag(), { mouse = true })
|
|
hl.bind(main_mod .. " + mouse:273", hl.dsp.window.resize(), { mouse = true })
|
|
|
|
-- i3 for_window/assign translations. Verify Wayland class/title values with `hyprctl clients`.
|
|
local function float_rule(name, match, border_size)
|
|
hl.window_rule({
|
|
name = name,
|
|
match = match,
|
|
float = true,
|
|
border_size = border_size,
|
|
})
|
|
end
|
|
|
|
hl.window_rule({ name = "thunderbird-workspace", match = { class = "^Thunderbird$" }, workspace = "9" })
|
|
float_rule("alsamixer", { title = "^alsamixer$" }, 1)
|
|
float_rule("qalculate", { title = "^Qalculate!$" })
|
|
float_rule("psensor", { class = "^Psensor$" })
|
|
float_rule("lxrandr", { title = "^lxrandr$" })
|
|
float_rule("blueman", { class = "^Blueman-manager$" })
|
|
float_rule("gparted", { class = "^GParted$" })
|
|
float_rule("pavucontrol", { class = "^pavucontrol$" })
|
|
float_rule("volume-control", { title = "^Volume Control$" })
|
|
float_rule("virtualbox", { class = ".*VirtualBox.*" })
|
|
hl.window_rule({ name = "virtualbox-manager-tiles", match = { class = ".*VirtualBox Manager.*" }, tile = true })
|
|
hl.window_rule({ name = "virtualbox-machine-tiles", match = { class = ".*VirtualBox Machine.*" }, tile = true })
|
|
-- Send music clients to the existing scratchpad without stealing startup focus.
|
|
hl.window_rule({ name = "spotify-music", match = { class = "^Spotify$" }, workspace = "special:scratchpad silent", no_initial_focus = true })
|
|
hl.window_rule({ name = "deezer-music", match = { class = "^Deezer$" }, workspace = "special:scratchpad silent", no_initial_focus = true })
|
|
|
|
hl.on("hyprland.start", function()
|
|
for _, command in ipairs(machine.startup or {}) do
|
|
hl.exec_cmd(command)
|
|
end
|
|
end)
|