Reputation: 340
I need to implement minimal Cocoa application without Xcode. I am trying this example:
https://www.cocoawithlove.com/2010/09/minimalist-cocoa-programming.html
#import <Cocoa/Cocoa.h>
int main()
{
[NSAutoreleasePool new];
[NSApplication sharedApplication];
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
id menubar = [[NSMenu new] autorelease];
id appMenuItem = [[NSMenuItem new] autorelease];
[menubar addItem:appMenuItem];
[NSApp setMainMenu:menubar];
id appMenu = [[NSMenu new] autorelease];
id appName = [[NSProcessInfo processInfo] processName];
id quitTitle = [@"Quit " stringByAppendingString:appName];
id quitMenuItem = [[[NSMenuItem alloc] initWithTitle:quitTitle
action:@selector(terminate:) keyEquivalent:@"q"] autorelease];
[appMenu addItem:quitMenuItem];
[appMenuItem setSubmenu:appMenu];
id window = [[[NSWindow alloc] initWithContentRect:NSMakeRect(10, 10, 200, 200)
styleMask:NSTitledWindowMask backing:NSBackingStoreBuffered defer:NO]
autorelease];
[window setTitle:appName];
[window makeKeyAndOrderFront:nil];
[NSApp activateIgnoringOtherApps:YES];
[NSApp run];
return 0;
}
It works well, except for one little problem: Immediately after the launch, menu is altered, but is inactive (clicking it does nothing). If I select some other application and then get back to that minimal one, menu starts working as expected.
Any idea how to fix this?
Upvotes: 2
Views: 514
Reputation: 51
looks like NSApplicationActivationPolicyRegular
and activateIgnoringOtherApps:
were missing according to https://github.com/rgl/minimal-cocoa-app
here is the updated code:
// cc -o min-cocoa min-cocoa.m -framework Cocoa
#import <Cocoa/Cocoa.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
[NSApplication sharedApplication];
id menubar = [NSMenu new];
id appMenuItem = [NSMenuItem new];
[menubar addItem:appMenuItem];
[NSApp setMainMenu:menubar];
id appMenu = [NSMenu new];
id appName = [[NSProcessInfo processInfo] processName];
id quitTitle = [@"Quit " stringByAppendingString:appName];
id quitMenuItem = [[NSMenuItem alloc] initWithTitle:quitTitle action:@selector(terminate:) keyEquivalent:@"q"] ;
[appMenu addItem:quitMenuItem];
[appMenuItem setSubmenu:appMenu];
id window = [[NSWindow alloc] initWithContentRect:NSMakeRect(10, 10, 200, 200) styleMask:NSWindowStyleMaskTitled backing:NSBackingStoreBuffered defer:NO];
[window setTitle:appName];
[window cascadeTopLeftFromPoint:NSMakePoint(20,20)];
[window makeKeyAndOrderFront:nil];
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
dispatch_async(dispatch_get_main_queue(), ^{
[NSApp activateIgnoringOtherApps:YES];
});
[NSApp run];
}
return 0;
}
Upvotes: 0
Reputation: 85955
I have same problem for minimal apps. They do not process events properly.
At this point (10.15.2 (19C57)) these are what it requires to work properly.
.app
extension. (maybe optional)Contents/Info.plist
with CFBundleIdentifier
value. (no other key is required)Contents/MacOS/(your-executable)
file.Upvotes: 1
Reputation: 47159
It appears to be a bug in macOS
somewhere above version 10.8.5.
I tried the code (and similar variations within 10.13.6) and they all failed in the way you've described. Compiling the same code and running on version 10.8.5 does not have the same behavior and the menu can be accessed normally as one would expect.
Conclusion:
I would recommend reporting the behavior to Apple.
Side Note: You'll want to remove the autorelease
portions of your code as ARC
prohibits this and cannot be used with the latest Xcode SDK's.
Upvotes: 0