Bug 1422230 - part 2: ContentCacheInParent should allow to query content relative to composition string even after sending eCompositionCommit(AsIs) event but not yet handled in the remote process r?m_kato draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Fri, 12 Jan 2018 15:05:24 +0900
changeset 719986 fc14cdbc39b5f87d5ad808f4178fca649ed30ffe
parent 719985 d1e2e27dc01b3e7d4482663638958ee078933f07
child 719987 bab5a287202d52da592c65aecd87ed8bbd359a2b
push id95417
push usermasayuki@d-toybox.com
push dateSat, 13 Jan 2018 00:49:22 +0000
reviewersm_kato
bugs1422230
milestone59.0a1
Bug 1422230 - part 2: ContentCacheInParent should allow to query content relative to composition string even after sending eCompositionCommit(AsIs) event but not yet handled in the remote process r?m_kato Currently, ContentCacheInParent uses selection when it handles query content event whose input offset is relative one after sending eCompositionCommit(AsIs) event but it's not yet handled by the remote process. However, in this case, selection may not be modified with committed string. So, when mPendingCommitCount is not 0, ContentCacheInParent should compute absolute offset with the latest composition string information. For doing this, it needs to keep storing mCompositionStart until eCompositionCommit(AsIs) is handled in the remote process actually. MozReview-Commit-ID: 2Dc69HNIbvh
widget/ContentCache.cpp
--- a/widget/ContentCache.cpp
+++ b/widget/ContentCache.cpp
@@ -543,37 +543,34 @@ ContentCacheInParent::AssignContent(cons
   // Only when there is one composition, the TextComposition instance in this
   // process is managing the composition in the remote process.  Therefore,
   // we shouldn't update composition start offset of TextComposition with
   // old composition which is still being handled by the child process.
   if (mWidgetHasComposition && mPendingCompositionCount == 1) {
     IMEStateManager::MaybeStartOffsetUpdatedInChild(aWidget, mCompositionStart);
   }
 
-  // When the widget has composition, we should set mCompositionStart to
-  // *current* composition start offset.  Note that, in strictly speaking,
-  // widget should not use WidgetQueryContentEvent if there are some pending
-  // compositions (i.e., when mPendingCompositionCount is 2 or more).
+  // When this instance allows to query content relative to composition string,
+  // we should modify mCompositionStart with the latest information in the
+  // remote process because now we have the information around the composition
+  // string.
   mCompositionStartInChild = aOther.mCompositionStart;
-  if (mWidgetHasComposition) {
+  if (mWidgetHasComposition || mPendingCommitCount) {
     if (aOther.mCompositionStart != UINT32_MAX) {
       if (mCompositionStart != aOther.mCompositionStart) {
         mCompositionStart = aOther.mCompositionStart;
         mPendingCommitLength = 0;
       }
     } else if (mCompositionStart != mSelection.StartOffset()) {
       mCompositionStart = mSelection.StartOffset();
       mPendingCommitLength = 0;
       NS_WARNING_ASSERTION(mCompositionStart != UINT32_MAX,
                            "mCompositionStart shouldn't be invalid offset when "
                            "the widget has composition");
     }
-  } else if (mCompositionStart != UINT32_MAX) {
-    mCompositionStart = UINT32_MAX;
-    mPendingCommitLength = 0;
   }
 
   MOZ_LOG(sContentCacheLog, LogLevel::Info,
     ("0x%p AssignContent(aNotification=%s), "
      "Succeeded, mText.Length()=%u, mSelection={ mAnchor=%u, mFocus=%u, "
      "mWritingMode=%s, mAnchorCharRects[eNextCharRect]=%s, "
      "mAnchorCharRects[ePrevCharRect]=%s, mFocusCharRects[eNextCharRect]=%s, "
      "mFocusCharRects[ePrevCharRect]=%s, mRect=%s }, "
@@ -635,17 +632,17 @@ ContentCacheInParent::HandleQueryContent
         MOZ_LOG(sContentCacheLog, LogLevel::Error,
           ("0x%p HandleQueryContentEvent(), FAILED due to "
            "aEvent.mInput.MakeOffsetAbsolute(0) failure, aEvent={ mMessage=%s, "
            "mInput={ mOffset=%" PRId64 ", mLength=%" PRIu32 " } }",
            this, ToChar(aEvent.mMessage), aEvent.mInput.mOffset,
            aEvent.mInput.mLength));
         return false;
       }
-    } else if (mWidgetHasComposition) {
+    } else if (mWidgetHasComposition || mPendingCommitCount) {
       if (NS_WARN_IF(!aEvent.mInput.MakeOffsetAbsolute(
                                       mCompositionStart +
                                         mPendingCommitLength))) {
         MOZ_LOG(sContentCacheLog, LogLevel::Error,
           ("0x%p HandleQueryContentEvent(), FAILED due to "
            "aEvent.mInput.MakeOffsetAbsolute(mCompositionStart + "
            "mPendingCommitLength) failure, "
            "mCompositionStart=%" PRIu32 ", mPendingCommitLength=%" PRIu32 ", "
@@ -1137,17 +1134,18 @@ ContentCacheInParent::OnCompositionEvent
     MOZ_ASSERT(aEvent.mMessage == eCompositionStart);
     MOZ_RELEASE_ASSERT(mPendingCompositionCount < UINT8_MAX);
     mPendingCompositionCount++;
   }
 
   mWidgetHasComposition = !aEvent.CausesDOMCompositionEndEvent();
 
   if (!mWidgetHasComposition) {
-    mCompositionStart = UINT32_MAX;
+    // mCompositionStart will be reset when commit event is completely handled
+    // in the remote process.
     if (mPendingCompositionCount == 1) {
       mPendingCommitLength = aEvent.mData.Length();
     }
     mPendingCommitCount++;
   } else if (aEvent.mMessage != eCompositionStart) {
     mCompositionString = aEvent.mData;
   }
 
@@ -1212,21 +1210,21 @@ ContentCacheInParent::OnEventNeedingAckH
                                                 EventMessage aMessage)
 {
   // This is called when the child process receives WidgetCompositionEvent or
   // WidgetSelectionEvent.
 
   MOZ_LOG(sContentCacheLog, LogLevel::Info,
     ("0x%p OnEventNeedingAckHandled(aWidget=0x%p, "
      "aMessage=%s), mPendingEventsNeedingAck=%u, "
-     "mPendingCompositionCount=%" PRIu8 ", mPendingCommitCount=%" PRIu8 ", "
-     "mIsChildIgnoringCompositionEvents=%s",
+     "mWidgetHasComposition=%s, mPendingCompositionCount=%" PRIu8 ", "
+     "mPendingCommitCount=%" PRIu8 ", mIsChildIgnoringCompositionEvents=%s",
      this, aWidget, ToChar(aMessage), mPendingEventsNeedingAck,
-     mPendingCompositionCount, mPendingCommitCount,
-     GetBoolName(mIsChildIgnoringCompositionEvents)));
+     GetBoolName(mWidgetHasComposition), mPendingCompositionCount,
+     mPendingCommitCount, GetBoolName(mIsChildIgnoringCompositionEvents)));
 
 #if MOZ_DIAGNOSTIC_ASSERT_ENABLED
   mReceivedEventMessages.AppendElement(aMessage);
 #endif // #if MOZ_DIAGNOSTIC_ASSERT_ENABLED
 
   bool isCommittedInChild =
     // Commit requester in the remote process has committed the composition.
     aMessage == eCompositionCommitRequestHandled ||
@@ -1297,16 +1295,23 @@ ContentCacheInParent::OnEventNeedingAckH
              mPendingCommitCount) {
     // If the remote process commits composition synchronously after
     // requesting commit composition and we've already sent commit composition,
     // it starts to ignore following composition events until receiving
     // eCompositionStart event.
     mIsChildIgnoringCompositionEvents = true;
   }
 
+  // If neither widget (i.e., IME) nor the remote process has composition,
+  // now, we can forget composition string informations.
+  if (!mWidgetHasComposition &&
+      !mPendingCompositionCount && !mPendingCommitCount) {
+    mCompositionStart = UINT32_MAX;
+  }
+
   if (NS_WARN_IF(!mPendingEventsNeedingAck)) {
 #if MOZ_DIAGNOSTIC_ASSERT_ENABLED
     nsPrintfCString info("\nThere is no pending events but received %s "
                          "message from the remote child\n\n",
                          ToChar(aMessage));
     AppendEventMessageLog(info);
     CrashReporter::AppendAppNotesToCrashReport(info);
 #endif // #if MOZ_DIAGNOSTIC_ASSERT_ENABLED