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

Unified Diff: ui/views/controls/native/native_view_host_mac.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 side-by-side diff with in-line comments
Download patch
Index: ui/views/controls/native/native_view_host_mac.mm
diff --git a/ui/views/controls/native/native_view_host_mac.mm b/ui/views/controls/native/native_view_host_mac.mm
index 45a315736a4513b9db41411a30ff1b3edf746ece..c5eabc390a591972b69c5bbcfed8acfc7289d980 100644
--- a/ui/views/controls/native/native_view_host_mac.mm
+++ b/ui/views/controls/native/native_view_host_mac.mm
@@ -12,6 +12,54 @@
#include "ui/views/widget/native_widget_mac.h"
#include "ui/views/widget/widget.h"
+// An NSView that allows the rendering size of its child subview to be different
+// than its own frame size, which will result in showing a scaled version of the
+// child.
+@interface NativeViewHostMacScalingView : NSView {
+}
+
+- (id)init;
+- (void)attach:(NSView*)subview;
+- (BOOL)hasAttachedSubview:(NSView*)subview;
+- (void)showWithFrame:(NSRect)frame andSize:(NSSize)size;
+@end
+
+@implementation NativeViewHostMacScalingView
+
+- (id)init {
+ if (self = [super initWithFrame:NSZeroRect]) {
+ // NativeViewHostMac::ShowWidget() provides manual layout.
+ [self setAutoresizingMask:NSViewNotSizable];
+ }
+ return self;
+}
+
+- (void)attach:(NSView*)subview {
+ if ([[self subviews] count] == 0) {
+ [self addSubview:subview];
+ } else if ([[self subviews] objectAtIndex:0] != subview) {
+ [self replaceSubview:[[self subviews] objectAtIndex:0] with:subview];
+ }
+}
+
+- (BOOL)hasAttachedSubview:(NSView*)subview {
+ if ([[self subviews] count] > 0 &&
+ [[self subviews] objectAtIndex:0] == subview) {
+ return YES;
+ }
+ return NO;
+}
+
+- (void)showWithFrame:(NSRect)frame andSize:(NSSize)size {
+ [self setFrame:frame];
+ const NSRect bounds = NSMakeRect(0, 0, size.width, size.height);
+ [self setBounds:bounds];
+ DCHECK([[self subviews] count] > 0);
+ [[[self subviews] objectAtIndex:0] setFrame:bounds];
+}
+
+@end // @implementation NativeViewHostMacScalingView
+
namespace views {
namespace {
@@ -41,16 +89,18 @@ void EnsureNativeViewHasNoChildWidgets(NSView* native_view) {
// NativeViewHostMac, NativeViewHostWrapper implementation:
void NativeViewHostMac::AttachNativeView() {
- DCHECK(host_->native_view());
- DCHECK(!native_view_);
- native_view_.reset([host_->native_view() retain]);
+ NSView* const native_view = host_->native_view();
+ DCHECK(native_view);
+ DCHECK(!scaling_view_);
+ scaling_view_.reset([[NativeViewHostMacScalingView alloc] init]);
+ [scaling_view_ attach:native_view];
- EnsureNativeViewHasNoChildWidgets(native_view_);
+ EnsureNativeViewHasNoChildWidgets(native_view);
BridgedNativeWidget* bridge = NativeWidgetMac::GetBridgeForNativeWindow(
host_->GetWidget()->GetNativeWindow());
DCHECK(bridge);
- [bridge->ns_view() addSubview:native_view_];
- bridge->SetAssociationForView(host_, native_view_);
+ [bridge->ns_view() addSubview:scaling_view_];
+ bridge->SetAssociationForView(host_, scaling_view_);
}
void NativeViewHostMac::NativeViewDetaching(bool destroyed) {
@@ -60,16 +110,21 @@ void EnsureNativeViewHasNoChildWidgets(NSView* native_view) {
// reference is retained until the NativeViewHost is detached.
DCHECK(!destroyed);
- // |native_view_| can be nil here if RemovedFromWidget() is called before
+ // |scaling_view_| can be nil here if RemovedFromWidget() is called before
// NativeViewHost::Detach().
- if (!native_view_) {
+ if (!scaling_view_) {
DCHECK(![host_->native_view() superview]);
return;
}
- DCHECK(native_view_ == host_->native_view());
+ DCHECK([scaling_view_ hasAttachedSubview:host_->native_view()]);
[host_->native_view() setHidden:YES];
+ // Retain the native view for the remainder of this scope, since removing it
+ // from its superview could cause it to be released.
+ const base::scoped_nsobject<NSView> retained_native_view(
+ [host_->native_view() retain]);
[host_->native_view() removeFromSuperview];
+ [scaling_view_ removeFromSuperview];
EnsureNativeViewHasNoChildWidgets(host_->native_view());
BridgedNativeWidget* bridge = NativeWidgetMac::GetBridgeForNativeWindow(
@@ -78,7 +133,7 @@ void EnsureNativeViewHasNoChildWidgets(NSView* native_view) {
if (bridge)
bridge->ClearAssociationForView(host_);
- native_view_.reset();
+ scaling_view_.reset();
}
void NativeViewHostMac::AddedToWidget() {
@@ -108,7 +163,14 @@ void EnsureNativeViewHasNoChildWidgets(NSView* native_view) {
NOTIMPLEMENTED();
}
-void NativeViewHostMac::ShowWidget(int x, int y, int w, int h) {
+void NativeViewHostMac::ShowWidget(int x,
+ int y,
+ int w,
+ int h,
+ int render_w,
+ int render_h) {
+ DCHECK(scaling_view_); // AttachNativeView() should have been called.
+
if (host_->fast_resize())
NOTIMPLEMENTED();
@@ -124,8 +186,9 @@ void EnsureNativeViewHasNoChildWidgets(NSView* native_view) {
// Convert window coordinates to the hosted view's superview, since that's how
// coordinates of the hosted view's frame is based.
NSRect container_rect =
- [[host_->native_view() superview] convertRect:window_rect fromView:nil];
- [host_->native_view() setFrame:container_rect];
+ [[scaling_view_ superview] convertRect:window_rect fromView:nil];
+ [scaling_view_ showWithFrame:container_rect
+ andSize:NSMakeSize(render_w, render_h)];
[host_->native_view() setHidden:NO];
}
« no previous file with comments | « ui/views/controls/native/native_view_host_mac.h ('k') | ui/views/controls/native/native_view_host_mac_unittest.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698