// // StatsPanel.swift // DynamicIsland // // Created by GitHub Copilot on 13/08/25. // import AppKit import SwiftUI class StatsPanel: NSPanel { init() { super.init( contentRect: .zero, styleMask: [.borderless, .nonactivatingPanel], backing: .buffered, defer: true ) setupWindow() setupContentView() } // Override to allow the panel to become key window (required for user interaction) override var canBecomeKey: Bool { return true } // Override to allow the panel to become main window (required for text input and controls) override var canBecomeMain: Bool { return true } private func setupWindow() { backgroundColor = .clear isOpaque = false hasShadow = true level = .floating isMovableByWindowBackground = true // Enable dragging titlebarAppearsTransparent = true titleVisibility = .hidden isFloatingPanel = true // Mark as floating panel for proper behavior // Allow dragging from any part of the window styleMask.insert(.fullSizeContentView) collectionBehavior = [ .canJoinAllSpaces, .stationary, .fullScreenAuxiliary // Float above full-screen apps ] // Accept mouse moved events for proper hover behavior acceptsMouseMovedEvents = true } private func setupContentView() { let contentView = StatsPanelView { self.close() } let hostingView = NSHostingView(rootView: contentView) self.contentView = hostingView // Set initial size let preferredSize = CGSize(width: 600, height: 400) hostingView.setFrameSize(preferredSize) setContentSize(preferredSize) } func positionNearNotch() { guard let screen = NSScreen.main else { return } let screenFrame = screen.visibleFrame let panelFrame = frame // Position at top center of screen (near where the notch would be) let xPosition = (screenFrame.width - panelFrame.width) / 2 + screenFrame.minX let yPosition = screenFrame.maxY - panelFrame.height - 10 // 10px from top setFrameOrigin(NSPoint(x: xPosition, y: yPosition)) } func positionNearMouse() { let mouseLocation = NSEvent.mouseLocation let panelFrame = frame // Position near mouse but ensure it stays on screen guard let screen = NSScreen.main else { return } let screenFrame = screen.visibleFrame var xPosition = mouseLocation.x - panelFrame.width / 2 var yPosition = mouseLocation.y - panelFrame.height - 20 // Keep within screen bounds xPosition = max(screenFrame.minX + 10, min(xPosition, screenFrame.maxX - panelFrame.width - 10)) yPosition = max(screenFrame.minY + 10, min(yPosition, screenFrame.maxY - panelFrame.height - 10)) setFrameOrigin(NSPoint(x: xPosition, y: yPosition)) } }