Bug 1456381 - TSFTextStore should discard pending composition update actions before recording composition end action r?m_kato draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Thu, 19 Apr 2018 20:42:00 +0900
changeset 787061 338894042a359dc68ab7fcf0faa46978c61cbf0d
parent 787057 1ee16be383f4f9b44da7d5f8ca7bb640fb938703
push id107621
push usermasayuki@d-toybox.com
push dateTue, 24 Apr 2018 05:24:57 +0000
reviewersm_kato
bugs1456381
milestone61.0a1
Bug 1456381 - TSFTextStore should discard pending composition update actions before recording composition end action r?m_kato TSFTextStore should discard pending composition update actions when it records end composition update action because end composition update action causes dispatching eCompositionCommit event and it replaces old composition string anyway. So, following eCompositionChange which is dispatched by preceding composition update actions are just redundant. MozReview-Commit-ID: HBHx2jA15ro
widget/windows/TSFTextStore.cpp
widget/windows/TSFTextStore.h
--- a/widget/windows/TSFTextStore.cpp
+++ b/widget/windows/TSFTextStore.cpp
@@ -5198,17 +5198,22 @@ TSFTextStore::RecordCompositionEndAction
   MaybeDispatchKeyboardEventAsProcessedByIME();
   if (mDestroyed) {
     MOZ_LOG(sTextStoreLog, LogLevel::Error,
       ("0x%p   TSFTextStore::RecordCompositionEndAction() FAILED due to "
        "destroyed during dispatching a keyboard event", this));
     return false;
   }
 
-  CompleteLastActionIfStillIncomplete();
+  // If we're handling incomplete composition update or already handled
+  // composition update, we can forget them since composition end will send
+  // the latest composition string and it overwrites the composition string
+  // even if we dispatch eCompositionChange event before that.  So, let's
+  // forget all composition updates now.
+  RemoveLastCompositionUpdateActions();
   PendingAction* action = mPendingActions.AppendElement();
   action->mType = PendingAction::Type::eCompositionEnd;
   action->mData = mComposition.mString;
 
   Content& contentForTSF = ContentForTSFRef();
   if (!contentForTSF.IsInitialized()) {
     MOZ_LOG(sTextStoreLog, LogLevel::Error,
       ("0x%p   TSFTextStore::RecordCompositionEndAction() FAILED due "
--- a/widget/windows/TSFTextStore.h
+++ b/widget/windows/TSFTextStore.h
@@ -777,16 +777,27 @@ protected:
   void CompleteLastActionIfStillIncomplete()
   {
     if (!IsPendingCompositionUpdateIncomplete()) {
       return;
     }
     RecordCompositionUpdateAction();
   }
 
+  void RemoveLastCompositionUpdateActions()
+  {
+    while (!mPendingActions.IsEmpty()) {
+      const PendingAction& lastAction = mPendingActions.LastElement();
+      if (lastAction.mType != PendingAction::Type::eCompositionUpdate) {
+        break;
+      }
+      mPendingActions.RemoveLastElement();
+    }
+  }
+
   // When On*Composition() is called without document lock, we need to flush
   // the recorded actions at quitting the method.
   // AutoPendingActionAndContentFlusher class is usedful for it.
   class MOZ_STACK_CLASS AutoPendingActionAndContentFlusher final
   {
   public:
     explicit AutoPendingActionAndContentFlusher(TSFTextStore* aTextStore)
       : mTextStore(aTextStore)