summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authorandybons@chromium.org <andybons@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-09 04:14:02 +0000
committerandybons@chromium.org <andybons@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-09 04:14:02 +0000
commitcf390ea428a6c56280c61b5998c8ffffefa971c5 (patch)
treefe65fd6ae8816a3994b52efc18db625987a26c11 /chrome/browser
parent3cd15376f3e5fdabe9f41c8f4b65f33025a3d0b6 (diff)
downloadchromium_src-cf390ea428a6c56280c61b5998c8ffffefa971c5.zip
chromium_src-cf390ea428a6c56280c61b5998c8ffffefa971c5.tar.gz
chromium_src-cf390ea428a6c56280c61b5998c8ffffefa971c5.tar.bz2
Fixes issue where clicking on a <SELECT> dropdown in an extension popup window would hard crash the browser.
I'm hoping that this will open up discussions for refactoring work amongst ExtensionHost and TabContentsView, since so much code is shared between the two and both need sufficient Mac love. BUG=29353 TEST=load a browser action with a popup that contains a SELECT element. click on the element and observe that it acts normally (no crashing). Review URL: http://codereview.chromium.org/465108 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@34136 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
-rw-r--r--chrome/browser/extensions/extension_host.cc18
-rw-r--r--chrome/browser/extensions/extension_host.h14
-rw-r--r--chrome/browser/extensions/extension_host_mac.h27
-rw-r--r--chrome/browser/extensions/extension_host_mac.mm37
-rw-r--r--chrome/browser/extensions/extension_process_manager.cc14
-rw-r--r--chrome/browser/views/extensions/extension_view.cc2
6 files changed, 106 insertions, 6 deletions
diff --git a/chrome/browser/extensions/extension_host.cc b/chrome/browser/extensions/extension_host.cc
index 1aa6ac8..0ad3a9e 100644
--- a/chrome/browser/extensions/extension_host.cc
+++ b/chrome/browser/extensions/extension_host.cc
@@ -450,8 +450,13 @@ void ExtensionHost::CreateNewWindow(int route_id) {
}
void ExtensionHost::CreateNewWidget(int route_id, bool activatable) {
- delegate_view_helper_.CreateNewWidget(route_id, activatable,
- site_instance()->GetProcess());
+ CreateNewWidgetInternal(route_id, activatable);
+}
+
+RenderWidgetHostView* ExtensionHost::CreateNewWidgetInternal(int route_id,
+ bool activatable) {
+ return delegate_view_helper_.CreateNewWidget(route_id, activatable,
+ site_instance()->GetProcess());
}
void ExtensionHost::ShowCreatedWindow(int route_id,
@@ -472,8 +477,13 @@ void ExtensionHost::ShowCreatedWindow(int route_id,
void ExtensionHost::ShowCreatedWidget(int route_id,
const gfx::Rect& initial_pos) {
- RenderWidgetHostView* widget_host_view =
- delegate_view_helper_.GetCreatedWidget(route_id);
+ ShowCreatedWidgetInternal(delegate_view_helper_.GetCreatedWidget(route_id),
+ initial_pos);
+}
+
+void ExtensionHost::ShowCreatedWidgetInternal(
+ RenderWidgetHostView* widget_host_view,
+ const gfx::Rect& initial_pos) {
Browser *browser = GetBrowser();
DCHECK(browser);
if (!browser)
diff --git a/chrome/browser/extensions/extension_host.h b/chrome/browser/extensions/extension_host.h
index 35fc89e..76f20d2 100644
--- a/chrome/browser/extensions/extension_host.h
+++ b/chrome/browser/extensions/extension_host.h
@@ -159,6 +159,20 @@ class ExtensionHost : public ExtensionPopupHost::PopupDelegate,
virtual TabContents* AsTabContents() { return NULL; }
virtual ExtensionHost* AsExtensionHost() { return this; }
+ protected:
+ // Internal functions used to support the CreateNewWidget() method. If a
+ // platform requires plugging into widget creation at a lower level, then a
+ // subclass might want to override these functions, but otherwise they should
+ // be fine just implementing RenderWidgetHostView::InitAsPopup().
+ //
+ // The Create function returns the newly created widget so it can be
+ // associated with the given route. When the widget needs to be shown later,
+ // we'll look it up again and pass the object to the Show functions rather
+ // than the route ID.
+ virtual RenderWidgetHostView* CreateNewWidgetInternal(int route_id,
+ bool activatable);
+ virtual void ShowCreatedWidgetInternal(RenderWidgetHostView* widget_host_view,
+ const gfx::Rect& initial_pos);
private:
friend class ProcessCreationQueue;
diff --git a/chrome/browser/extensions/extension_host_mac.h b/chrome/browser/extensions/extension_host_mac.h
new file mode 100644
index 0000000..0624826
--- /dev/null
+++ b/chrome/browser/extensions/extension_host_mac.h
@@ -0,0 +1,27 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_HOST_MAC_H_
+#define CHROME_BROWSER_EXTENSIONS_EXTENSION_HOST_MAC_H_
+
+#include "chrome/browser/extensions/extension_host.h"
+
+class RenderWidgetHostView;
+
+class ExtensionHostMac : public ExtensionHost {
+ public:
+ ExtensionHostMac(Extension* extension, SiteInstance* site_instance,
+ const GURL& url, ViewType::Type host_type) :
+ ExtensionHost(extension, site_instance, url, host_type) {}
+ virtual ~ExtensionHostMac() {}
+ protected:
+ virtual RenderWidgetHostView* CreateNewWidgetInternal(int route_id,
+ bool activatable);
+ virtual void ShowCreatedWidgetInternal(RenderWidgetHostView* widget_host_view,
+ const gfx::Rect& initial_pos);
+ private:
+ DISALLOW_COPY_AND_ASSIGN(ExtensionHostMac);
+};
+
+#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_HOST_MAC_H_
diff --git a/chrome/browser/extensions/extension_host_mac.mm b/chrome/browser/extensions/extension_host_mac.mm
new file mode 100644
index 0000000..d541deb
--- /dev/null
+++ b/chrome/browser/extensions/extension_host_mac.mm
@@ -0,0 +1,37 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "chrome/browser/extensions/extension_host_mac.h"
+
+#include "chrome/browser/renderer_host/render_widget_host_view_mac.h"
+
+RenderWidgetHostView* ExtensionHostMac::CreateNewWidgetInternal(
+ int route_id,
+ bool activatable) {
+ // A RenderWidgetHostViewMac has lifetime scoped to the view. We'll retain it
+ // to allow it to survive the trip without being hosed.
+ RenderWidgetHostView* widget_view =
+ ExtensionHost::CreateNewWidgetInternal(route_id, activatable);
+ RenderWidgetHostViewMac* widget_view_mac =
+ static_cast<RenderWidgetHostViewMac*>(widget_view);
+ [widget_view_mac->native_view() retain];
+
+ // |widget_view_mac| needs to know how to position itself in our view.
+ widget_view_mac->set_parent_view(view()->native_view());
+
+ return widget_view;
+}
+
+void ExtensionHostMac::ShowCreatedWidgetInternal(
+ RenderWidgetHostView* widget_host_view,
+ const gfx::Rect& initial_pos) {
+ ExtensionHost::ShowCreatedWidgetInternal(widget_host_view, initial_pos);
+
+ // A RenderWidgetHostViewMac has lifetime scoped to the view. Now that it's
+ // properly embedded (or purposefully ignored) we can release the reference we
+ // took in CreateNewWidgetInternal().
+ RenderWidgetHostViewMac* widget_view_mac =
+ static_cast<RenderWidgetHostViewMac*>(widget_host_view);
+ [widget_view_mac->native_view() release];
+}
diff --git a/chrome/browser/extensions/extension_process_manager.cc b/chrome/browser/extensions/extension_process_manager.cc
index 02587a4..7d6ca0b 100644
--- a/chrome/browser/extensions/extension_process_manager.cc
+++ b/chrome/browser/extensions/extension_process_manager.cc
@@ -5,6 +5,9 @@
#include "chrome/browser/extensions/extension_process_manager.h"
#include "chrome/browser/browsing_instance.h"
+#if defined(OS_MACOSX)
+#include "chrome/browser/extensions/extension_host_mac.h"
+#endif
#include "chrome/browser/extensions/extension_host.h"
#include "chrome/browser/extensions/extensions_service.h"
#include "chrome/browser/profile.h"
@@ -59,7 +62,12 @@ ExtensionHost* ExtensionProcessManager::CreateView(Extension* extension,
DCHECK(extension);
DCHECK(browser);
ExtensionHost* host =
+#if defined(OS_MACOSX)
+ new ExtensionHostMac(extension, GetSiteInstanceForURL(url), url,
+ view_type);
+#else
new ExtensionHost(extension, GetSiteInstanceForURL(url), url, view_type);
+#endif
host->CreateView(browser);
OnExtensionHostCreated(host, false);
return host;
@@ -104,8 +112,14 @@ ExtensionHost* ExtensionProcessManager::CreatePopup(const GURL& url,
ExtensionHost* ExtensionProcessManager::CreateBackgroundHost(
Extension* extension, const GURL& url) {
ExtensionHost* host =
+#if defined(OS_MACOSX)
+ new ExtensionHostMac(extension, GetSiteInstanceForURL(url), url,
+ ViewType::EXTENSION_BACKGROUND_PAGE);
+#else
new ExtensionHost(extension, GetSiteInstanceForURL(url), url,
ViewType::EXTENSION_BACKGROUND_PAGE);
+#endif
+
host->CreateRenderViewSoon(NULL); // create a RenderViewHost with no view
OnExtensionHostCreated(host, true);
return host;
diff --git a/chrome/browser/views/extensions/extension_view.cc b/chrome/browser/views/extensions/extension_view.cc
index 9bf87f5..7945307 100644
--- a/chrome/browser/views/extensions/extension_view.cc
+++ b/chrome/browser/views/extensions/extension_view.cc
@@ -13,8 +13,6 @@
#include "chrome/browser/renderer_host/render_widget_host_view_win.h"
#elif defined(OS_LINUX)
#include "chrome/browser/renderer_host/render_widget_host_view_gtk.h"
-#elif defined(OS_MACOSX)
-#include "chrome/browser/renderer_host/render_widget_host_view_mac.h"
#endif
ExtensionView::ExtensionView(ExtensionHost* host, Browser* browser)