From 0c2bc78774aac106f1adb5c24b269a54c6a77b44 Mon Sep 17 00:00:00 2001 From: "karlt+@karlt.net" Date: Thu, 27 Mar 2008 22:19:14 -0700 Subject: [PATCH] Be less sensitive about the shift modifier for key events with character codes. b=401086, r=neil, sr=jst --- content/xbl/src/nsXBLPrototypeHandler.cpp | 31 ++++++++++++++++++++--- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/content/xbl/src/nsXBLPrototypeHandler.cpp b/content/xbl/src/nsXBLPrototypeHandler.cpp index f7284e47e7b6..e54a063418f2 100644 --- a/content/xbl/src/nsXBLPrototypeHandler.cpp +++ b/content/xbl/src/nsXBLPrototypeHandler.cpp @@ -70,7 +70,6 @@ #include "nsContentUtils.h" #include "nsIScriptError.h" #include "nsXPIDLString.h" -#include "nsReadableUtils.h" #include "nsGkAtoms.h" #include "nsGUIEvent.h" #include "nsIXPConnect.h" @@ -606,7 +605,19 @@ nsXBLPrototypeHandler::KeyEventMatched(nsIDOMKeyEvent* aKeyEvent) if (mMisc) { aKeyEvent->GetCharCode(&code); - code = ToLowerCase(PRUnichar(code)); + // non-BMP characters are currently not handled. + if (!IS_IN_BMP(code)) + return PR_FALSE; + + // Ignore CapsLock, and distinguish between Ctrl-a and Ctrl-Shift-A, + // unless any Shift-state is explicitly permitted (in which case, + // mDetail is lowercase). + PRBool isShift; + aKeyEvent->GetShiftKey(&isShift); + if ((mKeyMask & cShiftMask) && isShift) + code = ToUpperCase(PRUnichar(code)); + else + code = ToLowerCase(PRUnichar(code)); } else aKeyEvent->GetKeyCode(&code); @@ -930,11 +941,19 @@ nsXBLPrototypeHandler::ConstructPrototype(nsIContent* aKeyElement, if (!key.IsEmpty()) { if (mKeyMask == 0) mKeyMask = cAllModifiers; - ToLowerCase(key); + // If Shift is required then ensure the case of the character matches the + // Shift-state. Otherwise normalize to lowercase. + if ((mKeyMask & (cShift | cShiftMask)) == (cShift | cShiftMask)) + ToUpperCase(key); + else + ToLowerCase(key); // We have a charcode. mMisc = 1; + // non-BMP characters are currently not handled. + // KeyEventMatched doesn't match against surrogate codes. mDetail = key[0]; + const PRUint8 GTK2Modifiers = cShift | cControl | cShiftMask | cControlMask; if ((mKeyMask & GTK2Modifiers) == GTK2Modifiers && modifiers.First() != PRUnichar(',') && @@ -1004,7 +1023,11 @@ nsXBLPrototypeHandler::ModifiersMatchMask(nsIDOMUIEvent* aEvent) return PR_FALSE; } - if (mKeyMask & cShiftMask) { + // Punctuation and characters from some scripts may be on any level, + // so ignore the Shift state for key events with unicase character codes. + // (The Shift state is considered in KeyEventMatched for letters from + // bicameral scripts.) + if (!(key && mMisc) && (mKeyMask & cShiftMask)) { key ? key->GetShiftKey(&keyPresent) : mouse->GetShiftKey(&keyPresent); if (keyPresent != ((mKeyMask & cShift) != 0)) return PR_FALSE;