--- a/layout/base/nsIPresShell.h
+++ b/layout/base/nsIPresShell.h
@@ -1255,76 +1255,82 @@ public:
bool IsActive()
{
return mIsActive;
}
// mouse capturing
static CapturingContentInfo gCaptureInfo;
- struct PointerCaptureInfo
+ class PointerCaptureInfo final
{
+ public:
nsCOMPtr<nsIContent> mPendingContent;
nsCOMPtr<nsIContent> mOverrideContent;
- bool mPrimaryState;
- explicit PointerCaptureInfo(nsIContent* aPendingContent, bool aPrimaryState) :
- mPendingContent(aPendingContent), mPrimaryState(aPrimaryState)
+ explicit PointerCaptureInfo(nsIContent* aPendingContent)
+ : mPendingContent(aPendingContent)
{
MOZ_COUNT_CTOR(PointerCaptureInfo);
}
+
~PointerCaptureInfo()
{
MOZ_COUNT_DTOR(PointerCaptureInfo);
}
bool Empty()
{
return !(mPendingContent || mOverrideContent);
}
};
- // Keeps a map between pointerId and element that currently capturing pointer
- // with such pointerId. If pointerId is absent in this map then nobody is
- // capturing it. Additionally keep information about pending capturing content.
- // Additionally keep information about primaryState of pointer event.
- static nsClassHashtable<nsUint32HashKey, PointerCaptureInfo>* gPointerCaptureList;
-
- struct PointerInfo
+ class PointerInfo final
{
- bool mActiveState;
- uint16_t mPointerType;
- bool mPrimaryState;
- PointerInfo(bool aActiveState, uint16_t aPointerType, bool aPrimaryState) :
- mActiveState(aActiveState), mPointerType(aPointerType), mPrimaryState(aPrimaryState) {}
+ public:
+ uint16_t mPointerType;
+ bool mActiveState;
+ bool mPrimaryState;
+ explicit PointerInfo(bool aActiveState, uint16_t aPointerType,
+ bool aPrimaryState)
+ : mPointerType(aPointerType)
+ , mActiveState(aActiveState)
+ , mPrimaryState(aPrimaryState)
+ {
+ }
};
- // Keeps information about pointers such as pointerId, activeState, pointerType, primaryState
- static nsClassHashtable<nsUint32HashKey, PointerInfo>* gActivePointersIds;
static void DispatchGotOrLostPointerCaptureEvent(bool aIsGotCapture,
uint32_t aPointerId,
uint16_t aPointerType,
bool aIsPrimary,
nsIContent* aCaptureTarget);
- static void SetPointerCapturingContent(uint32_t aPointerId, nsIContent* aContent);
+ static PointerCaptureInfo* GetPointerCaptureInfo(uint32_t aPointerId);
+ static void SetPointerCapturingContent(uint32_t aPointerId,
+ nsIContent* aContent);
static void ReleasePointerCapturingContent(uint32_t aPointerId);
static nsIContent* GetPointerCapturingContent(uint32_t aPointerId);
- // CheckPointerCaptureState checks cases, when got/lostpointercapture events should be fired.
+ // CheckPointerCaptureState checks cases, when got/lostpointercapture events
+ // should be fired.
static void CheckPointerCaptureState(uint32_t aPointerId,
uint16_t aPointerType, bool aIsPrimary);
- // GetPointerInfo returns true if pointer with aPointerId is situated in device, false otherwise.
- // aActiveState is additional information, which shows state of pointer like button state for mouse.
+ // GetPointerInfo returns true if pointer with aPointerId is situated in
+ // device, false otherwise.
+ // aActiveState is additional information, which shows state of pointer like
+ // button state for mouse.
static bool GetPointerInfo(uint32_t aPointerId, bool& aActiveState);
- // GetPointerType returns pointer type like mouse, pen or touch for pointer event with pointerId
+ // GetPointerType returns pointer type like mouse, pen or touch for pointer
+ // event with pointerId
static uint16_t GetPointerType(uint32_t aPointerId);
- // GetPointerPrimaryState returns state of attribute isPrimary for pointer event with pointerId
+ // GetPointerPrimaryState returns state of attribute isPrimary for pointer
+ // event with pointerId
static bool GetPointerPrimaryState(uint32_t aPointerId);
/**
* When capturing content is set, it traps all mouse events and retargets
* them at this content node. If capturing is not allowed
* (gCaptureInfo.mAllowed is false), then capturing is not set. However, if
* the CAPTURE_IGNOREALLOWED flag is set, the allowed state is ignored and
* capturing is set regardless. To disable capture, pass null for the value
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -224,18 +224,27 @@ using namespace mozilla::layers;
using namespace mozilla::gfx;
using namespace mozilla::layout;
using PaintFrameFlags = nsLayoutUtils::PaintFrameFlags;
CapturingContentInfo nsIPresShell::gCaptureInfo =
{ false /* mAllowed */, false /* mPointerLock */, false /* mRetargetToElement */,
false /* mPreventDrag */ };
nsIContent* nsIPresShell::gKeyDownTarget;
-nsClassHashtable<nsUint32HashKey, nsIPresShell::PointerCaptureInfo>* nsIPresShell::gPointerCaptureList;
-nsClassHashtable<nsUint32HashKey, nsIPresShell::PointerInfo>* nsIPresShell::gActivePointersIds;
+
+// Keeps a map between pointerId and element that currently capturing pointer
+// with such pointerId. If pointerId is absent in this map then nobody is
+// capturing it. Additionally keep information about pending capturing content.
+static nsClassHashtable<nsUint32HashKey,
+ nsIPresShell::PointerCaptureInfo>* sPointerCaptureList;
+
+// Keeps information about pointers such as pointerId, activeState, pointerType,
+// primaryState
+static nsClassHashtable<nsUint32HashKey,
+ nsIPresShell::PointerInfo>* sActivePointersIds;
// RangePaintInfo is used to paint ranges to offscreen buffers
struct RangePaintInfo {
RefPtr<nsRange> mRange;
nsDisplayListBuilder mBuilder;
nsDisplayList mList;
// offset of builder's reference frame to the root frame
@@ -4424,17 +4433,17 @@ PresShell::ContentRemoved(nsIDocument *a
if (mPointerEventTarget) {
if (nsContentUtils::ContentIsDescendantOf(mPointerEventTarget, aChild)) {
mPointerEventTarget = aMaybeContainer;
}
}
// We should check that aChild does not contain pointer capturing elements.
// If it does we should release the pointer capture for the elements.
- for (auto iter = gPointerCaptureList->Iter(); !iter.Done(); iter.Next()) {
+ for (auto iter = sPointerCaptureList->Iter(); !iter.Done(); iter.Next()) {
nsIPresShell::PointerCaptureInfo* data = iter.UserData();
if (data && data->mPendingContent &&
nsContentUtils::ContentIsDescendantOf(data->mPendingContent, aChild)) {
nsIPresShell::ReleasePointerCapturingContent(iter.Key());
}
}
bool didReconstruct;
@@ -6442,154 +6451,160 @@ nsIPresShell::SetCapturingContent(nsICon
gCaptureInfo.mRetargetToElement = ((aFlags & CAPTURE_RETARGETTOELEMENT) != 0) ||
((aFlags & CAPTURE_POINTERLOCK) != 0);
gCaptureInfo.mPreventDrag = (aFlags & CAPTURE_PREVENTDRAG) != 0;
gCaptureInfo.mPointerLock = (aFlags & CAPTURE_POINTERLOCK) != 0;
}
}
/* static */ void
-nsIPresShell::SetPointerCapturingContent(uint32_t aPointerId, nsIContent* aContent)
-{
- PointerCaptureInfo* pointerCaptureInfo = nullptr;
+nsIPresShell::SetPointerCapturingContent(uint32_t aPointerId,
+ nsIContent* aContent)
+{
MOZ_ASSERT(aContent != nullptr);
if (nsIDOMMouseEvent::MOZ_SOURCE_MOUSE == GetPointerType(aPointerId)) {
SetCapturingContent(aContent, CAPTURE_PREVENTDRAG);
}
- if (gPointerCaptureList->Get(aPointerId, &pointerCaptureInfo) &&
- pointerCaptureInfo) {
+ PointerCaptureInfo* pointerCaptureInfo = GetPointerCaptureInfo(aPointerId);
+ if (pointerCaptureInfo) {
pointerCaptureInfo->mPendingContent = aContent;
} else {
- gPointerCaptureList->Put(aPointerId,
- new PointerCaptureInfo(aContent, GetPointerPrimaryState(aPointerId)));
- }
+ sPointerCaptureList->Put(aPointerId, new PointerCaptureInfo(aContent));
+ }
+}
+
+/* static */ nsIPresShell::PointerCaptureInfo*
+nsIPresShell::GetPointerCaptureInfo(uint32_t aPointerId)
+{
+ PointerCaptureInfo* pointerCaptureInfo = nullptr;
+ sPointerCaptureList->Get(aPointerId, &pointerCaptureInfo);
+ return pointerCaptureInfo;
}
/* static */ void
nsIPresShell::ReleasePointerCapturingContent(uint32_t aPointerId)
{
if (nsIDOMMouseEvent::MOZ_SOURCE_MOUSE == GetPointerType(aPointerId)) {
SetCapturingContent(nullptr, CAPTURE_PREVENTDRAG);
}
- PointerCaptureInfo* pointerCaptureInfo = nullptr;
- if (gPointerCaptureList->Get(aPointerId, &pointerCaptureInfo) &&
- pointerCaptureInfo) {
+ PointerCaptureInfo* pointerCaptureInfo = GetPointerCaptureInfo(aPointerId);
+ if (pointerCaptureInfo) {
pointerCaptureInfo->mPendingContent = nullptr;
}
}
/* static */ nsIContent*
nsIPresShell::GetPointerCapturingContent(uint32_t aPointerId)
{
- PointerCaptureInfo* pointerCaptureInfo = nullptr;
- if (gPointerCaptureList->Get(aPointerId, &pointerCaptureInfo) && pointerCaptureInfo) {
+ PointerCaptureInfo* pointerCaptureInfo = GetPointerCaptureInfo(aPointerId);
+ if (pointerCaptureInfo) {
return pointerCaptureInfo->mOverrideContent;
}
return nullptr;
}
/* static */ void
nsIPresShell::CheckPointerCaptureState(uint32_t aPointerId,
uint16_t aPointerType, bool aIsPrimary)
{
- PointerCaptureInfo* captureInfo = nullptr;
- if (gPointerCaptureList->Get(aPointerId, &captureInfo) && captureInfo &&
+ PointerCaptureInfo* captureInfo = GetPointerCaptureInfo(aPointerId);
+ if (captureInfo &&
captureInfo->mPendingContent != captureInfo->mOverrideContent) {
// cache captureInfo->mPendingContent since it may be changed in the pointer
// event listener
nsIContent* pendingContent = captureInfo->mPendingContent.get();
if (captureInfo->mOverrideContent) {
DispatchGotOrLostPointerCaptureEvent(/* aIsGotCapture */ false,
aPointerId, aPointerType, aIsPrimary,
captureInfo->mOverrideContent);
}
if (pendingContent) {
DispatchGotOrLostPointerCaptureEvent(/* aIsGotCapture */ true, aPointerId,
aPointerType, aIsPrimary,
pendingContent);
}
captureInfo->mOverrideContent = pendingContent;
if (captureInfo->Empty()) {
- gPointerCaptureList->Remove(aPointerId);
+ sPointerCaptureList->Remove(aPointerId);
}
}
}
/* static */ uint16_t
nsIPresShell::GetPointerType(uint32_t aPointerId)
{
PointerInfo* pointerInfo = nullptr;
- if (gActivePointersIds->Get(aPointerId, &pointerInfo) && pointerInfo) {
+ if (sActivePointersIds->Get(aPointerId, &pointerInfo) && pointerInfo) {
return pointerInfo->mPointerType;
}
return nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN;
}
/* static */ bool
nsIPresShell::GetPointerPrimaryState(uint32_t aPointerId)
{
PointerInfo* pointerInfo = nullptr;
- if (gActivePointersIds->Get(aPointerId, &pointerInfo) && pointerInfo) {
+ if (sActivePointersIds->Get(aPointerId, &pointerInfo) && pointerInfo) {
return pointerInfo->mPrimaryState;
}
return false;
}
/* static */ bool
nsIPresShell::GetPointerInfo(uint32_t aPointerId, bool& aActiveState)
{
PointerInfo* pointerInfo = nullptr;
- if (gActivePointersIds->Get(aPointerId, &pointerInfo) && pointerInfo) {
+ if (sActivePointersIds->Get(aPointerId, &pointerInfo) && pointerInfo) {
aActiveState = pointerInfo->mActiveState;
return true;
}
return false;
}
void
PresShell::UpdateActivePointerState(WidgetGUIEvent* aEvent)
{
switch (aEvent->mMessage) {
case eMouseEnterIntoWidget:
// In this case we have to know information about available mouse pointers
if (WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent()) {
- gActivePointersIds->Put(mouseEvent->pointerId,
+ sActivePointersIds->Put(mouseEvent->pointerId,
new PointerInfo(false, mouseEvent->inputSource,
true));
}
break;
case ePointerDown:
// In this case we switch pointer to active state
if (WidgetPointerEvent* pointerEvent = aEvent->AsPointerEvent()) {
- gActivePointersIds->Put(pointerEvent->pointerId,
+ sActivePointersIds->Put(pointerEvent->pointerId,
new PointerInfo(true, pointerEvent->inputSource,
pointerEvent->mIsPrimary));
}
break;
case ePointerUp:
// In this case we remove information about pointer or turn off active state
if (WidgetPointerEvent* pointerEvent = aEvent->AsPointerEvent()) {
if(pointerEvent->inputSource != nsIDOMMouseEvent::MOZ_SOURCE_TOUCH) {
- gActivePointersIds->Put(pointerEvent->pointerId,
+ sActivePointersIds->Put(pointerEvent->pointerId,
new PointerInfo(false,
pointerEvent->inputSource,
pointerEvent->mIsPrimary));
} else {
- gActivePointersIds->Remove(pointerEvent->pointerId);
+ sActivePointersIds->Remove(pointerEvent->pointerId);
}
}
break;
case eMouseExitFromWidget:
// In this case we have to remove information about disappeared mouse
// pointers
if (WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent()) {
- gActivePointersIds->Remove(mouseEvent->pointerId);
+ sActivePointersIds->Remove(mouseEvent->pointerId);
}
break;
default:
break;
}
}
nsIContent*
@@ -6894,17 +6909,18 @@ DispatchPointerFromMouseOrTouch(PresShel
event.inputSource = mouseEvent->inputSource;
event.mMessage = pointerMessage;
event.button = button;
event.buttons = mouseEvent->buttons;
event.pressure = event.buttons ?
mouseEvent->pressure ? mouseEvent->pressure : 0.5f :
0.0f;
event.convertToPointer = mouseEvent->convertToPointer = false;
- aShell->HandleEvent(aFrame, &event, aDontRetargetEvents, aStatus, aTargetContent);
+ aShell->HandleEvent(aFrame, &event, aDontRetargetEvents, aStatus,
+ aTargetContent);
} else if (aEvent->mClass == eTouchEventClass) {
WidgetTouchEvent* touchEvent = aEvent->AsTouchEvent();
// loop over all touches and dispatch pointer events on each touch
// copy the event
switch (touchEvent->mMessage) {
case eTouchMove:
pointerMessage = ePointerMove;
break;
@@ -6939,17 +6955,18 @@ DispatchPointerFromMouseOrTouch(PresShel
event.tiltY = touch->tiltY;
event.mTime = touchEvent->mTime;
event.mTimeStamp = touchEvent->mTimeStamp;
event.mFlags = touchEvent->mFlags;
event.button = WidgetMouseEvent::eLeftButton;
event.buttons = WidgetMouseEvent::eLeftButtonFlag;
event.inputSource = nsIDOMMouseEvent::MOZ_SOURCE_TOUCH;
event.convertToPointer = touch->convertToPointer = false;
- aShell->HandleEvent(aFrame, &event, aDontRetargetEvents, aStatus, aTargetContent);
+ aShell->HandleEvent(aFrame, &event, aDontRetargetEvents, aStatus,
+ aTargetContent);
}
}
return NS_OK;
}
class ReleasePointerCaptureCaller
{
public:
@@ -7315,17 +7332,18 @@ PresShell::HandleEvent(nsIFrame* aFrame,
#endif
NS_ASSERTION(aFrame, "aFrame should be not null");
if (sPointerEventEnabled) {
nsWeakFrame weakFrame(aFrame);
nsCOMPtr<nsIContent> targetContent;
DispatchPointerFromMouseOrTouch(this, aFrame, aEvent, aDontRetargetEvents,
- aEventStatus, getter_AddRefs(targetContent));
+ aEventStatus,
+ getter_AddRefs(targetContent));
if (!weakFrame.IsAlive()) {
if (targetContent) {
aFrame = targetContent->GetPrimaryFrame();
if (!aFrame) {
PushCurrentEventInfo(aFrame, targetContent);
nsresult rv = HandleEventInternal(aEvent, aEventStatus, true);
PopCurrentEventInfo();
return rv;
@@ -7713,25 +7731,28 @@ PresShell::HandleEvent(nsIFrame* aFrame,
}
}
}
if (aEvent->mClass == ePointerEventClass &&
aEvent->mMessage != ePointerDown) {
if (WidgetPointerEvent* pointerEvent = aEvent->AsPointerEvent()) {
uint32_t pointerId = pointerEvent->pointerId;
- nsIContent* pointerCapturingContent = GetPointerCapturingContent(pointerId);
+ nsIContent* pointerCapturingContent =
+ GetPointerCapturingContent(pointerId);
if (pointerCapturingContent) {
if (nsIFrame* capturingFrame = pointerCapturingContent->GetPrimaryFrame()) {
- // If pointer capture is set, we should suppress pointerover/pointerenter events
- // for all elements except element which have pointer capture. (Code in EventStateManager)
+ // If pointer capture is set, we should suppress
+ // pointerover/pointerenter events for all elements except element
+ // which have pointer capture. (Code in EventStateManager)
pointerEvent->retargetedByPointerCapture =
frame && frame->GetContent() &&
- !nsContentUtils::ContentIsDescendantOf(frame->GetContent(), pointerCapturingContent);
+ !nsContentUtils::ContentIsDescendantOf(frame->GetContent(),
+ pointerCapturingContent);
frame = capturingFrame;
}
if (pointerEvent->mMessage == ePointerUp ||
pointerEvent->mMessage == ePointerCancel) {
// Implicitly releasing capture for given pointer.
// ePointerLostCapture should be send after ePointerUp or
// ePointerCancel.
@@ -7825,22 +7846,25 @@ PresShell::HandleEvent(nsIFrame* aFrame,
frame = shell->GetRootFrame();
}
}
}
}
}
}
- // Before HandlePositionedEvent we should save mPointerEventTarget in some cases
+ // Before HandlePositionedEvent we should save mPointerEventTarget in some
+ // cases
nsWeakFrame weakFrame;
- if (sPointerEventEnabled && aTargetContent && ePointerEventClass == aEvent->mClass) {
+ if (sPointerEventEnabled && aTargetContent &&
+ ePointerEventClass == aEvent->mClass) {
weakFrame = frame;
shell->mPointerEventTarget = frame->GetContent();
- MOZ_ASSERT(!frame->GetContent() || shell->GetDocument() == frame->GetContent()->OwnerDoc());
+ MOZ_ASSERT(!frame->GetContent() ||
+ shell->GetDocument() == frame->GetContent()->OwnerDoc());
}
nsresult rv;
if (shell != this) {
// Handle the event in the correct shell.
// Prevent deletion until we're done with event handling (bug 336582).
nsCOMPtr<nsIPresShell> kungFuDeathGrip(shell);
// We pass the subshell's root frame as the frame to start from. This is
@@ -7849,17 +7873,18 @@ PresShell::HandleEvent(nsIFrame* aFrame,
// now ask the subshell to dispatch it normally.
rv = shell->HandlePositionedEvent(frame, aEvent, aEventStatus);
} else {
rv = HandlePositionedEvent(frame, aEvent, aEventStatus);
}
// After HandlePositionedEvent we should reestablish
// content (which still live in tree) in some cases
- if (sPointerEventEnabled && aTargetContent && ePointerEventClass == aEvent->mClass) {
+ if (sPointerEventEnabled && aTargetContent &&
+ ePointerEventClass == aEvent->mClass) {
if (!weakFrame.IsAlive()) {
shell->mPointerEventTarget.swap(*aTargetContent);
}
}
return rv;
}
@@ -8319,17 +8344,18 @@ nsIPresShell::DispatchGotOrLostPointerCa
? NS_LITERAL_STRING("gotpointercapture")
: NS_LITERAL_STRING("lostpointercapture"),
init);
if (event) {
bool dummy;
// If the capturing element was removed from the DOM tree,
// lostpointercapture event should be fired at the document.
if (!aIsGotCapture && !aCaptureTarget->IsInUncomposedDoc()) {
- aCaptureTarget->OwnerDoc()->DispatchEvent(event->InternalDOMEvent(), &dummy);
+ aCaptureTarget->OwnerDoc()->DispatchEvent(event->InternalDOMEvent(),
+ &dummy);
} else {
aCaptureTarget->DispatchEvent(event->InternalDOMEvent(), &dummy);
}
}
}
nsresult
PresShell::DispatchEventToDOM(WidgetEvent* aEvent,
@@ -10864,28 +10890,29 @@ nsAccessibilityService*
nsIPresShell::AccService()
{
return GetAccService();
}
#endif
void nsIPresShell::InitializeStatics()
{
- NS_ASSERTION(!gPointerCaptureList, "InitializeStatics called multiple times!");
- gPointerCaptureList = new nsClassHashtable<nsUint32HashKey, PointerCaptureInfo>;
- gActivePointersIds = new nsClassHashtable<nsUint32HashKey, PointerInfo>;
+ MOZ_ASSERT(!sPointerCaptureList, "InitializeStatics called multiple times!");
+ sPointerCaptureList =
+ new nsClassHashtable<nsUint32HashKey, PointerCaptureInfo>;
+ sActivePointersIds = new nsClassHashtable<nsUint32HashKey, PointerInfo>;
}
void nsIPresShell::ReleaseStatics()
{
- NS_ASSERTION(gPointerCaptureList, "ReleaseStatics called without Initialize!");
- delete gPointerCaptureList;
- gPointerCaptureList = nullptr;
- delete gActivePointersIds;
- gActivePointersIds = nullptr;
+ MOZ_ASSERT(sPointerCaptureList, "ReleaseStatics called without Initialize!");
+ delete sPointerCaptureList;
+ sPointerCaptureList = nullptr;
+ delete sActivePointersIds;
+ sActivePointersIds = nullptr;
}
// Asks our docshell whether we're active.
void PresShell::QueryIsActive()
{
nsCOMPtr<nsISupports> container = mPresContext->GetContainerWeak();
if (mDocument) {
nsIDocument* displayDoc = mDocument->GetDisplayDocument();