Bug 1302956 part.1 NativeKey should store latest instance with sLatestInstance r?m_kato draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Thu, 15 Sep 2016 17:02:30 +0900
changeset 416869 e10076513f9507cd00877d35176e9cf1eb54963f
parent 416868 eab078823eeeb361d79d2035dddcdb4bfc7da952
child 416870 cde8cb015672baa9e827e41398f410dd9fe8488d
child 416980 59d9463a2b983a6a69c2589ba986a9fa5ceb2ecc
push id30275
push usermasayuki@d-toybox.com
push dateFri, 23 Sep 2016 06:48:35 +0000
reviewersm_kato
bugs1302956
milestone52.0a1
Bug 1302956 part.1 NativeKey should store latest instance with sLatestInstance r?m_kato For detecting nested creation of NativeKey instances, NativeKey should manage the latest instance with sLastestInstance for the other instances and previous instance with mLastInstance. MozReview-Commit-ID: BFZ0cr1640S
widget/windows/KeyboardLayout.cpp
widget/windows/KeyboardLayout.h
--- a/widget/windows/KeyboardLayout.cpp
+++ b/widget/windows/KeyboardLayout.cpp
@@ -1185,25 +1185,27 @@ VirtualKey::FillKbdState(PBYTE aKbdState
   }
 }
 
 /*****************************************************************************
  * mozilla::widget::NativeKey
  *****************************************************************************/
 
 uint8_t NativeKey::sDispatchedKeyOfAppCommand = 0;
+NativeKey* NativeKey::sLatestInstance = nullptr;
 
 LazyLogModule sNativeKeyLogger("NativeKeyWidgets");
 
 NativeKey::NativeKey(nsWindowBase* aWidget,
                      const MSG& aMessage,
                      const ModifierKeyState& aModKeyState,
                      HKL aOverrideKeyboardLayout,
                      nsTArray<FakeCharMsg>* aFakeCharMsgs)
-  : mWidget(aWidget)
+  : mLastInstance(sLatestInstance)
+  , 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)
@@ -1213,22 +1215,23 @@ NativeKey::NativeKey(nsWindowBase* aWidg
   , mScanCode(0)
   , mIsExtended(false)
   , mIsDeadKey(false)
   , mFakeCharMsgs(aFakeCharMsgs && aFakeCharMsgs->Length() ?
                     aFakeCharMsgs : nullptr)
 {
   MOZ_LOG(sNativeKeyLogger, LogLevel::Info,
     ("%p NativeKey::NativeKey(aWidget=0x%p { GetWindowHandle()=0x%p }, "
-     "aMessage=%s, aModKeyState=%s)",
+     "aMessage=%s, aModKeyState=%s), sLatestInstance=0x%p",
      this, aWidget, aWidget->GetWindowHandle(), ToString(aMessage).get(),
-     ToString(aModKeyState).get()));
+     ToString(aModKeyState).get(), sLatestInstance));
 
   MOZ_ASSERT(aWidget);
   MOZ_ASSERT(mDispatcher);
+  sLatestInstance = this;
   KeyboardLayout* keyboardLayout = KeyboardLayout::GetInstance();
   mKeyboardLayout = keyboardLayout->GetLayout();
   if (aOverrideKeyboardLayout && mKeyboardLayout != aOverrideKeyboardLayout) {
     keyboardLayout->OverrideLayout(aOverrideKeyboardLayout);
     mKeyboardLayout = keyboardLayout->GetLayout();
     MOZ_ASSERT(mKeyboardLayout == aOverrideKeyboardLayout);
     mIsOverridingKeyboardLayout = true;
   } else {
@@ -1510,16 +1513,17 @@ NativeKey::InitWithKeyChar()
 NativeKey::~NativeKey()
 {
   MOZ_LOG(sNativeKeyLogger, LogLevel::Debug,
     ("%p   NativeKey::~NativeKey(), destroyed", this));
   if (mIsOverridingKeyboardLayout) {
     KeyboardLayout* keyboardLayout = KeyboardLayout::GetInstance();
     keyboardLayout->RestoreLayout();
   }
+  sLatestInstance = mLastInstance;
 }
 
 void
 NativeKey::InitWithAppCommand()
 {
   if (GET_DEVICE_LPARAM(mMsg.lParam) != FAPPCOMMAND_KEY) {
     return;
   }
--- a/widget/windows/KeyboardLayout.h
+++ b/widget/windows/KeyboardLayout.h
@@ -254,16 +254,17 @@ public:
 
   /**
    * Returns true if aChar is a control character which shouldn't be inputted
    * into focused text editor.
    */
   static bool IsControlChar(char16_t aChar);
 
 private:
+  NativeKey* mLastInstance;
   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;
@@ -538,16 +539,26 @@ private:
   /**
    * IsFocusedWindowChanged() returns true if focused window is changed
    * after the instance is created.
    */
   bool IsFocusedWindowChanged() const
   {
     return mFocusedWndBeforeDispatch != ::GetFocus();
   }
+
+  // Calls of PeekMessage() from NativeKey might cause nested message handling
+  // due to (perhaps) odd API hook.  NativeKey should do nothing if given
+  // message is tried to be retrieved by another instance.
+
+  /**
+   * sLatestInstacne is a pointer to the newest instance of NativeKey which is
+   * handling a key or char message(s).
+   */
+  static NativeKey* sLatestInstance;
 };
 
 class KeyboardLayout
 {
   friend class NativeKey;
 
 private:
   KeyboardLayout();