Bug 1237216 TSFTextStore should forget redundant pending composition events for Korean TIPs r=emk
authorMasayuki Nakano <masayuki@d-toybox.com>
Mon, 18 Jan 2016 16:29:02 +0900
changeset 280376 73c6bdc7aa58f9139eb2d72377cffb56ad461f83
parent 280375 bbbedf2904265027f7406f2c4935518b7c863765
child 280377 d1dbf56316c794b6bf7496b8032a4ef693a5dbdb
push id19349
push usercbook@mozilla.com
push dateMon, 18 Jan 2016 13:25:30 +0000
treeherderb2g-inbound@fe695f1bc418 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersemk
bugs1237216
milestone46.0a1
Bug 1237216 TSFTextStore should forget redundant pending composition events for Korean TIPs r=emk
widget/windows/TSFTextStore.cpp
widget/windows/TSFTextStore.h
--- a/widget/windows/TSFTextStore.cpp
+++ b/widget/windows/TSFTextStore.cpp
@@ -4094,16 +4094,17 @@ TSFTextStore::RecordCompositionStartActi
     // We shouldn't dispatch selection set event before dispatching
     // compositionstart event because it may cause put caret different
     // position in HTML editor since generated flat text content and offset in
     // it are lossy data of HTML contents.
     action->mAdjustSelection = false;
   }
 
   lockedContent.StartComposition(aComposition, *action, aPreserveSelection);
+  action->mData = mComposition.mString;
 
   MOZ_LOG(sTextStoreLog, LogLevel::Info,
          ("TSF: 0x%p   TSFTextStore::RecordCompositionStartAction() succeeded: "
           "mComposition={ mStart=%ld, mString.Length()=%ld, "
           "mSelection={ acpStart=%ld, acpEnd=%ld, style.ase=%s, "
           "style.fInterimChar=%s } }",
           this, mComposition.mStart, mComposition.mString.Length(),
           mSelection.StartOffset(), mSelection.EndOffset(),
@@ -4132,16 +4133,43 @@ TSFTextStore::RecordCompositionEndAction
   if (!lockedContent.IsInitialized()) {
     MOZ_LOG(sTextStoreLog, LogLevel::Error,
            ("TSF: 0x%p   TSFTextStore::RecordCompositionEndAction() FAILED due "
             "to LockedContent() failure", this));
     return E_FAIL;
   }
   lockedContent.EndComposition(*action);
 
+  // If this composition was restart but the composition doesn't modify
+  // anything, we should remove the pending composition for preventing to
+  // dispatch redundant composition events.
+  for (size_t i = mPendingActions.Length(), j = 1; i > 0; --i, ++j) {
+    PendingAction& pendingAction = mPendingActions[i - 1];
+    if (pendingAction.mType == PendingAction::COMPOSITION_START) {
+      if (pendingAction.mData != action->mData) {
+        break;
+      }
+      // When only setting selection is necessary, we should append it.
+      if (pendingAction.mAdjustSelection) {
+        PendingAction* setSelection = mPendingActions.AppendElement();
+        setSelection->mType = PendingAction::SET_SELECTION;
+        setSelection->mSelectionStart = pendingAction.mSelectionStart;
+        setSelection->mSelectionLength = pendingAction.mSelectionLength;
+        setSelection->mSelectionReversed = false;
+      }
+      // Remove the redundant pending composition.
+      mPendingActions.RemoveElementsAt(i - 1, j);
+      MOZ_LOG(sTextStoreLog, LogLevel::Info,
+             ("TSF: 0x%p   TSFTextStore::RecordCompositionEndAction(), "
+              "succeeded, but the composition was canceled due to redundant",
+              this));
+      return S_OK;
+    }
+  }
+
   MOZ_LOG(sTextStoreLog, LogLevel::Info,
          ("TSF: 0x%p   TSFTextStore::RecordCompositionEndAction(), succeeded",
           this));
   return S_OK;
 }
 
 STDMETHODIMP
 TSFTextStore::OnStartComposition(ITfCompositionView* pComposition,
--- a/widget/windows/TSFTextStore.h
+++ b/widget/windows/TSFTextStore.h
@@ -513,17 +513,17 @@ protected:
       COMPOSITION_UPDATE,
       COMPOSITION_END,
       SET_SELECTION
     };
     ActionType mType;
     // For compositionstart and selectionset
     LONG mSelectionStart;
     LONG mSelectionLength;
-    // For compositionupdate and compositionend
+    // For compositionstart, compositionupdate and compositionend
     nsString mData;
     // For compositionupdate
     RefPtr<TextRangeArray> mRanges;
     // For selectionset
     bool mSelectionReversed;
     // For compositionupdate
     bool mIncomplete;
     // For compositionstart