Replace the three-tier load-adaptive polling (20s/120s/600s based on CPU-or-
RAM usage) with a flat 20s interval — fido2-token -L is cheap enough that
backing off under load isn't worth the added complexity or the latency in
noticing a key was removed.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
There was only one ReGreet skin in the whole repo (etc-greetd/), hand-styled
to match hyprdrive's glowy "Cosmonaut Shell" look (translucent glass, box-
shadow glow, scanlines). sysupdate.sh's _ensure_plymouth_regreet() offers to
deploy it on any machine that migrates to greetd, with no DE-awareness — so
it landed on a hyprlua box too.
Move the existing skin to desktopenvs/hyprdrive/greetd-regreet/ and add a
plain hyprlua variant at desktopenvs/hyprlua/greetd-regreet/ (flat @bg cards,
2px @violet border, @accent on hover/focus/active — no glow, matching
mnotifd/audio-panel/astal-menu's established look). config.toml and
regreet-session.sh have no DE-specific styling, so they stay shared at
etc-greetd/.
sysupdate.sh's _deploy_greetd() and the greetd-regreet.sh setup module now
resolve the active DE (reusing the same config-updater SOURCE_BASE detection
_de_source_dir() already uses elsewhere) and deploy the matching skin,
falling back to hyprdrive's for DEs without their own variant yet.
apply-theme.sh needed no functional change since it recolors whatever's
already deployed rather than reading the source path — just relabeled its
SYS_FILES entry for accuracy.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
mnotifd, mnotifhist, and audio-panel filled cards/pills with solid @violet
(border indistinguishable from fill), unlike the hollow @bg-fill +
@violet-border pills used everywhere else (eww bar, astal-menu). Flip
default-state fills to @bg, keep @accent for hover/checked/active states,
and drop the audio-panel default-device button's hardcoded green in favour
of @accent.
Also give the eww bar's drawer/notif/caffeine buttons the same circular
.icon-btn treatment as the screen-rotation buttons (touch variant only —
the laptop bar's 20px height has no room for a 40px circle), and make the
notif bell light up @accent whenever mnotifd's history cache has entries
(new notif-active-status.sh poll), rather than only matching hover.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Replace the OpenCV motion-detection daemon with a fido2-token -L check —
presence now means "a FIDO2/U2F key is plugged in", queried without any
touch/tap. Adaptive poll: 20s under light load, 120s under moderate,
600s under heavy. Drops the old motion "grace window" since key presence
doesn't flicker like camera motion did.
Removes presence_detect.py, the presence camera config/test flow from
enroll-biometrics.sh, and the python-opencv dependency (kept v4l-utils,
still used by howdy's camera setup). Adds a standalone presence-test.sh
instead of folding the FIDO check into enroll-biometrics.sh's dialog TUI —
there's nothing to enroll, so it doesn't belong in that flow.
.sb-tabbar now reserves 64px on the right, the same way .sb-header already
does for the title: the ✕ is a Gtk.Overlay child, so it claims no layout
space and the tab row grew straight under it once the row got wide enough
(the "General Settings" pill was overlapping the button's circle).
Also documents, next to `config vicinae` in hyprdrive's updater.conf, that
the cosmonaut.toml this deploys to ~/.config/vicinae/ is inert — vicinae only
reads named themes from ~/.local/share/vicinae/themes/, and silently falls
back to its default grey theme when the file isn't there. That is exactly
what happened on this machine: the theme was added after hyprdrive.sh last
ran, so the launcher had been rendering the stock grey palette.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The per-channel volume meters are now vertical faders (Gtk.Scale, inverted so
loud is up) instead of horizontal sliders, and the live peak indicator moved
out of its own bar above the card into the meter itself: a narrow violet
column Cairo-drawn inside the trough, so one glance reads both "what the
volume is set to" (the fill) and "what is actually reaching the mix" (the
column inside it).
- ui/peakbar.py is a DrawingArea rather than a Gtk.LevelBar: it has to grow
bottom-to-top over the same span as the scale's highlight, minus the
half-slider inset, and it sits in a Gtk.Overlay with can_target=False so
the scale underneath still gets every click and drag.
- ui/meter.py draws the value as its own label and drops the 100% mark;
either one would push the trough off-centre under the overlaid column.
The channel label is always appended (empty for mono) so a lone meter and
a split L/R pair keep the same trough height inside the card's stack.
- ui/card_base.py fans one peak monitor out to every meter of the card —
parec reports one mixed level per target, not a per-channel one.
- The trough's empty portion is transparent now (an idle meter and a silent
monitor both read as "nothing here"), and supersonic-booster's fill gets
the suite's emitted-magenta glow. Both stylesheets re-assert the
transparent background at class specificity: the CyberQueer theme's
`* { background-color: #1a1a1a }` was otherwise painting a dark stripe
straight through the fill where the peak column sits.
hyprlua's audio-panel is regenerated via regen-audio-panel.sh; its plain
stylesheet stays flat and glow-free by design, with @accent as the fill.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Adds a fifth mixer tab, Cards: one row per pactl card (onboard audio, USB
headsets, HDMI, Bluetooth) with just its profile dropdown (Analog Stereo
Duplex, Pro Audio, Off, etc.).
Profile is a card-level setting, not a per-device one — a single card can
back a device in both Output and Input Devices at once, and switching its
profile can make either side appear or disappear entirely. It used to live
on individual DeviceCards in both tabs, which was confusing (same card,
edited from two places) and is exactly what pavucontrol avoids by giving
profiles their own "Configuration" tab. Pulled it out of DeviceCard/
OutputTab/InputTab (which also drops their now-unneeded list_cards() fetch)
and into a new ui/profile_card.py + ui/cards_tab.py.
hyprlua's audio-panel picks this up via regen-audio-panel.sh, unchanged.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TkkH9eiCBfpWysUXAD9bDG
Each app card in the mixer panel's Applications tab now also shows an Input
dropdown next to Output, letting you re-route that app's own microphone
stream (pactl move-source-output) the same way Output already re-routes its
playback stream. Matches an app's sink-input to its source-output via
application.process.binary (falling back to name) — the same client tags
both when an app plays and records, e.g. Discord. Apps with no matching
recording stream get the dropdown disabled rather than hidden, so card
layout stays consistent across the row.
hyprlua's audio-panel picks this up via regen-audio-panel.sh, unchanged.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TkkH9eiCBfpWysUXAD9bDG
hyprdrive's vicinae used to ship the exact same "cyberqueer" theme as
hyprlua/hyprland. Vicinae's theme format is colors-only (no border-radius/
box-shadow/blur/animation hooks), so it can't reproduce the Cosmonaut Shell
suite's live Cairo-drawn scanline/sweep/noise overlay — but it can reuse the
same static palette that overlay sits on top of: emitted-magenta text
(#EB00A6), glow-violet borders (#8A5CFF), a near-black-violet background, and
translucent violet-glass secondary surfaces, matching orbit-menu/astro-menu/
station-bar/transmitter-panel/supersonic-booster's look.
Replaces desktopenvs/hyprdrive/vicinae/cyberqueer.toml with cosmonaut.toml,
repoints settings.json and hyprdrive.sh's install step at it, and adds a
second apply-theme.sh entry so live colors.conf edits keep syncing it
(alongside the fix for the pre-existing hyprlua/hyprland entry, which was
pointing at the inert ~/.config/vicinae/ copy instead of the
~/.local/share/vicinae/themes/ file vicinae actually reads).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TkkH9eiCBfpWysUXAD9bDG
Layer-shell surfaces can only anchor to a screen edge with a margin, not to
another process's widget, so this can't truly follow the invoking volume
button — but every bar variant in this repo (station-bar, eww/eww-touch/
eww-nobattery) keeps its volume control in the top-right zone, so anchoring
there approximates "under the control that opened it" well enough. Also
shrunk the panel (900px -> 460px, smaller cards/meters/tab height) so it
reads as a compact popover instead of a full-width mixer.
hyprlua's audio-panel is regenerated via regen-audio-panel.sh; its
hand-maintained plain theme seed (audio-panel-theme/style.css) got the same
sizing tweaks by hand since the regen script doesn't touch it.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TkkH9eiCBfpWysUXAD9bDG
A new layer-shell mixer panel with four tabs (Applications / Input Devices /
Output Devices / General Settings): per-app and per-device volume meters with
an independent left/right toggle, mute, live parec-based amplitude bars (so a
silent stream is visually distinct from a quiet one), output-device routing,
card profile switching (pro-audio vs stereo duplex etc.), and default-device
pickers. Backed by pactl -f json + pactl subscribe over pipewire-pulse
(verified against this box's real pactl; wpctl was dropped for lacking
per-channel volume and profile verbs).
hyprdrive gets the hologram-styled original (supersonic-booster); hyprlua's
plain-themed audio-panel is generated by a new
desktopenvs/hyprlua/scripts/regen-audio-panel.sh, extending the existing
regen-beacon.sh derivation pattern rather than hand-duplicating the app.
Wired into both DEs: Super+Shift+S keybind, autostart, config-updater,
apply-theme.sh, and the respective bars (station-bar's volume badge now opens
the panel; eww/eww-touch/eww-nobattery's volume slider does too, replacing
the old pavucontrol launch).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TkkH9eiCBfpWysUXAD9bDG
Discord's screen-share source picker wasn't matching the modal-dialog
windowrules and tiled instead of floating. It's the Qt "hyprland-share-picker"
binary, which sets its app_id/class via
QCoreApplication::setApplicationName("org.hyprland.xdg-desktop-portal-hyprland")
— neither the GTK portal-dialog rule (different class) nor the title-based
dialog-float rule (title doesn't match) catches it. Added a dedicated rule
matching that class with the same float+center-on-monitor treatment.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Monocle now also confines the cursor to the focused full-size window so it
can't slip onto another monitor. Hyprland has no cursor-confine dispatcher, so
this drives the confine_pointer window rule: one lazily-created rule per
workspace, matched by workspace id (follows focus), enabled/disabled in
lock-step with the monocle toggle and refreshed immediately.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Ports hyprdrive's astro-menu update to astal-menu (hand-maintained separately,
no regen script for this pair): a new config.py with a "layouts" key to
narrow/reorder which hypr/layouts-discovered layouts are offered and override
their per-layout options, plus 1s polling of the taskbar's workspace/layout
panel while the menu is open so it doesn't go stale across workspace
switches. No hologram code path here since astal-menu doesn't have one.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
config.json gains a "layouts" key to narrow which hypr/layouts-discovered
layouts astro-menu offers (and reorder them), plus per-layout option
overrides (trim directions, hide fit_method/stepper), without touching the
.lua layout sources.
Also: the taskbar's workspace/layout panel now polls every second while the
menu is open, since switching workspaces doesn't notify (or get blocked by)
the menu and the panel previously only refreshed on open.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
timer-run now offers Dismiss/Snooze 2m/Snooze 5m buttons via notify-send -A
(beacon/mnotifd both implement the freedesktop Actions spec) and rings the
alarm on a loop until the notification resolves, instead of playing once and
going silent.
screenrec.sh gets a real "Stop Recording" button in the same vein, replacing
a broken anonymous --action= and a `$nid=` assignment bug that never actually
captured the notification id; also fixes hyprlua's stale `dunstctl close`
call left over from the mnotifd migration (dunst is no longer running).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Adds regen-beacon.sh, a by-hand generator that produces hyprlua's plain-themed
notification daemon (mnotifd) and history viewer (mnotifhist) from hyprdrive's
beacon/transmitter-panel sources — stripping the Cosmonaut Shell hologram/
squiggle sci-fi treatment (now config-toggleable on beacon itself) and
renaming every beacon/transmitter-panel reference throughout, so future edits
to the hyprdrive originals propagate with one script run instead of two
hand-diverging copies. Wires mnotifd/mnotifhist into hyprlua in place of
dunst (autostart, keybinds, config-updater, install script incl. the D-Bus
activation shadow file).
Also adds a notification-history launcher button (verified bell glyph) to
station-bar and all three hyprlua EWW bar variants.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
beacon gains a disk-persisted history D-Bus interface (eu.abdelbaki.beacon.History1
- List/Get/Pop/PopLatest/Remove/Clear/InvokeAction, live Added/Removed/Cleared
signals) and support for apps to embed rich controls (toggle/slider/entry, not
just fire-and-dismiss buttons) via a custom x-beacon-controls notification hint,
plus a beaconctl CLI. transmitter-panel is a new Cosmonaut Shell popup (Super+
Ctrl+N) that browses that history, with a Clear All button and a per-entry
close button.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Super+E now toggles cursor "glass magnifier" zoom (wiki trick); Thunar
moves to Super+Shift+E and the pcmanfm-qt alt bind is dropped. Super+Alt+F
drops the calculator launch in favor of a real fullscreen toggle, and
Super+Ctrl+F is added to toggle the workspace's "monocle" layout via the
existing layouts registry. Also inlines unified-rotate.sh cw/ccw directly
in the Super+Ctrl+E/D rotation binds instead of going through the
confusingly-named (and reversed) screenrotationwcw/acw.sh wrapper scripts.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
bordered()'s glow re-strokes the rounded ring at widths up to border+22, so half
of each stroke falls outside the ring path. GTK clips a DrawingArea to its own
square allocation: along the straight edges that trims the outward spill to
nothing, but inside each corner the square patch between the arc and the widget
corner is still in-allocation and got painted solid accent red — square corners
peeking out from behind every rounded card border.
Clip the glow passes to the ring's outer silhouette (the widget rect rounded by
radius + border/2, exactly where the crisp stroke's outer edge runs) so the
bloom only reads inward. Crisp stroke and fill are unchanged.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The dunst package ships org.knopwob.dunst.service with
Name=org.freedesktop.Notifications, so D-Bus auto-activates dunst the
moment any app posts a notification, beating beacon to the name (beacon
then exits on name-lost). Shadow it with a user-level activation file
that Execs beacon-start.sh; ~/.local/share/dbus-1/services takes
precedence over /usr/share. Documented the install-time deploy in
updater.conf.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The bar hosts the StatusNotifierWatcher in-process (sni_watcher.py), so the
*_sync proxy creation and RegisterStatusNotifierHost call blocked the main
loop waiting on a reply only that same loop could produce — a self-deadlock
freezing the whole bar (clock, holo intro) until the 25s D-Bus timeout. Switch
to new_for_bus + call (async, fire-and-forget).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Swap the module's default background.jpg for ESA/Hubble Picture of the Week
potw2050a, "Rings of Relativity" (GAL-CLUS-022058s, one of the most complete
Einstein rings observed). Update CREDITS.md and the hyprdrive.sh install-module
comments to match. Credit: ESA/Hubble & NASA, S. Jha; Ack. L. Shatz — CC BY 4.0.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Add a `dialog-float` window rule to both hyprdrive and hyprlua: float any
window whose title looks like a dialog (Rename/Save/Open/Opening/Confirm/
Delete/Move/Copy/Replace/Properties/Preferences — covers file-manager rename
dialogs and Firefox "Opening <file>" download prompts), centred on the cursor
at its natural (minimum) size. Catches dialogs that carry no xdg/X11 dialog
hint and would otherwise tile; Hyprland still auto-floats the ones that do.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- beacon: snappier in-app dissolve (OUTRO_DURATION 0.4 -> 0.2).
- hyprland.lua: split the global `layers` animation into layersIn/layersOut
so open and close differ. layersIn keeps the springy myBezier slide-in;
layersOut slides the surface back off-screen with a new easeInQuint-ish
`slideOutLate` curve — it creeps slowly then whips away in the final
quarter, instead of a uniform fade.
- windowrules.lua: drop `no_anim` from the beacon layerrule (keep blur) so
notification cards ride those layer animations again (they slid in/out via
the global anim before, since no per-namespace no_anim was deployed).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
beacon (the Cosmonaut Shell notif daemon) already renders its holo
fade-in-from-noise intro (materialise out of static), but dunst held the
org.freedesktop.Notifications bus so beacon never started. Make beacon the
deployed and active notification daemon:
- updater.conf: manage `config beacon`; drop `config dunst` (now `ignore`d,
superseded). Also carries the pre-existing `config ghostty` line that was
already sitting uncommitted in this file.
- beacon: add a SIGUSR1 close-all handler (window.close_all) so the old
`dunstctl close-all` keybind has an equivalent.
- binds.lua: Super+Ctrl+C now runs `pkill -USR1 -f '[b]eacon/main.py'`
(bracket idiom avoids pkill self-matching its own wrapper).
- screenrec.sh: `dunstctl close` -> freedesktop CloseNotification via gdbus.
- timer-run: resolve the session bus via the beacon process, not dunst.
hyprlua keeps its own independent updater.conf + dunst and is untouched.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
kitty: regenerate scanlines.png — the old tile was a washed-out near-white
overlay that milked out the terminal. Replace it with a dark holographic tile
(gentle violet #5018DD tint + crisp violet scanlines every 4px + sparse
magenta/crimson grain) on a transparent base, so the window's own opacity/blur
still show the wallpaper through it. Seamlessly tileable; matches the suite's
HologramOverlay palette.
station-bar: add a caffeine badge to the right zone, a faithful port of
hyprlua's 4-state eww caffeine widget. Click toggles the shared idle-inhibit
lock via the same scripts/caffeine.sh; the glyph tracks manual inhibit (coffee)
/ webcam presence (eye) / idle (sleep) and glows magenta while presence holds
the lock, reading the same lock/flag files the status scripts do. Nerd Font
codepoints verified against Agave's cmap.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
hyprland's kitty theme was still the stock template (only 5 colors set,
ANSI colors commented out); brought it in line with hyprdrive/hyprlua's
full neon 16-color palette and dropped the now-redundant inline cursor
overrides in kitty.conf. Alacritty had no color scheme at all in any DE,
so added matching [colors] blocks to hyprdrive/hyprlua/hyprland so it
renders identically to kitty/ghostty. Registered alacritty.toml and
ghostty/config in apply-theme.sh so future colors.conf edits propagate.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
kitty: add a seamlessly-tiled scanlines+noise+ambient-bloom PNG as
background_image, giving kitty a static approximation of the suite's
HologramOverlay treatment since it has no per-frame draw hook or shader
support to do real bloom.
ghostty: port the CyberQueer theme (palette, cursor/selection colors)
to a new Ghostty config, with a real per-pixel custom-shader instead of
a static image — color-preserving bloom, procedural scanlines/grain, an
occasional analog glitch/roll burst (tear + vertical roll + chromatic
aberration), and a one-time hologram boot intro that resolves out of
colored static via a downward sweep. Window decorations and the tab bar
are disabled to match kitty's borderless look under Hyprland.
Not wired up anywhere yet — no keybind or $TERMINAL changes point at
Ghostty. This is just the config, ready to test.
Same fix as hyprdrive's kitty (6c07c10): the 16 ANSI colors were still
stock template defaults clashing with the violet/crimson palette used
everywhere else in the suite. Fill them in from colors.conf plus a
few new neon tints in the same hue family, set background to the
real #1A1A1A instead of pure black, add matching border/bell/mark
colors, and drop the stale cursor-color pair in kitty.conf that the
theme include was silently overriding anyway.
The 16 ANSI colors were still stock template defaults (plain green/
blue/cyan) clashing with the violet/crimson palette used everywhere
else in the suite. Fill them in from colors.conf plus a few new neon
tints in the same hue family, set background to the real #1A1A1A
instead of pure black, and add matching border/bell/mark colors. Also
drop a stale cursor-color pair in kitty.conf that the theme include
was silently overriding anyway.
orbit-menu and horizon-dock (and their eww-bar launcher buttons, autostart
hooks, and O-bind wrapping) were built inside hyprlua before hyprdrive
existed as a separate DE. hyprdrive is now the home for the full Cosmonaut
Shell suite, so hyprlua drops back to eww bars + vicinae launcher + the
astal-menu pop-open menu, unchanged, matching last Thursday's state.
hyprdrive itself is untouched.
Replaces the ∿-glyph label divider with a Gtk.DrawingArea that strokes a sampled
sine wave (soft-glow + bright-core passes), colour per urgency (magenta / accent),
phase-advanced each tick so it travels like a live signal. Background stays
transparent — a class-specific rule overrides the CyberQueer theme's universal
`background-color`, so no dark pill shows behind it.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
beacon is a GTK4 layer-shell notification daemon in the Cosmonaut Shell idiom.
It owns org.freedesktop.Notifications and renders each notification as a
holographic card: scanline/sweep/noise overlay (shared lib/hologram.py) clipped
to a rounded violet holo-glass card, emitted-magenta text, glow-violet frame
(accent + squiggle for critical), materialise-out-of-static intro / dissolve
outro, top-centre stack.
Implements the interactive spec subset: body markup, urgency, replaces_id,
per-urgency timeouts, action pills, icons (name/path/raw), click-to-dismiss, and
the NotificationClosed / ActionInvoked signals.
- scripts/beacon-start.sh: LD_PRELOAD launcher
- autostart.lua: dunst -> beacon
- windowrules.lua: blur layer-rule for the `beacon` namespace (no_anim; it has
its own hologram intro)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Themes dunst in the astro-menu idiom: emitted-magenta text, violet holo-glass
backgrounds (transparent for the compositor blur), glow-violet/accent frames,
Agave Nerd Font Mono, and a "radio squiggle" sine-wave divider between title and
body. (Superseded by the beacon daemon in a following commit, but kept as themed
fallback config.)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The materialise intro was driven only by the frame-clock tick, which stops
advancing when the compositor withholds frame callbacks (e.g. the bar restarted
into an idle compositor) — freezing it at t=0 with content stuck at opacity 0,
i.e. permanent static. Arm a GLib.timeout alongside start_intro() that
force-resolves the intro regardless, so content always appears.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Right-click now fetches the item's com.canonical.dbusmenu layout and renders it
in a GTK popover anchored to the icon, instead of calling the SNI ContextMenu
method. Fixes menus opening at screen (0,0) for apps that implement it (Discord)
and gives a menu at all for dbusmenu-only apps (nm-applet, blueman). Supports
sections, submenus, checkmarks, icons and Event-on-activate; themed to match the
suite (.station-tray-menu).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
`hyprctl dispatch` evaluates its argument as Lua here (hyprlua), so the old
native `dispatch exec <cmd>` form parsed as a Lua syntax error and was silently
dropped — every Tools/Scripts/Management entry failed to launch. Route through
hl.dsp.exec_cmd(...) instead (matching binds.lua), keeping the [tag ...] rule
prefix support.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
hyprdrive has no DE component owning org.kde.StatusNotifierWatcher (waybar/eww
used to), so tray apps had nowhere to register and every SNI host — including the
bar's own tray.py — saw an empty tray.
- sni_watcher.py: a minimal StatusNotifierWatcher — owns the name, tracks
registered items/hosts, drops items on NameOwnerChanged, and emits the
registration signals + PropertiesChanged so hosts stay live.
- main.py: start it in do_startup, before the bars.
- tray.py: watch the watcher name (bus_watch_name) instead of connecting once, so
the host attaches when our watcher appears and recovers if any watcher restarts.
Verified: the watcher owns the bus name, IsStatusNotifierHostRegistered is true,
and running tray apps (udiskie, nm-applet, blueman, Steam) register + render in
the bar the moment it comes up.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Second daily-driving pass over the Cosmonaut Shell suite.
Animations (all four surfaces):
- Removed every slide-in reveal; each surface now only "materialises out of
static" (compositor no_anim layerrule + in-app hologram intro). Longer, noisier,
gradual fade-in: the content opacity ramps 0->1 (fade_widget) instead of a solid
haze block popping on. Added a quick reverse "dissolve into static" outro on
close. horizon-dock/orbit-menu use a slower 2.4s intro. Fixed a warm-reopen bug
where a stale frame-clock baseline skipped the intro entirely.
horizon-dock:
- Center planet: bigger, sinks ~1/4 below the screen edge, translucent holographic
body with a wide bloom halo, specular sheen, rim glow and a breathing pulse.
- Ornamental satellite glyphs: two rings framing the windows orbit, each with a
random 3-7 satellites whose motion source is randomised (toward-cursor / mouseX
/ mouseY), so the quiet edges feel alive.
- Super+D now opens horizon-dock (astro-menu moved to Super+Shift+D).
orbit-menu:
- Classic dmenu mode: `--dmenu` reads newline items from stdin, shows them as ring
nodes, prints the choice to stdout (exit 1 on cancel). Standalone NON_UNIQUE app
so it never routes to the resident daemon; scripts/orbit-dmenu.sh wraps it with
the gtk4-layer-shell preload.
astro-menu (sci-fi rework):
- Replaced the map module with "Ship Systems": a Gtk.Grid system monitor backed by
backend/sysmon.sh. CPU->Thrusters, GPU->Hyperdrive, RAM->Life Support Systems,
Storage->Cargo Hold (one aligned row per mounted drive with capacity), each a
bracketed -<████░░░░>- usage meter + -( 54°C )- temperature readout.
- Renamed Bluetooth -> System Radio, Network -> Laser Antenna Uplink.
- Weather gains a "Planetary Environment Report" headline.
station-bar:
- The battery readout uses a fuel-tank glyph (the ship runs on fuel).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Daily-driving pass over the Cosmonaut Shell suite: transparency, holographic
effects, and layout/geometry fixes across every component built for the DE.
Global holographic layer (astro-menu/horizon-dock/station-bar lib/hologram.py):
- edge-fade mask (A8 DEST_OUT) so scanlines fade out at panel borders
- magenta particle field; "materialize from static" noise-mask intro animation
- optional clip_func so the mask follows non-rectangular / animated content
- universal `* { background-color: transparent }` at USER+1 to defeat the
CyberQueer theme painting opaque bg on plain containers; blur layer_rules
astro-menu: magenta text (alt red) for readability; thinner, glowier borders;
rounded map-texture corners; fixed transparency stacking + square corners.
orbit-menu: scanline mask now follows the zoom transition into a submenu.
horizon-dock: reworked into an orbit-menu node ~1/3 on-screen (<=2/3 width) with
horizon perspective (arched orbit rows), a non-functional center clock-sphere,
orbit glyph decorations, graceful edge fade-out, and centered/filled orbits;
tray removed; giant-surface clip fixed.
station-bar: redesigned as an extra Horizon Dock orbit — bare glowing color-coded
glyphs (no pills), width-adaptive, one bar per monitor, Super+Z toggles the
focused monitor's bar. Clickable HUD trapezoid around the title opens Astro Menu.
Workspaces are now per-monitor: each bar shows only its own monitor's workspaces
and highlights that monitor's active workspace. Populated workspaces show the
station glyph, empty ones the bare spaceship + number; the focused one is framed
by a `-< >-` reticle with the rocket prepended when there's a station to dock at.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
New leaner Hyprland DE (setup/modules/Desktop-Environments/hyprdrive.sh),
a sibling of hyprlua that drops the older EWW/nwg-shell/wofi/walker/
ulauncher stack in favor of a purpose-built, GTK4 layer-shell component
suite sharing one CyberQueer hologram visual language:
- orbit-menu radial power/utility menu (focal-point zoom nav, holographic
overlay, cosmetic satellites)
- horizon-dock hover-scrollable orbital app dock (open windows/favorites/
all apps orbits, SNI tray satellite)
- astro-menu astal-menu re-themed as a hologram info display (Location/
Weather/Bluetooth/Network quads, taskbar, app drawer)
- station-bar the EWW top bar's replacement ("Voidstation Status Bar"):
a thin curved layer-shell bar tracking Hyprland workspaces/
active window natively over .socket2.sock, no polling
Every component now shares one consistent hologram treatment: translucent
violet panel/node fills (replacing solid gray), a config-toggleable
scanline+sweep+noise overlay (lib/hologram.py, ported to horizon-dock and
station-bar to match orbit-menu/astro-menu), and glow-on-hover throughout.
Also adds horizon-dock to hyprlua (built there first, before hyprdrive
existed) and wires dependency checks, config-updater entries, and
apply-theme.sh color sync for every new component across both DEs.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nu8JkQ95hPAT8vADeGDAmL
Replaces the plain Gtk.Stack crossfade with a focal-point zoom (Gtk.Fixed +
Gsk.Transform): the clicked node's screen position becomes a pivot the parent
page zooms into while the child page slides in from that exact spot and grows
to become the new center — like a moon becoming the planet you now orbit.
Going back reverses the same motion around the same remembered point
(_stack_origins tracks it per depth).
Adds a holographic overlay (config.json "hologram" toggle, default on):
violet scanlines + a looping sweep band + magenta/red noise specs with real
per-particle lifetimes (fade in/out, not single-frame flicker), all composited
through a radial mask so it reads as one soft-edged glow over the menu rather
than tinting the whole square canvas.
Adds an opening-only intro (never plays between nodes): each button starts
invisible and fades in on a staggered cascade — center first, then ring nodes
in order — with a bright noise burst flashing at each node's position the
instant it starts appearing, like it's condensing out of the static.
Also fixes a transparency regression: the new hologram DrawingArea sits above
everything via Gtk.Overlay, and the cyberqueer theme's aggressive `*` selector
was painting it an opaque background, hiding the whole menu — forced
transparent via CSS, same fix pattern as the earlier orbit-node label bug.
Adds a decorative layer to the radial menu: small nerd-font glyphs orbit the
ring nodes (and occasionally the center) at a fixed radial "height" per
satellite, only their angle changes — easing toward the cursor plus a slight
idle wobble. Faint dashed/dotted/solid orbit-path circles trace each one.
Per page build (not per frame, so it never flickers):
- total count is 2 + random(1, (3 % node-amount) + 2), clamped to node
capacity, spread across at least 3 distinct nodes when there are that many
- a node can get up to 2 satellites; since each has its own fixed height they
never overlap, and the gap between a doubled pair is widened further
- a doubled pair splits its motion — one tracks only the cursor's X, the
other only Y, each with its own random phase offset so multiple doubled
nodes on one page don't move in lockstep
- every satellite gets independent horizontal/vertical response multipliers,
so it can read as more reactive to one direction than the other
- some satellites get tangential bracket flourishes (-<, -[, -(, -{, -|)
rotated to the orbit's local tangent
Toggleable via ~/.local/state/orbit-menu/config.json ({"satellites": false})
since config-updater wipes ~/.config/orbit-menu on every sync.
New GTK4 layer-shell radial menu (desktopenvs/hyprlua/orbit-menu/), following
astal-menu's single-instance D-Bus daemon conventions. Super+Shift+O opens
straight into a Power ring (sleep/reboot/poweroff/soft-reboot via hyprshutdown);
Super+Ctrl+O opens the full 5-category root (Power, Tools, Scripts sourced live
from ~/Documents/Scripts, Management, and a live open-Windows list with
go-to/bring-here/close/force-kill/get-pid/send-to-workspace actions). Adds a
round launcher button to all 3 eww bar variants with matching glow/hover CSS.
Also retunes hypridle (lock 30s, sleep 1min) and adds a HibernateDelaySec
systemd-sleep.conf.d fragment (deployed by sysupdate.sh) so the machine
hibernates ~80 minutes after going idle instead of drifting to sleep indefinitely.
A workspace with no seeded/published column count used to always start
at a hardcoded 2, regardless of monitor size. Now it picks
floor(usable_width / 700), so ~700px per column — 1080p still lands on
2, wider monitors start with more instead of one cramped column.
hypr-nav fell back to the raw "lua:columns" backend string on any
workspace that had never been explicitly switched via the menu (i.e.
every fresh workspace, since columns is the global default), which
didn't match the "columns" layout name it checks against — so focus/
move/resize silently took the generic dwindle-style path instead of
being forwarded to the custom layout. Strip the "lua:" prefix in the
fallback.
Also make focus/scroll u/d within a column wrap around instead of
stopping at the ends.
Decouple the base installer's "run dotfiles TUI" choice from cloning the
dotfiles repo into /etc/skel and from the new user's default shell, so
declining both actually yields a bare system: no dotfiles, plain bash,
no DE, no display manager, and a working agetty login on tty1. Also add
an explicit toggle in the TUI for syncing the configured user's ~/.config
back into /etc/skel, previously unconditional.
Separately, core.sh's "svc" component unconditionally staged a greetd
config that launches Hyprland and enabled greetd.service — even when no
DE was selected, and even for DEs (GNOME, KDE Plasma, COSMIC, XFCE,
LXQt, Sway) that install their own display manager. That left greetd
racing the DE's native DM (or agetty, in the no-DE case) for tty1, and
Sway additionally got a greeter pointed at the wrong compositor. Gate
greetd on the DE selection and have every DE module disown getty/greetd
before enabling its own DM, matching the pattern hyprland.sh/niri.sh
already used; add a Sway-specific tuigreet config.
Portal-backed file/app choosers (xdg-desktop-portal-gtk) — e.g. Steam's
"select library folder" picker, plus Chromium/Electron/Flatpak dialogs —
run in a separate process and open as parentless top-levels with no
xdg-dialog or X11-dialog hint. Hyprland can't tell they're dialogs and
tiles them, unlike in-process xdg dialogs which it auto-floats. Match the
portal backend's class and float + centre it so it lands above its parent.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
presence-detect.sh no longer mirrors the camera through a v4l2loopback device,
so the module setup is dead weight. Remove it:
- delete etc-v4l2loopback/ (modprobe.d + modules-load.d configs)
- drop the deploy blocks and linux-headers/v4l2loopback-dkms/v4l2loopback-utils
package installs from the niri and hyprlua DE installers
- remove _ensure_v4l2loopback() and its call from sysupdate.sh
- reword enroll-biometrics.sh's loopback filter comment (kept as a harmless
defensive exclusion) so it no longer points at the deleted config
Live system cleanup (module unload + /etc configs) is separate and needs root.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>