mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 941995 - Disable double-tapping and click delay on pages that are device-width or narrower (B2G). r=mbrubeck,botond
This commit is contained in:
parent
a7b51a7015
commit
31032942ac
@ -26,10 +26,11 @@ class MOZ_STACK_CLASS nsViewportInfo
|
||||
{
|
||||
public:
|
||||
nsViewportInfo(const mozilla::ScreenIntSize& aDisplaySize,
|
||||
bool aAllowZoom = true) :
|
||||
bool aAllowZoom = true, bool aAllowDoubleTapZoom = true) :
|
||||
mDefaultZoom(1.0),
|
||||
mAutoSize(true),
|
||||
mAllowZoom(aAllowZoom)
|
||||
mAllowZoom(aAllowZoom),
|
||||
mAllowDoubleTapZoom(aAllowDoubleTapZoom)
|
||||
{
|
||||
mSize = mozilla::gfx::RoundedToInt(mozilla::ScreenSize(aDisplaySize) / mDefaultZoom);
|
||||
mozilla::CSSToLayoutDeviceScale pixelRatio(1.0f);
|
||||
@ -43,13 +44,15 @@ class MOZ_STACK_CLASS nsViewportInfo
|
||||
const mozilla::CSSToScreenScale& aMaxZoom,
|
||||
const mozilla::CSSIntSize& aSize,
|
||||
bool aAutoSize,
|
||||
bool aAllowZoom) :
|
||||
bool aAllowZoom,
|
||||
bool aAllowDoubleTapZoom) :
|
||||
mDefaultZoom(aDefaultZoom),
|
||||
mMinZoom(aMinZoom),
|
||||
mMaxZoom(aMaxZoom),
|
||||
mSize(aSize),
|
||||
mAutoSize(aAutoSize),
|
||||
mAllowZoom(aAllowZoom)
|
||||
mAllowZoom(aAllowZoom),
|
||||
mAllowDoubleTapZoom(aAllowDoubleTapZoom)
|
||||
{
|
||||
ConstrainViewportValues();
|
||||
}
|
||||
@ -63,6 +66,9 @@ class MOZ_STACK_CLASS nsViewportInfo
|
||||
|
||||
bool IsAutoSizeEnabled() { return mAutoSize; }
|
||||
bool IsZoomAllowed() { return mAllowZoom; }
|
||||
bool IsDoubleTapZoomAllowed() { return mAllowDoubleTapZoom; }
|
||||
|
||||
void SetAllowDoubleTapZoom(bool aAllowDoubleTapZoom) { mAllowDoubleTapZoom = aAllowDoubleTapZoom; }
|
||||
|
||||
private:
|
||||
|
||||
@ -94,6 +100,11 @@ class MOZ_STACK_CLASS nsViewportInfo
|
||||
|
||||
// Whether or not the user can zoom in and out on the page. Default is true.
|
||||
bool mAllowZoom;
|
||||
|
||||
// Whether or not the user can double-tap to zoom in. When this is disabled
|
||||
// we can dispatch click events faster on a single tap because we don't have
|
||||
// to wait to detect the double-tap
|
||||
bool mAllowDoubleTapZoom;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -7453,11 +7453,15 @@ nsIDocument::AdoptNode(nsINode& aAdoptedNode, ErrorResult& rv)
|
||||
nsViewportInfo
|
||||
nsDocument::GetViewportInfo(const ScreenIntSize& aDisplaySize)
|
||||
{
|
||||
// In cases where the width of the CSS viewport is less than or equal to the width
|
||||
// of the display (i.e. width <= device-width) then we disable double-tap-to-zoom
|
||||
// behaviour. See bug 941995 for details.
|
||||
|
||||
switch (mViewportType) {
|
||||
case DisplayWidthHeight:
|
||||
return nsViewportInfo(aDisplaySize);
|
||||
case DisplayWidthHeightNoZoom:
|
||||
return nsViewportInfo(aDisplaySize, /* allowZoom */ false);
|
||||
return nsViewportInfo(aDisplaySize, /*allowZoom*/ false, /*allowDoubleTapZoom*/ false);
|
||||
case Unknown:
|
||||
{
|
||||
nsAutoString viewport;
|
||||
@ -7477,7 +7481,7 @@ nsDocument::GetViewportInfo(const ScreenIntSize& aDisplaySize)
|
||||
{
|
||||
// We're making an assumption that the docType can't change here
|
||||
mViewportType = DisplayWidthHeight;
|
||||
return nsViewportInfo(aDisplaySize);
|
||||
return nsViewportInfo(aDisplaySize, /*allowZoom*/true, /*allowDoubleTapZoom*/false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7486,7 +7490,7 @@ nsDocument::GetViewportInfo(const ScreenIntSize& aDisplaySize)
|
||||
GetHeaderData(nsGkAtoms::handheldFriendly, handheldFriendly);
|
||||
if (handheldFriendly.EqualsLiteral("true")) {
|
||||
mViewportType = DisplayWidthHeight;
|
||||
return nsViewportInfo(aDisplaySize);
|
||||
return nsViewportInfo(aDisplaySize, /*allowZoom*/true, /*allowDoubleTapZoom*/false);
|
||||
}
|
||||
|
||||
// Bug 940036. This is bad. When FirefoxOS was built, apps installed
|
||||
@ -7509,7 +7513,7 @@ nsDocument::GetViewportInfo(const ScreenIntSize& aDisplaySize)
|
||||
"ImplicitMetaViewportTagFallback");
|
||||
}
|
||||
mViewportType = DisplayWidthHeightNoZoom;
|
||||
return nsViewportInfo(aDisplaySize, /* allowZoom */ false);
|
||||
return nsViewportInfo(aDisplaySize, /*allowZoom*/false, /*allowDoubleTapZoom*/false);
|
||||
}
|
||||
}
|
||||
|
||||
@ -7583,6 +7587,7 @@ nsDocument::GetViewportInfo(const ScreenIntSize& aDisplaySize)
|
||||
(userScalable.EqualsLiteral("false"))) {
|
||||
mAllowZoom = false;
|
||||
}
|
||||
mAllowDoubleTapZoom = mAllowZoom;
|
||||
|
||||
mScaleStrEmpty = scaleStr.IsEmpty();
|
||||
mWidthStrEmpty = widthStr.IsEmpty();
|
||||
@ -7649,7 +7654,7 @@ nsDocument::GetViewportInfo(const ScreenIntSize& aDisplaySize)
|
||||
}
|
||||
|
||||
return nsViewportInfo(scaleFloat, scaleMinFloat, scaleMaxFloat, size,
|
||||
mAutoSize, mAllowZoom);
|
||||
mAutoSize, mAllowZoom, mAllowDoubleTapZoom);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1632,7 +1632,7 @@ private:
|
||||
mozilla::LayoutDeviceToScreenScale mScaleMaxFloat;
|
||||
mozilla::LayoutDeviceToScreenScale mScaleFloat;
|
||||
mozilla::CSSToLayoutDeviceScale mPixelRatio;
|
||||
bool mAutoSize, mAllowZoom, mValidScaleFloat, mValidMaxScale, mScaleStrEmpty, mWidthStrEmpty;
|
||||
bool mAutoSize, mAllowZoom, mAllowDoubleTapZoom, mValidScaleFloat, mValidMaxScale, mScaleStrEmpty, mWidthStrEmpty;
|
||||
mozilla::CSSIntSize mViewportSize;
|
||||
|
||||
nsrefcnt mStackRefCnt;
|
||||
|
@ -551,10 +551,12 @@ TabChild::HandlePossibleViewportChange()
|
||||
nsViewportInfo viewportInfo = nsContentUtils::GetViewportInfo(document, mInnerSize);
|
||||
uint32_t presShellId;
|
||||
ViewID viewId;
|
||||
if (APZCCallbackHelper::GetScrollIdentifiers(document->GetDocumentElement(),
|
||||
&presShellId, &viewId)) {
|
||||
bool scrollIdentifiersValid = APZCCallbackHelper::GetScrollIdentifiers(
|
||||
document->GetDocumentElement(), &presShellId, &viewId);
|
||||
if (scrollIdentifiersValid) {
|
||||
ZoomConstraints constraints(
|
||||
viewportInfo.IsZoomAllowed(),
|
||||
viewportInfo.IsDoubleTapZoomAllowed(),
|
||||
viewportInfo.GetMinZoom(),
|
||||
viewportInfo.GetMaxZoom());
|
||||
SendUpdateZoomConstraints(presShellId,
|
||||
@ -563,7 +565,6 @@ TabChild::HandlePossibleViewportChange()
|
||||
constraints);
|
||||
}
|
||||
|
||||
|
||||
float screenW = mInnerSize.width;
|
||||
float screenH = mInnerSize.height;
|
||||
CSSSize viewport(viewportInfo.GetSize());
|
||||
@ -666,6 +667,25 @@ TabChild::HandlePossibleViewportChange()
|
||||
// Force a repaint with these metrics. This, among other things, sets the
|
||||
// displayport, so we start with async painting.
|
||||
ProcessUpdateFrame(metrics);
|
||||
|
||||
if (viewportInfo.IsZoomAllowed() && scrollIdentifiersValid) {
|
||||
// If the CSS viewport is narrower than the screen (i.e. width <= device-width)
|
||||
// then we disable double-tap-to-zoom behaviour.
|
||||
bool allowDoubleTapZoom = (viewport.width > screenW / metrics.mDevPixelsPerCSSPixel.scale);
|
||||
if (allowDoubleTapZoom != viewportInfo.IsDoubleTapZoomAllowed()) {
|
||||
viewportInfo.SetAllowDoubleTapZoom(allowDoubleTapZoom);
|
||||
|
||||
ZoomConstraints constraints(
|
||||
viewportInfo.IsZoomAllowed(),
|
||||
viewportInfo.IsDoubleTapZoomAllowed(),
|
||||
viewportInfo.GetMinZoom(),
|
||||
viewportInfo.GetMaxZoom());
|
||||
SendUpdateZoomConstraints(presShellId,
|
||||
viewId,
|
||||
/* isRoot = */ true,
|
||||
constraints);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
@ -733,6 +733,7 @@ struct ParamTraits<mozilla::layers::ZoomConstraints>
|
||||
static void Write(Message* aMsg, const paramType& aParam)
|
||||
{
|
||||
WriteParam(aMsg, aParam.mAllowZoom);
|
||||
WriteParam(aMsg, aParam.mAllowDoubleTapZoom);
|
||||
WriteParam(aMsg, aParam.mMinZoom);
|
||||
WriteParam(aMsg, aParam.mMaxZoom);
|
||||
}
|
||||
@ -740,6 +741,7 @@ struct ParamTraits<mozilla::layers::ZoomConstraints>
|
||||
static bool Read(const Message* aMsg, void** aIter, paramType* aResult)
|
||||
{
|
||||
return (ReadParam(aMsg, aIter, &aResult->mAllowZoom) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mAllowDoubleTapZoom) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mMinZoom) &&
|
||||
ReadParam(aMsg, aIter, &aResult->mMaxZoom));
|
||||
}
|
||||
|
@ -410,19 +410,23 @@ struct ScrollableLayerGuid {
|
||||
|
||||
struct ZoomConstraints {
|
||||
bool mAllowZoom;
|
||||
bool mAllowDoubleTapZoom;
|
||||
CSSToScreenScale mMinZoom;
|
||||
CSSToScreenScale mMaxZoom;
|
||||
|
||||
ZoomConstraints()
|
||||
: mAllowZoom(true)
|
||||
, mAllowDoubleTapZoom(true)
|
||||
{
|
||||
MOZ_COUNT_CTOR(ZoomConstraints);
|
||||
}
|
||||
|
||||
ZoomConstraints(bool aAllowZoom,
|
||||
bool aAllowDoubleTapZoom,
|
||||
const CSSToScreenScale& aMinZoom,
|
||||
const CSSToScreenScale& aMaxZoom)
|
||||
: mAllowZoom(aAllowZoom)
|
||||
, mAllowDoubleTapZoom(aAllowDoubleTapZoom)
|
||||
, mMinZoom(aMinZoom)
|
||||
, mMaxZoom(aMaxZoom)
|
||||
{
|
||||
@ -437,6 +441,7 @@ struct ZoomConstraints {
|
||||
bool operator==(const ZoomConstraints& other) const
|
||||
{
|
||||
return mAllowZoom == other.mAllowZoom
|
||||
&& mAllowDoubleTapZoom == other.mAllowDoubleTapZoom
|
||||
&& mMinZoom == other.mMinZoom
|
||||
&& mMaxZoom == other.mMaxZoom;
|
||||
}
|
||||
|
@ -450,7 +450,7 @@ AsyncPanZoomController::AsyncPanZoomController(uint64_t aLayersId,
|
||||
mX(MOZ_THIS_IN_INITIALIZER_LIST()),
|
||||
mY(MOZ_THIS_IN_INITIALIZER_LIST()),
|
||||
mPanDirRestricted(false),
|
||||
mZoomConstraints(false, MIN_ZOOM, MAX_ZOOM),
|
||||
mZoomConstraints(false, false, MIN_ZOOM, MAX_ZOOM),
|
||||
mLastSampleTime(GetFrameTime()),
|
||||
mState(NOTHING),
|
||||
mLastAsyncScrollTime(GetFrameTime()),
|
||||
@ -957,9 +957,9 @@ nsEventStatus AsyncPanZoomController::OnLongPressUp(const TapGestureInput& aEven
|
||||
nsEventStatus AsyncPanZoomController::OnSingleTapUp(const TapGestureInput& aEvent) {
|
||||
APZC_LOG("%p got a single-tap-up in state %d\n", this, mState);
|
||||
nsRefPtr<GeckoContentController> controller = GetGeckoContentController();
|
||||
// If mZoomConstraints.mAllowZoom is true we wait for a call to OnSingleTapConfirmed before
|
||||
// If mZoomConstraints.mAllowDoubleTapZoom is true we wait for a call to OnSingleTapConfirmed before
|
||||
// sending event to content
|
||||
if (controller && !AllowZoom()) {
|
||||
if (controller && !AllowDoubleTapZoom()) {
|
||||
int32_t modifiers = WidgetModifiersToDOMModifiers(aEvent.modifiers);
|
||||
CSSIntPoint geckoScreenPoint;
|
||||
if (ConvertToGecko(aEvent.mPoint, &geckoScreenPoint)) {
|
||||
@ -1000,7 +1000,7 @@ nsEventStatus AsyncPanZoomController::OnDoubleTap(const TapGestureInput& aEvent)
|
||||
APZC_LOG("%p got a double-tap in state %d\n", this, mState);
|
||||
nsRefPtr<GeckoContentController> controller = GetGeckoContentController();
|
||||
if (controller) {
|
||||
if (AllowZoom()) {
|
||||
if (AllowDoubleTapZoom()) {
|
||||
int32_t modifiers = WidgetModifiersToDOMModifiers(aEvent.modifiers);
|
||||
CSSIntPoint geckoScreenPoint;
|
||||
if (ConvertToGecko(aEvent.mPoint, &geckoScreenPoint)) {
|
||||
@ -1961,6 +1961,11 @@ bool AsyncPanZoomController::AllowZoom() {
|
||||
&& !(mFrameMetrics.GetDisableScrollingX() || mFrameMetrics.GetDisableScrollingY());
|
||||
}
|
||||
|
||||
bool AsyncPanZoomController::AllowDoubleTapZoom() {
|
||||
ReentrantMonitorAutoEnter lock(mMonitor);
|
||||
return mZoomConstraints.mAllowDoubleTapZoom && AllowZoom();
|
||||
}
|
||||
|
||||
void AsyncPanZoomController::SetContentResponseTimer() {
|
||||
if (!mContentResponseTimeoutTask) {
|
||||
mContentResponseTimeoutTask =
|
||||
@ -1976,14 +1981,15 @@ void AsyncPanZoomController::TimeoutContentResponse() {
|
||||
}
|
||||
|
||||
void AsyncPanZoomController::UpdateZoomConstraints(const ZoomConstraints& aConstraints) {
|
||||
APZC_LOG("%p updating zoom constraints to %d %f %f\n", this, aConstraints.mAllowZoom,
|
||||
aConstraints.mMinZoom.scale, aConstraints.mMaxZoom.scale);
|
||||
APZC_LOG("%p updating zoom constraints to %d %d %f %f\n", this, aConstraints.mAllowZoom,
|
||||
aConstraints.mAllowDoubleTapZoom, aConstraints.mMinZoom.scale, aConstraints.mMaxZoom.scale);
|
||||
if (IsFloatNaN(aConstraints.mMinZoom.scale) || IsFloatNaN(aConstraints.mMaxZoom.scale)) {
|
||||
NS_WARNING("APZC received zoom constraints with NaN values; dropping...\n");
|
||||
return;
|
||||
}
|
||||
// inf float values and other bad cases should be sanitized by the code below.
|
||||
mZoomConstraints.mAllowZoom = aConstraints.mAllowZoom;
|
||||
mZoomConstraints.mAllowDoubleTapZoom = aConstraints.mAllowDoubleTapZoom;
|
||||
mZoomConstraints.mMinZoom = (MIN_ZOOM > aConstraints.mMinZoom ? MIN_ZOOM : aConstraints.mMinZoom);
|
||||
mZoomConstraints.mMaxZoom = (MAX_ZOOM > aConstraints.mMaxZoom ? aConstraints.mMaxZoom : MAX_ZOOM);
|
||||
if (mZoomConstraints.mMaxZoom < mZoomConstraints.mMinZoom) {
|
||||
|
@ -600,6 +600,7 @@ private:
|
||||
bool IsPanningState(PanZoomState mState);
|
||||
|
||||
bool AllowZoom();
|
||||
bool AllowDoubleTapZoom();
|
||||
|
||||
enum AxisLockMode {
|
||||
FREE, /* No locking at all */
|
||||
|
@ -331,7 +331,7 @@ TEST(AsyncPanZoomController, Pinch) {
|
||||
fm.mScrollOffset = CSSPoint(300, 300);
|
||||
fm.mZoom = CSSToScreenScale(2.0);
|
||||
apzc->SetFrameMetrics(fm);
|
||||
apzc->UpdateZoomConstraints(ZoomConstraints(true, CSSToScreenScale(0.25), CSSToScreenScale(4.0)));
|
||||
apzc->UpdateZoomConstraints(ZoomConstraints(true, true, CSSToScreenScale(0.25), CSSToScreenScale(4.0)));
|
||||
// the visible area of the document in CSS pixels is x=300 y=300 w=50 h=100
|
||||
|
||||
EXPECT_CALL(*mcc, SendAsyncScrollDOMEvent(_,_,_)).Times(AtLeast(1));
|
||||
@ -408,7 +408,7 @@ TEST(AsyncPanZoomController, Overzoom) {
|
||||
fm.mScrollOffset = CSSPoint(10, 0);
|
||||
fm.mZoom = CSSToScreenScale(1.0);
|
||||
apzc->SetFrameMetrics(fm);
|
||||
apzc->UpdateZoomConstraints(ZoomConstraints(true, CSSToScreenScale(0.25), CSSToScreenScale(4.0)));
|
||||
apzc->UpdateZoomConstraints(ZoomConstraints(true, true, CSSToScreenScale(0.25), CSSToScreenScale(4.0)));
|
||||
// the visible area of the document in CSS pixels is x=10 y=0 w=100 h=100
|
||||
|
||||
EXPECT_CALL(*mcc, SendAsyncScrollDOMEvent(_,_,_)).Times(AtLeast(1));
|
||||
@ -673,7 +673,7 @@ TEST(AsyncPanZoomController, ShortPress) {
|
||||
|
||||
apzc->SetFrameMetrics(TestFrameMetrics());
|
||||
apzc->NotifyLayersUpdated(TestFrameMetrics(), true);
|
||||
apzc->UpdateZoomConstraints(ZoomConstraints(false, CSSToScreenScale(1.0), CSSToScreenScale(1.0)));
|
||||
apzc->UpdateZoomConstraints(ZoomConstraints(false, false, CSSToScreenScale(1.0), CSSToScreenScale(1.0)));
|
||||
|
||||
int time = 0;
|
||||
nsEventStatus status = ApzcTap(apzc, 10, 10, time, 100, mcc.get());
|
||||
@ -697,7 +697,7 @@ TEST(AsyncPanZoomController, MediumPress) {
|
||||
|
||||
apzc->SetFrameMetrics(TestFrameMetrics());
|
||||
apzc->NotifyLayersUpdated(TestFrameMetrics(), true);
|
||||
apzc->UpdateZoomConstraints(ZoomConstraints(false, CSSToScreenScale(1.0), CSSToScreenScale(1.0)));
|
||||
apzc->UpdateZoomConstraints(ZoomConstraints(false, false, CSSToScreenScale(1.0), CSSToScreenScale(1.0)));
|
||||
|
||||
int time = 0;
|
||||
nsEventStatus status = ApzcTap(apzc, 10, 10, time, 400, mcc.get());
|
||||
@ -722,7 +722,7 @@ DoLongPressTest(bool aShouldUseTouchAction, uint32_t aBehavior) {
|
||||
|
||||
apzc->SetFrameMetrics(TestFrameMetrics());
|
||||
apzc->NotifyLayersUpdated(TestFrameMetrics(), true);
|
||||
apzc->UpdateZoomConstraints(ZoomConstraints(false, CSSToScreenScale(1.0), CSSToScreenScale(1.0)));
|
||||
apzc->UpdateZoomConstraints(ZoomConstraints(false, false, CSSToScreenScale(1.0), CSSToScreenScale(1.0)));
|
||||
|
||||
nsTArray<uint32_t> values;
|
||||
values.AppendElement(aBehavior);
|
||||
@ -785,7 +785,7 @@ TEST(AsyncPanZoomController, LongPressPreventDefault) {
|
||||
|
||||
apzc->SetFrameMetrics(TestFrameMetrics());
|
||||
apzc->NotifyLayersUpdated(TestFrameMetrics(), true);
|
||||
apzc->UpdateZoomConstraints(ZoomConstraints(false, CSSToScreenScale(1.0), CSSToScreenScale(1.0)));
|
||||
apzc->UpdateZoomConstraints(ZoomConstraints(false, false, CSSToScreenScale(1.0), CSSToScreenScale(1.0)));
|
||||
|
||||
EXPECT_CALL(*mcc, SendAsyncScrollDOMEvent(_,_,_)).Times(0);
|
||||
EXPECT_CALL(*mcc, RequestContentRepaint(_)).Times(0);
|
||||
|
@ -292,6 +292,7 @@ APZController::GetRootZoomConstraints(ZoomConstraints* aOutConstraints)
|
||||
// Until we support the meta-viewport tag properly allow zooming
|
||||
// from 1/4 to 4x by default.
|
||||
aOutConstraints->mAllowZoom = true;
|
||||
aOutConstraints->mAllowDoubleTapZoom = false;
|
||||
aOutConstraints->mMinZoom = CSSToScreenScale(0.25f);
|
||||
aOutConstraints->mMaxZoom = CSSToScreenScale(4.0f);
|
||||
return true;
|
||||
|
@ -1691,7 +1691,7 @@ MetroWidget::Observe(nsISupports *subject, const char *topic, const char16_t *da
|
||||
|
||||
ScrollableLayerGuid guid = ScrollableLayerGuid(mRootLayerTreeId, presShellId, viewId);
|
||||
APZController::sAPZC->UpdateZoomConstraints(guid,
|
||||
ZoomConstraints(false, CSSToScreenScale(1.0f), CSSToScreenScale(1.0f)));
|
||||
ZoomConstraints(false, false, CSSToScreenScale(1.0f), CSSToScreenScale(1.0f)));
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user