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
|
||||
APZCTreeManager::ReceiveInputEvent(const InputData& aEvent)
|
||||
{
|
||||
nsEventStatus result = nsEventStatus_eIgnore;
|
||||
gfx3DMatrix transformToApzc;
|
||||
gfx3DMatrix transformToScreen;
|
||||
switch (aEvent.mInputType) {
|
||||
@ -238,7 +239,7 @@ APZCTreeManager::ReceiveInputEvent(const InputData& aEvent)
|
||||
for (size_t i = 0; i < inputForApzc.mTouches.Length(); i++) {
|
||||
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
|
||||
// then null it out so we don't keep a dangling reference and leak things.
|
||||
if (multiTouchInput.mType == MultiTouchInput::MULTITOUCH_CANCEL ||
|
||||
@ -254,7 +255,7 @@ APZCTreeManager::ReceiveInputEvent(const InputData& aEvent)
|
||||
GetInputTransforms(apzc, transformToApzc, transformToScreen);
|
||||
PinchGestureInput inputForApzc(pinchInput);
|
||||
ApplyTransform(&(inputForApzc.mFocusPoint), transformToApzc);
|
||||
apzc->ReceiveInputEvent(inputForApzc);
|
||||
result = apzc->ReceiveInputEvent(inputForApzc);
|
||||
}
|
||||
break;
|
||||
} case TAPGESTURE_INPUT: {
|
||||
@ -264,12 +265,12 @@ APZCTreeManager::ReceiveInputEvent(const InputData& aEvent)
|
||||
GetInputTransforms(apzc, transformToApzc, transformToScreen);
|
||||
TapGestureInput inputForApzc(tapInput);
|
||||
ApplyTransform(&(inputForApzc.mPoint), transformToApzc);
|
||||
apzc->ReceiveInputEvent(inputForApzc);
|
||||
result = apzc->ReceiveInputEvent(inputForApzc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return nsEventStatus_eIgnore;
|
||||
return result;
|
||||
}
|
||||
|
||||
nsEventStatus
|
||||
|
@ -179,6 +179,20 @@ namespace {
|
||||
aData->mChanged = false;
|
||||
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 {
|
||||
@ -431,6 +445,8 @@ MetroInput::OnPointerPressed(UI::Core::ICoreWindow* aSender,
|
||||
mTouchStartDefaultPrevented = false;
|
||||
mTouchMoveDefaultPrevented = false;
|
||||
mIsFirstTouchMove = true;
|
||||
mCancelable = true;
|
||||
mTouchCancelSent = false;
|
||||
InitTouchEventTouchList(touchEvent);
|
||||
DispatchAsyncTouchEventWithCallback(touchEvent, &MetroInput::OnPointerPressedCallback);
|
||||
} else {
|
||||
@ -449,10 +465,12 @@ MetroInput::OnPointerPressedCallback()
|
||||
{
|
||||
nsEventStatus status = DeliverNextQueuedTouchEvent();
|
||||
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 content canceled the first touchstart don't generate any gesture based
|
||||
// input - clear the recognizer state without sending any events.
|
||||
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
|
||||
MetroInput::OnFirstPointerMoveCallback()
|
||||
{
|
||||
nsTouchEvent* event = static_cast<nsTouchEvent*>(mInputEventQueue.PopFront());
|
||||
MOZ_ASSERT(event);
|
||||
nsEventStatus status;
|
||||
mWidget->DispatchEvent(event, status);
|
||||
nsEventStatus status = DeliverNextQueuedTouchEvent();
|
||||
mCancelable = false;
|
||||
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
|
||||
@ -1096,17 +1117,67 @@ MetroInput::DispatchAsyncTouchEventIgnoreStatus(nsTouchEvent* aEvent)
|
||||
nsEventStatus
|
||||
MetroInput::DeliverNextQueuedTouchEvent()
|
||||
{
|
||||
nsEventStatus status;
|
||||
nsTouchEvent* event = static_cast<nsTouchEvent*>(mInputEventQueue.PopFront());
|
||||
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);
|
||||
// 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;
|
||||
}
|
||||
|
||||
// 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
|
||||
|
@ -196,6 +196,8 @@ private:
|
||||
bool mTouchStartDefaultPrevented;
|
||||
bool mTouchMoveDefaultPrevented;
|
||||
bool mIsFirstTouchMove;
|
||||
bool mCancelable;
|
||||
bool mTouchCancelSent;
|
||||
|
||||
// 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
|
||||
@ -271,6 +273,7 @@ private:
|
||||
|
||||
// Sync event dispatching
|
||||
void DispatchEventIgnoreStatus(nsGUIEvent *aEvent);
|
||||
void DispatchTouchCancel();
|
||||
|
||||
nsDeque mInputEventQueue;
|
||||
static nsEventStatus sThrowawayStatus;
|
||||
|
@ -31,6 +31,7 @@
|
||||
#endif
|
||||
#include "UIABridgePrivate.h"
|
||||
#include "WinMouseScrollHandler.h"
|
||||
#include "InputData.h"
|
||||
|
||||
using namespace Microsoft::WRL;
|
||||
using namespace Microsoft::WRL::Wrappers;
|
||||
@ -978,6 +979,39 @@ CompositorParent* MetroWidget::NewCompositorParent(int aSurfaceWidth, int aSurfa
|
||||
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*
|
||||
MetroWidget::GetLayerManager(PLayerTransactionChild* aShadowManager,
|
||||
LayersBackend aBackendHint,
|
||||
|
@ -196,6 +196,10 @@ public:
|
||||
virtual void SetTransparencyMode(nsTransparencyMode aMode);
|
||||
virtual nsTransparencyMode GetTransparencyMode();
|
||||
|
||||
// APZ related apis
|
||||
void ApzContentConsumingTouch();
|
||||
void ApzContentIgnoringTouch();
|
||||
nsEventStatus ApzReceiveInputEvent(nsTouchEvent* aEvent);
|
||||
nsresult RequestContentScroll();
|
||||
void RequestContentRepaintImplMainThread();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user