Bug 672175 part.10 Initialize mouse scroll events in MouseScrollHandler::LastEventInfo r=jimm

This commit is contained in:
Masayuki Nakano 2012-03-06 12:20:29 +09:00
Родитель d54e86dc51
Коммит 2e0cfb3f4c
4 изменённых файлов: 202 добавлений и 94 удалений

Просмотреть файл

@ -204,12 +204,9 @@ MouseScrollHandler::GetScrollTargetInfo(
nsMouseScrollEvent testEvent(true, NS_MOUSE_SCROLL, aWindow);
aWindow->InitEvent(testEvent);
testEvent.scrollFlags = aEventInfo.GetScrollFlags();
testEvent.isShift = aModifierKeyState.mIsShiftDown;
testEvent.isControl = aModifierKeyState.mIsControlDown;
testEvent.isMeta = false;
testEvent.isAlt = aModifierKeyState.mIsAltDown;
aModifierKeyState.InitInputEvent(testEvent);
testEvent.scrollFlags = aEventInfo.GetScrollFlags();
testEvent.delta = result.actualScrollAmount;
if ((aEventInfo.IsVertical() && aEventInfo.IsPositive()) ||
(!aEventInfo.IsVertical() && !aEventInfo.IsPositive())) {
@ -368,6 +365,145 @@ MouseScrollHandler::LastEventInfo::RecordEvent(const EventInfo& aEvent)
mTimeStamp = TimeStamp::Now();
}
/* static */
PRInt32
MouseScrollHandler::LastEventInfo::RoundDelta(double aDelta)
{
return (aDelta >= 0) ? (PRInt32)floor(aDelta) : (PRInt32)ceil(aDelta);
}
bool
MouseScrollHandler::LastEventInfo::InitMouseScrollEvent(
nsWindow* aWindow,
nsMouseScrollEvent& aMouseScrollEvent,
const ScrollTargetInfo& aScrollTargetInfo,
const nsModifierKeyState& aModKeyState)
{
NS_ABORT_IF_FALSE(aMouseScrollEvent.message == NS_MOUSE_SCROLL,
"aMouseScrollEvent must be NS_MOUSE_SCROLL");
// XXX Why don't we use lParam value? We should use lParam value because
// our internal message is always posted by original message handler.
// So, GetMessagePos() may return different cursor position.
aWindow->InitEvent(aMouseScrollEvent);
aModKeyState.InitInputEvent(aMouseScrollEvent);
// If we dispatch pixel scroll event after the line scroll event,
// we should set kHasPixels flag to the line scroll event.
aMouseScrollEvent.scrollFlags =
aScrollTargetInfo.dispatchPixelScrollEvent ?
nsMouseScrollEvent::kHasPixels : 0;
aMouseScrollEvent.scrollFlags |= GetScrollFlags();
// Our positive delta value means to bottom or right.
// But positive native delta value means to top or right.
// Use orienter for computing our delta value with native delta value.
PRInt32 orienter = mIsVertical ? -1 : 1;
// NOTE: Don't use aScrollTargetInfo.actualScrollAmount for computing the
// delta value of line/page scroll event. The value will be recomputed
// in ESM.
PRInt32 nativeDelta = mDelta + mRemainingDeltaForScroll;
if (IsPage()) {
aMouseScrollEvent.delta = nativeDelta * orienter / WHEEL_DELTA;
PRInt32 recomputedNativeDelta =
aMouseScrollEvent.delta * orienter / WHEEL_DELTA;
mRemainingDeltaForScroll = nativeDelta - recomputedNativeDelta;
} else {
double deltaPerUnit = (double)WHEEL_DELTA / GetScrollAmount();
aMouseScrollEvent.delta =
RoundDelta((double)nativeDelta * orienter / deltaPerUnit);
PRInt32 recomputedNativeDelta =
(PRInt32)(aMouseScrollEvent.delta * orienter * deltaPerUnit);
mRemainingDeltaForScroll = nativeDelta - recomputedNativeDelta;
}
PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
("MouseScroll::LastEventInfo::InitMouseScrollEvent: aWindow=%p, "
"aMouseScrollEvent { refPoint: { x: %d, y: %d }, delta: %d, "
"scrollFlags: 0x%04X, isShift: %s, isControl: %s, isAlt: %s, "
"isMeta: %s }, mRemainingDeltaForScroll: %d",
aWindow, aMouseScrollEvent.refPoint.x, aMouseScrollEvent.refPoint.y,
aMouseScrollEvent.delta, aMouseScrollEvent.scrollFlags,
GetBoolName(aMouseScrollEvent.isShift),
GetBoolName(aMouseScrollEvent.isControl),
GetBoolName(aMouseScrollEvent.isAlt),
GetBoolName(aMouseScrollEvent.isMeta), mRemainingDeltaForScroll));
return (aMouseScrollEvent.delta != 0);
}
bool
MouseScrollHandler::LastEventInfo::InitMousePixelScrollEvent(
nsWindow* aWindow,
nsMouseScrollEvent& aPixelScrollEvent,
const ScrollTargetInfo& aScrollTargetInfo,
const nsModifierKeyState& aModKeyState)
{
NS_ABORT_IF_FALSE(aPixelScrollEvent.message == NS_MOUSE_PIXEL_SCROLL,
"aPixelScrollEvent must be NS_MOUSE_PIXEL_SCROLL");
if (!aScrollTargetInfo.dispatchPixelScrollEvent) {
PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
("MouseScroll::LastEventInfo::InitMousePixelScrollEvent: aWindow=%p, "
"PixelScroll is disabled",
aWindow, mRemainingDeltaForPixel));
mRemainingDeltaForPixel = 0;
return false;
}
// XXX Why don't we use lParam value? We should use lParam value because
// our internal message is always posted by original message handler.
// So, GetMessagePos() may return different cursor position.
aWindow->InitEvent(aPixelScrollEvent);
aModKeyState.InitInputEvent(aPixelScrollEvent);
aPixelScrollEvent.scrollFlags = nsMouseScrollEvent::kAllowSmoothScroll;
aPixelScrollEvent.scrollFlags |= mIsVertical ?
nsMouseScrollEvent::kIsVertical : nsMouseScrollEvent::kIsHorizontal;
if (aScrollTargetInfo.actualScrollAction ==
nsQueryContentEvent::SCROLL_ACTION_PAGE) {
aPixelScrollEvent.scrollFlags |= nsMouseScrollEvent::kIsFullPage;
}
// Our positive delta value means to bottom or right.
// But positive native delta value means to top or right.
// Use orienter for computing our delta value with native delta value.
PRInt32 orienter = mIsVertical ? -1 : 1;
// However, pixel scroll event won't be recomputed the scroll amout and
// direction by ESM. Therefore, we need to set the computed amout and
// direction here.
if (aScrollTargetInfo.reversePixelScrollDirection) {
orienter *= -1;
}
PRInt32 nativeDelta = mDelta + mRemainingDeltaForPixel;
double deltaPerPixel = (double)WHEEL_DELTA /
aScrollTargetInfo.actualScrollAmount / aScrollTargetInfo.pixelsPerUnit;
aPixelScrollEvent.delta =
RoundDelta((double)nativeDelta * orienter / deltaPerPixel);
PRInt32 recomputedNativeDelta =
(PRInt32)(aPixelScrollEvent.delta * orienter * deltaPerPixel);
mRemainingDeltaForPixel = nativeDelta - recomputedNativeDelta;
PR_LOG(gMouseScrollLog, PR_LOG_ALWAYS,
("MouseScroll::LastEventInfo::InitMousePixelScrollEvent: aWindow=%p, "
"aPixelScrollEvent { refPoint: { x: %d, y: %d }, delta: %d, "
"scrollFlags: 0x%04X, isShift: %s, isControl: %s, isAlt: %s, "
"isMeta: %s }, mRemainingDeltaForScroll: %d",
aWindow, aPixelScrollEvent.refPoint.x, aPixelScrollEvent.refPoint.y,
aPixelScrollEvent.delta, aPixelScrollEvent.scrollFlags,
GetBoolName(aPixelScrollEvent.isShift),
GetBoolName(aPixelScrollEvent.isControl),
GetBoolName(aPixelScrollEvent.isAlt),
GetBoolName(aPixelScrollEvent.isMeta), mRemainingDeltaForPixel));
return (aPixelScrollEvent.delta != 0);
}
/******************************************************************************
*
* SystemSettings

Просмотреть файл

@ -15,6 +15,7 @@
class nsWindow;
class nsGUIEvent;
class nsMouseScrollEvent;
struct nsModifierKeyState;
namespace mozilla {
@ -160,6 +161,47 @@ public:
*/
void RecordEvent(const EventInfo& aEvent);
/**
* InitMouseScrollEvent() initializes NS_MOUSE_SCROLL event and
* recomputes the remaning detla for the event.
* This must be called only once during handling a message and after
* RecordEvent() is called.
*
* @param aWindow A window which will dispatch the event.
* @param aMouseScrollEvent An NS_MOUSE_SCROLL event, this will be
* initialized.
* @param aScrollTargetInfo The result of GetScrollTargetInfo().
* @param aModKeyState Current modifier key state.
* @return TRUE if the event is ready to dispatch.
* Otherwise, FALSE.
*/
bool InitMouseScrollEvent(nsWindow* aWindow,
nsMouseScrollEvent& aMouseScrollEvent,
const ScrollTargetInfo& aScrollTargetInfo,
const nsModifierKeyState& aModKeyState);
/**
* InitMousePixelScrollEvent() initializes NS_MOUSE_PIXEL_SCROLL event and
* recomputes the remaning detla for the event.
* This must be called only once during handling a message and after
* RecordEvent() is called.
*
* @param aWindow A window which will dispatch the event.
* @param aMouseScrollEvent An NS_MOUSE_PIXEL_SCROLL event, this will be
* initialized.
* @param aScrollTargetInfo The result of GetScrollTargetInfo().
* @param aModKeyState Current modifier key state.
* @return TRUE if the event is ready to dispatch.
* Otherwise, FALSE.
*/
bool InitMousePixelScrollEvent(nsWindow* aWindow,
nsMouseScrollEvent& aPixelScrollEvent,
const ScrollTargetInfo& aScrollTargetInfo,
const nsModifierKeyState& aModKeyState);
private:
static PRInt32 RoundDelta(double aDelta);
// The remaining native delta value (i.e., not handled by previous
// message handler).
PRInt32 mRemainingDeltaForScroll;

Просмотреть файл

@ -6258,11 +6258,6 @@ bool nsWindow::OnGesture(WPARAM wParam, LPARAM lParam)
return true; // Handled
}
static PRInt32 RoundDelta(double aDelta)
{
return aDelta >= 0 ? (PRInt32)floor(aDelta) : (PRInt32)ceil(aDelta);
}
/**
* OnMouseWheelInternal - mouse wheel event processing.
* aMessage may be WM_MOUSEWHEEL or WM_MOUSEHWHEEL but this is called when
@ -6297,58 +6292,14 @@ nsWindow::OnMouseWheelInternal(UINT aMessage, WPARAM aWParam, LPARAM aLParam,
nsModifierKeyState modKeyState = MouseScrollHandler::GetModifierKeyState();
// Our positive delta value means to bottom or right.
// But positive native delta value means to top or right.
// Use orienter for computing our delta value with native delta value.
PRInt32 orienter = eventInfo.IsVertical() ? -1 : 1;
// Create line (or page) scroll event.
nsMouseScrollEvent scrollEvent(true, NS_MOUSE_SCROLL, this);
// Initialize common members on line scroll event, pixel scroll event and
// test event.
InitEvent(scrollEvent);
scrollEvent.isShift = modKeyState.mIsShiftDown;
scrollEvent.isControl = modKeyState.mIsControlDown;
scrollEvent.isMeta = false;
scrollEvent.isAlt = modKeyState.mIsAltDown;
// Before dispatching line scroll event, we should get the current scroll
// event target information for pixel scroll.
MouseScrollHandler::ScrollTargetInfo scrollTargetInfo =
handler->GetScrollTargetInfo(this, eventInfo, modKeyState);
// If we dispatch pixel scroll event after the line scroll event,
// we should set kHasPixels flag to the line scroll event.
scrollEvent.scrollFlags = eventInfo.GetScrollFlags();
if (scrollTargetInfo.dispatchPixelScrollEvent) {
scrollEvent.scrollFlags |= nsMouseScrollEvent::kHasPixels;
}
PRInt32 nativeDeltaForScroll =
eventInfo.GetNativeDelta() + lastEventInfo.mRemainingDeltaForScroll;
// NOTE: Don't use scrollTargetInfo.actualScrollAmount for computing the
// delta value of line/page scroll event. The value will be
// recomputed in ESM.
if (eventInfo.IsPage()) {
scrollEvent.delta = nativeDeltaForScroll * orienter / WHEEL_DELTA;
PRInt32 recomputedNativeDelta = scrollEvent.delta * orienter / WHEEL_DELTA;
lastEventInfo.mRemainingDeltaForScroll =
nativeDeltaForScroll - recomputedNativeDelta;
} else {
double deltaPerUnit;
deltaPerUnit =
(double)WHEEL_DELTA / eventInfo.GetScrollAmount();
scrollEvent.delta =
RoundDelta((double)nativeDeltaForScroll * orienter / deltaPerUnit);
PRInt32 recomputedNativeDelta =
(PRInt32)(scrollEvent.delta * orienter * deltaPerUnit);
lastEventInfo.mRemainingDeltaForScroll =
nativeDeltaForScroll - recomputedNativeDelta;
}
if (scrollEvent.delta) {
nsMouseScrollEvent scrollEvent(true, NS_MOUSE_SCROLL, this);
if (lastEventInfo.InitMouseScrollEvent(this, scrollEvent,
scrollTargetInfo, modKeyState)) {
DispatchWindowEvent(&scrollEvent);
if (mOnDestroyCalled) {
lastEventInfo.ResetTransaction();
@ -6356,45 +6307,14 @@ nsWindow::OnMouseWheelInternal(UINT aMessage, WPARAM aWParam, LPARAM aLParam,
}
}
// If the query event failed, we cannot send pixel events.
if (!scrollTargetInfo.dispatchPixelScrollEvent) {
lastEventInfo.mRemainingDeltaForPixel = 0;
return;
}
nsMouseScrollEvent pixelEvent(true, NS_MOUSE_PIXEL_SCROLL, this);
InitEvent(pixelEvent);
pixelEvent.scrollFlags = nsMouseScrollEvent::kAllowSmoothScroll;
pixelEvent.scrollFlags |= eventInfo.IsVertical() ?
nsMouseScrollEvent::kIsVertical : nsMouseScrollEvent::kIsHorizontal;
if (scrollTargetInfo.actualScrollAction ==
nsQueryContentEvent::SCROLL_ACTION_PAGE) {
pixelEvent.scrollFlags |= nsMouseScrollEvent::kIsFullPage;
}
// Use same modifier state for pixel scroll event.
pixelEvent.isShift = scrollEvent.isShift;
pixelEvent.isControl = scrollEvent.isControl;
pixelEvent.isMeta = scrollEvent.isMeta;
pixelEvent.isAlt = scrollEvent.isAlt;
PRInt32 nativeDeltaForPixel =
eventInfo.GetNativeDelta() + lastEventInfo.mRemainingDeltaForPixel;
// Pixel scroll event won't be recomputed the scroll amout and direction by
// ESM. Therefore, we need to set the computed amout and direction here.
PRInt32 orienterForPixel =
scrollTargetInfo.reversePixelScrollDirection ? -orienter : orienter;
double deltaPerPixel =
(double)WHEEL_DELTA / scrollTargetInfo.actualScrollAmount /
scrollTargetInfo.pixelsPerUnit;
pixelEvent.delta =
RoundDelta((double)nativeDeltaForPixel * orienterForPixel / deltaPerPixel);
PRInt32 recomputedNativeDelta =
(PRInt32)(pixelEvent.delta * orienterForPixel * deltaPerPixel);
lastEventInfo.mRemainingDeltaForPixel =
nativeDeltaForPixel - recomputedNativeDelta;
if (pixelEvent.delta != 0) {
if (lastEventInfo.InitMousePixelScrollEvent(this, pixelEvent,
scrollTargetInfo, modKeyState)) {
DispatchWindowEvent(&pixelEvent);
if (mOnDestroyCalled) {
lastEventInfo.ResetTransaction();
return;
}
}
return;
}
@ -8312,6 +8232,14 @@ nsModifierKeyState::nsModifierKeyState()
mIsAltDown = IS_VK_DOWN(NS_VK_ALT);
}
void
nsModifierKeyState::InitInputEvent(nsInputEvent& aInputEvent) const
{
aInputEvent.isShift = mIsShiftDown;
aInputEvent.isControl = mIsControlDown;
aInputEvent.isMeta = false;
aInputEvent.isAlt = mIsAltDown;
}
// Note that the result of GetTopLevelWindow method can be different from the
// result of WinUtils::GetTopLevelHWND(). The result can be non-floating

Просмотреть файл

@ -266,6 +266,8 @@ struct nsModifierKeyState {
mIsAltDown(aIsAltDown)
{
}
void InitInputEvent(nsInputEvent& aInputEvent) const;
};
// Used for synthesizing events