Bug 833795 - Sample offset on touch start. r=drs

This commit is contained in:
Anthony Jones 2013-05-16 17:58:07 +12:00
parent b0a404041f
commit fe10673b12
4 changed files with 48 additions and 23 deletions

View File

@ -1525,29 +1525,32 @@ nsEventStateManager::IsRemoteTarget(nsIContent* target) {
return false;
}
/*static*/ void
nsEventStateManager::MapEventCoordinatesForChildProcess(nsFrameLoader* aFrameLoader,
nsEvent* aEvent)
/*static*/ nsIntPoint
nsEventStateManager::GetChildProcessOffset(nsFrameLoader* aFrameLoader,
const nsEvent& aEvent)
{
// The "toplevel widget" in child processes is always at position
// 0,0. Map the event coordinates to match that.
nsIFrame* targetFrame = aFrameLoader->GetPrimaryFrameOfOwningContent();
if (!targetFrame) {
return;
return nsIntPoint();
}
nsPresContext* presContext = targetFrame->PresContext();
// Find out how far we're offset from the nearest widget.
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(&aEvent,
targetFrame);
return pt.ToNearestPixels(presContext->AppUnitsPerDevPixel());
}
/*static*/ void
nsEventStateManager::MapEventCoordinatesForChildProcess(
const nsIntPoint& aOffset, nsEvent* aEvent)
{
if (aEvent->eventStructType != NS_TOUCH_EVENT) {
nsPoint pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent,
targetFrame);
aEvent->refPoint = pt.ToNearestPixels(presContext->AppUnitsPerDevPixel());
aEvent->refPoint = aOffset;
} else {
aEvent->refPoint = nsIntPoint();
// Find out how far we're offset from the nearest widget.
nsPoint offset =
nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, targetFrame);
nsIntPoint intOffset =
offset.ToNearestPixels(presContext->AppUnitsPerDevPixel());
nsTouchEvent* touchEvent = static_cast<nsTouchEvent*>(aEvent);
// Then offset all the touch points by that distance, to put them
// in the space where top-left is 0,0.
@ -1555,12 +1558,20 @@ nsEventStateManager::MapEventCoordinatesForChildProcess(nsFrameLoader* aFrameLoa
for (uint32_t i = 0; i < touches.Length(); ++i) {
nsIDOMTouch* touch = touches[i];
if (touch) {
touch->mRefPoint += intOffset;
touch->mRefPoint += aOffset;
}
}
}
}
/*static*/ void
nsEventStateManager::MapEventCoordinatesForChildProcess(nsFrameLoader* aFrameLoader,
nsEvent* aEvent)
{
nsIntPoint offset = GetChildProcessOffset(aFrameLoader, *aEvent);
MapEventCoordinatesForChildProcess(offset, aEvent);
}
bool
CrossProcessSafeEvent(const nsEvent& aEvent)
{

View File

@ -192,10 +192,15 @@ public:
static void SetFullScreenState(mozilla::dom::Element* aElement, bool aIsFullScreen);
static bool IsRemoteTarget(nsIContent* aTarget);
static nsIntPoint GetChildProcessOffset(nsFrameLoader* aFrameLoader,
const nsEvent& aEvent);
static void MapEventCoordinatesForChildProcess(nsFrameLoader* aFrameLoader,
nsEvent* aEvent);
static void MapEventCoordinatesForChildProcess(const nsIntPoint& aOffset,
nsEvent* aEvent);
// Holds the point in screen coords that a mouse event was dispatched to,
// before we went into pointer lock mode. This is constantly updated while
// the pointer is not locked, but we don't update it while the pointer is

View File

@ -636,6 +636,18 @@ bool TabParent::SendRealTouchEvent(nsTouchEvent& event)
return false;
}
if (event.message == NS_TOUCH_START) {
// Adjust the widget coordinates to be relative to our frame.
nsRefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
if (!frameLoader) {
// No frame anymore?
sEventCapturer = nullptr;
return false;
}
mChildProcessOffsetAtTouchStart =
nsEventStateManager::GetChildProcessOffset(frameLoader,
event);
MOZ_ASSERT((!sEventCapturer && mEventCaptureDepth == 0) ||
(sEventCapturer == this && mEventCaptureDepth > 0));
// We want to capture all remaining touch events in this series
@ -693,16 +705,8 @@ TabParent::TryCapture(const nsGUIEvent& aEvent)
return false;
}
// Adjust the widget coordinates to be relative to our frame.
nsRefPtr<nsFrameLoader> frameLoader = GetFrameLoader();
if (!frameLoader) {
// No frame anymore?
sEventCapturer = nullptr;
return false;
}
nsEventStateManager::MapEventCoordinatesForChildProcess(frameLoader, &event);
nsEventStateManager::MapEventCoordinatesForChildProcess(
mChildProcessOffsetAtTouchStart, &event);
SendRealTouchEvent(event);
return true;

View File

@ -313,6 +313,11 @@ private:
// dispatch to content.
void MaybeForwardEventToRenderFrame(const nsInputEvent& aEvent,
nsInputEvent* aOutEvent);
// The offset for the child process which is sampled at touch start. This
// means that the touch events are relative to where the frame was at the
// start of the touch. We need to look for a better solution to this
// problem see bug 872911.
nsIntPoint mChildProcessOffsetAtTouchStart;
// When true, we've initiated normal shutdown and notified our
// managing PContent.
bool mMarkedDestroying;