319078 Handle smooth mousewheel (and two-finger touchpad) scrolling. r=josh sr=darin r,sr=roc
git-svn-id: svn://10.0.0.236/trunk@203254 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
parent
54fe7a55b2
commit
ddab7ffe6e
@ -172,7 +172,8 @@ enum {
|
||||
MOUSE_SCROLL_N_LINES,
|
||||
MOUSE_SCROLL_PAGE,
|
||||
MOUSE_SCROLL_HISTORY,
|
||||
MOUSE_SCROLL_TEXTSIZE
|
||||
MOUSE_SCROLL_TEXTSIZE,
|
||||
MOUSE_SCROLL_PIXELS
|
||||
};
|
||||
|
||||
// mask values for ui.key.chromeAccess and ui.key.contentAccess
|
||||
@ -1817,7 +1818,7 @@ nsEventStateManager::DoScrollText(nsPresContext* aPresContext,
|
||||
nsInputEvent* aEvent,
|
||||
PRInt32 aNumLines,
|
||||
PRBool aScrollHorizontal,
|
||||
PRBool aScrollPage)
|
||||
ScrollQuantity aScrollQuantity)
|
||||
{
|
||||
nsCOMPtr<nsIContent> targetContent = aTargetFrame->GetContent();
|
||||
if (!targetContent)
|
||||
@ -1838,7 +1839,7 @@ nsEventStateManager::DoScrollText(nsPresContext* aPresContext,
|
||||
nsCOMPtr<nsIDOMAbstractView> view;
|
||||
docView->GetDefaultView(getter_AddRefs(view));
|
||||
|
||||
if (aScrollPage) {
|
||||
if (aScrollQuantity == eScrollByPage) {
|
||||
if (aNumLines > 0) {
|
||||
aNumLines = nsIDOMNSUIEvent::SCROLL_PAGE_DOWN;
|
||||
} else {
|
||||
@ -1963,7 +1964,7 @@ nsEventStateManager::DoScrollText(nsPresContext* aPresContext,
|
||||
PRInt32 scrollX = 0;
|
||||
PRInt32 scrollY = aNumLines;
|
||||
|
||||
if (aScrollPage)
|
||||
if (aScrollQuantity == eScrollByPage)
|
||||
scrollY = (scrollY > 0) ? 1 : -1;
|
||||
|
||||
if (aScrollHorizontal) {
|
||||
@ -1971,8 +1972,10 @@ nsEventStateManager::DoScrollText(nsPresContext* aPresContext,
|
||||
scrollY = 0;
|
||||
}
|
||||
|
||||
if (aScrollPage)
|
||||
if (aScrollQuantity == eScrollByPage)
|
||||
scrollView->ScrollByPages(scrollX, scrollY);
|
||||
else if (aScrollQuantity == eScrollByPixel)
|
||||
scrollView->ScrollByPixels(scrollX, scrollY);
|
||||
else
|
||||
scrollView->ScrollByLines(scrollX, scrollY);
|
||||
|
||||
@ -1986,7 +1989,7 @@ nsEventStateManager::DoScrollText(nsPresContext* aPresContext,
|
||||
*getter_AddRefs(newPresContext));
|
||||
if (NS_SUCCEEDED(rv) && newFrame)
|
||||
return DoScrollText(newPresContext, newFrame, aEvent, aNumLines,
|
||||
aScrollHorizontal, aScrollPage);
|
||||
aScrollHorizontal, aScrollQuantity);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
@ -2219,6 +2222,8 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext,
|
||||
numLines = msEvent->delta;
|
||||
if (msEvent->scrollFlags & nsMouseScrollEvent::kIsFullPage)
|
||||
action = MOUSE_SCROLL_PAGE;
|
||||
else if (msEvent->scrollFlags & nsMouseScrollEvent::kIsPixels)
|
||||
action = MOUSE_SCROLL_PIXELS;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -2253,13 +2258,27 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext,
|
||||
|
||||
switch (action) {
|
||||
case MOUSE_SCROLL_N_LINES:
|
||||
{
|
||||
DoScrollText(presContext, aTargetFrame, msEvent, numLines,
|
||||
(msEvent->scrollFlags & nsMouseScrollEvent::kIsHorizontal),
|
||||
eScrollByLine);
|
||||
}
|
||||
break;
|
||||
|
||||
case MOUSE_SCROLL_PAGE:
|
||||
{
|
||||
DoScrollText(presContext, aTargetFrame, msEvent, numLines,
|
||||
(msEvent->scrollFlags & nsMouseScrollEvent::kIsHorizontal),
|
||||
(action == MOUSE_SCROLL_PAGE));
|
||||
eScrollByPage);
|
||||
}
|
||||
break;
|
||||
|
||||
case MOUSE_SCROLL_PIXELS:
|
||||
{
|
||||
DoScrollText(presContext, aTargetFrame, msEvent, numLines,
|
||||
(msEvent->scrollFlags & nsMouseScrollEvent::kIsHorizontal),
|
||||
eScrollByPixel);
|
||||
}
|
||||
break;
|
||||
|
||||
case MOUSE_SCROLL_HISTORY:
|
||||
|
||||
@ -245,12 +245,18 @@ protected:
|
||||
nsPresContext* aPresContext,
|
||||
nsIFrame* &targetOuterFrame,
|
||||
nsPresContext* &presCtxOuter);
|
||||
|
||||
typedef enum {
|
||||
eScrollByPixel,
|
||||
eScrollByLine,
|
||||
eScrollByPage
|
||||
} ScrollQuantity;
|
||||
nsresult DoScrollText(nsPresContext* aPresContext,
|
||||
nsIFrame* aTargetFrame,
|
||||
nsInputEvent* aEvent,
|
||||
PRInt32 aNumLines,
|
||||
PRBool aScrollHorizontal,
|
||||
PRBool aScrollPage);
|
||||
ScrollQuantity aScrollQuantity);
|
||||
void ForceViewUpdate(nsIView* aView);
|
||||
void DoScrollHistory(PRInt32 direction);
|
||||
void DoScrollTextsize(nsIFrame *aTargetFrame, PRInt32 adjustment);
|
||||
|
||||
@ -49,8 +49,8 @@ struct nsSize;
|
||||
|
||||
// IID for the nsIScrollableView interface
|
||||
#define NS_ISCROLLABLEVIEW_IID \
|
||||
{ 0x36083bcf, 0x61d7, 0x4c24, \
|
||||
{ 0xa6, 0xd4, 0x2f, 0x05, 0xba, 0x2c, 0x1b, 0x51 } }
|
||||
{ 0x1fcd151c, 0x5e26, 0x4c9d, \
|
||||
{ 0xa5, 0x2c, 0x87, 0x43, 0x7d, 0x7b, 0x1c, 0xe8 } }
|
||||
|
||||
/**
|
||||
* A scrolling view allows an arbitrary view that you supply to be scrolled
|
||||
@ -175,6 +175,16 @@ public:
|
||||
*/
|
||||
NS_IMETHOD ScrollByWhole(PRBool aTop) = 0;
|
||||
|
||||
/**
|
||||
* Scroll the view left or right by aNumLinesX pixels. Positive values move
|
||||
* right. Scroll the view up or down by aNumLinesY pixels. Positive values
|
||||
* move down. Prevents scrolling off the end of the view.
|
||||
* @param aNumLinesX number of lines to scroll the view horizontally
|
||||
* @param aNumLinesY number of lines to scroll the view vertically
|
||||
* @return error status
|
||||
*/
|
||||
NS_IMETHOD ScrollByPixels(PRInt32 aNumPixelsX, PRInt32 aNumPixelsY) = 0;
|
||||
|
||||
/**
|
||||
* Check the view can scroll from current offset.
|
||||
* @param aHorizontal If checking to Left or to Right, true. Otherwise, false.
|
||||
|
||||
@ -468,6 +468,19 @@ NS_IMETHODIMP nsScrollPortView::ScrollByWhole(PRBool aTop)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsScrollPortView::ScrollByPixels(PRInt32 aNumPixelsX,
|
||||
PRInt32 aNumPixelsY)
|
||||
{
|
||||
nsCOMPtr<nsIDeviceContext> dev;
|
||||
mViewManager->GetDeviceContext(*getter_AddRefs(dev));
|
||||
float p2t = dev->DevUnitsToAppUnits();
|
||||
|
||||
nscoord dx = NSIntPixelsToTwips(aNumPixelsX, p2t);
|
||||
nscoord dy = NSIntPixelsToTwips(aNumPixelsY, p2t);
|
||||
|
||||
return ScrollTo(mOffsetX + dx, mOffsetY + dy, 0);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsScrollPortView::CanScroll(PRBool aHorizontal,
|
||||
PRBool aForward,
|
||||
PRBool &aResult)
|
||||
|
||||
@ -77,6 +77,7 @@ public:
|
||||
NS_IMETHOD GetPageScrollDistances(nsSize *aDistances);
|
||||
NS_IMETHOD ScrollByPages(PRInt32 aNumPagesX, PRInt32 aNumPagesY);
|
||||
NS_IMETHOD ScrollByWhole(PRBool aTop);
|
||||
NS_IMETHOD ScrollByPixels(PRInt32 aNumPixelsX, PRInt32 aNumPixelsY);
|
||||
NS_IMETHOD CanScroll(PRBool aHorizontal, PRBool aForward, PRBool &aResult);
|
||||
|
||||
NS_IMETHOD_(nsIView*) View();
|
||||
|
||||
@ -748,7 +748,8 @@ public:
|
||||
enum nsMouseScrollFlags {
|
||||
kIsFullPage = 1 << 0,
|
||||
kIsVertical = 1 << 1,
|
||||
kIsHorizontal = 1 << 2
|
||||
kIsHorizontal = 1 << 2,
|
||||
kIsPixels = 1 << 3
|
||||
};
|
||||
|
||||
nsMouseScrollEvent(PRBool isTrusted, PRUint32 msg, nsIWidget *w)
|
||||
|
||||
@ -1269,9 +1269,27 @@ PRBool nsMacEventHandler::ResizeEvent ( WindowRef inWindow )
|
||||
// Called from a mouseWheel carbon event, tell Gecko to scroll.
|
||||
//
|
||||
PRBool
|
||||
nsMacEventHandler::Scroll(EventMouseWheelAxis inAxis, PRInt32 inDelta,
|
||||
const Point& inMouseLoc, nsWindow* inWindow,
|
||||
PRUint32 inModifiers) {
|
||||
nsMacEventHandler::Scroll(PRInt32 aDeltaY, PRInt32 aDeltaX,
|
||||
PRBool aIsPixels, const Point& aMouseLoc,
|
||||
nsWindow* aWindow, PRUint32 aModifiers) {
|
||||
PRBool resY = ScrollAxis(nsMouseScrollEvent::kIsVertical, aDeltaY,
|
||||
aIsPixels, aMouseLoc, aWindow, aModifiers);
|
||||
PRBool resX = ScrollAxis(nsMouseScrollEvent::kIsHorizontal, aDeltaX,
|
||||
aIsPixels, aMouseLoc, aWindow, aModifiers);
|
||||
|
||||
return resY || resX;
|
||||
} // Scroll
|
||||
|
||||
|
||||
//
|
||||
// ScrollAxis
|
||||
//
|
||||
PRBool
|
||||
nsMacEventHandler::ScrollAxis(nsMouseScrollEvent::nsMouseScrollFlags aAxis,
|
||||
PRInt32 aDelta, PRBool aIsPixels,
|
||||
const Point& aMouseLoc, nsWindow* aWindow,
|
||||
PRUint32 aModifiers)
|
||||
{
|
||||
// Only scroll active windows. Treat popups as active.
|
||||
WindowRef windowRef = NS_STATIC_CAST(WindowRef,
|
||||
mTopLevelWidget->GetNativeData(NS_NATIVE_DISPLAY));
|
||||
@ -1281,16 +1299,21 @@ nsMacEventHandler::Scroll(EventMouseWheelAxis inAxis, PRInt32 inDelta,
|
||||
return PR_FALSE;
|
||||
|
||||
// Figure out which widget should be scrolled by traversing the widget
|
||||
// hierarchy beginning at the root nsWindow. inMouseLoc should be
|
||||
// hierarchy beginning at the root nsWindow. aMouseLoc should be
|
||||
// relative to the origin of this nsWindow. If the scroll event came
|
||||
// from an nsMacWindow, then inWindow should refer to that nsMacWindow.
|
||||
nsIWidget* widgetToScroll = inWindow->FindWidgetHit(inMouseLoc);
|
||||
// from an nsMacWindow, then aWindow should refer to that nsMacWindow.
|
||||
nsIWidget* widgetToScroll = aWindow->FindWidgetHit(aMouseLoc);
|
||||
|
||||
// Not all scroll events for the window are over a widget. Consider
|
||||
// the title bar.
|
||||
if (!widgetToScroll)
|
||||
return PR_FALSE;
|
||||
|
||||
if (aDelta == 0) {
|
||||
// Don't need to do anything, but eat the event anyway.
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
if (gRollupListener && gRollupWidget) {
|
||||
// Roll up the rollup widget if the scroll isn't targeted at it
|
||||
// (or one of its children) and the listener was told to do so.
|
||||
@ -1316,22 +1339,23 @@ nsMacEventHandler::Scroll(EventMouseWheelAxis inAxis, PRInt32 inDelta,
|
||||
|
||||
// The direction we get from the carbon event is opposite from the way
|
||||
// mozilla looks at it. Reverse the direction.
|
||||
scrollEvent.delta = -inDelta;
|
||||
scrollEvent.delta = -aDelta;
|
||||
|
||||
// If the scroll event comes from a mouse that only has a scroll wheel for
|
||||
// the vertical axis, and the shift key is held down, the system presents
|
||||
// it as a horizontal scroll and doesn't clear the shift key bit from
|
||||
// inModifiers. The Mac is supposed to scroll horizontally in such a case.
|
||||
// aModifiers. The Mac is supposed to scroll horizontally in such a case.
|
||||
//
|
||||
// If the scroll event comes from a mouse that can scroll both axes, the
|
||||
// system doesn't apply any of this shift-key fixery.
|
||||
scrollEvent.scrollFlags =
|
||||
(inAxis == kEventMouseWheelAxisX) ? nsMouseScrollEvent::kIsHorizontal :
|
||||
nsMouseScrollEvent::kIsVertical;
|
||||
scrollEvent.scrollFlags = aAxis;
|
||||
|
||||
if (aIsPixels)
|
||||
scrollEvent.scrollFlags |= nsMouseScrollEvent::kIsPixels;
|
||||
|
||||
// convert window-relative (local) mouse coordinates to widget-relative
|
||||
// coords for Gecko.
|
||||
nsPoint mouseLocRelativeToWidget(inMouseLoc.h, inMouseLoc.v);
|
||||
nsPoint mouseLocRelativeToWidget(aMouseLoc.h, aMouseLoc.v);
|
||||
nsRect bounds;
|
||||
widgetToScroll->GetBounds(bounds);
|
||||
nsPoint widgetOrigin(bounds.x, bounds.y);
|
||||
@ -1343,16 +1367,16 @@ nsMacEventHandler::Scroll(EventMouseWheelAxis inAxis, PRInt32 inDelta,
|
||||
scrollEvent.time = PR_IntervalNow();
|
||||
|
||||
// Translate OS event modifiers into Gecko event modifiers
|
||||
scrollEvent.isShift = ((inModifiers & shiftKey) != 0);
|
||||
scrollEvent.isControl = ((inModifiers & controlKey) != 0);
|
||||
scrollEvent.isAlt = ((inModifiers & optionKey) != 0);
|
||||
scrollEvent.isMeta = ((inModifiers & cmdKey) != 0);
|
||||
scrollEvent.isShift = ((aModifiers & shiftKey) != 0);
|
||||
scrollEvent.isControl = ((aModifiers & controlKey) != 0);
|
||||
scrollEvent.isAlt = ((aModifiers & optionKey) != 0);
|
||||
scrollEvent.isMeta = ((aModifiers & cmdKey) != 0);
|
||||
|
||||
nsEventStatus status;
|
||||
widgetToScroll->DispatchEvent(&scrollEvent, status);
|
||||
|
||||
return nsWindow::ConvertStatus(status);
|
||||
} // Scroll
|
||||
} // ScrollAxis
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
@ -132,7 +132,10 @@ public:
|
||||
// not have to rely on hacking up EventRecords to fake it.
|
||||
//
|
||||
virtual PRBool ResizeEvent ( WindowRef inWindow ) ;
|
||||
virtual PRBool Scroll ( EventMouseWheelAxis inAxis, PRInt32 inDelta, const Point& inMouseLoc, nsWindow* inWindow, PRUint32 inModifiers );
|
||||
virtual PRBool Scroll (PRInt32 aDeltaY, PRInt32 aDeltaX,
|
||||
PRBool aIsPixels,
|
||||
const Point& aMouseLoc,
|
||||
nsWindow* aWindow, PRUint32 aModifiers);
|
||||
|
||||
virtual void HandleActivateEvent(EventRef aEvent);
|
||||
inline nsMacEventDispatchHandler* GetEventDispatchHandler() { return mEventDispatchHandler; }
|
||||
@ -157,6 +160,11 @@ protected:
|
||||
virtual nsresult HandleStartComposition(void);
|
||||
virtual nsresult HandleEndComposition(void);
|
||||
virtual nsresult HandleTextEvent(PRUint32 textRangeCount, nsTextRangeArray textRangeArray);
|
||||
virtual PRBool ScrollAxis (nsMouseScrollEvent::nsMouseScrollFlags aAxis,
|
||||
PRInt32 aDelta, PRBool aIsPixels,
|
||||
const Point& aMouseLoc,
|
||||
nsWindow* aWindow,
|
||||
PRUint32 aModifiers);
|
||||
|
||||
protected:
|
||||
nsMacEventDispatchHandler* mEventDispatchHandler;
|
||||
|
||||
@ -66,6 +66,21 @@ typedef struct TransitionWindowOptions {
|
||||
WindowRef window;
|
||||
void* userData;
|
||||
} TransitionWindowOptions;
|
||||
|
||||
#define kEventParamWindowPartCode 'wpar'
|
||||
#define typeWindowPartCode 'wpar'
|
||||
#endif
|
||||
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4
|
||||
// http://developer.apple.com/qa/qa2005/qa1453.html
|
||||
// These are not defined in early versions of the 10.4/10.4u SDK (as of Xcode
|
||||
// 2.2), but they may appear in later releases. Since we can't check which
|
||||
// version of the SDK is in use beyond knowing that it's "10.4", define these
|
||||
// on 10.4. #defines should override what's present in the SDK when defined,
|
||||
// because the system headers use enums.
|
||||
#define kEventParamMouseWheelSmoothVerticalDelta 'saxy'
|
||||
#define kEventParamMouseWheelSmoothHorizontalDelta 'saxx'
|
||||
#define kEventMouseScroll 11
|
||||
#endif
|
||||
|
||||
typedef OSStatus (*TransitionWindowWithOptions_type) (WindowRef,
|
||||
@ -228,6 +243,7 @@ nsMacWindow::nsMacWindow() : Inherited()
|
||||
, mResizeIsFromUs(PR_FALSE)
|
||||
, mShown(PR_FALSE)
|
||||
, mSheetNeedsShow(PR_FALSE)
|
||||
, mInPixelMouseScroll(PR_FALSE)
|
||||
, mMacEventHandler(nsnull)
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3
|
||||
, mNeedsResize(PR_FALSE)
|
||||
@ -600,6 +616,7 @@ nsresult nsMacWindow::StandardCreate(nsIWidget *aParent,
|
||||
mWindowType != eWindowType_java) {
|
||||
const EventTypeSpec kScrollEventList[] = {
|
||||
{ kEventClassMouse, kEventMouseWheelMoved },
|
||||
{ kEventClassMouse, kEventMouseScroll },
|
||||
};
|
||||
|
||||
static EventHandlerUPP sScrollEventHandlerUPP;
|
||||
@ -693,37 +710,121 @@ nsresult nsMacWindow::StandardCreate(nsIWidget *aParent,
|
||||
|
||||
|
||||
pascal OSStatus
|
||||
nsMacWindow::ScrollEventHandler ( EventHandlerCallRef inHandlerChain, EventRef inEvent, void* userData )
|
||||
nsMacWindow::ScrollEventHandler(EventHandlerCallRef aHandlerCallRef,
|
||||
EventRef aEvent,
|
||||
void* aUserData)
|
||||
{
|
||||
OSStatus retVal = eventNotHandledErr;
|
||||
EventMouseWheelAxis axis = kEventMouseWheelAxisY;
|
||||
SInt32 delta = 0;
|
||||
|
||||
Point mouseLoc;
|
||||
UInt32 modifiers = 0;
|
||||
if (::GetEventParameter(inEvent, kEventParamMouseWheelAxis,
|
||||
typeMouseWheelAxis, NULL,
|
||||
sizeof(EventMouseWheelAxis), NULL, &axis) == noErr &&
|
||||
::GetEventParameter(inEvent, kEventParamMouseWheelDelta,
|
||||
typeLongInteger, NULL,
|
||||
sizeof(SInt32), NULL, &delta) == noErr &&
|
||||
::GetEventParameter(inEvent, kEventParamMouseLocation,
|
||||
if (::GetEventParameter(aEvent, kEventParamMouseLocation,
|
||||
typeQDPoint, NULL,
|
||||
sizeof(Point), NULL, &mouseLoc) == noErr &&
|
||||
::GetEventParameter(inEvent, kEventParamKeyModifiers,
|
||||
sizeof(Point), NULL, &mouseLoc) != noErr ||
|
||||
::GetEventParameter(aEvent, kEventParamKeyModifiers,
|
||||
typeUInt32, NULL,
|
||||
sizeof(UInt32), NULL, &modifiers) == noErr) {
|
||||
nsMacWindow* self = NS_REINTERPRET_CAST(nsMacWindow*, userData);
|
||||
NS_ENSURE_TRUE(self->mMacEventHandler.get(), eventNotHandledErr);
|
||||
if (self) {
|
||||
// Convert mouse to local coordinates since that's how the event handler
|
||||
// wants them
|
||||
StPortSetter portSetter(self->mWindowPtr);
|
||||
StOriginSetter originSetter(self->mWindowPtr);
|
||||
::GlobalToLocal(&mouseLoc);
|
||||
self->mMacEventHandler->Scroll(axis, delta, mouseLoc, self, modifiers);
|
||||
retVal = noErr;
|
||||
sizeof(UInt32), NULL, &modifiers) != noErr) {
|
||||
// Need both of these params regardless of event kind.
|
||||
return retVal;
|
||||
}
|
||||
|
||||
SInt32 deltaY = 0, deltaX = 0;
|
||||
PRBool isPixels = PR_FALSE;
|
||||
|
||||
nsMacWindow* self = NS_REINTERPRET_CAST(nsMacWindow*, aUserData);
|
||||
|
||||
EventKind kind = ::GetEventKind(aEvent);
|
||||
|
||||
switch (kind) {
|
||||
case kEventMouseWheelMoved: {
|
||||
// Notchy scrolling hardware, like conventional wheel mice, scroll
|
||||
// a line at a time.
|
||||
|
||||
if (self->mInPixelMouseScroll) {
|
||||
// A smooth scroll was already done by pixels. Don't scroll again by
|
||||
// lines.
|
||||
return noErr;
|
||||
}
|
||||
|
||||
EventMouseWheelAxis axis = kEventMouseWheelAxisY;
|
||||
SInt32 delta = 0;
|
||||
if (::GetEventParameter(aEvent, kEventParamMouseWheelAxis,
|
||||
typeMouseWheelAxis, NULL,
|
||||
sizeof(EventMouseWheelAxis), NULL,
|
||||
&axis) != noErr ||
|
||||
::GetEventParameter(aEvent, kEventParamMouseWheelDelta,
|
||||
typeLongInteger, NULL,
|
||||
sizeof(SInt32), NULL, &delta) != noErr) {
|
||||
// Need both of these params.
|
||||
return retVal;
|
||||
}
|
||||
|
||||
if (axis == kEventMouseWheelAxisY)
|
||||
deltaY = delta;
|
||||
else
|
||||
deltaX = delta;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case kEventMouseScroll: {
|
||||
// On Tiger or later, smooth scrolling hardware, like Apple touchpads
|
||||
// and Mighty Mice, scroll a pixel at a time. Handling this event means
|
||||
// that the system won't send a kEventMouseWheelMoved event.
|
||||
isPixels = PR_TRUE;
|
||||
OSErr errY, errX;
|
||||
errY = ::GetEventParameter(aEvent,
|
||||
kEventParamMouseWheelSmoothVerticalDelta,
|
||||
typeSInt32, NULL,
|
||||
sizeof(SInt32), NULL, &deltaY);
|
||||
errX = ::GetEventParameter(aEvent,
|
||||
kEventParamMouseWheelSmoothHorizontalDelta,
|
||||
typeSInt32, NULL,
|
||||
sizeof(SInt32), NULL, &deltaX);
|
||||
if (errY != noErr && errX != noErr) {
|
||||
// Need at least one of these params.
|
||||
return retVal;
|
||||
}
|
||||
if ((errY != noErr && errY != eventParameterNotFoundErr) ||
|
||||
(errX != noErr && errX != eventParameterNotFoundErr)) {
|
||||
// eventParameterNotFoundErr is the only permissible "error",
|
||||
// in that case, leave the delta set to 0.
|
||||
return retVal;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default: {
|
||||
// What?
|
||||
return retVal;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
// Convert mouse to local coordinates since that's how the event handler
|
||||
// wants them
|
||||
StPortSetter portSetter(self->mWindowPtr);
|
||||
StOriginSetter originSetter(self->mWindowPtr);
|
||||
::GlobalToLocal(&mouseLoc);
|
||||
self->mMacEventHandler->Scroll(deltaY, deltaX, isPixels, mouseLoc,
|
||||
self, modifiers);
|
||||
retVal = noErr;
|
||||
}
|
||||
|
||||
if (kind == kEventMouseScroll && (deltaX != 0 || deltaY != 0)) {
|
||||
// Plug-ins might depend on kEventMouseWheelMoved, so if the event was
|
||||
// kEventMouseScroll, call to the next handler to give the system the
|
||||
// chance to turn one event into the other. See
|
||||
// http://developer.apple.com/qa/qa2005/qa1453.html . When the
|
||||
// new event reaches this handler, mInPixelMouseScroll will prevent
|
||||
// double-scrolling.
|
||||
PRBool lastInPixelMouseScroll = self->mInPixelMouseScroll;
|
||||
self->mInPixelMouseScroll = PR_TRUE;
|
||||
::CallNextEventHandler(aHandlerCallRef, aEvent);
|
||||
self->mInPixelMouseScroll = lastInPixelMouseScroll;
|
||||
}
|
||||
|
||||
return retVal;
|
||||
} // ScrollEventHandler
|
||||
|
||||
@ -1930,8 +2031,9 @@ nsMacWindow::Scroll ( PRBool aVertical, PRInt16 aNumLines, PRInt16 aMouseLocalX,
|
||||
*_retval = PR_FALSE;
|
||||
NS_ENSURE_TRUE(mMacEventHandler.get(), NS_ERROR_FAILURE);
|
||||
Point localPoint = {aMouseLocalY, aMouseLocalX};
|
||||
*_retval = mMacEventHandler->Scroll(aVertical ? kEventMouseWheelAxisY : kEventMouseWheelAxisX,
|
||||
aNumLines, localPoint, this, 0);
|
||||
*_retval = mMacEventHandler->Scroll(aVertical ? aNumLines : 0,
|
||||
aVertical ? 0 : aNumLines,
|
||||
PR_FALSE, localPoint, this, 0);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
@ -146,8 +146,9 @@ protected:
|
||||
|
||||
pascal static OSStatus WindowEventHandler ( EventHandlerCallRef inHandlerChain,
|
||||
EventRef inEvent, void* userData ) ;
|
||||
pascal static OSStatus ScrollEventHandler ( EventHandlerCallRef inHandlerChain,
|
||||
EventRef inEvent, void* userData ) ;
|
||||
pascal static OSStatus ScrollEventHandler(EventHandlerCallRef aHandlerCallRef,
|
||||
EventRef aEvent,
|
||||
void* aUserData);
|
||||
pascal static OSStatus KeyEventHandler(EventHandlerCallRef aHandlerCallRef,
|
||||
EventRef aEvent,
|
||||
void* aUserData);
|
||||
@ -162,6 +163,7 @@ protected:
|
||||
PRPackedBool mResizeIsFromUs; // we originated the resize, prevent infinite recursion
|
||||
PRPackedBool mShown; // whether the window was actually shown on screen
|
||||
PRPackedBool mSheetNeedsShow; // a sheet that wants to be displayed but isn't because a sibling sheet is open
|
||||
PRPackedBool mInPixelMouseScroll;
|
||||
Point mBoundsOffset; // offset from window structure to content
|
||||
auto_ptr<nsMacEventHandler> mMacEventHandler;
|
||||
nsIWidget *mOffsetParent;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user