diff --git a/widget/tests/test_keycodes.xul b/widget/tests/test_keycodes.xul index fb49bef369bb..f32d2b73025e 100644 --- a/widget/tests/test_keycodes.xul +++ b/widget/tests/test_keycodes.xul @@ -60,6 +60,14 @@ function synthesizeNativeKey(aLayout, aKeyCode, aModifiers, aSystemChars, if (aModifiers.ctrlRight) modifiers |= 0x0800; if (aModifiers.alt) modifiers |= 0x1000; if (aModifiers.altRight) modifiers |= 0x2000; + if (IS_WIN && aModifiers.altGr) { + if (!aModifiers.ctrl && !aModifiers.ctrlRight) { + modifiers |= 0x0400; + } + if (!aModifiers.alt && !aModifiers.altRight) { + modifiers |= 0x1000; + } + } if (aModifiers.command) modifiers |= 0x4000; if (aModifiers.commandRight) modifiers |= 0x8000; if (aModifiers.help) modifiers |= 0x10000; @@ -175,18 +183,48 @@ function runKeyEventTests() function isStateChangingModifierKeyEvent(e) { + var flags = 0; + if (e.type == "keydown") { + flags = keyDownFlags ^ keyUpFlags; + } else if (e.type == "keyup") { + flags = keyUpFlags; + } switch (e.keyCode) { case e.DOM_VK_SHIFT: + is(e.ctrlKey, (flags & kCtrlFlag) != 0, name + ", Ctrl of Shift " + e.type + " event mismatch"); + is(e.metaKey, (flags & kMetaFlag) != 0, name + ", Command of Shift " + e.type + " event mismatch"); + is(e.altKey, (flags & kAltFlag) != 0, name + ", Alt of Shift " + e.type + " event mismatch"); + is(e.shiftKey, e.type == "keydown", name + ", Shift of Shift " + e.type + " event mismatch"); return (testingEvent.shift || testingEvent.shiftRight) && removeFlag(e, kShiftFlag); case e.DOM_VK_CONTROL: - return (testingEvent.ctrl || testingEvent.ctrlRight) && removeFlag(e, kCtrlFlag); + is(e.ctrlKey, e.type == "keydown", name + ", Ctrl of Ctrl " + e.type + " event mismatch"); + is(e.metaKey, (flags & kMetaFlag) != 0, name + ", Command of Ctrl " + e.type + " event mismatch"); + is(e.altKey, (flags & kAltFlag) != 0, name + ", Alt of Ctrl " + e.type + " event mismatch"); + is(e.shiftKey, (flags & kShiftFlag) != 0, name + ", Shift of Ctrl " + e.type + " event mismatch"); + return (testingEvent.ctrl || testingEvent.ctrlRight || (IS_WIN && testingEvent.altGr)) && removeFlag(e, kCtrlFlag); case e.DOM_VK_ALT: - return (testingEvent.alt || testingEvent.altRight) && removeFlag(e, kAltFlag); + is(e.ctrlKey, (flags & kCtrlFlag) != 0, name + ", Ctrl of Alt " + e.type + " event mismatch"); + is(e.metaKey, (flags & kMetaFlag) != 0, name + ", Command of Alt " + e.type + " event mismatch"); + is(e.altKey, e.type == "keydown", name + ", Alt of Alt " + e.type + " event mismatch"); + is(e.shiftKey, (flags & kShiftFlag) != 0, name + ", Shift of Alt " + e.type + " event mismatch"); + return (testingEvent.alt || testingEvent.altRight || (IS_WIN && testingEvent.altGr)) && removeFlag(e, kAltFlag); case e.DOM_VK_META: + is(e.ctrlKey, (flags & kCtrlFlag) != 0, name + ", Ctrl of Command " + e.type + " evnet mismatch"); + is(e.metaKey, e.type == "keydown", name + ", Command of Command " + e.type + " evnet mismatch"); + is(e.altKey, (flags & kAltFlag) != 0, name + ", Alt of Command " + e.type + " evnet mismatch"); + is(e.shiftKey, (flags & kShiftFlag) != 0, name + ", Shift of Command " + e.type + " evnet mismatch"); return testingEvent.command && removeFlag(e, kMetaFlag); case e.DOM_VK_NUM_LOCK: + is(e.ctrlKey, (flags & kCtrlFlag) != 0, name + ", Ctrl of NumLock " + e.type + " event mismatch"); + is(e.metaKey, (flags & kMetaFlag) != 0, name + ", Command of NumLock " + e.type + " event mismatch"); + is(e.altKey, (flags & kAltFlag) != 0, name + ", Alt of NumLock " + e.type + " event mismatch"); + is(e.shiftKey, (flags & kShiftFlag) != 0, name + ", Shift of NumLock " + e.type + " event mismatch"); return testingEvent.numLock && removeFlag(e, kNumLockFlag); case e.DOM_VK_CAPS_LOCK: + is(e.ctrlKey, (flags & kCtrlFlag) != 0, name + ", Ctrl of CapsLock " + e.type + " event mismatch"); + is(e.metaKey, (flags & kMetaFlag) != 0, name + ", Command of CapsLock " + e.type + " event mismatch"); + is(e.altKey, (flags & kAltFlag) != 0, name + ", Alt of CapsLock " + e.type + " event mismatch"); + is(e.shiftKey, (flags & kShiftFlag) != 0, name + ", Shift of CapsLock " + e.type + " event mismatch"); return testingEvent.capsLock && removeFlag(e, kCapsLockFlag); } return false; @@ -202,9 +240,12 @@ function runKeyEventTests() const SHOULD_DELIVER_KEYDOWN = 0x1; const SHOULD_DELIVER_KEYPRESS = 0x2; const SHOULD_DELIVER_KEYUP = 0x4; + const SHOULD_NOT_CAUSE_INPUT = 0x8; const SHOULD_DELIVER_ALL = SHOULD_DELIVER_KEYDOWN | SHOULD_DELIVER_KEYPRESS | SHOULD_DELIVER_KEYUP; + const SHOULD_DELIVER_ALL_BUT_NOT_CAUSE_INPUT = SHOULD_DELIVER_ALL | + SHOULD_NOT_CAUSE_INPUT; const SHOULD_DELIVER_KEYDOWN_KEYUP = SHOULD_DELIVER_KEYDOWN | SHOULD_DELIVER_KEYUP; const SHOULD_DELIVER_KEYDOWN_KEYPRESS = SHOULD_DELIVER_KEYDOWN | @@ -227,9 +268,9 @@ function runKeyEventTests() // state changing for synthesizeNativeKeyEvent. if (aEvent.shift || aEvent.shiftRight) keyDownFlags |= kShiftFlag; - if (aEvent.ctrl || aEvent.ctrlRight || aEvent.altGr) + if (aEvent.ctrl || aEvent.ctrlRight || (IS_WIN && aEvent.altGr)) keyDownFlags |= kCtrlFlag; - if (aEvent.alt || aEvent.altRight || aEvent.altGr) + if (aEvent.alt || aEvent.altRight || (IS_WIN && aEvent.altGr)) keyDownFlags |= kAltFlag; if (aEvent.command) keyDownFlags |= kMetaFlag; @@ -271,10 +312,18 @@ function runKeyEventTests() if (firedEventType != "") { var e = eventList[i]; - is(e.ctrlKey, aEvent.ctrl || aEvent.ctrlRight || 0, name + ", Ctrl mismatch"); - is(e.metaKey, aEvent.command || aEvent.commandRight || 0, name + ", Command mismatch"); - is(e.altKey, aEvent.alt || aEvent.altRight || 0, name + ", Alt mismatch"); - is(e.shiftKey, aEvent.shift || aEvent.shiftRight || 0, name + ", Shift mismatch"); + if (e.type == "keypress") { + var isCtrlExpected = aEvent.ctrl || aEvent.ctrlRight || false; + var isAltExpected = aEvent.alt || aEvent.altRight || false; + if (IS_WIN && aEvent.altGr) { + isCtrlExpected = isAltExpected = + ((aShouldDelivedEvent & SHOULD_NOT_CAUSE_INPUT) != 0); + } + is(e.ctrlKey, isCtrlExpected, name + ", Ctrl mismatch"); + is(e.metaKey, aEvent.command || aEvent.commandRight || false, name + ", Command mismatch"); + is(e.altKey, isAltExpected, name + ", Alt mismatch"); + is(e.shiftKey, aEvent.shift || aEvent.shiftRight || false, name + ", Shift mismatch"); + } if (aExpectGeckoChar.length > 0 && e.type == "keypress") { is(e.charCode, aExpectGeckoChar.charCodeAt(keypressCount++), name + ", charcode"); @@ -1594,44 +1643,24 @@ function runKeyEventTests() // Numpad testKey({layout:"US", keyCode:96, numLock:1, chars:"0"}, nsIDOMKeyEvent.DOM_VK_NUMPAD0, "0", SHOULD_DELIVER_ALL); - testKey({layout:"US", keyCode:96, numLock:1, shift:1, chars:"0"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD0, "0", SHOULD_DELIVER_ALL); testKey({layout:"US", keyCode:97, numLock:1, chars:"1"}, nsIDOMKeyEvent.DOM_VK_NUMPAD1, "1", SHOULD_DELIVER_ALL); - testKey({layout:"US", keyCode:97, numLock:1, shift:1, chars:"1"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD1, "1", SHOULD_DELIVER_ALL); testKey({layout:"US", keyCode:98, numLock:1, chars:"2"}, nsIDOMKeyEvent.DOM_VK_NUMPAD2, "2", SHOULD_DELIVER_ALL); - testKey({layout:"US", keyCode:98, numLock:1, shift:1, chars:"2"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD2, "2", SHOULD_DELIVER_ALL); testKey({layout:"US", keyCode:99, numLock:1, chars:"3"}, nsIDOMKeyEvent.DOM_VK_NUMPAD3, "3", SHOULD_DELIVER_ALL); - testKey({layout:"US", keyCode:99, numLock:1, shift:1, chars:"3"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD3, "3", SHOULD_DELIVER_ALL); testKey({layout:"US", keyCode:100, numLock:1, chars:"4"}, nsIDOMKeyEvent.DOM_VK_NUMPAD4, "4", SHOULD_DELIVER_ALL); - testKey({layout:"US", keyCode:100, numLock:1, shift:1, chars:"4"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD4, "4", SHOULD_DELIVER_ALL); testKey({layout:"US", keyCode:101, numLock:1, chars:"5"}, nsIDOMKeyEvent.DOM_VK_NUMPAD5, "5", SHOULD_DELIVER_ALL); - testKey({layout:"US", keyCode:101, numLock:1, shift:1, chars:"5"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD5, "5", SHOULD_DELIVER_ALL); testKey({layout:"US", keyCode:102, numLock:1, chars:"6"}, nsIDOMKeyEvent.DOM_VK_NUMPAD6, "6", SHOULD_DELIVER_ALL); - testKey({layout:"US", keyCode:102, numLock:1, shift:1, chars:"6"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD6, "6", SHOULD_DELIVER_ALL); testKey({layout:"US", keyCode:103, numLock:1, chars:"7"}, nsIDOMKeyEvent.DOM_VK_NUMPAD7, "7", SHOULD_DELIVER_ALL); - testKey({layout:"US", keyCode:103, numLock:1, shift:1, chars:"7"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD7, "7", SHOULD_DELIVER_ALL); testKey({layout:"US", keyCode:104, numLock:1, chars:"8"}, nsIDOMKeyEvent.DOM_VK_NUMPAD8, "8", SHOULD_DELIVER_ALL); - testKey({layout:"US", keyCode:104, numLock:1, shift:1, chars:"8"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD8, "8", SHOULD_DELIVER_ALL); testKey({layout:"US", keyCode:105, numLock:1, chars:"9"}, nsIDOMKeyEvent.DOM_VK_NUMPAD9, "9", SHOULD_DELIVER_ALL); - testKey({layout:"US", keyCode:105, numLock:1, shift:1, chars:"9"}, - nsIDOMKeyEvent.DOM_VK_NUMPAD9, "9", SHOULD_DELIVER_ALL); testKey({layout:"US", keyCode:106, numLock:1, chars:"*"}, nsIDOMKeyEvent.DOM_VK_MULTIPLY, "*", SHOULD_DELIVER_ALL); @@ -1832,10 +1861,10 @@ function runKeyEventTests() nsIDOMKeyEvent.DOM_VK_ASTERISK, "\u00B5", SHOULD_DELIVER_ALL); testKey({layout:"French", keyCode:220, capsLock:1, shift:1, chars:"*"}, nsIDOMKeyEvent.DOM_VK_ASTERISK, "*", SHOULD_DELIVER_ALL); - testKey({layout:"French", keyCode:226, capsLock:1, chars:">"}, - nsIDOMKeyEvent.DOM_VK_LESS_THAN, ">", SHOULD_DELIVER_ALL); - testKey({layout:"French", keyCode:226, capsLock:1, shift:1, chars:"<"}, + testKey({layout:"French", keyCode:226, capsLock:1, chars:"<"}, nsIDOMKeyEvent.DOM_VK_LESS_THAN, "<", SHOULD_DELIVER_ALL); + testKey({layout:"French", keyCode:226, capsLock:1, shift:1, chars:">"}, + nsIDOMKeyEvent.DOM_VK_LESS_THAN, ">", SHOULD_DELIVER_ALL); testKey({layout:"French", keyCode:188, capsLock:1, chars:"?"}, nsIDOMKeyEvent.DOM_VK_COMMA, "?", SHOULD_DELIVER_ALL); testKey({layout:"French", keyCode:188, capsLock:1, shift:1, chars:","}, @@ -1857,7 +1886,7 @@ function runKeyEventTests() testKey({layout:"French", keyCode:48, altGr:1, chars:"@"}, nsIDOMKeyEvent.DOM_VK_0, "@", SHOULD_DELIVER_ALL); testKey({layout:"French", keyCode:49, altGr:1, chars:""}, - nsIDOMKeyEvent.DOM_VK_1, "", SHOULD_DELIVER_KEYDOWN_KEYUP); + nsIDOMKeyEvent.DOM_VK_1, "&", SHOULD_DELIVER_ALL_BUT_NOT_CAUSE_INPUT); //testKey({layout:"French", keyCode:50, altGr:1, chars:""}, // nsIDOMKeyEvent.DOM_VK_2, "2", SHOULD_DELIVER_ALL); // Dead-key testKey({layout:"French", keyCode:51, altGr:1, chars:"#"}, diff --git a/widget/windows/nsWindow.cpp b/widget/windows/nsWindow.cpp index 53e05ff7c1da..94d151d26d6b 100644 --- a/widget/windows/nsWindow.cpp +++ b/widget/windows/nsWindow.cpp @@ -6410,6 +6410,25 @@ LRESULT nsWindow::OnKeyDown(const MSG &aMsg, if (msg.message == WM_DEADCHAR) { return false; } +#ifdef DEBUG + if (KeyboardLayout::IsPrintableCharKey(virtualKeyCode)) { + nsPrintfCString log( + "virtualKeyCode=0x%02X, inputtingChar={ mChars=[ 0x%04X, 0x%04X, " + "0x%04X, 0x%04X, 0x%04X ], mLength=%d }, wParam=0x%04X", + virtualKeyCode, inputtingChars.mChars[0], inputtingChars.mChars[1], + inputtingChars.mChars[2], inputtingChars.mChars[3], + inputtingChars.mChars[4], inputtingChars.mLength, msg.wParam); + if (!inputtingChars.mLength) { + log.Insert("length is zero: ", 0); + NS_ERROR(log.get()); + NS_ABORT(); + } else if (inputtingChars.mChars[0] != msg.wParam) { + log.Insert("character mismatch: ", 0); + NS_ERROR(log.get()); + NS_ABORT(); + } + } +#endif // #ifdef DEBUG return OnChar(msg, nativeKey, aModKeyState, nsnull, extraFlags); }