summaryrefslogtreecommitdiffstats
path: root/chrome/browser/ui/cocoa/browser_window_enter_fullscreen_transition.h
blob: d947200edfbad984fe189f5fbc940e898bcffdee (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CHROME_BROWSER_UI_COCOA_BROWSER_WINDOW_FULLSCREEN_TRANSITION_H_
#define CHROME_BROWSER_UI_COCOA_BROWSER_WINDOW_FULLSCREEN_TRANSITION_H_

#import <Cocoa/Cocoa.h>

// This class is responsible for managing the custom transition of a
// BrowserWindow from its normal state into an AppKit Fullscreen state.
//
// By default, when AppKit Fullscreens a window, it creates a new virtual
// desktop and slides it in from the right of the screen. At the same time, the
// old virtual desktop slides off to the left. This animation takes one second,
// and the time is not customizable without elevated privileges or a
// self-modifying binary
// (https://code.google.com/p/chromium/issues/detail?id=414527). During that
// second, no user interaction is possible.
//
// The default implementation of the AppKit transition smoothly animates a
// window from its original size to the full size of the screen. At the
// beginning of the animation, it takes a snapshot of the window's current
// state. Then it resizes the window, calls drawRect: (theorized, not tested),
// and takes a snapshot of the window's final state. The animation is a simple
// crossfade between the two snapshots. This has a flaw. Frequently, the
// renderer has not yet drawn content for the resized window by the time
// drawRect: is called. As a result, the animation is effectively a no-op. When
// the animation is finished, the new web content flashes in.
//
// The window's delegate can override two methods to customize the transition.
//  -customWindowsToEnterFullScreenForWindow:
//    The return of this method is an array of NSWindows. Each window that is
//    returned will be added to the new virtual desktop after the animation is
//    finished, but will not be a part of the animation itself.
//  -window:startCustomAnimationToEnterFullScreenWithDuration:
//    In this method, the window's delegate adds animations to the windows
//    returned in the above method.
//
// The goal of this class is to mimic the default animation, but instead of
// taking a snapshot of the final web content, it uses the live web content
// during the animation.
//
// See https://code.google.com/p/chromium/issues/detail?id=414527#c22 and its
// preceding comments for a more detailed description of the implementation,
// and the reasoning behind the decisions made.
//
// Recommended usage:
//  (Override method on NSWindow's delegate)
//  - (NSArray*)customWindowsToEnterFullScreenForWindow:(NSWindow*)window {
//    self.transition = [[[BrowserWindowEnterFullscreenTransition alloc]
//        initWithWindow:window] autorelease];
//    return [self.transition customWindowsToEnterFullScreen];
//  }
//
//  (Override method on NSWindow's delegate)
//  - (void)window:(NSWindow*)window
//  startCustomAnimationToEnterFullScreenWithDuration:(NSTimeInterval)duration {
//    [self.transition
//        startCustomAnimationToEnterFullScreenWithDuration:duration];
//  }
//
//  (Override method on NSWindow's delegate)
//  - (void)windowDidEnterFullScreen:(NSNotification*)notification {
//    self.transition = nil;
//  }
//
//  (Override method on NSWindow)
//  - (NSRect)constrainFrameRect:(NSRect)frame toScreen:(NSScreen*)screen {
//    if (self.transition && ![self.transition shouldWindowBeConstrained])
//      return frame;
//    return [super constrainFrameRect:frame toScreen:screen];
//  }

@interface BrowserWindowEnterFullscreenTransition : NSObject

// Designated initializer. |window| is the NSWindow that is going to be moved
// into a fullscreen Space (virtual desktop), and resized to have the same size
// as the screen. |window|'s root view must be layer backed.
- (instancetype)initWithWindow:(NSWindow*)window;

// Returns the windows to be used in the custom transition.
//   - Takes a snapshot of the current window.
//   - Makes a new snapshot window which shows the snapshot in the same
//   location as the current window.
//   - Adds the style mask NSFullScreenWindowMask to the current window.
//   - Makes the current window transparent, and resizes the current window to
//   be the same size as the screen.
- (NSArray*)customWindowsToEnterFullScreen;

// Begins the animations used for the custom fullscreen transition.
//   - Animates the snapshot to the full size of the screen while fading it out.
//   - Animates the current window from it's original location to its final
//   location, while fading it in.
// Note: The two animations are added to different layers in different windows.
// There is no explicit logic to keep the two animations in sync. If this
// proves to be a problem, the relevant layers should attempt to sync up their
// time offsets with CACurrentMediaTime().
- (void)startCustomAnimationToEnterFullScreenWithDuration:
    (NSTimeInterval)duration;

// When this method returns true, the NSWindow method
// -constrainFrameRect:toScreen: must return the frame rect without
// constraining it. The owner of the instance of this class is responsible for
// hooking up this logic.
- (BOOL)shouldWindowBeUnconstrained;

@end

#endif  // CHROME_BROWSER_UI_COCOA_BROWSER_WINDOW_FULLSCREEN_TRANSITION_H_