Commit Graph

11 Commits (4fe6181a935ff7b607613d6e611db8fbc135660e)

Author SHA1 Message Date
Amir Alexander Abdelbaki 4fe6181a93 made the hw-stats bar taller, so the close button doesn't touch any borders 2026-07-06 10:12:13 +02:00
Amir Alexander Abdelbaki 57dede403e feat(astal-menu): stats line, side-slide flag, drawer pop, tighter buttons
- Add a minimalist system-stats line at the top of the panel: CPU / MEM / GPU / disk
  utilisation + network down/up rate, read straight from /proc and /sys on a 2s timer
  (no subprocess). ui/statsbar.py.
- Opening side is selectable: `main.py --side top|bottom|left|right` (also via
  `menu-toggle.sh <verb> <side>` or just `menu-toggle.sh <side>`). The panel anchors
  flush to that edge, and the compositor's layer slide brings it in from there.
  Unified all layer anchoring into MenuWindow._apply_anchor.
- App drawer now does a bouncy pop-expand (CSS scale, play-once guard like the quads).
- Tighten the action-pill buttons vertically (padding 6->1px, min-height 32->22) so
  they stop wasting vertical space.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XUWCXM4KhjRkwheaA3X7bP
2026-07-06 09:26:37 +02:00
Amir Alexander Abdelbaki abea1bec43 feat(astal-menu): Bluetooth connect status + Forget button
- Connect flow now shows real status: a spinner + Cancel while connecting, and a red
  "failed" tag + Retry if the attempt stops without linking (via notify::connecting
  going false) or a 25s timeout backstop fires. Previously Connect gave no feedback
  and could look stuck forever.
- Add a Forget button on paired devices (adapter.remove_device) to unpair them.
- Track per-device pending/failed state so the row reflects connecting/failed/
  connected/paired accurately.

Verified the paired row renders Forget + Connect and the connected row renders
Forget + Disconnect.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XUWCXM4KhjRkwheaA3X7bP
2026-07-06 08:43:13 +02:00
Amir Alexander Abdelbaki 6a5a5bce97 feat(astal-menu): bouncy slide-in on open, springy pop on quad expand
- Main open: enable Hyprland's `layers` animation with the bouncy myBezier curve and
  a slide style, so the layer-shell control centre slides in from the top edge with a
  little overshoot instead of just appearing. (Also gives notifications/bar the same
  springy slide, which suits the DE.) A per-namespace layerrule was tried first but
  this hyprlua build doesn't honour its animation timing.
- Quad expand: a CSS @keyframes scale-bounce (scale 0.82 -> 1.05 -> 1.0) added to the
  expanded card on expand and cleared on collapse so it replays every time. Verified
  GTK4 CSS transforms/keyframes render on this build, and that the card scales during
  the animation.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XUWCXM4KhjRkwheaA3X7bP
2026-07-06 00:00:14 +02:00
Amir Alexander Abdelbaki 3aafd2cc17 fix(astal-menu): working favourites, 3-day weather, deploy-safe settings
Favourites:
- Pin/unpin from the drawer never worked: the right-click / long-press gestures
  were added to a Gtk.Button in the default (bubble) phase, where the button's own
  primary-click gesture swallowed them. Move them to the CAPTURE phase and claim the
  sequence (shared add_pin_gestures helper) so they fire reliably and don't also
  launch the app.
- Show a ★ on pinned tiles and re-render tiles when favourites change, so the state
  is visible and updates live.
- Verified end-to-end (right-click pins, right-click again unpins).

Weather: the expanded quad showed current conditions only. weather.sh used
`${2:-0}`, which rewrote the expanded view's intentionally-empty opts to "0"
(current only); use `${2-0}` so the empty value reaches wttr.in as its default
3-day forecast. Verified the expanded view now renders all three days.

Settings: move settings.json from CONFIG_DIR to XDG_STATE_HOME. The config-updater
`rm -rf`s ~/.config/astal-menu on every deploy, which was wiping pinned favourites
and quad toggles; the state dir is untouched by config sync. Migrates the old file.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XUWCXM4KhjRkwheaA3X7bP
2026-07-05 23:35:23 +02:00
Amir Alexander Abdelbaki 16f75edb13 style(astal-menu): fixed-shape switches, inset close button, shorter panel, uniform expand icons
- Switches: give them a fixed pill with a bordered round knob (the reset theme
  left them shapeless).
- Close (x) button: inset with a margin so it no longer overlaps the drawn border.
- Height: the panel overflowed the monitor. Trim the map compact height, quad
  min-height, card padding, grid/panel spacing, top margin, and drawer strip so it
  fits (≈1600 -> ≈1310 logical on a 1440 display).
- App drawer expand button: use the same nf-fa-expand/compress glyphs as the module
  expand buttons instead of chevrons, so all expand controls look uniform.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XUWCXM4KhjRkwheaA3X7bP
2026-07-05 20:48:52 +02:00
Amir Alexander Abdelbaki d468d66e5f feat(astal-menu): NetworkManager control panel; single-ring settings/close buttons
Network expanded view is rewritten into four tabs over a new nmcli backend
(backend/nm.py, JSON in/out):
- Adapters: each device foldout with editable IPv4 and IPv6 — Automatic/DHCP
  toggle, address, a linked subnet-mask <-> CIDR pair (edit either, the other
  follows), gateway; applied via `nmcli connection modify/up`. Manual fields dim
  when DHCP is on.
- Routes: the kernel routing table (read-only; editing kernel routes needs root).
- VLAN: pick a parent device + ID to create/bring up a VLAN, list + activate/delete.
- DNS: effective servers per device + a per-connection override (servers +
  ignore-automatic).
Verified reads and the write path end-to-end (VLAN add/delete via nmcli; each tab
rendered in a harness).

Also: flatten the settings-cog MenuButton's inner `button` node so it shows one
ring instead of two, and drop the border on the close (x) button.

Weather keeps its wttr.in 3-day forecast (unchanged, per request).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XUWCXM4KhjRkwheaA3X7bP
2026-07-05 20:32:39 +02:00
Amir Alexander Abdelbaki 4e5ee4f9ba fix(astal-menu): single module border; unblock rfkill so Bluetooth powers on
- Borders: with the app stylesheet now above the theme, the CSS `.quad-card`
  border rendered a second ring concentric with the Cairo bordered() ring. Drop the
  CSS border/background/radius from the card boxes so only the Cairo card shows.
- Bluetooth: the power/scan/connect controls were correctly wired to AstalBluetooth,
  but the adapter was rfkill soft-blocked, making set_powered a silent no-op. The
  power toggle now runs `rfkill unblock bluetooth` before powering on.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XUWCXM4KhjRkwheaA3X7bP
2026-07-05 20:11:36 +02:00
Amir Alexander Abdelbaki 503b7f3336 fix(astal-menu): float modules on transparent gaps (beat theme's global bg)
The panel showed a solid #1a1a1a slab between modules. Root cause: the CyberQueer
GTK theme is installed as ~/.config/gtk-4.0/gtk.css (a symlink), which GTK4 loads
at PRIORITY_USER (800) — above our PRIORITY_APPLICATION (600) — and its reset rule
`* { background-color: #1a1a1a }` painted every node, including the structural
containers between modules. Our transparency overrides silently lost the cascade.

Fixes:
- theme.py: load the app stylesheets at USER+1 so they sit just above the
  user-level theme symlink and actually win.
- style.css: blank the structural container nodes (window/.panel/overlay/revealer/
  grid/scrolledwindow/viewport/drawingarea) so the desktop shows between modules.
- window.py/quadgrid.py: draw each module's card background with the Cairo
  bordered(fill_bg=True) so cards stay opaque (incl. rounded corners) while the
  gaps go transparent — this GTK build doesn't paint CSS backgrounds on containers,
  hence the Cairo fill.

Popovers/buttons keep their backgrounds (the theme's rule still covers those nodes;
only structural containers are overridden). Verified visually end-to-end.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XUWCXM4KhjRkwheaA3X7bP
2026-07-05 19:51:54 +02:00
Amir Alexander Abdelbaki 277f04c65d fix(astal-menu): live-apply widget settings, float modules, IP-locate via traceroute
Widget settings popover toggles now take effect immediately. QuadCard only
rebuilt a card when its Enabled state flipped, so per-module feature toggles
(Wi-Fi, discovery, routes, CLI art, …) were persisted but never applied. The
card now rebuilds whenever any of its own feature values change, and the
incomplete partial per-module refresh callbacks (which also leaked a dead
subscription per rebuild) are dropped in favour of that single path.

Make the backmost surface transparent so each module floats on its own drawn
border/background: force `window`/`.background`/`.panel` transparent, since a
plain `.menu-window` rule did not override the GTK theme's solid window node.

Locate via IP now works and uses traceroute: geolocate.py traceroutes to
1.1.1.1, takes the first globally-routable hop (the ISP egress) and resolves it
through a public geolocation API, falling back to self-IP when traceroute is
missing or finds no public hop. The ip_locate toggle gates the lookup entirely
(placeholder when off). Adds `traceroute` to the hyprlua package list.

Autostart: `sleep 1 && hyprctl reload` after all spawns so layer-shell clients
settle on the final config.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XUWCXM4KhjRkwheaA3X7bP
2026-07-05 17:02:40 +02:00
Amir Alexander Abdelbaki 3d75182b54 feat(hyprlua): add astal-menu popup, replacing nwg-dock + nwg-drawer
A touch-friendly GTK4 popup control centre (Python + PyGObject, wlr-layer-shell)
launched from the EWW bar or Super+D. Replaces nwg-dock and nwg-drawer.

Layout: a floating, drawn-bordered panel (anchored top-centre so it never blocks
the rest of the screen) with a 2x2 quad grid over a full-width app drawer, plus a
top taskbar. Any quad expands over the others; the drawer expands to the bottom.

Modules:
- Location  — static OSM map (backend/staticmap.py) on IP geolocation
              (libshumate won't paint tiles in this env; shumate-demo is blank too)
- Weather   — wttr.in ANSI art rendered via an SGR parser into a TextView
- Bluetooth — AstalBluetooth: discovery/connect/disconnect + local history
- Network   — AstalNetwork wifi + nmcli/ip/ss for IP, DHCP/manual, routes, ports,
              public IP; per-feature toggles
- Taskbar   — open windows from hyprctl, grouped by app with pop-out per instance
- Favorites — pinned apps (right-click/long-press to pin) atop the app drawer

Notes:
- Frontend is Python/GTK4, not Lua: lgi/Astal-Lua are GTK3-only.
- Module borders are drawn with a Cairo overlay (lib/border.py); this GTK build's
  renderer skips CSS border/background on plain container widgets.
- Consumes Astal GObject libs (io/apps/network/bluetooth) via introspection.

Wiring: autostart + Super+D/Super+Shift+A binds, EWW launcher button in all three
bar variants, apply-theme.sh (_colors.css), installer packages, config-updater.
drawer.sh moved to scripts/deprecated/.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-05 00:11:39 +02:00