Bug 1149189 - Add dummy text change when setting composition to the same text; r=esawin

This commit is contained in:
Jim Chen 2015-03-31 18:20:27 -04:00
parent a12a40c194
commit 60406e63b7
2 changed files with 47 additions and 31 deletions

View File

@ -1827,6 +1827,16 @@ nsWindow::OnIMEEvent(AndroidGeckoEvent *ae)
InitEvent(event, nullptr);
DispatchEvent(&event);
}
} else if (composition->String().Equals(ae->Characters())) {
/* If the new text is the same as the existing composition text,
* the NS_COMPOSITION_CHANGE event does not generate a text
* change notification. However, the Java side still expects
* one, so we manually generate a notification. */
IMEChange dummyChange;
dummyChange.mStart = ae->Start();
dummyChange.mOldEnd = dummyChange.mNewEnd = ae->End();
AddIMETextChange(dummyChange);
}
{
@ -2244,19 +2254,25 @@ nsWindow::NotifyIMEOfTextChange(const IMENotification& aIMENotification)
/* Make sure Java's selection is up-to-date */
mIMESelectionChanged = false;
NotifyIME(NOTIFY_IME_OF_SELECTION_CHANGE);
PostFlushIMEChanges();
mIMETextChanges.AppendElement(IMEChange(aIMENotification));
AddIMETextChange(IMEChange(aIMENotification));
PostFlushIMEChanges();
return NS_OK;
}
void
nsWindow::AddIMETextChange(const IMEChange& aChange) {
mIMETextChanges.AppendElement(aChange);
// Now that we added a new range we need to go back and
// update all the ranges before that.
// Ranges that have offsets which follow this new range
// need to be updated to reflect new offsets
int32_t delta = aIMENotification.mTextChangeData.AdditionalLength();
const int32_t delta = aChange.mNewEnd - aChange.mOldEnd;
for (int32_t i = mIMETextChanges.Length() - 2; i >= 0; i--) {
IMEChange &previousChange = mIMETextChanges[i];
if (previousChange.mStart >
static_cast<int32_t>(
aIMENotification.mTextChangeData.mOldEndOffset)) {
if (previousChange.mStart > aChange.mOldEnd) {
previousChange.mStart += delta;
previousChange.mOldEnd += delta;
previousChange.mNewEnd += delta;
@ -2304,7 +2320,6 @@ nsWindow::NotifyIMEOfTextChange(const IMENotification& aIMENotification)
// so we can safely continue the merge starting at dst
srcIndex = dstIndex;
}
return NS_OK;
}
nsIMEUpdatePreference

View File

@ -170,8 +170,33 @@ protected:
nsWindow *FindTopLevel();
bool IsTopLevel();
struct IMEChange {
int32_t mStart, mOldEnd, mNewEnd;
IMEChange() :
mStart(-1), mOldEnd(-1), mNewEnd(-1)
{
}
IMEChange(const IMENotification& aIMENotification)
: mStart(aIMENotification.mTextChangeData.mStartOffset)
, mOldEnd(aIMENotification.mTextChangeData.mOldEndOffset)
, mNewEnd(aIMENotification.mTextChangeData.mNewEndOffset)
{
MOZ_ASSERT(aIMENotification.mMessage ==
mozilla::widget::NOTIFY_IME_OF_TEXT_CHANGE,
"IMEChange initialized with wrong notification");
MOZ_ASSERT(aIMENotification.mTextChangeData.IsInInt32Range(),
"The text change notification is out of range");
}
bool IsEmpty() const
{
return mStart < 0;
}
};
nsRefPtr<mozilla::TextComposition> GetIMEComposition();
void RemoveIMEComposition();
void AddIMETextChange(const IMEChange& aChange);
void PostFlushIMEChanges();
void FlushIMEChanges();
@ -197,30 +222,6 @@ protected:
nsRefPtr<mozilla::TextRangeArray> mIMERanges;
bool mIMEUpdatingContext;
nsAutoTArray<mozilla::AndroidGeckoEvent, 8> mIMEKeyEvents;
struct IMEChange {
int32_t mStart, mOldEnd, mNewEnd;
IMEChange() :
mStart(-1), mOldEnd(-1), mNewEnd(-1)
{
}
IMEChange(const IMENotification& aIMENotification)
: mStart(aIMENotification.mTextChangeData.mStartOffset)
, mOldEnd(aIMENotification.mTextChangeData.mOldEndOffset)
, mNewEnd(aIMENotification.mTextChangeData.mNewEndOffset)
{
MOZ_ASSERT(aIMENotification.mMessage ==
mozilla::widget::NOTIFY_IME_OF_TEXT_CHANGE,
"IMEChange initialized with wrong notification");
MOZ_ASSERT(aIMENotification.mTextChangeData.IsInInt32Range(),
"The text change notification is out of range");
}
bool IsEmpty()
{
return mStart < 0;
}
};
nsAutoTArray<IMEChange, 4> mIMETextChanges;
bool mIMESelectionChanged;