Bug 1469875 - Make nsPluginInstanceOwner::RequestCommitOrCancel() call IMEStateManager::NotifyIME() rather than calling nsIWidget::NotifyIME() r?m_kato
Any content code except TextComposition shouldn't call nsIWidget::NotifyIM()
since IMEStateManager and TextComposition manage state of the composition.
Therefore, we need to make nsPluginInstanceOwner::RequestCommitOrCancel()
call IMEStateManager::NotifyIME() instead.
Additionally, this method should ignore the request if composition has
already been gone. This patch makes check whether there is a TextComposition
instance for the widget and the composition is handled in the plugin owner
element.
MozReview-Commit-ID: 5cx5X2hGfek
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp
+++ b/dom/plugins/base/nsPluginInstanceOwner.cpp
@@ -887,21 +887,47 @@ nsPluginInstanceOwner::RequestCommitOrCa
nsCOMPtr<nsIWidget> widget = GetContainingWidgetIfOffset();
if (!widget) {
widget = GetRootWidgetForPluginFrame(mPluginFrame);
if (NS_WARN_IF(!widget)) {
return false;
}
}
- if (aCommitted) {
- widget->NotifyIME(widget::REQUEST_TO_COMMIT_COMPOSITION);
- } else {
- widget->NotifyIME(widget::REQUEST_TO_CANCEL_COMPOSITION);
+ // Retrieve TextComposition for the widget with IMEStateManager instead of
+ // using GetTextComposition() because we cannot know whether the method
+ // failed due to no widget or no composition.
+ RefPtr<TextComposition> composition =
+ IMEStateManager::GetTextCompositionFor(widget);
+ if (!composition) {
+ // If there is composition, we should just ignore this request since
+ // the composition may have been committed after the plugin process
+ // sent this request.
+ return true;
}
+
+ nsCOMPtr<nsIContent> content = do_QueryReferent(mContent);
+ if (content != composition->GetEventTargetNode()) {
+ // If the composition is handled in different node, that means that
+ // the composition for the plugin has gone and new composition has
+ // already started. So, request from the plugin should be ignored
+ // since user inputs different text now.
+ return true;
+ }
+
+ // If active composition is being handled in the plugin, let's request to
+ // commit/cancel the composition via both IMEStateManager and TextComposition
+ // for avoid breaking the status management of composition. I.e., don't
+ // call nsIWidget::NotifyIME() directly from here.
+ IMEStateManager::NotifyIME(aCommitted ?
+ widget::REQUEST_TO_COMMIT_COMPOSITION :
+ widget::REQUEST_TO_CANCEL_COMPOSITION,
+ widget, composition->GetTabParent());
+ // FYI: This instance may have been destroyed. Be careful if you need to
+ // access members of this class.
return true;
}
bool
nsPluginInstanceOwner::EnableIME(bool aEnable)
{
if (NS_WARN_IF(!mPluginFrame)) {
return false;