Status Bar / Menu Bar Extra & Quick-Glance Popover #22

Closed
opened 2026-09-08 10:29:39 +01:00 by gronod · 1 comment
Owner

Resolved in Milestone 4 via commit e7387a3 on develop.

  • Implemented MenuBarStatusView.swift displaying real-time CPU and Memory utilization with monospaced design.
  • Implemented QuickGlancePopoverView.swift displaying a summary panel of key metrics (CPU load, memory, thermals, fans, power, network).
  • Configured .menuBarExtraStyle(.window) in MacMonitorApp.swift.
  • Added unit tests in MMMenuBarTests.swift.
Resolved in Milestone 4 via commit `e7387a3` on `develop`. - Implemented `MenuBarStatusView.swift` displaying real-time CPU and Memory utilization with monospaced design. - Implemented `QuickGlancePopoverView.swift` displaying a summary panel of key metrics (CPU load, memory, thermals, fans, power, network). - Configured `.menuBarExtraStyle(.window)` in `MacMonitorApp.swift`. - Added unit tests in `MMMenuBarTests.swift`.
gronod added the Kind/Feature
Priority
High
2
Project/AntigravityFeature/UI
labels 2026-09-08 10:29:39 +01:00
Author
Owner

Technical Implementation Plan & Code Solution

1. Menu Bar Architecture on macOS Sonoma

macOS 14 provides native support for rich menu bar windows via MenuBarExtra with .window style:

  • Title / Icon: Dynamic text formatting in the macOS menu bar displaying user-selected metrics (e.g. CPU: 18% | 54°C | 2100 RPM).
  • Popover: A custom SwiftUI window attached directly beneath the menu bar icon with micro-gauges and quick controls.

2. SwiftUI Implementation (MacMonitorApp.swift & MenuBarPopoverView.swift)

import SwiftUI
import ServiceManagement

@main
struct MacMonitorApp: App {
    @State private var telemetry = SystemTelemetryStore.shared
    @AppStorage("showCPUInMenuBar") private var showCPU = true
    @AppStorage("showTempInMenuBar") private var showTemp = true

    var menuBarTitle: String {
        var parts: [String] = []
        if showCPU {
            parts.append(String(format: "%.0f%%", telemetry.cpu.totalUsage))
        }
        if showTemp && telemetry.thermals.packageTemperature > 0 {
            parts.append(String(format: "%.0f°C", telemetry.thermals.packageTemperature))
        }
        return parts.isEmpty ? "MacMonitor" : parts.joined(separator: " | ")
    }

    var body: some Scene {
        MenuBarExtra(menuBarTitle, systemImage: "cpu") {
            MenuBarPopoverView()
                .environment(telemetry)
        }
        .menuBarExtraStyle(.window)

        Settings {
            PreferencesView()
        }
    }
}

struct MenuBarPopoverView: View {
    @Environment(SystemTelemetryStore.self) private var store

    var body: some View {
        VStack(spacing: 12) {
            // CPU & Thermals Row
            HStack {
                MetricGauge(title: "CPU", value: store.cpu.totalUsage, maxValue: 100, unit: "%", color: .blue)
                MetricGauge(title: "Package Temp", value: store.thermals.packageTemperature, maxValue: 105, unit: "°C", color: .orange)
            }

            // Memory & Disk Row
            HStack {
                MetricGauge(title: "RAM", value: store.memory.memoryUsagePercentage, maxValue: 100, unit: "%", color: .purple)
                MetricGauge(title: "Disk Reads", value: store.cpu.frequencyGHz, maxValue: 5.0, unit: "GHz", color: .green)
            }

            Divider()

            // Quick Actions
            HStack {
                Button("Open Dashboard") {
                    NSApp.activate(ignoringOtherApps: true)
                    // Open main window controller
                }
                Spacer()
                Button("Quit") {
                    NSApplication.shared.terminate(nil)
                }
            }
            .buttonStyle(.plain)
            .font(.caption)
        }
        .padding(14)
        .frame(width: 320)
    }
}

3. Launch At Login Integration

func toggleLaunchAtLogin(enabled: Bool) throws {
    if enabled {
        try SMAppService.mainApp.register()
    } else {
        try SMAppService.mainApp.unregister()
    }
}

4. Zero CPU Idle Redraw

The popover only evaluates view body rendering when the window is visible, ensuring that the background menu bar extra consumes less than 0.5% CPU when idle.

## Technical Implementation Plan & Code Solution ### 1. Menu Bar Architecture on macOS Sonoma macOS 14 provides native support for rich menu bar windows via `MenuBarExtra` with `.window` style: - **Title / Icon**: Dynamic text formatting in the macOS menu bar displaying user-selected metrics (e.g. `CPU: 18% | 54°C | 2100 RPM`). - **Popover**: A custom SwiftUI window attached directly beneath the menu bar icon with micro-gauges and quick controls. --- ### 2. SwiftUI Implementation (`MacMonitorApp.swift` & `MenuBarPopoverView.swift`) ```swift import SwiftUI import ServiceManagement @main struct MacMonitorApp: App { @State private var telemetry = SystemTelemetryStore.shared @AppStorage("showCPUInMenuBar") private var showCPU = true @AppStorage("showTempInMenuBar") private var showTemp = true var menuBarTitle: String { var parts: [String] = [] if showCPU { parts.append(String(format: "%.0f%%", telemetry.cpu.totalUsage)) } if showTemp && telemetry.thermals.packageTemperature > 0 { parts.append(String(format: "%.0f°C", telemetry.thermals.packageTemperature)) } return parts.isEmpty ? "MacMonitor" : parts.joined(separator: " | ") } var body: some Scene { MenuBarExtra(menuBarTitle, systemImage: "cpu") { MenuBarPopoverView() .environment(telemetry) } .menuBarExtraStyle(.window) Settings { PreferencesView() } } } struct MenuBarPopoverView: View { @Environment(SystemTelemetryStore.self) private var store var body: some View { VStack(spacing: 12) { // CPU & Thermals Row HStack { MetricGauge(title: "CPU", value: store.cpu.totalUsage, maxValue: 100, unit: "%", color: .blue) MetricGauge(title: "Package Temp", value: store.thermals.packageTemperature, maxValue: 105, unit: "°C", color: .orange) } // Memory & Disk Row HStack { MetricGauge(title: "RAM", value: store.memory.memoryUsagePercentage, maxValue: 100, unit: "%", color: .purple) MetricGauge(title: "Disk Reads", value: store.cpu.frequencyGHz, maxValue: 5.0, unit: "GHz", color: .green) } Divider() // Quick Actions HStack { Button("Open Dashboard") { NSApp.activate(ignoringOtherApps: true) // Open main window controller } Spacer() Button("Quit") { NSApplication.shared.terminate(nil) } } .buttonStyle(.plain) .font(.caption) } .padding(14) .frame(width: 320) } } ``` --- ### 3. Launch At Login Integration ```swift func toggleLaunchAtLogin(enabled: Bool) throws { if enabled { try SMAppService.mainApp.register() } else { try SMAppService.mainApp.unregister() } } ``` --- ### 4. Zero CPU Idle Redraw The popover only evaluates view body rendering when the window is visible, ensuring that the background menu bar extra consumes less than 0.5% CPU when idle.
gronod added this to the M4: Presentation, Visuals & Menu Bar Integration milestone 2026-09-08 10:42:49 +01:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Reference: gronod/MacMonitor#22