Bug 1287576 - Update the touch-behavior notification code to behave like the set-target-apzc notification code. r?botond
In particular, this change uses the root frame of the touch target document,
so that the correct presShell resolution is used when doing the touch-action
hit test.
MozReview-Commit-ID: LIHi8J1ZNzw
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -2004,21 +2004,21 @@ TabChild::RecvRealTouchEvent(const Widge
WidgetTouchEvent localEvent(aEvent);
localEvent.mWidget = mPuppetWidget;
APZCCallbackHelper::ApplyCallbackTransform(localEvent, aGuid,
mPuppetWidget->GetDefaultScale());
if (localEvent.mMessage == eTouchStart && AsyncPanZoomEnabled()) {
+ nsCOMPtr<nsIDocument> document = GetDocument();
if (gfxPrefs::TouchActionEnabled()) {
APZCCallbackHelper::SendSetAllowedTouchBehaviorNotification(mPuppetWidget,
- localEvent, aInputBlockId, mSetAllowedTouchBehaviorCallback);
+ document, localEvent, aInputBlockId, mSetAllowedTouchBehaviorCallback);
}
- nsCOMPtr<nsIDocument> document = GetDocument();
APZCCallbackHelper::SendSetTargetAPZCNotification(mPuppetWidget, document,
localEvent, aGuid, aInputBlockId);
}
// Dispatch event to content (potentially a long-running operation)
nsEventStatus status = APZCCallbackHelper::DispatchWidgetEvent(localEvent);
if (!AsyncPanZoomEnabled()) {
--- a/gfx/layers/apz/util/APZCCallbackHelper.cpp
+++ b/gfx/layers/apz/util/APZCCallbackHelper.cpp
@@ -773,27 +773,34 @@ APZCCallbackHelper::SendSetTargetAPZCNot
}
}
}
}
void
APZCCallbackHelper::SendSetAllowedTouchBehaviorNotification(
nsIWidget* aWidget,
+ nsIDocument* aDocument,
const WidgetTouchEvent& aEvent,
uint64_t aInputBlockId,
const SetAllowedTouchBehaviorCallback& aCallback)
{
- nsTArray<TouchBehaviorFlags> flags;
- for (uint32_t i = 0; i < aEvent.mTouches.Length(); i++) {
- flags.AppendElement(
- TouchActionHelper::GetAllowedTouchBehavior(aWidget,
- aEvent.mTouches[i]->mRefPoint));
+ if (nsIPresShell* shell = aDocument->GetShell()) {
+ if (nsIFrame* rootFrame = shell->GetRootFrame()) {
+ rootFrame = UpdateRootFrameForTouchTargetDocument(rootFrame);
+
+ nsTArray<TouchBehaviorFlags> flags;
+ for (uint32_t i = 0; i < aEvent.mTouches.Length(); i++) {
+ flags.AppendElement(
+ TouchActionHelper::GetAllowedTouchBehavior(aWidget,
+ rootFrame, aEvent.mTouches[i]->mRefPoint));
+ }
+ aCallback(aInputBlockId, Move(flags));
+ }
}
- aCallback(aInputBlockId, Move(flags));
}
void
APZCCallbackHelper::NotifyMozMouseScrollEvent(const FrameMetrics::ViewID& aScrollId, const nsString& aEvent)
{
nsCOMPtr<nsIContent> targetContent = nsLayoutUtils::FindContentFor(aScrollId);
if (!targetContent) {
return;
--- a/gfx/layers/apz/util/APZCCallbackHelper.h
+++ b/gfx/layers/apz/util/APZCCallbackHelper.h
@@ -136,16 +136,17 @@ public:
nsIDocument* aDocument,
const WidgetGUIEvent& aEvent,
const ScrollableLayerGuid& aGuid,
uint64_t aInputBlockId);
/* Figure out the allowed touch behaviors of each touch point in |aEvent|
* and send that information to the provided callback. */
static void SendSetAllowedTouchBehaviorNotification(nsIWidget* aWidget,
+ nsIDocument* aDocument,
const WidgetTouchEvent& aEvent,
uint64_t aInputBlockId,
const SetAllowedTouchBehaviorCallback& aCallback);
/* Notify content of a mouse scroll testing event. */
static void NotifyMozMouseScrollEvent(const FrameMetrics::ViewID& aScrollId, const nsString& aEvent);
/* Notify content that the repaint flush is complete. */
--- a/gfx/layers/apz/util/TouchActionHelper.cpp
+++ b/gfx/layers/apz/util/TouchActionHelper.cpp
@@ -4,17 +4,16 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "TouchActionHelper.h"
#include "mozilla/layers/APZCTreeManager.h"
#include "nsContainerFrame.h"
#include "nsIScrollableFrame.h"
#include "nsLayoutUtils.h"
-#include "nsView.h"
namespace mozilla {
namespace layers {
void
TouchActionHelper::UpdateAllowedBehavior(uint32_t aTouchActionValue,
bool aConsiderPanning,
TouchBehaviorFlags& aOutBehavior)
@@ -41,32 +40,26 @@ TouchActionHelper::UpdateAllowedBehavior
} else if ((aTouchActionValue & NS_STYLE_TOUCH_ACTION_PAN_Y) && !(aTouchActionValue & NS_STYLE_TOUCH_ACTION_PAN_X)) {
aOutBehavior &= ~AllowedTouchBehavior::HORIZONTAL_PAN;
}
}
}
TouchBehaviorFlags
TouchActionHelper::GetAllowedTouchBehavior(nsIWidget* aWidget,
+ nsIFrame* aRootFrame,
const LayoutDeviceIntPoint& aPoint)
{
- nsView *view = nsView::GetViewFor(aWidget);
TouchBehaviorFlags behavior = AllowedTouchBehavior::VERTICAL_PAN | AllowedTouchBehavior::HORIZONTAL_PAN |
AllowedTouchBehavior::PINCH_ZOOM | AllowedTouchBehavior::DOUBLE_TAP_ZOOM;
- if (!view) {
- return behavior;
- }
+ nsPoint relativePoint =
+ nsLayoutUtils::GetEventCoordinatesRelativeTo(aWidget, aPoint, aRootFrame);
- nsIFrame *viewFrame = view->GetFrame();
-
- nsPoint relativePoint =
- nsLayoutUtils::GetEventCoordinatesRelativeTo(aWidget, aPoint, viewFrame);
-
- nsIFrame *target = nsLayoutUtils::GetFrameForPoint(viewFrame, relativePoint, nsLayoutUtils::IGNORE_ROOT_SCROLL_FRAME);
+ nsIFrame *target = nsLayoutUtils::GetFrameForPoint(aRootFrame, relativePoint, nsLayoutUtils::IGNORE_ROOT_SCROLL_FRAME);
if (!target) {
return behavior;
}
nsIScrollableFrame *nearestScrollableParent = nsLayoutUtils::GetNearestScrollableFrame(target, 0);
nsIFrame* nearestScrollableFrame = do_QueryFrame(nearestScrollableParent);
// We're walking up the DOM tree until we meet the element with touch behavior and accumulating
// touch-action restrictions of all elements in this chain.
--- a/gfx/layers/apz/util/TouchActionHelper.h
+++ b/gfx/layers/apz/util/TouchActionHelper.h
@@ -3,16 +3,17 @@
* 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/. */
#ifndef __mozilla_layers_TouchActionHelper_h__
#define __mozilla_layers_TouchActionHelper_h__
#include "mozilla/layers/APZUtils.h" // for TouchBehaviorFlags
+class nsIFrame;
class nsIWidget;
namespace mozilla {
namespace layers {
/*
* Helper class to figure out the allowed touch behavior for frames, as per
* the touch-action spec.
@@ -26,15 +27,16 @@ private:
public:
/*
* Performs hit testing on content, finds frame that corresponds to the aPoint and retrieves
* touch-action css property value from it according the rules specified in the spec:
* http://www.w3.org/TR/pointerevents/#the-touch-action-css-property.
*/
static TouchBehaviorFlags GetAllowedTouchBehavior(nsIWidget* aWidget,
+ nsIFrame* aRootFrame,
const LayoutDeviceIntPoint& aPoint);
};
} // namespace layers
} // namespace mozilla
#endif /*__mozilla_layers_TouchActionHelper_h__ */
--- a/widget/nsBaseWidget.cpp
+++ b/widget/nsBaseWidget.cpp
@@ -1116,17 +1116,17 @@ nsBaseWidget::ProcessUntransformedAPZEve
// EventStateManager did not route the event into the child process.
// It's safe to communicate to APZ that the event has been processed.
// TODO: Eventually we'll be able to move the SendSetTargetAPZCNotification
// call into APZEventState::Process*Event() as well.
if (WidgetTouchEvent* touchEvent = aEvent->AsTouchEvent()) {
if (touchEvent->mMessage == eTouchStart) {
if (gfxPrefs::TouchActionEnabled()) {
APZCCallbackHelper::SendSetAllowedTouchBehaviorNotification(this,
- *(original->AsTouchEvent()), aInputBlockId,
+ GetDocument(), *(original->AsTouchEvent()), aInputBlockId,
mSetAllowedTouchBehaviorCallback);
}
APZCCallbackHelper::SendSetTargetAPZCNotification(this, GetDocument(),
*(original->AsTouchEvent()), aGuid, aInputBlockId);
}
mAPZEventState->ProcessTouchEvent(*touchEvent, aGuid, aInputBlockId,
aApzResponse, status);
} else if (WidgetWheelEvent* wheelEvent = aEvent->AsWheelEvent()) {