mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 13:51:41 +00:00
Bug 974318 part.5 Use WidgetTextEvent::mRanges on Windows r=jimm
This commit is contained in:
parent
3d4f34f6ad
commit
73c72bc5e4
@ -1610,15 +1610,10 @@ nsIMM32Handler::DispatchTextEvent(nsWindow* aWindow,
|
||||
|
||||
aWindow->InitEvent(event, &point);
|
||||
|
||||
nsAutoTArray<TextRange, 4> textRanges;
|
||||
|
||||
if (aCheckAttr) {
|
||||
SetTextRangeList(textRanges);
|
||||
event.mRanges = CreateTextRangeArray();
|
||||
}
|
||||
|
||||
event.rangeCount = textRanges.Length();
|
||||
event.rangeArray = textRanges.Elements();
|
||||
|
||||
event.theText = mCompositionString.get();
|
||||
|
||||
aWindow->DispatchWindowEvent(&event);
|
||||
@ -1628,15 +1623,17 @@ nsIMM32Handler::DispatchTextEvent(nsWindow* aWindow,
|
||||
// it will call SetIMERelatedWindowsPos.
|
||||
}
|
||||
|
||||
void
|
||||
nsIMM32Handler::SetTextRangeList(nsTArray<TextRange> &aTextRangeList)
|
||||
already_AddRefed<TextRangeArray>
|
||||
nsIMM32Handler::CreateTextRangeArray()
|
||||
{
|
||||
// Sogou (Simplified Chinese IME) returns contradictory values: The cursor
|
||||
// position is actual cursor position. However, other values (composition
|
||||
// string and attributes) are empty. So, if you want to remove following
|
||||
// assertion, be careful.
|
||||
NS_ASSERTION(ShouldDrawCompositionStringOurselves(),
|
||||
"SetTextRangeList is called when we don't need to fire text event");
|
||||
"CreateTextRangeArray is called when we don't need to fire text event");
|
||||
|
||||
nsRefPtr<TextRangeArray> textRangeArray = new TextRangeArray();
|
||||
|
||||
TextRange range;
|
||||
if (mClauseArray.Length() == 0) {
|
||||
@ -1645,10 +1642,10 @@ nsIMM32Handler::SetTextRangeList(nsTArray<TextRange> &aTextRangeList)
|
||||
range.mStartOffset = 0;
|
||||
range.mEndOffset = mCompositionString.Length();
|
||||
range.mRangeType = NS_TEXTRANGE_RAWINPUT;
|
||||
aTextRangeList.AppendElement(range);
|
||||
textRangeArray->AppendElement(range);
|
||||
|
||||
PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
|
||||
("IMM32: SetTextRangeList, mClauseLength=0\n"));
|
||||
("IMM32: CreateTextRangeArray, mClauseLength=0\n"));
|
||||
} else {
|
||||
// iterate over the attributes
|
||||
uint32_t lastOffset = 0;
|
||||
@ -1656,7 +1653,8 @@ nsIMM32Handler::SetTextRangeList(nsTArray<TextRange> &aTextRangeList)
|
||||
uint32_t current = mClauseArray[i + 1];
|
||||
if (current > mCompositionString.Length()) {
|
||||
PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
|
||||
("IMM32: SetTextRangeList, mClauseArray[%ld]=%lu. This is larger than mCompositionString.Length()=%lu\n",
|
||||
("IMM32: CreateTextRangeArray, mClauseArray[%ld]=%lu. "
|
||||
"This is larger than mCompositionString.Length()=%lu\n",
|
||||
i + 1, current, mCompositionString.Length()));
|
||||
current = int32_t(mCompositionString.Length());
|
||||
}
|
||||
@ -1664,12 +1662,12 @@ nsIMM32Handler::SetTextRangeList(nsTArray<TextRange> &aTextRangeList)
|
||||
range.mRangeType = PlatformToNSAttr(mAttributeArray[lastOffset]);
|
||||
range.mStartOffset = lastOffset;
|
||||
range.mEndOffset = current;
|
||||
aTextRangeList.AppendElement(range);
|
||||
textRangeArray->AppendElement(range);
|
||||
|
||||
lastOffset = current;
|
||||
|
||||
PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
|
||||
("IMM32: SetTextRangeList, index=%ld, rangeType=%s, range=[%lu-%lu]\n",
|
||||
("IMM32: CreateTextRangeArray, index=%ld, rangeType=%s, range=[%lu-%lu]\n",
|
||||
i, GetRangeTypeName(range.mRangeType), range.mStartOffset,
|
||||
range.mEndOffset));
|
||||
}
|
||||
@ -1677,25 +1675,28 @@ nsIMM32Handler::SetTextRangeList(nsTArray<TextRange> &aTextRangeList)
|
||||
|
||||
if (mCursorPosition == NO_IME_CARET) {
|
||||
PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
|
||||
("IMM32: GetTextRangeList, no caret\n"));
|
||||
return;
|
||||
("IMM32: CreateTextRangeArray, no caret\n"));
|
||||
return textRangeArray.forget();
|
||||
}
|
||||
|
||||
int32_t cursor = mCursorPosition;
|
||||
if (uint32_t(cursor) > mCompositionString.Length()) {
|
||||
PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
|
||||
("IMM32: SetTextRangeList, mCursorPosition=%ld. This is larger than mCompositionString.Length()=%lu\n",
|
||||
("IMM32: CreateTextRangeArray, mCursorPosition=%ld. "
|
||||
"This is larger than mCompositionString.Length()=%lu\n",
|
||||
mCursorPosition, mCompositionString.Length()));
|
||||
cursor = mCompositionString.Length();
|
||||
}
|
||||
|
||||
range.mStartOffset = range.mEndOffset = cursor;
|
||||
range.mRangeType = NS_TEXTRANGE_CARETPOSITION;
|
||||
aTextRangeList.AppendElement(range);
|
||||
textRangeArray->AppendElement(range);
|
||||
|
||||
PR_LOG(gIMM32Log, PR_LOG_ALWAYS,
|
||||
("IMM32: SetTextRangeList, caret position=%ld\n",
|
||||
("IMM32: CreateTextRangeArray, caret position=%ld\n",
|
||||
range.mStartOffset));
|
||||
|
||||
return textRangeArray.forget();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "nscore.h"
|
||||
#include <windows.h>
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsString.h"
|
||||
#include "nsTArray.h"
|
||||
#include "mozilla/EventForwards.h"
|
||||
@ -285,7 +286,7 @@ protected:
|
||||
bool GetTargetClauseRange(uint32_t *aOffset, uint32_t *aLength = nullptr);
|
||||
void DispatchTextEvent(nsWindow* aWindow, const nsIMEContext &aIMEContext,
|
||||
bool aCheckAttr = true);
|
||||
void SetTextRangeList(nsTArray<mozilla::TextRange>& aTextRangeList);
|
||||
already_AddRefed<mozilla::TextRangeArray> CreateTextRangeArray();
|
||||
|
||||
nsresult EnsureClauseArray(int32_t aCount);
|
||||
nsresult EnsureAttributeArray(int32_t aCount);
|
||||
|
@ -1049,41 +1049,38 @@ nsTextStore::FlushPendingActions()
|
||||
PR_LOG(sTextStoreLog, PR_LOG_DEBUG,
|
||||
("TSF: 0x%p nsTextStore::FlushPendingActions() "
|
||||
"flushing COMPOSITION_UPDATE={ mData=\"%s\", "
|
||||
"mRanges.Length()=%d }",
|
||||
this, NS_ConvertUTF16toUTF8(action.mData).get(),
|
||||
action.mRanges.Length()));
|
||||
"mRanges=0x%p, mRanges->Length()=%d }",
|
||||
this, NS_ConvertUTF16toUTF8(action.mData).get(), action.mRanges,
|
||||
action.mRanges ? action.mRanges->Length() : 0));
|
||||
|
||||
if (action.mRanges.IsEmpty()) {
|
||||
TextRange wholeRange;
|
||||
wholeRange.mStartOffset = 0;
|
||||
wholeRange.mEndOffset = action.mData.Length();
|
||||
wholeRange.mRangeType = NS_TEXTRANGE_RAWINPUT;
|
||||
action.mRanges.AppendElement(wholeRange);
|
||||
} else {
|
||||
// Adjust offsets in the ranges for XP linefeed character (only \n).
|
||||
// XXX Following code is the safest approach. However, it wastes
|
||||
// a little performance. For ensuring the clauses do not
|
||||
// overlap each other, we should redesign TextRange later.
|
||||
for (uint32_t i = 0; i < action.mRanges.Length(); ++i) {
|
||||
TextRange& range = action.mRanges[i];
|
||||
TextRange nativeRange = range;
|
||||
if (nativeRange.mStartOffset > 0) {
|
||||
nsAutoString preText(
|
||||
Substring(action.mData, 0, nativeRange.mStartOffset));
|
||||
preText.ReplaceSubstring(NS_LITERAL_STRING("\r\n"),
|
||||
NS_LITERAL_STRING("\n"));
|
||||
range.mStartOffset = preText.Length();
|
||||
}
|
||||
if (nativeRange.Length() == 0) {
|
||||
range.mEndOffset = range.mStartOffset;
|
||||
} else {
|
||||
nsAutoString clause(
|
||||
Substring(action.mData,
|
||||
nativeRange.mStartOffset, nativeRange.Length()));
|
||||
clause.ReplaceSubstring(NS_LITERAL_STRING("\r\n"),
|
||||
NS_LITERAL_STRING("\n"));
|
||||
range.mEndOffset = range.mStartOffset + clause.Length();
|
||||
}
|
||||
if (!action.mRanges) {
|
||||
NS_WARNING("How does this case occur?");
|
||||
action.mRanges = new TextRangeArray();
|
||||
}
|
||||
|
||||
// Adjust offsets in the ranges for XP linefeed character (only \n).
|
||||
// XXX Following code is the safest approach. However, it wastes
|
||||
// a little performance. For ensuring the clauses do not
|
||||
// overlap each other, we should redesign TextRange later.
|
||||
for (uint32_t i = 0; i < action.mRanges->Length(); ++i) {
|
||||
TextRange& range = action.mRanges->ElementAt(i);
|
||||
TextRange nativeRange = range;
|
||||
if (nativeRange.mStartOffset > 0) {
|
||||
nsAutoString preText(
|
||||
Substring(action.mData, 0, nativeRange.mStartOffset));
|
||||
preText.ReplaceSubstring(NS_LITERAL_STRING("\r\n"),
|
||||
NS_LITERAL_STRING("\n"));
|
||||
range.mStartOffset = preText.Length();
|
||||
}
|
||||
if (nativeRange.Length() == 0) {
|
||||
range.mEndOffset = range.mStartOffset;
|
||||
} else {
|
||||
nsAutoString clause(
|
||||
Substring(action.mData,
|
||||
nativeRange.mStartOffset, nativeRange.Length()));
|
||||
clause.ReplaceSubstring(NS_LITERAL_STRING("\r\n"),
|
||||
NS_LITERAL_STRING("\n"));
|
||||
range.mEndOffset = range.mStartOffset + clause.Length();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1113,15 +1110,14 @@ nsTextStore::FlushPendingActions()
|
||||
WidgetTextEvent textEvent(true, NS_TEXT_TEXT, mWidget);
|
||||
mWidget->InitEvent(textEvent);
|
||||
textEvent.theText = mComposition.mLastData;
|
||||
if (action.mRanges.IsEmpty()) {
|
||||
if (action.mRanges->IsEmpty()) {
|
||||
TextRange wholeRange;
|
||||
wholeRange.mStartOffset = 0;
|
||||
wholeRange.mEndOffset = textEvent.theText.Length();
|
||||
wholeRange.mRangeType = NS_TEXTRANGE_RAWINPUT;
|
||||
action.mRanges.AppendElement(wholeRange);
|
||||
action.mRanges->AppendElement(wholeRange);
|
||||
}
|
||||
textEvent.rangeArray = action.mRanges.Elements();
|
||||
textEvent.rangeCount = action.mRanges.Length();
|
||||
textEvent.mRanges = action.mRanges;
|
||||
mWidget->DispatchWindowEvent(&textEvent);
|
||||
// Be aware, the mWidget might already have been destroyed.
|
||||
break;
|
||||
@ -1648,11 +1644,10 @@ nsTextStore::RecordCompositionUpdateAction()
|
||||
|
||||
PendingAction* action = GetPendingCompositionUpdate();
|
||||
action->mData = mComposition.mString;
|
||||
nsTArray<TextRange>& textRanges = action->mRanges;
|
||||
// The ranges might already have been initialized already, however, if this
|
||||
// is called again, that means we need to overwrite the ranges with current
|
||||
// The ranges might already have been initialized, however, if this is
|
||||
// called again, that means we need to overwrite the ranges with current
|
||||
// information.
|
||||
textRanges.Clear();
|
||||
action->mRanges->Clear();
|
||||
|
||||
TextRange newRange;
|
||||
// No matter if we have display attribute info or not,
|
||||
@ -1660,7 +1655,7 @@ nsTextStore::RecordCompositionUpdateAction()
|
||||
newRange.mStartOffset = 0;
|
||||
newRange.mEndOffset = action->mData.Length();
|
||||
newRange.mRangeType = NS_TEXTRANGE_RAWINPUT;
|
||||
textRanges.AppendElement(newRange);
|
||||
action->mRanges->AppendElement(newRange);
|
||||
|
||||
nsRefPtr<ITfRange> range;
|
||||
while (S_OK == enumRanges->Next(1, getter_AddRefs(range), nullptr) && range) {
|
||||
@ -1700,14 +1695,14 @@ nsTextStore::RecordCompositionUpdateAction()
|
||||
}
|
||||
}
|
||||
|
||||
TextRange& lastRange = textRanges[textRanges.Length() - 1];
|
||||
TextRange& lastRange = action->mRanges->LastElement();
|
||||
if (lastRange.mStartOffset == newRange.mStartOffset) {
|
||||
// Replace range if last range is the same as this one
|
||||
// So that ranges don't overlap and confuse the editor
|
||||
lastRange = newRange;
|
||||
} else {
|
||||
lastRange.mEndOffset = newRange.mStartOffset;
|
||||
textRanges.AppendElement(newRange);
|
||||
action->mRanges->AppendElement(newRange);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1719,8 +1714,8 @@ nsTextStore::RecordCompositionUpdateAction()
|
||||
// string, however, Gecko doesn't support the wide caret drawing now (Gecko
|
||||
// doesn't support XOR drawing), unfortunately. For now, we should change
|
||||
// the range style to undefined.
|
||||
if (!currentSel.IsCollapsed() && textRanges.Length() == 1) {
|
||||
TextRange& range = textRanges[0];
|
||||
if (!currentSel.IsCollapsed() && action->mRanges->Length() == 1) {
|
||||
TextRange& range = action->mRanges->ElementAt(0);
|
||||
LONG start = currentSel.MinOffset();
|
||||
LONG end = currentSel.MaxOffset();
|
||||
if ((LONG)range.mStartOffset == start - mComposition.mStart &&
|
||||
@ -1738,7 +1733,7 @@ nsTextStore::RecordCompositionUpdateAction()
|
||||
TextRange caretRange;
|
||||
caretRange.mStartOffset = caretRange.mEndOffset = uint32_t(caretPosition);
|
||||
caretRange.mRangeType = NS_TEXTRANGE_CARETPOSITION;
|
||||
textRanges.AppendElement(caretRange);
|
||||
action->mRanges->AppendElement(caretRange);
|
||||
|
||||
PR_LOG(sTextStoreLog, PR_LOG_ALWAYS,
|
||||
("TSF: 0x%p nsTextStore::RecordCompositionUpdateAction() "
|
||||
|
@ -501,7 +501,7 @@ protected:
|
||||
// For compositionupdate and compositionend
|
||||
nsString mData;
|
||||
// For compositionupdate
|
||||
nsTArray<mozilla::TextRange> mRanges;
|
||||
nsRefPtr<mozilla::TextRangeArray> mRanges;
|
||||
// For selectionset
|
||||
bool mSelectionReversed;
|
||||
};
|
||||
@ -521,9 +521,7 @@ protected:
|
||||
}
|
||||
PendingAction* newAction = mPendingActions.AppendElement();
|
||||
newAction->mType = PendingAction::COMPOSITION_UPDATE;
|
||||
// We think that 4 ranges (3 clauses and caret position) are enough for
|
||||
// most cases.
|
||||
newAction->mRanges.SetCapacity(4);
|
||||
newAction->mRanges = new mozilla::TextRangeArray();
|
||||
return newAction;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user