/src/mozilla-central/gfx/layers/apz/util/APZEventState.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 "APZEventState.h" |
8 | | |
9 | | #include "ActiveElementManager.h" |
10 | | #include "APZCCallbackHelper.h" |
11 | | #include "gfxPrefs.h" |
12 | | #include "LayersLogging.h" |
13 | | #include "mozilla/BasicEvents.h" |
14 | | #include "mozilla/dom/MouseEventBinding.h" |
15 | | #include "mozilla/dom/TabChild.h" |
16 | | #include "mozilla/dom/TabGroup.h" |
17 | | #include "mozilla/IntegerPrintfMacros.h" |
18 | | #include "mozilla/Move.h" |
19 | | #include "mozilla/Preferences.h" |
20 | | #include "mozilla/TouchEvents.h" |
21 | | #include "mozilla/layers/APZCCallbackHelper.h" |
22 | | #include "nsCOMPtr.h" |
23 | | #include "nsDocShell.h" |
24 | | #include "nsIDOMWindowUtils.h" |
25 | | #include "nsINamed.h" |
26 | | #include "nsIScrollableFrame.h" |
27 | | #include "nsIScrollbarMediator.h" |
28 | | #include "nsITimer.h" |
29 | | #include "nsIWeakReferenceUtils.h" |
30 | | #include "nsIWidget.h" |
31 | | #include "nsLayoutUtils.h" |
32 | | #include "nsQueryFrame.h" |
33 | | #include "TouchManager.h" |
34 | | #include "nsLayoutUtils.h" |
35 | | #include "nsIScrollableFrame.h" |
36 | | #include "nsIScrollbarMediator.h" |
37 | | #include "mozilla/TouchEvents.h" |
38 | | #include "mozilla/widget/nsAutoRollup.h" |
39 | | |
40 | | #define APZES_LOG(...) |
41 | | // #define APZES_LOG(...) printf_stderr("APZES: " __VA_ARGS__) |
42 | | |
43 | | // Static helper functions |
44 | | namespace { |
45 | | |
46 | | int32_t |
47 | | WidgetModifiersToDOMModifiers(mozilla::Modifiers aModifiers) |
48 | 0 | { |
49 | 0 | int32_t result = 0; |
50 | 0 | if (aModifiers & mozilla::MODIFIER_SHIFT) { |
51 | 0 | result |= nsIDOMWindowUtils::MODIFIER_SHIFT; |
52 | 0 | } |
53 | 0 | if (aModifiers & mozilla::MODIFIER_CONTROL) { |
54 | 0 | result |= nsIDOMWindowUtils::MODIFIER_CONTROL; |
55 | 0 | } |
56 | 0 | if (aModifiers & mozilla::MODIFIER_ALT) { |
57 | 0 | result |= nsIDOMWindowUtils::MODIFIER_ALT; |
58 | 0 | } |
59 | 0 | if (aModifiers & mozilla::MODIFIER_META) { |
60 | 0 | result |= nsIDOMWindowUtils::MODIFIER_META; |
61 | 0 | } |
62 | 0 | if (aModifiers & mozilla::MODIFIER_ALTGRAPH) { |
63 | 0 | result |= nsIDOMWindowUtils::MODIFIER_ALTGRAPH; |
64 | 0 | } |
65 | 0 | if (aModifiers & mozilla::MODIFIER_CAPSLOCK) { |
66 | 0 | result |= nsIDOMWindowUtils::MODIFIER_CAPSLOCK; |
67 | 0 | } |
68 | 0 | if (aModifiers & mozilla::MODIFIER_FN) { |
69 | 0 | result |= nsIDOMWindowUtils::MODIFIER_FN; |
70 | 0 | } |
71 | 0 | if (aModifiers & mozilla::MODIFIER_FNLOCK) { |
72 | 0 | result |= nsIDOMWindowUtils::MODIFIER_FNLOCK; |
73 | 0 | } |
74 | 0 | if (aModifiers & mozilla::MODIFIER_NUMLOCK) { |
75 | 0 | result |= nsIDOMWindowUtils::MODIFIER_NUMLOCK; |
76 | 0 | } |
77 | 0 | if (aModifiers & mozilla::MODIFIER_SCROLLLOCK) { |
78 | 0 | result |= nsIDOMWindowUtils::MODIFIER_SCROLLLOCK; |
79 | 0 | } |
80 | 0 | if (aModifiers & mozilla::MODIFIER_SYMBOL) { |
81 | 0 | result |= nsIDOMWindowUtils::MODIFIER_SYMBOL; |
82 | 0 | } |
83 | 0 | if (aModifiers & mozilla::MODIFIER_SYMBOLLOCK) { |
84 | 0 | result |= nsIDOMWindowUtils::MODIFIER_SYMBOLLOCK; |
85 | 0 | } |
86 | 0 | if (aModifiers & mozilla::MODIFIER_OS) { |
87 | 0 | result |= nsIDOMWindowUtils::MODIFIER_OS; |
88 | 0 | } |
89 | 0 | return result; |
90 | 0 | } |
91 | | |
92 | | } // namespace |
93 | | |
94 | | namespace mozilla { |
95 | | namespace layers { |
96 | | |
97 | | static int32_t sActiveDurationMs = 10; |
98 | | static bool sActiveDurationMsSet = false; |
99 | | |
100 | | APZEventState::APZEventState(nsIWidget* aWidget, |
101 | | ContentReceivedInputBlockCallback&& aCallback) |
102 | | : mWidget(nullptr) // initialized in constructor body |
103 | | , mActiveElementManager(new ActiveElementManager()) |
104 | | , mContentReceivedInputBlockCallback(std::move(aCallback)) |
105 | | , mPendingTouchPreventedResponse(false) |
106 | | , mPendingTouchPreventedBlockId(0) |
107 | | , mEndTouchIsClick(false) |
108 | | , mTouchEndCancelled(false) |
109 | | , mLastTouchIdentifier(0) |
110 | 0 | { |
111 | 0 | nsresult rv; |
112 | 0 | mWidget = do_GetWeakReference(aWidget, &rv); |
113 | 0 | MOZ_ASSERT(NS_SUCCEEDED(rv), "APZEventState constructed with a widget that" |
114 | 0 | " does not support weak references. APZ will NOT work!"); |
115 | 0 |
|
116 | 0 | if (!sActiveDurationMsSet) { |
117 | 0 | Preferences::AddIntVarCache(&sActiveDurationMs, |
118 | 0 | "ui.touch_activation.duration_ms", |
119 | 0 | sActiveDurationMs); |
120 | 0 | sActiveDurationMsSet = true; |
121 | 0 | } |
122 | 0 | } |
123 | | |
124 | | APZEventState::~APZEventState() |
125 | 0 | {} |
126 | | |
127 | | class DelayedFireSingleTapEvent final : public nsITimerCallback |
128 | | , public nsINamed |
129 | | { |
130 | | public: |
131 | | NS_DECL_ISUPPORTS |
132 | | |
133 | | DelayedFireSingleTapEvent(nsWeakPtr aWidget, |
134 | | LayoutDevicePoint& aPoint, |
135 | | Modifiers aModifiers, |
136 | | int32_t aClickCount, |
137 | | nsITimer* aTimer, |
138 | | RefPtr<nsIContent>& aTouchRollup) |
139 | | : mWidget(aWidget) |
140 | | , mPoint(aPoint) |
141 | | , mModifiers(aModifiers) |
142 | | , mClickCount(aClickCount) |
143 | | // Hold the reference count until we are called back. |
144 | | , mTimer(aTimer) |
145 | | , mTouchRollup(aTouchRollup) |
146 | 0 | { |
147 | 0 | } |
148 | | |
149 | | NS_IMETHOD Notify(nsITimer*) override |
150 | 0 | { |
151 | 0 | if (nsCOMPtr<nsIWidget> widget = do_QueryReferent(mWidget)) { |
152 | 0 | widget::nsAutoRollup rollup(mTouchRollup.get()); |
153 | 0 | APZCCallbackHelper::FireSingleTapEvent(mPoint, mModifiers, mClickCount, widget); |
154 | 0 | } |
155 | 0 | mTimer = nullptr; |
156 | 0 | return NS_OK; |
157 | 0 | } |
158 | | |
159 | | NS_IMETHOD |
160 | | GetName(nsACString& aName) override |
161 | 0 | { |
162 | 0 | aName.AssignLiteral("DelayedFireSingleTapEvent"); |
163 | 0 | return NS_OK; |
164 | 0 | } |
165 | | |
166 | 0 | void ClearTimer() { |
167 | 0 | mTimer = nullptr; |
168 | 0 | } |
169 | | |
170 | | private: |
171 | | ~DelayedFireSingleTapEvent() |
172 | 0 | { |
173 | 0 | } |
174 | | |
175 | | nsWeakPtr mWidget; |
176 | | LayoutDevicePoint mPoint; |
177 | | Modifiers mModifiers; |
178 | | int32_t mClickCount; |
179 | | nsCOMPtr<nsITimer> mTimer; |
180 | | RefPtr<nsIContent> mTouchRollup; |
181 | | }; |
182 | | |
183 | | NS_IMPL_ISUPPORTS(DelayedFireSingleTapEvent, nsITimerCallback, nsINamed) |
184 | | |
185 | | void |
186 | | APZEventState::ProcessSingleTap(const CSSPoint& aPoint, |
187 | | const CSSToLayoutDeviceScale& aScale, |
188 | | Modifiers aModifiers, |
189 | | const ScrollableLayerGuid& aGuid, |
190 | | int32_t aClickCount) |
191 | 0 | { |
192 | 0 | APZES_LOG("Handling single tap at %s on %s with %d\n", |
193 | 0 | Stringify(aPoint).c_str(), Stringify(aGuid).c_str(), mTouchEndCancelled); |
194 | 0 |
|
195 | 0 | RefPtr<nsIContent> touchRollup = GetTouchRollup(); |
196 | 0 | mTouchRollup = nullptr; |
197 | 0 |
|
198 | 0 | nsCOMPtr<nsIWidget> widget = GetWidget(); |
199 | 0 | if (!widget) { |
200 | 0 | return; |
201 | 0 | } |
202 | 0 | |
203 | 0 | if (mTouchEndCancelled) { |
204 | 0 | return; |
205 | 0 | } |
206 | 0 | |
207 | 0 | LayoutDevicePoint ldPoint = aPoint * aScale; |
208 | 0 |
|
209 | 0 | APZES_LOG("Scheduling timer for click event\n"); |
210 | 0 | nsCOMPtr<nsITimer> timer = NS_NewTimer(); |
211 | 0 | dom::TabChild* tabChild = widget->GetOwningTabChild(); |
212 | 0 |
|
213 | 0 | if (tabChild && XRE_IsContentProcess()) { |
214 | 0 | timer->SetTarget( |
215 | 0 | tabChild->TabGroup()->EventTargetFor(TaskCategory::Other)); |
216 | 0 | } |
217 | 0 | RefPtr<DelayedFireSingleTapEvent> callback = |
218 | 0 | new DelayedFireSingleTapEvent(mWidget, ldPoint, aModifiers, aClickCount, |
219 | 0 | timer, touchRollup); |
220 | 0 | nsresult rv = timer->InitWithCallback(callback, |
221 | 0 | sActiveDurationMs, |
222 | 0 | nsITimer::TYPE_ONE_SHOT); |
223 | 0 | if (NS_FAILED(rv)) { |
224 | 0 | // Make |callback| not hold the timer, so they will both be destructed when |
225 | 0 | // we leave the scope of this function. |
226 | 0 | callback->ClearTimer(); |
227 | 0 | } |
228 | 0 | } |
229 | | |
230 | | bool |
231 | | APZEventState::FireContextmenuEvents(const nsCOMPtr<nsIPresShell>& aPresShell, |
232 | | const CSSPoint& aPoint, |
233 | | const CSSToLayoutDeviceScale& aScale, |
234 | | Modifiers aModifiers, |
235 | | const nsCOMPtr<nsIWidget>& aWidget) |
236 | 0 | { |
237 | 0 | // Converting the modifiers to DOM format for the DispatchMouseEvent call |
238 | 0 | // is the most useless thing ever because nsDOMWindowUtils::SendMouseEvent |
239 | 0 | // just converts them back to widget format, but that API has many callers, |
240 | 0 | // including in JS code, so it's not trivial to change. |
241 | 0 | bool eventHandled = |
242 | 0 | APZCCallbackHelper::DispatchMouseEvent(aPresShell, NS_LITERAL_STRING("contextmenu"), |
243 | 0 | aPoint, 2, 1, WidgetModifiersToDOMModifiers(aModifiers), true, |
244 | 0 | dom::MouseEvent_Binding::MOZ_SOURCE_TOUCH, |
245 | 0 | 0 /* Use the default value here. */); |
246 | 0 |
|
247 | 0 | APZES_LOG("Contextmenu event handled: %d\n", eventHandled); |
248 | 0 | if (eventHandled) { |
249 | 0 | // If the contextmenu event was handled then we're showing a contextmenu, |
250 | 0 | // and so we should remove any activation |
251 | 0 | mActiveElementManager->ClearActivation(); |
252 | 0 | #ifndef XP_WIN |
253 | 0 | } else { |
254 | 0 | // If the contextmenu wasn't consumed, fire the eMouseLongTap event. |
255 | 0 | nsEventStatus status = APZCCallbackHelper::DispatchSynthesizedMouseEvent( |
256 | 0 | eMouseLongTap, /*time*/ 0, aPoint * aScale, aModifiers, |
257 | 0 | /*clickCount*/ 1, aWidget); |
258 | 0 | eventHandled = (status == nsEventStatus_eConsumeNoDefault); |
259 | 0 | APZES_LOG("eMouseLongTap event handled: %d\n", eventHandled); |
260 | 0 | #endif |
261 | 0 | } |
262 | 0 |
|
263 | 0 | return eventHandled; |
264 | 0 | } |
265 | | |
266 | | void |
267 | | APZEventState::ProcessLongTap(const nsCOMPtr<nsIPresShell>& aPresShell, |
268 | | const CSSPoint& aPoint, |
269 | | const CSSToLayoutDeviceScale& aScale, |
270 | | Modifiers aModifiers, |
271 | | const ScrollableLayerGuid& aGuid, |
272 | | uint64_t aInputBlockId) |
273 | 0 | { |
274 | 0 | APZES_LOG("Handling long tap at %s\n", Stringify(aPoint).c_str()); |
275 | 0 |
|
276 | 0 | nsCOMPtr<nsIWidget> widget = GetWidget(); |
277 | 0 | if (!widget) { |
278 | 0 | return; |
279 | 0 | } |
280 | 0 | |
281 | 0 | SendPendingTouchPreventedResponse(false); |
282 | 0 |
|
283 | | #ifdef XP_WIN |
284 | | // On Windows, we fire the contextmenu events when the user lifts their |
285 | | // finger, in keeping with the platform convention. This happens in the |
286 | | // ProcessLongTapUp function. However, we still fire the eMouseLongTap event |
287 | | // at this time, because things like text selection or dragging may want |
288 | | // to know about it. |
289 | | nsEventStatus status = APZCCallbackHelper::DispatchSynthesizedMouseEvent( |
290 | | eMouseLongTap, /*time*/ 0, aPoint * aScale, aModifiers, /*clickCount*/ 1, |
291 | | widget); |
292 | | |
293 | | bool eventHandled = (status == nsEventStatus_eConsumeNoDefault); |
294 | | #else |
295 | | bool eventHandled = FireContextmenuEvents(aPresShell, aPoint, aScale, |
296 | 0 | aModifiers, widget); |
297 | 0 | #endif |
298 | 0 | mContentReceivedInputBlockCallback(aGuid, aInputBlockId, eventHandled); |
299 | 0 |
|
300 | 0 | if (eventHandled) { |
301 | 0 | // Also send a touchcancel to content, so that listeners that might be |
302 | 0 | // waiting for a touchend don't trigger. |
303 | 0 | WidgetTouchEvent cancelTouchEvent(true, eTouchCancel, widget.get()); |
304 | 0 | cancelTouchEvent.mModifiers = aModifiers; |
305 | 0 | auto ldPoint = LayoutDeviceIntPoint::Round(aPoint * aScale); |
306 | 0 | cancelTouchEvent.mTouches.AppendElement(new mozilla::dom::Touch(mLastTouchIdentifier, |
307 | 0 | ldPoint, LayoutDeviceIntPoint(), 0, 0)); |
308 | 0 | APZCCallbackHelper::DispatchWidgetEvent(cancelTouchEvent); |
309 | 0 | } |
310 | 0 | } |
311 | | |
312 | | void |
313 | | APZEventState::ProcessLongTapUp(const nsCOMPtr<nsIPresShell>& aPresShell, |
314 | | const CSSPoint& aPoint, |
315 | | const CSSToLayoutDeviceScale& aScale, |
316 | | Modifiers aModifiers) |
317 | 0 | { |
318 | | #ifdef XP_WIN |
319 | | nsCOMPtr<nsIWidget> widget = GetWidget(); |
320 | | if (widget) { |
321 | | FireContextmenuEvents(aPresShell, aPoint, aScale, aModifiers, widget); |
322 | | } |
323 | | #endif |
324 | | } |
325 | | |
326 | | void |
327 | | APZEventState::ProcessTouchEvent(const WidgetTouchEvent& aEvent, |
328 | | const ScrollableLayerGuid& aGuid, |
329 | | uint64_t aInputBlockId, |
330 | | nsEventStatus aApzResponse, |
331 | | nsEventStatus aContentResponse) |
332 | 0 | { |
333 | 0 | if (aEvent.mMessage == eTouchStart && aEvent.mTouches.Length() > 0) { |
334 | 0 | mActiveElementManager->SetTargetElement(aEvent.mTouches[0]->GetTarget()); |
335 | 0 | mLastTouchIdentifier = aEvent.mTouches[0]->Identifier(); |
336 | 0 | } |
337 | 0 |
|
338 | 0 | bool isTouchPrevented = aContentResponse == nsEventStatus_eConsumeNoDefault; |
339 | 0 | bool sentContentResponse = false; |
340 | 0 | APZES_LOG("Handling event type %d\n", aEvent.mMessage); |
341 | 0 | switch (aEvent.mMessage) { |
342 | 0 | case eTouchStart: { |
343 | 0 | mTouchEndCancelled = false; |
344 | 0 | mTouchRollup = do_GetWeakReference(widget::nsAutoRollup::GetLastRollup()); |
345 | 0 |
|
346 | 0 | sentContentResponse = SendPendingTouchPreventedResponse(false); |
347 | 0 | // sentContentResponse can be true here if we get two TOUCH_STARTs in a row |
348 | 0 | // and just responded to the first one. |
349 | 0 |
|
350 | 0 | // We're about to send a response back to APZ, but we should only do it |
351 | 0 | // for events that went through APZ (which should be all of them). |
352 | 0 | MOZ_ASSERT(aEvent.mFlags.mHandledByAPZ); |
353 | 0 |
|
354 | 0 | if (isTouchPrevented) { |
355 | 0 | mContentReceivedInputBlockCallback(aGuid, aInputBlockId, isTouchPrevented); |
356 | 0 | sentContentResponse = true; |
357 | 0 | } else { |
358 | 0 | APZES_LOG("Event not prevented; pending response for %" PRIu64 " %s\n", |
359 | 0 | aInputBlockId, Stringify(aGuid).c_str()); |
360 | 0 | mPendingTouchPreventedResponse = true; |
361 | 0 | mPendingTouchPreventedGuid = aGuid; |
362 | 0 | mPendingTouchPreventedBlockId = aInputBlockId; |
363 | 0 | } |
364 | 0 | break; |
365 | 0 | } |
366 | 0 |
|
367 | 0 | case eTouchEnd: |
368 | 0 | if (isTouchPrevented) { |
369 | 0 | mTouchEndCancelled = true; |
370 | 0 | mEndTouchIsClick = false; |
371 | 0 | } |
372 | 0 | MOZ_FALLTHROUGH; |
373 | 0 | case eTouchCancel: |
374 | 0 | mActiveElementManager->HandleTouchEndEvent(mEndTouchIsClick); |
375 | 0 | MOZ_FALLTHROUGH; |
376 | 0 | case eTouchMove: { |
377 | 0 | if (mPendingTouchPreventedResponse) { |
378 | 0 | MOZ_ASSERT(aGuid == mPendingTouchPreventedGuid); |
379 | 0 | } |
380 | 0 | sentContentResponse = SendPendingTouchPreventedResponse(isTouchPrevented); |
381 | 0 | break; |
382 | 0 | } |
383 | 0 |
|
384 | 0 | default: |
385 | 0 | MOZ_ASSERT_UNREACHABLE("Unknown touch event type"); |
386 | 0 | break; |
387 | 0 | } |
388 | 0 |
|
389 | 0 | if (sentContentResponse && !isTouchPrevented && |
390 | 0 | aApzResponse == nsEventStatus_eConsumeDoDefault && |
391 | 0 | gfxPrefs::PointerEventsEnabled()) { |
392 | 0 | WidgetTouchEvent cancelEvent(aEvent); |
393 | 0 | cancelEvent.mMessage = eTouchPointerCancel; |
394 | 0 | cancelEvent.mFlags.mCancelable = false; // mMessage != eTouchCancel; |
395 | 0 | for (uint32_t i = 0; i < cancelEvent.mTouches.Length(); ++i) { |
396 | 0 | if (mozilla::dom::Touch* touch = cancelEvent.mTouches[i]) { |
397 | 0 | touch->convertToPointer = true; |
398 | 0 | } |
399 | 0 | } |
400 | 0 | nsEventStatus status; |
401 | 0 | cancelEvent.mWidget->DispatchEvent(&cancelEvent, status); |
402 | 0 | } |
403 | 0 | } |
404 | | |
405 | | void |
406 | | APZEventState::ProcessWheelEvent(const WidgetWheelEvent& aEvent, |
407 | | const ScrollableLayerGuid& aGuid, |
408 | | uint64_t aInputBlockId) |
409 | 0 | { |
410 | 0 | // If this event starts a swipe, indicate that it shouldn't result in a |
411 | 0 | // scroll by setting defaultPrevented to true. |
412 | 0 | bool defaultPrevented = aEvent.DefaultPrevented() || aEvent.TriggersSwipe(); |
413 | 0 | mContentReceivedInputBlockCallback(aGuid, aInputBlockId, defaultPrevented); |
414 | 0 | } |
415 | | |
416 | | void |
417 | | APZEventState::ProcessMouseEvent(const WidgetMouseEvent& aEvent, |
418 | | const ScrollableLayerGuid& aGuid, |
419 | | uint64_t aInputBlockId) |
420 | 0 | { |
421 | 0 | bool defaultPrevented = false; |
422 | 0 | mContentReceivedInputBlockCallback(aGuid, aInputBlockId, defaultPrevented); |
423 | 0 | } |
424 | | |
425 | | void |
426 | | APZEventState::ProcessAPZStateChange(ViewID aViewId, |
427 | | APZStateChange aChange, |
428 | | int aArg) |
429 | 0 | { |
430 | 0 | switch (aChange) |
431 | 0 | { |
432 | 0 | case APZStateChange::eTransformBegin: |
433 | 0 | { |
434 | 0 | nsIScrollableFrame* sf = nsLayoutUtils::FindScrollableFrameFor(aViewId); |
435 | 0 | if (sf) { |
436 | 0 | sf->SetTransformingByAPZ(true); |
437 | 0 | } |
438 | 0 | nsIScrollbarMediator* scrollbarMediator = do_QueryFrame(sf); |
439 | 0 | if (scrollbarMediator) { |
440 | 0 | scrollbarMediator->ScrollbarActivityStarted(); |
441 | 0 | } |
442 | 0 |
|
443 | 0 | nsIContent* content = nsLayoutUtils::FindContentFor(aViewId); |
444 | 0 | nsIDocument* doc = content ? content->GetComposedDoc() : nullptr; |
445 | 0 | nsCOMPtr<nsIDocShell> docshell(doc ? doc->GetDocShell() : nullptr); |
446 | 0 | if (docshell && sf) { |
447 | 0 | nsDocShell* nsdocshell = static_cast<nsDocShell*>(docshell.get()); |
448 | 0 | nsdocshell->NotifyAsyncPanZoomStarted(); |
449 | 0 | } |
450 | 0 | break; |
451 | 0 | } |
452 | 0 | case APZStateChange::eTransformEnd: |
453 | 0 | { |
454 | 0 | nsIScrollableFrame* sf = nsLayoutUtils::FindScrollableFrameFor(aViewId); |
455 | 0 | if (sf) { |
456 | 0 | sf->SetTransformingByAPZ(false); |
457 | 0 | } |
458 | 0 | nsIScrollbarMediator* scrollbarMediator = do_QueryFrame(sf); |
459 | 0 | if (scrollbarMediator) { |
460 | 0 | scrollbarMediator->ScrollbarActivityStopped(); |
461 | 0 | } |
462 | 0 |
|
463 | 0 | nsIContent* content = nsLayoutUtils::FindContentFor(aViewId); |
464 | 0 | nsIDocument* doc = content ? content->GetComposedDoc() : nullptr; |
465 | 0 | nsCOMPtr<nsIDocShell> docshell(doc ? doc->GetDocShell() : nullptr); |
466 | 0 | if (docshell && sf) { |
467 | 0 | nsDocShell* nsdocshell = static_cast<nsDocShell*>(docshell.get()); |
468 | 0 | nsdocshell->NotifyAsyncPanZoomStopped(); |
469 | 0 | } |
470 | 0 | break; |
471 | 0 | } |
472 | 0 | case APZStateChange::eStartTouch: |
473 | 0 | { |
474 | 0 | mActiveElementManager->HandleTouchStart(aArg); |
475 | 0 | break; |
476 | 0 | } |
477 | 0 | case APZStateChange::eStartPanning: |
478 | 0 | { |
479 | 0 | // The user started to pan, so we don't want anything to be :active. |
480 | 0 | mActiveElementManager->ClearActivation(); |
481 | 0 | break; |
482 | 0 | } |
483 | 0 | case APZStateChange::eEndTouch: |
484 | 0 | { |
485 | 0 | mEndTouchIsClick = aArg; |
486 | 0 | mActiveElementManager->HandleTouchEnd(); |
487 | 0 | break; |
488 | 0 | } |
489 | 0 | } |
490 | 0 | } |
491 | | |
492 | | void |
493 | | APZEventState::ProcessClusterHit() |
494 | 0 | { |
495 | 0 | // If we hit a cluster of links then we shouldn't activate any of them, |
496 | 0 | // as we will be showing the zoomed view. (This is only called on Fennec). |
497 | 0 | #ifndef MOZ_WIDGET_ANDROID |
498 | 0 | MOZ_ASSERT(false); |
499 | 0 | #endif |
500 | 0 | mActiveElementManager->ClearActivation(); |
501 | 0 | } |
502 | | |
503 | | bool |
504 | | APZEventState::SendPendingTouchPreventedResponse(bool aPreventDefault) |
505 | 0 | { |
506 | 0 | if (mPendingTouchPreventedResponse) { |
507 | 0 | APZES_LOG("Sending response %d for pending guid: %s\n", aPreventDefault, |
508 | 0 | Stringify(mPendingTouchPreventedGuid).c_str()); |
509 | 0 | mContentReceivedInputBlockCallback(mPendingTouchPreventedGuid, |
510 | 0 | mPendingTouchPreventedBlockId, aPreventDefault); |
511 | 0 | mPendingTouchPreventedResponse = false; |
512 | 0 | return true; |
513 | 0 | } |
514 | 0 | return false; |
515 | 0 | } |
516 | | |
517 | | already_AddRefed<nsIWidget> |
518 | | APZEventState::GetWidget() const |
519 | 0 | { |
520 | 0 | nsCOMPtr<nsIWidget> result = do_QueryReferent(mWidget); |
521 | 0 | return result.forget(); |
522 | 0 | } |
523 | | |
524 | | already_AddRefed<nsIContent> |
525 | | APZEventState::GetTouchRollup() const |
526 | 0 | { |
527 | 0 | nsCOMPtr<nsIContent> result = do_QueryReferent(mTouchRollup); |
528 | 0 | return result.forget(); |
529 | 0 | } |
530 | | |
531 | | } // namespace layers |
532 | | } // namespace mozilla |