diff options
Diffstat (limited to 'content')
-rw-r--r-- | content/common/plugin_messages.h | 21 | ||||
-rw-r--r-- | content/plugin/webplugin_delegate_stub.cc | 25 | ||||
-rw-r--r-- | content/plugin/webplugin_delegate_stub.h | 7 | ||||
-rw-r--r-- | content/plugin/webplugin_proxy.cc | 13 | ||||
-rw-r--r-- | content/plugin/webplugin_proxy.h | 8 | ||||
-rw-r--r-- | content/renderer/render_view.cc | 51 | ||||
-rw-r--r-- | content/renderer/render_view.h | 9 | ||||
-rw-r--r-- | content/renderer/webplugin_delegate_proxy.cc | 51 | ||||
-rw-r--r-- | content/renderer/webplugin_delegate_proxy.h | 13 |
9 files changed, 195 insertions, 3 deletions
diff --git a/content/common/plugin_messages.h b/content/common/plugin_messages.h index 2dc4959..8b57345 100644 --- a/content/common/plugin_messages.h +++ b/content/common/plugin_messages.h @@ -203,6 +203,17 @@ IPC_SYNC_MESSAGE_ROUTED1_2(PluginMsg_HandleInputEvent, IPC_MESSAGE_ROUTED1(PluginMsg_SetContentAreaFocus, bool /* has_focus */) +#if defined(OS_WIN) +IPC_MESSAGE_ROUTED4(PluginMsg_ImeCompositionUpdated, + string16 /* text */, + std::vector<int> /* clauses */, + std::vector<int>, /* target */ + int /* cursor_position */) + +IPC_MESSAGE_ROUTED1(PluginMsg_ImeCompositionCompleted, + string16 /* text */) +#endif + #if defined(OS_MACOSX) IPC_MESSAGE_ROUTED1(PluginMsg_SetWindowFocus, bool /* has_focus */) @@ -304,6 +315,16 @@ IPC_SYNC_MESSAGE_ROUTED1_0(PluginHostMsg_SetWindow, // in HandleEvent calls. IPC_SYNC_MESSAGE_ROUTED1_0(PluginHostMsg_SetWindowlessPumpEvent, HANDLE /* modal_loop_pump_messages_event */) + +// 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 +// sends this message to control the IME status of a browser process. I would +// note that a plug-in sends this message to a renderer process that hosts this +// plug-in (not directly to a browser process) so the renderer process can +// update its IME status. +IPC_MESSAGE_ROUTED2(PluginHostMsg_NotifyIMEStatus, + int /* input_type */, + gfx::Rect /* caret_rect */) #endif IPC_MESSAGE_ROUTED1(PluginHostMsg_URLRequest, diff --git a/content/plugin/webplugin_delegate_stub.cc b/content/plugin/webplugin_delegate_stub.cc index dce1058..2d1037c 100644 --- a/content/plugin/webplugin_delegate_stub.cc +++ b/content/plugin/webplugin_delegate_stub.cc @@ -110,6 +110,12 @@ bool WebPluginDelegateStub::OnMessageReceived(const IPC::Message& msg) { IPC_MESSAGE_HANDLER(PluginMsg_SendJavaScriptStream, OnSendJavaScriptStream) IPC_MESSAGE_HANDLER(PluginMsg_SetContentAreaFocus, OnSetContentAreaFocus) +#if defined(OS_WIN) + IPC_MESSAGE_HANDLER(PluginMsg_ImeCompositionUpdated, + OnImeCompositionUpdated) + IPC_MESSAGE_HANDLER(PluginMsg_ImeCompositionCompleted, + OnImeCompositionCompleted) +#endif #if defined(OS_MACOSX) IPC_MESSAGE_HANDLER(PluginMsg_SetWindowFocus, OnSetWindowFocus) IPC_MESSAGE_HANDLER(PluginMsg_ContainerHidden, OnContainerHidden) @@ -324,6 +330,25 @@ void WebPluginDelegateStub::OnSetContentAreaFocus(bool has_focus) { delegate_->SetContentAreaHasFocus(has_focus); } +#if defined(OS_WIN) +void WebPluginDelegateStub::OnImeCompositionUpdated( + const string16& text, + const std::vector<int>& clauses, + const std::vector<int>& target, + int cursor_position) { + if (delegate_) + delegate_->ImeCompositionUpdated(text, clauses, target, cursor_position); +#if defined(OS_WIN) + webplugin_->UpdateIMEStatus(); +#endif +} + +void WebPluginDelegateStub::OnImeCompositionCompleted(const string16& text) { + if (delegate_) + delegate_->ImeCompositionCompleted(text); +} +#endif + #if defined(OS_MACOSX) void WebPluginDelegateStub::OnSetWindowFocus(bool has_focus) { if (delegate_) diff --git a/content/plugin/webplugin_delegate_stub.h b/content/plugin/webplugin_delegate_stub.h index 4a12b9a..a3be8a0 100644 --- a/content/plugin/webplugin_delegate_stub.h +++ b/content/plugin/webplugin_delegate_stub.h @@ -81,6 +81,13 @@ class WebPluginDelegateStub : public IPC::Channel::Listener, void OnGetFormValue(string16* value, bool* success); void OnSetContentAreaFocus(bool has_focus); +#if defined(OS_WIN) + void OnImeCompositionUpdated(const string16& text, + const std::vector<int>& clauses, + const std::vector<int>& target, + int cursor_position); + void OnImeCompositionCompleted(const string16& text); +#endif #if defined(OS_MACOSX) void OnSetWindowFocus(bool has_focus); void OnContainerHidden(); diff --git a/content/plugin/webplugin_proxy.cc b/content/plugin/webplugin_proxy.cc index 2f7ef5f..4b167e1 100644 --- a/content/plugin/webplugin_proxy.cc +++ b/content/plugin/webplugin_proxy.cc @@ -747,3 +747,16 @@ void WebPluginProxy::ResourceClientDeleted( void WebPluginProxy::URLRedirectResponse(bool allow, int resource_id) { Send(new PluginHostMsg_URLRedirectResponse(route_id_, allow, resource_id)); } + +#if defined(OS_WIN) +void WebPluginProxy::UpdateIMEStatus() { + // Retrieve the IME status from a plug-in and send it to a renderer process + // when the plug-in has updated it. + int input_type; + gfx::Rect caret_rect; + if (!delegate_->GetIMEStatus(&input_type, &caret_rect)) + return; + + Send(new PluginHostMsg_NotifyIMEStatus(route_id_, input_type, caret_rect)); +} +#endif diff --git a/content/plugin/webplugin_proxy.h b/content/plugin/webplugin_proxy.h index b6e3175..54f8894 100644 --- a/content/plugin/webplugin_proxy.h +++ b/content/plugin/webplugin_proxy.h @@ -168,6 +168,14 @@ class WebPluginProxy : public webkit::npapi::WebPlugin { virtual void URLRedirectResponse(bool allow, int resource_id); +#if defined(OS_WIN) + // Retrieves the IME status from a windowless plug-in and sends it to a + // renderer process. A renderer process will convert the coordinates from + // local to the window coordinates and send the converted coordinates to a + // browser process. + void UpdateIMEStatus(); +#endif + private: bool Send(IPC::Message* msg); diff --git a/content/renderer/render_view.cc b/content/renderer/render_view.cc index 8311958..5a20971 100644 --- a/content/renderer/render_view.cc +++ b/content/renderer/render_view.cc @@ -327,6 +327,9 @@ RenderView::RenderView(RenderThreadBase* render_thread, cached_has_main_frame_horizontal_scrollbar_(false), cached_has_main_frame_vertical_scrollbar_(false), ALLOW_THIS_IN_INITIALIZER_LIST(pepper_delegate_(this)), +#if defined(OS_WIN) + focused_plugin_id_(-1), +#endif ALLOW_THIS_IN_INITIALIZER_LIST(cookie_jar_(this)), geolocation_dispatcher_(NULL), speech_input_dispatcher_(NULL), @@ -4045,6 +4048,32 @@ void RenderView::OnImeSetComposition( // TODO(kinaba) This temporal remedy can be removed after PPAPI is extended // with an IME handling interface. if (!pepper_delegate_.IsPluginFocused()) { +#if defined(OS_WIN) + // When a plug-in has focus, we create platform-specific IME data used by + // our IME emulator and send it directly to the focused plug-in, i.e. we + // bypass WebKit. (WebPluginDelegate dispatches this IME data only when its + // instance ID is the same one as the specified ID.) + if (focused_plugin_id_ >= 0) { + std::vector<int> clauses; + std::vector<int> target; + for (size_t i = 0; i < underlines.size(); ++i) { + clauses.push_back(underlines[i].startOffset); + clauses.push_back(underlines[i].endOffset); + if (underlines[i].thick) { + target.clear(); + target.push_back(underlines[i].startOffset); + target.push_back(underlines[i].endOffset); + } + } + std::set<WebPluginDelegateProxy*>::iterator it; + for (it = plugin_delegates_.begin(); + it != plugin_delegates_.end(); ++it) { + (*it)->ImeCompositionUpdated(text, clauses, target, selection_end, + focused_plugin_id_); + } + return; + } +#endif RenderWidget::OnImeSetComposition(text, underlines, selection_start, @@ -4069,6 +4098,19 @@ void RenderView::OnImeConfirmComposition(const string16& text) { webwidget_->handleInputEvent(char_event); } } else { +#if defined(OS_WIN) + // Same as OnImeSetComposition(), we send the text from IMEs directly to + // plug-ins. When we send IME text directly to plug-ins, we should not send + // it to WebKit to prevent WebKit from controlling IMEs. + if (focused_plugin_id_ >= 0) { + std::set<WebPluginDelegateProxy*>::iterator it; + for (it = plugin_delegates_.begin(); + it != plugin_delegates_.end(); ++it) { + (*it)->ImeCompositionCompleted(text, focused_plugin_id_); + } + return; + } +#endif RenderWidget::OnImeConfirmComposition(text); } } @@ -4099,6 +4141,15 @@ bool RenderView::CanComposeInline() { return true; } +#if defined(OS_WIN) +void RenderView::PluginFocusChanged(bool focused, int plugin_id) { + if (focused) + focused_plugin_id_ = plugin_id; + else + focused_plugin_id_ = -1; +} +#endif + #if defined(OS_MACOSX) void RenderView::PluginFocusChanged(bool focused, int plugin_id) { IPC::Message* msg = new ViewHostMsg_PluginFocusChanged(routing_id(), diff --git a/content/renderer/render_view.h b/content/renderer/render_view.h index e22152e..fe293aa 100644 --- a/content/renderer/render_view.h +++ b/content/renderer/render_view.h @@ -309,10 +309,12 @@ class RenderView : public RenderWidget, // Request updated policy regarding firewall NAT traversal being enabled. void RequestRemoteAccessClientFirewallTraversal(); -#if defined(OS_MACOSX) +#if defined(OS_MACOSX) || defined(OS_WIN) // Informs the render view that the given plugin has gained or lost focus. void PluginFocusChanged(bool focused, int plugin_id); +#endif +#if defined(OS_MACOSX) // Starts plugin IME. void StartPluginIme(); @@ -1130,6 +1132,11 @@ class RenderView : public RenderWidget, // or tab focus and visibily. These are non-owning references. std::set<WebPluginDelegateProxy*> plugin_delegates_; +#if defined(OS_WIN) + // The ID of the focused NPAPI plug-in. + int focused_plugin_id_; +#endif + // Helper objects ------------------------------------------------------------ RendererWebCookieJarImpl cookie_jar_; diff --git a/content/renderer/webplugin_delegate_proxy.cc b/content/renderer/webplugin_delegate_proxy.cc index 0f84f1b..121f5a3 100644 --- a/content/renderer/webplugin_delegate_proxy.cc +++ b/content/renderer/webplugin_delegate_proxy.cc @@ -190,7 +190,7 @@ 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_); @@ -425,6 +425,8 @@ bool WebPluginDelegateProxy::OnMessageReceived(const IPC::Message& msg) { #if defined(OS_WIN) IPC_MESSAGE_HANDLER(PluginHostMsg_SetWindowlessPumpEvent, OnSetWindowlessPumpEvent) + IPC_MESSAGE_HANDLER(PluginHostMsg_NotifyIMEStatus, + OnNotifyIMEStatus) #endif IPC_MESSAGE_HANDLER(PluginHostMsg_CancelResource, OnCancelResource) IPC_MESSAGE_HANDLER(PluginHostMsg_InvalidateRect, OnInvalidateRect) @@ -482,7 +484,7 @@ void WebPluginDelegateProxy::OnChannelError() { if (!channel_host_->expecting_shutdown()) render_view_->PluginCrashed(info_.path); -#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_); @@ -939,6 +941,10 @@ void WebPluginDelegateProxy::DidFinishLoadWithReason( 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( @@ -971,6 +977,35 @@ void WebPluginDelegateProxy::SetContentAreaFocus(bool has_focus) { Send(msg); } +#if defined(OS_WIN) +void WebPluginDelegateProxy::ImeCompositionUpdated( + const 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 plug-in 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 string16& text, + int plugin_id) { + // Dispatch the IME text if this plug-in 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_, @@ -1056,6 +1091,18 @@ void WebPluginDelegateProxy::OnSetWindowlessPumpEvent( modal_loop_pump_messages_event_.reset( new base::WaitableEvent(modal_loop_pump_messages_event)); } + +void WebPluginDelegateProxy::OnNotifyIMEStatus(int input_type, + const gfx::Rect& caret_rect) { + if (!render_view_) + return; + + render_view_->Send(new ViewHostMsg_ImeUpdateTextInputState( + render_view_->routing_id(), + static_cast<ui::TextInputType>(input_type), + true, + caret_rect)); +} #endif void WebPluginDelegateProxy::OnCancelResource(int id) { diff --git a/content/renderer/webplugin_delegate_proxy.h b/content/renderer/webplugin_delegate_proxy.h index 5b66a3c..6cfc3a3 100644 --- a/content/renderer/webplugin_delegate_proxy.h +++ b/content/renderer/webplugin_delegate_proxy.h @@ -82,6 +82,18 @@ 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 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 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); @@ -139,6 +151,7 @@ class WebPluginDelegateProxy void OnSetWindow(gfx::PluginWindowHandle window); #if defined(OS_WIN) void OnSetWindowlessPumpEvent(HANDLE modal_loop_pump_messages_event); + void OnNotifyIMEStatus(const int input_mode, const gfx::Rect& caret_rect); #endif void OnCompleteURL(const std::string& url_in, std::string* url_out, bool* result); |