4

In Mac OS X, what API do I need to call in order to place a window over not only the entire screen, but the menu bar and dock as well? Also, is it possible to effectively "lock" the screen into this position, disabling Mission Control, launchpad, etc.?

I have tried the following code within the App Delegate's implementation file:

- (void)awakeFromNib {
    @try {
        NSApplicationPresentationOptions options = NSApplicationPresentationDisableForceQuit + NSApplicationPresentationDisableHideApplication + NSApplicationPresentationDisableProcessSwitching + NSApplicationPresentationHideDock + NSApplicationPresentationHideMenuBar + NSApplicationPresentationFullScreen;
        [NSApp setPresentationOptions:options];
        NSLog(@"Set presentation options"); 

    }
    @catch (NSException *exception) {
        NSLog(@"Error. Invalid options");
    }

}

NSLog reads "Set presentation options", but nothing else happens. Any tips?

The Kraken
  • 3,158
  • 5
  • 30
  • 67

3 Answers3

5

This would basically involve the same sorts of thing as "kiosk mode". See Apple's Kiosk Mode Programming Topic.

You basically use -[NSApplication setPresentationOptions:] or -[NSView enterFullScreenMode:withOptions:] with an option dictionary containing the key NSFullScreenModeApplicationPresentationOptions whose value is an NSNumber containing the same sort of presentation option values as the NSApplication method takes.

Ken Thomases
  • 88,520
  • 7
  • 116
  • 154
  • Thanks for the response. Please see the above code I have placed in the App Delegate file. Strangely, nothing happens. – The Kraken May 19 '12 at 17:15
  • Nothing, including no output from the `NSLog()` call? – Ken Thomases May 19 '12 at 17:29
  • NSLog does read "Set presentation options", so it is not an invalid call. It's just that nothing is actually happening to the screen. – The Kraken May 19 '12 at 17:37
  • Hmm, not sure what's going on. Seems like it should work. I can't imagine that `NSApp` is `nil`. Well, if you can't get this to work, you can capture the display using [Quartz Display Services](https://developer.apple.com/library/mac/#documentation/graphicsimaging/Conceptual/QuartzDisplayServicesConceptual/Introduction/Introduction.html). That doesn't prevent Force Quit, though. – Ken Thomases May 19 '12 at 17:52
  • Figured it out, had conflicting code in the MainWindow and App Delegate files. – The Kraken May 30 '12 at 22:31
  • How did you avoid Mission Control being able to kick in? – JeremyLaurenson Feb 26 '13 at 03:36
  • `NSApplicationPresentationDisableProcessSwitching` should do that. If it doesn't, you may need to capture the display as I mention in my comment above. – Ken Thomases Feb 26 '13 at 04:38
  • @TheKraken I'm having the same issue. What was the conflicting code? I created a new Cocoa Application in Xcode and just added your code to `AppDelegate.m`. I want the whole screen to turn black and not be able to do anything. But, in debug mode (for testing), I'd like to still be able to hit `⌘.` (or whatever) to kill the app. – ma11hew28 Mar 03 '13 at 12:25
  • I'm having a similar issue. Option+Function key(e.g. option+F2) allows user launch preferences panel, and `NSApplicationPresentationDisableProcessSwitching` can't prevent it in my case. – Daijirō Wachi Jan 18 '17 at 23:31
3

In Xcode, create a new Cocoa Application, and paste the code below in AppDelegate.m.

- (void)awakeFromNib
{
    // Lock app in full screen mode for 10 seconds.
    NSApplicationPresentationOptions presentationOptions = (NSApplicationPresentationHideDock |
                                                            NSApplicationPresentationHideMenuBar |
                                                            NSApplicationPresentationDisableAppleMenu |
                                                            NSApplicationPresentationDisableProcessSwitching |
                                                            NSApplicationPresentationDisableForceQuit |
                                                            NSApplicationPresentationDisableSessionTermination |
                                                            NSApplicationPresentationDisableHideApplication);
    NSDictionary *fullScreenOptions = @{NSFullScreenModeApplicationPresentationOptions: @(presentationOptions)};
    [_window.contentView enterFullScreenMode:[NSScreen mainScreen] withOptions:fullScreenOptions];
    [_window.contentView performSelector:@selector(exitFullScreenModeWithOptions:) withObject:nil afterDelay:10.0];
}

You will still be able to quit the app with ⌘Q. To prevent that, you can delete the Key Equivalent of the Quit Menu Item.

Xcode Interface Builder: Menu Item

Or, you can subclass NSApplication and override -sendEvent: to do nothing, thereby ignoring all events (keyboard, mouse, etc.) sent to your application.

Community
  • 1
  • 1
ma11hew28
  • 121,420
  • 116
  • 450
  • 651
2

The options are |'d together using a bitwise OR:

NSApplicationPresentationOptions options = NSApplicationPresentationDisableForceQuit | NSApplicationPresentationDisableHideApplication | NSApplicationPresentationDisableProcessSwitching | NSApplicationPresentationHideDock | NSApplicationPresentationHideMenuBar | NSApplicationPresentationFullScreen; [NSApp setPresentationOptions:options];

Aditya Vaidyam
  • 6,259
  • 3
  • 24
  • 26