зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
8f62c5aa3c
Коммит
0b9b9bf032
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************
|
||||
|
|
Загрузка…
Ссылка в новой задаче