[Cocoa] More tweaks and refactoring to prepare for ARC
[WebKit.git] / Source / WebKitLegacy / mac / WebView / WebFullScreenController.mm
1 /*
2  * Copyright (C) 2010-2017 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #if ENABLE(FULLSCREEN_API) && !PLATFORM(IOS)
27
28 #import "WebFullScreenController.h"
29
30 #import "WebNSWindowExtras.h"
31 #import "WebPreferencesPrivate.h"
32 #import "WebViewInternal.h"
33 #import "WebWindowAnimation.h"
34 #import <WebCore/Document.h>
35 #import <WebCore/Element.h>
36 #import <WebCore/FloatRect.h>
37 #import <WebCore/Frame.h>
38 #import <WebCore/FrameView.h>
39 #import <WebCore/HTMLElement.h>
40 #import <WebCore/IntRect.h>
41 #import <WebCore/RenderLayer.h>
42 #import <WebCore/RenderLayerBacking.h>
43 #import <WebCore/RenderObject.h>
44 #import <WebCore/RenderView.h>
45 #import <WebCore/WebCoreFullScreenWindow.h>
46 #import <wtf/RetainPtr.h>
47 #import <wtf/SoftLinking.h>
48
49 using namespace WebCore;
50
51 static const CFTimeInterval defaultAnimationDuration = 0.5;
52
53 static IntRect screenRectOfContents(Element* element)
54 {
55     ASSERT(element);
56     if (element->renderer() && element->renderer()->hasLayer() && element->renderer()->enclosingLayer()->isComposited()) {
57         FloatQuad contentsBox = static_cast<FloatRect>(element->renderer()->enclosingLayer()->backing()->contentsBox());
58         contentsBox = element->renderer()->localToAbsoluteQuad(contentsBox);
59         return element->renderer()->view().frameView().contentsToScreen(contentsBox.enclosingBoundingBox());
60     }
61     return element->screenRect();
62 }
63
64 @interface WebFullScreenController(Private)<NSAnimationDelegate>
65 - (void)_updateMenuAndDockForFullScreen;
66 - (void)_swapView:(NSView*)view with:(NSView*)otherView;
67 - (Document*)_document;
68 - (void)_startEnterFullScreenAnimationWithDuration:(NSTimeInterval)duration;
69 - (void)_startExitFullScreenAnimationWithDuration:(NSTimeInterval)duration;
70 @end
71
72 static NSRect convertRectToScreen(NSWindow *window, NSRect rect)
73 {
74     return [window convertRectToScreen:rect];
75 }
76
77 @implementation WebFullScreenController
78
79 #pragma mark -
80 #pragma mark Initialization
81 - (id)init
82 {
83     // Do not defer window creation, to make sure -windowNumber is created (needed by WebWindowScaleAnimation).
84     NSWindow *window = [[WebCoreFullScreenWindow alloc] initWithContentRect:NSZeroRect styleMask:NSWindowStyleMaskClosable backing:NSBackingStoreBuffered defer:NO];
85     self = [super initWithWindow:window];
86     [window release];
87     if (!self)
88         return nil;
89     [self windowDidLoad];
90
91     return self;
92 }
93
94 - (void)dealloc
95 {
96     [self setWebView:nil];
97
98     [NSObject cancelPreviousPerformRequestsWithTarget:self];
99     
100     [[NSNotificationCenter defaultCenter] removeObserver:self];
101     [super dealloc];
102 }
103
104 @synthesize initialFrame=_initialFrame;
105 @synthesize finalFrame=_finalFrame;
106
107 - (void)windowDidLoad
108 {
109     [super windowDidLoad];
110
111     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidResignActive:) name:NSApplicationDidResignActiveNotification object:NSApp];
112     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(applicationDidChangeScreenParameters:) name:NSApplicationDidChangeScreenParametersNotification object:NSApp];
113 }
114
115 #pragma mark -
116 #pragma mark Accessors
117
118 - (WebView*)webView
119 {
120     return _webView;
121 }
122
123 - (void)setWebView:(WebView *)webView
124 {
125     [webView retain];
126     [_webView release];
127     _webView = webView;
128 }
129
130 - (NSView*)webViewPlaceholder
131 {
132     return _webViewPlaceholder.get();
133 }
134
135 - (Element*)element
136 {
137     return _element.get();
138 }
139
140 - (void)setElement:(RefPtr<Element>&&)element
141 {
142     _element = WTFMove(element);
143 }
144
145 - (BOOL)isFullScreen
146 {
147     return _isFullScreen;
148 }
149
150 #pragma mark -
151 #pragma mark NSWindowController overrides
152
153 - (void)cancelOperation:(id)sender
154 {
155     [self performSelector:@selector(requestExitFullScreen) withObject:nil afterDelay:0];
156 }
157
158 #pragma mark -
159 #pragma mark Notifications
160
161 - (void)applicationDidResignActive:(NSNotification*)notification
162 {   
163     NSWindow* fullscreenWindow = [self window];
164
165     // Replicate the QuickTime Player (X) behavior when losing active application status:
166     // Is the fullscreen screen the main screen? (Note: this covers the case where only a 
167     // single screen is available.)  Is the fullscreen screen on the current space? IFF so, 
168     // then exit fullscreen mode. 
169     if (fullscreenWindow.screen == [NSScreen screens][0] && fullscreenWindow.onActiveSpace)
170          [self cancelOperation:self];
171 }
172
173 - (void)applicationDidChangeScreenParameters:(NSNotification*)notification
174 {
175     // The user may have changed the main screen by moving the menu bar, or they may have changed
176     // the Dock's size or location, or they may have changed the fullscreen screen's dimensions. 
177     // Update our presentation parameters, and ensure that the full screen window occupies the 
178     // entire screen:
179     [self _updateMenuAndDockForFullScreen];
180     NSWindow* window = [self window];
181     NSRect screenFrame = [[window screen] frame];
182     [window setFrame:screenFrame display:YES];
183     [_backgroundWindow.get() setFrame:screenFrame display:YES];
184 }
185
186 #pragma mark -
187 #pragma mark Exposed Interface
188
189 - (void)enterFullScreen:(NSScreen *)screen
190 {
191     if (_isFullScreen)
192         return;
193     _isFullScreen = YES;
194     
195     [self _updateMenuAndDockForFullScreen];   
196     
197     if (!screen)
198         screen = [NSScreen mainScreen];
199     NSRect screenFrame = [screen frame];
200
201     NSRect webViewFrame = convertRectToScreen([_webView window], [_webView convertRect:[_webView frame] toView:nil]);
202
203     // Flip coordinate system:
204     webViewFrame.origin.y = NSMaxY([[[NSScreen screens] objectAtIndex:0] frame]) - NSMaxY(webViewFrame);
205     
206     CGWindowID windowID = [[_webView window] windowNumber];
207     RetainPtr<CGImageRef> webViewContents = adoptCF(CGWindowListCreateImage(NSRectToCGRect(webViewFrame), kCGWindowListOptionIncludingWindow, windowID, kCGWindowImageShouldBeOpaque));
208     
209     // Screen updates to be re-enabled in beganEnterFullScreenWithInitialFrame:finalFrame:
210 #pragma clang diagnostic push
211 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
212     NSDisableScreenUpdates();
213     [[self window] setAutodisplay:NO];
214 #pragma clang diagnostic pop
215
216     NSResponder *webWindowFirstResponder = [[_webView window] firstResponder];
217     [[self window] setFrame:screenFrame display:NO];
218
219     _initialFrame = screenRectOfContents(_element.get());
220
221     // Swap the webView placeholder into place.
222     if (!_webViewPlaceholder) {
223         _webViewPlaceholder = adoptNS([[NSView alloc] init]);
224         [_webViewPlaceholder.get() setLayer:[CALayer layer]];
225         [_webViewPlaceholder.get() setWantsLayer:YES];
226     }
227     [[_webViewPlaceholder.get() layer] setContents:(__bridge id)webViewContents.get()];
228     _scrollPosition = [_webView _mainCoreFrame]->view()->scrollPosition();
229     [self _swapView:_webView with:_webViewPlaceholder.get()];
230     
231     // Then insert the WebView into the full screen window
232     NSView* contentView = [[self window] contentView];
233     [contentView addSubview:_webView positioned:NSWindowBelow relativeTo:nil];
234     [_webView setFrame:[contentView bounds]];
235     [[_webViewPlaceholder.get() window] recalculateKeyViewLoop];
236     
237     [[self window] makeResponder:webWindowFirstResponder firstResponderIfDescendantOfView:_webView];
238
239     _savedScale = [_webView _viewScaleFactor];
240     [_webView _scaleWebView:1 atOrigin:NSMakePoint(0, 0)];
241     [self _document]->webkitWillEnterFullScreenForElement(_element.get());
242     [self _document]->setAnimatingFullScreen(true);
243     [self _document]->updateLayout();
244
245     _finalFrame = screenRectOfContents(_element.get());
246     
247     [self _updateMenuAndDockForFullScreen];   
248     
249     [self _startEnterFullScreenAnimationWithDuration:defaultAnimationDuration];
250
251     _isEnteringFullScreen = true;
252 }
253
254 static void setClipRectForWindow(NSWindow *window, NSRect clipRect)
255 {
256     CGSWindowID windowNumber = (CGSWindowID)window.windowNumber;
257     CGSRegionObj shape;
258     CGRect cgClipRect = NSRectToCGRect(clipRect);
259     CGSNewRegionWithRect(&cgClipRect, &shape);
260     CGSSetWindowClipShape(CGSMainConnectionID(), windowNumber, shape);
261     CGSReleaseRegion(shape);
262 }
263
264 - (void)finishedEnterFullScreenAnimation:(bool)completed
265 {
266     if (!_isEnteringFullScreen)
267         return;
268     _isEnteringFullScreen = NO;
269     
270     if (completed) {
271 #pragma clang diagnostic push
272 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
273         // Screen updates to be re-enabled at the end of this block
274         NSDisableScreenUpdates();
275 #pragma clang diagnostic pop
276         [self _document]->setAnimatingFullScreen(false);
277         [self _document]->webkitDidEnterFullScreenForElement(_element.get());
278         
279         NSRect windowBounds = [[self window] frame];
280         windowBounds.origin = NSZeroPoint;
281         setClipRectForWindow(self.window, windowBounds);
282         
283         NSWindow *webWindow = [_webViewPlaceholder.get() window];
284         // In Lion, NSWindow will animate into and out of orderOut operations. Suppress that
285         // behavior here, making sure to reset the animation behavior afterward.
286         NSWindowAnimationBehavior animationBehavior = [webWindow animationBehavior];
287         [webWindow setAnimationBehavior:NSWindowAnimationBehaviorNone];
288         [webWindow orderOut:self];
289         [webWindow setAnimationBehavior:animationBehavior];
290         
291         [_fadeAnimation.get() stopAnimation];
292         [_fadeAnimation.get() setWindow:nil];
293         _fadeAnimation = nullptr;
294         
295         [_backgroundWindow.get() orderOut:self];
296         [_backgroundWindow.get() setFrame:NSZeroRect display:YES];
297 #pragma clang diagnostic push
298 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
299         NSEnableScreenUpdates();
300 #pragma clang diagnostic pop
301     } else
302         [_scaleAnimation.get() stopAnimation];
303 }
304
305 - (void)requestExitFullScreen
306 {
307     if (!_element)
308         return;
309     _element->document().webkitCancelFullScreen();
310 }
311
312 - (void)exitFullScreen
313 {
314     if (!_isFullScreen)
315         return;
316     _isFullScreen = NO;
317
318 #pragma clang diagnostic push
319 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
320     // Screen updates to be re-enabled in beganExitFullScreenWithInitialFrame:finalFrame:
321     NSDisableScreenUpdates();
322     [[self window] setAutodisplay:NO];
323 #pragma clang diagnostic pop
324
325     _finalFrame = screenRectOfContents(_element.get());
326
327     [self _document]->webkitWillExitFullScreenForElement(_element.get());
328     [self _document]->setAnimatingFullScreen(true);
329
330     if (_isEnteringFullScreen)
331         [self finishedEnterFullScreenAnimation:NO];
332     
333     [self _updateMenuAndDockForFullScreen];
334     
335     NSWindow* webWindow = [_webViewPlaceholder.get() window];
336     // In Lion, NSWindow will animate into and out of orderOut operations. Suppress that
337     // behavior here, making sure to reset the animation behavior afterward.
338     NSWindowAnimationBehavior animationBehavior = [webWindow animationBehavior];
339     [webWindow setAnimationBehavior:NSWindowAnimationBehaviorNone];
340     // If the user has moved the fullScreen window into a new space, temporarily change
341     // the collectionBehavior of the webView's window so that it is pulled into the active space:
342     if (!webWindow.onActiveSpace) {
343         NSWindowCollectionBehavior behavior = [webWindow collectionBehavior];
344         [webWindow setCollectionBehavior:NSWindowCollectionBehaviorCanJoinAllSpaces];
345         [webWindow orderWindow:NSWindowBelow relativeTo:[[self window] windowNumber]];
346         [webWindow setCollectionBehavior:behavior];
347     } else
348         [webWindow orderWindow:NSWindowBelow relativeTo:[[self window] windowNumber]];
349     [webWindow setAnimationBehavior:animationBehavior];
350
351     [self _startExitFullScreenAnimationWithDuration:defaultAnimationDuration];
352     _isExitingFullScreen = YES;    
353 }
354
355 - (void)finishedExitFullScreenAnimation:(bool)completed
356 {
357     if (!_isExitingFullScreen)
358         return;
359     _isExitingFullScreen = NO;
360     
361     [self _updateMenuAndDockForFullScreen];
362
363 #pragma clang diagnostic push
364 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
365     // Screen updates to be re-enabled at the end of this function
366     NSDisableScreenUpdates();
367 #pragma clang diagnostic pop
368
369     [self _document]->setAnimatingFullScreen(false);
370     [self _document]->webkitDidExitFullScreenForElement(_element.get());
371     [_webView _scaleWebView:_savedScale atOrigin:NSMakePoint(0, 0)];
372
373     NSResponder *firstResponder = [[self window] firstResponder];
374     [self _swapView:_webViewPlaceholder.get() with:_webView];
375     [_webView _mainCoreFrame]->view()->setScrollPosition(_scrollPosition);
376     [[_webView window] makeResponder:firstResponder firstResponderIfDescendantOfView:_webView];
377     
378     NSRect windowBounds = [[self window] frame];
379     windowBounds.origin = NSZeroPoint;
380     setClipRectForWindow(self.window, windowBounds);
381     
382     [[self window] orderOut:self];
383     [[self window] setFrame:NSZeroRect display:YES];
384     
385     [_fadeAnimation.get() stopAnimation];
386     [_fadeAnimation.get() setWindow:nil];
387     _fadeAnimation = nullptr;
388     
389     [_backgroundWindow.get() orderOut:self];
390     [_backgroundWindow.get() setFrame:NSZeroRect display:YES];
391
392     [[_webView window] makeKeyAndOrderFront:self];
393
394 #pragma clang diagnostic push
395 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
396     NSEnableScreenUpdates();
397 #pragma clang diagnostic pop
398 }
399
400 - (void)performClose:(id)sender
401 {
402     if (_isFullScreen)
403         [self cancelOperation:sender];
404 }
405
406 - (void)close
407 {
408     // We are being asked to close rapidly, most likely because the page 
409     // has closed or the web process has crashed.  Just walk through our
410     // normal exit full screen sequence, but don't wait to be called back
411     // in response.
412     if (_isFullScreen)
413         [self exitFullScreen];
414     
415     if (_isExitingFullScreen)
416         [self finishedExitFullScreenAnimation:YES];
417     
418     [super close];
419 }
420
421 #pragma mark -
422 #pragma mark NSAnimation delegate
423
424 - (void)animationDidEnd:(NSAnimation*)animation
425 {
426     if (_isFullScreen)
427         [self finishedEnterFullScreenAnimation:YES];
428     else
429         [self finishedExitFullScreenAnimation:YES];
430 }
431
432 #pragma mark -
433 #pragma mark Internal Interface
434
435 - (void)_updateMenuAndDockForFullScreen
436 {
437     NSApplicationPresentationOptions options = NSApplicationPresentationDefault;
438     NSScreen* fullscreenScreen = [[self window] screen];
439     
440     if (_isFullScreen) {
441         // Auto-hide the menu bar if the fullscreenScreen contains the menu bar:
442         // NOTE: if the fullscreenScreen contains the menu bar but not the dock, we must still 
443         // auto-hide the dock, or an exception will be thrown.
444         if ([[NSScreen screens] objectAtIndex:0] == fullscreenScreen)
445             options |= (NSApplicationPresentationAutoHideMenuBar | NSApplicationPresentationAutoHideDock);
446         // Check if the current screen contains the dock by comparing the screen's frame to its
447         // visibleFrame; if a dock is present, the visibleFrame will differ. If the current screen
448         // contains the dock, hide it.
449         else if (!NSEqualRects([fullscreenScreen frame], [fullscreenScreen visibleFrame]))
450             options |= NSApplicationPresentationAutoHideDock;
451     }
452     
453     NSApp.presentationOptions = options;
454 }
455
456 #pragma mark -
457 #pragma mark Utility Functions
458
459 - (Document*)_document 
460 {
461     return &_element->document();
462 }
463
464 - (void)_swapView:(NSView*)view with:(NSView*)otherView
465 {
466     [CATransaction begin];
467     [CATransaction setDisableActions:YES];
468     [otherView setFrame:[view frame]];        
469     [otherView setAutoresizingMask:[view autoresizingMask]];
470     [otherView removeFromSuperview];
471     [[view superview] addSubview:otherView positioned:NSWindowAbove relativeTo:view];
472     [view removeFromSuperview];
473     [CATransaction commit];
474 }
475
476 static RetainPtr<NSWindow> createBackgroundFullscreenWindow(NSRect frame)
477 {
478     NSWindow *window = [[NSWindow alloc] initWithContentRect:frame styleMask:NSWindowStyleMaskBorderless backing:NSBackingStoreBuffered defer:NO];
479     [window setOpaque:YES];
480     [window setBackgroundColor:[NSColor blackColor]];
481     [window setReleasedWhenClosed:NO];
482     return adoptNS(window);
483 }
484
485 static NSRect windowFrameFromApparentFrames(NSRect screenFrame, NSRect initialFrame, NSRect finalFrame)
486 {
487     NSRect initialWindowFrame;
488     if (!NSWidth(initialFrame) || !NSWidth(finalFrame) || !NSHeight(initialFrame) || !NSHeight(finalFrame))
489         return screenFrame;
490
491     CGFloat xScale = NSWidth(screenFrame) / NSWidth(finalFrame);
492     CGFloat yScale = NSHeight(screenFrame) / NSHeight(finalFrame);
493     CGFloat xTrans = NSMinX(screenFrame) - NSMinX(finalFrame);
494     CGFloat yTrans = NSMinY(screenFrame) - NSMinY(finalFrame);
495     initialWindowFrame.size = NSMakeSize(NSWidth(initialFrame) * xScale, NSHeight(initialFrame) * yScale);
496     initialWindowFrame.origin = NSMakePoint
497     ( NSMinX(initialFrame) + xTrans / (NSWidth(finalFrame) / NSWidth(initialFrame))
498      , NSMinY(initialFrame) + yTrans / (NSHeight(finalFrame) / NSHeight(initialFrame)));
499     return initialWindowFrame;
500 }
501
502 - (void)_startEnterFullScreenAnimationWithDuration:(NSTimeInterval)duration
503 {
504     NSRect screenFrame = [[[self window] screen] frame];
505     NSRect initialWindowFrame = windowFrameFromApparentFrames(screenFrame, _initialFrame, _finalFrame);
506     
507     _scaleAnimation = adoptNS([[WebWindowScaleAnimation alloc] initWithHintedDuration:duration window:[self window] initalFrame:initialWindowFrame finalFrame:screenFrame]);
508     
509     [_scaleAnimation.get() setAnimationBlockingMode:NSAnimationNonblocking];
510     [_scaleAnimation.get() setDelegate:self];
511     [_scaleAnimation.get() setCurrentProgress:0];
512     [_scaleAnimation.get() startAnimation];
513     
514     // setClipRectForWindow takes window coordinates, so convert from screen coordinates here:
515     NSRect finalBounds = _finalFrame;
516 #pragma clang diagnostic push
517 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
518     finalBounds.origin = [[self window] convertScreenToBase:finalBounds.origin];
519 #pragma clang diagnostic pop
520     setClipRectForWindow(self.window, finalBounds);
521     
522     [[self window] makeKeyAndOrderFront:self];
523     
524     if (!_backgroundWindow)
525         _backgroundWindow = createBackgroundFullscreenWindow(screenFrame);
526     else
527         [_backgroundWindow.get() setFrame:screenFrame display:NO];
528     
529     CGFloat currentAlpha = 0;
530     if (_fadeAnimation) {
531         currentAlpha = [_fadeAnimation.get() currentAlpha];
532         [_fadeAnimation.get() stopAnimation];
533         [_fadeAnimation.get() setWindow:nil];
534     }
535     
536     _fadeAnimation = adoptNS([[WebWindowFadeAnimation alloc] initWithDuration:duration 
537                                                                        window:_backgroundWindow.get() 
538                                                                  initialAlpha:currentAlpha 
539                                                                    finalAlpha:1]);
540     [_fadeAnimation.get() setAnimationBlockingMode:NSAnimationNonblocking];
541     [_fadeAnimation.get() setCurrentProgress:0];
542     [_fadeAnimation.get() startAnimation];
543     
544     [_backgroundWindow.get() orderWindow:NSWindowBelow relativeTo:[[self window] windowNumber]];
545     
546 #pragma clang diagnostic push
547 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
548     [[self window] setAutodisplay:YES];
549 #pragma clang diagnostic pop
550     [[self window] displayIfNeeded];
551 #pragma clang diagnostic push
552 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
553     // Screen updates disabled in enterFullScreen:
554     NSEnableScreenUpdates();
555 #pragma clang diagnostic pop
556 }
557
558 - (void)_startExitFullScreenAnimationWithDuration:(NSTimeInterval)duration
559 {
560     NSRect screenFrame = [[[self window] screen] frame];
561     NSRect initialWindowFrame = windowFrameFromApparentFrames(screenFrame, _initialFrame, _finalFrame);
562     
563     NSRect currentFrame = _scaleAnimation ? [_scaleAnimation.get() currentFrame] : [[self window] frame];
564     _scaleAnimation = adoptNS([[WebWindowScaleAnimation alloc] initWithHintedDuration:duration window:[self window] initalFrame:currentFrame finalFrame:initialWindowFrame]);
565     
566     [_scaleAnimation.get() setAnimationBlockingMode:NSAnimationNonblocking];
567     [_scaleAnimation.get() setDelegate:self];
568     [_scaleAnimation.get() setCurrentProgress:0];
569     [_scaleAnimation.get() startAnimation];
570     
571     if (!_backgroundWindow)
572         _backgroundWindow = createBackgroundFullscreenWindow(screenFrame);
573     else
574         [_backgroundWindow.get() setFrame:screenFrame display:NO];
575     
576     CGFloat currentAlpha = 1;
577     if (_fadeAnimation) {
578         currentAlpha = [_fadeAnimation.get() currentAlpha];
579         [_fadeAnimation.get() stopAnimation];
580         [_fadeAnimation.get() setWindow:nil];
581     }
582     _fadeAnimation = adoptNS([[WebWindowFadeAnimation alloc] initWithDuration:duration 
583                                                                        window:_backgroundWindow.get() 
584                                                                  initialAlpha:currentAlpha 
585                                                                    finalAlpha:0]);
586     [_fadeAnimation.get() setAnimationBlockingMode:NSAnimationNonblocking];
587     [_fadeAnimation.get() setCurrentProgress:0];
588     [_fadeAnimation.get() startAnimation];
589     
590     [_backgroundWindow.get() orderWindow:NSWindowBelow relativeTo:[[self window] windowNumber]];
591     
592     // setClipRectForWindow takes window coordinates, so convert from screen coordinates here:
593     NSRect finalBounds = _finalFrame;
594 #pragma clang diagnostic push
595 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
596     finalBounds.origin = [[self window] convertScreenToBase:finalBounds.origin];
597 #pragma clang diagnostic pop
598     setClipRectForWindow(self.window, finalBounds);
599     
600 #pragma clang diagnostic push
601 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
602     [[self window] setAutodisplay:YES];
603 #pragma clang diagnostic pop
604     [[self window] displayIfNeeded];
605
606 #pragma clang diagnostic push
607 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
608     // Screen updates disabled in exitFullScreen:
609     NSEnableScreenUpdates();
610 #pragma clang diagnostic pop
611 }
612
613 @end
614
615
616 #endif /* ENABLE(FULLSCREEN_API) && !PLATFORM(IOS) */