summaryrefslogtreecommitdiffstats
path: root/chrome/renderer
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/renderer')
-rw-r--r--chrome/renderer/render_view.cc26
-rw-r--r--chrome/renderer/render_view.h11
2 files changed, 36 insertions, 1 deletions
diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc
index 253a869..f6c19d7 100644
--- a/chrome/renderer/render_view.cc
+++ b/chrome/renderer/render_view.cc
@@ -156,7 +156,8 @@ RenderView::RenderView()
disable_popup_blocking_(false),
has_unload_listener_(false),
decrement_shared_popup_at_destruction_(false),
- greasemonkey_enabled_(false) {
+ greasemonkey_enabled_(false),
+ waiting_for_create_window_ack_(false) {
resource_dispatcher_ = new ResourceDispatcher(this);
#ifdef CHROME_PERSONALIZATION
personalization_ = Personalization::CreateRendererPersonalization();
@@ -291,9 +292,22 @@ void RenderView::Init(HWND parent_hwnd,
}
void RenderView::OnMessageReceived(const IPC::Message& message) {
+ // If the current RenderView instance represents a popup, then we
+ // need to wait for ViewMsg_CreatingNew_ACK to be sent by the browser.
+ // As part of this ack we also receive the browser window handle, which
+ // parents any plugins instantiated in this RenderView instance.
+ // Plugins can be instantiated only when we receive the parent window
+ // handle as they are child windows.
+ if (waiting_for_create_window_ack_ &&
+ resource_dispatcher_->IsResourceMessage(message)) {
+ queued_resource_messages_.push(new IPC::Message(message));
+ return;
+ }
+
// Let the resource dispatcher intercept resource messages first.
if (resource_dispatcher_->OnMessageReceived(message))
return;
+
IPC_BEGIN_MESSAGE_MAP(RenderView, message)
IPC_MESSAGE_HANDLER(ViewMsg_CreatingNew_ACK, OnCreatingNewAck)
IPC_MESSAGE_HANDLER(ViewMsg_CaptureThumbnail, SendThumbnail)
@@ -375,6 +389,15 @@ void RenderView::OnMessageReceived(const IPC::Message& message) {
// view.
void RenderView::OnCreatingNewAck(HWND parent) {
CompleteInit(parent);
+
+ waiting_for_create_window_ack_ = false;
+
+ while (!queued_resource_messages_.empty()) {
+ IPC::Message* queued_msg = queued_resource_messages_.front();
+ queued_resource_messages_.pop();
+ resource_dispatcher_->OnMessageReceived(*queued_msg);
+ delete queued_msg;
+ }
}
void RenderView::SendThumbnail() {
@@ -1715,6 +1738,7 @@ WebView* RenderView::CreateWebView(WebView* webview, bool user_gesture) {
prefs, shared_popup_counter_,
routing_id);
view->set_opened_by_user_gesture(user_gesture);
+ view->set_waiting_for_create_window_ack(true);
// Copy over the alternate error page URL so we can have alt error pages in
// the new render view (we don't need the browser to send the URL back down).
diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h
index cba9df9..9c50dfe 100644
--- a/chrome/renderer/render_view.h
+++ b/chrome/renderer/render_view.h
@@ -512,6 +512,10 @@ class RenderView : public RenderWidget, public WebViewDelegate,
// A helper method used by WasOpenedByUserGesture.
bool WasOpenedByUserGestureHelper() const;
+ void set_waiting_for_create_window_ack(bool wait) {
+ waiting_for_create_window_ack_ = wait;
+ }
+
// Handles resource loads for this view.
scoped_refptr<ResourceDispatcher> resource_dispatcher_;
@@ -658,6 +662,13 @@ class RenderView : public RenderWidget, public WebViewDelegate,
// True if Greasemonkey is enabled in this process.
bool greasemonkey_enabled_;
+ // Resource message queue. Used to queue up resource IPCs if we need
+ // to wait for an ACK from the browser before proceeding.
+ std::queue<IPC::Message*> queued_resource_messages_;
+
+ // Set if we are waiting for an ack for ViewHostMsg_CreateWindow
+ bool waiting_for_create_window_ack_;
+
DISALLOW_COPY_AND_ASSIGN(RenderView);
};