зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1501062 - Set the visible region on scrollthumb WebRenderLayerScrollData items. r=botond
This field is used by APZ to implement the feature where the scrollbar snaps back to the starting position if the mouse gets too far away.
This commit is contained in:
Родитель
ee8ccacb05
Коммит
c277149ab9
|
@ -351,6 +351,8 @@ function moveMouseAndScrollWheelOver(element, dx, dy, testDriver, waitForScroll
|
|||
// processed by the widget code can be detected by listening for the mousemove
|
||||
// events in the caller, or for some other event that is triggered by the
|
||||
// mousemove, such as the scroll event resulting from the scrollbar drag.
|
||||
// Note: helper_scrollbar_snap_bug1501062.html contains a copy of this code
|
||||
// with modifications. Fixes here should be copied there if appropriate.
|
||||
function* dragVerticalScrollbar(element, testDriver, distance = 20, increment = 5) {
|
||||
var boundingClientRect = element.getBoundingClientRect();
|
||||
var verticalScrollbarWidth = boundingClientRect.width - element.clientWidth;
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width; initial-scale=1.0">
|
||||
<title>Exercising the slider.snapMultiplier code</title>
|
||||
<script type="application/javascript" src="apz_test_native_event_utils.js"></script>
|
||||
<script type="application/javascript" src="apz_test_utils.js"></script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/paint_listener.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="scrollable" style="width: 300px; height: 300px; overflow: auto">
|
||||
<div id="filler" style="height: 2000px; background-image: linear-gradient(red,blue)"></div>
|
||||
</div>
|
||||
</body>
|
||||
<script type="text/javascript">
|
||||
function* test(testDriver) {
|
||||
// Note that this pref is a read-once-on-startup pref so we can't change it
|
||||
// and have the change take effect. Instead we just use the value to determine
|
||||
// what the expected behaviour is.
|
||||
var snapMultiplier = SpecialPowers.getIntPref("slider.snapMultiplier");
|
||||
|
||||
// Much of the code below is "inlined" from dragVerticalScrollbar. Reusing
|
||||
// that code was nontrivial given the modifications we needed to make, and
|
||||
// would have increased the complexity of that helper function more than I'd
|
||||
// like. However if any bugfixes are made to that function this code might
|
||||
// need to be updated as well.
|
||||
|
||||
var scrollableDiv = document.getElementById('scrollable');
|
||||
var boundingClientRect = scrollableDiv.getBoundingClientRect();
|
||||
var verticalScrollbarWidth = boundingClientRect.width - scrollableDiv.clientWidth;
|
||||
if (verticalScrollbarWidth == 0) {
|
||||
ok(true, "No scrollbar, can't do this test");
|
||||
return;
|
||||
}
|
||||
|
||||
// register a scroll listener for the initial drag
|
||||
scrollableDiv.addEventListener('scroll', () => setTimeout(testDriver, 0), {once: true});
|
||||
|
||||
var upArrowHeight = verticalScrollbarWidth; // assume square scrollbar buttons
|
||||
var mouseX = scrollableDiv.clientWidth + (verticalScrollbarWidth / 2);
|
||||
var mouseY = upArrowHeight + 5; // start dragging somewhere in the thumb
|
||||
|
||||
dump("Starting drag at " + mouseX + ", " + mouseY + " from top-left of #" + scrollableDiv.id + "\n");
|
||||
|
||||
// Move the mouse to the scrollbar thumb and drag it down
|
||||
yield synthesizeNativeMouseEvent(scrollableDiv, mouseX, mouseY, nativeMouseMoveEventMsg(), testDriver);
|
||||
yield synthesizeNativeMouseEvent(scrollableDiv, mouseX, mouseY, nativeMouseDownEventMsg(), testDriver);
|
||||
// drag down by 100 pixels
|
||||
mouseY += 100;
|
||||
yield synthesizeNativeMouseEvent(scrollableDiv, mouseX, mouseY, nativeMouseMoveEventMsg(), testDriver);
|
||||
|
||||
// wait here until the scroll event listener is triggered.
|
||||
yield;
|
||||
var savedScrollPos = scrollableDiv.scrollTop;
|
||||
ok(savedScrollPos > 0, "Scrolled to " + savedScrollPos);
|
||||
|
||||
// register a new scroll event listener. The next mousemove below will either
|
||||
// trigger the snapback behaviour (if snapMultiplier > 0) or trigger a vertical
|
||||
// scroll (if snapMultiplier == 0) because of the x- and y-coordinates we move
|
||||
// the mouse to. This allows us to wait for a scroll event in either case.
|
||||
// If we only triggered the snapback case then waiting for the scroll to
|
||||
// "not happen" in the other case would be more error-prone.
|
||||
scrollableDiv.addEventListener('scroll', () => setTimeout(testDriver, 0), {once: true});
|
||||
// Add 2 to snapMultipler just to make sure we get far enough away from the scrollbar
|
||||
var snapBackDistance = (snapMultiplier + 2) * verticalScrollbarWidth;
|
||||
yield synthesizeNativeMouseEvent(scrollableDiv, mouseX + snapBackDistance, mouseY + 10, nativeMouseMoveEventMsg(), testDriver);
|
||||
|
||||
// wait here until the scroll happens
|
||||
yield;
|
||||
if (snapMultiplier > 0) {
|
||||
ok(scrollableDiv.scrollTop == 0, "Scroll position snapped back to " + scrollableDiv.scrollTop);
|
||||
} else {
|
||||
ok(scrollableDiv.scrollTop > savedScrollPos, "Scroll position increased to " + scrollableDiv.scrollTop);
|
||||
}
|
||||
|
||||
// Now we move the mouse back to the old position to ensure the scroll position
|
||||
// gets restored properly
|
||||
scrollableDiv.addEventListener('scroll', () => setTimeout(testDriver, 0), {once: true});
|
||||
yield synthesizeNativeMouseEvent(scrollableDiv, mouseX, mouseY, nativeMouseMoveEventMsg(), testDriver);
|
||||
|
||||
// wait here until the scroll happens
|
||||
yield;
|
||||
ok(scrollableDiv.scrollTop == savedScrollPos, "Scroll position was restored to " + scrollableDiv.scrollTop);
|
||||
|
||||
// Release mouse and ensure the scroll position stuck
|
||||
yield synthesizeNativeMouseEvent(scrollableDiv, mouseX, mouseY, nativeMouseUpEventMsg(), testDriver);
|
||||
// Flush everything just to be safe
|
||||
yield flushApzRepaints(testDriver);
|
||||
|
||||
ok(scrollableDiv.scrollTop == savedScrollPos, "Final scroll position was " + scrollableDiv.scrollTop);
|
||||
}
|
||||
|
||||
waitUntilApzStable()
|
||||
.then(runContinuation(test))
|
||||
.then(subtestDone);
|
||||
|
||||
</script>
|
||||
</html>
|
|
@ -25,7 +25,10 @@ var subtests = [
|
|||
// Test for scrollbar-dragging on a scrollframe inside an SVGEffects
|
||||
{'file': 'helper_bug1331693.html'},
|
||||
// Test for scrollbar-dragging on a transformed scrollframe inside a fixed-pos item
|
||||
{'file': 'helper_bug1462961.html'}
|
||||
{'file': 'helper_bug1462961.html'},
|
||||
// Scrollbar dragging where we exercise the snapback behaviour by moving the
|
||||
// mouse away from the scrollbar during drag
|
||||
{'file': 'helper_scrollbar_snap_bug1501062.html'}
|
||||
];
|
||||
|
||||
if (isApzEnabled()) {
|
||||
|
|
|
@ -74,6 +74,7 @@ public:
|
|||
void SetEventRegionsOverride(const EventRegionsOverride& aOverride) { mEventRegionsOverride = aOverride; }
|
||||
EventRegionsOverride GetEventRegionsOverride() const { return mEventRegionsOverride; }
|
||||
|
||||
void SetVisibleRegion(const LayerIntRegion& aRegion) { mVisibleRegion = aRegion; }
|
||||
const LayerIntRegion& GetVisibleRegion() const { return mVisibleRegion; }
|
||||
void SetReferentId(LayersId aReferentId) { mReferentId = Some(aReferentId); }
|
||||
Maybe<LayersId> GetReferentId() const { return mReferentId; }
|
||||
|
|
|
@ -7118,6 +7118,12 @@ nsDisplayOwnLayer::UpdateScrollData(
|
|||
aLayerData->SetScrollbarData(mScrollbarData);
|
||||
if (IsScrollThumbLayer()) {
|
||||
aLayerData->SetScrollbarAnimationId(mWrAnimationId);
|
||||
LayoutDeviceRect bounds = LayoutDeviceIntRect::FromAppUnits(
|
||||
mBounds, mFrame->PresContext()->AppUnitsPerDevPixel());
|
||||
// Assume a resolution of 1.0 for now because this is a WebRender codepath
|
||||
// and we don't really handle resolution on the Gecko side
|
||||
LayerIntRect layerBounds = RoundedOut(bounds * LayoutDeviceToLayerScale(1.0f));
|
||||
aLayerData->SetVisibleRegion(LayerIntRegion(layerBounds));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче