mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 915213 - Transform all gecko input through the apzc via widget to compensate for zoom. r=bbondy
This commit is contained in:
parent
17fa48d08b
commit
a774def610
@ -203,6 +203,7 @@ namespace winrt {
|
|||||||
MetroInput::MetroInput(MetroWidget* aWidget,
|
MetroInput::MetroInput(MetroWidget* aWidget,
|
||||||
UI::Core::ICoreWindow* aWindow)
|
UI::Core::ICoreWindow* aWindow)
|
||||||
: mWidget(aWidget),
|
: mWidget(aWidget),
|
||||||
|
mChromeHitTestCacheForTouch(false),
|
||||||
mWindow(aWindow)
|
mWindow(aWindow)
|
||||||
{
|
{
|
||||||
LogFunction();
|
LogFunction();
|
||||||
@ -644,6 +645,43 @@ MetroInput::OnPointerReleased(UI::Core::ICoreWindow* aSender,
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tests for chrome vs. content target so we know whether input coordinates need
|
||||||
|
// to be transformed through the apz. Eventually this hit testing should move
|
||||||
|
// into the apz (bug 918288).
|
||||||
|
bool
|
||||||
|
MetroInput::HitTestChrome(const LayoutDeviceIntPoint& pt)
|
||||||
|
{
|
||||||
|
// Confirm this event targets content. We pick this up in browser's input.js.
|
||||||
|
nsMouseEvent hittest(true, NS_MOUSE_MOZHITTEST, mWidget.Get(), nsMouseEvent::eReal, nsMouseEvent::eNormal);
|
||||||
|
hittest.refPoint = pt;
|
||||||
|
nsEventStatus status;
|
||||||
|
mWidget->DispatchEvent(&hittest, status);
|
||||||
|
return (status == nsEventStatus_eConsumeNoDefault);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MetroInput::TransformRefPoint(const Foundation::Point& aPosition, LayoutDeviceIntPoint& aRefPointOut)
|
||||||
|
{
|
||||||
|
// If this event is destined for content we need to transform our ref point through
|
||||||
|
// the apz so that zoom can be accounted for.
|
||||||
|
LayoutDeviceIntPoint pt = LayoutDeviceIntPoint::FromUntyped(MetroUtils::LogToPhys(aPosition));
|
||||||
|
aRefPointOut = pt;
|
||||||
|
// This is currently a general contained rect hit test, it may produce a false positive for
|
||||||
|
// overlay chrome elements.
|
||||||
|
bool apzIntersect = mWidget->HitTestAPZC(mozilla::ScreenPoint(pt.x, pt.y));
|
||||||
|
if (apzIntersect && HitTestChrome(pt)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
nsMouseEvent event(true,
|
||||||
|
NS_MOUSE_MOVE,
|
||||||
|
mWidget.Get(),
|
||||||
|
nsMouseEvent::eReal,
|
||||||
|
nsMouseEvent::eNormal);
|
||||||
|
event.refPoint = aRefPointOut;
|
||||||
|
mWidget->ApzReceiveInputEvent(&event);
|
||||||
|
aRefPointOut = event.refPoint;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MetroInput::InitGeckoMouseEventFromPointerPoint(
|
MetroInput::InitGeckoMouseEventFromPointerPoint(
|
||||||
nsMouseEvent* aEvent,
|
nsMouseEvent* aEvent,
|
||||||
@ -667,7 +705,7 @@ MetroInput::InitGeckoMouseEventFromPointerPoint(
|
|||||||
props->get_Pressure(&pressure);
|
props->get_Pressure(&pressure);
|
||||||
mGestureRecognizer->CanBeDoubleTap(aPointerPoint, &canBeDoubleTap);
|
mGestureRecognizer->CanBeDoubleTap(aPointerPoint, &canBeDoubleTap);
|
||||||
|
|
||||||
aEvent->refPoint = LayoutDeviceIntPoint::FromUntyped(MetroUtils::LogToPhys(position));
|
TransformRefPoint(position, aEvent->refPoint);
|
||||||
|
|
||||||
if (!canBeDoubleTap) {
|
if (!canBeDoubleTap) {
|
||||||
aEvent->clickCount = 1;
|
aEvent->clickCount = 1;
|
||||||
@ -965,8 +1003,7 @@ MetroInput::OnTapped(UI::Input::IGestureRecognizer* aSender,
|
|||||||
|
|
||||||
Foundation::Point position;
|
Foundation::Point position;
|
||||||
aArgs->get_Position(&position);
|
aArgs->get_Position(&position);
|
||||||
HandleSingleTap(
|
HandleSingleTap(position);
|
||||||
LayoutDeviceIntPoint::FromUntyped(MetroUtils::LogToPhys(position)));
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -987,18 +1024,20 @@ MetroInput::OnRightTapped(UI::Input::IGestureRecognizer* aSender,
|
|||||||
|
|
||||||
Foundation::Point position;
|
Foundation::Point position;
|
||||||
aArgs->get_Position(&position);
|
aArgs->get_Position(&position);
|
||||||
HandleLongTap(
|
HandleLongTap(position);
|
||||||
LayoutDeviceIntPoint::FromUntyped(MetroUtils::LogToPhys(position)));
|
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MetroInput::HandleSingleTap(const LayoutDeviceIntPoint& aPoint)
|
MetroInput::HandleSingleTap(const Foundation::Point& aPoint)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_INPUT
|
#ifdef DEBUG_INPUT
|
||||||
LogFunction();
|
LogFunction();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
LayoutDeviceIntPoint refPoint;
|
||||||
|
TransformRefPoint(aPoint, refPoint);
|
||||||
|
|
||||||
// send mousemove
|
// send mousemove
|
||||||
nsMouseEvent* mouseEvent = new nsMouseEvent(true,
|
nsMouseEvent* mouseEvent = new nsMouseEvent(true,
|
||||||
@ -1006,7 +1045,7 @@ MetroInput::HandleSingleTap(const LayoutDeviceIntPoint& aPoint)
|
|||||||
mWidget.Get(),
|
mWidget.Get(),
|
||||||
nsMouseEvent::eReal,
|
nsMouseEvent::eReal,
|
||||||
nsMouseEvent::eNormal);
|
nsMouseEvent::eNormal);
|
||||||
mouseEvent->refPoint = aPoint;
|
mouseEvent->refPoint = refPoint;
|
||||||
mouseEvent->clickCount = 1;
|
mouseEvent->clickCount = 1;
|
||||||
mouseEvent->inputSource = nsIDOMMouseEvent::MOZ_SOURCE_TOUCH;
|
mouseEvent->inputSource = nsIDOMMouseEvent::MOZ_SOURCE_TOUCH;
|
||||||
DispatchAsyncEventIgnoreStatus(mouseEvent);
|
DispatchAsyncEventIgnoreStatus(mouseEvent);
|
||||||
@ -1017,7 +1056,7 @@ MetroInput::HandleSingleTap(const LayoutDeviceIntPoint& aPoint)
|
|||||||
mWidget.Get(),
|
mWidget.Get(),
|
||||||
nsMouseEvent::eReal,
|
nsMouseEvent::eReal,
|
||||||
nsMouseEvent::eNormal);
|
nsMouseEvent::eNormal);
|
||||||
mouseEvent->refPoint = aPoint;
|
mouseEvent->refPoint = refPoint;
|
||||||
mouseEvent->clickCount = 1;
|
mouseEvent->clickCount = 1;
|
||||||
mouseEvent->inputSource = nsIDOMMouseEvent::MOZ_SOURCE_TOUCH;
|
mouseEvent->inputSource = nsIDOMMouseEvent::MOZ_SOURCE_TOUCH;
|
||||||
mouseEvent->button = nsMouseEvent::buttonType::eLeftButton;
|
mouseEvent->button = nsMouseEvent::buttonType::eLeftButton;
|
||||||
@ -1028,7 +1067,7 @@ MetroInput::HandleSingleTap(const LayoutDeviceIntPoint& aPoint)
|
|||||||
mWidget.Get(),
|
mWidget.Get(),
|
||||||
nsMouseEvent::eReal,
|
nsMouseEvent::eReal,
|
||||||
nsMouseEvent::eNormal);
|
nsMouseEvent::eNormal);
|
||||||
mouseEvent->refPoint = aPoint;
|
mouseEvent->refPoint = refPoint;
|
||||||
mouseEvent->clickCount = 1;
|
mouseEvent->clickCount = 1;
|
||||||
mouseEvent->inputSource = nsIDOMMouseEvent::MOZ_SOURCE_TOUCH;
|
mouseEvent->inputSource = nsIDOMMouseEvent::MOZ_SOURCE_TOUCH;
|
||||||
mouseEvent->button = nsMouseEvent::buttonType::eLeftButton;
|
mouseEvent->button = nsMouseEvent::buttonType::eLeftButton;
|
||||||
@ -1055,18 +1094,20 @@ MetroInput::HandleSingleTap(const LayoutDeviceIntPoint& aPoint)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MetroInput::HandleLongTap(const LayoutDeviceIntPoint& aPoint)
|
MetroInput::HandleLongTap(const Foundation::Point& aPoint)
|
||||||
{
|
{
|
||||||
#ifdef DEBUG_INPUT
|
#ifdef DEBUG_INPUT
|
||||||
LogFunction();
|
LogFunction();
|
||||||
#endif
|
#endif
|
||||||
|
LayoutDeviceIntPoint refPoint;
|
||||||
|
TransformRefPoint(aPoint, refPoint);
|
||||||
|
|
||||||
nsMouseEvent* contextEvent = new nsMouseEvent(true,
|
nsMouseEvent* contextEvent = new nsMouseEvent(true,
|
||||||
NS_CONTEXTMENU,
|
NS_CONTEXTMENU,
|
||||||
mWidget.Get(),
|
mWidget.Get(),
|
||||||
nsMouseEvent::eReal,
|
nsMouseEvent::eReal,
|
||||||
nsMouseEvent::eNormal);
|
nsMouseEvent::eNormal);
|
||||||
contextEvent->refPoint = aPoint;
|
contextEvent->refPoint = refPoint;
|
||||||
contextEvent->inputSource = nsIDOMMouseEvent::MOZ_SOURCE_TOUCH;
|
contextEvent->inputSource = nsIDOMMouseEvent::MOZ_SOURCE_TOUCH;
|
||||||
DispatchAsyncEventIgnoreStatus(contextEvent);
|
DispatchAsyncEventIgnoreStatus(contextEvent);
|
||||||
}
|
}
|
||||||
@ -1128,7 +1169,7 @@ MetroInput::DeliverNextQueuedTouchEvent()
|
|||||||
* (ignoring return result) and to content and return the content event
|
* (ignoring return result) and to content and return the content event
|
||||||
* status result to our caller.
|
* status result to our caller.
|
||||||
* 2) mTouchStartDefaultPrevented or mTouchMoveDefaultPrevented are true
|
* 2) mTouchStartDefaultPrevented or mTouchMoveDefaultPrevented are true
|
||||||
* Deliver touch directly to content and bypass the apz. Our callers
|
* Deliver touch to content after transforming through the apz. Our callers
|
||||||
* handle calling cancel for the touch sequence on the apz.
|
* handle calling cancel for the touch sequence on the apz.
|
||||||
* 3) mTouchStartDefaultPrevented and mTouchMoveDefaultPrevented are false
|
* 3) mTouchStartDefaultPrevented and mTouchMoveDefaultPrevented are false
|
||||||
* Deliver events to the apz. If the apz returns eConsumeNoDefault dispatch
|
* Deliver events to the apz. If the apz returns eConsumeNoDefault dispatch
|
||||||
@ -1137,17 +1178,33 @@ MetroInput::DeliverNextQueuedTouchEvent()
|
|||||||
* the overhead of delivering dom events.)
|
* the overhead of delivering dom events.)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// Test for chrome vs. content target. To do this we only use the first touch
|
||||||
|
// point since that will be the input batch target. Cache this for touch events
|
||||||
|
// since HitTestChrome has to send a dom event.
|
||||||
|
if (event->message == NS_TOUCH_START) {
|
||||||
|
nsRefPtr<Touch> touch = event->touches[0];
|
||||||
|
LayoutDeviceIntPoint pt = LayoutDeviceIntPoint::FromUntyped(touch->mRefPoint);
|
||||||
|
bool apzIntersect = mWidget->HitTestAPZC(mozilla::ScreenPoint(pt.x, pt.y));
|
||||||
|
mChromeHitTestCacheForTouch = (apzIntersect && HitTestChrome(pt));
|
||||||
|
}
|
||||||
|
|
||||||
// Check if content called preventDefault on touchstart or first touchmove. If so
|
// Check if content called preventDefault on touchstart or first touchmove. If so
|
||||||
// send directly to content, do not forward to the apz.
|
// and the event is destined for chrome, send the event. If destined for content,
|
||||||
|
// translate coordinates through the apz then send.
|
||||||
if (mTouchStartDefaultPrevented || mTouchMoveDefaultPrevented) {
|
if (mTouchStartDefaultPrevented || mTouchMoveDefaultPrevented) {
|
||||||
// continue delivering events to content
|
if (!mChromeHitTestCacheForTouch) {
|
||||||
|
// ContentReceivedTouch has already been called so this shouldn't cause
|
||||||
|
// the apz to react. We still need to transform our coordinates though.
|
||||||
|
mWidget->ApzReceiveInputEvent(event);
|
||||||
|
}
|
||||||
mWidget->DispatchEvent(event, status);
|
mWidget->DispatchEvent(event, status);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Forward event data to apz. If the apz consumes the event, don't forward to
|
// Forward event data to apz. If the apz consumes the event, don't forward to
|
||||||
// content if this is not a cancelable event.
|
// content if this is not a cancelable event.
|
||||||
status = mWidget->ApzReceiveInputEvent(event);
|
nsTouchEvent transformedEvent(*event);
|
||||||
|
status = mWidget->ApzReceiveInputEvent(event, &transformedEvent);
|
||||||
if (!mCancelable && status == nsEventStatus_eConsumeNoDefault) {
|
if (!mCancelable && status == nsEventStatus_eConsumeNoDefault) {
|
||||||
if (!mTouchCancelSent) {
|
if (!mTouchCancelSent) {
|
||||||
mTouchCancelSent = true;
|
mTouchCancelSent = true;
|
||||||
@ -1156,8 +1213,9 @@ MetroInput::DeliverNextQueuedTouchEvent()
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deliver event to content
|
// Deliver event. If this is destined for chrome, use the untransformed event
|
||||||
mWidget->DispatchEvent(event, status);
|
// data, if it's destined for content, use the transformed event.
|
||||||
|
mWidget->DispatchEvent(!mChromeHitTestCacheForTouch ? &transformedEvent : event, status);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,8 +145,8 @@ public:
|
|||||||
HRESULT OnRightTapped(IGestureRecognizer* aSender,
|
HRESULT OnRightTapped(IGestureRecognizer* aSender,
|
||||||
IRightTappedEventArgs* aArgs);
|
IRightTappedEventArgs* aArgs);
|
||||||
|
|
||||||
void HandleSingleTap(const mozilla::LayoutDeviceIntPoint& aPoint);
|
void HandleSingleTap(const Point& aPoint);
|
||||||
void HandleLongTap(const mozilla::LayoutDeviceIntPoint& aPoint);
|
void HandleLongTap(const Point& aPoint);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Microsoft::WRL::ComPtr<ICoreWindow> mWindow;
|
Microsoft::WRL::ComPtr<ICoreWindow> mWindow;
|
||||||
@ -159,7 +159,13 @@ private:
|
|||||||
void RegisterInputEvents();
|
void RegisterInputEvents();
|
||||||
void UnregisterInputEvents();
|
void UnregisterInputEvents();
|
||||||
|
|
||||||
|
// Hit testing for chrome content
|
||||||
|
bool mChromeHitTestCacheForTouch;
|
||||||
|
bool HitTestChrome(const LayoutDeviceIntPoint& pt);
|
||||||
|
|
||||||
// Event processing helpers. See function definitions for more info.
|
// Event processing helpers. See function definitions for more info.
|
||||||
|
void TransformRefPoint(const Point& aPosition,
|
||||||
|
LayoutDeviceIntPoint& aRefPointOut);
|
||||||
void OnPointerNonTouch(IPointerPoint* aPoint);
|
void OnPointerNonTouch(IPointerPoint* aPoint);
|
||||||
void InitGeckoMouseEventFromPointerPoint(nsMouseEvent* aEvent,
|
void InitGeckoMouseEventFromPointerPoint(nsMouseEvent* aEvent,
|
||||||
IPointerPoint* aPoint);
|
IPointerPoint* aPoint);
|
||||||
|
@ -999,17 +999,38 @@ MetroWidget::ApzContentIgnoringTouch()
|
|||||||
MetroWidget::sAPZC->ContentReceivedTouch(mRootLayerTreeId, false);
|
MetroWidget::sAPZC->ContentReceivedTouch(mRootLayerTreeId, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
MetroWidget::HitTestAPZC(ScreenPoint& pt)
|
||||||
|
{
|
||||||
|
if (!MetroWidget::sAPZC) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return MetroWidget::sAPZC->HitTestAPZC(pt);
|
||||||
|
}
|
||||||
|
|
||||||
nsEventStatus
|
nsEventStatus
|
||||||
MetroWidget::ApzReceiveInputEvent(nsTouchEvent* aEvent)
|
MetroWidget::ApzReceiveInputEvent(nsInputEvent* aEvent)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(aEvent);
|
MOZ_ASSERT(aEvent);
|
||||||
|
|
||||||
if (!MetroWidget::sAPZC) {
|
if (!MetroWidget::sAPZC) {
|
||||||
return nsEventStatus_eIgnore;
|
return nsEventStatus_eIgnore;
|
||||||
}
|
}
|
||||||
|
nsInputEvent& event = static_cast<nsInputEvent&>(*aEvent);
|
||||||
|
return MetroWidget::sAPZC->ReceiveInputEvent(event);
|
||||||
|
}
|
||||||
|
|
||||||
MultiTouchInput inputData(*aEvent);
|
nsEventStatus
|
||||||
return MetroWidget::sAPZC->ReceiveInputEvent(inputData);
|
MetroWidget::ApzReceiveInputEvent(nsInputEvent* aInEvent, nsInputEvent* aOutEvent)
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(aInEvent);
|
||||||
|
MOZ_ASSERT(aOutEvent);
|
||||||
|
|
||||||
|
if (!MetroWidget::sAPZC) {
|
||||||
|
return nsEventStatus_eIgnore;
|
||||||
|
}
|
||||||
|
nsInputEvent& event = static_cast<nsInputEvent&>(*aInEvent);
|
||||||
|
return MetroWidget::sAPZC->ReceiveInputEvent(event, aOutEvent);
|
||||||
}
|
}
|
||||||
|
|
||||||
LayerManager*
|
LayerManager*
|
||||||
|
@ -24,7 +24,6 @@
|
|||||||
#include "mozilla/layers/CompositorParent.h"
|
#include "mozilla/layers/CompositorParent.h"
|
||||||
#include "mozilla/layers/APZCTreeManager.h"
|
#include "mozilla/layers/APZCTreeManager.h"
|
||||||
#include "mozilla/layers/LayerManagerComposite.h"
|
#include "mozilla/layers/LayerManagerComposite.h"
|
||||||
#include "Units.h"
|
|
||||||
#include "nsDeque.h"
|
#include "nsDeque.h"
|
||||||
#include "APZController.h"
|
#include "APZController.h"
|
||||||
|
|
||||||
@ -199,7 +198,9 @@ public:
|
|||||||
// APZ related apis
|
// APZ related apis
|
||||||
void ApzContentConsumingTouch();
|
void ApzContentConsumingTouch();
|
||||||
void ApzContentIgnoringTouch();
|
void ApzContentIgnoringTouch();
|
||||||
nsEventStatus ApzReceiveInputEvent(nsTouchEvent* aEvent);
|
nsEventStatus ApzReceiveInputEvent(nsInputEvent* aEvent);
|
||||||
|
nsEventStatus ApzReceiveInputEvent(nsInputEvent* aInEvent, nsInputEvent* aOutEvent);
|
||||||
|
bool HitTestAPZC(mozilla::ScreenPoint& pt);
|
||||||
nsresult RequestContentScroll();
|
nsresult RequestContentScroll();
|
||||||
void RequestContentRepaintImplMainThread();
|
void RequestContentRepaintImplMainThread();
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user