From 3acb27d747a4f9b26164a3a62b2b682b0778aa17 Mon Sep 17 00:00:00 2001 From: Alex Mazanov Date: Thu, 27 Feb 2025 08:48:18 -0500 Subject: [PATCH] Improve detachavle windows #397 Signed-off-by: Alex Mazanov --- SwiftBar/MenuBar/MenuBarItem.swift | 33 +++++++++++++++++++++++++++ SwiftBar/UI/WebView.swift | 36 +++++++++++++++++++++--------- 2 files changed, 58 insertions(+), 11 deletions(-) diff --git a/SwiftBar/MenuBar/MenuBarItem.swift b/SwiftBar/MenuBar/MenuBarItem.swift index 8ce992a..1029826 100644 --- a/SwiftBar/MenuBar/MenuBarItem.swift +++ b/SwiftBar/MenuBar/MenuBarItem.swift @@ -386,6 +386,16 @@ extension MenubarItem { } func hideWebPopover(_ sender: AnyObject?) { + // If the popover is detached, don't automatically close it when clicking outside + if let window = webPopover.contentViewController?.view.window, + window.styleMask.contains(.titled) + { + // Only stop the monitor for detached windows, don't close the window + stopPopupMonitor() + return + } + + // Normal popover behavior for non-detached popovers webPopover.performClose(sender) if plugin?.metadata?.persistentWebView == false { resetWebPopoverContent() @@ -803,4 +813,27 @@ extension MenubarItem: NSPopoverDelegate { func popoverShouldDetach(_: NSPopover) -> Bool { true } + + func popoverDidDetach(_ popover: NSPopover) { + // For webPopover, configure the detached window properly + if popover == webPopover, let window = popover.contentViewController?.view.window { + // Set the window to have proper controls + window.styleMask = [ + .titled, + .closable, + .miniaturizable, + .resizable, + ] + window.isReleasedWhenClosed = false + + // Set a minimum window size to ensure controls are visible + window.minSize = NSSize(width: 300, height: 200) + + // Set window title to match the plugin name + window.title = "‎ SwiftBar: \(plugin?.name ?? "")" + + // Stop the popup monitor when detached to prevent auto-closing on outside clicks + stopPopupMonitor() + } + } } diff --git a/SwiftBar/UI/WebView.swift b/SwiftBar/UI/WebView.swift index 544bdf4..08e7dac 100644 --- a/SwiftBar/UI/WebView.swift +++ b/SwiftBar/UI/WebView.swift @@ -15,19 +15,33 @@ struct WebView: NSViewRepresentable { struct WebPanelView: View { let request: URLRequest let name: String + + // This property lets us detect if we're in a detached window + @State private var isDetachedWindow: Bool = false + var body: some View { - VStack { - ZStack { - if #available(macOS 12.0, *) { - Rectangle().fill(.bar) - } else if #available(macOS 12.0, *) { - Rectangle().fill(.background) - } else { - Rectangle().fill(.gray) + VStack(spacing: 0) { + if !isDetachedWindow { + ZStack { + if #available(macOS 12.0, *) { + Rectangle().fill(.bar) + } else { + Rectangle().fill(.background) + } + HStack { + Spacer() + Text("SwiftBar: \(name)") + .font(.headline) + .lineLimit(1) + + Spacer() + } + .padding(.horizontal, 12) } - Text("SwiftBar: \(name)") - .font(.headline) - }.frame(height: 20) + .frame(height: 28) + .padding(.top, 4) + } + WebView(request: request) } }