Handle in-process APZ events correctly on Windows. (bug 1111873 part 2, r=kats)

--HG--
extra : rebase_source : 8ca5156392705e3a1806fc6a15154dbaa380f438
This commit is contained in:
David Anderson 2014-12-18 15:25:03 -08:00
Родитель 82682ed576
Коммит e2f100731e
8 изменённых файлов: 79 добавлений и 9 удалений

Просмотреть файл

@ -2150,6 +2150,11 @@ TabParent::MaybeForwardEventToRenderFrame(WidgetInputEvent& aEvent,
if (aOutInputBlockId) {
*aOutInputBlockId = InputAPZContext::GetInputBlockId();
}
// Let the widget know that the event will be sent to the child process,
// which will (hopefully) send a confirmation notice back to APZ.
InputAPZContext::SetRoutedToChildProcess();
return nsEventStatus_eIgnore;
}

Просмотреть файл

@ -1013,6 +1013,13 @@ APZCTreeManager::SetTargetAPZC(uint64_t aInputBlockId,
mInputQueue->SetConfirmedTargetApzc(aInputBlockId, target);
}
void
APZCTreeManager::SetTargetAPZC(uint64_t aInputBlockId, const ScrollableLayerGuid& aTarget)
{
nsRefPtr<AsyncPanZoomController> target = GetTargetAPZC(aTarget);
mInputQueue->SetConfirmedTargetApzc(aInputBlockId, target);
}
void
APZCTreeManager::UpdateZoomConstraints(const ScrollableLayerGuid& aGuid,
const ZoomConstraints& aConstraints)

Просмотреть файл

@ -228,6 +228,12 @@ public:
void SetTargetAPZC(uint64_t aInputBlockId,
const nsTArray<ScrollableLayerGuid>& aTargets);
/**
* Helper function for SetTargetAPZC when used with single-target events,
* such as mouse wheel events.
*/
void SetTargetAPZC(uint64_t aInputBlockId, const ScrollableLayerGuid& aTarget);
/**
* Updates any zoom constraints contained in the <meta name="viewport"> tag.
*/

Просмотреть файл

@ -10,6 +10,7 @@ namespace layers {
ScrollableLayerGuid InputAPZContext::sGuid;
uint64_t InputAPZContext::sBlockId = 0;
bool InputAPZContext::sRoutedToChildProcess = false;
/*static*/ ScrollableLayerGuid
InputAPZContext::GetTargetLayerGuid()
@ -23,19 +24,34 @@ InputAPZContext::GetInputBlockId()
return sBlockId;
}
/*static*/ void
InputAPZContext::SetRoutedToChildProcess()
{
sRoutedToChildProcess = true;
}
InputAPZContext::InputAPZContext(const ScrollableLayerGuid& aGuid,
const uint64_t& aBlockId)
: mOldGuid(sGuid)
, mOldBlockId(sBlockId)
, mOldRoutedToChildProcess(sRoutedToChildProcess)
{
sGuid = aGuid;
sBlockId = aBlockId;
sRoutedToChildProcess = false;
}
InputAPZContext::~InputAPZContext()
{
sGuid = mOldGuid;
sBlockId = mOldBlockId;
sRoutedToChildProcess = mOldRoutedToChildProcess;
}
bool
InputAPZContext::WasRoutedToChildProcess()
{
return sRoutedToChildProcess;
}
}

Просмотреть файл

@ -20,18 +20,23 @@ class MOZ_STACK_CLASS InputAPZContext
private:
static ScrollableLayerGuid sGuid;
static uint64_t sBlockId;
static bool sRoutedToChildProcess;
public:
static ScrollableLayerGuid GetTargetLayerGuid();
static uint64_t GetInputBlockId();
static void SetRoutedToChildProcess();
InputAPZContext(const ScrollableLayerGuid& aGuid,
const uint64_t& aBlockId);
~InputAPZContext();
bool WasRoutedToChildProcess();
private:
ScrollableLayerGuid mOldGuid;
uint64_t mOldBlockId;
bool mOldRoutedToChildProcess;
};
}

Просмотреть файл

@ -46,6 +46,8 @@
#include "mozilla/VsyncDispatcher.h"
#include "mozilla/layers/APZCTreeManager.h"
#include "mozilla/layers/ChromeProcessController.h"
#include "mozilla/layers/InputAPZContext.h"
#include "mozilla/dom/TabParent.h"
#ifdef ACCESSIBILITY
#include "nsAccessibilityService.h"
@ -940,6 +942,27 @@ void nsBaseWidget::ConfigureAPZCTreeManager()
}
}
nsEventStatus
nsBaseWidget::DispatchEventForAPZ(WidgetGUIEvent* aEvent,
const ScrollableLayerGuid& aGuid,
uint64_t aInputBlockId)
{
InputAPZContext context(aGuid, aInputBlockId);
nsEventStatus status;
DispatchEvent(aEvent, status);
if (mAPZC && !context.WasRoutedToChildProcess()) {
// APZ did not find a dispatch-to-content region in the child process,
// and EventStateManager did not route the event into the child process.
// It's safe to communicate to APZ that the event has been processed.
mAPZC->SetTargetAPZC(aInputBlockId, aGuid);
mAPZC->ContentReceivedInputBlock(aInputBlockId, aEvent->mFlags.mDefaultPrevented);
}
return status;
}
void
nsBaseWidget::GetPreferredCompositorBackends(nsTArray<LayersBackend>& aHints)
{

Просмотреть файл

@ -36,6 +36,7 @@ class CompositorChild;
class CompositorParent;
class APZCTreeManager;
class GeckoContentController;
struct ScrollableLayerGuid;
}
class VsyncDispatcher;
@ -88,6 +89,7 @@ protected:
typedef mozilla::layers::CompositorParent CompositorParent;
typedef mozilla::layers::APZCTreeManager APZCTreeManager;
typedef mozilla::layers::GeckoContentController GeckoContentController;
typedef mozilla::layers::ScrollableLayerGuid ScrollableLayerGuid;
typedef mozilla::ScreenRotation ScreenRotation;
virtual ~nsBaseWidget();
@ -311,6 +313,12 @@ protected:
virtual void ConfigureAPZCTreeManager();
virtual already_AddRefed<GeckoContentController> CreateRootContentController();
// Dispatch an event that has been routed through APZ directly from the
// widget.
nsEventStatus DispatchEventForAPZ(mozilla::WidgetGUIEvent* aEvent,
const ScrollableLayerGuid& aGuid,
uint64_t aInputBlockId);
const nsIntRegion RegionFromArray(const nsTArray<nsIntRect>& aRects);
void ArrayFromRegion(const nsIntRegion& aRegion, nsTArray<nsIntRect>& aRects);

Просмотреть файл

@ -3742,20 +3742,20 @@ bool nsWindow::DispatchKeyboardEvent(WidgetGUIEvent* event)
bool nsWindow::DispatchScrollEvent(WidgetGUIEvent* aEvent)
{
uint64_t inputBlockId = 0;
ScrollableLayerGuid guid;
nsEventStatus status;
if (mAPZC && aEvent->mClass == eWheelEventClass) {
nsEventStatus status = mAPZC->ReceiveInputEvent(*aEvent->AsWheelEvent(), &guid, &inputBlockId);
if (status == nsEventStatus_eConsumeNoDefault) {
uint64_t inputBlockId = 0;
ScrollableLayerGuid guid;
nsEventStatus result = mAPZC->ReceiveInputEvent(*aEvent->AsWheelEvent(), &guid, &inputBlockId);
if (result == nsEventStatus_eConsumeNoDefault) {
return true;
}
status = DispatchEventForAPZ(aEvent, guid, inputBlockId);
} else {
DispatchEvent(aEvent, status);
}
InputAPZContext context(guid, inputBlockId);
nsEventStatus status;
DispatchEvent(aEvent, status);
return ConvertStatus(status);
}