12bde8e466a4451c7319e3a072d118917957d6554Steve Block/*
22bde8e466a4451c7319e3a072d118917957d6554Steve Block * Copyright (C) 2009, 2010, 2011 Apple Inc. All rights reserved.
32bde8e466a4451c7319e3a072d118917957d6554Steve Block *
42bde8e466a4451c7319e3a072d118917957d6554Steve Block * Redistribution and use in source and binary forms, with or without
52bde8e466a4451c7319e3a072d118917957d6554Steve Block * modification, are permitted provided that the following conditions
62bde8e466a4451c7319e3a072d118917957d6554Steve Block * are met:
72bde8e466a4451c7319e3a072d118917957d6554Steve Block * 1. Redistributions of source code must retain the above copyright
82bde8e466a4451c7319e3a072d118917957d6554Steve Block *    notice, this list of conditions and the following disclaimer.
92bde8e466a4451c7319e3a072d118917957d6554Steve Block * 2. Redistributions in binary form must reproduce the above copyright
102bde8e466a4451c7319e3a072d118917957d6554Steve Block *    notice, this list of conditions and the following disclaimer in the
112bde8e466a4451c7319e3a072d118917957d6554Steve Block *    documentation and/or other materials provided with the distribution.
122bde8e466a4451c7319e3a072d118917957d6554Steve Block *
132bde8e466a4451c7319e3a072d118917957d6554Steve Block * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
142bde8e466a4451c7319e3a072d118917957d6554Steve Block * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
152bde8e466a4451c7319e3a072d118917957d6554Steve Block * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
162bde8e466a4451c7319e3a072d118917957d6554Steve Block * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
172bde8e466a4451c7319e3a072d118917957d6554Steve Block * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
182bde8e466a4451c7319e3a072d118917957d6554Steve Block * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
192bde8e466a4451c7319e3a072d118917957d6554Steve Block * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
202bde8e466a4451c7319e3a072d118917957d6554Steve Block * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
212bde8e466a4451c7319e3a072d118917957d6554Steve Block * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
222bde8e466a4451c7319e3a072d118917957d6554Steve Block * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
232bde8e466a4451c7319e3a072d118917957d6554Steve Block * THE POSSIBILITY OF SUCH DAMAGE.
242bde8e466a4451c7319e3a072d118917957d6554Steve Block */
252bde8e466a4451c7319e3a072d118917957d6554Steve Block
262bde8e466a4451c7319e3a072d118917957d6554Steve Block#import "config.h"
272bde8e466a4451c7319e3a072d118917957d6554Steve Block
282bde8e466a4451c7319e3a072d118917957d6554Steve Block#if ENABLE(FULLSCREEN_API)
292bde8e466a4451c7319e3a072d118917957d6554Steve Block
302bde8e466a4451c7319e3a072d118917957d6554Steve Block#import "WKFullScreenWindowController.h"
312bde8e466a4451c7319e3a072d118917957d6554Steve Block
322bde8e466a4451c7319e3a072d118917957d6554Steve Block#import "LayerTreeContext.h"
332bde8e466a4451c7319e3a072d118917957d6554Steve Block#import "WKAPICast.h"
342bde8e466a4451c7319e3a072d118917957d6554Steve Block#import "WKViewInternal.h"
352bde8e466a4451c7319e3a072d118917957d6554Steve Block#import "WebFullScreenManagerProxy.h"
362bde8e466a4451c7319e3a072d118917957d6554Steve Block#import "WebPageProxy.h"
372bde8e466a4451c7319e3a072d118917957d6554Steve Block#import <Carbon/Carbon.h> // For SetSystemUIMode()
382bde8e466a4451c7319e3a072d118917957d6554Steve Block#import <IOKit/pwr_mgt/IOPMLib.h> // For IOPMAssertionCreate()
392bde8e466a4451c7319e3a072d118917957d6554Steve Block#import <QuartzCore/QuartzCore.h>
402bde8e466a4451c7319e3a072d118917957d6554Steve Block#import <WebCore/FloatRect.h>
412bde8e466a4451c7319e3a072d118917957d6554Steve Block#import <WebCore/IntRect.h>
422bde8e466a4451c7319e3a072d118917957d6554Steve Block#import <WebKitSystemInterface.h>
432bde8e466a4451c7319e3a072d118917957d6554Steve Block
442bde8e466a4451c7319e3a072d118917957d6554Steve Blockstatic const NSTimeInterval tickleTimerInterval = 1.0;
452bde8e466a4451c7319e3a072d118917957d6554Steve Block
462bde8e466a4451c7319e3a072d118917957d6554Steve Blockusing namespace WebKit;
472bde8e466a4451c7319e3a072d118917957d6554Steve Blockusing namespace WebCore;
482bde8e466a4451c7319e3a072d118917957d6554Steve Block
492bde8e466a4451c7319e3a072d118917957d6554Steve Block#if defined(BUILDING_ON_LEOPARD)
502bde8e466a4451c7319e3a072d118917957d6554Steve Block@interface CATransaction(SnowLeopardConvenienceFunctions)
512bde8e466a4451c7319e3a072d118917957d6554Steve Block+ (void)setDisableActions:(BOOL)flag;
522bde8e466a4451c7319e3a072d118917957d6554Steve Block+ (void)setAnimationDuration:(CFTimeInterval)dur;
532bde8e466a4451c7319e3a072d118917957d6554Steve Block@end
542bde8e466a4451c7319e3a072d118917957d6554Steve Block
552bde8e466a4451c7319e3a072d118917957d6554Steve Block@implementation CATransaction(SnowLeopardConvenienceFunctions)
562bde8e466a4451c7319e3a072d118917957d6554Steve Block+ (void)setDisableActions:(BOOL)flag
572bde8e466a4451c7319e3a072d118917957d6554Steve Block{
582bde8e466a4451c7319e3a072d118917957d6554Steve Block    [self setValue:[NSNumber numberWithBool:flag] forKey:kCATransactionDisableActions];
592bde8e466a4451c7319e3a072d118917957d6554Steve Block}
602bde8e466a4451c7319e3a072d118917957d6554Steve Block
612bde8e466a4451c7319e3a072d118917957d6554Steve Block+ (void)setAnimationDuration:(CFTimeInterval)dur
622bde8e466a4451c7319e3a072d118917957d6554Steve Block{
632bde8e466a4451c7319e3a072d118917957d6554Steve Block    [self setValue:[NSNumber numberWithDouble:dur] forKey:kCATransactionAnimationDuration];
642bde8e466a4451c7319e3a072d118917957d6554Steve Block}
652bde8e466a4451c7319e3a072d118917957d6554Steve Block@end
662bde8e466a4451c7319e3a072d118917957d6554Steve Block
672bde8e466a4451c7319e3a072d118917957d6554Steve Block#endif
682bde8e466a4451c7319e3a072d118917957d6554Steve Block
692bde8e466a4451c7319e3a072d118917957d6554Steve Block@interface WKFullScreenWindow : NSWindow
702bde8e466a4451c7319e3a072d118917957d6554Steve Block{
712bde8e466a4451c7319e3a072d118917957d6554Steve Block    NSView* _animationView;
722bde8e466a4451c7319e3a072d118917957d6554Steve Block    CALayer* _backgroundLayer;
732bde8e466a4451c7319e3a072d118917957d6554Steve Block}
742bde8e466a4451c7319e3a072d118917957d6554Steve Block- (CALayer*)backgroundLayer;
752bde8e466a4451c7319e3a072d118917957d6554Steve Block- (NSView*)animationView;
762bde8e466a4451c7319e3a072d118917957d6554Steve Block@end
772bde8e466a4451c7319e3a072d118917957d6554Steve Block
782bde8e466a4451c7319e3a072d118917957d6554Steve Block@interface WKFullScreenWindowController(Private)
792bde8e466a4451c7319e3a072d118917957d6554Steve Block- (void)_requestExitFullScreenWithAnimation:(BOOL)animation;
802bde8e466a4451c7319e3a072d118917957d6554Steve Block- (void)_updateMenuAndDockForFullScreen;
812bde8e466a4451c7319e3a072d118917957d6554Steve Block- (void)_updatePowerAssertions;
822bde8e466a4451c7319e3a072d118917957d6554Steve Block- (WKFullScreenWindow *)_fullScreenWindow;
832bde8e466a4451c7319e3a072d118917957d6554Steve Block- (CFTimeInterval)_animationDuration;
842bde8e466a4451c7319e3a072d118917957d6554Steve Block- (void)_swapView:(NSView*)view with:(NSView*)otherView;
852bde8e466a4451c7319e3a072d118917957d6554Steve Block- (WebFullScreenManagerProxy*)_manager;
862bde8e466a4451c7319e3a072d118917957d6554Steve Block@end
872bde8e466a4451c7319e3a072d118917957d6554Steve Block
882bde8e466a4451c7319e3a072d118917957d6554Steve Block@interface NSWindow(IsOnActiveSpaceAdditionForTigerAndLeopard)
892bde8e466a4451c7319e3a072d118917957d6554Steve Block- (BOOL)isOnActiveSpace;
902bde8e466a4451c7319e3a072d118917957d6554Steve Block@end
912bde8e466a4451c7319e3a072d118917957d6554Steve Block
922bde8e466a4451c7319e3a072d118917957d6554Steve Block@implementation WKFullScreenWindowController
932bde8e466a4451c7319e3a072d118917957d6554Steve Block
942bde8e466a4451c7319e3a072d118917957d6554Steve Block#pragma mark -
952bde8e466a4451c7319e3a072d118917957d6554Steve Block#pragma mark Initialization
962bde8e466a4451c7319e3a072d118917957d6554Steve Block- (id)init
972bde8e466a4451c7319e3a072d118917957d6554Steve Block{
982bde8e466a4451c7319e3a072d118917957d6554Steve Block    NSWindow *window = [[WKFullScreenWindow alloc] initWithContentRect:NSZeroRect styleMask:NSBorderlessWindowMask backing:NSBackingStoreBuffered defer:NO];
992bde8e466a4451c7319e3a072d118917957d6554Steve Block    self = [super initWithWindow:window];
1002bde8e466a4451c7319e3a072d118917957d6554Steve Block    [window release];
1012bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!self)
1022bde8e466a4451c7319e3a072d118917957d6554Steve Block        return nil;
1032bde8e466a4451c7319e3a072d118917957d6554Steve Block    [self windowDidLoad];
1042bde8e466a4451c7319e3a072d118917957d6554Steve Block
1052bde8e466a4451c7319e3a072d118917957d6554Steve Block    return self;
1062bde8e466a4451c7319e3a072d118917957d6554Steve Block}
1072bde8e466a4451c7319e3a072d118917957d6554Steve Block
1082bde8e466a4451c7319e3a072d118917957d6554Steve Block- (void)dealloc
1092bde8e466a4451c7319e3a072d118917957d6554Steve Block{
1102bde8e466a4451c7319e3a072d118917957d6554Steve Block    [self setWebView:nil];
1112bde8e466a4451c7319e3a072d118917957d6554Steve Block
1122bde8e466a4451c7319e3a072d118917957d6554Steve Block    [NSObject cancelPreviousPerformRequestsWithTarget:self];
1132bde8e466a4451c7319e3a072d118917957d6554Steve Block
1142bde8e466a4451c7319e3a072d118917957d6554Steve Block    [[NSNotificationCenter defaultCenter] removeObserver:self];
1152bde8e466a4451c7319e3a072d118917957d6554Steve Block    [super dealloc];
1162bde8e466a4451c7319e3a072d118917957d6554Steve Block}
1172bde8e466a4451c7319e3a072d118917957d6554Steve Block
1182bde8e466a4451c7319e3a072d118917957d6554Steve Block- (void)windowDidLoad
1192bde8e466a4451c7319e3a072d118917957d6554Steve Block{
1202bde8e466a4451c7319e3a072d118917957d6554Steve Block    [super windowDidLoad];
1212bde8e466a4451c7319e3a072d118917957d6554Steve Block
1222bde8e466a4451c7319e3a072d118917957d6554Steve Block    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidResignActive:) name:NSApplicationDidResignActiveNotification object:NSApp];
1232bde8e466a4451c7319e3a072d118917957d6554Steve Block    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidChangeScreenParameters:) name:NSApplicationDidChangeScreenParametersNotification object:NSApp];
1242bde8e466a4451c7319e3a072d118917957d6554Steve Block}
1252bde8e466a4451c7319e3a072d118917957d6554Steve Block
1262bde8e466a4451c7319e3a072d118917957d6554Steve Block#pragma mark -
1272bde8e466a4451c7319e3a072d118917957d6554Steve Block#pragma mark Accessors
1282bde8e466a4451c7319e3a072d118917957d6554Steve Block
1292bde8e466a4451c7319e3a072d118917957d6554Steve Block- (WKView*)webView
1302bde8e466a4451c7319e3a072d118917957d6554Steve Block{
1312bde8e466a4451c7319e3a072d118917957d6554Steve Block    return _webView;
1322bde8e466a4451c7319e3a072d118917957d6554Steve Block}
1332bde8e466a4451c7319e3a072d118917957d6554Steve Block
1342bde8e466a4451c7319e3a072d118917957d6554Steve Block- (void)setWebView:(WKView *)webView
1352bde8e466a4451c7319e3a072d118917957d6554Steve Block{
1362bde8e466a4451c7319e3a072d118917957d6554Steve Block    [webView retain];
1372bde8e466a4451c7319e3a072d118917957d6554Steve Block    [_webView release];
1382bde8e466a4451c7319e3a072d118917957d6554Steve Block    _webView = webView;
1392bde8e466a4451c7319e3a072d118917957d6554Steve Block}
1402bde8e466a4451c7319e3a072d118917957d6554Steve Block
1412bde8e466a4451c7319e3a072d118917957d6554Steve Block#pragma mark -
1422bde8e466a4451c7319e3a072d118917957d6554Steve Block#pragma mark Notifications
1432bde8e466a4451c7319e3a072d118917957d6554Steve Block
1442bde8e466a4451c7319e3a072d118917957d6554Steve Block- (void)applicationDidResignActive:(NSNotification*)notification
1452bde8e466a4451c7319e3a072d118917957d6554Steve Block{
1462bde8e466a4451c7319e3a072d118917957d6554Steve Block    // Check to see if the fullScreenWindow is on the active space; this function is available
1472bde8e466a4451c7319e3a072d118917957d6554Steve Block    // on 10.6 and later, so default to YES if the function is not available:
1482bde8e466a4451c7319e3a072d118917957d6554Steve Block    NSWindow* fullScreenWindow = [self _fullScreenWindow];
1492bde8e466a4451c7319e3a072d118917957d6554Steve Block    BOOL isOnActiveSpace = ([fullScreenWindow respondsToSelector:@selector(isOnActiveSpace)] ? [fullScreenWindow isOnActiveSpace] : YES);
1502bde8e466a4451c7319e3a072d118917957d6554Steve Block
1512bde8e466a4451c7319e3a072d118917957d6554Steve Block    // Replicate the QuickTime Player (X) behavior when losing active application status:
1522bde8e466a4451c7319e3a072d118917957d6554Steve Block    // Is the fullScreen screen the main screen? (Note: this covers the case where only a
1532bde8e466a4451c7319e3a072d118917957d6554Steve Block    // single screen is available.)  Is the fullScreen screen on the current space? IFF so,
1542bde8e466a4451c7319e3a072d118917957d6554Steve Block    // then exit fullScreen mode.
1552bde8e466a4451c7319e3a072d118917957d6554Steve Block    if ([fullScreenWindow screen] == [[NSScreen screens] objectAtIndex:0] && isOnActiveSpace)
1562bde8e466a4451c7319e3a072d118917957d6554Steve Block        [self _requestExitFullScreenWithAnimation:NO];
1572bde8e466a4451c7319e3a072d118917957d6554Steve Block}
1582bde8e466a4451c7319e3a072d118917957d6554Steve Block
1592bde8e466a4451c7319e3a072d118917957d6554Steve Block- (void)applicationDidChangeScreenParameters:(NSNotification*)notification
1602bde8e466a4451c7319e3a072d118917957d6554Steve Block{
1612bde8e466a4451c7319e3a072d118917957d6554Steve Block    // The user may have changed the main screen by moving the menu bar, or they may have changed
1622bde8e466a4451c7319e3a072d118917957d6554Steve Block    // the Dock's size or location, or they may have changed the fullScreen screen's dimensions.
1632bde8e466a4451c7319e3a072d118917957d6554Steve Block    // Update our presentation parameters, and ensure that the full screen window occupies the
1642bde8e466a4451c7319e3a072d118917957d6554Steve Block    // entire screen:
1652bde8e466a4451c7319e3a072d118917957d6554Steve Block    [self _updateMenuAndDockForFullScreen];
1662bde8e466a4451c7319e3a072d118917957d6554Steve Block    NSWindow* window = [self window];
1672bde8e466a4451c7319e3a072d118917957d6554Steve Block    [window setFrame:[[window screen] frame] display:YES];
1682bde8e466a4451c7319e3a072d118917957d6554Steve Block}
1692bde8e466a4451c7319e3a072d118917957d6554Steve Block
1702bde8e466a4451c7319e3a072d118917957d6554Steve Block#pragma mark -
1712bde8e466a4451c7319e3a072d118917957d6554Steve Block#pragma mark Exposed Interface
1722bde8e466a4451c7319e3a072d118917957d6554Steve Block
1732bde8e466a4451c7319e3a072d118917957d6554Steve Block- (void)enterFullScreen:(NSScreen *)screen
1742bde8e466a4451c7319e3a072d118917957d6554Steve Block{
1752bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (_isFullScreen)
1762bde8e466a4451c7319e3a072d118917957d6554Steve Block        return;
1772bde8e466a4451c7319e3a072d118917957d6554Steve Block
1782bde8e466a4451c7319e3a072d118917957d6554Steve Block    _isFullScreen = YES;
1792bde8e466a4451c7319e3a072d118917957d6554Steve Block    _isAnimating = YES;
1802bde8e466a4451c7319e3a072d118917957d6554Steve Block
1812bde8e466a4451c7319e3a072d118917957d6554Steve Block    NSDisableScreenUpdates();
1822bde8e466a4451c7319e3a072d118917957d6554Steve Block
1832bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!screen)
1842bde8e466a4451c7319e3a072d118917957d6554Steve Block        screen = [NSScreen mainScreen];
1852bde8e466a4451c7319e3a072d118917957d6554Steve Block    NSRect screenFrame = [screen frame];
1862bde8e466a4451c7319e3a072d118917957d6554Steve Block
1872bde8e466a4451c7319e3a072d118917957d6554Steve Block    NSRect webViewFrame = [_webView convertRectToBase:[_webView frame]];
1882bde8e466a4451c7319e3a072d118917957d6554Steve Block    webViewFrame.origin = [[_webView window] convertBaseToScreen:webViewFrame.origin];
1892bde8e466a4451c7319e3a072d118917957d6554Steve Block
1902bde8e466a4451c7319e3a072d118917957d6554Steve Block    // In the case of a multi-monitor setup where the webView straddles two
1912bde8e466a4451c7319e3a072d118917957d6554Steve Block    // monitors, we must create a window large enough to contain the destination
1922bde8e466a4451c7319e3a072d118917957d6554Steve Block    // frame and the initial frame.
1932bde8e466a4451c7319e3a072d118917957d6554Steve Block    NSRect windowFrame = NSUnionRect(screenFrame, webViewFrame);
1942bde8e466a4451c7319e3a072d118917957d6554Steve Block    [[self window] setFrame:windowFrame display:YES];
1952bde8e466a4451c7319e3a072d118917957d6554Steve Block
1962bde8e466a4451c7319e3a072d118917957d6554Steve Block    CALayer* backgroundLayer = [[self _fullScreenWindow] backgroundLayer];
1972bde8e466a4451c7319e3a072d118917957d6554Steve Block    NSRect backgroundFrame = {[[self window] convertScreenToBase:screenFrame.origin], screenFrame.size};
1982bde8e466a4451c7319e3a072d118917957d6554Steve Block    backgroundFrame = [[[self window] contentView] convertRectFromBase:backgroundFrame];
1992bde8e466a4451c7319e3a072d118917957d6554Steve Block
2002bde8e466a4451c7319e3a072d118917957d6554Steve Block    [CATransaction begin];
2012bde8e466a4451c7319e3a072d118917957d6554Steve Block    [CATransaction setDisableActions:YES];
2022bde8e466a4451c7319e3a072d118917957d6554Steve Block    [backgroundLayer setFrame:NSRectToCGRect(backgroundFrame)];
2032bde8e466a4451c7319e3a072d118917957d6554Steve Block    [CATransaction commit];
2042bde8e466a4451c7319e3a072d118917957d6554Steve Block
2052bde8e466a4451c7319e3a072d118917957d6554Steve Block    CFTimeInterval duration = [self _animationDuration];
2062bde8e466a4451c7319e3a072d118917957d6554Steve Block    [self _manager]->willEnterFullScreen();
2072bde8e466a4451c7319e3a072d118917957d6554Steve Block    [self _manager]->beginEnterFullScreenAnimation(duration);
2082bde8e466a4451c7319e3a072d118917957d6554Steve Block}
2092bde8e466a4451c7319e3a072d118917957d6554Steve Block
2102bde8e466a4451c7319e3a072d118917957d6554Steve Block- (void)beganEnterFullScreenAnimation
2112bde8e466a4451c7319e3a072d118917957d6554Steve Block{
2122bde8e466a4451c7319e3a072d118917957d6554Steve Block    [self _updateMenuAndDockForFullScreen];
2132bde8e466a4451c7319e3a072d118917957d6554Steve Block    [self _updatePowerAssertions];
2142bde8e466a4451c7319e3a072d118917957d6554Steve Block
2152bde8e466a4451c7319e3a072d118917957d6554Steve Block    // In a previous incarnation, the NSWindow attached to this controller may have
2162bde8e466a4451c7319e3a072d118917957d6554Steve Block    // been on a different screen. Temporarily change the collectionBehavior of the window:
2172bde8e466a4451c7319e3a072d118917957d6554Steve Block    NSWindow* fullScreenWindow = [self window];
2182bde8e466a4451c7319e3a072d118917957d6554Steve Block    NSWindowCollectionBehavior behavior = [fullScreenWindow collectionBehavior];
2192bde8e466a4451c7319e3a072d118917957d6554Steve Block    [fullScreenWindow setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces];
2202bde8e466a4451c7319e3a072d118917957d6554Steve Block    [fullScreenWindow makeKeyAndOrderFront:self];
2212bde8e466a4451c7319e3a072d118917957d6554Steve Block    [fullScreenWindow setCollectionBehavior:behavior];
2222bde8e466a4451c7319e3a072d118917957d6554Steve Block
2232bde8e466a4451c7319e3a072d118917957d6554Steve Block    // Start the opacity animation. We can use implicit animations here because we don't care when
2242bde8e466a4451c7319e3a072d118917957d6554Steve Block    // the animation finishes.
2252bde8e466a4451c7319e3a072d118917957d6554Steve Block    [CATransaction begin];
2262bde8e466a4451c7319e3a072d118917957d6554Steve Block    [CATransaction setAnimationDuration:[self _animationDuration]];
2272bde8e466a4451c7319e3a072d118917957d6554Steve Block    [[[self _fullScreenWindow] backgroundLayer] setOpacity:1];
2282bde8e466a4451c7319e3a072d118917957d6554Steve Block    [CATransaction commit];
2292bde8e466a4451c7319e3a072d118917957d6554Steve Block
2302bde8e466a4451c7319e3a072d118917957d6554Steve Block    NSEnableScreenUpdates();
2312bde8e466a4451c7319e3a072d118917957d6554Steve Block    _isAnimating = YES;
2322bde8e466a4451c7319e3a072d118917957d6554Steve Block}
2332bde8e466a4451c7319e3a072d118917957d6554Steve Block
2342bde8e466a4451c7319e3a072d118917957d6554Steve Block- (void)finishedEnterFullScreenAnimation:(bool)completed
2352bde8e466a4451c7319e3a072d118917957d6554Steve Block{
2362bde8e466a4451c7319e3a072d118917957d6554Steve Block    NSDisableScreenUpdates();
2372bde8e466a4451c7319e3a072d118917957d6554Steve Block
2382bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (completed) {
2392bde8e466a4451c7319e3a072d118917957d6554Steve Block        // Swap the webView placeholder into place.
2402bde8e466a4451c7319e3a072d118917957d6554Steve Block        if (!_webViewPlaceholder)
2412bde8e466a4451c7319e3a072d118917957d6554Steve Block            _webViewPlaceholder.adoptNS([[NSView alloc] init]);
2422bde8e466a4451c7319e3a072d118917957d6554Steve Block        [self _swapView:_webView with:_webViewPlaceholder.get()];
2432bde8e466a4451c7319e3a072d118917957d6554Steve Block
2442bde8e466a4451c7319e3a072d118917957d6554Steve Block        // Then insert the WebView into the full screen window
2452bde8e466a4451c7319e3a072d118917957d6554Steve Block        NSView* animationView = [[self _fullScreenWindow] animationView];
2462bde8e466a4451c7319e3a072d118917957d6554Steve Block        [animationView addSubview:_webView positioned:NSWindowBelow relativeTo:_layerHostingView.get()];
2472bde8e466a4451c7319e3a072d118917957d6554Steve Block        [_webView setFrame:[animationView bounds]];
2482bde8e466a4451c7319e3a072d118917957d6554Steve Block
2492bde8e466a4451c7319e3a072d118917957d6554Steve Block        // FIXME: In Barolo, orderIn will animate, which is not what we want.  Find a way
2502bde8e466a4451c7319e3a072d118917957d6554Steve Block        // to work around this behavior.
2512bde8e466a4451c7319e3a072d118917957d6554Steve Block        //[[_webViewPlaceholder.get() window] orderOut:self];
2522bde8e466a4451c7319e3a072d118917957d6554Steve Block        [[self window] makeKeyAndOrderFront:self];
2532bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
2542bde8e466a4451c7319e3a072d118917957d6554Steve Block
2552bde8e466a4451c7319e3a072d118917957d6554Steve Block    [self _manager]->didEnterFullScreen();
2562bde8e466a4451c7319e3a072d118917957d6554Steve Block    NSEnableScreenUpdates();
2572bde8e466a4451c7319e3a072d118917957d6554Steve Block
2582bde8e466a4451c7319e3a072d118917957d6554Steve Block    _isAnimating = NO;
2592bde8e466a4451c7319e3a072d118917957d6554Steve Block}
2602bde8e466a4451c7319e3a072d118917957d6554Steve Block
2612bde8e466a4451c7319e3a072d118917957d6554Steve Block- (void)exitFullScreen
2622bde8e466a4451c7319e3a072d118917957d6554Steve Block{
2632bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!_isFullScreen)
2642bde8e466a4451c7319e3a072d118917957d6554Steve Block        return;
2652bde8e466a4451c7319e3a072d118917957d6554Steve Block
2662bde8e466a4451c7319e3a072d118917957d6554Steve Block    _isFullScreen = NO;
2672bde8e466a4451c7319e3a072d118917957d6554Steve Block    _isAnimating = YES;
2682bde8e466a4451c7319e3a072d118917957d6554Steve Block
2692bde8e466a4451c7319e3a072d118917957d6554Steve Block    NSDisableScreenUpdates();
2702bde8e466a4451c7319e3a072d118917957d6554Steve Block
2712bde8e466a4451c7319e3a072d118917957d6554Steve Block    [self _manager]->willExitFullScreen();
2722bde8e466a4451c7319e3a072d118917957d6554Steve Block    [self _manager]->beginExitFullScreenAnimation([self _animationDuration]);
2732bde8e466a4451c7319e3a072d118917957d6554Steve Block}
2742bde8e466a4451c7319e3a072d118917957d6554Steve Block
2752bde8e466a4451c7319e3a072d118917957d6554Steve Block- (void)beganExitFullScreenAnimation
2762bde8e466a4451c7319e3a072d118917957d6554Steve Block{
2772bde8e466a4451c7319e3a072d118917957d6554Steve Block    [self _updateMenuAndDockForFullScreen];
2782bde8e466a4451c7319e3a072d118917957d6554Steve Block    [self _updatePowerAssertions];
2792bde8e466a4451c7319e3a072d118917957d6554Steve Block
2802bde8e466a4451c7319e3a072d118917957d6554Steve Block    // The user may have moved the fullScreen window in Spaces, so temporarily change
2812bde8e466a4451c7319e3a072d118917957d6554Steve Block    // the collectionBehavior of the webView's window:
2822bde8e466a4451c7319e3a072d118917957d6554Steve Block    NSWindow* webWindow = [[self webView] window];
2832bde8e466a4451c7319e3a072d118917957d6554Steve Block    NSWindowCollectionBehavior behavior = [webWindow collectionBehavior];
2842bde8e466a4451c7319e3a072d118917957d6554Steve Block    [webWindow setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces];
2852bde8e466a4451c7319e3a072d118917957d6554Steve Block    [webWindow orderWindow:NSWindowBelow relativeTo:[[self window] windowNumber]];
2862bde8e466a4451c7319e3a072d118917957d6554Steve Block    [webWindow setCollectionBehavior:behavior];
2872bde8e466a4451c7319e3a072d118917957d6554Steve Block
2882bde8e466a4451c7319e3a072d118917957d6554Steve Block    // Swap the webView back into its original position:
2892bde8e466a4451c7319e3a072d118917957d6554Steve Block    if ([_webView window] == [self window])
2902bde8e466a4451c7319e3a072d118917957d6554Steve Block        [self _swapView:_webViewPlaceholder.get() with:_webView];
2912bde8e466a4451c7319e3a072d118917957d6554Steve Block
2922bde8e466a4451c7319e3a072d118917957d6554Steve Block    [CATransaction begin];
2932bde8e466a4451c7319e3a072d118917957d6554Steve Block    [CATransaction setAnimationDuration:[self _animationDuration]];
2942bde8e466a4451c7319e3a072d118917957d6554Steve Block    [[[self _fullScreenWindow] backgroundLayer] setOpacity:0];
2952bde8e466a4451c7319e3a072d118917957d6554Steve Block    [CATransaction commit];
2962bde8e466a4451c7319e3a072d118917957d6554Steve Block
2972bde8e466a4451c7319e3a072d118917957d6554Steve Block    NSEnableScreenUpdates();
2982bde8e466a4451c7319e3a072d118917957d6554Steve Block    _isAnimating = YES;
2992bde8e466a4451c7319e3a072d118917957d6554Steve Block}
3002bde8e466a4451c7319e3a072d118917957d6554Steve Block
3012bde8e466a4451c7319e3a072d118917957d6554Steve Block- (void)finishedExitFullScreenAnimation:(bool)completed
3022bde8e466a4451c7319e3a072d118917957d6554Steve Block{
3032bde8e466a4451c7319e3a072d118917957d6554Steve Block    NSDisableScreenUpdates();
3042bde8e466a4451c7319e3a072d118917957d6554Steve Block
3052bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (completed) {
3062bde8e466a4451c7319e3a072d118917957d6554Steve Block        [self _updateMenuAndDockForFullScreen];
3072bde8e466a4451c7319e3a072d118917957d6554Steve Block        [self _updatePowerAssertions];
3082bde8e466a4451c7319e3a072d118917957d6554Steve Block        [NSCursor setHiddenUntilMouseMoves:YES];
3092bde8e466a4451c7319e3a072d118917957d6554Steve Block
3102bde8e466a4451c7319e3a072d118917957d6554Steve Block        [[self window] orderOut:self];
3112bde8e466a4451c7319e3a072d118917957d6554Steve Block        [[_webView window] makeKeyAndOrderFront:self];
3122bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
3132bde8e466a4451c7319e3a072d118917957d6554Steve Block
3142bde8e466a4451c7319e3a072d118917957d6554Steve Block    [self _manager]->didExitFullScreen();
3152bde8e466a4451c7319e3a072d118917957d6554Steve Block    NSEnableScreenUpdates();
3162bde8e466a4451c7319e3a072d118917957d6554Steve Block
3172bde8e466a4451c7319e3a072d118917957d6554Steve Block    _isAnimating = NO;
3182bde8e466a4451c7319e3a072d118917957d6554Steve Block}
3192bde8e466a4451c7319e3a072d118917957d6554Steve Block
3202bde8e466a4451c7319e3a072d118917957d6554Steve Block- (void)enterAcceleratedCompositingMode:(const WebKit::LayerTreeContext&)layerTreeContext
3212bde8e466a4451c7319e3a072d118917957d6554Steve Block{
3222bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (_layerHostingView)
3232bde8e466a4451c7319e3a072d118917957d6554Steve Block        return;
3242bde8e466a4451c7319e3a072d118917957d6554Steve Block
3252bde8e466a4451c7319e3a072d118917957d6554Steve Block    ASSERT(!layerTreeContext.isEmpty());
3262bde8e466a4451c7319e3a072d118917957d6554Steve Block
3272bde8e466a4451c7319e3a072d118917957d6554Steve Block    // Create an NSView that will host our layer tree.
3282bde8e466a4451c7319e3a072d118917957d6554Steve Block    _layerHostingView.adoptNS([[NSView alloc] initWithFrame:[[self window] frame]]);
3292bde8e466a4451c7319e3a072d118917957d6554Steve Block    [_layerHostingView.get() setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
3302bde8e466a4451c7319e3a072d118917957d6554Steve Block
3312bde8e466a4451c7319e3a072d118917957d6554Steve Block    [CATransaction begin];
3322bde8e466a4451c7319e3a072d118917957d6554Steve Block    [CATransaction setDisableActions:YES];
3332bde8e466a4451c7319e3a072d118917957d6554Steve Block    WKFullScreenWindow* window = [self _fullScreenWindow];
3342bde8e466a4451c7319e3a072d118917957d6554Steve Block    [[window animationView] addSubview:_layerHostingView.get()];
3352bde8e466a4451c7319e3a072d118917957d6554Steve Block
3362bde8e466a4451c7319e3a072d118917957d6554Steve Block    // Create a root layer that will back the NSView.
3372bde8e466a4451c7319e3a072d118917957d6554Steve Block    RetainPtr<CALayer> rootLayer(AdoptNS, [[CALayer alloc] init]);
3382bde8e466a4451c7319e3a072d118917957d6554Steve Block#ifndef NDEBUG
3392bde8e466a4451c7319e3a072d118917957d6554Steve Block    [rootLayer.get() setName:@"Hosting root layer"];
3402bde8e466a4451c7319e3a072d118917957d6554Steve Block#endif
3412bde8e466a4451c7319e3a072d118917957d6554Steve Block
3422bde8e466a4451c7319e3a072d118917957d6554Steve Block    CALayer *renderLayer = WKMakeRenderLayer(layerTreeContext.contextID);
3432bde8e466a4451c7319e3a072d118917957d6554Steve Block    [rootLayer.get() addSublayer:renderLayer];
3442bde8e466a4451c7319e3a072d118917957d6554Steve Block
3452bde8e466a4451c7319e3a072d118917957d6554Steve Block    [_layerHostingView.get() setLayer:rootLayer.get()];
3462bde8e466a4451c7319e3a072d118917957d6554Steve Block    [_layerHostingView.get() setWantsLayer:YES];
3472bde8e466a4451c7319e3a072d118917957d6554Steve Block    [[window backgroundLayer] setHidden:NO];
3482bde8e466a4451c7319e3a072d118917957d6554Steve Block    [CATransaction commit];
3492bde8e466a4451c7319e3a072d118917957d6554Steve Block}
3502bde8e466a4451c7319e3a072d118917957d6554Steve Block
3512bde8e466a4451c7319e3a072d118917957d6554Steve Block- (void)exitAcceleratedCompositingMode
3522bde8e466a4451c7319e3a072d118917957d6554Steve Block{
3532bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!_layerHostingView)
3542bde8e466a4451c7319e3a072d118917957d6554Steve Block        return;
3552bde8e466a4451c7319e3a072d118917957d6554Steve Block
3562bde8e466a4451c7319e3a072d118917957d6554Steve Block    [CATransaction begin];
3572bde8e466a4451c7319e3a072d118917957d6554Steve Block    [CATransaction setDisableActions:YES];
3582bde8e466a4451c7319e3a072d118917957d6554Steve Block    [_layerHostingView.get() removeFromSuperview];
3592bde8e466a4451c7319e3a072d118917957d6554Steve Block    [_layerHostingView.get() setLayer:nil];
3602bde8e466a4451c7319e3a072d118917957d6554Steve Block    [_layerHostingView.get() setWantsLayer:NO];
3612bde8e466a4451c7319e3a072d118917957d6554Steve Block    [[[self _fullScreenWindow] backgroundLayer] setHidden:YES];
3622bde8e466a4451c7319e3a072d118917957d6554Steve Block    [CATransaction commit];
3632bde8e466a4451c7319e3a072d118917957d6554Steve Block
3642bde8e466a4451c7319e3a072d118917957d6554Steve Block    _layerHostingView = 0;
3652bde8e466a4451c7319e3a072d118917957d6554Steve Block}
3662bde8e466a4451c7319e3a072d118917957d6554Steve Block
3672bde8e466a4451c7319e3a072d118917957d6554Steve Block- (WebCore::IntRect)getFullScreenRect
3682bde8e466a4451c7319e3a072d118917957d6554Steve Block{
3692bde8e466a4451c7319e3a072d118917957d6554Steve Block    return enclosingIntRect([[self window] frame]);
3702bde8e466a4451c7319e3a072d118917957d6554Steve Block}
3712bde8e466a4451c7319e3a072d118917957d6554Steve Block
3722bde8e466a4451c7319e3a072d118917957d6554Steve Block#pragma mark -
3732bde8e466a4451c7319e3a072d118917957d6554Steve Block#pragma mark Internal Interface
3742bde8e466a4451c7319e3a072d118917957d6554Steve Block
3752bde8e466a4451c7319e3a072d118917957d6554Steve Block- (void)_updateMenuAndDockForFullScreen
3762bde8e466a4451c7319e3a072d118917957d6554Steve Block{
3772bde8e466a4451c7319e3a072d118917957d6554Steve Block    // NSApplicationPresentationOptions is available on > 10.6 only:
3782bde8e466a4451c7319e3a072d118917957d6554Steve Block#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
3792bde8e466a4451c7319e3a072d118917957d6554Steve Block    NSApplicationPresentationOptions options = NSApplicationPresentationDefault;
3802bde8e466a4451c7319e3a072d118917957d6554Steve Block    NSScreen* fullScreenScreen = [[self window] screen];
3812bde8e466a4451c7319e3a072d118917957d6554Steve Block
3822bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (_isFullScreen) {
3832bde8e466a4451c7319e3a072d118917957d6554Steve Block        // Auto-hide the menu bar if the fullScreenScreen contains the menu bar:
3842bde8e466a4451c7319e3a072d118917957d6554Steve Block        // NOTE: if the fullScreenScreen contains the menu bar but not the dock, we must still
3852bde8e466a4451c7319e3a072d118917957d6554Steve Block        // auto-hide the dock, or an exception will be thrown.
3862bde8e466a4451c7319e3a072d118917957d6554Steve Block        if ([[NSScreen screens] objectAtIndex:0] == fullScreenScreen)
3872bde8e466a4451c7319e3a072d118917957d6554Steve Block            options |= (NSApplicationPresentationAutoHideMenuBar | NSApplicationPresentationAutoHideDock);
3882bde8e466a4451c7319e3a072d118917957d6554Steve Block        // Check if the current screen contains the dock by comparing the screen's frame to its
3892bde8e466a4451c7319e3a072d118917957d6554Steve Block        // visibleFrame; if a dock is present, the visibleFrame will differ. If the current screen
3902bde8e466a4451c7319e3a072d118917957d6554Steve Block        // contains the dock, hide it.
3912bde8e466a4451c7319e3a072d118917957d6554Steve Block        else if (!NSEqualRects([fullScreenScreen frame], [fullScreenScreen visibleFrame]))
3922bde8e466a4451c7319e3a072d118917957d6554Steve Block            options |= NSApplicationPresentationAutoHideDock;
3932bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
3942bde8e466a4451c7319e3a072d118917957d6554Steve Block
3952bde8e466a4451c7319e3a072d118917957d6554Steve Block    if ([NSApp respondsToSelector:@selector(setPresentationOptions:)])
3962bde8e466a4451c7319e3a072d118917957d6554Steve Block        [NSApp setPresentationOptions:options];
3972bde8e466a4451c7319e3a072d118917957d6554Steve Block    else
3982bde8e466a4451c7319e3a072d118917957d6554Steve Block#endif
3992bde8e466a4451c7319e3a072d118917957d6554Steve Block        SetSystemUIMode(_isFullScreen ? kUIModeNormal : kUIModeAllHidden, 0);
4002bde8e466a4451c7319e3a072d118917957d6554Steve Block}
4012bde8e466a4451c7319e3a072d118917957d6554Steve Block
4022bde8e466a4451c7319e3a072d118917957d6554Steve Block#if !defined(BUILDING_ON_TIGER) // IOPMAssertionCreateWithName not defined on < 10.5
4032bde8e466a4451c7319e3a072d118917957d6554Steve Block- (void)_disableIdleDisplaySleep
4042bde8e466a4451c7319e3a072d118917957d6554Steve Block{
4052bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (_idleDisplaySleepAssertion == kIOPMNullAssertionID)
4062bde8e466a4451c7319e3a072d118917957d6554Steve Block#if defined(BUILDING_ON_LEOPARD) // IOPMAssertionCreateWithName is not defined in the 10.5 SDK
4072bde8e466a4451c7319e3a072d118917957d6554Steve Block        IOPMAssertionCreate(kIOPMAssertionTypeNoDisplaySleep, kIOPMAssertionLevelOn, &_idleDisplaySleepAssertion);
4082bde8e466a4451c7319e3a072d118917957d6554Steve Block#else // IOPMAssertionCreate is depreciated in > 10.5
4092bde8e466a4451c7319e3a072d118917957d6554Steve Block    IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep, kIOPMAssertionLevelOn, CFSTR("WebKit playing a video fullScreen."), &_idleDisplaySleepAssertion);
4102bde8e466a4451c7319e3a072d118917957d6554Steve Block#endif
4112bde8e466a4451c7319e3a072d118917957d6554Steve Block}
4122bde8e466a4451c7319e3a072d118917957d6554Steve Block
4132bde8e466a4451c7319e3a072d118917957d6554Steve Block- (void)_enableIdleDisplaySleep
4142bde8e466a4451c7319e3a072d118917957d6554Steve Block{
4152bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (_idleDisplaySleepAssertion != kIOPMNullAssertionID) {
4162bde8e466a4451c7319e3a072d118917957d6554Steve Block        IOPMAssertionRelease(_idleDisplaySleepAssertion);
4172bde8e466a4451c7319e3a072d118917957d6554Steve Block        _idleDisplaySleepAssertion = kIOPMNullAssertionID;
4182bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
4192bde8e466a4451c7319e3a072d118917957d6554Steve Block}
4202bde8e466a4451c7319e3a072d118917957d6554Steve Block
4212bde8e466a4451c7319e3a072d118917957d6554Steve Block- (void)_disableIdleSystemSleep
4222bde8e466a4451c7319e3a072d118917957d6554Steve Block{
4232bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (_idleSystemSleepAssertion == kIOPMNullAssertionID)
4242bde8e466a4451c7319e3a072d118917957d6554Steve Block#if defined(BUILDING_ON_LEOPARD) // IOPMAssertionCreateWithName is not defined in the 10.5 SDK
4252bde8e466a4451c7319e3a072d118917957d6554Steve Block        IOPMAssertionCreate(kIOPMAssertionTypeNoIdleSleep, kIOPMAssertionLevelOn, &_idleSystemSleepAssertion);
4262bde8e466a4451c7319e3a072d118917957d6554Steve Block#else // IOPMAssertionCreate is depreciated in > 10.5
4272bde8e466a4451c7319e3a072d118917957d6554Steve Block    IOPMAssertionCreateWithName(kIOPMAssertionTypeNoIdleSleep, kIOPMAssertionLevelOn, CFSTR("WebKit playing a video fullScreen."), &_idleSystemSleepAssertion);
4282bde8e466a4451c7319e3a072d118917957d6554Steve Block#endif
4292bde8e466a4451c7319e3a072d118917957d6554Steve Block}
4302bde8e466a4451c7319e3a072d118917957d6554Steve Block
4312bde8e466a4451c7319e3a072d118917957d6554Steve Block- (void)_enableIdleSystemSleep
4322bde8e466a4451c7319e3a072d118917957d6554Steve Block{
4332bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (_idleSystemSleepAssertion != kIOPMNullAssertionID) {
4342bde8e466a4451c7319e3a072d118917957d6554Steve Block        IOPMAssertionRelease(_idleSystemSleepAssertion);
4352bde8e466a4451c7319e3a072d118917957d6554Steve Block        _idleSystemSleepAssertion = kIOPMNullAssertionID;
4362bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
4372bde8e466a4451c7319e3a072d118917957d6554Steve Block}
4382bde8e466a4451c7319e3a072d118917957d6554Steve Block
4392bde8e466a4451c7319e3a072d118917957d6554Steve Block- (void)_enableTickleTimer
4402bde8e466a4451c7319e3a072d118917957d6554Steve Block{
4412bde8e466a4451c7319e3a072d118917957d6554Steve Block    [_tickleTimer invalidate];
4422bde8e466a4451c7319e3a072d118917957d6554Steve Block    [_tickleTimer release];
4432bde8e466a4451c7319e3a072d118917957d6554Steve Block    _tickleTimer = [[NSTimer scheduledTimerWithTimeInterval:tickleTimerInterval target:self selector:@selector(_tickleTimerFired) userInfo:nil repeats:YES] retain];
4442bde8e466a4451c7319e3a072d118917957d6554Steve Block}
4452bde8e466a4451c7319e3a072d118917957d6554Steve Block
4462bde8e466a4451c7319e3a072d118917957d6554Steve Block- (void)_disableTickleTimer
4472bde8e466a4451c7319e3a072d118917957d6554Steve Block{
4482bde8e466a4451c7319e3a072d118917957d6554Steve Block    [_tickleTimer invalidate];
4492bde8e466a4451c7319e3a072d118917957d6554Steve Block    [_tickleTimer release];
4502bde8e466a4451c7319e3a072d118917957d6554Steve Block    _tickleTimer = nil;
4512bde8e466a4451c7319e3a072d118917957d6554Steve Block}
4522bde8e466a4451c7319e3a072d118917957d6554Steve Block
4532bde8e466a4451c7319e3a072d118917957d6554Steve Block- (void)_tickleTimerFired
4542bde8e466a4451c7319e3a072d118917957d6554Steve Block{
4552bde8e466a4451c7319e3a072d118917957d6554Steve Block    UpdateSystemActivity(OverallAct);
4562bde8e466a4451c7319e3a072d118917957d6554Steve Block}
4572bde8e466a4451c7319e3a072d118917957d6554Steve Block#endif
4582bde8e466a4451c7319e3a072d118917957d6554Steve Block
4592bde8e466a4451c7319e3a072d118917957d6554Steve Block- (void)_updatePowerAssertions
4602bde8e466a4451c7319e3a072d118917957d6554Steve Block{
4612bde8e466a4451c7319e3a072d118917957d6554Steve Block#if !defined(BUILDING_ON_TIGER)
4622bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (_isPlaying && _isFullScreen) {
4632bde8e466a4451c7319e3a072d118917957d6554Steve Block        [self _disableIdleSystemSleep];
4642bde8e466a4451c7319e3a072d118917957d6554Steve Block        [self _disableIdleDisplaySleep];
4652bde8e466a4451c7319e3a072d118917957d6554Steve Block        [self _enableTickleTimer];
4662bde8e466a4451c7319e3a072d118917957d6554Steve Block    } else {
4672bde8e466a4451c7319e3a072d118917957d6554Steve Block        [self _enableIdleSystemSleep];
4682bde8e466a4451c7319e3a072d118917957d6554Steve Block        [self _enableIdleDisplaySleep];
4692bde8e466a4451c7319e3a072d118917957d6554Steve Block        [self _disableTickleTimer];
4702bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
4712bde8e466a4451c7319e3a072d118917957d6554Steve Block#endif
4722bde8e466a4451c7319e3a072d118917957d6554Steve Block}
4732bde8e466a4451c7319e3a072d118917957d6554Steve Block
4742bde8e466a4451c7319e3a072d118917957d6554Steve Block- (WebFullScreenManagerProxy*)_manager
4752bde8e466a4451c7319e3a072d118917957d6554Steve Block{
4762bde8e466a4451c7319e3a072d118917957d6554Steve Block    WebPageProxy* webPage = toImpl([_webView pageRef]);
4772bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!webPage)
4782bde8e466a4451c7319e3a072d118917957d6554Steve Block        return 0;
4792bde8e466a4451c7319e3a072d118917957d6554Steve Block    return webPage->fullScreenManager();
4802bde8e466a4451c7319e3a072d118917957d6554Steve Block}
4812bde8e466a4451c7319e3a072d118917957d6554Steve Block
4822bde8e466a4451c7319e3a072d118917957d6554Steve Block- (void)_requestExit
4832bde8e466a4451c7319e3a072d118917957d6554Steve Block{
4842bde8e466a4451c7319e3a072d118917957d6554Steve Block    [self exitFullScreen];
4852bde8e466a4451c7319e3a072d118917957d6554Steve Block    _forceDisableAnimation = NO;
4862bde8e466a4451c7319e3a072d118917957d6554Steve Block}
4872bde8e466a4451c7319e3a072d118917957d6554Steve Block
4882bde8e466a4451c7319e3a072d118917957d6554Steve Block- (void)_requestExitFullScreenWithAnimation:(BOOL)animation
4892bde8e466a4451c7319e3a072d118917957d6554Steve Block{
4902bde8e466a4451c7319e3a072d118917957d6554Steve Block    _forceDisableAnimation = !animation;
4912bde8e466a4451c7319e3a072d118917957d6554Steve Block    [self performSelector:@selector(_requestExit) withObject:nil afterDelay:0];
4922bde8e466a4451c7319e3a072d118917957d6554Steve Block
4932bde8e466a4451c7319e3a072d118917957d6554Steve Block}
4942bde8e466a4451c7319e3a072d118917957d6554Steve Block
4952bde8e466a4451c7319e3a072d118917957d6554Steve Block- (void)_swapView:(NSView*)view with:(NSView*)otherView
4962bde8e466a4451c7319e3a072d118917957d6554Steve Block{
4972bde8e466a4451c7319e3a072d118917957d6554Steve Block    [otherView setFrame:[view frame]];
4982bde8e466a4451c7319e3a072d118917957d6554Steve Block    [otherView setAutoresizingMask:[view autoresizingMask]];
4992bde8e466a4451c7319e3a072d118917957d6554Steve Block    [otherView removeFromSuperview];
5002bde8e466a4451c7319e3a072d118917957d6554Steve Block    [[view superview] replaceSubview:view with:otherView];
5012bde8e466a4451c7319e3a072d118917957d6554Steve Block}
5022bde8e466a4451c7319e3a072d118917957d6554Steve Block
5032bde8e466a4451c7319e3a072d118917957d6554Steve Block#pragma mark -
5042bde8e466a4451c7319e3a072d118917957d6554Steve Block#pragma mark Utility Functions
5052bde8e466a4451c7319e3a072d118917957d6554Steve Block
5062bde8e466a4451c7319e3a072d118917957d6554Steve Block- (WKFullScreenWindow *)_fullScreenWindow
5072bde8e466a4451c7319e3a072d118917957d6554Steve Block{
5082bde8e466a4451c7319e3a072d118917957d6554Steve Block    ASSERT([[self window] isKindOfClass:[WKFullScreenWindow class]]);
5092bde8e466a4451c7319e3a072d118917957d6554Steve Block    return (WKFullScreenWindow *)[self window];
5102bde8e466a4451c7319e3a072d118917957d6554Steve Block}
5112bde8e466a4451c7319e3a072d118917957d6554Steve Block
5122bde8e466a4451c7319e3a072d118917957d6554Steve Block- (CFTimeInterval)_animationDuration
5132bde8e466a4451c7319e3a072d118917957d6554Steve Block{
5142bde8e466a4451c7319e3a072d118917957d6554Steve Block    static const CFTimeInterval defaultDuration = 0.5;
5152bde8e466a4451c7319e3a072d118917957d6554Steve Block    CFTimeInterval duration = defaultDuration;
5162bde8e466a4451c7319e3a072d118917957d6554Steve Block#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
5172bde8e466a4451c7319e3a072d118917957d6554Steve Block    NSUInteger modifierFlags = [NSEvent modifierFlags];
5182bde8e466a4451c7319e3a072d118917957d6554Steve Block#else
5192bde8e466a4451c7319e3a072d118917957d6554Steve Block    NSUInteger modifierFlags = [[NSApp currentEvent] modifierFlags];
5202bde8e466a4451c7319e3a072d118917957d6554Steve Block#endif
5212bde8e466a4451c7319e3a072d118917957d6554Steve Block    if ((modifierFlags & NSControlKeyMask) == NSControlKeyMask)
5222bde8e466a4451c7319e3a072d118917957d6554Steve Block        duration *= 2;
5232bde8e466a4451c7319e3a072d118917957d6554Steve Block    if ((modifierFlags & NSShiftKeyMask) == NSShiftKeyMask)
5242bde8e466a4451c7319e3a072d118917957d6554Steve Block        duration *= 10;
5252bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (_forceDisableAnimation) {
5262bde8e466a4451c7319e3a072d118917957d6554Steve Block        // This will disable scale animation
5272bde8e466a4451c7319e3a072d118917957d6554Steve Block        duration = 0;
5282bde8e466a4451c7319e3a072d118917957d6554Steve Block    }
5292bde8e466a4451c7319e3a072d118917957d6554Steve Block    return duration;
5302bde8e466a4451c7319e3a072d118917957d6554Steve Block}
5312bde8e466a4451c7319e3a072d118917957d6554Steve Block
5322bde8e466a4451c7319e3a072d118917957d6554Steve Block@end
5332bde8e466a4451c7319e3a072d118917957d6554Steve Block
5342bde8e466a4451c7319e3a072d118917957d6554Steve Block#pragma mark -
5352bde8e466a4451c7319e3a072d118917957d6554Steve Block@implementation WKFullScreenWindow
5362bde8e466a4451c7319e3a072d118917957d6554Steve Block
5372bde8e466a4451c7319e3a072d118917957d6554Steve Block- (id)initWithContentRect:(NSRect)contentRect styleMask:(NSUInteger)aStyle backing:(NSBackingStoreType)bufferingType defer:(BOOL)flag
5382bde8e466a4451c7319e3a072d118917957d6554Steve Block{
5392bde8e466a4451c7319e3a072d118917957d6554Steve Block    UNUSED_PARAM(aStyle);
5402bde8e466a4451c7319e3a072d118917957d6554Steve Block    self = [super initWithContentRect:contentRect styleMask:NSBorderlessWindowMask backing:bufferingType defer:flag];
5412bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!self)
5422bde8e466a4451c7319e3a072d118917957d6554Steve Block        return nil;
5432bde8e466a4451c7319e3a072d118917957d6554Steve Block    [self setOpaque:NO];
5442bde8e466a4451c7319e3a072d118917957d6554Steve Block    [self setBackgroundColor:[NSColor clearColor]];
5452bde8e466a4451c7319e3a072d118917957d6554Steve Block    [self setIgnoresMouseEvents:NO];
5462bde8e466a4451c7319e3a072d118917957d6554Steve Block    [self setAcceptsMouseMovedEvents:YES];
5472bde8e466a4451c7319e3a072d118917957d6554Steve Block    [self setReleasedWhenClosed:NO];
5482bde8e466a4451c7319e3a072d118917957d6554Steve Block    [self setHasShadow:YES];
5492bde8e466a4451c7319e3a072d118917957d6554Steve Block#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)
5502bde8e466a4451c7319e3a072d118917957d6554Steve Block    [self setMovable:NO];
5512bde8e466a4451c7319e3a072d118917957d6554Steve Block#else
5522bde8e466a4451c7319e3a072d118917957d6554Steve Block    [self setMovableByWindowBackground:NO];
5532bde8e466a4451c7319e3a072d118917957d6554Steve Block#endif
5542bde8e466a4451c7319e3a072d118917957d6554Steve Block
5552bde8e466a4451c7319e3a072d118917957d6554Steve Block    NSView* contentView = [self contentView];
5562bde8e466a4451c7319e3a072d118917957d6554Steve Block    _animationView = [[NSView alloc] initWithFrame:[contentView bounds]];
5572bde8e466a4451c7319e3a072d118917957d6554Steve Block
5582bde8e466a4451c7319e3a072d118917957d6554Steve Block    CALayer* contentLayer = [[CALayer alloc] init];
5592bde8e466a4451c7319e3a072d118917957d6554Steve Block    [_animationView setLayer:contentLayer];
5602bde8e466a4451c7319e3a072d118917957d6554Steve Block    [_animationView setWantsLayer:YES];
5612bde8e466a4451c7319e3a072d118917957d6554Steve Block    [_animationView setAutoresizingMask:NSViewWidthSizable|NSViewHeightSizable];
5622bde8e466a4451c7319e3a072d118917957d6554Steve Block    [contentView addSubview:_animationView];
5632bde8e466a4451c7319e3a072d118917957d6554Steve Block
5642bde8e466a4451c7319e3a072d118917957d6554Steve Block    _backgroundLayer = [[CALayer alloc] init];
5652bde8e466a4451c7319e3a072d118917957d6554Steve Block    [contentLayer addSublayer:_backgroundLayer];
5662bde8e466a4451c7319e3a072d118917957d6554Steve Block
5672bde8e466a4451c7319e3a072d118917957d6554Steve Block    [_backgroundLayer setBackgroundColor:CGColorGetConstantColor(kCGColorBlack)];
5682bde8e466a4451c7319e3a072d118917957d6554Steve Block    [_backgroundLayer setOpacity:0];
5692bde8e466a4451c7319e3a072d118917957d6554Steve Block    return self;
5702bde8e466a4451c7319e3a072d118917957d6554Steve Block}
5712bde8e466a4451c7319e3a072d118917957d6554Steve Block
5722bde8e466a4451c7319e3a072d118917957d6554Steve Block- (void)dealloc
5732bde8e466a4451c7319e3a072d118917957d6554Steve Block{
5742bde8e466a4451c7319e3a072d118917957d6554Steve Block    [_animationView release];
5752bde8e466a4451c7319e3a072d118917957d6554Steve Block    [_backgroundLayer release];
5762bde8e466a4451c7319e3a072d118917957d6554Steve Block    [super dealloc];
5772bde8e466a4451c7319e3a072d118917957d6554Steve Block}
5782bde8e466a4451c7319e3a072d118917957d6554Steve Block
5792bde8e466a4451c7319e3a072d118917957d6554Steve Block- (BOOL)canBecomeKeyWindow
5802bde8e466a4451c7319e3a072d118917957d6554Steve Block{
5812bde8e466a4451c7319e3a072d118917957d6554Steve Block    return YES;
5822bde8e466a4451c7319e3a072d118917957d6554Steve Block}
5832bde8e466a4451c7319e3a072d118917957d6554Steve Block
5842bde8e466a4451c7319e3a072d118917957d6554Steve Block- (void)keyDown:(NSEvent *)theEvent
5852bde8e466a4451c7319e3a072d118917957d6554Steve Block{
5862bde8e466a4451c7319e3a072d118917957d6554Steve Block    if ([[theEvent charactersIgnoringModifiers] isEqual:@"\e"]) // Esacpe key-code
5872bde8e466a4451c7319e3a072d118917957d6554Steve Block        [self cancelOperation:self];
5882bde8e466a4451c7319e3a072d118917957d6554Steve Block    else [super keyDown:theEvent];
5892bde8e466a4451c7319e3a072d118917957d6554Steve Block}
5902bde8e466a4451c7319e3a072d118917957d6554Steve Block
5912bde8e466a4451c7319e3a072d118917957d6554Steve Block- (void)cancelOperation:(id)sender
5922bde8e466a4451c7319e3a072d118917957d6554Steve Block{
5932bde8e466a4451c7319e3a072d118917957d6554Steve Block    UNUSED_PARAM(sender);
5942bde8e466a4451c7319e3a072d118917957d6554Steve Block    [[self windowController] _requestExitFullScreenWithAnimation:YES];
5952bde8e466a4451c7319e3a072d118917957d6554Steve Block}
5962bde8e466a4451c7319e3a072d118917957d6554Steve Block
5972bde8e466a4451c7319e3a072d118917957d6554Steve Block- (CALayer*)backgroundLayer
5982bde8e466a4451c7319e3a072d118917957d6554Steve Block{
5992bde8e466a4451c7319e3a072d118917957d6554Steve Block    return _backgroundLayer;
6002bde8e466a4451c7319e3a072d118917957d6554Steve Block}
6012bde8e466a4451c7319e3a072d118917957d6554Steve Block
6022bde8e466a4451c7319e3a072d118917957d6554Steve Block- (NSView*)animationView
6032bde8e466a4451c7319e3a072d118917957d6554Steve Block{
6042bde8e466a4451c7319e3a072d118917957d6554Steve Block    return _animationView;
6052bde8e466a4451c7319e3a072d118917957d6554Steve Block}
6062bde8e466a4451c7319e3a072d118917957d6554Steve Block@end
6072bde8e466a4451c7319e3a072d118917957d6554Steve Block
6082bde8e466a4451c7319e3a072d118917957d6554Steve Block#endif
609