Bug 301089 - Pressing a key while another key held down does not generate keydown eventp=O. Atsushi (Torisugari) <torisugari@gmail.com>r+sr=roc

This commit is contained in:
asqueella@gmail.com 2007-04-27 09:34:44 -07:00
parent f32e01f616
commit b715161c4f
2 changed files with 45 additions and 13 deletions

View File

@ -305,7 +305,6 @@ nsWindow::nsWindow()
mContainerGotFocus = PR_FALSE;
mContainerLostFocus = PR_FALSE;
mContainerBlockFocus = PR_FALSE;
mInKeyRepeat = PR_FALSE;
mIsVisible = PR_FALSE;
mRetryPointerGrab = PR_FALSE;
mRetryKeyboardGrab = PR_FALSE;
@ -323,6 +322,8 @@ nsWindow::nsWindow()
initialize_prefs();
}
memset(mKeyDownFlags, 0, sizeof(mKeyDownFlags));
if (mLastDragMotionWindow == this)
mLastDragMotionWindow = NULL;
mDragMotionWidget = 0;
@ -1520,9 +1521,9 @@ nsWindow::GetAttention(PRInt32 aCycleCount)
void
nsWindow::LoseFocus(void)
{
// make sure that we reset our repeat counter so the next keypress
// make sure that we reset our key down counter so the next keypress
// for this widget will get the down event
mInKeyRepeat = PR_FALSE;
memset(mKeyDownFlags, 0, sizeof(mKeyDownFlags));
// Dispatch a lostfocus event
DispatchLostFocusEvent();
@ -2181,15 +2182,18 @@ nsWindow::OnKeyPressEvent(GtkWidget *aWidget, GdkEventKey *aEvent)
nsCOMPtr<nsIWidget> kungFuDeathGrip = this;
// If the key repeat flag isn't set then set it so we don't send
// If the key down flag isn't set then set it so we don't send
// another key down event on the next key press -- DOM events are
// key down, key press and key up. X only has key press and key
// release. gtk2 already filters the extra key release events for
// us.
PRBool isKeyDownCancelled = PR_FALSE;
if (!mInKeyRepeat) {
mInKeyRepeat = PR_TRUE;
PRUint32 domVirtualKeyCode = GdkKeyCodeToDOMKeyCode(aEvent->keyval);
if (!IsKeyDown(domVirtualKeyCode)) {
SetKeyDownFlag(domVirtualKeyCode);
// send the key down event
nsKeyEvent downEvent(PR_TRUE, NS_KEY_DOWN, this);
@ -2210,9 +2214,6 @@ nsWindow::OnKeyPressEvent(GtkWidget *aWidget, GdkEventKey *aEvent)
|| aEvent->keyval == GDK_Alt_R
|| aEvent->keyval == GDK_Meta_L
|| aEvent->keyval == GDK_Meta_R) {
// reset the key repeat flag so that the next keypress gets the
// key down event
mInKeyRepeat = PR_FALSE;
return TRUE;
}
nsKeyEvent event(PR_TRUE, NS_KEY_PRESS, this);
@ -2293,13 +2294,13 @@ nsWindow::OnKeyReleaseEvent(GtkWidget *aWidget, GdkEventKey *aEvent)
nsEventStatus status;
// unset the repeat flag
mInKeyRepeat = PR_FALSE;
// send the key event as a key up event
nsKeyEvent event(PR_TRUE, NS_KEY_UP, this);
InitKeyEvent(event, aEvent);
// unset the key down flag
ClearKeyDownFlag(event.keyCode);
DispatchEvent(&event, status);
// If the event was consumed, return.

View File

@ -375,7 +375,6 @@ private:
PRUint32 mContainerGotFocus : 1,
mContainerLostFocus : 1,
mContainerBlockFocus : 1,
mInKeyRepeat : 1,
mIsVisible : 1,
mRetryPointerGrab : 1,
mActivatePending : 1,
@ -442,6 +441,38 @@ private:
static guint DragMotionTimerCallback (gpointer aClosure);
static void DragLeaveTimerCallback (nsITimer *aTimer, void *aClosure);
/* Key Down event is DOM Virtual Key driven, needs 256 bits. */
PRUint32 mKeyDownFlags[8];
/* Helper methods for DOM Key Down event suppression. */
PRUint32* GetFlagWord32(PRUint32 aKeyCode, PRUint32* aMask) {
/* Mozilla DOM Virtual Key Code is from 0 to 224. */
NS_ASSERTION((aKeyCode <= 0xFF), "Invalid DOM Key Code");
aKeyCode &= 0xFF;
/* 32 = 2^5 = 0x20 */
*aMask = PRUint32(1) << (aKeyCode & 0x1F);
return &mKeyDownFlags[(aKeyCode >> 5)];
};
PRBool IsKeyDown(PRUint32 aKeyCode) {
PRUint32 mask;
PRUint32* flag = GetFlagWord32(aKeyCode, &mask);
return ((*flag) & mask) != 0;
};
void SetKeyDownFlag(PRUint32 aKeyCode) {
PRUint32 mask;
PRUint32* flag = GetFlagWord32(aKeyCode, &mask);
*flag |= mask;
};
void ClearKeyDownFlag(PRUint32 aKeyCode) {
PRUint32 mask;
PRUint32* flag = GetFlagWord32(aKeyCode, &mask);
*flag &= ~mask;
};
};
class nsChildWindow : public nsWindow {