Bug 1257759 part.9 Implement nsWindow::OnKeyEventInPluginProcess() on Windows r=jimm

Implementing nsWindow::OnWindowedPluginKeyEvent() on Windows.  This patch makes NativeKey class dispatches eKeyDownOnPlugin and eKeyUpOnPlugin when the method is called.

MozReview-Commit-ID: L8yRZvDaQKR

--HG--
extra : rebase_source : 387ce72dcea23a92bd8c774fc54a8bff8da6c844
This commit is contained in:
Masayuki Nakano 2016-04-15 17:02:36 +09:00
Родитель 8f62c5aa3c
Коммит 0b9b9bf032
4 изменённых файлов: 108 добавлений и 13 удалений

Просмотреть файл

@ -679,6 +679,7 @@ uint8_t NativeKey::sDispatchedKeyOfAppCommand = 0;
NativeKey::NativeKey(nsWindowBase* aWidget,
const MSG& aMessage,
const ModifierKeyState& aModKeyState,
HKL aOverrideKeyboardLayout,
nsTArray<FakeCharMsg>* aFakeCharMsgs)
: mWidget(aWidget)
, mDispatcher(aWidget->GetTextEventDispatcher())
@ -701,6 +702,14 @@ NativeKey::NativeKey(nsWindowBase* aWidget,
MOZ_ASSERT(mDispatcher);
KeyboardLayout* keyboardLayout = KeyboardLayout::GetInstance();
mKeyboardLayout = keyboardLayout->GetLayout();
if (aOverrideKeyboardLayout && mKeyboardLayout != aOverrideKeyboardLayout) {
keyboardLayout->OverrideLayout(aOverrideKeyboardLayout);
mKeyboardLayout = keyboardLayout->GetLayout();
MOZ_ASSERT(mKeyboardLayout == aOverrideKeyboardLayout);
mIsOverridingKeyboardLayout = true;
} else {
mIsOverridingKeyboardLayout = false;
}
if (mMsg.message == WM_APPCOMMAND) {
InitWithAppCommand();
@ -712,14 +721,19 @@ NativeKey::NativeKey(nsWindowBase* aWidget,
switch (mMsg.message) {
case WM_KEYDOWN:
case WM_SYSKEYDOWN:
case MOZ_WM_KEYDOWN:
case WM_KEYUP:
case WM_SYSKEYUP: {
case WM_SYSKEYUP:
case MOZ_WM_KEYUP: {
// If the key message is sent from other application like a11y tools, the
// scancode value might not be set proper value. Then, probably the value
// is 0.
// NOTE: If the virtual keycode can be caused by both non-extended key
// and extended key, the API returns the non-extended key's
// scancode. E.g., VK_LEFT causes "4" key on numpad.
// NOTE: Cannot compute scancode from keycode if the key message comes
// from plugin process since active keyboard layout may be
// different.
if (!mScanCode) {
uint16_t scanCodeEx = ComputeScanCodeExFromVirtualKeyCode(mMsg.wParam);
if (scanCodeEx) {
@ -889,6 +903,14 @@ NativeKey::NativeKey(nsWindowBase* aWidget,
}
}
NativeKey::~NativeKey()
{
if (mIsOverridingKeyboardLayout) {
KeyboardLayout* keyboardLayout = KeyboardLayout::GetInstance();
keyboardLayout->RestoreLayout();
}
}
void
NativeKey::InitWithAppCommand()
{
@ -991,6 +1013,8 @@ NativeKey::IsFollowedByDeadCharMessage() const
MSG nextMsg;
if (mFakeCharMsgs) {
nextMsg = mFakeCharMsgs->ElementAt(0).GetCharMsg(mMsg.hwnd);
} else if (IsKeyMessageOnPlugin()) {
return false;
} else {
if (!WinUtils::PeekMessage(&nextMsg, mMsg.hwnd, WM_KEYFIRST, WM_KEYLAST,
PM_NOREMOVE | PM_NOYIELD)) {
@ -1183,12 +1207,14 @@ NativeKey::InitKeyEvent(WidgetKeyboardEvent& aKeyEvent,
switch (aKeyEvent.mMessage) {
case eKeyDown:
case eKeyDownOnPlugin:
aKeyEvent.keyCode = mDOMKeyCode;
// Unique id for this keydown event and its associated keypress.
sUniqueKeyEventId++;
aKeyEvent.mUniqueId = sUniqueKeyEventId;
break;
case eKeyUp:
case eKeyUpOnPlugin:
aKeyEvent.keyCode = mDOMKeyCode;
// Set defaultPrevented of the key event if the VK_MENU is not a system
// key release, so that the menu bar does not trigger. This helps avoid
@ -1462,7 +1488,7 @@ NativeKey::HandleKeyDownMessage(bool* aEventDispatched) const
}
bool defaultPrevented = false;
if (mFakeCharMsgs ||
if (mFakeCharMsgs || IsKeyMessageOnPlugin() ||
!RedirectedKeyDownMessageManager::IsRedirectedMessage(mMsg)) {
// Ignore [shift+]alt+space so the OS can handle it.
if (mModKeyState.IsAlt() && !mModKeyState.IsControl() &&
@ -1476,7 +1502,9 @@ NativeKey::HandleKeyDownMessage(bool* aEventDispatched) const
}
bool isIMEEnabled = WinUtils::IsIMEEnabled(mWidget->GetInputContext());
WidgetKeyboardEvent keydownEvent(true, eKeyDown, mWidget);
EventMessage keyDownMessage =
IsKeyMessageOnPlugin() ? eKeyDownOnPlugin : eKeyDown;
WidgetKeyboardEvent keydownEvent(true, keyDownMessage, mWidget);
nsEventStatus status = InitKeyEvent(keydownEvent, mModKeyState, &mMsg);
bool dispatched =
mDispatcher->DispatchKeyboardEvent(eKeyDown, keydownEvent, status,
@ -1491,6 +1519,12 @@ NativeKey::HandleKeyDownMessage(bool* aEventDispatched) const
}
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()) {
return true;
}
@ -1504,8 +1538,8 @@ NativeKey::HandleKeyDownMessage(bool* aEventDispatched) const
// application, we shouldn't redirect the message to it because the keydown
// message is processed by us, so, nobody shouldn't process it.
HWND focusedWnd = ::GetFocus();
if (!defaultPrevented && !mFakeCharMsgs && focusedWnd &&
!mWidget->PluginHasFocus() && !isIMEEnabled &&
if (!defaultPrevented && !mFakeCharMsgs && !IsKeyMessageOnPlugin() &&
focusedWnd && !mWidget->PluginHasFocus() && !isIMEEnabled &&
WinUtils::IsIMEEnabled(mWidget->GetInputContext())) {
RedirectedKeyDownMessageManager::RemoveNextCharMessage(focusedWnd);
@ -1733,6 +1767,7 @@ NativeKey::HandleKeyUpMessage(bool* aEventDispatched) const
WidgetKeyboardEvent keyupEvent(true, eKeyUp, mWidget);
nsEventStatus status = InitKeyEvent(keyupEvent, mModKeyState, &mMsg);
EventMessage keyUpMessage = IsKeyMessageOnPlugin() ? eKeyUpOnPlugin : eKeyUp;
bool dispatched =
mDispatcher->DispatchKeyboardEvent(eKeyUp, keyupEvent, status,
const_cast<NativeKey*>(this));
@ -1747,6 +1782,13 @@ NativeKey::NeedsToHandleWithoutFollowingCharMessages() const
{
MOZ_ASSERT(IsKeyDownMessage());
// We cannot know following char messages of key messages in a plugin
// process. So, let's compute the character to be inputted with every
// printable key should be computed with the keyboard layout.
if (IsKeyMessageOnPlugin()) {
return true;
}
// Enter and backspace are always handled here to avoid for example the
// confusion between ctrl-enter and ctrl-J.
if (mDOMKeyCode == NS_VK_RETURN || mDOMKeyCode == NS_VK_BACK) {
@ -1850,6 +1892,7 @@ bool
NativeKey::GetFollowingCharMessage(MSG& aCharMsg) const
{
MOZ_ASSERT(IsKeyDownMessage());
MOZ_ASSERT(!IsKeyMessageOnPlugin());
aCharMsg.message = WM_NULL;
@ -2060,6 +2103,7 @@ bool
NativeKey::DispatchPluginEventsAndDiscardsCharMessages() const
{
MOZ_ASSERT(IsKeyDownMessage());
MOZ_ASSERT(!IsKeyMessageOnPlugin());
// Remove a possible WM_CHAR or WM_SYSCHAR messages from the message queue.
// They can be more than one because of:
@ -3320,6 +3364,8 @@ KeyboardLayout::SynthesizeNativeKeyEvent(nsWindowBase* aWidget,
keySequence.AppendElement(KeyPair(aNativeKeyCode, argumentKeySpecific));
// Simulate the pressing of each modifier key and then the real key
// FYI: Each NativeKey instance here doesn't need to override keyboard layout
// since this method overrides and restores the keyboard layout.
for (uint32_t i = 0; i < keySequence.Length(); ++i) {
uint8_t key = keySequence[i].mGeneral;
uint8_t keySpecific = keySequence[i].mSpecific;
@ -3361,7 +3407,7 @@ KeyboardLayout::SynthesizeNativeKeyEvent(nsWindowBase* aWidget,
fakeCharMsg->mScanCode = scanCode;
fakeCharMsg->mIsDeadKey = makeDeadCharMsg;
}
NativeKey nativeKey(aWidget, keyDownMsg, modKeyState, &fakeCharMsgs);
NativeKey nativeKey(aWidget, keyDownMsg, modKeyState, 0, &fakeCharMsgs);
bool dispatched;
nativeKey.HandleKeyDownMessage(&dispatched);
// If some char messages are not consumed, let's emulate the widget

Просмотреть файл

@ -14,6 +14,7 @@
#include "mozilla/Attributes.h"
#include "mozilla/EventForwards.h"
#include "mozilla/TextEventDispatcher.h"
#include "mozilla/widget/WinMessages.h"
#include "mozilla/widget/WinModifierKeyState.h"
#include <windows.h>
@ -170,7 +171,7 @@ public:
UniCharsAndModifiers GetUniChars(ShiftState aShiftState) const;
};
class MOZ_STACK_CLASS NativeKey
class MOZ_STACK_CLASS NativeKey final
{
friend class KeyboardLayout;
@ -203,8 +204,11 @@ public:
NativeKey(nsWindowBase* aWidget,
const MSG& aMessage,
const ModifierKeyState& aModKeyState,
HKL aOverrideKeyboardLayout = 0,
nsTArray<FakeCharMsg>* aFakeCharMsgs = nullptr);
~NativeKey();
/**
* Handle WM_KEYDOWN message or WM_SYSKEYDOWN message. The instance must be
* initialized with WM_KEYDOWN or WM_SYSKEYDOWN.
@ -292,6 +296,9 @@ private:
// Please note that the event may not cause any text input even if this
// is true. E.g., it might be dead key state or Ctrl key may be pressed.
bool mIsPrintableKey;
// mIsOverridingKeyboardLayout is true if the instance temporarily overriding
// keyboard layout with specified by the constructor.
bool mIsOverridingKeyboardLayout;
nsTArray<FakeCharMsg>* mFakeCharMsgs;
@ -320,6 +327,7 @@ private:
case WM_SYSCHAR:
case WM_DEADCHAR:
case WM_SYSDEADCHAR:
case MOZ_WM_KEYDOWN:
return ((mMsg.lParam & (1 << 30)) != 0);
case WM_APPCOMMAND:
if (mVirtualKeyCode) {
@ -355,11 +363,15 @@ private:
bool IsKeyDownMessage() const
{
return (mMsg.message == WM_KEYDOWN || mMsg.message == WM_SYSKEYDOWN);
return (mMsg.message == WM_KEYDOWN ||
mMsg.message == WM_SYSKEYDOWN ||
mMsg.message == MOZ_WM_KEYDOWN);
}
bool IsKeyUpMessage() const
{
return (mMsg.message == WM_KEYUP || mMsg.message == WM_SYSKEYUP);
return (mMsg.message == WM_KEYUP ||
mMsg.message == WM_SYSKEYUP ||
mMsg.message == MOZ_WM_KEYUP);
}
bool IsPrintableCharMessage(const MSG& aMSG) const
{
@ -395,6 +407,11 @@ private:
}
bool MayBeSameCharMessage(const MSG& aCharMsg1, const MSG& aCharMsg2) const;
bool IsFollowedByDeadCharMessage() const;
bool IsKeyMessageOnPlugin() const
{
return (mMsg.message == MOZ_WM_KEYDOWN ||
mMsg.message == MOZ_WM_KEYUP);
}
/**
* GetFollowingCharMessage() returns following char message of handling

Просмотреть файл

@ -34,8 +34,8 @@
// Internal message used for hiding the on-screen keyboard
#define MOZ_WM_DISMISS_ONSCREEN_KEYBOARD (WM_APP+0x0317)
// Following MOZ_WM_*KEY* messages are used by PluginInstanceChild internally.
// (never posted to the queue)
// Following MOZ_WM_*KEY* messages are used by PluginInstanceChild and
// NativeKey internally. (never posted to the queue)
#define MOZ_WM_KEYDOWN (WM_APP+0x0318)
#define MOZ_WM_KEYUP (WM_APP+0x0319)
#define MOZ_WM_SYSKEYDOWN (WM_APP+0x031A)

Просмотреть файл

@ -134,6 +134,7 @@
#include "mozilla/WindowsVersion.h"
#include "mozilla/TextEvents.h" // For WidgetKeyboardEvent
#include "mozilla/TextEventDispatcherListener.h"
#include "mozilla/widget/WinNativeEventData.h"
#include "nsThemeConstants.h"
#include "nsBidiKeyboard.h"
@ -7874,8 +7875,39 @@ nsresult
nsWindow::OnWindowedPluginKeyEvent(const NativeEventData& aKeyEventData,
nsIKeyEventInPluginCallback* aCallback)
{
// TODO: Implement in the following patch.
return NS_ERROR_NOT_IMPLEMENTED;
if (NS_WARN_IF(!mWnd)) {
return NS_OK;
}
const WinNativeKeyEventData* eventData =
static_cast<const WinNativeKeyEventData*>(aKeyEventData);
switch (eventData->mMessage) {
case WM_KEYDOWN:
case WM_SYSKEYDOWN: {
MSG mozMsg =
WinUtils::InitMSG(MOZ_WM_KEYDOWN, eventData->mWParam,
eventData->mLParam, mWnd);
ModifierKeyState modifierKeyState(eventData->mModifiers);
NativeKey nativeKey(this, mozMsg, modifierKeyState,
eventData->GetKeyboardLayout());
return nativeKey.HandleKeyDownMessage() ? NS_SUCCESS_EVENT_CONSUMED :
NS_OK;
}
case WM_KEYUP:
case WM_SYSKEYUP: {
MSG mozMsg =
WinUtils::InitMSG(MOZ_WM_KEYUP, eventData->mWParam,
eventData->mLParam, mWnd);
ModifierKeyState modifierKeyState(eventData->mModifiers);
NativeKey nativeKey(this, mozMsg, modifierKeyState,
eventData->GetKeyboardLayout());
return nativeKey.HandleKeyUpMessage() ? NS_SUCCESS_EVENT_CONSUMED : NS_OK;
}
default:
// We shouldn't consume WM_*CHAR messages here even if the preceding
// keydown or keyup event on the plugin is consumed. It should be
// managed in each plugin window rather than top level window.
return NS_OK;
}
}
/**************************************************************