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

Side by Side Diff: chrome/browser/ui/cocoa/tab_contents/tab_contents_controller.mm

Issue 2138213003: Mac: Do layout before adding the WebContents to the view hierarchy when switching tabs (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: ensureContentsVisibleInSuperview Created 4 years, 5 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 (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/tab_contents/tab_contents_controller.h" 5 #import "chrome/browser/ui/cocoa/tab_contents/tab_contents_controller.h"
6 6
7 #include <stdint.h> 7 #include <stdint.h>
8 8
9 #include <utility> 9 #include <utility>
10 10
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 } 64 }
65 65
66 private: 66 private:
67 TabContentsController* const controller_; 67 TabContentsController* const controller_;
68 68
69 DISALLOW_COPY_AND_ASSIGN(FullscreenObserver); 69 DISALLOW_COPY_AND_ASSIGN(FullscreenObserver);
70 }; 70 };
71 71
72 @interface TabContentsController (TabContentsContainerViewDelegate) 72 @interface TabContentsController (TabContentsContainerViewDelegate)
73 - (BOOL)contentsInFullscreenCaptureMode; 73 - (BOOL)contentsInFullscreenCaptureMode;
74 // Computes and returns the frame to use for the contents view within the 74 // Computes and returns the frame to use for the contents view using the size of
75 // container view. 75 // |container| as the target size.
76 - (NSRect)frameForContentsView; 76 - (NSRect)frameForContentsViewIn:(NSView*)container;
77 77
78 // Returns YES if the content view should be resized. 78 // Returns YES if the content view should be resized.
79 - (BOOL)shouldResizeContentView; 79 - (BOOL)shouldResizeContentView;
80 80
81 // Returns YES if the content view is inside a popup. 81 // Returns YES if the content view is inside a popup.
82 - (BOOL)isPopup; 82 - (BOOL)isPopup;
83 83
84 @end 84 @end
85 85
86 // An NSView with special-case handling for when the contents view does not 86 // An NSView with special-case handling for when the contents view does not
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 - (void)resizeSubviewsWithOldSize:(NSSize)oldBoundsSize { 123 - (void)resizeSubviewsWithOldSize:(NSSize)oldBoundsSize {
124 NSView* const contentsView = 124 NSView* const contentsView =
125 [[self subviews] count] > 0 ? [[self subviews] objectAtIndex:0] : nil; 125 [[self subviews] count] > 0 ? [[self subviews] objectAtIndex:0] : nil;
126 if (!contentsView || [contentsView autoresizingMask] == NSViewNotSizable || 126 if (!contentsView || [contentsView autoresizingMask] == NSViewNotSizable ||
127 !delegate_ || 127 !delegate_ ||
128 (![delegate_ shouldResizeContentView] && [delegate_ isPopup])) { 128 (![delegate_ shouldResizeContentView] && [delegate_ isPopup])) {
129 return; 129 return;
130 } 130 }
131 131
132 ScopedCAActionDisabler disabler; 132 ScopedCAActionDisabler disabler;
133 [contentsView setFrame:[delegate_ frameForContentsView]]; 133 [contentsView setFrame:[delegate_ frameForContentsViewIn:self]];
134 } 134 }
135 135
136 // Update the background layer's color whenever the view needs to repaint. 136 // Update the background layer's color whenever the view needs to repaint.
137 - (void)setNeedsDisplayInRect:(NSRect)rect { 137 - (void)setNeedsDisplayInRect:(NSRect)rect {
138 [super setNeedsDisplayInRect:rect]; 138 [super setNeedsDisplayInRect:rect];
139 [self updateBackgroundColor]; 139 [self updateBackgroundColor];
140 } 140 }
141 141
142 - (void)updateBackgroundColor { 142 - (void)updateBackgroundColor {
143 // This view is sometimes flashed into visibility (e.g, when closing 143 // This view is sometimes flashed into visibility (e.g, when closing
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 [super dealloc]; 210 [super dealloc];
211 } 211 }
212 212
213 - (void)loadView { 213 - (void)loadView {
214 base::scoped_nsobject<NSView> view( 214 base::scoped_nsobject<NSView> view(
215 [[TabContentsContainerView alloc] initWithDelegate:self]); 215 [[TabContentsContainerView alloc] initWithDelegate:self]);
216 [view setAutoresizingMask:NSViewHeightSizable|NSViewWidthSizable]; 216 [view setAutoresizingMask:NSViewHeightSizable|NSViewWidthSizable];
217 [self setView:view]; 217 [self setView:view];
218 } 218 }
219 219
220 - (void)ensureContentsSizeDoesNotChange { 220 - (void)ensureContentsVisibleInSuperview:(NSView*)superview {
221 NSView* contentsContainer = [self view];
222 NSArray* subviews = [contentsContainer subviews];
223 if ([subviews count] > 0) {
224 NSView* currentSubview = [subviews objectAtIndex:0];
225 [currentSubview setAutoresizingMask:NSViewNotSizable];
226 }
227 }
228
229 - (void)ensureContentsVisible {
230 if (!contents_) 221 if (!contents_)
231 return; 222 return;
223
232 ScopedCAActionDisabler disabler; 224 ScopedCAActionDisabler disabler;
233 NSView* contentsContainer = [self view]; 225 NSView* contentsContainer = [self view];
234 NSArray* subviews = [contentsContainer subviews]; 226 NSArray* subviews = [contentsContainer subviews];
235 NSView* contentsNativeView; 227 NSView* contentsNativeView;
236 content::RenderWidgetHostView* const fullscreenView = 228 content::RenderWidgetHostView* const fullscreenView =
237 isEmbeddingFullscreenWidget_ ? 229 isEmbeddingFullscreenWidget_ ?
238 contents_->GetFullscreenRenderWidgetHostView() : NULL; 230 contents_->GetFullscreenRenderWidgetHostView() : NULL;
239 if (fullscreenView) { 231 if (fullscreenView) {
240 contentsNativeView = fullscreenView->GetNativeView(); 232 contentsNativeView = fullscreenView->GetNativeView();
241 } else { 233 } else {
242 isEmbeddingFullscreenWidget_ = NO; 234 isEmbeddingFullscreenWidget_ = NO;
243 contentsNativeView = contents_->GetNativeView(); 235 contentsNativeView = contents_->GetNativeView();
244 } 236 }
245 237
246 if ([self shouldResizeContentView]) 238 if ([self shouldResizeContentView])
247 [contentsNativeView setFrame:[self frameForContentsView]]; 239 [contentsNativeView setFrame:[self frameForContentsViewIn:superview]];
248 240
249 if ([subviews count] == 0) { 241 if ([subviews count] == 0) {
250 [contentsContainer addSubview:contentsNativeView]; 242 [contentsContainer addSubview:contentsNativeView];
251 } else if ([subviews objectAtIndex:0] != contentsNativeView) { 243 } else if ([subviews objectAtIndex:0] != contentsNativeView) {
252 [contentsContainer replaceSubview:[subviews objectAtIndex:0] 244 [contentsContainer replaceSubview:[subviews objectAtIndex:0]
253 with:contentsNativeView]; 245 with:contentsNativeView];
254 } 246 }
247
248 [contentsNativeView setAutoresizingMask:NSViewNotSizable];
249 [contentsContainer setFrame:[superview bounds]];
250 [superview addSubview:contentsContainer];
255 [contentsNativeView setAutoresizingMask:NSViewWidthSizable| 251 [contentsNativeView setAutoresizingMask:NSViewWidthSizable|
256 NSViewHeightSizable]; 252 NSViewHeightSizable];
257 253
258 [contentsContainer setNeedsDisplay:YES]; 254 [contentsContainer setNeedsDisplay:YES];
259 255
260 // Push the background color down to the RenderWidgetHostView, so that if 256 // Push the background color down to the RenderWidgetHostView, so that if
261 // there is a flash between contents appearing, it will be the theme's color, 257 // there is a flash between contents appearing, it will be the theme's color,
262 // not white. 258 // not white.
263 SkColor skBackgroundColor = SK_ColorWHITE; 259 SkColor skBackgroundColor = SK_ColorWHITE;
264 const ThemeProvider* theme = [[[self view] window] themeProvider]; 260 const ThemeProvider* theme = [[[self view] window] themeProvider];
265 if (theme) 261 if (theme)
266 skBackgroundColor = theme->GetColor(ThemeProperties::COLOR_NTP_BACKGROUND); 262 skBackgroundColor = theme->GetColor(ThemeProperties::COLOR_NTP_BACKGROUND);
267 content::RenderWidgetHostView* rwhv = contents_->GetRenderWidgetHostView(); 263 content::RenderWidgetHostView* rwhv = contents_->GetRenderWidgetHostView();
268 if (rwhv) 264 if (rwhv)
269 rwhv->SetBackgroundColor(skBackgroundColor); 265 rwhv->SetBackgroundColor(skBackgroundColor);
270 } 266 }
271 267
272 - (void)updateFullscreenWidgetFrame { 268 - (void)updateFullscreenWidgetFrame {
273 // This should only apply if a fullscreen widget is embedded. 269 // This should only apply if a fullscreen widget is embedded.
274 if (!isEmbeddingFullscreenWidget_ || blockFullscreenResize_) 270 if (!isEmbeddingFullscreenWidget_ || blockFullscreenResize_)
275 return; 271 return;
276 272
277 content::RenderWidgetHostView* const fullscreenView = 273 content::RenderWidgetHostView* const fullscreenView =
278 contents_->GetFullscreenRenderWidgetHostView(); 274 contents_->GetFullscreenRenderWidgetHostView();
279 if (fullscreenView) 275 if (fullscreenView) {
280 [fullscreenView->GetNativeView() setFrame:[self frameForContentsView]]; 276 [fullscreenView->GetNativeView()
277 setFrame:[self frameForContentsViewIn:[self view]]];
278 }
281 } 279 }
282 280
283 - (void)changeWebContents:(WebContents*)newContents { 281 - (void)changeWebContents:(WebContents*)newContents {
284 contents_ = newContents; 282 contents_ = newContents;
285 fullscreenObserver_->Observe(contents_); 283 fullscreenObserver_->Observe(contents_);
286 isEmbeddingFullscreenWidget_ = 284 isEmbeddingFullscreenWidget_ =
287 contents_ && contents_->GetFullscreenRenderWidgetHostView(); 285 contents_ && contents_->GetFullscreenRenderWidgetHostView();
288 } 286 }
289 287
290 // Returns YES if the tab represented by this controller is the front-most. 288 // Returns YES if the tab represented by this controller is the front-most.
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
322 // focus (for example, if the omnibox has focus instead). The WebContents 320 // focus (for example, if the omnibox has focus instead). The WebContents
323 // logic will restore focus to the appropriate view. 321 // logic will restore focus to the appropriate view.
324 } 322 }
325 323
326 - (void)tabDidChange:(WebContents*)updatedContents { 324 - (void)tabDidChange:(WebContents*)updatedContents {
327 // Calling setContentView: here removes any first responder status 325 // Calling setContentView: here removes any first responder status
328 // the view may have, so avoid changing the view hierarchy unless 326 // the view may have, so avoid changing the view hierarchy unless
329 // the view is different. 327 // the view is different.
330 if ([self webContents] != updatedContents) { 328 if ([self webContents] != updatedContents) {
331 [self changeWebContents:updatedContents]; 329 [self changeWebContents:updatedContents];
332 [self ensureContentsVisible]; 330 [self ensureContentsVisibleInSuperview:[[self view] superview]];
333 } 331 }
334 } 332 }
335 333
336 - (void)toggleFullscreenWidget:(BOOL)enterFullscreen { 334 - (void)toggleFullscreenWidget:(BOOL)enterFullscreen {
337 isEmbeddingFullscreenWidget_ = enterFullscreen && 335 isEmbeddingFullscreenWidget_ = enterFullscreen &&
338 contents_ && contents_->GetFullscreenRenderWidgetHostView(); 336 contents_ && contents_->GetFullscreenRenderWidgetHostView();
339 [self ensureContentsVisible]; 337 [self ensureContentsVisibleInSuperview:[[self view] superview]];
340 } 338 }
341 339
342 - (BOOL)contentsInFullscreenCaptureMode { 340 - (BOOL)contentsInFullscreenCaptureMode {
343 // Note: Grab a known-valid WebContents pointer from |fullscreenObserver_|. 341 // Note: Grab a known-valid WebContents pointer from |fullscreenObserver_|.
344 content::WebContents* const wc = fullscreenObserver_->web_contents(); 342 content::WebContents* const wc = fullscreenObserver_->web_contents();
345 if (!wc || 343 if (!wc ||
346 wc->GetCapturerCount() == 0 || 344 wc->GetCapturerCount() == 0 ||
347 wc->GetPreferredSize().IsEmpty() || 345 wc->GetPreferredSize().IsEmpty() ||
348 !(isEmbeddingFullscreenWidget_ || 346 !(isEmbeddingFullscreenWidget_ ||
349 (wc->GetDelegate() && 347 (wc->GetDelegate() &&
350 wc->GetDelegate()->IsFullscreenForTabOrPending(wc)))) { 348 wc->GetDelegate()->IsFullscreenForTabOrPending(wc)))) {
351 return NO; 349 return NO;
352 } 350 }
353 return YES; 351 return YES;
354 } 352 }
355 353
356 - (NSRect)frameForContentsView { 354 - (NSRect)frameForContentsViewIn:(NSView*)container {
357 const NSSize containerSize = [[self view] frame].size; 355 gfx::Rect rect([container bounds]);
358 gfx::Rect rect;
359 rect.set_width(containerSize.width);
360 rect.set_height(containerSize.height);
361 356
362 // In most cases, the contents view is simply sized to fill the container 357 // In most cases, the contents view is simply sized to fill the container
363 // view's bounds. Only WebContentses that are in fullscreen mode and being 358 // view's bounds. Only WebContentses that are in fullscreen mode and being
364 // screen-captured will engage the special layout/sizing behavior. 359 // screen-captured will engage the special layout/sizing behavior.
365 if (![self contentsInFullscreenCaptureMode]) 360 if (![self contentsInFullscreenCaptureMode])
366 return NSRectFromCGRect(rect.ToCGRect()); 361 return NSRectFromCGRect(rect.ToCGRect());
367 362
368 // Size the contents view to the capture video resolution and center it. If 363 // Size the contents view to the capture video resolution and center it. If
369 // the container view is not large enough to fit it at the preferred size, 364 // the container view is not large enough to fit it at the preferred size,
370 // scale down to fit (preserving aspect ratio). 365 // scale down to fit (preserving aspect ratio).
(...skipping 24 matching lines...) Expand all
395 390
396 - (BOOL)shouldResizeContentView { 391 - (BOOL)shouldResizeContentView {
397 return !isEmbeddingFullscreenWidget_ || !blockFullscreenResize_; 392 return !isEmbeddingFullscreenWidget_ || !blockFullscreenResize_;
398 } 393 }
399 394
400 - (BOOL)isPopup { 395 - (BOOL)isPopup {
401 return isPopup_; 396 return isPopup_;
402 } 397 }
403 398
404 @end 399 @end
OLDNEW
« no previous file with comments | « chrome/browser/ui/cocoa/tab_contents/tab_contents_controller.h ('k') | chrome/browser/ui/cocoa/tabs/tab_strip_controller.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698