NSDatePicker in NSStatusBar NSSMenuItem not receiving input
Your NSDatePicker needs to return "acceptsFirstMouse" as true, which is readonly, so you'll to do that in a subclass.
Works in a test project running the code you supplied.
refresh NSMenuItem on click/open of NSStatusItem
Keep a reference to the created NSMenuItem
in your app delegate and update its state (assuming you use the item only in a single menu).
class AppDelegate: NSApplicationDelegate {
var fooMenuItem: NSMenuItem?
}
func createStatusBarItem() {
...
let enableDisableMenuItem = NSMenuItem(title: "Enabled", action: #selector(toggleAdvancedMouseHandlingObjc), keyEquivalent: "e")
self.fooMenuItem = enableDisableMenuItem
...
}
@objc func toggleAdvancedMouseHandlingObjc() {
if sHandler.isAdvancedMouseHandlingEnabled() {
sHandler.disableAdvancedMouseHandling()
} else {
sHandler.enableAdvancedMouseHandling()
}
self.fooMenuItem.state = sHandler.isAdvancedMouseHandlingEnabled() ? NSControl.StateValue.on : NSControl.StateValue.off
}
Listen for Actions on a NSStatusItem With a Menu
This solution came from a previous SO question:Highlighting NSStatusItem with attributed string
and may do what you want. Unfortunately, popUpStatusItemMenu is now deprecated.
#import <Cocoa/Cocoa.h>
@interface AppDelegate : NSObject <NSApplicationDelegate> {
NSStatusItem* statusItem;
NSMenu* statusMenu;
NSMenuItem* menuItem;
}
-(void)statusItemHandler:(id)sender;
-(void)menuHandler:(id)sender;
@end
@implementation AppDelegate
-(void)menuHandler:(id)sender {
NSLog(@"Menu item = %@",sender);
}
-(void)statusItemHandler:(id)sender {
NSLog(@"StatusItem hit.");
statusMenu = [[NSMenu alloc] init];
menuItem = [statusMenu addItemWithTitle: @"Item 1" action:@selector(menuHandler:) keyEquivalent:@""];
menuItem = [statusMenu addItemWithTitle: @"Item 2" action:@selector(menuHandler:) keyEquivalent:@""];
[statusMenu addItem:[NSMenuItem separatorItem]];
menuItem = [statusMenu addItemWithTitle:@"Quit" action:@selector(terminate:) keyEquivalent:@""];
[statusItem popUpStatusItemMenu:statusMenu];
}
-(void)applicationDidFinishLaunching:(NSNotification *)notification {
statusItem = [[NSStatusBar systemStatusBar] statusItemWithLength:NSSquareStatusItemLength];
statusItem.button.title = @"\U0001F410";
statusItem.button.action = @selector(statusItemHandler:);
}
@end
int main(){
NSApplication *application = [NSApplication sharedApplication];
[application setActivationPolicy:NSApplicationActivationPolicyRegular];
AppDelegate *appDelegate = [[AppDelegate alloc] init];
[application setDelegate:appDelegate];
[application activateIgnoringOtherApps:YES];
[application run];
return 0;
}
NSStatusItem shows only up if it is defined outside of my method
Because if you only declare the object inside the method and don't keep a reference to it elsewhere it will be scoped to the method. When the method finishes execution your object will be released and go away.
If you want it to live as long as the app runs, you would want to assign it to a property of the app delegate or another object that is going to live as long as the app.
CGEventTap + NSStatusItem problems
The third argument of the function should be 1, was still 0 in the actual code. If its 1 then its a Listen CGEventTap and thus cannot modify or filter the event.
This also fixes an issue the event tap could have together with the game Minecraft. So if your CGEventTap only needs to listen and not filter make sure that that argument is set to 0x1 or 1
Menu in system status bar is disabled
Menu validation does not find any implementor of specified action in responder chain so disable it. You have to specify target for each menu item:
let item = menu.addItem(
withTitle: "Order a burrito",
action: #selector(StatusBarFactory.x(_:)),
keyEquivalent: "A")
item.target = _instance_of_StatusBarFactory_here // like StatusBarFactory.shared
Force NSStatusItem to Redraw
As provided by Willeke in the comments, the solution is to use the needsDisplay
property. The working function is:
-(void)buttonPressed {
[[[statusItem button] image] setTemplate: false];
[[statusItem button] setNeedsDisplay: true];
}
Related Topics
How to Override Internal Framework Method in Application (Outside Framework)
A Concise Way to Not Execute a Loop Now That C-Style for Loops Are Going to Be Removed from Swift 3
Swift Display Image UIimageview
Reachability Change Notification Should Be Called Only Once
Using Multiple Hosting Controllers in Swiftui on Watchos
Why Is My Libraries Not Able to Expand on The Cocoapods and Shows as Objective-C Not Swift
+' Is Deprecated: Mixed-Type Addition Is Deprecated in Swift 3.1
Alamofire Https Change in 10.3
My Structure Does Not Conform to Protocol 'Decodable'/'Encodable'
iOS 10 App Crashes When Accessing Camera
Debug View Hierarchy Does Not Render UI
Swift Difference Between Double and Float64
Swift Combine How Set<Anycancellable> Works
How to Present a UIcollectionview in Swiftui with UIviewcontrollerrepresentable
Table View Cells Changing Colors When Scrolling Swift
Is The for Loop Condition Evaluated Each Loop in Swift