summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
authorjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-11-01 14:41:41 +0000
committerjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-11-01 14:41:41 +0000
commit611687564dbe98218211b73a4a83e24992a9c43f (patch)
treef88e64f553fbce623377fe86816692ba1189bd94 /content
parent294dc62b2e603a64feeb8226452d31775606b4d2 (diff)
downloadchromium_src-611687564dbe98218211b73a4a83e24992a9c43f.zip
chromium_src-611687564dbe98218211b73a4a83e24992a9c43f.tar.gz
chromium_src-611687564dbe98218211b73a4a83e24992a9c43f.tar.bz2
Make "dummy window" which is used for windowless plugins be parented in the browser. This is a step towards removing usage of parent hwnd in the renderer which is problematic on aura since that hwnd changes. In non-aura builds, this doesn't change so caching worked.
Review URL: https://codereview.chromium.org/11361024 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@165373 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r--content/browser/renderer_host/render_widget_host_impl.cc44
-rw-r--r--content/browser/renderer_host/render_widget_host_impl.h15
-rw-r--r--content/browser/renderer_host/render_widget_host_view_aura.cc9
-rw-r--r--content/browser/renderer_host/render_widget_host_view_aura.h3
-rw-r--r--content/common/plugin_messages.h5
-rw-r--r--content/common/view_messages.h8
-rw-r--r--content/plugin/webplugin_proxy.cc9
-rw-r--r--content/plugin/webplugin_proxy.h3
-rw-r--r--content/renderer/webplugin_delegate_proxy.cc29
-rw-r--r--content/renderer/webplugin_delegate_proxy.h10
10 files changed, 117 insertions, 18 deletions
diff --git a/content/browser/renderer_host/render_widget_host_impl.cc b/content/browser/renderer_host/render_widget_host_impl.cc
index 3c26fff..7300206 100644
--- a/content/browser/renderer_host/render_widget_host_impl.cc
+++ b/content/browser/renderer_host/render_widget_host_impl.cc
@@ -55,6 +55,7 @@
#include "webkit/glue/webcursor.h"
#include "webkit/glue/webpreferences.h"
#include "webkit/plugins/npapi/webplugin.h"
+#include "webkit/plugins/npapi/webplugin_delegate_impl.h"
#if defined(TOOLKIT_GTK)
#include "content/browser/renderer_host/backing_store_gtk.h"
@@ -65,6 +66,7 @@
using base::Time;
using base::TimeDelta;
using base::TimeTicks;
+using webkit::npapi::WebPluginDelegateImpl;
using WebKit::WebGestureEvent;
using WebKit::WebInputEvent;
using WebKit::WebKeyboardEvent;
@@ -344,6 +346,12 @@ bool RenderWidgetHostImpl::OnMessageReceived(const IPC::Message &msg) {
IPC_MESSAGE_HANDLER(ViewHostMsg_DestroyPluginContainer,
OnMsgDestroyPluginContainer)
#endif
+#if defined(OS_WIN)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_WindowlessPluginDummyWindowCreated,
+ OnWindowlessPluginDummyWindowCreated)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_WindowlessPluginDummyWindowDestroyed,
+ OnWindowlessPluginDummyWindowDestroyed)
+#endif
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP_EX()
@@ -1862,6 +1870,29 @@ void RenderWidgetHostImpl::OnMsgGetRootWindowRect(gfx::NativeViewId window_id,
}
#endif
+#if defined(OS_WIN)
+void RenderWidgetHostImpl::OnWindowlessPluginDummyWindowCreated(
+ gfx::NativeViewId dummy_activation_window) {
+ HWND hwnd = reinterpret_cast<HWND>(dummy_activation_window);
+ CHECK(WebPluginDelegateImpl::IsDummyActivationWindow(hwnd));
+ SetParent(hwnd, reinterpret_cast<HWND>(GetNativeViewId()));
+ dummy_windows_for_activation_.push_back(hwnd);
+}
+
+void RenderWidgetHostImpl::OnWindowlessPluginDummyWindowDestroyed(
+ gfx::NativeViewId dummy_activation_window) {
+ HWND hwnd = reinterpret_cast<HWND>(dummy_activation_window);
+ std::list<HWND>::iterator i = dummy_windows_for_activation_.begin();
+ for (; i != dummy_windows_for_activation_.end(); ++i) {
+ if ((*i) == hwnd) {
+ dummy_windows_for_activation_.erase(i);
+ return;
+ }
+ }
+ NOTREACHED() << "Unknown dummy window";
+}
+#endif
+
bool RenderWidgetHostImpl::PaintBackingStoreRect(
TransportDIB::Id bitmap,
const gfx::Rect& bitmap_rect,
@@ -2144,6 +2175,19 @@ void RenderWidgetHostImpl::AcknowledgeSwapBuffersToRenderer() {
}
#if defined(USE_AURA)
+
+void RenderWidgetHostImpl::ParentChanged(gfx::NativeViewId new_parent) {
+#if defined(OS_WIN)
+ HWND hwnd = reinterpret_cast<HWND>(new_parent);
+ if (!hwnd)
+ hwnd = WebPluginDelegateImpl::GetDefaultDummyActivationWindowParent();
+ for (std::list<HWND>::iterator i = dummy_windows_for_activation_.begin();
+ i != dummy_windows_for_activation_.end(); ++i) {
+ SetParent(*i, hwnd);
+ }
+#endif
+}
+
// static
void RenderWidgetHostImpl::SendFrontSurfaceIsProtected(
bool is_protected,
diff --git a/content/browser/renderer_host/render_widget_host_impl.h b/content/browser/renderer_host/render_widget_host_impl.h
index 3f75810..6869123 100644
--- a/content/browser/renderer_host/render_widget_host_impl.h
+++ b/content/browser/renderer_host/render_widget_host_impl.h
@@ -6,6 +6,7 @@
#define CONTENT_BROWSER_RENDERER_HOST_RENDER_WIDGET_HOST_IMPL_H_
#include <deque>
+#include <list>
#include <map>
#include <queue>
#include <string>
@@ -403,6 +404,10 @@ class CONTENT_EXPORT RenderWidgetHostImpl : virtual public RenderWidgetHost,
void AcknowledgeSwapBuffersToRenderer();
#if defined(USE_AURA)
+ // Called by the view when the parent changes. If a parent isn't available,
+ // NULL is used.
+ void ParentChanged(gfx::NativeViewId new_parent);
+
// Called by the view in response to visibility changes:
// 1. After the front surface is guarenteed to no longer be in use by the ui
// (protected false),
@@ -604,6 +609,12 @@ class CONTENT_EXPORT RenderWidgetHostImpl : virtual public RenderWidgetHost,
void OnMsgCreatePluginContainer(gfx::PluginWindowHandle id);
void OnMsgDestroyPluginContainer(gfx::PluginWindowHandle id);
#endif
+#if defined(OS_WIN)
+ void OnWindowlessPluginDummyWindowCreated(
+ gfx::NativeViewId dummy_activation_window);
+ void OnWindowlessPluginDummyWindowDestroyed(
+ gfx::NativeViewId dummy_activation_window);
+#endif
// Called (either immediately or asynchronously) after we're done with our
// BackingStore and can send an ACK to the renderer so it can paint onto it
@@ -840,6 +851,10 @@ class CONTENT_EXPORT RenderWidgetHostImpl : virtual public RenderWidgetHost,
scoped_ptr<TouchEventQueue> touch_event_queue_;
scoped_ptr<GestureEventFilter> gesture_event_filter_;
+#if defined(OS_WIN)
+ std::list<HWND> dummy_windows_for_activation_;
+#endif
+
DISALLOW_COPY_AND_ASSIGN(RenderWidgetHostImpl);
};
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.cc b/content/browser/renderer_host/render_widget_host_view_aura.cc
index d3c8990..53025fea 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.cc
+++ b/content/browser/renderer_host/render_widget_host_view_aura.cc
@@ -186,6 +186,10 @@ class RenderWidgetHostViewAura::WindowObserver : public aura::WindowObserver {
virtual ~WindowObserver() {}
// Overridden from aura::WindowObserver:
+ virtual void OnWindowAddedToRootWindow(aura::Window* window) OVERRIDE {
+ view_->AddingToRootWindow();
+ }
+
virtual void OnWindowRemovingFromRootWindow(aura::Window* window) OVERRIDE {
view_->RemovingFromRootWindow();
}
@@ -1885,7 +1889,12 @@ void RenderWidgetHostViewAura::InsertSyncPointAndACK(
route_id, gpu_host_id, presented, sync_point);
}
+void RenderWidgetHostViewAura::AddingToRootWindow() {
+ host_->ParentChanged(GetNativeViewId());
+}
+
void RenderWidgetHostViewAura::RemovingFromRootWindow() {
+ host_->ParentChanged(NULL);
// We are about to disconnect ourselves from the compositor, we need to issue
// the callbacks now, because we won't get notified when the frame is done.
// TODO(piman): this might in theory cause a race where the GPU process starts
diff --git a/content/browser/renderer_host/render_widget_host_view_aura.h b/content/browser/renderer_host/render_widget_host_view_aura.h
index 18b1fa5..3005eb8 100644
--- a/content/browser/renderer_host/render_widget_host_view_aura.h
+++ b/content/browser/renderer_host/render_widget_host_view_aura.h
@@ -252,6 +252,9 @@ class RenderWidgetHostViewAura
bool presented,
ui::Compositor* compositor);
+ // Called when window_ gets added to a new window tree.
+ void AddingToRootWindow();
+
// Called when window_ is removed from the window tree.
void RemovingFromRootWindow();
diff --git a/content/common/plugin_messages.h b/content/common/plugin_messages.h
index 00799b1..08e4d70 100644
--- a/content/common/plugin_messages.h
+++ b/content/common/plugin_messages.h
@@ -308,8 +308,9 @@ IPC_SYNC_MESSAGE_ROUTED1_0(PluginHostMsg_SetWindow,
// passed in for windowless plugins and is used to indicate if messages
// are to be pumped in sync calls to the plugin process. Currently used
// in HandleEvent calls.
-IPC_SYNC_MESSAGE_ROUTED1_0(PluginHostMsg_SetWindowlessPumpEvent,
- HANDLE /* modal_loop_pump_messages_event */)
+IPC_SYNC_MESSAGE_ROUTED2_0(PluginHostMsg_SetWindowlessData,
+ HANDLE /* modal_loop_pump_messages_event */,
+ gfx::NativeViewId /* dummy_activation_window*/)
// Send the IME status retrieved from a windowless plug-in. A windowless plug-in
// uses the IME attached to a browser process as a renderer does. A plug-in
diff --git a/content/common/view_messages.h b/content/common/view_messages.h
index 41297b3..1692d63 100644
--- a/content/common/view_messages.h
+++ b/content/common/view_messages.h
@@ -1802,6 +1802,14 @@ IPC_SYNC_MESSAGE_CONTROL4_2(ViewHostMsg_OpenChannelToPlugin,
IPC::ChannelHandle /* channel_handle */,
webkit::WebPluginInfo /* info */)
+#if defined(OS_WIN)
+IPC_MESSAGE_ROUTED1(ViewHostMsg_WindowlessPluginDummyWindowCreated,
+ gfx::NativeViewId /* dummy_activation_window */)
+
+IPC_MESSAGE_ROUTED1(ViewHostMsg_WindowlessPluginDummyWindowDestroyed,
+ gfx::NativeViewId /* dummy_activation_window */)
+#endif
+
// Get the list of proxies to use for |url|, as a semicolon delimited list
// of "<TYPE> <HOST>:<PORT>" | "DIRECT".
IPC_SYNC_MESSAGE_CONTROL1_2(ViewHostMsg_ResolveProxy,
diff --git a/content/plugin/webplugin_proxy.cc b/content/plugin/webplugin_proxy.cc
index 0d5ed27..a403dc0 100644
--- a/content/plugin/webplugin_proxy.cc
+++ b/content/plugin/webplugin_proxy.cc
@@ -140,14 +140,15 @@ void WebPluginProxy::WillDestroyWindow(gfx::PluginWindowHandle window) {
}
#if defined(OS_WIN)
-void WebPluginProxy::SetWindowlessPumpEvent(HANDLE pump_messages_event) {
+void WebPluginProxy::SetWindowlessData(
+ HANDLE pump_messages_event, gfx::NativeViewId dummy_activation_window) {
HANDLE pump_messages_event_for_renderer = NULL;
BrokerDuplicateHandle(pump_messages_event, channel_->peer_pid(),
&pump_messages_event_for_renderer,
SYNCHRONIZE | EVENT_MODIFY_STATE, 0);
- DCHECK(pump_messages_event_for_renderer != NULL);
- Send(new PluginHostMsg_SetWindowlessPumpEvent(
- route_id_, pump_messages_event_for_renderer));
+ DCHECK(pump_messages_event_for_renderer);
+ Send(new PluginHostMsg_SetWindowlessData(
+ route_id_, pump_messages_event_for_renderer, dummy_activation_window));
}
#endif
diff --git a/content/plugin/webplugin_proxy.h b/content/plugin/webplugin_proxy.h
index 6141f3a..686c7c4 100644
--- a/content/plugin/webplugin_proxy.h
+++ b/content/plugin/webplugin_proxy.h
@@ -67,7 +67,8 @@ class WebPluginProxy : public webkit::npapi::WebPlugin {
virtual void WillDestroyWindow(gfx::PluginWindowHandle window) OVERRIDE;
#if defined(OS_WIN)
- void SetWindowlessPumpEvent(HANDLE pump_messages_event);
+ void SetWindowlessData(HANDLE pump_messages_event,
+ gfx::NativeViewId dummy_activation_window);
#endif
virtual void CancelResource(unsigned long id) OVERRIDE;
diff --git a/content/renderer/webplugin_delegate_proxy.cc b/content/renderer/webplugin_delegate_proxy.cc
index 5e5bf67..4e8676b 100644
--- a/content/renderer/webplugin_delegate_proxy.cc
+++ b/content/renderer/webplugin_delegate_proxy.cc
@@ -202,6 +202,8 @@ WebPluginDelegateProxy::WebPluginDelegateProxy(
uses_shared_bitmaps_(false),
#if defined(OS_MACOSX)
uses_compositor_(false),
+#elif defined(OS_WIN)
+ dummy_activation_window_(NULL),
#endif
window_(gfx::kNullPluginWindow),
mime_type_(mime_type),
@@ -230,6 +232,14 @@ void WebPluginDelegateProxy::PluginDestroyed() {
render_view_->PluginFocusChanged(false, instance_id_);
#endif
+#if defined(OS_WIN)
+ if (dummy_activation_window_ && render_view_) {
+ render_view_->Send(new ViewHostMsg_WindowlessPluginDummyWindowDestroyed(
+ render_view_->routing_id(), dummy_activation_window_));
+ }
+ dummy_activation_window_ = NULL;
+#endif
+
if (window_)
WillDestroyWindow();
@@ -466,17 +476,14 @@ bool WebPluginDelegateProxy::OnMessageReceived(const IPC::Message& msg) {
IPC_BEGIN_MESSAGE_MAP(WebPluginDelegateProxy, msg)
IPC_MESSAGE_HANDLER(PluginHostMsg_SetWindow, OnSetWindow)
#if defined(OS_WIN)
- IPC_MESSAGE_HANDLER(PluginHostMsg_SetWindowlessPumpEvent,
- OnSetWindowlessPumpEvent)
- IPC_MESSAGE_HANDLER(PluginHostMsg_NotifyIMEStatus,
- OnNotifyIMEStatus)
+ IPC_MESSAGE_HANDLER(PluginHostMsg_SetWindowlessData, OnSetWindowlessData)
+ IPC_MESSAGE_HANDLER(PluginHostMsg_NotifyIMEStatus, OnNotifyIMEStatus)
#endif
IPC_MESSAGE_HANDLER(PluginHostMsg_CancelResource, OnCancelResource)
IPC_MESSAGE_HANDLER(PluginHostMsg_InvalidateRect, OnInvalidateRect)
IPC_MESSAGE_HANDLER(PluginHostMsg_GetWindowScriptNPObject,
OnGetWindowScriptNPObject)
- IPC_MESSAGE_HANDLER(PluginHostMsg_GetPluginElement,
- OnGetPluginElement)
+ IPC_MESSAGE_HANDLER(PluginHostMsg_GetPluginElement, OnGetPluginElement)
IPC_MESSAGE_HANDLER(PluginHostMsg_ResolveProxy, OnResolveProxy)
IPC_MESSAGE_HANDLER(PluginHostMsg_SetCookie, OnSetCookie)
IPC_MESSAGE_HANDLER(PluginHostMsg_GetCookies, OnGetCookies)
@@ -1145,9 +1152,15 @@ void WebPluginDelegateProxy::WillDestroyWindow() {
}
#if defined(OS_WIN)
-void WebPluginDelegateProxy::OnSetWindowlessPumpEvent(
- HANDLE modal_loop_pump_messages_event) {
+void WebPluginDelegateProxy::OnSetWindowlessData(
+ HANDLE modal_loop_pump_messages_event,
+ gfx::NativeViewId dummy_activation_window) {
DCHECK(modal_loop_pump_messages_event_ == NULL);
+ DCHECK(dummy_activation_window_ == NULL);
+
+ dummy_activation_window_ = dummy_activation_window;
+ render_view_->Send(new ViewHostMsg_WindowlessPluginDummyWindowCreated(
+ render_view_->routing_id(), dummy_activation_window_));
// Bug 25583: this can be null because some "virus scanners" block the
// DuplicateHandle call in the plugin process.
diff --git a/content/renderer/webplugin_delegate_proxy.h b/content/renderer/webplugin_delegate_proxy.h
index c3dc470..2cab740 100644
--- a/content/renderer/webplugin_delegate_proxy.h
+++ b/content/renderer/webplugin_delegate_proxy.h
@@ -150,7 +150,8 @@ class WebPluginDelegateProxy
// we translate into calls to the real WebPlugin.
void OnSetWindow(gfx::PluginWindowHandle window);
#if defined(OS_WIN)
- void OnSetWindowlessPumpEvent(HANDLE modal_loop_pump_messages_event);
+ void OnSetWindowlessData(HANDLE modal_loop_pump_messages_event,
+ gfx::NativeViewId dummy_activation_window);
void OnNotifyIMEStatus(const int input_mode, const gfx::Rect& caret_rect);
#endif
void OnCompleteURL(const std::string& url_in, std::string* url_out,
@@ -281,6 +282,9 @@ class WebPluginDelegateProxy
bool uses_shared_bitmaps_;
#if defined(OS_MACOSX)
bool uses_compositor_;
+#elif defined(OS_WIN)
+ // Used for windowless plugins so that keyboard activation works.
+ gfx::NativeViewId dummy_activation_window_;
#endif
gfx::PluginWindowHandle window_;
scoped_refptr<PluginChannelHost> channel_host_;
@@ -294,8 +298,8 @@ class WebPluginDelegateProxy
NPObject* npobject_;
base::WeakPtr<NPObjectStub> window_script_object_;
- // Event passed in by the plugin process and is used to decide if
- // messages need to be pumped in the NPP_HandleEvent sync call.
+ // Event passed in by the plugin process and is used to decide if messages
+ // need to be pumped in the NPP_HandleEvent sync call.
scoped_ptr<base::WaitableEvent> modal_loop_pump_messages_event_;
// Bitmap for crashed plugin