зеркало из https://github.com/mozilla/gecko-dev.git
Bug 677252 part.1 Reimplement keycode computation in cocoa widget r=smaug+smichaud
This commit is contained in:
Родитель
94c45bf1d7
Коммит
4d7f3814a7
|
@ -138,6 +138,7 @@ export::
|
|||
LOCAL_INCLUDES = \
|
||||
$(TK_CFLAGS) \
|
||||
-I$(srcdir)/../xpwidgets \
|
||||
-I$(srcdir)/../shared \
|
||||
$(NULL)
|
||||
|
||||
LDFLAGS += \
|
||||
|
|
|
@ -61,6 +61,7 @@ namespace widget {
|
|||
// Key code constants
|
||||
enum
|
||||
{
|
||||
kSpaceKeyCode = 0x31,
|
||||
kEscapeKeyCode = 0x35,
|
||||
kRCommandKeyCode = 0x36, // right command key
|
||||
kCommandKeyCode = 0x37,
|
||||
|
@ -71,6 +72,7 @@ enum
|
|||
kRShiftKeyCode = 0x3C, // right shift key
|
||||
kROptionKeyCode = 0x3D, // right option key
|
||||
kRControlKeyCode = 0x3E, // right control key
|
||||
|
||||
kClearKeyCode = 0x47,
|
||||
|
||||
// function keys
|
||||
|
@ -89,6 +91,10 @@ enum
|
|||
kF13KeyCode = 0x69,
|
||||
kF14KeyCode = 0x6B,
|
||||
kF15KeyCode = 0x71,
|
||||
kF16KeyCode = 0x6A,
|
||||
kF17KeyCode = 0x40,
|
||||
kF18KeyCode = 0x4F,
|
||||
kF19KeyCode = 0x50,
|
||||
|
||||
kPrintScreenKeyCode = kF13KeyCode,
|
||||
kScrollLockKeyCode = kF14KeyCode,
|
||||
|
@ -112,10 +118,14 @@ enum
|
|||
kKeypadDecimalKeyCode = 0x41,
|
||||
kKeypadDivideKeyCode = 0x4B,
|
||||
kKeypadEqualsKeyCode = 0x51, // no correpsonding gecko key code
|
||||
|
||||
kEnterKeyCode = 0x4C,
|
||||
kReturnKeyCode = 0x24,
|
||||
kPowerbookEnterKeyCode = 0x34, // Enter on Powerbook's keyboard is different
|
||||
|
||||
// IME keys
|
||||
kJapanese_Kana = 0x68,
|
||||
|
||||
kInsertKeyCode = 0x72, // also help key
|
||||
kDeleteKeyCode = 0x75, // also forward delete key
|
||||
kTabKeyCode = 0x30,
|
||||
|
@ -287,6 +297,19 @@ public:
|
|||
*/
|
||||
void InitKeyEvent(NSEvent *aNativeKeyEvent, nsKeyEvent& aKeyEvent);
|
||||
|
||||
/**
|
||||
* ComputeGeckoKeyCode() returns Gecko keycode for aNativeKeyCode on current
|
||||
* keyboard layout.
|
||||
*
|
||||
* @param aNativeKeyCode A native keycode.
|
||||
* @param aKbType A native Keyboard Type value. Typically,
|
||||
* this is a result of ::LMGetKbdType().
|
||||
* @param aCmdIsPressed TRUE if Cmd key is pressed. Otherwise, FALSE.
|
||||
* @return The computed Gecko keycode.
|
||||
*/
|
||||
PRUint32 ComputeGeckoKeyCode(UInt32 aNativeKeyCode, UInt32 aKbType,
|
||||
bool aCmdIsPressed);
|
||||
|
||||
protected:
|
||||
/**
|
||||
* TranslateToString() computes the inputted text from the native keyCode,
|
||||
|
@ -317,7 +340,7 @@ protected:
|
|||
* returns the charCode of it. Otherwise,
|
||||
* returns 0.
|
||||
*/
|
||||
PRUint32 TranslateToChar(UInt32 aKeyCode, UInt32 aModifiers, UInt32 aKbdType);
|
||||
PRUint32 TranslateToChar(UInt32 aKeyCode, UInt32 aModifiers, UInt32 aKbType);
|
||||
|
||||
/**
|
||||
* InitKeyPressEvent() initializes aKeyEvent for aNativeKeyEvent.
|
||||
|
@ -328,8 +351,11 @@ protected:
|
|||
* @param aKeyEvent The result -- a Gecko key event initialized
|
||||
* from the native key event. This must be
|
||||
* NS_KEY_PRESS event.
|
||||
* @param aKbType A native Keyboard Type value. Typically,
|
||||
* this is a result of ::LMGetKbdType().
|
||||
*/
|
||||
void InitKeyPressEvent(NSEvent *aNativeKeyEvent, nsKeyEvent& aKeyEvent);
|
||||
void InitKeyPressEvent(NSEvent *aNativeKeyEvent, nsKeyEvent& aKeyEvent,
|
||||
UInt32 aKbType);
|
||||
|
||||
bool GetBoolProperty(const CFStringRef aKey);
|
||||
bool GetStringProperty(const CFStringRef aKey, CFStringRef &aStr);
|
||||
|
@ -402,25 +428,6 @@ public:
|
|||
const nsAString& aCharacters,
|
||||
const nsAString& aUnmodifiedCharacters);
|
||||
|
||||
/**
|
||||
* ComputeGeckoKeyCode() computes Gecko defined keyCode from the native
|
||||
* keyCode or the characters.
|
||||
*
|
||||
* @param aNativeKeyCode A native keyCode.
|
||||
* @param aCharacters Characters from the native key event (obtained
|
||||
* using charactersIgnoringModifiers). If the
|
||||
* native event contains one or more characters,
|
||||
* the result is computed from this.
|
||||
* @return Gecko keyCode value for aNativeKeyCode (if
|
||||
* aCharacters is empty), otherwise for
|
||||
* aCharacters (if aCharacters is non-empty).
|
||||
* Or zero if the aCharacters contains one or
|
||||
* more Unicode characters, or if aNativeKeyCode
|
||||
* cannot be mapped to a Gecko keyCode.
|
||||
*/
|
||||
static PRUint32 ComputeGeckoKeyCode(UInt32 aNativeKeyCode,
|
||||
NSString *aCharacters);
|
||||
|
||||
/**
|
||||
* IsSpecialGeckoKey() checks whether aNativeKeyCode is mapped to a special
|
||||
* Gecko keyCode. A key is "special" if it isn't used for text input.
|
||||
|
@ -628,16 +635,6 @@ protected:
|
|||
*/
|
||||
static bool IsPrintableChar(PRUnichar aChar);
|
||||
|
||||
/**
|
||||
* ComputeGeckoKeyCodeFromChar() computes Gecko defined keyCode value from
|
||||
* aChar. If aChar is not an ASCII character, this always returns FALSE.
|
||||
*
|
||||
* @param aChar A unicode character.
|
||||
* @return A Gecko defined keyCode. Or zero if aChar
|
||||
* is a unicode character.
|
||||
*/
|
||||
static PRUint32 ComputeGeckoKeyCodeFromChar(PRUnichar aChar);
|
||||
|
||||
/**
|
||||
* IsNormalCharInputtingEvent() checks whether aKeyEvent causes text input.
|
||||
*
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
#include "nsBidiUtils.h"
|
||||
#include "nsToolkit.h"
|
||||
#include "nsCocoaUtils.h"
|
||||
#include "WidgetUtils.h"
|
||||
#include "nsPrintfCString.h"
|
||||
|
||||
#ifdef __LP64__
|
||||
|
@ -662,7 +663,7 @@ TISInputSourceWrapper::InitKeyEvent(NSEvent *aNativeKeyEvent,
|
|||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
|
||||
|
||||
PR_LOG(gLog, PR_LOG_ALWAYS,
|
||||
("%p TISInputSourceWrapper::InitKeyEvent, aNativeKeyEvent=%p"
|
||||
("%p TISInputSourceWrapper::InitKeyEvent, aNativeKeyEvent=%p, "
|
||||
"aKeyEvent.message=%s",
|
||||
this, aNativeKeyEvent, GetGeckoKeyEventType(aKeyEvent)));
|
||||
|
||||
|
@ -675,12 +676,15 @@ TISInputSourceWrapper::InitKeyEvent(NSEvent *aNativeKeyEvent,
|
|||
aKeyEvent.refPoint = nsIntPoint(0, 0);
|
||||
aKeyEvent.isChar = false; // XXX not used in XP level
|
||||
|
||||
NSString* str = nil;
|
||||
if ([aNativeKeyEvent type] != NSFlagsChanged) {
|
||||
str = [aNativeKeyEvent charactersIgnoringModifiers];
|
||||
}
|
||||
// If a keyboard layout override is set, we also need to force the keyboard
|
||||
// type to something ANSI to avoid test failures on machines with JIS
|
||||
// keyboards (since the pair of keyboard layout and physical keyboard type
|
||||
// form the actual key layout). This assumes that the test setting the
|
||||
// override was written assuming an ANSI keyboard.
|
||||
UInt32 kbType = mOverrideKeyboard ? eKbdType_ANSI : ::LMGetKbdType();
|
||||
|
||||
aKeyEvent.keyCode =
|
||||
TextInputHandler::ComputeGeckoKeyCode([aNativeKeyEvent keyCode], str);
|
||||
ComputeGeckoKeyCode([aNativeKeyEvent keyCode], kbType, aKeyEvent.IsMeta());
|
||||
|
||||
switch ([aNativeKeyEvent keyCode]) {
|
||||
case kCommandKeyCode:
|
||||
|
@ -731,7 +735,7 @@ TISInputSourceWrapper::InitKeyEvent(NSEvent *aNativeKeyEvent,
|
|||
|
||||
if (aKeyEvent.message == NS_KEY_PRESS &&
|
||||
!TextInputHandler::IsSpecialGeckoKey([aNativeKeyEvent keyCode])) {
|
||||
InitKeyPressEvent(aNativeKeyEvent, aKeyEvent);
|
||||
InitKeyPressEvent(aNativeKeyEvent, aKeyEvent, kbType);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -746,21 +750,26 @@ TISInputSourceWrapper::InitKeyEvent(NSEvent *aNativeKeyEvent,
|
|||
|
||||
void
|
||||
TISInputSourceWrapper::InitKeyPressEvent(NSEvent *aNativeKeyEvent,
|
||||
nsKeyEvent& aKeyEvent)
|
||||
nsKeyEvent& aKeyEvent,
|
||||
UInt32 aKbType)
|
||||
{
|
||||
NS_ASSERTION(aKeyEvent.message == NS_KEY_PRESS,
|
||||
"aKeyEvent must be NS_KEY_PRESS event");
|
||||
|
||||
PR_LOG(gLog, PR_LOG_ALWAYS,
|
||||
("%p TISInputSourceWrapper::InitKeyPressEvent, aNativeKeyEvent=%p"
|
||||
"aKeyEvent.message=%s",
|
||||
this, aNativeKeyEvent, GetGeckoKeyEventType(aKeyEvent)));
|
||||
"aKeyEvent.message=%s, aKbType=0x%X, IsOpenedIMEMode()=%s",
|
||||
this, aNativeKeyEvent, GetGeckoKeyEventType(aKeyEvent), aKbType,
|
||||
TrueOrFalse(IsOpenedIMEMode())));
|
||||
|
||||
aKeyEvent.isChar = true; // this is not a special key XXX not used in XP
|
||||
|
||||
aKeyEvent.charCode = 0;
|
||||
NSString* chars = [aNativeKeyEvent characters];
|
||||
if ([chars length] > 0) {
|
||||
// XXX This is wrong at Hiragana or Katakana with Kana-Nyuryoku mode or
|
||||
// Chinese or Koran IME modes. We should use ASCII characters for the
|
||||
// charCode.
|
||||
aKeyEvent.charCode = [chars characterAtIndex:0];
|
||||
}
|
||||
|
||||
|
@ -785,13 +794,6 @@ TISInputSourceWrapper::InitKeyPressEvent(NSEvent *aNativeKeyEvent,
|
|||
TISInputSourceWrapper USLayout("com.apple.keylayout.US");
|
||||
bool isRomanKeyboardLayout = IsASCIICapable();
|
||||
|
||||
// If a keyboard layout override is set, we also need to force the
|
||||
// keyboard type to something ANSI to avoid test failures on machines
|
||||
// with JIS keyboards (since the pair of keyboard layout and physical
|
||||
// keyboard type form the actual key layout). This assumes that the
|
||||
// test setting the override was written assuming an ANSI keyboard.
|
||||
UInt32 kbType = mOverrideKeyboard ? eKbdType_ANSI : ::LMGetKbdType();
|
||||
|
||||
UInt32 key = [aNativeKeyEvent keyCode];
|
||||
|
||||
// Caps lock and num lock modifier state:
|
||||
|
@ -805,29 +807,29 @@ TISInputSourceWrapper::InitKeyPressEvent(NSEvent *aNativeKeyEvent,
|
|||
|
||||
PR_LOG(gLog, PR_LOG_ALWAYS,
|
||||
("%p TISInputSourceWrapper::InitKeyPressEvent, "
|
||||
"isRomanKeyboardLayout=%s, kbType=0x%X, key=0x%X",
|
||||
this, TrueOrFalse(isRomanKeyboardLayout), kbType, key));
|
||||
"isRomanKeyboardLayout=%s, key=0x%X",
|
||||
this, TrueOrFalse(isRomanKeyboardLayout), aKbType, key));
|
||||
|
||||
nsString str;
|
||||
|
||||
// normal chars
|
||||
PRUint32 unshiftedChar = TranslateToChar(key, lockState, kbType);
|
||||
PRUint32 unshiftedChar = TranslateToChar(key, lockState, aKbType);
|
||||
UInt32 shiftLockMod = shiftKey | lockState;
|
||||
PRUint32 shiftedChar = TranslateToChar(key, shiftLockMod, kbType);
|
||||
PRUint32 shiftedChar = TranslateToChar(key, shiftLockMod, aKbType);
|
||||
|
||||
// characters generated with Cmd key
|
||||
// XXX we should remove CapsLock state, which changes characters from
|
||||
// Latin to Cyrillic with Russian layout on 10.4 only when Cmd key
|
||||
// is pressed.
|
||||
UInt32 numState = (lockState & ~alphaLock); // only num lock state
|
||||
PRUint32 uncmdedChar = TranslateToChar(key, numState, kbType);
|
||||
PRUint32 uncmdedChar = TranslateToChar(key, numState, aKbType);
|
||||
UInt32 shiftNumMod = numState | shiftKey;
|
||||
PRUint32 uncmdedShiftChar = TranslateToChar(key, shiftNumMod, kbType);
|
||||
PRUint32 uncmdedUSChar = USLayout.TranslateToChar(key, numState, kbType);
|
||||
PRUint32 uncmdedShiftChar = TranslateToChar(key, shiftNumMod, aKbType);
|
||||
PRUint32 uncmdedUSChar = USLayout.TranslateToChar(key, numState, aKbType);
|
||||
UInt32 cmdNumMod = cmdKey | numState;
|
||||
PRUint32 cmdedChar = TranslateToChar(key, cmdNumMod, kbType);
|
||||
PRUint32 cmdedChar = TranslateToChar(key, cmdNumMod, aKbType);
|
||||
UInt32 cmdShiftNumMod = shiftKey | cmdNumMod;
|
||||
PRUint32 cmdedShiftChar = TranslateToChar(key, cmdShiftNumMod, kbType);
|
||||
PRUint32 cmdedShiftChar = TranslateToChar(key, cmdShiftNumMod, aKbType);
|
||||
|
||||
// Is the keyboard layout changed by Cmd key?
|
||||
// E.g., Arabic, Russian, Hebrew, Greek and Dvorak-QWERTY.
|
||||
|
@ -886,11 +888,11 @@ TISInputSourceWrapper::InitKeyPressEvent(NSEvent *aNativeKeyEvent,
|
|||
} else if (uncmdedUSChar == cmdedChar) {
|
||||
// It looks like characters from a US layout are provided when Command
|
||||
// is down.
|
||||
PRUint32 ch = USLayout.TranslateToChar(key, lockState, kbType);
|
||||
PRUint32 ch = USLayout.TranslateToChar(key, lockState, aKbType);
|
||||
if (ch) {
|
||||
cmdedChar = ch;
|
||||
}
|
||||
ch = USLayout.TranslateToChar(key, shiftLockMod, kbType);
|
||||
ch = USLayout.TranslateToChar(key, shiftLockMod, aKbType);
|
||||
if (ch) {
|
||||
cmdedShiftChar = ch;
|
||||
}
|
||||
|
@ -946,6 +948,162 @@ TISInputSourceWrapper::InitKeyPressEvent(NSEvent *aNativeKeyEvent,
|
|||
this, TrueOrFalse(hasCmdShiftOnlyChar), originalCmdedShiftChar));
|
||||
}
|
||||
|
||||
PRUint32
|
||||
TISInputSourceWrapper::ComputeGeckoKeyCode(UInt32 aNativeKeyCode,
|
||||
UInt32 aKbType,
|
||||
bool aCmdIsPressed)
|
||||
{
|
||||
PR_LOG(gLog, PR_LOG_ALWAYS,
|
||||
("%p TISInputSourceWrapper::ComputeGeckoKeyCode, aNativeKeyCode=0x%X, "
|
||||
"aKbType=0x%X, aCmdIsPressed=%s, IsOpenedIMEMode()=%s, "
|
||||
"IsASCIICapable()=%s",
|
||||
this, aNativeKeyCode, aKbType, TrueOrFalse(aCmdIsPressed),
|
||||
TrueOrFalse(IsOpenedIMEMode()), TrueOrFalse(IsASCIICapable())));
|
||||
|
||||
switch (aNativeKeyCode) {
|
||||
case kSpaceKeyCode: return NS_VK_SPACE;
|
||||
case kEscapeKeyCode: return NS_VK_ESCAPE;
|
||||
|
||||
// modifiers
|
||||
case kRCommandKeyCode:
|
||||
case kCommandKeyCode: return NS_VK_META;
|
||||
case kRShiftKeyCode:
|
||||
case kShiftKeyCode: return NS_VK_SHIFT;
|
||||
case kCapsLockKeyCode: return NS_VK_CAPS_LOCK;
|
||||
case kRControlKeyCode:
|
||||
case kControlKeyCode: return NS_VK_CONTROL;
|
||||
case kROptionKeyCode:
|
||||
case kOptionkeyCode: return NS_VK_ALT;
|
||||
|
||||
case kClearKeyCode: return NS_VK_CLEAR;
|
||||
|
||||
// function keys
|
||||
case kF1KeyCode: return NS_VK_F1;
|
||||
case kF2KeyCode: return NS_VK_F2;
|
||||
case kF3KeyCode: return NS_VK_F3;
|
||||
case kF4KeyCode: return NS_VK_F4;
|
||||
case kF5KeyCode: return NS_VK_F5;
|
||||
case kF6KeyCode: return NS_VK_F6;
|
||||
case kF7KeyCode: return NS_VK_F7;
|
||||
case kF8KeyCode: return NS_VK_F8;
|
||||
case kF9KeyCode: return NS_VK_F9;
|
||||
case kF10KeyCode: return NS_VK_F10;
|
||||
case kF11KeyCode: return NS_VK_F11;
|
||||
case kF12KeyCode: return NS_VK_F12;
|
||||
// case kF13KeyCode: return NS_VK_F13; // clash with the 3 below
|
||||
// case kF14KeyCode: return NS_VK_F14;
|
||||
// case kF15KeyCode: return NS_VK_F15;
|
||||
case kF16KeyCode: return NS_VK_F16;
|
||||
case kF17KeyCode: return NS_VK_F17;
|
||||
case kF18KeyCode: return NS_VK_F18;
|
||||
case kF19KeyCode: return NS_VK_F19;
|
||||
|
||||
case kPauseKeyCode: return NS_VK_PAUSE;
|
||||
case kScrollLockKeyCode: return NS_VK_SCROLL_LOCK;
|
||||
case kPrintScreenKeyCode: return NS_VK_PRINTSCREEN;
|
||||
|
||||
// keypad
|
||||
case kKeypad0KeyCode: return NS_VK_NUMPAD0;
|
||||
case kKeypad1KeyCode: return NS_VK_NUMPAD1;
|
||||
case kKeypad2KeyCode: return NS_VK_NUMPAD2;
|
||||
case kKeypad3KeyCode: return NS_VK_NUMPAD3;
|
||||
case kKeypad4KeyCode: return NS_VK_NUMPAD4;
|
||||
case kKeypad5KeyCode: return NS_VK_NUMPAD5;
|
||||
case kKeypad6KeyCode: return NS_VK_NUMPAD6;
|
||||
case kKeypad7KeyCode: return NS_VK_NUMPAD7;
|
||||
case kKeypad8KeyCode: return NS_VK_NUMPAD8;
|
||||
case kKeypad9KeyCode: return NS_VK_NUMPAD9;
|
||||
|
||||
case kKeypadMultiplyKeyCode: return NS_VK_MULTIPLY;
|
||||
case kKeypadAddKeyCode: return NS_VK_ADD;
|
||||
case kKeypadSubtractKeyCode: return NS_VK_SUBTRACT;
|
||||
case kKeypadDecimalKeyCode: return NS_VK_DECIMAL;
|
||||
case kKeypadDivideKeyCode: return NS_VK_DIVIDE;
|
||||
|
||||
// IME keys
|
||||
case kJapanese_Kana: return NS_VK_KANA;
|
||||
|
||||
// these may clash with forward delete and help
|
||||
case kInsertKeyCode: return NS_VK_INSERT;
|
||||
case kDeleteKeyCode: return NS_VK_DELETE;
|
||||
|
||||
case kBackspaceKeyCode: return NS_VK_BACK;
|
||||
case kTabKeyCode: return NS_VK_TAB;
|
||||
|
||||
case kHomeKeyCode: return NS_VK_HOME;
|
||||
case kEndKeyCode: return NS_VK_END;
|
||||
|
||||
case kPageUpKeyCode: return NS_VK_PAGE_UP;
|
||||
case kPageDownKeyCode: return NS_VK_PAGE_DOWN;
|
||||
|
||||
case kLeftArrowKeyCode: return NS_VK_LEFT;
|
||||
case kRightArrowKeyCode: return NS_VK_RIGHT;
|
||||
case kUpArrowKeyCode: return NS_VK_UP;
|
||||
case kDownArrowKeyCode: return NS_VK_DOWN;
|
||||
|
||||
case kVK_ANSI_1: return NS_VK_1;
|
||||
case kVK_ANSI_2: return NS_VK_2;
|
||||
case kVK_ANSI_3: return NS_VK_3;
|
||||
case kVK_ANSI_4: return NS_VK_4;
|
||||
case kVK_ANSI_5: return NS_VK_5;
|
||||
case kVK_ANSI_6: return NS_VK_6;
|
||||
case kVK_ANSI_7: return NS_VK_7;
|
||||
case kVK_ANSI_8: return NS_VK_8;
|
||||
case kVK_ANSI_9: return NS_VK_9;
|
||||
case kVK_ANSI_0: return NS_VK_0;
|
||||
|
||||
case kEnterKeyCode:
|
||||
case kReturnKeyCode:
|
||||
case kPowerbookEnterKeyCode: return NS_VK_RETURN;
|
||||
}
|
||||
|
||||
// If Cmd key is pressed, that causes switching keyboard layout temporarily.
|
||||
// E.g., Dvorak-QWERTY. Therefore, if Cmd key is pressed, we should honor it.
|
||||
UInt32 modifiers = aCmdIsPressed ? cmdKey : 0;
|
||||
|
||||
PRUint32 charCode = TranslateToChar(aNativeKeyCode, modifiers, aKbType);
|
||||
|
||||
// Special case for Mac. Mac inputs Yen sign (U+00A5) directly instead of
|
||||
// Back slash (U+005C). We should return NS_VK_BACK_SLASH for compatibility
|
||||
// with other platforms.
|
||||
// XXX How about Won sign (U+20A9) which has same problem as Yen sign?
|
||||
if (charCode == 0x00A5) {
|
||||
return NS_VK_BACK_SLASH;
|
||||
}
|
||||
|
||||
PRUint32 keyCode = WidgetUtils::ComputeKeyCodeFromChar(charCode);
|
||||
if (keyCode) {
|
||||
return keyCode;
|
||||
}
|
||||
|
||||
// If the unshifed char isn't an ASCII character, use shifted char.
|
||||
charCode = TranslateToChar(aNativeKeyCode, modifiers | shiftKey, aKbType);
|
||||
keyCode = WidgetUtils::ComputeKeyCodeFromChar(charCode);
|
||||
if (keyCode) {
|
||||
return keyCode;
|
||||
}
|
||||
|
||||
// If this is ASCII capable, give up to compute it.
|
||||
if (IsASCIICapable()) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Retry with ASCII capable keyboard layout.
|
||||
TISInputSourceWrapper currentKeyboardLayout;
|
||||
currentKeyboardLayout.InitByCurrentASCIICapableKeyboardLayout();
|
||||
NS_ENSURE_TRUE(mInputSource != currentKeyboardLayout.mInputSource, 0);
|
||||
keyCode = currentKeyboardLayout.ComputeGeckoKeyCode(aNativeKeyCode, aKbType,
|
||||
aCmdIsPressed);
|
||||
|
||||
// However, if keyCode isn't for an alphabet keys or a numeric key, we should
|
||||
// ignore it. For example, comma key of Thai layout is same as close-square-
|
||||
// bracket key of US layout and an unicode character key of Thai layout is
|
||||
// same as comma key of US layout. If we return NS_VK_COMMA for latter key,
|
||||
// web application developers cannot distinguish with the former key.
|
||||
return ((keyCode >= NS_VK_A && keyCode <= NS_VK_Z) ||
|
||||
(keyCode >= NS_VK_0 && keyCode <= NS_VK_9)) ? keyCode : 0;
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
|
||||
|
@ -1375,9 +1533,6 @@ TextInputHandler::InsertText(NSAttributedString *aAttrString)
|
|||
|
||||
// Dispatch keypress event with char instead of textEvent
|
||||
nsKeyEvent keypressEvent(true, NS_KEY_PRESS, mWidget);
|
||||
keypressEvent.charCode = str.CharAt(0);
|
||||
keypressEvent.keyCode = 0;
|
||||
keypressEvent.isChar = true;
|
||||
|
||||
// Don't set other modifiers from the current event, because here in
|
||||
// -insertText: they've already been taken into account in creating
|
||||
|
@ -1390,7 +1545,7 @@ TextInputHandler::InsertText(NSAttributedString *aAttrString)
|
|||
|
||||
if (currentKeyEvent) {
|
||||
NSEvent* keyEvent = currentKeyEvent->mKeyEvent;
|
||||
nsCocoaUtils::InitInputEvent(keypressEvent, keyEvent);
|
||||
InitKeyEvent(keyEvent, keypressEvent);
|
||||
|
||||
// XXX The ASCII characters inputting mode of egbridge (Japanese IME)
|
||||
// might send the keyDown event with wrong keyboard layout if other
|
||||
|
@ -1406,19 +1561,15 @@ TextInputHandler::InsertText(NSAttributedString *aAttrString)
|
|||
if (currentKeyEvent->mKeyDownHandled) {
|
||||
keypressEvent.flags |= NS_EVENT_FLAG_NO_DEFAULT;
|
||||
}
|
||||
|
||||
if (!IsPrintableChar(keypressEvent.charCode)) {
|
||||
keypressEvent.keyCode =
|
||||
ComputeGeckoKeyCode([keyEvent keyCode],
|
||||
[keyEvent charactersIgnoringModifiers]);
|
||||
keypressEvent.charCode = 0;
|
||||
}
|
||||
} else {
|
||||
nsCocoaUtils::InitInputEvent(keypressEvent, static_cast<NSEvent*>(nsnull));
|
||||
keypressEvent.charCode = str.CharAt(0);
|
||||
keypressEvent.keyCode = 0;
|
||||
keypressEvent.isChar = true;
|
||||
// Note that insertText is not called only at key pressing.
|
||||
if (!IsPrintableChar(keypressEvent.charCode)) {
|
||||
keypressEvent.keyCode =
|
||||
ComputeGeckoKeyCodeFromChar(keypressEvent.charCode);
|
||||
WidgetUtils::ComputeKeyCodeFromChar(keypressEvent.charCode);
|
||||
keypressEvent.charCode = 0;
|
||||
}
|
||||
}
|
||||
|
@ -3137,6 +3288,9 @@ PluginTextInputHandler::HandleCarbonPluginKeyEvent(EventRef aKeyEvent)
|
|||
&macKeyCode);
|
||||
NS_ENSURE_TRUE(status == noErr, );
|
||||
|
||||
TISInputSourceWrapper currentKeyboardLayout;
|
||||
currentKeyboardLayout.InitByCurrentKeyboardLayout();
|
||||
|
||||
EventRef cloneEvent = ::CopyEvent(aKeyEvent);
|
||||
for (PRUint32 i = 0; i < numCharCodes; ++i) {
|
||||
status = ::SetEventParameter(cloneEvent, kEventParamKeyMacCharCodes,
|
||||
|
@ -3148,7 +3302,9 @@ PluginTextInputHandler::HandleCarbonPluginKeyEvent(EventRef aKeyEvent)
|
|||
nsKeyEvent keydownEvent(true, NS_KEY_DOWN, mWidget);
|
||||
nsCocoaUtils::InitInputEvent(keydownEvent, cocoaModifiers);
|
||||
|
||||
PRUint32 keyCode = ComputeGeckoKeyCode(macKeyCode, @"");
|
||||
PRUint32 keyCode =
|
||||
currentKeyboardLayout.ComputeGeckoKeyCode(macKeyCode, ::LMGetKbdType(),
|
||||
keydownEvent.IsMeta());
|
||||
PRUint32 charCode(charCodes.ElementAt(i));
|
||||
|
||||
keydownEvent.time = PR_IntervalNow();
|
||||
|
@ -3156,6 +3312,7 @@ PluginTextInputHandler::HandleCarbonPluginKeyEvent(EventRef aKeyEvent)
|
|||
if (IsSpecialGeckoKey(macKeyCode)) {
|
||||
keydownEvent.keyCode = keyCode;
|
||||
} else {
|
||||
// XXX This is wrong. charCode must be 0 for keydown event.
|
||||
keydownEvent.charCode = charCode;
|
||||
keydownEvent.isChar = true;
|
||||
}
|
||||
|
@ -3657,156 +3814,6 @@ TextInputHandlerBase::IsPrintableChar(PRUnichar aChar)
|
|||
return (aChar >= 0x20 && aChar <= 0x7E) || aChar >= 0xA0;
|
||||
}
|
||||
|
||||
/* static */ PRUint32
|
||||
TextInputHandlerBase::ComputeGeckoKeyCodeFromChar(PRUnichar aChar)
|
||||
{
|
||||
// We don't support the key code for non-ASCII characters
|
||||
if (aChar > 0x7E) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// lowercase
|
||||
if (aChar >= 'a' && aChar <= 'z') {
|
||||
return PRUint32(toupper(aChar));
|
||||
}
|
||||
// uppercase
|
||||
if (aChar >= 'A' && aChar <= 'Z') {
|
||||
return PRUint32(aChar);
|
||||
}
|
||||
// numeric
|
||||
if (aChar >= '0' && aChar <= '9') {
|
||||
return PRUint32(aChar - '0' + NS_VK_0);
|
||||
}
|
||||
|
||||
switch (aChar) {
|
||||
case kReturnCharCode:
|
||||
case kEnterCharCode:
|
||||
case '\n':
|
||||
return NS_VK_RETURN;
|
||||
case '{':
|
||||
case '[':
|
||||
return NS_VK_OPEN_BRACKET;
|
||||
case '}':
|
||||
case ']':
|
||||
return NS_VK_CLOSE_BRACKET;
|
||||
case '\'':
|
||||
case '"':
|
||||
return NS_VK_QUOTE;
|
||||
|
||||
case '\\': return NS_VK_BACK_SLASH;
|
||||
case ' ': return NS_VK_SPACE;
|
||||
case ';': return NS_VK_SEMICOLON;
|
||||
case '=': return NS_VK_EQUALS;
|
||||
case ',': return NS_VK_COMMA;
|
||||
case '.': return NS_VK_PERIOD;
|
||||
case '/': return NS_VK_SLASH;
|
||||
case '`': return NS_VK_BACK_QUOTE;
|
||||
case '\t': return NS_VK_TAB;
|
||||
case '-': return NS_VK_SUBTRACT;
|
||||
case '+': return NS_VK_ADD;
|
||||
|
||||
default:
|
||||
if (!IsPrintableChar(aChar)) {
|
||||
NS_WARNING("ComputeGeckoKeyCodeFromChar() has failed.");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ PRUint32
|
||||
TextInputHandlerBase::ComputeGeckoKeyCode(UInt32 aNativeKeyCode,
|
||||
NSString *aCharacters)
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
|
||||
|
||||
switch (aNativeKeyCode) {
|
||||
// modifiers. We don't get separate events for these
|
||||
case kEscapeKeyCode: return NS_VK_ESCAPE;
|
||||
case kRCommandKeyCode:
|
||||
case kCommandKeyCode: return NS_VK_META;
|
||||
case kRShiftKeyCode:
|
||||
case kShiftKeyCode: return NS_VK_SHIFT;
|
||||
case kCapsLockKeyCode: return NS_VK_CAPS_LOCK;
|
||||
case kRControlKeyCode:
|
||||
case kControlKeyCode: return NS_VK_CONTROL;
|
||||
case kROptionKeyCode:
|
||||
case kOptionkeyCode: return NS_VK_ALT;
|
||||
case kClearKeyCode: return NS_VK_CLEAR;
|
||||
|
||||
// function keys
|
||||
case kF1KeyCode: return NS_VK_F1;
|
||||
case kF2KeyCode: return NS_VK_F2;
|
||||
case kF3KeyCode: return NS_VK_F3;
|
||||
case kF4KeyCode: return NS_VK_F4;
|
||||
case kF5KeyCode: return NS_VK_F5;
|
||||
case kF6KeyCode: return NS_VK_F6;
|
||||
case kF7KeyCode: return NS_VK_F7;
|
||||
case kF8KeyCode: return NS_VK_F8;
|
||||
case kF9KeyCode: return NS_VK_F9;
|
||||
case kF10KeyCode: return NS_VK_F10;
|
||||
case kF11KeyCode: return NS_VK_F11;
|
||||
case kF12KeyCode: return NS_VK_F12;
|
||||
// case kF13KeyCode: return NS_VK_F13; // clash with the 3 below
|
||||
// case kF14KeyCode: return NS_VK_F14;
|
||||
// case kF15KeyCode: return NS_VK_F15;
|
||||
case kPauseKeyCode: return NS_VK_PAUSE;
|
||||
case kScrollLockKeyCode: return NS_VK_SCROLL_LOCK;
|
||||
case kPrintScreenKeyCode: return NS_VK_PRINTSCREEN;
|
||||
|
||||
// keypad
|
||||
case kKeypad0KeyCode: return NS_VK_NUMPAD0;
|
||||
case kKeypad1KeyCode: return NS_VK_NUMPAD1;
|
||||
case kKeypad2KeyCode: return NS_VK_NUMPAD2;
|
||||
case kKeypad3KeyCode: return NS_VK_NUMPAD3;
|
||||
case kKeypad4KeyCode: return NS_VK_NUMPAD4;
|
||||
case kKeypad5KeyCode: return NS_VK_NUMPAD5;
|
||||
case kKeypad6KeyCode: return NS_VK_NUMPAD6;
|
||||
case kKeypad7KeyCode: return NS_VK_NUMPAD7;
|
||||
case kKeypad8KeyCode: return NS_VK_NUMPAD8;
|
||||
case kKeypad9KeyCode: return NS_VK_NUMPAD9;
|
||||
|
||||
case kKeypadMultiplyKeyCode: return NS_VK_MULTIPLY;
|
||||
case kKeypadAddKeyCode: return NS_VK_ADD;
|
||||
case kKeypadSubtractKeyCode: return NS_VK_SUBTRACT;
|
||||
case kKeypadDecimalKeyCode: return NS_VK_DECIMAL;
|
||||
case kKeypadDivideKeyCode: return NS_VK_DIVIDE;
|
||||
|
||||
// these may clash with forward delete and help
|
||||
case kInsertKeyCode: return NS_VK_INSERT;
|
||||
case kDeleteKeyCode: return NS_VK_DELETE;
|
||||
|
||||
case kBackspaceKeyCode: return NS_VK_BACK;
|
||||
case kTabKeyCode: return NS_VK_TAB;
|
||||
case kHomeKeyCode: return NS_VK_HOME;
|
||||
case kEndKeyCode: return NS_VK_END;
|
||||
case kPageUpKeyCode: return NS_VK_PAGE_UP;
|
||||
case kPageDownKeyCode: return NS_VK_PAGE_DOWN;
|
||||
case kLeftArrowKeyCode: return NS_VK_LEFT;
|
||||
case kRightArrowKeyCode: return NS_VK_RIGHT;
|
||||
case kUpArrowKeyCode: return NS_VK_UP;
|
||||
case kDownArrowKeyCode: return NS_VK_DOWN;
|
||||
case kVK_ANSI_1: return NS_VK_1;
|
||||
case kVK_ANSI_2: return NS_VK_2;
|
||||
case kVK_ANSI_3: return NS_VK_3;
|
||||
case kVK_ANSI_4: return NS_VK_4;
|
||||
case kVK_ANSI_5: return NS_VK_5;
|
||||
case kVK_ANSI_6: return NS_VK_6;
|
||||
case kVK_ANSI_7: return NS_VK_7;
|
||||
case kVK_ANSI_8: return NS_VK_8;
|
||||
case kVK_ANSI_9: return NS_VK_9;
|
||||
case kVK_ANSI_0: return NS_VK_0;
|
||||
|
||||
default:
|
||||
// if we haven't gotten the key code already, look at the char code
|
||||
if ([aCharacters length] > 0) {
|
||||
return ComputeGeckoKeyCodeFromChar([aCharacters characterAtIndex:0]);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(0);
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
TextInputHandlerBase::IsSpecialGeckoKey(UInt32 aNativeKeyCode)
|
||||
|
@ -3843,12 +3850,18 @@ TextInputHandlerBase::IsSpecialGeckoKey(UInt32 aNativeKeyCode)
|
|||
case kPauseKeyCode:
|
||||
case kScrollLockKeyCode:
|
||||
case kPrintScreenKeyCode:
|
||||
case kF16KeyCode:
|
||||
case kF17KeyCode:
|
||||
case kF18KeyCode:
|
||||
case kF19KeyCode:
|
||||
|
||||
case kInsertKeyCode:
|
||||
case kDeleteKeyCode:
|
||||
case kTabKeyCode:
|
||||
case kBackspaceKeyCode:
|
||||
|
||||
case kJapanese_Kana:
|
||||
|
||||
case kHomeKeyCode:
|
||||
case kEndKeyCode:
|
||||
case kPageUpKeyCode:
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Загрузка…
Ссылка в новой задаче