fix(hyprlua): columns layout breaks on fresh workspaces, wrap focus u/d

hypr-nav fell back to the raw "lua:columns" backend string on any
workspace that had never been explicitly switched via the menu (i.e.
every fresh workspace, since columns is the global default), which
didn't match the "columns" layout name it checks against — so focus/
move/resize silently took the generic dwindle-style path instead of
being forwarded to the custom layout. Strip the "lua:" prefix in the
fallback.

Also make focus/scroll u/d within a column wrap around instead of
stopping at the ends.
main
Amir Alexander Abdelbaki 2026-07-16 09:01:21 +02:00
parent a24a27fff6
commit c313f0694c
2 changed files with 18 additions and 4 deletions

View File

@ -379,9 +379,14 @@ local function layout_msg(ctx, cmd)
hl.dispatch(hl.dsp.focus({ window = "address:" .. cols[nc][ni] }))
end
else
local ni = fi + (decrease(arg) and -1 or 1)
if cols[fc] and ni >= 1 and ni <= #cols[fc] then
hl.dispatch(hl.dsp.focus({ window = "address:" .. cols[fc][ni] }))
-- within-column step WRAPS at the ends (both keyboard focus u/d and the
-- mouse wheel, which forwards here too — see hypr-nav's scroll case).
local list = cols[fc]
if list and #list > 0 then
local n = #list
local step = decrease(arg) and -1 or 1
local ni = ((fi - 1 + step) % n + n) % n + 1
hl.dispatch(hl.dsp.focus({ window = "address:" .. list[ni] }))
end
end
elseif verb == "move" then

View File

@ -86,8 +86,17 @@ def active_layout_name(wsid) -> str | None:
return name
except (FileNotFoundError, json.JSONDecodeError, TypeError):
pass
# A workspace the user has never explicitly switched via the menu has no entry
# in STATE (write_state()/M.set only fires on a menu pick) — that's every fresh
# workspace at session start, since it's just inheriting the global default. Fall
# back to the raw Hyprland option, which for a custom Lua layout is the "lua:<name>"
# backend string (see layouts/init.lua's M.set_default), not the registry name — strip
# the prefix so this still compares equal to COLUMNS_LAYOUT below.
opt = hypr_json("getoption", "general:layout")
return opt.get("str") if opt else None
raw = opt.get("str") if opt else None
if raw and raw.startswith("lua:"):
return raw[len("lua:"):]
return raw
def tape_axis() -> str: