6 Commits

Author SHA1 Message Date
trey 15a20af8a5 Added Ctrl-Alt-Delete menu 2026-06-28 14:42:47 -04:00
trey d014f9c268 Fixed workspace order in single-monitor mode 2026-06-28 13:35:06 -04:00
trey 76226cb637 Fixed randomizeWallpaper() 2026-06-28 11:53:26 -04:00
trey 4f391cf1ca Fixed hypridle 2026-06-28 11:01:17 -04:00
trey 9663c18c7e Updated SUPER + down to cycle to the next window 2026-06-28 09:48:38 -04:00
trey 307163b567 Remapped keybinds to match Windows 11 defaults 2026-06-28 09:45:56 -04:00
5 changed files with 113 additions and 32 deletions
+36 -8
View File
@@ -247,21 +247,45 @@ function M.randomizeWallpaper()
local home = os.getenv("HOME") local home = os.getenv("HOME")
local april_dir = home .. "/images/April" local april_dir = home .. "/images/April"
local sbm_dir = home .. "/images/Seven Beats Music" local sbm_dir = home .. "/images/Seven Beats Music"
local black_png = home .. "/images/black.png"
-- Choose image source based on monitor count -- Determine if we are on the home WiFi ("keep")
local img_dir = (#monitors <= 1) and april_dir or sbm_dir 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 = {} local images = {}
local handle = io.popen('find "' .. img_dir .. '" -type f \\( -name "*.jpg" -o -name "*.png" -o -name "*.jpeg" \\) 2>/dev/null') if img_dir then
if handle then local handle = io.popen('find "' .. img_dir .. '" -type f \\( -name "*.jpg" -o -name "*.png" -o -name "*.jpeg" \\) 2>/dev/null')
for line in handle:lines() do if handle then
table.insert(images, line) for line in handle:lines() do
table.insert(images, line)
end
handle:close()
end end
handle:close() else
table.insert(images, black_png)
end end
if #images == 0 then return 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 -- Pick a unique random image for each monitor
math.randomseed(os.time()) math.randomseed(os.time())
local used = {} local used = {}
@@ -277,8 +301,12 @@ function M.randomizeWallpaper()
end end
attempts = attempts + 1 attempts = attempts + 1
end end
if not img then img = images[1] end -- fallback if we run out of unique images
if img then if img then
hl.dispatch(hl.dsp.exec_cmd('hyprctl hyprpaper reload "' .. mon.name .. ',' .. img .. '"')) -- 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 end
end end
+3 -9
View File
@@ -1,5 +1,6 @@
general { general {
lock_cmd = pidof hyprlock || hyprlock # avoid starting multiple hyprlock instances. 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. 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. 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. 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 { listener {
timeout = 300 timeout = 300
# 1. Lock the vault via DBus, 2. Start the lock screen # 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" && hyprlock 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
# When hyprlock exits (via fingerprint or password), instantly run the unlock script
on-resume = ~/.local/bin/unlock-ring.sh
} }
listener { listener {
+38 -14
View File
@@ -183,6 +183,7 @@ bind("SUPER + Q", dsp.exec_cmd("hyprctl reload && killall -SIGUSR2 waybar && not
-- BUG FIX: SUPER + SHIFT + Q was bound to both tmux kill and uwsm stop. -- 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("tmux kill-server"))
bind("SUPER + SHIFT + Q", dsp.exec_cmd("killall -q signal-desktop; uwsm stop")) bind("SUPER + SHIFT + Q", dsp.exec_cmd("killall -q signal-desktop; uwsm stop"))
bind("CTRL + ALT + Delete", dsp.exec_cmd("bash ~/.config/hypr/scripts/sysmenu.sh"))
bind("SUPER + L", dsp.exec_cmd("hyprlock")) bind("SUPER + L", dsp.exec_cmd("hyprlock"))
bind("switch:Lid Switch", dsp.exec_cmd("hyprlock")) bind("switch:Lid Switch", dsp.exec_cmd("hyprlock"))
@@ -199,30 +200,56 @@ end)
-- App launchers using our custom Lua focusOrLaunch function -- App launchers using our custom Lua focusOrLaunch function
bind("SUPER + return", function() fn.focusOrLaunch("alacritty", "Alacritty") end) bind("SUPER + return", function() fn.focusOrLaunch("alacritty", "Alacritty") end)
bind("SUPER + A", function() fn.focusOrLaunch("slack", "Slack", "Slack") end) bind("SUPER + SHIFT + 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 + 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 + 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 + 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) -- Windows 11 equivalent shortcuts
bind("SUPER + V", function() fn.focusOrLaunch("alacritty", "Alacritty") end) 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 -- Window control
bind("SUPER + C", dsp.window.close()) bind("SUPER + C", dsp.window.close())
bind("ALT + F4", dsp.window.close())
bind("SUPER + T", dsp.window.float({ action = "toggle" })) bind("SUPER + T", dsp.window.float({ action = "toggle" }))
bind("SUPER + space", dsp.window.fullscreen({ mode = 1 })) bind("SUPER + space", dsp.window.fullscreen({ mode = 1 }))
-- BUG FIX: H/J/K were redundantly bound to move_focus AND fullscreen. -- Cycle Layouts
bind("SUPER + H", dsp.focus({ direction = "l" })) local layouts = { "dwindle", "master", "scrolling" }
bind("SUPER + K", dsp.focus({ direction = "u" })) local layout_icons = { dwindle = "", master = "", scrolling = "" }
bind("SUPER + J", dsp.focus({ direction = "d" })) 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 + X", dsp.exec_cmd("dunstctl close"))
bind("SUPER + Y", dsp.exec_cmd("dunstctl close-all")) bind("SUPER + Y", dsp.exec_cmd("dunstctl close-all"))
-- Workspace control -- Workspace control
bind("SUPER + right", function() hl.dispatch(hl.dsp.focus({ workspace = "m+1" })) end) bind("SUPER + CTRL + 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 + 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 + 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 + L", function() hl.dispatch(hl.dsp.focus({ workspace = "m+1" })) end)
bind("SUPER + SHIFT + M", function() fn.mv2workspace() end) bind("SUPER + SHIFT + M", function() fn.mv2workspace() end)
@@ -233,9 +260,6 @@ bind("SUPER + SHIFT + left", function() fn.moveWorkspace(-1) end)
bind("SUPER + SHIFT + right", 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) 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 -- Laptop keys
bind("XF86MonBrightnessUp", dsp.exec_cmd("brightnessctl -- set +10%")) bind("XF86MonBrightnessUp", dsp.exec_cmd("brightnessctl -- set +10%"))
bind("XF86MonBrightnessDown", dsp.exec_cmd("brightnessctl -- set -10%")) bind("XF86MonBrightnessDown", dsp.exec_cmd("brightnessctl -- set -10%"))
+33
View File
@@ -0,0 +1,33 @@
#!/usr/bin/env bash
# Options for the menu
lock="Lock"
logout="Sign-Out"
reboot="Reboot"
poweroff="Power Off"
options="$lock\n$logout\n$reboot\n$poweroff"
# Fullscreen rofi menu with large centered text mimicking Windows 11
chosen=$(echo -e "$options" | rofi -dmenu -i -p "CTRL-ALT-DEL" \
-theme-str 'window { fullscreen: true; background-color: #000000cc; }' \
-theme-str 'mainbox { children: [listview]; padding: 25% 35%; }' \
-theme-str 'listview { columns: 1; lines: 4; spacing: 15px; scrollbar: false; }' \
-theme-str 'element { padding: 15px; border-radius: 10px; }' \
-theme-str 'element-text { horizontal-align: 0.5; vertical-align: 0.5; font: "sans-serif 20"; }' \
-theme-str 'element selected { background-color: #3366ff; text-color: white; }')
case $chosen in
$lock)
loginctl lock-session
;;
$logout)
hyprctl dispatch exit
;;
$reboot)
zsh -c 'source ~/.zsh_functions && reboot'
;;
$poweroff)
systemctl poweroff
;;
esac
+3 -1
View File
@@ -18,7 +18,9 @@ local function assign_workspaces()
package.loaded["workspace_config"] = nil -- force reload in case it changed package.loaded["workspace_config"] = nil -- force reload in case it changed
local ws_config = require("workspace_config") local ws_config = require("workspace_config")
for _, ws in ipairs(ws_config) do -- Iterate in REVERSE to assign the most negative IDs to the first items, counteracting Waybar's low-to-high sorting!
for i = #ws_config, 1, -1 do
local ws = ws_config[i]
local target_mon = has_dock and ws.monitor or "eDP-1" 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 }) hl.workspace_rule({ workspace = "name:" .. ws.name, monitor = target_mon, persistent = true, default = true })
end end