Bug 677279 - Send momentum scroll events to the location of the last non-momentum scroll event. r=smichaud

This commit is contained in:
Markus Stange 2011-08-18 00:30:52 +02:00
parent a84c59346f
commit 4f4c30310a
4 changed files with 30 additions and 11 deletions

View File

@ -357,6 +357,7 @@ class ChildViewMouseTracker {
public:
static void MouseMoved(NSEvent* aEvent);
static void MouseScrolled(NSEvent* aEvent);
static void OnDestroyView(ChildView* aView);
static void OnDestroyWindow(NSWindow* aWindow);
static BOOL WindowAcceptsEvent(NSWindow* aWindow, NSEvent* aEvent,
@ -370,6 +371,7 @@ public:
static ChildView* sLastMouseEventView;
static NSEvent* sLastMouseMoveEvent;
static NSWindow* sWindowUnderMouse;
static NSPoint sLastScrollEventScreenLocation;
};
//-------------------------------------------------------------------------

View File

@ -128,6 +128,7 @@ extern nsISupportsArray *gDraggedTransferables;
ChildView* ChildViewMouseTracker::sLastMouseEventView = nil;
NSEvent* ChildViewMouseTracker::sLastMouseMoveEvent = nil;
NSWindow* ChildViewMouseTracker::sWindowUnderMouse = nil;
NSPoint ChildViewMouseTracker::sLastScrollEventScreenLocation = NSZeroPoint;
#ifdef INVALIDATE_DEBUGGING
static void blinkRect(Rect* r);
@ -3691,8 +3692,7 @@ NSEvent* gLastDragMouseDownEvent = nil;
// No sense in firing off a Gecko event.
return;
BOOL isMomentumScroll = [theEvent respondsToSelector:@selector(_scrollPhase)] &&
[theEvent _scrollPhase] != 0;
BOOL isMomentumScroll = nsCocoaUtils::IsMomentumScrollEvent(theEvent);
if (scrollDelta != 0) {
// Send the line scroll event.
@ -3814,14 +3814,11 @@ NSEvent* gLastDragMouseDownEvent = nil;
-(void)scrollWheel:(NSEvent*)theEvent
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;
nsAutoRetainCocoaObject kungFuDeathGrip(self);
if ([self maybeRollup:theEvent])
return;
ChildViewMouseTracker::MouseScrolled(theEvent);
if (!mGeckoChild)
if ([self maybeRollup:theEvent])
return;
// It's possible for a single NSScrollWheel event to carry both useful
@ -3829,11 +3826,7 @@ NSEvent* gLastDragMouseDownEvent = nil;
// NSMouseScrollEvent can only carry one axis at a time, so the system
// event will be split into two Gecko events if necessary.
[self scrollWheel:theEvent forAxis:nsMouseScrollEvent::kIsVertical];
if (!mGeckoChild)
return;
[self scrollWheel:theEvent forAxis:nsMouseScrollEvent::kIsHorizontal];
NS_OBJC_END_TRY_ABORT_BLOCK;
}
-(NSMenu*)menuForEvent:(NSEvent*)theEvent
@ -4967,6 +4960,15 @@ ChildViewMouseTracker::MouseMoved(NSEvent* aEvent)
}
}
void
ChildViewMouseTracker::MouseScrolled(NSEvent* aEvent)
{
if (!nsCocoaUtils::IsMomentumScrollEvent(aEvent)) {
// Store the position so we can pin future momentum scroll events.
sLastScrollEventScreenLocation = nsCocoaUtils::ScreenLocationForEvent(aEvent);
}
}
ChildView*
ChildViewMouseTracker::ViewForEvent(NSEvent* aEvent)
{

View File

@ -141,6 +141,8 @@ class nsCocoaUtils
// the event was originally targeted at is still alive!
static NSPoint EventLocationForWindow(NSEvent* anEvent, NSWindow* aWindow);
static BOOL IsMomentumScrollEvent(NSEvent* aEvent);
// Hides the Menu bar and the Dock. Multiple hide/show requests can be nested.
static void HideOSChromeOnScreen(PRBool aShouldHide, NSScreen* aScreen);

View File

@ -40,6 +40,7 @@
#include "gfxImageSurface.h"
#include "nsCocoaUtils.h"
#include "nsChildView.h"
#include "nsMenuBarX.h"
#include "nsCocoaWindow.h"
#include "nsCOMPtr.h"
@ -105,6 +106,11 @@ NSPoint nsCocoaUtils::ScreenLocationForEvent(NSEvent* anEvent)
if (!anEvent || [anEvent type] == NSMouseMoved)
return [NSEvent mouseLocation];
// Pin momentum scroll events to the location of the last user-controlled
// scroll event.
if (IsMomentumScrollEvent(anEvent))
return ChildViewMouseTracker::sLastScrollEventScreenLocation;
return [[anEvent window] convertBaseToScreen:[anEvent locationInWindow]];
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(NSMakePoint(0.0, 0.0));
@ -128,6 +134,13 @@ NSPoint nsCocoaUtils::EventLocationForWindow(NSEvent* anEvent, NSWindow* aWindow
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(NSMakePoint(0.0, 0.0));
}
BOOL nsCocoaUtils::IsMomentumScrollEvent(NSEvent* aEvent)
{
return [aEvent type] == NSScrollWheel &&
[aEvent respondsToSelector:@selector(_scrollPhase)] &&
[aEvent _scrollPhase] != 0;
}
void nsCocoaUtils::HideOSChromeOnScreen(PRBool aShouldHide, NSScreen* aScreen)
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK;