Main menu:

Site search

 

July 2017
M T W T F S S
« Oct    
 12
3456789
10111213141516
17181920212223
24252627282930
31  

Categories

Archives

Links:

Going fullscreen in Cocoa - Part III

Time for a completely different approach. This time when I start the fade out to black, I create a borderless window with the same dimensions as the screen I want to fade. This window has a black background but with an initial alpha value of 0.0 (so it’s not visible yet). Let’s call this a curtain window which act as a layer above anything else that might be on the screen. During the fading period, I increase the alpha value in small steps to 1.0 so that the black background of the curtain window becomes gradually visible thus obscuring everything below it. During the reverse fade, I change the alpha value back to 0.0 again in small steps and at the end I simply remove the curtain window.

During the fade process, I also hide the cursur using

[NSCursor hide];

and

[NSCursor unhide];

This is the final fade code:

NSWindow    *curtainWindow;

...

- (void)fadeInDisplay:(NSScreen*)theScreen
             fadeTime:(double)fadeTime
{
    int     fadeSteps       = 100;
    double  fadeInterval    = (fadeTime / (double) fadeSteps);

    int     step;
    double  fade;

    if ([self curtainWindow] != nil)
    {
        for (step = 0; step < fadeSteps; step++)
        {
            fade = 1.0 - (step * fadeInterval);
            [[self curtainWindow] setAlphaValue:fade];

            NSDate *nextDate = [NSDate dateWithTimeIntervalSinceNow:fadeInterval];
            [[NSRunLoop currentRunLoop] runUntilDate:nextDate];
        } /* end for */
    } /* end if */
    [[self curtainWindow] close];
    [self setCurtainWindow:nil];

    [NSCursor unhide];
} /* end fadeInDisplay:fadeTime: */

- (void)fadeOutDisplay:(NSScreen*)theScreen
              fadeTime:(double)fadeTime;
{
    int     fadeSteps       = 100;
    double  fadeInterval    = (fadeTime / (double) fadeSteps);

    int     step;
    double  fade;

    [NSCursor hide];

    [self setCurtainWindow:[[NSWindow alloc]
        initWithContentRect:[theScreen frame]
                  styleMask:NSBorderlessWindowMask
                    backing:NSBackingStoreBuffered
                      defer:YES
                     screen:theScreen]];

    [[self curtainWindow] setAlphaValue:0.0];
    [[self curtainWindow] setBackgroundColor:[NSColor blackColor]];
    [[self curtainWindow] setLevel:NSScreenSaverWindowLevel];

    [[self curtainWindow] makeKeyAndOrderFront:nil];
    [[self curtainWindow] setFrame:[[self curtainWindow]
        frameRectForContentRect:[theScreen frame]]
                           display:YES
                           animate:NO];

    for (step = 0; step < fadeSteps; step++)
    {
        fade = step * fadeInterval;
        [[self curtainWindow] setAlphaValue:fade];

        NSDate *nextDate = [NSDate dateWithTimeIntervalSinceNow:fadeInterval];
        [[NSRunLoop currentRunLoop] runUntilDate:nextDate];
    } /* end for */
} /* end fadeOutDisplay:fadeTime: */

For me, this works a lot better than changing the gamma values as in part II of the series. The screen fades smoothly to black without becoming first brighter as it happened when I change the gamma values of a screen. And I don’t have to worry about that kCGErrorNoneAvailable error code.

And here you can download a small sample project: goFullScreen_part_III_usingLayer.zip

Write a comment

You need to login to post comments!