mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 856497 - Fix dynamic viewport sizing for margin changes. r=kats
The viewport wasn't being recalculated when the viewport margins changed, and was also subject to some rounding errors. Round off the values before comparing them (as they're screen pixels), and make sure to update the viewport when the margins change. Margins were also not correctly being altered when in overscroll, which could cause bottom-aligned fixed position content to be incorrectly offset.
This commit is contained in:
parent
6f88a2a1c4
commit
81e4e4068e
@ -592,6 +592,11 @@ abstract public class BrowserApp extends GeckoApp
|
||||
|
||||
mBrowserToolbar.updateBackButton(false);
|
||||
mBrowserToolbar.updateForwardButton(false);
|
||||
|
||||
// Reset mToolbarHeight before setting margins so we force the
|
||||
// Viewport:FixedMarginsChanged message to be sent again now that
|
||||
// Gecko has loaded.
|
||||
mToolbarHeight = 0;
|
||||
((BrowserToolbarLayout)mBrowserToolbar.getLayout()).refreshMargins();
|
||||
|
||||
mDoorHangerPopup.setAnchor(mBrowserToolbar.mFavicon);
|
||||
|
@ -259,69 +259,62 @@ public class GeckoLayerClient implements LayerView.Listener, PanZoomTarget
|
||||
});
|
||||
}
|
||||
|
||||
private boolean adjustFixedLayerMarginsForOverscroll(ImmutableViewportMetrics metrics, RectF adjustedMargins) {
|
||||
private void adjustFixedLayerMarginsForOverscroll(ImmutableViewportMetrics metrics, RectF adjustedMargins) {
|
||||
// When the page is in overscroll, we want that to 'eat into' the fixed
|
||||
// margin on that side of the viewport. This is because overscroll
|
||||
// equates to extra visible area and we use the fixed margins to stop
|
||||
// fixed position elements from being obscured by chrome.
|
||||
// In this situation, we also want to do the opposite adjustment to the
|
||||
// other end of the axis, so that when overscroll is cancelled out by
|
||||
// the margin area, the opposite side isn't pushed out of the viewport.
|
||||
boolean changed = false;
|
||||
// When we're overscrolled, we also want to make sure that the fixed
|
||||
// content on the non-overscroll side isn't obscured by the edge of the
|
||||
// window, so when adjusting one side of a margin, we apply the opposite
|
||||
// adjustment to the other side of the margin.
|
||||
adjustedMargins.left = metrics.fixedLayerMarginLeft;
|
||||
adjustedMargins.top = metrics.fixedLayerMarginTop;
|
||||
adjustedMargins.right = metrics.fixedLayerMarginRight;
|
||||
adjustedMargins.bottom = metrics.fixedLayerMarginBottom;
|
||||
|
||||
if (metrics.getPageWidth() > metrics.getWidthWithoutMargins()) {
|
||||
// The maximum margins are determined by the scrollable area of the page.
|
||||
float maxMarginWidth = Math.max(0, metrics.getPageWidth() - metrics.getWidthWithoutMargins());
|
||||
float maxMarginHeight = Math.max(0, metrics.getPageHeight() - metrics.getHeightWithoutMargins());
|
||||
|
||||
// Adjust for left overscroll
|
||||
if (metrics.viewportRectLeft < metrics.pageRectLeft && metrics.fixedLayerMarginLeft > 0) {
|
||||
adjustedMargins.left = Math.max(0, metrics.fixedLayerMarginLeft
|
||||
- (metrics.pageRectLeft - metrics.viewportRectLeft));
|
||||
adjustedMargins.right += metrics.fixedLayerMarginLeft - adjustedMargins.left;
|
||||
changed = true;
|
||||
float leftOverscroll = metrics.pageRectLeft - metrics.viewportRectLeft;
|
||||
if (leftOverscroll > 0) {
|
||||
adjustedMargins.left = FloatUtils.clamp(adjustedMargins.left - leftOverscroll, 0, maxMarginWidth);
|
||||
adjustedMargins.right = FloatUtils.clamp(adjustedMargins.right + leftOverscroll, 0, maxMarginWidth - adjustedMargins.left);
|
||||
}
|
||||
|
||||
// Adjust for right overscroll
|
||||
if (metrics.viewportRectRight < metrics.pageRectRight && metrics.fixedLayerMarginRight > 0) {
|
||||
adjustedMargins.right = Math.max(0, metrics.fixedLayerMarginRight
|
||||
- (metrics.pageRectRight - metrics.viewportRectRight));
|
||||
adjustedMargins.left += metrics.fixedLayerMarginRight - adjustedMargins.right;
|
||||
changed = true;
|
||||
}
|
||||
float rightOverscroll = metrics.viewportRectRight - metrics.pageRectRight;
|
||||
if (rightOverscroll > 0) {
|
||||
adjustedMargins.right = FloatUtils.clamp(adjustedMargins.right - rightOverscroll, 0, maxMarginWidth);
|
||||
adjustedMargins.left = FloatUtils.clamp(adjustedMargins.left + rightOverscroll, 0, maxMarginWidth - adjustedMargins.right);
|
||||
}
|
||||
|
||||
if (metrics.getPageHeight() > metrics.getHeightWithoutMargins()) {
|
||||
// Adjust for top overscroll
|
||||
if (metrics.viewportRectTop < metrics.pageRectTop && metrics.fixedLayerMarginTop > 0) {
|
||||
adjustedMargins.top = Math.max(0, metrics.fixedLayerMarginTop
|
||||
- (metrics.pageRectTop - metrics.viewportRectTop));
|
||||
adjustedMargins.bottom += metrics.fixedLayerMarginTop - adjustedMargins.top;
|
||||
changed = true;
|
||||
float topOverscroll = metrics.pageRectTop - metrics.viewportRectTop;
|
||||
if (topOverscroll > 0) {
|
||||
adjustedMargins.top = FloatUtils.clamp(adjustedMargins.top - topOverscroll, 0, maxMarginHeight);
|
||||
adjustedMargins.bottom = FloatUtils.clamp(adjustedMargins.bottom + topOverscroll, 0, maxMarginHeight - adjustedMargins.top);
|
||||
}
|
||||
|
||||
// Adjust for bottom overscroll
|
||||
if (metrics.viewportRectBottom < metrics.pageRectBottom && metrics.fixedLayerMarginBottom > 0) {
|
||||
adjustedMargins.bottom = Math.max(0, metrics.fixedLayerMarginBottom
|
||||
- (metrics.pageRectBottom - metrics.viewportRectBottom));
|
||||
adjustedMargins.top += metrics.fixedLayerMarginBottom - adjustedMargins.bottom;
|
||||
changed = true;
|
||||
float bottomOverscroll = metrics.viewportRectBottom - metrics.pageRectBottom;
|
||||
if (bottomOverscroll > 0) {
|
||||
adjustedMargins.bottom = FloatUtils.clamp(adjustedMargins.bottom - bottomOverscroll, 0, maxMarginHeight);
|
||||
adjustedMargins.top = FloatUtils.clamp(adjustedMargins.top + bottomOverscroll, 0, maxMarginHeight - adjustedMargins.bottom);
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
private void adjustViewport(DisplayPortMetrics displayPort) {
|
||||
ImmutableViewportMetrics metrics = getViewportMetrics();
|
||||
ImmutableViewportMetrics clampedMetrics = metrics.clamp();
|
||||
|
||||
RectF fixedLayerMargins = new RectF();
|
||||
if (adjustFixedLayerMarginsForOverscroll(metrics, fixedLayerMargins)) {
|
||||
adjustFixedLayerMarginsForOverscroll(metrics, fixedLayerMargins);
|
||||
clampedMetrics = clampedMetrics.setFixedLayerMargins(
|
||||
fixedLayerMargins.left, fixedLayerMargins.top,
|
||||
fixedLayerMargins.right, fixedLayerMargins.bottom);
|
||||
}
|
||||
|
||||
if (displayPort == null) {
|
||||
displayPort = DisplayPortCalculator.calculate(metrics, mPanZoomController.getVelocityVector());
|
||||
|
@ -7,6 +7,8 @@ package org.mozilla.gecko.util;
|
||||
|
||||
import android.graphics.PointF;
|
||||
|
||||
import java.lang.IllegalArgumentException;
|
||||
|
||||
public final class FloatUtils {
|
||||
private FloatUtils() {}
|
||||
|
||||
@ -26,4 +28,16 @@ public final class FloatUtils {
|
||||
public static float interpolate(float from, float to, float t) {
|
||||
return from + (to - from) * t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns 'value', clamped so that it isn't any lower than 'low', and it
|
||||
* isn't any higher than 'high'.
|
||||
*/
|
||||
public static float clamp(float value, float low, float high) {
|
||||
if (high < low) {
|
||||
throw new IllegalArgumentException(
|
||||
"clamp called with invalid parameters (" + high + " < " + low + ")" );
|
||||
}
|
||||
return Math.max(low, Math.min(high, value));
|
||||
}
|
||||
}
|
||||
|
@ -1311,6 +1311,7 @@ var BrowserApp = {
|
||||
|
||||
case "Viewport:FixedMarginsChanged":
|
||||
gViewportMargins = JSON.parse(aData);
|
||||
this.selectedTab.updateViewportSize(gScreenWidth);
|
||||
break;
|
||||
|
||||
case "nsPref:changed":
|
||||
@ -2952,13 +2953,13 @@ Tab.prototype = {
|
||||
// within the screen size, so remeasure when the page size remains within
|
||||
// the threshold of screen + margins, in case it's sizing itself relative
|
||||
// to the viewport.
|
||||
if (!this.updatingViewportForPageSizeChange) {
|
||||
if (!this.updatingViewportForPageSizeChange && aPageSizeUpdate) {
|
||||
this.updatingViewportForPageSizeChange = true;
|
||||
if (((viewport.pageBottom - viewport.pageTop
|
||||
< gScreenHeight + gViewportMargins.top + gViewportMargins.bottom)
|
||||
if (((Math.round(viewport.pageBottom - viewport.pageTop)
|
||||
<= gScreenHeight + gViewportMargins.top + gViewportMargins.bottom)
|
||||
!= this.viewportExcludesVerticalMargins) ||
|
||||
((viewport.pageRight - viewport.pageLeft
|
||||
< gScreenWidth + gViewportMargins.left + gViewportMargins.right)
|
||||
((Math.round(viewport.pageRight - viewport.pageLeft)
|
||||
<= gScreenWidth + gViewportMargins.left + gViewportMargins.right)
|
||||
!= this.viewportExcludesHorizontalMargins)) {
|
||||
this.updateViewportSize(gScreenWidth);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user