Bug 843236 Use widget::KeyboardLayout and widget::NativeKey for handling key messages on Metrofox r=tabraldes

This commit is contained in:
Masayuki Nakano 2013-07-02 13:55:58 +09:00
parent 8702a7d71d
commit a4d314bcea
4 changed files with 71 additions and 574 deletions

View File

@ -33,6 +33,7 @@ public:
/*
* Dispatch a gecko event for this widget.
* Returns true if it's consumed. Otherwise, false.
*/
virtual bool DispatchWindowEvent(nsGUIEvent* aEvent) = 0;

View File

@ -98,12 +98,6 @@ namespace {
pressure);
}
bool
IsControlCharacter(uint32_t aCharCode) {
return (0x1F >= aCharCode
|| (0x7F <= aCharCode && 0x9F >= aCharCode));
}
/**
* Converts from the Devices::Input::PointerDeviceType enumeration
* to a nsIDOMMouseEvent::MOZ_SOURCE_* value.
@ -177,7 +171,6 @@ MetroInput::MetroInput(MetroWidget* aWidget,
mTokenPointerEntered.value = 0;
mTokenPointerExited.value = 0;
mTokenPointerWheelChanged.value = 0;
mTokenAcceleratorKeyActivated.value = 0;
mTokenEdgeStarted.value = 0;
mTokenEdgeCanceled.value = 0;
mTokenEdgeCompleted.value = 0;
@ -189,12 +182,6 @@ MetroInput::MetroInput(MetroWidget* aWidget,
mTouches.Init();
// Note that this is not thread-safe.
if (!sIsVirtualKeyMapInitialized) {
InitializeVirtualKeyMap();
sIsVirtualKeyMapInitialized = true;
}
// Create our Gesture Recognizer
ActivateGenericInstance(RuntimeClass_Windows_UI_Input_GestureRecognizer,
mGestureRecognizer);
@ -209,49 +196,6 @@ MetroInput::~MetroInput()
UnregisterInputEvents();
}
/**
* This function handles the `AcceleratorKeyActivated` event, which is fired
* every time a keyboard key is pressed or released, and every time that a
* character (unicode or otherwise) is identified as having been inputted
* by the user.
*
* @param sender the CoreDispatcher that fired this event
* @param aArgs the event-specific args we use when processing this event
* @returns S_OK
*/
HRESULT
MetroInput::OnAcceleratorKeyActivated(UI::Core::ICoreDispatcher* sender,
UI::Core::IAcceleratorKeyEventArgs* aArgs) {
UI::Core::CoreAcceleratorKeyEventType type;
System::VirtualKey vkey;
aArgs->get_EventType(&type);
aArgs->get_VirtualKey(&vkey);
#ifdef DEBUG_INPUT
LogFunction();
Log("Accelerator key! Type: %d Value: %d", type, vkey);
#endif
switch(type) {
case UI::Core::CoreAcceleratorKeyEventType_KeyUp:
case UI::Core::CoreAcceleratorKeyEventType_SystemKeyUp:
OnKeyUp(vkey);
break;
case UI::Core::CoreAcceleratorKeyEventType_KeyDown:
case UI::Core::CoreAcceleratorKeyEventType_SystemKeyDown:
OnKeyDown(vkey);
break;
case UI::Core::CoreAcceleratorKeyEventType_Character:
case UI::Core::CoreAcceleratorKeyEventType_SystemCharacter:
case UI::Core::CoreAcceleratorKeyEventType_UnicodeCharacter:
OnCharacterReceived(vkey);
break;
}
return S_OK;
}
/**
* When the user swipes her/his finger in from the top of the screen,
* we receive this event.
@ -423,104 +367,6 @@ MetroInput::OnPointerWheelChanged(UI::Core::ICoreWindow* aSender,
return S_OK;
}
// This helper function is used when a character has been received by our
// app. This function is responsible for sending an appropriate gecko
// event in response to the character entered.
void
MetroInput::OnCharacterReceived(uint32_t aCharCode)
{
// We only send NS_KEY_PRESS events for printable characters
if (IsControlCharacter(aCharCode)) {
return;
}
nsKeyEvent keyEvent(true, NS_KEY_PRESS, mWidget.Get());
mModifierKeyState.Update();
if (mModifierKeyState.IsAltGr()) {
mModifierKeyState.Unset(MODIFIER_CONTROL
| MODIFIER_ALT);
}
mModifierKeyState.InitInputEvent(keyEvent);
keyEvent.time = ::GetMessageTime();
keyEvent.isChar = true;
keyEvent.charCode = aCharCode;
keyEvent.mKeyNameIndex = KEY_NAME_INDEX_PrintableKey;
DispatchEventIgnoreStatus(&keyEvent);
}
// This helper function is responsible for sending an appropriate gecko
// event in response to a keyboard key being pressed down.
void
MetroInput::OnKeyDown(uint32_t aVKey)
{
// We can only send a gecko event if there is a gecko virtual key code that
// corresponds to the Windows virtual key code
uint32_t mozKey = GetMozKeyCode(aVKey);
if (!mozKey) {
return;
}
nsKeyEvent keyEvent(true, NS_KEY_DOWN, mWidget.Get());
mModifierKeyState.Update();
mModifierKeyState.InitInputEvent(keyEvent);
keyEvent.time = ::GetMessageTime();
keyEvent.keyCode = mozKey;
keyEvent.mKeyNameIndex = GetDOMKeyNameIndex(aVKey);
DispatchEventIgnoreStatus(&keyEvent);
// If the key being pressed is not a printable character (e.g.
// enter, delete, backspace, alt, etc), we will not receive a character
// event for this key press, which means that our OnCharacterReceived
// function won't get called, and that we will never send a gecko
// keypress event for this character.
//
// If the control key is currently down while this key was pressed,
// then Windows will either send us a character event indicating that a
// control character has been generated, or it will not send us any
// character event (depending on which key has been pressed).
//
// We want gecko to be aware of every keypress, so we send the
// keypress here.
//
// Note: We use MapVirtualKey to determine what character code we will
// send in our NS_KEY_PRESS event. MapVirtualKey does not provide a very
// good mapping from virtual key code to character. It doesn't
// take into account any additional keys (shift, caps lock, etc), or
// any diacritics that might already have been pressed, and it
// ALWAYS gives the upper-case version of latin characters a-z. Thus,
// we only use it if we absolutely have to. In this case, Windows isn't
// going to send us character events, so the only way to come up with a
// character value to send in our NS_KEY_PRESS is to use MapVirtualKey.
keyEvent.charCode = MapVirtualKey(aVKey, MAPVK_VK_TO_CHAR);
keyEvent.isChar = !IsControlCharacter(keyEvent.charCode);
if (!keyEvent.isChar
|| (mModifierKeyState.IsControl()
&& !mModifierKeyState.IsAltGr())) {
keyEvent.message = NS_KEY_PRESS;
DispatchEventIgnoreStatus(&keyEvent);
}
}
// This helper function is responsible for sending an appropriate gecko
// event in response to a keyboard key being released.
void
MetroInput::OnKeyUp(uint32_t aVKey)
{
uint32_t mozKey = GetMozKeyCode(aVKey);
if (!mozKey) {
return;
}
nsKeyEvent keyEvent(true, NS_KEY_UP, mWidget.Get());
mModifierKeyState.Update();
mModifierKeyState.InitInputEvent(keyEvent);
keyEvent.time = ::GetMessageTime();
keyEvent.keyCode = mozKey;
keyEvent.mKeyNameIndex = GetDOMKeyNameIndex(aVKey);
DispatchEventIgnoreStatus(&keyEvent);
}
/**
* This helper function is used by our processing of PointerPressed,
* PointerReleased, and PointerMoved events.
@ -1240,14 +1086,6 @@ MetroInput::UnregisterInputEvents() {
edge->remove_Completed(mTokenEdgeCompleted);
}
}
// Unregister ourselves from the AcceleratorKeyActivated event
WRL::ComPtr<ICoreAcceleratorKeys> coreAcceleratorKeys;
if (SUCCEEDED(mDispatcher.As<ICoreAcceleratorKeys>(&coreAcceleratorKeys))) {
coreAcceleratorKeys->remove_AcceleratorKeyActivated(
mTokenAcceleratorKeyActivated);
}
// Unregister ourselves from the window events. This is extremely important;
// once this object is destroyed we don't want Windows to try to send events
// to it.
@ -1269,277 +1107,6 @@ MetroInput::UnregisterInputEvents() {
mGestureRecognizer->remove_RightTapped(mTokenRightTapped);
}
// Since this is static, it should automatically be initialized
// to all 0 bytes.
uint32_t MetroInput::sVirtualKeyMap[255];
bool MetroInput::sIsVirtualKeyMapInitialized = false;
// References
// nsVKList.h - defines NS_VK_*
// nsIDOMKeyEvent.idl - defines the values that NS_VK_* are based on
// nsDOMKeyNameList.h - defines KeyNameIndex values
void
MetroInput::InitializeVirtualKeyMap() {
sVirtualKeyMap[System::VirtualKey::VirtualKey_Cancel] = NS_VK_CANCEL;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Help] = NS_VK_HELP;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Back] = NS_VK_BACK;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Tab] = NS_VK_TAB;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Clear] = NS_VK_CLEAR;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Enter] = NS_VK_RETURN;
// NS_VK_ENTER is never used.
sVirtualKeyMap[System::VirtualKey::VirtualKey_Shift] = NS_VK_SHIFT;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Control] = NS_VK_CONTROL;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Menu] = NS_VK_ALT;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Pause] = NS_VK_PAUSE;
sVirtualKeyMap[System::VirtualKey::VirtualKey_CapitalLock] = NS_VK_CAPS_LOCK;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Kana] = NS_VK_KANA;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Hangul] = NS_VK_HANGUL;
// NS_VK_EISU (Japanese Mac keyboard only)
sVirtualKeyMap[System::VirtualKey::VirtualKey_Junja] = NS_VK_JUNJA;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Final] = NS_VK_FINAL;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Hanja] = NS_VK_HANJA;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Kanji] = NS_VK_KANJI;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Escape] = NS_VK_ESCAPE;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Convert] = NS_VK_CONVERT;
sVirtualKeyMap[System::VirtualKey::VirtualKey_NonConvert] = NS_VK_NONCONVERT;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Accept] = NS_VK_ACCEPT;
sVirtualKeyMap[System::VirtualKey::VirtualKey_ModeChange] = NS_VK_MODECHANGE;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Space] = NS_VK_SPACE;
sVirtualKeyMap[System::VirtualKey::VirtualKey_PageUp] = NS_VK_PAGE_UP;
sVirtualKeyMap[System::VirtualKey::VirtualKey_PageDown] = NS_VK_PAGE_DOWN;
sVirtualKeyMap[System::VirtualKey::VirtualKey_End] = NS_VK_END;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Home] = NS_VK_HOME;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Left] = NS_VK_LEFT;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Up] = NS_VK_UP;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Right] = NS_VK_RIGHT;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Down] = NS_VK_DOWN;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Select] = NS_VK_SELECT;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Print] = NS_VK_PRINT;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Execute] = NS_VK_EXECUTE;
sVirtualKeyMap[VK_SNAPSHOT] = NS_VK_PRINTSCREEN;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Insert] = NS_VK_INSERT;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Delete] = NS_VK_DELETE;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Number0] = NS_VK_0;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Number1] = NS_VK_1;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Number2] = NS_VK_2;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Number3] = NS_VK_3;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Number4] = NS_VK_4;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Number5] = NS_VK_5;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Number6] = NS_VK_6;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Number7] = NS_VK_7;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Number8] = NS_VK_8;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Number9] = NS_VK_9;
// NS_VK_COLON
sVirtualKeyMap[VK_OEM_1] = NS_VK_SEMICOLON;
// NS_VK_LESS_THAN
// NS_VK_EQUALS
// NS_VK_GREATER_THAN
// NS_VK_QUESTION_MARK
// NS_VK_AT
sVirtualKeyMap[System::VirtualKey::VirtualKey_A] = NS_VK_A;
sVirtualKeyMap[System::VirtualKey::VirtualKey_B] = NS_VK_B;
sVirtualKeyMap[System::VirtualKey::VirtualKey_C] = NS_VK_C;
sVirtualKeyMap[System::VirtualKey::VirtualKey_D] = NS_VK_D;
sVirtualKeyMap[System::VirtualKey::VirtualKey_E] = NS_VK_E;
sVirtualKeyMap[System::VirtualKey::VirtualKey_F] = NS_VK_F;
sVirtualKeyMap[System::VirtualKey::VirtualKey_G] = NS_VK_G;
sVirtualKeyMap[System::VirtualKey::VirtualKey_H] = NS_VK_H;
sVirtualKeyMap[System::VirtualKey::VirtualKey_I] = NS_VK_I;
sVirtualKeyMap[System::VirtualKey::VirtualKey_J] = NS_VK_J;
sVirtualKeyMap[System::VirtualKey::VirtualKey_K] = NS_VK_K;
sVirtualKeyMap[System::VirtualKey::VirtualKey_L] = NS_VK_L;
sVirtualKeyMap[System::VirtualKey::VirtualKey_M] = NS_VK_M;
sVirtualKeyMap[System::VirtualKey::VirtualKey_N] = NS_VK_N;
sVirtualKeyMap[System::VirtualKey::VirtualKey_O] = NS_VK_O;
sVirtualKeyMap[System::VirtualKey::VirtualKey_P] = NS_VK_P;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Q] = NS_VK_Q;
sVirtualKeyMap[System::VirtualKey::VirtualKey_R] = NS_VK_R;
sVirtualKeyMap[System::VirtualKey::VirtualKey_S] = NS_VK_S;
sVirtualKeyMap[System::VirtualKey::VirtualKey_T] = NS_VK_T;
sVirtualKeyMap[System::VirtualKey::VirtualKey_U] = NS_VK_U;
sVirtualKeyMap[System::VirtualKey::VirtualKey_V] = NS_VK_V;
sVirtualKeyMap[System::VirtualKey::VirtualKey_W] = NS_VK_W;
sVirtualKeyMap[System::VirtualKey::VirtualKey_X] = NS_VK_X;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Y] = NS_VK_Y;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Z] = NS_VK_Z;
sVirtualKeyMap[System::VirtualKey::VirtualKey_LeftWindows] = NS_VK_WIN;
sVirtualKeyMap[System::VirtualKey::VirtualKey_RightWindows] = NS_VK_WIN;
sVirtualKeyMap[System::VirtualKey::VirtualKey_LeftMenu] = NS_VK_CONTEXT_MENU;
sVirtualKeyMap[System::VirtualKey::VirtualKey_RightMenu] = NS_VK_CONTEXT_MENU;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Sleep] = NS_VK_SLEEP;
sVirtualKeyMap[System::VirtualKey::VirtualKey_NumberPad0] = NS_VK_NUMPAD0;
sVirtualKeyMap[System::VirtualKey::VirtualKey_NumberPad1] = NS_VK_NUMPAD1;
sVirtualKeyMap[System::VirtualKey::VirtualKey_NumberPad2] = NS_VK_NUMPAD2;
sVirtualKeyMap[System::VirtualKey::VirtualKey_NumberPad3] = NS_VK_NUMPAD3;
sVirtualKeyMap[System::VirtualKey::VirtualKey_NumberPad4] = NS_VK_NUMPAD4;
sVirtualKeyMap[System::VirtualKey::VirtualKey_NumberPad5] = NS_VK_NUMPAD5;
sVirtualKeyMap[System::VirtualKey::VirtualKey_NumberPad6] = NS_VK_NUMPAD6;
sVirtualKeyMap[System::VirtualKey::VirtualKey_NumberPad7] = NS_VK_NUMPAD7;
sVirtualKeyMap[System::VirtualKey::VirtualKey_NumberPad8] = NS_VK_NUMPAD8;
sVirtualKeyMap[System::VirtualKey::VirtualKey_NumberPad9] = NS_VK_NUMPAD9;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Multiply] = NS_VK_MULTIPLY;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Add] = NS_VK_ADD;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Separator] = NS_VK_SEPARATOR;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Subtract] = NS_VK_SUBTRACT;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Decimal] = NS_VK_DECIMAL;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Divide] = NS_VK_DIVIDE;
sVirtualKeyMap[System::VirtualKey::VirtualKey_F1] = NS_VK_F1;
sVirtualKeyMap[System::VirtualKey::VirtualKey_F2] = NS_VK_F2;
sVirtualKeyMap[System::VirtualKey::VirtualKey_F3] = NS_VK_F3;
sVirtualKeyMap[System::VirtualKey::VirtualKey_F4] = NS_VK_F4;
sVirtualKeyMap[System::VirtualKey::VirtualKey_F5] = NS_VK_F5;
sVirtualKeyMap[System::VirtualKey::VirtualKey_F6] = NS_VK_F6;
sVirtualKeyMap[System::VirtualKey::VirtualKey_F7] = NS_VK_F7;
sVirtualKeyMap[System::VirtualKey::VirtualKey_F8] = NS_VK_F8;
sVirtualKeyMap[System::VirtualKey::VirtualKey_F9] = NS_VK_F9;
sVirtualKeyMap[System::VirtualKey::VirtualKey_F10] = NS_VK_F10;
sVirtualKeyMap[System::VirtualKey::VirtualKey_F11] = NS_VK_F11;
sVirtualKeyMap[System::VirtualKey::VirtualKey_F12] = NS_VK_F12;
sVirtualKeyMap[System::VirtualKey::VirtualKey_F13] = NS_VK_F13;
sVirtualKeyMap[System::VirtualKey::VirtualKey_F14] = NS_VK_F14;
sVirtualKeyMap[System::VirtualKey::VirtualKey_F15] = NS_VK_F15;
sVirtualKeyMap[System::VirtualKey::VirtualKey_F16] = NS_VK_F16;
sVirtualKeyMap[System::VirtualKey::VirtualKey_F17] = NS_VK_F17;
sVirtualKeyMap[System::VirtualKey::VirtualKey_F18] = NS_VK_F18;
sVirtualKeyMap[System::VirtualKey::VirtualKey_F19] = NS_VK_F19;
sVirtualKeyMap[System::VirtualKey::VirtualKey_F20] = NS_VK_F20;
sVirtualKeyMap[System::VirtualKey::VirtualKey_F21] = NS_VK_F21;
sVirtualKeyMap[System::VirtualKey::VirtualKey_F22] = NS_VK_F22;
sVirtualKeyMap[System::VirtualKey::VirtualKey_F23] = NS_VK_F23;
sVirtualKeyMap[System::VirtualKey::VirtualKey_F24] = NS_VK_F24;
sVirtualKeyMap[System::VirtualKey::VirtualKey_NumberKeyLock] = NS_VK_NUM_LOCK;
sVirtualKeyMap[System::VirtualKey::VirtualKey_Scroll] = NS_VK_SCROLL_LOCK;
// NS_VK_CIRCUMFLEX
// NS_VK_EXCLAMATION
// NS_VK_DOUBLE_QUOTE
// NS_VK_HASH
// NS_VK_DOLLAR
// NS_VK_PERCENT
// NS_VK_AMPERSAND
// NS_VK_UNDERSCORE
// NS_VK_OPEN_PAREN
// NS_VK_CLOSE_PAREN
// NS_VK_ASTERISK
sVirtualKeyMap[VK_OEM_PLUS] = NS_VK_PLUS;
// NS_VK_PIPE
sVirtualKeyMap[VK_OEM_MINUS] = NS_VK_HYPHEN_MINUS;
// NS_VK_OPEN_CURLY_BRACKET
// NS_VK_CLOSE_CURLY_BRACKET
// NS_VK_TILDE
sVirtualKeyMap[VK_OEM_COMMA] = NS_VK_COMMA;
sVirtualKeyMap[VK_OEM_PERIOD] = NS_VK_PERIOD;
sVirtualKeyMap[VK_OEM_2] = NS_VK_SLASH;
sVirtualKeyMap[VK_OEM_3] = NS_VK_BACK_QUOTE;
sVirtualKeyMap[VK_OEM_4] = NS_VK_OPEN_BRACKET;
sVirtualKeyMap[VK_OEM_5] = NS_VK_BACK_SLASH;
sVirtualKeyMap[VK_OEM_6] = NS_VK_CLOSE_BRACKET;
sVirtualKeyMap[VK_OEM_7] = NS_VK_QUOTE;
// NS_VK_META
// NS_VK_ALTGR
}
uint32_t
MetroInput::GetMozKeyCode(uint32_t aKey)
{
return sVirtualKeyMap[aKey];
}
KeyNameIndex
MetroInput::GetDOMKeyNameIndex(uint32_t aVirtualKey)
{
switch (aVirtualKey) {
#define NS_NATIVE_KEY_TO_DOM_KEY_NAME_INDEX(aNativeKey, aKeyNameIndex) \
case aNativeKey: return aKeyNameIndex;
#define NS_JAPANESE_NATIVE_KEY_TO_DOM_KEY_NAME_INDEX(aNativeKey, aKeyNameIndex)
#define NS_KOREAN_NATIVE_KEY_TO_DOM_KEY_NAME_INDEX(aNativeKey, aKeyNameIndex)
#define NS_OTHER_NATIVE_KEY_TO_DOM_KEY_NAME_INDEX(aNativeKey, aKeyNameIndex)
#include "NativeKeyToDOMKeyName.h"
#undef NS_NATIVE_KEY_TO_DOM_KEY_NAME_INDEX
#undef NS_JAPANESE_NATIVE_KEY_TO_DOM_KEY_NAME_INDEX
#undef NS_KOREAN_NATIVE_KEY_TO_DOM_KEY_NAME_INDEX
#undef NS_OTHER_NATIVE_KEY_TO_DOM_KEY_NAME_INDEX
// printable keys:
case System::VirtualKey::VirtualKey_Number0:
case System::VirtualKey::VirtualKey_Number1:
case System::VirtualKey::VirtualKey_Number2:
case System::VirtualKey::VirtualKey_Number3:
case System::VirtualKey::VirtualKey_Number4:
case System::VirtualKey::VirtualKey_Number5:
case System::VirtualKey::VirtualKey_Number6:
case System::VirtualKey::VirtualKey_Number7:
case System::VirtualKey::VirtualKey_Number8:
case System::VirtualKey::VirtualKey_Number9:
case System::VirtualKey::VirtualKey_A:
case System::VirtualKey::VirtualKey_B:
case System::VirtualKey::VirtualKey_C:
case System::VirtualKey::VirtualKey_D:
case System::VirtualKey::VirtualKey_E:
case System::VirtualKey::VirtualKey_F:
case System::VirtualKey::VirtualKey_G:
case System::VirtualKey::VirtualKey_H:
case System::VirtualKey::VirtualKey_I:
case System::VirtualKey::VirtualKey_J:
case System::VirtualKey::VirtualKey_K:
case System::VirtualKey::VirtualKey_L:
case System::VirtualKey::VirtualKey_M:
case System::VirtualKey::VirtualKey_N:
case System::VirtualKey::VirtualKey_O:
case System::VirtualKey::VirtualKey_P:
case System::VirtualKey::VirtualKey_Q:
case System::VirtualKey::VirtualKey_R:
case System::VirtualKey::VirtualKey_S:
case System::VirtualKey::VirtualKey_T:
case System::VirtualKey::VirtualKey_U:
case System::VirtualKey::VirtualKey_V:
case System::VirtualKey::VirtualKey_W:
case System::VirtualKey::VirtualKey_X:
case System::VirtualKey::VirtualKey_Y:
case System::VirtualKey::VirtualKey_Z:
case VK_NUMPAD0:
case VK_NUMPAD1:
case VK_NUMPAD2:
case VK_NUMPAD3:
case VK_NUMPAD4:
case VK_NUMPAD5:
case VK_NUMPAD6:
case VK_NUMPAD7:
case VK_NUMPAD8:
case VK_NUMPAD9:
case VK_OEM_1:
case VK_OEM_PLUS:
case VK_OEM_COMMA:
case VK_OEM_MINUS:
case VK_OEM_PERIOD:
case VK_OEM_2:
case VK_OEM_3:
case VK_OEM_4:
case VK_OEM_5:
case VK_OEM_6:
case VK_OEM_7:
case VK_OEM_8:
case VK_OEM_102:
return KEY_NAME_INDEX_PrintableKey;
default:
return KEY_NAME_INDEX_Unidentified;
}
}
void
MetroInput::RegisterInputEvents()
{
@ -1548,18 +1115,6 @@ MetroInput::RegisterInputEvents()
"Must have a GestureRecognizer for input events!");
NS_ASSERTION(mDispatcher,
"Must have a CoreDispatcher to register for input events!");
// Register for the AcceleratorKeyActivated event. This is sent to us
// from our CoreDispatcher, but we have to use the ICoreAcceleratorKeys
// interface of our CoreDispatcher.
WRL::ComPtr<ICoreAcceleratorKeys> coreAcceleratorKeys;
mDispatcher.As<ICoreAcceleratorKeys>(&coreAcceleratorKeys);
coreAcceleratorKeys->add_AcceleratorKeyActivated(
WRL::Callback<AcceleratorKeyActivatedHandler>(
this,
&MetroInput::OnAcceleratorKeyActivated).Get(),
&mTokenAcceleratorKeyActivated);
// Register for edge swipe
WRL::ComPtr<UI::Input::IEdgeGestureStatics> edgeStatics;
Foundation::GetActivationFactory(

View File

@ -109,12 +109,6 @@ public:
ICoreDispatcher* aDispatcher);
virtual ~MetroInput();
// This event is received from our CoreDispatcher. All keyboard and
// character events are handled in this function. See function
// definition for more info.
HRESULT OnAcceleratorKeyActivated(ICoreDispatcher* aSender,
IAcceleratorKeyEventArgs* aArgs);
// These input events are received from our window. These are basic
// pointer and keyboard press events. MetroInput responds to them
// by sending gecko events and forwarding these input events to its
@ -170,9 +164,6 @@ private:
void UnregisterInputEvents();
// Event processing helpers. See function definitions for more info.
void OnKeyDown(uint32_t aVKey);
void OnKeyUp(uint32_t aVKey);
void OnCharacterReceived(uint32_t aVKey);
void OnPointerNonTouch(IPointerPoint* aPoint);
void InitGeckoMouseEventFromPointerPoint(nsMouseEvent& aEvent,
IPointerPoint* aPoint);
@ -238,18 +229,6 @@ private:
nsRefPtr<mozilla::dom::Touch>,
nsRefPtr<mozilla::dom::Touch> > mTouches;
// When a key press is received, we convert the Windows virtual key
// into a gecko virtual key to send in a gecko event.
//
// Source:
// http://msdn.microsoft.com
// /en-us/library/windows/apps/windows.system.virtualkey.aspx
static uint32_t sVirtualKeyMap[255];
static bool sIsVirtualKeyMapInitialized;
static void InitializeVirtualKeyMap();
static uint32_t GetMozKeyCode(uint32_t aKey);
// Computes DOM key name index for the aVirtualKey.
static KeyNameIndex GetDOMKeyNameIndex(uint32_t aVirtualKey);
// These registration tokens are set when we register ourselves to receive
// events from our window. We must hold on to them for the entire duration
// that we want to receive these events. When we are done, we must
@ -261,12 +240,6 @@ private:
EventRegistrationToken mTokenPointerExited;
EventRegistrationToken mTokenPointerWheelChanged;
// This registration token is set when we register ourselves to handle
// the `AcceleratorKeyActivated` event received from our CoreDispatcher.
// When we are done, we must unregister ourselves with the CoreDispatcher
// using this token.
EventRegistrationToken mTokenAcceleratorKeyActivated;
// When we register ourselves to handle edge gestures, we receive a
// token. To we unregister ourselves, we must use the token we received.
EventRegistrationToken mTokenEdgeStarted;

View File

@ -148,6 +148,7 @@ MetroWidget::MetroWidget() :
if (!gInstanceCount) {
UserActivity();
nsTextStore::Initialize();
KeyboardLayout::GetInstance()->OnLayoutChange(::GetKeyboardLayout(0));
} // !gInstanceCount
gInstanceCount++;
}
@ -450,104 +451,10 @@ MetroWidget::SynthesizeNativeKeyEvent(int32_t aNativeKeyboardLayout,
const nsAString& aCharacters,
const nsAString& aUnmodifiedCharacters)
{
Log("ENTERED SynthesizeNativeKeyEvent");
// According to MSDN, valid virtual-key codes are in the range 1 to 254.
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms646271%28v=vs.85%29.aspx
NS_ENSURE_ARG_RANGE(aNativeKeyCode, 1, 254);
// Store a list of all loaded keyboard layouts
int32_t const numKeyboardLayouts = GetKeyboardLayoutList(0, NULL);
if (numKeyboardLayouts == 0) {
return NS_ERROR_FAILURE;
}
HKL* keyboardLayoutList = new HKL[numKeyboardLayouts];
GetKeyboardLayoutList(numKeyboardLayouts, keyboardLayoutList);
// Store the current keyboard layout
HKL const oldKeyboardLayout = ::GetKeyboardLayout(0);
Log(" Current keyboard layout: %08x", oldKeyboardLayout);
Log(" Loading keyboard layout: %08x", aNativeKeyboardLayout);
// Load the requested keyboard layout
nsPrintfCString layoutName("%08x", aNativeKeyboardLayout);
HKL const newKeyboardLayout = ::LoadKeyboardLayoutA(layoutName.get(),
KLF_REPLACELANG);
Log(" ::LoadKeyboardLayoutA returned %08x", newKeyboardLayout);
// We have a list of all keyboard layouts that were loaded before we called
// ::LoadKeyboardLayout. Now, we loop through that list to determine which
// of these cases we've hit:
// A) The layout we loaded was already loaded
// B) The layout we loaded was not already loaded, and it replaced
// another layout in the list
// C) The layout we loaded was not already loaded, and it has not
// replaced another layout
bool haveLoaded = true;
bool haveActivated = false;
bool haveReplaced = false;
if (GetKeyboardLayoutList(0, NULL) == numKeyboardLayouts) {
haveReplaced = true;
for (int32_t i = 0; i < numKeyboardLayouts; i++) {
if (keyboardLayoutList[i] == newKeyboardLayout) {
Log(" %08x found in list of loaded keyboard layouts", newKeyboardLayout);
haveLoaded = false;
haveReplaced = false;
break;
}
}
}
// If the requested keyboard layout was already active when this function
// was called, then we don't need to activate our keyboard layout
if (oldKeyboardLayout != newKeyboardLayout) {
Log(" %08x != %08x", oldKeyboardLayout, newKeyboardLayout);
haveActivated = true;
Log(" Activating keyboard layout: %08x", newKeyboardLayout);
HKL ret = ::ActivateKeyboardLayout(newKeyboardLayout, KLF_SETFORPROCESS);
Log(" ::ActivateKeyboardLayout returned %08x", ret);
}
INPUT inputs[2];
memset(&inputs, 0, 2*sizeof(INPUT));
inputs[0].type = inputs[1].type = INPUT_KEYBOARD;
inputs[0].ki.wVk = inputs[1].ki.wVk = aNativeKeyCode;
inputs[1].ki.dwFlags |= KEYEVENTF_KEYUP;
SendInputs(aModifierFlags, inputs, 2);
// Now that all the events have been processed, we can set the keyboard
// layout list back to its original state. If we didn't activate a
// keyboard (meaning that the requested keyboard was already the active
// keyboard), we don't have to do anything.
if (haveActivated) {
// If we replaced a keyboard in the layout list, let's be safe and reload
// all the keyboards that were in the original list.
if (haveReplaced) {
Log(" Loading all previous layouts");
for (int32_t i = 0; i < numKeyboardLayouts; i++) {
nsPrintfCString layoutName("%08x", keyboardLayoutList[i]);
HKL ret = ::LoadKeyboardLayoutA(layoutName.get(), KLF_REPLACELANG);
Log(" ::LoadKeyboardLayoutA returned %08x", ret);
}
}
// Any keyboards that were in the keyboard layout list when we entered
// this function should be loaded, so let's go ahead and activate the
// keyboard layout that was active when we entered.
Log(" Activating previous layout %08x", oldKeyboardLayout);
HKL ret = ::ActivateKeyboardLayout(oldKeyboardLayout, KLF_SETFORPROCESS);
Log(" ::ActivateKeyboardLayout returned %08x", ret);
// If we loaded a keyboard that was not already loaded, and that didn't
// replace another keyboard in the keyboard layout list, let's unload it.
if (haveLoaded && !haveReplaced) {
Log(" Unloading keyboard layout %08x", newKeyboardLayout);
::UnloadKeyboardLayout(newKeyboardLayout);
}
}
delete[] keyboardLayoutList;
Log("EXITING SynthesizeNativeKeyEvent");
return NS_OK;
KeyboardLayout* keyboardLayout = KeyboardLayout::GetInstance();
return keyboardLayout->SynthesizeNativeKeyEvent(
this, aNativeKeyboardLayout, aNativeKeyCode, aModifierFlags,
aCharacters, aUnmodifiedCharacters);
}
nsresult
@ -681,6 +588,67 @@ MetroWidget::WindowProcedure(HWND aWnd, UINT aMsg, WPARAM aWParam, LPARAM aLPara
break;
}
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
{
MSG msg = WinUtils::InitMSG(aMsg, aWParam, aLParam, aWnd);
// If this method doesn't call NativeKey::HandleKeyDownMessage(), this
// method must clean up the redirected message information itself. For
// more information, see above comment of
// RedirectedKeyDownMessageManager::AutoFlusher class definition in
// KeyboardLayout.h.
RedirectedKeyDownMessageManager::AutoFlusher
redirectedMsgFlusher(this, msg);
if (nsTextStore::IsComposingOn(this)) {
break;
}
ModifierKeyState modKeyState;
NativeKey nativeKey(this, msg, modKeyState);
processDefault = !nativeKey.HandleKeyDownMessage();
// HandleKeyDownMessage cleaned up the redirected message information
// itself, so, we should do nothing.
redirectedMsgFlusher.Cancel();
break;
}
case WM_KEYUP:
case WM_SYSKEYUP:
{
if (nsTextStore::IsComposingOn(this)) {
break;
}
MSG msg = WinUtils::InitMSG(aMsg, aWParam, aLParam, aWnd);
ModifierKeyState modKeyState;
NativeKey nativeKey(this, msg, modKeyState);
processDefault = !nativeKey.HandleKeyUpMessage();
break;
}
case WM_CHAR:
case WM_SYSCHAR:
{
if (nsTextStore::IsComposingOn(this)) {
nsTextStore::CommitComposition(false);
}
MSG msg = WinUtils::InitMSG(aMsg, aWParam, aLParam, aWnd);
ModifierKeyState modKeyState;
NativeKey nativeKey(this, msg, modKeyState);
processDefault = !nativeKey.HandleCharMessage(msg);
break;
}
case WM_INPUTLANGCHANGE:
{
KeyboardLayout::GetInstance()->
OnLayoutChange(reinterpret_cast<HKL>(aLParam));
processResult = 1;
break;
}
default:
{
if (aWParam == WM_USER_TSF_TEXTCHANGE) {
@ -974,10 +942,10 @@ MetroWidget::InitEvent(nsGUIEvent& event, nsIntPoint* aPoint)
bool
MetroWidget::DispatchWindowEvent(nsGUIEvent* aEvent)
{
nsEventStatus aStatus;
if (!aEvent || NS_FAILED(DispatchEvent(aEvent, aStatus)))
return false;
return true;
MOZ_ASSERT(aEvent);
nsEventStatus status = nsEventStatus_eIgnore;
DispatchEvent(aEvent, status);
return (status == nsEventStatus_eConsumeNoDefault);
}
NS_IMETHODIMP