Journal

By Steve Challis

Recent Entries

Archive

RSS/Atom

Home

Projects

Taking OpenGL Fullscreen with Cocoa

February 6th, 2010 — 4 Comments — Permalink

  • opengl
  • cocoa
  • objective-c
  • xcode
  • interface-builder
  • how-to

This is a quick how-to on dynamically making a Cocoa OpenGL view fullscreen. It's pretty simple really - when the user initiates fullscreen, we call a method on our view which creates a new borderless window on top of all other windows and sets the contents to be our view. For this, I'm going to go ahead and assume that you have created a custom OpenGLView and have instantiated it in a regular NSWindow.

We'll start off by adding a few variables to the view interface. These will allow us to keep track of the non-fullscreen starting window and our newly created fullscreen window, as well as which state we are in. It is important to keep track of the starting window so that we know where to restore the view to when switching away from fullscreen.

@interface MyOpenGLView : NSOpenGLView {
    NSWindow *fullscreenWindow;
    NSWindow *startingWindow;
    BOOL fullscreenOn;
}

@property (assign) IBOutlet NSWindow *startingWindow;

- (IBAction) toggleFullscreen:(id)sender;

Now, in the implementation we synthesize startingWindow so that we have access to it:

@synthesize startingWindow;

Also in the implementation, the toggleFullscreen method should look something like this:

- (IBAction) toggleFullScreen:(id)sender {
    if( fullscreenOn == true ) {
        [fullscreenWindow close];
        [startingWindow setAcceptsMouseMovedEvents:YES];
        [startingWindow setContentView: self];
        [startingWindow makeKeyAndOrderFront: self];
        [startingWindow makeFirstResponder: self];
        fullscreenOn = false;
    }
    else  {
        NSRect frame = [[NSScreen mainScreen] frame];
        // Instantiate new borderless window
        fullscreenWindow = [[NSWindow alloc]
                            initWithContentRect:frame
                            styleMask:NSBorderlessWindowMask
                            backing:NSBackingStoreBuffered
                            defer: NO];
        [startingWindow setAcceptsMouseMovedEvents:NO];
        if(fullscreenWindow != nil) {
            // Set the options for our new fullscreen window
            [fullscreenWindow setTitle: @"Full Screen"];            
            [fullscreenWindow setReleasedWhenClosed: YES];
            [fullscreenWindow setAcceptsMouseMovedEvents:YES];
            [fullscreenWindow setContentView: self];
            [fullscreenWindow makeKeyAndOrderFront:self ];
            // By setting the window level to just beneath the screensaver,
            // only this window will be visible (no menu bar or dock)
            [fullscreenWindow setLevel: NSScreenSaverWindowLevel-1];
            [fullscreenWindow makeFirstResponder:self];
            fullscreenOn = true;
        } else {
            NSLog(@"Error: could not create fullscreen window!");
        }
    }
}

We can now tie everything together in Interface Builder by hooking up the startingWindow outlet to our main window:

Connect the view outlet to out main window

And finally, create a menu option which we hook up to the toggleFullscreen action of our view:

Connect the fullscreen menu option to the toggleFullscreen action of our view

Save, rebuild and enjoy fullscreen goodness!

Discussion

  • Dan 1 month, 2 weeks ago

    This is exactly what I want to do, but it's assuming I've set up the project already for this code... care to elaborate for beginners?

  • Steve Challis 1 month, 1 week ago

    Dan, the process of creating a project and a custom OpenGLView is described in this post. It is simply a matter of selecting the default Cocoa Application template and then subclassing NSOpenGLView.

  • Bastiaan Olij 3 weeks ago

    Great post, thanks!

    Only thing for me that doesn't want to work (yet) is that returning from fullscreen to windowed mode, my openGL view isn't showing anymore. Any ideas what i have overlooked?

  • Bastiaan Olij 2 weeks, 6 days ago

    Brilliant! I had overlooked the second to last step, hooking up the startingWindow outlet.

    Works like a charm!

Leave A Reply

You may use Markdown syntax but raw HTML will be escaped and headings normalised.

Log in

Powered by Mumblr – a basic Django tumblelog application that uses MongoDB with MongoEngine. Fork it on Github. Designed and developed by Harry Marr and Steve Challis.

Unless otherwise noted, everything here is available under the Creative Commons Attribution-Share Alike 3.0 license. Sharing is fucking cool.

Home / Projects / Recent / Archive / RSS /