Bug 1422230 - part 3: TSFTextStore should store composition string information until both TSF/TIP and our content finish handling composition r=m_kato
authorMasayuki Nakano <masayuki@d-toybox.com>
Fri, 12 Jan 2018 15:23:43 +0900
changeset 399276 d02c066d501be954cd60ea4b20b5ed291cd6b938
parent 399275 9aa31af5773b97fdcc06a1f4da8830be7ff096bd
child 399277 3700de32eedbe6670085841c3a36fe091f7a1543
push id58050
push usermasayuki@d-toybox.com
push dateMon, 15 Jan 2018 07:16:33 +0000
treeherderautoland@3700de32eedb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersm_kato
bugs1422230
milestone59.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 1422230 - part 3: TSFTextStore should store composition string information until both TSF/TIP and our content finish handling composition r=m_kato If remote process hasn't handled dispatched commit event yet, TSFTextStore needs to dispatch query content event relative to latest composition string information. So, TSFTextStore::mContentForTSF should cache composition start and composition string length until pending composition events are handled by content actually. MozReview-Commit-ID: ARM851nNZGz
widget/windows/TSFTextStore.cpp
widget/windows/TSFTextStore.h
--- a/widget/windows/TSFTextStore.cpp
+++ b/widget/windows/TSFTextStore.cpp
@@ -6805,16 +6805,17 @@ TSFTextStore::Content::ReplaceTextWith(L
       } else if (mMinTextModifiedOffset >=
                    static_cast<uint32_t>(mComposition.mStart) &&
                  mMinTextModifiedOffset <
                    static_cast<uint32_t>(mComposition.EndOffset())) {
         // The previous change to the composition string is canceled.
         mMinTextModifiedOffset = firstDifferentOffset =
           mComposition.EndOffset();
       }
+      mLatestCompositionEndOffset = mComposition.EndOffset();
       MOZ_LOG(sTextStoreLog, LogLevel::Debug,
         ("0x%p   TSFTextStore::Content::ReplaceTextWith(aStart=%d, "
          "aLength=%d, aReplaceString=\"%s\"), mComposition={ mStart=%d, "
          "mString=\"%s\" }, mLastCompositionString=\"%s\", "
          "mMinTextModifiedOffset=%u, firstDifferentOffset=%u",
          this, aStart, aLength, GetEscapedUTF8String(aReplaceString).get(),
          mComposition.mStart, GetEscapedUTF8String(mComposition.mString).get(),
          GetEscapedUTF8String(mLastCompositionString).get(),
@@ -6842,16 +6843,18 @@ TSFTextStore::Content::StartComposition(
   MOZ_ASSERT(mInitialized);
   MOZ_ASSERT(aCompositionView);
   MOZ_ASSERT(!mComposition.mView);
   MOZ_ASSERT(aCompStart.mType == PendingAction::COMPOSITION_START);
 
   mComposition.Start(aCompositionView, aCompStart.mSelectionStart,
     GetSubstring(static_cast<uint32_t>(aCompStart.mSelectionStart),
                  static_cast<uint32_t>(aCompStart.mSelectionLength)));
+  mLatestCompositionStartOffset = mComposition.mStart;
+  mLatestCompositionEndOffset = mComposition.EndOffset();
   if (!aPreserveSelection) {
     // XXX Do we need to set a new writing-mode here when setting a new
     // selection? Currently, we just preserve the existing value.
     mSelection.SetSelection(mComposition.mStart, mComposition.mString.Length(),
                             false, mSelection.GetWritingMode());
   }
 }
 
@@ -6872,16 +6875,18 @@ TSFTextStore::Content::RestoreCommittedC
                static_cast<uint32_t>(aPendingCompositionStart.mSelectionStart),
                static_cast<uint32_t>(aCanceledCompositionEnd.mData.Length())) ==
                aCanceledCompositionEnd.mData);
 
   // Restore the committed string as composing string.
   mComposition.Start(aCompositionView,
                      aPendingCompositionStart.mSelectionStart,
                      aCanceledCompositionEnd.mData);
+  mLatestCompositionStartOffset = mComposition.mStart;
+  mLatestCompositionEndOffset = mComposition.EndOffset();
 }
 
 void
 TSFTextStore::Content::EndComposition(const PendingAction& aCompEnd)
 {
   MOZ_ASSERT(mInitialized);
   MOZ_ASSERT(mComposition.mView);
   MOZ_ASSERT(aCompEnd.mType == PendingAction::COMPOSITION_END);
--- a/widget/windows/TSFTextStore.h
+++ b/widget/windows/TSFTextStore.h
@@ -794,16 +794,17 @@ protected:
     {
       mText = aText;
       if (mComposition.IsComposing()) {
         mLastCompositionString = mComposition.mString;
       } else {
         mLastCompositionString.Truncate();
       }
       mMinTextModifiedOffset = NOT_MODIFIED;
+      mLatestCompositionStartOffset = mLatestCompositionEndOffset = LONG_MAX;
       mInitialized = true;
     }
 
     void OnLayoutChanged()
     {
       mMinTextModifiedOffset = NOT_MODIFIED;
     }
 
@@ -845,16 +846,28 @@ protected:
       MOZ_ASSERT(mInitialized);
       return mLastCompositionString;
     }
     uint32_t MinTextModifiedOffset() const
     {
       MOZ_ASSERT(mInitialized);
       return mMinTextModifiedOffset;
     }
+    LONG LatestCompositionStartOffset() const
+    {
+      MOZ_ASSERT(mInitialized);
+      MOZ_ASSERT(HasOrHadComposition());
+      return mLatestCompositionStartOffset;
+    }
+    LONG LatestCompositionEndOffset() const
+    {
+      MOZ_ASSERT(mInitialized);
+      MOZ_ASSERT(HasOrHadComposition());
+      return mLatestCompositionEndOffset;
+    }
 
     // Returns true if layout of the character at the aOffset has not been
     // calculated.
     bool IsLayoutChangedAt(uint32_t aOffset) const
     {
       return IsLayoutChanged() && (mMinTextModifiedOffset <= aOffset);
     }
     // Returns true if layout of the content has been changed, i.e., the new
@@ -864,27 +877,39 @@ protected:
       return mInitialized && (mMinTextModifiedOffset != NOT_MODIFIED);
     }
     // Returns minimum offset of modified text range.
     uint32_t MinOffsetOfLayoutChanged() const
     {
       return mInitialized ? mMinTextModifiedOffset : NOT_MODIFIED;
     }
 
+    bool HasOrHadComposition() const
+    {
+      return mInitialized &&
+             mLatestCompositionStartOffset != LONG_MAX &&
+             mLatestCompositionEndOffset != LONG_MAX;
+    }
+
     TSFTextStore::Composition& Composition() { return mComposition; }
     TSFTextStore::Selection& Selection() { return mSelection; }
 
   private:
     nsString mText;
     // mLastCompositionString stores the composition string when the document
     // is locked. This is necessary to compute mMinTextModifiedOffset.
     nsString mLastCompositionString;
     TSFTextStore::Composition& mComposition;
     TSFTextStore::Selection& mSelection;
 
+    // The latest composition's start and end offset.  If composition hasn't
+    // been started since this instance is initialized, they are LONG_MAX.
+    LONG mLatestCompositionStartOffset;
+    LONG mLatestCompositionEndOffset;
+
     // The minimum offset of modified part of the text.
     enum : uint32_t
     {
       NOT_MODIFIED = UINT32_MAX
     };
     uint32_t mMinTextModifiedOffset;
 
     bool mInitialized;