--- 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