Bug 1869043 allow a device to be specified with MediaTrackGraph::NotifyWhenDeviceStar...
[gecko.git] / layout / base / GeckoMVMContext.cpp
blob85bb21b85ea995fca248575b072561a7cf6becdf
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "GeckoMVMContext.h"
7 #include "mozilla/DisplayPortUtils.h"
8 #include "mozilla/PresShell.h"
9 #include "mozilla/Services.h"
10 #include "mozilla/dom/Document.h"
11 #include "mozilla/dom/VisualViewport.h"
12 #include "nsCOMPtr.h"
13 #include "nsGlobalWindowInner.h"
14 #include "nsIDOMEventListener.h"
15 #include "nsIFrame.h"
16 #include "nsIObserverService.h"
17 #include "nsIScrollableFrame.h"
18 #include "nsLayoutUtils.h"
19 #include "nsPIDOMWindow.h"
20 #include "nsPresContext.h"
22 namespace mozilla {
24 GeckoMVMContext::GeckoMVMContext(dom::Document* aDocument,
25 PresShell* aPresShell)
26 : mDocument(aDocument), mPresShell(aPresShell) {
27 if (nsCOMPtr<nsPIDOMWindowOuter> window = mDocument->GetWindow()) {
28 mEventTarget = window->GetChromeEventHandler();
32 void GeckoMVMContext::AddEventListener(const nsAString& aType,
33 nsIDOMEventListener* aListener,
34 bool aUseCapture) {
35 if (mEventTarget) {
36 mEventTarget->AddEventListener(aType, aListener, aUseCapture);
40 void GeckoMVMContext::RemoveEventListener(const nsAString& aType,
41 nsIDOMEventListener* aListener,
42 bool aUseCapture) {
43 if (mEventTarget) {
44 mEventTarget->RemoveEventListener(aType, aListener, aUseCapture);
48 void GeckoMVMContext::AddObserver(nsIObserver* aObserver, const char* aTopic,
49 bool aOwnsWeak) {
50 if (nsCOMPtr<nsIObserverService> observerService =
51 services::GetObserverService()) {
52 observerService->AddObserver(aObserver, aTopic, aOwnsWeak);
56 void GeckoMVMContext::RemoveObserver(nsIObserver* aObserver,
57 const char* aTopic) {
58 if (nsCOMPtr<nsIObserverService> observerService =
59 services::GetObserverService()) {
60 observerService->RemoveObserver(aObserver, aTopic);
64 void GeckoMVMContext::Destroy() {
65 mEventTarget = nullptr;
66 mDocument = nullptr;
67 mPresShell = nullptr;
70 nsViewportInfo GeckoMVMContext::GetViewportInfo(
71 const ScreenIntSize& aDisplaySize) const {
72 MOZ_ASSERT(mDocument);
73 return mDocument->GetViewportInfo(aDisplaySize);
76 CSSToLayoutDeviceScale GeckoMVMContext::CSSToDevPixelScale() const {
77 MOZ_ASSERT(mPresShell);
78 return mPresShell->GetPresContext()->CSSToDevPixelScale();
81 float GeckoMVMContext::GetResolution() const {
82 MOZ_ASSERT(mPresShell);
83 return mPresShell->GetResolution();
86 bool GeckoMVMContext::SubjectMatchesDocument(nsISupports* aSubject) const {
87 MOZ_ASSERT(mDocument);
88 return SameCOMIdentity(aSubject, ToSupports(mDocument));
91 Maybe<CSSRect> GeckoMVMContext::CalculateScrollableRectForRSF() const {
92 MOZ_ASSERT(mPresShell);
93 if (nsIScrollableFrame* rootScrollableFrame =
94 mPresShell->GetRootScrollFrameAsScrollable()) {
95 return Some(
96 CSSRect::FromAppUnits(nsLayoutUtils::CalculateScrollableRectForFrame(
97 rootScrollableFrame, nullptr)));
99 return Nothing();
102 bool GeckoMVMContext::IsResolutionUpdatedByApz() const {
103 MOZ_ASSERT(mPresShell);
104 return mPresShell->IsResolutionUpdatedByApz();
107 LayoutDeviceMargin
108 GeckoMVMContext::ScrollbarAreaToExcludeFromCompositionBounds() const {
109 MOZ_ASSERT(mPresShell);
110 return LayoutDeviceMargin::FromAppUnits(
111 nsLayoutUtils::ScrollbarAreaToExcludeFromCompositionBoundsFor(
112 mPresShell->GetRootScrollFrame()),
113 mPresShell->GetPresContext()->AppUnitsPerDevPixel());
116 Maybe<LayoutDeviceIntSize> GeckoMVMContext::GetDocumentViewerSize() const {
117 MOZ_ASSERT(mPresShell);
118 LayoutDeviceIntSize result;
119 if (nsLayoutUtils::GetDocumentViewerSize(mPresShell->GetPresContext(),
120 result)) {
121 return Some(result);
123 return Nothing();
126 bool GeckoMVMContext::AllowZoomingForDocument() const {
127 MOZ_ASSERT(mDocument);
128 return nsLayoutUtils::AllowZoomingForDocument(mDocument);
131 bool GeckoMVMContext::IsInReaderMode() const {
132 MOZ_ASSERT(mDocument);
133 nsString uri;
134 if (NS_FAILED(mDocument->GetDocumentURI(uri))) {
135 return false;
137 static auto readerModeUriPrefix = u"about:reader"_ns;
138 return StringBeginsWith(uri, readerModeUriPrefix);
141 bool GeckoMVMContext::IsDocumentLoading() const {
142 MOZ_ASSERT(mDocument);
143 return mDocument->GetReadyStateEnum() == dom::Document::READYSTATE_LOADING;
146 void GeckoMVMContext::SetResolutionAndScaleTo(float aResolution,
147 ResolutionChangeOrigin aOrigin) {
148 MOZ_ASSERT(mPresShell);
149 mPresShell->SetResolutionAndScaleTo(aResolution, aOrigin);
152 void GeckoMVMContext::SetVisualViewportSize(const CSSSize& aSize) {
153 MOZ_ASSERT(mPresShell);
154 mPresShell->SetVisualViewportSize(
155 nsPresContext::CSSPixelsToAppUnits(aSize.width),
156 nsPresContext::CSSPixelsToAppUnits(aSize.height));
159 void GeckoMVMContext::PostVisualViewportResizeEventByDynamicToolbar() {
160 MOZ_ASSERT(mDocument);
162 // We only fire visual viewport events and don't want to cause any explicit
163 // reflows here since in general we don't use the up-to-date visual viewport
164 // size for layout.
165 if (auto* window = nsGlobalWindowInner::Cast(mDocument->GetInnerWindow())) {
166 window->VisualViewport()->PostResizeEvent();
170 void GeckoMVMContext::UpdateDisplayPortMargins() {
171 MOZ_ASSERT(mPresShell);
172 if (nsIFrame* root = mPresShell->GetRootScrollFrame()) {
173 nsIContent* content = root->GetContent();
174 bool hasDisplayPort = DisplayPortUtils::HasNonMinimalDisplayPort(content);
175 bool hasResolution = mPresShell->GetResolution() != 1.0f;
176 if (!hasDisplayPort && !hasResolution) {
177 // We only want to update the displayport if there is one already, or
178 // add one if there's a resolution on the document (see bug 1225508
179 // comment 1).
180 return;
182 nsRect displayportBase = nsRect(
183 nsPoint(0, 0), nsLayoutUtils::CalculateCompositionSizeForFrame(root));
184 // We only create MobileViewportManager for root content documents. If that
185 // ever changes we'd need to limit the size of this displayport base rect
186 // because non-toplevel documents have no limit on their size.
187 MOZ_ASSERT(
188 mPresShell->GetPresContext()->IsRootContentDocumentCrossProcess());
189 DisplayPortUtils::SetDisplayPortBaseIfNotSet(content, displayportBase);
190 nsIScrollableFrame* scrollable = do_QueryFrame(root);
191 DisplayPortUtils::CalculateAndSetDisplayPortMargins(
192 scrollable, DisplayPortUtils::RepaintMode::Repaint);
196 void GeckoMVMContext::Reflow(const CSSSize& aNewSize) {
197 RefPtr doc = mDocument;
198 RefPtr ps = mPresShell;
200 MOZ_ASSERT(doc);
201 MOZ_ASSERT(ps);
203 if (ps->ResizeReflowIgnoreOverride(CSSPixel::ToAppUnits(aNewSize.width),
204 CSSPixel::ToAppUnits(aNewSize.height))) {
205 doc->FlushPendingNotifications(FlushType::InterruptibleLayout);
209 ScreenIntCoord GeckoMVMContext::GetDynamicToolbarOffset() {
210 const nsPresContext* presContext = mPresShell->GetPresContext();
211 return presContext->HasDynamicToolbar()
212 ? presContext->GetDynamicToolbarMaxHeight() -
213 presContext->GetDynamicToolbarHeight()
214 : ScreenIntCoord(0);
217 } // namespace mozilla