| 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
|
|
|