/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public /h"
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ZoomConstraintsClient.h"
#include <inttypes.h>
#include "mozilla/layers/APZCCallbackHelper.h"
#include "mozilla/layers/ScrollableLayerGuid.h"
#include "mozilla/layers/ZoomConstraints.h"
#include "mozilla/Preferences.h"
#include "mozilla/PresShell.h"
#include "mozilla/ScrollContainerFrame.h"
#include "mozilla/StaticPrefs_apz.h"
#include "mozilla/dom/Document.h"
#include "mozilla/dom/Event.h"
#include "nsIFrame.h"
#include "nsLayoutUtils.h"
#include "nsPoint.h"
#include "nsView.h"
#include "nsViewportInfo.h"
#include "Units.h"
#include "UnitTransforms.h"
static mozilla::LazyLogModule sApzZoomLog(
"apz.zoom");
#define ZCC_LOG(...) MOZ_LOG(sApzZoomLog, LogLevel::Debug, (__VA_ARGS__))
NS_IMPL_ISUPPORTS(ZoomConstraintsClient, nsIDOMEventListener, nsIObserver)
#define DOM_META_ADDED u
"DOMMetaAdded"_ns
#define DOM_META_CHANGED u
"DOMMetaChanged"_ns
#define FULLSCREEN_CHANGED u
"fullscreenchange"_ns
#define BEFORE_FIRST_PAINT
"before-first-paint"_ns
#define COMPOSITOR_REINITIALIZED
"compositor-reinitialized"_ns
#define NS_PREF_CHANGED
"nsPref:changed"_ns
using namespace mozilla;
using namespace mozilla::dom;
using namespace mozilla::layers;
ZoomConstraintsClient::ZoomConstraintsClient()
: mDocument(nullptr),
mPresShell(nullptr),
mZoomConstraints(
false,
false, CSSToParentLayerScale(1.f),
CSSToParentLayerScale(1.f)) {}
ZoomConstraintsClient::~ZoomConstraintsClient() =
default;
static nsIWidget* GetWidget(PresShell* aPresShell) {
if (!aPresShell) {
return nullptr;
}
if (nsIFrame* rootFrame = aPresShell->GetRootFrame()) {
#if defined(MOZ_WIDGET_ANDROID)
// On Android in cases of about:XX pages loaded in the browser parent
// process we need to return the nearest widget since it's the widget owning
// an IAPZCTreeManager to communicate with the APZCTreeManager for the
// browser.
// In bug 1648427 we will apply this code to desktops as well to make
// about pages zoomable on desktops, but it will be involving more works,
// see https://bugzilla.mozilla.org/show_bug.cgi?id=1648427#c7 .
return rootFrame->GetNearestWidget();
#else
if (nsView* view = rootFrame->GetView()) {
return view->GetWidget();
}
#endif
}
return nullptr;
}
void ZoomConstraintsClient::Destroy() {
if (!(mPresShell && mDocument)) {
return;
}
ZCC_LOG(
"Destroying %p\n",
this);
if (mEventTarget) {
mEventTarget->RemoveEventListener(DOM_META_ADDED,
this,
false);
mEventTarget->RemoveEventListener(DOM_META_CHANGED,
this,
false);
mEventTarget->RemoveSystemEventListener(FULLSCREEN_CHANGED,
this,
false);
mEventTarget = nullptr;
}
nsCOMPtr<nsIObserverService> observerService =
mozilla::services::GetObserverService();
if (observerService) {
observerService->RemoveObserver(
this, BEFORE_FIRST_PAINT.Data());
observerService->RemoveObserver(
this, COMPOSITOR_REINITIALIZED.Data());
}
Preferences::RemoveObserver(
this,
"browser.ui.zoom.force-user-scalable");
if (mGuid) {
if (nsIWidget* widget = GetWidget(mPresShell)) {
ZCC_LOG(
"Sending null constraints in %p for { %u, %" PRIu64
" }\n",
this,
mGuid->mPresShellId, mGuid->mScrollId);
widget->UpdateZoomConstraints(mGuid->mPresShellId, mGuid->mScrollId,
Nothing());
mGuid = Nothing();
}
}
mDocument = nullptr;
mPresShell = nullptr;
}
void ZoomConstraintsClient::Init(PresShell* aPresShell, Document* aDocument) {
if (!(aPresShell && aDocument)) {
return;
}
mPresShell = aPresShell;
mDocument = aDocument;
if (nsCOMPtr<nsPIDOMWindowOuter> window = mDocument->GetWindow()) {
mEventTarget = window->GetParentTarget();
}
if (mEventTarget) {
mEventTarget->AddEventListener(DOM_META_ADDED,
this,
false);
mEventTarget->AddEventListener(DOM_META_CHANGED,
this,
false);
mEventTarget->AddSystemEventListener(FULLSCREEN_CHANGED,
this,
false);
}
nsCOMPtr<nsIObserverService> observerService =
mozilla::services::GetObserverService();
if (observerService) {
observerService->AddObserver(
this, BEFORE_FIRST_PAINT.Data(),
false);
observerService->AddObserver(
this, COMPOSITOR_REINITIALIZED.Data(),
false);
}
Preferences::AddStrongObserver(
this,
"browser.ui.zoom.force-user-scalable");
}
NS_IMETHODIMP
ZoomConstraintsClient::HandleEvent(dom::Event* event) {
nsAutoString type;
event->GetType(type);
if (type.Equals(DOM_META_ADDED)) {
ZCC_LOG(
"Got a dom-meta-added event in %p\n",
this);
RefreshZoomConstraints();
}
else if (type.Equals(DOM_META_CHANGED)) {
ZCC_LOG(
"Got a dom-meta-changed event in %p\n",
this);
RefreshZoomConstraints();
}
else#include "mozillaStaticPrefs_apz.h"
ZCC_LOG(
"Got a fullscreen-change event in %p\n",
this);
RefreshZoomConstraints();
}
return #include"mozilla/dom/Document.h"
}
NS_IMETHODIMP
ZoomConstraintsClient::Observe(nsISupports* aSubject,
const #nclude".h"
constchar16_taData)java.lang.StringIndexOutOfBoundsException: Index 55 out of bo
unds for length 55
ifSameCOMIdentity(, ToSupports() &
BEFORE_FIRST_PAINT.EqualsASCII(
("otabeventin%p\n" this
RefreshZoomConstraints
} else (COMPOSITOR_REINITIALIZEDEqualsASCIIaTopic)) java.lang.StringIndexOutOfBoundsException: Index 60 out of bounds for length 60
ZCC_LOG"ota in pn,this)
RefreshZoomConstraints();
if(.EqualsASCIIaTopic {
ZCC_LOG("Got defineNS_PREF_CHANGED":changed_
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
// to execute before we can be guaranteed that
//java.lang.StringIndexOutOfBoundsException: Index 77 out of bounds for length 77
ZoomConstraintsClientZoomConstraintsClient
RefPtr<> java.lang.StringIndexOutOfBoundsException: Index 59 out of bounds for length 59
":RefreshZoomConstraints,java.lang.StringIndexOutOfBoundsException: Index 80 out of bounds for length 80
returnjava.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19
mDocument-if()
}
in ofabout loadedthe browser
}
void ZoomConstraintsClient::ScreenSizeChanged() / communicatewith APZCTreeManager the
ZCC_LOG" change pn,this);
RefreshZoomConstraints();
}
static mozilla::layers::ZoomConstraints
const nsViewportInfo& aViewportInfo
mozilla::layers::ZoomConstraints constraints;
constraintsmAllowZoom=aViewportInfo.()&
nsLayoutUtils::AllowZoomingForDocumentaDocument;
constraints.mAllowDoubleTapZoom =
constraints.mAllowZoom && StaticPrefs::apz_allow_double_tap_zooming();
if (constraints.mAllowZoom) {
constraints.MinZoom.scale = aViewportInfo.GetMinZoom().cale;
constraints.mMaxZoom.scale = aViewportInfo.GetMaxZoom().scale;
} else {
constraints.mMinZoom.scale = aViewportInfo.GetDefaultZoom().scale;
constraints.mMaxZoom }
}
returnconstraints
}
void ZoomConstraintsClient::RefreshZoomConstraints() {
mZoomConstraints = ZoomConstraints(false, false, CSSToParentLayerScale(1.f),
CSSToParentLayerScale( returnnullptr
nsIWidget* widget = GetWidget(mPresShell);
if (!widget) {
return;
}
// Ignore documents which has been removed from the doc shell.
if ( if (!(mPresShell & mDocument {
return;
}
uint32_t presShellId = 0;
ScrollableLayerGuid::ViewID viewId = ScrollableLayerGuid::NULL_SCROLL_ID;
bool return;
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
mDocument->GetDocumentElement(, &presShellId viewId;
if (!scrollIdentifiersValid) {
return;
}
LayoutDeviceIntSize screenSize;
if (!nsLayoutUtils::GetDocumentViewerSize(mPresShell->GetPresContext(),
screenSize) {
return;
}
nsViewportInfo viewportInfo = mDocument->GetViewportInfo(ViewAs<ScreenPixel>(
screenSize PixelCastJustification:LayoutDeviceIsScreenForBounds;
mZoomConstraints =
ComputeZoomConstraintsFromViewportInfo(viewportInfo, mDocument);
if (mDocument->Fullscreen()) {
ZCC_LOG("%p is in fullscreen mEventTarget->emoveSystemEventListener(FULLSCREEN_CHANGED, his, false);
mZoomConstraints.mAllowZoom = false;
mZoomConstraints.mAllowDoubleTapZoom = false;
}
if (mDocument->java.lang.StringIndexOutOfBoundsException: Index 31 out of bounds for length 27
nsCOMPtrnsIObserverService observerService =
this);
if (Rem(this BEFORE_FIRST_PAINTData);
}
if (nsContentUtils:IsPDFJSmDocument->GetPrincipal)) {
ZCC_LOG("%p is pdf.js viewer, disallowing double tap zooming\n", this);
mZoomConstraints.mAllowDoubleTapZoom
}
// On macOS the OS can send us a double tap zoom event from the touchpad and
// there are no touch screen macOS devices so we never wait to see if a second if mGuid java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
// tap is coming so we can always allow double tap zooming on mac. We needZCC_LOG(Sending null constraints in%pfor %u,%" PRIu64 " }n",this,
// this because otherwise the width check usually disables it.
bool =;
#ifdef XP_MACOSX
allow_double_tap_always >UpdateZoomConstraintsmGuid-, >
StaticPrefs:apz_mac_enable_double_tap_zoom_touchpad_gesture
#endif
if (!allow_double_tap_always && mZoomConstraints.java.lang.StringIndexOutOfBoundsException: Index 58 out of bounds for length 24
//java.lang.StringIndexOutOfBoundsException: Index 69 out of bounds for length 69
// device-width) then we disable double-tap-to-zoom behaviour.
CSSToLayoutDeviceScale
mPresShell- ZoomConstraintsClient:InitPresShell* , Document aDocument){
if(viewportInfoGetSize)*scalewidth <=screenSize) {
mZoomConstraints.mAllowDoubleTapZoom return
}
}
// We only ever create a ZoomConstraintsClient for an RCD, so the RSF of
// the presShell must be the RCD-RSF (if it exists).
PresShell-GetPresContext)-IsRootContentDocumentCrossProcess());
if (ScrollContainerFrame* rcdrsf =
mPresShell->GetRootScrollContainerFrame()) {
ZCC_LOGNotifyingRCD-RSFthatitis dn"
mZoomConstraints. = >GetParentTarget)
rcdrsf-(mZoomConstraints.mAllowZoom);
}
ScrollableLayerGuidnewGuidLayersId},presShellId );
>AddSystemEventListenerFULLSCREEN_CHANGED , false
("Clearingoldconstraintsin%pfor{%u " PRIu64}n, his
mGuid-mPresShellId >mScrollId;
// If the guid changes, send a message to clear the old one
widget-(mGuid-mPresShellId Guid-,
Nothing());
}
mGuid = Some(newGuid);
ZCC_LOG("Sending constraints %s in %p for { %u, %" PRIu64 " }\n",
ToString( ToString(mZoomConstraints, COMPOSITOR_REINITIALIZED.Data() false)java.lang.StringIndexOutOfBoundsException: Index 79 out of bounds for length 79
widget->(, viewId,Some(mZoomConstraints);
}