Issue with Quit application menu in cocoa application - macos

I have a cocoa application running on Mac OS 10.6.8
I am adding an entry to apple menu in the app, for quitting my application. The code is like this:
item = [menu addItemWithTitle: #"Quit Myapp" , NSLocalizedString(#"Quit", nil), applicationName] action:#selector(terminate:) keyEquivalent:#"q"];
[item setTarget:NSAPP];
Now, my problem is that when a modal dialog is opened using runModal of NSOpenPanel, this quit menu item is still enabled. Rest of the menu items are disabled as usual. I am not able to understand why.
If I change the above code so that menu item's target is not NSApp, but another cocoa object, then the problem disappears.
Could someone please let me know if it is a known issue. Is it wrong to set the NSApp as a menu item's target?

Why don't you use the Application Menu from Interface Builder?

I agree with the others that doing this is probably a bad idea. That said, set (or leave) the target as nil to target the responder chain. That will probably make it disable when a model window is up.
Update:
Hmm. Checking a new MainMenu NIB, I see that the Quit menu item does actually target the application object. So, that may not be the issue.
By the way, in the code snippets above, you're targeting NSAPP, whatever that is, rather than NSApp.
Also, the argument list to -addItemWithTitle:... is all messed up and makes no sense. You should clean up your question to reflect actual code.

Related

macOS / Qt: Disabling the "Quit" menu item on my application's dock menu

I've writing a macOS application with Qt. This application is a launch agent, meaning that it's launched by launchd and always running in the background. Normally the application only has a menu bar icon, and it doesn't have any open windows or a Dock icon. (i.e. the shared NSApplication instance's activationPolicy property is set to a value of NSApplicationActivationPolicyAccessory.)
However, there are a few menu items available in its menu bar item that open some windows, and when those windows are open the app switches to not being background-only any longer, so it will have a Dock icon and menu bar. (i.e. activationPolicy is changed to NSApplicationActivationPolicyRegular.) With there being a Dock icon, that means it's possible for the user to right-click it and open its menu, and that menu has its default menu item for quitting the application.
Since the app is a launch agent, though, and is intended to always be running, quitting it just causes launchd to relaunch the app. I'd like to disable or remove this menu item if possible, or otherwise prevent the user from being able to quit the app in this manner.
Is there any way to do that? If there's a way to accomplish this purely using Qt's functions that would be great, but if not it's fine for me to use macOS specific functions too.
I should add that because this is a Qt application, I can't use the same method as outlined here because I don't have access to the application's delegate. I would need to use another approach. (For example, it may be possible to swizzle methods on Qt's application delegate, though if there's a cleaner way to accomplish this than I'd much rather do that.)
After doing some more research, I've found that it's not possible to remove the "Quit" menu item from an application's Dock menu, or any of the other standard menu items there as they are created and handled by the Dock itself.
It is possible to stop an application from quitting when the user quits the application via the Dock. In a Qt application the method is to subclass QApplication and override its bool event(QEvent *) method. The overridden method should check for events of type QEvent::Close, call the ignore() method on the event, and then return true. Note though that this will stop the application from quitting via all other conventional methods as well.
edit: It is also possible to tell when the app is being quit via the Dock, at least when using Apple's native API. See: macOS: Is there any way to know when the user has tried to quit an application via its Dock icon?
By using Objective-C method swizzling it's possible to override the applicationShouldTerminate: method of Qt's application delegate and prevent a Qt app from being quit by the dock.

Mac app, NSDocument window does not appear in Window menu

I have continued work on an app made by another. It looks in relevant parts identical to the standard NSDocument window-based app that you get when starting a new project (where the Window menu works like normal, ie. the NSDocument appears in the Window menu with the title Untitled).
But in this app, something seems to have happened to the Window menu or the app, that has somehow disconnected this automated behavior from the NSDocument.
Quite substantial work is needed to get this finished, submitted, and later rejected (by reviewers) app into a fresh project.
I'm looking to the experienced Mac app devs for:
What requirements/dependencies need to be fulfilled for the NSDocument to appear in the Window menu as normal?
I have checked MyDocument.h/.m (they are the standard stubs, virtually unchanged), and properties and outlets/delegates in MyDocument.xib, MainMenu.xib (none seem to be missing), and -Info.plist (which is identical to that of a New Project app). I'm experienced with XCode and Cocoa Touch, but not yet with Cocoa.
I'm willing to check things and write test code and give quick feedback, if you would help me over this last hurdle :)
I just had the same problem, and solved it by creating a reference to the window, and showing the window when the nib gets loaded:
- (void)windowControllerDidLoadNib:(NSWindowController *)aController
{
[super windowControllerDidLoadNib:aController];
[window makeKeyAndOrderFront: self];
}
The cause of the problem is still unknown to me. If after trying that it doesn't work, try debugging it. You may discover the real cause, for example the window may have been already deallocated because there isn't any strong reference (not even in NSApp) to it.

Transmit NSMenu commands to the current window?

Newbie OS X developer here, although fairly experienced with iOS.
I am missing something basic about the way the top-level NSMenu interacts with the application. I want the File->Save command to go to the current window. So far I have only been able to receive NSMenu actions in the app delegate. Am I supposed to keep track of the active window there and invoke methods from the app delegate?
Firstly, it sounds like you need to read up on Mac menu handling, because there are a lot of things you need to know about in order to deal with menus correctly.
To answer your specific question, if a menu item has a target of nil, such as the Save menu item, then the menu handling system walks up the responder chain, starting from the currently active control or view (first responder), looking for an object that implements the action selector for that menu item.
If you don't understand how the responder chain works, you should read about that too, because it's fundamental to understanding how Mac apps work.
If you want your window controller to handle the ‑save: action when its window is the main window, then all you need to do is implement the ‑save: action in your window controller. Because the window controller is in the responder chain before the application delegate, its implementation of the method will be used.

update statusbar menu on click mac os x cocoa

I've been playing around with a statusbar menu app and what I'd like it to do is to update the content of the menu when it is clicked. I've been able to get everything working on the awakefromnib function and it works as expected. Now i just want to update the menu everytime I click on the status bar. This surely can be done, since it's done in the dropbox statusbar menu and many of the native app statusbar menus. I'm not able to associate a action directly with the click of the menu and I don't want to leave a loop running in the background cause I don't really see a need for it. Any ideas? An alternative would be to have an action associated to a menu item which does not cause the menu to get hidden again. Any help would be welcome.
Just set a delegate for your menu, and implement the -(void)menuWillOpen:(NSMenu *)menu method.

Mac OS X - app without menu?

I'd like to build an app that does not have a menubar, a dock icon, or sits in the app switcher. Basically, it should be like Quicksilver: I'd active it through a global hot key, say from Safari, and a little window appears, but Safari does not get inactive, neither does a different menubar show. I hope you understand what I mean...
How would I do that? I can prevent the dock icon, the app switcher, but I do not know how I can prevent the other apps from becoming inactive when my app's window shows or how I can remove the menu.
Thanks for any hints!
Try searching for "LSUIElement". That should give you all the information you need.
(Specifically, this page in the documentation).
As Dave already said, add
LSUIElement YES
in your application's Info.plist file. That will get rid of icon and menu bar.
Then, to actually bring a window to the front at the appropriate time (e.g. when triggered through a global keyboard shortcut), you could do something like this:
ProcessSerialNumber psn = {0, kCurrentProcess};
SetFrontProcess(&psn);
[someWindow makeKeyAndOrderFront:nil];

Resources