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

Unified 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: Remove DCHECK 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 side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/cocoa/extensions/extension_popup_controller.mm
diff --git a/chrome/browser/ui/cocoa/extensions/extension_popup_controller.mm b/chrome/browser/ui/cocoa/extensions/extension_popup_controller.mm
index 8cc1a36b04ebc9b93e82ab1ba5e860b46f50a9b5..640b98cbc7d0ef9e776a90e10de9846f6ea1ad63 100644
--- a/chrome/browser/ui/cocoa/extensions/extension_popup_controller.mm
+++ b/chrome/browser/ui/cocoa/extensions/extension_popup_controller.mm
@@ -46,12 +46,13 @@ CGFloat Clamp(CGFloat value, CGFloat min, CGFloat max) {
@interface ExtensionPopupController (Private)
// Callers should be using the public static method for initialization.
-// NOTE: This takes ownership of |host|.
-- (id)initWithHost:(extensions::ExtensionViewHost*)host
- parentWindow:(NSWindow*)parentWindow
- anchoredAt:(NSPoint)anchoredAt
- arrowLocation:(info_bubble::BubbleArrowLocation)arrowLocation
- devMode:(BOOL)devMode;
+- (id)initWithParentWindow:(NSWindow*)parentWindow
+ anchoredAt:(NSPoint)anchoredAt
+ arrowLocation:(info_bubble::BubbleArrowLocation)arrowLocation
+ devMode:(BOOL)devMode;
+
+// Set the ExtensionViewHost, taking ownership.
+- (void)setExtensionViewHost:(scoped_ptr<extensions::ExtensionViewHost>)host;
// Called when the extension's hosted NSView has been resized.
- (void)extensionViewFrameChanged;
@@ -150,11 +151,10 @@ class DevtoolsNotificationBridge : public content::NotificationObserver {
@synthesize extensionId = extensionId_;
-- (id)initWithHost:(extensions::ExtensionViewHost*)host
- parentWindow:(NSWindow*)parentWindow
- anchoredAt:(NSPoint)anchoredAt
- arrowLocation:(info_bubble::BubbleArrowLocation)arrowLocation
- devMode:(BOOL)devMode {
+- (id)initWithParentWindow:(NSWindow*)parentWindow
+ anchoredAt:(NSPoint)anchoredAt
+ arrowLocation:(info_bubble::BubbleArrowLocation)arrowLocation
+ devMode:(BOOL)devMode {
base::scoped_nsobject<InfoBubbleWindow> window([[InfoBubbleWindow alloc]
initWithContentRect:ui::kWindowSizeDeterminedLater
styleMask:NSBorderlessWindowMask
@@ -167,36 +167,9 @@ class DevtoolsNotificationBridge : public content::NotificationObserver {
if ((self = [super initWithWindow:window
parentWindow:parentWindow
anchoredAt:anchoredAt])) {
- host_.reset(host);
- extensionId_ = host_->extension_id();
beingInspected_ = devMode;
ignoreWindowDidResignKey_ = NO;
-
- InfoBubbleView* view = self.bubble;
- [view setArrowLocation:arrowLocation];
-
- extensionView_ = host->view()->GetNativeView();
- container_.reset(new ExtensionPopupContainer(self));
- static_cast<ExtensionViewMac*>(host->view())
- ->set_container(container_.get());
-
- NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
- [center addObserver:self
- selector:@selector(extensionViewFrameChanged)
- name:NSViewFrameDidChangeNotification
- object:extensionView_];
-
- [view addSubview:extensionView_];
-
- notificationBridge_.reset(new DevtoolsNotificationBridge(self));
- registrar_.reset(new content::NotificationRegistrar);
- if (beingInspected_) {
- // Listen for the extension to finish loading so the dev tools can be
- // opened.
- registrar_->Add(notificationBridge_.get(),
- extensions::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING,
- content::Source<BrowserContext>(host->browser_context()));
- }
+ [[self bubble] setArrowLocation:arrowLocation];
}
return self;
}
@@ -285,29 +258,25 @@ class DevtoolsNotificationBridge : public content::NotificationObserver {
// Make Mac behavior the same with Windows and others.
if (gPopup) {
std::string extension_id = url.host();
- extensions::ExtensionViewHost* host = [gPopup extensionViewHost];
- if (extension_id == host->extension_id()) {
- [gPopup close];
+ std::string old_extension_id = [gPopup extensionViewHost]->extension_id();
+ [gPopup close]; // Starts the animation to fade out the popup.
+ if (extension_id == old_extension_id)
return nil;
- }
}
- extensions::ExtensionViewHost* host =
- extensions::ExtensionViewHostFactory::CreatePopupHost(url, browser);
- DCHECK(host);
- if (!host)
- return nil;
-
- [gPopup close];
-
- // Takes ownership of |host|. Also will autorelease itself when the popup is
- // closed, so no need to do that here.
+ // Create the popup first. This establishes an initially hidden NSWindow so
+ // that the renderer is able to gather correct screen metrics for the initial
+ // paint.
gPopup = [[ExtensionPopupController alloc]
- initWithHost:host
- parentWindow:browser->window()->GetNativeWindow()
- anchoredAt:anchoredAt
- arrowLocation:arrowLocation
- devMode:devMode];
+ initWithParentWindow:browser->window()->GetNativeWindow()
+ anchoredAt:anchoredAt
+ arrowLocation:arrowLocation
+ devMode:devMode];
+
+ scoped_ptr<extensions::ExtensionViewHost> host(
+ extensions::ExtensionViewHostFactory::CreatePopupHost(url, browser));
+ DCHECK(host);
+ [gPopup setExtensionViewHost:host.Pass()];
return gPopup;
}
@@ -315,6 +284,36 @@ class DevtoolsNotificationBridge : public content::NotificationObserver {
return gPopup;
}
+- (void)setExtensionViewHost:(scoped_ptr<extensions::ExtensionViewHost>)host {
+ DCHECK(!host_);
+ DCHECK(host);
+ host_.swap(host);
+
+ extensionId_ = host_->extension_id();
+ container_.reset(new ExtensionPopupContainer(self));
+ ExtensionViewMac* hostView = static_cast<ExtensionViewMac*>(host_->view());
+ hostView->set_container(container_.get());
+ hostView->CreateWidgetHostViewIn([self bubble]);
+
+ extensionView_ = hostView->GetNativeView();
+
+ NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
+ [center addObserver:self
+ selector:@selector(extensionViewFrameChanged)
+ name:NSViewFrameDidChangeNotification
+ object:extensionView_];
+
+ notificationBridge_.reset(new DevtoolsNotificationBridge(self));
+ registrar_.reset(new content::NotificationRegistrar);
+ if (beingInspected_) {
+ // Listen for the extension to finish loading so the dev tools can be
+ // opened.
+ registrar_->Add(notificationBridge_.get(),
+ extensions::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING,
+ content::Source<BrowserContext>(host_->browser_context()));
+ }
+}
+
- (void)extensionViewFrameChanged {
// If there are no changes in the width or height of the frame, then ignore.
if (NSEqualSizes([extensionView_ frame].size, extensionFrame_.size))
@@ -382,7 +381,7 @@ class DevtoolsNotificationBridge : public content::NotificationObserver {
// When we update the size, the window will become visible. Stay hidden until
// the host is loaded.
pendingSize_ = newSize;
- if (!host_->did_stop_loading())
+ if (!host_ || !host_->did_stop_loading())
return;
// No need to use CA here, our caller calls us repeatedly to animate the
« 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