Bug 1384584 - TextComposition::DispatchCompositionEvent() shouldn't send composition events to focused TabParent after its RequestIMEToCommitComposition() synthesizes eCompositionCommit(AsIs) event synchronously r=m_kato
authorMasayuki Nakano <masayuki@d-toybox.com>
Wed, 26 Jul 2017 23:23:38 +0900
changeset 616827 fad5412d0735fa726c4c98c14d50cc1039f376f9
parent 616826 19d5f43ce7d087016c23cedc653d2ab7de9f02c7
child 616828 444f087b3ffb3cfcddcebc8e9593e99f1e065e1f
push id70824
push userbmo:emilio+bugs@crisal.io
push dateThu, 27 Jul 2017 14:50:07 +0000
reviewersm_kato
bugs1384584
milestone56.0a1
Bug 1384584 - TextComposition::DispatchCompositionEvent() shouldn't send composition events to focused TabParent after its RequestIMEToCommitComposition() synthesizes eCompositionCommit(AsIs) event synchronously r=m_kato When TextComposition::RequestIMEToCommitComposition() is called but the request is handled by native IME asynchronously, TextComposition synthesizes eCompositionCommit(AsIs) event to commit composition synchronously. (This behavior helps web apps which tries to commit composition from JS.) Then, TextComposition::DispatchCompositionEvent() should ignore following composition events which are actually sent from native IME. However, if composition is in a remote process, TextComposition::DispatchCompositionEvent() in the main process doesn't discard the following events coming from native IME. Therefore, ContentCacheInParent is confused by this unexpected events. So, TextComposition::DispatchCompositionEvent() shouldn't send the following unnecessary composition events to TabParent. Note that in remote process, composition is committed synchronously with the hack mentioned above and synthesized eCompositionCommit(AsIs) event of TextComposition::RequestIMEToCommitComposition() in the parent process looks like coming from native IME. Therefore, following composition events coming from native IME are not necessary for the remote process. MozReview-Commit-ID: 2uKFxcAq88J
dom/events/TextComposition.cpp
--- a/dom/events/TextComposition.cpp
+++ b/dom/events/TextComposition.cpp
@@ -241,16 +241,27 @@ void
 TextComposition::DispatchCompositionEvent(
                    WidgetCompositionEvent* aCompositionEvent,
                    nsEventStatus* aStatus,
                    EventDispatchingCallback* aCallBack,
                    bool aIsSynthesized)
 {
   mWasCompositionStringEmpty = mString.IsEmpty();
 
+  // If this instance has requested to commit or cancel composition but
+  // is not synthesizing commit event, that means that the IME commits or
+  // cancels the composition asynchronously.  Typically, iBus behaves so.
+  // Then, synthesized events which were dispatched immediately after
+  // the request has already committed our editor's composition string and
+  // told it to web apps.  Therefore, we should ignore the delayed events.
+  if (mRequestedToCommitOrCancel && !aIsSynthesized) {
+    *aStatus = nsEventStatus_eConsumeNoDefault;
+    return;
+  }
+
   // If the content is a container of TabParent, composition should be in the
   // remote process.
   if (mTabParent) {
     Unused << mTabParent->SendCompositionEvent(*aCompositionEvent);
     aCompositionEvent->StopPropagation();
     if (aCompositionEvent->CausesDOMTextEvent()) {
       mLastData = aCompositionEvent->mData;
       mLastRanges = aCompositionEvent->mRanges;
@@ -289,27 +300,16 @@ TextComposition::DispatchCompositionEven
     aCompositionEvent->mRanges = nullptr;
   }
 
   if (!IsValidStateForComposition(aCompositionEvent->mWidget)) {
     *aStatus = nsEventStatus_eConsumeNoDefault;
     return;
   }
 
-  // If this instance has requested to commit or cancel composition but
-  // is not synthesizing commit event, that means that the IME commits or
-  // cancels the composition asynchronously.  Typically, iBus behaves so.
-  // Then, synthesized events which were dispatched immediately after
-  // the request has already committed our editor's composition string and
-  // told it to web apps.  Therefore, we should ignore the delayed events.
-  if (mRequestedToCommitOrCancel && !aIsSynthesized) {
-    *aStatus = nsEventStatus_eConsumeNoDefault;
-    return;
-  }
-
   // IME may commit composition with empty string for a commit request or
   // with non-empty string for a cancel request.  We should prevent such
   // unexpected result.  E.g., web apps may be confused if they implement
   // autocomplete which attempts to commit composition forcibly when the user
   // selects one of suggestions but composition string is cleared by IME.
   // Note that most Chinese IMEs don't expose actual composition string to us.
   // They typically tell us an IDEOGRAPHIC SPACE or empty string as composition
   // string.  Therefore, we should hack it only when: