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)
|
, mModKeyState(aModKeyState)
|
||||||
, mVirtualKeyCode(0)
|
, mVirtualKeyCode(0)
|
||||||
, mOriginalVirtualKeyCode(0)
|
, mOriginalVirtualKeyCode(0)
|
||||||
|
, shiftedLatinChar(0)
|
||||||
|
, unshiftedLatinChar(0)
|
||||||
, mScanCode(0)
|
, mScanCode(0)
|
||||||
, mIsExtended(false)
|
, mIsExtended(false)
|
||||||
, mIsDeadKey(false)
|
, mIsDeadKey(false)
|
||||||
@ -857,6 +859,14 @@ NativeKey::NativeKey(nsWindowBase* aWidget,
|
|||||||
(IsFollowedByDeadCharMessage() ||
|
(IsFollowedByDeadCharMessage() ||
|
||||||
keyboardLayout->IsDeadKey(mOriginalVirtualKeyCode, mModKeyState));
|
keyboardLayout->IsDeadKey(mOriginalVirtualKeyCode, mModKeyState));
|
||||||
mIsPrintableKey = KeyboardLayout::IsPrintableCharKey(mOriginalVirtualKeyCode);
|
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
|
void
|
||||||
@ -2066,84 +2076,94 @@ NativeKey::DispatchPluginEventsAndDiscardsCharMessages() const
|
|||||||
return false;
|
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
|
bool
|
||||||
NativeKey::DispatchKeyPressEventsWithKeyboardLayout() const
|
NativeKey::DispatchKeyPressEventsWithKeyboardLayout() const
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(IsKeyDownMessage());
|
MOZ_ASSERT(IsKeyDownMessage());
|
||||||
MOZ_ASSERT(!mIsDeadKey);
|
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() &&
|
if (inputtingChars.IsEmpty() &&
|
||||||
shiftedChars.IsEmpty() && unshiftedChars.IsEmpty()) {
|
shiftedChars.IsEmpty() && unshiftedChars.IsEmpty()) {
|
||||||
nsresult rv = mDispatcher->BeginNativeInputTransaction();
|
nsresult rv = mDispatcher->BeginNativeInputTransaction();
|
||||||
|
@ -293,6 +293,29 @@ private:
|
|||||||
// indicates both the dead characters and the base characters.
|
// indicates both the dead characters and the base characters.
|
||||||
UniCharsAndModifiers mCommittedCharsAndModifiers;
|
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;
|
WORD mScanCode;
|
||||||
bool mIsExtended;
|
bool mIsExtended;
|
||||||
bool mIsDeadKey;
|
bool mIsDeadKey;
|
||||||
@ -484,6 +507,13 @@ private:
|
|||||||
* or Backspace.
|
* or Backspace.
|
||||||
*/
|
*/
|
||||||
bool NeedsToHandleWithoutFollowingCharMessages() const;
|
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
|
class KeyboardLayout
|
||||||
|
Loading…
Reference in New Issue
Block a user