summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
Diffstat (limited to 'content')
-rw-r--r--content/common/plugin_messages.h21
-rw-r--r--content/plugin/webplugin_delegate_stub.cc25
-rw-r--r--content/plugin/webplugin_delegate_stub.h7
-rw-r--r--content/plugin/webplugin_proxy.cc13
-rw-r--r--content/plugin/webplugin_proxy.h8
-rw-r--r--content/renderer/render_view.cc51
-rw-r--r--content/renderer/render_view.h9
-rw-r--r--content/renderer/webplugin_delegate_proxy.cc51
-rw-r--r--content/renderer/webplugin_delegate_proxy.h13
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);