feat(omarchy): mark each provider in the bar with its own logo - #3795
jsonMartin wants to merge 8 commits into
Conversation
|
🦞👀 Pull request received. I will update this pull request when review starts. ClawSweeper review completeClawSweeper finished reviewing this revision. The review result is being finalized. |
|
Codex review: blocked before merge. Reviewed September 21, 2026, 3:24 PM ET / 19:24 UTC (Revision 5). ClawSweeper reviewWhat this changesThe branch adds themed provider logos and text fallbacks to the Omarchy bar, packages the existing SVG assets, and carries stacked quota-display, settings, and Antigravity deduplication changes. Merge readiness⛔ Blocked before merge - 4 items remain The change remains useful and has convincing visual proof. Earlier findings are resolved; no new actionable defect was found. Logo distribution and the stacked change’s wider upgrade default still require maintainer approval. Priority: P2 Review scores
Verification
How this fits togetherCodexBar’s Linux backend turns provider CLI output and saved preferences into a private usage snapshot. The Omarchy widget polls that snapshot and renders usage alongside locally installed provider logos. flowchart LR
A[Provider CLI output] --> C[Linux usage model]
B[Saved display preferences] --> C
C --> D[Private usage snapshot]
D --> E[Omarchy bar]
F[Packaged provider logos] --> E
E --> G[Logo or text fallback with quotas]
Decision needed
Why: Both choices are explicitly presented for maintainer approval in this PR and its included stack; successful rendering and preference preservation cannot establish product acceptance. Before merge
Agent review detailsSecurityNone. Review metrics
Merge-risk optionsMaintainer options:
Technical reviewBest possible solution: Reuse the existing logos and text fallbacks, with an approved distribution scope and compact upgrade behavior unless maintainers explicitly accept the wider default. Do we have a high-confidence way to reproduce the issue? Not applicable to the primary feature request; installed-bar screenshots directly demonstrate the new rendering and fallback scenarios. Is this the best way to solve the issue? Yes for the logo layer: reusing existing assets and generating label text and entries from one model is maintainable. The stacked default-width change still needs a product choice. AGENTS.md: found and applied where relevant. Codex review notes: model internal, reasoning medium; reviewed against 1caaeb8837dd. LabelsLabel justifications:
EvidenceWhat I checked:
Likely related people:
Rating scale
Overall follows the weaker of proof and patch quality. Workflow
HistoryReview history (4 earlier review cycles)
|
Antigravity reports every pool as a quota-summary extra and copies the tightest pool of each model family into its positional windows. The popup listed both, so each representative appeared twice: once under a bare cadence label and again under its family title. Show each representative in its positional slot under its family title and drop its extra copy. The representatives stay first, so the tray meters and summary still report the binding pools, and the extra limit can no longer hide one. The row keeps the pool's own key, so alert history follows a pool when another becomes binding, and families are matched as Core selects them so equal values cannot borrow another family's title.
2d25c1d to
c126be3
Compare
…e bar The bar showed one quota per provider and no pace, so the weekly burn rate was only visible by opening a window. Show each provider's session quota, weekly quota and weekly pace. Nothing here recomputes pace. The CLI already emits a signed delta per window, produced by Core, so the shared model carries it through and renders it in the compact form of MenuBarDisplayText.paceText. The pace shown is the weekly window's, never whichever lane is most constrained, and a pace Core cannot compute contributes no segment rather than a placeholder that reads like data. Lanes are resolved from the cadence a provider reports, the way Core's semantic windows do, so no provider name is hard-coded and a provider without a session window emits neither that segment nor its separator. Three rules came out of testing against real provider shapes rather than from design: - Antigravity marks a per-family summary set with quota-summary ids, and its positional window is only whichever family represents them, so a tighter family was hidden behind it. Matching on that marker rather than on percentages matters: Claude's general weekly can coincide with one of its per-model caps, and reading that coincidence as a summary replaced the general quota with a cap scoped beneath it. - Kimi delivers a subscription-only account's entire quota through extraRateWindows, so treating every extra as an optional sub-cap dropped it. - Cursor bills its total, its Auto/Composer usage and its API usage over one cycle, so keeping only the tightest of a duration replaced the headline quota with a subquota. Percentages run through the existing quota preference, so the bar follows the used or remaining setting without the adapter inverting anything, and the existing Show pace preference now governs the bar as well as the native cards. Caps scoped to a single model are off by default behind a new preference, since most providers that publish them restate a general lane. A new Providers in the bar preference bounds how many providers the bar shows, two by default, and counts the rest, so an upgrade cannot widen an existing multi-provider bar. It is display only: every configured provider is still polled and listed in the popup. At the default font each character occupies roughly 7 logical pixels, so four providers each showing a session lane, a weekly lane and a pace come to about 1500 logical pixels; the README says so, and 0 shows every provider where the display has room. The tray tooltip names the provider's own leading quota. A cadence the bar derives from a per-model cap is skipped while the provider reports a quota of its own, so Cursor's exhausted weekly Grok allowance cannot read as an exhausted account in a tooltip that carries no lane name. The adapter also stopped reusing a previous poll's body, which let a backend that had gone away keep reporting the quota it last had.
The bar identified providers with a two-letter tag. Draw the provider's own mark instead, recoloured to the bar's foreground so themes still apply. Splitting the label is the part that needed care. barLabel built one joined string, and a frontend cannot safely split that back apart on a separator the lane text also uses. barSegments returns one tag-and-text pair per displayed provider and barLabel is built from it, so the two cannot drift. The bar's display limit lives inside barSegments rather than in barLabel, or a frontend reading the entries would show providers the label said were hidden; a three-provider test pins the providers, their order and the overflow count. The entries travel as barEntries beside barLabel, which the tooltip still uses and which a frontend falls back to when the backend predates this field. Drawing marks hides the button's own label, which is what carried the overflow count, so the count is drawn beside them. Colorization scales each pixel's luminance, so a mark drawn in black stayed black on a dark bar. Every pixel is flattened to white first, keeping only its alpha, so each mark becomes an exact tint of the foreground whatever colours its SVG uses. The marks are the ones the Mac app already ships. They are copied by glob, so no provider name is hard-coded and a provider without one keeps its text tag rather than leaving a gap. Both the installer and the release archive carry them, since an archive without them would fall back to text with nothing explaining why. The archive's allowlist test checks the fixed files and the mark filenames instead of a member count, so it still fails if a checkout leaks in. The badge sizes itself to whichever child it draws. Taking the larger of the mark and the hidden text tag reserved the width of the provider id, which left a gap beside the mark for any provider without a short tag.
c126be3 to
628d276
Compare
…up-duplicates # Conflicts: # Integrations/Linux/Shared/Usage.js # Integrations/Linux/tests/test_desktop.py
# Conflicts: # Integrations/Linux/Shared/Usage.js
Adopt the logo renderer and SVG packaging from #3795 independently of #3794 and #3799. Share compact text segments with the existing summary so quota selection, display mode, ordering, and overflow stay unchanged. Preserve text fallback for missing logos and older IPC backends. Closes #3795 Refs #3794 Co-authored-by: jsonMartin <4033621+jsonMartin@users.noreply.github.com> (cherry picked from commit b6c59b6)
|
Thanks @jsonMartin. Your logo renderer and SVG packaging are adopted in #3845, independently of #3794 and #3799. The adaptation preserves today's compact quota labels, two-entry limit, used/remaining setting, and backend polling. Missing logos and older backends retain text fallback. Model, installer, archive, isolated Linux IPC, account-action, debug build, and lint checks passed. Linux desktop and Linux CLI CI passed; Landed on main via train #3867; closing this PR as superseded. |
TL;DR
The Omarchy bar now shows each provider's logo, tinted to match the bar's text colour. A provider with no installed logo keeps its text tag, and older backends still fall back to text. This adds the Mac app's 71 logo SVGs (about 96 KB) to the plugin and release archive, which needs the maintainer's approval below. It builds on #3794 and #3799.
What changes
+Nstill counts hidden providers beside the logos.Panel.qml; rendering and fallback behaviour were checked with installed-bar screenshots.Question for the maintainer
This puts the 71 logo SVGs (about 96 KB) into a new distribution path: the Quickshell plugin directory and the Linux release archive. That's your call. I'm happy to ship a subset, load them from the CLI bundle instead, or drop this PR.
Details
Provider entries and text fallback
barLabelwas one combined string. The separator between providers also appears between usage values, so splitting that string could split a provider's values apart.barSegmentsnow returns one tag-and-text pair per displayed provider.barLabelis built from those pairs, and a test checks that they produce the same label. The pairs are sent asbarEntriesalongsidebarLabel. The tooltip still usesbarLabel, and a frontend can fall back to it when an older backend has nobarEntries.The display limit is applied inside
barSegments, so the text label and logo entries always show the same providers. When logos hide the combined label, the panel draws its+Ncount beside them.Logo colour and packaging
MultiEffectnormally applies colour according to each pixel's brightness. Black or near-black logos, including Qoder, Zenmux, Alibaba, Kilo and OpenCode, therefore stayed black on a dark bar while their text tags were hidden.Setting
contrast: -1andbrightness: 0.5first turns every pixel into white while preserving transparency. In the shader's terms, this is premultiplied white:rgb = a, permultieffect.frag. Colouring that result gives an exact tint of the foreground, whatever colours the SVG uses.The logos come from
Sources/CodexBar/Resources/ProviderIcon-*.svg, which the Mac app already ships. The installer and release archive copy files matching that pattern, without a hard-coded list of provider names. A provider without a logo keeps its text tag.Including the logos in the archive matters because an archive without them would silently fall back to text. The archive test now checks the fixed files and logo filenames against an allowed list, instead of checking the total number of files. It still fails if files from the checkout leak into the archive.
Depends on
This builds on #3794 (which builds on #3799). GitHub's native stacked pull requests do not support cross-fork stacks, so this branch also carries their commits. This PR's own change is commit
628d2769e. The branch hasmainmerged in (at1caaeb883) so it merges cleanly.Proof
All data is synthetic;
acmeis a provider with no installed logo.Installed Omarchy bar. This commit's
Panel.qmland logos were installed withinstall.py --omarchyon Omarchy (Hyprland), then the Omarchy shell was restarted. A syntheticcodexbar-linuxbackend served the real runtime socket that the installed widget polls.With the default display limit (2), the bar shows Codex's logo,
acme's text-tag fallback, and the count of hidden providers.Setting Providers in the bar to All shows every logo, tinted to the bar foreground.
With an older backend built from
main, this commit's widget falls back to the tooltip summary text. That backend publishes neitherbarLabelnorbarEntries.Logo tint. Qt 6.11 rendered these logos on the GPU with the shipped
MultiEffectsettings. The comparison shows Qoder and Zenmux (black fills), Codex (white) and Doubao (blue) on a dark bar.Fresh install and upgrade.
install.py --omarchyran twice into an isolated HOME, with preferences changed between runs.Tests
CI never loads
Panel.qml. Logo rendering, the missing-logo text fallback, the hidden-provider count and older-backend compatibility are verified by the installed-bar screenshots above, not by test.