Add the installer, uninstaller, and generated docs

This commit is contained in:
2026-09-20 00:19:38 -04:00
parent 0c422e7345
commit 3e65d176e3
100 changed files with 2585 additions and 0 deletions
+15
View File
@@ -0,0 +1,15 @@
-- Essential application bindings.
o.bind("SUPER + RETURN", "Terminal", { blob = "terminal" })
o.bind("SUPER + SHIFT + RETURN", "Browser", { blob = "browser" })
o.bind("SUPER + SHIFT + F", "File manager", { blob = "nautilus" })
o.bind("SUPER + ALT + SHIFT + F", "File manager (cwd)", { blob = "nautilus-cwd" })
o.bind("SUPER + SHIFT + B", "Browser", { blob = "browser" })
o.bind("SUPER + SHIFT + ALT + B", "Browser (private)", { blob = "browser --private" })
o.bind("SUPER + SHIFT + N", "Editor", { blob = "editor" })
if o.preinstalled_bindings_enabled() then
o.bind("SUPER + SHIFT + M", "Music", { blob = "spotify" })
o.bind("SUPER + SHIFT + D", "Docker", { tui = "blob-launch-docker-tui" })
o.bind("SUPER + SHIFT + G", "Signal", { blob = "signal" })
o.bind("SUPER + SHIFT + O", "Obsidian", { launch = "obsidian", focus = "^obsidian$" })
end
+48
View File
@@ -0,0 +1,48 @@
-- Send with explicit mods to the focused surface by omitting the window target,
-- so universal clipboard shortcuts reach both normal windows and focused
-- layer-shell surfaces such as Blob panels. A virtual keyboard (wtype) won't
-- do: the physically held SUPER merges into the injected chord at the seat.
-- The down/up split works around Hyprland send_shortcut sometimes leaving
-- synthetic key state stuck/repeating.
-- https://github.com/hyprwm/Hyprland/discussions/14099
local function send_shortcut_once(mods, key)
return function()
hl.dispatch(hl.dsp.send_key_state({ mods = mods, key = key, state = "down" }))
hl.timer(function()
hl.dispatch(hl.dsp.send_key_state({ mods = mods, key = key, state = "up" }))
end, { timeout = 50, type = "oneshot" })
end
end
-- Lean on the terminal tag from default/hypr/apps/terminals.lua so there's one
-- definition of what counts as a terminal. Dynamic tags carry a trailing "*".
local function active_window_is_terminal()
local window = hl.get_active_window()
if not window then
return false
end
for _, tag in ipairs(window.tags or {}) do
if tag:gsub("%*$", "") == "terminal" then
return true
end
end
return false
end
local function universal_clipboard_shortcut(default_mods, default_key, terminal_mods, terminal_key)
return function()
if active_window_is_terminal() then
send_shortcut_once(terminal_mods, terminal_key)()
else
send_shortcut_once(default_mods, default_key)()
end
end
end
o.bind("SUPER + C", "Universal copy", universal_clipboard_shortcut("CTRL", "C", "CTRL", "Insert"))
o.bind("SUPER + V", "Universal paste", universal_clipboard_shortcut("CTRL", "V", "SHIFT", "Insert"))
o.bind("SUPER + X", "Universal cut", send_shortcut_once("CTRL", "X"))
o.bind("SUPER + CTRL + V", "Clipboard manager", "blob-shell shell toggle blob.clipboard")
+34
View File
@@ -0,0 +1,34 @@
-- Volume, brightness, keyboard backlight, and touchpad controls.
o.bind("XF86AudioRaiseVolume", "Volume up", "blob-audio-volume raise", { locked = true, repeating = true })
o.bind("XF86AudioLowerVolume", "Volume down", "blob-audio-volume lower", { locked = true, repeating = true })
o.bind("XF86AudioMute", "Mute", "blob-audio-volume mute-toggle", { locked = true })
o.bind("XF86AudioMicMute", "Mute microphone", "blob-audio-input-mute", { locked = true })
o.bind("XF86MonBrightnessUp", "Brightness up", "blob-brightness-display +5%", { locked = true, repeating = true })
o.bind("XF86MonBrightnessDown", "Brightness down", "blob-brightness-display 5%-", { locked = true, repeating = true })
o.bind("SHIFT + XF86MonBrightnessUp", "Brightness maximum", "blob-brightness-display 100%", { locked = true, repeating = true })
o.bind("SHIFT + XF86MonBrightnessDown", "Brightness minimum", "blob-brightness-display 1%", { locked = true, repeating = true })
o.bind("XF86KbdBrightnessUp", "Keyboard brightness up", "blob-brightness-keyboard up", { locked = true, repeating = true })
o.bind("XF86KbdBrightnessDown", "Keyboard brightness down", "blob-brightness-keyboard down", { locked = true, repeating = true })
o.bind("XF86KbdLightOnOff", "Keyboard backlight cycle", "blob-brightness-keyboard cycle", { locked = true })
o.bind_toggle("XF86TouchpadToggle", "Toggle touchpad", "touchpad", { locked = true })
o.bind("XF86TouchpadOn", "Enable touchpad", "blob-toggle-touchpad on", { locked = true })
o.bind("XF86TouchpadOff", "Disable touchpad", "blob-toggle-touchpad off", { locked = true })
-- Precise volume and brightness controls.
o.bind("ALT + XF86AudioRaiseVolume", "Volume up precise", "blob-audio-volume +1", { locked = true, repeating = true })
o.bind("ALT + XF86AudioLowerVolume", "Volume down precise", "blob-audio-volume -1", { locked = true, repeating = true })
o.bind("ALT + XF86MonBrightnessUp", "Brightness up precise", "blob-brightness-display +1%", { locked = true, repeating = true })
o.bind("ALT + XF86MonBrightnessDown", "Brightness down precise", "blob-brightness-display 1%-", { locked = true, repeating = true })
-- Media controls.
o.bind("XF86AudioNext", "Next track", "blob-shell media next", { locked = true })
o.bind("ALT + XF86AudioPlay", "Next track", "blob-shell media next", { locked = true })
o.bind("XF86AudioPause", "Pause", "blob-shell media playPause", { locked = true })
o.bind("XF86AudioPlay", "Play", "blob-shell media playPause", { locked = true })
o.bind("XF86AudioPrev", "Previous track", "blob-shell media previous", { locked = true })
o.bind("ALT + SHIFT + XF86AudioPlay", "Previous track", "blob-shell media previous", { locked = true })
o.bind("XF86Eject", "Eject media", "eject", { locked = true })
o.bind("SHIFT + XF86AudioMute", "Switch audio output", "blob-audio-sink-switch", { locked = true })
o.bind("SHIFT + XF86AudioPause", "Switch media source", "blob-audio-source-switch", { locked = true })
o.bind("SHIFT + XF86AudioPlay", "Switch media source", "blob-audio-source-switch", { locked = true })
+95
View File
@@ -0,0 +1,95 @@
o.bind("SUPER + W", "Close window", hl.dsp.window.close())
o.bind("CTRL + ALT + DELETE", "Close all windows", "blob-hypr-window-close-all")
o.bind("SUPER + J", "Toggle window split", hl.dsp.layout("togglesplit"))
o.bind("SUPER + P", "Pseudo window", hl.dsp.window.pseudo())
o.bind("SUPER + T", "Toggle window floating/tiling", hl.dsp.window.float({ action = "toggle" }))
o.bind("SUPER + F", "Full screen", hl.dsp.window.fullscreen({ mode = "fullscreen" }))
o.bind("SUPER + CTRL + F", "Tiled full screen", "blob-hypr-window-tiled-fullscreen-toggle")
o.bind("SUPER + ALT + F", "Full width", hl.dsp.window.fullscreen({ mode = "maximized" }))
o.bind("SUPER + O", "Pop window out (float & pin)", "blob-hypr-window-pop")
o.bind("SUPER + ALT + Home", "Save window width", "blob-hypr-window-width save")
o.bind("SUPER + Home", "Restore window width", "blob-hypr-window-width restore")
o.bind("SUPER + L", "Toggle workspace layout", "blob-hypr-workspace-layout-toggle")
o.bind("SUPER + LEFT", "Focus on left window", hl.dsp.focus({ direction = "l" }))
o.bind("SUPER + RIGHT", "Focus on right window", hl.dsp.focus({ direction = "r" }))
o.bind("SUPER + UP", "Focus on above window", hl.dsp.focus({ direction = "u" }))
o.bind("SUPER + DOWN", "Focus on below window", hl.dsp.focus({ direction = "d" }))
for workspace = 1, 10 do
local key = "code:" .. tostring(workspace + 9)
o.bind("SUPER + " .. key, "Switch to workspace " .. workspace, hl.dsp.focus({ workspace = tostring(workspace) }))
o.bind("SUPER + SHIFT + " .. key, "Move window to workspace " .. workspace, hl.dsp.window.move({ workspace = tostring(workspace) }))
o.bind("SUPER + SHIFT + ALT + " .. key, "Move window silently to workspace " .. workspace, hl.dsp.window.move({ workspace = tostring(workspace), follow = false }))
end
o.bind("SUPER + S", "Toggle scratchpad", hl.dsp.workspace.toggle_special("scratchpad"))
o.bind("SUPER + ALT + S", "Move window to scratchpad", hl.dsp.window.move({ workspace = "special:scratchpad", follow = false }))
o.bind("SUPER + TAB", "Next workspace", hl.dsp.focus({ workspace = "e+1" }))
o.bind("SUPER + SHIFT + TAB", "Previous workspace", hl.dsp.focus({ workspace = "e-1" }))
o.bind("SUPER + CTRL + TAB", "Former workspace", hl.dsp.focus({ workspace = "previous" }))
o.bind("SUPER + SHIFT + ALT + LEFT", "Move workspace to left monitor", hl.dsp.workspace.move({ monitor = "l" }))
o.bind("SUPER + SHIFT + ALT + RIGHT", "Move workspace to right monitor", hl.dsp.workspace.move({ monitor = "r" }))
o.bind("SUPER + SHIFT + ALT + UP", "Move workspace to up monitor", hl.dsp.workspace.move({ monitor = "u" }))
o.bind("SUPER + SHIFT + ALT + DOWN", "Move workspace to down monitor", hl.dsp.workspace.move({ monitor = "d" }))
o.bind("SUPER + SHIFT + LEFT", "Swap window to the left", hl.dsp.window.swap({ direction = "l" }))
o.bind("SUPER + SHIFT + RIGHT", "Swap window to the right", hl.dsp.window.swap({ direction = "r" }))
o.bind("SUPER + SHIFT + UP", "Swap window up", hl.dsp.window.swap({ direction = "u" }))
o.bind("SUPER + SHIFT + DOWN", "Swap window down", hl.dsp.window.swap({ direction = "d" }))
o.bind("ALT + TAB", "Focus on next window", hl.dsp.window.cycle_next())
o.bind("ALT + SHIFT + TAB", "Focus on previous window", hl.dsp.window.cycle_next({ next = false }))
o.bind("ALT + TAB", "Reveal active window on top", hl.dsp.window.bring_to_top())
o.bind("ALT + SHIFT + TAB", "Reveal active window on top", hl.dsp.window.bring_to_top())
o.bind("CTRL + ALT + TAB", "Focus on next monitor", hl.dsp.focus({ monitor = "+1" }))
o.bind("CTRL + ALT + SHIFT + TAB", "Focus on previous monitor", hl.dsp.focus({ monitor = "-1" }))
o.bind("SUPER + code:20", "Expand window left", hl.dsp.window.resize({ x = -100, y = 0, relative = true }))
o.bind("SUPER + code:21", "Shrink window left", hl.dsp.window.resize({ x = 100, y = 0, relative = true }))
o.bind("SUPER + SHIFT + code:20", "Shrink window up", hl.dsp.window.resize({ x = 0, y = -100, relative = true }))
o.bind("SUPER + SHIFT + code:21", "Expand window down", hl.dsp.window.resize({ x = 0, y = 100, relative = true }))
o.bind("SUPER + ALT + code:20", "Expand window left a little", hl.dsp.window.resize({ x = -25, y = 0, relative = true }))
o.bind("SUPER + ALT + code:21", "Shrink window left a little", hl.dsp.window.resize({ x = 25, y = 0, relative = true }))
o.bind("SUPER + SHIFT + ALT + code:20", "Shrink window up a little", hl.dsp.window.resize({ x = 0, y = -25, relative = true }))
o.bind("SUPER + SHIFT + ALT + code:21", "Expand window down a little", hl.dsp.window.resize({ x = 0, y = 25, relative = true }))
o.bind("SUPER + CTRL + code:20", "Expand window left a lot", hl.dsp.window.resize({ x = -300, y = 0, relative = true }))
o.bind("SUPER + CTRL + code:21", "Shrink window left a lot", hl.dsp.window.resize({ x = 300, y = 0, relative = true }))
o.bind("SUPER + CTRL + SHIFT + code:20", "Shrink window up a lot", hl.dsp.window.resize({ x = 0, y = -300, relative = true }))
o.bind("SUPER + CTRL + SHIFT + code:21", "Expand window down a lot", hl.dsp.window.resize({ x = 0, y = 300, relative = true }))
o.bind("SUPER + mouse_down", "Scroll active workspace forward", hl.dsp.focus({ workspace = "e+1" }))
o.bind("SUPER + mouse_up", "Scroll active workspace backward", hl.dsp.focus({ workspace = "e-1" }))
o.bind("SUPER + mouse:272", "Move window", hl.dsp.window.drag(), { mouse = true })
o.bind("SUPER + mouse:273", "Resize window", hl.dsp.window.resize(), { mouse = true })
o.bind("SUPER + G", "Toggle window grouping", hl.dsp.group.toggle())
o.bind("SUPER + ALT + G", "Move active window out of group", hl.dsp.window.move({ out_of_group = true }))
o.bind("SUPER + ALT + LEFT", "Move window to group on left", hl.dsp.window.move({ into_group = "l" }))
o.bind("SUPER + ALT + RIGHT", "Move window to group on right", hl.dsp.window.move({ into_group = "r" }))
o.bind("SUPER + ALT + UP", "Move window to group on top", hl.dsp.window.move({ into_group = "u" }))
o.bind("SUPER + ALT + DOWN", "Move window to group on bottom", hl.dsp.window.move({ into_group = "d" }))
o.bind("SUPER + ALT + TAB", "Next window in group", hl.dsp.group.next())
o.bind("SUPER + ALT + SHIFT + TAB", "Previous window in group", hl.dsp.group.prev())
o.bind("SUPER + CTRL + LEFT", "Move grouped window focus left", hl.dsp.group.prev())
o.bind("SUPER + CTRL + RIGHT", "Move grouped window focus right", hl.dsp.group.next())
o.bind("SUPER + ALT + mouse_down", "Next window in group", hl.dsp.group.next())
o.bind("SUPER + ALT + mouse_up", "Previous window in group", hl.dsp.group.prev())
for index = 1, 5 do
o.bind("SUPER + ALT + code:" .. tostring(index + 9), "Switch to group window " .. index, hl.dsp.group.active({ index = index }))
end
o.bind("SUPER + SLASH", "Monitor scaling up", "blob-hypr-monitor-scaling up")
o.bind("SUPER + ALT + SLASH", "Monitor scaling down", "blob-hypr-monitor-scaling down")
+121
View File
@@ -0,0 +1,121 @@
o.bind("SUPER + SPACE", "Blob menu", "blob-menu toggle")
o.bind("SUPER + ALT + SPACE", "Apps menu", "blob-menu toggle apps")
o.bind("SUPER + CTRL + E", "Emojis", "blob-shell shell toggle blob.emojis")
o.bind("SUPER + CTRL + C", "Capture menu", "blob-menu toggle capture")
o.bind("SUPER + CTRL + O", "Toggle menu", "blob-menu toggle toggle")
o.bind("SUPER + CTRL + H", "Hardware menu", "blob-menu toggle hardware")
o.bind("SUPER + SHIFT + code:201", "Blob menu", "blob-menu toggle root")
o.bind("SUPER + ESCAPE", "System menu", "blob-menu toggle system")
o.bind("XF86PowerOff", "Power menu", "blob-menu toggle system", { locked = true })
o.bind("SUPER + K", "Keybindings", "blob-menu-keybindings")
o.bind_toggle("SUPER + SHIFT + SPACE", "Toggle top bar", "bar")
o.bind("SUPER + CTRL + SPACE", "Background switcher", "blob-menu toggle background")
o.bind("SUPER + SHIFT + CTRL + SPACE", "Theme menu", "blob-menu toggle theme")
o.bind("SUPER + BACKSPACE", "Toggle window transparency", "blob-hypr-window-transparency-toggle")
o.bind("SUPER + SHIFT + BACKSPACE", "Toggle window gaps", "blob-hypr-window-gaps-toggle")
o.bind("SUPER + CTRL + BACKSPACE", "Toggle single-window square aspect", "blob-hypr-window-single-square-aspect-toggle")
-- xkbcommon names the comma keysym "comma"; the upper-case "COMMA" does not match.
o.bind("SUPER + comma", "Dismiss last notification", "blob-shell notifications dismissOne")
o.bind("SUPER + SHIFT + comma", "Dismiss all notifications", "blob-shell notifications dismissAll")
o.bind_toggle("SUPER + CTRL + comma", "Toggle silencing notifications", "notification-silencing")
o.bind("SUPER + ALT + comma", "Invoke last notification", "blob-shell notifications invokeLast")
o.bind("SUPER + SHIFT + ALT + comma", "Open notification history", "blob-shell notifications showHistory")
o.bind_toggle("SUPER + CTRL + I", "Toggle locking on idle", "idle")
o.bind_toggle("SUPER + CTRL + N", "Toggle nightlight", "nightlight")
o.bind("SUPER + CTRL + Delete", "Toggle laptop display", "blob-hypr-monitor-internal toggle")
o.bind("SUPER + CTRL + ALT + Delete", "Toggle laptop display mirroring", "blob-hypr-monitor-mirror toggle")
o.bind("switch:on:Lid Switch", nil, "blob-system-lid", { locked = true })
o.bind("switch:off:Lid Switch", nil, "blob-hypr-monitor-clamshell", { locked = true })
o.bind("PRINT", "Screenshot", "blob-capture-screenshot")
o.bind("ALT + PRINT", "Screenrecording", "blob-capture-record --stop-recording || blob-menu toggle trigger.capture.screenrecord")
o.bind("SUPER + ALT + code:34", "Make webcam overlay smaller", "blob-capture-webcam-resize smaller")
o.bind("SUPER + ALT + code:35", "Make webcam overlay larger", "blob-capture-webcam-resize larger")
o.bind("SUPER + PRINT", "Color picker", "pkill hyprpicker || hyprpicker -a")
o.bind("SUPER + CTRL + PRINT", "Extract text (OCR) from screenshot", "blob-capture-text")
-- Keyboard control for the slurp region picker (see blob-capture-region).
-- The binds live exactly as long as a selection layer is on screen (slurp
-- opens one per monitor), so they cannot leak or get stuck.
-- Unbinding by key would take a same-key binding out of the user's own config
-- with it, so each handle is kept and removed individually.
local selection_layers = 0
local selection_binds = {}
hl.on("layer.opened", function(layer)
if layer.namespace == "selection" then
selection_layers = selection_layers + 1
if selection_layers == 1 then
selection_binds = {
hl.bind("RETURN", hl.dsp.exec_cmd("blob-capture-region --take-window"), { description = "Capture highlighted window" }),
hl.bind("CTRL + RETURN", hl.dsp.exec_cmd("blob-capture-region --take-fullscreen"), { description = "Capture entire screen" }),
hl.bind("TAB", hl.dsp.exec_cmd("blob-capture-region --select-window next"), { description = "Select next window to capture" }),
hl.bind("CTRL + TAB", hl.dsp.exec_cmd("blob-capture-region --select-window prev"), { description = "Select previous window to capture" }),
}
for _, direction in ipairs({ "left", "right", "up", "down" }) do
table.insert(
selection_binds,
hl.bind(direction:upper(), hl.dsp.exec_cmd("blob-capture-region --select-window " .. direction), { description = "Select window to capture" })
)
end
end
end
end)
hl.on("layer.closed", function(layer)
if layer.namespace == "selection" and selection_layers > 0 then
selection_layers = selection_layers - 1
if selection_layers == 0 then
for _, keybind in ipairs(selection_binds) do
keybind:unbind()
end
selection_binds = {}
end
end
end)
o.bind("SUPER + CTRL + S", "Share", "blob-menu toggle share")
o.bind("SUPER + CTRL + PERIOD", "Transcode", "blob-transcode")
o.bind("SUPER + CTRL + R", "Set reminder", "blob-menu toggle reminder-set")
o.bind("SUPER + CTRL + ALT + R", "Show reminders", "blob-reminder show")
o.bind("SUPER + SHIFT + CTRL + R", "Clear reminders", "blob-reminder clear")
o.bind("SUPER + CTRL + ALT + T", "Show time", "blob-notification-time")
o.bind("SUPER + CTRL + ALT + B", "Show battery remaining", "blob-notification-battery")
o.bind("SUPER + CTRL + ALT + W", "Toggle weather", "blob-notification-weather")
o.bind("SUPER + CTRL + A", "Audio", "blob-shell shell toggle blob.audio")
o.bind("SUPER + CTRL + B", "Bluetooth", "blob-shell shell toggle blob.bluetooth")
o.bind("SUPER + CTRL + D", "Display", "blob-shell shell toggle blob.monitor")
o.bind("SUPER + CTRL + ALT + D", "Calendar", "blob-shell shell toggle blob.clock")
o.bind("SUPER + CTRL + W", "Network", "blob-shell shell toggle blob.network")
o.bind("SUPER + CTRL + P", "Power", "blob-shell shell toggle blob.power")
o.bind("SUPER + CTRL + T", "Activity", { tui = "btop" })
-- The letters above name a panel; the numbers count them. 1 is the leftmost
-- panel in the bar's right section, and a widget with no panel of its own (the
-- tray) is not counted, so the number matches the icon a user would point at.
-- A bar with fewer panels than this leaves the tail of the range doing nothing.
for panel = 1, 9 do
o.bind(
"SUPER + CTRL + code:" .. tostring(panel + 9),
"Bar panel " .. panel,
"blob-shell -q shell togglePanelAt right " .. panel
)
end
o.bind("SUPER + CTRL + Z", "Zoom in", function()
local zoom = hl.get_config("cursor.zoom_factor") or 1
hl.config({ cursor = { zoom_factor = zoom + 1 } })
end)
o.bind("SUPER + CTRL + ALT + Z", "Reset zoom", function()
hl.config({ cursor = { zoom_factor = 1 } })
end)
o.bind("SUPER + CTRL + L", "Lock system", "blob-system-lock")