feat(menubar): customizable metric widgets in the status item (#82)#84
Merged
Conversation
Replaces the fixed "42% · 5.2G" metrics string with a configurable, reorderable row of metric widgets, the way a desktop system monitor lets you pick what to glance at. - Store.menuBarItems: an ordered [MenuBarItem] (metric + style + colour), JSON-persisted. Defaults to the historical CPU + memory pair, and only ever shows in Metrics mode (which stays opt-in - the default is still the icon), so nothing changes for existing users until they customise. - MenuBarWidgets.swift (new): MenuBarMetric (CPU/RAM/GPU/disk/net/IO/fan/temp/battery), MenuBarWidgetStyle (value / label+value / bar / sparkline / speed-down-up / battery glyph), MenuBarColorMode (utilization/accent/mono/pressure), and MenuBarRenderer which draws the whole row into an NSImage via a drawing handler so monochrome text tracks the light/dark menu bar. Re-implemented in our own MIT Swift + Brand tokens. - StatusBarController renders the row from the live feed: a snapshot sink (CPU/RAM/GPU/disk/fan/temp/battery + cpu/mem/gpu sparkline rings) and a 1 Hz sink (live net/disk rates + their sparklines off the ring). Drawing is a few strings + shapes; it never walks the running-app list or does other blocking work on main - consistent with the hang fixes in #83. - SettingsView > Menu Bar gains a metrics editor (add / remove / reorder, per-metric style + colour pickers) shown when Display = Metrics; edits persist and re-render the status item live. Build: xcodebuild Debug succeeds, no new warnings. Satisfies #82.
…runner Follow-up on #84 after hands-on testing: - Popup (#82, the real ask): Store.popupSections/popupTiles gate PopupView's sections + the six metric tiles; a 'Popup contents' settings section toggles them. - Widgets: MenuBarItem gains label/value/fill/history/pictogram/units + a wider colour palette (tolerant decode keeps old configs); the editor is now an expandable per-widget options panel (desktop-monitor-style depth). - Runner: new MenuBarRunner draws original built-in animations + decodes a custom GIF (ImageIO); playback speed tracks a chosen metric. StatusBarController animates it standalone (.runner mode) or prepended to the widget row (row cached between frames so it stays hang-safe). 'Animated icon' settings section + GIF import (NSOpenPanel wrapped in withoutAppHangTracking). No third-party runner artwork bundled — the mechanism is re-implemented (MIT).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Satisfies #82 — let users choose which metrics appear in the menu bar and how each is displayed, the way a desktop system monitor does. Replaces the single fixed
" 42% · 5.2G"string in Metrics mode with a configurable, reorderable row of metric widgets.Re-implemented in Burrow's own MIT Swift + Brand design system (no GPL code copied; the look/UX follows the common menu-bar-monitor conventions).
Widget styles
42%CPU 42%Metrics: CPU, RAM, GPU, disk used, network, disk I/O, fan, temperature, battery. Each offers only the styles that make sense for it; colour mode is per-widget (by utilization / accent / monochrome / by pressure).
How it's wired
Store.menuBarItems— ordered[MenuBarItem](metric + style + colour), JSON-persisted. Default = CPU + memory, and Metrics mode stays opt-in (default is the icon) → no change for existing users until they customize.MenuBarWidgets.swift(new) — the model +MenuBarRenderer, which draws the row into anNSImagevia a drawing handler so monochrome text re-resolves for light/dark menu bars. The status button keeps its existing click/right-click action untouched (no custom hit-testing view).StatusBarControllerbuilds the values from the live feed (a snapshot sink + a 1 Hz sink) and re-renders. Drawing is a few strings/shapes and reads only already-published live values — noNSWorkspace/blocking work on the main thread (consistent with the hang fixes in fix(perf): eliminate the main-thread App Hangs (Sentry triage) #83).SettingsView ▸ Menu Bar— an editor (add / remove / reorder, per-metric style + colour pickers) shown when Display = Metrics; edits persist + re-render the status item live.Test plan
xcodebuildDebug build succeeds, no new warnings.Notes
origin/main; no file overlap, so the two can land in either order.