From 5c1c90138e2b5aa10f025868bf528dce460f7ec1 Mon Sep 17 00:00:00 2001 From: mobrava <82764703+mobrava@users.noreply.github.com> Date: Sat, 29 Aug 2026 11:19:56 +0900 Subject: [PATCH] Prewarm the history panel after launch The first Cmd+Shift+V after a relaunch had to build the panel and its NSHostingView from scratch. Measured on a real launch, that took 140-180ms before the 250ms reveal animation could even start. The panel window is transparent until SwiftUI renders its first frame, so nothing was on screen during that window: a second press landed mid-reveal, read isVisible as true, and cancelled the reveal. The panel only appeared to open on the third press. Render the panel once off screen 300ms after launch so the first press only pays for the animation. Same measurement after the change: 61ms from hotkey to the panel being ordered in, down from 168ms. --- Clipbara/AppState.swift | 7 +++++++ Clipbara/Panel/PanelController.swift | 25 +++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/Clipbara/AppState.swift b/Clipbara/AppState.swift index 7645df6..229fa5d 100644 --- a/Clipbara/AppState.swift +++ b/Clipbara/AppState.swift @@ -40,6 +40,13 @@ final class AppState { self?.previewItem = nil } setupHotkey() + + // Render the panel once off screen so the first hotkey press is instant. + Task { @MainActor [weak self] in + try? await Task.sleep(for: .milliseconds(300)) + guard let self, let container = self.modelContainer else { return } + self.panelController.prewarm(modelContainer: container, appState: self) + } } func togglePanel() { diff --git a/Clipbara/Panel/PanelController.swift b/Clipbara/Panel/PanelController.swift index 53e57e9..5cc753d 100644 --- a/Clipbara/Panel/PanelController.swift +++ b/Clipbara/Panel/PanelController.swift @@ -31,6 +31,31 @@ final class PanelController { } } + /// Builds the panel and renders its first frame off screen so the first + /// hotkey press only has to animate. Called shortly after launch. + func prewarm(modelContainer: ModelContainer, appState: AppState) { + guard panel == nil else { return } + self.appState = appState + + let screenFrame = (NSScreen.main ?? NSScreen.screens.first!).visibleFrame + let frame = panelFrame(in: screenFrame, itemCount: 0, y: screenFrame.origin.y) + .offsetBy(dx: 0, dy: -baseHeight) + + let warm = ClipbaraPanel(contentRect: frame) + warm.alphaValue = 0 + warm.contentView = NSHostingView( + rootView: HistoryPanelView() + .environment(appState) + .modelContainer(modelContainer) + ) + warm.orderFrontRegardless() + warm.contentView?.layoutSubtreeIfNeeded() + warm.displayIfNeeded() + warm.orderOut(nil) + warm.alphaValue = 1 + panel = warm + } + func showPanel(modelContainer: ModelContainer, appState: AppState) { guard !isVisible else { return } self.appState = appState