Skip to content

feat(themes): add Top Bar theme, hide-until-hover placement and 5% low-usage alarm - #164

Open
articdevil03 wants to merge 1 commit into
CodeZeno:mainfrom
articdevil03:top-bar
Open

articdevil03 wants to merge 1 commit into
CodeZeno:mainfrom
articdevil03:top-bar

Conversation

@articdevil03

Copy link
Copy Markdown

Summary

Refs #163 (proposal and discussion).

Adds an optional Top Bar: a built-in theme that docks a wide, short usage strip at the top centre of a chosen monitor, stays collapsed as a small click-through tab, and slides down when the cursor rests on it. It also adds a 5% low-usage alarm. Both are opt-in through the theme and settings; Classic, Compact and custom taskbar/floating themes behave as before.

Top Bar, light
Top Bar, dark
Low-usage alarm

Theme engine (general, usable by any theme)

  • auto_hide placement option for floating roots docked to a monitor's top or bottom edge: a collapsed handle, an 80 ms rest-to-open intent delay (not while the left button is held), ~250 ms slide, 0.6 s leave delay. The collapsed handle is click-through; the cursor is polled only while a hiding surface is visible (suspended behind fullscreen apps).
  • handle_color, a countdown number format (<1m, 14m, 2h 14m, 3d 4h, localized suffixes), data.updated.* bindings, light/dark colour expressions, alarm.* bindings and a snooze_alarm() click action (also listed in Studio).
  • Settings > Display: Hide until hover (Use theme setting / Enabled / Disabled), Widget display (monitor for edge-docked widgets), Alarm at 5% remaining. Studio's Positioning section shows and can clear an active override.

Top Bar theme (src/themes/top-bar.json, generated by tools/gen_top_bar.py, which reproduces the JSON byte-for-byte from the repo root)

  • One block per enabled provider, left to right; each limit shows %, a thin bar and "Resets in" countdown; Claude's Fable weekly cap via the existing claude.model.fable binding. Amber at 70%, red at 90%. Follows Windows light/dark. Width grows with providers and stays within the monitor.
  • A layout guard test renders every text and pill (1-3+ providers, normal/amber/red/alarm/stale states, 100/125/150% scale, light/dark, all 14 locales) and fails if any two come closer than 2 px or leave the card.

5% low-usage alarm (on by default, can be turned off)

  • Covers, for every enabled provider and account, the headline windows as the poller fills them (session/five-hour, weekly, monthly) plus Claude model caps under the unambiguous model.<slug> rule. Sub-quotas a poller does not surface as a headline window (e.g. Copilot metered Chat/Completions, Antigravity's non-preferred groups) are out of scope.
  • A fresh (non-stale) low reading always counts; the "updated" age shown on the bar follows the last fresh refresh, not the last cache write.
  • Plays a bundled, original "warning pulse" WAV (synthesized for this PR, no third-party audio; src/assets/README.md) once per crossing, at most once a minute, silent with a "No Sounds" scheme or muted system sounds. Edge-docked surfaces stay revealed while a quota is low; a Snooze 1h button on the bar and a context-menu item let them hide again.
  • A crossing clears on a good reading above 5% remaining or when its reset time has passed (5-minute grace for clock skew); stale carried-forward readings never create a crossing or keep one past its reset; a reading without a reset keeps the last one. Turning the alarm or a provider off and on forgets crossings but not the sound cooldown.

Testing

  • On Windows 11 25H2, Rust 1.95.0: cargo fmt --all -- --check, cargo clippy --all-targets -- -D warnings, cargo test --locked (583 passed, 0 failed, 5 ignored), cargo build --locked --release.
  • New tests cover the auto-hide geometry and state machine, saved-drag handling (Top Bar stays docked; ordinary top/bottom floating custom themes still honour a saved drag), the alarm scan and crossing history, the sound/hold-open/snooze path through the real render and timer call sites, settings round trips, and the layout guard above. Each new guard was mutation-checked (behaviour broken on purpose, test red, restored).
  • Used daily on a two-monitor 1920x1080 setup for the Top Bar, with Claude and Codex enabled.
  • Not verified: other Windows versions, non-100-150% scaling, and native-speaker review of the new strings in the 13 non-English locales (machine-written; corrections welcome).

Notes for reviewers

  • This is larger than CONTRIBUTING suggests for one PR, and CONTRIBUTING asks to discuss substantial changes first. Happy to split it (placement, theme, alarm) or adjust the approach; it is offered as one PR so the pieces can be seen working together.
  • Overlap: open PR feat(theme): show Fable quota in horizontal themes #158 also shows Fable in horizontal themes; this PR uses the same claude.model.fable binding.
  • Two small fixes outside the feature were needed for a clean cargo test/clippy run on this machine: poller/retry_after.rs (a test assumed the PC had been up for over a day) and a clippy lint in window/taskbar_collision.rs. I can move them to a separate PR.
  • Known limit: two Claude caps that share a model name have no stable model shortcut; such a cap clears at its reset.

Checklist

  • I have read CONTRIBUTING.md and CODE_OF_CONDUCT.md.
  • The change is focused and contains no credentials or sensitive data.
  • I have added or updated relevant documentation and tests, where applicable.
  • I have left changelog and version changes to maintainers unless requested.

🤖 Generated with Claude Code

https://claude.ai/code/session_011HqUMQbM9NB7PuC292Sh69

…w-usage alarm

Adds an optional built-in "Top Bar" theme: a wide, short strip docked at the
top centre of a chosen monitor that stays collapsed as a small click-through
tab and slides down when the cursor rests on it. One block per enabled
provider, left to right, with %, a thin bar and a "Resets in" countdown;
follows Windows light/dark.

Theme engine (usable by any theme): an auto_hide placement option for
edge-docked floating roots, handle_color, a countdown number format,
data.updated.* bindings, light/dark colour expressions, alarm.* bindings and
a snooze_alarm() click action. Settings > Display gains Hide until hover (Use
theme setting / Enabled / Disabled), Widget display and Alarm at 5%
remaining; Studio shows and can clear an active override and previews colour
expressions.

The 5% low-usage alarm covers each enabled provider's and account's headline
windows plus Claude model caps, plays a bundled original WAV at most once a
minute, keeps edge-docked surfaces revealed while a quota is low, and offers
Snooze 1h on the bar and in the context menu.

The Top Bar theme JSON is generated by tools/gen_top_bar.py. Also fixes a
test that assumed more than a day of uptime (poller/retry_after.rs) and a
clippy lint in window/taskbar_collision.rs.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011HqUMQbM9NB7PuC292Sh69
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