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
--- 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();