Cocoa : Repport click on dock icon - cocoa

Is there a way to report every mouse click on the application dock icon?

Not completely safe (also activated by double-click on the application itself),
but definitely the most easy way to implement:
- (BOOL)applicationShouldHandleReopen:(NSApplication *)theApplication hasVisibleWindows:(BOOL)flag
Quote from NSApplicationDelegate Protocol Reference:
These events are sent whenever the Finder reactivates an already running application because someone double-clicked it again or used the dock to activate it.

I would like to suggest an alternative solution to the answer provided by Anne, which avoids conflicting with the event in which the user double clicks on the application icon, instead of on the dock icon.
Thus, I suggest to use
- (BOOL)applicationShouldOpenUntitledFile:(NSApplication *)sender;
See also the Apple's documentation.

Related

macOS: How to detect when an application's finder icon has been opened?

When a macOS application is already open and running, is there any way for it to detect when its Finder icon is opened?
In that situation, opening its Finder icon causes the application to become active, and I can detect that event using NSNotificationCenter or the application delegate's applicationDidBecomeActive: method.
However, so far I haven't found a way to distinguish that activation event from any of the other ways an application can become active, such as clicking on its window, clicking on its Dock icon, switching to it using command+tab, activating it with AppleScript, and so on. I tried checking to see if any of these circumstances used an apple event to activate the app with [[NSAppleEventManager sharedAppleEventManager] currentAppleEvent], but it returns nil as there is no current apple event, so that doesn't help.
The app delegate method -applicationShouldHandleReopen:hasVisibleWindows: is called on such a re-open event.
Note that (re-)opening from the Finder, Launchpad, or Dock is the same, by design.

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.

Display NSPopover above dock icon

How can I display an NSPopover above my app's dock icon?
There are two ways to customise the dock menu, based on if your application is running or not. See the Apple documentation for customising it when its open here:
http://developer.apple.com/library/mac/#documentation/Carbon/Conceptual/customizing_docktile/docktasks_cocoa/docktasks_cocoa.html#//apple_ref/doc/uid/TP30000986-CH3-SW1
To summarise, you basically provide a menu in the main application's XIB or storyboard which contains the extra menu options that you want to add to the dock menu.
To customise your Dock icon's menu when the application is not running, see the guide here:
http://developer.apple.com/library/mac/#documentation/Carbon/Conceptual/customizing_docktile/CreatingaDockTilePlug-in/CreatingaDockTilePlug-in.html
Basically, you need to create a plugin which you drop into your application's resource folder. This works very like the original method, but executes inside Finder's dock process.

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];

Why cannot I open the Preferences from each windows?

I have come across this Cocoa application (source code) that shows a main Window.
As long as this window is key it is possible to open the Preferences window from the Main menu as well as by hitting Command-, but when the main window is not key and another window from the same app is, the NSMenuItem is grayed out and the keyboard shortcut does not respond.
I've inspected the xib file associated to the Main Menu and that NSMenuItem is sending a openPreferences:(id)sender IBAction to the FirstResponder which sould be the NSApplication.
What am I missing (I am still a newbie at mac cocoa programming)? How can I fix it so that the preferences are reachable from each application window?
Probably the original author implemented - (BOOL)validateMenuItem:(NSMenuItem *)menuItem and returns NO under some circumstances.
NSMenuValidationProtocol documentation.
Update: Another quick guess: Maybe the object that handles the IBAction for the menu item is not in the responder chain anymore after you open the second window. NSMenuItems are only enabled if the action selector can be found in the responder chain.

Resources