Bug 970141 Use CSS pixels rather than device pixels for delta values of WheelEvent r=smaug

This commit is contained in:
Masayuki Nakano 2014-03-11 14:14:07 +09:00
parent 7419257b87
commit bdda211421
3 changed files with 52 additions and 8 deletions

View File

@ -17,9 +17,17 @@ WheelEvent::WheelEvent(EventTarget* aOwner,
: MouseEvent(aOwner, aPresContext,
aWheelEvent ? aWheelEvent :
new WidgetWheelEvent(false, 0, nullptr))
, mAppUnitsPerDevPixel(0)
{
if (aWheelEvent) {
mEventIsInternal = false;
// If the delta mode is pixel, the WidgetWheelEvent's delta values are in
// device pixels. However, JS contents need the delta values in CSS pixels.
// We should store the value of mAppUnitsPerDevPixel here because
// it might be changed by changing zoom or something.
if (aWheelEvent->deltaMode == nsIDOMWheelEvent::DOM_DELTA_PIXEL) {
mAppUnitsPerDevPixel = aPresContext->AppUnitsPerDevPixel();
}
} else {
mEventIsInternal = true;
mEvent->time = PR_Now();
@ -71,7 +79,11 @@ WheelEvent::InitWheelEvent(const nsAString& aType,
double
WheelEvent::DeltaX()
{
return mEvent->AsWheelEvent()->deltaX;
if (!mAppUnitsPerDevPixel) {
return mEvent->AsWheelEvent()->deltaX;
}
return mEvent->AsWheelEvent()->deltaX *
mAppUnitsPerDevPixel / nsPresContext::AppUnitsPerCSSPixel();
}
NS_IMETHODIMP
@ -86,7 +98,11 @@ WheelEvent::GetDeltaX(double* aDeltaX)
double
WheelEvent::DeltaY()
{
return mEvent->AsWheelEvent()->deltaY;
if (!mAppUnitsPerDevPixel) {
return mEvent->AsWheelEvent()->deltaY;
}
return mEvent->AsWheelEvent()->deltaY *
mAppUnitsPerDevPixel / nsPresContext::AppUnitsPerCSSPixel();
}
NS_IMETHODIMP
@ -101,7 +117,11 @@ WheelEvent::GetDeltaY(double* aDeltaY)
double
WheelEvent::DeltaZ()
{
return mEvent->AsWheelEvent()->deltaZ;
if (!mAppUnitsPerDevPixel) {
return mEvent->AsWheelEvent()->deltaZ;
}
return mEvent->AsWheelEvent()->deltaZ *
mAppUnitsPerDevPixel / nsPresContext::AppUnitsPerCSSPixel();
}
NS_IMETHODIMP

View File

@ -43,10 +43,16 @@ public:
return WheelEventBinding::Wrap(aCx, aScope, this);
}
// NOTE: DeltaX(), DeltaY() and DeltaZ() return CSS pixels when deltaMode is
// DOM_DELTA_PIXEL. (The internal event's delta values are device pixels
// if it's dispatched by widget)
double DeltaX();
double DeltaY();
double DeltaZ();
uint32_t DeltaMode();
private:
int32_t mAppUnitsPerDevPixel;
};
} // namespace dom

View File

@ -1147,10 +1147,18 @@ function doTestZoom(aSettings, aCallback)
function doTestZoomedScroll(aCallback)
{
var zoom = 1.0;
function setFullZoom(aWindow, aZoom)
{
zoom = aZoom;
SpecialPowers.setFullZoom(aWindow, aZoom);
}
function prepareTestZoomedPixelScroll()
{
// Reset zoom and store the scroll amount into the data.
synthesizeKey("0", { accelKey: true });
zoom = 1.0;
onZoomReset(testZoomedPixelScroll);
}
@ -1160,7 +1168,7 @@ function doTestZoomedScroll(aCallback)
gScrollableElement.scrollLeft = 1000;
// Ensure not to be in reflow.
hitEventLoop(function () {
function handler(aEvent)
function mousePixelScrollHandler(aEvent)
{
if (aEvent.axis == MouseScrollEvent.HORIZONTAL_AXIS) {
is(aEvent.detail, 16,
@ -1172,7 +1180,15 @@ function doTestZoomedScroll(aCallback)
ok(false, "doTestZoomedScroll: The axis of MozMousePixelScroll for pixel wheel event is invalid, got " + aEvent.axis);
}
}
window.addEventListener("MozMousePixelScroll", handler, true);
function wheelHandler(aEvent)
{
is(aEvent.deltaX, 16.0 / zoom,
"doTestZoomedScroll: The deltaX of wheel for pixel is wrong");
is(aEvent.deltaY, 16.0 / zoom,
"doTestZoomedScroll: The deltaY of wheel for pixel is wrong");
}
window.addEventListener("MozMousePixelScroll", mousePixelScrollHandler, true);
window.addEventListener("wheel", wheelHandler, true);
synthesizeWheel(gScrollableElement, 10, 10,
{ deltaMode: WheelEvent.DOM_DELTA_PIXEL,
deltaX: 16.0, deltaY: 16.0, lineOrPageDeltaX: 0, lineOrPageDeltaY: 0 });
@ -1186,7 +1202,7 @@ function doTestZoomedScroll(aCallback)
"doTestZoomedScroll: scrolledY must be larger than 1000 for pixel wheel event, got " + scrolledY);
// Zoom
SpecialPowers.setFullZoom(window, 2.0);
setFullZoom(window, 2.0);
// Ensure not to be in reflow.
hitEventLoop(function () {
gScrollableElement.scrollTop = 1000;
@ -1202,7 +1218,8 @@ function doTestZoomedScroll(aCallback)
ok(Math.abs(gScrollableElement.scrollTop - (1000 + (scrolledY - 1000) / 2)) <= 1,
"doTestZoomedScroll: zoomed vertical scroll amount by pixel wheel event is different from normal, scrollTop=" +
gScrollableElement.scrollTop + ", scrolledY=" + scrolledY);
window.removeEventListener("MozMousePixelScroll", handler, true);
window.removeEventListener("MozMousePixelScroll", mousePixelScrollHandler, true);
window.removeEventListener("wheel", wheelHandler, true);
synthesizeKey("0", { accelKey: true });
onZoomReset(prepareTestZoomedLineScroll);
@ -1216,6 +1233,7 @@ function doTestZoomedScroll(aCallback)
{
// Reset zoom and store the scroll amount into the data.
synthesizeKey("0", { accelKey: true });
zoom = 1.0;
onZoomReset(testZoomedLineScroll);
}
function testZoomedLineScroll()
@ -1261,7 +1279,7 @@ function doTestZoomedScroll(aCallback)
"doTestZoomedScroll: scrolledY must be larger than 1000 for line wheel event, got " + scrolledY);
// Zoom
SpecialPowers.setFullZoom(window, 2.0);
setFullZoom(window, 2.0);
// Ensure not to be in reflow.
hitEventLoop(function () {
gScrollableElement.scrollTop = 1000;