Dotfiles/desktopenvs/hyprlua/astal-menu
Amir Alexander Abdelbaki 6631405570 feat(hyprlua): taskbar quad-takeover, columns layout, screen-absolute nav
astal-menu: the taskbar ⤢ toggle now collapses the compact strip and mounts
its workspace/window panel as a takeover overlay covering the 2x2 quads (with
a Back button), instead of a popover/inline reveal. QuadGrid gains a generic
takeover overlay; the menu window coordinates show/hide and resets on close.

hypr: new "Columns" layout (scrolling backend presented as independent columns)
with a menu dropdown to pick orientation — "Left / Right" or "Up / Down" — via a
new dir_labels manifest field. The layout menu now tracks direction dropdowns and
fit switches per-layout, so a second directional layout no longer clobbers the
first.

binds/scripts: focus & window-move keys (hjkl + arrows) route through a new
hypr-nav helper so they stay screen-absolute in the scrolling/columns layouts
(the layout otherwise resolves a perpendicular direction onto "scroll the tape",
rotating the keys with scrolling:direction). Adds explicit cross-monitor binds:
Super+,/. focus prev/next monitor, Super+Shift+,/. move the window there.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SUN7gg6GGfnToghMijLm5Y
2026-07-07 09:28:41 +02:00
..
backend feat(astal-menu): pannable map with night/satellite tiles 2026-07-06 08:59:05 +02:00
lib feat(hyprlua): add astal-menu popup, replacing nwg-dock + nwg-drawer 2026-07-05 00:11:39 +02:00
modules feat(astal-menu): pannable map with night/satellite tiles 2026-07-06 08:59:05 +02:00
services feat(hyprlua): add astal-menu popup, replacing nwg-dock + nwg-drawer 2026-07-05 00:11:39 +02:00
style feat(astal-menu): tabbed workspace-layout selector 2026-07-06 11:59:47 +02:00
ui feat(hyprlua): taskbar quad-takeover, columns layout, screen-absolute nav 2026-07-07 09:28:41 +02:00
.gitignore feat(hyprlua): add astal-menu popup, replacing nwg-dock + nwg-drawer 2026-07-05 00:11:39 +02:00
README.md feat(hyprlua): add astal-menu popup, replacing nwg-dock + nwg-drawer 2026-07-05 00:11:39 +02:00
appservices.py feat(hyprlua): add astal-menu popup, replacing nwg-dock + nwg-drawer 2026-07-05 00:11:39 +02:00
main.py feat(astal-menu): stats line, side-slide flag, drawer pop, tighter buttons 2026-07-06 09:26:37 +02:00
module_base.py feat(hyprlua): add astal-menu popup, replacing nwg-dock + nwg-drawer 2026-07-05 00:11:39 +02:00
paths.py fix(astal-menu): working favourites, 3-day weather, deploy-safe settings 2026-07-05 23:35:23 +02:00
registry.py feat(hyprlua): add astal-menu popup, replacing nwg-dock + nwg-drawer 2026-07-05 00:11:39 +02:00
settings.py fix(astal-menu): working favourites, 3-day weather, deploy-safe settings 2026-07-05 23:35:23 +02:00
theme.py fix(astal-menu): float modules on transparent gaps (beat theme's global bg) 2026-07-05 19:51:54 +02:00
window.py feat(hyprlua): taskbar quad-takeover, columns layout, screen-absolute nav 2026-07-07 09:28:41 +02:00

README.md

astal-menu

A touch-friendly GTK4 popup control centre for the hyprlua desktop, replacing nwg-dock and nwg-drawer. Triggered from the EWW top bar (or Super+D).

Layout: a 2×2 quad grid of feature modules over a full-width application drawer. Any quad can expand to overlay the other three; the drawer can expand to the bottom of the screen. A single margined root box letterboxes the menu identically in every state.

Stack

  • Frontend: Python + PyGObject + GTK4, as a wlr-layer-shell surface (gtk4-layer-shell). Chosen over Lua because lgi/Astal-Lua only support GTK3.
  • Location map: a static OSM image stitched from tiles (backend/staticmap.py, Pillow). libshumate does not paint tiles in this environment (the official shumate-demo shows the same blank map), though tile downloads work — hence the static fallback.
  • Services: Astal GObject libraries via introspection — AstalNetwork, AstalBluetooth, AstalApps — plus our own IP-geolocation singleton.
  • Backends: Python/Bash scripts in backend/ (JSON on stdout), run async via Gio.Subprocess so nothing blocks the UI.
  • Theme: style/_colors.css (@define-color, generated from ~/Dotfiles/colors.conf by apply-theme.sh) + style/style.css.

Running

main.py is single-instance. The autostart launches a hidden resident daemon; verbs are forwarded over D-Bus:

scripts/astal-menu-start.sh          # resident daemon (hidden); sets LD_PRELOAD
scripts/menu-toggle.sh               # --toggle
scripts/menu-toggle.sh appdrawer     # open with the app drawer expanded

astal-menu-start.sh must LD_PRELOAD libgtk4-layer-shell (it loads after libwayland under PyGObject otherwise).

Adding a module

  1. Create modules/<name>.py exposing a top-level SPEC = ModuleSpec(...) whose build(ctx) returns a ModuleInstance(compact=…, expanded=…, …).
    • compact shows in the 2×2 cell; a distinct expanded widget enables the expand button (they must be separate instances — GTK widgets have one parent).
    • Declare per-feature toggles via features=[Feature("id", "Label", default)]; read them with ctx.feature("id"). A disabled quad never calls build().
    • Shared state (network, bluetooth, location) is on ctx.services.
  2. Append its SPEC to ALL_SPECS in registry.py. Nothing else changes.

Files

main.py          app + single-instance IPC        window.py    layer-shell + letterbox
registry.py      module list (extension seam)      settings.py  JSON toggles/order
module_base.py   ModuleSpec / ModuleInstance / ModuleContext
appservices.py   shared Astal services + location
ui/              quadcard, quadgrid, appdrawer
modules/         location, weather, bluetooth, network
services/        location (geolocation singleton)
lib/             ansi (SGR→TextTag), proc (async subprocess)
backend/         geolocate.py, weather.sh, network.sh
style/           _colors.css, style.css