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

Side by Side Diff: chrome/browser/ui/cocoa/extensions/extension_popup_controller.mm

Issue 653843002: Mac: Attach Extension NSViews to the view hierarchy before creating renderers (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix test Created 5 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/extensions/extension_popup_controller.h" 5 #import "chrome/browser/ui/cocoa/extensions/extension_popup_controller.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/callback.h" 9 #include "base/callback.h"
10 #include "chrome/browser/chrome_notification_types.h" 10 #include "chrome/browser/chrome_notification_types.h"
(...skipping 28 matching lines...) Expand all
39 39
40 // Given a value and a rage, clamp the value into the range. 40 // Given a value and a rage, clamp the value into the range.
41 CGFloat Clamp(CGFloat value, CGFloat min, CGFloat max) { 41 CGFloat Clamp(CGFloat value, CGFloat min, CGFloat max) {
42 return std::max(min, std::min(max, value)); 42 return std::max(min, std::min(max, value));
43 } 43 }
44 44
45 } // namespace 45 } // namespace
46 46
47 @interface ExtensionPopupController (Private) 47 @interface ExtensionPopupController (Private)
48 // Callers should be using the public static method for initialization. 48 // Callers should be using the public static method for initialization.
49 // NOTE: This takes ownership of |host|. 49 - (id)initWithParentWindow:(NSWindow*)parentWindow
50 - (id)initWithHost:(extensions::ExtensionViewHost*)host 50 anchoredAt:(NSPoint)anchoredAt
51 parentWindow:(NSWindow*)parentWindow 51 arrowLocation:(info_bubble::BubbleArrowLocation)arrowLocation
52 anchoredAt:(NSPoint)anchoredAt 52 devMode:(BOOL)devMode;
53 arrowLocation:(info_bubble::BubbleArrowLocation)arrowLocation 53
54 devMode:(BOOL)devMode; 54 // Set the ExtensionViewHost, taking ownership.
55 - (void)setExtensionViewHost:(scoped_ptr<extensions::ExtensionViewHost>)host;
55 56
56 // Called when the extension's hosted NSView has been resized. 57 // Called when the extension's hosted NSView has been resized.
57 - (void)extensionViewFrameChanged; 58 - (void)extensionViewFrameChanged;
58 59
59 // Called when the extension's size changes. 60 // Called when the extension's size changes.
60 - (void)onSizeChanged:(NSSize)newSize; 61 - (void)onSizeChanged:(NSSize)newSize;
61 62
62 // Called when the extension view is shown. 63 // Called when the extension view is shown.
63 - (void)onViewDidShow; 64 - (void)onViewDidShow;
64 65
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 // know what it is for notifications, but our ExtensionViewHost may not be 144 // know what it is for notifications, but our ExtensionViewHost may not be
144 // valid. 145 // valid.
145 WebContents* web_contents_; 146 WebContents* web_contents_;
146 base::Callback<void(content::DevToolsAgentHost*, bool)> devtools_callback_; 147 base::Callback<void(content::DevToolsAgentHost*, bool)> devtools_callback_;
147 }; 148 };
148 149
149 @implementation ExtensionPopupController 150 @implementation ExtensionPopupController
150 151
151 @synthesize extensionId = extensionId_; 152 @synthesize extensionId = extensionId_;
152 153
153 - (id)initWithHost:(extensions::ExtensionViewHost*)host 154 - (id)initWithParentWindow:(NSWindow*)parentWindow
154 parentWindow:(NSWindow*)parentWindow 155 anchoredAt:(NSPoint)anchoredAt
155 anchoredAt:(NSPoint)anchoredAt 156 arrowLocation:(info_bubble::BubbleArrowLocation)arrowLocation
156 arrowLocation:(info_bubble::BubbleArrowLocation)arrowLocation 157 devMode:(BOOL)devMode {
157 devMode:(BOOL)devMode {
158 base::scoped_nsobject<InfoBubbleWindow> window([[InfoBubbleWindow alloc] 158 base::scoped_nsobject<InfoBubbleWindow> window([[InfoBubbleWindow alloc]
159 initWithContentRect:ui::kWindowSizeDeterminedLater 159 initWithContentRect:ui::kWindowSizeDeterminedLater
160 styleMask:NSBorderlessWindowMask 160 styleMask:NSBorderlessWindowMask
161 backing:NSBackingStoreBuffered 161 backing:NSBackingStoreBuffered
162 defer:YES]); 162 defer:YES]);
163 if (!window.get()) 163 if (!window.get())
164 return nil; 164 return nil;
165 165
166 anchoredAt = [parentWindow convertBaseToScreen:anchoredAt]; 166 anchoredAt = [parentWindow convertBaseToScreen:anchoredAt];
167 if ((self = [super initWithWindow:window 167 if ((self = [super initWithWindow:window
168 parentWindow:parentWindow 168 parentWindow:parentWindow
169 anchoredAt:anchoredAt])) { 169 anchoredAt:anchoredAt])) {
170 host_.reset(host);
171 extensionId_ = host_->extension_id();
172 beingInspected_ = devMode; 170 beingInspected_ = devMode;
173 ignoreWindowDidResignKey_ = NO; 171 ignoreWindowDidResignKey_ = NO;
174 172 [[self bubble] setArrowLocation:arrowLocation];
175 InfoBubbleView* view = self.bubble;
176 [view setArrowLocation:arrowLocation];
177
178 extensionView_ = host->view()->GetNativeView();
179 container_.reset(new ExtensionPopupContainer(self));
180 static_cast<ExtensionViewMac*>(host->view())
181 ->set_container(container_.get());
182
183 NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
184 [center addObserver:self
185 selector:@selector(extensionViewFrameChanged)
186 name:NSViewFrameDidChangeNotification
187 object:extensionView_];
188
189 [view addSubview:extensionView_];
tapted 2015/02/18 06:00:11 note this line is now moved to ExtensionViewMac::C
190
191 notificationBridge_.reset(new DevtoolsNotificationBridge(self));
192 registrar_.reset(new content::NotificationRegistrar);
193 if (beingInspected_) {
194 // Listen for the extension to finish loading so the dev tools can be
195 // opened.
196 registrar_->Add(notificationBridge_.get(),
197 extensions::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING,
198 content::Source<BrowserContext>(host->browser_context()));
199 }
200 } 173 }
201 return self; 174 return self;
202 } 175 }
203 176
177 - (void)setExtensionViewHost:(scoped_ptr<extensions::ExtensionViewHost>)host {
Robert Sesek 2015/02/18 14:56:20 This method should be down around line 320.
tapted 2015/02/18 22:35:28 Done.
178 DCHECK(!host_);
179 DCHECK(host);
180 host_.swap(host);
181
182 extensionId_ = host_->extension_id();
183 container_.reset(new ExtensionPopupContainer(self));
184 ExtensionViewMac* hostView = static_cast<ExtensionViewMac*>(host_->view());
185 hostView->set_container(container_.get());
186 hostView->CreateWidgetHostViewIn([self bubble]);
tapted 2015/02/18 06:00:11 note this line is new
187
188 extensionView_ = hostView->GetNativeView();
189
190 NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
191 [center addObserver:self
192 selector:@selector(extensionViewFrameChanged)
193 name:NSViewFrameDidChangeNotification
194 object:extensionView_];
195
196 notificationBridge_.reset(new DevtoolsNotificationBridge(self));
197 registrar_.reset(new content::NotificationRegistrar);
198 if (beingInspected_) {
199 // Listen for the extension to finish loading so the dev tools can be
200 // opened.
201 registrar_->Add(notificationBridge_.get(),
202 extensions::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING,
203 content::Source<BrowserContext>(host_->browser_context()));
204 }
205 }
206
204 - (void)dealloc { 207 - (void)dealloc {
205 [[NSNotificationCenter defaultCenter] removeObserver:self]; 208 [[NSNotificationCenter defaultCenter] removeObserver:self];
206 [super dealloc]; 209 [super dealloc];
207 } 210 }
208 211
209 - (void)showDevTools { 212 - (void)showDevTools {
210 DevToolsWindow::OpenDevToolsWindow(host_->host_contents()); 213 DevToolsWindow::OpenDevToolsWindow(host_->host_contents());
211 } 214 }
212 215
213 - (void)close { 216 - (void)close {
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
283 286
284 // If we click the browser/page action again, we should close the popup. 287 // If we click the browser/page action again, we should close the popup.
285 // Make Mac behavior the same with Windows and others. 288 // Make Mac behavior the same with Windows and others.
286 if (gPopup) { 289 if (gPopup) {
287 std::string extension_id = url.host(); 290 std::string extension_id = url.host();
288 extensions::ExtensionViewHost* host = [gPopup extensionViewHost]; 291 extensions::ExtensionViewHost* host = [gPopup extensionViewHost];
289 if (extension_id == host->extension_id()) { 292 if (extension_id == host->extension_id()) {
290 [gPopup close]; 293 [gPopup close];
291 return nil; 294 return nil;
292 } 295 }
296
297 [gPopup close];
Robert Sesek 2015/02/18 14:56:20 Move this above line 292 and then delete 293.
tapted 2015/02/18 22:35:28 Done.
293 } 298 }
294 299
295 extensions::ExtensionViewHost* host = 300 // Create the popup first. This establishes an initially hidden NSWindow so
296 extensions::ExtensionViewHostFactory::CreatePopupHost(url, browser); 301 // that the renderer is able to gather correct screen metrics for the initial
302 // paint.
303 gPopup = [[ExtensionPopupController alloc]
304 initWithParentWindow:browser->window()->GetNativeWindow()
305 anchoredAt:anchoredAt
306 arrowLocation:arrowLocation
307 devMode:devMode];
308
309 scoped_ptr<extensions::ExtensionViewHost> host(
310 extensions::ExtensionViewHostFactory::CreatePopupHost(url, browser));
297 DCHECK(host); 311 DCHECK(host);
298 if (!host) 312 [gPopup setExtensionViewHost:host.Pass()];
299 return nil;
300
301 [gPopup close];
302
303 // Takes ownership of |host|. Also will autorelease itself when the popup is
304 // closed, so no need to do that here.
305 gPopup = [[ExtensionPopupController alloc]
306 initWithHost:host
307 parentWindow:browser->window()->GetNativeWindow()
308 anchoredAt:anchoredAt
309 arrowLocation:arrowLocation
310 devMode:devMode];
311 return gPopup; 313 return gPopup;
312 } 314 }
313 315
314 + (ExtensionPopupController*)popup { 316 + (ExtensionPopupController*)popup {
315 return gPopup; 317 return gPopup;
316 } 318 }
317 319
318 - (void)extensionViewFrameChanged { 320 - (void)extensionViewFrameChanged {
319 // If there are no changes in the width or height of the frame, then ignore. 321 // If there are no changes in the width or height of the frame, then ignore.
320 if (NSEqualSizes([extensionView_ frame].size, extensionFrame_.size)) 322 if (NSEqualSizes([extensionView_ frame].size, extensionFrame_.size))
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
375 // the notification is fired (and consequently the view contents have loaded). 377 // the notification is fired (and consequently the view contents have loaded).
376 if (![window isVisible]) { 378 if (![window isVisible]) {
377 [self showWindow:self]; 379 [self showWindow:self];
378 } 380 }
379 } 381 }
380 382
381 - (void)onSizeChanged:(NSSize)newSize { 383 - (void)onSizeChanged:(NSSize)newSize {
382 // When we update the size, the window will become visible. Stay hidden until 384 // When we update the size, the window will become visible. Stay hidden until
383 // the host is loaded. 385 // the host is loaded.
384 pendingSize_ = newSize; 386 pendingSize_ = newSize;
385 if (!host_->did_stop_loading()) 387 if (!host_ || !host_->did_stop_loading())
386 return; 388 return;
387 389
388 // No need to use CA here, our caller calls us repeatedly to animate the 390 // No need to use CA here, our caller calls us repeatedly to animate the
389 // resizing. 391 // resizing.
390 NSRect frame = [extensionView_ frame]; 392 NSRect frame = [extensionView_ frame];
391 frame.size = newSize; 393 frame.size = newSize;
392 394
393 // |new_size| is in pixels. Convert to view units. 395 // |new_size| is in pixels. Convert to view units.
394 frame.size = [extensionView_ convertSize:frame.size fromView:nil]; 396 frame.size = [extensionView_ convertSize:frame.size fromView:nil];
395 397
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 return minSize; 435 return minSize;
434 } 436 }
435 437
436 // Private (TestingAPI) 438 // Private (TestingAPI)
437 + (NSSize)maxPopupSize { 439 + (NSSize)maxPopupSize {
438 NSSize maxSize = {ExtensionViewMac::kMaxWidth, ExtensionViewMac::kMaxHeight}; 440 NSSize maxSize = {ExtensionViewMac::kMaxWidth, ExtensionViewMac::kMaxHeight};
439 return maxSize; 441 return maxSize;
440 } 442 }
441 443
442 @end 444 @end
OLDNEW
« no previous file with comments | « chrome/browser/extensions/extension_view_host.cc ('k') | chrome/browser/ui/cocoa/extensions/extension_view_mac.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698