diff options
author | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-01 14:41:41 +0000 |
---|---|---|
committer | jam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-11-01 14:41:41 +0000 |
commit | 611687564dbe98218211b73a4a83e24992a9c43f (patch) | |
tree | f88e64f553fbce623377fe86816692ba1189bd94 /content | |
parent | 294dc62b2e603a64feeb8226452d31775606b4d2 (diff) | |
download | chromium_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.cc | 44 | ||||
-rw-r--r-- | content/browser/renderer_host/render_widget_host_impl.h | 15 | ||||
-rw-r--r-- | content/browser/renderer_host/render_widget_host_view_aura.cc | 9 | ||||
-rw-r--r-- | content/browser/renderer_host/render_widget_host_view_aura.h | 3 | ||||
-rw-r--r-- | content/common/plugin_messages.h | 5 | ||||
-rw-r--r-- | content/common/view_messages.h | 8 | ||||
-rw-r--r-- | content/plugin/webplugin_proxy.cc | 9 | ||||
-rw-r--r-- | content/plugin/webplugin_proxy.h | 3 | ||||
-rw-r--r-- | content/renderer/webplugin_delegate_proxy.cc | 29 | ||||
-rw-r--r-- | content/renderer/webplugin_delegate_proxy.h | 10 |
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 |