Skip to content

feat(converter): align dispatcher + env mappings with Hyprland 0.55 typed Lua API - #7

Merged
EIonTusk merged 1 commit into
masterfrom
feat/typed-lua-api-dispatchers
Jun 1, 2026
Merged

feat(converter): align dispatcher + env mappings with Hyprland 0.55 typed Lua API#7
EIonTusk merged 1 commit into
masterfrom
feat/typed-lua-api-dispatchers

Conversation

@EIonTusk

@EIonTusk EIonTusk commented May 30, 2026

Copy link
Copy Markdown
Owner

Summary

  • Rewrites every legacy hyprlang dispatcher mapping against the official 0.55 wiki and Hyprland source — fixing 15+ dispatchers that were emitting positional args where the typed API requires tables, plus several mis-mapped semantics (killwindowkill not close, swapnextswap not cycle_next, focuscurrentorlastfocus({last=true}), fullscreen_state default action explicitly toggle since 0.55 defaults to set).
  • Drops four polyfills that the typed API covers natively (envdhl.env(K, V, true), execr-oncehl.dispatch(hl.dsp.exec_raw(...)), focusworkspaceoncurrentmonitorfocus({on_current_monitor=true}), loadconfig → inline hyprctl reload closure). Only hl_source_glob remains since require()/dofile() can't glob.
  • Adds the env-var fallback fix (undeclared \$HOME/\$XDG_* survives inside exec strings for /bin/sh to expand; declared \$mainMod still rewrites to a Lua local; non-shell contexts fast-fail on undeclared refs), CSS-shorthand gap parsing into the typed HL.CssGap struct, and submap-block buffering into hl.define_submap("name", function() ... end).

Test plan

  • go test ./... passes (incl. new polyfills_test.go covering each migrated dispatcher with on/off polyfill variants)
  • go vet ./... clean
  • go test ./internal/converter -fuzz FuzzConvert -fuzztime 15s no panics
  • (cd web/wasm && GOOS=js GOARCH=wasm go build -o /tmp/main.wasm .) succeeds
  • go run ./cmd/hyprlang2lua ~/.config/hypr/hyprland.conf | luac -p /dev/stdin produces syntactically valid Lua
  • Load the generated .lua in a Hyprland 0.55 session and confirm bindings behave (only static syntax validated locally; runtime smoke test is the user's call)

…yped Lua API

Rewrites every legacy hyprlang dispatcher mapping against the official
0.55 wiki and Hyprland source (LuaBindingsDispatchers.cpp,
LuaBindingsConfigRules.cpp, KeybindManager.cpp). Earlier passes emitted
positional args where the typed API requires tables, mis-mapped a few
semantics, and used polyfill helpers for features the typed API now
covers natively.

Highlights:

- env / envd: route to hl.env(K, V) and hl.env(K, V, true) — the third
  arg is the dbus boolean per Hyprland source. envd's systemd / D-Bus
  propagation no longer needs a polyfill helper.
- execr-once -> hl.dispatch(hl.dsp.exec_raw(cmd)) (native; previous
  setsid-wrapping polyfill was inverse of exec_raw's "no shell" semantic).
- focusworkspaceoncurrentmonitor -> hl.dsp.focus({on_current_monitor=true})
  (native field; polyfill dropped).
- loadconfig -> inline `function() hl.exec_cmd("hyprctl reload") end`.
- movecurrentworkspacetomonitor -> inline closure resolving the active
  workspace via hl.get_active_workspace().
- 15+ dispatchers moved from positional to typed-table emission:
  signal, signalwindow, setprop, tagwindow, alterzorder, fullscreenstate,
  fakefullscreen, lockactivegroup, lockgroups, denywindowfromgroup,
  changegroupactive (f/b -> next/prev, numeric -> active{index}),
  moveintogroup / moveoutofgroup (window namespace, window selector),
  cyclenext, swapnext (swap, not cycle_next), swapwindow, renameworkspace,
  moveworkspacetomonitor, swapactiveworkspaces, dpms, pass, sendshortcut,
  sendkeystate, movecursor, movecursortocorner, centerwindow.
- New dispatcher mappings: forcekillactive, signalwindow, toggleswallow,
  movewindoworgroup, movegroupwindow, noop, movewindow mon:NAME [silent].
- killwindow now maps to kill (SIGKILL) per 0.54 wiki, not close.
- focuscurrentorlast -> focus({last=true}); no current_or_last field
  exists in 0.55.
- Always emit action="toggle" on fullscreen_state because 0.55's default
  is "set" (verified in Hyprland source) where 0.54's was "toggle".
- set_prop always quotes value as Lua string; the typed API requires a
  string and would reject numeric literals at config load.

Beyond dispatchers:

- CSS-shorthand gap values (`gaps_in = 5 10 15 20`) parse into the typed
  HL.CssGap struct { top, right, bottom, left } per CSS box-shorthand.
  Applies to general.gaps_in/gaps_out/float_gaps and monitorv2 reserved.
- Source globs (`source = path/*.conf`) emit hl_source_glob — the one
  remaining polyfill, since require()/dofile can't glob.
- submap = NAME ... submap = reset buffers contained bind* directives
  and emits hl.define_submap("NAME", function() ... end).
- exec/hyprctl-dispatch rewrites: bind = ..., exec, hyprctl dispatch X
  is detected and routed through the direct hl.dsp.* call.

Undeclared $var handling:

- Two-mode formatter: g.fmtVal (default, fast-fails on undeclared $X by
  emitting a Lua local reference) vs g.fmtShell (preserves $HOME / $XDG_*
  verbatim so /bin/sh expands at runtime). Shell-context callers (exec,
  execr, formatExecCall) use fmtShell; everything else (bind keys, config
  values, dispatcher table fields) uses fmtVal so typos surface as load
  errors instead of silently non-matching binds.

Tests + goldens:

- New polyfills_test.go covers each migrated path with on/off polyfill
  variants where relevant.
- New testdata/05_polyfills.conf fixture exercises every helper + the
  env-var fallback + CSS-shorthand gap path end-to-end (golden + merged
  golden refreshed).
- Golden test's merged case now runs with MergeCalls=true AND
  Polyfill=true to mirror CLI / web-UI production defaults.
- Existing TestModifierCaseNormalization updated to declare \$mainMod
  explicitly (the prior test relied on the now-fixed eager $-rewrite).
- All commit-level dispatcher reshapes verified through luac -p on the
  comprehensive 137-line end-to-end output and a real-world user config
  (304 hyprlang lines -> 336 Lua lines, 100% coverage, 0 flagged).
@EIonTusk
EIonTusk merged commit 958e7eb into master Jun 1, 2026
1 check passed
@EIonTusk
EIonTusk deleted the feat/typed-lua-api-dispatchers branch June 1, 2026 09:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant