Files
omarchycn/default/hypr/helpers.lua
T
David Heinemeier HanssonandClaude Opus 5 0965ac2e4f Fix o.shell_succeeds() always returning false inside Hyprland
Hyprland reaps its own children, so os.execute() gets ECHILD from waitpid and
never sees an exit status. Every call reported failure, which meant the NVIDIA
env detection in hypr/nvidia.lua never set NVD_BACKEND, LIBVA_DRIVER_NAME or
__GLX_VENDOR_LIBRARY_NAME. Read a marker off stdout instead.

Closes #6914

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-15 07:12:25 -07:00

155 lines
3.6 KiB
Lua

-- Shared helpers for Hyprland Lua configuration.
o = o or {}
local function shell_quote(value)
return "'" .. tostring(value):gsub("'", "'\\''") .. "'"
end
o.shell_quote = shell_quote
local function file_exists(path)
local file = io.open(path, "r")
if file then
file:close()
return true
end
return false
end
-- Hyprland reaps its own children, so os.execute() can't retrieve an exit status
-- from inside the compositor. Read a marker off stdout instead.
function o.shell_succeeds(command)
-- Subshell, so the redirection covers every command rather than binding to
-- the last one and letting an earlier one write its own OK into the pipe.
local pipe = io.popen("( " .. command .. " ) >/dev/null 2>&1 && echo OK")
if not pipe then
return false
end
local output = pipe:read("*a") or ""
pipe:close()
return output:find("OK", 1, true) ~= nil
end
function o.cmd_present(command)
if command:find("/", 1, true) then
return file_exists(command)
end
local path = os.getenv("PATH") or "/usr/local/bin:/usr/bin"
for directory in (path .. ":"):gmatch("([^:]*):") do
if file_exists((directory ~= "" and directory or ".") .. "/" .. command) then
return true
end
end
return false
end
function o.cmd_missing(command)
return not o.cmd_present(command)
end
local function command_from(value, description)
if type(value) ~= "table" then
return value
end
if value.omarchy then
return "omarchy-launch-" .. value.omarchy
elseif value.focus and value.launch then
return o.launch_sole(value.focus, value.launch)
elseif value.launch then
return o.launch(value.launch)
elseif value.webapp then
if value.focus then
return o.launch_webapp_sole(description, value.webapp)
else
return o.launch_webapp(value.webapp)
end
elseif value.tui then
if value.focus then
return "omarchy-launch-or-focus-tui " .. shell_quote(value.tui)
else
return "omarchy-launch-tui " .. shell_quote(value.tui)
end
end
return value
end
function o.preinstalled_bindings_enabled()
if _G.omarchy_preinstalled_bindings ~= nil then
return _G.omarchy_preinstalled_bindings == true
end
return not file_exists((os.getenv("HOME") or "") .. "/.local/state/omarchy/preinstalls-removed")
end
function o.bind(keys, description, dispatcher, options)
local opts = options or {}
if description then
opts.description = description
end
dispatcher = command_from(dispatcher, description)
if type(dispatcher) == "string" then
dispatcher = hl.dsp.exec_cmd(dispatcher)
end
hl.bind(keys, dispatcher, opts)
end
function o.launch(command)
return "uwsm-app -- " .. command
end
function o.exec_on_start(command)
hl.on("hyprland.start", function()
hl.exec_cmd(command)
end)
end
function o.launch_on_start(command)
o.exec_on_start(o.launch(command))
end
function o.launch_webapp(url)
return "omarchy-launch-webapp " .. shell_quote(url)
end
function o.launch_webapp_sole(name, url)
return "omarchy-launch-or-focus-webapp " .. shell_quote(name) .. " " .. shell_quote(url)
end
function o.launch_sole(match, command)
return "omarchy-launch-or-focus " .. shell_quote(match) .. " " .. shell_quote(o.launch(command))
end
function o.bind_toggle(keys, description, toggle, options)
o.bind(keys, description, "omarchy-toggle-" .. toggle, options)
end
function o.notify(message)
return "notify-send -u low " .. shell_quote(message)
end
function o.window(match, rules)
rules.match = rules.match or {}
if type(match) == "string" then
rules.match.class = match
else
for key, value in pairs(match) do
rules.match[key] = value
end
end
hl.window_rule(rules)
end