зеркало из https://github.com/mozilla/gecko-dev.git
Bug 855975 part.8 Move nsWindow::OnChar() to widget::NativeKey::HandleCharMessage() r=jimm
This commit is contained in:
Родитель
e96de74786
Коммит
672ed5b1c6
|
@ -731,6 +731,126 @@ NativeKey::DispatchKeyDownEvent(bool* aEventDispatched) const
|
|||
return DispatchKeyEvent(keydownEvent, &mMsg);
|
||||
}
|
||||
|
||||
bool
|
||||
NativeKey::HandleCharMessage(const MSG& aCharMsg,
|
||||
bool* aEventDispatched,
|
||||
const EventFlags* aExtraFlags) const
|
||||
{
|
||||
MOZ_ASSERT(mMsg.message == WM_KEYDOWN || mMsg.message == WM_SYSKEYDOWN ||
|
||||
mMsg.message == WM_CHAR || mMsg.message == WM_SYSCHAR);
|
||||
MOZ_ASSERT(aCharMsg.message == WM_CHAR || aCharMsg.message == WM_SYSCHAR);
|
||||
|
||||
if (aEventDispatched) {
|
||||
*aEventDispatched = false;
|
||||
}
|
||||
|
||||
// Alt+Space key is handled by OS, we shouldn't touch it.
|
||||
if (mModKeyState.IsAlt() && !mModKeyState.IsControl() &&
|
||||
mVirtualKeyCode == VK_SPACE) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Bug 818235: Ignore Ctrl+Enter.
|
||||
if (!mModKeyState.IsAlt() && mModKeyState.IsControl() &&
|
||||
mVirtualKeyCode == VK_RETURN) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// XXXmnakao I think that if aNativeKeyDown is null, such lonely WM_CHAR
|
||||
// should cause composition events because they are not caused
|
||||
// by actual keyboard operation.
|
||||
|
||||
static const PRUnichar U_SPACE = 0x20;
|
||||
static const PRUnichar U_EQUAL = 0x3D;
|
||||
|
||||
// First, handle normal text input or non-printable key case here.
|
||||
if ((!mModKeyState.IsAlt() && !mModKeyState.IsControl()) ||
|
||||
mModKeyState.IsAltGr() ||
|
||||
(mOriginalVirtualKeyCode &&
|
||||
!KeyboardLayout::IsPrintableCharKey(mOriginalVirtualKeyCode))) {
|
||||
nsKeyEvent keypressEvent(true, NS_KEY_PRESS, mWidget);
|
||||
if (aExtraFlags) {
|
||||
keypressEvent.mFlags.Union(*aExtraFlags);
|
||||
}
|
||||
if (aCharMsg.wParam >= U_SPACE) {
|
||||
keypressEvent.charCode = static_cast<uint32_t>(aCharMsg.wParam);
|
||||
} else {
|
||||
keypressEvent.keyCode = mDOMKeyCode;
|
||||
}
|
||||
// When AltGr (Alt+Ctrl) is pressed, that causes normal text input.
|
||||
// At this time, if either alt or ctrl flag is set, nsEditor ignores the
|
||||
// keypress event. For avoiding this issue, we should remove ctrl and alt
|
||||
// flags.
|
||||
ModifierKeyState modKeyState(mModKeyState);
|
||||
modKeyState.Unset(MODIFIER_ALT | MODIFIER_CONTROL);
|
||||
InitKeyEvent(keypressEvent, modKeyState);
|
||||
if (aEventDispatched) {
|
||||
*aEventDispatched = true;
|
||||
}
|
||||
return DispatchKeyEvent(keypressEvent, &aCharMsg);
|
||||
}
|
||||
|
||||
// XXX It seems that following code was implemented for shortcut key
|
||||
// handling. However, it's now handled in WM_KEYDOWN message handler.
|
||||
// So, this actually runs only when WM_CHAR is sent/posted without
|
||||
// WM_KEYDOWN. I think that we don't need to keypress event in such
|
||||
// case especially for shortcut keys.
|
||||
|
||||
PRUnichar uniChar;
|
||||
// Ctrl+A Ctrl+Z, see Programming Windows 3.1 page 110 for details
|
||||
if (mModKeyState.IsControl() && aCharMsg.wParam <= 0x1A) {
|
||||
// Bug 16486: Need to account for shift here.
|
||||
uniChar = aCharMsg.wParam - 1 + (mModKeyState.IsShift() ? 'A' : 'a');
|
||||
} else if (mModKeyState.IsControl() && aCharMsg.wParam <= 0x1F) {
|
||||
// Bug 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 = aCharMsg.wParam - 1 + 'A';
|
||||
} else if (aCharMsg.wParam < U_SPACE ||
|
||||
(aCharMsg.wParam == U_EQUAL && mModKeyState.IsControl())) {
|
||||
uniChar = 0;
|
||||
} else {
|
||||
uniChar = aCharMsg.wParam;
|
||||
}
|
||||
|
||||
// Bug 50255 and Bug 351310: Keep the characters unshifted for shortcuts and
|
||||
// accesskeys and make sure that numbers are always passed as such.
|
||||
if (uniChar && (mModKeyState.IsControl() || mModKeyState.IsAlt())) {
|
||||
KeyboardLayout* keyboardLayout = KeyboardLayout::GetInstance();
|
||||
PRUnichar unshiftedCharCode =
|
||||
(mVirtualKeyCode >= '0' && mVirtualKeyCode <= '9') ?
|
||||
mVirtualKeyCode : mModKeyState.IsShift() ?
|
||||
ComputeUnicharFromScanCode() : 0;
|
||||
// Ignore diacritics (top bit set) and key mapping errors (char code 0)
|
||||
if (static_cast<int32_t>(unshiftedCharCode) > 0) {
|
||||
uniChar = unshiftedCharCode;
|
||||
}
|
||||
}
|
||||
|
||||
// Bug 285161 and Bug 295095: They were caused by the initial fix for
|
||||
// bug 178110. When pressing (alt|ctrl)+char, the char must be lowercase
|
||||
// unless shift is pressed too.
|
||||
if (!mModKeyState.IsShift() &&
|
||||
(mModKeyState.IsAlt() || mModKeyState.IsControl())) {
|
||||
uniChar = towlower(uniChar);
|
||||
}
|
||||
|
||||
nsKeyEvent keypressEvent(true, NS_KEY_PRESS, mWidget);
|
||||
if (aExtraFlags) {
|
||||
keypressEvent.mFlags.Union(*aExtraFlags);
|
||||
}
|
||||
keypressEvent.charCode = uniChar;
|
||||
if (!keypressEvent.charCode) {
|
||||
keypressEvent.keyCode = mDOMKeyCode;
|
||||
}
|
||||
InitKeyEvent(keypressEvent, mModKeyState);
|
||||
if (aEventDispatched) {
|
||||
*aEventDispatched = true;
|
||||
}
|
||||
return DispatchKeyEvent(keypressEvent, &aCharMsg);
|
||||
}
|
||||
|
||||
bool
|
||||
NativeKey::HandleKeyUpMessage(bool* aEventDispatched) const
|
||||
{
|
||||
|
|
|
@ -337,6 +337,15 @@ public:
|
|||
*/
|
||||
bool DispatchKeyDownEvent(bool* aEventDispatched = nullptr) const;
|
||||
|
||||
/**
|
||||
* Handles WM_CHAR message or WM_SYSCHAR message. The instance must be
|
||||
* initialized with WM_KEYDOWN, WM_SYSKEYDOWN or them.
|
||||
* Returns true if dispatched keypress event is consumed. Otherwise, false.
|
||||
*/
|
||||
bool HandleCharMessage(const MSG& aCharMsg,
|
||||
bool* aEventDispatched = nullptr,
|
||||
const EventFlags* aExtraFlags = nullptr) const;
|
||||
|
||||
/**
|
||||
* Handles keyup message. Returns true if the event is consumed.
|
||||
* Otherwise, false.
|
||||
|
|
|
@ -5618,18 +5618,16 @@ void nsWindow::RemoveNextCharMessage(HWND aWnd)
|
|||
|
||||
LRESULT nsWindow::ProcessCharMessage(const MSG &aMsg, bool *aEventDispatched)
|
||||
{
|
||||
NS_PRECONDITION(aMsg.message == WM_CHAR || aMsg.message == WM_SYSCHAR,
|
||||
"message is not keydown event");
|
||||
PR_LOG(gWindowsLog, PR_LOG_ALWAYS,
|
||||
("%s charCode=%d scanCode=%d\n",
|
||||
aMsg.message == WM_SYSCHAR ? "WM_SYSCHAR" : "WM_CHAR",
|
||||
aMsg.wParam, HIWORD(aMsg.lParam) & 0xFF));
|
||||
|
||||
if (IMEHandler::IsComposingOn(this)) {
|
||||
IMEHandler::NotifyIME(this, REQUEST_TO_COMMIT_COMPOSITION);
|
||||
}
|
||||
// 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)
|
||||
// if a child window didn't handle it (for example Alt+Space in a content
|
||||
// window)
|
||||
ModifierKeyState modKeyState;
|
||||
NativeKey nativeKey(this, aMsg, modKeyState);
|
||||
return OnChar(aMsg, nativeKey, modKeyState, aEventDispatched);
|
||||
return static_cast<LRESULT>(nativeKey.HandleCharMessage(aMsg,
|
||||
aEventDispatched));
|
||||
}
|
||||
|
||||
LRESULT nsWindow::ProcessKeyUpMessage(const MSG &aMsg, bool *aEventDispatched)
|
||||
|
@ -5833,7 +5831,7 @@ nsWindow::SynthesizeNativeKeyEvent(int32_t aNativeKeyboardLayout,
|
|||
nsFakeCharMessage fakeMsg = { chars.CharAt(j), scanCode, false };
|
||||
MSG msg = fakeMsg.GetCharMessage(mWnd);
|
||||
NativeKey nativeKey(this, msg, modKeyState);
|
||||
OnChar(msg, nativeKey, modKeyState, nullptr);
|
||||
nativeKey.HandleCharMessage(msg);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -6558,7 +6556,8 @@ LRESULT nsWindow::OnKeyDown(const MSG &aMsg,
|
|||
}
|
||||
}
|
||||
#endif // #ifdef DEBUG
|
||||
return OnChar(msg, nativeKey, aModKeyState, nullptr, &extraFlags);
|
||||
return static_cast<LRESULT>(
|
||||
nativeKey.HandleCharMessage(msg, nullptr, &extraFlags));
|
||||
}
|
||||
|
||||
// If prevent default set for keydown, do same for keypress
|
||||
|
@ -6578,12 +6577,12 @@ LRESULT nsWindow::OnKeyDown(const MSG &aMsg,
|
|||
msg.message == WM_SYSCHAR ? "WM_SYSCHAR" : "WM_CHAR",
|
||||
msg.wParam, HIWORD(msg.lParam) & 0xFF));
|
||||
|
||||
BOOL result = OnChar(msg, nativeKey, aModKeyState, nullptr, &extraFlags);
|
||||
bool result = nativeKey.HandleCharMessage(msg, nullptr, &extraFlags);
|
||||
// If a syschar keypress wasn't processed, Windows may want to
|
||||
// handle it to activate a native menu.
|
||||
if (!result && msg.message == WM_SYSCHAR)
|
||||
::DefWindowProcW(mWnd, msg.message, msg.wParam, msg.lParam);
|
||||
return result;
|
||||
return static_cast<LRESULT>(result);
|
||||
}
|
||||
else if (!aModKeyState.IsControl() && !aModKeyState.IsAlt() &&
|
||||
!aModKeyState.IsWin() &&
|
||||
|
@ -6749,94 +6748,6 @@ LRESULT nsWindow::OnKeyDown(const MSG &aMsg,
|
|||
return noDefault;
|
||||
}
|
||||
|
||||
// OnChar
|
||||
LRESULT nsWindow::OnChar(const MSG &aMsg,
|
||||
const NativeKey& aNativeKey,
|
||||
const ModifierKeyState &aModKeyState,
|
||||
bool *aEventDispatched,
|
||||
const EventFlags *aExtraFlags)
|
||||
{
|
||||
// ignore [shift+]alt+space so the OS can handle it
|
||||
if (aModKeyState.IsAlt() && !aModKeyState.IsControl() &&
|
||||
IS_VK_DOWN(NS_VK_SPACE)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
uint32_t charCode = aMsg.wParam;
|
||||
// Ignore Ctrl+Enter (bug 318235)
|
||||
if (aModKeyState.IsControl() && charCode == 0xA) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// WM_CHAR with Control and Alt (== AltGr) down really means a normal character
|
||||
ModifierKeyState modKeyState(aModKeyState);
|
||||
if (modKeyState.IsAlt() && modKeyState.IsControl()) {
|
||||
modKeyState.Unset(MODIFIER_ALT | MODIFIER_CONTROL);
|
||||
}
|
||||
|
||||
if (IMEHandler::IsComposingOn(this)) {
|
||||
IMEHandler::NotifyIME(this, REQUEST_TO_COMMIT_COMPOSITION);
|
||||
}
|
||||
|
||||
wchar_t uniChar;
|
||||
// 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 (modKeyState.IsShift()) {
|
||||
uniChar = charCode - 1 + 'A';
|
||||
} else {
|
||||
uniChar = charCode - 1 + 'a';
|
||||
}
|
||||
} 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 && modKeyState.IsControl())) {
|
||||
uniChar = 0;
|
||||
} else {
|
||||
uniChar = charCode;
|
||||
}
|
||||
}
|
||||
|
||||
// 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 && (modKeyState.IsControl() || modKeyState.IsAlt())) {
|
||||
KeyboardLayout* keyboardLayout = KeyboardLayout::GetInstance();
|
||||
UINT virtualKeyCode = aNativeKey.ComputeVirtualKeyCodeFromScanCode();
|
||||
UINT unshiftedCharCode =
|
||||
virtualKeyCode >= '0' && virtualKeyCode <= '9' ? virtualKeyCode :
|
||||
modKeyState.IsShift() ? aNativeKey.ComputeUnicharFromScanCode() : 0;
|
||||
// ignore diacritics (top bit set) and key mapping errors (char code 0)
|
||||
if ((INT)unshiftedCharCode > 0)
|
||||
uniChar = unshiftedCharCode;
|
||||
}
|
||||
|
||||
// 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 (!modKeyState.IsShift() &&
|
||||
(aModKeyState.IsAlt() || aModKeyState.IsControl())) {
|
||||
uniChar = towlower(uniChar);
|
||||
}
|
||||
|
||||
nsKeyEvent keypressEvent(true, NS_KEY_PRESS, this);
|
||||
if (aExtraFlags) {
|
||||
keypressEvent.mFlags.Union(*aExtraFlags);
|
||||
}
|
||||
keypressEvent.charCode = uniChar;
|
||||
if (!keypressEvent.charCode) {
|
||||
keypressEvent.keyCode = aNativeKey.GetDOMKeyCode();
|
||||
}
|
||||
aNativeKey.InitKeyEvent(keypressEvent, modKeyState);
|
||||
bool result = aNativeKey.DispatchKeyEvent(keypressEvent, &aMsg);
|
||||
if (aEventDispatched)
|
||||
*aEventDispatched = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
nsWindow::SetupKeyModifiersSequence(nsTArray<KeyPair>* aArray, uint32_t aModifiers)
|
||||
{
|
||||
|
|
|
@ -362,17 +362,6 @@ protected:
|
|||
virtual void OnDestroy();
|
||||
virtual bool OnMove(int32_t aX, int32_t aY);
|
||||
virtual bool OnResize(nsIntRect &aWindowRect);
|
||||
/**
|
||||
* @param aVirtualKeyCode If caller knows which key exactly caused the
|
||||
* aMsg, set the virtual key code.
|
||||
* Otherwise, 0.
|
||||
* @param aScanCode If aVirutalKeyCode isn't 0, set the scan code.
|
||||
*/
|
||||
LRESULT OnChar(const MSG &aMsg,
|
||||
const NativeKey& aNativeKey,
|
||||
const mozilla::widget::ModifierKeyState &aModKeyState,
|
||||
bool *aEventDispatched,
|
||||
const mozilla::widget::EventFlags* aExtraFlags = nullptr);
|
||||
LRESULT OnKeyDown(const MSG &aMsg,
|
||||
const mozilla::widget::ModifierKeyState &aModKeyState,
|
||||
bool *aEventDispatched,
|
||||
|
|
Загрузка…
Ссылка в новой задаче