Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
76226cb637 | ||
|
|
4f391cf1ca | ||
|
|
9663c18c7e | ||
|
|
307163b567 | ||
|
|
3cadcad501 |
No files matched your search
+14
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"diagnostics": {
|
||||
"globals": [
|
||||
"hl"
|
||||
]
|
||||
},
|
||||
"workspace": {
|
||||
"library": [
|
||||
"/usr/share/hypr/stubs",
|
||||
"/usr/share/hyprland/stubs"
|
||||
],
|
||||
"checkThirdParty": false
|
||||
}
|
||||
}
|
||||
+314
@@ -0,0 +1,314 @@
|
||||
-- ~/.config/hypr/functions.lua
|
||||
local M = {}
|
||||
|
||||
-- focusOrLaunch: checks if a window with the given class exists.
|
||||
-- If it does, focuses it (and sends specific shortcuts if it's qutebrowser).
|
||||
-- If not, optionally switches to a workspace and launches the app.
|
||||
function M.focusOrLaunch(app_cmd, class_name, workspace_name)
|
||||
local clients = hl.get_windows()
|
||||
local found = false
|
||||
|
||||
for _, client in ipairs(clients) do
|
||||
if client.class == class_name then
|
||||
hl.dispatch(hl.dsp.focus({ window = "class:" .. class_name }))
|
||||
-- Specific qutebrowser logic ported from your zsh script
|
||||
if app_cmd:match("qutebrowser") then
|
||||
hl.dispatch(hl.dsp.send_shortcut({ mods = "", key = "Escape", window = "class:" .. class_name }))
|
||||
hl.dispatch(hl.dsp.send_shortcut({ mods = "", key = "0", window = "class:" .. class_name }))
|
||||
hl.dispatch(hl.dsp.send_shortcut({ mods = "", key = "1", window = "class:" .. class_name }))
|
||||
hl.dispatch(hl.dsp.send_shortcut({ mods = "ALT", key = "J", window = "class:" .. class_name }))
|
||||
hl.dispatch(hl.dsp.send_shortcut({ mods = "", key = "Escape", window = "class:" .. class_name }))
|
||||
end
|
||||
found = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if not found then
|
||||
if workspace_name and #workspace_name > 0 then
|
||||
hl.dispatch(hl.dsp.focus({ workspace = workspace_name }))
|
||||
end
|
||||
hl.dispatch(hl.dsp.exec_cmd(app_cmd))
|
||||
end
|
||||
end
|
||||
|
||||
function M.getActiveWorkspaceName()
|
||||
local f = io.popen("hyprctl -j activeworkspace | jq -r '.name'")
|
||||
local active_ws_name = f:read("*a"):gsub("%s+", "")
|
||||
f:close()
|
||||
return active_ws_name
|
||||
end
|
||||
|
||||
function M.mv2workspace()
|
||||
local cmd = [[
|
||||
bash -c '
|
||||
WORKSPACES=$(hyprctl -j workspaces | jq -r ".[] | .name")
|
||||
ACTIVE="$(hyprctl -j activewindow)"
|
||||
CLASS="$(jq -r ".class" <<< "$ACTIVE")"
|
||||
TITLE="$(jq -r ".title" <<< "$ACTIVE")"
|
||||
ADDR="$(jq -r ".address" <<< "$ACTIVE")"
|
||||
PROMPT="Move window of ${CLASS} with title '\''${TITLE}'\'' to which workspace? "
|
||||
NEW_WS="$(echo "$WORKSPACES" | rofi -dmenu -p "$PROMPT")"
|
||||
if [ -n "$NEW_WS" ]; then
|
||||
hyprctl dispatch "hl.dsp.window.move({ workspace = \"$NEW_WS\", window = \"address:$ADDR\", follow = false })"
|
||||
fi
|
||||
'
|
||||
]]
|
||||
hl.dispatch(hl.dsp.exec_cmd(cmd))
|
||||
end
|
||||
|
||||
function M.createWorkspace(after_name)
|
||||
local after_str = after_name or ""
|
||||
local cmd = string.format([[
|
||||
bash -c '
|
||||
NEW_NAME=$(rofi -dmenu -p "new workspace name" -l 0 < /dev/null | tr -d "[:space:]")
|
||||
if [ -z "$NEW_NAME" ]; then exit 0; fi
|
||||
|
||||
ACTIVE_MON=$(hyprctl -j monitors | jq -r ".[] | select(.focused) | .name")
|
||||
NEW_LINE=" { name = \"$NEW_NAME\", monitor = \"$ACTIVE_MON\" },"
|
||||
FILE="$HOME/.config/hypr/workspace_config.lua"
|
||||
|
||||
AFTER="%s"
|
||||
|
||||
if [ -n "$AFTER" ] && grep -q "name *= *\"$AFTER\"" "$FILE"; then
|
||||
sed -i "/name *= *\"$AFTER\"/a \\$NEW_LINE" "$FILE"
|
||||
else
|
||||
sed -i "/^}/i \\$NEW_LINE" "$FILE"
|
||||
fi
|
||||
hyprctl reload
|
||||
'
|
||||
]], after_str)
|
||||
hl.dispatch(hl.dsp.exec_cmd(cmd))
|
||||
end
|
||||
|
||||
function M.deleteWorkspace()
|
||||
local cmd = [[
|
||||
bash -c '
|
||||
ACTIVE_WS=$(hyprctl -j activeworkspace | jq -r ".name")
|
||||
if [ -z "$ACTIVE_WS" ]; then exit 0; fi
|
||||
FILE="$HOME/.config/hypr/workspace_config.lua"
|
||||
sed -i "/name *= *\"$ACTIVE_WS\"/d" "$FILE"
|
||||
hyprctl dispatch "hl.dsp.focus({ workspace = \"m-1\" })"
|
||||
hyprctl reload
|
||||
'
|
||||
]]
|
||||
hl.dispatch(hl.dsp.exec_cmd(cmd))
|
||||
end
|
||||
|
||||
function M.moveWorkspace(direction, target_monitor)
|
||||
-- If no target_monitor is provided and direction is nil, prompt interactively via async bash to avoid deadlocks
|
||||
if (not target_monitor or target_monitor == "") and not direction then
|
||||
local cmd = [[
|
||||
bash -c '
|
||||
ACTIVE_WS=$(hyprctl -j activeworkspace | jq -r ".name")
|
||||
if [ -z "$ACTIVE_WS" ]; then exit 0; fi
|
||||
MONITORS=$(hyprctl -j monitors | jq -r ".[].name")
|
||||
PROMPT="Move workspace '\''$ACTIVE_WS'\'' to which monitor? "
|
||||
NEW_MON=$(echo "$MONITORS" | rofi -dmenu -p "$PROMPT")
|
||||
if [ -n "$NEW_MON" ]; then
|
||||
FILE="$HOME/.config/hypr/workspace_config.lua"
|
||||
sed -i -E "/name *= *\"$ACTIVE_WS\"/ s/monitor *= *\"[^\"]+\"/monitor = \"$NEW_MON\"/" "$FILE"
|
||||
hyprctl reload
|
||||
fi
|
||||
'
|
||||
]]
|
||||
hl.dispatch(hl.dsp.exec_cmd(cmd))
|
||||
return
|
||||
end
|
||||
|
||||
-- NATIVE LUA PATH for directional shifts or explicit monitor arguments passed from keybinds
|
||||
local active_ws_name = M.getActiveWorkspaceName()
|
||||
if not active_ws_name or active_ws_name == "" then return end
|
||||
|
||||
local path = os.getenv("HOME") .. "/.config/hypr/workspace_config.lua"
|
||||
local f_in = io.open(path, "r")
|
||||
if not f_in then return end
|
||||
|
||||
local lines = {}
|
||||
local ws_idx = nil
|
||||
|
||||
for line in f_in:lines() do
|
||||
table.insert(lines, line)
|
||||
if line:match('name%s*=%s*"' .. active_ws_name .. '"') then
|
||||
ws_idx = #lines
|
||||
end
|
||||
end
|
||||
f_in:close()
|
||||
|
||||
if not ws_idx then return end
|
||||
|
||||
if target_monitor and target_monitor ~= "" then
|
||||
lines[ws_idx] = lines[ws_idx]:gsub('monitor%s*=%s*"[^"]+"', 'monitor = "' .. target_monitor .. '"')
|
||||
end
|
||||
|
||||
if direction then
|
||||
local first_idx = 2
|
||||
local last_idx = #lines - 1
|
||||
|
||||
while first_idx < #lines and not lines[first_idx]:match("name%s*=") do first_idx = first_idx + 1 end
|
||||
while last_idx > 1 and not lines[last_idx]:match("name%s*=") do last_idx = last_idx - 1 end
|
||||
|
||||
if first_idx <= last_idx then
|
||||
local current_line = table.remove(lines, ws_idx)
|
||||
local new_idx = ws_idx
|
||||
|
||||
if direction > 0 then
|
||||
new_idx = ws_idx + 1
|
||||
if new_idx > last_idx then
|
||||
new_idx = first_idx
|
||||
end
|
||||
elseif direction < 0 then
|
||||
new_idx = ws_idx - 1
|
||||
if new_idx < first_idx then
|
||||
new_idx = last_idx
|
||||
end
|
||||
end
|
||||
|
||||
table.insert(lines, new_idx, current_line)
|
||||
end
|
||||
end
|
||||
|
||||
local f_out = io.open(path, "w")
|
||||
for _, line in ipairs(lines) do
|
||||
f_out:write(line .. "\n")
|
||||
end
|
||||
f_out:close()
|
||||
|
||||
hl.dispatch(hl.dsp.exec_cmd("hyprctl reload"))
|
||||
end
|
||||
|
||||
function M.pasteMacro(script_path)
|
||||
local cmd = string.format([[
|
||||
bash -c '
|
||||
exec > /tmp/paste.log 2>&1
|
||||
out="$(%s)"
|
||||
echo -n "$out" | wl-copy
|
||||
|
||||
# 1. Wait a moment for physical keys to be released
|
||||
sleep 0.3
|
||||
# 2. Release modifiers logically, then execute CTRL+V
|
||||
wtype -m logo -m ctrl -m shift -m alt -M ctrl -k v -m ctrl
|
||||
|
||||
# 3. Wait a full second to ensure Wayland apps finish reading the clipboard asynchronously
|
||||
sleep 1.0
|
||||
|
||||
# 4. Scrub the password from cliphist securely
|
||||
PREV=$(cliphist list | awk "NR==2")
|
||||
cliphist list | awk "NR==1" | cliphist delete
|
||||
if [ -n "$PREV" ]; then
|
||||
echo "$PREV" | cliphist decode | wl-copy
|
||||
else
|
||||
wl-copy -c
|
||||
fi
|
||||
'
|
||||
]], script_path)
|
||||
hl.dispatch(hl.dsp.exec_cmd(cmd))
|
||||
end
|
||||
|
||||
function M.pasteText(text)
|
||||
local cmd = string.format([[
|
||||
bash -c '
|
||||
exec &> /tmp/$(date +%%FT%%H%%M%%S)_paste.log
|
||||
echo -n "%s" | wl-copy
|
||||
|
||||
# Wait a moment for physical keys to be released, then execute CTRL+V
|
||||
sleep 0.3
|
||||
wtype -m logo -m ctrl -m shift -m alt -M ctrl -k v -m ctrl
|
||||
# Note: We do not scrub cliphist here because dates are not sensitive passwords,
|
||||
# which completely eliminates the paste race condition for dates!
|
||||
'
|
||||
]], text)
|
||||
hl.dispatch(hl.dsp.exec_cmd(cmd))
|
||||
end
|
||||
|
||||
function M.timetracker()
|
||||
local cmd = [[
|
||||
bash -c '
|
||||
CHOICE=$(echo -e "Begin...\nEnd..." | rofi -dmenu -theme-str "inputbar {enabled: false;}" -i -matching prefix -auto-select -l 2)
|
||||
if [ "$CHOICE" = "Begin..." ]; then
|
||||
DATE_STR=$(date "+%F %T")
|
||||
wtype -m logo -m ctrl -m shift -m alt -k Escape
|
||||
wtype "I${DATE_STR}: Begin "
|
||||
elif [ "$CHOICE" = "End..." ]; then
|
||||
DATE_STR=$(date "+%F %T")
|
||||
wtype -m logo -m ctrl -m shift -m alt -k Escape
|
||||
wtype "I${DATE_STR}: End "
|
||||
wtype -k Escape
|
||||
wtype "kly\$jpo"
|
||||
wtype "${DATE_STR}: Begin "
|
||||
fi
|
||||
'
|
||||
]]
|
||||
hl.dispatch(hl.dsp.exec_cmd(cmd))
|
||||
end
|
||||
|
||||
function M.randomizeWallpaper()
|
||||
local monitors = hl.get_monitors()
|
||||
local home = os.getenv("HOME")
|
||||
local april_dir = home .. "/images/April"
|
||||
local sbm_dir = home .. "/images/Seven Beats Music"
|
||||
local black_png = home .. "/images/black.png"
|
||||
|
||||
-- Determine if we are on the home WiFi ("keep")
|
||||
local is_home_wifi = false
|
||||
local f = io.popen("bash -c '/usr/bin/iwgetid -r 2>/dev/null || /usr/bin/nmcli -t -f active,ssid dev wifi 2>/dev/null | grep \"^yes\" | cut -d: -f2'")
|
||||
if f then
|
||||
local ssid = f:read("*a")
|
||||
f:close()
|
||||
if ssid and ssid:match("keep") then
|
||||
is_home_wifi = true
|
||||
end
|
||||
end
|
||||
|
||||
-- Select image source based on location
|
||||
local img_dir = nil
|
||||
if #monitors > 1 then
|
||||
img_dir = sbm_dir
|
||||
elseif is_home_wifi then
|
||||
img_dir = april_dir
|
||||
end
|
||||
|
||||
local images = {}
|
||||
if img_dir then
|
||||
local handle = io.popen('find "' .. img_dir .. '" -type f \\( -name "*.jpg" -o -name "*.png" -o -name "*.jpeg" \\) 2>/dev/null')
|
||||
if handle then
|
||||
for line in handle:lines() do
|
||||
table.insert(images, line)
|
||||
end
|
||||
handle:close()
|
||||
end
|
||||
else
|
||||
table.insert(images, black_png)
|
||||
end
|
||||
|
||||
if #images == 0 then return end
|
||||
|
||||
-- Unload old wallpapers from memory
|
||||
hl.dispatch(hl.dsp.exec_cmd("hyprctl hyprpaper unload all"))
|
||||
|
||||
-- Pick a unique random image for each monitor
|
||||
math.randomseed(os.time())
|
||||
local used = {}
|
||||
for _, mon in ipairs(monitors) do
|
||||
local img = nil
|
||||
local attempts = 0
|
||||
while attempts < #images do
|
||||
local idx = math.random(1, #images)
|
||||
if not used[idx] then
|
||||
img = images[idx]
|
||||
used[idx] = true
|
||||
break
|
||||
end
|
||||
attempts = attempts + 1
|
||||
end
|
||||
if not img then img = images[1] end -- fallback if we run out of unique images
|
||||
|
||||
if img then
|
||||
-- Standard hyprpaper IPC
|
||||
hl.dispatch(hl.dsp.exec_cmd('hyprctl hyprpaper preload "' .. img .. '"'))
|
||||
hl.dispatch(hl.dsp.exec_cmd('hyprctl hyprpaper wallpaper "' .. mon.name .. ',' .. img .. '"'))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
||||
+5
-9
@@ -1,5 +1,6 @@
|
||||
general {
|
||||
lock_cmd = pidof hyprlock || hyprlock # avoid starting multiple hyprlock instances.
|
||||
unlock_cmd = ~/.local/bin/unlock-ring.sh # run when session is unlocked (hyprlock exits)
|
||||
before_sleep_cmd = loginctl lock-session # lock before suspend.
|
||||
after_sleep_cmd = hyprctl dispatch dpms on # to avoid having to press a key twice to turn on the display.
|
||||
}
|
||||
@@ -17,17 +18,10 @@ listener {
|
||||
on-resume = brightnessctl -rd rgb:kbd_backlight # turn on keyboard backlight.
|
||||
}
|
||||
|
||||
#listener {
|
||||
# timeout = 300 # 5min
|
||||
# on-timeout = loginctl lock-session # lock screen when timeout has passed
|
||||
#}
|
||||
|
||||
listener {
|
||||
timeout = 300
|
||||
# 1. Lock the vault via DBus, 2. Start the lock screen
|
||||
on-timeout = busctl --user call org.freedesktop.secrets /org/freedesktop/secrets org.freedesktop.Secret.Service Lock "as" 1 "/org/freedesktop/secrets/aliases/default" && hyprlock
|
||||
# When hyprlock exits (via fingerprint or password), instantly run the unlock script
|
||||
on-resume = ~/.local/bin/unlock-ring.sh
|
||||
# 1. Lock the vault via DBus, 2. Start the lock screen (using ';' so it locks even if the vault fails/is already locked)
|
||||
on-timeout = busctl --user call org.freedesktop.secrets /org/freedesktop/secrets org.freedesktop.Secret.Service Lock "as" 1 "/org/freedesktop/secrets/aliases/default" ; loginctl lock-session
|
||||
}
|
||||
|
||||
listener {
|
||||
@@ -40,3 +34,5 @@ listener {
|
||||
timeout = 900 # 10min
|
||||
on-timeout = systemd-ac-power || systemctl suspend # only suspend pc on battery
|
||||
}
|
||||
|
||||
# vim:ft=hyprlang
|
||||
+305
@@ -0,0 +1,305 @@
|
||||
-- ~/.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 + SHIFT + A", function() fn.focusOrLaunch("slack", "Slack", "Slack") end)
|
||||
bind("SUPER + SHIFT + 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)
|
||||
|
||||
-- Windows 11 equivalent shortcuts
|
||||
bind("SUPER + S", dsp.exec_cmd(launcher)) -- Win+S for Search/Launcher
|
||||
bind("SUPER + R", dsp.exec_cmd(launcher)) -- Win+R for Run
|
||||
bind("SUPER + E", dsp.exec_cmd("nautilus")) -- Win+E for Explorer
|
||||
bind("SUPER + V", dsp.exec_cmd("cliphist list | rofi -dmenu -p 'paste' | cliphist decode | " .. copy .. " && " .. paste)) -- Win+V for Clipboard
|
||||
bind("SUPER + SHIFT + S", function() fn.focusOrLaunch("pavucontrol", "org.pulseaudio.pavucontrol", "org.pulseaudio.pavucontrol") end)
|
||||
|
||||
-- Window control
|
||||
bind("SUPER + C", dsp.window.close())
|
||||
bind("ALT + F4", dsp.window.close())
|
||||
bind("SUPER + T", dsp.window.float({ action = "toggle" }))
|
||||
bind("SUPER + space", dsp.window.fullscreen({ mode = 1 }))
|
||||
|
||||
-- Cycle Layouts
|
||||
local layouts = { "dwindle", "master", "scrolling" }
|
||||
local layout_icons = { dwindle = "", master = "", scrolling = "" }
|
||||
local layout_idx = 1
|
||||
|
||||
local function cycle_layout()
|
||||
layout_idx = (layout_idx % #layouts) + 1
|
||||
local new_layout = layouts[layout_idx]
|
||||
|
||||
hl.config({ general = { layout = new_layout } })
|
||||
|
||||
os.execute("echo '" .. layout_icons[new_layout] .. "' > /tmp/hypr_layout.txt")
|
||||
os.execute("pkill -RTMIN+8 waybar")
|
||||
end
|
||||
|
||||
bind("SUPER + right", function() cycle_layout() end)
|
||||
bind("SUPER + left", function() cycle_layout() end)
|
||||
bind("SUPER + up", dsp.window.fullscreen({ mode = 1 }))
|
||||
bind("SUPER + down", hl.dsp.window.cycle_next())
|
||||
|
||||
-- XMonad-style cycle & Alt+Tab (using native dsp dispatchers)
|
||||
bind("SUPER + J", hl.dsp.window.cycle_next())
|
||||
bind("SUPER + K", hl.dsp.window.cycle_next({ prev = true }))
|
||||
bind("ALT + Tab", hl.dsp.window.cycle_next())
|
||||
bind("ALT + SHIFT + Tab", hl.dsp.window.cycle_next({ prev = true }))
|
||||
|
||||
bind("SUPER + X", dsp.exec_cmd("dunstctl close"))
|
||||
bind("SUPER + Y", dsp.exec_cmd("dunstctl close-all"))
|
||||
|
||||
-- Workspace control
|
||||
bind("SUPER + CTRL + right", function() hl.dispatch(hl.dsp.focus({ workspace = "m+1" })) end)
|
||||
bind("SUPER + CTRL + 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)
|
||||
|
||||
-- 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)
|
||||
+8
-8
@@ -1,19 +1,20 @@
|
||||
ipc = true
|
||||
splash = false
|
||||
wallpaper {
|
||||
monitor = DP-7
|
||||
path = /home/trey/images/black.png
|
||||
fit_mode = cover
|
||||
}
|
||||
|
||||
wallpaper {
|
||||
monitor = eDP-1
|
||||
path = /home/trey/images/black.png
|
||||
fit_mode = cover
|
||||
}
|
||||
|
||||
wallpaper {
|
||||
monitor = DP-7
|
||||
path = /home/trey/images/Seven Beats Music/2024-09-16.jpg
|
||||
fit_mode = cover
|
||||
}
|
||||
|
||||
wallpaper {
|
||||
monitor = DP-8
|
||||
path = /home/trey/images/Seven Beats Music/2024-10-14.jpg
|
||||
path = /home/trey/images/black.png
|
||||
fit_mode = cover
|
||||
}
|
||||
|
||||
@@ -22,4 +23,3 @@ wallpaper {
|
||||
path = /home/trey/images/black.png
|
||||
fit_mode = cover
|
||||
}
|
||||
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,42 @@
|
||||
general {
|
||||
lock_cmd = pidof hyprlock || hyprlock # avoid starting multiple hyprlock instances.
|
||||
before_sleep_cmd = loginctl lock-session # lock before suspend.
|
||||
after_sleep_cmd = hyprctl dispatch dpms on # to avoid having to press a key twice to turn on the display.
|
||||
}
|
||||
|
||||
listener {
|
||||
timeout = 150 # 2.5min.
|
||||
on-timeout = brightnessctl -s set 10 # set monitor backlight to minimum, avoid 0 on OLED monitor.
|
||||
on-resume = brightnessctl -r # monitor backlight restore.
|
||||
}
|
||||
|
||||
# turn off keyboard backlight, comment out this section if you dont have a keyboard backlight.
|
||||
listener {
|
||||
timeout = 150 # 2.5min.
|
||||
on-timeout = brightnessctl -sd rgb:kbd_backlight set 0 # turn off keyboard backlight.
|
||||
on-resume = brightnessctl -rd rgb:kbd_backlight # turn on keyboard backlight.
|
||||
}
|
||||
|
||||
#listener {
|
||||
# timeout = 300 # 5min
|
||||
# on-timeout = loginctl lock-session # lock screen when timeout has passed
|
||||
#}
|
||||
|
||||
listener {
|
||||
timeout = 300
|
||||
# 1. Lock the vault via DBus, 2. Start the lock screen
|
||||
on-timeout = busctl --user call org.freedesktop.secrets /org/freedesktop/secrets org.freedesktop.Secret.Service Lock "as" 1 "/org/freedesktop/secrets/aliases/default" && hyprlock
|
||||
# When hyprlock exits (via fingerprint or password), instantly run the unlock script
|
||||
on-resume = ~/.local/bin/unlock-ring.sh
|
||||
}
|
||||
|
||||
listener {
|
||||
timeout = 330 # 5.5min
|
||||
on-timeout = hyprctl dispatch dpms off # screen off when timeout has passed
|
||||
on-resume = hyprctl dispatch dpms on # screen on when activity is detected after timeout has fired.
|
||||
}
|
||||
|
||||
listener {
|
||||
timeout = 900 # 10min
|
||||
on-timeout = systemd-ac-power || systemctl suspend # only suspend pc on battery
|
||||
}
|
||||
File renamed without changes.
@@ -0,0 +1,70 @@
|
||||
auth {
|
||||
fingerprint {
|
||||
enabled = true
|
||||
}
|
||||
}
|
||||
|
||||
background {
|
||||
# path = screenshot
|
||||
color = rgb(000000)
|
||||
}
|
||||
|
||||
input-field {
|
||||
size = 200, 30
|
||||
outline_thickness = 1
|
||||
rounding = 10
|
||||
outer_color = rgb(665c54)
|
||||
inner_color = rgb(3c3836)
|
||||
font_color = rgb(ebdbb2)
|
||||
check_color = rgb(d79921)
|
||||
fail_color = rgb(cc241d)
|
||||
fade_on_empty = false
|
||||
placeholder_text = password
|
||||
fail_text =
|
||||
}
|
||||
|
||||
label {
|
||||
text = cmd[update:500]date +"%FT%H:%M:%S"
|
||||
color = rgb(ebdbb2)
|
||||
font_size = 45
|
||||
font_family = monospace
|
||||
|
||||
position = 0, 60
|
||||
halign = center
|
||||
valign = center
|
||||
}
|
||||
|
||||
label {
|
||||
text = cmd[update:3000]pidof spotify > /dev/null && echo "<span foreground='##b8bb26' size='25000' rise='-4.5pt'> </span>$(playerctl -p spotify metadata xesam:title) - $(playerctl -p spotify metadata xesam:artist)"
|
||||
color = rgb(ebdbb2)
|
||||
font_size = 14
|
||||
font_family = JetBrains Mono Nerd Font Mono Semibold
|
||||
|
||||
position = 0, -420
|
||||
halign = center
|
||||
valign = center
|
||||
}
|
||||
|
||||
label {
|
||||
text = cmd[update:60] uptime -p
|
||||
color = rgb(ebdbb2)
|
||||
offont_size = 10
|
||||
font_family = monospace
|
||||
|
||||
position = 0, -450
|
||||
halign = center
|
||||
valign = center
|
||||
}
|
||||
|
||||
listener {
|
||||
timeout = 300 # 5 minutes
|
||||
on-timeout = sleep 60 && busctl --user call org.freedesktop.secrets /org/freedesktop/secrets org.freedesktop.Secret.Service Lock "as" 1 "/org/freedesktop/secrets/aliases/default" && hyprlock
|
||||
}
|
||||
|
||||
listener {
|
||||
timeout = 330 # 5.5 minutes
|
||||
on-timeout = hyprctl dispatch dpms off # screen off
|
||||
on-resume = hyprctl dispatch dpms on # screen on
|
||||
}
|
||||
|
||||
# vim:ft=hyprlang
|
||||
@@ -0,0 +1,25 @@
|
||||
splash = false
|
||||
wallpaper {
|
||||
monitor = eDP-1
|
||||
path = /home/trey/images/black.png
|
||||
fit_mode = cover
|
||||
}
|
||||
|
||||
wallpaper {
|
||||
monitor = DP-7
|
||||
path = /home/trey/images/Seven Beats Music/2024-09-16.jpg
|
||||
fit_mode = cover
|
||||
}
|
||||
|
||||
wallpaper {
|
||||
monitor = DP-8
|
||||
path = /home/trey/images/Seven Beats Music/2024-10-14.jpg
|
||||
fit_mode = cover
|
||||
}
|
||||
|
||||
wallpaper {
|
||||
monitor =
|
||||
path = /home/trey/images/black.png
|
||||
fit_mode = cover
|
||||
}
|
||||
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,7 @@
|
||||
workspace = 1, defaultName:shell, monitor:eDP-1, persistent:true, default:true
|
||||
workspace = 3, defaultName:browser, monitor:eDP-1, persistent:true, default:true
|
||||
workspace = 4, defaultName:work, monitor:eDP-1, persistent:true, default:true
|
||||
workspace = 5, defaultName:jobs, monitor:eDP-1, persistent:true, default:true
|
||||
workspace = 6, defaultName:meeting, monitor:eDP-1, persistent:true, default:true
|
||||
workspace = 7, defaultName:monitoring, monitor:eDP-1, persistent:true, default:true
|
||||
workspace = 8, defaultName:ai, monitor:eDP-1, persistent:true, default:true
|
||||
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Background loop to monitor battery status and trigger dunstify on low power.
|
||||
while true; do
|
||||
if [ ! -d /sys/class/power_supply/BAT0 ]; then
|
||||
sleep 60
|
||||
continue
|
||||
fi
|
||||
|
||||
STATUS=$(cat /sys/class/power_supply/BAT0/status 2>/dev/null)
|
||||
# Using the native kernel capacity file instead of relying on ibam
|
||||
CAPACITY=$(cat /sys/class/power_supply/BAT0/capacity 2>/dev/null)
|
||||
|
||||
if [ -z "$CAPACITY" ]; then
|
||||
sleep 60
|
||||
continue
|
||||
fi
|
||||
|
||||
# Trigger notification at 5% or below
|
||||
if [ "$STATUS" == "Discharging" ] && [ "$CAPACITY" -le 5 ]; then
|
||||
if [ ! -f "/run/user/${UID}/battery_low" ]; then
|
||||
logger "Low power! Triggering notification...."
|
||||
dunstify --urgency=critical \
|
||||
--icon=/usr/share/icons/breeze-dark/emblems/16/emblem-warning.svg \
|
||||
"LOW BATTERY!" \
|
||||
"Battery level is at ${CAPACITY}%, plug power quick!"
|
||||
touch "/run/user/${UID}/battery_low"
|
||||
fi
|
||||
|
||||
# Clear the notification if we plug back in and rise above 5%
|
||||
elif [ "$STATUS" == "Charging" ] && [ "$CAPACITY" -gt 5 ]; then
|
||||
if [ -f "/run/user/${UID}/battery_low" ]; then
|
||||
logger "Power reconnected and above 5 percent, clearing notification state."
|
||||
rm -f "/run/user/${UID}/battery_low"
|
||||
|
||||
# Find and close the specific dunst notification by ID
|
||||
for id in $(dunstctl history | jq '.data[0][] | select(.summary.data == "LOW BATTERY!") | .id.data'); do
|
||||
dunstify --close=${id}
|
||||
done
|
||||
fi
|
||||
fi
|
||||
|
||||
sleep 60
|
||||
done
|
||||
@@ -1,35 +0,0 @@
|
||||
#!/usr/bin/env zsh
|
||||
|
||||
#set -x
|
||||
old_profile="$(kanshictl status | jq -r '.current_profile')"
|
||||
new_profile="${1}"
|
||||
shift
|
||||
|
||||
if [[ "${old_profile}" == "${new_profile}" ]]; then
|
||||
if [[ "${1}" != "--force" ]] && [[ "${1}" != '-f' ]]; then
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
case "${new_profile}" in
|
||||
home_office)
|
||||
perl -pi -e 'if (/shell/) {s/monitor:.*?,/monitor:DP-6,/}' ${XDG_CONFIG_HOME}/hypr/workspaces.conf
|
||||
perl -pi -e 'if (/browser/) {s/monitor:.*?,/monitor:DP-6,/}' ${XDG_CONFIG_HOME}/hypr/workspaces.conf
|
||||
perl -pi -e 'if (/work/) {s/monitor:.*?,/monitor:HDMI-A-1,/}' ${XDG_CONFIG_HOME}/hypr/workspaces.conf
|
||||
perl -pi -e 'if (/jobs/) {s/monitor:.*?,/monitor:HDMI-A-1,/}' ${XDG_CONFIG_HOME}/hypr/workspaces.conf
|
||||
kanshictl switch home_office
|
||||
hyprctl reload
|
||||
killall -s USR2 waybar
|
||||
;;
|
||||
single_headed)
|
||||
perl -pi -e 's/monitor:.*?,/monitor:eDP-1,/' ${XDG_CONFIG_HOME}/hypr/workspaces.conf
|
||||
kanshictl switch single_headed
|
||||
hyprctl reload
|
||||
killall -s USR2 waybar
|
||||
;;
|
||||
*)
|
||||
print "Invalid profile!" >&2
|
||||
;;
|
||||
esac
|
||||
|
||||
#set +x
|
||||
@@ -0,0 +1,8 @@
|
||||
return {
|
||||
{ name = "shell", monitor = "DP-8" },
|
||||
{ name = "browser", monitor = "DP-8" },
|
||||
{ name = "jobs", monitor = "DP-7" },
|
||||
{ name = "work", monitor = "DP-7" },
|
||||
{ name = "meeting", monitor = "eDP-1" },
|
||||
{ name = "monitoring", monitor = "eDP-1" },
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
workspace = 1, defaultName:shell, monitor:DP-8, persistent:true, default:true
|
||||
workspace = 3, defaultName:browser, monitor:DP-8, persistent:true, default:true
|
||||
workspace = 4, defaultName:work, monitor:DP-7, persistent:true, default:true
|
||||
workspace = 5, defaultName:jobs, monitor:DP-7, persistent:true, default:true
|
||||
workspace = 6, defaultName:meeting, monitor:eDP-1, persistent:true, default:true
|
||||
workspace = 7, defaultName:monitoring, monitor:eDP-1, persistent:true, default:true
|
||||
workspace = 8, defaultName:ai, monitor:eDP-1, persistent:true, default:true
|
||||
@@ -0,0 +1,37 @@
|
||||
-- ~/.config/hypr/workspaces.lua
|
||||
-- Dynamic workspace assignment: replaces kanshi + scripts
|
||||
-- Detects monitor configuration and assigns workspaces accordingly.
|
||||
|
||||
local function get_monitor_names()
|
||||
local names = {}
|
||||
for _, m in ipairs(hl.get_monitors()) do
|
||||
names[m.name] = true
|
||||
end
|
||||
return names
|
||||
end
|
||||
|
||||
local function assign_workspaces()
|
||||
local monitors = get_monitor_names()
|
||||
local has_dock = monitors["DP-7"] and monitors["DP-8"]
|
||||
|
||||
-- Read workspace configurations
|
||||
package.loaded["workspace_config"] = nil -- force reload in case it changed
|
||||
local ws_config = require("workspace_config")
|
||||
|
||||
for _, ws in ipairs(ws_config) do
|
||||
local target_mon = has_dock and ws.monitor or "eDP-1"
|
||||
hl.workspace_rule({ workspace = "name:" .. ws.name, monitor = target_mon, persistent = true, default = true })
|
||||
end
|
||||
end
|
||||
|
||||
-- Apply on initial load
|
||||
assign_workspaces()
|
||||
|
||||
-- Re-apply when monitors change
|
||||
hl.on("monitor.added", function(monitor)
|
||||
assign_workspaces()
|
||||
end)
|
||||
|
||||
hl.on("monitor.removed", function(monitor)
|
||||
assign_workspaces()
|
||||
end)
|
||||
Reference in new issue
Block a user