зеркало из https://github.com/mozilla/gecko-dev.git
Bug 961703 Commit or cancel composition when text/selection/focus is changed during composition for avoiding making some TIPs confused r=m_kato
This commit is contained in:
Родитель
f4da7ac2d5
Коммит
d50712b914
|
@ -678,7 +678,15 @@ bool
|
||||||
nsTextStore::Destroy(void)
|
nsTextStore::Destroy(void)
|
||||||
{
|
{
|
||||||
PR_LOG(sTextStoreLog, PR_LOG_ALWAYS,
|
PR_LOG(sTextStoreLog, PR_LOG_ALWAYS,
|
||||||
("TSF: 0x%p nsTextStore::Destroy()", this));
|
("TSF: 0x%p nsTextStore::Destroy(), mComposition.IsComposing()=%s",
|
||||||
|
this, GetBoolName(mComposition.IsComposing())));
|
||||||
|
|
||||||
|
// If there is composition, TSF keeps the composition even after the text
|
||||||
|
// store destroyed. So, we should clear the composition here.
|
||||||
|
if (mComposition.IsComposing()) {
|
||||||
|
NS_WARNING("Composition is still alive at destroying the text store");
|
||||||
|
CommitCompositionInternal(false);
|
||||||
|
}
|
||||||
|
|
||||||
mContent.Clear();
|
mContent.Clear();
|
||||||
mSelection.MarkDirty();
|
mSelection.MarkDirty();
|
||||||
|
@ -3065,18 +3073,22 @@ nsTextStore::OnTextChangeInternal(uint32_t aStart,
|
||||||
{
|
{
|
||||||
PR_LOG(sTextStoreLog, PR_LOG_DEBUG,
|
PR_LOG(sTextStoreLog, PR_LOG_DEBUG,
|
||||||
("TSF: 0x%p nsTextStore::OnTextChangeInternal(aStart=%lu, "
|
("TSF: 0x%p nsTextStore::OnTextChangeInternal(aStart=%lu, "
|
||||||
"aOldEnd=%lu, aNewEnd=%lu), mSink=0x%p, mSinkMask=%s",
|
"aOldEnd=%lu, aNewEnd=%lu), mSink=0x%p, mSinkMask=%s, "
|
||||||
|
"mComposition.IsComposing()=%s",
|
||||||
this, aStart, aOldEnd, aNewEnd, mSink.get(),
|
this, aStart, aOldEnd, aNewEnd, mSink.get(),
|
||||||
GetSinkMaskNameStr(mSinkMask).get()));
|
GetSinkMaskNameStr(mSinkMask).get(),
|
||||||
|
GetBoolName(mComposition.IsComposing())));
|
||||||
|
|
||||||
if (IsReadLocked()) {
|
if (IsReadLocked()) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_ASSERTION(!mComposition.IsComposing(), "text changed during composition");
|
|
||||||
mSelection.MarkDirty();
|
mSelection.MarkDirty();
|
||||||
|
|
||||||
if (mSink && 0 != (mSinkMask & TS_AS_TEXT_CHANGE)) {
|
if (!mSink || !(mSinkMask & TS_AS_TEXT_CHANGE)) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
if (aStart >= INT32_MAX || aOldEnd >= INT32_MAX || aNewEnd >= INT32_MAX) {
|
if (aStart >= INT32_MAX || aOldEnd >= INT32_MAX || aNewEnd >= INT32_MAX) {
|
||||||
PR_LOG(sTextStoreLog, PR_LOG_ERROR,
|
PR_LOG(sTextStoreLog, PR_LOG_ERROR,
|
||||||
("TSF: 0x%p nsTextStore::OnTextChangeInternal() FAILED due to "
|
("TSF: 0x%p nsTextStore::OnTextChangeInternal() FAILED due to "
|
||||||
|
@ -3085,6 +3097,18 @@ nsTextStore::OnTextChangeInternal(uint32_t aStart,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Some TIPs are confused by text change notification during composition.
|
||||||
|
// Especially, some of them stop working for composition in our process.
|
||||||
|
// For preventing it, let's commit the composition.
|
||||||
|
if (mComposition.IsComposing()) {
|
||||||
|
PR_LOG(sTextStoreLog, PR_LOG_ALWAYS,
|
||||||
|
("TSF: 0x%p nsTextStore::OnTextChangeInternal(), "
|
||||||
|
"committing the composition for avoiding making TIP confused...",
|
||||||
|
this));
|
||||||
|
CommitCompositionInternal(false);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
TS_TEXTCHANGE textChange;
|
TS_TEXTCHANGE textChange;
|
||||||
textChange.acpStart = static_cast<LONG>(aStart);
|
textChange.acpStart = static_cast<LONG>(aStart);
|
||||||
textChange.acpOldEnd = static_cast<LONG>(aOldEnd);
|
textChange.acpOldEnd = static_cast<LONG>(aOldEnd);
|
||||||
|
@ -3096,7 +3120,7 @@ nsTextStore::OnTextChangeInternal(uint32_t aStart,
|
||||||
"acpNewEnd=%ld })...", this, textChange.acpStart,
|
"acpNewEnd=%ld })...", this, textChange.acpStart,
|
||||||
textChange.acpOldEnd, textChange.acpNewEnd));
|
textChange.acpOldEnd, textChange.acpNewEnd));
|
||||||
mSink->OnTextChange(0, &textChange);
|
mSink->OnTextChange(0, &textChange);
|
||||||
}
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3105,28 +3129,45 @@ nsTextStore::OnSelectionChangeInternal(void)
|
||||||
{
|
{
|
||||||
PR_LOG(sTextStoreLog, PR_LOG_DEBUG,
|
PR_LOG(sTextStoreLog, PR_LOG_DEBUG,
|
||||||
("TSF: 0x%p nsTextStore::OnSelectionChangeInternal(), "
|
("TSF: 0x%p nsTextStore::OnSelectionChangeInternal(), "
|
||||||
"mSink=0x%p, mSinkMask=%s, mIsRecordingActionsWithoutLock=%s",
|
"mSink=0x%p, mSinkMask=%s, mIsRecordingActionsWithoutLock=%s, "
|
||||||
|
"mComposition.IsComposing()=%s",
|
||||||
this, mSink.get(), GetSinkMaskNameStr(mSinkMask).get(),
|
this, mSink.get(), GetSinkMaskNameStr(mSinkMask).get(),
|
||||||
GetBoolName(mIsRecordingActionsWithoutLock)));
|
GetBoolName(mIsRecordingActionsWithoutLock),
|
||||||
|
GetBoolName(mComposition.IsComposing())));
|
||||||
|
|
||||||
if (IsReadLocked()) {
|
if (IsReadLocked()) {
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_ASSERTION(!mComposition.IsComposing(),
|
|
||||||
"selection changed during composition");
|
|
||||||
mSelection.MarkDirty();
|
mSelection.MarkDirty();
|
||||||
|
|
||||||
if (mSink && 0 != (mSinkMask & TS_AS_SEL_CHANGE)) {
|
if (!mSink || !(mSinkMask & TS_AS_SEL_CHANGE)) {
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Some TIPs are confused by selection change notification during composition.
|
||||||
|
// Especially, some of them stop working for composition in our process.
|
||||||
|
// For preventing it, let's commit the composition.
|
||||||
|
if (mComposition.IsComposing()) {
|
||||||
|
PR_LOG(sTextStoreLog, PR_LOG_ALWAYS,
|
||||||
|
("TSF: 0x%p nsTextStore::OnSelectionChangeInternal(), "
|
||||||
|
"committing the composition for avoiding making TIP confused...",
|
||||||
|
this));
|
||||||
|
CommitCompositionInternal(false);
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mIsRecordingActionsWithoutLock) {
|
||||||
PR_LOG(sTextStoreLog, PR_LOG_ALWAYS,
|
PR_LOG(sTextStoreLog, PR_LOG_ALWAYS,
|
||||||
("TSF: 0x%p nsTextStore::OnSelectionChangeInternal(), calling "
|
("TSF: 0x%p nsTextStore::OnSelectionChangeInternal(), calling "
|
||||||
"mSink->OnSelectionChange()...", this));
|
"mSink->OnSelectionChange()...", this));
|
||||||
if (!mIsRecordingActionsWithoutLock) {
|
|
||||||
mSink->OnSelectionChange();
|
mSink->OnSelectionChange();
|
||||||
} else {
|
} else {
|
||||||
|
PR_LOG(sTextStoreLog, PR_LOG_ALWAYS,
|
||||||
|
("TSF: 0x%p nsTextStore::OnSelectionChangeInternal(), pending "
|
||||||
|
"a call of mSink->OnSelectionChange()...", this));
|
||||||
mNotifySelectionChange = true;
|
mNotifySelectionChange = true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче