I'm making an app for the macOS menu/status bar in SwiftUI that when clicked on, opens a NSPopover
. The app is centred around a TextEditor
(new in Big Sur), but that TextEditor
doesn't seem to respond to the typical Cmd + C/V/X keyboard shortcuts for copying, pasting, and cutting. I know TextEditors
do support these shortcuts because if I start a new project in XCode and I don't put it in a NSPopover
(I just put it into a regular Mac app, for example), it works. The copy/paste/cut options still appear in the right-click menu, but I'm not sure why I can't use keyboard shortcuts to access them in the NSPopover
.
I believe it has something to do with the fact that when you click to open the popover, macOS doesn't "focus" on the app. Usually, when you open an app, you'd see the app name and the relevant menu options in the top left of the Mac menu bar (next to the Apple logo). My app doesn't do this (presumably because it's a popover).
Here's the relevant code:
TextEditor in ContentView.swift:
TextEditor(text: $userData.note)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.padding(10)
.font(.body)
.background(Color(red: 30 / 255, green: 30 / 255, blue: 30 / 255))
NSPopover logic in NotedApp.swift:
@main
struct MenuBarPopoverApp: App {
@NSApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
var body: some Scene {
Settings{
EmptyView()
}
}
}
class AppDelegate: NSObject, NSApplicationDelegate {
var popover = NSPopover.init()
var statusBarItem: NSStatusItem?
func applicationDidFinishLaunching(_ notification: Notification) {
let contentView = ContentView()
popover.behavior = .transient
popover.animates = false
popover.contentViewController = NSViewController()
popover.contentViewController?.view = NSHostingView(rootView: contentView)
statusBarItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
statusBarItem?.button?.title = "Noted"
statusBarItem?.button?.action = #selector(AppDelegate.togglePopover(_:))
}
@objc func showPopover(_ sender: AnyObject?) {
if let button = statusBarItem?.button {
popover.show(relativeTo: button.bounds, of: button, preferredEdge: NSRectEdge.minY)
}
}
@objc func closePopover(_ sender: AnyObject?) {
popover.performClose(sender)
}
@objc func togglePopover(_ sender: AnyObject?) {
if popover.isShown {
closePopover(sender)
} else {
showPopover(sender)
}
}
}
You can find the entire app in a GitHub repository here: https://github.com/R-Taneja/Noted