Bug 1422230 - part 3: TSFTextStore should store composition string information until both TSF/TIP and our content finish handling composition r?m_kato draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Fri, 12 Jan 2018 15:23:43 +0900
changeset 719987 bab5a287202d52da592c65aecd87ed8bbd359a2b
parent 719986 fc14cdbc39b5f87d5ad808f4178fca649ed30ffe
child 719988 319e641c3efdf660190b4888c846873ba96a5ef2
push id95417
push usermasayuki@d-toybox.com
push dateSat, 13 Jan 2018 00:49:22 +0000
reviewersm_kato
bugs1422230
milestone59.0a1
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;