diff options
Diffstat (limited to 'content/renderer/npapi')
-rw-r--r-- | content/renderer/npapi/webplugin_delegate_proxy.cc | 104 | ||||
-rw-r--r-- | content/renderer/npapi/webplugin_delegate_proxy.h | 25 | ||||
-rw-r--r-- | content/renderer/npapi/webplugin_impl.h | 6 |
3 files changed, 132 insertions, 3 deletions
diff --git a/content/renderer/npapi/webplugin_delegate_proxy.cc b/content/renderer/npapi/webplugin_delegate_proxy.cc index d69fd40..2e80b85 100644 --- a/content/renderer/npapi/webplugin_delegate_proxy.cc +++ b/content/renderer/npapi/webplugin_delegate_proxy.cc @@ -108,6 +108,8 @@ WebPluginDelegateProxy::WebPluginDelegateProxy( uses_shared_bitmaps_(true), #if defined(OS_MACOSX) uses_compositor_(false), +#elif defined(OS_WIN) + dummy_activation_window_(NULL), #endif mime_type_(mime_type), instance_id_(MSG_ROUTING_NONE), @@ -130,12 +132,20 @@ WebPluginDelegateProxy::SharedBitmap::SharedBitmap() {} WebPluginDelegateProxy::SharedBitmap::~SharedBitmap() {} void WebPluginDelegateProxy::PluginDestroyed() { -#if defined(OS_MACOSX) +#if defined(OS_MACOSX) || defined(OS_WIN) // Ensure that the renderer doesn't think the plugin still has focus. if (render_view_) 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_->GetRoutingID(), dummy_activation_window_)); + } + dummy_activation_window_ = NULL; +#endif + if (render_view_.get()) render_view_->UnregisterPluginDelegate(this); @@ -294,6 +304,10 @@ bool WebPluginDelegateProxy::OnMessageReceived(const IPC::Message& msg) { IPC_MESSAGE_HANDLER(PluginHostMsg_CancelDocumentLoad, OnCancelDocumentLoad) IPC_MESSAGE_HANDLER(PluginHostMsg_DidStartLoading, OnDidStartLoading) IPC_MESSAGE_HANDLER(PluginHostMsg_DidStopLoading, OnDidStopLoading) +#if defined(OS_WIN) + IPC_MESSAGE_HANDLER(PluginHostMsg_SetWindowlessData, OnSetWindowlessData) + IPC_MESSAGE_HANDLER(PluginHostMsg_NotifyIMEStatus, OnNotifyIMEStatus) +#endif #if defined(OS_MACOSX) IPC_MESSAGE_HANDLER(PluginHostMsg_FocusChanged, OnFocusChanged); @@ -321,7 +335,7 @@ void WebPluginDelegateProxy::OnChannelError() { info_.path, channel_host_->peer_pid()); } -#if defined(OS_MACOSX) +#if defined(OS_MACOSX) || defined(OS_WIN) // Ensure that the renderer doesn't think the plugin still has focus. if (render_view_) render_view_->PluginFocusChanged(false, instance_id_); @@ -577,6 +591,10 @@ bool WebPluginDelegateProxy::GetFormValue(base::string16* value) { void WebPluginDelegateProxy::SetFocus(bool focused) { Send(new PluginMsg_SetFocus(instance_id_, focused)); +#if defined(OS_WIN) + if (render_view_) + render_view_->PluginFocusChanged(focused, instance_id_); +#endif } bool WebPluginDelegateProxy::HandleInputEvent( @@ -584,7 +602,14 @@ bool WebPluginDelegateProxy::HandleInputEvent( WebCursor::CursorInfo* cursor_info) { bool handled = false; WebCursor cursor; - Send(new PluginMsg_HandleInputEvent(instance_id_, &event, &handled, &cursor)); + // A windowless plugin can enter a modal loop in the context of a + // NPP_HandleEvent call, in which case we need to pump messages to + // the plugin. We pass of the corresponding event handle to the + // plugin process, which is set if the plugin does enter a modal loop. + IPC::SyncMessage* message = new PluginMsg_HandleInputEvent( + instance_id_, &event, &handled, &cursor); + message->set_pump_messages_event(modal_loop_pump_messages_event_.get()); + Send(message); return handled; } @@ -601,6 +626,35 @@ void WebPluginDelegateProxy::SetContentAreaFocus(bool has_focus) { Send(msg); } +#if defined(OS_WIN) +void WebPluginDelegateProxy::ImeCompositionUpdated( + const base::string16& text, + const std::vector<int>& clauses, + const std::vector<int>& target, + int cursor_position, + int plugin_id) { + // Dispatch the raw IME data if this plugin is the focused one. + if (instance_id_ != plugin_id) + return; + + IPC::Message* msg = new PluginMsg_ImeCompositionUpdated(instance_id_, + text, clauses, target, cursor_position); + msg->set_unblock(true); + Send(msg); +} + +void WebPluginDelegateProxy::ImeCompositionCompleted(const base::string16& text, + int plugin_id) { + // Dispatch the IME text if this plugin is the focused one. + if (instance_id_ != plugin_id) + return; + + IPC::Message* msg = new PluginMsg_ImeCompositionCompleted(instance_id_, text); + msg->set_unblock(true); + Send(msg); +} +#endif + #if defined(OS_MACOSX) void WebPluginDelegateProxy::SetWindowFocus(bool window_has_focus) { IPC::Message* msg = new PluginMsg_SetWindowFocus(instance_id_, @@ -652,6 +706,50 @@ void WebPluginDelegateProxy::ImeCompositionCompleted(const base::string16& text, } #endif // OS_MACOSX +#if defined(OS_WIN) +void WebPluginDelegateProxy::OnSetWindowlessData( + HANDLE modal_loop_pump_messages_event_handle, + gfx::NativeViewId dummy_activation_window) { + DCHECK(!modal_loop_pump_messages_event_.get()); + DCHECK(!dummy_activation_window_); + base::win::ScopedHandle modal_loop_pump_messages_event( + modal_loop_pump_messages_event_handle); + + dummy_activation_window_ = dummy_activation_window; + render_view_->Send(new ViewHostMsg_WindowlessPluginDummyWindowCreated( + render_view_->GetRoutingID(), dummy_activation_window_)); + + // Bug 25583: this can be null because some "virus scanners" block the + // DuplicateHandle call in the plugin process. + if (!modal_loop_pump_messages_event.IsValid()) + return; + + modal_loop_pump_messages_event_.reset( + new base::WaitableEvent(std::move(modal_loop_pump_messages_event))); +} + +void WebPluginDelegateProxy::OnNotifyIMEStatus(int input_type, + const gfx::Rect& caret_rect) { + if (!render_view_) + return; + + ViewHostMsg_TextInputState_Params params; + params.type = static_cast<ui::TextInputType>(input_type); + params.mode = ui::TEXT_INPUT_MODE_DEFAULT; + params.can_compose_inline = true; + render_view_->Send(new ViewHostMsg_TextInputStateChanged( + render_view_->GetRoutingID(), params)); + + ViewHostMsg_SelectionBounds_Params bounds_params; + bounds_params.anchor_rect = bounds_params.focus_rect = caret_rect; + bounds_params.anchor_dir = bounds_params.focus_dir = + blink::WebTextDirectionLeftToRight; + bounds_params.is_anchor_first = true; + render_view_->Send(new ViewHostMsg_SelectionBoundsChanged( + render_view_->GetRoutingID(), bounds_params)); +} +#endif + void WebPluginDelegateProxy::OnInvalidateRect(const gfx::Rect& rect) { if (!plugin_) return; diff --git a/content/renderer/npapi/webplugin_delegate_proxy.h b/content/renderer/npapi/webplugin_delegate_proxy.h index d980de8..9e3643e 100644 --- a/content/renderer/npapi/webplugin_delegate_proxy.h +++ b/content/renderer/npapi/webplugin_delegate_proxy.h @@ -80,6 +80,19 @@ class WebPluginDelegateProxy // Informs the plugin that its containing content view has gained or lost // first responder status. virtual void SetContentAreaFocus(bool has_focus); +#if defined(OS_WIN) + // Informs the plugin that plugin IME has updated its status. + virtual void ImeCompositionUpdated( + const base::string16& text, + const std::vector<int>& clauses, + const std::vector<int>& target, + int cursor_position, + int plugin_id); + // Informs the plugin that plugin IME has completed. + // If |text| is empty, composition was cancelled. + virtual void ImeCompositionCompleted(const base::string16& text, + int plugin_id); +#endif #if defined(OS_MACOSX) // Informs the plugin that its enclosing window has gained or lost focus. virtual void SetWindowFocus(bool window_has_focus); @@ -143,6 +156,11 @@ class WebPluginDelegateProxy uint32_t surface_id); void OnAcceleratedPluginSwappedIOSurface(); #endif +#if defined(OS_WIN) + void OnSetWindowlessData(HANDLE modal_loop_pump_messages_event_handle, + gfx::NativeViewId dummy_activation_window); + void OnNotifyIMEStatus(const int input_mode, const gfx::Rect& caret_rect); +#endif // Helper function that sends the UpdateGeometry message. void SendUpdateGeometry(bool bitmaps_changed); @@ -208,6 +226,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 scoped_refptr<PluginChannelHost> channel_host_; std::string mime_type_; @@ -222,6 +243,10 @@ class WebPluginDelegateProxy // Dummy NPP used to uniquely identify this plugin. scoped_ptr<NPP_t> npp_; + // 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 SkBitmap* sad_plugin_; diff --git a/content/renderer/npapi/webplugin_impl.h b/content/renderer/npapi/webplugin_impl.h index 8d54cc3..3e695e6 100644 --- a/content/renderer/npapi/webplugin_impl.h +++ b/content/renderer/npapi/webplugin_impl.h @@ -110,6 +110,12 @@ class WebPluginImpl : public WebPlugin, void DidStartLoading() override; void DidStopLoading() override; bool IsOffTheRecord() override; +#if defined(OS_WIN) + void SetWindowlessData(HANDLE pump_messages_event, + gfx::NativeViewId dummy_activation_window) override {} + void ReparentPluginWindow(HWND window, HWND parent) { } + void ReportExecutableMemory(size_t size) { } +#endif #if defined(OS_MACOSX) WebPluginAcceleratedSurface* GetAcceleratedSurface( gfx::GpuPreference gpu_preference) override; |