Bug 1304620 part.4 ContentCacheInParent::mCompositionStart should be set to better value for mWidgetHasComposition state r?m_kato
ContentCacheInParent::mCompositionStart was set to ContentCacheInChild::mCompositionStart without any check. However, that's clearly wrong approach. For example, when the remote process handles some composition events after eCompositionCommit(AsIs) in the parent process, mCompositionStart is valid offset even after mWidgetHasComposition is set to false. Similarly, even after parent process sends eCompositionStart, the remote process may send invalid offset for mCompositionStart due to no composition in it.
For solving this issue, ContentCacheInParent should check mWidgetHasComposition.
If it's true and coming offset is valid, let's use it (even if mPendingCompositionCount is 2 or bigger since widget shouldn't use WidgetQueryContentEvent when there are some pending events).
If the coming offset is invalid but mWidgetHasComposition is false, let's use selection start instead because HandleQueryContentEvent() can work around selection start offset only.
Otherwise, i.e., mWidgetHasComposition is false, we should always set mCompositionStart to invalid offset.
MozReview-Commit-ID: IONU0Cbhpil
--- a/widget/ContentCache.cpp
+++ b/widget/ContentCache.cpp
@@ -515,32 +515,48 @@ ContentCacheInParent::ContentCacheInPare
{
}
void
ContentCacheInParent::AssignContent(const ContentCache& aOther,
nsIWidget* aWidget,
const IMENotification* aNotification)
{
- mCompositionStart = aOther.mCompositionStart;
mText = aOther.mText;
mSelection = aOther.mSelection;
mFirstCharRect = aOther.mFirstCharRect;
mCaret = aOther.mCaret;
mTextRectArray = aOther.mTextRectArray;
mEditorRect = aOther.mEditorRect;
// 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).
+ if (mWidgetHasComposition) {
+ if (aOther.mCompositionStart != UINT32_MAX) {
+ mCompositionStart = aOther.mCompositionStart;
+ } else {
+ mCompositionStart = mSelection.StartOffset();
+ NS_WARNING_ASSERTION(mCompositionStart != UINT32_MAX,
+ "mCompositionStart shouldn't be invalid offset when "
+ "the widget has composition");
+ }
+ } else {
+ mCompositionStart = UINT32_MAX;
+ }
+
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 }, "
"mFirstCharRect=%s, mCaret={ mOffset=%u, mRect=%s }, mTextRectArray={ "
"mStart=%u, mRects.Length()=%u }, mWidgetHasComposition=%s, "