Avoid dropped control-key events by making LastModifierState global. b=463802 r=masayuki,josh sr=roc

This commit is contained in:
Steven Michaud 2008-12-16 10:50:19 -06:00
parent 461b256ed4
commit acf9b9c319
3 changed files with 29 additions and 8 deletions

View File

@ -62,6 +62,7 @@
// defined in nsChildView.mm
extern nsIRollupListener * gRollupListener;
extern nsIWidget * gRollupWidget;
extern PRUint32 gLastModifierState;
// defined in nsCocoaWindow.mm
extern PRInt32 gXULModalLevel;
@ -816,6 +817,10 @@ nsAppShell::AfterProcessNextEvent(nsIThreadInternal *aThread,
selector:@selector(applicationWillTerminate:)
name:NSApplicationWillTerminateNotification
object:NSApp];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(applicationDidBecomeActive:)
name:NSApplicationDidBecomeActiveNotification
object:NSApp];
[[NSDistributedNotificationCenter defaultCenter] addObserver:self
selector:@selector(beginMenuTracking:)
name:@"com.apple.HIToolbox.beginMenuTrackingNotification"
@ -850,6 +855,25 @@ nsAppShell::AfterProcessNextEvent(nsIThreadInternal *aThread,
NS_OBJC_END_TRY_ABORT_BLOCK;
}
// applicationDidBecomeActive
//
// Make sure gLastModifierState is updated when we become active (since we
// won't have received [ChildView flagsChanged:] messages while inactive).
- (void)applicationDidBecomeActive:(NSNotification*)aNotification
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
// [NSEvent modifierFlags] is valid on every kind of event, so we don't need
// to worry about getting an NSInternalInconsistencyException here.
NSEvent* currentEvent = [NSApp currentEvent];
if (currentEvent) {
gLastModifierState =
nsCocoaUtils::GetCocoaEventModifierFlags(currentEvent) & NSDeviceIndependentModifierFlagsMask;
}
NS_OBJC_END_TRY_ABORT_BLOCK;
}
// beginMenuTracking
//
// Roll up our context menu (if any) when some other app (or the OS) opens

View File

@ -174,8 +174,6 @@ enum {
// when handling |draggingUpdated:| messages.
nsIDragService* mDragService;
PRUint32 mLastModifierState;
// For use with plugins, so that we can support IME in them. We can't use
// Cocoa TSM documents (those created and managed by the NSTSMInputContext
// class) -- for some reason TSMProcessRawKeyEvent() doesn't work with them.

View File

@ -136,6 +136,8 @@ static void blinkRgn(RgnHandle rgn);
nsIRollupListener * gRollupListener = nsnull;
nsIWidget * gRollupWidget = nsnull;
PRUint32 gLastModifierState = 0;
@interface ChildView(Private)
@ -6021,10 +6023,7 @@ static BOOL keyUpAlreadySentKeyDown = NO;
// CapsLock state and other modifier states are different:
// CapsLock state does not revert when the CapsLock key goes up, as the
// modifier state does for other modifier keys on key up. Also,
// mLastModifierState is set only when this view is the first responder. We
// cannot trust mLastModifierState to accurately reflect the state of CapsLock
// since CapsLock maybe have been toggled when another window was active.
// modifier state does for other modifier keys on key up.
if ([theEvent keyCode] == kCapsLockKeyCode) {
// Fire key down event for caps lock.
[self fireKeyEventForFlagsChanged:theEvent keyDown:YES];
@ -6043,7 +6042,7 @@ static BOOL keyUpAlreadySentKeyDown = NO;
for (PRUint32 i = 0; i < kModifierCount; i++) {
PRUint32 modifierBit = kModifierMaskTable[i];
if ((modifiers & modifierBit) != (mLastModifierState & modifierBit)) {
if ((modifiers & modifierBit) != (gLastModifierState & modifierBit)) {
BOOL isKeyDown = (modifiers & modifierBit) != 0 ? YES : NO;
[self fireKeyEventForFlagsChanged:theEvent keyDown:isKeyDown];
@ -6058,7 +6057,7 @@ static BOOL keyUpAlreadySentKeyDown = NO;
}
}
mLastModifierState = modifiers;
gLastModifierState = modifiers;
}
// check if the hand scroll cursor needs to be set/unset