Bug 757688 part.2 Move nsModifierKeyState to KeyboardLayout and redesign it r=jimm

This commit is contained in:
Masayuki Nakano 2012-06-15 18:52:50 +09:00
parent e108421e79
commit bdafe1e737
9 changed files with 271 additions and 188 deletions

View File

@ -73,6 +73,87 @@ public:
};
/*****************************************************************************
* mozilla::widget::ModifierKeyState
*****************************************************************************/
void
ModifierKeyState::Update()
{
mModifiers = 0;
if (IS_VK_DOWN(VK_SHIFT)) {
mModifiers |= MODIFIER_SHIFT;
}
if (IS_VK_DOWN(VK_CONTROL)) {
mModifiers |= MODIFIER_CONTROL;
}
if (IS_VK_DOWN(VK_MENU)) {
mModifiers |= MODIFIER_ALT;
}
if (IS_VK_DOWN(VK_LWIN) || IS_VK_DOWN(VK_RWIN)) {
mModifiers |= MODIFIER_WIN;
}
if (::GetKeyState(VK_CAPITAL) & 1) {
mModifiers |= MODIFIER_CAPSLOCK;
}
if (::GetKeyState(VK_NUMLOCK) & 1) {
mModifiers |= MODIFIER_NUMLOCK;
}
if (::GetKeyState(VK_SCROLL) & 1) {
mModifiers |= MODIFIER_SCROLL;
}
EnsureAltGr();
}
void
ModifierKeyState::InitInputEvent(nsInputEvent& aInputEvent) const
{
aInputEvent.modifiers = mModifiers;
switch(aInputEvent.eventStructType) {
case NS_MOUSE_EVENT:
case NS_MOUSE_SCROLL_EVENT:
case NS_DRAG_EVENT:
case NS_SIMPLE_GESTURE_EVENT:
case NS_MOZTOUCH_EVENT:
InitMouseEvent(aInputEvent);
break;
}
}
void
ModifierKeyState::InitMouseEvent(nsInputEvent& aMouseEvent) const
{
NS_ASSERTION(aMouseEvent.eventStructType == NS_MOUSE_EVENT ||
aMouseEvent.eventStructType == NS_MOUSE_SCROLL_EVENT ||
aMouseEvent.eventStructType == NS_DRAG_EVENT ||
aMouseEvent.eventStructType == NS_SIMPLE_GESTURE_EVENT ||
aMouseEvent.eventStructType == NS_MOZTOUCH_EVENT,
"called with non-mouse event");
nsMouseEvent_base& mouseEvent = static_cast<nsMouseEvent_base&>(aMouseEvent);
mouseEvent.buttons = 0;
if (::GetKeyState(VK_LBUTTON) < 0) {
mouseEvent.buttons |= nsMouseEvent::eLeftButtonFlag;
}
if (::GetKeyState(VK_RBUTTON) < 0) {
mouseEvent.buttons |= nsMouseEvent::eRightButtonFlag;
}
if (::GetKeyState(VK_MBUTTON) < 0) {
mouseEvent.buttons |= nsMouseEvent::eMiddleButtonFlag;
}
if (::GetKeyState(VK_XBUTTON1) < 0) {
mouseEvent.buttons |= nsMouseEvent::e4thButtonFlag;
}
if (::GetKeyState(VK_XBUTTON2) < 0) {
mouseEvent.buttons |= nsMouseEvent::e5thButtonFlag;
}
}
/*****************************************************************************
* mozilla::widget::VirtualKey
*****************************************************************************/
inline PRUnichar
VirtualKey::GetCompositeChar(PRUint8 aShiftState, PRUnichar aBaseChar) const
@ -198,6 +279,10 @@ VirtualKey::GetNativeUniChars(PRUint8 aShiftState,
return index;
}
/*****************************************************************************
* mozilla::widget::NativeKey
*****************************************************************************/
NativeKey::NativeKey(const KeyboardLayout& aKeyboardLayout,
nsWindow* aWindow,
const MSG& aKeyOrCharMessage) :
@ -327,6 +412,9 @@ NativeKey::GetKeyLocation() const
}
}
/*****************************************************************************
* mozilla::widget::KeyboardLayout
*****************************************************************************/
KeyboardLayout::KeyboardLayout() :
mKeyboardLayout(0)
@ -573,12 +661,12 @@ KeyboardLayout::LoadLayout(HKL aLayout)
// static
PRUint8
KeyboardLayout::GetShiftState(const nsModifierKeyState& aModifierKeyState)
KeyboardLayout::GetShiftState(const ModifierKeyState& aModifierKeyState)
{
bool isShift = !!aModifierKeyState.mIsShiftDown;
bool isCtrl = !!aModifierKeyState.mIsControlDown;
bool isAlt = !!aModifierKeyState.mIsAltDown;
bool isCaps = !!aModifierKeyState.mIsCapsLocked;
bool isShift = aModifierKeyState.IsShift();
bool isCtrl = aModifierKeyState.IsControl();
bool isAlt = aModifierKeyState.IsAlt();
bool isCaps = aModifierKeyState.IsCapsLocked();
return ((isCaps << 3) | (isAlt << 2) | (isCtrl << 1) | isShift);
}
@ -1017,6 +1105,10 @@ KeyboardLayout::ConvertNativeKeyCodeToDOMKeyCode(UINT aNativeKeyCode) const
return 0;
}
/*****************************************************************************
* mozilla::widget::DeadKeyTable
*****************************************************************************/
PRUnichar
DeadKeyTable::GetCompositeChar(PRUnichar aBaseChar) const
{

View File

@ -7,6 +7,7 @@
#define KeyboardLayout_h__
#include "nscore.h"
#include "nsEvent.h"
#include <windows.h>
#define NS_NUM_OF_KEYS 54
@ -59,6 +60,99 @@ enum eKeyShiftFlags
eCapsLock = 0x08
};
class ModifierKeyState {
public:
ModifierKeyState()
{
Update();
}
ModifierKeyState(bool aIsShiftDown, bool aIsControlDown, bool aIsAltDown)
{
Update();
Unset(MODIFIER_SHIFT | MODIFIER_CONTROL | MODIFIER_ALT | MODIFIER_ALTGRAPH);
Modifiers modifiers = 0;
if (aIsShiftDown) {
modifiers |= MODIFIER_SHIFT;
}
if (aIsControlDown) {
modifiers |= MODIFIER_CONTROL;
}
if (aIsAltDown) {
modifiers |= MODIFIER_ALT;
}
if (modifiers) {
Set(modifiers);
}
}
void Update();
void Unset(Modifiers aRemovingModifiers)
{
mModifiers &= ~aRemovingModifiers;
// Note that we don't need to unset AltGr flag here automatically.
// For nsEditor, we need to remove Alt and Control flags but AltGr isn't
// checked in nsEditor, so, it can be kept.
}
void Set(Modifiers aAddingModifiers)
{
mModifiers |= aAddingModifiers;
EnsureAltGr();
}
void SetKeyShiftFlags(PRUint8 aKeyShiftFlags)
{
Unset(MODIFIER_SHIFT | MODIFIER_CONTROL | MODIFIER_ALT |
MODIFIER_ALTGRAPH | MODIFIER_CAPSLOCK);
Modifiers modifiers = 0;
if (aKeyShiftFlags & eShift) {
modifiers |= MODIFIER_SHIFT;
}
if (aKeyShiftFlags & eCtrl) {
modifiers |= MODIFIER_CONTROL;
}
if (aKeyShiftFlags & eAlt) {
modifiers |= MODIFIER_ALT;
}
if (aKeyShiftFlags & eCapsLock) {
modifiers |= MODIFIER_CAPSLOCK;
}
if (modifiers) {
Set(modifiers);
}
}
void InitInputEvent(nsInputEvent& aInputEvent) const;
bool IsShift() const { return (mModifiers & MODIFIER_SHIFT) != 0; }
bool IsControl() const { return (mModifiers & MODIFIER_CONTROL) != 0; }
bool IsAlt() const { return (mModifiers & MODIFIER_ALT) != 0; }
bool IsAltGr() const { return IsControl() && IsAlt(); }
bool IsWin() const { return (mModifiers & MODIFIER_WIN) != 0; }
bool IsCapsLocked() const { return (mModifiers & MODIFIER_CAPSLOCK) != 0; }
bool IsNumLocked() const { return (mModifiers & MODIFIER_NUMLOCK) != 0; }
bool IsScrollLocked() const { return (mModifiers & MODIFIER_SCROLL) != 0; }
private:
Modifiers mModifiers;
void EnsureAltGr()
{
// If both Control key and Alt key are pressed, it means AltGr is pressed.
// Ideally, we should check whether the current keyboard layout has AltGr
// or not. However, setting AltGr flags for keyboard which doesn't have
// AltGr must not be serious bug. So, it should be OK for now.
if (IsAltGr()) {
mModifiers |= MODIFIER_ALTGRAPH;
}
}
void InitMouseEvent(nsInputEvent& aMouseEvent) const;
};
struct DeadKeyEntry;
class DeadKeyTable;
@ -193,7 +287,7 @@ public:
/**
* GetShiftState() returns shift state for aModifierKeyState.
*/
static PRUint8 GetShiftState(const nsModifierKeyState& aModifierKeyState);
static PRUint8 GetShiftState(const ModifierKeyState& aModifierKeyState);
static bool IsPrintableCharKey(PRUint8 aVirtualKey);
static bool IsNumpadKey(PRUint8 aVirtualKey);

View File

@ -11,6 +11,7 @@
#include "WinMouseScrollHandler.h"
#include "nsWindow.h"
#include "KeyboardLayout.h"
#include "WinUtils.h"
#include "nsGkAtoms.h"
#include "nsIDOMWindowUtils.h"
@ -325,16 +326,16 @@ MouseScrollHandler::InitEvent(nsWindow* aWindow,
}
/* static */
nsModifierKeyState
ModifierKeyState
MouseScrollHandler::GetModifierKeyState(UINT aMessage)
{
nsModifierKeyState result;
ModifierKeyState result;
// Assume the Control key is down if the Elantech touchpad has sent the
// mis-ordered WM_KEYDOWN/WM_MOUSEWHEEL messages. (See the comment in
// MouseScrollHandler::Device::Elantech::HandleKeyMessage().)
if ((aMessage == MOZ_WM_MOUSEVWHEEL || aMessage == WM_MOUSEWHEEL) &&
!result.mIsControlDown) {
result.mIsControlDown = Device::Elantech::IsZooming();
!result.IsControl() && Device::Elantech::IsZooming()) {
result.Set(MODIFIER_CONTROL);
}
return result;
}
@ -362,7 +363,7 @@ MouseScrollHandler::ScrollTargetInfo
MouseScrollHandler::GetScrollTargetInfo(
nsWindow* aWindow,
const EventInfo& aEventInfo,
const nsModifierKeyState& aModifierKeyState)
const ModifierKeyState& aModifierKeyState)
{
ScrollTargetInfo result;
result.dispatchPixelScrollEvent = false;
@ -688,7 +689,7 @@ MouseScrollHandler::HandleMouseWheelMessage(nsWindow* aWindow,
mLastEventInfo.RecordEvent(eventInfo);
nsModifierKeyState modKeyState = GetModifierKeyState(aMessage);
ModifierKeyState modKeyState = GetModifierKeyState(aMessage);
// Before dispatching line scroll event, we should get the current scroll
// event target information for pixel scroll.
@ -761,7 +762,7 @@ MouseScrollHandler::HandleScrollMessageAsMouseWheelMessage(nsWindow* aWindow,
mIsWaitingInternalMessage = false;
nsModifierKeyState modKeyState = GetModifierKeyState(aMessage);
ModifierKeyState modKeyState = GetModifierKeyState(aMessage);
nsMouseScrollEvent scrollEvent(true, NS_MOUSE_SCROLL, aWindow);
scrollEvent.scrollFlags =
@ -917,7 +918,7 @@ MouseScrollHandler::LastEventInfo::InitMouseScrollEvent(
nsWindow* aWindow,
nsMouseScrollEvent& aMouseScrollEvent,
const ScrollTargetInfo& aScrollTargetInfo,
const nsModifierKeyState& aModKeyState)
const ModifierKeyState& aModKeyState)
{
NS_ABORT_IF_FALSE(aMouseScrollEvent.message == NS_MOUSE_SCROLL,
"aMouseScrollEvent must be NS_MOUSE_SCROLL");
@ -979,7 +980,7 @@ MouseScrollHandler::LastEventInfo::InitMousePixelScrollEvent(
nsWindow* aWindow,
nsMouseScrollEvent& aPixelScrollEvent,
const ScrollTargetInfo& aScrollTargetInfo,
const nsModifierKeyState& aModKeyState)
const ModifierKeyState& aModKeyState)
{
NS_ABORT_IF_FALSE(aPixelScrollEvent.message == NS_MOUSE_PIXEL_SCROLL,
"aPixelScrollEvent must be NS_MOUSE_PIXEL_SCROLL");

View File

@ -17,11 +17,12 @@ class nsWindow;
class nsGUIEvent;
class nsMouseScrollEvent;
struct nsIntPoint;
struct nsModifierKeyState;
namespace mozilla {
namespace widget {
class ModifierKeyState;
class MouseScrollHandler {
public:
static MouseScrollHandler* GetInstance();
@ -87,7 +88,7 @@ private:
*
* @param aMessage Handling message.
*/
static nsModifierKeyState GetModifierKeyState(UINT aMessage);
static ModifierKeyState GetModifierKeyState(UINT aMessage);
/**
* MozGetMessagePos() returns the mouse cursor position when GetMessage()
@ -205,7 +206,7 @@ private:
ScrollTargetInfo GetScrollTargetInfo(
nsWindow* aWindow,
const EventInfo& aEvent,
const nsModifierKeyState& aModiferKeyState);
const ModifierKeyState& aModiferKeyState);
class EventInfo {
public:
@ -295,7 +296,7 @@ private:
bool InitMouseScrollEvent(nsWindow* aWindow,
nsMouseScrollEvent& aMouseScrollEvent,
const ScrollTargetInfo& aScrollTargetInfo,
const nsModifierKeyState& aModKeyState);
const ModifierKeyState& aModKeyState);
/**
* InitMousePixelScrollEvent() initializes NS_MOUSE_PIXEL_SCROLL event and
@ -314,7 +315,7 @@ private:
bool InitMousePixelScrollEvent(nsWindow* aWindow,
nsMouseScrollEvent& aPixelScrollEvent,
const ScrollTargetInfo& aScrollTargetInfo,
const nsModifierKeyState& aModKeyState);
const ModifierKeyState& aModKeyState);
private:
static PRInt32 RoundDelta(double aDelta);

View File

@ -715,7 +715,7 @@ nsIMM32Handler::OnIMENotify(nsWindow* aWindow,
// keypress event. So, we should find another way for the bug.
// add hacky code here
nsModifierKeyState modKeyState(false, false, true);
mozilla::widget::ModifierKeyState modKeyState(false, false, true);
mozilla::widget::NativeKey nativeKey; // Dummy is okay for this usage.
nsKeyEvent keyEvent(true, NS_KEY_PRESS, aWindow);
keyEvent.keyCode = 192;
@ -1696,7 +1696,7 @@ nsIMM32Handler::DispatchTextEvent(nsWindow* aWindow,
event.rangeArray = textRanges.Elements();
event.theText = mCompositionString.get();
nsModifierKeyState modKeyState;
mozilla::widget::ModifierKeyState modKeyState;
modKeyState.InitInputEvent(event);
aWindow->DispatchWindowEvent(&event);

View File

@ -15,6 +15,9 @@
#include "nsIWidget.h"
#include "nsWindow.h"
#include "nsClipboard.h"
#include "KeyboardLayout.h"
using namespace mozilla::widget;
/* Define Class IDs */
static NS_DEFINE_IID(kCDragServiceCID, NS_DRAGSERVICE_CID);
@ -169,7 +172,7 @@ nsNativeDragTarget::DispatchDragDropEvent(PRUint32 aEventType, POINTL aPT)
event.refPoint.y = 0;
}
nsModifierKeyState modifierKeyState;
ModifierKeyState modifierKeyState;
modifierKeyState.InitInputEvent(event);
event.inputSource = static_cast<nsBaseDragService*>(mDragService)->GetInputSource();

View File

@ -3527,7 +3527,7 @@ bool nsWindow::DispatchWindowEvent(nsGUIEvent* event, nsEventStatus &aStatus) {
void nsWindow::InitKeyEvent(nsKeyEvent& aKeyEvent,
const NativeKey& aNativeKey,
const nsModifierKeyState &aModKeyState)
const ModifierKeyState &aModKeyState)
{
nsIntPoint point(0, 0);
InitEvent(aKeyEvent, &point);
@ -3733,7 +3733,7 @@ bool nsWindow::DispatchMouseEvent(PRUint32 aEventType, WPARAM wParam,
InitEvent(event, &eventPoint);
}
nsModifierKeyState modifierKeyState;
ModifierKeyState modifierKeyState;
modifierKeyState.InitInputEvent(event);
event.button = aButton;
event.inputSource = aInputSource;
@ -3937,7 +3937,7 @@ nsWindow::DispatchAccessibleEvent(PRUint32 aEventType)
nsAccessibleEvent event(true, aEventType, this);
InitEvent(event, nsnull);
nsModifierKeyState modifierKeyState;
ModifierKeyState modifierKeyState;
modifierKeyState.InitInputEvent(event);
DispatchWindowEvent(&event);
@ -5020,7 +5020,7 @@ bool nsWindow::ProcessMessage(UINT msg, WPARAM &wParam, LPARAM &lParam,
nsMouseEvent event(true, NS_MOUSE_ACTIVATE, this,
nsMouseEvent::eReal);
InitEvent(event);
nsModifierKeyState modifierKeyState;
ModifierKeyState modifierKeyState;
modifierKeyState.InitInputEvent(event);
DispatchWindowEvent(&event);
if (sSwitchKeyboardLayout && mLastKeyboardLayout)
@ -5542,7 +5542,7 @@ LRESULT nsWindow::ProcessCharMessage(const MSG &aMsg, bool *aEventDispatched)
// These must be checked here too as a lone WM_CHAR could be received
// if a child window didn't handle it (for example Alt+Space in a content window)
nsModifierKeyState modKeyState;
ModifierKeyState modKeyState;
NativeKey nativeKey(gKbdLayout, this, aMsg);
return OnChar(aMsg, nativeKey, modKeyState, aEventDispatched);
}
@ -5555,7 +5555,7 @@ LRESULT nsWindow::ProcessKeyUpMessage(const MSG &aMsg, bool *aEventDispatched)
("%s VK=%d\n", aMsg.message == WM_SYSKEYDOWN ?
"WM_SYSKEYUP" : "WM_KEYUP", aMsg.wParam));
nsModifierKeyState modKeyState;
ModifierKeyState modKeyState;
// Note: the original code passed (HIWORD(lParam)) to OnKeyUp as
// scan code. However, this breaks Alt+Num pad input.
@ -5567,7 +5567,7 @@ LRESULT nsWindow::ProcessKeyUpMessage(const MSG &aMsg, bool *aEventDispatched)
// translating ALT+number key combinations.
// ignore [shift+]alt+space so the OS can handle it
if (modKeyState.mIsAltDown && !modKeyState.mIsControlDown &&
if (modKeyState.IsAlt() && !modKeyState.IsControl() &&
IS_VK_DOWN(NS_VK_SPACE)) {
return FALSE;
}
@ -5599,7 +5599,7 @@ LRESULT nsWindow::ProcessKeyDownMessage(const MSG &aMsg,
// nsWindow.h.
AutoForgetRedirectedKeyDownMessage forgetRedirectedMessage(this, aMsg);
nsModifierKeyState modKeyState;
ModifierKeyState modKeyState;
// Note: the original code passed (HIWORD(lParam)) to OnKeyDown as
// scan code. However, this breaks Alt+Num pad input.
@ -5611,12 +5611,12 @@ LRESULT nsWindow::ProcessKeyDownMessage(const MSG &aMsg,
// translating ALT+number key combinations.
// ignore [shift+]alt+space so the OS can handle it
if (modKeyState.mIsAltDown && !modKeyState.mIsControlDown &&
if (modKeyState.IsAlt() && !modKeyState.IsControl() &&
IS_VK_DOWN(NS_VK_SPACE))
return FALSE;
LRESULT result = 0;
if (modKeyState.mIsAltDown && nsIMM32Handler::IsStatusChanged()) {
if (modKeyState.IsAlt() && nsIMM32Handler::IsStatusChanged()) {
nsIMM32Handler::NotifyEndStatusChange();
} else if (!nsIMM32Handler::IsComposingOn(this)) {
result = OnKeyDown(aMsg, modKeyState, aEventDispatched, nsnull);
@ -5626,7 +5626,7 @@ LRESULT nsWindow::ProcessKeyDownMessage(const MSG &aMsg,
}
if (aMsg.wParam == VK_MENU ||
(aMsg.wParam == VK_F10 && !modKeyState.mIsShiftDown)) {
(aMsg.wParam == VK_F10 && !modKeyState.IsShift())) {
// We need to let Windows handle this keypress,
// by returning false, if there's a native menu
// bar somewhere in our containing window hierarchy.
@ -5685,7 +5685,7 @@ nsWindow::SynthesizeNativeKeyEvent(PRInt32 aNativeKeyboardLayout,
kbdState[keySpecific] = 0x81;
}
::SetKeyboardState(kbdState);
nsModifierKeyState modKeyState;
ModifierKeyState modKeyState;
UINT scanCode = ::MapVirtualKeyEx(aNativeKeyCode, MAPVK_VK_TO_VSC,
gKbdLayout.GetLayout());
LPARAM lParam = static_cast<LPARAM>(scanCode << 16);
@ -5710,7 +5710,7 @@ nsWindow::SynthesizeNativeKeyEvent(PRInt32 aNativeKeyboardLayout,
kbdState[keySpecific] = 0;
}
::SetKeyboardState(kbdState);
nsModifierKeyState modKeyState;
ModifierKeyState modKeyState;
UINT scanCode = ::MapVirtualKeyEx(aNativeKeyCode, MAPVK_VK_TO_VSC,
gKbdLayout.GetLayout());
LPARAM lParam = static_cast<LPARAM>(scanCode << 16);
@ -6110,7 +6110,7 @@ bool nsWindow::OnTouch(WPARAM wParam, LPARAM lParam)
touchPoint.ScreenToClient(mWnd);
nsMozTouchEvent touchEvent(true, msg, this, pInputs[i].dwID);
nsModifierKeyState modifierKeyState;
ModifierKeyState modifierKeyState;
modifierKeyState.InitInputEvent(touchEvent);
touchEvent.inputSource = nsIDOMMouseEvent::MOZ_SOURCE_TOUCH;
touchEvent.refPoint = touchPoint;
@ -6137,7 +6137,7 @@ bool nsWindow::OnGesture(WPARAM wParam, LPARAM lParam)
nsEventStatus status;
nsModifierKeyState modifierKeyState;
ModifierKeyState modifierKeyState;
modifierKeyState.InitInputEvent(event);
event.button = 0;
@ -6177,7 +6177,7 @@ bool nsWindow::OnGesture(WPARAM wParam, LPARAM lParam)
}
// Polish up and send off the new event
nsModifierKeyState modifierKeyState;
ModifierKeyState modifierKeyState;
modifierKeyState.InitInputEvent(event);
event.button = 0;
event.time = ::GetMessageTime();
@ -6224,7 +6224,7 @@ bool nsWindow::IsRedirectedKeyDownMessage(const MSG &aMsg)
* looking at or touching the message queue.
*/
LRESULT nsWindow::OnKeyDown(const MSG &aMsg,
nsModifierKeyState &aModKeyState,
const ModifierKeyState &aModKeyState,
bool *aEventDispatched,
nsFakeCharMessage* aFakeCharMessage)
{
@ -6331,7 +6331,7 @@ LRESULT nsWindow::OnKeyDown(const MSG &aMsg,
// Enter and backspace are always handled here to avoid for example the
// confusion between ctrl-enter and ctrl-J.
if (DOMKeyCode == NS_VK_RETURN || DOMKeyCode == NS_VK_BACK ||
((aModKeyState.mIsControlDown || aModKeyState.mIsAltDown)
((aModKeyState.IsControl() || aModKeyState.IsAlt())
&& !isDeadKey && KeyboardLayout::IsPrintableCharKey(virtualKeyCode)))
{
// Remove a possible WM_CHAR or WM_SYSCHAR messages from the message queue.
@ -6397,7 +6397,7 @@ LRESULT nsWindow::OnKeyDown(const MSG &aMsg,
::DefWindowProcW(mWnd, msg.message, msg.wParam, msg.lParam);
return result;
}
else if (!aModKeyState.mIsControlDown && !aModKeyState.mIsAltDown &&
else if (!aModKeyState.IsControl() && !aModKeyState.IsAlt() &&
(KeyboardLayout::IsPrintableCharKey(virtualKeyCode) ||
KeyboardLayout::IsNumpadKey(virtualKeyCode)))
{
@ -6448,7 +6448,7 @@ LRESULT nsWindow::OnKeyDown(const MSG &aMsg,
ArrayLength(uniChars));
}
if (aModKeyState.mIsControlDown ^ aModKeyState.mIsAltDown) {
if (aModKeyState.IsControl() ^ aModKeyState.IsAlt()) {
PRUint8 capsLockState = (::GetKeyState(VK_CAPITAL) & 1) ? eCapsLock : 0;
numOfUnshiftedChars =
gKbdLayout.GetUniCharsWithShiftState(virtualKeyCode, capsLockState,
@ -6493,19 +6493,20 @@ LRESULT nsWindow::OnKeyDown(const MSG &aMsg,
// But don't replace the charCode when the charCode is not same as
// unmodified characters. In such case, Ctrl is sometimes used for a
// part of character inputting key combination like Shift.
if (aModKeyState.mIsControlDown) {
if (aModKeyState.IsControl()) {
PRUint8 currentState = eCtrl;
if (aModKeyState.mIsShiftDown)
if (aModKeyState.IsShift()) {
currentState |= eShift;
}
PRUint32 ch =
aModKeyState.mIsShiftDown ? shiftedLatinChar : unshiftedLatinChar;
aModKeyState.IsShift() ? shiftedLatinChar : unshiftedLatinChar;
if (ch &&
(numOfUniChars == 0 ||
StringCaseInsensitiveEquals(uniChars, numOfUniChars,
aModKeyState.mIsShiftDown ? shiftedChars : unshiftedChars,
aModKeyState.mIsShiftDown ? numOfShiftedChars :
numOfUnshiftedChars))) {
aModKeyState.IsShift() ? shiftedChars : unshiftedChars,
aModKeyState.IsShift() ? numOfShiftedChars :
numOfUnshiftedChars))) {
numOfUniChars = numOfShiftStates = 1;
uniChars[0] = ch;
shiftStates[0] = currentState;
@ -6524,6 +6525,7 @@ LRESULT nsWindow::OnKeyDown(const MSG &aMsg,
for (PRUint32 cnt = 0; cnt < num; cnt++) {
PRUint16 uniChar, shiftedChar, unshiftedChar;
uniChar = shiftedChar = unshiftedChar = 0;
ModifierKeyState modKeyState(aModKeyState);
if (skipUniChars <= cnt) {
if (cnt - skipUniChars < numOfShiftStates) {
// If key in combination with Alt and/or Ctrl produces a different
@ -6532,12 +6534,7 @@ LRESULT nsWindow::OnKeyDown(const MSG &aMsg,
// and base character does not produce a valid composite character
// then both produced dead-key character and following base
// character may have different modifier flags, too.
aModKeyState.mIsShiftDown =
(shiftStates[cnt - skipUniChars] & eShift) != 0;
aModKeyState.mIsControlDown =
(shiftStates[cnt - skipUniChars] & eCtrl) != 0;
aModKeyState.mIsAltDown =
(shiftStates[cnt - skipUniChars] & eAlt) != 0;
modKeyState.SetKeyShiftFlags(shiftStates[cnt - skipUniChars]);
}
uniChar = uniChars[cnt - skipUniChars];
}
@ -6584,7 +6581,7 @@ LRESULT nsWindow::OnKeyDown(const MSG &aMsg,
keypressEvent.flags |= extraFlags;
keypressEvent.charCode = uniChar;
keypressEvent.alternativeCharCodes.AppendElements(altArray);
InitKeyEvent(keypressEvent, nativeKey, aModKeyState);
InitKeyEvent(keypressEvent, nativeKey, modKeyState);
DispatchKeyEvent(keypressEvent, nsnull);
}
} else {
@ -6600,7 +6597,7 @@ LRESULT nsWindow::OnKeyDown(const MSG &aMsg,
// OnKeyUp
LRESULT nsWindow::OnKeyUp(const MSG &aMsg,
nsModifierKeyState &aModKeyState,
const ModifierKeyState &aModKeyState,
bool *aEventDispatched)
{
// NOTE: VK_PROCESSKEY never comes with WM_KEYUP
@ -6619,47 +6616,48 @@ LRESULT nsWindow::OnKeyUp(const MSG &aMsg,
// OnChar
LRESULT nsWindow::OnChar(const MSG &aMsg,
const NativeKey& aNativeKey,
nsModifierKeyState &aModKeyState,
const ModifierKeyState &aModKeyState,
bool *aEventDispatched, PRUint32 aFlags)
{
// ignore [shift+]alt+space so the OS can handle it
if (aModKeyState.mIsAltDown && !aModKeyState.mIsControlDown &&
if (aModKeyState.IsAlt() && !aModKeyState.IsControl() &&
IS_VK_DOWN(NS_VK_SPACE)) {
return FALSE;
}
PRUint32 charCode = aMsg.wParam;
// Ignore Ctrl+Enter (bug 318235)
if (aModKeyState.mIsControlDown && charCode == 0xA) {
if (aModKeyState.IsControl() && charCode == 0xA) {
return FALSE;
}
// WM_CHAR with Control and Alt (== AltGr) down really means a normal character
bool saveIsAltDown = aModKeyState.mIsAltDown;
bool saveIsControlDown = aModKeyState.mIsControlDown;
if (aModKeyState.mIsAltDown && aModKeyState.mIsControlDown)
aModKeyState.mIsAltDown = aModKeyState.mIsControlDown = false;
ModifierKeyState modKeyState(aModKeyState);
if (modKeyState.IsAlt() && modKeyState.IsControl()) {
modKeyState.Unset(MODIFIER_ALT | MODIFIER_CONTROL);
}
if (nsIMM32Handler::IsComposingOn(this)) {
ResetInputState();
}
wchar_t uniChar;
if (aModKeyState.mIsControlDown && charCode <= 0x1A) { // Ctrl+A Ctrl+Z, see Programming Windows 3.1 page 110 for details
// Ctrl+A Ctrl+Z, see Programming Windows 3.1 page 110 for details
if (modKeyState.IsControl() && charCode <= 0x1A) {
// need to account for shift here. bug 16486
if (aModKeyState.mIsShiftDown)
if (modKeyState.IsShift()) {
uniChar = charCode - 1 + 'A';
else
} else {
uniChar = charCode - 1 + 'a';
}
else if (aModKeyState.mIsControlDown && charCode <= 0x1F) {
}
} else if (modKeyState.IsControl() && charCode <= 0x1F) {
// Fix for 50255 - <ctrl><[> and <ctrl><]> are not being processed.
// also fixes ctrl+\ (x1c), ctrl+^ (x1e) and ctrl+_ (x1f)
// for some reason the keypress handler need to have the uniChar code set
// with the addition of a upper case A not the lower case.
uniChar = charCode - 1 + 'A';
} else { // 0x20 - SPACE, 0x3D - EQUALS
if (charCode < 0x20 || (charCode == 0x3D && aModKeyState.mIsControlDown)) {
if (charCode < 0x20 || (charCode == 0x3D && modKeyState.IsControl())) {
uniChar = 0;
} else {
uniChar = charCode;
@ -6668,15 +6666,15 @@ LRESULT nsWindow::OnChar(const MSG &aMsg,
// Keep the characters unshifted for shortcuts and accesskeys and make sure
// that numbers are always passed as such (among others: bugs 50255 and 351310)
if (uniChar && (aModKeyState.mIsControlDown || aModKeyState.mIsAltDown)) {
if (uniChar && (modKeyState.IsControl() || modKeyState.IsAlt())) {
UINT virtualKeyCode = ::MapVirtualKeyEx(aNativeKey.GetScanCode(),
MAPVK_VSC_TO_VK,
gKbdLayout.GetLayout());
UINT unshiftedCharCode =
virtualKeyCode >= '0' && virtualKeyCode <= '9' ? virtualKeyCode :
aModKeyState.mIsShiftDown ? ::MapVirtualKeyEx(virtualKeyCode,
MAPVK_VK_TO_CHAR,
gKbdLayout.GetLayout()) : 0;
modKeyState.IsShift() ? ::MapVirtualKeyEx(virtualKeyCode,
MAPVK_VK_TO_CHAR,
gKbdLayout.GetLayout()) : 0;
// ignore diacritics (top bit set) and key mapping errors (char code 0)
if ((INT)unshiftedCharCode > 0)
uniChar = unshiftedCharCode;
@ -6685,7 +6683,8 @@ LRESULT nsWindow::OnChar(const MSG &aMsg,
// Fix for bug 285161 (and 295095) which was caused by the initial fix for bug 178110.
// When pressing (alt|ctrl)+char, the char must be lowercase unless shift is
// pressed too.
if (!aModKeyState.mIsShiftDown && (saveIsAltDown || saveIsControlDown)) {
if (!modKeyState.IsShift() &&
(aModKeyState.IsAlt() || aModKeyState.IsControl())) {
uniChar = towlower(uniChar);
}
@ -6695,12 +6694,10 @@ LRESULT nsWindow::OnChar(const MSG &aMsg,
if (!keypressEvent.charCode) {
keypressEvent.keyCode = aNativeKey.GetDOMKeyCode();
}
InitKeyEvent(keypressEvent, aNativeKey, aModKeyState);
InitKeyEvent(keypressEvent, aNativeKey, modKeyState);
bool result = DispatchKeyEvent(keypressEvent, &aMsg);
if (aEventDispatched)
*aEventDispatched = true;
aModKeyState.mIsAltDown = saveIsAltDown;
aModKeyState.mIsControlDown = saveIsControlDown;
return result;
}
@ -7899,83 +7896,6 @@ nsWindow::DealWithPopups(HWND inWnd, UINT inMsg, WPARAM inWParam, LPARAM inLPara
**************************************************************
**************************************************************/
// nsModifierKeyState used in various character processing.
void
nsModifierKeyState::Update()
{
mIsShiftDown = IS_VK_DOWN(VK_SHIFT);
mIsControlDown = IS_VK_DOWN(VK_CONTROL);
mIsAltDown = IS_VK_DOWN(VK_MENU);
mIsWinDown = IS_VK_DOWN(VK_LWIN) || IS_VK_DOWN(VK_RWIN);
mIsCapsLocked = (::GetKeyState(VK_CAPITAL) & 1);
mIsNumLocked = (::GetKeyState(VK_NUMLOCK) & 1);
mIsScrollLocked = (::GetKeyState(VK_SCROLL) & 1);
}
void
nsModifierKeyState::InitInputEvent(nsInputEvent& aInputEvent) const
{
aInputEvent.modifiers = 0;
if (mIsShiftDown) {
aInputEvent.modifiers |= MODIFIER_SHIFT;
}
if (mIsControlDown) {
aInputEvent.modifiers |= MODIFIER_CONTROL;
}
if (mIsAltDown) {
aInputEvent.modifiers |= MODIFIER_ALT;
}
if (mIsWinDown) {
aInputEvent.modifiers |= MODIFIER_WIN;
}
if (mIsCapsLocked) {
aInputEvent.modifiers |= MODIFIER_CAPSLOCK;
}
if (mIsNumLocked) {
aInputEvent.modifiers |= MODIFIER_NUMLOCK;
}
if (mIsScrollLocked) {
aInputEvent.modifiers |= MODIFIER_SCROLL;
}
// If both Control key and Alt key are pressed, it means AltGr is pressed.
// Ideally, we should check whether the current keyboard layout has AltGr
// or not. However, setting AltGr flags for keyboard which doesn't have
// AltGr must not be serious bug. So, it should be OK for now.
if (mIsControlDown && mIsAltDown) {
aInputEvent.modifiers |= MODIFIER_ALTGRAPH;
}
switch(aInputEvent.eventStructType) {
case NS_MOUSE_EVENT:
case NS_MOUSE_SCROLL_EVENT:
case NS_DRAG_EVENT:
case NS_SIMPLE_GESTURE_EVENT:
case NS_MOZTOUCH_EVENT:
break;
default:
return;
}
nsMouseEvent_base& mouseEvent = static_cast<nsMouseEvent_base&>(aInputEvent);
mouseEvent.buttons = 0;
if (::GetKeyState(VK_LBUTTON) < 0) {
mouseEvent.buttons |= nsMouseEvent::eLeftButtonFlag;
}
if (::GetKeyState(VK_RBUTTON) < 0) {
mouseEvent.buttons |= nsMouseEvent::eRightButtonFlag;
}
if (::GetKeyState(VK_MBUTTON) < 0) {
mouseEvent.buttons |= nsMouseEvent::eMiddleButtonFlag;
}
if (::GetKeyState(VK_XBUTTON1) < 0) {
mouseEvent.buttons |= nsMouseEvent::e4thButtonFlag;
}
if (::GetKeyState(VK_XBUTTON2) < 0) {
mouseEvent.buttons |= nsMouseEvent::e5thButtonFlag;
}
}
// Note that the result of GetTopLevelWindow method can be different from the
// result of WinUtils::GetTopLevelHWND(). The result can be non-floating
// window. Because our top level window may be contained in another window

View File

@ -53,6 +53,7 @@ class imgIContainer;
namespace mozilla {
namespace widget {
class NativeKey;
class ModifierKeyState;
} // namespace widget
} // namespacw mozilla;
@ -190,7 +191,7 @@ public:
virtual bool DispatchWindowEvent(nsGUIEvent*event, nsEventStatus &aStatus);
void InitKeyEvent(nsKeyEvent& aKeyEvent,
const NativeKey& aNativeKey,
const nsModifierKeyState &aModKeyState);
const mozilla::widget::ModifierKeyState &aModKeyState);
virtual bool DispatchKeyEvent(nsKeyEvent& aKeyEvent,
const MSG *aMsgSentToPlugin);
void DispatchPendingEvents();
@ -370,15 +371,15 @@ protected:
*/
LRESULT OnChar(const MSG &aMsg,
const NativeKey& aNativeKey,
nsModifierKeyState &aModKeyState,
const mozilla::widget::ModifierKeyState &aModKeyState,
bool *aEventDispatched,
PRUint32 aFlags = 0);
LRESULT OnKeyDown(const MSG &aMsg,
nsModifierKeyState &aModKeyState,
const mozilla::widget::ModifierKeyState &aModKeyState,
bool *aEventDispatched,
nsFakeCharMessage* aFakeCharMessage);
LRESULT OnKeyUp(const MSG &aMsg,
nsModifierKeyState &aModKeyState,
const mozilla::widget::ModifierKeyState &aModKeyState,
bool *aEventDispatched);
bool OnGesture(WPARAM wParam, LPARAM lParam);
bool OnTouch(WPARAM wParam, LPARAM lParam);

View File

@ -225,35 +225,6 @@ struct nsFakeCharMessage {
}
};
// Used in char processing
struct nsModifierKeyState {
bool mIsShiftDown;
bool mIsControlDown;
bool mIsAltDown;
bool mIsWinDown;
bool mIsCapsLocked;
bool mIsNumLocked;
bool mIsScrollLocked;
nsModifierKeyState()
{
Update();
}
nsModifierKeyState(bool aIsShiftDown, bool aIsControlDown,
bool aIsAltDown)
{
Update();
mIsShiftDown = aIsShiftDown;
mIsControlDown = aIsControlDown;
mIsAltDown = aIsAltDown;
}
void Update();
void InitInputEvent(nsInputEvent& aInputEvent) const;
};
// Used for synthesizing events
struct KeyPair {
PRUint8 mGeneral;