зеркало из https://github.com/mozilla/gecko-dev.git
Bug 968148 - Implement PointerCapture for pointer events. r=smaug
--HG-- extra : rebase_source : 331cf187194c8827e4b75835e85b2d79fdc419c7
This commit is contained in:
Родитель
026df43863
Коммит
2af751cef5
|
@ -632,6 +632,32 @@ public:
|
||||||
GetElementsByClassName(const nsAString& aClassNames);
|
GetElementsByClassName(const nsAString& aClassNames);
|
||||||
bool MozMatchesSelector(const nsAString& aSelector,
|
bool MozMatchesSelector(const nsAString& aSelector,
|
||||||
ErrorResult& aError);
|
ErrorResult& aError);
|
||||||
|
void SetPointerCapture(int32_t aPointerId, ErrorResult& aError)
|
||||||
|
{
|
||||||
|
bool activeState = false;
|
||||||
|
if (!nsIPresShell::GetPointerInfo(aPointerId, activeState)) {
|
||||||
|
aError.Throw(NS_ERROR_DOM_INVALID_POINTER_ERR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!activeState) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
nsIPresShell::SetPointerCapturingContent(aPointerId, this);
|
||||||
|
}
|
||||||
|
void ReleasePointerCapture(int32_t aPointerId, ErrorResult& aError)
|
||||||
|
{
|
||||||
|
bool activeState = false;
|
||||||
|
if (!nsIPresShell::GetPointerInfo(aPointerId, activeState)) {
|
||||||
|
aError.Throw(NS_ERROR_DOM_INVALID_POINTER_ERR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ignoring ReleasePointerCapture call on incorrect element (on element
|
||||||
|
// that didn't have capture before).
|
||||||
|
if (nsIPresShell::GetPointerCapturingContent(aPointerId) == this) {
|
||||||
|
nsIPresShell::ReleasePointerCapturingContent(aPointerId, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
void SetCapture(bool aRetargetToElement)
|
void SetCapture(bool aRetargetToElement)
|
||||||
{
|
{
|
||||||
// If there is already an active capture, ignore this request. This would
|
// If there is already an active capture, ignore this request. This would
|
||||||
|
|
|
@ -50,6 +50,7 @@ enum DOM4ErrorTypeCodeMap {
|
||||||
TimeoutError = nsIDOMDOMException::TIMEOUT_ERR,
|
TimeoutError = nsIDOMDOMException::TIMEOUT_ERR,
|
||||||
InvalidNodeTypeError = nsIDOMDOMException::INVALID_NODE_TYPE_ERR,
|
InvalidNodeTypeError = nsIDOMDOMException::INVALID_NODE_TYPE_ERR,
|
||||||
DataCloneError = nsIDOMDOMException::DATA_CLONE_ERR,
|
DataCloneError = nsIDOMDOMException::DATA_CLONE_ERR,
|
||||||
|
InvalidPointerId = nsIDOMDOMException::INVALID_POINTER_ERR,
|
||||||
EncodingError = 0,
|
EncodingError = 0,
|
||||||
|
|
||||||
/* XXX Should be JavaScript native errors */
|
/* XXX Should be JavaScript native errors */
|
||||||
|
|
|
@ -30,6 +30,7 @@ DOM4_MSG_DEF(QuotaExceededError, "The quota has been exceeded.", NS_ERROR_DOM_QU
|
||||||
DOM4_MSG_DEF(TimeoutError, "The operation timed out.", NS_ERROR_DOM_TIMEOUT_ERR)
|
DOM4_MSG_DEF(TimeoutError, "The operation timed out.", NS_ERROR_DOM_TIMEOUT_ERR)
|
||||||
DOM4_MSG_DEF(InvalidNodeTypeError, "The supplied node is incorrect or has an incorrect ancestor for this operation.", NS_ERROR_DOM_INVALID_NODE_TYPE_ERR)
|
DOM4_MSG_DEF(InvalidNodeTypeError, "The supplied node is incorrect or has an incorrect ancestor for this operation.", NS_ERROR_DOM_INVALID_NODE_TYPE_ERR)
|
||||||
DOM4_MSG_DEF(DataCloneError, "The object could not be cloned.", NS_ERROR_DOM_DATA_CLONE_ERR)
|
DOM4_MSG_DEF(DataCloneError, "The object could not be cloned.", NS_ERROR_DOM_DATA_CLONE_ERR)
|
||||||
|
DOM4_MSG_DEF(InvalidPointerId, "Invalid pointer id.", NS_ERROR_DOM_INVALID_POINTER_ERR)
|
||||||
|
|
||||||
/* XXX Should be JavaScript native TypeError */
|
/* XXX Should be JavaScript native TypeError */
|
||||||
DOM4_MSG_DEF(TypeError, "The method parameter is missing or invalid.", NS_ERROR_TYPE_ERR)
|
DOM4_MSG_DEF(TypeError, "The method parameter is missing or invalid.", NS_ERROR_TYPE_ERR)
|
||||||
|
|
|
@ -48,26 +48,21 @@ ConvertStringToPointerType(const nsAString& aPointerTypeArg)
|
||||||
return nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN;
|
return nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
//static
|
// static
|
||||||
already_AddRefed<PointerEvent>
|
already_AddRefed<PointerEvent>
|
||||||
PointerEvent::Constructor(const GlobalObject& aGlobal,
|
PointerEvent::Constructor(EventTarget* aOwner,
|
||||||
const nsAString& aType,
|
const nsAString& aType,
|
||||||
const PointerEventInit& aParam,
|
const PointerEventInit& aParam)
|
||||||
ErrorResult& aRv)
|
|
||||||
{
|
{
|
||||||
nsCOMPtr<EventTarget> t = do_QueryInterface(aGlobal.GetAsSupports());
|
nsRefPtr<PointerEvent> e = new PointerEvent(aOwner, nullptr, nullptr);
|
||||||
nsRefPtr<PointerEvent> e = new PointerEvent(t, nullptr, nullptr);
|
bool trusted = e->Init(aOwner);
|
||||||
bool trusted = e->Init(t);
|
|
||||||
|
|
||||||
aRv = e->InitMouseEvent(aType, aParam.mBubbles, aParam.mCancelable,
|
e->InitMouseEvent(aType, aParam.mBubbles, aParam.mCancelable,
|
||||||
aParam.mView, aParam.mDetail, aParam.mScreenX,
|
aParam.mView, aParam.mDetail, aParam.mScreenX,
|
||||||
aParam.mScreenY, aParam.mClientX, aParam.mClientY,
|
aParam.mScreenY, aParam.mClientX, aParam.mClientY,
|
||||||
aParam.mCtrlKey, aParam.mAltKey, aParam.mShiftKey,
|
aParam.mCtrlKey, aParam.mAltKey, aParam.mShiftKey,
|
||||||
aParam.mMetaKey, aParam.mButton,
|
aParam.mMetaKey, aParam.mButton,
|
||||||
aParam.mRelatedTarget);
|
aParam.mRelatedTarget);
|
||||||
if (aRv.Failed()) {
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
WidgetPointerEvent* widgetEvent = e->mEvent->AsPointerEvent();
|
WidgetPointerEvent* widgetEvent = e->mEvent->AsPointerEvent();
|
||||||
widgetEvent->pointerId = aParam.mPointerId;
|
widgetEvent->pointerId = aParam.mPointerId;
|
||||||
|
@ -84,6 +79,17 @@ PointerEvent::Constructor(const GlobalObject& aGlobal,
|
||||||
return e.forget();
|
return e.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// static
|
||||||
|
already_AddRefed<PointerEvent>
|
||||||
|
PointerEvent::Constructor(const GlobalObject& aGlobal,
|
||||||
|
const nsAString& aType,
|
||||||
|
const PointerEventInit& aParam,
|
||||||
|
ErrorResult& aRv)
|
||||||
|
{
|
||||||
|
nsCOMPtr<EventTarget> owner = do_QueryInterface(aGlobal.GetAsSupports());
|
||||||
|
return Constructor(owner, aType, aParam);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PointerEvent::GetPointerType(nsAString& aPointerType)
|
PointerEvent::GetPointerType(nsAString& aPointerType)
|
||||||
{
|
{
|
||||||
|
|
|
@ -34,6 +34,11 @@ public:
|
||||||
const PointerEventInit& aParam,
|
const PointerEventInit& aParam,
|
||||||
ErrorResult& aRv);
|
ErrorResult& aRv);
|
||||||
|
|
||||||
|
static already_AddRefed<PointerEvent>
|
||||||
|
Constructor(EventTarget* aOwner,
|
||||||
|
const nsAString& aType,
|
||||||
|
const PointerEventInit& aParam);
|
||||||
|
|
||||||
int32_t PointerId();
|
int32_t PointerId();
|
||||||
int32_t Width();
|
int32_t Width();
|
||||||
int32_t Height();
|
int32_t Height();
|
||||||
|
|
|
@ -45,6 +45,7 @@ interface nsIDOMDOMException : nsISupports
|
||||||
const unsigned short TIMEOUT_ERR = 23;
|
const unsigned short TIMEOUT_ERR = 23;
|
||||||
const unsigned short INVALID_NODE_TYPE_ERR = 24;
|
const unsigned short INVALID_NODE_TYPE_ERR = 24;
|
||||||
const unsigned short DATA_CLONE_ERR = 25;
|
const unsigned short DATA_CLONE_ERR = 25;
|
||||||
|
const unsigned short INVALID_POINTER_ERR = 26;
|
||||||
|
|
||||||
readonly attribute unsigned short code;
|
readonly attribute unsigned short code;
|
||||||
};
|
};
|
||||||
|
|
|
@ -89,6 +89,13 @@ interface Element : Node {
|
||||||
[Throws, Pure]
|
[Throws, Pure]
|
||||||
boolean mozMatchesSelector(DOMString selector);
|
boolean mozMatchesSelector(DOMString selector);
|
||||||
|
|
||||||
|
// Pointer events methods.
|
||||||
|
[Throws, Pref="dom.w3c_pointer_events.enabled"]
|
||||||
|
void setPointerCapture(long pointerId);
|
||||||
|
|
||||||
|
[Throws, Pref="dom.w3c_pointer_events.enabled"]
|
||||||
|
void releasePointerCapture(long pointerId);
|
||||||
|
|
||||||
// Proprietary extensions
|
// Proprietary extensions
|
||||||
/**
|
/**
|
||||||
* Set this during a mousedown event to grab and retarget all mouse events
|
* Set this during a mousedown event to grab and retarget all mouse events
|
||||||
|
|
|
@ -105,6 +105,10 @@ interface GlobalEventHandlers {
|
||||||
attribute EventHandler onpointerenter;
|
attribute EventHandler onpointerenter;
|
||||||
[Pref="dom.w3c_pointer_events.enabled"]
|
[Pref="dom.w3c_pointer_events.enabled"]
|
||||||
attribute EventHandler onpointerleave;
|
attribute EventHandler onpointerleave;
|
||||||
|
[Pref="dom.w3c_pointer_events.enabled"]
|
||||||
|
attribute EventHandler ongotpointercapture;
|
||||||
|
[Pref="dom.w3c_pointer_events.enabled"]
|
||||||
|
attribute EventHandler onlostpointercapture;
|
||||||
|
|
||||||
// Mozilla-specific handlers
|
// Mozilla-specific handlers
|
||||||
attribute EventHandler onmozfullscreenchange;
|
attribute EventHandler onmozfullscreenchange;
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include <stdio.h> // for FILE definition
|
#include <stdio.h> // for FILE definition
|
||||||
#include "nsChangeHint.h"
|
#include "nsChangeHint.h"
|
||||||
#include "nsRefPtrHashtable.h"
|
#include "nsRefPtrHashtable.h"
|
||||||
|
#include "nsClassHashtable.h"
|
||||||
#include "nsPresArena.h"
|
#include "nsPresArena.h"
|
||||||
#include "nsIImageLoadingContent.h"
|
#include "nsIImageLoadingContent.h"
|
||||||
#include "nsMargin.h"
|
#include "nsMargin.h"
|
||||||
|
@ -1163,6 +1164,32 @@ public:
|
||||||
static nsRefPtrHashtable<nsUint32HashKey, mozilla::dom::Touch>* gCaptureTouchList;
|
static nsRefPtrHashtable<nsUint32HashKey, mozilla::dom::Touch>* gCaptureTouchList;
|
||||||
static bool gPreventMouseEvents;
|
static bool gPreventMouseEvents;
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
static nsRefPtrHashtable<nsUint32HashKey, nsIContent>* gPointerCaptureList;
|
||||||
|
|
||||||
|
struct PointerInfo
|
||||||
|
{
|
||||||
|
bool mActiveState;
|
||||||
|
uint16_t mPointerType;
|
||||||
|
PointerInfo(bool aActiveState, uint16_t aPointerType) :
|
||||||
|
mActiveState(aActiveState), mPointerType(aPointerType) {}
|
||||||
|
};
|
||||||
|
// Keeps information about pointers such as pointerId, activeState, pointerType
|
||||||
|
static nsClassHashtable<nsUint32HashKey, PointerInfo>* gActivePointersIds;
|
||||||
|
|
||||||
|
static void DispatchGotOrLostPointerCaptureEvent(bool aIsGotCapture,
|
||||||
|
uint32_t aPointerId,
|
||||||
|
nsIContent* aCaptureTarget);
|
||||||
|
static void SetPointerCapturingContent(uint32_t aPointerId, nsIContent* aContent);
|
||||||
|
static void ReleasePointerCapturingContent(uint32_t aPointerId, nsIContent* aContent);
|
||||||
|
static nsIContent* GetPointerCapturingContent(uint32_t aPointerId);
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When capturing content is set, it traps all mouse events and retargets
|
* When capturing content is set, it traps all mouse events and retargets
|
||||||
* them at this content node. If capturing is not allowed
|
* them at this content node. If capturing is not allowed
|
||||||
|
|
|
@ -46,6 +46,7 @@
|
||||||
#include "mozilla/dom/Element.h"
|
#include "mozilla/dom/Element.h"
|
||||||
#include "mozilla/dom/Event.h" // for Event::GetEventPopupControlState()
|
#include "mozilla/dom/Event.h" // for Event::GetEventPopupControlState()
|
||||||
#include "mozilla/dom/ShadowRoot.h"
|
#include "mozilla/dom/ShadowRoot.h"
|
||||||
|
#include "mozilla/dom/PointerEvent.h"
|
||||||
#include "nsIDocument.h"
|
#include "nsIDocument.h"
|
||||||
#include "nsCSSStyleSheet.h"
|
#include "nsCSSStyleSheet.h"
|
||||||
#include "nsAnimationManager.h"
|
#include "nsAnimationManager.h"
|
||||||
|
@ -81,6 +82,7 @@
|
||||||
#include "nsILineIterator.h" // for ScrollContentIntoView
|
#include "nsILineIterator.h" // for ScrollContentIntoView
|
||||||
#include "pldhash.h"
|
#include "pldhash.h"
|
||||||
#include "mozilla/dom/Touch.h"
|
#include "mozilla/dom/Touch.h"
|
||||||
|
#include "mozilla/dom/PointerEventBinding.h"
|
||||||
#include "nsIObserverService.h"
|
#include "nsIObserverService.h"
|
||||||
#include "nsDocShell.h" // for reflow observation
|
#include "nsDocShell.h" // for reflow observation
|
||||||
#include "nsIBaseWindow.h"
|
#include "nsIBaseWindow.h"
|
||||||
|
@ -188,6 +190,8 @@ CapturingContentInfo nsIPresShell::gCaptureInfo =
|
||||||
false /* mPreventDrag */, nullptr /* mContent */ };
|
false /* mPreventDrag */, nullptr /* mContent */ };
|
||||||
nsIContent* nsIPresShell::gKeyDownTarget;
|
nsIContent* nsIPresShell::gKeyDownTarget;
|
||||||
nsRefPtrHashtable<nsUint32HashKey, dom::Touch>* nsIPresShell::gCaptureTouchList;
|
nsRefPtrHashtable<nsUint32HashKey, dom::Touch>* nsIPresShell::gCaptureTouchList;
|
||||||
|
nsRefPtrHashtable<nsUint32HashKey, nsIContent>* nsIPresShell::gPointerCaptureList;
|
||||||
|
nsClassHashtable<nsUint32HashKey, nsIPresShell::PointerInfo>* nsIPresShell::gActivePointersIds;
|
||||||
bool nsIPresShell::gPreventMouseEvents = false;
|
bool nsIPresShell::gPreventMouseEvents = false;
|
||||||
|
|
||||||
// convert a color value to a string, in the CSS format #RRGGBB
|
// convert a color value to a string, in the CSS format #RRGGBB
|
||||||
|
@ -5957,6 +5961,98 @@ nsIPresShell::SetCapturingContent(nsIContent* aContent, uint8_t aFlags)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* static */ void
|
||||||
|
nsIPresShell::SetPointerCapturingContent(uint32_t aPointerId, nsIContent* aContent)
|
||||||
|
{
|
||||||
|
nsIContent* content = GetPointerCapturingContent(aPointerId);
|
||||||
|
|
||||||
|
PointerInfo* pointerInfo = nullptr;
|
||||||
|
if (!content && gActivePointersIds->Get(aPointerId, &pointerInfo) &&
|
||||||
|
pointerInfo &&
|
||||||
|
nsIDOMMouseEvent::MOZ_SOURCE_MOUSE == pointerInfo->mPointerType) {
|
||||||
|
SetCapturingContent(aContent, CAPTURE_PREVENTDRAG);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (content) {
|
||||||
|
// Releasing capture for given pointer.
|
||||||
|
gPointerCaptureList->Remove(aPointerId);
|
||||||
|
DispatchGotOrLostPointerCaptureEvent(false, aPointerId, content);
|
||||||
|
// Need to check the state because a lostpointercapture listener
|
||||||
|
// may have called SetPointerCapture
|
||||||
|
if (GetPointerCapturingContent(aPointerId)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
gPointerCaptureList->Put(aPointerId, aContent);
|
||||||
|
DispatchGotOrLostPointerCaptureEvent(true, aPointerId, aContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */ void
|
||||||
|
nsIPresShell::ReleasePointerCapturingContent(uint32_t aPointerId, nsIContent* aContent)
|
||||||
|
{
|
||||||
|
if (gActivePointersIds->Get(aPointerId)) {
|
||||||
|
SetCapturingContent(nullptr, CAPTURE_PREVENTDRAG);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Releasing capture for given pointer.
|
||||||
|
gPointerCaptureList->Remove(aPointerId);
|
||||||
|
|
||||||
|
DispatchGotOrLostPointerCaptureEvent(false, aPointerId, aContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */ nsIContent*
|
||||||
|
nsIPresShell::GetPointerCapturingContent(uint32_t aPointerId)
|
||||||
|
{
|
||||||
|
return gPointerCaptureList->GetWeak(aPointerId);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* static */ bool
|
||||||
|
nsIPresShell::GetPointerInfo(uint32_t aPointerId, bool& aActiveState)
|
||||||
|
{
|
||||||
|
PointerInfo* pointerInfo = nullptr;
|
||||||
|
if (gActivePointersIds->Get(aPointerId, &pointerInfo) && pointerInfo) {
|
||||||
|
aActiveState = pointerInfo->mActiveState;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
PresShell::UpdateActivePointerState(WidgetGUIEvent* aEvent)
|
||||||
|
{
|
||||||
|
switch (aEvent->message) {
|
||||||
|
case NS_MOUSE_ENTER:
|
||||||
|
// In this case we have to know information about available mouse pointers
|
||||||
|
if (WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent()) {
|
||||||
|
gActivePointersIds->Put(mouseEvent->pointerId, new PointerInfo(false, mouseEvent->inputSource));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NS_POINTER_DOWN:
|
||||||
|
// In this case we switch pointer to active state
|
||||||
|
if (WidgetPointerEvent* pointerEvent = aEvent->AsPointerEvent()) {
|
||||||
|
gActivePointersIds->Put(pointerEvent->pointerId, new PointerInfo(true, pointerEvent->inputSource));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NS_POINTER_UP:
|
||||||
|
// 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, new PointerInfo(false, pointerEvent->inputSource));
|
||||||
|
} else {
|
||||||
|
gActivePointersIds->Remove(pointerEvent->pointerId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case NS_MOUSE_EXIT:
|
||||||
|
// In this case we have to remove information about disappeared mouse pointers
|
||||||
|
if (WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent()) {
|
||||||
|
gActivePointersIds->Remove(mouseEvent->pointerId);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
nsIContent*
|
nsIContent*
|
||||||
PresShell::GetCurrentEventContent()
|
PresShell::GetCurrentEventContent()
|
||||||
{
|
{
|
||||||
|
@ -6368,6 +6464,31 @@ DispatchPointerFromMouseOrTouch(PresShell* aShell,
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class ReleasePointerCaptureCaller
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ReleasePointerCaptureCaller() :
|
||||||
|
mPointerId(0),
|
||||||
|
mContent(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
~ReleasePointerCaptureCaller()
|
||||||
|
{
|
||||||
|
if (mContent) {
|
||||||
|
nsIPresShell::ReleasePointerCapturingContent(mPointerId, mContent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void SetTarget(uint32_t aPointerId, nsIContent* aContent)
|
||||||
|
{
|
||||||
|
mPointerId = aPointerId;
|
||||||
|
mContent = aContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int32_t mPointerId;
|
||||||
|
nsCOMPtr<nsIContent> mContent;
|
||||||
|
};
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
PresShell::HandleEvent(nsIFrame* aFrame,
|
PresShell::HandleEvent(nsIFrame* aFrame,
|
||||||
WidgetGUIEvent* aEvent,
|
WidgetGUIEvent* aEvent,
|
||||||
|
@ -6387,6 +6508,9 @@ PresShell::HandleEvent(nsIFrame* aFrame,
|
||||||
}
|
}
|
||||||
|
|
||||||
RecordMouseLocation(aEvent);
|
RecordMouseLocation(aEvent);
|
||||||
|
if (sPointerEventEnabled) {
|
||||||
|
UpdateActivePointerState(aEvent);
|
||||||
|
}
|
||||||
|
|
||||||
if (!nsContentUtils::IsSafeToRunScript())
|
if (!nsContentUtils::IsSafeToRunScript())
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
@ -6468,8 +6592,8 @@ PresShell::HandleEvent(nsIFrame* aFrame,
|
||||||
|
|
||||||
nsIFrame* frame = aFrame;
|
nsIFrame* frame = aFrame;
|
||||||
|
|
||||||
bool dispatchUsingCoordinates = aEvent->IsUsingCoordinates();
|
if (aEvent->IsUsingCoordinates()) {
|
||||||
if (dispatchUsingCoordinates) {
|
ReleasePointerCaptureCaller releasePointerCaptureCaller;
|
||||||
if (nsLayoutUtils::AreAsyncAnimationsEnabled() && mDocument) {
|
if (nsLayoutUtils::AreAsyncAnimationsEnabled() && mDocument) {
|
||||||
if (aEvent->eventStructType == NS_TOUCH_EVENT) {
|
if (aEvent->eventStructType == NS_TOUCH_EVENT) {
|
||||||
nsIDocument::UnlockPointer();
|
nsIDocument::UnlockPointer();
|
||||||
|
@ -6679,6 +6803,27 @@ PresShell::HandleEvent(nsIFrame* aFrame,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (aEvent->eventStructType == NS_POINTER_EVENT &&
|
||||||
|
aEvent->message != NS_POINTER_DOWN) {
|
||||||
|
if (WidgetPointerEvent* pointerEvent = aEvent->AsPointerEvent()) {
|
||||||
|
uint32_t pointerId = pointerEvent->pointerId;
|
||||||
|
nsIContent* pointerCapturingContent = GetPointerCapturingContent(pointerId);
|
||||||
|
|
||||||
|
if (pointerCapturingContent) {
|
||||||
|
if (nsIFrame* capturingFrame = pointerCapturingContent->GetPrimaryFrame()) {
|
||||||
|
frame = capturingFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pointerEvent->message == NS_POINTER_UP ||
|
||||||
|
pointerEvent->message == NS_POINTER_CANCEL) {
|
||||||
|
// Implicitly releasing capture for given pointer.
|
||||||
|
// LOST_POINTER_CAPTURE should be send after NS_POINTER_UP or NS_POINTER_CANCEL.
|
||||||
|
releasePointerCaptureCaller.SetTarget(pointerId, pointerCapturingContent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Suppress mouse event if it's being targeted at an element inside
|
// Suppress mouse event if it's being targeted at an element inside
|
||||||
// a document which needs events suppressed
|
// a document which needs events suppressed
|
||||||
if (aEvent->eventStructType == NS_MOUSE_EVENT &&
|
if (aEvent->eventStructType == NS_MOUSE_EVENT &&
|
||||||
|
@ -7267,6 +7412,26 @@ PresShell::HandleEventInternal(WidgetEvent* aEvent, nsEventStatus* aStatus)
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsIPresShell::DispatchGotOrLostPointerCaptureEvent(bool aIsGotCapture,
|
||||||
|
uint32_t aPointerId,
|
||||||
|
nsIContent* aCaptureTarget)
|
||||||
|
{
|
||||||
|
PointerEventInit init;
|
||||||
|
init.mPointerId = aPointerId;
|
||||||
|
init.mBubbles = true;
|
||||||
|
nsRefPtr<mozilla::dom::PointerEvent> event;
|
||||||
|
event = PointerEvent::Constructor(aCaptureTarget,
|
||||||
|
aIsGotCapture
|
||||||
|
? NS_LITERAL_STRING("gotpointercapture")
|
||||||
|
: NS_LITERAL_STRING("lostpointercapture"),
|
||||||
|
init);
|
||||||
|
if (event) {
|
||||||
|
bool dummy;
|
||||||
|
aCaptureTarget->DispatchEvent(event->InternalDOMEvent(), &dummy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PresShell::DispatchTouchEvent(WidgetEvent* aEvent,
|
PresShell::DispatchTouchEvent(WidgetEvent* aEvent,
|
||||||
nsEventStatus* aStatus,
|
nsEventStatus* aStatus,
|
||||||
|
@ -9814,6 +9979,8 @@ void nsIPresShell::InitializeStatics()
|
||||||
{
|
{
|
||||||
NS_ASSERTION(!gCaptureTouchList, "InitializeStatics called multiple times!");
|
NS_ASSERTION(!gCaptureTouchList, "InitializeStatics called multiple times!");
|
||||||
gCaptureTouchList = new nsRefPtrHashtable<nsUint32HashKey, dom::Touch>;
|
gCaptureTouchList = new nsRefPtrHashtable<nsUint32HashKey, dom::Touch>;
|
||||||
|
gPointerCaptureList = new nsRefPtrHashtable<nsUint32HashKey, nsIContent>;
|
||||||
|
gActivePointersIds = new nsClassHashtable<nsUint32HashKey, PointerInfo>;
|
||||||
}
|
}
|
||||||
|
|
||||||
void nsIPresShell::ReleaseStatics()
|
void nsIPresShell::ReleaseStatics()
|
||||||
|
@ -9821,6 +9988,10 @@ void nsIPresShell::ReleaseStatics()
|
||||||
NS_ASSERTION(gCaptureTouchList, "ReleaseStatics called without Initialize!");
|
NS_ASSERTION(gCaptureTouchList, "ReleaseStatics called without Initialize!");
|
||||||
delete gCaptureTouchList;
|
delete gCaptureTouchList;
|
||||||
gCaptureTouchList = nullptr;
|
gCaptureTouchList = nullptr;
|
||||||
|
delete gPointerCaptureList;
|
||||||
|
gPointerCaptureList = nullptr;
|
||||||
|
delete gActivePointersIds;
|
||||||
|
gActivePointersIds = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Asks our docshell whether we're active.
|
// Asks our docshell whether we're active.
|
||||||
|
|
|
@ -700,6 +700,7 @@ protected:
|
||||||
virtual void ResumePainting() MOZ_OVERRIDE;
|
virtual void ResumePainting() MOZ_OVERRIDE;
|
||||||
|
|
||||||
void UpdateImageVisibility();
|
void UpdateImageVisibility();
|
||||||
|
void UpdateActivePointerState(mozilla::WidgetGUIEvent* aEvent);
|
||||||
|
|
||||||
nsRevocableEventPtr<nsRunnableMethod<PresShell> > mUpdateImageVisibilityEvent;
|
nsRevocableEventPtr<nsRunnableMethod<PresShell> > mUpdateImageVisibilityEvent;
|
||||||
|
|
||||||
|
|
|
@ -44,14 +44,16 @@ class WidgetPointerHelper
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
bool convertToPointer;
|
bool convertToPointer;
|
||||||
|
uint32_t pointerId;
|
||||||
uint32_t tiltX;
|
uint32_t tiltX;
|
||||||
uint32_t tiltY;
|
uint32_t tiltY;
|
||||||
|
|
||||||
WidgetPointerHelper() : convertToPointer(true), tiltX(0), tiltY(0) {}
|
WidgetPointerHelper() : convertToPointer(true), pointerId(0), tiltX(0), tiltY(0) {}
|
||||||
|
|
||||||
void AssignPointerHelperData(const WidgetPointerHelper& aEvent)
|
void AssignPointerHelperData(const WidgetPointerHelper& aEvent)
|
||||||
{
|
{
|
||||||
convertToPointer = aEvent.convertToPointer;
|
convertToPointer = aEvent.convertToPointer;
|
||||||
|
pointerId = aEvent.pointerId;
|
||||||
tiltX = aEvent.tiltX;
|
tiltX = aEvent.tiltX;
|
||||||
tiltY = aEvent.tiltY;
|
tiltY = aEvent.tiltY;
|
||||||
}
|
}
|
||||||
|
@ -560,7 +562,6 @@ public:
|
||||||
|
|
||||||
WidgetPointerEvent(bool aIsTrusted, uint32_t aMsg, nsIWidget* w)
|
WidgetPointerEvent(bool aIsTrusted, uint32_t aMsg, nsIWidget* w)
|
||||||
: WidgetMouseEvent(aIsTrusted, aMsg, w, NS_POINTER_EVENT, eReal)
|
: WidgetMouseEvent(aIsTrusted, aMsg, w, NS_POINTER_EVENT, eReal)
|
||||||
, pointerId(0)
|
|
||||||
, width(0)
|
, width(0)
|
||||||
, height(0)
|
, height(0)
|
||||||
, isPrimary(true)
|
, isPrimary(true)
|
||||||
|
@ -570,7 +571,6 @@ public:
|
||||||
|
|
||||||
WidgetPointerEvent(const WidgetMouseEvent& aEvent)
|
WidgetPointerEvent(const WidgetMouseEvent& aEvent)
|
||||||
: WidgetMouseEvent(aEvent)
|
: WidgetMouseEvent(aEvent)
|
||||||
, pointerId(0)
|
|
||||||
, width(0)
|
, width(0)
|
||||||
, height(0)
|
, height(0)
|
||||||
, isPrimary(true)
|
, isPrimary(true)
|
||||||
|
@ -609,7 +609,6 @@ public:
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t pointerId;
|
|
||||||
uint32_t width;
|
uint32_t width;
|
||||||
uint32_t height;
|
uint32_t height;
|
||||||
bool isPrimary;
|
bool isPrimary;
|
||||||
|
@ -620,7 +619,6 @@ public:
|
||||||
{
|
{
|
||||||
AssignMouseEventData(aEvent, aCopyTargets);
|
AssignMouseEventData(aEvent, aCopyTargets);
|
||||||
|
|
||||||
pointerId = aEvent.pointerId;
|
|
||||||
width = aEvent.width;
|
width = aEvent.width;
|
||||||
height = aEvent.height;
|
height = aEvent.height;
|
||||||
isPrimary = aEvent.isPrimary;
|
isPrimary = aEvent.isPrimary;
|
||||||
|
|
|
@ -808,6 +808,7 @@ MetroInput::InitGeckoMouseEventFromPointerPoint(
|
||||||
aPointerPoint->get_PointerDevice(device.GetAddressOf());
|
aPointerPoint->get_PointerDevice(device.GetAddressOf());
|
||||||
device->get_PointerDeviceType(&deviceType);
|
device->get_PointerDeviceType(&deviceType);
|
||||||
aPointerPoint->get_Properties(props.GetAddressOf());
|
aPointerPoint->get_Properties(props.GetAddressOf());
|
||||||
|
aPointerPoint->get_PointerId(&aEvent->pointerId);
|
||||||
props->get_Pressure(&pressure);
|
props->get_Pressure(&pressure);
|
||||||
props->get_XTilt(&tiltX);
|
props->get_XTilt(&tiltX);
|
||||||
props->get_YTilt(&tiltY);
|
props->get_YTilt(&tiltY);
|
||||||
|
|
|
@ -486,6 +486,7 @@
|
||||||
ERROR(NS_ERROR_DOM_ENCODING_NOT_SUPPORTED_ERR, FAILURE(28)),
|
ERROR(NS_ERROR_DOM_ENCODING_NOT_SUPPORTED_ERR, FAILURE(28)),
|
||||||
ERROR(NS_ERROR_DOM_ENCODING_NOT_UTF_ERR, FAILURE(29)),
|
ERROR(NS_ERROR_DOM_ENCODING_NOT_UTF_ERR, FAILURE(29)),
|
||||||
ERROR(NS_ERROR_DOM_ENCODING_DECODE_ERR, FAILURE(30)),
|
ERROR(NS_ERROR_DOM_ENCODING_DECODE_ERR, FAILURE(30)),
|
||||||
|
ERROR(NS_ERROR_DOM_INVALID_POINTER_ERR, FAILURE(31)),
|
||||||
/* DOM error codes defined by us */
|
/* DOM error codes defined by us */
|
||||||
ERROR(NS_ERROR_DOM_SECMAN_ERR, FAILURE(1001)),
|
ERROR(NS_ERROR_DOM_SECMAN_ERR, FAILURE(1001)),
|
||||||
ERROR(NS_ERROR_DOM_WRONG_TYPE_ERR, FAILURE(1002)),
|
ERROR(NS_ERROR_DOM_WRONG_TYPE_ERR, FAILURE(1002)),
|
||||||
|
|
Загрузка…
Ссылка в новой задаче