Bug 271815 GTK2 IM over-the-spot doesn't work with Chinese IM because the editor doesn't return correct caret position r=timeless, sr=roc, a=dveditz

git-svn-id: svn://10.0.0.236/branches/MOZILLA_1_8_0_BRANCH@207598 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
masayuki%d-toybox.com
2006-08-16 16:35:59 +00:00
parent 1ad82c8c11
commit 25534ee2c4

View File

@@ -1553,93 +1553,106 @@ nsPlaintextEditor::GetEmbeddedObjects(nsISupportsArray** aNodeList)
NS_IMETHODIMP
nsPlaintextEditor::SetCompositionString(const nsAString& aCompositionString, nsIPrivateTextRangeList* aTextRangeList,nsTextEventReply* aReply)
{
NS_ASSERTION(aTextRangeList, "null ptr");
if (!aTextRangeList)
return NS_ERROR_NULL_POINTER;
// workaround for windows ime bug 23558: we get every ime event twice.
// for escape keypress, this causes an empty string to be passed
// twice, which freaks out the editor. This is to detect and avoid that
// situation:
if (aCompositionString.IsEmpty() && !mIMETextNode)
if (!aTextRangeList && !aCompositionString.IsEmpty())
{
return NS_OK;
NS_ERROR("aTextRangeList is null but the composition string is not null");
return NS_ERROR_NULL_POINTER;
}
mIMETextRangeList = aTextRangeList;
nsCOMPtr<nsIPresShell> ps = do_QueryReferent(mPresShellWeak);
if (!ps)
return NS_ERROR_NOT_INITIALIZED;
// XXX_kin: BEGIN HACK! HACK! HACK!
// XXX_kin:
// XXX_kin: This is lame! The IME stuff needs caret coordinates
// XXX_kin: synchronously, but the editor could be using async
// XXX_kin: updates (reflows and paints) for performance reasons.
// XXX_kin: In order to give IME what it needs, we have to temporarily
// XXX_kin: switch to sync updating during this call so that the
// XXX_kin: nsAutoPlaceHolderBatch can force sync reflows, paints,
// XXX_kin: and selection scrolling, so that we get back accurate
// XXX_kin: caret coordinates.
PRUint32 flags = 0;
PRBool restoreFlags = PR_FALSE;
if (NS_SUCCEEDED(GetFlags(&flags)) &&
(flags & nsIPlaintextEditor::eEditorUseAsyncUpdatesMask))
{
if (NS_SUCCEEDED(SetFlags(flags & (~nsIPlaintextEditor::eEditorUseAsyncUpdatesMask))))
restoreFlags = PR_TRUE;
}
// XXX_kin: END HACK! HACK! HACK!
nsCOMPtr<nsISelection> selection;
nsresult result = GetSelection(getter_AddRefs(selection));
if (NS_FAILED(result)) return result;
nsCOMPtr<nsICaret> caretP;
// we need the nsAutoPlaceHolderBatch destructor called before hitting
// GetCaretCoordinates so the states in Frame system sync with content
// therefore, we put the nsAutoPlaceHolderBatch into a inner block
ps->GetCaret(getter_AddRefs(caretP));
// We should return caret position if it is possible. Because this event
// dispatcher always expects to be returned the correct caret position.
// But in following cases, we don't need to process the composition string,
// so, we only need to return the caret position.
// aCompositionString.IsEmpty() && !mIMETextNode:
// Workaround for Windows IME bug 23558: We get every IME event twice.
// For escape keypress, this causes an empty string to be passed
// twice, which freaks out the editor.
// aCompositionString.IsEmpty() && !aTextRangeList:
// Some Chinese IMEs for Linux are always composition string and text range
// list are empty when listing the Chinese characters. In this case,
// we don't need to process composition string too. See bug 271815.
if (!aCompositionString.IsEmpty() || (mIMETextNode && aTextRangeList))
{
nsAutoPlaceHolderBatch batch(this, gIMETxnName);
mIMETextRangeList = aTextRangeList;
SetIsIMEComposing(); // We set mIsIMEComposing properly.
// XXX_kin: BEGIN HACK! HACK! HACK!
// XXX_kin:
// XXX_kin: This is lame! The IME stuff needs caret coordinates
// XXX_kin: synchronously, but the editor could be using async
// XXX_kin: updates (reflows and paints) for performance reasons.
// XXX_kin: In order to give IME what it needs, we have to temporarily
// XXX_kin: switch to sync updating during this call so that the
// XXX_kin: nsAutoPlaceHolderBatch can force sync reflows, paints,
// XXX_kin: and selection scrolling, so that we get back accurate
// XXX_kin: caret coordinates.
result = InsertText(aCompositionString);
PRUint32 flags = 0;
PRBool restoreFlags = PR_FALSE;
mIMEBufferLength = aCompositionString.Length();
ps->GetCaret(getter_AddRefs(caretP));
if (caretP)
caretP->SetCaretDOMSelection(selection);
// second part of 23558 fix:
if (aCompositionString.IsEmpty())
if (NS_SUCCEEDED(GetFlags(&flags)) &&
(flags & nsIPlaintextEditor::eEditorUseAsyncUpdatesMask))
{
mIMETextNode = nsnull;
if (NS_SUCCEEDED(SetFlags(
flags & (~nsIPlaintextEditor::eEditorUseAsyncUpdatesMask))))
restoreFlags = PR_TRUE;
}
// XXX_kin: END HACK! HACK! HACK!
// we need the nsAutoPlaceHolderBatch destructor called before hitting
// GetCaretCoordinates so the states in Frame system sync with content
// therefore, we put the nsAutoPlaceHolderBatch into a inner block
{
nsAutoPlaceHolderBatch batch(this, gIMETxnName);
SetIsIMEComposing(); // We set mIsIMEComposing properly.
result = InsertText(aCompositionString);
mIMEBufferLength = aCompositionString.Length();
if (caretP)
caretP->SetCaretDOMSelection(selection);
// second part of 23558 fix:
if (aCompositionString.IsEmpty())
mIMETextNode = nsnull;
}
// XXX_kin: BEGIN HACK! HACK! HACK!
// XXX_kin:
// XXX_kin: Restore the previous set of flags!
if (restoreFlags)
SetFlags(flags);
// XXX_kin: END HACK! HACK! HACK!
}
// XXX_kin: BEGIN HACK! HACK! HACK!
// XXX_kin:
// XXX_kin: Restore the previous set of flags!
if (restoreFlags)
SetFlags(flags);
// XXX_kin: END HACK! HACK! HACK!
if (caretP)
{
result = caretP->GetCaretCoordinates(nsICaret::eIMECoordinates, selection,
&(aReply->mCursorPosition), &(aReply->mCursorIsCollapsed), nsnull);
result = caretP->GetCaretCoordinates(nsICaret::eIMECoordinates,
selection,
&(aReply->mCursorPosition),
&(aReply->mCursorIsCollapsed),
nsnull);
NS_ASSERTION(NS_SUCCEEDED(result), "cannot get caret position");
}
return result;
}