From 39b1ff744ab174a75a861de462efe34ea443ca32 Mon Sep 17 00:00:00 2001 From: Beingpax Date: Wed, 2 Jul 2025 20:32:58 +0545 Subject: [PATCH] Improved Fallback Window --- .../TranscriptionFallbackManager.swift | 25 ++++++++++++++++--- .../Common/TranscriptionFallbackView.swift | 12 +-------- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/VoiceInk/Services/TranscriptionFallbackManager.swift b/VoiceInk/Services/TranscriptionFallbackManager.swift index 46d062b..f1bf85b 100644 --- a/VoiceInk/Services/TranscriptionFallbackManager.swift +++ b/VoiceInk/Services/TranscriptionFallbackManager.swift @@ -18,6 +18,9 @@ class TranscriptionFallbackManager { private var fallbackWindow: NSPanel? + /// Observer that listens for the fallback window losing key status so it can be dismissed automatically. + private var windowObserver: Any? + private init() {} /// Displays the fallback window with the provided transcription text. @@ -58,6 +61,15 @@ class TranscriptionFallbackManager { panel.makeFirstResponder(hostingController.view) } } + + // Automatically close the window when the user clicks outside of it. + windowObserver = NotificationCenter.default.addObserver( + forName: NSWindow.didResignKeyNotification, + object: panel, + queue: .main + ) { [weak self] _ in + self?.dismiss() + } } /// Dynamically resizes the window based on new text content @@ -68,9 +80,9 @@ class TranscriptionFallbackManager { let newSize = calculateOptimalSize(for: text) let currentFrame = window.frame - // Keep the window centered while resizing + // Preserve the bottom anchor and center horizontally while resizing let newX = currentFrame.midX - (newSize.width / 2) - let newY = currentFrame.midY - (newSize.height / 2) + let newY = currentFrame.minY // keep the bottom position constant let newFrame = NSRect(x: newX, y: newY, width: newSize.width, height: newSize.height) @@ -89,6 +101,12 @@ class TranscriptionFallbackManager { fallbackWindow = nil + // Remove the key-window observer if it exists. + if let observer = windowObserver { + NotificationCenter.default.removeObserver(observer) + windowObserver = nil + } + NSAnimationContext.runAnimationGroup({ context in context.duration = 0.2 window.animator().alphaValue = 0 @@ -147,7 +165,8 @@ class TranscriptionFallbackManager { if let activeScreen = NSScreen.main { let screenRect = activeScreen.visibleFrame let xPos = screenRect.midX - (finalSize.width / 2) - let yPos = screenRect.midY - (finalSize.height / 2) + let padding: CGFloat = 40 // increased distance from bottom of visible frame (above Dock) + let yPos = screenRect.minY + padding panel.setFrameOrigin(NSPoint(x: xPos, y: yPos)) } diff --git a/VoiceInk/Views/Common/TranscriptionFallbackView.swift b/VoiceInk/Views/Common/TranscriptionFallbackView.swift index 2dce94d..ddd429c 100644 --- a/VoiceInk/Views/Common/TranscriptionFallbackView.swift +++ b/VoiceInk/Views/Common/TranscriptionFallbackView.swift @@ -14,16 +14,7 @@ struct TranscriptionFallbackView: View { VStack(spacing: 0) { // Title Bar HStack { - if isHoveringTitleBar { - Button(action: onClose) { - Image(systemName: "xmark") - .font(.system(size: 9, weight: .semibold)) - } - .buttonStyle(TitleBarButtonStyle(color: .red)) - .keyboardShortcut(.cancelAction) - } else { - Spacer().frame(width: 20, height: 20) - } + Spacer().frame(width: 20, height: 20) Spacer() @@ -61,7 +52,6 @@ struct TranscriptionFallbackView: View { .scrollContentBackground(.hidden) .background(Color.clear) .padding(.horizontal, 16) - .padding(.vertical, 12) .onAppear { editableText = transcriptionText }