Reputation: 83
I have a Mac OS menu bar which when clicked opens a popup view, I want to add upon this by incorporating a quit function. When the icon is right clicked another popup menu will be presented.
I am stuck on trying to get the another popup menu to present, I am able to detect a right click on the icon but I unable to show the popup menu view.
Preview when i left click
POPUP MENU VIEW FOR BOTH POPUPS
@main
struct MenuNoteApp: App {
let persistenceController = PersistenceController.shared
@Environment(\.scenePhase) var scenePhase
@NSApplicationDelegateAdaptor(AppDelegate.self) var delegate
var body: some Scene {
WindowGroup {
ContentView().environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)
}
.onChange(of: scenePhase) { _ in
persistenceController.save()
}
}
}
extension NSStatusBarButton {
open override func rightMouseUp(with event: NSEvent) {
// Detect right click and prints right click
print("right click")
}
}
class AppDelegate: NSObject,NSApplicationDelegate{
let persistenceController = PersistenceController.shared
// Status Item
var statusItem: NSStatusItem?
// PopOver
var popOver = NSPopover()
var popOverOptions = NSPopover()
func applicationDidFinishLaunching( _ notification: Notification){
// Menu View
let menuView = MenuView().environment(\.managedObjectContext, PersistenceController.preview.container.viewContext)
// Creating PopOver
popOver.behavior = .transient
popOver.animates = true
// Setting Empty View Controller And Setting View as SwiftUI View with help of hosting controller
popOver.contentViewController = NSViewController()
popOver.contentViewController?.view = NSHostingView(rootView: menuView)
popOverOptions.contentViewController = NSViewController()
popOverOptions.contentViewController?.view = NSHostingView(rootView: OptionsView())
// Creating Status Bar Button
statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)
// Check if status button is available
if let MenuButton = statusItem?.button {
MenuButton.image = NSImage(systemSymbolName: "note", accessibilityDescription: nil)
MenuButton.action = #selector(MenuButtonToggle)
}
}
// Button Action
@objc func MenuButtonToggle(sender: AnyObject){
if popOver.isShown{
popOver.performClose(sender)
}
else if popOverOptions.isShown{
popOverOptions.performClose(sender)
}
else{
//Present Pop Over
if let menuButton = statusItem?.button{
// popOver is the main view while popOverOpitions is the second view
self.popOver.show(relativeTo: menuButton.bounds, of: menuButton, preferredEdge: NSRectEdge.minY)
}
}
}
}
Upvotes: 0
Views: 301
Reputation: 541
Instead of overriding functions in NSStatusBarButton
, you should detect the left and right click behavior within the MenuButtonToggle
function.
First, you should register the right-click action, inside your the if-let inside applicationDidFinishLaunching
, like so:
if let menuButton = statusItem?.button {
menuButton.image = NSImage(systemSymbolName: "note", accessibilityDescription: nil)
menuButton.action = #selector(MenuButtonToggle)
menuButton.sendAction(on: [.leftMouseUp, .rightMouseUp]) // register action on right click too
}
Then, you want to update the MenuButtonToggle
function to act differently depending on left and right clicks.
@objc func menuButtonToggle(sender: AnyObject){
// ... previous logic here
if let event = NSApp.currentEvent {
if event.type == NSEventType.rightMouseUp {
// Right button click
self.popOver.show(...)
} else {
// Left button click
self.popOverOptions.show(...)
}
}
}
Upvotes: 2