Bug 1300003 part.2 Don't continue to dispatch eKeyPress event at handling WM_KEYDOWN or following WM_CHAR messages if focused window is changed during dispatching an event r?m_kato
While dispatching an event, focused widget may be changed. In such case, NativeKey shouldn't continue to dispatch remaining events (eKeyPress events) for preventing to dispatch to input text in unexpected website.
MozReview-Commit-ID: 7geuqks0LQK
--- a/widget/windows/KeyboardLayout.cpp
+++ b/widget/windows/KeyboardLayout.cpp
@@ -844,16 +844,17 @@ uint8_t NativeKey::sDispatchedKeyOfAppCo
NativeKey::NativeKey(nsWindowBase* aWidget,
const MSG& aMessage,
const ModifierKeyState& aModKeyState,
HKL aOverrideKeyboardLayout,
nsTArray<FakeCharMsg>* aFakeCharMsgs)
: mWidget(aWidget)
, mDispatcher(aWidget->GetTextEventDispatcher())
, mMsg(aMessage)
+ , mFocusedWndBeforeDispatch(::GetFocus())
, mDOMKeyCode(0)
, mKeyNameIndex(KEY_NAME_INDEX_Unidentified)
, mCodeNameIndex(CODE_NAME_INDEX_UNKNOWN)
, mModKeyState(aModKeyState)
, mVirtualKeyCode(0)
, mOriginalVirtualKeyCode(0)
, mShiftedLatinChar(0)
, mUnshiftedLatinChar(0)
@@ -1740,17 +1741,17 @@ NativeKey::HandleKeyDownMessage(bool* aE
defaultPrevented = status == nsEventStatus_eConsumeNoDefault;
// We don't need to handle key messages on plugin for eKeyPress since
// eKeyDownOnPlugin is handled as both eKeyDown and eKeyPress.
if (IsKeyMessageOnPlugin()) {
return defaultPrevented;
}
- if (mWidget->Destroyed()) {
+ if (mWidget->Destroyed() || IsFocusedWindowChanged()) {
return true;
}
// If IMC wasn't associated to the window but is associated it now (i.e.,
// focus is moved from a non-editable editor to an editor by keydown
// event handler), WM_CHAR and WM_SYSCHAR shouldn't cause first character
// inputting if IME is opened. But then, we should redirect the native
// keydown message to IME.
@@ -1812,17 +1813,17 @@ NativeKey::HandleKeyDownMessage(bool* aE
}
if (!mFollowingCharMsgs.IsEmpty()) {
bool consumed = false;
for (size_t i = 0; i < mFollowingCharMsgs.Length(); ++i) {
consumed =
DispatchKeyPressEventForFollowingCharMessage(mFollowingCharMsgs[i]) ||
consumed;
- if (mWidget->Destroyed()) {
+ if (mWidget->Destroyed() || IsFocusedWindowChanged()) {
return true;
}
}
return consumed;
}
// If WM_KEYDOWN of VK_PACKET isn't followed by WM_CHAR, we don't need to
// dispatch keypress events.
@@ -2352,17 +2353,17 @@ NativeKey::DispatchPluginEventsAndDiscar
MOZ_ASSERT(!IsKeyMessageOnPlugin());
bool anyCharMessagesRemoved = false;
for (size_t i = 0; i < mFollowingCharMsgs.Length(); ++i) {
anyCharMessagesRemoved = true;
MOZ_RELEASE_ASSERT(!mWidget->Destroyed(),
"NativeKey tries to dispatch a plugin event on destroyed widget");
mWidget->DispatchPluginEvent(mFollowingCharMsgs[i]);
- if (mWidget->Destroyed()) {
+ if (mWidget->Destroyed() || IsFocusedWindowChanged()) {
return true;
}
}
if (!mFakeCharMsgs && !anyCharMessagesRemoved &&
mDOMKeyCode == NS_VK_BACK && IsIMEDoingKakuteiUndo()) {
// This is for a hack for ATOK and WXG. So, PeekMessage() must scceed!
MSG msg;
--- a/widget/windows/KeyboardLayout.h
+++ b/widget/windows/KeyboardLayout.h
@@ -262,16 +262,20 @@ private:
RefPtr<nsWindowBase> mWidget;
RefPtr<TextEventDispatcher> mDispatcher;
HKL mKeyboardLayout;
MSG mMsg;
// mFollowingCharMsgs stores WM_CHAR, WM_SYSCHAR, WM_DEADCHAR or
// WM_SYSDEADCHAR message which follows WM_KEYDOWN.
// Note that the stored messaged are already removed from the queue.
nsTArray<MSG> mFollowingCharMsgs;
+ // If dispatching eKeyDown or eKeyPress event causes focus change,
+ // the instance shouldn't handle remaning char messages. For checking it,
+ // this should store first focused window.
+ HWND mFocusedWndBeforeDispatch;
uint32_t mDOMKeyCode;
KeyNameIndex mKeyNameIndex;
CodeNameIndex mCodeNameIndex;
ModifierKeyState mModKeyState;
// mVirtualKeyCode distinguishes left key or right key of modifier key.
@@ -521,16 +525,25 @@ private:
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();
+
+ /**
+ * IsFocusedWindowChanged() returns true if focused window is changed
+ * after the instance is created.
+ */
+ bool IsFocusedWindowChanged() const
+ {
+ return mFocusedWndBeforeDispatch != ::GetFocus();
+ }
};
class KeyboardLayout
{
friend class NativeKey;
private:
KeyboardLayout();