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

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

Issue 2654413002: Stretching NativeViewHost, and misc tab capture fixes.
Patch Set: Gettin' it all working on ui/cocoa and MacViews too. Created 3 years, 10 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
11 #include "base/mac/scoped_cftyperef.h" 11 #include "base/mac/scoped_cftyperef.h"
12 #include "base/mac/scoped_nsobject.h" 12 #include "base/mac/scoped_nsobject.h"
13 #include "base/macros.h" 13 #include "base/macros.h"
14 #include "chrome/browser/devtools/devtools_window.h" 14 #include "chrome/browser/devtools/devtools_window.h"
15 #import "chrome/browser/themes/theme_properties.h" 15 #import "chrome/browser/themes/theme_properties.h"
16 #import "chrome/browser/themes/theme_service.h" 16 #import "chrome/browser/themes/theme_service.h"
17 #import "chrome/browser/ui/cocoa/themed_window.h" 17 #import "chrome/browser/ui/cocoa/themed_window.h"
18 #include "chrome/browser/ui/view_ids.h" 18 #include "chrome/browser/ui/view_ids.h"
19 #include "content/public/browser/render_view_host.h" 19 #include "content/public/browser/render_view_host.h"
20 #include "content/public/browser/render_widget_host.h" 20 #include "content/public/browser/render_widget_host.h"
21 #include "content/public/browser/render_widget_host_view.h" 21 #include "content/public/browser/render_widget_host_view.h"
22 #include "content/public/browser/web_contents.h" 22 #include "content/public/browser/web_contents.h"
23 #include "content/public/browser/web_contents_observer.h" 23 #include "content/public/browser/web_contents_observer.h"
24 #include "skia/ext/skia_utils_mac.h" 24 #include "skia/ext/skia_utils_mac.h"
25 #include "ui/base/cocoa/animation_utils.h" 25 #include "ui/base/cocoa/animation_utils.h"
26 #include "ui/gfx/geometry/rect.h" 26 #include "ui/gfx/geometry/rect_conversions.h"
27 #include "ui/gfx/geometry/rect_f.h"
28 #include "ui/gfx/geometry/size.h"
29 #include "ui/gfx/geometry/size_f.h"
27 30
28 using content::WebContents; 31 using content::WebContents;
29 using content::WebContentsObserver; 32 using content::WebContentsObserver;
30 33
31 // FullscreenObserver is used by TabContentsController to monitor for the 34 // FullscreenObserver is used by TabContentsController to monitor for the
32 // showing/destruction of fullscreen render widgets. When notified, 35 // showing/destruction of fullscreen render widgets. When notified,
33 // TabContentsController will alter its child view hierarchy to either embed a 36 // TabContentsController will alter its child view hierarchy to either embed a
34 // fullscreen render widget view or restore the normal WebContentsView render 37 // fullscreen render widget view or restore the normal WebContentsView render
35 // view. The embedded fullscreen render widget will fill the user's screen in 38 // view. The embedded fullscreen render widget will fill the user's screen in
36 // the case where TabContentsController's NSView is a subview of a browser 39 // the case where TabContentsController's NSView is a subview of a browser
(...skipping 26 matching lines...) Expand all
63 } 66 }
64 67
65 private: 68 private:
66 TabContentsController* const controller_; 69 TabContentsController* const controller_;
67 70
68 DISALLOW_COPY_AND_ASSIGN(FullscreenObserver); 71 DISALLOW_COPY_AND_ASSIGN(FullscreenObserver);
69 }; 72 };
70 73
71 @interface TabContentsController (TabContentsContainerViewDelegate) 74 @interface TabContentsController (TabContentsContainerViewDelegate)
72 - (BOOL)contentsInFullscreenCaptureMode; 75 - (BOOL)contentsInFullscreenCaptureMode;
73 // Computes and returns the frame to use for the contents view using the size of 76
74 // |container| as the target size. 77 // Computes and returns the frame to use for the scaling view within the
75 - (NSRect)frameForContentsViewIn:(NSView*)container; 78 // TabContentsContainerView.
79 - (NSRect)frameForScalingViewIn:(NSView*)container;
80
81 // Computes and returns the bounds to use for the scaling view within the
82 // TabContentsContainerView. In the normal case, the bounds size will be
83 // equivalent to frame size. In 'AutoEmbedFullscreen mode', the bounds size is
84 // set to the video capture resolution, which is almost always different from
85 // the frame size. See 'AutoEmbedFullscreen mode' in header file comments.
86 - (NSRect)boundsForScalingViewIn:(NSView*)container;
76 87
77 // Returns YES if the content view should be resized. 88 // Returns YES if the content view should be resized.
78 - (BOOL)shouldResizeContentView; 89 - (BOOL)shouldResizeContentView;
79 90
80 // Returns YES if the content view is inside a popup. 91 // Returns YES if the content view is inside a popup.
81 - (BOOL)isPopup; 92 - (BOOL)isPopup;
82 93
83 @end 94 @end
84 95
85 // An NSView with special-case handling for when the contents view does not 96 // An NSView with special-case handling for when the contents view does not
86 // expand to fill the entire tab contents area. See 'AutoEmbedFullscreen mode' 97 // expand to fill the entire tab contents area. See 'AutoEmbedFullscreen mode'
87 // in header file comments. 98 // in header file comments.
99 //
100 // This view creates and manages its own subview, a "scaling" view, which acts
101 // as a container for the contents view. It allows the rendering size of the
102 // contents view to be something different than its normal on-screen display
103 // size.
88 @interface TabContentsContainerView : NSView { 104 @interface TabContentsContainerView : NSView {
89 @private 105 @private
90 TabContentsController* delegate_; // weak 106 TabContentsController* delegate_; // weak
91 } 107 }
92 108
109 - (void)ensureContentsVisible:(NSView*)contentsView;
93 - (void)updateBackgroundColor; 110 - (void)updateBackgroundColor;
94 @end 111 @end
95 112
96 @implementation TabContentsContainerView 113 @implementation TabContentsContainerView
97 114
98 - (id)initWithDelegate:(TabContentsController*)delegate { 115 - (id)initWithDelegate:(TabContentsController*)delegate {
99 if ((self = [super initWithFrame:NSZeroRect])) { 116 if ((self = [super initWithFrame:NSZeroRect])) {
100 delegate_ = delegate; 117 delegate_ = delegate;
118
101 ScopedCAActionDisabler disabler; 119 ScopedCAActionDisabler disabler;
102 base::scoped_nsobject<CALayer> layer([[CALayer alloc] init]); 120 base::scoped_nsobject<CALayer> layer([[CALayer alloc] init]);
103 [self setLayer:layer]; 121 [self setLayer:layer];
104 [self setWantsLayer:YES]; 122 [self setWantsLayer:YES];
105 [self updateBackgroundColor]; 123 [self updateBackgroundColor];
124
125 // Create and add the scaling view.
126 [self addSubview:[[NSView alloc] initWithFrame:NSZeroRect]];
106 } 127 }
107 return self; 128 return self;
108 } 129 }
109 130
110 // Called by the delegate during dealloc to invalidate the pointer held by this 131 // Called by the delegate during dealloc to invalidate the pointer held by this
111 // view. 132 // view.
112 - (void)delegateDestroyed { 133 - (void)delegateDestroyed {
113 delegate_ = nil; 134 delegate_ = nil;
114 } 135 }
115 136
116 // Override auto-resizing logic to query the delegate for the exact frame to 137 // Returns the scaling view, which is the child of TabContentsContainerView.
117 // use for the contents view. 138 - (NSView*)scalingView {
118 // TODO(spqchan): The popup check is a temporary solution to fix the regression 139 return [[self subviews] objectAtIndex:0];
119 // issue described in crbug.com/604288. This method doesn't really affect 140 }
120 // fullscreen if the content is inside a normal browser window, but would 141
121 // cause a flash fullscreen widget to blow up if it's inside a popup. 142 // Return the contents view, which is the child of the scaling view; or nil if
143 // there isn't one attached.
144 - (NSView*)contentsView {
145 NSArray* const scalingViewSubviews = [[self scalingView] subviews];
146 if ([scalingViewSubviews count] == 0)
147 return nil; // No contents view attached.
148 return [scalingViewSubviews objectAtIndex:0];
149 }
150
151 // Override auto-resizing logic to query the delegate for the exact frame and
152 // bounds to use for the contents view, and then perform manual layout of the
153 // scaling view (child view) and contents view (grandchild view).
122 - (void)resizeSubviewsWithOldSize:(NSSize)oldBoundsSize { 154 - (void)resizeSubviewsWithOldSize:(NSSize)oldBoundsSize {
123 NSView* const contentsView = 155 ScopedCAActionDisabler disabler;
124 [[self subviews] count] > 0 ? [[self subviews] objectAtIndex:0] : nil; 156
125 if (!contentsView || [contentsView autoresizingMask] == NSViewNotSizable || 157 NSView* const contentsView = [self contentsView];
126 !delegate_ || 158 if (!contentsView)
159 return; // No contents view attached yet.
160
161 // TODO(spqchan): The popup check is a temporary solution to fix the
162 // regression described in crbug.com/604288. This method doesn't really affect
163 // fullscreen if the content is inside a normal browser window, but would
164 // cause a flash fullscreen widget to blow up if it's inside a popup.
165 if (!delegate_ ||
127 (![delegate_ shouldResizeContentView] && [delegate_ isPopup])) { 166 (![delegate_ shouldResizeContentView] && [delegate_ isPopup])) {
128 return; 167 return;
129 } 168 }
130 169
131 ScopedCAActionDisabler disabler; 170 // Set the position and size of the scaling view within this container view.
132 [contentsView setFrame:[delegate_ frameForContentsViewIn:self]]; 171 NSView* const scalingView = [self scalingView];
172 [scalingView setFrame:[delegate_ frameForScalingViewIn:self]];
173 const NSRect scalingViewBounds = [delegate_ boundsForScalingViewIn:self];
174 [scalingView setBounds:scalingViewBounds];
175
176 // Update the position and size of the contents view, if it has changed.
177 if (!NSEqualRects(scalingViewBounds, [contentsView frame]))
178 [contentsView setFrame:scalingViewBounds];
133 } 179 }
134 180
135 // Update the background layer's color whenever the view needs to repaint. 181 // Update the background layer's color whenever the view needs to repaint.
136 - (void)setNeedsDisplayInRect:(NSRect)rect { 182 - (void)setNeedsDisplayInRect:(NSRect)rect {
137 [super setNeedsDisplayInRect:rect]; 183 [super setNeedsDisplayInRect:rect];
138 [self updateBackgroundColor]; 184 [self updateBackgroundColor];
139 } 185 }
140 186
187 - (void)ensureContentsVisible:(NSView*)contentsView {
188 DCHECK(contentsView);
189
190 // TabContentsContainerView performs manual layout.
191 [contentsView setAutoresizingMask:NSViewNotSizable];
192
193 NSView* const scalingView = [self scalingView];
194 if ([[scalingView subviews] count] == 0) {
195 [scalingView addSubview:contentsView];
196 } else if ([[scalingView subviews] objectAtIndex:0] != contentsView) {
197 [scalingView replaceSubview:[[scalingView subviews] objectAtIndex:0]
198 with:contentsView];
199 }
200
201 [self resizeSubviewsWithOldSize:[self bounds].size];
202 }
203
141 - (void)updateBackgroundColor { 204 - (void)updateBackgroundColor {
142 // This view is sometimes flashed into visibility (e.g, when closing 205 // This view is sometimes flashed into visibility (e.g, when closing
143 // windows or opening new tabs), so ensure that the flash be the theme 206 // windows or opening new tabs), so ensure that the flash be the theme
144 // background color in those cases. 207 // background color in those cases.
145 SkColor skBackgroundColor = SK_ColorWHITE; 208 SkColor skBackgroundColor = SK_ColorWHITE;
146 const ThemeProvider* theme = [[self window] themeProvider]; 209 const ThemeProvider* theme = [[self window] themeProvider];
147 if (theme) 210 if (theme)
148 skBackgroundColor = theme->GetColor(ThemeProperties::COLOR_NTP_BACKGROUND); 211 skBackgroundColor = theme->GetColor(ThemeProperties::COLOR_NTP_BACKGROUND);
149 212
150 // If the page is in fullscreen tab capture mode, change the background color 213 // If the page is in fullscreen tab capture mode, change the background color
(...skipping 11 matching lines...) Expand all
162 base::ScopedCFTypeRef<CGColorRef> cgBackgroundColor( 225 base::ScopedCFTypeRef<CGColorRef> cgBackgroundColor(
163 skia::CGColorCreateFromSkColor(skBackgroundColor)); 226 skia::CGColorCreateFromSkColor(skBackgroundColor));
164 [[self layer] setBackgroundColor:cgBackgroundColor]; 227 [[self layer] setBackgroundColor:cgBackgroundColor];
165 } 228 }
166 229
167 - (ViewID)viewID { 230 - (ViewID)viewID {
168 return VIEW_ID_TAB_CONTAINER; 231 return VIEW_ID_TAB_CONTAINER;
169 } 232 }
170 233
171 - (BOOL)acceptsFirstResponder { 234 - (BOOL)acceptsFirstResponder {
172 return [[self subviews] count] > 0 && 235 NSView* const contentsView = [self contentsView];
173 [[[self subviews] objectAtIndex:0] acceptsFirstResponder]; 236 return contentsView && [contentsView acceptsFirstResponder];
174 } 237 }
175 238
176 // When receiving a click-to-focus in the solid color area surrounding the 239 // When receiving a click-to-focus in the solid color area surrounding the
177 // WebContents' native view, immediately transfer focus to WebContents' native 240 // WebContents' native view, immediately transfer focus to WebContents' native
178 // view. 241 // view.
179 - (BOOL)becomeFirstResponder { 242 - (BOOL)becomeFirstResponder {
180 if (![self acceptsFirstResponder]) 243 if (![self acceptsFirstResponder])
181 return NO; 244 return NO;
182 return [[self window] makeFirstResponder:[[self subviews] objectAtIndex:0]]; 245 return [[self window] makeFirstResponder:[self contentsView]];
183 } 246 }
184 247
185 - (BOOL)canBecomeKeyView { 248 - (BOOL)canBecomeKeyView {
186 return NO; // Tab/Shift-Tab should focus the subview, not this view. 249 return NO; // Tab/Shift-Tab should focus the subview, not this view.
187 } 250 }
188 251
189 @end // @implementation TabContentsContainerView 252 @end // @implementation TabContentsContainerView
190 253
191 @implementation TabContentsController 254 @implementation TabContentsController
192 @synthesize webContents = contents_; 255 @synthesize webContents = contents_;
(...skipping 21 matching lines...) Expand all
214 [[TabContentsContainerView alloc] initWithDelegate:self]); 277 [[TabContentsContainerView alloc] initWithDelegate:self]);
215 [view setAutoresizingMask:NSViewHeightSizable|NSViewWidthSizable]; 278 [view setAutoresizingMask:NSViewHeightSizable|NSViewWidthSizable];
216 [self setView:view]; 279 [self setView:view];
217 } 280 }
218 281
219 - (void)ensureContentsVisibleInSuperview:(NSView*)superview { 282 - (void)ensureContentsVisibleInSuperview:(NSView*)superview {
220 if (!contents_) 283 if (!contents_)
221 return; 284 return;
222 285
223 ScopedCAActionDisabler disabler; 286 ScopedCAActionDisabler disabler;
224 NSView* contentsContainer = [self view]; 287
225 NSArray* subviews = [contentsContainer subviews];
226 NSView* contentsNativeView; 288 NSView* contentsNativeView;
227 content::RenderWidgetHostView* const fullscreenView = 289 content::RenderWidgetHostView* const fullscreenView =
228 isEmbeddingFullscreenWidget_ ? 290 isEmbeddingFullscreenWidget_ ?
229 contents_->GetFullscreenRenderWidgetHostView() : NULL; 291 contents_->GetFullscreenRenderWidgetHostView() : NULL;
230 if (fullscreenView) { 292 if (fullscreenView) {
231 contentsNativeView = fullscreenView->GetNativeView(); 293 contentsNativeView = fullscreenView->GetNativeView();
232 } else { 294 } else {
233 isEmbeddingFullscreenWidget_ = NO; 295 isEmbeddingFullscreenWidget_ = NO;
234 contentsNativeView = contents_->GetNativeView(); 296 contentsNativeView = contents_->GetNativeView();
235 } 297 }
236 298
237 if ([self shouldResizeContentView]) 299 TabContentsContainerView* const contentsContainer =
238 [contentsNativeView setFrame:[self frameForContentsViewIn:superview]]; 300 static_cast<TabContentsContainerView*>([self view]);
239 301 [contentsContainer ensureContentsVisible:contentsNativeView];
240 if ([subviews count] == 0) {
241 [contentsContainer addSubview:contentsNativeView];
242 } else if ([subviews objectAtIndex:0] != contentsNativeView) {
243 [contentsContainer replaceSubview:[subviews objectAtIndex:0]
244 with:contentsNativeView];
245 }
246
247 [contentsNativeView setAutoresizingMask:NSViewNotSizable];
248 [contentsContainer setFrame:[superview bounds]]; 302 [contentsContainer setFrame:[superview bounds]];
249 [superview addSubview:contentsContainer]; 303 [superview addSubview:contentsContainer];
250 [contentsNativeView setAutoresizingMask:NSViewWidthSizable|
251 NSViewHeightSizable];
252
253 [contentsContainer setNeedsDisplay:YES]; 304 [contentsContainer setNeedsDisplay:YES];
254 305
255 // Push the background color down to the RenderWidgetHostView, so that if 306 // Push the background color down to the RenderWidgetHostView, so that if
256 // there is a flash between contents appearing, it will be the theme's color, 307 // there is a flash between contents appearing, it will be the theme's color,
257 // not white. 308 // not white.
258 SkColor skBackgroundColor = SK_ColorWHITE; 309 SkColor skBackgroundColor = SK_ColorWHITE;
259 const ThemeProvider* theme = [[[self view] window] themeProvider]; 310 const ThemeProvider* theme = [[[self view] window] themeProvider];
260 if (theme) 311 if (theme)
261 skBackgroundColor = theme->GetColor(ThemeProperties::COLOR_NTP_BACKGROUND); 312 skBackgroundColor = theme->GetColor(ThemeProperties::COLOR_NTP_BACKGROUND);
262 content::RenderWidgetHostView* rwhv = contents_->GetRenderWidgetHostView(); 313 content::RenderWidgetHostView* rwhv = contents_->GetRenderWidgetHostView();
263 if (rwhv) 314 if (rwhv)
264 rwhv->SetBackgroundColor(skBackgroundColor); 315 rwhv->SetBackgroundColor(skBackgroundColor);
265 } 316 }
266 317
267 - (void)updateFullscreenWidgetFrame { 318 - (void)updateFullscreenWidgetFrame {
268 // This should only apply if a fullscreen widget is embedded. 319 // This should only apply if a fullscreen widget is embedded.
269 if (!isEmbeddingFullscreenWidget_ || blockFullscreenResize_) 320 if (!isEmbeddingFullscreenWidget_ || blockFullscreenResize_)
270 return; 321 return;
271 322
272 content::RenderWidgetHostView* const fullscreenView = 323 content::RenderWidgetHostView* const fullscreenView =
273 contents_->GetFullscreenRenderWidgetHostView(); 324 contents_->GetFullscreenRenderWidgetHostView();
274 if (fullscreenView) { 325 if (fullscreenView) {
275 [fullscreenView->GetNativeView() 326 [static_cast<TabContentsContainerView*>([self view])
276 setFrame:[self frameForContentsViewIn:[self view]]]; 327 ensureContentsVisible:fullscreenView->GetNativeView()];
277 } 328 }
278 } 329 }
279 330
280 - (void)changeWebContents:(WebContents*)newContents { 331 - (void)changeWebContents:(WebContents*)newContents {
281 contents_ = newContents; 332 contents_ = newContents;
282 fullscreenObserver_->Observe(contents_); 333 fullscreenObserver_->Observe(contents_);
283 isEmbeddingFullscreenWidget_ = 334 isEmbeddingFullscreenWidget_ =
284 contents_ && contents_->GetFullscreenRenderWidgetHostView(); 335 contents_ && contents_->GetFullscreenRenderWidgetHostView();
285 } 336 }
286 337
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 wc->GetCapturerCount() == 0 || 394 wc->GetCapturerCount() == 0 ||
344 wc->GetPreferredSize().IsEmpty() || 395 wc->GetPreferredSize().IsEmpty() ||
345 !(isEmbeddingFullscreenWidget_ || 396 !(isEmbeddingFullscreenWidget_ ||
346 (wc->GetDelegate() && 397 (wc->GetDelegate() &&
347 wc->GetDelegate()->IsFullscreenForTabOrPending(wc)))) { 398 wc->GetDelegate()->IsFullscreenForTabOrPending(wc)))) {
348 return NO; 399 return NO;
349 } 400 }
350 return YES; 401 return YES;
351 } 402 }
352 403
353 - (NSRect)frameForContentsViewIn:(NSView*)container { 404 - (NSRect)frameForScalingViewIn:(NSView*)container {
354 gfx::Rect rect([container bounds]); 405 NSRect bounds = [container bounds];
406 bounds.origin = NSZeroPoint;
355 407
356 // In most cases, the contents view is simply sized to fill the container 408 // In most cases, the contents view is simply sized to fill the container
357 // view's bounds. Only WebContentses that are in fullscreen mode and being 409 // view's bounds. Only WebContentses that are in fullscreen mode and being
358 // screen-captured will engage the special layout/sizing behavior. 410 // screen-captured will engage the special layout/sizing behavior.
359 if (![self contentsInFullscreenCaptureMode]) 411 if (![self contentsInFullscreenCaptureMode])
360 return NSRectFromCGRect(rect.ToCGRect()); 412 return bounds;
361 413
362 // Size the contents view to the capture video resolution and center it. If 414 // For 'AutoEmbedFullscreen mode', scale the view to fit within the container,
363 // the container view is not large enough to fit it at the preferred size, 415 // and center it.
364 // scale down to fit (preserving aspect ratio). 416 gfx::RectF rect(bounds);
365 content::WebContents* const wc = fullscreenObserver_->web_contents(); 417 gfx::Size captureSize =
366 const gfx::Size captureSize = wc->GetPreferredSize(); 418 fullscreenObserver_->web_contents()->GetPreferredSize();
367 if (captureSize.width() <= rect.width() && 419 DCHECK(!captureSize.IsEmpty());
368 captureSize.height() <= rect.height()) { 420 const float x = captureSize.width() * rect.height();
369 // No scaling, just centering. 421 const float y = captureSize.height() * rect.width();
370 rect.ClampToCenteredSize(captureSize); 422 if (y < x) {
423 rect.ClampToCenteredSize(gfx::SizeF(rect.width(), y / captureSize.width()));
371 } else { 424 } else {
372 // Scale down, preserving aspect ratio, and center. 425 rect.ClampToCenteredSize(
373 // TODO(miu): This is basically media::ComputeLetterboxRegion(), and it 426 gfx::SizeF(x / captureSize.height(), rect.height()));
374 // looks like others have written this code elsewhere. Let's consolidate
375 // into a shared function ui/gfx/geometry or around there.
376 const int64_t x = static_cast<int64_t>(captureSize.width()) * rect.height();
377 const int64_t y = static_cast<int64_t>(captureSize.height()) * rect.width();
378 if (y < x) {
379 rect.ClampToCenteredSize(gfx::Size(
380 rect.width(), static_cast<int>(y / captureSize.width())));
381 } else {
382 rect.ClampToCenteredSize(gfx::Size(
383 static_cast<int>(x / captureSize.height()), rect.height()));
384 }
385 } 427 }
428 // Ensure the bounds align with pixel boundaries.
429 return gfx::ToEnclosedRect(rect).ToCGRect();
430 }
386 431
387 return NSRectFromCGRect(rect.ToCGRect()); 432 - (NSRect)boundsForScalingViewIn:(NSView*)container {
433 NSRect bounds;
434 bounds.origin = NSZeroPoint;
435
436 // When in 'AutoEmbedFullscreen mode' mode, the bounds size is set to the
437 // video capture resolution. See header file for more details.
438 if ([self contentsInFullscreenCaptureMode]) {
439 content::WebContents* const wc = fullscreenObserver_->web_contents();
440 gfx::Size captureSize = wc->GetPreferredSize();
441 DCHECK(!captureSize.IsEmpty());
442 bounds.size = captureSize.ToCGSize();
443 } else {
444 bounds.size = [container bounds].size;
445 }
446 return bounds;
388 } 447 }
389 448
390 - (BOOL)shouldResizeContentView { 449 - (BOOL)shouldResizeContentView {
391 return !isEmbeddingFullscreenWidget_ || !blockFullscreenResize_; 450 return !isEmbeddingFullscreenWidget_ || !blockFullscreenResize_;
392 } 451 }
393 452
394 - (BOOL)isPopup { 453 - (BOOL)isPopup {
395 return isPopup_; 454 return isPopup_;
396 } 455 }
397 456
398 @end 457 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698