From 5d19cc44715dfc57fb18e7945643fc2aa338fbea Mon Sep 17 00:00:00 2001 From: zhenan <1254455745@qq.com> Date: Wed, 3 Jun 2026 00:36:01 +0800 Subject: [PATCH 1/2] Add menu ticker content display toggles --- .../Repositories/SettingsRepository.swift | 3 +++ PanBar/Infrastructure/TickerPreferences.swift | 19 ++++++++++++++- PanBar/MenuBar/CarouselTickerView.swift | 15 ++++++++---- PanBar/MenuBar/CompactTickerView.swift | 15 ++++++++---- PanBar/MenuBar/MenuBarTickerView.swift | 1 + PanBar/MenuBar/MinimalTickerView.swift | 17 +++++++++---- PanBar/MenuBar/StatusItemController.swift | 13 +++++++--- PanBar/MenuBar/TickerRenderer.swift | 8 +++++-- PanBar/MenuBar/TickerView.swift | 15 ++++++++---- PanBar/Resources/Localizable.xcstrings | 24 +++++++++++++++++++ PanBar/Settings/Panes/TickerPane.swift | 13 ++++++++++ 11 files changed, 120 insertions(+), 23 deletions(-) diff --git a/PanBar/Data/Persistence/Repositories/SettingsRepository.swift b/PanBar/Data/Persistence/Repositories/SettingsRepository.swift index d751596..030e6a4 100644 --- a/PanBar/Data/Persistence/Repositories/SettingsRepository.swift +++ b/PanBar/Data/Persistence/Repositories/SettingsRepository.swift @@ -57,6 +57,9 @@ struct SettingsRepository { static let tickerShowTotalAssets = "ticker_show_total_assets" static let tickerShowTodayPnL = "ticker_show_today_pnl" static let tickerShowAllTimePnL = "ticker_show_alltime_pnl" + static let tickerShowAppIcon = "ticker_show_app_icon" + static let tickerShowQuoteCode = "ticker_show_quote_code" + static let tickerShowQuoteName = "ticker_show_quote_name" static let tickerMenuBarWidth = "ticker_menu_bar_width" static let tickerScrollMenuBarWidth = "ticker_scroll_menu_bar_width" static let tickerCarouselMenuBarWidth = "ticker_carousel_menu_bar_width" diff --git a/PanBar/Infrastructure/TickerPreferences.swift b/PanBar/Infrastructure/TickerPreferences.swift index f64062f..996ccd6 100644 --- a/PanBar/Infrastructure/TickerPreferences.swift +++ b/PanBar/Infrastructure/TickerPreferences.swift @@ -32,6 +32,15 @@ final class TickerPreferences: ObservableObject { @Published var showAllTimePnL: Bool { didSet { try? repo.set(SettingsRepository.Keys.tickerShowAllTimePnL, showAllTimePnL ? "1" : "0") } } + @Published var showAppIcon: Bool { + didSet { try? repo.set(SettingsRepository.Keys.tickerShowAppIcon, showAppIcon ? "1" : "0") } + } + @Published var showQuoteCode: Bool { + didSet { try? repo.set(SettingsRepository.Keys.tickerShowQuoteCode, showQuoteCode ? "1" : "0") } + } + @Published var showQuoteName: Bool { + didSet { try? repo.set(SettingsRepository.Keys.tickerShowQuoteName, showQuoteName ? "1" : "0") } + } @Published var menuBarWidth: Int { didSet { let clamped = Self.clampMenuBarWidth(menuBarWidth) @@ -139,9 +148,13 @@ final class TickerPreferences: ObservableObject { } else { self.tickerIndexIDs = [] } - self.displayMode = TickerDisplayMode(rawValue: repo.string(SettingsRepository.Keys.tickerDisplayMode) ?? "") ?? .scroll + let storedDisplayMode = TickerDisplayMode(rawValue: repo.string(SettingsRepository.Keys.tickerDisplayMode) ?? "") ?? .scroll + self.displayMode = storedDisplayMode == .scrollNoCode ? .scroll : storedDisplayMode self.minimalMetric = MinimalMetric(rawValue: repo.string(SettingsRepository.Keys.tickerMinimalMetric) ?? "") ?? .todayPnL self.carouselDwell = Int(repo.string(SettingsRepository.Keys.tickerCarouselDwell) ?? "") ?? 4 + self.showAppIcon = repo.string(SettingsRepository.Keys.tickerShowAppIcon) != "0" + self.showQuoteCode = storedDisplayMode == .scrollNoCode ? false : repo.string(SettingsRepository.Keys.tickerShowQuoteCode) != "0" + self.showQuoteName = repo.string(SettingsRepository.Keys.tickerShowQuoteName) != "0" let rawLegacyWidth = Int(repo.string(SettingsRepository.Keys.tickerMenuBarWidth) ?? "") ?? 280 let legacyWidth = Self.clampMenuBarWidth(rawLegacyWidth) self.menuBarWidth = legacyWidth @@ -164,14 +177,18 @@ final class TickerPreferences: ObservableObject { /// 菜单栏 ticker 的展现形式。 enum TickerDisplayMode: String, CaseIterable, Identifiable, Codable { case scroll // 经典左右滚动(默认) + case scrollNoCode // 旧版本兼容:现在用 showQuoteCode 控制 case carousel // 一条一条上下淡入轮播 case compact // 三个简写卡片(今日 / 总盈亏 / 总市值) case minimal // 只显示一个用户选定的数字 + static let allCases: [TickerDisplayMode] = [.scroll, .carousel, .compact, .minimal] + var id: String { rawValue } var displayName: String { switch self { case .scroll: return L("displayMode.scroll", comment: "") + case .scrollNoCode: return L("displayMode.scroll", comment: "") case .carousel: return L("displayMode.carousel", comment: "") case .compact: return L("displayMode.compact", comment: "") case .minimal: return L("displayMode.minimal", comment: "") diff --git a/PanBar/MenuBar/CarouselTickerView.swift b/PanBar/MenuBar/CarouselTickerView.swift index ad5821c..635df12 100644 --- a/PanBar/MenuBar/CarouselTickerView.swift +++ b/PanBar/MenuBar/CarouselTickerView.swift @@ -22,6 +22,7 @@ final class CarouselTickerView: NSView { let iconWidth: CGFloat = 18 var preferredTotalWidth: CGFloat? + var showsIcon: Bool = true var visibleTextWidth: CGFloat = 200 var privacyHidden: Bool = false @@ -29,7 +30,11 @@ final class CarouselTickerView: NSView { if let preferredTotalWidth { return max(40, preferredTotalWidth) } - return iconWidth + 6 + visibleTextWidth + 4 + return leadingTextX + visibleTextWidth + 4 + } + + private var leadingTextX: CGFloat { + showsIcon ? iconWidth + 6 : 2 } override var isFlipped: Bool { false } @@ -127,12 +132,14 @@ final class CarouselTickerView: NSView { } override func draw(_ dirtyRect: NSRect) { - drawIcon(in: NSRect(x: 2, y: (bounds.height - iconWidth) / 2, width: iconWidth, height: iconWidth)) + if showsIcon { + drawIcon(in: NSRect(x: 2, y: (bounds.height - iconWidth) / 2, width: iconWidth, height: iconWidth)) + } let textRect = NSRect( - x: iconWidth + 6, + x: leadingTextX, y: 0, - width: max(20, totalWidth - iconWidth - 10), + width: max(20, totalWidth - leadingTextX - 4), height: bounds.height ) diff --git a/PanBar/MenuBar/CompactTickerView.swift b/PanBar/MenuBar/CompactTickerView.swift index ee11ca1..aa56984 100644 --- a/PanBar/MenuBar/CompactTickerView.swift +++ b/PanBar/MenuBar/CompactTickerView.swift @@ -14,6 +14,7 @@ final class CompactTickerView: NSView { var scheme: TickerColorScheme = .east var privacyHidden: Bool = false var preferredTotalWidth: CGFloat? + var showsIcon: Bool = true /// hover 状态(放着满足协议,固定模式实际用不到) var hovered: Bool = false var onContentChanged: (() -> Void)? @@ -39,7 +40,11 @@ final class CompactTickerView: NSView { if let preferredTotalWidth { return max(40, preferredTotalWidth) } - return iconWidth + 6 + max(60, contentWidth) + 4 + return leadingTextX + max(60, contentWidth) + 4 + } + + private var leadingTextX: CGFloat { + showsIcon ? iconWidth + 6 : 2 } override var isFlipped: Bool { false } @@ -68,18 +73,20 @@ final class CompactTickerView: NSView { } override func draw(_ dirtyRect: NSRect) { - drawIcon(in: NSRect(x: 2, y: (bounds.height - iconWidth) / 2, width: iconWidth, height: iconWidth)) + if showsIcon { + drawIcon(in: NSRect(x: 2, y: (bounds.height - iconWidth) / 2, width: iconWidth, height: iconWidth)) + } if privacyHidden { let dots = NSAttributedString(string: "•••", attributes: [ .font: valueFont, .foregroundColor: NSColor.secondaryLabelColor ]) - dots.draw(at: NSPoint(x: iconWidth + 8, y: bounds.midY - dots.size().height / 2)) + dots.draw(at: NSPoint(x: leadingTextX + 4, y: bounds.midY - dots.size().height / 2)) return } - var x: CGFloat = iconWidth + 6 + var x: CGFloat = leadingTextX for (i, piece) in renderPieces().enumerated() { if i > 0 { x += slotSpacing } let size = piece.size() diff --git a/PanBar/MenuBar/MenuBarTickerView.swift b/PanBar/MenuBar/MenuBarTickerView.swift index a6fa210..5524864 100644 --- a/PanBar/MenuBar/MenuBarTickerView.swift +++ b/PanBar/MenuBar/MenuBarTickerView.swift @@ -10,6 +10,7 @@ protocol MenuBarTickerView: NSView { var totalWidth: CGFloat { get } var privacyHidden: Bool { get set } var preferredTotalWidth: CGFloat? { get set } + var showsIcon: Bool { get set } /// 鼠标 hover 状态;由 controller 监听 button 的 tracking area 同步过来 var hovered: Bool { get set } /// 内容变化通知(动画帧 / 数据更新),controller 重新捕图。 diff --git a/PanBar/MenuBar/MinimalTickerView.swift b/PanBar/MenuBar/MinimalTickerView.swift index 3b9f034..73b3876 100644 --- a/PanBar/MenuBar/MinimalTickerView.swift +++ b/PanBar/MenuBar/MinimalTickerView.swift @@ -14,6 +14,7 @@ final class MinimalTickerView: NSView { var scheme: TickerColorScheme = .east var privacyHidden: Bool = false var preferredTotalWidth: CGFloat? + var showsIcon: Bool = true var hovered: Bool = false var onContentChanged: (() -> Void)? @@ -24,8 +25,12 @@ final class MinimalTickerView: NSView { if let preferredTotalWidth { return max(40, preferredTotalWidth) } - guard let _ = content else { return iconWidth + 40 } - return iconWidth + 6 + max(56, renderedString().size().width) + 6 + guard let _ = content else { return leadingTextX + 40 } + return leadingTextX + max(56, renderedString().size().width) + 6 + } + + private var leadingTextX: CGFloat { + showsIcon ? iconWidth + 6 : 2 } override var isFlipped: Bool { false } @@ -54,20 +59,22 @@ final class MinimalTickerView: NSView { } override func draw(_ dirtyRect: NSRect) { - drawIcon(in: NSRect(x: 2, y: (bounds.height - iconWidth) / 2, width: iconWidth, height: iconWidth)) + if showsIcon { + drawIcon(in: NSRect(x: 2, y: (bounds.height - iconWidth) / 2, width: iconWidth, height: iconWidth)) + } if privacyHidden { let dots = NSAttributedString(string: "•••", attributes: [ .font: valueFont, .foregroundColor: NSColor.secondaryLabelColor ]) - dots.draw(at: NSPoint(x: iconWidth + 8, y: bounds.midY - dots.size().height / 2)) + dots.draw(at: NSPoint(x: leadingTextX + 4, y: bounds.midY - dots.size().height / 2)) return } let str = renderedString() let size = str.size() - let p = NSPoint(x: iconWidth + 6, y: (bounds.height - size.height) / 2) + let p = NSPoint(x: leadingTextX, y: (bounds.height - size.height) / 2) str.draw(at: p) } diff --git a/PanBar/MenuBar/StatusItemController.swift b/PanBar/MenuBar/StatusItemController.swift index 839838a..fff6524 100644 --- a/PanBar/MenuBar/StatusItemController.swift +++ b/PanBar/MenuBar/StatusItemController.swift @@ -63,7 +63,11 @@ final class StatusItemController { } private func applyPrefs() { - renderer = TickerRenderer(scheme: prefs.colorScheme) + renderer = TickerRenderer( + scheme: prefs.colorScheme, + showsQuoteCode: prefs.showQuoteCode, + showsQuoteName: prefs.showQuoteName + ) // mode 变化:整个 view 都要换 if prefs.displayMode != currentMode { swapTickerView(to: prefs.displayMode) @@ -77,7 +81,10 @@ final class StatusItemController { tickerView.preferredTotalWidth = prefs.compactAutoWidth ? nil : CGFloat(prefs.compactMenuBarWidth) case .minimal: tickerView.preferredTotalWidth = nil + case .scrollNoCode: + tickerView.preferredTotalWidth = prefs.scrollAutoWidth ? nil : CGFloat(prefs.scrollMenuBarWidth) } + tickerView.showsIcon = prefs.showAppIcon // 各模式独立配置 if let scroll = tickerView as? TickerView { scroll.pixelsPerSecond = prefs.scrollSpeed.pixelsPerSecond @@ -102,7 +109,7 @@ final class StatusItemController { private static func makeView(for mode: TickerDisplayMode, scheme: TickerColorScheme) -> MenuBarTickerView { let frame = NSRect(x: 0, y: 0, width: 200, height: 22) switch mode { - case .scroll: + case .scroll, .scrollNoCode: return TickerView(frame: frame) case .carousel: return CarouselTickerView(frame: frame) @@ -207,7 +214,7 @@ final class StatusItemController { /// 各模式根据当前数据自己组装,写回到 statusItem.length。 private func render(quotes: [SymbolID: Quote]) { switch currentMode { - case .scroll: + case .scroll, .scrollNoCode: guard let view = tickerView as? TickerView else { return } let items = buildTickerItems(quotes: quotes) view.update(attributed: renderer.render(items: items)) diff --git a/PanBar/MenuBar/TickerRenderer.swift b/PanBar/MenuBar/TickerRenderer.swift index 38f441f..b1d11f2 100644 --- a/PanBar/MenuBar/TickerRenderer.swift +++ b/PanBar/MenuBar/TickerRenderer.swift @@ -20,6 +20,8 @@ enum TickerDirection { struct TickerRenderer { var scheme: TickerColorScheme = .east var font: NSFont = NSFont.menuBarFont(ofSize: 0) + var showsQuoteCode: Bool = true + var showsQuoteName: Bool = true /// 涨色 / 跌色:走 SemanticColors,与 Popover 保持一致 + 菜单栏对比度优化。 private var upColor: NSColor { SemanticColors.upNS(scheme: scheme) } @@ -137,8 +139,10 @@ struct TickerRenderer { let name = shortenedName(q.name, market: q.symbol.market) let s = NSMutableAttributedString() - s.append(NSAttributedString(string: display + " ", attributes: symbolAttr)) - if !name.isEmpty { + if showsQuoteCode { + s.append(NSAttributedString(string: display + " ", attributes: symbolAttr)) + } + if showsQuoteName && !name.isEmpty { s.append(NSAttributedString(string: name + " ", attributes: nameAttr)) } s.append(NSAttributedString(string: formatPrice(q.price) + " ", attributes: valueAttr)) diff --git a/PanBar/MenuBar/TickerView.swift b/PanBar/MenuBar/TickerView.swift index adf0b57..458458c 100644 --- a/PanBar/MenuBar/TickerView.swift +++ b/PanBar/MenuBar/TickerView.swift @@ -20,6 +20,7 @@ final class TickerView: NSView { /// 文字与图标之间的间距。 let iconWidth: CGFloat = 18 var preferredTotalWidth: CGFloat? + var showsIcon: Bool = true /// 滚动文字可视区宽度(超出会被裁剪)。 var visibleTextWidth: CGFloat = 280 /// 隐私模式:屏幕共享或用户手动开启时,只显示图标和 "•••",不绘制具体行情。 @@ -42,7 +43,11 @@ final class TickerView: NSView { if let preferredTotalWidth { return max(40, preferredTotalWidth) } - return iconWidth + 6 + visibleTextWidth + 4 + return leadingTextX + visibleTextWidth + 4 + } + + private var leadingTextX: CGFloat { + showsIcon ? iconWidth + 6 : 2 } // MARK: lifecycle @@ -141,12 +146,14 @@ final class TickerView: NSView { let ctx = NSGraphicsContext.current?.cgContext // P 图标(左侧) - drawIcon(in: NSRect(x: 2, y: (bounds.height - iconWidth) / 2, width: iconWidth, height: iconWidth)) + if showsIcon { + drawIcon(in: NSRect(x: 2, y: (bounds.height - iconWidth) / 2, width: iconWidth, height: iconWidth)) + } let textRect = NSRect( - x: iconWidth + 6, + x: leadingTextX, y: 0, - width: max(20, totalWidth - iconWidth - 10), + width: max(20, totalWidth - leadingTextX - 4), height: bounds.height ) diff --git a/PanBar/Resources/Localizable.xcstrings b/PanBar/Resources/Localizable.xcstrings index 3e558cf..d51cc45 100644 --- a/PanBar/Resources/Localizable.xcstrings +++ b/PanBar/Resources/Localizable.xcstrings @@ -554,6 +554,30 @@ "zh-Hans" : { "stringUnit" : { "state" : "translated", "value" : "菜单栏宽度: %d pt" } } } }, + "ticker.contentSection" : { + "localizations" : { + "en" : { "stringUnit" : { "state" : "translated", "value" : "Display content" } }, + "zh-Hans" : { "stringUnit" : { "state" : "translated", "value" : "显示内容" } } + } + }, + "ticker.showAppIcon" : { + "localizations" : { + "en" : { "stringUnit" : { "state" : "translated", "value" : "Show app icon" } }, + "zh-Hans" : { "stringUnit" : { "state" : "translated", "value" : "显示应用图标" } } + } + }, + "ticker.showQuoteCode" : { + "localizations" : { + "en" : { "stringUnit" : { "state" : "translated", "value" : "Show quote code" } }, + "zh-Hans" : { "stringUnit" : { "state" : "translated", "value" : "显示代码" } } + } + }, + "ticker.showQuoteName" : { + "localizations" : { + "en" : { "stringUnit" : { "state" : "translated", "value" : "Show quote name" } }, + "zh-Hans" : { "stringUnit" : { "state" : "translated", "value" : "显示名称" } } + } + }, "ticker.summarySection" : { "localizations" : { "en" : { "stringUnit" : { "state" : "translated", "value" : "Summary metrics" } }, diff --git a/PanBar/Settings/Panes/TickerPane.swift b/PanBar/Settings/Panes/TickerPane.swift index 311a832..500038e 100644 --- a/PanBar/Settings/Panes/TickerPane.swift +++ b/PanBar/Settings/Panes/TickerPane.swift @@ -88,6 +88,14 @@ private struct TickerPaneContent: View { } } + Section(header: Text(L("ticker.contentSection", comment: "")).font(.headline)) { + Toggle(L("ticker.showAppIcon", comment: ""), isOn: $prefs.showAppIcon) + if showsQuoteContentControls { + Toggle(L("ticker.showQuoteCode", comment: ""), isOn: $prefs.showQuoteCode) + Toggle(L("ticker.showQuoteName", comment: ""), isOn: $prefs.showQuoteName) + } + } + Section(header: Text(L("ticker.summarySection", comment: "")).font(.headline)) { Toggle(L("ticker.showTodayPnL", comment: ""), isOn: $prefs.showTodayPnL) Toggle(L("ticker.showAllTimePnL", comment: ""), isOn: $prefs.showAllTimePnL) @@ -165,12 +173,17 @@ private struct TickerPaneContent: View { private var displayModeHint: String { switch prefs.displayMode { case .scroll: return L("displayMode.scroll.hint", comment: "") + case .scrollNoCode: return L("displayMode.scroll.hint", comment: "") case .carousel: return L("displayMode.carousel.hint", comment: "") case .compact: return L("displayMode.compact.hint", comment: "") case .minimal: return L("displayMode.minimal.hint", comment: "") } } + private var showsQuoteContentControls: Bool { + prefs.displayMode == .scroll || prefs.displayMode == .scrollNoCode || prefs.displayMode == .carousel + } + private func marketBadge(_ m: Market) -> some View { Text(m.displayName) .font(.system(size: 10)) From 5a553703a990db5ec45d35bbaeed1105c07f3379 Mon Sep 17 00:00:00 2001 From: zhenan <1254455745@qq.com> Date: Wed, 3 Jun 2026 09:08:48 +0800 Subject: [PATCH 2/2] Persist legacy no-code ticker migration --- PanBar/Infrastructure/TickerPreferences.swift | 11 +++++++++-- PanBar/MenuBar/CompactTickerView.swift | 15 ++++++--------- 2 files changed, 15 insertions(+), 11 deletions(-) diff --git a/PanBar/Infrastructure/TickerPreferences.swift b/PanBar/Infrastructure/TickerPreferences.swift index 996ccd6..a8ec550 100644 --- a/PanBar/Infrastructure/TickerPreferences.swift +++ b/PanBar/Infrastructure/TickerPreferences.swift @@ -149,11 +149,18 @@ final class TickerPreferences: ObservableObject { self.tickerIndexIDs = [] } let storedDisplayMode = TickerDisplayMode(rawValue: repo.string(SettingsRepository.Keys.tickerDisplayMode) ?? "") ?? .scroll - self.displayMode = storedDisplayMode == .scrollNoCode ? .scroll : storedDisplayMode + let migratesScrollNoCode = storedDisplayMode == .scrollNoCode + self.displayMode = migratesScrollNoCode ? .scroll : storedDisplayMode + if migratesScrollNoCode { + try? repo.set(SettingsRepository.Keys.tickerDisplayMode, TickerDisplayMode.scroll.rawValue) + } self.minimalMetric = MinimalMetric(rawValue: repo.string(SettingsRepository.Keys.tickerMinimalMetric) ?? "") ?? .todayPnL self.carouselDwell = Int(repo.string(SettingsRepository.Keys.tickerCarouselDwell) ?? "") ?? 4 self.showAppIcon = repo.string(SettingsRepository.Keys.tickerShowAppIcon) != "0" - self.showQuoteCode = storedDisplayMode == .scrollNoCode ? false : repo.string(SettingsRepository.Keys.tickerShowQuoteCode) != "0" + self.showQuoteCode = migratesScrollNoCode ? false : repo.string(SettingsRepository.Keys.tickerShowQuoteCode) != "0" + if migratesScrollNoCode { + try? repo.set(SettingsRepository.Keys.tickerShowQuoteCode, "0") + } self.showQuoteName = repo.string(SettingsRepository.Keys.tickerShowQuoteName) != "0" let rawLegacyWidth = Int(repo.string(SettingsRepository.Keys.tickerMenuBarWidth) ?? "") ?? 280 let legacyWidth = Self.clampMenuBarWidth(rawLegacyWidth) diff --git a/PanBar/MenuBar/CompactTickerView.swift b/PanBar/MenuBar/CompactTickerView.swift index aa56984..6b83d87 100644 --- a/PanBar/MenuBar/CompactTickerView.swift +++ b/PanBar/MenuBar/CompactTickerView.swift @@ -19,7 +19,8 @@ final class CompactTickerView: NSView { var hovered: Bool = false var onContentChanged: (() -> Void)? - let iconWidth: CGFloat = 18 + private let visibleIconWidth: CGFloat = 18 + var iconWidth: CGFloat { showsIcon ? visibleIconWidth : -4 } private let slotSpacing: CGFloat = 10 private let labelFont = NSFont.systemFont(ofSize: 9, weight: .semibold) private let valueFont = NSFont.monospacedDigitSystemFont(ofSize: 12, weight: .semibold) @@ -40,11 +41,7 @@ final class CompactTickerView: NSView { if let preferredTotalWidth { return max(40, preferredTotalWidth) } - return leadingTextX + max(60, contentWidth) + 4 - } - - private var leadingTextX: CGFloat { - showsIcon ? iconWidth + 6 : 2 + return iconWidth + 6 + max(60, contentWidth) + 4 } override var isFlipped: Bool { false } @@ -74,7 +71,7 @@ final class CompactTickerView: NSView { override func draw(_ dirtyRect: NSRect) { if showsIcon { - drawIcon(in: NSRect(x: 2, y: (bounds.height - iconWidth) / 2, width: iconWidth, height: iconWidth)) + drawIcon(in: NSRect(x: 2, y: (bounds.height - visibleIconWidth) / 2, width: visibleIconWidth, height: visibleIconWidth)) } if privacyHidden { @@ -82,11 +79,11 @@ final class CompactTickerView: NSView { .font: valueFont, .foregroundColor: NSColor.secondaryLabelColor ]) - dots.draw(at: NSPoint(x: leadingTextX + 4, y: bounds.midY - dots.size().height / 2)) + dots.draw(at: NSPoint(x: iconWidth + 10, y: bounds.midY - dots.size().height / 2)) return } - var x: CGFloat = leadingTextX + var x: CGFloat = iconWidth + 6 for (i, piece) in renderPieces().enumerated() { if i > 0 { x += slotSpacing } let size = piece.size()