mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-19 16:25:38 +00:00
Bug 1137561 part.6 Store some strings which may be inputted by the key with some modifier state before dispatching keydown event r=m_kato
This commit is contained in:
parent
22e9178025
commit
1728345f86
@ -669,6 +669,8 @@ NativeKey::NativeKey(nsWindowBase* aWidget,
|
||||
, mModKeyState(aModKeyState)
|
||||
, mVirtualKeyCode(0)
|
||||
, mOriginalVirtualKeyCode(0)
|
||||
, shiftedLatinChar(0)
|
||||
, unshiftedLatinChar(0)
|
||||
, mScanCode(0)
|
||||
, mIsExtended(false)
|
||||
, mIsDeadKey(false)
|
||||
@ -857,6 +859,14 @@ NativeKey::NativeKey(nsWindowBase* aWidget,
|
||||
(IsFollowedByDeadCharMessage() ||
|
||||
keyboardLayout->IsDeadKey(mOriginalVirtualKeyCode, mModKeyState));
|
||||
mIsPrintableKey = KeyboardLayout::IsPrintableCharKey(mOriginalVirtualKeyCode);
|
||||
|
||||
// Compute some strings which may be inputted by the key with various
|
||||
// modifier state if this key event won't cause text input actually.
|
||||
// They will be used for setting alternativeCharCodes in the callback
|
||||
// method which will be called by TextEventDispatcher.
|
||||
if (IsKeyDownMessage() && NeedsToHandleWithoutFollowingCharMessages()) {
|
||||
ComputeInputtingStringWithKeyboardLayout();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
@ -2066,84 +2076,94 @@ NativeKey::DispatchPluginEventsAndDiscardsCharMessages() const
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
NativeKey::ComputeInputtingStringWithKeyboardLayout()
|
||||
{
|
||||
KeyboardLayout* keyboardLayout = KeyboardLayout::GetInstance();
|
||||
|
||||
if (KeyboardLayout::IsPrintableCharKey(mVirtualKeyCode)) {
|
||||
inputtingChars = mCommittedCharsAndModifiers;
|
||||
} else {
|
||||
inputtingChars.Clear();
|
||||
}
|
||||
shiftedChars.Clear();
|
||||
unshiftedChars.Clear();
|
||||
shiftedLatinChar = unshiftedLatinChar = 0;
|
||||
|
||||
// XXX How about when Win key is pressed?
|
||||
if (mModKeyState.IsControl() == mModKeyState.IsAlt()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ModifierKeyState capsLockState(
|
||||
mModKeyState.GetModifiers() & MODIFIER_CAPSLOCK);
|
||||
|
||||
unshiftedChars =
|
||||
keyboardLayout->GetUniCharsAndModifiers(mVirtualKeyCode, capsLockState);
|
||||
capsLockState.Set(MODIFIER_SHIFT);
|
||||
shiftedChars =
|
||||
keyboardLayout->GetUniCharsAndModifiers(mVirtualKeyCode, capsLockState);
|
||||
|
||||
// The current keyboard cannot input alphabets or numerics,
|
||||
// we should append them for Shortcut/Access keys.
|
||||
// E.g., for Cyrillic keyboard layout.
|
||||
capsLockState.Unset(MODIFIER_SHIFT);
|
||||
WidgetUtils::GetLatinCharCodeForKeyCode(mDOMKeyCode,
|
||||
capsLockState.GetModifiers(),
|
||||
&unshiftedLatinChar,
|
||||
&shiftedLatinChar);
|
||||
|
||||
// If the shiftedLatinChar isn't 0, the key code is NS_VK_[A-Z].
|
||||
if (shiftedLatinChar) {
|
||||
// If the produced characters of the key on current keyboard layout
|
||||
// are same as computed Latin characters, we shouldn't append the
|
||||
// Latin characters to alternativeCharCode.
|
||||
if (unshiftedLatinChar == unshiftedChars.mChars[0] &&
|
||||
shiftedLatinChar == shiftedChars.mChars[0]) {
|
||||
shiftedLatinChar = unshiftedLatinChar = 0;
|
||||
}
|
||||
} else if (unshiftedLatinChar) {
|
||||
// If the shiftedLatinChar is 0, the keyCode doesn't produce
|
||||
// alphabet character. At that time, the character may be produced
|
||||
// with Shift key. E.g., on French keyboard layout, NS_VK_PERCENT
|
||||
// key produces LATIN SMALL LETTER U WITH GRAVE (U+00F9) without
|
||||
// Shift key but with Shift key, it produces '%'.
|
||||
// If the unshiftedLatinChar is produced by the key on current
|
||||
// keyboard layout, we shouldn't append it to alternativeCharCode.
|
||||
if (unshiftedLatinChar == unshiftedChars.mChars[0] ||
|
||||
unshiftedLatinChar == shiftedChars.mChars[0]) {
|
||||
unshiftedLatinChar = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mModKeyState.IsControl()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the charCode is not ASCII character, we should replace the
|
||||
// charCode with ASCII character only when Ctrl is pressed.
|
||||
// But don't replace the charCode when the charCode is not same as
|
||||
// unmodified characters. In such case, Ctrl is sometimes used for a
|
||||
// part of character inputting key combination like Shift.
|
||||
uint32_t ch =
|
||||
mModKeyState.IsShift() ? shiftedLatinChar : unshiftedLatinChar;
|
||||
if (!ch) {
|
||||
return;
|
||||
}
|
||||
if (inputtingChars.IsEmpty() ||
|
||||
inputtingChars.UniCharsCaseInsensitiveEqual(
|
||||
mModKeyState.IsShift() ? shiftedChars : unshiftedChars)) {
|
||||
inputtingChars.Clear();
|
||||
inputtingChars.Append(ch, mModKeyState.GetModifiers());
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
NativeKey::DispatchKeyPressEventsWithKeyboardLayout() const
|
||||
{
|
||||
MOZ_ASSERT(IsKeyDownMessage());
|
||||
MOZ_ASSERT(!mIsDeadKey);
|
||||
|
||||
KeyboardLayout* keyboardLayout = KeyboardLayout::GetInstance();
|
||||
|
||||
UniCharsAndModifiers inputtingChars(mCommittedCharsAndModifiers);
|
||||
UniCharsAndModifiers shiftedChars;
|
||||
UniCharsAndModifiers unshiftedChars;
|
||||
uint32_t shiftedLatinChar = 0;
|
||||
uint32_t unshiftedLatinChar = 0;
|
||||
|
||||
if (!KeyboardLayout::IsPrintableCharKey(mVirtualKeyCode)) {
|
||||
inputtingChars.Clear();
|
||||
}
|
||||
|
||||
if (mModKeyState.IsControl() ^ mModKeyState.IsAlt()) {
|
||||
ModifierKeyState capsLockState(
|
||||
mModKeyState.GetModifiers() & MODIFIER_CAPSLOCK);
|
||||
|
||||
unshiftedChars =
|
||||
keyboardLayout->GetUniCharsAndModifiers(mVirtualKeyCode, capsLockState);
|
||||
capsLockState.Set(MODIFIER_SHIFT);
|
||||
shiftedChars =
|
||||
keyboardLayout->GetUniCharsAndModifiers(mVirtualKeyCode, capsLockState);
|
||||
|
||||
// The current keyboard cannot input alphabets or numerics,
|
||||
// we should append them for Shortcut/Access keys.
|
||||
// E.g., for Cyrillic keyboard layout.
|
||||
capsLockState.Unset(MODIFIER_SHIFT);
|
||||
WidgetUtils::GetLatinCharCodeForKeyCode(mDOMKeyCode,
|
||||
capsLockState.GetModifiers(),
|
||||
&unshiftedLatinChar,
|
||||
&shiftedLatinChar);
|
||||
|
||||
// If the shiftedLatinChar isn't 0, the key code is NS_VK_[A-Z].
|
||||
if (shiftedLatinChar) {
|
||||
// If the produced characters of the key on current keyboard layout
|
||||
// are same as computed Latin characters, we shouldn't append the
|
||||
// Latin characters to alternativeCharCode.
|
||||
if (unshiftedLatinChar == unshiftedChars.mChars[0] &&
|
||||
shiftedLatinChar == shiftedChars.mChars[0]) {
|
||||
shiftedLatinChar = unshiftedLatinChar = 0;
|
||||
}
|
||||
} else if (unshiftedLatinChar) {
|
||||
// If the shiftedLatinChar is 0, the keyCode doesn't produce
|
||||
// alphabet character. At that time, the character may be produced
|
||||
// with Shift key. E.g., on French keyboard layout, NS_VK_PERCENT
|
||||
// key produces LATIN SMALL LETTER U WITH GRAVE (U+00F9) without
|
||||
// Shift key but with Shift key, it produces '%'.
|
||||
// If the unshiftedLatinChar is produced by the key on current
|
||||
// keyboard layout, we shouldn't append it to alternativeCharCode.
|
||||
if (unshiftedLatinChar == unshiftedChars.mChars[0] ||
|
||||
unshiftedLatinChar == shiftedChars.mChars[0]) {
|
||||
unshiftedLatinChar = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// If the charCode is not ASCII character, we should replace the
|
||||
// charCode with ASCII character only when Ctrl is pressed.
|
||||
// But don't replace the charCode when the charCode is not same as
|
||||
// unmodified characters. In such case, Ctrl is sometimes used for a
|
||||
// part of character inputting key combination like Shift.
|
||||
if (mModKeyState.IsControl()) {
|
||||
uint32_t ch =
|
||||
mModKeyState.IsShift() ? shiftedLatinChar : unshiftedLatinChar;
|
||||
if (ch &&
|
||||
(!inputtingChars.mLength ||
|
||||
inputtingChars.UniCharsCaseInsensitiveEqual(
|
||||
mModKeyState.IsShift() ? shiftedChars : unshiftedChars))) {
|
||||
inputtingChars.Clear();
|
||||
inputtingChars.Append(ch, mModKeyState.GetModifiers());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (inputtingChars.IsEmpty() &&
|
||||
shiftedChars.IsEmpty() && unshiftedChars.IsEmpty()) {
|
||||
nsresult rv = mDispatcher->BeginNativeInputTransaction();
|
||||
|
@ -293,6 +293,29 @@ private:
|
||||
// indicates both the dead characters and the base characters.
|
||||
UniCharsAndModifiers mCommittedCharsAndModifiers;
|
||||
|
||||
// Following strings are computed by
|
||||
// ComputeInputtingStringWithKeyboardLayout() which is typically called
|
||||
// before dispatching keydown event.
|
||||
// TODO: following new member names are temporary name for making the changes
|
||||
// in KeyboardLayout.cpp easier to read. They will be renamed following
|
||||
// patch.
|
||||
// mInputtingStringAndModifiers's string is the string to be
|
||||
// inputted into the focused editor and its modifier state is proper
|
||||
// modifier state for inputting the string into the editor.
|
||||
UniCharsAndModifiers inputtingChars;
|
||||
// mShiftedString is the string to be inputted into the editor with
|
||||
// current modifier state with active shift state.
|
||||
UniCharsAndModifiers shiftedChars;
|
||||
// mUnshiftedString is the string to be inputted into the editor with
|
||||
// current modifier state without shift state.
|
||||
UniCharsAndModifiers unshiftedChars;
|
||||
// Following integers are computed by
|
||||
// ComputeInputtingStringWithKeyboardLayout() which is typically called
|
||||
// before dispatching keydown event. The meaning of these values is same
|
||||
// as charCode.
|
||||
uint32_t shiftedLatinChar;
|
||||
uint32_t unshiftedLatinChar;
|
||||
|
||||
WORD mScanCode;
|
||||
bool mIsExtended;
|
||||
bool mIsDeadKey;
|
||||
@ -484,6 +507,13 @@ private:
|
||||
* or Backspace.
|
||||
*/
|
||||
bool NeedsToHandleWithoutFollowingCharMessages() const;
|
||||
|
||||
/**
|
||||
* ComputeInputtingStringWithKeyboardLayout() computes string to be inputted
|
||||
* with the key and the modifier state, without shift state and with shift
|
||||
* state.
|
||||
*/
|
||||
void ComputeInputtingStringWithKeyboardLayout();
|
||||
};
|
||||
|
||||
class KeyboardLayout
|
||||
|
Loading…
Reference in New Issue
Block a user