Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Mjoyufull/layerstacked

Repository files navigation

layerstacked

Lua helpers for stacked named special workspaces on Hyprland: multiple layers per numeric workspace (special:sp4_1, special:sp4_2, …) instead of a single .

made to satifsy this random idea "i have seen the vision, a infront scrollin window manager you have your regular workspaces but you can open infinite amounts of topworkspaces on top of the current one by adding a mod key to switch to a specific later depending on the active workspace say your on active workspace 8 but you want to go on toped workspace 6 so you hit super+shift+6 and boom your now ontop of your current workspace 6 top workspaces removed"

Requirements

  • Hyprland
  • hyprctl on PATH
  • jq
  • Lua 5.1+ (5.3/5.4 recommended) as lua

Install

Copy or symlink this directory somewhere stable, shi idk e.g.:

mkdir -p ~/.config/hypr/scripts
cp -r layerstacked ~/.config/hypr/scripts/
# or
ln -s /path/to/repo/layerstacked ~/.config/hypr/scripts/layerstacked

Scripts resolve hypr.lua / state.lua from their own directory, so keep the folder intact.

State file

  • Path: $XDG_STATE_HOME/hypr_layerstack/state.lua, or
    ~/.local/state/hypr_layerstack/state.lua if XDG_STATE_HOME is unset.
  • Holds stack (last viewed depth per base workspace id; kept when you close the overlay so toggle_layer reopens the same depth) and window_home (per-window return targets for toggle_window.lua).

Hyprland options (recommended)

Option Suggested Why
binds:hide_special_on_workspace_change true Stops specials from following you when you change workspace with Super+1 etc.
misc:close_special_on_empty false Empty layers stay defined; you open them with binds anyway.

Scripts

Script Arguments What it does
toggle_layer.lua On a layer → workspace <base> to drop overlay; on base → workspace special:…. Same workspace dispatcher approach as navigate.lua.
toggle_window.lua On a layer → move window to base and remember sp… in window_home. On base with memory → restore. On base without memory → send to sp{base}_{stack[base] or 1}.
navigate.lua up | down | deeper | shallower | <n> Change view via workspace special:… / workspace <id> (not togglespecialworkspace; see README section below). Prefer deeper / shallower if up / down keys misbind.
send_to_layer.lua <n> movetoworkspacesilent special:sp{base}_{n}. Optional follow — edit FOLLOW_AFTER_SEND at top of the file.
send_up_down.lua up | down On a layer → move window one level up/down. On base (normal workspace) → up sends to sp{base}_{stack[base] or 1}; down no-op.

Naming: layers use special:sp{workspace_id}_{depth} (e.g. base workspace 4, layer 2special:sp4_2).
hyprctl dispatch togglespecialworkspace takes the short name (sp4_2).
movetoworkspace / movetoworkspacesilent use the full special:sp4_2 form.

Run from the shell

Use the directory that contains the .lua files (adjust the path):

L=~/.config/hypr/scripts/layerstacked

lua "$L/navigate.lua" up
lua "$L/navigate.lua" down
lua "$L/navigate.lua" deeper
lua "$L/navigate.lua" shallower
lua "$L/navigate.lua" 3

lua "$L/toggle_layer.lua"
lua "$L/toggle_window.lua"

lua "$L/send_to_layer.lua" 2
lua "$L/send_up_down.lua" up
lua "$L/send_up_down.lua" down

Executable bit + shebang:

chmod +x "$L"/*.lua
"$L/toggle_layer.lua"

Hyprland bind = example

Set L to your real path (no trailing slash required if you use …/layerstacked/toggle_layer.lua).

$L = ~/.config/hypr/scripts/layerstacked

# Same muscle memory as a simple scratch: view toggle + window stash
bind = $mod, S, exec, lua $L/toggle_layer.lua
bind = $mod SHIFT, S, exec, lua $L/toggle_window.lua

# Navigate view — prefer deeper/shallower if up/down binds are ignored (Hypr key-name quirk)
bind = $mod CTRL, bracketright, exec, lua $L/navigate.lua up
bind = $mod CTRL, bracketleft, exec, lua $L/navigate.lua down
# bind = $mod CTRL, up, exec, lua $L/navigate.lua up
# bind = $mod CTRL, down, exec, lua $L/navigate.lua down
bind = $mod CTRL, 1, exec, lua $L/navigate.lua 1
bind = $mod CTRL, 2, exec, lua $L/navigate.lua 2
bind = $mod CTRL, 3, exec, lua $L/navigate.lua 3

# Send focused window to layer n (silent unless you enable FOLLOW_AFTER_SEND)
bind = $mod CTRL SHIFT, 1, exec, lua $L/send_to_layer.lua 1
bind = $mod CTRL SHIFT, 2, exec, lua $L/send_to_layer.lua 2

# Nudge window between layers all the way down to base
bind = $mod ALT, bracketleft, exec, lua $L/send_up_down.lua down
bind = $mod ALT, bracketright, exec, lua $L/send_up_down.lua up

With uwsm (wrap only if you need the systemd session env):

bind = $mod, S, exec, uwsm app -- lua ~/.config/hypr/scripts/layerstacked/toggle_layer.lua

Follow the window after send_to_layer

Edit send_to_layer.lua:

local FOLLOW_AFTER_SEND = true

Then a dispatch also runs togglespecialworkspace sp{base}_{n} so your view jumps to that layer.

Sanity check (optional)

hyprctl dispatch togglespecialworkspace sp999test
hyprctl dispatch togglespecialworkspace sp999test2
hyprctl activewindow -j | jq -r '.workspace.name'   # expect special:sp999test2

Why navigation uses workspace, not togglespecialworkspace

Hyprland’s togglespecialworkspace closes the special if that exact special is already the active one on the monitor. So “go deeper” from layer 1 with wrong depth detection, or any re-dispatch of the same name, looks like a toggle off instead of staying open or stepping to another layer.

navigate.lua and toggle_layer.lua therefore use hyprctl dispatch workspace special:sp{n}_{d} to switch layers (Hyprland calls setSpecialWorkspace — swap without that toggle bug) and workspace <base_id> to drop back to the numeric base workspace (works with binds:hide_special_on_workspace_change).

Why view toggles read the monitor, not the active window

View toggles and navigation resolve from the focused monitor’s specialWorkspace.name and active workspace in hyprctl monitors -j, not from activewindow.workspace.*.

If they used activewindow, a fast cross-monitor switch can still leave the previously focused window as Hyprland’s active window for a moment. Then a view-only bind like toggle_layer.lua can reopen sp5_2 on the newly focused monitor while you are already on workspace 3 there.

Window-moving scripts still use the active window where that is the correct subject.

Limit

Hyprland allows at most 97 named special workspaces at once — stay within that for total sp* names in use.

About

Lua helpers for **stacked named special workspaces** on Hyprland: multiple layers per numeric workspace (`special:sp4_1`, `special:sp4_2`, …) instead of a single .

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages