mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 914829 - MetroInput should forward touch input to apz first, then to content. r=kats, tabraldes
This commit is contained in:
parent
29cf090b6f
commit
217abb186c
@ -213,6 +213,7 @@ ApplyTransform(nsIntPoint* aPoint, const gfx3DMatrix& aMatrix)
|
|||||||
nsEventStatus
|
nsEventStatus
|
||||||
APZCTreeManager::ReceiveInputEvent(const InputData& aEvent)
|
APZCTreeManager::ReceiveInputEvent(const InputData& aEvent)
|
||||||
{
|
{
|
||||||
|
nsEventStatus result = nsEventStatus_eIgnore;
|
||||||
gfx3DMatrix transformToApzc;
|
gfx3DMatrix transformToApzc;
|
||||||
gfx3DMatrix transformToScreen;
|
gfx3DMatrix transformToScreen;
|
||||||
switch (aEvent.mInputType) {
|
switch (aEvent.mInputType) {
|
||||||
@ -238,7 +239,7 @@ APZCTreeManager::ReceiveInputEvent(const InputData& aEvent)
|
|||||||
for (size_t i = 0; i < inputForApzc.mTouches.Length(); i++) {
|
for (size_t i = 0; i < inputForApzc.mTouches.Length(); i++) {
|
||||||
ApplyTransform(&(inputForApzc.mTouches[i].mScreenPoint), transformToApzc);
|
ApplyTransform(&(inputForApzc.mTouches[i].mScreenPoint), transformToApzc);
|
||||||
}
|
}
|
||||||
mApzcForInputBlock->ReceiveInputEvent(inputForApzc);
|
result = mApzcForInputBlock->ReceiveInputEvent(inputForApzc);
|
||||||
// If we have an mApzcForInputBlock and it's the end of the touch sequence
|
// If we have an mApzcForInputBlock and it's the end of the touch sequence
|
||||||
// then null it out so we don't keep a dangling reference and leak things.
|
// then null it out so we don't keep a dangling reference and leak things.
|
||||||
if (multiTouchInput.mType == MultiTouchInput::MULTITOUCH_CANCEL ||
|
if (multiTouchInput.mType == MultiTouchInput::MULTITOUCH_CANCEL ||
|
||||||
@ -254,7 +255,7 @@ APZCTreeManager::ReceiveInputEvent(const InputData& aEvent)
|
|||||||
GetInputTransforms(apzc, transformToApzc, transformToScreen);
|
GetInputTransforms(apzc, transformToApzc, transformToScreen);
|
||||||
PinchGestureInput inputForApzc(pinchInput);
|
PinchGestureInput inputForApzc(pinchInput);
|
||||||
ApplyTransform(&(inputForApzc.mFocusPoint), transformToApzc);
|
ApplyTransform(&(inputForApzc.mFocusPoint), transformToApzc);
|
||||||
apzc->ReceiveInputEvent(inputForApzc);
|
result = apzc->ReceiveInputEvent(inputForApzc);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
} case TAPGESTURE_INPUT: {
|
} case TAPGESTURE_INPUT: {
|
||||||
@ -264,12 +265,12 @@ APZCTreeManager::ReceiveInputEvent(const InputData& aEvent)
|
|||||||
GetInputTransforms(apzc, transformToApzc, transformToScreen);
|
GetInputTransforms(apzc, transformToApzc, transformToScreen);
|
||||||
TapGestureInput inputForApzc(tapInput);
|
TapGestureInput inputForApzc(tapInput);
|
||||||
ApplyTransform(&(inputForApzc.mPoint), transformToApzc);
|
ApplyTransform(&(inputForApzc.mPoint), transformToApzc);
|
||||||
apzc->ReceiveInputEvent(inputForApzc);
|
result = apzc->ReceiveInputEvent(inputForApzc);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nsEventStatus_eIgnore;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsEventStatus
|
nsEventStatus
|
||||||
|
@ -179,6 +179,20 @@ namespace {
|
|||||||
aData->mChanged = false;
|
aData->mChanged = false;
|
||||||
return PL_DHASH_NEXT;
|
return PL_DHASH_NEXT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper for making sure event ptrs get freed.
|
||||||
|
class AutoDeleteEvent
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AutoDeleteEvent(nsGUIEvent* aPtr) :
|
||||||
|
mPtr(aPtr) {}
|
||||||
|
~AutoDeleteEvent() {
|
||||||
|
if (mPtr) {
|
||||||
|
delete mPtr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nsGUIEvent* mPtr;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
@ -431,6 +445,8 @@ MetroInput::OnPointerPressed(UI::Core::ICoreWindow* aSender,
|
|||||||
mTouchStartDefaultPrevented = false;
|
mTouchStartDefaultPrevented = false;
|
||||||
mTouchMoveDefaultPrevented = false;
|
mTouchMoveDefaultPrevented = false;
|
||||||
mIsFirstTouchMove = true;
|
mIsFirstTouchMove = true;
|
||||||
|
mCancelable = true;
|
||||||
|
mTouchCancelSent = false;
|
||||||
InitTouchEventTouchList(touchEvent);
|
InitTouchEventTouchList(touchEvent);
|
||||||
DispatchAsyncTouchEventWithCallback(touchEvent, &MetroInput::OnPointerPressedCallback);
|
DispatchAsyncTouchEventWithCallback(touchEvent, &MetroInput::OnPointerPressedCallback);
|
||||||
} else {
|
} else {
|
||||||
@ -449,10 +465,12 @@ MetroInput::OnPointerPressedCallback()
|
|||||||
{
|
{
|
||||||
nsEventStatus status = DeliverNextQueuedTouchEvent();
|
nsEventStatus status = DeliverNextQueuedTouchEvent();
|
||||||
mTouchStartDefaultPrevented = (nsEventStatus_eConsumeNoDefault == status);
|
mTouchStartDefaultPrevented = (nsEventStatus_eConsumeNoDefault == status);
|
||||||
// If content cancelled the first touchstart don't generate any gesture based
|
|
||||||
// input - clear the recognizer state without sending any events.
|
|
||||||
if (mTouchStartDefaultPrevented) {
|
if (mTouchStartDefaultPrevented) {
|
||||||
|
// If content canceled the first touchstart don't generate any gesture based
|
||||||
|
// input - clear the recognizer state without sending any events.
|
||||||
mGestureRecognizer->CompleteGesture();
|
mGestureRecognizer->CompleteGesture();
|
||||||
|
// Let the apz know content wants to consume touch events.
|
||||||
|
mWidget->ApzContentConsumingTouch();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -549,12 +567,15 @@ MetroInput::OnPointerMoved(UI::Core::ICoreWindow* aSender,
|
|||||||
void
|
void
|
||||||
MetroInput::OnFirstPointerMoveCallback()
|
MetroInput::OnFirstPointerMoveCallback()
|
||||||
{
|
{
|
||||||
nsTouchEvent* event = static_cast<nsTouchEvent*>(mInputEventQueue.PopFront());
|
nsEventStatus status = DeliverNextQueuedTouchEvent();
|
||||||
MOZ_ASSERT(event);
|
mCancelable = false;
|
||||||
nsEventStatus status;
|
|
||||||
mWidget->DispatchEvent(event, status);
|
|
||||||
mTouchMoveDefaultPrevented = (nsEventStatus_eConsumeNoDefault == status);
|
mTouchMoveDefaultPrevented = (nsEventStatus_eConsumeNoDefault == status);
|
||||||
delete event;
|
// Let the apz know whether content wants to consume touch events
|
||||||
|
if (mTouchMoveDefaultPrevented) {
|
||||||
|
mWidget->ApzContentConsumingTouch();
|
||||||
|
} else if (!mTouchMoveDefaultPrevented && !mTouchStartDefaultPrevented) {
|
||||||
|
mWidget->ApzContentIgnoringTouch();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This event is raised when the user lifts the left mouse button, lifts a
|
// This event is raised when the user lifts the left mouse button, lifts a
|
||||||
@ -1096,19 +1117,69 @@ MetroInput::DispatchAsyncTouchEventIgnoreStatus(nsTouchEvent* aEvent)
|
|||||||
nsEventStatus
|
nsEventStatus
|
||||||
MetroInput::DeliverNextQueuedTouchEvent()
|
MetroInput::DeliverNextQueuedTouchEvent()
|
||||||
{
|
{
|
||||||
|
nsEventStatus status;
|
||||||
nsTouchEvent* event = static_cast<nsTouchEvent*>(mInputEventQueue.PopFront());
|
nsTouchEvent* event = static_cast<nsTouchEvent*>(mInputEventQueue.PopFront());
|
||||||
MOZ_ASSERT(event);
|
MOZ_ASSERT(event);
|
||||||
nsEventStatus status;
|
|
||||||
|
AutoDeleteEvent wrap(event);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We go through states here and make different decisions in each:
|
||||||
|
*
|
||||||
|
* 1) delivering first touchpoint touchstart or its first touchmove
|
||||||
|
* Our callers (OnFirstPointerMoveCallback, OnPointerPressedCallback) will
|
||||||
|
* check our result and set mTouchStartDefaultPrevented or
|
||||||
|
* mTouchMoveDefaultPrevented appropriately. Deliver touch events to the apz
|
||||||
|
* (ignoring return result) and to content and return the content event
|
||||||
|
* status result to our caller.
|
||||||
|
* 2) mTouchStartDefaultPrevented or mTouchMoveDefaultPrevented are true
|
||||||
|
* Deliver touch directly to content and bypass the apz. Our callers
|
||||||
|
* handle calling cancel for the touch sequence on the apz.
|
||||||
|
* 3) mTouchStartDefaultPrevented and mTouchMoveDefaultPrevented are false
|
||||||
|
* Deliver events to the apz. If the apz returns eConsumeNoDefault dispatch
|
||||||
|
* a touchcancel to content and do not deliver any additional events there.
|
||||||
|
* (If the apz is doing something with the events we can save ourselves
|
||||||
|
* the overhead of delivering dom events.)
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Check if content called preventDefault on touchstart or first touchmove. If so
|
||||||
|
// send directly to content, do not forward to the apz.
|
||||||
|
if (mTouchStartDefaultPrevented || mTouchMoveDefaultPrevented) {
|
||||||
|
// continue delivering events to content
|
||||||
mWidget->DispatchEvent(event, status);
|
mWidget->DispatchEvent(event, status);
|
||||||
// Deliver to the apz if content has *not* cancelled touchstart or the first touchmove.
|
|
||||||
if (!mTouchStartDefaultPrevented && !mTouchMoveDefaultPrevented && MetroWidget::sAPZC) {
|
|
||||||
MultiTouchInput inputData(*event);
|
|
||||||
MetroWidget::sAPZC->ReceiveInputEvent(inputData);
|
|
||||||
}
|
|
||||||
delete event;
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Forward event data to apz. If the apz consumes the event, don't forward to
|
||||||
|
// content if this is not a cancelable event.
|
||||||
|
status = mWidget->ApzReceiveInputEvent(event);
|
||||||
|
if (!mCancelable && status == nsEventStatus_eConsumeNoDefault) {
|
||||||
|
if (!mTouchCancelSent) {
|
||||||
|
mTouchCancelSent = true;
|
||||||
|
DispatchTouchCancel();
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Deliver event to content
|
||||||
|
mWidget->DispatchEvent(event, status);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MetroInput::DispatchTouchCancel()
|
||||||
|
{
|
||||||
|
LogFunction();
|
||||||
|
// From the spec: The touch point or points that were removed must be
|
||||||
|
// included in the changedTouches attribute of the TouchEvent, and must
|
||||||
|
// not be included in the touches and targetTouches attributes.
|
||||||
|
// (We are 'removing' all touch points that have been sent to content
|
||||||
|
// thus far.)
|
||||||
|
nsTouchEvent touchEvent(true, NS_TOUCH_CANCEL, mWidget.Get());
|
||||||
|
InitTouchEventTouchList(&touchEvent);
|
||||||
|
mWidget->DispatchEvent(&touchEvent, sThrowawayStatus);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MetroInput::DispatchAsyncTouchEventWithCallback(nsTouchEvent* aEvent, void (MetroInput::*Callback)())
|
MetroInput::DispatchAsyncTouchEventWithCallback(nsTouchEvent* aEvent, void (MetroInput::*Callback)())
|
||||||
{
|
{
|
||||||
|
@ -196,6 +196,8 @@ private:
|
|||||||
bool mTouchStartDefaultPrevented;
|
bool mTouchStartDefaultPrevented;
|
||||||
bool mTouchMoveDefaultPrevented;
|
bool mTouchMoveDefaultPrevented;
|
||||||
bool mIsFirstTouchMove;
|
bool mIsFirstTouchMove;
|
||||||
|
bool mCancelable;
|
||||||
|
bool mTouchCancelSent;
|
||||||
|
|
||||||
// In the old Win32 way of doing things, we would receive a WM_TOUCH event
|
// In the old Win32 way of doing things, we would receive a WM_TOUCH event
|
||||||
// that told us the state of every touchpoint on the touch surface. If
|
// that told us the state of every touchpoint on the touch surface. If
|
||||||
@ -271,6 +273,7 @@ private:
|
|||||||
|
|
||||||
// Sync event dispatching
|
// Sync event dispatching
|
||||||
void DispatchEventIgnoreStatus(nsGUIEvent *aEvent);
|
void DispatchEventIgnoreStatus(nsGUIEvent *aEvent);
|
||||||
|
void DispatchTouchCancel();
|
||||||
|
|
||||||
nsDeque mInputEventQueue;
|
nsDeque mInputEventQueue;
|
||||||
static nsEventStatus sThrowawayStatus;
|
static nsEventStatus sThrowawayStatus;
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
#endif
|
#endif
|
||||||
#include "UIABridgePrivate.h"
|
#include "UIABridgePrivate.h"
|
||||||
#include "WinMouseScrollHandler.h"
|
#include "WinMouseScrollHandler.h"
|
||||||
|
#include "InputData.h"
|
||||||
|
|
||||||
using namespace Microsoft::WRL;
|
using namespace Microsoft::WRL;
|
||||||
using namespace Microsoft::WRL::Wrappers;
|
using namespace Microsoft::WRL::Wrappers;
|
||||||
@ -978,6 +979,39 @@ CompositorParent* MetroWidget::NewCompositorParent(int aSurfaceWidth, int aSurfa
|
|||||||
return compositor;
|
return compositor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MetroWidget::ApzContentConsumingTouch()
|
||||||
|
{
|
||||||
|
LogFunction();
|
||||||
|
if (!MetroWidget::sAPZC) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
MetroWidget::sAPZC->ContentReceivedTouch(mRootLayerTreeId, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MetroWidget::ApzContentIgnoringTouch()
|
||||||
|
{
|
||||||
|
LogFunction();
|
||||||
|
if (!MetroWidget::sAPZC) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
MetroWidget::sAPZC->ContentReceivedTouch(mRootLayerTreeId, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
nsEventStatus
|
||||||
|
MetroWidget::ApzReceiveInputEvent(nsTouchEvent* aEvent)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(aEvent);
|
||||||
|
|
||||||
|
if (!MetroWidget::sAPZC) {
|
||||||
|
return nsEventStatus_eIgnore;
|
||||||
|
}
|
||||||
|
|
||||||
|
MultiTouchInput inputData(*aEvent);
|
||||||
|
return MetroWidget::sAPZC->ReceiveInputEvent(inputData);
|
||||||
|
}
|
||||||
|
|
||||||
LayerManager*
|
LayerManager*
|
||||||
MetroWidget::GetLayerManager(PLayerTransactionChild* aShadowManager,
|
MetroWidget::GetLayerManager(PLayerTransactionChild* aShadowManager,
|
||||||
LayersBackend aBackendHint,
|
LayersBackend aBackendHint,
|
||||||
|
@ -196,6 +196,10 @@ public:
|
|||||||
virtual void SetTransparencyMode(nsTransparencyMode aMode);
|
virtual void SetTransparencyMode(nsTransparencyMode aMode);
|
||||||
virtual nsTransparencyMode GetTransparencyMode();
|
virtual nsTransparencyMode GetTransparencyMode();
|
||||||
|
|
||||||
|
// APZ related apis
|
||||||
|
void ApzContentConsumingTouch();
|
||||||
|
void ApzContentIgnoringTouch();
|
||||||
|
nsEventStatus ApzReceiveInputEvent(nsTouchEvent* aEvent);
|
||||||
nsresult RequestContentScroll();
|
nsresult RequestContentScroll();
|
||||||
void RequestContentRepaintImplMainThread();
|
void RequestContentRepaintImplMainThread();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user