Bug 1302956 part.1 NativeKey should store latest instance with sLatestInstance r=m_kato
authorMasayuki Nakano <masayuki@d-toybox.com>
Thu, 15 Sep 2016 17:02:30 +0900
changeset 358100 2903829cac14bb1fc70c0810a623304e10fa282b
parent 358099 eb840c87b5fdb85756a6f6c32458bfb05240c534
child 358101 3c4ca5845f2c12974cad7617efe5f12137603721
push id6795
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 14:19:46 +0000
treeherdermozilla-beta@76101b503191 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersm_kato
bugs1302956
milestone52.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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();