From 1d352685ba1f9201ab6cd438e1d7f760fce20105 Mon Sep 17 00:00:00 2001 From: Ivan Malison Date: Thu, 2 Jul 2026 22:05:44 -0700 Subject: [PATCH] hypr: use nstack auto_stacks so new windows always get their own column The columns layout previously relied on a 25ms-delayed 'setstackcount ' dispatch from lua window events, which missed cases like float->tile toggles (no event fires) and dispatch routing to the wrong workspace, leaving a stale stack count and tiling new windows into an existing column. The nstack plugin now sizes stacks to the window count natively (auto_stacks); the lua path keeps the numeric dispatch for the grid layout and falls back to it when an older plugin build is loaded. Bumps hyprNStack to 2ba62ce (auto_stacks support). Co-Authored-By: Claude Fable 5 --- dotfiles/config/hypr/hyprland/core.lua | 39 +++++++++++++++-------- dotfiles/config/hypr/hyprland/layouts.lua | 7 ++++ nixos/flake.lock | 6 ++-- 3 files changed, 36 insertions(+), 16 deletions(-) diff --git a/dotfiles/config/hypr/hyprland/core.lua b/dotfiles/config/hypr/hyprland/core.lua index b9d391b1..450c5e74 100644 --- a/dotfiles/config/hypr/hyprland/core.lua +++ b/dotfiles/config/hypr/hyprland/core.lua @@ -171,27 +171,39 @@ function M.setup(ctx) end end + -- True when the running hyprNStack build knows the auto_stacks option + -- (old builds crash-parse "setstackcount auto", so callers must gate on this). + local function nstack_supports_auto_stacks() + return hl.get_config("plugin.nstack.layout.auto_stacks") ~= nil + end + local function apply_nstack_config() if verify_config or not enable_nstack or not configure_nstack_plugin_from_lua then return end + local layout = { + orientation = "left", + new_on_top = false, + new_near_focused = true, + new_is_master = false, + no_gaps_when_only = true, + special_scale_factor = 0.8, + inherit_fullscreen = true, + stacks = 1, + center_single_master = false, + mfact = 0.0, + single_mfact = 1.0, + } + + if nstack_supports_auto_stacks() then + layout.auto_stacks = true + end + hl.config({ plugin = { nstack = { - layout = { - orientation = "left", - new_on_top = false, - new_near_focused = true, - new_is_master = false, - no_gaps_when_only = true, - special_scale_factor = 0.8, - inherit_fullscreen = true, - stacks = 1, - center_single_master = false, - mfact = 0.0, - single_mfact = 1.0, - }, + layout = layout, }, }, }) @@ -589,6 +601,7 @@ function M.setup(ctx) ctx.hyprexpo = hyprexpo ctx.hyprwinview = hyprwinview ctx.workspacehistory = workspacehistory + ctx.nstack_supports_auto_stacks = nstack_supports_auto_stacks ctx.apply_nstack_config = apply_nstack_config ctx.apply_hyprexpo_config = apply_hyprexpo_config ctx.apply_hyprwinview_config = apply_hyprwinview_config diff --git a/dotfiles/config/hypr/hyprland/layouts.lua b/dotfiles/config/hypr/hyprland/layouts.lua index d0c8b737..fa7943ff 100644 --- a/dotfiles/config/hypr/hyprland/layouts.lua +++ b/dotfiles/config/hypr/hyprland/layouts.lua @@ -69,6 +69,13 @@ function M.setup(ctx) return end + if current_layout == columns_layout and nstack_supports_auto_stacks() then + -- The plugin sizes stacks to the window count on every recalculation, + -- which also covers paths that fire no window events (e.g. float -> tile). + dispatch(hl.dsp.layout("setstackcount auto")) + return + end + local stack_count = count if current_layout == grid_layout then stack_count = math.ceil(math.sqrt(count)) diff --git a/nixos/flake.lock b/nixos/flake.lock index cd53e217..7e5a4268 100644 --- a/nixos/flake.lock +++ b/nixos/flake.lock @@ -860,11 +860,11 @@ ] }, "locked": { - "lastModified": 1778996094, - "narHash": "sha256-62Xp8TFDrHER1GD5g9c/gvWmD0QsBNxh0OsnHzQIU3M=", + "lastModified": 1783055075, + "narHash": "sha256-FH4KUwZpOQqhd/LGjPgrq0CiWlro/t9h/jBGQnD8fdc=", "owner": "colonelpanic8", "repo": "hyprNStack", - "rev": "1abcbbe76bda28915ab6f76572bef2f6b3364b01", + "rev": "2ba62ce3dcddfe022276163d716bb654c9d7f16d", "type": "github" }, "original": {