зеркало из https://github.com/mozilla/gecko-dev.git
Bug 892606 part.3 FakeCharMsg should be marked as consumed and only non-consumed char message should be synthesized r=jimm
This commit is contained in:
Родитель
f29b3580a9
Коммит
890fa71e70
|
@ -398,10 +398,11 @@ VirtualKey::FillKbdState(PBYTE aKbdState,
|
|||
NativeKey::NativeKey(nsWindowBase* aWidget,
|
||||
const MSG& aKeyOrCharMessage,
|
||||
const ModifierKeyState& aModKeyState,
|
||||
const FakeCharMsg* aFakeCharMsg) :
|
||||
nsTArray<FakeCharMsg>* aFakeCharMsgs) :
|
||||
mWidget(aWidget), mMsg(aKeyOrCharMessage), mDOMKeyCode(0),
|
||||
mModKeyState(aModKeyState), mVirtualKeyCode(0), mOriginalVirtualKeyCode(0),
|
||||
mIsFakeCharMsg(false)
|
||||
mFakeCharMsgs(aFakeCharMsgs && aFakeCharMsgs->Length() ?
|
||||
aFakeCharMsgs : nullptr)
|
||||
{
|
||||
MOZ_ASSERT(aWidget);
|
||||
KeyboardLayout* keyboardLayout = KeyboardLayout::GetInstance();
|
||||
|
@ -417,9 +418,8 @@ NativeKey::NativeKey(nsWindowBase* aWidget,
|
|||
case WM_KEYDOWN:
|
||||
case WM_SYSKEYDOWN:
|
||||
// Store following WM_*CHAR message into mCharMsg.
|
||||
if (aFakeCharMsg) {
|
||||
mCharMsg = aFakeCharMsg->GetCharMsg(mMsg.hwnd);
|
||||
mIsFakeCharMsg = true;
|
||||
if (mFakeCharMsgs) {
|
||||
mCharMsg = mFakeCharMsgs->ElementAt(0).GetCharMsg(mMsg.hwnd);
|
||||
} else {
|
||||
MSG msg;
|
||||
if (WinUtils::PeekMessage(&msg, mMsg.hwnd, WM_KEYFIRST, WM_KEYLAST,
|
||||
|
@ -777,20 +777,16 @@ NativeKey::DispatchKeyEvent(nsKeyEvent& aKeyEvent,
|
|||
}
|
||||
|
||||
bool
|
||||
NativeKey::HandleKeyDownMessage(bool* aEventDispatched,
|
||||
bool* aWasKeyDownDefaultPrevented) const
|
||||
NativeKey::HandleKeyDownMessage(bool* aEventDispatched) const
|
||||
{
|
||||
MOZ_ASSERT(mMsg.message == WM_KEYDOWN || mMsg.message == WM_SYSKEYDOWN);
|
||||
|
||||
if (aEventDispatched) {
|
||||
*aEventDispatched = false;
|
||||
}
|
||||
if (aWasKeyDownDefaultPrevented) {
|
||||
*aWasKeyDownDefaultPrevented = false;
|
||||
}
|
||||
|
||||
bool defaultPrevented = false;
|
||||
if (mIsFakeCharMsg ||
|
||||
if (mFakeCharMsgs ||
|
||||
!RedirectedKeyDownMessageManager::IsRedirectedMessage(mMsg)) {
|
||||
// Ignore [shift+]alt+space so the OS can handle it.
|
||||
if (mModKeyState.IsAlt() && !mModKeyState.IsControl() &&
|
||||
|
@ -807,11 +803,6 @@ NativeKey::HandleKeyDownMessage(bool* aEventDispatched,
|
|||
defaultPrevented = DispatchKeyEvent(keydownEvent, &mMsg);
|
||||
|
||||
if (mWidget->Destroyed()) {
|
||||
// If this was destroyed by the keydown event handler, we shouldn't
|
||||
// dispatch keypress event on this window.
|
||||
if (aWasKeyDownDefaultPrevented) {
|
||||
*aWasKeyDownDefaultPrevented = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -824,7 +815,7 @@ NativeKey::HandleKeyDownMessage(bool* aEventDispatched,
|
|||
// application, we shouldn't redirect the message to it because the keydown
|
||||
// message is processed by us, so, nobody shouldn't process it.
|
||||
HWND focusedWnd = ::GetFocus();
|
||||
if (!defaultPrevented && !mIsFakeCharMsg && focusedWnd &&
|
||||
if (!defaultPrevented && !mFakeCharMsgs && focusedWnd &&
|
||||
!mWidget->PluginHasFocus() && !isIMEEnabled &&
|
||||
WinUtils::IsIMEEnabled(mWidget->GetInputContext())) {
|
||||
RedirectedKeyDownMessageManager::RemoveNextCharMessage(focusedWnd);
|
||||
|
@ -847,9 +838,6 @@ NativeKey::HandleKeyDownMessage(bool* aEventDispatched,
|
|||
// Return here. We shouldn't dispatch keypress event for this WM_KEYDOWN.
|
||||
// If it's needed, it will be dispatched after next (redirected)
|
||||
// WM_KEYDOWN.
|
||||
if (aWasKeyDownDefaultPrevented) {
|
||||
*aWasKeyDownDefaultPrevented = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
|
@ -861,10 +849,6 @@ NativeKey::HandleKeyDownMessage(bool* aEventDispatched,
|
|||
}
|
||||
}
|
||||
|
||||
if (aWasKeyDownDefaultPrevented) {
|
||||
*aWasKeyDownDefaultPrevented = defaultPrevented;
|
||||
}
|
||||
|
||||
RedirectedKeyDownMessageManager::Forget();
|
||||
|
||||
// If the key was processed by IME, we shouldn't dispatch keypress event.
|
||||
|
@ -1085,7 +1069,10 @@ NativeKey::RemoveFollowingCharMessage() const
|
|||
{
|
||||
MOZ_ASSERT(IsFollowedByCharMessage());
|
||||
|
||||
if (mIsFakeCharMsg) {
|
||||
if (mFakeCharMsgs) {
|
||||
MOZ_ASSERT(!mFakeCharMsgs->ElementAt(0).mConsumed,
|
||||
"Doesn't assume that it's used for removing two or more char messages");
|
||||
mFakeCharMsgs->ElementAt(0).mConsumed = true;
|
||||
return mCharMsg;
|
||||
}
|
||||
|
||||
|
@ -1107,11 +1094,23 @@ NativeKey::RemoveMessageAndDispatchPluginEvent(UINT aFirstMsg,
|
|||
UINT aLastMsg) const
|
||||
{
|
||||
MSG msg;
|
||||
if (mIsFakeCharMsg) {
|
||||
if (aFirstMsg > WM_CHAR || aLastMsg < WM_CHAR) {
|
||||
return false;
|
||||
if (mFakeCharMsgs) {
|
||||
DebugOnly<bool> found = false;
|
||||
for (uint32_t i = 0; i < mFakeCharMsgs->Length(); i++) {
|
||||
FakeCharMsg& fakeCharMsg = mFakeCharMsgs->ElementAt(i);
|
||||
if (fakeCharMsg.mConsumed) {
|
||||
continue;
|
||||
}
|
||||
MSG fakeMsg = fakeCharMsg.GetCharMsg(mMsg.hwnd);
|
||||
if (fakeMsg.message < aFirstMsg || fakeMsg.message > aLastMsg) {
|
||||
continue;
|
||||
}
|
||||
fakeCharMsg.mConsumed = true;
|
||||
msg = fakeMsg;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
msg = mCharMsg;
|
||||
MOZ_ASSERT(found, "Fake char message must be found");
|
||||
} else {
|
||||
WinUtils::GetMessage(&msg, mMsg.hwnd, aFirstMsg, aLastMsg);
|
||||
}
|
||||
|
@ -1127,8 +1126,13 @@ NativeKey::DispatchPluginEventsAndDiscardsCharMessages() const
|
|||
{
|
||||
MOZ_ASSERT(mMsg.message == WM_KEYDOWN || mMsg.message == WM_SYSKEYDOWN);
|
||||
|
||||
if (mIsFakeCharMsg) {
|
||||
return RemoveMessageAndDispatchPluginEvent(WM_KEYFIRST, WM_KEYLAST);
|
||||
if (mFakeCharMsgs) {
|
||||
for (uint32_t i = 0; i < mFakeCharMsgs->Length(); i++) {
|
||||
if (RemoveMessageAndDispatchPluginEvent(WM_KEYFIRST, WM_KEYLAST)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Remove a possible WM_CHAR or WM_SYSCHAR messages from the message queue.
|
||||
|
@ -1330,7 +1334,7 @@ NativeKey::DispatchKeyPressEventForFollowingCharMessage() const
|
|||
MOZ_ASSERT(mMsg.message == WM_KEYDOWN || mMsg.message == WM_SYSKEYDOWN);
|
||||
|
||||
const MSG& msg = RemoveFollowingCharMessage();
|
||||
if (mIsFakeCharMsg) {
|
||||
if (mFakeCharMsgs) {
|
||||
if (msg.message == WM_DEADCHAR) {
|
||||
return false;
|
||||
}
|
||||
|
@ -2310,20 +2314,25 @@ KeyboardLayout::SynthesizeNativeKeyEvent(nsWindowBase* aWidget,
|
|||
NativeKey nativeKey(aWidget, keyDownMsg, modKeyState);
|
||||
nativeKey.HandleKeyDownMessage();
|
||||
} else {
|
||||
NativeKey::FakeCharMsg fakeMsgForKeyDown = { chars.CharAt(0), scanCode,
|
||||
makeDeadCharMsg };
|
||||
NativeKey nativeKey(aWidget, keyDownMsg, modKeyState,
|
||||
&fakeMsgForKeyDown);
|
||||
bool dispatched, keyDownDefaultPrevented;
|
||||
nativeKey.HandleKeyDownMessage(&dispatched, &keyDownDefaultPrevented);
|
||||
if (!keyDownDefaultPrevented) {
|
||||
for (uint32_t j = 1; j < chars.Length(); j++) {
|
||||
NativeKey::FakeCharMsg fakeMsgForChar = { chars.CharAt(j), scanCode,
|
||||
false };
|
||||
MSG charMsg = fakeMsgForChar.GetCharMsg(aWidget->GetWindowHandle());
|
||||
NativeKey nativeKey(aWidget, charMsg, modKeyState);
|
||||
nativeKey.HandleCharMessage(charMsg);
|
||||
nsAutoTArray<NativeKey::FakeCharMsg, 10> fakeCharMsgs;
|
||||
for (uint32_t j = 0; j < chars.Length(); j++) {
|
||||
NativeKey::FakeCharMsg* fakeCharMsg = fakeCharMsgs.AppendElement();
|
||||
fakeCharMsg->mCharCode = chars.CharAt(j);
|
||||
fakeCharMsg->mScanCode = scanCode;
|
||||
fakeCharMsg->mIsDeadKey = makeDeadCharMsg;
|
||||
}
|
||||
NativeKey nativeKey(aWidget, keyDownMsg, modKeyState, &fakeCharMsgs);
|
||||
bool dispatched;
|
||||
nativeKey.HandleKeyDownMessage(&dispatched);
|
||||
// If some char messages are not consumed, let's emulate the widget
|
||||
// receiving the message directly.
|
||||
for (uint32_t j = 1; j < fakeCharMsgs.Length(); j++) {
|
||||
if (fakeCharMsgs[j].mConsumed) {
|
||||
continue;
|
||||
}
|
||||
MSG charMsg = fakeCharMsgs[j].GetCharMsg(aWidget->GetWindowHandle());
|
||||
NativeKey nativeKey(aWidget, charMsg, modKeyState);
|
||||
nativeKey.HandleCharMessage(charMsg);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -297,6 +297,12 @@ public:
|
|||
UINT mCharCode;
|
||||
UINT mScanCode;
|
||||
bool mIsDeadKey;
|
||||
bool mConsumed;
|
||||
|
||||
FakeCharMsg() :
|
||||
mCharCode(0), mScanCode(0), mIsDeadKey(false), mConsumed(false)
|
||||
{
|
||||
}
|
||||
|
||||
MSG GetCharMsg(HWND aWnd) const
|
||||
{
|
||||
|
@ -314,7 +320,7 @@ public:
|
|||
NativeKey(nsWindowBase* aWidget,
|
||||
const MSG& aKeyOrCharMessage,
|
||||
const ModifierKeyState& aModKeyState,
|
||||
const FakeCharMsg* aFakeCharMsg = nullptr);
|
||||
nsTArray<FakeCharMsg>* aFakeCharMsgs = nullptr);
|
||||
|
||||
/**
|
||||
* Handle WM_KEYDOWN message or WM_SYSKEYDOWN message. The instance must be
|
||||
|
@ -322,8 +328,7 @@ public:
|
|||
* Returns true if dispatched keydown event or keypress event is consumed.
|
||||
* Otherwise, false.
|
||||
*/
|
||||
bool HandleKeyDownMessage(bool* aEventDispatched = nullptr,
|
||||
bool* aWasKeyDownDefaultPrevented = nullptr) const;
|
||||
bool HandleKeyDownMessage(bool* aEventDispatched = nullptr) const;
|
||||
|
||||
/**
|
||||
* Handles WM_CHAR message or WM_SYSCHAR message. The instance must be
|
||||
|
@ -373,7 +378,8 @@ private:
|
|||
// Please note that the event may not cause any text input even if this
|
||||
// is true. E.g., it might be dead key state or Ctrl key may be pressed.
|
||||
bool mIsPrintableKey;
|
||||
bool mIsFakeCharMsg;
|
||||
|
||||
nsTArray<FakeCharMsg>* mFakeCharMsgs;
|
||||
|
||||
NativeKey()
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче