Omarchy never sets XCURSOR_THEME, so asking GSettings on every cold boot replaced the "default" alias with whatever GSettings held, which is the schema default Adwaita when nothing was ever set. That overrode a theme chosen through ~/.icons/default and exported the substitute to every application. The saved theme and GSettings are now consulted only when recovering from the blank startup theme or an interrupted reveal. Co-Authored-By: Codex XHigh <codex@openai.com>
100 lines
4.6 KiB
Lua
100 lines
4.6 KiB
Lua
local function cursor_theme(value)
|
|
if value and value ~= "" and value ~= "omarchy-startup" then return value end
|
|
end
|
|
|
|
local function normal_theme(interrupted)
|
|
local current = os.getenv("XCURSOR_THEME")
|
|
local theme = cursor_theme(current)
|
|
-- Only a lost preference needs recovering; an unset theme still means the default alias.
|
|
if theme or not (interrupted or current == "omarchy-startup") then return theme or "default" end
|
|
theme = cursor_theme(os.getenv("OMARCHY_STARTUP_CURSOR_THEME"))
|
|
if theme then return theme end
|
|
local pipe = io.popen("gsettings get org.gnome.desktop.interface cursor-theme 2>/dev/null", "r")
|
|
if pipe then
|
|
theme = cursor_theme((pipe:read("*a") or ""):match("^'(.-)'%s*$"))
|
|
pipe:close()
|
|
end
|
|
return theme or "default"
|
|
end
|
|
|
|
local function normal_path()
|
|
local kept = {}
|
|
for entry in (os.getenv("XCURSOR_PATH") or "~/.local/share/icons:~/.icons:/usr/share/icons:/usr/share/pixmaps"):gmatch("[^:]+") do
|
|
if not entry:match("/default/hypr/cursors$") then table.insert(kept, entry) end
|
|
end
|
|
return table.concat(kept, ":")
|
|
end
|
|
|
|
-- Hyprland polls cursor.invisible, so its first frames need a blank cursor too.
|
|
function omarchy_startup_cursor_restore(loaded)
|
|
if not omarchy_startup_cursor_pending then return end
|
|
local cursor = omarchy_startup_cursor
|
|
if loaded then
|
|
omarchy_startup_cursor_pending = false
|
|
hl.env("OMARCHY_STARTUP_CURSOR_SESSION", "")
|
|
hl.env("OMARCHY_STARTUP_CURSOR_THEME", "")
|
|
hl.config({ cursor = cursor.config })
|
|
if cursor.config.enable_hyprcursor and cursor.hyprcursor then
|
|
hl.exec_cmd("hyprctl setcursor " .. o.shell_quote(cursor.hyprcursor) .. " " .. cursor.size)
|
|
end
|
|
elseif not cursor.restoring then
|
|
-- Reload the normal Xcursor fallback before enabling Hyprcursor or GSettings.
|
|
cursor.restoring = true
|
|
hl.env("XCURSOR_PATH", cursor.path)
|
|
hl.env("XCURSOR_THEME", cursor.xcursor)
|
|
hl.exec_cmd("dbus-update-activation-environment --systemd XCURSOR_PATH XCURSOR_THEME")
|
|
local complete = "if omarchy_startup_cursor and omarchy_startup_cursor.xcursor == " .. string.format("%q", cursor.xcursor)
|
|
.. " and omarchy_startup_cursor.size == " .. cursor.size .. " then omarchy_startup_cursor_restore(true) end"
|
|
hl.exec_cmd("hyprctl setcursor " .. o.shell_quote(cursor.xcursor) .. " " .. cursor.size
|
|
.. " && hyprctl eval " .. o.shell_quote(complete))
|
|
end
|
|
end
|
|
|
|
hl.on("config.reloaded", function()
|
|
local recover = false
|
|
if omarchy_startup_cursor_pending == nil then
|
|
-- An ordinary reload must not hide the pointer, but an interrupted reveal survives.
|
|
local cold = #hl.get_monitors() == 0
|
|
local session = os.getenv("HYPRLAND_INSTANCE_SIGNATURE")
|
|
local interrupted = session and os.getenv("OMARCHY_STARTUP_CURSOR_SESSION") == session
|
|
recover = not cold and not interrupted and os.getenv("XCURSOR_THEME") == "omarchy-startup"
|
|
omarchy_startup_cursor_pending = cold or interrupted or recover
|
|
if omarchy_startup_cursor_pending then
|
|
local hyprcursor = hl.get_config("cursor.enable_hyprcursor")
|
|
omarchy_startup_cursor = {
|
|
config = {
|
|
invisible = hl.get_config("cursor.invisible"),
|
|
enable_hyprcursor = hyprcursor,
|
|
sync_gsettings_theme = hl.get_config("cursor.sync_gsettings_theme"),
|
|
},
|
|
hyprcursor = os.getenv("HYPRCURSOR_THEME"),
|
|
size = tonumber((hyprcursor and os.getenv("HYPRCURSOR_SIZE")) or os.getenv("XCURSOR_SIZE")) or 24,
|
|
path = normal_path(),
|
|
xcursor = normal_theme(interrupted),
|
|
}
|
|
if omarchy_startup_cursor.size <= 0 then omarchy_startup_cursor.size = 24 end
|
|
-- Compositor environment survives Lua reloads; a session id prevents stale inheritance.
|
|
hl.env("OMARCHY_STARTUP_CURSOR_THEME", omarchy_startup_cursor.xcursor)
|
|
hl.env("OMARCHY_STARTUP_CURSOR_SESSION", os.getenv("HYPRLAND_INSTANCE_SIGNATURE"))
|
|
if cold then
|
|
hl.env("XCURSOR_PATH", os.getenv("OMARCHY_PATH") .. "/default/hypr/cursors:" .. omarchy_startup_cursor.path)
|
|
hl.env("XCURSOR_THEME", "omarchy-startup")
|
|
else
|
|
hl.env("XCURSOR_PATH", omarchy_startup_cursor.path)
|
|
hl.env("XCURSOR_THEME", omarchy_startup_cursor.xcursor)
|
|
end
|
|
end
|
|
end
|
|
if omarchy_startup_cursor_pending then
|
|
-- Keep the temporary cursor private to the compositor, including GSettings.
|
|
hl.config({ cursor = { invisible = true, enable_hyprcursor = false, sync_gsettings_theme = false } })
|
|
hl.timer(function()
|
|
if omarchy_startup_cursor_pending then
|
|
omarchy_startup_cursor.restoring = false
|
|
omarchy_startup_cursor_restore()
|
|
end
|
|
end, { timeout = 15000, type = "oneshot" })
|
|
if recover then omarchy_startup_cursor_restore() end
|
|
end
|
|
end)
|