Compare commits

...
8 Commits
Author SHA1 Message Date
gitadmin a8cd242a26 feat(hyprland): make M key layout-aware for swap/consume-or-expel 2026-08-28 11:58:50 -04:00
gitadmin 521a105f35 feat(fish): add ngit alias for neogit 2026-08-28 11:58:08 -04:00
gitadmin ac490653e8 chore: shorten default bare repo dir to .bare 2026-08-28 11:57:16 -04:00
gitadmin 892e32439e refactor(hyprland): tune visuals, overhaul animations, add cursor/binds settings 2026-08-28 11:54:51 -04:00
gitadmin 8a3ae0f6bd feat: add screen recording, OCR capture, and improved screenshot workflow 2026-08-28 11:52:43 -04:00
gitadmin b65af6a730 feat(herdr): add herdr-annotate plugin with keybindings 2026-08-27 12:05:45 -04:00
gitadmin 7b1f04b530 refactor(hypr): split monolithic config into modules
Extract monitors, functions, rules, env vars, and onstart into
separate files. Add toggle_pin, toggle_master_scrolling, and
layout-aware keybinds for scrolling layout.
2026-08-22 12:27:44 -04:00
gitadmin d605f4c388 refactor(permission-system): reorganize path permissions and add vault access 2026-08-21 15:18:09 -04:00
14 changed files with 605 additions and 424 deletions
+1
View File
@@ -33,6 +33,7 @@ if status is-interactive
alias oo "cd $SECOND_BRAIN"
alias on "nvim '+Obsidian new'"
alias os "nvim '+Obsidian search'"
alias ngit "nvim +Neogit"
alias zdiff "nvim '+Zdiff'"
alias review "nvim '+Zdiff origin/HEAD'"
alias mini "NVIM_APPNAME=mini.nvim nvim"
+18
View File
@@ -47,5 +47,23 @@ type = "plugin_action"
command = "herdr-zoxide.browse"
description = "Browse zoxide directories"
[[keys.command]]
key = "prefix+a"
type = "plugin_action"
command = "annotate.capture"
description = "annotate text"
[[keys.command]]
key = "prefix+shift+a"
type = "plugin_action"
command = "annotate.copy-context"
description = "copy annotations as context"
[[keys.command]]
key = "prefix+m"
type = "plugin_action"
command = "annotate.manage"
description = "manage annotations"
[ui.toast]
delivery = "herdr"
+28
View File
@@ -0,0 +1,28 @@
-- Cursor size
hl.env("XCURSOR_SIZE", "24")
hl.env("HYPRCURSOR_SIZE", "24")
-- Force all apps to use Wayland
hl.env("GDK_BACKEND", "wayland,x11,*")
hl.env("QT_QPA_PLATFORM", "wayland;xcb")
hl.env("QT_STYLE_OVERRIDE", "kvantum")
hl.env("SDL_VIDEODRIVER", "wayland")
hl.env("MOZ_ENABLE_WAYLAND", "1")
hl.env("ELECTRON_OZONE_PLATFORM_HINT", "wayland")
hl.env("OZONE_PLATFORM", "wayland")
hl.env("XDG_SESSION_TYPE", "wayland")
-- Allow better support for screen sharing (Google Meet"," Discord, etc)
hl.env("XDG_CURRENT_DESKTOP", "Hyprland")
hl.env("XDG_SESSION_DESKTOP", "Hyprland")
-- Use XCompose file
hl.env("XCOMPOSEFILE", "~/.XCompose")
-- Make Chromium use XCompose and all Wayland
hl.env("CHROMIUM_FLAGS", "--enable-features=UseOzonePlatform --ozone-platform=wayland --gtk-version=4")
-- Make .desktop files available for wofi
hl.env("XDG_DATA_DIRS", "/usr/share:/usr/local/share:~/.local/share")
+198
View File
@@ -0,0 +1,198 @@
function sysinfo()
local mem = io.popen("free -h | awk '/^Mem/ {print $3 \"/\" $2}'"):read("*a")
local cpu = io.popen("top -bn1 | grep 'Cpu(s)' | awk '{print $2 + $4 \"%\"}'"):read("*a")
local battery = io.popen("acpi -b | awk -F', ' '{print $2}'"):read("*a")
local time = os.date("%Y-%m-%d %H:%M:%S")
local monitor = hl.get_active_monitor()
local workspace_id = monitor.active_workspace.id
local mesg = "System Info"
.. "\nDate: " .. time
.. "\nFocused monitor: " .. monitor.name
.. "\nWorkspace: " .. workspace_id
.. "\nBattery: " .. battery
.. "CPU: " .. cpu .. " MEM: " .. mem
hl.notification.create({ text = mesg, icon = "hint", duration = 5000 })
end
function toggle_pin()
local win = hl.get_active_window()
if win == nil then
return
end
local is_pinned = win.pinned
hl.dispatch(hl.dsp.window.pin({ action = is_pinned and "unset" or "set" }))
end
function dispatch_focus_or_launch(opts)
return function()
focus_or_launch(opts)
end
end
function focus_or_launch(opts)
local match = opts.match
local cmd = opts.cmd
local field = opts.field or "class" -- class, title, initialClass, initialTitle
local use_workspace = opts.use_workspace ~= false
local clients = hl.get_windows()
for _, client in ipairs(clients) do
local value = client[field]
if value and string.find(string.lower(value), string.lower(match), 1, true) then
if use_workspace and client.workspace and client.workspace.id then
hl.dispatch(hl.dsp.focus({
workspace = client.workspace.id,
on_current_monitor = true,
}))
end
hl.dispatch(hl.dsp.focus({
window = "address:" .. client.address
}))
local layout = client.layout
if not (layout and layout.name == "master" and layout.is_master) then
hl.dispatch(hl.dsp.layout("swapwithmaster"))
end
return
end
end
hl.exec_cmd(cmd)
end
function fetch_or_launch(opts)
local match = opts.match
local cmd = opts.cmd
local field = opts.field or "class" -- class, title, initialClass, initialTitle
local use_workspace = opts.use_workspace ~= false
local clients = hl.get_windows()
local active_workspace = hl.get_active_workspace()
for _, client in ipairs(clients) do
local value = client[field]
if value and string.find(string.lower(value), string.lower(match), 1, true) then
if use_workspace and client.workspace and client.workspace.id then
hl.dispatch(hl.dsp.window.move({
workspace = active_workspace,
on_current_monitor = true,
window = client,
}))
end
hl.dispatch(hl.dsp.focus({ window = client }))
local layout = client.layout
if not (layout and layout.name == "master" and layout.is_master) then
hl.dispatch(hl.dsp.layout("swapwithmaster"))
end
return
end
end
hl.exec_cmd(cmd)
end
function toggle_master()
local ws = hl.get_active_workspace()
if not ws then
return
end
local mfact = nil
for _, win in ipairs(ws:get_windows()) do
local layout = win.layout
if layout and layout.name == "master" and layout.is_master then
mfact = math.floor(layout.perc_master * 100 + 0.5) / 100
break
end
end
if mfact == 0.7 then
mfact = 0.5
else
mfact = 0.7
end
hl.dispatch(hl.dsp.layout("mfact exact " .. mfact))
end
function toggle_float_with_limit()
local win = hl.get_active_window()
if win == nil then
return
end
local was_floating = win.floating
hl.dispatch(hl.dsp.window.float({ action = "toggle" }))
if was_floating then
return
end
local mon = win.monitor and hl.get_monitor(win.monitor) or hl.get_active_monitor()
if mon == nil or mon.size == nil or win == nil or win.size == nil then
return
end
local max_width = math.floor(mon.width * 0.8)
local max_height = math.floor(mon.height * 0.8)
local scale = math.max(1, win.size.x / max_width, win.size.y / max_height)
hl.notification.create({
text = "Scale " ..
scale .. " Max float size: " .. win.size.x / max_width .. "x" .. win.size.y / max_height,
duration = 2000,
icon =
"hint"
})
if scale > 1 then
hl.dispatch(hl.dsp.window.resize({
x = math.floor(max_width),
y = math.floor(max_height),
relative = false,
window = win
}))
end
end
function cycle_next_window(opts)
return function()
hl.dispatch(hl.dsp.window.cycle_next(opts))
local win = hl.get_active_window()
if win and win.floating then
hl.dispatch(hl.dsp.window.alter_zorder({ mode = "top" }))
end
end
end
function window_resize_percentage(px, py)
local win = hl.get_active_window()
if win == nil or win.monitor == nil then
return
end
local mon = hl.get_monitor(win.monitor)
if mon == nil or mon.size == nil or mon.size.height == nil or mon.size.width == nil then
return
end
local sx = math.floor(mon.size.width * px)
local sy = math.floor(mon.size.height * py)
if not win.floating then
hl.dispatch(hl.dsp.window.float({ action = "set" }))
end
if win.fullscreen then
hl.dispatch(hl.dsp.window.fullscreen({ action = "unset" }))
end
hl.dispatch(hl.dsp.window.resize({ x = sx, y = sy, relative = false }))
end
function toggle_master_scrolling()
local current = hl.get_config("general.layout")
local next_layout = current == "master" and "scrolling" or "master"
hl.config({ general = { layout = next_layout } })
end
+113 -400
View File
@@ -1,62 +1,19 @@
-- require("keybinds.lua")
hl.monitor({ output = "desc:Lenovo Group Limited 0x41A0", mode = "highrr", position = "0x0", scale = "1.0" })
hl.monitor({ output = "desc:Samsung Display Corp. 0x4143", mode = "highrr", position = "0x0", scale = "2" })
hl.monitor({
output = "desc:LG Electronics LG HDR 4K 406NTZN74597",
mode = "preferred",
position = "auto-right",
scale =
"1.333333"
})
hl.monitor({
output = "desc:Ancor Communications Inc ASUS MG28U 0x00009B77",
mode = "preferred",
position = "auto-right",
scale =
"1.333333"
})
-- local terminal = "ghostty -e"
local terminal = "foot"
local _notify_cmd = "notify-send"
local browser = "gtk-launch firefox.desktop"
local webapp = "chromium --new-window --ozone-platform=wayland --app="
local music = "gtk-launch spotify.desktop"
-- hl.monitor({ output = "eDP-1", mode = "preferred", position = "0x0", scale = "1.0" })
local LEADER = "SUPER + "
local HYPR = "SUPER + CONTROL + SHIFT + ALT + "
hl.monitor({
output = "desc:LG Electronics LG HDR WQHD 0x0006530C",
mode = "preferred",
position = "auto-up",
scale =
"1.333333"
})
hl.monitor({ output = "CAP Capture 0x00000001", mode = "1920x1080@60", position = "auto-down", scale = 1 })
hl.monitor({ output = "HDMI-A-1", mode = "1920x1080@60", position = "auto-down", scale = 1 })
hl.monitor({ output = "HDMI-A-2", mode = "1920x1080@60", position = "auto-down", scale = 1 })
hl.monitor({
output = "desc:Ancor Communications Inc ASUS PB238 DCLMTF074371",
mode = "preferred",
position = "auto",
scale =
"1.0"
})
hl.monitor({ output = "desc:Lenovo Group Limited L15 U133R0A2", mode = "preferred", position = "auto-left", scale = 1 })
hl.monitor({ output = "desc:Lenovo Group Limited M15 V30F2A15", mode = "preferred", position = "auto-left", scale = 1 })
hl.monitor({ output = "desc:Proteon TYPE-C 8R33926O00QS", mode = "preferred", position = "auto-right", scale = "1.0" })
hl.monitor({ output = "desc:Stargate Technology TYPE-C", mode = "preferred", position = "auto-down", scale = "1.0" })
hl.monitor({ output = "desc:GWD ARZOPA 000000000000", mode = "preferred", position = "auto-down", scale = "1.0" })
hl.monitor({ output = "desc:BNQ BenQ EX3203R 7CL00509019", mode = "preferred", position = "auto", scale = 1 })
hl.monitor({ output = "desc:BNQ BenQ EX3501R N4M05650019", mode = "preferred", position = "auto-right", scale = "1.0" })
hl.monitor({
output = "desc:Dell Inc. DELL U3818DW 97F8P8AD0HEL",
mode = "preferred",
position = "auto-left",
scale =
"1.0"
})
hl.monitor({
output = "desc:Microstep MSI MAG342CQR DB6H252300057",
mode = "preferred",
position = "auto-left",
scale =
"1.0"
})
require("monitors")
require("functions")
require("rules")
require("theme")
require("envs")
require("onstart")
hl.config({
input = {
@@ -87,8 +44,8 @@ hl.config({
},
general = {
gaps_in = 0,
gaps_out = 0,
gaps_in = 3,
gaps_out = 3,
border_size = 2,
allow_tearing = true,
snap = {
@@ -111,21 +68,30 @@ hl.config({
dwindle = {
preserve_split = true,
smart_split = false,
force_split = 2,
},
scrolling = {
column_width = 1.0
focus_fit_method = 0,
column_width = 0.49,
fullscreen_on_one_column = true
},
cursor = {
hide_on_key_press = true,
warp_on_change_workspace = 1,
},
binds = {
hide_special_on_workspace_change = true,
},
decoration = {
rounding = 3,
rounding = 1,
active_opacity = 1.0,
inactive_opacity = 1.0,
dim_inactive = false,
inactive_opacity = 0.95,
dim_inactive = true,
dim_special = 0.0,
dim_strength = 0.2,
dim_strength = 0.3,
shadow = {
enabled = false,
@@ -151,13 +117,18 @@ hl.config({
misc = {
disable_hyprland_logo = true,
disable_splash_rendering = true,
disable_scale_notification = true,
focus_on_activate = true,
anr_missed_pings = 3,
on_focus_under_fullscreen = 1,
mouse_move_enables_dpms = true,
animate_manual_resizes = true,
mouse_move_focuses_monitor = true,
enable_swallow = true,
enable_anr_dialog = false,
force_default_wallpaper = true,
initial_workspace_tracking = 0,
allow_session_lock_restore = true,
},
xwayland = {
@@ -166,158 +137,39 @@ hl.config({
animations = {
enabled = true,
-- animation = borderangle, 1, 50, linear, loop
-- bezier = generic, 0.05, 0.9, 0.1, 1.08
-- bezier = almostLinear,0.5,0.5,0.75,1.0
-- bezier = quick,0.15,0,0.1,1
--
-- animation = windows, 1, 3, almostLinear
-- animation = windowsOut, 1, 3, quick
-- animation = windowsIn, 1, 3, quick
-- animation = border, 1, 10, generic
-- animation = fade, 1, 3, almostLinear
-- animation = workspaces, 1, 1, quick
-- animation = layers, 1, 3, quick
}
})
hl.curve("almostLinear", { type = "bezier", points = { { 0.5, 0.5 }, { 0.75, 1.0 } } })
hl.curve("linear", { type = "bezier", points = { { 0, 0 }, { 1, 1 } } })
hl.curve("generic", { type = "bezier", points = { { 0.5, 0.9 }, { 0.1, 1.08 } } })
hl.curve("quick", { type = "bezier", points = { { 0.15, 0 }, { 0.1, 1.0 } } })
hl.curve("overshoot", { type = "bezier", points = { { 0.5, 0.9 }, { 0.1, 1.1 } } })
hl.curve("rubber", { type = "spring", mass = 1, stiffness = 70, dampening = 10 })
hl.animation({ leaf = "windows", enabled = true, speed = 3, bezier = "almostLinear" })
hl.animation({ leaf = "border", enabled = true, speed = 1, spring = "rubber" })
hl.animation({ leaf = "workspaces", enabled = true, speed = 1, bezier = "quick" })
hl.animation({ leaf = "layers", enabled = true, speed = 3, bezier = "quick" })
hl.animation({ leaf = "fade", enabled = true, speed = 3, bezier = "almostLinear" })
hl.curve("easeOutQuint", { type = "bezier", points = { { 0.23, 1 }, { 0.32, 1 } } })
hl.curve("easeInOutCubic", { type = "bezier", points = { { 0.65, 0.05 }, { 0.36, 1 } } })
-- local terminal = "ghostty -e"
local terminal = "foot"
local _notify_cmd = "notify-send"
local browser = "gtk-launch firefox.desktop"
local webapp = "chromium --new-window --ozone-platform=wayland --app="
local music = "gtk-launch spotify.desktop"
hl.animation({ leaf = "global", enabled = true, speed = 10, bezier = "default" })
hl.animation({ leaf = "border", enabled = true, speed = 5.39, bezier = "easeOutQuint" })
hl.animation({ leaf = "windows", enabled = true, speed = 3.79, bezier = "easeOutQuint" })
hl.animation({ leaf = "windowsIn", enabled = true, speed = 4.1, bezier = "easeOutQuint", style = "popin 87%" })
hl.animation({ leaf = "windowsOut", enabled = true, speed = 1.49, bezier = "linear", style = "popin 87%" })
hl.animation({ leaf = "fadeIn", enabled = true, speed = 1.73, bezier = "almostLinear" })
hl.animation({ leaf = "fadeOut", enabled = true, speed = 1.46, bezier = "almostLinear" })
hl.animation({ leaf = "fade", enabled = true, speed = 3.03, bezier = "quick" })
hl.animation({ leaf = "fadeSwitch", enabled = false })
hl.animation({ leaf = "layers", enabled = true, speed = 3.81, bezier = "easeOutQuint" })
hl.animation({ leaf = "layersIn", enabled = true, speed = 4, bezier = "easeOutQuint", style = "fade" })
hl.animation({ leaf = "layersOut", enabled = true, speed = 1.5, bezier = "linear", style = "fade" })
hl.animation({ leaf = "fadeLayersIn", enabled = true, speed = 1.79, bezier = "almostLinear" })
hl.animation({ leaf = "fadeLayersOut", enabled = true, speed = 1.39, bezier = "almostLinear" })
hl.animation({ leaf = "workspaces", enabled = true, speed = 0.5, bezier = "quick" })
local LEADER = "SUPER + "
local HYPR = "SUPER + CONTROL + SHIFT + ALT + "
hl.animation({ leaf = "specialWorkspaceIn", enabled = true, speed = 3, bezier = "easeOutQuint", style = "slide top" })
hl.animation({ leaf = "specialWorkspaceOut", enabled = true, speed = 2, bezier = "easeInOutCubic", style = "slide bottom" })
function sysinfo()
local mem = io.popen("free -h | awk '/^Mem/ {print $3 \"/\" $2}'"):read("*a")
local cpu = io.popen("top -bn1 | grep 'Cpu(s)' | awk '{print $2 + $4 \"%\"}'"):read("*a")
local battery = io.popen("acpi -b | awk -F', ' '{print $2}'"):read("*a")
local time = os.date("%Y-%m-%d %H:%M:%S")
local monitor = hl.get_active_monitor()
local workspace_id = monitor.active_workspace.id
local mesg = "System Info"
.. "\nDate: " .. time
.. "\nFocused monitor: " .. monitor.name
.. "\nWorkspace: " .. workspace_id
.. "\nBattery: " .. battery
.. "CPU: " .. cpu .. " MEM: " .. mem
hl.notification.create({ text = mesg, icon = "hint", duration = 5000 })
end
function dispatch_focus_or_launch(opts)
return function()
focus_or_launch(opts)
end
end
function focus_or_launch(opts)
local match = opts.match
local cmd = opts.cmd
local field = opts.field or "class" -- class, title, initialClass, initialTitle
local use_workspace = opts.use_workspace ~= false
local clients = hl.get_windows()
for _, client in ipairs(clients) do
local value = client[field]
if value and string.find(string.lower(value), string.lower(match), 1, true) then
if use_workspace and client.workspace and client.workspace.id then
hl.dispatch(hl.dsp.focus({
workspace = client.workspace.id,
on_current_monitor = true,
}))
end
hl.dispatch(hl.dsp.focus({
window = "address:" .. client.address
}))
local layout = client.layout
if not (layout and layout.name == "master" and layout.is_master) then
hl.dispatch(hl.dsp.layout("swapwithmaster"))
end
return
end
end
hl.exec_cmd(cmd)
end
function fetch_or_launch(opts)
local match = opts.match
local cmd = opts.cmd
local field = opts.field or "class" -- class, title, initialClass, initialTitle
local use_workspace = opts.use_workspace ~= false
local clients = hl.get_windows()
local active_workspace = hl.get_active_workspace()
for _, client in ipairs(clients) do
local value = client[field]
if value and string.find(string.lower(value), string.lower(match), 1, true) then
if use_workspace and client.workspace and client.workspace.id then
hl.dispatch(hl.dsp.window.move({
workspace = active_workspace,
on_current_monitor = true,
window = client,
}))
end
hl.dispatch(hl.dsp.focus({ window = client }))
local layout = client.layout
if not (layout and layout.name == "master" and layout.is_master) then
hl.dispatch(hl.dsp.layout("swapwithmaster"))
end
return
end
end
hl.exec_cmd(cmd)
end
function toggle_master()
local ws = hl.get_active_workspace()
if not ws then
return
end
local mfact = nil
for _, win in ipairs(ws:get_windows()) do
local layout = win.layout
if layout and layout.name == "master" and layout.is_master then
mfact = math.floor(layout.perc_master * 100 + 0.5) / 100
break
end
end
if mfact == 0.7 then
mfact = 0.5
else
mfact = 0.7
end
hl.dispatch(hl.dsp.layout("mfact exact " .. mfact))
end
-- Keybindings
hl.bind(LEADER .. "SHIFT + return", hl.dsp.exec_cmd("gtk-launch herdr.desktop"), { description = "Open herdr terminal" })
hl.bind(LEADER .. "return", hl.dsp.exec_cmd("gtk-launch tmux.desktop"), { description = "Open tmux terminal" })
@@ -328,6 +180,12 @@ hl.bind(LEADER .. "B", hl.dsp.exec_raw(browser), { description = "Open browser"
hl.bind(LEADER .. "S", hl.dsp.exec_raw("ostt launch --paste"), { description = "Open ostt" })
hl.bind(LEADER .. "I", sysinfo, { description = "Show system info" })
hl.bind(
LEADER .. "Y",
toggle_master_scrolling,
{ description = "Layout: Toggle master/scrolling" }
)
-- Open rofi on first press, closes it on second
hl.bind(LEADER .. "Space", hl.dsp.exec_raw("rofi -show combi --modes combi"),
{ release = true, description = "Open Application Menu" })
@@ -342,22 +200,32 @@ hl.bind(LEADER .. "slash",
{ release = true, description = "Open rofi-pass" }
)
hl.bind(HYPR .. "P", hl.dsp.exec_cmd("gtk-launch pi.desktop"), { description = "Open pi tui" })
hl.bind(HYPR .. "V", hl.dsp.exec_cmd("pavucontrol"), { description = "Volume control" })
hl.bind(HYPR .. "B", hl.dsp.exec_cmd("blueberry"), { description = "Bluetooth manager" })
hl.bind(HYPR .. "semicolon", hl.dsp.exec_cmd("~/.local/bin/set-wallpaper.sh categories/quotes"),
{ description = "get new wallpaper" })
hl.bind("Print", hl.dsp.exec_cmd("hyprshot -m window"), { description = "Take screenshot" })
hl.bind("SHIFT + Print", hl.dsp.exec_cmd("hyprshot -m region"), { description = "Take screenshot" })
hl.bind("Print",
hl.dsp.exec_cmd("hyprshot -m window -o ~/Pictures/ -- tensaku-edit"),
{ description = "Take screenshot" })
hl.bind("SHIFT + Print",
hl.dsp.exec_cmd("hyprshot -m region -o ~/Pictures/ -- tensaku-edit"),
{ description = "Take screenshot" })
hl.bind(HYPR .. "A", dispatch_focus_or_launch({
match = "Goose",
field = "class",
cmd = "gtk-launch goose-desktop.desktop"
}), { description = "Goose Desktop" })
hl.bind("ALT + Print",
hl.dsp.exec_cmd("hyprshot -m region --raw -z | /usr/bin/tesseract stdin stdout --oem 1 --psm 6 -l eng | wl-copy"),
{ description = "Capture text" })
hl.bind("SUPER + Print",
hl.dsp.exec_cmd("~/.local/bin/screen-recorder -o ~/Videos/$(date +'%Y-%m-%d_%H%M%S')_recording.mp4"),
{ description = "Start/Stop screen recording" })
hl.bind("SUPER + SHIFT + Print",
hl.dsp.exec_cmd("~/.local/bin/screen-recorder stop"),
{ description = "Stop screen recording" })
hl.bind(HYPR .. "A", hl.dsp.exec_cmd("gtk-launch pi.desktop"), { description = "Open pi tui" })
hl.bind(HYPR .. "C", dispatch_focus_or_launch({
match = "chrome-chatgpt.com",
cmd = "gtk-launch ChatGPT.desktop",
@@ -434,47 +302,11 @@ hl.bind(LEADER .. "CTRL + F", hl.dsp.window.fullscreen_state({ internal = 2, cli
hl.bind(LEADER .. "ALT + F", hl.dsp.window.fullscreen_state({ internal = 0, client = 2, action = "toggle" }),
{ description = "Window: Toggle fullscreen state 2" })
function toggle_float_with_limit()
local win = hl.get_active_window()
if win == nil then
return
end
local was_floating = win.floating
hl.dispatch(hl.dsp.window.float({ action = "toggle" }))
if was_floating then
return
end
local mon = win.monitor and hl.get_monitor(win.monitor) or hl.get_active_monitor()
if mon == nil or mon.size == nil or win == nil or win.size == nil then
return
end
local max_width = math.floor(mon.width * 0.8)
local max_height = math.floor(mon.height * 0.8)
local scale = math.max(1, win.size.x / max_width, win.size.y / max_height)
hl.notification.create({
text = "Scale " ..
scale .. " Max float size: " .. win.size.x / max_width .. "x" .. win.size.y / max_height,
duration = 2000,
icon =
"hint"
})
if scale > 1 then
hl.dispatch(hl.dsp.window.resize({
x = math.floor(max_width),
y = math.floor(max_height),
relative = false,
window = win
}))
end
end
hl.bind(LEADER .. "T", toggle_float_with_limit,
{ description = "Window: Toggle floating/tiling (max 80%)" })
hl.bind(LEADER .. "P", hl.dsp.window.pseudo(), { description = "Window: Toggle pseudo tiling" })
-- hl.bind(LEADER .. "P", hl.dsp.window.pseudo(), { description = "Window: Toggle pseudo tiling" })
hl.bind(LEADER .. "P", toggle_pin, { description = "Window: Toggle Pin" })
hl.bind(LEADER .. "A", hl.dsp.window.alter_zorder({ mode = "top" }), { description = "Window: Move to top" })
@@ -498,17 +330,6 @@ hl.bind(LEADER .. "ALT + comma", function()
hl.dispatch(hl.dsp.layout("cyclenext"))
end, { description = "Window: Swap with prev" })
function cycle_next_window(opts)
return function()
hl.dispatch(hl.dsp.window.cycle_next(opts))
local win = hl.get_active_window()
if win and win.floating then
hl.dispatch(hl.dsp.window.alter_zorder({ mode = "top" }))
end
end
end
hl.bind("ALT + Tab", cycle_next_window({ next = true }), { description = "Window: Cycle next" })
hl.bind("ALT + SHIFT + Tab", cycle_next_window({ next = false }), { description = "Window: Cycle prev" })
@@ -518,18 +339,42 @@ hl.bind(LEADER .. "ALT + Tab", hl.dsp.focus({ workspace = "previous", on_current
-- arrange split ratio
hl.bind(LEADER .. "X", toggle_master, { description = "Layout: Toggle master size" })
-- hl.bind(LEADER .. "equal", hl.dsp.layout("mfact exact 0.5"))
hl.bind(LEADER .. "M", hl.dsp.layout("swapwithmaster"))
hl.bind(LEADER .. "M", function()
local current_layout = hl.get_config("general.layout")
if current_layout == "master" then
hl.dispatch(hl.dsp.layout("swapwithmaster"))
end
if current_layout == "scrolling" then
hl.dispatch(hl.dsp.layout("consume_or_expel next"))
end
end, { description = "Layout: Swap with master" })
-- hl.bind(LEADER .. "M", hl.dsp.layout("rollnext"))
hl.bind(LEADER .. "period", function()
hl.dispatch(hl.dsp.layout("cycleprev"))
hl.dispatch(hl.dsp.layout("swapwithmaster"))
local current_layout = hl.get_config("general.layout")
if current_layout == "master" then
hl.dispatch(hl.dsp.layout("cycleprev"))
hl.dispatch(hl.dsp.layout("swapwithmaster"))
end
if current_layout == "scrolling" then
hl.dispatch(hl.dsp.layout("swapcol r"))
hl.dispatch(hl.dsp.layout("focus l"))
end
-- hl.dispatch(hl.dsp.layout("focus r"))
end, { description = "Layout: Cycle next" })
hl.bind(LEADER .. "comma", function()
hl.dispatch(hl.dsp.layout("cyclenext"))
hl.dispatch(hl.dsp.layout("swapwithmaster"))
local current_layout = hl.get_config("general.layout")
if current_layout == "master" then
hl.dispatch(hl.dsp.layout("cyclenext"))
hl.dispatch(hl.dsp.layout("swapwithmaster"))
end
if current_layout == "scrolling" then
hl.dispatch(hl.dsp.layout("swapcol l"))
hl.dispatch(hl.dsp.layout("focus r"))
end
-- hl.dispatch(hl.dsp.layout("focus l"))
end, { description = "Layout: Cycle previous" })
@@ -538,7 +383,6 @@ hl.bind(LEADER .. "SHIFT + semicolon", hl.dsp.window.move({ workspace = "special
{ description = "Window: Move to special workspace" })
hl.bind(LEADER .. "C", hl.dsp.window.center(), { description = "Window: Center" })
hl.bind(LEADER .. "Escape", hl.dsp.exec_raw("loginctl lock-session"), { description = "Lock screen" })
hl.bind(LEADER .. "SHIFT + escape", hl.dsp.exec_raw("systemctl suspend"), { description = "Suspend" })
hl.bind(LEADER .. "ALT + escape", hl.dsp.exec_raw("uwsm stop,"), { description = "Stop UWSM" })
@@ -565,27 +409,6 @@ hl.on("keybinds.submap", function(name)
hl.notification.create({ text = "Entered submap: " .. name, duration = 2000, icon = "hint" })
end)
function window_resize_percentage(px, py)
local win = hl.get_active_window()
if win == nil or win.monitor == nil then
return
end
local mon = hl.get_monitor(win.monitor)
if mon == nil or mon.size == nil or mon.size.height == nil or mon.size.width == nil then
return
end
local sx = math.floor(mon.size.width * px)
local sy = math.floor(mon.size.height * py)
if not win.floating then
hl.dispatch(hl.dsp.window.float({ action = "set" }))
end
if win.fullscreen then
hl.dispatch(hl.dsp.window.fullscreen({ action = "unset" }))
end
hl.dispatch(hl.dsp.window.resize({ x = sx, y = sy, relative = false }))
end
hl.bind(LEADER .. "F10", hl.dsp.submap("notification menu"))
hl.define_submap("notification menu", function()
hl.bind("Q", hl.dsp.exit())
@@ -686,7 +509,7 @@ hl.bind(LEADER .. " + mouse:273", hl.dsp.window.resize(), { mouse = true })
hl.bind("mouse:275", hl.dsp.window.cycle_next({ next = true }), { click = true, description = "Window: Cycle next" })
hl.bind("mouse:276", hl.dsp.window.cycle_next({ next = false }), { click = true, description = "Window: Cycle previous" })
-- Gestures
-- hl.gesture({ fingers = 3, direction = "horizontal", action = "workspace" })
-- hl.gesture({ fingers = 3, direction = "down", mods = "ALT", action = "close" })
-- hl.gesture({ fingers = 3, direction = "up", mods = "SUPER", scale = 1.5, action = "fullscreen" })
@@ -695,113 +518,3 @@ hl.bind("mouse:276", hl.dsp.window.cycle_next({ next = false }), { click = true,
-- hl.gesture({ fingers = 2, direction = "pinch", action = "cursorZoom", zoom_level = 2 })
-- hl.gesture({ fingers = 2, direction = "pinch", action = "cursorZoom", zoom_level = 1.2, mode = "mult" })
-- hl.gesture({ fingers = 2, direction = "pinch", action = "cursorZoom", zoom_level = 1, mode = "live" })
hl.workspace_rule({ workspace = "special:special", border_size = 3 })
hl.window_rule({
match = { class = "(blueberry.py|Impala|Wiremix|org.gnome.NautilusPreviewer|com.gabm.satty|Omarchy|About|TUI.float|org.pulseaudio.pavucontrol)" },
tag =
"+floating-window"
})
hl.window_rule({
match = { class = "terminal-pi" },
float = true,
center = true,
workspace = "special:special",
size = { "monitor_w/2", "monitor_h/2" }
})
hl.window_rule({
match = { class = "quicknotes" },
tag = "+floating-window"
})
hl.window_rule({
name = "ostt floating windows",
match = { class = "ostt-popup" },
float = true,
no_anim = true,
move = { 10, 10 },
size = { 320, 240 },
})
hl.window_rule({
match = {
class = "(xdg-desktop-portal-gtk|sublime_text|DesktopEditors)",
title = "^(Open.*Files?|Save.*Files?|Save.*As|All Files|Save)"
},
tag = "+floating-window"
})
hl.window_rule({
match = { class = "code" },
fullscreen_state = 1,
})
hl.window_rule({
-- Fix some dragging issues with XWayland
name = "fix-xwayland-drags",
match = {
class = "^$",
title = "^$",
xwayland = true,
float = true,
fullscreen = false,
pin = false,
},
no_focus = true,
})
hl.window_rule({ match = { tag = "floating-window" }, float = true, center = true, size = { "monitor_w/2", "monitor_h/2" } })
hl.window_rule({ match = { class = "(rofi|wofi)" }, tag = "+user-menu" })
hl.window_rule({ match = { class = "^(pinentry-)" }, tag = "+user-menu" })
hl.window_rule({ match = { class = "^(gcr-prompter)$" }, tag = "+user-menu" })
hl.window_rule({ match = { tag = "user-menu" }, stay_focused = true, no_anim = true, float = true, center = true, size = { "monitor_w/3", "monitor_h/3" } })
hl.window_rule({
name = "Picture in Picture windows",
match = { title = "^.*[Pp]icture[ -][Ii]n[ -][Pp]icture.*$" },
float = true,
pin = true,
rounding = 7,
opacity = "1 1",
move = { "monitor_w-window_w-10", "monitor_h-window_h-10" },
size = { "monitor_w/4", "monitor_h/4" },
})
-- Cursor size
hl.env("XCURSOR_SIZE", "24")
hl.env("HYPRCURSOR_SIZE", "24")
-- Force all apps to use Wayland
hl.env("GDK_BACKEND", "wayland,x11,*")
hl.env("QT_QPA_PLATFORM", "wayland;xcb")
hl.env("QT_STYLE_OVERRIDE", "kvantum")
hl.env("SDL_VIDEODRIVER", "wayland")
hl.env("MOZ_ENABLE_WAYLAND", "1")
hl.env("ELECTRON_OZONE_PLATFORM_HINT", "wayland")
hl.env("OZONE_PLATFORM", "wayland")
hl.env("XDG_SESSION_TYPE", "wayland")
-- Allow better support for screen sharing (Google Meet"," Discord, etc)
hl.env("XDG_CURRENT_DESKTOP", "Hyprland")
hl.env("XDG_SESSION_DESKTOP", "Hyprland")
-- Use XCompose file
hl.env("XCOMPOSEFILE", "~/.XCompose")
-- Make Chromium use XCompose and all Wayland
hl.env("CHROMIUM_FLAGS", "--enable-features=UseOzonePlatform --ozone-platform=wayland --gtk-version=4")
-- Make .desktop files available for wofi
hl.env("XDG_DATA_DIRS", "/usr/share:/usr/local/share:~/.local/share")
-- TODO: add theme link
require("theme")
hl.on("hyprland.start", function()
hl.exec_cmd("hyprctl setcursor Pop 24")
end)
+58
View File
@@ -0,0 +1,58 @@
hl.monitor({ output = "desc:Lenovo Group Limited 0x41A0", mode = "highrr", position = "0x0", scale = "1.0" })
hl.monitor({ output = "desc:Samsung Display Corp. 0x4143", mode = "highrr", position = "0x0", scale = "2" })
hl.monitor({
output = "desc:LG Electronics LG HDR 4K 406NTZN74597",
mode = "preferred",
position = "auto-right",
scale =
"1.333333"
})
hl.monitor({
output = "desc:Ancor Communications Inc ASUS MG28U 0x00009B77",
mode = "preferred",
position = "auto-right",
scale =
"1.333333"
})
-- hl.monitor({ output = "eDP-1", mode = "preferred", position = "0x0", scale = "1.0" })
hl.monitor({
output = "desc:LG Electronics LG HDR WQHD 0x0006530C",
mode = "preferred",
position = "auto-up",
scale =
"1.333333"
})
hl.monitor({ output = "CAP Capture 0x00000001", mode = "1920x1080@60", position = "auto-down", scale = 1 })
hl.monitor({ output = "HDMI-A-1", mode = "1920x1080@60", position = "auto-down", scale = 1 })
hl.monitor({ output = "HDMI-A-2", mode = "1920x1080@60", position = "auto-down", scale = 1 })
hl.monitor({
output = "desc:Ancor Communications Inc ASUS PB238 DCLMTF074371",
mode = "preferred",
position = "auto",
scale =
"1.0"
})
hl.monitor({ output = "desc:Lenovo Group Limited L15 U133R0A2", mode = "preferred", position = "auto-left", scale = 1 })
hl.monitor({ output = "desc:Lenovo Group Limited M15 V30F2A15", mode = "preferred", position = "auto-left", scale = 1 })
hl.monitor({ output = "desc:Proteon TYPE-C 8R33926O00QS", mode = "preferred", position = "auto-right", scale = "1.0" })
hl.monitor({ output = "desc:Stargate Technology TYPE-C", mode = "preferred", position = "auto-down", scale = "1.0" })
hl.monitor({ output = "desc:GWD ARZOPA 000000000000", mode = "preferred", position = "auto-down", scale = "1.0" })
hl.monitor({ output = "desc:BNQ BenQ EX3203R 7CL00509019", mode = "preferred", position = "auto", scale = 1 })
hl.monitor({ output = "desc:BNQ BenQ EX3501R N4M05650019", mode = "preferred", position = "auto-right", scale = "1.0" })
hl.monitor({
output = "desc:Dell Inc. DELL U3818DW 97F8P8AD0HEL",
mode = "preferred",
position = "auto-left",
scale =
"1.0"
})
hl.monitor({
output = "desc:Microstep MSI MAG342CQR DB6H252300057",
mode = "preferred",
position = "auto-left",
scale =
"1.0"
})
+3
View File
@@ -0,0 +1,3 @@
hl.on("hyprland.start", function()
hl.exec_cmd("hyprctl setcursor Pop 24")
end)
+75
View File
@@ -0,0 +1,75 @@
hl.workspace_rule({ workspace = "special:special", border_size = 3 })
hl.window_rule({
match = { class = "(blueberry.py|Impala|Wiremix|org.gnome.NautilusPreviewer|com.gabm.satty|Omarchy|About|TUI.float|org.pulseaudio.pavucontrol)" },
tag =
"+floating-window"
})
hl.window_rule({
match = { class = "terminal-pi" },
float = true,
center = true,
workspace = "special:special",
size = { "monitor_w/2", "monitor_h/2" }
})
hl.window_rule({
match = { class = "quicknotes" },
tag = "+floating-window"
})
hl.window_rule({
name = "ostt floating windows",
match = { class = "ostt-popup" },
float = true,
no_anim = true,
move = { 10, 10 },
size = { 320, 240 },
})
hl.window_rule({
match = {
class = "(xdg-desktop-portal-gtk|sublime_text|DesktopEditors)",
title = "^(Open.*Files?|Save.*Files?|Save.*As|All Files|Save)"
},
tag = "+floating-window"
})
hl.window_rule({
match = { class = "code" },
fullscreen_state = 1,
})
hl.window_rule({
-- Fix some dragging issues with XWayland
name = "fix-xwayland-drags",
match = {
class = "^$",
title = "^$",
xwayland = true,
float = true,
fullscreen = false,
pin = false,
},
no_focus = true,
})
hl.window_rule({ match = { tag = "floating-window" }, float = true, center = true, size = { "monitor_w/2", "monitor_h/2" } })
hl.window_rule({ match = { class = "(rofi|wofi)" }, tag = "+user-menu" })
hl.window_rule({ match = { class = "^(pinentry-)" }, tag = "+user-menu" })
hl.window_rule({ match = { class = "^(gcr-prompter)$" }, tag = "+user-menu" })
hl.window_rule({ match = { tag = "user-menu" }, stay_focused = true, no_anim = true, float = true, center = true, size = { "monitor_w/3", "monitor_h/3" } })
hl.window_rule({
name = "Picture in Picture windows",
match = { title = "^.*[Pp]icture[ -][Ii]n[ -][Pp]icture.*$" },
float = true,
pin = true,
rounding = 7,
opacity = "1 1",
move = { "monitor_w-window_w-10", "monitor_h-window_h-10" },
size = { "monitor_w/4", "monitor_h/4" },
})
+1
View File
@@ -54,6 +54,7 @@ run = [
'herdr plugin install devashish2203/herdr-worktrunk --yes',
'herdr plugin install qu8n/herdr-automatic-rename --yes',
'herdr plugin install den-tanui/herdr-zoxide --yes',
'herdr plugin install plannotator/herdr-annotate --yes',
]
[tasks.light]
@@ -1,26 +1,26 @@
{
"permission": {
"*": "ask",
"path": {
"./*": "allow",
"./.*": "allow",
"~/.ssh/*": "deny",
"*.env": "deny",
"*.env.*": "deny",
"*.env.example": "allow",
"/tmp/*": "ask"
"permission": {
"*": "ask",
"path": {
"./*": "allow",
"./.*": "allow",
"~/.ssh/*": "deny",
"*.env": "deny",
"*.env.*": "deny",
"*.env.example": "allow"
},
"bash": {
"*": "ask",
"rm -rf *": "deny",
"sudo *": "ask"
},
"external_directory": {
"*": "ask",
"/tmp/*": "ask",
"~/Documents/sjb-brain/*": "allow"
}
},
"bash": {
"*": "ask",
"rm -rf *": "deny",
"sudo *": "ask"
},
"external_directory": {
"*": "ask",
"~/Documents/sjb-brain/*": "allow"
}
},
"debugLog": false,
"permissionReviewLog": true,
"yoloMode": true
"debugLog": false,
"permissionReviewLog": true,
"yoloMode": true
}
+1
View File
@@ -88,6 +88,7 @@ dotfiles.default_mode = "symlink-each"
"~/.local/bin/hyprland-fetch-client" = { source = "script/hyprland-fetch-client", mode = "symlink" }
"~/.local/bin/hyprland-focus-client" = { source = "script/hyprland-focus-client", mode = "symlink" }
"~/.local/bin/terminal-launcher" = { source = "script/terminal-launcher", mode = "symlink" }
"~/.local/bin/screen-recorder" = { source = "script/screen-recorder", mode = "symlink" }
"~/.local/bin/battery" = { source = "script/battery", mode = "symlink" }
# "~/.config/bin/ec" = { source = "script/ec", mode = "symlink" }
+2
View File
@@ -79,6 +79,8 @@ slurp
spotify
tenacity
tensaku-bin
tesseract
tesseract-data-eng
ttf-0xproto-nerd
ttf-bitstream-vera
ttf-dejavu
+1 -1
View File
@@ -6,7 +6,7 @@ Usage: git bare-clone [-d bare-repo-dir] [-h] <git-repo-url> [workspace]
EOF
}
BARE_REPO_DIR="./.git-repo"
BARE_REPO_DIR="./.bare"
while getopts ":d:h" opt; do
case "$opt" in
d) BARE_REPO_DIR="$OPTARG" ;;
+83
View File
@@ -0,0 +1,83 @@
#!/bin/sh
LOG_FILE=$([[ ${DEBUG_SCREENRECORDER:-false} == "true" ]] && echo "/tmp/screenrecord.log" || echo "/dev/null")
usage() {
echo "Usage: screen-recorder stop | screen-recorder [-a] [-m region|monitor|window] -o <output_filename>" >&2
}
if [ "$#" -eq 1 ] && [ "$1" = stop ]; then
pkill -SIGINT -f "gpu-screen-recorder"
count=0
while pgrep -f "gpu-screen-recorder" >/dev/null && ((count < 50)); do
sleep 0.1
count=$((count + 1))
done
if pgrep -f "gpu-screen-recorder" >/dev/null; then
pkill -9 -f "gpu-screen-recorder"
fi
notify-send "Screen Recorder" "Recording stopped" -t 2000
exit $?
fi
if pgrep -f "gpu-screen-recorder" >/dev/null; then
notify-send "Screen Recorder" "Recording is already in progress" -t 2000
exit 1
fi
mode=monitor
output_filename="/tmp/output.mp4"
audio_args=()
while getopts ":am:o:h" opt; do
case "$opt" in
a) audio_args=(-a default_input -ac aac) ;;
m) mode=$OPTARG ;;
o) output_filename=$OPTARG ;;
h) usage; exit 0 ;;
:) usage; exit 1 ;;
\?) usage; exit 1 ;;
esac
done
shift $((OPTIND - 1))
if [ "$#" -ne 0 ] || [ -z "$output_filename" ]; then
usage
exit 1
fi
script_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
recorder=$(PATH=$(printf '%s' "$PATH" | awk -v RS=: -v ORS=: -v script_dir="$script_dir" '$0 != script_dir') command -v gpu-screen-recorder)
if [ -z "$recorder" ]; then
echo "gpu-screen-recorder executable not found" >&2
exit 1
fi
capture_args=()
case "$mode" in
monitor)
target=$(hyprctl monitors -j | jq -r '.[] | select(.focused == true) | .name')
[ -n "$target" ] || exit 1
capture_args=(-w "$target")
;;
region)
target=$(slurp -f '%wx%h+%x+%y') || exit 1
[ -n "$target" ] || exit 1
capture_args=(-w region -region "$target")
;;
window)
target=$(hyprctl clients -j |
jq -r '.[] | select(.mapped == true and .hidden == false and .at != null and .size != null) | "\(.at[0]),\(.at[1]) \(.size[0])x\(.size[1]) \((.title // .class // "window") | gsub("[\\r\\n]"; " "))"' |
slurp -r) || exit 1
[ -n "$target" ] || exit 1
capture_args=(-w region -region "$target")
;;
*)
echo "Invalid mode: $mode" >&2
usage
exit 1
;;
esac
exec "$recorder" "${capture_args[@]}" "${audio_args[@]}" -k auto -f 60 -fm cfr -fallback-cpu-encoding yes -o "$output_filename" 2>>"$LOG_FILE" &