Bug 1300937 part.2 Automated tests which synthesize native key events on Windows should specify scan code value explicitly r=smaug
☠☠ backed out by ef298f2e9e09 ☠ ☠
authorMasayuki Nakano <masayuki@d-toybox.com>
Tue, 13 Sep 2016 19:38:23 +0900
changeset 355270 be88a60abb7ad0608d8e001e81af8e57a282b334
parent 355269 6a8bf7596f42d22961f4d79f1cd8b282618dafb5
child 355271 e94d6d5771038e904d83722fad5718f4f68603a5
push id6570
push userraliiev@mozilla.com
push dateMon, 14 Nov 2016 12:26:13 +0000
treeherdermozilla-beta@f455459b2ae5 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1300937
milestone51.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1300937 part.2 Automated tests which synthesize native key events on Windows should specify scan code value explicitly r=smaug On Windows, some keys are called "extended key". Their scan code include 0xE000. For example, Enter key in standard position is 0x001C but Numpad's Enter key is 0xE01C. Unfortunately, both of them cause same virtual keycode value, VK_RETURN. Therefore, currently, nsIDOMWindowUtils.sendNativeKey() can synthesize only one native key event of them (only non-extended key's event). Additionally, MapVirtualKeyEx() API with MAPVK_VK_TO_VSC (even with MAPVK_VK_TO_VSC_EX) don't return extended scancode value as expected. For solving these issues, we should include scan code value to the virtual keycode value at calling sendNativeKey(). Fortunately, virtual keycode value on Windows is 0 ~ 255 (0x00 ~ 0xFF) but aNativeKeyCode of sendNativeKey() is int32_t. So, we can use upper 16 bit for specifying scan code. This patch explicitly specifies scan code value at defining WIN_VK_* in NativeKeyCodes.js. Additionally, this patch duplicates native virtual keycode definition for Home, End, Insert, Delete, PageUp, PageDown, ArrowUp, ArrowLeft, ArrowDown, ArrowRight and Enter as WIN_VK_* and WIN_VK_NUMPAD_*. This makes automated tests can specify both positions' keys explicitly. Finally, this patch adds some tests to test_keycodes.xul for testing KeyboardEvent.code value of those keys in both positions. MozReview-Commit-ID: 8n1rQ71dilg
testing/mochitest/tests/SimpleTest/NativeKeyCodes.js
widget/tests/test_keycodes.xul
widget/windows/KeyboardLayout.cpp
widget/windows/nsWindowDefs.h
--- a/testing/mochitest/tests/SimpleTest/NativeKeyCodes.js
+++ b/testing/mochitest/tests/SimpleTest/NativeKeyCodes.js
@@ -1,223 +1,240 @@
 /**
  * This file defines all virtual keycodes for synthesizeNativeKey() of
  * EventUtils.js and nsIDOMWindowUtils.sendNativeKeyEvent().
  * These values are defined in each platform's SDK or documents.
  */
 
 // Windows
+// Windows' native key code values may include scan code value which can be
+// retrieved with |((code & 0xFFFF0000 >> 16)|.  If the value is 0, it will
+// be computed with active keyboard layout automatically.
+// FYI: Don't define scan code here for printable keys, numeric keys and
+//      IME keys because they depend on active keyboard layout.
 
-const WIN_VK_LBUTTON                    = 0x01;
-const WIN_VK_RBUTTON                    = 0x02;
-const WIN_VK_CANCEL                     = 0x03;
-const WIN_VK_MBUTTON                    = 0x04;
-const WIN_VK_XBUTTON1                   = 0x05;
-const WIN_VK_XBUTTON2                   = 0x06;
-const WIN_VK_BACK                       = 0x08;
-const WIN_VK_TAB                        = 0x09;
-const WIN_VK_CLEAR                      = 0x0C;
-const WIN_VK_RETURN                     = 0x0D;
-const WIN_VK_SHIFT                      = 0x10;
-const WIN_VK_CONTROL                    = 0x11;
-const WIN_VK_MENU                       = 0x12;
-const WIN_VK_PAUSE                      = 0x13;
-const WIN_VK_CAPITAL                    = 0x14;
-const WIN_VK_KANA                       = 0x15;
-const WIN_VK_HANGUEL                    = 0x15;
-const WIN_VK_HANGUL                     = 0x15;
-const WIN_VK_JUNJA                      = 0x17;
-const WIN_VK_FINAL                      = 0x18;
-const WIN_VK_HANJA                      = 0x19;
-const WIN_VK_KANJI                      = 0x19;
-const WIN_VK_ESCAPE                     = 0x1B;
-const WIN_VK_CONVERT                    = 0x1C;
-const WIN_VK_NONCONVERT                 = 0x1D;
-const WIN_VK_ACCEPT                     = 0x1E;
-const WIN_VK_MODECHANGE                 = 0x1F;
-const WIN_VK_SPACE                      = 0x20;
-const WIN_VK_PRIOR                      = 0x21;
-const WIN_VK_NEXT                       = 0x22;
-const WIN_VK_END                        = 0x23;
-const WIN_VK_HOME                       = 0x24;
-const WIN_VK_LEFT                       = 0x25;
-const WIN_VK_UP                         = 0x26;
-const WIN_VK_RIGHT                      = 0x27;
-const WIN_VK_DOWN                       = 0x28;
-const WIN_VK_SELECT                     = 0x29;
-const WIN_VK_PRINT                      = 0x2A;
-const WIN_VK_EXECUTE                    = 0x2B;
-const WIN_VK_SNAPSHOT                   = 0x2C;
-const WIN_VK_INSERT                     = 0x2D;
-const WIN_VK_DELETE                     = 0x2E;
-const WIN_VK_HELP                       = 0x2F;
-const WIN_VK_0                          = 0x30;
-const WIN_VK_1                          = 0x31;
-const WIN_VK_2                          = 0x32;
-const WIN_VK_3                          = 0x33;
-const WIN_VK_4                          = 0x34;
-const WIN_VK_5                          = 0x35;
-const WIN_VK_6                          = 0x36;
-const WIN_VK_7                          = 0x37;
-const WIN_VK_8                          = 0x38;
-const WIN_VK_9                          = 0x39;
-const WIN_VK_A                          = 0x41;
-const WIN_VK_B                          = 0x42;
-const WIN_VK_C                          = 0x43;
-const WIN_VK_D                          = 0x44;
-const WIN_VK_E                          = 0x45;
-const WIN_VK_F                          = 0x46;
-const WIN_VK_G                          = 0x47;
-const WIN_VK_H                          = 0x48;
-const WIN_VK_I                          = 0x49;
-const WIN_VK_J                          = 0x4A;
-const WIN_VK_K                          = 0x4B;
-const WIN_VK_L                          = 0x4C;
-const WIN_VK_M                          = 0x4D;
-const WIN_VK_N                          = 0x4E;
-const WIN_VK_O                          = 0x4F;
-const WIN_VK_P                          = 0x50;
-const WIN_VK_Q                          = 0x51;
-const WIN_VK_R                          = 0x52;
-const WIN_VK_S                          = 0x53;
-const WIN_VK_T                          = 0x54;
-const WIN_VK_U                          = 0x55;
-const WIN_VK_V                          = 0x56;
-const WIN_VK_W                          = 0x57;
-const WIN_VK_X                          = 0x58;
-const WIN_VK_Y                          = 0x59;
-const WIN_VK_Z                          = 0x5A;
-const WIN_VK_LWIN                       = 0x5B;
-const WIN_VK_RWIN                       = 0x5C;
-const WIN_VK_APPS                       = 0x5D;
-const WIN_VK_SLEEP                      = 0x5F;
-const WIN_VK_NUMPAD0                    = 0x60;
-const WIN_VK_NUMPAD1                    = 0x61;
-const WIN_VK_NUMPAD2                    = 0x62;
-const WIN_VK_NUMPAD3                    = 0x63;
-const WIN_VK_NUMPAD4                    = 0x64;
-const WIN_VK_NUMPAD5                    = 0x65;
-const WIN_VK_NUMPAD6                    = 0x66;
-const WIN_VK_NUMPAD7                    = 0x67;
-const WIN_VK_NUMPAD8                    = 0x68;
-const WIN_VK_NUMPAD9                    = 0x69;
-const WIN_VK_MULTIPLY                   = 0x6A;
-const WIN_VK_ADD                        = 0x6B;
-const WIN_VK_SEPARATOR                  = 0x6C;
-const WIN_VK_OEM_NEC_SEPARATE           = 0x6C;
-const WIN_VK_SUBTRACT                   = 0x6D;
-const WIN_VK_DECIMAL                    = 0x6E;
-const WIN_VK_DIVIDE                     = 0x6F;
-const WIN_VK_F1                         = 0x70;
-const WIN_VK_F2                         = 0x71;
-const WIN_VK_F3                         = 0x72;
-const WIN_VK_F4                         = 0x73;
-const WIN_VK_F5                         = 0x74;
-const WIN_VK_F6                         = 0x75;
-const WIN_VK_F7                         = 0x76;
-const WIN_VK_F8                         = 0x77;
-const WIN_VK_F9                         = 0x78;
-const WIN_VK_F10                        = 0x79;
-const WIN_VK_F11                        = 0x7A;
-const WIN_VK_F12                        = 0x7B;
-const WIN_VK_F13                        = 0x7C;
-const WIN_VK_F14                        = 0x7D;
-const WIN_VK_F15                        = 0x7E;
-const WIN_VK_F16                        = 0x7F;
-const WIN_VK_F17                        = 0x80;
-const WIN_VK_F18                        = 0x81;
-const WIN_VK_F19                        = 0x82;
-const WIN_VK_F20                        = 0x83;
-const WIN_VK_F21                        = 0x84;
-const WIN_VK_F22                        = 0x85;
-const WIN_VK_F23                        = 0x86;
-const WIN_VK_F24                        = 0x87;
-const WIN_VK_NUMLOCK                    = 0x90;
-const WIN_VK_SCROLL                     = 0x91;
-const WIN_VK_OEM_FJ_JISHO               = 0x92;
-const WIN_VK_OEM_NEC_EQUAL              = 0x92;
-const WIN_VK_OEM_FJ_MASSHOU             = 0x93;
-const WIN_VK_OEM_FJ_TOUROKU             = 0x94;
-const WIN_VK_OEM_FJ_LOYA                = 0x95;
-const WIN_VK_OEM_FJ_ROYA                = 0x96;
-const WIN_VK_LSHIFT                     = 0xA0;
-const WIN_VK_RSHIFT                     = 0xA1;
-const WIN_VK_LCONTROL                   = 0xA2;
-const WIN_VK_RCONTROL                   = 0xA3;
-const WIN_VK_LMENU                      = 0xA4;
-const WIN_VK_RMENU                      = 0xA5;
-const WIN_VK_BROWSER_BACK               = 0xA6;
-const WIN_VK_BROWSER_FORWARD            = 0xA7;
-const WIN_VK_BROWSER_REFRESH            = 0xA8;
-const WIN_VK_BROWSER_STOP               = 0xA9;
-const WIN_VK_BROWSER_SEARCH             = 0xAA;
-const WIN_VK_BROWSER_FAVORITES          = 0xAB;
-const WIN_VK_BROWSER_HOME               = 0xAC;
-const WIN_VK_VOLUME_MUTE                = 0xAD;
-const WIN_VK_VOLUME_DOWN                = 0xAE;
-const WIN_VK_VOLUME_UP                  = 0xAF;
-const WIN_VK_MEDIA_NEXT_TRACK           = 0xB0;
-const WIN_VK_OEM_FJ_000                 = 0xB0;
-const WIN_VK_MEDIA_PREV_TRACK           = 0xB1;
-const WIN_VK_OEM_FJ_EUQAL               = 0xB1;
-const WIN_VK_MEDIA_STOP                 = 0xB2;
-const WIN_VK_MEDIA_PLAY_PAUSE           = 0xB3;
-const WIN_VK_OEM_FJ_00                  = 0xB3;
-const WIN_VK_LAUNCH_MAIL                = 0xB4;
-const WIN_VK_LAUNCH_MEDIA_SELECT        = 0xB5;
-const WIN_VK_LAUNCH_APP1                = 0xB6;
-const WIN_VK_LAUNCH_APP2                = 0xB7;
-const WIN_VK_OEM_1                      = 0xBA;
-const WIN_VK_OEM_PLUS                   = 0xBB;
-const WIN_VK_OEM_COMMA                  = 0xBC;
-const WIN_VK_OEM_MINUS                  = 0xBD;
-const WIN_VK_OEM_PERIOD                 = 0xBE;
-const WIN_VK_OEM_2                      = 0xBF;
-const WIN_VK_OEM_3                      = 0xC0;
-const WIN_VK_ABNT_C1                    = 0xC1;
-const WIN_VK_ABNT_C2                    = 0xC2;
-const WIN_VK_OEM_4                      = 0xDB;
-const WIN_VK_OEM_5                      = 0xDC;
-const WIN_VK_OEM_6                      = 0xDD;
-const WIN_VK_OEM_7                      = 0xDE;
-const WIN_VK_OEM_8                      = 0xDF;
-const WIN_VK_OEM_NEC_DP1                = 0xE0;
-const WIN_VK_OEM_AX                     = 0xE1;
-const WIN_VK_OEM_NEC_DP2                = 0xE1;
-const WIN_VK_OEM_102                    = 0xE2;
-const WIN_VK_OEM_NEC_DP3                = 0xE2;
-const WIN_VK_ICO_HELP                   = 0xE3;
-const WIN_VK_OEM_NEC_DP4                = 0xE3;
-const WIN_VK_ICO_00                     = 0xE4;
-const WIN_VK_PROCESSKEY                 = 0xE5;
-const WIN_VK_ICO_CLEAR                  = 0xE6;
-const WIN_VK_PACKET                     = 0xE7;
-const WIN_VK_ERICSSON_BASE              = 0xE8;
-const WIN_VK_OEM_RESET                  = 0xE9;
-const WIN_VK_OEM_JUMP                   = 0xEA;
-const WIN_VK_OEM_PA1                    = 0xEB;
-const WIN_VK_OEM_PA2                    = 0xEC;
-const WIN_VK_OEM_PA3                    = 0xED;
-const WIN_VK_OEM_WSCTRL                 = 0xEE;
-const WIN_VK_OEM_CUSEL                  = 0xEF;
-const WIN_VK_OEM_ATTN                   = 0xF0;
-const WIN_VK_OEM_FINISH                 = 0xF1;
-const WIN_VK_OEM_COPY                   = 0xF2;
-const WIN_VK_OEM_AUTO                   = 0xF3;
-const WIN_VK_OEM_ENLW                   = 0xF4;
-const WIN_VK_OEM_BACKTAB                = 0xF5;
-const WIN_VK_ATTN                       = 0xF6;
-const WIN_VK_CRSEL                      = 0xF7;
-const WIN_VK_EXSEL                      = 0xF8;
-const WIN_VK_EREOF                      = 0xF9;
-const WIN_VK_PLAY                       = 0xFA;
-const WIN_VK_ZOOM                       = 0xFB;
-const WIN_VK_NONAME                     = 0xFC;
-const WIN_VK_PA1                        = 0xFD;
-const WIN_VK_OEM_CLEAR                  = 0xFE;
+const WIN_VK_LBUTTON                    = 0x00000001;
+const WIN_VK_RBUTTON                    = 0x00000002;
+const WIN_VK_CANCEL                     = 0xE0460003;
+const WIN_VK_MBUTTON                    = 0x00000004;
+const WIN_VK_XBUTTON1                   = 0x00000005;
+const WIN_VK_XBUTTON2                   = 0x00000006;
+const WIN_VK_BACK                       = 0x000E0008;
+const WIN_VK_TAB                        = 0x000F0009;
+const WIN_VK_CLEAR                      = 0x004C000C;
+const WIN_VK_RETURN                     = 0x001C000D;
+const WIN_VK_SHIFT                      = 0x002A0010;
+const WIN_VK_CONTROL                    = 0x001D0011;
+const WIN_VK_MENU                       = 0x00380012;
+const WIN_VK_PAUSE                      = 0x00450013;
+const WIN_VK_CAPITAL                    = 0x003A0014;
+const WIN_VK_KANA                       = 0x00000015;
+const WIN_VK_HANGUEL                    = 0x00000015;
+const WIN_VK_HANGUL                     = 0x00000015;
+const WIN_VK_JUNJA                      = 0x00000017;
+const WIN_VK_FINAL                      = 0x00000018;
+const WIN_VK_HANJA                      = 0x00000019;
+const WIN_VK_KANJI                      = 0x00000019;
+const WIN_VK_ESCAPE                     = 0x0001001B;
+const WIN_VK_CONVERT                    = 0x0000001C;
+const WIN_VK_NONCONVERT                 = 0x0000001D;
+const WIN_VK_ACCEPT                     = 0x0000001E;
+const WIN_VK_MODECHANGE                 = 0x0000001F;
+const WIN_VK_SPACE                      = 0x00390020;
+const WIN_VK_PRIOR                      = 0xE0490021;
+const WIN_VK_NEXT                       = 0xE0510022;
+const WIN_VK_END                        = 0xE04F0023;
+const WIN_VK_HOME                       = 0xE0470024;
+const WIN_VK_LEFT                       = 0xE04B0025;
+const WIN_VK_UP                         = 0xE0480026;
+const WIN_VK_RIGHT                      = 0xE04D0027;
+const WIN_VK_DOWN                       = 0xE0500028;
+const WIN_VK_SELECT                     = 0x00000029;
+const WIN_VK_PRINT                      = 0x0000002A;
+const WIN_VK_EXECUTE                    = 0x0000002B;
+const WIN_VK_SNAPSHOT                   = 0xE037002C;
+const WIN_VK_INSERT                     = 0xE052002D;
+const WIN_VK_DELETE                     = 0xE053002E;
+const WIN_VK_HELP                       = 0x0000002F;
+const WIN_VK_0                          = 0x00000030;
+const WIN_VK_1                          = 0x00000031;
+const WIN_VK_2                          = 0x00000032;
+const WIN_VK_3                          = 0x00000033;
+const WIN_VK_4                          = 0x00000034;
+const WIN_VK_5                          = 0x00000035;
+const WIN_VK_6                          = 0x00000036;
+const WIN_VK_7                          = 0x00000037;
+const WIN_VK_8                          = 0x00000038;
+const WIN_VK_9                          = 0x00000039;
+const WIN_VK_A                          = 0x00000041;
+const WIN_VK_B                          = 0x00000042;
+const WIN_VK_C                          = 0x00000043;
+const WIN_VK_D                          = 0x00000044;
+const WIN_VK_E                          = 0x00000045;
+const WIN_VK_F                          = 0x00000046;
+const WIN_VK_G                          = 0x00000047;
+const WIN_VK_H                          = 0x00000048;
+const WIN_VK_I                          = 0x00000049;
+const WIN_VK_J                          = 0x0000004A;
+const WIN_VK_K                          = 0x0000004B;
+const WIN_VK_L                          = 0x0000004C;
+const WIN_VK_M                          = 0x0000004D;
+const WIN_VK_N                          = 0x0000004E;
+const WIN_VK_O                          = 0x0000004F;
+const WIN_VK_P                          = 0x00000050;
+const WIN_VK_Q                          = 0x00000051;
+const WIN_VK_R                          = 0x00000052;
+const WIN_VK_S                          = 0x00000053;
+const WIN_VK_T                          = 0x00000054;
+const WIN_VK_U                          = 0x00000055;
+const WIN_VK_V                          = 0x00000056;
+const WIN_VK_W                          = 0x00000057;
+const WIN_VK_X                          = 0x00000058;
+const WIN_VK_Y                          = 0x00000059;
+const WIN_VK_Z                          = 0x0000005A;
+const WIN_VK_LWIN                       = 0xE05B005B;
+const WIN_VK_RWIN                       = 0xE05C005C;
+const WIN_VK_APPS                       = 0xE05D005D;
+const WIN_VK_SLEEP                      = 0x0000005F;
+const WIN_VK_NUMPAD0                    = 0x00520060;
+const WIN_VK_NUMPAD1                    = 0x004F0061;
+const WIN_VK_NUMPAD2                    = 0x00500062;
+const WIN_VK_NUMPAD3                    = 0x00510063;
+const WIN_VK_NUMPAD4                    = 0x004B0064;
+const WIN_VK_NUMPAD5                    = 0x004C0065;
+const WIN_VK_NUMPAD6                    = 0x004D0066;
+const WIN_VK_NUMPAD7                    = 0x00470067;
+const WIN_VK_NUMPAD8                    = 0x00480068;
+const WIN_VK_NUMPAD9                    = 0x00490069;
+const WIN_VK_MULTIPLY                   = 0x0037006A;
+const WIN_VK_ADD                        = 0x004E006B;
+const WIN_VK_SEPARATOR                  = 0x0000006C;
+const WIN_VK_OEM_NEC_SEPARATE           = 0x0000006C;
+const WIN_VK_SUBTRACT                   = 0x004A006D;
+const WIN_VK_DECIMAL                    = 0x0053006E;
+const WIN_VK_DIVIDE                     = 0xE035006F;
+const WIN_VK_F1                         = 0x003B0070;
+const WIN_VK_F2                         = 0x003C0071;
+const WIN_VK_F3                         = 0x003D0072;
+const WIN_VK_F4                         = 0x003E0073;
+const WIN_VK_F5                         = 0x003F0074;
+const WIN_VK_F6                         = 0x00400075;
+const WIN_VK_F7                         = 0x00410076;
+const WIN_VK_F8                         = 0x00420077;
+const WIN_VK_F9                         = 0x00430078;
+const WIN_VK_F10                        = 0x00440079;
+const WIN_VK_F11                        = 0x0057007A;
+const WIN_VK_F12                        = 0x0058007B;
+const WIN_VK_F13                        = 0x0064007C;
+const WIN_VK_F14                        = 0x0065007D;
+const WIN_VK_F15                        = 0x0066007E;
+const WIN_VK_F16                        = 0x0067007F;
+const WIN_VK_F17                        = 0x00680080;
+const WIN_VK_F18                        = 0x00690081;
+const WIN_VK_F19                        = 0x006A0082;
+const WIN_VK_F20                        = 0x006B0083;
+const WIN_VK_F21                        = 0x006C0084;
+const WIN_VK_F22                        = 0x006D0085;
+const WIN_VK_F23                        = 0x006E0086;
+const WIN_VK_F24                        = 0x00760087;
+const WIN_VK_NUMLOCK                    = 0xE0450090;
+const WIN_VK_SCROLL                     = 0x00460091;
+const WIN_VK_OEM_FJ_JISHO               = 0x00000092;
+const WIN_VK_OEM_NEC_EQUAL              = 0x00000092;
+const WIN_VK_OEM_FJ_MASSHOU             = 0x00000093;
+const WIN_VK_OEM_FJ_TOUROKU             = 0x00000094;
+const WIN_VK_OEM_FJ_LOYA                = 0x00000095;
+const WIN_VK_OEM_FJ_ROYA                = 0x00000096;
+const WIN_VK_LSHIFT                     = 0x002A00A0;
+const WIN_VK_RSHIFT                     = 0x003600A1;
+const WIN_VK_LCONTROL                   = 0x001D00A2;
+const WIN_VK_RCONTROL                   = 0xE01D00A3;
+const WIN_VK_LMENU                      = 0x003800A4;
+const WIN_VK_RMENU                      = 0xE03800A5;
+const WIN_VK_BROWSER_BACK               = 0xE06A00A6;
+const WIN_VK_BROWSER_FORWARD            = 0xE06900A7;
+const WIN_VK_BROWSER_REFRESH            = 0xE06700A8;
+const WIN_VK_BROWSER_STOP               = 0xE06800A9;
+const WIN_VK_BROWSER_SEARCH             = 0x000000AA;
+const WIN_VK_BROWSER_FAVORITES          = 0xE06600AB;
+const WIN_VK_BROWSER_HOME               = 0xE03200AC;
+const WIN_VK_VOLUME_MUTE                = 0xE02000AD;
+const WIN_VK_VOLUME_DOWN                = 0xE02E00AE;
+const WIN_VK_VOLUME_UP                  = 0xE03000AF;
+const WIN_VK_MEDIA_NEXT_TRACK           = 0xE01900B0;
+const WIN_VK_OEM_FJ_000                 = 0x000000B0;
+const WIN_VK_MEDIA_PREV_TRACK           = 0xE01000B1;
+const WIN_VK_OEM_FJ_EUQAL               = 0x000000B1;
+const WIN_VK_MEDIA_STOP                 = 0xE02400B2;
+const WIN_VK_MEDIA_PLAY_PAUSE           = 0xE02200B3;
+const WIN_VK_OEM_FJ_00                  = 0x000000B3;
+const WIN_VK_LAUNCH_MAIL                = 0xE06C00B4;
+const WIN_VK_LAUNCH_MEDIA_SELECT        = 0xE06D00B5;
+const WIN_VK_LAUNCH_APP1                = 0xE06B00B6;
+const WIN_VK_LAUNCH_APP2                = 0xE02100B7;
+const WIN_VK_OEM_1                      = 0x000000BA;
+const WIN_VK_OEM_PLUS                   = 0x000000BB;
+const WIN_VK_OEM_COMMA                  = 0x000000BC;
+const WIN_VK_OEM_MINUS                  = 0x000000BD;
+const WIN_VK_OEM_PERIOD                 = 0x000000BE;
+const WIN_VK_OEM_2                      = 0x000000BF;
+const WIN_VK_OEM_3                      = 0x000000C0;
+const WIN_VK_ABNT_C1                    = 0x000000C1;
+const WIN_VK_ABNT_C2                    = 0x000000C2;
+const WIN_VK_OEM_4                      = 0x000000DB;
+const WIN_VK_OEM_5                      = 0x000000DC;
+const WIN_VK_OEM_6                      = 0x000000DD;
+const WIN_VK_OEM_7                      = 0x000000DE;
+const WIN_VK_OEM_8                      = 0x000000DF;
+const WIN_VK_OEM_NEC_DP1                = 0x000000E0;
+const WIN_VK_OEM_AX                     = 0x000000E1;
+const WIN_VK_OEM_NEC_DP2                = 0x000000E1;
+const WIN_VK_OEM_102                    = 0x000000E2;
+const WIN_VK_OEM_NEC_DP3                = 0x000000E2;
+const WIN_VK_ICO_HELP                   = 0x000000E3;
+const WIN_VK_OEM_NEC_DP4                = 0x000000E3;
+const WIN_VK_ICO_00                     = 0x000000E4;
+const WIN_VK_PROCESSKEY                 = 0x000000E5;
+const WIN_VK_ICO_CLEAR                  = 0x000000E6;
+const WIN_VK_PACKET                     = 0x000000E7;
+const WIN_VK_ERICSSON_BASE              = 0x000000E8;
+const WIN_VK_OEM_RESET                  = 0x000000E9;
+const WIN_VK_OEM_JUMP                   = 0x000000EA;
+const WIN_VK_OEM_PA1                    = 0x000000EB;
+const WIN_VK_OEM_PA2                    = 0x000000EC;
+const WIN_VK_OEM_PA3                    = 0x000000ED;
+const WIN_VK_OEM_WSCTRL                 = 0x000000EE;
+const WIN_VK_OEM_CUSEL                  = 0x000000EF;
+const WIN_VK_OEM_ATTN                   = 0x000000F0;
+const WIN_VK_OEM_FINISH                 = 0x000000F1;
+const WIN_VK_OEM_COPY                   = 0x000000F2;
+const WIN_VK_OEM_AUTO                   = 0x000000F3;
+const WIN_VK_OEM_ENLW                   = 0x000000F4;
+const WIN_VK_OEM_BACKTAB                = 0x000000F5;
+const WIN_VK_ATTN                       = 0x000000F6;
+const WIN_VK_CRSEL                      = 0x000000F7;
+const WIN_VK_EXSEL                      = 0x000000F8;
+const WIN_VK_EREOF                      = 0x000000F9;
+const WIN_VK_PLAY                       = 0x000000FA;
+const WIN_VK_ZOOM                       = 0x000000FB;
+const WIN_VK_NONAME                     = 0x000000FC;
+const WIN_VK_PA1                        = 0x000000FD;
+const WIN_VK_OEM_CLEAR                  = 0x000000FE;
+
+const WIN_VK_NUMPAD_RETURN              = 0xE01C000D;
+const WIN_VK_NUMPAD_PRIOR               = 0x00490021;
+const WIN_VK_NUMPAD_NEXT                = 0x00510022;
+const WIN_VK_NUMPAD_END                 = 0x004F0023;
+const WIN_VK_NUMPAD_HOME                = 0x00470024;
+const WIN_VK_NUMPAD_LEFT                = 0x004B0025;
+const WIN_VK_NUMPAD_UP                  = 0x00480026;
+const WIN_VK_NUMPAD_RIGHT               = 0x004D0027;
+const WIN_VK_NUMPAD_DOWN                = 0x00500028;
+const WIN_VK_NUMPAD_INSERT              = 0x0052002D;
+const WIN_VK_NUMPAD_DELETE              = 0x0053002E;
 
 // Mac
 
 const MAC_VK_ANSI_A                     = 0x00;
 const MAC_VK_ANSI_S                     = 0x01;
 const MAC_VK_ANSI_D                     = 0x02;
 const MAC_VK_ANSI_F                     = 0x03;
 const MAC_VK_ANSI_H                     = 0x04;
--- a/widget/tests/test_keycodes.xul
+++ b/widget/tests/test_keycodes.xul
@@ -1992,34 +1992,34 @@ function* runKeyEventTests()
                   "Alt", "AltLeft", nsIDOMKeyEvent.DOM_VK_ALT, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_LEFT);
     yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_RMENU,
                    modifiers:{altRightKey:1}, chars:""},
                   "Alt", "AltRight", nsIDOMKeyEvent.DOM_VK_ALT, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_RIGHT);
 
     // Win keys
     yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_LWIN,
                    modifiers:{}, chars:""},
-                  "OS" /* bug 1232918 */, "" /* TODO, should be "OSLeft" */, nsIDOMKeyEvent.DOM_VK_WIN, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_LEFT);
+                  "OS" /* bug 1232918 */, "OSLeft", nsIDOMKeyEvent.DOM_VK_WIN, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_LEFT);
     yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_RWIN,
                    modifiers:{}, chars:""},
-                  "OS" /* bug 1232918 */, "" /* TODO, should be "OSRight" */, nsIDOMKeyEvent.DOM_VK_WIN, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_RIGHT);
+                  "OS" /* bug 1232918 */, "OSRight", nsIDOMKeyEvent.DOM_VK_WIN, "", SHOULD_DELIVER_KEYDOWN_KEYUP, KeyboardEvent.DOM_KEY_LOCATION_RIGHT);
 
     // all keys on keyboard (keyCode test)
     yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_BACK,
                    modifiers:{}, chars:"\u0008"},
                   "Backspace", "Backspace", nsIDOMKeyEvent.DOM_VK_BACK_SPACE, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
     yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_TAB,
                    modifiers:{}, chars:"\t"},
                   "Tab", "Tab", nsIDOMKeyEvent.DOM_VK_TAB, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
     yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_RETURN,
                    modifiers:{}, chars:"\r"},
                   "Enter", "Enter", nsIDOMKeyEvent.DOM_VK_RETURN, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
     yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_PAUSE,
                    modifiers:{}, chars:""},
-                  "Pause", "ControlRight" /* TODO, should be "Pause" */, nsIDOMKeyEvent.DOM_VK_PAUSE, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
+                  "Pause", "Pause", nsIDOMKeyEvent.DOM_VK_PAUSE, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
     yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_KANA,
                    modifiers:{}, chars:""},
                   "Unidentified", "", nsIDOMKeyEvent.DOM_VK_KANA, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
     yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_JUNJA,
                    modifiers:{}, chars:""},
                   "JunjaMode", "", nsIDOMKeyEvent.DOM_VK_JUNJA, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
     yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_FINAL,
                    modifiers:{}, chars:""},
@@ -2058,17 +2058,46 @@ function* runKeyEventTests()
                    modifiers:{}, chars:""},
                   "PrintScreen", "PrintScreen", nsIDOMKeyEvent.DOM_VK_PRINTSCREEN, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
     yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_HELP,
                    modifiers:{}, chars:""},
                   "Help", "", nsIDOMKeyEvent.DOM_VK_HELP, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
     yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_SLEEP,
                    modifiers:{}, chars:""},
                   "Standby", "", nsIDOMKeyEvent.DOM_VK_SLEEP, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
-    // XXX TODO: we cannot test Home, Up, PageUp, Left, Right, End, Down, PageDown, Ins and Del.
+    yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_PRIOR,
+                   modifiers:{}, chars:""},
+                  "PageUp", "PageUp", nsIDOMKeyEvent.DOM_VK_PAGE_UP, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
+    yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_NEXT,
+                   modifiers:{}, chars:""},
+                  "PageDown", "PageDown", nsIDOMKeyEvent.DOM_VK_PAGE_DOWN, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
+    yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_END,
+                   modifiers:{}, chars:""},
+                  "End", "End", nsIDOMKeyEvent.DOM_VK_END, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
+    yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_HOME,
+                   modifiers:{}, chars:""},
+                  "Home", "Home", nsIDOMKeyEvent.DOM_VK_HOME, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
+    yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_LEFT,
+                   modifiers:{}, chars:""},
+                  "ArrowLeft", "ArrowLeft", nsIDOMKeyEvent.DOM_VK_LEFT, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
+    yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_UP,
+                   modifiers:{}, chars:""},
+                  "ArrowUp", "ArrowUp", nsIDOMKeyEvent.DOM_VK_UP, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
+    yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_RIGHT,
+                   modifiers:{}, chars:""},
+                  "ArrowRight", "ArrowRight", nsIDOMKeyEvent.DOM_VK_RIGHT, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
+    yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_DOWN,
+                   modifiers:{}, chars:""},
+                  "ArrowDown", "ArrowDown", nsIDOMKeyEvent.DOM_VK_DOWN, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
+    yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_INSERT,
+                   modifiers:{}, chars:""},
+                  "Insert", "Insert", nsIDOMKeyEvent.DOM_VK_INSERT, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
+    yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_DELETE,
+                   modifiers:{}, chars:""},
+                  "Delete", "Delete", nsIDOMKeyEvent.DOM_VK_DELETE, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
 
     // Backspace and Enter are handled with special path in mozilla::widget::NativeKey.  So, let's test them with modifiers too.
     yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_BACK,
                    modifiers:{ctrlKey:1}, chars:"\u007F"},
                   "Backspace", "Backspace", nsIDOMKeyEvent.DOM_VK_BACK_SPACE, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
     yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_BACK,
                    modifiers:{altKey:1}, chars:"\u0008"},
                   "Backspace", "Backspace", nsIDOMKeyEvent.DOM_VK_BACK_SPACE, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_STANDARD);
@@ -2431,50 +2460,56 @@ function* runKeyEventTests()
     yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_DECIMAL,
                    modifiers:{numLockKey:1}, chars:"."},
                   ".", "NumpadDecimal", nsIDOMKeyEvent.DOM_VK_DECIMAL, ".", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD);
     yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_DECIMAL,
                    modifiers:{numLockKey:1, shiftKey:1}, chars:"."},
                   ".", "NumpadDecimal", nsIDOMKeyEvent.DOM_VK_DECIMAL, ".", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD);
     yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_DIVIDE,
                    modifiers:{numLockKey:1}, chars:"/"},
-                  "/", "Slash" /* TODO, should be "NumpadDivide" */, nsIDOMKeyEvent.DOM_VK_DIVIDE, "/", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD);
+                  "/", "NumpadDivide", nsIDOMKeyEvent.DOM_VK_DIVIDE, "/", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD);
     yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_DIVIDE,
                    modifiers:{numLockKey:1, shiftKey:1}, chars:"/"},
-                  "/", "Slash" /* TODO, should be "NumpadDivide" */, nsIDOMKeyEvent.DOM_VK_DIVIDE, "/", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD);
+                  "/", "NumpadDivide", nsIDOMKeyEvent.DOM_VK_DIVIDE, "/", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD);
+    yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_NUMPAD_RETURN,
+                   modifiers:{numLockKey:1}, chars:"\r"},
+                  "Enter", "NumpadEnter", nsIDOMKeyEvent.DOM_VK_RETURN, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD);
+    yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_NUMPAD_RETURN,
+                   modifiers:{numLockKey:1, shiftKey:1}, chars:"\r"},
+                  "Enter", "NumpadEnter", nsIDOMKeyEvent.DOM_VK_RETURN, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD);
 
     // Numpad without NumLock
-    yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_PRIOR,
+    yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_NUMPAD_PRIOR,
                    modifiers:{}, chars:""},
                   "PageUp", "Numpad9", nsIDOMKeyEvent.DOM_VK_PAGE_UP, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD);
-    yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_NEXT,
+    yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_NUMPAD_NEXT,
                    modifiers:{}, chars:""},
                   "PageDown", "Numpad3", nsIDOMKeyEvent.DOM_VK_PAGE_DOWN, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD);
-    yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_END,
+    yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_NUMPAD_END,
                    modifiers:{}, chars:""},
                   "End", "Numpad1", nsIDOMKeyEvent.DOM_VK_END, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD);
-    yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_HOME,
+    yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_NUMPAD_HOME,
                    modifiers:{}, chars:""},
                   "Home", "Numpad7", nsIDOMKeyEvent.DOM_VK_HOME, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD);
-    yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_LEFT,
+    yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_NUMPAD_LEFT,
                    modifiers:{}, chars:""},
                   "ArrowLeft", "Numpad4", nsIDOMKeyEvent.DOM_VK_LEFT, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD);
-    yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_UP,
+    yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_NUMPAD_UP,
                    modifiers:{}, chars:""},
                   "ArrowUp", "Numpad8", nsIDOMKeyEvent.DOM_VK_UP, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD);
-    yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_RIGHT,
+    yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_NUMPAD_RIGHT,
                    modifiers:{}, chars:""},
                   "ArrowRight", "Numpad6", nsIDOMKeyEvent.DOM_VK_RIGHT, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD);
-    yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_DOWN,
+    yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_NUMPAD_DOWN,
                    modifiers:{}, chars:""},
                   "ArrowDown", "Numpad2", nsIDOMKeyEvent.DOM_VK_DOWN, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD);
-    yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_INSERT,
+    yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_NUMPAD_INSERT,
                    modifiers:{}, chars:""},
                   "Insert", "Numpad0", nsIDOMKeyEvent.DOM_VK_INSERT, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD);
-    yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_DELETE,
+    yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_NUMPAD_DELETE,
                    modifiers:{}, chars:""},
                   "Delete", "NumpadDecimal", nsIDOMKeyEvent.DOM_VK_DELETE, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD);
     yield testKey({layout:KEYBOARD_LAYOUT_EN_US, keyCode:WIN_VK_CLEAR,
                    modifiers:{}, chars:""},
                   "Clear", "Numpad5", nsIDOMKeyEvent.DOM_VK_CLEAR, "", SHOULD_DELIVER_ALL, KeyboardEvent.DOM_KEY_LOCATION_NUMPAD);
 
     // Even if widget receives unknown keycode, it should dispatch key events
     // whose keycode is 0 rather than native keycode.
--- a/widget/windows/KeyboardLayout.cpp
+++ b/widget/windows/KeyboardLayout.cpp
@@ -3723,93 +3723,95 @@ KeyboardLayout::SynthesizeNativeKeyEvent
   memset(kbdState, 0, sizeof(kbdState));
   // This changes the state of the keyboard for the current thread only,
   // and we'll restore it soon, so this should be OK.
   ::SetKeyboardState(kbdState);
 
   OverrideLayout(loadedLayout);
 
   uint8_t argumentKeySpecific = 0;
-  switch (aNativeKeyCode) {
+  switch (aNativeKeyCode & 0xFF) {
     case VK_SHIFT:
       aModifierFlags &= ~(nsIWidget::SHIFT_L | nsIWidget::SHIFT_R);
       argumentKeySpecific = VK_LSHIFT;
       break;
     case VK_LSHIFT:
       aModifierFlags &= ~nsIWidget::SHIFT_L;
-      argumentKeySpecific = aNativeKeyCode;
-      aNativeKeyCode = VK_SHIFT;
+      argumentKeySpecific = aNativeKeyCode & 0xFF;
+      aNativeKeyCode = (aNativeKeyCode & 0xFFFF0000) | VK_SHIFT;
       break;
     case VK_RSHIFT:
       aModifierFlags &= ~nsIWidget::SHIFT_R;
-      argumentKeySpecific = aNativeKeyCode;
-      aNativeKeyCode = VK_SHIFT;
+      argumentKeySpecific = aNativeKeyCode & 0xFF;
+      aNativeKeyCode = (aNativeKeyCode & 0xFFFF0000) | VK_SHIFT;
       break;
     case VK_CONTROL:
       aModifierFlags &= ~(nsIWidget::CTRL_L | nsIWidget::CTRL_R);
       argumentKeySpecific = VK_LCONTROL;
       break;
     case VK_LCONTROL:
       aModifierFlags &= ~nsIWidget::CTRL_L;
-      argumentKeySpecific = aNativeKeyCode;
-      aNativeKeyCode = VK_CONTROL;
+      argumentKeySpecific = aNativeKeyCode & 0xFF;
+      aNativeKeyCode = (aNativeKeyCode & 0xFFFF0000) | VK_CONTROL;
       break;
     case VK_RCONTROL:
       aModifierFlags &= ~nsIWidget::CTRL_R;
-      argumentKeySpecific = aNativeKeyCode;
-      aNativeKeyCode = VK_CONTROL;
+      argumentKeySpecific = aNativeKeyCode & 0xFF;
+      aNativeKeyCode = (aNativeKeyCode & 0xFFFF0000) | VK_CONTROL;
       break;
     case VK_MENU:
       aModifierFlags &= ~(nsIWidget::ALT_L | nsIWidget::ALT_R);
       argumentKeySpecific = VK_LMENU;
       break;
     case VK_LMENU:
       aModifierFlags &= ~nsIWidget::ALT_L;
-      argumentKeySpecific = aNativeKeyCode;
-      aNativeKeyCode = VK_MENU;
+      argumentKeySpecific = aNativeKeyCode & 0xFF;
+      aNativeKeyCode = (aNativeKeyCode & 0xFFFF0000) | VK_MENU;
       break;
     case VK_RMENU:
       aModifierFlags &= ~nsIWidget::ALT_R;
-      argumentKeySpecific = aNativeKeyCode;
-      aNativeKeyCode = VK_MENU;
+      argumentKeySpecific = aNativeKeyCode & 0xFF;
+      aNativeKeyCode = (aNativeKeyCode & 0xFFFF0000) | VK_MENU;
       break;
     case VK_CAPITAL:
       aModifierFlags &= ~nsIWidget::CAPS_LOCK;
       argumentKeySpecific = VK_CAPITAL;
       break;
     case VK_NUMLOCK:
       aModifierFlags &= ~nsIWidget::NUM_LOCK;
       argumentKeySpecific = VK_NUMLOCK;
       break;
   }
 
   AutoTArray<KeyPair,10> keySequence;
   WinUtils::SetupKeyModifiersSequence(&keySequence, aModifierFlags);
-  NS_ASSERTION(aNativeKeyCode >= 0 && aNativeKeyCode < 256,
-               "Native VK key code out of range");
   keySequence.AppendElement(KeyPair(aNativeKeyCode, argumentKeySpecific));
 
   // Simulate the pressing of each modifier key and then the real key
   // FYI: Each NativeKey instance here doesn't need to override keyboard layout
   //      since this method overrides and restores the keyboard layout.
   for (uint32_t i = 0; i < keySequence.Length(); ++i) {
     uint8_t key = keySequence[i].mGeneral;
     uint8_t keySpecific = keySequence[i].mSpecific;
+    uint16_t scanCode = keySequence[i].mScanCode;
     kbdState[key] = 0x81; // key is down and toggled on if appropriate
     if (keySpecific) {
       kbdState[keySpecific] = 0x81;
     }
     ::SetKeyboardState(kbdState);
     ModifierKeyState modKeyState;
-    UINT scanCode =
-      ComputeScanCodeForVirtualKeyCode(keySpecific ? keySpecific : key);
+    // If scan code isn't specified explicitly, let's compute it with current
+    // keyboard layout.
+    if (!scanCode) {
+      scanCode =
+        ComputeScanCodeForVirtualKeyCode(keySpecific ? keySpecific : key);
+    }
     LPARAM lParam = static_cast<LPARAM>(scanCode << 16);
-    // Add extended key flag to the lParam for right control key and right alt
-    // key.
-    if (keySpecific == VK_RCONTROL || keySpecific == VK_RMENU) {
+    // If the scan code is for an extended key, set extended key flag.
+    if ((scanCode & 0xFF00) == 0xE000) {
       lParam |= 0x1000000;
     }
     bool makeSysKeyMsg = IsSysKey(key, modKeyState);
     MSG keyDownMsg =
       WinUtils::InitMSG(makeSysKeyMsg ? WM_SYSKEYDOWN : WM_KEYDOWN,
                         key, lParam, aWidget->GetWindowHandle());
     if (i == keySequence.Length() - 1) {
       bool makeDeadCharMsg =
@@ -3851,28 +3853,32 @@ KeyboardLayout::SynthesizeNativeKeyEvent
     } else {
       NativeKey nativeKey(aWidget, keyDownMsg, modKeyState);
       nativeKey.HandleKeyDownMessage();
     }
   }
   for (uint32_t i = keySequence.Length(); i > 0; --i) {
     uint8_t key = keySequence[i - 1].mGeneral;
     uint8_t keySpecific = keySequence[i - 1].mSpecific;
+    uint16_t scanCode = keySequence[i - 1].mScanCode;
     kbdState[key] = 0; // key is up and toggled off if appropriate
     if (keySpecific) {
       kbdState[keySpecific] = 0;
     }
     ::SetKeyboardState(kbdState);
     ModifierKeyState modKeyState;
-    UINT scanCode =
-      ComputeScanCodeForVirtualKeyCode(keySpecific ? keySpecific : key);
+    // If scan code isn't specified explicitly, let's compute it with current
+    // keyboard layout.
+    if (!scanCode) {
+      scanCode =
+        ComputeScanCodeForVirtualKeyCode(keySpecific ? keySpecific : key);
+    }
     LPARAM lParam = static_cast<LPARAM>(scanCode << 16);
-    // Add extended key flag to the lParam for right control key and right alt
-    // key.
-    if (keySpecific == VK_RCONTROL || keySpecific == VK_RMENU) {
+    // If the scan code is for an extended key, set extended key flag.
+    if ((scanCode & 0xFF00) == 0xE000) {
       lParam |= 0x1000000;
     }
     // Don't use WM_SYSKEYUP for Alt keyup.
     bool makeSysKeyMsg = IsSysKey(key, modKeyState) && key != VK_MENU;
     MSG keyUpMsg = WinUtils::InitMSG(makeSysKeyMsg ? WM_SYSKEYUP : WM_KEYUP,
                                      key, lParam,
                                      aWidget->GetWindowHandle());
     NativeKey nativeKey(aWidget, keyUpMsg, modKeyState);
--- a/widget/windows/nsWindowDefs.h
+++ b/widget/windows/nsWindowDefs.h
@@ -79,21 +79,27 @@ const wchar_t kClassNameTransition[] = L
 
 /**************************************************************
  *
  * SECTION: structs
  * 
  **************************************************************/
 
 // Used for synthesizing events
-struct KeyPair {
+struct KeyPair
+{
   uint8_t mGeneral;
   uint8_t mSpecific;
+  uint16_t mScanCode;
   KeyPair(uint32_t aGeneral, uint32_t aSpecific)
-    : mGeneral(uint8_t(aGeneral)), mSpecific(uint8_t(aSpecific)) {}
+    : mGeneral(aGeneral & 0xFF)
+    , mSpecific(aSpecific & 0xFF)
+    , mScanCode((aGeneral & 0xFFFF0000) >> 16)
+  {
+  }
 };
 
 #if (WINVER < 0x0600)
 struct TITLEBARINFOEX
 {
     DWORD cbSize;
     RECT rcTitleBar;
     DWORD rgstate[CCHILDREN_TITLEBAR + 1];