From c313f0694c59b944dac36d34130502c89fb5fb5e Mon Sep 17 00:00:00 2001 From: The_miro Date: Thu, 16 Jul 2026 09:01:21 +0200 Subject: [PATCH] fix(hyprlua): columns layout breaks on fresh workspaces, wrap focus u/d MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- desktopenvs/hyprlua/hypr/layouts/columns.lua | 11 ++++++++--- desktopenvs/hyprlua/scripts/hypr-nav | 11 ++++++++++- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/desktopenvs/hyprlua/hypr/layouts/columns.lua b/desktopenvs/hyprlua/hypr/layouts/columns.lua index 429f3d3..94ba967 100644 --- a/desktopenvs/hyprlua/hypr/layouts/columns.lua +++ b/desktopenvs/hyprlua/hypr/layouts/columns.lua @@ -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 diff --git a/desktopenvs/hyprlua/scripts/hypr-nav b/desktopenvs/hyprlua/scripts/hypr-nav index 886e934..1abdc56 100755 --- a/desktopenvs/hyprlua/scripts/hypr-nav +++ b/desktopenvs/hyprlua/scripts/hypr-nav @@ -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:" + # 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: