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

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

Issue 1876313002: Fixed a fullscreen race condition on OSX (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@2661
Patch Set: Created 4 years, 8 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
« no previous file with comments | « chrome/browser/ui/cocoa/browser_window_fullscreen_transition.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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_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/bind_objc_block.h" 9 #include "base/mac/bind_objc_block.h"
10 #include "base/mac/foundation_util.h" 10 #include "base/mac/foundation_util.h"
11 #include "base/mac/mac_util.h" 11 #include "base/mac/mac_util.h"
12 #import "base/mac/sdk_forward_declarations.h" 12 #import "base/mac/sdk_forward_declarations.h"
13 #include "base/macros.h" 13 #include "base/macros.h"
14 #include "base/memory/scoped_ptr.h" 14 #include "base/memory/scoped_ptr.h"
15 #import "chrome/browser/ui/cocoa/browser_window_controller.h"
15 #import "chrome/browser/ui/cocoa/framed_browser_window.h" 16 #import "chrome/browser/ui/cocoa/framed_browser_window.h"
16 #import "chrome/browser/ui/cocoa/tabs/tab_strip_background_view.h" 17 #import "chrome/browser/ui/cocoa/tabs/tab_strip_background_view.h"
17 18
18 namespace { 19 namespace {
19 20
20 NSString* const kPrimaryWindowAnimationID = @"PrimaryWindowAnimationID"; 21 NSString* const kPrimaryWindowAnimationID = @"PrimaryWindowAnimationID";
21 NSString* const kSnapshotWindowAnimationID = @"SnapshotWindowAnimationID"; 22 NSString* const kSnapshotWindowAnimationID = @"SnapshotWindowAnimationID";
22 NSString* const kAnimationIDKey = @"AnimationIDKey"; 23 NSString* const kAnimationIDKey = @"AnimationIDKey";
23 24
24 // The fraction of the duration from AppKit's startCustomAnimation methods 25 // The fraction of the duration from AppKit's startCustomAnimation methods
25 // that we want our animation to run in. 26 // that we want our animation to run in. Yosemite's fraction is smaller
27 // since its fullscreen transition is significantly slower.
26 CGFloat const kAnimationDurationFraction = 0.5; 28 CGFloat const kAnimationDurationFraction = 0.5;
29 CGFloat const kAnimationDurationFractionYosemite = 0.3;
27 30
28 // This class has two simultaneous animations to resize and reposition layers. 31 // This class has two simultaneous animations to resize and reposition layers.
29 // These animations must use the same timing function, otherwise there will be 32 // These animations must use the same timing function, otherwise there will be
30 // visual discordance. 33 // visual discordance.
31 NSString* TransformAnimationTimingFunction() { 34 NSString* TransformAnimationTimingFunction() {
32 return kCAMediaTimingFunctionEaseInEaseOut; 35 return kCAMediaTimingFunctionEaseInEaseOut;
33 } 36 }
34 37
35 // This class locks and unlocks the FrameBrowserWindow. Its destructor ensures 38 // This class locks and unlocks the FrameBrowserWindow. Its destructor ensures
36 // that the lock gets released. 39 // that the lock gets released.
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 87
85 @end 88 @end
86 89
87 @interface BrowserWindowFullscreenTransition () { 90 @interface BrowserWindowFullscreenTransition () {
88 // Flag to keep track of whether we are entering or exiting fullscreen. 91 // Flag to keep track of whether we are entering or exiting fullscreen.
89 BOOL isEnteringFullscreen_; 92 BOOL isEnteringFullscreen_;
90 93
91 // The window which is undergoing the fullscreen transition. 94 // The window which is undergoing the fullscreen transition.
92 base::scoped_nsobject<FramedBrowserWindow> primaryWindow_; 95 base::scoped_nsobject<FramedBrowserWindow> primaryWindow_;
93 96
97 // The window which is undergoing the fullscreen transition.
98 BrowserWindowController* controller_; // weak
99
94 // A layer that holds a snapshot of the original state of |primaryWindow_|. 100 // A layer that holds a snapshot of the original state of |primaryWindow_|.
95 base::scoped_nsobject<CALayer> snapshotLayer_; 101 base::scoped_nsobject<CALayer> snapshotLayer_;
96 102
97 // A temporary window that holds |snapshotLayer_|. 103 // A temporary window that holds |snapshotLayer_|.
98 base::scoped_nsobject<NSWindow> snapshotWindow_; 104 base::scoped_nsobject<NSWindow> snapshotWindow_;
99 105
100 // The tabstrip background view in the window. During the exit fullscreen 106 // The tabstrip background view in the window. During the exit fullscreen
101 // animation, this view be hidden while a dummy tabstrip background will be 107 // animation, this view be hidden while a dummy tabstrip background will be
102 // drawn over the content view. 108 // drawn over the content view.
103 base::scoped_nsobject<NSView> tabStripBackgroundView_; 109 base::scoped_nsobject<NSView> tabStripBackgroundView_;
(...skipping 20 matching lines...) Expand all
124 // The frame that |primaryWindow_| is expected to have after the transition 130 // The frame that |primaryWindow_| is expected to have after the transition
125 // is finished. 131 // is finished.
126 NSRect finalFrame_; 132 NSRect finalFrame_;
127 133
128 // This view draws the tabstrip background during the exit animation. 134 // This view draws the tabstrip background during the exit animation.
129 base::scoped_nsobject<FullscreenTabStripBackgroundView> 135 base::scoped_nsobject<FullscreenTabStripBackgroundView>
130 fullscreenTabStripBackgroundView_; 136 fullscreenTabStripBackgroundView_;
131 137
132 // Locks and unlocks the FullSizeContentWindow. 138 // Locks and unlocks the FullSizeContentWindow.
133 scoped_ptr<FrameAndStyleLock> lock_; 139 scoped_ptr<FrameAndStyleLock> lock_;
140
141 // Flag that indicates if the animation was completed. Sets to true at the
142 // end of the animation.
143 BOOL completedTransition_;
134 } 144 }
135 145
136 // Takes a snapshot of |primaryWindow_| and puts it in |snapshotLayer_|. 146 // Takes a snapshot of |primaryWindow_| and puts it in |snapshotLayer_|.
137 - (void)takeSnapshot; 147 - (void)takeSnapshot;
138 148
139 // Creates |snapshotWindow_| and adds |snapshotLayer_| to it. 149 // Creates |snapshotWindow_| and adds |snapshotLayer_| to it.
140 - (void)makeAndPrepareSnapshotWindow; 150 - (void)makeAndPrepareSnapshotWindow;
141 151
142 // This method has several effects on |primaryWindow_|: 152 // This method has several effects on |primaryWindow_|:
143 // - Saves current state. 153 // - Saves current state.
(...skipping 29 matching lines...) Expand all
173 // relative to the second screen. As a result, we use this method to convert a 183 // relative to the second screen. As a result, we use this method to convert a
174 // NSPoint so that it's relative to the screen it's on. 184 // NSPoint so that it's relative to the screen it's on.
175 - (NSPoint)pointRelativeToCurrentScreen:(NSPoint)point; 185 - (NSPoint)pointRelativeToCurrentScreen:(NSPoint)point;
176 186
177 @end 187 @end
178 188
179 @implementation BrowserWindowFullscreenTransition 189 @implementation BrowserWindowFullscreenTransition
180 190
181 // -------------------------Public Methods---------------------------- 191 // -------------------------Public Methods----------------------------
182 192
183 - (instancetype)initEnterWithWindow:(FramedBrowserWindow*)window { 193 - (instancetype)initEnterWithController:(BrowserWindowController*)controller {
184 DCHECK(window); 194 DCHECK(controller);
185 DCHECK([self rootLayerOfWindow:window]); 195 DCHECK([self rootLayerOfWindow:[controller window]]);
186 if ((self = [super init])) { 196 if ((self = [super init])) {
187 primaryWindow_.reset([window retain]); 197 controller_ = controller;
198 FramedBrowserWindow* framedBrowserWindow =
199 base::mac::ObjCCast<FramedBrowserWindow>([controller window]);
200 primaryWindow_.reset([framedBrowserWindow retain]);
188 201
189 isEnteringFullscreen_ = YES; 202 isEnteringFullscreen_ = YES;
190 initialFrame_ = [primaryWindow_ frame]; 203 initialFrame_ = [primaryWindow_ frame];
191 finalFrame_ = [[primaryWindow_ screen] frame]; 204 finalFrame_ = [[primaryWindow_ screen] frame];
192 } 205 }
193 return self; 206 return self;
194 } 207 }
195 208
196 - (instancetype)initExitWithWindow:(FramedBrowserWindow*)window 209 - (instancetype)initExitWithController:(BrowserWindowController*)controller {
197 frame:(NSRect)frame 210 DCHECK(controller);
198 tabStripBackgroundView:(NSView*)view { 211 DCHECK([self rootLayerOfWindow:[controller window]]);
199 DCHECK(window);
200 DCHECK([self rootLayerOfWindow:window]);
201 if ((self = [super init])) { 212 if ((self = [super init])) {
202 primaryWindow_.reset([window retain]); 213 controller_ = controller;
203 tabStripBackgroundView_.reset([view retain]); 214 FramedBrowserWindow* framedBrowserWindow =
215 base::mac::ObjCCast<FramedBrowserWindow>([controller window]);
216 primaryWindow_.reset([framedBrowserWindow retain]);
217
204 isEnteringFullscreen_ = NO; 218 isEnteringFullscreen_ = NO;
205 finalFrame_ = frame;
206 initialFrame_ = [[primaryWindow_ screen] frame]; 219 initialFrame_ = [[primaryWindow_ screen] frame];
220 finalFrame_ = [controller savedRegularWindowFrame];
221 tabStripBackgroundView_.reset([[controller tabStripBackgroundView] retain]);
207 222
208 lock_.reset(new FrameAndStyleLock(window)); 223 lock_.reset(new FrameAndStyleLock(framedBrowserWindow));
209 } 224 }
210 return self; 225 return self;
211 } 226 }
212 227
213 - (NSArray*)customWindowsForFullScreenTransition { 228 - (NSArray*)customWindowsForFullScreenTransition {
214 [self takeSnapshot]; 229 [self takeSnapshot];
215 [self makeAndPrepareSnapshotWindow]; 230 [self makeAndPrepareSnapshotWindow];
216 return @[ primaryWindow_.get(), snapshotWindow_.get() ]; 231 return @[ primaryWindow_.get(), snapshotWindow_.get() ];
217 } 232 }
218 233
234 - (BOOL)isTransitionCompleted {
235 return completedTransition_;
236 }
237
219 - (void)startCustomFullScreenAnimationWithDuration:(NSTimeInterval)duration { 238 - (void)startCustomFullScreenAnimationWithDuration:(NSTimeInterval)duration {
220 CGFloat animationDuration = duration * kAnimationDurationFraction; 239 CGFloat durationFraction = base::mac::IsOSYosemite()
240 ? kAnimationDurationFractionYosemite
241 : kAnimationDurationFraction;
242 CGFloat animationDuration = duration * durationFraction;
221 [self preparePrimaryWindowForAnimation]; 243 [self preparePrimaryWindowForAnimation];
222 [self animatePrimaryWindowWithDuration:animationDuration]; 244 [self animatePrimaryWindowWithDuration:animationDuration];
223 [self animateSnapshotWindowWithDuration:animationDuration]; 245 [self animateSnapshotWindowWithDuration:animationDuration];
224 } 246 }
225 247
226 - (BOOL)shouldWindowBeUnconstrained { 248 - (BOOL)shouldWindowBeUnconstrained {
227 return changingPrimaryWindowSize_; 249 return changingPrimaryWindowSize_;
228 } 250 }
229 251
230 - (NSSize)desiredWindowLayoutSize { 252 - (NSSize)desiredWindowLayoutSize {
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
494 DCHECK_EQ(NSHeight(content.frame), expectedSize.height); 516 DCHECK_EQ(NSHeight(content.frame), expectedSize.height);
495 DCHECK_EQ(NSWidth(content.frame), expectedSize.width); 517 DCHECK_EQ(NSWidth(content.frame), expectedSize.width);
496 518
497 // Restore the state of the primary window and make it visible again. 519 // Restore the state of the primary window and make it visible again.
498 [primaryWindow_ setOpaque:primaryWindowInitialOpaque_]; 520 [primaryWindow_ setOpaque:primaryWindowInitialOpaque_];
499 [primaryWindow_ setBackgroundColor:primaryWindowInitialBackgroundColor_]; 521 [primaryWindow_ setBackgroundColor:primaryWindowInitialBackgroundColor_];
500 522
501 CALayer* root = [self rootLayerOfWindow:primaryWindow_]; 523 CALayer* root = [self rootLayerOfWindow:primaryWindow_];
502 [root removeAnimationForKey:kPrimaryWindowAnimationID]; 524 [root removeAnimationForKey:kPrimaryWindowAnimationID];
503 root.opacity = 1; 525 root.opacity = 1;
526
527 if (!isEnteringFullscreen_)
528 [controller_ exitFullscreenAnimationFinished];
504 } 529 }
530
531 completedTransition_ = YES;
505 } 532 }
506 533
507 - (CALayer*)rootLayerOfWindow:(NSWindow*)window { 534 - (CALayer*)rootLayerOfWindow:(NSWindow*)window {
508 return [[[window contentView] superview] layer]; 535 return [[[window contentView] superview] layer];
509 } 536 }
510 537
511 - (NSPoint)pointRelativeToCurrentScreen:(NSPoint)point { 538 - (NSPoint)pointRelativeToCurrentScreen:(NSPoint)point {
512 NSRect screenFrame = [[primaryWindow_ screen] frame]; 539 NSRect screenFrame = [[primaryWindow_ screen] frame];
513 return NSMakePoint(point.x - screenFrame.origin.x, 540 return NSMakePoint(point.x - screenFrame.origin.x,
514 point.y - screenFrame.origin.y); 541 point.y - screenFrame.origin.y);
515 } 542 }
516 543
517 @end 544 @end
OLDNEW
« no previous file with comments | « chrome/browser/ui/cocoa/browser_window_fullscreen_transition.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698