diff --git a/widget/windows/KeyboardLayout.cpp b/widget/windows/KeyboardLayout.cpp index 1e0d22a97e56..43571fc1688e 100644 --- a/widget/windows/KeyboardLayout.cpp +++ b/widget/windows/KeyboardLayout.cpp @@ -355,12 +355,24 @@ KeyboardLayout::IsNumpadKey(PRUint8 aVirtualKey) return VK_NUMPAD0 <= aVirtualKey && aVirtualKey <= VK_DIVIDE; } +bool +KeyboardLayout::IsDeadKey(PRUint8 aVirtualKey, + PRUint8 aShiftState) const +{ + PRInt32 virtualKeyIndex = GetKeyIndex(aVirtualKey); + if (virtualKeyIndex < 0) { + return false; + } + + return mVirtualKeys[virtualKeyIndex].IsDeadKey(aShiftState); +} + void KeyboardLayout::OnKeyDown(PRUint8 aVirtualKey) { - mLastVirtualKeyIndex = GetKeyIndex(aVirtualKey); + PRInt32 virtualKeyIndex = GetKeyIndex(aVirtualKey); - if (mLastVirtualKeyIndex < 0) { + if (virtualKeyIndex < 0) { // Does not produce any printable characters, but still preserves the // dead-key state. mNumOfChars = 0; @@ -372,13 +384,13 @@ KeyboardLayout::OnKeyDown(PRUint8 aVirtualKey) return; } - mLastShiftState = GetShiftState(kbdState); + PRUint8 shiftState = GetShiftState(kbdState); - if (mVirtualKeys[mLastVirtualKeyIndex].IsDeadKey(mLastShiftState)) { + if (mVirtualKeys[virtualKeyIndex].IsDeadKey(shiftState)) { if (mActiveDeadKey < 0) { // Dead-key state activated. No characters generated. mActiveDeadKey = aVirtualKey; - mDeadKeyShiftState = mLastShiftState; + mDeadKeyShiftState = shiftState; mNumOfChars = 0; return; } @@ -388,9 +400,8 @@ KeyboardLayout::OnKeyDown(PRUint8 aVirtualKey) PRInt32 activeDeadKeyIndex = GetKeyIndex(mActiveDeadKey); mVirtualKeys[activeDeadKeyIndex].GetUniChars(mDeadKeyShiftState, mChars, mShiftStates); - mVirtualKeys[mLastVirtualKeyIndex].GetUniChars(mLastShiftState, - &mChars[1], - &mShiftStates[1]); + mVirtualKeys[virtualKeyIndex].GetUniChars(shiftState, &mChars[1], + &mShiftStates[1]); mNumOfChars = 2; DeactivateDeadKeyState(); return; @@ -399,8 +410,8 @@ KeyboardLayout::OnKeyDown(PRUint8 aVirtualKey) PRUint8 finalShiftState; PRUnichar uniChars[5]; PRUint32 numOfBaseChars = - mVirtualKeys[mLastVirtualKeyIndex].GetUniChars(mLastShiftState, uniChars, - &finalShiftState); + mVirtualKeys[virtualKeyIndex].GetUniChars(shiftState, uniChars, + &finalShiftState); if (mActiveDeadKey < 0) { // No dead-keys are active. Just return the produced characters. memcpy(mChars, uniChars, numOfBaseChars * sizeof(PRUnichar)); @@ -560,6 +571,19 @@ KeyboardLayout::LoadLayout(HKL aLayout) } +// static +PRUint8 +KeyboardLayout::GetShiftState(const nsModifierKeyState& aModifierKeyState) +{ + bool isShift = !!aModifierKeyState.mIsShiftDown; + bool isCtrl = !!aModifierKeyState.mIsControlDown; + bool isAlt = !!aModifierKeyState.mIsAltDown; + bool isCaps = !!aModifierKeyState.mIsCapsLocked; + + return ((isCaps << 3) | (isAlt << 2) | (isCtrl << 1) | isShift); +} + +// static PRUint8 KeyboardLayout::GetShiftState(const PBYTE aKbdState) { diff --git a/widget/windows/KeyboardLayout.h b/widget/windows/KeyboardLayout.h index 3188e7202596..f2d8e7b8a6da 100644 --- a/widget/windows/KeyboardLayout.h +++ b/widget/windows/KeyboardLayout.h @@ -27,6 +27,7 @@ #define VK_OEM_CLEAR 0xFE class nsWindow; +struct nsModifierKeyState; namespace mozilla { namespace widget { @@ -162,8 +163,6 @@ class KeyboardLayout DeadKeyTableListEntry* mDeadKeyTableListHead; PRInt32 mActiveDeadKey; // -1 = no active dead-key PRUint8 mDeadKeyShiftState; - PRInt32 mLastVirtualKeyIndex; - PRUint8 mLastShiftState; PRUnichar mChars[5]; // Dead-key + up to 4 characters PRUint8 mShiftStates[5]; PRUint8 mNumOfChars; @@ -191,14 +190,18 @@ public: KeyboardLayout(); ~KeyboardLayout(); + /** + * GetShiftState() returns shift state for aModifierKeyState. + */ + static PRUint8 GetShiftState(const nsModifierKeyState& aModifierKeyState); + static bool IsPrintableCharKey(PRUint8 aVirtualKey); static bool IsNumpadKey(PRUint8 aVirtualKey); - bool IsDeadKey() const - { - return (mLastVirtualKeyIndex >= 0) ? - mVirtualKeys[mLastVirtualKeyIndex].IsDeadKey(mLastShiftState) : false; - } + /** + * IsDeadKey() returns true if aVirtualKey is a dead key with aShiftState. + */ + bool IsDeadKey(PRUint8 aVirtualKey, PRUint8 aShiftState) const; void LoadLayout(HKL aLayout); void OnKeyDown(PRUint8 aVirtualKey); diff --git a/widget/windows/nsWindow.cpp b/widget/windows/nsWindow.cpp index 58abcf7f3852..e4f638970923 100644 --- a/widget/windows/nsWindow.cpp +++ b/widget/windows/nsWindow.cpp @@ -6322,6 +6322,8 @@ LRESULT nsWindow::OnKeyDown(const MSG &aMsg, return noDefault; } + PRUint8 currentShiftState = KeyboardLayout::GetShiftState(aModKeyState); + bool isDeadKey = gKbdLayout.IsDeadKey(virtualKeyCode, currentShiftState); PRUint32 extraFlags = (noDefault ? NS_EVENT_FLAG_NO_DEFAULT : 0); MSG msg; BOOL gotMsg = aFakeCharMessage || @@ -6330,7 +6332,7 @@ LRESULT nsWindow::OnKeyDown(const MSG &aMsg, // confusion between ctrl-enter and ctrl-J. if (DOMKeyCode == NS_VK_RETURN || DOMKeyCode == NS_VK_BACK || ((aModKeyState.mIsControlDown || aModKeyState.mIsAltDown) - && !gKbdLayout.IsDeadKey() && KeyboardLayout::IsPrintableCharKey(virtualKeyCode))) + && !isDeadKey && KeyboardLayout::IsPrintableCharKey(virtualKeyCode))) { // Remove a possible WM_CHAR or WM_SYSCHAR messages from the message queue. // They can be more than one because of: @@ -6405,8 +6407,9 @@ LRESULT nsWindow::OnKeyDown(const MSG &aMsg, return PluginHasFocus() && noDefault; } - if (gKbdLayout.IsDeadKey ()) + if (isDeadKey) { return PluginHasFocus() && noDefault; + } PRUint8 shiftStates[5]; PRUnichar uniChars[5];