aboutsummaryrefslogtreecommitdiff
path: root/hypr/hyprland.lua
diff options
context:
space:
mode:
Diffstat (limited to 'hypr/hyprland.lua')
-rw-r--r--hypr/hyprland.lua105
1 files changed, 99 insertions, 6 deletions
diff --git a/hypr/hyprland.lua b/hypr/hyprland.lua
index 5ea8ec0..ae12430 100644
--- a/hypr/hyprland.lua
+++ b/hypr/hyprland.lua
@@ -1,13 +1,34 @@
+-- Hyprland configuration, in the style of Protesilaos Stavrou's Sway config.
+-- Ref: https://github.com/protesilaos/dotfiles/tree/master/wayland-tc/.config/sway
+--
+-- Prot runs Sway (i3-style, manual tiling); this is Hyprland (dwindle,
+-- dynamic tiling). Bindings and colours are carried over faithfully; the
+-- places where Hyprland has no equivalent are marked "SUBSTITUTION" below.
+
+---------------------
+---- MY PROGRAMS ----
+---------------------
+
+-- Prot uses gnome-terminal. SUBSTITUTION: ghostty, which is already
+-- installed here (and you said no kitty).
local terminal = "ghostty"
local fileManager = "dolphin"
+-- Prot's exact wofi invocation, minus the `| xargs swaymsg exec --` pipe,
+-- which exists only to hand the command back to Sway. Hyprland execs directly.
local menu = "wofi -G -I -i -n --show drun"
+-- Prot points at ~/Pictures/light.jpg, which does not exist here.
+-- SUBSTITUTION: one of your own wallpapers. Change this one string to swap it.
local wallpaper = os.getenv("HOME") .. "/Pictures/wallhaven-8gdrq2_2560x1440.png"
local font = "FiraCode Nerd Font"
+------------------
+---- MONITORS ----
+------------------
+
hl.monitor({
output = "",
mode = "preferred",
@@ -16,6 +37,10 @@ hl.monitor({
})
+-------------------
+---- AUTOSTART ----
+-------------------
+
hl.on("hyprland.start", function()
hl.exec_cmd("waybar")
hl.exec_cmd("mako")
@@ -24,22 +49,48 @@ hl.on("hyprland.start", function()
hl.exec_cmd("/usr/libexec/kf6/polkit-kde-authentication-agent-1")
end)
+
+-------------------------------
+---- ENVIRONMENT VARIABLES ----
+-------------------------------
+
hl.env("XCURSOR_SIZE", "24")
hl.env("HYPRCURSOR_SIZE", "24")
+-- Qt/KDE apps (dolphin, konsole) render natively rather than through XWayland.
hl.env("QT_QPA_PLATFORM", "wayland")
hl.env("QT_WAYLAND_DISABLE_WINDOWDECORATION", "1")
hl.env("MOZ_ENABLE_WAYLAND", "1")
+
+-----------------------
+---- LOOK AND FEEL ----
+-----------------------
+
+-- Prot's colours, from his 'modus-themes' for Emacs:
+-- #ffffff white focused border (matches mako border-color)
+-- #f78fe7 magenta focused-but-inactive border
+-- #575757 grey unfocused border
+-- #a60000 red urgent
+-- #ffa200 orange indicator
+--
+-- SUBSTITUTION: Sway's `client.*` lines set five colours per window state
+-- (border, background, text, indicator, child_border) because Sway draws
+-- title bars. Hyprland has no title bars, so only the border colours carry
+-- over. The backgrounds/text/indicator values have nowhere to go, and
+-- Hyprland has no global "urgent" border colour at all.
+
hl.config({
general = {
- gaps_in = 5,
+ -- Prot: `gaps inner 10px` / `gaps outer 0`
+ gaps_in = 5, -- Hyprland counts this per-edge, so 5 => 10px between windows
gaps_out = 0,
+ -- Prot: `default_border pixel 3`
border_size = 2,
col = {
- active_border = "rgba(f4bb82ff)",
+ active_border = "rgba(ffffffff)",
inactive_border = "rgba(575757ff)",
},
@@ -49,6 +100,8 @@ hl.config({
},
decoration = {
+ -- Prot's Sway config has no rounding, shadows or blur. Keeping that:
+ -- square corners, no effects.
rounding = 0,
active_opacity = 1.0,
@@ -62,6 +115,7 @@ hl.config({
enabled = true,
},
+ -- Prot: `workspace_auto_back_and_forth yes`
binds = {
workspace_back_and_forth = true,
},
@@ -76,10 +130,12 @@ hl.config({
},
})
+-- Groups are Hyprland's equivalent of Sway's tabbed layout (see $mod+t below).
+-- Coloured to match Prot's focused/unfocused window states.
hl.config({
group = {
col = {
- border_active = "rgba(f4bb82ff)",
+ border_active = "rgba(ffffffff)",
border_inactive = "rgba(575757ff)",
},
groupbar = {
@@ -100,10 +156,20 @@ hl.animation({ leaf = "global", enabled = true, speed = 8, bezier = "ease
hl.animation({ leaf = "border", enabled = true, speed = 5.39, bezier = "easeOutQuint" })
hl.animation({ leaf = "workspaces", enabled = true, speed = 4, bezier = "easeOutQuint", style = "slide" })
+
+---------------
+---- INPUT ----
+---------------
+
hl.config({
input = {
+ -- Prot uses `xkb_layout "us,gr"` with win+space to toggle, because he
+ -- writes Greek. SUBSTITUTION: us only, matching your current
+ -- localectl setting. Add ",gr" and the kb_options line back if you
+ -- ever want the second layout.
kb_layout = "us",
+ -- Prot: `focus_follows_mouse yes`
follow_mouse = 1,
sensitivity = 0,
@@ -111,8 +177,13 @@ hl.config({
})
+---------------------
+---- KEYBINDINGS ----
+---------------------
+
local mod = "SUPER"
+-- Prot's home-row direction keys, like vim.
local left, down, up, right = "H", "J", "K", "L"
hl.bind(mod .. " + Return", hl.dsp.exec_cmd(terminal))
@@ -121,10 +192,15 @@ hl.bind(mod .. " + D", hl.dsp.exec_cmd(menu))
hl.bind(mod .. " + E", hl.dsp.exec_cmd(fileManager))
hl.bind(mod .. " + SHIFT + C", hl.dsp.exec_cmd("hyprctl reload"))
+-- Prot wraps exit in a swaynag confirmation prompt. SUBSTITUTION: Hyprland
+-- has no swaynag, so this exits immediately with no confirmation dialog.
hl.bind(mod .. " + SHIFT + E", hl.dsp.exit())
+-- ADDITION: Prot's config has no lock binding (his swayidle block is
+-- commented out). $mod+L is taken by "focus right", so lock goes on Escape.
hl.bind(mod .. " + Escape", hl.dsp.exec_cmd("hyprlock"))
+-- Move focus, vim keys and arrows both
hl.bind(mod .. " + " .. left, hl.dsp.focus({ direction = "left" }))
hl.bind(mod .. " + " .. down, hl.dsp.focus({ direction = "down" }))
hl.bind(mod .. " + " .. up, hl.dsp.focus({ direction = "up" }))
@@ -134,6 +210,7 @@ hl.bind(mod .. " + down", hl.dsp.focus({ direction = "down" }))
hl.bind(mod .. " + up", hl.dsp.focus({ direction = "up" }))
hl.bind(mod .. " + right", hl.dsp.focus({ direction = "right" }))
+-- Move the focused window, same keys plus Shift
hl.bind(mod .. " + SHIFT + " .. left, hl.dsp.window.move({ direction = "left" }))
hl.bind(mod .. " + SHIFT + " .. down, hl.dsp.window.move({ direction = "down" }))
hl.bind(mod .. " + SHIFT + " .. up, hl.dsp.window.move({ direction = "up" }))
@@ -143,31 +220,42 @@ hl.bind(mod .. " + SHIFT + down", hl.dsp.window.move({ direction = "down" }
hl.bind(mod .. " + SHIFT + up", hl.dsp.window.move({ direction = "up" }))
hl.bind(mod .. " + SHIFT + right", hl.dsp.window.move({ direction = "right" }))
+-- Workspaces
for i = 1, 10 do
- local key = i % 10
+ local key = i % 10 -- 10 maps to key 0
hl.bind(mod .. " + " .. key, hl.dsp.focus({ workspace = i }))
hl.bind(mod .. " + SHIFT + " .. key, hl.dsp.window.move({ workspace = i }))
end
-hl.bind(mod .. " + B", hl.dsp.layout("orientationright"))
-hl.bind(mod .. " + V", hl.dsp.layout("orientationbottom"))
+---- Layout ----
+-- Prot: `$mod+s split toggle` — flips the current split's orientation.
hl.bind(mod .. " + S", hl.dsp.layout("togglesplit"))
+-- Prot: `$mod+t layout toggle tabbed split`.
+-- SUBSTITUTION: Hyprland calls this a "group"; the groupbar above is its
+-- tab bar.
hl.bind(mod .. " + T", hl.dsp.group.toggle())
+-- Sway cycles tabs with the ordinary focus keys; in Hyprland those navigate
+-- out of the group instead, so grouped windows need their own bindings.
hl.bind(mod .. " + Tab", hl.dsp.group.next())
hl.bind(mod .. " + SHIFT + Tab", hl.dsp.group.prev())
hl.bind(mod .. " + F", hl.dsp.window.fullscreen())
hl.bind(mod .. " + SHIFT + space", hl.dsp.window.float({ action = "toggle" }))
+-- Prot: `floating_modifier $mod normal`
hl.bind(mod .. " + mouse:272", hl.dsp.window.drag(), { mouse = true })
hl.bind(mod .. " + mouse:273", hl.dsp.window.resize(), { mouse = true })
+---- ADDITIONS (not in Prot's config) ----
+
+-- Screenshots. Requires grim and slurp.
hl.bind("Print", hl.dsp.exec_cmd("grim - | wl-copy"))
hl.bind("SHIFT + Print", hl.dsp.exec_cmd("grim -g \"$(slurp)\" - | wl-copy"))
+-- Media 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 })
@@ -178,6 +266,10 @@ hl.bind("XF86AudioPlay", hl.dsp.exec_cmd("playerctl play-pause"), { locke
hl.bind("XF86AudioPrev", hl.dsp.exec_cmd("playerctl previous"), { locked = true })
+--------------------------------
+---- WINDOWS AND WORKSPACES ----
+--------------------------------
+
hl.window_rule({
name = "suppress-maximize-events",
match = { class = ".*" },
@@ -185,6 +277,7 @@ hl.window_rule({
})
hl.window_rule({
+ -- Fix some dragging issues with XWayland
name = "fix-xwayland-drags",
match = {
class = "^$",