This patch tries to dispatch ePointerRawUpdate with PresShell::EventHandler::DispatchPrecedingPointerEvent as same as usual pointer events. For using the path, this patch adds 2 internal events, eMouseRawUpdate and eTouchRawUpdate which are never dispatched into the DOM because PresShell::EventHandler::DispatchPrecedingPointerEvent will return false for that and then the caller will stop handling the internal events. There are 3 dispatchers of the internal raw update events. One is PresShell::EnsurePrecedingPointerRawUpdate(). This dispatches the internal event if and only if the coming event of PresShell::HandleEvent will cause ePointerMove. The reason why PresShell::HandleEvent handles the preceding raw-update event is, we should support ePointerRawUpdate events for synthesized events for tests (in-process ones) and in the main process. Additionally, if a pointerrawupdate event may destroy the target <iframe>. In such ase, the following pointermove may need to be dispatched on its parent window or another <iframe> window. Therefore, we need to dispatch the internal raw update event before considering the target window (PresShell) and handling the capturing element. The others are BrowserChild::RecvRealMouseMoveEvent and BrowserChild::RecvRealTouchMoveEvent. They dispatch the internal events when they won't dispatch the received event immediately to coalesce with further similar input. For avoiding to dispatch the internal event for same source event, this adds WidgetPointerHelper::convertToPointerRawUpdate member to check it in PresShell::HandlePrecedingPointerRawUpdate. Differential Revision: https://phabricator.services.mozilla.com/D243404
100 lines
2.9 KiB
C++
100 lines
2.9 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#ifndef mozilla_dom_CoalescedInputData_h
|
|
#define mozilla_dom_CoalescedInputData_h
|
|
|
|
#include "mozilla/UniquePtr.h"
|
|
#include "mozilla/layers/ScrollableLayerGuid.h"
|
|
#include "nsRefreshObservers.h"
|
|
|
|
class nsRefreshDriver;
|
|
|
|
namespace mozilla::dom {
|
|
|
|
class BrowserChild;
|
|
|
|
template <class InputEventType>
|
|
class CoalescedInputData {
|
|
protected:
|
|
using ScrollableLayerGuid = mozilla::layers::ScrollableLayerGuid;
|
|
|
|
UniquePtr<InputEventType> mCoalescedInputEvent;
|
|
ScrollableLayerGuid mGuid;
|
|
uint64_t mInputBlockId = 0;
|
|
uint32_t mGeneration = 0;
|
|
|
|
void AdvanceGeneration() {
|
|
if (!IsEmpty()) {
|
|
mGeneration++;
|
|
}
|
|
}
|
|
|
|
public:
|
|
CoalescedInputData() = default;
|
|
|
|
void RetrieveDataFrom(CoalescedInputData& aSource) {
|
|
aSource.AdvanceGeneration();
|
|
AdvanceGeneration();
|
|
mCoalescedInputEvent = std::move(aSource.mCoalescedInputEvent);
|
|
mGuid = aSource.mGuid;
|
|
mInputBlockId = aSource.mInputBlockId;
|
|
}
|
|
|
|
bool IsEmpty() { return !mCoalescedInputEvent; }
|
|
|
|
bool CanCoalesce(const InputEventType& aEvent,
|
|
const ScrollableLayerGuid& aGuid,
|
|
const uint64_t& aInputBlockId);
|
|
|
|
UniquePtr<InputEventType> TakeCoalescedEvent() {
|
|
AdvanceGeneration();
|
|
return std::move(mCoalescedInputEvent);
|
|
}
|
|
|
|
ScrollableLayerGuid GetScrollableLayerGuid() { return mGuid; }
|
|
|
|
uint64_t GetInputBlockId() { return mInputBlockId; }
|
|
|
|
/**
|
|
* The generation number of the latest state stored by the instance.
|
|
* It'll be incremented when the coalesced event data is retrieved or taken.
|
|
* So, this is useful to avoid handling same coalesced events twice when
|
|
* a nested event loop may handle this.
|
|
* NOTE: You should compare the value only with `==` or `!=`. Do not use
|
|
* `<` nor `>` because the value may circulate to 0 from UINT32_MAX.
|
|
*/
|
|
[[nodiscard]] uint32_t Generation() const { return mGeneration; }
|
|
};
|
|
|
|
class CoalescedInputFlusher : public nsARefreshObserver {
|
|
public:
|
|
explicit CoalescedInputFlusher(BrowserChild* aBrowserChild);
|
|
|
|
virtual void WillRefresh(mozilla::TimeStamp aTime) override = 0;
|
|
|
|
NS_INLINE_DECL_REFCOUNTING(CoalescedInputFlusher, override)
|
|
|
|
void StartObserver();
|
|
void RemoveObserver();
|
|
|
|
/**
|
|
* Return a refresh driver which is proper one for BrowserChild.
|
|
* Note that this is not a getter of mRefreshDriver.
|
|
*/
|
|
[[nodiscard]] nsRefreshDriver* GetRefreshDriver();
|
|
|
|
protected:
|
|
virtual ~CoalescedInputFlusher();
|
|
|
|
BrowserChild* mBrowserChild;
|
|
// A refresh driver which this instance waits for the next refresh of.
|
|
RefPtr<nsRefreshDriver> mRefreshDriver;
|
|
};
|
|
} // namespace mozilla::dom
|
|
|
|
#endif // mozilla_dom_CoalescedInputData_h
|