Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1062)

Side by Side Diff: chrome/browser/ui/cocoa/browser_window_fullscreen_transition.mm

Issue 1276383004: Implemented fullscreen exit animation with AppKit (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed format issues Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #import "chrome/browser/ui/cocoa/browser_window_enter_fullscreen_transition.h" 5 #import "chrome/browser/ui/cocoa/browser_window_fullscreen_transition.h"
6 6
7 #include <QuartzCore/QuartzCore.h> 7 #include <QuartzCore/QuartzCore.h>
8 8
9 #include "base/mac/scoped_cftyperef.h" 9 #include "base/mac/scoped_cftyperef.h"
10 #include "base/mac/scoped_nsobject.h" 10 #include "base/mac/scoped_nsobject.h"
11 #include "base/mac/sdk_forward_declarations.h" 11 #include "base/mac/sdk_forward_declarations.h"
12 #import "chrome/browser/ui/cocoa/framed_browser_window.h"
13 #import "chrome/browser/ui/cocoa/full_size_content_window.h"
12 14
13 namespace { 15 namespace {
14 16
15 NSString* const kPrimaryWindowAnimationID = @"PrimaryWindowAnimationID"; 17 NSString* const kPrimaryWindowAnimationID = @"PrimaryWindowAnimationID";
16 NSString* const kSnapshotWindowAnimationID = @"SnapshotWindowAnimationID"; 18 NSString* const kSnapshotWindowAnimationID = @"SnapshotWindowAnimationID";
17 NSString* const kAnimationIDKey = @"AnimationIDKey"; 19 NSString* const kAnimationIDKey = @"AnimationIDKey";
18 20
19 // This class has two simultaneous animations to resize and reposition layers. 21 // This class has two simultaneous animations to resize and reposition layers.
20 // These animations must use the same timing function, otherwise there will be 22 // These animations must use the same timing function, otherwise there will be
21 // visual discordance. 23 // visual discordance.
22 NSString* TransformAnimationTimingFunction() { 24 NSString* TransformAnimationTimingFunction() {
23 return kCAMediaTimingFunctionEaseInEaseOut; 25 return kCAMediaTimingFunctionEaseInEaseOut;
24 } 26 }
25 27
26 } // namespace 28 } // namespace
27 29
28 @interface BrowserWindowEnterFullscreenTransition () { 30
31 @interface BrowserWindowFullscreenTransition () {
32
33 // Flag to keep track of whether we are entering or exiting full screen
34 BOOL isEnteringFullscreen;
35
29 // The window which is undergoing the fullscreen transition. 36 // The window which is undergoing the fullscreen transition.
30 base::scoped_nsobject<NSWindow> primaryWindow_; 37 base::scoped_nsobject<FramedBrowserWindow> primaryWindow_;
31 38
32 // A layer that holds a snapshot of the original state of |primaryWindow_|. 39 // A layer that holds a snapshot of the original state of |primaryWindow_|.
33 base::scoped_nsobject<CALayer> snapshotLayer_; 40 base::scoped_nsobject<CALayer> snapshotLayer_;
34 41
35 // A temporary window that holds |snapshotLayer_|. 42 // A temporary window that holds |snapshotLayer_|.
36 base::scoped_nsobject<NSWindow> snapshotWindow_; 43 base::scoped_nsobject<NSWindow> snapshotWindow_;
37 44
38 // The frame of the |primaryWindow_| before the transition began.
39 NSRect primaryWindowInitialFrame_;
40
41 // The background color of |primaryWindow_| before the transition began. 45 // The background color of |primaryWindow_| before the transition began.
42 base::scoped_nsobject<NSColor> primaryWindowInitialBackgroundColor_; 46 base::scoped_nsobject<NSColor> primaryWindowInitialBackgroundColor_;
43 47
44 // Whether |primaryWindow_| was opaque before the transition began. 48 // Whether |primaryWindow_| was opaque before the transition began.
45 BOOL primaryWindowInitialOpaque_; 49 BOOL primaryWindowInitialOpaque_;
46 50
47 // Whether the instance is in the process of changing the size of 51 // Whether the instance is in the process of changing the size of
48 // |primaryWindow_|. 52 // |primaryWindow_|.
49 BOOL changingPrimaryWindowSize_; 53 BOOL changingPrimaryWindowSize_;
50 54
55 // The frame of the |primaryWindow_| before it starts the transition.
56 NSRect initialFrame_;
57
58 // The frame of the |primaryWindow_| before it starts the transition
59 // relative the the coordinates of its current screen
erikchen 2015/08/10 18:06:25 s/the/to
spqchan1 2015/08/11 21:43:48 Done.
60 NSRect initialFrameRelativeToScreen_;
61
51 // The frame that |primaryWindow_| is expected to have after the transition 62 // The frame that |primaryWindow_| is expected to have after the transition
52 // is finished. 63 // is finished.
53 NSRect primaryWindowFinalFrame_; 64 NSRect finalFrame_;
54 } 65 }
55 66
56 // Takes a snapshot of |primaryWindow_| and puts it in |snapshotLayer_|. 67 // Takes a snapshot of |primaryWindow_| and puts it in |snapshotLayer_|.
57 - (void)takeSnapshot; 68 - (void)takeSnapshot;
58 69
59 // Creates |snapshotWindow_| and adds |snapshotLayer_| to it. 70 // Creates |snapshotWindow_| and adds |snapshotLayer_| to it.
60 - (void)makeAndPrepareSnapshotWindow; 71 - (void)makeAndPrepareSnapshotWindow;
61 72
62 // This method has several effects on |primaryWindow_|: 73 // This method has several effects on |primaryWindow_|:
63 // - Saves current state. 74 // - Saves current state.
64 // - Makes window transparent, with clear background. 75 // - Makes window transparent, with clear background.
65 // - Adds NSFullScreenWindowMask style mask. 76 // - If we are entering full screen, it will also:
66 // - Sets the size to the screen's size. 77 // - Adds NSFullScreenWindowMask style mask.
78 // - Sets the size to the screen's size.
67 - (void)preparePrimaryWindowForAnimation; 79 - (void)preparePrimaryWindowForAnimation;
68 80
81 // Returns the windows to be used in the custom transition.
82 // - Takes a snapshot of the current window.
83 // - Makes a new snapshot window which shows the snapshot in the same
84 // location as the current window.
85 // - Adds the style mask NSFullScreenWindowMask to the current window.
erikchen 2015/08/10 18:06:25 Doesn't this only apply to the enter fullscreen tr
spqchan1 2015/08/12 21:07:36 Done.
86 // - Makes the current window transparent, and resizes the current window to
87 // be the same size as the screen.
88 - (NSArray*)customWindowsForFullScreenTransition;
89
69 // Applies the fullscreen animation to |snapshotLayer_|. 90 // Applies the fullscreen animation to |snapshotLayer_|.
70 - (void)animateSnapshotWindowWithDuration:(CGFloat)duration; 91 - (void)animateSnapshotWindowWithDuration:(CGFloat)duration;
71 92
72 // Applies the fullscreen animation to the root layer of |primaryWindow_|. 93 - (void)setPrimaryWindowToFinalFrame;
erikchen 2015/08/10 18:06:25 What does this method do? Comment please. The ver
spqchan1 2015/08/12 21:07:37 Changed to changePrimaryWindowToFinalFrame
73 - (void)animatePrimaryWindowWithDuration:(CGFloat)duration;
74 94
75 // Override of CAAnimation delegate method.
76 - (void)animationDidStop:(CAAnimation*)theAnimation finished:(BOOL)flag;
77
78 // Returns the layer of the root view of |window|.
79 - (CALayer*)rootLayerOfWindow:(NSWindow*)window; 95 - (CALayer*)rootLayerOfWindow:(NSWindow*)window;
80 96
81 @end 97 @end
82 98
83 @implementation BrowserWindowEnterFullscreenTransition 99 @implementation BrowserWindowFullscreenTransition
84 100
85 // -------------------------Public Methods---------------------------- 101 // -------------------------Public Methods----------------------------
86 102
87 - (instancetype)initWithWindow:(NSWindow*)window { 103 - (instancetype)initWithWindow:(FramedBrowserWindow*)window {
88 DCHECK(window); 104 DCHECK(window);
89 DCHECK([self rootLayerOfWindow:window]); 105 DCHECK([self rootLayerOfWindow:window]);
90 if ((self = [super init])) { 106 if ((self = [super init])) {
91 primaryWindow_.reset([window retain]); 107 primaryWindow_.reset([window retain]);
92 } 108 }
93 return self; 109 return self;
94 } 110 }
95 111
96 - (NSArray*)customWindowsToEnterFullScreen { 112 - (NSArray*)customWindowsToEnterFullScreenTransition {
97 [self takeSnapshot]; 113 isEnteringFullscreen = YES;
98 [self makeAndPrepareSnapshotWindow]; 114 initialFrame_ = [primaryWindow_ frame];
99 [self preparePrimaryWindowForAnimation]; 115 finalFrame_ = [[primaryWindow_ screen] frame];
100 return @[ primaryWindow_.get(), snapshotWindow_.get() ]; 116
117 return [self customWindowsForFullScreenTransition];
101 } 118 }
102 119
103 - (void)startCustomAnimationToEnterFullScreenWithDuration: 120 - (NSArray*)customWindowsToExitFullScreenTransition {
121 isEnteringFullscreen = NO;
122 finalFrame_ = initialFrame_;
erikchen 2015/08/10 18:06:25 It looks like you're trying to keep this class aro
spqchan1 2015/08/12 21:07:36 Done.
123 initialFrame_ = [[primaryWindow_ screen] frame];
124
125 // Calculate the inital frame that is relative to coordinates of the
126 // screen which it's on
127 initialFrameRelativeToScreen_ = finalFrame_;
128 CGFloat screenOriginX = finalFrame_.origin.x - initialFrame_.origin.x;
129 CGFloat screenOriginY = finalFrame_.origin.y - initialFrame_.origin.y;
130 initialFrameRelativeToScreen_.origin =
131 CGPointMake(screenOriginX, screenOriginY);
erikchen 2015/08/10 18:06:25 This logic can be moved into initial setup, and th
spqchan1 2015/08/12 21:07:36 Done.
132
133 return [self customWindowsForFullScreenTransition];
134 }
135
136 // Right before the animation begins, change the content view size
137 // and lock the primary window so that OSX can't make changes to it
erikchen 2015/08/10 18:06:25 All method comments should be at the declarations,
spqchan1 2015/08/12 21:07:36 Done.
138 // before we finish the animation
139 - (void)startCustomExitFullScreenAnimationWithDuration:
104 (NSTimeInterval)duration { 140 (NSTimeInterval)duration {
erikchen 2015/08/10 18:06:25 Given the way that you've organized this class, I
spqchan1 2015/08/12 21:07:37 Done.
141 FullSizeContentView* content =
142 (FullSizeContentView*)[primaryWindow_ contentView];
erikchen 2015/08/10 18:06:25 No C-style casts
spqchan1 2015/08/12 21:07:36 Done.
143 [content forceFrameSize:finalFrame_.size];
erikchen 2015/08/10 18:06:25 At some point, don't you need to undo the forceFra
spqchan1 2015/08/11 21:43:48 Once the NSWindow is resized, the content will als
144 [primaryWindow_ setFrameAndStyleLock:YES];
145
146 [self animatePrimaryWindowWithDuration:duration];
105 [self animateSnapshotWindowWithDuration:duration]; 147 [self animateSnapshotWindowWithDuration:duration];
148 }
149
150 - (void)startCustomEnterFullScreenAnimationWithDuration:
151 (NSTimeInterval)duration {
106 [self animatePrimaryWindowWithDuration:duration]; 152 [self animatePrimaryWindowWithDuration:duration];
153 [self animateSnapshotWindowWithDuration:duration];
107 } 154 }
108 155
109 - (BOOL)shouldWindowBeUnconstrained { 156 - (BOOL)shouldWindowBeUnconstrained {
110 return changingPrimaryWindowSize_; 157 return changingPrimaryWindowSize_;
111 } 158 }
112 159
113 // -------------------------Private Methods---------------------------- 160 // -------------------------Private Methods----------------------------
114 161
115 - (void)takeSnapshot { 162 - (void)takeSnapshot {
116 base::ScopedCFTypeRef<CGImageRef> windowSnapshot(CGWindowListCreateImage( 163 base::ScopedCFTypeRef<CGImageRef> windowSnapshot(CGWindowListCreateImage(
(...skipping 24 matching lines...) Expand all
141 [snapshotWindow_ orderFront:nil]; 188 [snapshotWindow_ orderFront:nil];
142 [[[snapshotWindow_ contentView] layer] addSublayer:snapshotLayer_]; 189 [[[snapshotWindow_ contentView] layer] addSublayer:snapshotLayer_];
143 190
144 // Compute the frame of the snapshot layer such that the snapshot is 191 // Compute the frame of the snapshot layer such that the snapshot is
145 // positioned exactly on top of the original position of |primaryWindow_|. 192 // positioned exactly on top of the original position of |primaryWindow_|.
146 NSRect snapshotLayerFrame = 193 NSRect snapshotLayerFrame =
147 [snapshotWindow_ convertRectFromScreen:[primaryWindow_ frame]]; 194 [snapshotWindow_ convertRectFromScreen:[primaryWindow_ frame]];
148 [snapshotLayer_ setFrame:snapshotLayerFrame]; 195 [snapshotLayer_ setFrame:snapshotLayerFrame];
149 } 196 }
150 197
151 - (void)preparePrimaryWindowForAnimation { 198 - (NSArray*)customWindowsForFullScreenTransition {
152 // Save initial state of |primaryWindow_|. 199 [self takeSnapshot];
153 primaryWindowInitialFrame_ = [primaryWindow_ frame]; 200 [self makeAndPrepareSnapshotWindow];
154 primaryWindowInitialBackgroundColor_.reset( 201 [self preparePrimaryWindowForAnimation];
155 [[primaryWindow_ backgroundColor] copy]); 202 return @[ primaryWindow_.get(), snapshotWindow_.get() ];
156 primaryWindowInitialOpaque_ = [primaryWindow_ isOpaque];
157
158 primaryWindowFinalFrame_ = [[primaryWindow_ screen] frame];
159
160 // Make |primaryWindow_| invisible. This must happen before the window is
161 // resized, since resizing the window will call drawRect: and cause content
162 // to flash over the entire screen.
163 [primaryWindow_ setOpaque:NO];
164 [primaryWindow_ setBackgroundColor:[NSColor clearColor]];
165 CALayer* rootLayer = [self rootLayerOfWindow:primaryWindow_];
166 rootLayer.opacity = 0;
167
168 // As soon as the style mask includes the flag NSFullScreenWindowMask, the
169 // window is expected to receive fullscreen layout. This must be set before
170 // the window is resized, as that causes a relayout.
171 [primaryWindow_
172 setStyleMask:[primaryWindow_ styleMask] | NSFullScreenWindowMask];
173
174 // Resize |primaryWindow_|.
175 changingPrimaryWindowSize_ = YES;
176 [primaryWindow_ setFrame:primaryWindowFinalFrame_ display:YES];
177 changingPrimaryWindowSize_ = NO;
178 } 203 }
179 204
180 - (void)animateSnapshotWindowWithDuration:(CGFloat)duration { 205 - (void)animateSnapshotWindowWithDuration:(CGFloat)duration {
181 // Move the snapshot layer until it's bottom-left corner is at the 206 [snapshotWindow_ orderFront:nil];
erikchen 2015/08/10 18:06:25 why did you add this? Right now the snapshotWindow
spqchan1 2015/08/12 21:07:37 Remove it from the original location
182 // bottom-left corner of the screen. 207 NSRect finalScreenFrame = [snapshotWindow_ convertRectFromScreen:finalFrame_];
erikchen 2015/08/10 18:06:25 I don't understand this variable. Please add comme
spqchan1 2015/08/12 21:07:36 Done.
208
183 CABasicAnimation* positionAnimation = 209 CABasicAnimation* positionAnimation =
184 [CABasicAnimation animationWithKeyPath:@"position"]; 210 [CABasicAnimation animationWithKeyPath:@"position"];
185 positionAnimation.toValue = [NSValue valueWithPoint:NSZeroPoint]; 211 positionAnimation.toValue = [NSValue valueWithPoint:finalScreenFrame.origin];
186 positionAnimation.timingFunction = [CAMediaTimingFunction 212 positionAnimation.timingFunction = [CAMediaTimingFunction
187 functionWithName:TransformAnimationTimingFunction()]; 213 functionWithName:TransformAnimationTimingFunction()];
188 214
189 // Expand the bounds until it covers the screen. 215 // Resize the bounds until it reaches the expected size at the end of the
190 NSRect finalBounds = NSMakeRect(0, 0, NSWidth(primaryWindowFinalFrame_), 216 // animation.
191 NSHeight(primaryWindowFinalFrame_)); 217 NSRect finalBounds = NSMakeRect(0, 0, NSWidth(finalFrame_),
218 NSHeight(finalFrame_));
192 CABasicAnimation* boundsAnimation = 219 CABasicAnimation* boundsAnimation =
193 [CABasicAnimation animationWithKeyPath:@"bounds"]; 220 [CABasicAnimation animationWithKeyPath:@"bounds"];
194 boundsAnimation.toValue = [NSValue valueWithRect:finalBounds]; 221 boundsAnimation.toValue = [NSValue valueWithRect:finalBounds];
195 boundsAnimation.timingFunction = [CAMediaTimingFunction 222 boundsAnimation.timingFunction = [CAMediaTimingFunction
196 functionWithName:TransformAnimationTimingFunction()]; 223 functionWithName:TransformAnimationTimingFunction()];
197 224
198 // Fade out the snapshot layer. 225 // Fade out the snapshot layer.
199 CABasicAnimation* opacityAnimation = 226 CABasicAnimation* opacityAnimation =
200 [CABasicAnimation animationWithKeyPath:@"opacity"]; 227 [CABasicAnimation animationWithKeyPath:@"opacity"];
201 opacityAnimation.toValue = @(0.0); 228 opacityAnimation.toValue = @(0.0);
202 opacityAnimation.timingFunction = 229 opacityAnimation.timingFunction =
203 [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]; 230 [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn];
204 231
205 // Fill forwards, and don't remove the animation. When the animation 232 // Fill forwards, and don't remove the animation. When the animation
206 // completes, the entire window will be removed. 233 // completes, the entire window will be removed.
207 CAAnimationGroup* group = [CAAnimationGroup animation]; 234 CAAnimationGroup* group = [CAAnimationGroup animation];
208 group.removedOnCompletion = NO; 235 group.removedOnCompletion = NO;
209 group.fillMode = kCAFillModeForwards; 236 group.fillMode = kCAFillModeForwards;
210 group.animations = @[ positionAnimation, boundsAnimation, opacityAnimation ]; 237 group.animations = @[ positionAnimation, boundsAnimation, opacityAnimation ];
211 group.duration = duration; 238 group.duration = duration;
212 [group setValue:kSnapshotWindowAnimationID forKey:kAnimationIDKey]; 239 [group setValue:kSnapshotWindowAnimationID forKey:kAnimationIDKey];
213 group.delegate = self; 240 group.delegate = self;
214 241
215 [snapshotLayer_ addAnimation:group forKey:nil]; 242 [snapshotLayer_ addAnimation:group forKey:nil];
216 } 243 }
217 244
218 - (void)animatePrimaryWindowWithDuration:(CGFloat)duration { 245 - (void)animatePrimaryWindowWithDuration:(CGFloat)duration {
246
erikchen 2015/08/10 18:06:25 whitespace
spqchan1 2015/08/11 21:43:48 Done.
spqchan1 2015/08/11 21:43:48 Done.
219 // As soon as the window's root layer is scaled down, the opacity should be 247 // As soon as the window's root layer is scaled down, the opacity should be
220 // set back to 1. There are a couple of ways to do this. The easiest is to 248 // set back to 1. There are a couple of ways to do this. The easiest is to
221 // just have a dummy animation as part of the same animation group. 249 // just have a dummy animation as part of the same animation group.
222 CABasicAnimation* opacityAnimation = 250 CABasicAnimation* opacityAnimation =
223 [CABasicAnimation animationWithKeyPath:@"opacity"]; 251 [CABasicAnimation animationWithKeyPath:@"opacity"];
224 opacityAnimation.fromValue = @(1.0); 252 opacityAnimation.fromValue = @(1.0);
225 opacityAnimation.toValue = @(1.0); 253 opacityAnimation.toValue = @(1.0);
254 opacityAnimation.duration = duration;
erikchen 2015/08/10 18:06:25 why is this necessary? Shouldn't setting the group
spqchan1 2015/08/11 21:43:48 Removed it. This is dead code from an experiment.
226 255
227 // The root layer's size should start scaled down to the initial size of 256 // The root layer's size should start scaled down to the initial size of
228 // |primaryWindow_|. The animation increases the size until the root layer 257 // |primaryWindow_|. The animation increases the size until the root layer
229 // fills the screen. 258 // fills the screen.
230 NSRect initialFrame = primaryWindowInitialFrame_; 259 NSRect initialFrame = initialFrame_;
231 NSRect endFrame = primaryWindowFinalFrame_; 260 NSRect endFrame = finalFrame_;
232 CGFloat xScale = NSWidth(initialFrame) / NSWidth(endFrame); 261 CGFloat xScale = NSWidth(initialFrame) / NSWidth(endFrame);
233 CGFloat yScale = NSHeight(initialFrame) / NSHeight(endFrame); 262 CGFloat yScale = NSHeight(initialFrame) / NSHeight(endFrame);
234 CATransform3D initial = CATransform3DMakeScale(xScale, yScale, 1); 263 CATransform3D initial = CATransform3DMakeScale(xScale, yScale, 1);
235 CABasicAnimation* transformAnimation = 264 CABasicAnimation* transformAnimation =
236 [CABasicAnimation animationWithKeyPath:@"transform"]; 265 [CABasicAnimation animationWithKeyPath:@"transform"];
237 transformAnimation.fromValue = [NSValue valueWithCATransform3D:initial]; 266 transformAnimation.fromValue = [NSValue valueWithCATransform3D:initial];
238 267
239 CALayer* root = [self rootLayerOfWindow:primaryWindow_];
240
241 // Calculate the initial position of the root layer. This calculation is 268 // Calculate the initial position of the root layer. This calculation is
242 // agnostic of the anchorPoint. 269 // agnostic of the anchorPoint.
270 CALayer* root = [self rootLayerOfWindow:primaryWindow_];
243 CGFloat layerStartPositionDeltaX = NSMidX(initialFrame) - NSMidX(endFrame); 271 CGFloat layerStartPositionDeltaX = NSMidX(initialFrame) - NSMidX(endFrame);
244 CGFloat layerStartPositionDeltaY = NSMidY(initialFrame) - NSMidY(endFrame); 272 CGFloat layerStartPositionDeltaY = NSMidY(initialFrame) - NSMidY(endFrame);
245 NSPoint layerStartPosition = 273 NSPoint layerStartPosition =
246 NSMakePoint(root.position.x + layerStartPositionDeltaX, 274 NSMakePoint(root.position.x + layerStartPositionDeltaX,
247 root.position.y + layerStartPositionDeltaY); 275 root.position.y + layerStartPositionDeltaY);
248 276
249 // Animate the primary window from its initial position. 277 // Animate the primary window from its initial position.
250 CABasicAnimation* positionAnimation = 278 CABasicAnimation* positionAnimation =
251 [CABasicAnimation animationWithKeyPath:@"position"]; 279 [CABasicAnimation animationWithKeyPath:@"position"];
252 positionAnimation.fromValue = [NSValue valueWithPoint:layerStartPosition]; 280 positionAnimation.fromValue = [NSValue valueWithPoint:layerStartPosition];
253 281
254 CAAnimationGroup* group = [CAAnimationGroup animation]; 282 CAAnimationGroup* group = [CAAnimationGroup animation];
255 group.removedOnCompletion = NO; 283 group.removedOnCompletion = NO;
256 group.fillMode = kCAFillModeForwards; 284 group.fillMode = kCAFillModeForwards;
257 group.animations = 285 group.animations =
258 @[ transformAnimation, opacityAnimation, positionAnimation ]; 286 @[ opacityAnimation, positionAnimation, transformAnimation];
erikchen 2015/08/10 18:06:25 formatting (missing whitespace)
spqchan1 2015/08/11 21:43:48 Done.
259 group.timingFunction = [CAMediaTimingFunction 287 group.timingFunction = [CAMediaTimingFunction
260 functionWithName:TransformAnimationTimingFunction()]; 288 functionWithName:TransformAnimationTimingFunction()];
261 group.duration = duration; 289 group.duration = duration;
262 [group setValue:kPrimaryWindowAnimationID forKey:kAnimationIDKey]; 290 [group setValue:kPrimaryWindowAnimationID forKey:kAnimationIDKey];
263 group.delegate = self; 291 group.delegate = self;
264 292
265 [root addAnimation:group forKey:kPrimaryWindowAnimationID]; 293 [root addAnimation:group forKey:kPrimaryWindowAnimationID];
266 } 294 }
267 295
296 - (void)preparePrimaryWindowForAnimation {
erikchen 2015/08/10 18:06:25 Why did you move the location of this method? I ge
spqchan1 2015/08/12 21:07:37 Done
297 // Save the initial state of the primary window
298 primaryWindowInitialBackgroundColor_.reset(
299 [[primaryWindow_ backgroundColor] copy]);
300 primaryWindowInitialOpaque_ = [primaryWindow_ isOpaque];
301
302 [primaryWindow_ setOpaque:NO];
303
304 CALayer* root = [self rootLayerOfWindow:primaryWindow_];
305 root.opacity = 0;
306 root.frame = initialFrameRelativeToScreen_;
307
308 if (isEnteringFullscreen) {
309 [primaryWindow_
310 setStyleMask:[primaryWindow_ styleMask] | NSFullScreenWindowMask];
311 [self setPrimaryWindowToFinalFrame];
312 }
313
314 }
315
316 - (void)setPrimaryWindowToFinalFrame {
317 changingPrimaryWindowSize_ = YES;
318 [primaryWindow_ setFrame:finalFrame_ display:NO];
319 changingPrimaryWindowSize_ = NO;
320 }
321
322
268 - (void)animationDidStop:(CAAnimation*)theAnimation finished:(BOOL)flag { 323 - (void)animationDidStop:(CAAnimation*)theAnimation finished:(BOOL)flag {
269 NSString* animationID = [theAnimation valueForKey:kAnimationIDKey]; 324 NSString* animationID = [theAnimation valueForKey:kAnimationIDKey];
325
326 // Remove the snapshot window
270 if ([animationID isEqual:kSnapshotWindowAnimationID]) { 327 if ([animationID isEqual:kSnapshotWindowAnimationID]) {
271 [snapshotWindow_ orderOut:nil]; 328 [snapshotWindow_ orderOut:nil];
272 snapshotWindow_.reset(); 329 snapshotWindow_.reset();
273 snapshotLayer_.reset(); 330 snapshotLayer_.reset();
274 return; 331 return;
275 } 332 }
276 333
277 if ([animationID isEqual:kPrimaryWindowAnimationID]) { 334 if ([animationID isEqual:kPrimaryWindowAnimationID]) {
278 [primaryWindow_ setOpaque:YES]; 335 // If we're exiting full screen, we want to set the primary window
336 // size to the expected frame at the end
erikchen 2015/08/10 18:06:25 formatting of the comment. Also periods.
spqchan1 2015/08/11 21:43:48 Done.
337 // We will also need to unlock the frame
338 if (!isEnteringFullscreen) {
339 [primaryWindow_ setFrameAndStyleLock:NO];
erikchen 2015/08/10 18:06:25 It's very, very important that we remember to call
spqchan1 2015/08/11 21:43:48 Done.
340 [primaryWindow_
341 setStyleMask:[primaryWindow_ styleMask] & ~NSFullScreenWindowMask];
342 [self setPrimaryWindowToFinalFrame];
343 }
344
345 // Restore the state of the primary window and make it visible again
346 [primaryWindow_ setOpaque:primaryWindowInitialOpaque_];
279 [primaryWindow_ setBackgroundColor:primaryWindowInitialBackgroundColor_]; 347 [primaryWindow_ setBackgroundColor:primaryWindowInitialBackgroundColor_];
348
280 CALayer* root = [self rootLayerOfWindow:primaryWindow_]; 349 CALayer* root = [self rootLayerOfWindow:primaryWindow_];
350 [root removeAnimationForKey:kPrimaryWindowAnimationID];
281 root.opacity = 1; 351 root.opacity = 1;
282 [root removeAnimationForKey:kPrimaryWindowAnimationID]; 352
283 } 353 }
284 } 354 }
285 355
286 - (CALayer*)rootLayerOfWindow:(NSWindow*)window { 356 - (CALayer*)rootLayerOfWindow:(NSWindow*)window {
287 return [[[window contentView] superview] layer]; 357 return [[[window contentView] superview] layer];
288 } 358 }
289 359
290 @end 360 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698