--- a/widget/cocoa/TextInputHandler.mm
+++ b/widget/cocoa/TextInputHandler.mm
@@ -1679,20 +1679,22 @@ TextInputHandler::HandleKeyDownEvent(NSE
this));
}
}
// Note: mWidget might have become null here. Don't count on it from here on.
MOZ_LOG(gLog, LogLevel::Info,
("%p TextInputHandler::HandleKeyDownEvent, "
- "keydown handled=%s, keypress handled=%s, causedOtherKeyEvents=%s",
+ "keydown handled=%s, keypress handled=%s, causedOtherKeyEvents=%s, "
+ "compositionDispatched=%s",
this, TrueOrFalse(currentKeyEvent->mKeyDownHandled),
TrueOrFalse(currentKeyEvent->mKeyPressHandled),
- TrueOrFalse(currentKeyEvent->mCausedOtherKeyEvents)));
+ TrueOrFalse(currentKeyEvent->mCausedOtherKeyEvents),
+ TrueOrFalse(currentKeyEvent->mCompositionDispatched)));
// Insert empty line to the log for easier to read.
MOZ_LOG(gLog, LogLevel::Info, (""));
return currentKeyEvent->IsDefaultPrevented();
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(false);
}
void
@@ -2118,28 +2120,30 @@ TextInputHandler::InsertText(NSAttribute
KeyEventState* currentKeyEvent = GetCurrentKeyEvent();
MOZ_LOG(gLog, LogLevel::Info,
("%p TextInputHandler::InsertText, aAttrString=\"%s\", "
"aReplacementRange=%p { location=%llu, length=%llu }, "
"IsIMEComposing()=%s, IgnoreIMEComposition()=%s, "
"keyevent=%p, keydownHandled=%s, keypressDispatched=%s, "
- "causedOtherKeyEvents=%s",
+ "causedOtherKeyEvents=%s, compositionDispatched=%s",
this, GetCharacters([aAttrString string]), aReplacementRange,
aReplacementRange ? aReplacementRange->location : 0,
aReplacementRange ? aReplacementRange->length : 0,
TrueOrFalse(IsIMEComposing()), TrueOrFalse(IgnoreIMEComposition()),
currentKeyEvent ? currentKeyEvent->mKeyEvent : nullptr,
currentKeyEvent ?
TrueOrFalse(currentKeyEvent->mKeyDownHandled) : "N/A",
currentKeyEvent ?
TrueOrFalse(currentKeyEvent->mKeyPressDispatched) : "N/A",
currentKeyEvent ?
- TrueOrFalse(currentKeyEvent->mCausedOtherKeyEvents) : "N/A"));
+ TrueOrFalse(currentKeyEvent->mCausedOtherKeyEvents) : "N/A",
+ currentKeyEvent ?
+ TrueOrFalse(currentKeyEvent->mCompositionDispatched) : "N/A"));
if (IgnoreIMEComposition()) {
return;
}
InputContext context = mWidget->GetInputContext();
bool isEditable = (context.mIMEState.mEnabled == IMEState::ENABLED ||
context.mIMEState.mEnabled == IMEState::PASSWORD);
@@ -2195,21 +2199,26 @@ TextInputHandler::InsertText(NSAttribute
bool isReplacingSpecifiedRange =
isEditable && aReplacementRange &&
aReplacementRange->location != NSNotFound &&
!NSEqualRanges(selectedRange, *aReplacementRange);
// If this is not caused by pressing a key, there is a composition or
// replacing a range which is different from current selection, let's
// insert the text as committing a composition.
- if (!currentKeyEvent || IsIMEComposing() || isReplacingSpecifiedRange) {
+ // If InsertText() is called two or more times, we should insert all
+ // text with composition events.
+ // XXX When InsertText() is called multiple times, Chromium dispatches
+ // only one composition event. So, we need to store InsertText()
+ // calls and flush later.
+ if (!currentKeyEvent || currentKeyEvent->mCompositionDispatched ||
+ IsIMEComposing() || isReplacingSpecifiedRange) {
InsertTextAsCommittingComposition(aAttrString, aReplacementRange);
if (currentKeyEvent) {
- currentKeyEvent->mKeyPressHandled = true;
- currentKeyEvent->mKeyPressDispatched = true;
+ currentKeyEvent->mCompositionDispatched = true;
}
return;
}
// Don't let the same event be fired twice when hitting
// enter/return! (Bug 420502)
if (currentKeyEvent && !currentKeyEvent->CanDispatchKeyPressEvent()) {
return;
@@ -3152,38 +3161,40 @@ IMEInputHandler::SetMarkedText(NSAttribu
KeyEventState* currentKeyEvent = GetCurrentKeyEvent();
MOZ_LOG(gLog, LogLevel::Info,
("%p IMEInputHandler::SetMarkedText, "
"aAttrString=\"%s\", aSelectedRange={ location=%llu, length=%llu }, "
"aReplacementRange=%p { location=%llu, length=%llu }, "
"Destroyed()=%s, IgnoreIMEComposition()=%s, IsIMEComposing()=%s, "
"mMarkedRange={ location=%llu, length=%llu }, keyevent=%p, "
- "keydownHandled=%s, keypressDispatched=%s, causedOtherKeyEvents=%s",
+ "keydownHandled=%s, keypressDispatched=%s, causedOtherKeyEvents=%s, "
+ "compositionDispatched=%s",
this, GetCharacters([aAttrString string]),
aSelectedRange.location, aSelectedRange.length, aReplacementRange,
aReplacementRange ? aReplacementRange->location : 0,
aReplacementRange ? aReplacementRange->length : 0,
TrueOrFalse(Destroyed()), TrueOrFalse(IgnoreIMEComposition()),
TrueOrFalse(IsIMEComposing()),
mMarkedRange.location, mMarkedRange.length,
currentKeyEvent ? currentKeyEvent->mKeyEvent : nullptr,
currentKeyEvent ?
TrueOrFalse(currentKeyEvent->mKeyDownHandled) : "N/A",
currentKeyEvent ?
TrueOrFalse(currentKeyEvent->mKeyPressDispatched) : "N/A",
currentKeyEvent ?
- TrueOrFalse(currentKeyEvent->mCausedOtherKeyEvents) : "N/A"));
-
- // If SetMarkedText() is called during composition, that means that
+ TrueOrFalse(currentKeyEvent->mCausedOtherKeyEvents) : "N/A",
+ currentKeyEvent ?
+ TrueOrFalse(currentKeyEvent->mCompositionDispatched) : "N/A"));
+
+ // If SetMarkedText() is called during handling a key press, that means that
// the key event caused this composition. So, keypress event shouldn't
- // be dispatched later, let's consume it here.
+ // be dispatched later, let's mark the key event causing composition event.
if (currentKeyEvent) {
- currentKeyEvent->mKeyPressHandled = true;
- currentKeyEvent->mKeyPressDispatched = true;
+ currentKeyEvent->mCompositionDispatched = true;
}
if (Destroyed() || IgnoreIMEComposition()) {
return;
}
RefPtr<IMEInputHandler> kungFuDeathGrip(this);