/src/mozilla-central/layout/base/MobileViewportManager.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* vim: set ts=8 sts=2 et sw=2 tw=80: */ |
3 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
4 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
5 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
6 | | |
7 | | #include "MobileViewportManager.h" |
8 | | |
9 | | #include "gfxPrefs.h" |
10 | | #include "LayersLogging.h" |
11 | | #include "mozilla/PresShell.h" |
12 | | #include "mozilla/dom/Event.h" |
13 | | #include "mozilla/dom/EventTarget.h" |
14 | | #include "nsIFrame.h" |
15 | | #include "nsLayoutUtils.h" |
16 | | #include "nsViewManager.h" |
17 | | #include "nsViewportInfo.h" |
18 | | #include "UnitTransforms.h" |
19 | | #include "nsIDocument.h" |
20 | | |
21 | | #define MVM_LOG(...) |
22 | | // #define MVM_LOG(...) printf_stderr("MVM: " __VA_ARGS__) |
23 | | |
24 | | NS_IMPL_ISUPPORTS(MobileViewportManager, nsIDOMEventListener, nsIObserver) |
25 | | |
26 | 0 | #define DOM_META_ADDED NS_LITERAL_STRING("DOMMetaAdded") |
27 | 0 | #define DOM_META_CHANGED NS_LITERAL_STRING("DOMMetaChanged") |
28 | 0 | #define FULL_ZOOM_CHANGE NS_LITERAL_STRING("FullZoomChange") |
29 | 0 | #define LOAD NS_LITERAL_STRING("load") |
30 | 0 | #define BEFORE_FIRST_PAINT NS_LITERAL_CSTRING("before-first-paint") |
31 | | |
32 | | using namespace mozilla; |
33 | | using namespace mozilla::layers; |
34 | | |
35 | | MobileViewportManager::MobileViewportManager(nsIPresShell* aPresShell, |
36 | | nsIDocument* aDocument) |
37 | | : mDocument(aDocument) |
38 | | , mPresShell(aPresShell) |
39 | | , mIsFirstPaint(false) |
40 | | , mPainted(false) |
41 | 0 | { |
42 | 0 | MOZ_ASSERT(mPresShell); |
43 | 0 | MOZ_ASSERT(mDocument); |
44 | 0 |
|
45 | 0 | MVM_LOG("%p: creating with presShell %p document %p\n", this, mPresShell, aDocument); |
46 | 0 |
|
47 | 0 | if (nsCOMPtr<nsPIDOMWindowOuter> window = mDocument->GetWindow()) { |
48 | 0 | mEventTarget = window->GetChromeEventHandler(); |
49 | 0 | } |
50 | 0 | if (mEventTarget) { |
51 | 0 | mEventTarget->AddEventListener(DOM_META_ADDED, this, false); |
52 | 0 | mEventTarget->AddEventListener(DOM_META_CHANGED, this, false); |
53 | 0 | mEventTarget->AddEventListener(FULL_ZOOM_CHANGE, this, false); |
54 | 0 | mEventTarget->AddEventListener(LOAD, this, true); |
55 | 0 | } |
56 | 0 |
|
57 | 0 | nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService(); |
58 | 0 | if (observerService) { |
59 | 0 | observerService->AddObserver(this, BEFORE_FIRST_PAINT.Data(), false); |
60 | 0 | } |
61 | 0 | } |
62 | | |
63 | | MobileViewportManager::~MobileViewportManager() |
64 | 0 | { |
65 | 0 | } |
66 | | |
67 | | void |
68 | | MobileViewportManager::Destroy() |
69 | 0 | { |
70 | 0 | MVM_LOG("%p: destroying\n", this); |
71 | 0 |
|
72 | 0 | if (mEventTarget) { |
73 | 0 | mEventTarget->RemoveEventListener(DOM_META_ADDED, this, false); |
74 | 0 | mEventTarget->RemoveEventListener(DOM_META_CHANGED, this, false); |
75 | 0 | mEventTarget->RemoveEventListener(FULL_ZOOM_CHANGE, this, false); |
76 | 0 | mEventTarget->RemoveEventListener(LOAD, this, true); |
77 | 0 | mEventTarget = nullptr; |
78 | 0 | } |
79 | 0 |
|
80 | 0 | nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService(); |
81 | 0 | if (observerService) { |
82 | 0 | observerService->RemoveObserver(this, BEFORE_FIRST_PAINT.Data()); |
83 | 0 | } |
84 | 0 |
|
85 | 0 | mDocument = nullptr; |
86 | 0 | mPresShell = nullptr; |
87 | 0 | } |
88 | | |
89 | | void |
90 | | MobileViewportManager::SetRestoreResolution(float aResolution, |
91 | | LayoutDeviceIntSize aDisplaySize) |
92 | 0 | { |
93 | 0 | SetRestoreResolution(aResolution); |
94 | 0 | ScreenIntSize restoreDisplaySize = ViewAs<ScreenPixel>(aDisplaySize, |
95 | 0 | PixelCastJustification::LayoutDeviceIsScreenForBounds); |
96 | 0 | mRestoreDisplaySize = Some(restoreDisplaySize); |
97 | 0 | } |
98 | | |
99 | | void |
100 | | MobileViewportManager::SetRestoreResolution(float aResolution) |
101 | 0 | { |
102 | 0 | mRestoreResolution = Some(aResolution); |
103 | 0 | } |
104 | | |
105 | | void |
106 | | MobileViewportManager::RequestReflow() |
107 | 0 | { |
108 | 0 | MVM_LOG("%p: got a reflow request\n", this); |
109 | 0 | RefreshViewportSize(false); |
110 | 0 | } |
111 | | |
112 | | void |
113 | | MobileViewportManager::ResolutionUpdated() |
114 | 0 | { |
115 | 0 | MVM_LOG("%p: resolution updated\n", this); |
116 | 0 | if (!mPainted) { |
117 | 0 | // Save the value, so our default zoom calculation |
118 | 0 | // can take it into account later on. |
119 | 0 | SetRestoreResolution(mPresShell->GetResolution()); |
120 | 0 | } |
121 | 0 | RefreshVisualViewportSize(); |
122 | 0 | } |
123 | | |
124 | | NS_IMETHODIMP |
125 | | MobileViewportManager::HandleEvent(dom::Event* event) |
126 | 0 | { |
127 | 0 | nsAutoString type; |
128 | 0 | event->GetType(type); |
129 | 0 |
|
130 | 0 | if (type.Equals(DOM_META_ADDED)) { |
131 | 0 | MVM_LOG("%p: got a dom-meta-added event\n", this); |
132 | 0 | RefreshViewportSize(mPainted); |
133 | 0 | } else if (type.Equals(DOM_META_CHANGED)) { |
134 | 0 | MVM_LOG("%p: got a dom-meta-changed event\n", this); |
135 | 0 | RefreshViewportSize(mPainted); |
136 | 0 | } else if (type.Equals(FULL_ZOOM_CHANGE)) { |
137 | 0 | MVM_LOG("%p: got a full-zoom-change event\n", this); |
138 | 0 | RefreshViewportSize(false); |
139 | 0 | } else if (type.Equals(LOAD)) { |
140 | 0 | MVM_LOG("%p: got a load event\n", this); |
141 | 0 | if (!mPainted) { |
142 | 0 | // Load event got fired before the before-first-paint message |
143 | 0 | SetInitialViewport(); |
144 | 0 | } |
145 | 0 | } |
146 | 0 | return NS_OK; |
147 | 0 | } |
148 | | |
149 | | NS_IMETHODIMP |
150 | | MobileViewportManager::Observe(nsISupports* aSubject, const char* aTopic, const char16_t* aData) |
151 | 0 | { |
152 | 0 | if (SameCOMIdentity(aSubject, mDocument) && BEFORE_FIRST_PAINT.EqualsASCII(aTopic)) { |
153 | 0 | MVM_LOG("%p: got a before-first-paint event\n", this); |
154 | 0 | if (!mPainted) { |
155 | 0 | // before-first-paint message arrived before load event |
156 | 0 | SetInitialViewport(); |
157 | 0 | } |
158 | 0 | } |
159 | 0 | return NS_OK; |
160 | 0 | } |
161 | | |
162 | | void |
163 | | MobileViewportManager::SetInitialViewport() |
164 | 0 | { |
165 | 0 | MVM_LOG("%p: setting initial viewport\n", this); |
166 | 0 | mIsFirstPaint = true; |
167 | 0 | mPainted = true; |
168 | 0 | RefreshViewportSize(false); |
169 | 0 | } |
170 | | |
171 | | CSSToScreenScale |
172 | | MobileViewportManager::ClampZoom(const CSSToScreenScale& aZoom, |
173 | | const nsViewportInfo& aViewportInfo) |
174 | 0 | { |
175 | 0 | CSSToScreenScale zoom = aZoom; |
176 | 0 | if (zoom < aViewportInfo.GetMinZoom()) { |
177 | 0 | zoom = aViewportInfo.GetMinZoom(); |
178 | 0 | MVM_LOG("%p: Clamped to %f\n", this, zoom.scale); |
179 | 0 | } |
180 | 0 | if (zoom > aViewportInfo.GetMaxZoom()) { |
181 | 0 | zoom = aViewportInfo.GetMaxZoom(); |
182 | 0 | MVM_LOG("%p: Clamped to %f\n", this, zoom.scale); |
183 | 0 | } |
184 | 0 | return zoom; |
185 | 0 | } |
186 | | |
187 | | LayoutDeviceToLayerScale |
188 | | MobileViewportManager::ScaleResolutionWithDisplayWidth(const LayoutDeviceToLayerScale& aRes, |
189 | | const float& aDisplayWidthChangeRatio, |
190 | | const CSSSize& aNewViewport, |
191 | | const CSSSize& aOldViewport) |
192 | 0 | { |
193 | 0 | float cssViewportChangeRatio = (aOldViewport.width == 0) |
194 | 0 | ? 1.0f : aNewViewport.width / aOldViewport.width; |
195 | 0 | LayoutDeviceToLayerScale newRes(aRes.scale * aDisplayWidthChangeRatio |
196 | 0 | / cssViewportChangeRatio); |
197 | 0 | MVM_LOG("%p: Old resolution was %f, changed by %f/%f to %f\n", this, aRes.scale, |
198 | 0 | aDisplayWidthChangeRatio, cssViewportChangeRatio, newRes.scale); |
199 | 0 | return newRes; |
200 | 0 | } |
201 | | |
202 | | CSSToScreenScale |
203 | | MobileViewportManager::UpdateResolution(const nsViewportInfo& aViewportInfo, |
204 | | const ScreenIntSize& aDisplaySize, |
205 | | const CSSSize& aViewport, |
206 | | const Maybe<float>& aDisplayWidthChangeRatio) |
207 | 0 | { |
208 | 0 | CSSToLayoutDeviceScale cssToDev = |
209 | 0 | mPresShell->GetPresContext()->CSSToDevPixelScale(); |
210 | 0 | LayoutDeviceToLayerScale res(mPresShell->GetResolution()); |
211 | 0 |
|
212 | 0 | if (mIsFirstPaint) { |
213 | 0 | CSSToScreenScale defaultZoom; |
214 | 0 | if (mRestoreResolution) { |
215 | 0 | LayoutDeviceToLayerScale restoreResolution(mRestoreResolution.value()); |
216 | 0 | if (mRestoreDisplaySize) { |
217 | 0 | CSSSize prevViewport = mDocument->GetViewportInfo(mRestoreDisplaySize.value()).GetSize(); |
218 | 0 | float restoreDisplayWidthChangeRatio = (mRestoreDisplaySize.value().width > 0) |
219 | 0 | ? (float)aDisplaySize.width / (float)mRestoreDisplaySize.value().width : 1.0f; |
220 | 0 |
|
221 | 0 | restoreResolution = |
222 | 0 | ScaleResolutionWithDisplayWidth(restoreResolution, |
223 | 0 | restoreDisplayWidthChangeRatio, |
224 | 0 | aViewport, |
225 | 0 | prevViewport); |
226 | 0 | } |
227 | 0 | defaultZoom = CSSToScreenScale(restoreResolution.scale * cssToDev.scale); |
228 | 0 | MVM_LOG("%p: restored zoom is %f\n", this, defaultZoom.scale); |
229 | 0 | defaultZoom = ClampZoom(defaultZoom, aViewportInfo); |
230 | 0 | } else { |
231 | 0 | defaultZoom = aViewportInfo.GetDefaultZoom(); |
232 | 0 | MVM_LOG("%p: default zoom from viewport is %f\n", this, defaultZoom.scale); |
233 | 0 | if (!aViewportInfo.IsDefaultZoomValid()) { |
234 | 0 | defaultZoom = MaxScaleRatio(ScreenSize(aDisplaySize), aViewport); |
235 | 0 | MVM_LOG("%p: Intrinsic computed zoom is %f\n", this, defaultZoom.scale); |
236 | 0 | defaultZoom = ClampZoom(defaultZoom, aViewportInfo); |
237 | 0 | } |
238 | 0 | } |
239 | 0 | MOZ_ASSERT(aViewportInfo.GetMinZoom() <= defaultZoom && |
240 | 0 | defaultZoom <= aViewportInfo.GetMaxZoom()); |
241 | 0 |
|
242 | 0 | CSSToParentLayerScale zoom = ViewTargetAs<ParentLayerPixel>(defaultZoom, |
243 | 0 | PixelCastJustification::ScreenIsParentLayerForRoot); |
244 | 0 |
|
245 | 0 | LayoutDeviceToLayerScale resolution = zoom / cssToDev * ParentLayerToLayerScale(1); |
246 | 0 | MVM_LOG("%p: setting resolution %f\n", this, resolution.scale); |
247 | 0 | mPresShell->SetResolutionAndScaleTo(resolution.scale); |
248 | 0 |
|
249 | 0 | return defaultZoom; |
250 | 0 | } |
251 | 0 |
|
252 | 0 | // If this is not a first paint, then in some cases we want to update the pre- |
253 | 0 | // existing resolution so as to maintain how much actual content is visible |
254 | 0 | // within the display width. Note that "actual content" may be different with |
255 | 0 | // respect to CSS pixels because of the CSS viewport size changing. |
256 | 0 | // |
257 | 0 | // aDisplayWidthChangeRatio is non-empty if: |
258 | 0 | // (a) The meta-viewport tag information changes, and so the CSS viewport |
259 | 0 | // might change as a result. If this happens after the content has been |
260 | 0 | // painted, we want to adjust the zoom to compensate. OR |
261 | 0 | // (b) The display size changed from a nonzero value to another nonzero value. |
262 | 0 | // This covers the case where e.g. the device was rotated, and again we |
263 | 0 | // want to adjust the zoom to compensate. |
264 | 0 | // Note in particular that aDisplayWidthChangeRatio will be None if all that |
265 | 0 | // happened was a change in the full-zoom. In this case, we still want to |
266 | 0 | // compute a new CSS viewport, but we don't want to update the resolution. |
267 | 0 | // |
268 | 0 | // Given the above, the algorithm below accounts for all types of changes I |
269 | 0 | // can conceive of: |
270 | 0 | // 1. screen size changes, CSS viewport does not (pages with no meta viewport |
271 | 0 | // or a fixed size viewport) |
272 | 0 | // 2. screen size changes, CSS viewport also does (pages with a device-width |
273 | 0 | // viewport) |
274 | 0 | // 3. screen size remains constant, but CSS viewport changes (meta viewport |
275 | 0 | // tag is added or removed) |
276 | 0 | // 4. neither screen size nor CSS viewport changes |
277 | 0 | if (aDisplayWidthChangeRatio) { |
278 | 0 | res = ScaleResolutionWithDisplayWidth(res, aDisplayWidthChangeRatio.value(), |
279 | 0 | aViewport, mMobileViewportSize); |
280 | 0 | mPresShell->SetResolutionAndScaleTo(res.scale); |
281 | 0 | } |
282 | 0 |
|
283 | 0 | return ViewTargetAs<ScreenPixel>(cssToDev * res / ParentLayerToLayerScale(1), |
284 | 0 | PixelCastJustification::ScreenIsParentLayerForRoot); |
285 | 0 | } |
286 | | |
287 | | void |
288 | | MobileViewportManager::UpdateVisualViewportSize(const ScreenIntSize& aDisplaySize, |
289 | | const CSSToScreenScale& aZoom) |
290 | 0 | { |
291 | 0 | ScreenSize compositionSize(aDisplaySize); |
292 | 0 | ScreenMargin scrollbars = |
293 | 0 | LayoutDeviceMargin::FromAppUnits( |
294 | 0 | nsLayoutUtils::ScrollbarAreaToExcludeFromCompositionBoundsFor( |
295 | 0 | mPresShell->GetRootScrollFrame()), |
296 | 0 | mPresShell->GetPresContext()->AppUnitsPerDevPixel()) |
297 | 0 | // Scrollbars are not subject to resolution scaling, so LD pixels = |
298 | 0 | // Screen pixels for them. |
299 | 0 | * LayoutDeviceToScreenScale(1.0f); |
300 | 0 |
|
301 | 0 | compositionSize.width -= scrollbars.LeftRight(); |
302 | 0 | compositionSize.height -= scrollbars.TopBottom(); |
303 | 0 | CSSSize compSize = compositionSize / aZoom; |
304 | 0 | MVM_LOG("%p: Setting VVPS %s\n", this, Stringify(compSize).c_str()); |
305 | 0 | nsLayoutUtils::SetVisualViewportSize(mPresShell, compSize); |
306 | 0 | } |
307 | | |
308 | | void |
309 | | MobileViewportManager::UpdateDisplayPortMargins() |
310 | 0 | { |
311 | 0 | if (nsIFrame* root = mPresShell->GetRootScrollFrame()) { |
312 | 0 | bool hasDisplayPort = nsLayoutUtils::HasDisplayPort(root->GetContent()); |
313 | 0 | bool hasResolution = mPresShell->ScaleToResolution() && |
314 | 0 | mPresShell->GetResolution() != 1.0f; |
315 | 0 | if (!hasDisplayPort && !hasResolution) { |
316 | 0 | // We only want to update the displayport if there is one already, or |
317 | 0 | // add one if there's a resolution on the document (see bug 1225508 |
318 | 0 | // comment 1). |
319 | 0 | return; |
320 | 0 | } |
321 | 0 | nsRect displayportBase = |
322 | 0 | nsRect(nsPoint(0, 0), nsLayoutUtils::CalculateCompositionSizeForFrame(root)); |
323 | 0 | // We only create MobileViewportManager for root content documents. If that ever changes |
324 | 0 | // we'd need to limit the size of this displayport base rect because non-toplevel documents |
325 | 0 | // have no limit on their size. |
326 | 0 | MOZ_ASSERT(mPresShell->GetPresContext()->IsRootContentDocument()); |
327 | 0 | nsLayoutUtils::SetDisplayPortBaseIfNotSet(root->GetContent(), displayportBase); |
328 | 0 | nsIScrollableFrame* scrollable = do_QueryFrame(root); |
329 | 0 | nsLayoutUtils::CalculateAndSetDisplayPortMargins(scrollable, |
330 | 0 | nsLayoutUtils::RepaintMode::DoNotRepaint); |
331 | 0 | } |
332 | 0 | } |
333 | | |
334 | | void |
335 | | MobileViewportManager::RefreshVisualViewportSize() |
336 | 0 | { |
337 | 0 | // This function is a subset of RefreshViewportSize, and only updates the |
338 | 0 | // visual viewport size. |
339 | 0 |
|
340 | 0 | if (!gfxPrefs::APZAllowZooming()) { |
341 | 0 | return; |
342 | 0 | } |
343 | 0 | |
344 | 0 | ScreenIntSize displaySize = ViewAs<ScreenPixel>( |
345 | 0 | mDisplaySize, PixelCastJustification::LayoutDeviceIsScreenForBounds); |
346 | 0 |
|
347 | 0 | CSSToLayoutDeviceScale cssToDev = |
348 | 0 | mPresShell->GetPresContext()->CSSToDevPixelScale(); |
349 | 0 | LayoutDeviceToLayerScale res(mPresShell->GetResolution()); |
350 | 0 | CSSToScreenScale zoom = ViewTargetAs<ScreenPixel>(cssToDev * res / ParentLayerToLayerScale(1), |
351 | 0 | PixelCastJustification::ScreenIsParentLayerForRoot); |
352 | 0 |
|
353 | 0 | UpdateVisualViewportSize(displaySize, zoom); |
354 | 0 | } |
355 | | |
356 | | void |
357 | | MobileViewportManager::RefreshViewportSize(bool aForceAdjustResolution) |
358 | 0 | { |
359 | 0 | // This function gets called by the various triggers that may result in a |
360 | 0 | // change of the CSS viewport. In some of these cases (e.g. the meta-viewport |
361 | 0 | // tag changes) we want to update the resolution and in others (e.g. the full |
362 | 0 | // zoom changing) we don't want to update the resolution. See the comment in |
363 | 0 | // UpdateResolution for some more detail on this. An important assumption we |
364 | 0 | // make here is that this RefreshViewportSize function will be called |
365 | 0 | // separately for each trigger that changes. For instance it should never get |
366 | 0 | // called such that both the full zoom and the meta-viewport tag have changed; |
367 | 0 | // instead it would get called twice - once after each trigger changes. This |
368 | 0 | // assumption is what allows the aForceAdjustResolution parameter to work as |
369 | 0 | // intended; if this assumption is violated then we will need to add extra |
370 | 0 | // complicated logic in UpdateResolution to ensure we only do the resolution |
371 | 0 | // update in the right scenarios. |
372 | 0 |
|
373 | 0 | Maybe<float> displayWidthChangeRatio; |
374 | 0 | LayoutDeviceIntSize newDisplaySize; |
375 | 0 | if (nsLayoutUtils::GetContentViewerSize(mPresShell->GetPresContext(), newDisplaySize)) { |
376 | 0 | // See the comment in UpdateResolution for why we're doing this. |
377 | 0 | if (mDisplaySize.width > 0) { |
378 | 0 | if (aForceAdjustResolution || mDisplaySize.width != newDisplaySize.width) { |
379 | 0 | displayWidthChangeRatio = Some((float)newDisplaySize.width / (float)mDisplaySize.width); |
380 | 0 | } |
381 | 0 | } else if (aForceAdjustResolution) { |
382 | 0 | displayWidthChangeRatio = Some(1.0f); |
383 | 0 | } |
384 | 0 |
|
385 | 0 | MVM_LOG("%p: Display width change ratio is %f\n", this, displayWidthChangeRatio.valueOr(0.0f)); |
386 | 0 | mDisplaySize = newDisplaySize; |
387 | 0 | } |
388 | 0 |
|
389 | 0 | MVM_LOG("%p: Computing CSS viewport using %d,%d\n", this, |
390 | 0 | mDisplaySize.width, mDisplaySize.height); |
391 | 0 | if (mDisplaySize.width == 0 || mDisplaySize.height == 0) { |
392 | 0 | // We can't do anything useful here, we should just bail out |
393 | 0 | return; |
394 | 0 | } |
395 | 0 | |
396 | 0 | ScreenIntSize displaySize = ViewAs<ScreenPixel>( |
397 | 0 | mDisplaySize, PixelCastJustification::LayoutDeviceIsScreenForBounds); |
398 | 0 | nsViewportInfo viewportInfo = mDocument->GetViewportInfo(displaySize); |
399 | 0 |
|
400 | 0 | CSSSize viewport = viewportInfo.GetSize(); |
401 | 0 | MVM_LOG("%p: Computed CSS viewport %s\n", this, Stringify(viewport).c_str()); |
402 | 0 |
|
403 | 0 | if (!mIsFirstPaint && mMobileViewportSize == viewport) { |
404 | 0 | // Nothing changed, so no need to do a reflow |
405 | 0 | return; |
406 | 0 | } |
407 | 0 | |
408 | 0 | // If it's the first-paint or the viewport changed, we need to update |
409 | 0 | // various APZ properties (the zoom and some things that might depend on it) |
410 | 0 | MVM_LOG("%p: Updating properties because %d || %d\n", this, |
411 | 0 | mIsFirstPaint, mMobileViewportSize != viewport); |
412 | 0 |
|
413 | 0 | if (gfxPrefs::APZAllowZooming()) { |
414 | 0 | CSSToScreenScale zoom = UpdateResolution(viewportInfo, displaySize, viewport, |
415 | 0 | displayWidthChangeRatio); |
416 | 0 | MVM_LOG("%p: New zoom is %f\n", this, zoom.scale); |
417 | 0 | UpdateVisualViewportSize(displaySize, zoom); |
418 | 0 | } |
419 | 0 | if (gfxPlatform::AsyncPanZoomEnabled()) { |
420 | 0 | UpdateDisplayPortMargins(); |
421 | 0 | } |
422 | 0 |
|
423 | 0 | CSSSize oldSize = mMobileViewportSize; |
424 | 0 |
|
425 | 0 | // Update internal state. |
426 | 0 | mIsFirstPaint = false; |
427 | 0 | mMobileViewportSize = viewport; |
428 | 0 |
|
429 | 0 | // Kick off a reflow. |
430 | 0 | mPresShell->ResizeReflowIgnoreOverride( |
431 | 0 | nsPresContext::CSSPixelsToAppUnits(viewport.width), |
432 | 0 | nsPresContext::CSSPixelsToAppUnits(viewport.height), |
433 | 0 | nsPresContext::CSSPixelsToAppUnits(oldSize.width), |
434 | 0 | nsPresContext::CSSPixelsToAppUnits(oldSize.height)); |
435 | 0 | } |