зеркало из https://github.com/mozilla/pjs.git
319078 Handle smooth mousewheel (and two-finger touchpad) scrolling. r=josh sr=darin r,sr=roc
This commit is contained in:
Родитель
f16c2abd26
Коммит
a844b938c3
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,181 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
#ifndef MacWindow_h__
|
||||
#define MacWindow_h__
|
||||
|
||||
#include <memory> // for auto_ptr
|
||||
#include <Carbon/Carbon.h>
|
||||
|
||||
using std::auto_ptr;
|
||||
|
||||
#include "nsRegionPool.h"
|
||||
#include "nsWindow.h"
|
||||
#include "nsMacEventHandler.h"
|
||||
#include "nsIEventSink.h"
|
||||
#include "nsIMacTextInputEventSink.h"
|
||||
#include "nsPIWidgetMac.h"
|
||||
#include "nsPIEventSinkStandalone.h"
|
||||
|
||||
class nsMacEventHandler;
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
//
|
||||
// nsMacWindow
|
||||
//
|
||||
//-------------------------------------------------------------------------
|
||||
// MacOS native window
|
||||
|
||||
class nsMacWindow : public nsChildWindow, public nsIEventSink, public nsPIWidgetMac,
|
||||
public nsPIEventSinkStandalone, public nsIMacTextInputEventSink
|
||||
{
|
||||
private:
|
||||
typedef nsChildWindow Inherited;
|
||||
|
||||
public:
|
||||
nsMacWindow();
|
||||
virtual ~nsMacWindow();
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIEVENTSINK
|
||||
NS_DECL_NSPIWIDGETMAC
|
||||
NS_DECL_NSPIEVENTSINKSTANDALONE
|
||||
NS_DECL_NSIMACTEXTINPUTEVENTSINK
|
||||
|
||||
/*
|
||||
// nsIWidget interface
|
||||
NS_IMETHOD Create(nsIWidget *aParent,
|
||||
const nsRect &aRect,
|
||||
EVENT_CALLBACK aHandleEventFunction,
|
||||
nsIDeviceContext *aContext,
|
||||
nsIAppShell *aAppShell = nsnull,
|
||||
nsIToolkit *aToolkit = nsnull,
|
||||
nsWidgetInitData *aInitData = nsnull);
|
||||
*/
|
||||
NS_IMETHOD Create(nsNativeWidget aParent,
|
||||
const nsRect &aRect,
|
||||
EVENT_CALLBACK aHandleEventFunction,
|
||||
nsIDeviceContext *aContext,
|
||||
nsIAppShell *aAppShell = nsnull,
|
||||
nsIToolkit *aToolkit = nsnull,
|
||||
nsWidgetInitData *aInitData = nsnull);
|
||||
|
||||
// Utility method for implementing both Create(nsIWidget ...) and
|
||||
// Create(nsNativeWidget...)
|
||||
|
||||
virtual nsresult StandardCreate(nsIWidget *aParent,
|
||||
const nsRect &aRect,
|
||||
EVENT_CALLBACK aHandleEventFunction,
|
||||
nsIDeviceContext *aContext,
|
||||
nsIAppShell *aAppShell,
|
||||
nsIToolkit *aToolkit,
|
||||
nsWidgetInitData *aInitData,
|
||||
nsNativeWidget aNativeParent = nsnull);
|
||||
|
||||
NS_IMETHOD Show(PRBool aState);
|
||||
NS_IMETHOD ConstrainPosition(PRBool aAllowSlop,
|
||||
PRInt32 *aX, PRInt32 *aY);
|
||||
NS_IMETHOD Move(PRInt32 aX, PRInt32 aY);
|
||||
NS_IMETHOD PlaceBehind(nsTopLevelWidgetZPlacement aPlacement,
|
||||
nsIWidget *aWidget, PRBool aActivate);
|
||||
NS_IMETHOD SetSizeMode(PRInt32 aMode);
|
||||
|
||||
NS_IMETHOD Resize(PRInt32 aWidth,PRInt32 aHeight, PRBool aRepaint);
|
||||
virtual nsresult Resize(PRInt32 aWidth,PRInt32 aHeight, PRBool aRepaint, PRBool aFromUI);
|
||||
NS_IMETHOD GetScreenBounds(nsRect &aRect);
|
||||
virtual PRBool OnPaint(nsPaintEvent &event);
|
||||
|
||||
NS_IMETHOD SetTitle(const nsAString& aTitle);
|
||||
|
||||
void UserStateForResize();
|
||||
|
||||
// nsIKBStateControl interface
|
||||
NS_IMETHOD ResetInputState();
|
||||
|
||||
void MoveToGlobalPoint(PRInt32 aX, PRInt32 aY);
|
||||
|
||||
void IsActive(PRBool* aActive);
|
||||
void SetIsActive(PRBool aActive);
|
||||
WindowPtr GetWindowTop(WindowPtr baseWindowRef);
|
||||
void UpdateWindowMenubar(WindowPtr parentWindow, PRBool enableFlag);
|
||||
|
||||
NS_IMETHOD Update();
|
||||
|
||||
protected:
|
||||
|
||||
pascal static OSErr DragTrackingHandler ( DragTrackingMessage theMessage, WindowPtr theWindow,
|
||||
void *handlerRefCon, DragReference theDrag );
|
||||
pascal static OSErr DragReceiveHandler (WindowPtr theWindow,
|
||||
void *handlerRefCon, DragReference theDragRef) ;
|
||||
DragTrackingHandlerUPP mDragTrackingHandlerUPP;
|
||||
DragReceiveHandlerUPP mDragReceiveHandlerUPP;
|
||||
|
||||
|
||||
pascal static OSStatus WindowEventHandler ( EventHandlerCallRef inHandlerChain,
|
||||
EventRef inEvent, void* userData ) ;
|
||||
pascal static OSStatus ScrollEventHandler ( EventHandlerCallRef inHandlerChain,
|
||||
EventRef inEvent, void* userData ) ;
|
||||
pascal static OSStatus KeyEventHandler(EventHandlerCallRef aHandlerCallRef,
|
||||
EventRef aEvent,
|
||||
void* aUserData);
|
||||
nsresult GetDesktopRect(Rect* desktopRect);
|
||||
|
||||
PRPackedBool mWindowMadeHere; // true if we created the window
|
||||
PRPackedBool mIsSheet; // true if the window is a sheet (Mac OS X)
|
||||
PRPackedBool mAcceptsActivation;
|
||||
PRPackedBool mIsActive;
|
||||
PRPackedBool mZoomOnShow;
|
||||
PRPackedBool mZooming;
|
||||
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
|
||||
Point mBoundsOffset; // offset from window structure to content
|
||||
auto_ptr<nsMacEventHandler> mMacEventHandler;
|
||||
nsIWidget *mOffsetParent;
|
||||
nsCOMPtr<nsIWidget> mDeathGripDuringTransition;
|
||||
|
||||
#if MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_3
|
||||
PRPackedBool mNeedsResize;
|
||||
struct {
|
||||
PRInt32 width;
|
||||
PRInt32 height;
|
||||
PRPackedBool repaint;
|
||||
PRPackedBool fromUI;
|
||||
} mResizeTo;
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // MacWindow_h__
|
Загрузка…
Ссылка в новой задаче