mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-01 17:23:59 +00:00
Bug 920036 - Send touch inputs through the APZ before sending them to the gecko thread. r=mwu,dvander,smaug
This commit is contained in:
parent
277a11f599
commit
846e3755ae
@ -2208,7 +2208,11 @@ TabParent::MaybeForwardEventToRenderFrame(WidgetInputEvent& aEvent,
|
||||
ScrollableLayerGuid* aOutTargetGuid,
|
||||
uint64_t* aOutInputBlockId)
|
||||
{
|
||||
if (aEvent.mClass == eWheelEventClass) {
|
||||
if (aEvent.mClass == eWheelEventClass
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
|| aEvent.mClass == eTouchEventClass
|
||||
#endif
|
||||
) {
|
||||
// Wheel events must be sent to APZ directly from the widget. New APZ-
|
||||
// aware events should follow suit and move there as well. However, we
|
||||
// do need to inform the child process of the correct target and block
|
||||
|
@ -24,7 +24,6 @@
|
||||
#include "gfxPrefs.h"
|
||||
#include "libui/Input.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/MouseEvents.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/TouchEvents.h"
|
||||
@ -333,21 +332,6 @@ GeckoTouchDispatcher::ResampleTouchMoves(MultiTouchInput& aOutTouch, TimeStamp a
|
||||
aOutTouch.mTimeStamp = sampleTime;
|
||||
}
|
||||
|
||||
// Some touch events get sent as mouse events. If APZ doesn't capture the event
|
||||
// and if a touch only has 1 touch input, we can send a mouse event.
|
||||
void
|
||||
GeckoTouchDispatcher::DispatchMouseEvent(MultiTouchInput& aMultiTouch,
|
||||
bool aForwardToChildren)
|
||||
{
|
||||
WidgetMouseEvent mouseEvent = aMultiTouch.ToWidgetMouseEvent(nullptr);
|
||||
if (mouseEvent.message == NS_EVENT_NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
mouseEvent.mFlags.mNoCrossProcessBoundaryForwarding = !aForwardToChildren;
|
||||
nsWindow::DispatchInputEvent(mouseEvent);
|
||||
}
|
||||
|
||||
static bool
|
||||
IsExpired(const MultiTouchInput& aTouch)
|
||||
{
|
||||
@ -372,9 +356,7 @@ GeckoTouchDispatcher::DispatchTouchEvent(MultiTouchInput& aMultiTouch)
|
||||
return;
|
||||
}
|
||||
|
||||
bool captured = false;
|
||||
WidgetTouchEvent event = aMultiTouch.ToWidgetTouchEvent(nullptr);
|
||||
nsEventStatus status = nsWindow::DispatchInputEvent(event, &captured);
|
||||
nsWindow::DispatchTouchInput(aMultiTouch);
|
||||
|
||||
if (mEnabledUniformityInfo && profiler_is_active()) {
|
||||
const char* touchAction = "Invalid";
|
||||
@ -395,11 +377,6 @@ GeckoTouchDispatcher::DispatchTouchEvent(MultiTouchInput& aMultiTouch)
|
||||
TouchDataPayload* payload = new TouchDataPayload(touchPoint);
|
||||
PROFILER_MARKER_PAYLOAD(touchAction, payload);
|
||||
}
|
||||
|
||||
if (!captured && (aMultiTouch.mTouches.Length() == 1)) {
|
||||
bool forwardToChildren = status != nsEventStatus_eConsumeNoDefault;
|
||||
DispatchMouseEvent(aMultiTouch, forwardToChildren);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
|
@ -47,6 +47,9 @@
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "mozilla/layers/APZCTreeManager.h"
|
||||
#include "mozilla/layers/CompositorParent.h"
|
||||
#include "mozilla/layers/InputAPZContext.h"
|
||||
#include "mozilla/MouseEvents.h"
|
||||
#include "mozilla/TouchEvents.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "HwcComposer2D.h"
|
||||
|
||||
@ -227,33 +230,89 @@ nsWindow::NotifyVsync(TimeStamp aVsyncTimestamp)
|
||||
}
|
||||
}
|
||||
|
||||
nsEventStatus
|
||||
nsWindow::DispatchInputEvent(WidgetGUIEvent& aEvent, bool* aWasCaptured)
|
||||
/*static*/ nsEventStatus
|
||||
nsWindow::DispatchInputEvent(WidgetGUIEvent& aEvent)
|
||||
{
|
||||
if (aWasCaptured) {
|
||||
*aWasCaptured = false;
|
||||
}
|
||||
if (!gFocusedWindow) {
|
||||
return nsEventStatus_eIgnore;
|
||||
}
|
||||
|
||||
gFocusedWindow->UserActivity();
|
||||
|
||||
nsEventStatus status;
|
||||
aEvent.widget = gFocusedWindow;
|
||||
gFocusedWindow->DispatchEvent(&aEvent, status);
|
||||
return status;
|
||||
}
|
||||
|
||||
/*static*/ void
|
||||
nsWindow::DispatchTouchInput(MultiTouchInput& aInput)
|
||||
{
|
||||
if (!gFocusedWindow) {
|
||||
return;
|
||||
}
|
||||
|
||||
gFocusedWindow->UserActivity();
|
||||
gFocusedWindow->DispatchTouchInputViaAPZ(aInput);
|
||||
}
|
||||
|
||||
void
|
||||
nsWindow::DispatchTouchInputViaAPZ(MultiTouchInput& aInput)
|
||||
{
|
||||
if (!mAPZC) {
|
||||
// In general mAPZC should not be null, but during initial setup
|
||||
// it might be, so we handle that case by ignoring touch input there.
|
||||
return;
|
||||
}
|
||||
|
||||
// First send it through the APZ code
|
||||
mozilla::layers::ScrollableLayerGuid guid;
|
||||
uint64_t inputBlockId;
|
||||
nsEventStatus rv = mAPZC->ReceiveInputEvent(aInput, &guid, &inputBlockId);
|
||||
// If the APZ says to drop it, then we drop it
|
||||
if (rv == nsEventStatus_eConsumeNoDefault) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Convert it to an event we can send to Gecko
|
||||
WidgetTouchEvent event = aInput.ToWidgetTouchEvent(this);
|
||||
|
||||
// If there is an event capturing child process, send it directly there.
|
||||
// This happens if we already sent a touchstart event through the root
|
||||
// process hit test and it ended up going to a child process. The event
|
||||
// capturing process should get all subsequent touch events in the same
|
||||
// event block. In this case the TryCapture call below will return true,
|
||||
// and the child process will take care of responding to the event as needed
|
||||
// so we don't need to do anything else here.
|
||||
if (TabParent* capturer = TabParent::GetEventCapturer()) {
|
||||
bool captured = capturer->TryCapture(aEvent);
|
||||
if (aWasCaptured) {
|
||||
*aWasCaptured = captured;
|
||||
}
|
||||
if (captured) {
|
||||
return nsEventStatus_eConsumeNoDefault;
|
||||
InputAPZContext context(guid, inputBlockId);
|
||||
if (capturer->TryCapture(event)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
nsEventStatus status;
|
||||
gFocusedWindow->DispatchEvent(&aEvent, status);
|
||||
return status;
|
||||
// If it didn't get captured, dispatch the event into the gecko root process
|
||||
// for "normal" flow. The event might get sent to the child process still,
|
||||
// but if it doesn't we need to notify the APZ of various things. All of
|
||||
// that happens in DispatchEventForAPZ
|
||||
rv = DispatchEventForAPZ(&event, guid, inputBlockId);
|
||||
|
||||
// Finally, if the touch event had only one touch point, generate a mouse
|
||||
// event for it and send it through the gecko root process.
|
||||
// Technically we should not need to do this if the touch event was routed
|
||||
// to the child process, but that seems to expose a bug in B2G where the
|
||||
// keyboard doesn't go away in some cases.
|
||||
// Also for now we're dispatching mouse events from all touch events because
|
||||
// we need this for click events to work in the chrome process. Once we have
|
||||
// APZ and ChromeProcessController::HandleSingleTap working for the chrome
|
||||
// process we shouldn't need to do this at all.
|
||||
if (event.touches.Length() == 1) {
|
||||
WidgetMouseEvent mouseEvent = aInput.ToWidgetMouseEvent(this);
|
||||
if (mouseEvent.message != NS_EVENT_NULL) {
|
||||
mouseEvent.mFlags.mNoCrossProcessBoundaryForwarding = (rv == nsEventStatus_eConsumeNoDefault);
|
||||
DispatchEvent(&mouseEvent, rv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -16,6 +16,7 @@
|
||||
#ifndef nsWindow_h
|
||||
#define nsWindow_h
|
||||
|
||||
#include "InputData.h"
|
||||
#include "nsBaseWidget.h"
|
||||
#include "nsRegion.h"
|
||||
#include "nsIIdleServiceInternal.h"
|
||||
@ -51,8 +52,8 @@ public:
|
||||
|
||||
static void NotifyVsync(mozilla::TimeStamp aVsyncTimestamp);
|
||||
static void DoDraw(void);
|
||||
static nsEventStatus DispatchInputEvent(mozilla::WidgetGUIEvent& aEvent,
|
||||
bool* aWasCaptured = nullptr);
|
||||
static nsEventStatus DispatchInputEvent(mozilla::WidgetGUIEvent& aEvent);
|
||||
static void DispatchTouchInput(mozilla::MultiTouchInput& aInput);
|
||||
|
||||
NS_IMETHOD Create(nsIWidget *aParent,
|
||||
void *aNativeParent,
|
||||
@ -87,6 +88,7 @@ public:
|
||||
return NS_OK;
|
||||
}
|
||||
virtual nsIntPoint WidgetToScreenOffset();
|
||||
void DispatchTouchInputViaAPZ(mozilla::MultiTouchInput& aInput);
|
||||
NS_IMETHOD DispatchEvent(mozilla::WidgetGUIEvent* aEvent,
|
||||
nsEventStatus& aStatus);
|
||||
NS_IMETHOD CaptureRollupEvents(nsIRollupListener *aListener,
|
||||
|
Loading…
Reference in New Issue
Block a user