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