Implementing a "close" button in a OSX menu-bar app - objective-c

My OSX app lives entirely in the menu bar, and thus does not have a conventional "main window" with a close button nor a standard system menu. The app was rejected due to lack of compliance with the HIG: "we have found there is no way to quit the app." Of course, the Cntrl+Q hotkey works, but that's besides the point. To clarify, here's what my app looks like: http://airgif.com/images/mordor.png
The question is: what is the preferred method for implementing a quit button in a menu-bar app? Is it sufficient to simply have a NSButton with the title of "quit app" somewhere within the app's settings?

The usual approach is just to have a quit command at the bottom of the menu.

From the Beginning of Time, Apple has enforced the Human Interface Guidelines.
A way for the user to quit the app is required.
After all, we don’t want OSX to look like some webpages with popups you can’t get rid of.

Related

Cocoa Background Mode When all windows closed

I am developing an OS X app
That uses StatusBar and Also has Windows
I would to move my app to "background" (That only StatusBar will be shown and windows ofc and not applications main menu)
When all it's windows are closed.
(I want to do it so, the app won't appear in cmd+tab menu etc, I want only StatusBar to be).
I am quite don't know where in documents to look for it and if it is even possible.
I have found that in Info.Plist I can put a flag to enable "LSBackgroundOnly" - then I see only my StatusBar.
But I want to switch between background and foreground, Since I want to allow my user to open the main Application Window via the StatusBar menu as well.
What would be the best approach or where to look for this ?
Sorry to flag as a possible duplicate. The other question doesn't exactly have good keywords for searching, but the answer is the same:
Use or modify the code in the answer here.
The info.plist settings are or OSX versions before 10.9 and cannot be changed at runtime. 10.9+ you can use NSApplication's setActivationPolicy and application delegate functions to do what you want. See discussion here and here as well.

OS X menubar extras + Apple HIG + UX pattern in conflict - when quit isn't quit

A quick search of Apple's Human Interface Guidelines and Developer Library yields an unequivocal guideline:
Users, and not apps, place menu bar extras in the menu bar.
Anecdotal data backs that up: submitting an app where - upon quit of a dock process/main view, the extra is left running - yields a tidy rejection.
Now - I'm a User experience designer (UXD) who typically plays, I mean, works in the mobile and web space. So please pardon my lack of Obj C chops, thanks.
I understand well the guideline and behavior/pattern: apps like Skitch, Wunderlist, Evernote, et al however very clearly leave the extra (often termed HelperApp) running in the menu bar on quit of main app. They all, do offer explicit user toggle of this w/i preferences.
There's no additional Human Interface Guidelines w/ specifics around handling this requirement for user control. Must this be included in onboarding? Dialog at 1st quit? Again: I can speak to best behavior UX wise, but my (very senior) dev wants the mandate - how are others not getting rejected?
Focus: what means of user control is/are mandated to avoid rejection?
Known/given: include in preferences
Other: ???
After hours of searching online and Apple Dev guidelines, I humbly bring this question here. There simply isn't time to play a carnival game of requirements: guess, get rejected, repeat. Thanks in advance.
Do you have a button somewhere in your user interface that adds the menu extra to the menu bar? Or does your app just do it automatically without the user telling it to do so?
I think that's the distinction, your app must only add an extra when instructed to do so. Also if the primary purpose of your app is to create a menu extra (eg, I have one that puts a calendar in the menu bar) then just launching the app is an implicit instruction, so it can be added automatically.
Ultimately, this rule really is vague and can't be clarified. What it comes down to, is that there should not be many menu extras in a user's menu bar unless the user explicitly chooses to have them. So unless your app really needs a menu extra, you must disable it by default.
If you think the reviewer should have allowed your app through then reply to the rejection explaining your position. I've had an app change to approved once after doing that.
If they still reject your app, then you can appeal the app rejection.
Alternatively, just disable the menu extra by default and have a button somewhere to add it to the menu bar.
Also, all of this assumes you are using NSStatusItem and not the "real" menu extra system — which is a private API. Only NSStatusItem menu extras can be placed in the app store as far as I know.

Add button to OSX lock screen

Is it possible to alter the existing OSX lock screen ? For example if I wanted to add a button above the users profile image that says "Hello World" on click.. is this possible?
The goal is to run an AppleScript when the button is clicked.
EDIT -
/System/Library/PrivateFrameworks/LoginUIKit.framework
Inside here you have the ability to change the login screen images and such, but also it contains several compiled nib files abbreviated with 'LUI' which I am assuming stands for 'Locked User Interface'. I'm about to set up parallels and try to open them in Snow Leopard with xcode 3.2.6, and see if I can edit the nibs. If I'm able to accomplish this, would editing such files be in violation of their TOS?
Another possibility was running a window above it. On screen lock I can get the window above the screensaver simply by saying
[window setLevel:NSScreenSaverLevel]
but still, that doesn't overlay the login screen.
I feel like this shouldn't even be possible, but I seen something similar on the Knock to Unlock app.
Did you try to use the following line?
[window setLevel:CGShieldingWindowLevel()+1];
I'm using it to do the same as KnockToUnlock and it works like a charm. I see my window above the login screen either if I come on the login screen from the sleep mode or the screensaver.
Hope this helps.

Why does OSX/Cocoa dock icon revert to default before going away?

I'm working on wrapping some Cocoa functionality in an Objective-C library that will be called from a cross-platform C library. One of my goals is to provide someone who does development in C on Linux with the ability to deploy to OSX without having to get into XCode, nib files, etc. I want them to be able to compile and link their code on OSX using the command line tools, and end up with a regular resizeable main window with the usual buttons and so on, an application menu and a dock icon that looks and behaves as expected, etc.
I'm working on OSX 10.8.5. I have XCode 5.0 installed. Here's my gcc --version output:
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 5.0 (clang-500.2.76) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin12.5.0
Thread model: posix
I've figured out how to present a main window, how to set up the application menu, and various other things, programmatically, without using XCode or any nib or plist, but I've run into a problem with the dock icon.
I set a custom dock icon image by calling:
[NSApp setApplicationIconImage:dockImage];
When the user quits the app, the dock icon image reverts to something else (some kind of default application icon or view), briefly, before going away. How can I prevent that from happening without using XCode to create a nib or a plist?
I've tried setting the activation policy of NSApp to prohibitted in the app delegate's applicationShouldTerminate method, to try to hide the dock icon before this switch back occurs. That didn't help, it does hide the window and the dock icon, but the dock icon still switches back to the default icon, briefly, as part of the process of hiding. I confirmed this by returning NSTerminateLator, and confirming that setting the activation policy to prohibited does cause the dock and the icon to hide even though the app is not terminating, and not setting it leaves it unhidden.
I've tried subclassing NSApplication and overriding the setApplicationIconImage call. I have confirmed that it is being called a second time, by something other than my code (well, or not directly by my code, anyway), just before the program exits. I've tried preventing the second call to it from working by calling the super function the first time, but not the second time, and I've confirmed that code in that function can prevent my code from changing the application icon, but that didn't fix the problem. It still happens anyway, somehow.
I've also tried removing the application badge, like this:
[[window dockTile] setShowsApplicationBadge: NO];
just in case it was something to do with that, but that didn't work. The docs say that app badges are no longer relevant as of 10.6, but I was grasping at straws.
Being stumped on the programmatic front, I'm now trying to find out how to package an .app from scratch,without using XCode, and see if maybe I can create a plist from scratch that has a reference to application image in it. But a programmatic solution would be preferable, as I'd really like to minimize what goes into the OSX-specific packaging of a deployment.
Another possibility might be to use XCode once, to produce a very generic, bare-bones .app that my deployment scripts copy and alter.
Please don't shoot my question down as being "too broad" or "not constructive" or something like that. I realize I'm reinventing wheels that already exist in various forms, but there's no law against trying to build a better mouse trap, or just a different or even a worse one, for that matter. I realize I'm trying to fix a problem that a lot of people would consider inconsequential, but XCode-produced apps don't have this problem, and I really don't want the tools I'm creating to produce any user-visible artifacts like that. I'm not intending to diss Apple's tool chain or invite debate about whether or not what I'm pursuing should be pursued. I have a specific, technical problem that I'm looking for solution to that is within the constraints of my goals.

Locking a screen in 10.6

How would I go about locking a screen like Keychain does, meaning preventing all access to Dock, menubar, desktop, etc. Basically just a black screen that I can add a password field to, for the user to return to the desktop? I am well aware of the Carbon method, but I want the NSApplication method because this is an all Cocoa application.
Thanks~
If you can get away with not writing this code yourself, all for the better. It is usually a terrible idea to write your own code to lock the screen, considering the number of vulnerabilities that have been found in screen locking code over the years. If you have a Carbon call that can do it, go ahead and use that... don't worry about the "purity" of your Cocoa code.
However, if you decide to write this yourself, here's what you do:
First, capture all the screens using CoreGraphics. See: http://developer.apple.com/mac/library/documentation/GraphicsImaging/Conceptual/QuartzDisplayServicesConceptual/Articles/DisplayCapture.html
Next, create a new NSWindow and put it in front of the window that's used for capturing the screens. You'll have to call a CG function to get the "order" of the black window covering each screen, and order the new window in front of that. Normally, the black window has an order so far forward that everything is behind it. Put a password field in the window. Do NOT use an ordinary text field or write your own code for password input. The password input field has a ton of special code in it so you can't copy text out of it, and other programs can't listen to keystrokes while you're typing into a password field. So use the one that Apple provides.
Last, put the computer in "kiosk mode". This mode allows you to disable alt-tab, user switching, the menubar and dock, and even the ability to force quit. See: http://developer.apple.com/mac/library/technotes/KioskMode/Introduction/Introduction.html
It's not a lot of code, it just uses a few different APIs so you'll spend most of your time bouncing between API docs. I suggest writing the screen lock code as its own application (just add a new application target to your Xcode project) and then put the screen locker inside your application bundle. This used to be (as of 10.4) how Apple Remote Desktop implemented the "Lock Screen" functionality, but I can't find the app anymore.
I believe the Cocoa replacement to the SetSystemUIMode API was not introduced until 10.6.
If you can live with Snow-Leopard-only code, the answer is - setPresentationOptions: on NSApplication.