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

Side by Side 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 unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 #include "ui/views/controls/native/native_view_host_mac.h" 5 #include "ui/views/controls/native/native_view_host_mac.h"
6 6
7 #import <Cocoa/Cocoa.h> 7 #import <Cocoa/Cocoa.h>
8 8
9 #include "base/mac/foundation_util.h" 9 #include "base/mac/foundation_util.h"
10 #import "ui/views/cocoa/bridged_native_widget.h" 10 #import "ui/views/cocoa/bridged_native_widget.h"
11 #include "ui/views/controls/native/native_view_host.h" 11 #include "ui/views/controls/native/native_view_host.h"
12 #include "ui/views/widget/native_widget_mac.h" 12 #include "ui/views/widget/native_widget_mac.h"
13 #include "ui/views/widget/widget.h" 13 #include "ui/views/widget/widget.h"
14 14
15 // An NSView that allows the rendering size of its child subview to be different
16 // than its own frame size, which will result in showing a scaled version of the
17 // child.
18 @interface NativeViewHostMacScalingView : NSView {
19 }
20
21 - (id)init;
22 - (void)attach:(NSView*)subview;
23 - (BOOL)hasAttachedSubview:(NSView*)subview;
24 - (void)showWithFrame:(NSRect)frame andSize:(NSSize)size;
25 @end
26
27 @implementation NativeViewHostMacScalingView
28
29 - (id)init {
30 if (self = [super initWithFrame:NSZeroRect]) {
31 // NativeViewHostMac::ShowWidget() provides manual layout.
32 [self setAutoresizingMask:NSViewNotSizable];
33 }
34 return self;
35 }
36
37 - (void)attach:(NSView*)subview {
38 if ([[self subviews] count] == 0) {
39 [self addSubview:subview];
40 } else if ([[self subviews] objectAtIndex:0] != subview) {
41 [self replaceSubview:[[self subviews] objectAtIndex:0] with:subview];
42 }
43 }
44
45 - (BOOL)hasAttachedSubview:(NSView*)subview {
46 if ([[self subviews] count] > 0 &&
47 [[self subviews] objectAtIndex:0] == subview) {
48 return YES;
49 }
50 return NO;
51 }
52
53 - (void)showWithFrame:(NSRect)frame andSize:(NSSize)size {
54 [self setFrame:frame];
55 const NSRect bounds = NSMakeRect(0, 0, size.width, size.height);
56 [self setBounds:bounds];
57 DCHECK([[self subviews] count] > 0);
58 [[[self subviews] objectAtIndex:0] setFrame:bounds];
59 }
60
61 @end // @implementation NativeViewHostMacScalingView
62
15 namespace views { 63 namespace views {
16 namespace { 64 namespace {
17 65
18 void EnsureNativeViewHasNoChildWidgets(NSView* native_view) { 66 void EnsureNativeViewHasNoChildWidgets(NSView* native_view) {
19 DCHECK(native_view); 67 DCHECK(native_view);
20 // Mac's NativeViewHost has no support for hosting its own child widgets. 68 // Mac's NativeViewHost has no support for hosting its own child widgets.
21 // This check is probably overly restrictive, since the Widget containing the 69 // This check is probably overly restrictive, since the Widget containing the
22 // NativeViewHost _is_ allowed child Widgets. However, we don't know yet 70 // NativeViewHost _is_ allowed child Widgets. However, we don't know yet
23 // whether those child Widgets need to be distinguished from Widgets that code 71 // whether those child Widgets need to be distinguished from Widgets that code
24 // might want to associate with the hosted NSView instead. 72 // might want to associate with the hosted NSView instead.
25 { 73 {
26 Widget::Widgets child_widgets; 74 Widget::Widgets child_widgets;
27 Widget::GetAllChildWidgets(native_view, &child_widgets); 75 Widget::GetAllChildWidgets(native_view, &child_widgets);
28 CHECK_GE(1u, child_widgets.size()); // 1 (itself) or 0 if detached. 76 CHECK_GE(1u, child_widgets.size()); // 1 (itself) or 0 if detached.
29 } 77 }
30 } 78 }
31 79
32 } // namespace 80 } // namespace
33 81
34 NativeViewHostMac::NativeViewHostMac(NativeViewHost* host) : host_(host) { 82 NativeViewHostMac::NativeViewHostMac(NativeViewHost* host) : host_(host) {
35 } 83 }
36 84
37 NativeViewHostMac::~NativeViewHostMac() { 85 NativeViewHostMac::~NativeViewHostMac() {
38 } 86 }
39 87
40 //////////////////////////////////////////////////////////////////////////////// 88 ////////////////////////////////////////////////////////////////////////////////
41 // NativeViewHostMac, NativeViewHostWrapper implementation: 89 // NativeViewHostMac, NativeViewHostWrapper implementation:
42 90
43 void NativeViewHostMac::AttachNativeView() { 91 void NativeViewHostMac::AttachNativeView() {
44 DCHECK(host_->native_view()); 92 NSView* const native_view = host_->native_view();
45 DCHECK(!native_view_); 93 DCHECK(native_view);
46 native_view_.reset([host_->native_view() retain]); 94 DCHECK(!scaling_view_);
95 scaling_view_.reset([[NativeViewHostMacScalingView alloc] init]);
96 [scaling_view_ attach:native_view];
47 97
48 EnsureNativeViewHasNoChildWidgets(native_view_); 98 EnsureNativeViewHasNoChildWidgets(native_view);
49 BridgedNativeWidget* bridge = NativeWidgetMac::GetBridgeForNativeWindow( 99 BridgedNativeWidget* bridge = NativeWidgetMac::GetBridgeForNativeWindow(
50 host_->GetWidget()->GetNativeWindow()); 100 host_->GetWidget()->GetNativeWindow());
51 DCHECK(bridge); 101 DCHECK(bridge);
52 [bridge->ns_view() addSubview:native_view_]; 102 [bridge->ns_view() addSubview:scaling_view_];
53 bridge->SetAssociationForView(host_, native_view_); 103 bridge->SetAssociationForView(host_, scaling_view_);
54 } 104 }
55 105
56 void NativeViewHostMac::NativeViewDetaching(bool destroyed) { 106 void NativeViewHostMac::NativeViewDetaching(bool destroyed) {
57 // |destroyed| is only true if this class calls host_->NativeViewDestroyed(). 107 // |destroyed| is only true if this class calls host_->NativeViewDestroyed().
58 // Aura does this after observing an aura OnWindowDestroying, but NSViews 108 // Aura does this after observing an aura OnWindowDestroying, but NSViews
59 // are reference counted so there isn't a reliable signal. Instead, a 109 // are reference counted so there isn't a reliable signal. Instead, a
60 // reference is retained until the NativeViewHost is detached. 110 // reference is retained until the NativeViewHost is detached.
61 DCHECK(!destroyed); 111 DCHECK(!destroyed);
62 112
63 // |native_view_| can be nil here if RemovedFromWidget() is called before 113 // |scaling_view_| can be nil here if RemovedFromWidget() is called before
64 // NativeViewHost::Detach(). 114 // NativeViewHost::Detach().
65 if (!native_view_) { 115 if (!scaling_view_) {
66 DCHECK(![host_->native_view() superview]); 116 DCHECK(![host_->native_view() superview]);
67 return; 117 return;
68 } 118 }
69 119
70 DCHECK(native_view_ == host_->native_view()); 120 DCHECK([scaling_view_ hasAttachedSubview:host_->native_view()]);
71 [host_->native_view() setHidden:YES]; 121 [host_->native_view() setHidden:YES];
122 // Retain the native view for the remainder of this scope, since removing it
123 // from its superview could cause it to be released.
124 const base::scoped_nsobject<NSView> retained_native_view(
125 [host_->native_view() retain]);
72 [host_->native_view() removeFromSuperview]; 126 [host_->native_view() removeFromSuperview];
127 [scaling_view_ removeFromSuperview];
73 128
74 EnsureNativeViewHasNoChildWidgets(host_->native_view()); 129 EnsureNativeViewHasNoChildWidgets(host_->native_view());
75 BridgedNativeWidget* bridge = NativeWidgetMac::GetBridgeForNativeWindow( 130 BridgedNativeWidget* bridge = NativeWidgetMac::GetBridgeForNativeWindow(
76 host_->GetWidget()->GetNativeWindow()); 131 host_->GetWidget()->GetNativeWindow());
77 // BridgedNativeWidget can be null when Widget is closing. 132 // BridgedNativeWidget can be null when Widget is closing.
78 if (bridge) 133 if (bridge)
79 bridge->ClearAssociationForView(host_); 134 bridge->ClearAssociationForView(host_);
80 135
81 native_view_.reset(); 136 scaling_view_.reset();
82 } 137 }
83 138
84 void NativeViewHostMac::AddedToWidget() { 139 void NativeViewHostMac::AddedToWidget() {
85 if (!host_->native_view()) 140 if (!host_->native_view())
86 return; 141 return;
87 142
88 AttachNativeView(); 143 AttachNativeView();
89 host_->Layout(); 144 host_->Layout();
90 } 145 }
91 146
92 void NativeViewHostMac::RemovedFromWidget() { 147 void NativeViewHostMac::RemovedFromWidget() {
93 if (!host_->native_view()) 148 if (!host_->native_view())
94 return; 149 return;
95 150
96 NativeViewDetaching(false); 151 NativeViewDetaching(false);
97 } 152 }
98 153
99 void NativeViewHostMac::InstallClip(int x, int y, int w, int h) { 154 void NativeViewHostMac::InstallClip(int x, int y, int w, int h) {
100 NOTIMPLEMENTED(); 155 NOTIMPLEMENTED();
101 } 156 }
102 157
103 bool NativeViewHostMac::HasInstalledClip() { 158 bool NativeViewHostMac::HasInstalledClip() {
104 return false; 159 return false;
105 } 160 }
106 161
107 void NativeViewHostMac::UninstallClip() { 162 void NativeViewHostMac::UninstallClip() {
108 NOTIMPLEMENTED(); 163 NOTIMPLEMENTED();
109 } 164 }
110 165
111 void NativeViewHostMac::ShowWidget(int x, int y, int w, int h) { 166 void NativeViewHostMac::ShowWidget(int x,
167 int y,
168 int w,
169 int h,
170 int render_w,
171 int render_h) {
172 DCHECK(scaling_view_); // AttachNativeView() should have been called.
173
112 if (host_->fast_resize()) 174 if (host_->fast_resize())
113 NOTIMPLEMENTED(); 175 NOTIMPLEMENTED();
114 176
115 // Coordinates will be from the top left of the parent Widget. The NativeView 177 // Coordinates will be from the top left of the parent Widget. The NativeView
116 // is already in the same NSWindow, so just flip to get Cooca coordinates and 178 // is already in the same NSWindow, so just flip to get Cooca coordinates and
117 // then convert to the containing view. 179 // then convert to the containing view.
118 NSRect window_rect = NSMakeRect( 180 NSRect window_rect = NSMakeRect(
119 x, 181 x,
120 host_->GetWidget()->GetClientAreaBoundsInScreen().height() - y - h, 182 host_->GetWidget()->GetClientAreaBoundsInScreen().height() - y - h,
121 w, 183 w,
122 h); 184 h);
123 185
124 // Convert window coordinates to the hosted view's superview, since that's how 186 // Convert window coordinates to the hosted view's superview, since that's how
125 // coordinates of the hosted view's frame is based. 187 // coordinates of the hosted view's frame is based.
126 NSRect container_rect = 188 NSRect container_rect =
127 [[host_->native_view() superview] convertRect:window_rect fromView:nil]; 189 [[scaling_view_ superview] convertRect:window_rect fromView:nil];
128 [host_->native_view() setFrame:container_rect]; 190 [scaling_view_ showWithFrame:container_rect
191 andSize:NSMakeSize(render_w, render_h)];
129 [host_->native_view() setHidden:NO]; 192 [host_->native_view() setHidden:NO];
130 } 193 }
131 194
132 void NativeViewHostMac::HideWidget() { 195 void NativeViewHostMac::HideWidget() {
133 [host_->native_view() setHidden:YES]; 196 [host_->native_view() setHidden:YES];
134 } 197 }
135 198
136 void NativeViewHostMac::SetFocus() { 199 void NativeViewHostMac::SetFocus() {
137 if ([host_->native_view() acceptsFirstResponder]) 200 if ([host_->native_view() acceptsFirstResponder])
138 [[host_->native_view() window] makeFirstResponder:host_->native_view()]; 201 [[host_->native_view() window] makeFirstResponder:host_->native_view()];
(...skipping 17 matching lines...) Expand all
156 return gfx::kNullCursor; 219 return gfx::kNullCursor;
157 } 220 }
158 221
159 // static 222 // static
160 NativeViewHostWrapper* NativeViewHostWrapper::CreateWrapper( 223 NativeViewHostWrapper* NativeViewHostWrapper::CreateWrapper(
161 NativeViewHost* host) { 224 NativeViewHost* host) {
162 return new NativeViewHostMac(host); 225 return new NativeViewHostMac(host);
163 } 226 }
164 227
165 } // namespace views 228 } // namespace views
OLDNEW
« 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