Bug 1469875 - Make nsPluginInstanceOwner::RequestCommitOrCancel() call IMEStateManager::NotifyIME() rather than calling nsIWidget::NotifyIME() r=m_kato
authorMasayuki Nakano <masayuki@d-toybox.com>
Fri, 29 Jun 2018 17:32:09 +0900
changeset 424642 28aec373fa436a5a7f0b1f8ea5c80dc355368443
parent 424641 d4ae24cec3ff1ad8633df5070073e7d492595786
child 424643 1685a7c2dd324adc1f4d268c52d184e23fab37b3
push id34220
push usertoros@mozilla.com
push dateMon, 02 Jul 2018 21:52:37 +0000
treeherdermozilla-central@959983b7d19e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersm_kato
bugs1469875
milestone63.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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
dom/plugins/base/nsPluginInstanceOwner.cpp
--- 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;