mirror of
https://github.com/tiennm99/ccs.git
synced 2026-10-13 18:15:23 +00:00
Lead the dropdown with subscriptions: a dedicated card shows the binding window as the hero (gauge, remaining %, reset countdown, and a burn-rate 'left at this pace' line), a secondary window, and the Opus/Sonnet split for Max, with a stale marker for older Codex data. Demote spend/usage to a compact strip and surface cross-tool headroom. Add pure burn-rate / time-to-exhaustion and binding-window math in Core. Kill the menu scroll indicator for real (NSScrollView hider) so content stays aligned. Spend-cap alerts default off (pay-per-use, opt-in).
44 lines
1.7 KiB
Swift
44 lines
1.7 KiB
Swift
import SwiftUI
|
|
import AppKit
|
|
|
|
/// Zero-size bridge that walks up to the enclosing `NSScrollView` at runtime and
|
|
/// hard-disables both scrollers.
|
|
///
|
|
/// Why this exists on top of `.scrollIndicators(.never)`: inside a
|
|
/// `MenuBarExtra` popover the SwiftUI indicator preference is sometimes ignored,
|
|
/// and AppKit still draws a vertical scroller whose track steals horizontal width
|
|
/// and shoves content out of alignment. Reaching the real `NSScrollView` and
|
|
/// setting `hasVerticalScroller = false` (plus overlay/autohide) guarantees no
|
|
/// scroller chrome regardless of how the popover hosts the SwiftUI content.
|
|
struct ScrollerHider: NSViewRepresentable {
|
|
func makeNSView(context: Context) -> NSView {
|
|
let probe = NSView(frame: .zero)
|
|
// Defer the walk until the view is in the hierarchy; at make-time the
|
|
// enclosing scroll view does not exist yet.
|
|
DispatchQueue.main.async { hideScroller(from: probe) }
|
|
return probe
|
|
}
|
|
|
|
func updateNSView(_ nsView: NSView, context: Context) {
|
|
// The scroll view can be rebuilt on content changes inside the popover, so
|
|
// re-apply on each update to keep the scroller suppressed.
|
|
DispatchQueue.main.async { hideScroller(from: nsView) }
|
|
}
|
|
|
|
/// Walk superviews until the first `NSScrollView`, then disable its scrollers.
|
|
private func hideScroller(from view: NSView) {
|
|
var current: NSView? = view.superview
|
|
while let v = current {
|
|
if let scroll = v as? NSScrollView {
|
|
scroll.hasVerticalScroller = false
|
|
scroll.hasHorizontalScroller = false
|
|
scroll.scrollerStyle = .overlay
|
|
scroll.autohidesScrollers = true
|
|
scroll.drawsBackground = false
|
|
return
|
|
}
|
|
current = v.superview
|
|
}
|
|
}
|
|
}
|