Mail's inherited InsertText() calls CancelInputMethod()
indirectly, and since InsertText() is called inside BTextView::HandleInputMethodChanged(), this method would see fInline slip away from under its feet.. Now we call the BTextView version explicitly. Fixes bug #1022, although I'm not sure if this is completely correct. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22444 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -806,7 +806,6 @@ BTextView::MessageReceived(BMessage *message)
|
|||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case B_INPUT_METHOD_STARTED:
|
case B_INPUT_METHOD_STARTED:
|
||||||
{
|
{
|
||||||
PRINT(("B_INPUT_METHOD_STARTED\n"));
|
|
||||||
BMessenger messenger;
|
BMessenger messenger;
|
||||||
if (message->FindMessenger("be:reply_to", &messenger) == B_OK) {
|
if (message->FindMessenger("be:reply_to", &messenger) == B_OK) {
|
||||||
ASSERT(fInline == NULL);
|
ASSERT(fInline == NULL);
|
||||||
@@ -816,19 +815,16 @@ BTextView::MessageReceived(BMessage *message)
|
|||||||
}
|
}
|
||||||
|
|
||||||
case B_INPUT_METHOD_STOPPED:
|
case B_INPUT_METHOD_STOPPED:
|
||||||
PRINT(("B_INPUT_METHOD_STOPPED\n"));
|
|
||||||
delete fInline;
|
delete fInline;
|
||||||
fInline = NULL;
|
fInline = NULL;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case B_INPUT_METHOD_CHANGED:
|
case B_INPUT_METHOD_CHANGED:
|
||||||
PRINT(("B_INPUT_METHOD_CHANGED\n"));
|
|
||||||
if (fInline != NULL)
|
if (fInline != NULL)
|
||||||
HandleInputMethodChanged(message);
|
HandleInputMethodChanged(message);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case B_INPUT_METHOD_LOCATION_REQUEST:
|
case B_INPUT_METHOD_LOCATION_REQUEST:
|
||||||
PRINT(("B_INPUT_METHOD_LOCATION_REQUEST\n"));
|
|
||||||
if (fInline != NULL)
|
if (fInline != NULL)
|
||||||
HandleInputMethodLocationRequest();
|
HandleInputMethodLocationRequest();
|
||||||
break;
|
break;
|
||||||
@@ -3102,8 +3098,6 @@ BTextView::HandleAlphaKey(const char *bytes, int32 numBytes)
|
|||||||
void
|
void
|
||||||
BTextView::Refresh(int32 fromOffset, int32 toOffset, bool erase, bool scroll)
|
BTextView::Refresh(int32 fromOffset, int32 toOffset, bool erase, bool scroll)
|
||||||
{
|
{
|
||||||
PRINT(("Refresh(fromOffset: %ld, toOffset: %ld, erase: %d, scroll: %d\n",
|
|
||||||
fromOffset, toOffset, erase, scroll));
|
|
||||||
// TODO: Cleanup
|
// TODO: Cleanup
|
||||||
float saveHeight = fTextRect.Height();
|
float saveHeight = fTextRect.Height();
|
||||||
int32 fromLine = LineAt(fromOffset);
|
int32 fromLine = LineAt(fromOffset);
|
||||||
@@ -3644,9 +3638,6 @@ BTextView::DrawLines(int32 startLine, int32 endLine, int32 startOffset, bool era
|
|||||||
if (!Window())
|
if (!Window())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
PRINT(("DrawLines(startLine: %ld, endLine: %ld, startOffset: %ld, erase: %d\n",
|
|
||||||
startLine, endLine, startOffset, erase));
|
|
||||||
|
|
||||||
// clip the text
|
// clip the text
|
||||||
BRect clipRect = Bounds() & fTextRect;
|
BRect clipRect = Bounds() & fTextRect;
|
||||||
clipRect.InsetBy(-1, -1);
|
clipRect.InsetBy(-1, -1);
|
||||||
@@ -4438,7 +4429,7 @@ BTextView::HandleInputMethodChanged(BMessage *message)
|
|||||||
// Delete the previously inserted text (if any)
|
// Delete the previously inserted text (if any)
|
||||||
if (fInline->IsActive()) {
|
if (fInline->IsActive()) {
|
||||||
int32 oldOffset = fInline->Offset();
|
int32 oldOffset = fInline->Offset();
|
||||||
DeleteText(oldOffset, oldOffset + fInline->Length());
|
BTextView::DeleteText(oldOffset, oldOffset + fInline->Length());
|
||||||
fClickOffset = fSelStart = fSelEnd = oldOffset;
|
fClickOffset = fSelStart = fSelEnd = oldOffset;
|
||||||
|
|
||||||
if (confirmed)
|
if (confirmed)
|
||||||
@@ -4474,7 +4465,13 @@ BTextView::HandleInputMethodChanged(BMessage *message)
|
|||||||
fInline->SetSelectionLength(selectionEnd - selectionStart);
|
fInline->SetSelectionLength(selectionEnd - selectionStart);
|
||||||
|
|
||||||
// Insert the new text
|
// Insert the new text
|
||||||
InsertText(string, stringLen, fSelStart, NULL);
|
// We call the base InsertText(), because inherited method could do bad things:
|
||||||
|
// Mail, for example, does call InsertText() with a runarray parameter
|
||||||
|
// (even if we pass NULL here). That causes SetRunArray() to be called,
|
||||||
|
// which in turn calls CancelInputMethod(), which would destroy fInline
|
||||||
|
// (and we call some of its functions later). Bug #1022.
|
||||||
|
// TODO: Check if R5 really does this
|
||||||
|
BTextView::InsertText(string, stringLen, fSelStart, NULL);
|
||||||
fSelStart += stringLen;
|
fSelStart += stringLen;
|
||||||
fClickOffset = fSelEnd = fSelStart;
|
fClickOffset = fSelEnd = fSelStart;
|
||||||
|
|
||||||
@@ -4522,22 +4519,24 @@ BTextView::CancelInputMethod()
|
|||||||
if (!fInline)
|
if (!fInline)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
BMessage message(B_INPUT_METHOD_EVENT);
|
_BInlineInput_ *inlineInput = fInline;
|
||||||
message.AddInt32("be:opcode", B_INPUT_METHOD_STOPPED);
|
fInline = NULL;
|
||||||
fInline->Method()->SendMessage(&message);
|
|
||||||
|
|
||||||
// Delete the previously inserted text (if any)
|
// Delete the previously inserted text (if any)
|
||||||
if (fInline->IsActive()) {
|
if (inlineInput->IsActive()) {
|
||||||
int32 oldOffset = fInline->Offset();
|
int32 oldOffset = inlineInput->Offset();
|
||||||
DeleteText(oldOffset, oldOffset + fInline->Length());
|
DeleteText(oldOffset, oldOffset + inlineInput->Length());
|
||||||
fClickOffset = fSelStart = fSelEnd = oldOffset;
|
fClickOffset = fSelStart = fSelEnd = oldOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
delete fInline;
|
|
||||||
fInline = NULL;
|
|
||||||
|
|
||||||
if (Window())
|
if (Window())
|
||||||
Refresh(0, fText->Length(), true, false);
|
Refresh(0, fText->Length(), true, false);
|
||||||
|
|
||||||
|
BMessage message(B_INPUT_METHOD_EVENT);
|
||||||
|
message.AddInt32("be:opcode", B_INPUT_METHOD_STOPPED);
|
||||||
|
inlineInput->Method()->SendMessage(&message);
|
||||||
|
|
||||||
|
delete inlineInput;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user