Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

67
Views
Request key for TextField in macOS status bar app

I am writing a little status bar app, which includes a text input.

The app is added to the status bar as a NSMenuItem which holds a NSHostingViewController with the SwiftUI-View. The status bar menu is added through an App delegate inside SwiftUIs @main scene. I've set "Application is agent" in the info.plist to true and I have an empty scene as @main in SwiftUI.

Problem: When I try to edit text, in the status bar app, the text field is not clickable and does not receive text input. When I add a window, the text field in the status bar app works as expected as long as the window is in foreground.

From my understanding, this is caused by the text field not being inside a window marked as key window. Is there any workaround to make the text field work as expected without the need for an additional app window?

Minimal example for the app delegate:

class AppDelegate: NSObject, NSApplicationDelegate {

  private var statusItem: NSStatusItem?
  func applicationDidFinishLaunching(_ notification: Notification) {
    self.statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)

    if let statusBarButton = statusItem?.button {
        statusBarButton.image = NSImage(systemSymbolName: "6.circle", accessibilityDescription: "")
        statusBarButton.image?.isTemplate = true
    }

    let menuItem = NSMenuItem()
    menuItem.view = createView()

    let menu = NSMenu()
    menu.addItem(menuItem)

    statusItem?.menu = menu
  }


  private func createView() -> NSView {
   let view = HostingView(rootView: ContentView())

   view.frame = NSRect(x: 0, y: 0, width: 520, height: 260)

   return view
  }
}

SwiftUI @main

import SwiftUI
import AppKit

@main
struct MacApp: App {
    @NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

    var body: some Scene {
        Settings {
            EmptyView()
        }
    }
}

Edit: I figured out, that there are two windows registered for my app. One for the status bar icon and one for the menu. However, the code below does not result in the menu window to become the key window. (although it is in fact the only window which returns true for .canBecomeKey)

.onAppear {
   let window = NSApp.windows.first { $0.canBecomeKey }
   window?.makeKey()
}

Second Edit: Apparently, the problem is not, that the window is not able to become key, but that the app is not set as the active app when the status bar menu is opened. I came up with this rather ugly hack, which causes the menu to close and re-open when another app was in focus before, but at least buttons and textfields work as expected with this:

func applicationDidFinishLaunching(_ notification: Notification) {
    ...
    // Also let AppDelegate implement NSMenuDelegate
    menu.delegate = self
    ...
}

func menuWillOpen(_ menu: NSMenu) {
        #warning("This is a hack to activate the app when the menu is shown. This will cause the menu to close and re-open when another window was focused before.")
        if !NSApp.isActive {
            NSApp.activate(ignoringOtherApps: true)
            DispatchQueue.main.async {
                self.statusItem?.button?.performClick(nil)
            }
        }
    }

I am still looking for a proper solution.

over 4 years ago · Santiago Trujillo
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!