mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1235899 - Don't allow frame reconstruction to clobber the APZ scroll offset. r=botond
MozReview-Commit-ID: HZMavMJNtmq
This commit is contained in:
parent
5c388980b8
commit
ce22853404
@ -104,7 +104,6 @@ GK_ATOM(applet, "applet")
|
||||
GK_ATOM(applyImports, "apply-imports")
|
||||
GK_ATOM(applyTemplates, "apply-templates")
|
||||
GK_ATOM(mozapptype, "mozapptype")
|
||||
GK_ATOM(apz, "apz")
|
||||
GK_ATOM(archive, "archive")
|
||||
GK_ATOM(area, "area")
|
||||
GK_ATOM(arrow, "arrow")
|
||||
@ -2270,13 +2269,20 @@ GK_ATOM(SendMail, "SendMail")
|
||||
GK_ATOM(ForwardMail, "ForwardMail")
|
||||
GK_ATOM(ReplyToMail, "ReplyToMail")
|
||||
|
||||
// Smooth scroll events origins
|
||||
// Scroll origins (these are used in various scrolling functions in
|
||||
// nsIScrollableFrame and ScrollFrameHelper). These are divided into two lists
|
||||
// - origins in the first one have smooth-scrolling prefs associated with them,
|
||||
// under the "general.smoothScroll.<origin>.*" pref branch. Origins in the
|
||||
// second one do not.
|
||||
GK_ATOM(mouseWheel, "mouseWheel") // For discrete wheel events (e.g. not OSX magic mouse)
|
||||
GK_ATOM(pixels, "pixels")
|
||||
GK_ATOM(lines, "lines")
|
||||
GK_ATOM(pages, "pages")
|
||||
GK_ATOM(scrollbars, "scrollbars")
|
||||
GK_ATOM(other, "other")
|
||||
// Scroll origins without smooth-scrolling prefs
|
||||
GK_ATOM(apz, "apz")
|
||||
GK_ATOM(restore, "restore")
|
||||
|
||||
#ifdef ACCESSIBILITY
|
||||
GK_ATOM(alert, "alert")
|
||||
|
@ -92,11 +92,11 @@ ScrollFrameTo(nsIScrollableFrame* aFrame, const CSSPoint& aPoint, bool& aSuccess
|
||||
|
||||
// If the scrollable frame is currently in the middle of an async or smooth
|
||||
// scroll then we don't want to interrupt it (see bug 961280).
|
||||
// Also if the scrollable frame got a scroll request from something other than us
|
||||
// Also if the scrollable frame got a scroll request from a higher priority origin
|
||||
// since the last layers update, then we don't want to push our scroll request
|
||||
// because we'll clobber that one, which is bad.
|
||||
bool scrollInProgress = aFrame->IsProcessingAsyncScroll()
|
||||
|| (aFrame->LastScrollOrigin() && aFrame->LastScrollOrigin() != nsGkAtoms::apz)
|
||||
|| nsLayoutUtils::CanScrollOriginClobberApz(aFrame->LastScrollOrigin())
|
||||
|| aFrame->LastSmoothScrollOrigin();
|
||||
if (!scrollInProgress) {
|
||||
aFrame->ScrollToCSSPixelsApproximate(targetScrollPosition, nsGkAtoms::apz);
|
||||
|
@ -8581,6 +8581,14 @@ nsLayoutUtils::SetScrollPositionClampingScrollPortSize(nsIPresShell* aPresShell,
|
||||
MaybeReflowForInflationScreenSizeChange(presContext);
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
nsLayoutUtils::CanScrollOriginClobberApz(nsIAtom* aScrollOrigin)
|
||||
{
|
||||
return aScrollOrigin != nullptr
|
||||
&& aScrollOrigin != nsGkAtoms::apz
|
||||
&& aScrollOrigin != nsGkAtoms::restore;
|
||||
}
|
||||
|
||||
/* static */ FrameMetrics
|
||||
nsLayoutUtils::ComputeFrameMetrics(nsIFrame* aForFrame,
|
||||
nsIFrame* aScrollFrame,
|
||||
@ -8637,11 +8645,10 @@ nsLayoutUtils::ComputeFrameMetrics(nsIFrame* aForFrame,
|
||||
nsPoint smoothScrollPosition = scrollableFrame->LastScrollDestination();
|
||||
metrics.SetSmoothScrollOffset(CSSPoint::FromAppUnits(smoothScrollPosition));
|
||||
|
||||
// If the frame was scrolled since the last layers update, and by
|
||||
// something other than the APZ code, we want to tell the APZ to update
|
||||
// If the frame was scrolled since the last layers update, and by something
|
||||
// that is higher priority than APZ, we want to tell the APZ to update
|
||||
// its scroll offset.
|
||||
nsIAtom* lastScrollOrigin = scrollableFrame->LastScrollOrigin();
|
||||
if (lastScrollOrigin && lastScrollOrigin != nsGkAtoms::apz) {
|
||||
if (CanScrollOriginClobberApz(scrollableFrame->LastScrollOrigin())) {
|
||||
metrics.SetScrollOffsetUpdated(scrollableFrame->CurrentScrollGeneration());
|
||||
}
|
||||
nsIAtom* lastSmoothScrollOrigin = scrollableFrame->LastSmoothScrollOrigin();
|
||||
|
@ -2722,6 +2722,15 @@ public:
|
||||
static void SetScrollPositionClampingScrollPortSize(nsIPresShell* aPresShell,
|
||||
CSSSize aSize);
|
||||
|
||||
/**
|
||||
* Returns true if the given scroll origin is "higher priority" than APZ.
|
||||
* In general any content programmatic scrolls (e.g. scrollTo calls) are
|
||||
* higher priority, and take precedence over APZ scrolling. This function
|
||||
* returns true for those, and returns false for other origins like APZ
|
||||
* itself, or scroll position updates from the history restore code.
|
||||
*/
|
||||
static bool CanScrollOriginClobberApz(nsIAtom* aScrollOrigin);
|
||||
|
||||
static FrameMetrics ComputeFrameMetrics(nsIFrame* aForFrame,
|
||||
nsIFrame* aScrollFrame,
|
||||
nsIContent* aContent,
|
||||
|
@ -1725,9 +1725,15 @@ private:
|
||||
void
|
||||
ScrollFrameHelper::AsyncScroll::InitPreferences(TimeStamp aTime, nsIAtom *aOrigin)
|
||||
{
|
||||
if (!aOrigin){
|
||||
if (!aOrigin || aOrigin == nsGkAtoms::restore) {
|
||||
// We don't have special prefs for "restore", just treat it as "other".
|
||||
// "restore" scrolls are (for now) always instant anyway so unless something
|
||||
// changes we should never have aOrigin == nsGkAtoms::restore here.
|
||||
aOrigin = nsGkAtoms::other;
|
||||
}
|
||||
// Likewise we should never get APZ-triggered scrolls here, and if that changes
|
||||
// something is likely broken somewhere.
|
||||
MOZ_ASSERT(aOrigin != nsGkAtoms::apz);
|
||||
|
||||
// Read preferences only on first iteration or for a different event origin.
|
||||
if (!mIsFirstIteration && aOrigin == mOrigin) {
|
||||
@ -3938,7 +3944,8 @@ ScrollFrameHelper::ScrollToRestoredPosition()
|
||||
scrollToPos.x = mScrollPort.x -
|
||||
(mScrollPort.XMost() - scrollToPos.x - mScrolledFrame->GetRect().width);
|
||||
nsWeakFrame weakFrame(mOuter);
|
||||
ScrollTo(scrollToPos, nsIScrollableFrame::INSTANT);
|
||||
ScrollToWithOrigin(scrollToPos, nsIScrollableFrame::INSTANT,
|
||||
nsGkAtoms::restore, nullptr);
|
||||
if (!weakFrame.IsAlive()) {
|
||||
return;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user