Bug 855975 part.11 Sort out the if statement which checks whether the native keydown message needs to be handled without following char messages r=jimm

This commit is contained in:
Masayuki Nakano
2013-05-29 15:34:48 +09:00
parent 19fff406ac
commit eebe0b5bff
3 changed files with 61 additions and 15 deletions

View File

@@ -548,6 +548,9 @@ NativeKey::NativeKey(nsWindowBase* aWidget,
keyboardLayout->ConvertNativeKeyCodeToKeyNameIndex(mOriginalVirtualKeyCode); keyboardLayout->ConvertNativeKeyCodeToKeyNameIndex(mOriginalVirtualKeyCode);
keyboardLayout->InitNativeKey(*this, mModKeyState); keyboardLayout->InitNativeKey(*this, mModKeyState);
mIsDeadKey = keyboardLayout->IsDeadKey(mOriginalVirtualKeyCode, mModKeyState);
mIsPrintableKey = KeyboardLayout::IsPrintableCharKey(mOriginalVirtualKeyCode);
} }
UINT UINT
@@ -874,6 +877,35 @@ NativeKey::HandleKeyUpMessage(bool* aEventDispatched) const
return DispatchKeyEvent(keyupEvent, &mMsg); return DispatchKeyEvent(keyupEvent, &mMsg);
} }
bool
NativeKey::NeedsToHandleWithoutFollowingCharMessages() const
{
MOZ_ASSERT(mMsg.message == WM_KEYDOWN || mMsg.message == WM_SYSKEYDOWN);
// Enter and backspace are always handled here to avoid for example the
// confusion between ctrl-enter and ctrl-J.
if (mDOMKeyCode == NS_VK_RETURN || mDOMKeyCode == NS_VK_BACK) {
return true;
}
// If any modifier keys which may cause printable keys becoming non-printable
// are not pressed, we don't need special handling for the key.
if (!mModKeyState.IsControl() && !mModKeyState.IsAlt() &&
!mModKeyState.IsWin()) {
return false;
}
// If the key event causes dead key event, we don't need to dispatch keypress
// event.
if (mIsDeadKey) {
return false;
}
// Even if the key is a printable key, it might cause non-printable character
// input with modifier key(s).
return IsPrintableKey();
}
bool bool
NativeKey::DispatchKeyPressEventsWithKeyboardLayout( NativeKey::DispatchKeyPressEventsWithKeyboardLayout(
const UniCharsAndModifiers& aInputtingChars, const UniCharsAndModifiers& aInputtingChars,

View File

@@ -296,6 +296,14 @@ public:
{ {
return (mMsg.message == WM_KEYDOWN || mMsg.message == WM_SYSKEYDOWN); return (mMsg.message == WM_KEYDOWN || mMsg.message == WM_SYSKEYDOWN);
} }
bool IsDeadKey() const { return mIsDeadKey; }
/**
* IsPrintableKey() returns true if the key may be a printable key without
* any modifier keys. Otherwise, false.
* Please note that the event may not cause any text input even if this
* returns true. E.g., it might be dead key state or Ctrl key may be pressed.
*/
inline bool IsPrintableKey() const { return mIsPrintableKey; }
WORD GetScanCode() const { return mScanCode; } WORD GetScanCode() const { return mScanCode; }
uint8_t GetVirtualKeyCode() const { return mVirtualKeyCode; } uint8_t GetVirtualKeyCode() const { return mVirtualKeyCode; }
uint8_t GetOriginalVirtualKeyCode() const { return mOriginalVirtualKeyCode; } uint8_t GetOriginalVirtualKeyCode() const { return mOriginalVirtualKeyCode; }
@@ -340,6 +348,15 @@ public:
const UniCharsAndModifiers& aInputtingChars, const UniCharsAndModifiers& aInputtingChars,
const EventFlags& aExtraFlags) const; const EventFlags& aExtraFlags) const;
/**
* Checkes whether the key event down message is handled without following
* WM_CHAR messages. For example, if following WM_CHAR message indicates
* control character input, the WM_CHAR message is unclear whether it's
* caused by a printable key with Ctrl or just a function key such as Enter
* or Backspace.
*/
bool NeedsToHandleWithoutFollowingCharMessages() const;
/** /**
* Dspatces keydown event. Retrns true if the event is consumed. * Dspatces keydown event. Retrns true if the event is consumed.
* Otherwise, false. * Otherwise, false.
@@ -385,6 +402,8 @@ private:
WORD mScanCode; WORD mScanCode;
bool mIsExtended; bool mIsExtended;
bool mIsDeadKey;
bool mIsPrintableKey;
NativeKey() NativeKey()
{ {

View File

@@ -6463,8 +6463,6 @@ LRESULT nsWindow::OnKeyDown(const MSG &aMsg,
return noDefault; return noDefault;
} }
UINT virtualKeyCode = nativeKey.GetOriginalVirtualKeyCode();
bool isDeadKey = keyboardLayout->IsDeadKey(virtualKeyCode, aModKeyState);
EventFlags extraFlags; EventFlags extraFlags;
extraFlags.mDefaultPrevented = noDefault; extraFlags.mDefaultPrevented = noDefault;
MSG msg; MSG msg;
@@ -6473,10 +6471,7 @@ LRESULT nsWindow::OnKeyDown(const MSG &aMsg,
PM_NOREMOVE | PM_NOYIELD); PM_NOREMOVE | PM_NOYIELD);
// Enter and backspace are always handled here to avoid for example the // Enter and backspace are always handled here to avoid for example the
// confusion between ctrl-enter and ctrl-J. // confusion between ctrl-enter and ctrl-J.
if (DOMKeyCode == NS_VK_RETURN || DOMKeyCode == NS_VK_BACK || if (nativeKey.NeedsToHandleWithoutFollowingCharMessages()) {
((aModKeyState.IsControl() || aModKeyState.IsAlt() || aModKeyState.IsWin())
&& !isDeadKey && KeyboardLayout::IsPrintableCharKey(virtualKeyCode)))
{
// Remove a possible WM_CHAR or WM_SYSCHAR messages from the message queue. // Remove a possible WM_CHAR or WM_SYSCHAR messages from the message queue.
// They can be more than one because of: // They can be more than one because of:
// * Dead-keys not pairing with base character // * Dead-keys not pairing with base character
@@ -6518,13 +6513,14 @@ LRESULT nsWindow::OnKeyDown(const MSG &aMsg,
return false; return false;
} }
#ifdef DEBUG #ifdef DEBUG
if (KeyboardLayout::IsPrintableCharKey(virtualKeyCode)) { if (nativeKey.IsPrintableKey()) {
nsPrintfCString log( nsPrintfCString log(
"virtualKeyCode=0x%02X, inputtingChar={ mChars=[ 0x%04X, 0x%04X, " "OriginalVirtualKeyCode=0x%02X, inputtingChar={ mChars=[ 0x%04X, "
"0x%04X, 0x%04X, 0x%04X ], mLength=%d }, wParam=0x%04X", "0x%04X, 0x%04X, 0x%04X, 0x%04X ], mLength=%d }, wParam=0x%04X",
virtualKeyCode, inputtingChars.mChars[0], inputtingChars.mChars[1], nativeKey.GetOriginalVirtualKeyCode(), inputtingChars.mChars[0],
inputtingChars.mChars[2], inputtingChars.mChars[3], inputtingChars.mChars[1], inputtingChars.mChars[2],
inputtingChars.mChars[4], inputtingChars.mLength, msg.wParam); inputtingChars.mChars[3], inputtingChars.mChars[4],
inputtingChars.mLength, msg.wParam);
if (!inputtingChars.mLength) { if (!inputtingChars.mLength) {
log.Insert("length is zero: ", 0); log.Insert("length is zero: ", 0);
NS_ERROR(log.get()); NS_ERROR(log.get());
@@ -6565,15 +6561,14 @@ LRESULT nsWindow::OnKeyDown(const MSG &aMsg,
return static_cast<LRESULT>(result); return static_cast<LRESULT>(result);
} }
else if (!aModKeyState.IsControl() && !aModKeyState.IsAlt() && else if (!aModKeyState.IsControl() && !aModKeyState.IsAlt() &&
!aModKeyState.IsWin() && !aModKeyState.IsWin() && nativeKey.IsPrintableKey()) {
KeyboardLayout::IsPrintableCharKey(virtualKeyCode)) {
// If this is simple KeyDown event but next message is not WM_CHAR, // If this is simple KeyDown event but next message is not WM_CHAR,
// this event may not input text, so we should ignore this event. // this event may not input text, so we should ignore this event.
// See bug 314130. // See bug 314130.
return PluginHasFocus() && noDefault; return PluginHasFocus() && noDefault;
} }
if (isDeadKey) { if (nativeKey.IsDeadKey()) {
return PluginHasFocus() && noDefault; return PluginHasFocus() && noDefault;
} }