mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-14 10:43:24 +00:00
Bug 1343451 - part 4: Make TextInputHandler dispatches eKeyDown event with marking it as "processed by IME" r=m_kato
First of all, TextInputHandler::HandleKeyDown() dispatches an eKeyDown event before sending IME. This is different behavior from Gecko on the other platforms and it means TextInputHandler does not know if the eKeyDown event will be handled by IME. Therefore, we need to make TextInputHandler dispatch an eKeyDown event dispatch when it needs to dispatch another event. Therefore, this patch makes TextInputHandler not dispatch an eKeyDown even from its HandleKeyDown() unless it's already has composition (because if it's already had composition, any eKeyDown event except modifier keys should be marked as "processed by IME" for compatibility with the other browsers). For dispatching eKeyDown event only once for a native keydown event, this patch implements TextInputHandlerBase::MaybeDispatchCurrentKeydownEvent() to check whether eKeyDown event has already been dispatched for the event and if it's not so, dispatches eKeyDown event. Note that on macOS, dead keys are implemented as IME. However, we need to treat dead keys as is. Therefore, if current keydown event is a dead keydown event, MaybeDispatchCurrentKeydownEvent() should NOT mark dispatching eKeyDown event and its following eKeyDown event as "processed by IME". MozReview-Commit-ID: 7epk8wdAznd --HG-- extra : rebase_source : 0ed30ff3e108170fd96eabe626e0530473f2f3b1
This commit is contained in:
parent
3db8525089
commit
6857169b5e
@ -243,6 +243,9 @@ public:
|
||||
* dispatch a Gecko key event.
|
||||
* @param aKeyEvent The result -- a Gecko key event initialized
|
||||
* from the native key event.
|
||||
* @param aIsProcessedByIME true if aNativeKeyEvent has been handled
|
||||
* by IME (but except if the composition was
|
||||
* started with dead key).
|
||||
* @param aInsertString If caller expects that the event will cause
|
||||
* a character to be input (say in an editor),
|
||||
* the caller should set this. Otherwise,
|
||||
@ -251,6 +254,7 @@ public:
|
||||
* characters of aNativeKeyEvent.
|
||||
*/
|
||||
void InitKeyEvent(NSEvent *aNativeKeyEvent, WidgetKeyboardEvent& aKeyEvent,
|
||||
bool aIsProcessedByIME,
|
||||
const nsAString *aInsertString = nullptr);
|
||||
|
||||
/**
|
||||
@ -303,6 +307,15 @@ public:
|
||||
static CodeNameIndex ComputeGeckoCodeNameIndex(UInt32 aNativeKeyCode,
|
||||
UInt32 aKbType);
|
||||
|
||||
/**
|
||||
* TranslateToChar() checks if aNativeKeyEvent is a dead key.
|
||||
*
|
||||
* @param aNativeKeyEvent A native key event.
|
||||
* @return Returns true if the key event is a dead key
|
||||
* event. Otherwise, false.
|
||||
*/
|
||||
bool IsDeadKey(NSEvent* aNativeKeyEvent);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* TranslateToString() computes the inputted text from the native keyCode,
|
||||
@ -343,7 +356,7 @@ protected:
|
||||
* @param aKbType A native Keyboard Type value. Typically,
|
||||
* this is a result of ::LMGetKbdType().
|
||||
* @return Returns true if the key with specified
|
||||
* modifier state isa dead key. Otherwise,
|
||||
* modifier state is a dead key. Otherwise,
|
||||
* false.
|
||||
*/
|
||||
bool IsDeadKey(UInt32 aKeyCode, UInt32 aModifiers, UInt32 aKbType);
|
||||
@ -433,6 +446,9 @@ public:
|
||||
* dispatch a Gecko key event.
|
||||
* @param aKeyEvent The result -- a Gecko key event initialized
|
||||
* from the native key event.
|
||||
* @param aIsProcessedByIME true if aNativeKeyEvent has been handled
|
||||
* by IME (but except if the composition was
|
||||
* started with dead key).
|
||||
* @param aInsertString If caller expects that the event will cause
|
||||
* a character to be input (say in an editor),
|
||||
* the caller should set this. Otherwise,
|
||||
@ -441,6 +457,7 @@ public:
|
||||
* characters of aNativeKeyEvent.
|
||||
*/
|
||||
void InitKeyEvent(NSEvent *aNativeKeyEvent, WidgetKeyboardEvent& aKeyEvent,
|
||||
bool aIsProcessedByIME,
|
||||
const nsAString *aInsertString = nullptr);
|
||||
|
||||
/**
|
||||
@ -552,6 +569,8 @@ protected:
|
||||
// Unique id associated with a keydown / keypress event. It's ok if this
|
||||
// wraps over long periods.
|
||||
uint32_t mUniqueId;
|
||||
// Whether keydown event was dispatched for mKeyEvent.
|
||||
bool mKeyDownDispatched;
|
||||
// Whether keydown event was consumed by web contents or chrome contents.
|
||||
bool mKeyDownHandled;
|
||||
// Whether keypress event was dispatched for mKeyEvent.
|
||||
@ -604,6 +623,7 @@ protected:
|
||||
}
|
||||
mInsertString = nullptr;
|
||||
mInsertedString.Truncate();
|
||||
mKeyDownDispatched = false;
|
||||
mKeyDownHandled = false;
|
||||
mKeyPressDispatched = false;
|
||||
mKeyPressHandled = false;
|
||||
@ -617,6 +637,11 @@ protected:
|
||||
mCompositionDispatched;
|
||||
}
|
||||
|
||||
bool CanDispatchKeyDownEvent() const
|
||||
{
|
||||
return !mKeyDownDispatched;
|
||||
}
|
||||
|
||||
bool CanDispatchKeyPressEvent() const
|
||||
{
|
||||
return !mKeyPressDispatched && !IsDefaultPrevented();
|
||||
@ -765,7 +790,8 @@ protected:
|
||||
}
|
||||
|
||||
void InitKeyEvent(TextInputHandlerBase* aHandler,
|
||||
WidgetKeyboardEvent& aKeyEvent);
|
||||
WidgetKeyboardEvent& aKeyEvent,
|
||||
bool aIsProcessedByIME);
|
||||
|
||||
/**
|
||||
* GetUnhandledString() returns characters of the event which have not been
|
||||
@ -1059,6 +1085,7 @@ public:
|
||||
NSRange MarkedRange();
|
||||
|
||||
bool IsIMEComposing() { return mIsIMEComposing; }
|
||||
bool IsDeadKeyComposing() { return mIsDeadKeyComposing; }
|
||||
bool IsIMEOpened();
|
||||
bool IsIMEEnabled() { return mIsIMEEnabled; }
|
||||
bool IsASCIICapableOnly() { return mIsASCIICapableOnly; }
|
||||
@ -1112,6 +1139,19 @@ protected:
|
||||
void InsertTextAsCommittingComposition(NSAttributedString* aAttrString,
|
||||
NSRange* aReplacementRange);
|
||||
|
||||
/**
|
||||
* MaybeDispatchCurrentKeydownEvent() dispatches eKeyDown event for current
|
||||
* key event. If eKeyDown for current key event has already been dispatched,
|
||||
* this does nothing.
|
||||
*
|
||||
* @param aIsProcessedByIME true if current key event is handled by IME.
|
||||
* @return true if the caller can continue to handle
|
||||
* current key event. Otherwise, false. E.g.,
|
||||
* focus is moved, the widget has been destroyed
|
||||
* or something.
|
||||
*/
|
||||
bool MaybeDispatchCurrentKeydownEvent(bool aIsProcessedByIME);
|
||||
|
||||
private:
|
||||
// If mIsIMEComposing is true, the composition string is stored here.
|
||||
NSString* mIMECompositionString;
|
||||
@ -1125,6 +1165,9 @@ private:
|
||||
mozilla::WritingMode mWritingMode;
|
||||
|
||||
bool mIsIMEComposing;
|
||||
// If the composition started with dead key, mIsDeadKeyComposing is set to
|
||||
// true.
|
||||
bool mIsDeadKeyComposing;
|
||||
bool mIsIMEEnabled;
|
||||
bool mIsASCIICapableOnly;
|
||||
bool mIgnoreIMECommit;
|
||||
|
@ -399,6 +399,84 @@ TISInputSourceWrapper::TranslateToChar(UInt32 aKeyCode, UInt32 aModifiers,
|
||||
return static_cast<uint32_t>(str.CharAt(0));
|
||||
}
|
||||
|
||||
bool
|
||||
TISInputSourceWrapper::IsDeadKey(NSEvent* aNativeKeyEvent)
|
||||
{
|
||||
if ([[aNativeKeyEvent characters] length]) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Assmue that if control key or command key is pressed, it's not a dead key.
|
||||
NSUInteger cocoaState = [aNativeKeyEvent modifierFlags];
|
||||
if (cocoaState & (NSControlKeyMask | NSCommandKeyMask)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
UInt32 nativeKeyCode = [aNativeKeyEvent keyCode];
|
||||
switch (nativeKeyCode) {
|
||||
case kVK_ANSI_A:
|
||||
case kVK_ANSI_B:
|
||||
case kVK_ANSI_C:
|
||||
case kVK_ANSI_D:
|
||||
case kVK_ANSI_E:
|
||||
case kVK_ANSI_F:
|
||||
case kVK_ANSI_G:
|
||||
case kVK_ANSI_H:
|
||||
case kVK_ANSI_I:
|
||||
case kVK_ANSI_J:
|
||||
case kVK_ANSI_K:
|
||||
case kVK_ANSI_L:
|
||||
case kVK_ANSI_M:
|
||||
case kVK_ANSI_N:
|
||||
case kVK_ANSI_O:
|
||||
case kVK_ANSI_P:
|
||||
case kVK_ANSI_Q:
|
||||
case kVK_ANSI_R:
|
||||
case kVK_ANSI_S:
|
||||
case kVK_ANSI_T:
|
||||
case kVK_ANSI_U:
|
||||
case kVK_ANSI_V:
|
||||
case kVK_ANSI_W:
|
||||
case kVK_ANSI_X:
|
||||
case kVK_ANSI_Y:
|
||||
case kVK_ANSI_Z:
|
||||
case kVK_ANSI_1:
|
||||
case kVK_ANSI_2:
|
||||
case kVK_ANSI_3:
|
||||
case kVK_ANSI_4:
|
||||
case kVK_ANSI_5:
|
||||
case kVK_ANSI_6:
|
||||
case kVK_ANSI_7:
|
||||
case kVK_ANSI_8:
|
||||
case kVK_ANSI_9:
|
||||
case kVK_ANSI_0:
|
||||
case kVK_ANSI_Equal:
|
||||
case kVK_ANSI_Minus:
|
||||
case kVK_ANSI_RightBracket:
|
||||
case kVK_ANSI_LeftBracket:
|
||||
case kVK_ANSI_Quote:
|
||||
case kVK_ANSI_Semicolon:
|
||||
case kVK_ANSI_Backslash:
|
||||
case kVK_ANSI_Comma:
|
||||
case kVK_ANSI_Slash:
|
||||
case kVK_ANSI_Period:
|
||||
case kVK_ANSI_Grave:
|
||||
case kVK_JIS_Yen:
|
||||
case kVK_JIS_Underscore:
|
||||
break;
|
||||
default:
|
||||
// Let's assume that dead key can be only a printable key in standard
|
||||
// position.
|
||||
return false;
|
||||
}
|
||||
|
||||
// If TranslateToChar() returns non-zero value, that means that
|
||||
// the key may input a character with different dead key state.
|
||||
UInt32 kbType = GetKbdType();
|
||||
UInt32 carbonState = nsCocoaUtils::ConvertToCarbonModifier(cocoaState);
|
||||
return IsDeadKey(nativeKeyCode, carbonState, kbType);
|
||||
}
|
||||
|
||||
bool
|
||||
TISInputSourceWrapper::IsDeadKey(UInt32 aKeyCode,
|
||||
UInt32 aModifiers,
|
||||
@ -906,17 +984,25 @@ TISInputSourceWrapper::ComputeInsertStringForCharCode(
|
||||
void
|
||||
TISInputSourceWrapper::InitKeyEvent(NSEvent *aNativeKeyEvent,
|
||||
WidgetKeyboardEvent& aKeyEvent,
|
||||
bool aIsProcessedByIME,
|
||||
const nsAString *aInsertString)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
MOZ_ASSERT(!aIsProcessedByIME || aKeyEvent.mMessage != eKeyPress,
|
||||
"eKeyPress event should not be marked as proccessed by IME");
|
||||
|
||||
MOZ_LOG(gLog, LogLevel::Info,
|
||||
("%p TISInputSourceWrapper::InitKeyEvent, aNativeKeyEvent=%p, "
|
||||
"aKeyEvent.mMessage=%s, aInsertString=%p, IsOpenedIMEMode()=%s",
|
||||
this, aNativeKeyEvent, GetGeckoKeyEventType(aKeyEvent), aInsertString,
|
||||
"aKeyEvent.mMessage=%s, aProcessedByIME=%s, aInsertString=%p, "
|
||||
"IsOpenedIMEMode()=%s",
|
||||
this, aNativeKeyEvent, GetGeckoKeyEventType(aKeyEvent),
|
||||
TrueOrFalse(aIsProcessedByIME), aInsertString,
|
||||
TrueOrFalse(IsOpenedIMEMode())));
|
||||
|
||||
NS_ENSURE_TRUE(aNativeKeyEvent, );
|
||||
if (NS_WARN_IF(!aNativeKeyEvent)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCocoaUtils::InitInputEvent(aKeyEvent, aNativeKeyEvent);
|
||||
|
||||
@ -945,8 +1031,18 @@ TISInputSourceWrapper::InitKeyEvent(NSEvent *aNativeKeyEvent,
|
||||
UInt32 kbType = GetKbdType();
|
||||
UInt32 nativeKeyCode = [aNativeKeyEvent keyCode];
|
||||
|
||||
// macOS handles dead key as IME. If the key is first key press of dead
|
||||
// key, we should use KEY_NAME_INDEX_Dead for first (dead) key event.
|
||||
// So, if aIsProcessedByIME is true, it may be dead key. Let's check
|
||||
// if current key event is a dead key's keydown event.
|
||||
bool isProcessedByIME =
|
||||
aIsProcessedByIME &&
|
||||
!TISInputSourceWrapper::CurrentInputSource().IsDeadKey(aNativeKeyEvent);
|
||||
|
||||
aKeyEvent.mKeyCode =
|
||||
ComputeGeckoKeyCode(nativeKeyCode, kbType, aKeyEvent.IsMeta());
|
||||
isProcessedByIME ?
|
||||
NS_VK_PROCESSKEY :
|
||||
ComputeGeckoKeyCode(nativeKeyCode, kbType, aKeyEvent.IsMeta());
|
||||
|
||||
switch (nativeKeyCode) {
|
||||
case kVK_Command:
|
||||
@ -999,7 +1095,9 @@ TISInputSourceWrapper::InitKeyEvent(NSEvent *aNativeKeyEvent,
|
||||
this, OnOrOff(aKeyEvent.IsShift()), OnOrOff(aKeyEvent.IsControl()),
|
||||
OnOrOff(aKeyEvent.IsAlt()), OnOrOff(aKeyEvent.IsMeta())));
|
||||
|
||||
if (IsPrintableKeyEvent(aNativeKeyEvent)) {
|
||||
if (isProcessedByIME) {
|
||||
aKeyEvent.mKeyNameIndex = KEY_NAME_INDEX_Process;
|
||||
} else if (IsPrintableKeyEvent(aNativeKeyEvent)) {
|
||||
aKeyEvent.mKeyNameIndex = KEY_NAME_INDEX_USE_STRING;
|
||||
// If insertText calls this method, let's use the string.
|
||||
if (aInsertString && !aInsertString->IsEmpty() &&
|
||||
@ -1628,7 +1726,7 @@ TextInputHandler::HandleKeyDownEvent(NSEvent* aNativeEvent,
|
||||
}
|
||||
|
||||
WidgetKeyboardEvent imeEvent(true, eKeyDown, widget);
|
||||
currentKeyEvent->InitKeyEvent(this, imeEvent);
|
||||
currentKeyEvent->InitKeyEvent(this, imeEvent, false);
|
||||
imeEvent.mPluginTextEventString.Assign(committed);
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
mDispatcher->DispatchKeyboardEvent(eKeyDown, imeEvent, status,
|
||||
@ -1637,50 +1735,18 @@ TextInputHandler::HandleKeyDownEvent(NSEvent* aNativeEvent,
|
||||
return true;
|
||||
}
|
||||
|
||||
NSResponder* firstResponder = [[mView window] firstResponder];
|
||||
RefPtr<TextInputHandler> kungFuDeathGrip(this);
|
||||
|
||||
nsresult rv = mDispatcher->BeginNativeInputTransaction();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
MOZ_LOG(gLog, LogLevel::Error,
|
||||
("%p IMEInputHandler::HandleKeyDownEvent, "
|
||||
"FAILED, due to BeginNativeInputTransaction() failure "
|
||||
"at dispatching keydown for ordinal cases", this));
|
||||
// When we're already in a composition, we need always to mark the eKeyDown
|
||||
// event as "processed by IME". So, let's dispatch eKeyDown event here in
|
||||
// such case.
|
||||
if (IsIMEComposing() && !MaybeDispatchCurrentKeydownEvent(true)) {
|
||||
MOZ_LOG(gLog, LogLevel::Info,
|
||||
("%p IMEInputHandler::HandleKeyDownEvent, eKeyDown caused focus move or "
|
||||
"something and canceling the composition", this));
|
||||
return false;
|
||||
}
|
||||
|
||||
WidgetKeyboardEvent keydownEvent(true, eKeyDown, widget);
|
||||
currentKeyEvent->InitKeyEvent(this, keydownEvent);
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
mDispatcher->DispatchKeyboardEvent(eKeyDown, keydownEvent, status,
|
||||
currentKeyEvent);
|
||||
currentKeyEvent->mKeyDownHandled =
|
||||
(status == nsEventStatus_eConsumeNoDefault);
|
||||
|
||||
if (Destroyed()) {
|
||||
MOZ_LOG(gLog, LogLevel::Info,
|
||||
("%p TextInputHandler::HandleKeyDownEvent, "
|
||||
"widget was destroyed by keydown event", this));
|
||||
return currentKeyEvent->IsDefaultPrevented();
|
||||
}
|
||||
|
||||
// The key down event may have shifted the focus, in which
|
||||
// case we should not fire the key press.
|
||||
// XXX This is a special code only on Cocoa widget, why is this needed?
|
||||
if (firstResponder != [[mView window] firstResponder]) {
|
||||
MOZ_LOG(gLog, LogLevel::Info,
|
||||
("%p TextInputHandler::HandleKeyDownEvent, "
|
||||
"view lost focus by keydown event", this));
|
||||
return currentKeyEvent->IsDefaultPrevented();
|
||||
}
|
||||
|
||||
if (currentKeyEvent->IsDefaultPrevented()) {
|
||||
MOZ_LOG(gLog, LogLevel::Info,
|
||||
("%p TextInputHandler::HandleKeyDownEvent, "
|
||||
"keydown event's default is prevented", this));
|
||||
return true;
|
||||
}
|
||||
|
||||
// Let Cocoa interpret the key events, caching IsIMEComposing first.
|
||||
bool wasComposing = IsIMEComposing();
|
||||
bool interpretKeyEventsCalled = false;
|
||||
@ -1710,9 +1776,33 @@ TextInputHandler::HandleKeyDownEvent(NSEvent* aNativeEvent,
|
||||
"IsIMEComposing()=%s",
|
||||
this, TrueOrFalse(wasComposing), TrueOrFalse(IsIMEComposing())));
|
||||
|
||||
if (currentKeyEvent->CanDispatchKeyDownEvent()) {
|
||||
// Dispatch eKeyDown event if nobody has dispatched it yet.
|
||||
// NOTE: Although reaching here means that the native keydown event may
|
||||
// not be handled by IME. However, we cannot know if it is.
|
||||
// For example, Japanese IME of Apple shows candidate window for
|
||||
// typing window. They, you can switch the sort order with Tab key.
|
||||
// However, when you choose "Symbol" of the sort order, there may
|
||||
// be no candiate words. In this case, IME handles the Tab key
|
||||
// actually, but we cannot know it because composition string is
|
||||
// not updated. So, let's mark eKeyDown event as "processed by IME"
|
||||
// when there is composition string. This is same as Chrome.
|
||||
MOZ_LOG(gLog, LogLevel::Info,
|
||||
("%p TextInputHandler::HandleKeyDownEvent, trying to dispatch eKeyDown "
|
||||
"event since it's not yet dispatched",
|
||||
this));
|
||||
if (!MaybeDispatchCurrentKeydownEvent(IsIMEComposing())) {
|
||||
return true; // treat the eKeydDown event as consumed.
|
||||
}
|
||||
MOZ_LOG(gLog, LogLevel::Info,
|
||||
("%p TextInputHandler::HandleKeyDownEvent, eKeyDown event has been "
|
||||
"dispatched",
|
||||
this));
|
||||
}
|
||||
|
||||
if (currentKeyEvent->CanDispatchKeyPressEvent() &&
|
||||
!wasComposing && !IsIMEComposing()) {
|
||||
rv = mDispatcher->BeginNativeInputTransaction();
|
||||
nsresult rv = mDispatcher->BeginNativeInputTransaction();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
MOZ_LOG(gLog, LogLevel::Error,
|
||||
("%p IMEInputHandler::HandleKeyDownEvent, "
|
||||
@ -1722,7 +1812,7 @@ TextInputHandler::HandleKeyDownEvent(NSEvent* aNativeEvent,
|
||||
}
|
||||
|
||||
WidgetKeyboardEvent keypressEvent(true, eKeyPress, widget);
|
||||
currentKeyEvent->InitKeyEvent(this, keypressEvent);
|
||||
currentKeyEvent->InitKeyEvent(this, keypressEvent, false);
|
||||
|
||||
// If we called interpretKeyEvents and this isn't normal character input
|
||||
// then IME probably ate the event for some reason. We do not want to
|
||||
@ -1737,6 +1827,11 @@ TextInputHandler::HandleKeyDownEvent(NSEvent* aNativeEvent,
|
||||
// our default action for this key.
|
||||
if (!(interpretKeyEventsCalled &&
|
||||
IsNormalCharInputtingEvent(keypressEvent))) {
|
||||
MOZ_LOG(gLog, LogLevel::Info,
|
||||
("%p TextInputHandler::HandleKeyDownEvent, trying to dispatch "
|
||||
"eKeyPress event since it's not yet dispatched",
|
||||
this));
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
currentKeyEvent->mKeyPressDispatched =
|
||||
mDispatcher->MaybeDispatchKeypressEvents(keypressEvent, status,
|
||||
currentKeyEvent);
|
||||
@ -1744,7 +1839,8 @@ TextInputHandler::HandleKeyDownEvent(NSEvent* aNativeEvent,
|
||||
(status == nsEventStatus_eConsumeNoDefault);
|
||||
currentKeyEvent->mKeyPressDispatched = true;
|
||||
MOZ_LOG(gLog, LogLevel::Info,
|
||||
("%p TextInputHandler::HandleKeyDownEvent, keypress event dispatched",
|
||||
("%p TextInputHandler::HandleKeyDownEvent, eKeyPress event has been "
|
||||
"dispatched",
|
||||
this));
|
||||
}
|
||||
}
|
||||
@ -1798,8 +1894,10 @@ TextInputHandler::HandleKeyUpEvent(NSEvent* aNativeEvent)
|
||||
return;
|
||||
}
|
||||
|
||||
// Neither Chrome for macOS nor Safari marks "keyup" event as "processed by
|
||||
// IME" even during composition. So, let's follow this behavior.
|
||||
WidgetKeyboardEvent keyupEvent(true, eKeyUp, mWidget);
|
||||
InitKeyEvent(aNativeEvent, keyupEvent);
|
||||
InitKeyEvent(aNativeEvent, keyupEvent, false);
|
||||
|
||||
KeyEventState currentKeyEvent(aNativeEvent);
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
@ -2143,7 +2241,7 @@ TextInputHandler::DispatchKeyEventForFlagsChanged(NSEvent* aNativeEvent,
|
||||
GetKeyNameForNativeKeyCode([aNativeEvent keyCode]), [aNativeEvent keyCode],
|
||||
TrueOrFalse(aDispatchKeyDown), TrueOrFalse(IsIMEComposing())));
|
||||
|
||||
if ([aNativeEvent type] != NSFlagsChanged || IsIMEComposing()) {
|
||||
if ([aNativeEvent type] != NSFlagsChanged) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2157,9 +2255,11 @@ TextInputHandler::DispatchKeyEventForFlagsChanged(NSEvent* aNativeEvent,
|
||||
|
||||
EventMessage message = aDispatchKeyDown ? eKeyDown : eKeyUp;
|
||||
|
||||
// Fire a key event.
|
||||
// Fire a key event for the modifier key. Note that even if modifier key
|
||||
// is pressed during composition, we shouldn't mark the keyboard event as
|
||||
// "processed by IME" since neither Chrome for macOS nor Safari does it.
|
||||
WidgetKeyboardEvent keyEvent(true, message, mWidget);
|
||||
InitKeyEvent(aNativeEvent, keyEvent);
|
||||
InitKeyEvent(aNativeEvent, keyEvent, false);
|
||||
|
||||
// Attach a plugin event, in case keyEvent gets dispatched to a plugin. Only
|
||||
// one field is needed -- the type. The other fields can be constructed as
|
||||
@ -2195,13 +2295,16 @@ TextInputHandler::InsertText(NSAttributedString* aAttrString,
|
||||
("%p TextInputHandler::InsertText, aAttrString=\"%s\", "
|
||||
"aReplacementRange=%p { location=%lu, length=%lu }, "
|
||||
"IsIMEComposing()=%s, "
|
||||
"keyevent=%p, keydownHandled=%s, keypressDispatched=%s, "
|
||||
"keyevent=%p, keydownDispatched=%s, "
|
||||
"keydownHandled=%s, keypressDispatched=%s, "
|
||||
"causedOtherKeyEvents=%s, compositionDispatched=%s",
|
||||
this, GetCharacters([aAttrString string]), aReplacementRange,
|
||||
static_cast<unsigned long>(aReplacementRange ? aReplacementRange->location : 0),
|
||||
static_cast<unsigned long>(aReplacementRange ? aReplacementRange->length : 0),
|
||||
TrueOrFalse(IsIMEComposing()),
|
||||
currentKeyEvent ? currentKeyEvent->mKeyEvent : nullptr,
|
||||
currentKeyEvent ?
|
||||
TrueOrFalse(currentKeyEvent->mKeyDownDispatched) : "N/A",
|
||||
currentKeyEvent ?
|
||||
TrueOrFalse(currentKeyEvent->mKeyDownHandled) : "N/A",
|
||||
currentKeyEvent ?
|
||||
@ -2253,8 +2356,21 @@ TextInputHandler::InsertText(NSAttributedString* aAttrString,
|
||||
if (!currentKeyEvent) {
|
||||
return;
|
||||
}
|
||||
// Delete the selected range.
|
||||
|
||||
// When current keydown event causes this empty text input, let's
|
||||
// dispatch eKeyDown event before any other events. Note that if we're
|
||||
// in a composition, we've already dispatched eKeyDown event from
|
||||
// TextInputHandler::HandleKeyDownEvent().
|
||||
// XXX Should we mark this eKeyDown event as "processed by IME"?
|
||||
RefPtr<TextInputHandler> kungFuDeathGrip(this);
|
||||
if (!IsIMEComposing() && !MaybeDispatchCurrentKeydownEvent(false)) {
|
||||
MOZ_LOG(gLog, LogLevel::Info,
|
||||
("%p IMEInputHandler::InsertText, eKeyDown caused focus move or "
|
||||
"something and canceling the composition", this));
|
||||
return;
|
||||
}
|
||||
|
||||
// Delete the selected range.
|
||||
WidgetContentCommandEvent deleteCommandEvent(true, eContentCommandDelete,
|
||||
mWidget);
|
||||
DispatchEvent(deleteCommandEvent);
|
||||
@ -2303,13 +2419,23 @@ TextInputHandler::InsertText(NSAttributedString* aAttrString,
|
||||
return;
|
||||
}
|
||||
|
||||
// This is the normal path to input a character when you press a key.
|
||||
// Let's dispatch eKeyDown event now.
|
||||
RefPtr<TextInputHandler> kungFuDeathGrip(this);
|
||||
if (!MaybeDispatchCurrentKeydownEvent(false)) {
|
||||
MOZ_LOG(gLog, LogLevel::Info,
|
||||
("%p IMEInputHandler::InsertText, eKeyDown caused focus move or "
|
||||
"something and canceling the composition", this));
|
||||
return;
|
||||
}
|
||||
|
||||
// XXX Shouldn't we hold mDispatcher instead of mWidget?
|
||||
RefPtr<nsChildView> widget(mWidget);
|
||||
nsresult rv = mDispatcher->BeginNativeInputTransaction();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
MOZ_LOG(gLog, LogLevel::Error,
|
||||
("%p IMEInputHandler::HandleKeyUpEvent, "
|
||||
"FAILED, due to BeginNativeInputTransaction() failure", this));
|
||||
MOZ_LOG(gLog, LogLevel::Error,
|
||||
("%p IMEInputHandler::InsertText, "
|
||||
"FAILED, due to BeginNativeInputTransaction() failure", this));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2325,7 +2451,7 @@ TextInputHandler::InsertText(NSAttributedString* aAttrString,
|
||||
// the input string.
|
||||
|
||||
if (currentKeyEvent) {
|
||||
currentKeyEvent->InitKeyEvent(this, keypressEvent);
|
||||
currentKeyEvent->InitKeyEvent(this, keypressEvent, false);
|
||||
} else {
|
||||
nsCocoaUtils::InitInputEvent(keypressEvent, static_cast<NSEvent*>(nullptr));
|
||||
keypressEvent.mKeyNameIndex = KEY_NAME_INDEX_USE_STRING;
|
||||
@ -2391,6 +2517,18 @@ TextInputHandler::HandleCommand(Command aCommand)
|
||||
return false;
|
||||
}
|
||||
|
||||
// When current keydown event causes this command, let's dispatch
|
||||
// eKeyDown event before any other events. Note that if we're in a
|
||||
// composition, we've already dispatched eKeyDown event from
|
||||
// TextInputHandler::HandleKeyDownEvent().
|
||||
RefPtr<TextInputHandler> kungFuDeathGrip(this);
|
||||
if (!IsIMEComposing() && !MaybeDispatchCurrentKeydownEvent(false)) {
|
||||
MOZ_LOG(gLog, LogLevel::Info,
|
||||
("%p IMEInputHandler::SetMarkedText, eKeyDown caused focus move or "
|
||||
"something and canceling the composition", this));
|
||||
return false;
|
||||
}
|
||||
|
||||
// If it's in composition, we cannot dispatch keypress event.
|
||||
// Therefore, we should use different approach or give up to handle
|
||||
// the command.
|
||||
@ -2487,7 +2625,7 @@ TextInputHandler::HandleCommand(Command aCommand)
|
||||
if (!dispatchFakeKeyPress) {
|
||||
// If we're acutally handling a key press, we should dispatch
|
||||
// the keypress event as-is.
|
||||
currentKeyEvent->InitKeyEvent(this, keypressEvent);
|
||||
currentKeyEvent->InitKeyEvent(this, keypressEvent, false);
|
||||
} else {
|
||||
// Otherwise, we should dispatch "fake" keypress event.
|
||||
// However, for making it possible to compute edit commands, we need to
|
||||
@ -2753,11 +2891,15 @@ TextInputHandler::DoCommandBySelector(const char* aSelector)
|
||||
|
||||
MOZ_LOG(gLog, LogLevel::Info,
|
||||
("%p TextInputHandler::DoCommandBySelector, aSelector=\"%s\", "
|
||||
"Destroyed()=%s, keydownHandled=%s, keypressHandled=%s, "
|
||||
"causedOtherKeyEvents=%s",
|
||||
"Destroyed()=%s, keydownDispatched=%s, keydownHandled=%s, "
|
||||
"keypressDispatched=%s, keypressHandled=%s, causedOtherKeyEvents=%s",
|
||||
this, aSelector ? aSelector : "", TrueOrFalse(Destroyed()),
|
||||
currentKeyEvent ?
|
||||
TrueOrFalse(currentKeyEvent->mKeyDownDispatched) : "N/A",
|
||||
currentKeyEvent ?
|
||||
TrueOrFalse(currentKeyEvent->mKeyDownHandled) : "N/A",
|
||||
currentKeyEvent ?
|
||||
TrueOrFalse(currentKeyEvent->mKeyPressDispatched) : "N/A",
|
||||
currentKeyEvent ?
|
||||
TrueOrFalse(currentKeyEvent->mKeyPressHandled) : "N/A",
|
||||
currentKeyEvent ?
|
||||
@ -2769,6 +2911,18 @@ TextInputHandler::DoCommandBySelector(const char* aSelector)
|
||||
return Destroyed();
|
||||
}
|
||||
|
||||
// When current keydown event causes this command, let's dispatch
|
||||
// eKeyDown event before any other events. Note that if we're in a
|
||||
// composition, we've already dispatched eKeyDown event from
|
||||
// TextInputHandler::HandleKeyDownEvent().
|
||||
RefPtr<TextInputHandler> kungFuDeathGrip(this);
|
||||
if (!IsIMEComposing() && !MaybeDispatchCurrentKeydownEvent(false)) {
|
||||
MOZ_LOG(gLog, LogLevel::Info,
|
||||
("%p IMEInputHandler::SetMarkedText, eKeyDown caused focus move or "
|
||||
"something and canceling the composition", this));
|
||||
return true;
|
||||
}
|
||||
|
||||
// If the key operation causes this command, should dispatch a keypress
|
||||
// event.
|
||||
// XXX This must be worng. Even if this command is caused by the key
|
||||
@ -2786,7 +2940,7 @@ TextInputHandler::DoCommandBySelector(const char* aSelector)
|
||||
}
|
||||
|
||||
WidgetKeyboardEvent keypressEvent(true, eKeyPress, widget);
|
||||
currentKeyEvent->InitKeyEvent(this, keypressEvent);
|
||||
currentKeyEvent->InitKeyEvent(this, keypressEvent, false);
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
currentKeyEvent->mKeyPressDispatched =
|
||||
@ -3399,6 +3553,11 @@ IMEInputHandler::DispatchCompositionStartEvent()
|
||||
|
||||
NS_ASSERTION(!mIsIMEComposing, "There is a composition already");
|
||||
mIsIMEComposing = true;
|
||||
KeyEventState* currentKeyEvent = GetCurrentKeyEvent();
|
||||
mIsDeadKeyComposing =
|
||||
currentKeyEvent && currentKeyEvent->mKeyEvent &&
|
||||
TISInputSourceWrapper::CurrentInputSource().
|
||||
IsDeadKey(currentKeyEvent->mKeyEvent);
|
||||
|
||||
nsEventStatus status;
|
||||
rv = mDispatcher->StartComposition(status);
|
||||
@ -3549,7 +3708,7 @@ IMEInputHandler::DispatchCompositionCommitEvent(const nsAString* aCommitString)
|
||||
}
|
||||
}
|
||||
|
||||
mIsIMEComposing = false;
|
||||
mIsIMEComposing = mIsDeadKeyComposing = false;
|
||||
mIMECompositionStart = UINT32_MAX;
|
||||
if (mIMECompositionString) {
|
||||
[mIMECompositionString release];
|
||||
@ -3568,6 +3727,89 @@ IMEInputHandler::DispatchCompositionCommitEvent(const nsAString* aCommitString)
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(false);
|
||||
}
|
||||
|
||||
bool
|
||||
IMEInputHandler::MaybeDispatchCurrentKeydownEvent(bool aIsProcessedByIME)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
if (Destroyed()) {
|
||||
return false;
|
||||
}
|
||||
MOZ_ASSERT(mWidget);
|
||||
|
||||
KeyEventState* currentKeyEvent = GetCurrentKeyEvent();
|
||||
if (!currentKeyEvent ||
|
||||
!currentKeyEvent->CanDispatchKeyDownEvent()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
NSEvent* nativeEvent = currentKeyEvent->mKeyEvent;
|
||||
if (NS_WARN_IF(!nativeEvent) ||
|
||||
[nativeEvent type] != NSKeyDown) {
|
||||
return true;
|
||||
}
|
||||
|
||||
MOZ_LOG(gLog, LogLevel::Info,
|
||||
("%p IMEInputHandler::MaybeDispatchKeydownEvent, aIsProcessedByIME=%s "
|
||||
"currentKeyEvent={ mKeyEvent(%p)={ type=%s, keyCode=%s (0x%X) } }, "
|
||||
"aIsProcesedBy=%s, IsDeadKeyComposing()=%s",
|
||||
this, TrueOrFalse(aIsProcessedByIME), nativeEvent,
|
||||
GetNativeKeyEventType(nativeEvent),
|
||||
GetKeyNameForNativeKeyCode([nativeEvent keyCode]), [nativeEvent keyCode],
|
||||
TrueOrFalse(IsIMEComposing()), TrueOrFalse(IsDeadKeyComposing())));
|
||||
|
||||
RefPtr<IMEInputHandler> kungFuDeathGrip(this);
|
||||
RefPtr<TextEventDispatcher> dispatcher(mDispatcher);
|
||||
nsresult rv = dispatcher->BeginNativeInputTransaction();
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
MOZ_LOG(gLog, LogLevel::Error,
|
||||
("%p IMEInputHandler::DispatchKeyEventForFlagsChanged, "
|
||||
"FAILED, due to BeginNativeInputTransaction() failure", this));
|
||||
return false;
|
||||
}
|
||||
|
||||
NSResponder* firstResponder = [[mView window] firstResponder];
|
||||
|
||||
// Mark currentKeyEvent as "dispatched eKeyDown event" and actually do it.
|
||||
currentKeyEvent->mKeyDownDispatched = true;
|
||||
|
||||
RefPtr<nsChildView> widget(mWidget);
|
||||
|
||||
WidgetKeyboardEvent keydownEvent(true, eKeyDown, widget);
|
||||
// Don't mark the eKeyDown event as "processed by IME" if the composition
|
||||
// is started with dead key.
|
||||
currentKeyEvent->InitKeyEvent(this, keydownEvent,
|
||||
aIsProcessedByIME && !IsDeadKeyComposing());
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
dispatcher->DispatchKeyboardEvent(eKeyDown, keydownEvent, status,
|
||||
currentKeyEvent);
|
||||
currentKeyEvent->mKeyDownHandled =
|
||||
(status == nsEventStatus_eConsumeNoDefault);
|
||||
|
||||
if (Destroyed()) {
|
||||
MOZ_LOG(gLog, LogLevel::Info,
|
||||
("%p IMEInputHandler::MaybeDispatchKeydownEvent, "
|
||||
"widget was destroyed by keydown event", this));
|
||||
return false;
|
||||
}
|
||||
|
||||
// The key down event may have shifted the focus, in which case, we should
|
||||
// not continue to handle current key sequence and let's commit current
|
||||
// composition.
|
||||
if (firstResponder != [[mView window] firstResponder]) {
|
||||
MOZ_LOG(gLog, LogLevel::Info,
|
||||
("%p IMEInputHandler::MaybeDispatchKeydownEvent, "
|
||||
"view lost focus by keydown event", this));
|
||||
CommitIMEComposition();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(false);
|
||||
}
|
||||
|
||||
void
|
||||
IMEInputHandler::InsertTextAsCommittingComposition(
|
||||
NSAttributedString* aAttrString,
|
||||
@ -3596,6 +3838,22 @@ IMEInputHandler::InsertTextAsCommittingComposition(
|
||||
return;
|
||||
}
|
||||
|
||||
// When current keydown event causes this text input, let's dispatch
|
||||
// eKeyDown event before any other events. Note that if we're in a
|
||||
// composition, we've already dispatched eKeyDown event from
|
||||
// TextInputHandler::HandleKeyDownEvent().
|
||||
// XXX Should we mark the eKeyDown event as "processed by IME"?
|
||||
// However, if the key causes two or more Unicode characters as
|
||||
// UTF-16 string, this is used. So, perhaps, we need to improve
|
||||
// HandleKeyDownEvent() before do that.
|
||||
RefPtr<IMEInputHandler> kungFuDeathGrip(this);
|
||||
if (!IsIMEComposing() && !MaybeDispatchCurrentKeydownEvent(false)) {
|
||||
MOZ_LOG(gLog, LogLevel::Info,
|
||||
("%p IMEInputHandler::InsertTextAsCommittingComposition, eKeyDown "
|
||||
"caused focus move or something and canceling the composition", this));
|
||||
return;
|
||||
}
|
||||
|
||||
// First, commit current composition with the latest composition string if the
|
||||
// replacement range is different from marked range.
|
||||
if (IsIMEComposing() && aReplacementRange &&
|
||||
@ -3610,8 +3868,6 @@ IMEInputHandler::InsertTextAsCommittingComposition(
|
||||
}
|
||||
}
|
||||
|
||||
RefPtr<IMEInputHandler> kungFuDeathGrip(this);
|
||||
|
||||
nsString str;
|
||||
nsCocoaUtils::GetStringForNSString([aAttrString string], str);
|
||||
|
||||
@ -3658,7 +3914,8 @@ IMEInputHandler::SetMarkedText(NSAttributedString* aAttrString,
|
||||
"aReplacementRange=%p { location=%lu, length=%lu }, "
|
||||
"Destroyed()=%s, IsIMEComposing()=%s, "
|
||||
"mMarkedRange={ location=%lu, length=%lu }, keyevent=%p, "
|
||||
"keydownHandled=%s, keypressDispatched=%s, causedOtherKeyEvents=%s, "
|
||||
"keydownDispatched=%s, keydownHandled=%s, "
|
||||
"keypressDispatched=%s, causedOtherKeyEvents=%s, "
|
||||
"compositionDispatched=%s",
|
||||
this, GetCharacters([aAttrString string]),
|
||||
static_cast<unsigned long>(aSelectedRange.location),
|
||||
@ -3669,6 +3926,8 @@ IMEInputHandler::SetMarkedText(NSAttributedString* aAttrString,
|
||||
static_cast<unsigned long>(mMarkedRange.location),
|
||||
static_cast<unsigned long>(mMarkedRange.length),
|
||||
currentKeyEvent ? currentKeyEvent->mKeyEvent : nullptr,
|
||||
currentKeyEvent ?
|
||||
TrueOrFalse(currentKeyEvent->mKeyDownDispatched) : "N/A",
|
||||
currentKeyEvent ?
|
||||
TrueOrFalse(currentKeyEvent->mKeyDownHandled) : "N/A",
|
||||
currentKeyEvent ?
|
||||
@ -3678,19 +3937,32 @@ IMEInputHandler::SetMarkedText(NSAttributedString* aAttrString,
|
||||
currentKeyEvent ?
|
||||
TrueOrFalse(currentKeyEvent->mCompositionDispatched) : "N/A"));
|
||||
|
||||
RefPtr<IMEInputHandler> kungFuDeathGrip(this);
|
||||
|
||||
// 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 mark the key event causing composition event.
|
||||
if (currentKeyEvent) {
|
||||
currentKeyEvent->mCompositionDispatched = true;
|
||||
|
||||
// When current keydown event causes this text input, let's dispatch
|
||||
// eKeyDown event before any other events. Note that if we're in a
|
||||
// composition, we've already dispatched eKeyDown event from
|
||||
// TextInputHandler::HandleKeyDownEvent(). On the other hand, if we're
|
||||
// not in composition, the key event starts new composition. So, we
|
||||
// need to mark the eKeyDown event as "processed by IME".
|
||||
if (!IsIMEComposing() && !MaybeDispatchCurrentKeydownEvent(true)) {
|
||||
MOZ_LOG(gLog, LogLevel::Info,
|
||||
("%p IMEInputHandler::SetMarkedText, eKeyDown caused focus move or "
|
||||
"something and canceling the composition", this));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (Destroyed()) {
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<IMEInputHandler> kungFuDeathGrip(this);
|
||||
|
||||
// First, commit current composition with the latest composition string if the
|
||||
// replacement range is different from marked range.
|
||||
if (IsIMEComposing() && aReplacementRange &&
|
||||
@ -4147,6 +4419,7 @@ IMEInputHandler::IMEInputHandler(nsChildView* aWidget,
|
||||
, mIMECompositionString(nullptr)
|
||||
, mIMECompositionStart(UINT32_MAX)
|
||||
, mIsIMEComposing(false)
|
||||
, mIsDeadKeyComposing(false)
|
||||
, mIsIMEEnabled(true)
|
||||
, mIsASCIICapableOnly(false)
|
||||
, mIgnoreIMECommit(false)
|
||||
@ -4305,13 +4578,15 @@ IMEInputHandler::CommitIMEComposition()
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
if (!IsIMEComposing())
|
||||
return;
|
||||
|
||||
MOZ_LOG(gLog, LogLevel::Info,
|
||||
("%p IMEInputHandler::CommitIMEComposition, mIMECompositionString=%s",
|
||||
this, GetCharacters(mIMECompositionString)));
|
||||
|
||||
// If this is called before dispatching eCompositionStart, IsIMEComposing()
|
||||
// returns false. Even in such case, we need to commit composition *in*
|
||||
// IME if this is called by preceding eKeyDown event of eCompositionStart.
|
||||
// So, we need to call KillIMEComposition() even when IsIMEComposing()
|
||||
// returns false.
|
||||
KillIMEComposition();
|
||||
|
||||
if (!IsIMEComposing())
|
||||
@ -4585,6 +4860,7 @@ TextInputHandlerBase::DispatchEvent(WidgetGUIEvent& aEvent)
|
||||
void
|
||||
TextInputHandlerBase::InitKeyEvent(NSEvent *aNativeKeyEvent,
|
||||
WidgetKeyboardEvent& aKeyEvent,
|
||||
bool aIsProcessedByIME,
|
||||
const nsAString* aInsertString)
|
||||
{
|
||||
NS_ASSERTION(aNativeKeyEvent, "aNativeKeyEvent must not be NULL");
|
||||
@ -4592,11 +4868,12 @@ TextInputHandlerBase::InitKeyEvent(NSEvent *aNativeKeyEvent,
|
||||
if (mKeyboardOverride.mOverrideEnabled) {
|
||||
TISInputSourceWrapper tis;
|
||||
tis.InitByLayoutID(mKeyboardOverride.mKeyboardLayout, true);
|
||||
tis.InitKeyEvent(aNativeKeyEvent, aKeyEvent, aInsertString);
|
||||
tis.InitKeyEvent(aNativeKeyEvent, aKeyEvent, aIsProcessedByIME,
|
||||
aInsertString);
|
||||
return;
|
||||
}
|
||||
TISInputSourceWrapper::CurrentInputSource().
|
||||
InitKeyEvent(aNativeKeyEvent, aKeyEvent, aInsertString);
|
||||
InitKeyEvent(aNativeKeyEvent, aKeyEvent, aIsProcessedByIME, aInsertString);
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -4889,7 +5166,8 @@ TextInputHandlerBase::EnsureSecureEventInputDisabled()
|
||||
void
|
||||
TextInputHandlerBase::KeyEventState::InitKeyEvent(
|
||||
TextInputHandlerBase* aHandler,
|
||||
WidgetKeyboardEvent& aKeyEvent)
|
||||
WidgetKeyboardEvent& aKeyEvent,
|
||||
bool aIsProcessedByIME)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
@ -4919,7 +5197,8 @@ TextInputHandlerBase::KeyEventState::InitKeyEvent(
|
||||
}
|
||||
|
||||
aKeyEvent.mUniqueId = mUniqueId;
|
||||
aHandler->InitKeyEvent(nativeEvent, aKeyEvent, mInsertString);
|
||||
aHandler->InitKeyEvent(nativeEvent, aKeyEvent, aIsProcessedByIME,
|
||||
mInsertString);
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user