diff options
Diffstat (limited to 'chrome/renderer')
-rw-r--r-- | chrome/renderer/render_view.cc | 26 | ||||
-rw-r--r-- | chrome/renderer/render_view.h | 11 |
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); }; |