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 draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Mon, 05 Sep 2016 18:56:34 +0900
changeset 413988 ee33f37eec3dfa7acdf6f63b52916c18e1eef7ab
parent 413987 584208e811a63590ff6fe890fc6c9cc27ec3021b
child 413989 1e935dbe069674513b4a2a6b0b5994fa1af3377d
push id29569
push usermasayuki@d-toybox.com
push dateThu, 15 Sep 2016 12:25:58 +0000
reviewersm_kato
bugs1300003
milestone51.0a1
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
widget/windows/KeyboardLayout.cpp
widget/windows/KeyboardLayout.h
--- 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();