mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-26 14:22:01 +00:00
Bug 842927 part.3 Implement D3E KeyboardEvent.key on Windows (Desktop) r=smaug+jimm
This commit is contained in:
parent
a14e2178fc
commit
877ab22109
@ -384,7 +384,8 @@ VirtualKey::FillKbdState(PBYTE aKbdState,
|
||||
NativeKey::NativeKey(const KeyboardLayout& aKeyboardLayout,
|
||||
nsWindow* aWindow,
|
||||
const MSG& aKeyOrCharMessage) :
|
||||
mDOMKeyCode(0), mVirtualKeyCode(0), mOriginalVirtualKeyCode(0)
|
||||
mDOMKeyCode(0), mMessage(aKeyOrCharMessage.message),
|
||||
mVirtualKeyCode(0), mOriginalVirtualKeyCode(0)
|
||||
{
|
||||
mScanCode = WinUtils::GetScanCode(aKeyOrCharMessage.lParam);
|
||||
mIsExtended = WinUtils::IsExtendedScanCode(aKeyOrCharMessage.lParam);
|
||||
@ -392,7 +393,7 @@ NativeKey::NativeKey(const KeyboardLayout& aKeyboardLayout,
|
||||
// extended keys due to the API limitation.
|
||||
bool canComputeVirtualKeyCodeFromScanCode =
|
||||
(!mIsExtended || WinUtils::GetWindowsVersion() >= WinUtils::VISTA_VERSION);
|
||||
switch (aKeyOrCharMessage.message) {
|
||||
switch (mMessage) {
|
||||
case WM_KEYDOWN:
|
||||
case WM_KEYUP:
|
||||
case WM_SYSKEYDOWN:
|
||||
@ -540,6 +541,8 @@ NativeKey::NativeKey(const KeyboardLayout& aKeyboardLayout,
|
||||
|
||||
mDOMKeyCode =
|
||||
aKeyboardLayout.ConvertNativeKeyCodeToDOMKeyCode(mOriginalVirtualKeyCode);
|
||||
mKeyNameIndex =
|
||||
aKeyboardLayout.ConvertNativeKeyCodeToKeyNameIndex(mOriginalVirtualKeyCode);
|
||||
}
|
||||
|
||||
UINT
|
||||
@ -659,48 +662,66 @@ KeyboardLayout::IsDeadKey(uint8_t aVirtualKey,
|
||||
VirtualKey::ModifiersToShiftState(aModKeyState.GetModifiers()));
|
||||
}
|
||||
|
||||
UniCharsAndModifiers
|
||||
KeyboardLayout::OnKeyDown(uint8_t aVirtualKey,
|
||||
const ModifierKeyState& aModKeyState)
|
||||
void
|
||||
KeyboardLayout::InitNativeKey(NativeKey& aNativeKey,
|
||||
const ModifierKeyState& aModKeyState)
|
||||
{
|
||||
if (mPendingKeyboardLayout) {
|
||||
LoadLayout(mPendingKeyboardLayout);
|
||||
}
|
||||
|
||||
int32_t virtualKeyIndex = GetKeyIndex(aVirtualKey);
|
||||
uint8_t virtualKey = aNativeKey.GetOriginalVirtualKeyCode();
|
||||
int32_t virtualKeyIndex = GetKeyIndex(virtualKey);
|
||||
|
||||
if (virtualKeyIndex < 0) {
|
||||
// Does not produce any printable characters, but still preserves the
|
||||
// dead-key state.
|
||||
return UniCharsAndModifiers();
|
||||
return;
|
||||
}
|
||||
|
||||
bool isKeyDown = aNativeKey.IsKeyDownMessage();
|
||||
uint8_t shiftState =
|
||||
VirtualKey::ModifiersToShiftState(aModKeyState.GetModifiers());
|
||||
|
||||
if (mVirtualKeys[virtualKeyIndex].IsDeadKey(shiftState)) {
|
||||
if (mActiveDeadKey < 0) {
|
||||
// Dead-key state activated. No characters generated.
|
||||
mActiveDeadKey = aVirtualKey;
|
||||
mDeadKeyShiftState = shiftState;
|
||||
return UniCharsAndModifiers();
|
||||
if ((isKeyDown && mActiveDeadKey < 0) ||
|
||||
(!isKeyDown && mActiveDeadKey == virtualKey)) {
|
||||
// First dead key event doesn't generate characters.
|
||||
if (isKeyDown) {
|
||||
// Dead-key state activated at keydown.
|
||||
mActiveDeadKey = virtualKey;
|
||||
mDeadKeyShiftState = shiftState;
|
||||
}
|
||||
UniCharsAndModifiers deadChars =
|
||||
mVirtualKeys[virtualKeyIndex].GetNativeUniChars(shiftState);
|
||||
NS_ASSERTION(deadChars.mLength == 1,
|
||||
"dead key must generate only one character");
|
||||
aNativeKey.mKeyNameIndex =
|
||||
WidgetUtils::GetDeadKeyNameIndex(deadChars.mChars[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
// Dead-key followed by another dead-key. Reset dead-key state and
|
||||
// return both dead-key characters.
|
||||
int32_t activeDeadKeyIndex = GetKeyIndex(mActiveDeadKey);
|
||||
UniCharsAndModifiers result =
|
||||
UniCharsAndModifiers prevDeadChars =
|
||||
mVirtualKeys[activeDeadKeyIndex].GetUniChars(mDeadKeyShiftState);
|
||||
result += mVirtualKeys[virtualKeyIndex].GetUniChars(shiftState);
|
||||
DeactivateDeadKeyState();
|
||||
return result;
|
||||
UniCharsAndModifiers newChars =
|
||||
mVirtualKeys[virtualKeyIndex].GetUniChars(shiftState);
|
||||
// But keypress events should be fired for each committed character.
|
||||
aNativeKey.mCommittedCharsAndModifiers = prevDeadChars + newChars;
|
||||
if (isKeyDown) {
|
||||
DeactivateDeadKeyState();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
UniCharsAndModifiers baseChars =
|
||||
mVirtualKeys[virtualKeyIndex].GetUniChars(shiftState);
|
||||
if (mActiveDeadKey < 0) {
|
||||
// No dead-keys are active. Just return the produced characters.
|
||||
return baseChars;
|
||||
aNativeKey.mCommittedCharsAndModifiers = baseChars;
|
||||
return;
|
||||
}
|
||||
|
||||
// Dead-key was active. See if pressed base character does produce
|
||||
@ -712,20 +733,25 @@ KeyboardLayout::OnKeyDown(uint8_t aVirtualKey,
|
||||
if (compositeChar) {
|
||||
// Active dead-key and base character does produce exactly one
|
||||
// composite character.
|
||||
UniCharsAndModifiers result;
|
||||
result.Append(compositeChar, baseChars.mModifiers[0]);
|
||||
DeactivateDeadKeyState();
|
||||
return result;
|
||||
aNativeKey.mCommittedCharsAndModifiers.Append(compositeChar,
|
||||
baseChars.mModifiers[0]);
|
||||
if (isKeyDown) {
|
||||
DeactivateDeadKeyState();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// There is no valid dead-key and base character combination.
|
||||
// Return dead-key character followed by base character.
|
||||
UniCharsAndModifiers result =
|
||||
UniCharsAndModifiers deadChars =
|
||||
mVirtualKeys[activeDeadKeyIndex].GetUniChars(mDeadKeyShiftState);
|
||||
result += baseChars;
|
||||
DeactivateDeadKeyState();
|
||||
// But keypress events should be fired for each committed character.
|
||||
aNativeKey.mCommittedCharsAndModifiers = deadChars + baseChars;
|
||||
if (isKeyDown) {
|
||||
DeactivateDeadKeyState();
|
||||
}
|
||||
|
||||
return result;
|
||||
return;
|
||||
}
|
||||
|
||||
UniCharsAndModifiers
|
||||
@ -1254,6 +1280,24 @@ KeyboardLayout::ConvertNativeKeyCodeToDOMKeyCode(UINT aNativeKeyCode) const
|
||||
return 0;
|
||||
}
|
||||
|
||||
KeyNameIndex
|
||||
KeyboardLayout::ConvertNativeKeyCodeToKeyNameIndex(uint8_t aVirtualKey) const
|
||||
{
|
||||
switch (aVirtualKey) {
|
||||
|
||||
#define NS_NATIVE_KEY_TO_DOM_KEY_NAME_INDEX(aNativeKey, aKeyNameIndex) \
|
||||
case aNativeKey: return aKeyNameIndex;
|
||||
|
||||
#include "NativeKeyToDOMKeyName.h"
|
||||
|
||||
#undef NS_NATIVE_KEY_TO_DOM_KEY_NAME_INDEX
|
||||
|
||||
default:
|
||||
return IsPrintableCharKey(aVirtualKey) ? KEY_NAME_INDEX_PrintableKey :
|
||||
KEY_NAME_INDEX_Unidentified;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
* mozilla::widget::DeadKeyTable
|
||||
*****************************************************************************/
|
||||
|
@ -271,7 +271,8 @@ public:
|
||||
class NativeKey {
|
||||
public:
|
||||
NativeKey() :
|
||||
mDOMKeyCode(0), mVirtualKeyCode(0), mOriginalVirtualKeyCode(0),
|
||||
mDOMKeyCode(0), mKeyNameIndex(KEY_NAME_INDEX_Unidentified),
|
||||
mMessage(0), mVirtualKeyCode(0), mOriginalVirtualKeyCode(0),
|
||||
mScanCode(0), mIsExtended(false)
|
||||
{
|
||||
}
|
||||
@ -281,25 +282,48 @@ public:
|
||||
const MSG& aKeyOrCharMessage);
|
||||
|
||||
uint32_t GetDOMKeyCode() const { return mDOMKeyCode; }
|
||||
KeyNameIndex GetKeyNameIndex() const { return mKeyNameIndex; }
|
||||
const UniCharsAndModifiers& GetCommittedCharsAndModifiers() const
|
||||
{
|
||||
return mCommittedCharsAndModifiers;
|
||||
}
|
||||
|
||||
// The result is one of nsIDOMKeyEvent::DOM_KEY_LOCATION_*.
|
||||
uint32_t GetKeyLocation() const;
|
||||
UINT GetMessage() const { return mMessage; }
|
||||
bool IsKeyDownMessage() const
|
||||
{
|
||||
return (mMessage == WM_KEYDOWN || mMessage == WM_SYSKEYDOWN);
|
||||
}
|
||||
WORD GetScanCode() const { return mScanCode; }
|
||||
uint8_t GetVirtualKeyCode() const { return mVirtualKeyCode; }
|
||||
uint8_t GetOriginalVirtualKeyCode() const { return mOriginalVirtualKeyCode; }
|
||||
|
||||
private:
|
||||
uint32_t mDOMKeyCode;
|
||||
KeyNameIndex mKeyNameIndex;
|
||||
|
||||
// The message which the instance was initialized with.
|
||||
UINT mMessage;
|
||||
|
||||
// mVirtualKeyCode distinguishes left key or right key of modifier key.
|
||||
uint8_t mVirtualKeyCode;
|
||||
// mOriginalVirtualKeyCode doesn't distinguish left key or right key of
|
||||
// modifier key. However, if the given keycode is VK_PROCESS, it's resolved
|
||||
// to a keycode before it's handled by IME.
|
||||
uint8_t mOriginalVirtualKeyCode;
|
||||
|
||||
// mCommittedChars indicates the inputted characters which is committed by
|
||||
// the key. If dead key fail to composite a character, mCommittedChars
|
||||
// indicates both the dead characters and the base characters.
|
||||
UniCharsAndModifiers mCommittedCharsAndModifiers;
|
||||
|
||||
WORD mScanCode;
|
||||
bool mIsExtended;
|
||||
|
||||
UINT GetScanCodeWithExtendedFlag() const;
|
||||
|
||||
friend class KeyboardLayout;
|
||||
};
|
||||
|
||||
class KeyboardLayout
|
||||
@ -357,12 +381,13 @@ public:
|
||||
const ModifierKeyState& aModKeyState) const;
|
||||
|
||||
/**
|
||||
* OnKeyDown() must be called when actually widget receives WM_KEYDOWN
|
||||
* message. This method is stateful. This saves current dead key state
|
||||
* and computes current inputted character(s).
|
||||
* InitNativeKey() must be called when actually widget receives WM_KEYDOWN or
|
||||
* WM_KEYUP. This method is stateful. This saves current dead key state at
|
||||
* WM_KEYDOWN. Additionally, computes current inputted character(s) and set
|
||||
* them to the aNativeKey.
|
||||
*/
|
||||
UniCharsAndModifiers OnKeyDown(uint8_t aVirtualKey,
|
||||
const ModifierKeyState& aModKeyState);
|
||||
void InitNativeKey(NativeKey& aNativeKey,
|
||||
const ModifierKeyState& aModKeyState);
|
||||
|
||||
/**
|
||||
* LoadLayout() loads the keyboard layout. If aLoadLater is true,
|
||||
@ -372,6 +397,12 @@ public:
|
||||
|
||||
uint32_t ConvertNativeKeyCodeToDOMKeyCode(UINT aNativeKeyCode) const;
|
||||
|
||||
/**
|
||||
* ConvertNativeKeyCodeToKeyNameIndex() returns KeyNameIndex value for
|
||||
* non-printable keys (except some special keys like space key).
|
||||
*/
|
||||
KeyNameIndex ConvertNativeKeyCodeToKeyNameIndex(uint8_t aVirtualKey) const;
|
||||
|
||||
HKL GetLayout() const
|
||||
{
|
||||
return mPendingKeyboardLayout ? mPendingKeyboardLayout : mKeyboardLayout;
|
||||
|
@ -3622,6 +3622,7 @@ void nsWindow::InitKeyEvent(nsKeyEvent& aKeyEvent,
|
||||
{
|
||||
nsIntPoint point(0, 0);
|
||||
InitEvent(aKeyEvent, &point);
|
||||
aKeyEvent.mKeyNameIndex = aNativeKey.GetKeyNameIndex();
|
||||
aKeyEvent.location = aNativeKey.GetKeyLocation();
|
||||
aModKeyState.InitInputEvent(aKeyEvent);
|
||||
}
|
||||
@ -5654,6 +5655,7 @@ LRESULT nsWindow::ProcessCharMessage(const MSG &aMsg, bool *aEventDispatched)
|
||||
// if a child window didn't handle it (for example Alt+Space in a content window)
|
||||
ModifierKeyState modKeyState;
|
||||
NativeKey nativeKey(gKbdLayout, this, aMsg);
|
||||
gKbdLayout.InitNativeKey(nativeKey, modKeyState);
|
||||
return OnChar(aMsg, nativeKey, modKeyState, aEventDispatched);
|
||||
}
|
||||
|
||||
@ -6461,12 +6463,9 @@ LRESULT nsWindow::OnKeyDown(const MSG &aMsg,
|
||||
nsFakeCharMessage* aFakeCharMessage)
|
||||
{
|
||||
NativeKey nativeKey(gKbdLayout, this, aMsg);
|
||||
UINT virtualKeyCode = nativeKey.GetOriginalVirtualKeyCode();
|
||||
gKbdLayout.InitNativeKey(nativeKey, aModKeyState);
|
||||
UniCharsAndModifiers inputtingChars =
|
||||
gKbdLayout.OnKeyDown(virtualKeyCode, aModKeyState);
|
||||
|
||||
// Use only DOMKeyCode for XP processing.
|
||||
// Use virtualKeyCode for gKbdLayout and native processing.
|
||||
nativeKey.GetCommittedCharsAndModifiers();
|
||||
uint32_t DOMKeyCode = nativeKey.GetDOMKeyCode();
|
||||
|
||||
#ifdef DEBUG
|
||||
@ -6554,6 +6553,7 @@ LRESULT nsWindow::OnKeyDown(const MSG &aMsg,
|
||||
return noDefault;
|
||||
}
|
||||
|
||||
UINT virtualKeyCode = nativeKey.GetOriginalVirtualKeyCode();
|
||||
bool isDeadKey = gKbdLayout.IsDeadKey(virtualKeyCode, aModKeyState);
|
||||
EventFlags extraFlags;
|
||||
extraFlags.mDefaultPrevented = noDefault;
|
||||
@ -6830,6 +6830,7 @@ LRESULT nsWindow::OnKeyUp(const MSG &aMsg,
|
||||
*aEventDispatched = true;
|
||||
nsKeyEvent keyupEvent(true, NS_KEY_UP, this);
|
||||
NativeKey nativeKey(gKbdLayout, this, aMsg);
|
||||
gKbdLayout.InitNativeKey(nativeKey, aModKeyState);
|
||||
keyupEvent.keyCode = nativeKey.GetDOMKeyCode();
|
||||
InitKeyEvent(keyupEvent, nativeKey, aModKeyState);
|
||||
// Set defaultPrevented of the key event if the VK_MENU is not a system key
|
||||
|
Loading…
Reference in New Issue
Block a user