Search code examples
swiftmacosswiftuiswiftui-list

List in NSPopover on macOS: cannot figure out how to set background transparent


I am having a hard time to figure out why my popover window is not transparent. You can see in the image below. popover

I am trying to get the black square to be the same color as the surrounding (transparent).

I also tried these NSWindow styles, but without luck. It seems whatever I find or try nothing happens or changes for the fact. I would appreciate any help or tips. Thanks

https://github.com/lukakerr/NSWindowStyles

here is my code:

import SwiftUI

@main
struct GPTbarApp: App {
    
    @NSApplicationDelegateAdaptor(AppDelegate.self) private var appDelegate
    
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

class AppDelegate: NSObject, NSApplicationDelegate {
    
    private var statusItem: NSStatusItem!
    private var popover: NSPopover!
    
    @MainActor func applicationDidFinishLaunching(_ notification: Notification) {
        statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
        
        if let statusButton = statusItem.button {
            statusButton.image = NSImage(systemSymbolName: "info.circle.fill", accessibilityDescription: "Information")
            statusButton.action = #selector(togglePopover)
        }
        
        self.popover = NSPopover()
        self.popover.contentSize = NSSize(width: 300, height: 300)
        self.popover.behavior = .transient
        
        let hostingController = NSHostingController(rootView: ContentView())
        hostingController.view.wantsLayer = true
        hostingController.view.layer?.backgroundColor = NSColor.clear.cgColor // Set the layer's background color to clear
        
        self.popover.contentViewController = hostingController
    }
    
    @objc func togglePopover() {
        if let button = statusItem.button {
            if popover.isShown {
                self.popover.performClose(nil)
            } else {
                popover.show(relativeTo: button.bounds, of: button, preferredEdge: .minY)
            }
        }
    }
}

ContentView:

import SwiftUI
import OpenAISwift

struct ContentView: View {
    
    @State private var search: String = ""
    @State private var responses: [String] = []
    
    let openAI = OpenAISwift(authToken: "sk-")
    
    private var isFormValid: Bool {
        !search.isEmpty
    }
    
    private func performSearch() {
        responses.append("You: \(search)")
        
        openAI.sendCompletion(with: search, maxTokens: 500) { result in
            switch result {
            case .success(let success):
                let response = "\(success.choices?.first?.text ?? "")"
                responses.append(response)
            case .failure(let failure):
                print(failure.localizedDescription)
            }
        }
    }
    
    var body: some View {
        VStack {
            Spacer()
            
            List(responses, id: \.self) { response in
                Text(response)
                    .background(Color.clear) // Set the background color of the text to clear
            }
            .listStyle(.plain) // Set the list style to plain
            
            HStack {
                TextField("Search.", text: $search)
                    .textFieldStyle(.roundedBorder)
                
                Button {
                    performSearch()
                } label: {
                    Image(systemName: "magnifyingglass.circle.fill")
                        .font(.title)
                }
                .buttonStyle(.borderless)
                .disabled(!isFormValid)
            }
        }
        .padding()
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

Solution

  • In macOS 13.0+, use this for your List:

    List(responses, id: \.self) { response in
       Text(response)
    }
    .listStyle(.plain)
    .scrollContentBackground(.hidden)