Deactivate agent app after launch in Cocoa - cocoa

What method should be called to deactivate an app right after it's launch in applicationDidFinishLaunching: delegate method has been called? Or maybe there is a better place to do that? The documentation for deactivate method for NSApplication says that I shouldn't call this method directly since AppKit knows better how to deactivate stuff.

Maybe using -[NSApplication hide:] would work, or perhaps activate another app using -[NSRunningApplication activateWithOptions:] (10.6 only, tho). However, I don't foresee many problems with using deactivate:.

It's not clear what you're trying to achieve.
You can use -hide: to deactivate your app. I also wouldn't hesitate using -deactivate if it actually does what you need. It's just that normal applications do not explicitly deactivate themselves; I think that's what the documentation is saying.
However, if you set LSUIElement in Info.plist your application should not become active when launched; it also won't have a menu bar or dock icon.

Related

Mac - How to programmatically hide NSApplicationActivationPolicyAccessory or LSUIElement application?

I have a small Swift-based Cocoa app that I'm writing. It's a single window app, something like Spotlight/QuickSilver/Alfred. It's set as NSApplicationActivationPolicyAccessory (docs) (though I've tried the same thing using LSUIElement, which is equivalent). It's activated via a global hot key.
Everything works well, except that when it's active I can't hide the application using NSRunningApplication.currentApplication().hide().
The docs for the hide method say "The property of this value will be NO if the application has already quit, or if of a type that is unable to be hidden." (emphasis mine), and I'm getting a NO back (though I'm actually using Swift, so I'm getting false).
I can understand why a NSApplicationActivationPolicyProhibited app wouldn't be able to be hidden, since it's never active, but it's confusing to me that this would be the case with NSApplicationActivationPolicyAccessory too.
I tried myWindow.orderOut(self);, but that just hides the window without hiding my application and returning focus to the previous app.
I do store a reference to the previously active application, so if need be I can manually activate that app again, but I'm hoping there is a cleaner method of doing this.
Use NSApplication.sharedApplication().hide(nil). One would normally address the application object (instance of NSApplication) rather than an instance of NSRunningApplication to operate on the current app.
The manual solution is to store a reference to the previously active NSRunningApplication instance (called previouslyActiveApplication below), and then activate it when you want to deactivate your NSApplicationActivationPolicyAccessory application, like so:
previouslyActiveApplication!.activateWithOptions(NSApplicationActivationOptions.ActivateIgnoringOtherApps);

Cocoa osx: Add a menu item on dock elements for all running applications

I'm working to an application for OSX and I would to add a new menu item on the menu shown when you click on a dock icon.
The menu isn't for my application but it must appear for all running apps.
I've found only this doc http://cocoadevcentral.com/articles/000036.php but it adds to its own app.
My app will run on OSX 10.6 or superior
You can't do that with the public API. You need to inject code into the Dock. In 10.6, the standard way to inject the code is to use the OSAX loading trick, described in this blog post for that. Then you need to do Objective-C runtime hackery to replace the method, using method_exchangeImplementations.
Anyway it's a tricky process. But if you have the will, you can. SIMBL might (or might not) help you.

Cocoa NSStatusBar Global HotKey

I have created an NSStatusBar cocoa application which sits in the system status bar.
I want to assign a hotkey so that when pressed it toggles my applications and show the menu.
Is this possible?, In my searching and experimenting I have found a few different ways of assigning global hot keys that can be pressed when your application is in the background but I can't find any way to problematically make the menu show.
Is this possible?, If anyone thinks a way of assigning a global hotkey is best please post it.
Thanks.
One of the hotkey tutorials I found was on http://dbachrach.com/blog/2005/11/program-global-hotkeys-in-cocoa-easily/ for anyone interested.
If you're targeting 10.6+, there's some new API for NSEvent that can do global hotkeys. For more information, check out this awesome blog post: http://cocoakids.net/global-hotkeys-in-cocoa-on-snow-leopard
EDIT (a long time later)
Tooting my own horn a bit: I could never get things like PTHotKey and other libraries to work the way I was expecting, so I eventually gave up and wrote my own HotKey wrapper. It has a very simple API (you give it a key code, modifiers, a target, and an action), that even supports fun things like 10.6's blocks. You can download the source here: http://github.com/davedelong/DDHotKey
There is an actual hotkey API, which still exists in Snow Leopard and is available in 64-bit. It's designed specifically for this purpose, unlike the NSEvent methods, which are essentially just a block-based wrapper around CGEventTaps.
The difference is that the NSEvent methods (or CGEventTaps directly) make you look at every event that comes in, whereas the hotkey API only calls your function when the user presses your hotkey.

Localizing Application (main) Menu?

I'm porting a UNIX application which uses the Qt framework (Qt, not QuickTime) to Mac/Cocoa. Life is good, generally. Qt has a Cocoa implementation, so with some Objective-C++, I've gotten lots of Mac-specific bits working.
I can't get the main menu (i.e., the Application menu) to translate. It's set using:
[NSApp setMainMenu:menu];
I've got my en.lproj, ja.lproj, fr.lproj, etc. folders set up, and they have InfoPlist.strings files. Qt handles the internal localization of application-specific menus. But if I switch languages, I still have "Quit Avogadro".
I've read through as much documentation in the Mac Dev Center as possible, but can't find an answer.
I know that strings in the mainMenu are handled by Cocoa -- they're not localized in any Apple application. Any ideas on the magic trigger? Any ideas for where to look?
Thanks in advance!
I wanted to add some information to this, in case someone else is looking to do this. I was also trying to modify the application main menu and I was attempting to set it in the awakeFromNib method. This never worked because according to this thread we need to modify the application main menu AFTER the menu has been set. Otherwise, the application will always use the title found in its Info.plist. So, this means that if you ever change your application's name, you never have to update your application's MainMenu.nib.
It turns out that this was a Qt bug: https://bugreports.qt-project.org//browse/QTBUG-4463
It's fixed in Qt 4.7 and later

OS X - App doesn't show up in force quit. How do I fix that?

I'm writing a Cocoa application that installs itself as an menulet in the menu bar (i.e. like the volume or battery icons). When the program crashes, it isn't possible to use the Force-Quit dialog, because it doesn't show up in the list. Of course, I can still kill it using the command-line, but my users don't know how to do that. Is there any way to fix this, say by making the program show up in the Force-Quit dialog?
(Note: the app is Leopard only).
To be honest, the proper solution is to make sure your app never hangs or crashes for users. This should be your #1 priority, rather than figuring out how to let users deal with crashes and hangs. Obviously it isn't always possible to make sure your app never breaks in these ways, but it should definitely be the exception rather than the rule.
On another note, MenuExtras is a private API which I hope you aren't using to create your "menulet". Rather, the public class NSStatusItem (part of Cocoa) is the Apple-approved, recommended way to install icons into your menu bar.
Not really an answer, but hopefully helpful still ...
I think that most people who know how to force quit also know they can kill a process in the activity monitor. Just make sure it's not named '93AZkZ' or something.
You could provide a PreferencePane for your application that can send the proper signal to it, if you want to allow users an easy way to shut it down or restart it. This is the pattern that MySQL uses on OS X.

Resources