mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-09 19:35:51 +00:00
Bug 633602 - Implement Pointer Lock (Mouse Lock) API. r=roc, smaug
This commit is contained in:
parent
a1f5e3dae5
commit
012b498c6b
@ -780,6 +780,12 @@ public:
|
||||
*/
|
||||
static void ExitFullScreen(bool aRunAsync);
|
||||
|
||||
|
||||
virtual void RequestPointerLock(Element* aElement) = 0;
|
||||
|
||||
static void UnlockPointer();
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
// Document notification API's
|
||||
|
@ -1329,6 +1329,8 @@ private:
|
||||
NodeHasExplicitBaseURI,
|
||||
// Set if the element has some style states locked
|
||||
ElementHasLockedStyleStates,
|
||||
// Set if element has pointer locked
|
||||
ElementHasPointerLock,
|
||||
// Guard value
|
||||
BooleanFlagCount
|
||||
};
|
||||
@ -1387,6 +1389,9 @@ public:
|
||||
bool IsPurpleRoot() const { return GetBoolFlag(NodeIsPurpleRoot); }
|
||||
|
||||
bool HasListenerManager() { return HasFlag(NODE_HAS_LISTENERMANAGER); }
|
||||
bool HasPointerLock() const { return GetBoolFlag(ElementHasPointerLock); }
|
||||
void SetPointerLock() { SetBoolFlag(ElementHasPointerLock); }
|
||||
void ClearPointerLock() { ClearBoolFlag(ElementHasPointerLock); }
|
||||
protected:
|
||||
void SetParentIsContent(bool aValue) { SetBoolFlag(ParentIsContent, aValue); }
|
||||
void SetInDocument() { SetBoolFlag(IsInDocument); }
|
||||
|
@ -8658,6 +8658,13 @@ nsDocument::ExitFullScreen()
|
||||
// dispatch to so that we dispatch in the specified order.
|
||||
nsAutoTArray<nsIDocument*, 8> changed;
|
||||
|
||||
// We may also need to unlock the pointer, if it's locked.
|
||||
nsCOMPtr<Element> pointerLockedElement =
|
||||
do_QueryReferent(nsEventStateManager::sPointerLockedElement);
|
||||
if (pointerLockedElement) {
|
||||
UnlockPointer();
|
||||
}
|
||||
|
||||
// Walk the tree of full-screen documents, and reset their full-screen state.
|
||||
ResetFullScreen(root, static_cast<void*>(&changed));
|
||||
|
||||
@ -8688,12 +8695,20 @@ nsDocument::RestorePreviousFullScreenState()
|
||||
return;
|
||||
}
|
||||
|
||||
// If fullscreen mode is updated the pointer should be unlocked
|
||||
nsCOMPtr<Element> pointerLockedElement =
|
||||
do_QueryReferent(nsEventStateManager::sPointerLockedElement);
|
||||
if (pointerLockedElement) {
|
||||
UnlockPointer();
|
||||
}
|
||||
|
||||
// Clear full-screen stacks in all descendant documents, bottom up.
|
||||
nsCOMPtr<nsIDocument> fullScreenDoc(do_QueryReferent(sFullScreenDoc));
|
||||
nsIDocument* doc = fullScreenDoc;
|
||||
while (doc != this) {
|
||||
NS_ASSERTION(doc->IsFullScreenDoc(), "Should be full-screen doc");
|
||||
static_cast<nsDocument*>(doc)->ClearFullScreenStack();
|
||||
UnlockPointer();
|
||||
DispatchFullScreenChange(doc);
|
||||
doc = doc->GetParentDocument();
|
||||
}
|
||||
@ -8702,6 +8717,7 @@ nsDocument::RestorePreviousFullScreenState()
|
||||
NS_ASSERTION(doc == this, "Must have reached this doc.");
|
||||
while (doc != nsnull) {
|
||||
static_cast<nsDocument*>(doc)->FullScreenStackPop();
|
||||
UnlockPointer();
|
||||
DispatchFullScreenChange(doc);
|
||||
if (static_cast<nsDocument*>(doc)->mFullScreenStack.IsEmpty()) {
|
||||
// Full-screen stack in document is empty. Go back up to the parent
|
||||
@ -8977,7 +8993,22 @@ nsDocument::RequestFullScreen(Element* aElement, bool aWasCallerChrome)
|
||||
|
||||
// Remember the root document, so that if a full-screen document is hidden
|
||||
// we can reset full-screen state in the remaining visible full-screen documents.
|
||||
sFullScreenRootDoc = do_GetWeakReference(nsContentUtils::GetRootDocument(this));
|
||||
nsIDocument* fullScreenDoc = nsContentUtils::GetRootDocument(this);
|
||||
sFullScreenRootDoc = do_GetWeakReference(fullScreenDoc);
|
||||
|
||||
// If a document is already in fullscreen, then unlock the mouse pointer
|
||||
// before setting a new document to fullscreen
|
||||
if (fullScreenDoc) {
|
||||
UnlockPointer();
|
||||
}
|
||||
|
||||
// If a document is already in fullscreen, then unlock the mouse pointer
|
||||
// before setting a new document to fullscreen
|
||||
nsCOMPtr<Element> pointerLockedElement =
|
||||
do_QueryReferent(nsEventStateManager::sPointerLockedElement);
|
||||
if (pointerLockedElement) {
|
||||
UnlockPointer();
|
||||
}
|
||||
|
||||
// Set the full-screen element. This sets the full-screen style on the
|
||||
// element, and the full-screen-ancestor styles on ancestors of the element
|
||||
@ -9141,6 +9172,223 @@ nsDocument::IsFullScreenEnabled(bool aCallerIsChrome, bool aLogFailure)
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
DispatchPointerLockChange(nsIDocument* aTarget)
|
||||
{
|
||||
nsRefPtr<nsAsyncDOMEvent> e =
|
||||
new nsAsyncDOMEvent(aTarget,
|
||||
NS_LITERAL_STRING("mozpointerlockchange"),
|
||||
true,
|
||||
false);
|
||||
e->PostDOMEvent();
|
||||
}
|
||||
|
||||
static void
|
||||
DispatchPointerLockError(nsIDocument* aTarget)
|
||||
{
|
||||
nsRefPtr<nsAsyncDOMEvent> e =
|
||||
new nsAsyncDOMEvent(aTarget,
|
||||
NS_LITERAL_STRING("mozpointerlockerror"),
|
||||
true,
|
||||
false);
|
||||
e->PostDOMEvent();
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::RequestPointerLock(Element* aElement)
|
||||
{
|
||||
NS_ASSERTION(aElement,
|
||||
"Must pass non-null element to nsDocument::RequestPointerLock");
|
||||
|
||||
nsCOMPtr<Element> pointerLockedElement =
|
||||
do_QueryReferent(nsEventStateManager::sPointerLockedElement);
|
||||
if (aElement == pointerLockedElement) {
|
||||
DispatchPointerLockChange(this);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ShouldLockPointer(aElement) ||
|
||||
!SetPointerLock(aElement, NS_STYLE_CURSOR_NONE)) {
|
||||
DispatchPointerLockError(this);
|
||||
return;
|
||||
}
|
||||
|
||||
aElement->SetPointerLock();
|
||||
nsEventStateManager::sPointerLockedElement = do_GetWeakReference(aElement);
|
||||
nsEventStateManager::sPointerLockedDoc =
|
||||
do_GetWeakReference(static_cast<nsIDocument*>(this));
|
||||
DispatchPointerLockChange(this);
|
||||
}
|
||||
|
||||
bool
|
||||
nsDocument::ShouldLockPointer(Element* aElement)
|
||||
{
|
||||
// Check if pointer lock pref is enabled
|
||||
if (!Preferences::GetBool("full-screen-api.pointer-lock.enabled")) {
|
||||
NS_WARNING("ShouldLockPointer(): Pointer Lock pref not enabled");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aElement != GetFullScreenElement()) {
|
||||
NS_WARNING("ShouldLockPointer(): Element not in fullscreen");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!aElement->IsInDoc()) {
|
||||
NS_WARNING("ShouldLockPointer(): Element without Document");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if the element is in a document with a docshell.
|
||||
nsCOMPtr<nsIDocument> ownerDoc = aElement->OwnerDoc();
|
||||
if (!ownerDoc) {
|
||||
return false;
|
||||
}
|
||||
if (!nsCOMPtr<nsISupports>(ownerDoc->GetContainer())) {
|
||||
return false;
|
||||
}
|
||||
nsCOMPtr<nsPIDOMWindow> ownerWindow = ownerDoc->GetWindow();
|
||||
if (!ownerWindow) {
|
||||
return false;
|
||||
}
|
||||
nsCOMPtr<nsPIDOMWindow> ownerInnerWindow = ownerDoc->GetInnerWindow();
|
||||
if (!ownerInnerWindow) {
|
||||
return false;
|
||||
}
|
||||
if (ownerWindow->GetCurrentInnerWindow() != ownerInnerWindow) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
nsDocument::SetPointerLock(Element* aElement, int aCursorStyle)
|
||||
{
|
||||
// NOTE: aElement will be nsnull when unlocking.
|
||||
nsCOMPtr<nsPIDOMWindow> window = GetWindow();
|
||||
if (!window) {
|
||||
NS_WARNING("SetPointerLock(): No Window");
|
||||
return false;
|
||||
}
|
||||
|
||||
nsIDocShell *docShell = window->GetDocShell();
|
||||
if (!docShell) {
|
||||
NS_WARNING("SetPointerLock(): No DocShell (window already closed?)");
|
||||
return false;
|
||||
}
|
||||
|
||||
nsRefPtr<nsPresContext> presContext;
|
||||
docShell->GetPresContext(getter_AddRefs(presContext));
|
||||
if (!presContext) {
|
||||
NS_WARNING("SetPointerLock(): Unable to get presContext in \
|
||||
domWindow->GetDocShell()->GetPresContext()");
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIPresShell> shell = presContext->PresShell();
|
||||
if (!shell) {
|
||||
NS_WARNING("SetPointerLock(): Unable to find presContext->PresShell()");
|
||||
return false;
|
||||
}
|
||||
|
||||
nsIFrame* rootFrame = shell->GetRootFrame();
|
||||
if (!rootFrame) {
|
||||
NS_WARNING("SetPointerLock(): Unable to get root frame");
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIWidget> widget = rootFrame->GetNearestWidget();
|
||||
if (!widget) {
|
||||
NS_WARNING("SetPointerLock(): Unable to find widget in \
|
||||
shell->GetRootFrame()->GetNearestWidget();");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (aElement && (aElement->OwnerDoc() != this)) {
|
||||
NS_WARNING("SetPointerLock(): Element not in this document.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Hide the cursor and set pointer lock for future mouse events
|
||||
nsRefPtr<nsEventStateManager> esm = presContext->EventStateManager();
|
||||
esm->SetCursor(aCursorStyle, nsnull, false,
|
||||
0.0f, 0.0f, widget, true);
|
||||
esm->SetPointerLock(widget, aElement);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
nsDocument::UnlockPointer()
|
||||
{
|
||||
if (!nsEventStateManager::sIsPointerLocked) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocument> pointerLockedDoc =
|
||||
do_QueryReferent(nsEventStateManager::sPointerLockedDoc);
|
||||
if (!pointerLockedDoc) {
|
||||
return;
|
||||
}
|
||||
nsDocument* doc = static_cast<nsDocument*>(pointerLockedDoc.get());
|
||||
if (!doc->SetPointerLock(nsnull, NS_STYLE_CURSOR_AUTO)) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<Element> pointerLockedElement =
|
||||
do_QueryReferent(nsEventStateManager::sPointerLockedElement);
|
||||
if (!pointerLockedElement) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsEventStateManager::sPointerLockedElement = nsnull;
|
||||
nsEventStateManager::sPointerLockedDoc = nsnull;
|
||||
pointerLockedElement->ClearPointerLock();
|
||||
DispatchPointerLockChange(pointerLockedDoc);
|
||||
}
|
||||
|
||||
void
|
||||
nsIDocument::UnlockPointer()
|
||||
{
|
||||
nsDocument::UnlockPointer();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocument::MozExitPointerLock()
|
||||
{
|
||||
UnlockPointer();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDocument::GetMozPointerLockElement(nsIDOMElement** aPointerLockedElement)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aPointerLockedElement);
|
||||
*aPointerLockedElement = nsnull;
|
||||
nsCOMPtr<Element> pointerLockedElement =
|
||||
do_QueryReferent(nsEventStateManager::sPointerLockedElement);
|
||||
if (!pointerLockedElement) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Make sure pointer locked element is in the same document and domain.
|
||||
nsCOMPtr<nsIDocument> pointerLockedDoc =
|
||||
do_QueryReferent(nsEventStateManager::sPointerLockedDoc);
|
||||
nsDocument* doc = static_cast<nsDocument*>(pointerLockedDoc.get());
|
||||
if (doc != this) {
|
||||
return NS_OK;
|
||||
}
|
||||
nsCOMPtr<nsIDOMNode> pointerLockedNode =
|
||||
do_QueryInterface(pointerLockedElement);
|
||||
nsresult rv = nsContentUtils::CheckSameOrigin(this, pointerLockedNode.get());
|
||||
if (NS_FAILED(rv)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
return CallQueryInterface(pointerLockedElement, aPointerLockedElement);
|
||||
}
|
||||
|
||||
#define EVENT(name_, id_, type_, struct_) \
|
||||
NS_IMETHODIMP nsDocument::GetOn##name_(JSContext *cx, jsval *vp) { \
|
||||
return nsINode::GetOn##name_(cx, vp); \
|
||||
|
@ -988,6 +988,11 @@ public:
|
||||
// Returns the top element from the full-screen stack.
|
||||
Element* FullScreenStackTop();
|
||||
|
||||
void RequestPointerLock(Element* aElement);
|
||||
bool ShouldLockPointer(Element* aElement);
|
||||
bool SetPointerLock(Element* aElement, int aCursorStyle);
|
||||
static void UnlockPointer();
|
||||
|
||||
// This method may fire a DOM event; if it does so it will happen
|
||||
// synchronously.
|
||||
void UpdateVisibilityState();
|
||||
|
@ -3274,6 +3274,9 @@ nsGenericElement::UnbindFromTree(bool aDeep, bool aNullParent)
|
||||
// Fully exit full-screen.
|
||||
nsIDocument::ExitFullScreen(false);
|
||||
}
|
||||
if (HasPointerLock()) {
|
||||
nsIDocument::UnlockPointer();
|
||||
}
|
||||
if (GetParent()) {
|
||||
NS_RELEASE(mParent);
|
||||
} else {
|
||||
@ -6418,7 +6421,15 @@ nsINode::Contains(nsIDOMNode* aOther, bool* aReturn)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsGenericElement::MozRequestFullScreen()
|
||||
NS_IMETHODIMP
|
||||
nsGenericElement::MozRequestPointerLock()
|
||||
{
|
||||
OwnerDoc()->RequestPointerLock(this);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGenericElement::MozRequestFullScreen()
|
||||
{
|
||||
// Only grant full-screen requests if this is called from inside a trusted
|
||||
// event handler (i.e. inside an event handler for a user initiated event).
|
||||
|
@ -592,6 +592,8 @@ GK_ATOM(mousethrough, "mousethrough")
|
||||
GK_ATOM(mouseup, "mouseup")
|
||||
GK_ATOM(mozfullscreenchange, "mozfullscreenchange")
|
||||
GK_ATOM(mozfullscreenerror, "mozfullscreenerror")
|
||||
GK_ATOM(mozpointerlockchange, "mozpointerlockchange")
|
||||
GK_ATOM(mozpointerlockerror, "mozpointerlockerror")
|
||||
GK_ATOM(moz_opaque, "moz-opaque")
|
||||
GK_ATOM(moz_action_hint, "mozactionhint")
|
||||
GK_ATOM(x_moz_errormessage, "x-moz-errormessage")
|
||||
@ -713,6 +715,8 @@ GK_ATOM(onmouseup, "onmouseup")
|
||||
GK_ATOM(onMozAfterPaint, "onMozAfterPaint")
|
||||
GK_ATOM(onmozfullscreenchange, "onmozfullscreenchange")
|
||||
GK_ATOM(onmozfullscreenerror, "onmozfullscreenerror")
|
||||
GK_ATOM(onmozpointerlockchange, "onmozpointerlockchange")
|
||||
GK_ATOM(onmozpointerlockerror, "onmozpointerlockerror")
|
||||
GK_ATOM(onMozMousePixelScroll, "onMozMousePixelScroll")
|
||||
GK_ATOM(onMozScrolledAreaChanged, "onMozScrolledAreaChanged")
|
||||
GK_ATOM(ononline, "ononline")
|
||||
|
@ -275,6 +275,14 @@ EVENT(mozfullscreenerror,
|
||||
NS_FULLSCREENERROR,
|
||||
EventNameType_HTML,
|
||||
NS_EVENT_NULL)
|
||||
EVENT(mozpointerlockchange,
|
||||
NS_POINTERLOCKCHANGE,
|
||||
EventNameType_HTML,
|
||||
NS_EVENT_NULL)
|
||||
EVENT(mozpointerlockerror,
|
||||
NS_POINTERLOCKERROR,
|
||||
EventNameType_HTML,
|
||||
NS_EVENT_NULL)
|
||||
// Not supported yet; probably never because "wheel" is a better idea.
|
||||
// EVENT(mousewheel)
|
||||
EVENT(pause,
|
||||
|
@ -100,6 +100,8 @@ static const char* const sEventNames[] = {
|
||||
"MozBeforeResize",
|
||||
"mozfullscreenchange",
|
||||
"mozfullscreenerror",
|
||||
"mozpointerlockchange",
|
||||
"mozpointerlockerror",
|
||||
"MozSwipeGesture",
|
||||
"MozMagnifyGestureStart",
|
||||
"MozMagnifyGestureUpdate",
|
||||
@ -1169,6 +1171,10 @@ nsDOMEvent::GetScreenCoords(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent,
|
||||
nsIntPoint aPoint)
|
||||
{
|
||||
if (nsEventStateManager::sIsPointerLocked) {
|
||||
return nsEventStateManager::sLastScreenPoint;
|
||||
}
|
||||
|
||||
if (!aEvent ||
|
||||
(aEvent->eventStructType != NS_MOUSE_EVENT &&
|
||||
aEvent->eventStructType != NS_POPUP_EVENT &&
|
||||
@ -1224,6 +1230,10 @@ nsDOMEvent::GetClientCoords(nsPresContext* aPresContext,
|
||||
nsIntPoint aPoint,
|
||||
nsIntPoint aDefaultPoint)
|
||||
{
|
||||
if (nsEventStateManager::sIsPointerLocked) {
|
||||
return nsEventStateManager::sLastClientPoint;
|
||||
}
|
||||
|
||||
if (!aEvent ||
|
||||
(aEvent->eventStructType != NS_MOUSE_EVENT &&
|
||||
aEvent->eventStructType != NS_POPUP_EVENT &&
|
||||
|
@ -183,6 +183,8 @@ public:
|
||||
eDOMEvents_beforeresize,
|
||||
eDOMEvents_mozfullscreenchange,
|
||||
eDOMEvents_mozfullscreenerror,
|
||||
eDOMEvents_mozpointerlockchange,
|
||||
eDOMEvents_mozpointerlockerror,
|
||||
eDOMEvents_MozSwipeGesture,
|
||||
eDOMEvents_MozMagnifyGestureStart,
|
||||
eDOMEvents_MozMagnifyGestureUpdate,
|
||||
|
@ -233,6 +233,24 @@ nsDOMMouseEvent::GetRelatedTarget(nsIDOMEventTarget** aRelatedTarget)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMMouseEvent::GetMozMovementX(PRInt32* aMovementX)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aMovementX);
|
||||
*aMovementX = GetMovementPoint().x;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMMouseEvent::GetMozMovementY(PRInt32* aMovementY)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aMovementY);
|
||||
*aMovementY = GetMovementPoint().y;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD nsDOMMouseEvent::GetScreenX(PRInt32* aScreenX)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aScreenX);
|
||||
|
@ -49,7 +49,6 @@
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsEventStateManager.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsIScrollableFrame.h"
|
||||
#include "DictionaryHelpers.h"
|
||||
|
||||
@ -58,6 +57,9 @@ nsDOMUIEvent::nsDOMUIEvent(nsPresContext* aPresContext, nsGUIEvent* aEvent)
|
||||
static_cast<nsEvent *>(aEvent) :
|
||||
static_cast<nsEvent *>(new nsUIEvent(false, 0, 0)))
|
||||
, mClientPoint(0, 0), mLayerPoint(0, 0), mPagePoint(0, 0)
|
||||
, mIsPointerLocked(nsEventStateManager::sIsPointerLocked)
|
||||
, mLastScreenPoint(nsEventStateManager::sLastScreenPoint)
|
||||
, mLastClientPoint(nsEventStateManager::sLastClientPoint)
|
||||
{
|
||||
if (aEvent) {
|
||||
mEventIsInternal = false;
|
||||
@ -124,9 +126,9 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDOMUIEvent)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsDOMEvent)
|
||||
|
||||
nsIntPoint
|
||||
nsDOMUIEvent::GetScreenPoint()
|
||||
nsDOMUIEvent::GetMovementPoint()
|
||||
{
|
||||
if (!mEvent ||
|
||||
if (!mEvent ||
|
||||
(mEvent->eventStructType != NS_MOUSE_EVENT &&
|
||||
mEvent->eventStructType != NS_POPUP_EVENT &&
|
||||
mEvent->eventStructType != NS_MOUSE_SCROLL_EVENT &&
|
||||
@ -136,43 +138,41 @@ nsDOMUIEvent::GetScreenPoint()
|
||||
return nsIntPoint(0, 0);
|
||||
}
|
||||
|
||||
if (!((nsGUIEvent*)mEvent)->widget ) {
|
||||
return mEvent->refPoint;
|
||||
if (!((nsGUIEvent*)mEvent)->widget) {
|
||||
return mEvent->lastRefPoint;
|
||||
}
|
||||
|
||||
nsIntPoint offset = mEvent->refPoint +
|
||||
// Calculate the delta between the previous screen point and the current one.
|
||||
nsIntPoint currentPoint = CalculateScreenPoint(mPresContext, mEvent);
|
||||
|
||||
// Adjust previous event's refPoint so it compares to current screenX, screenY
|
||||
nsIntPoint offset = mEvent->lastRefPoint +
|
||||
((nsGUIEvent*)mEvent)->widget->WidgetToScreenOffset();
|
||||
nscoord factor = mPresContext->DeviceContext()->UnscaledAppUnitsPerDevPixel();
|
||||
return nsIntPoint(nsPresContext::AppUnitsToIntCSSPixels(offset.x * factor),
|
||||
nsPresContext::AppUnitsToIntCSSPixels(offset.y * factor));
|
||||
nsIntPoint lastPoint = nsIntPoint(nsPresContext::AppUnitsToIntCSSPixels(offset.x * factor),
|
||||
nsPresContext::AppUnitsToIntCSSPixels(offset.y * factor));
|
||||
|
||||
return currentPoint - lastPoint;
|
||||
}
|
||||
|
||||
nsIntPoint
|
||||
nsDOMUIEvent::GetScreenPoint()
|
||||
{
|
||||
if (mIsPointerLocked) {
|
||||
return mLastScreenPoint;
|
||||
}
|
||||
|
||||
return CalculateScreenPoint(mPresContext, mEvent);
|
||||
}
|
||||
|
||||
nsIntPoint
|
||||
nsDOMUIEvent::GetClientPoint()
|
||||
{
|
||||
if (!mEvent ||
|
||||
(mEvent->eventStructType != NS_MOUSE_EVENT &&
|
||||
mEvent->eventStructType != NS_POPUP_EVENT &&
|
||||
mEvent->eventStructType != NS_MOUSE_SCROLL_EVENT &&
|
||||
mEvent->eventStructType != NS_MOZTOUCH_EVENT &&
|
||||
mEvent->eventStructType != NS_DRAG_EVENT &&
|
||||
mEvent->eventStructType != NS_SIMPLE_GESTURE_EVENT) ||
|
||||
!mPresContext ||
|
||||
!((nsGUIEvent*)mEvent)->widget) {
|
||||
return mClientPoint;
|
||||
if (mIsPointerLocked) {
|
||||
return mLastClientPoint;
|
||||
}
|
||||
|
||||
nsPoint pt(0, 0);
|
||||
nsIPresShell* shell = mPresContext->GetPresShell();
|
||||
if (!shell) {
|
||||
return nsIntPoint(0, 0);
|
||||
}
|
||||
nsIFrame* rootFrame = shell->GetRootFrame();
|
||||
if (rootFrame)
|
||||
pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(mEvent, rootFrame);
|
||||
|
||||
return nsIntPoint(nsPresContext::AppUnitsToIntCSSPixels(pt.x),
|
||||
nsPresContext::AppUnitsToIntCSSPixels(pt.y));
|
||||
return CalculateClientPoint(mPresContext, mEvent, &mClientPoint);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -41,6 +41,7 @@
|
||||
|
||||
#include "nsIDOMUIEvent.h"
|
||||
#include "nsDOMEvent.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
|
||||
class nsDOMUIEvent : public nsDOMEvent,
|
||||
public nsIDOMUIEvent
|
||||
@ -66,10 +67,67 @@ public:
|
||||
|
||||
virtual nsresult InitFromCtor(const nsAString& aType,
|
||||
JSContext* aCx, jsval* aVal);
|
||||
|
||||
static nsIntPoint CalculateScreenPoint(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent)
|
||||
{
|
||||
if (!aEvent ||
|
||||
(aEvent->eventStructType != NS_MOUSE_EVENT &&
|
||||
aEvent->eventStructType != NS_POPUP_EVENT &&
|
||||
aEvent->eventStructType != NS_MOUSE_SCROLL_EVENT &&
|
||||
aEvent->eventStructType != NS_MOZTOUCH_EVENT &&
|
||||
aEvent->eventStructType != NS_DRAG_EVENT &&
|
||||
aEvent->eventStructType != NS_SIMPLE_GESTURE_EVENT)) {
|
||||
return nsIntPoint(0, 0);
|
||||
}
|
||||
|
||||
if (!((nsGUIEvent*)aEvent)->widget ) {
|
||||
return aEvent->refPoint;
|
||||
}
|
||||
|
||||
nsIntPoint offset = aEvent->refPoint +
|
||||
((nsGUIEvent*)aEvent)->widget->WidgetToScreenOffset();
|
||||
nscoord factor = aPresContext->DeviceContext()->UnscaledAppUnitsPerDevPixel();
|
||||
return nsIntPoint(nsPresContext::AppUnitsToIntCSSPixels(offset.x * factor),
|
||||
nsPresContext::AppUnitsToIntCSSPixels(offset.y * factor));
|
||||
}
|
||||
|
||||
static nsIntPoint CalculateClientPoint(nsPresContext* aPresContext,
|
||||
nsEvent* aEvent,
|
||||
nsIntPoint* aDefaultClientPoint)
|
||||
{
|
||||
if (!aEvent ||
|
||||
(aEvent->eventStructType != NS_MOUSE_EVENT &&
|
||||
aEvent->eventStructType != NS_POPUP_EVENT &&
|
||||
aEvent->eventStructType != NS_MOUSE_SCROLL_EVENT &&
|
||||
aEvent->eventStructType != NS_MOZTOUCH_EVENT &&
|
||||
aEvent->eventStructType != NS_DRAG_EVENT &&
|
||||
aEvent->eventStructType != NS_SIMPLE_GESTURE_EVENT) ||
|
||||
!aPresContext ||
|
||||
!((nsGUIEvent*)aEvent)->widget) {
|
||||
return (nsnull == aDefaultClientPoint ? nsIntPoint(0, 0) :
|
||||
nsIntPoint(aDefaultClientPoint->x, aDefaultClientPoint->y));
|
||||
}
|
||||
|
||||
nsPoint pt(0, 0);
|
||||
nsIPresShell* shell = aPresContext->GetPresShell();
|
||||
if (!shell) {
|
||||
return nsIntPoint(0, 0);
|
||||
}
|
||||
nsIFrame* rootFrame = shell->GetRootFrame();
|
||||
if (rootFrame) {
|
||||
pt = nsLayoutUtils::GetEventCoordinatesRelativeTo(aEvent, rootFrame);
|
||||
}
|
||||
|
||||
return nsIntPoint(nsPresContext::AppUnitsToIntCSSPixels(pt.x),
|
||||
nsPresContext::AppUnitsToIntCSSPixels(pt.y));
|
||||
}
|
||||
|
||||
protected:
|
||||
// Internal helper functions
|
||||
nsIntPoint GetScreenPoint();
|
||||
nsIntPoint GetClientPoint();
|
||||
nsIntPoint GetMovementPoint();
|
||||
nsIntPoint GetLayerPoint();
|
||||
nsIntPoint GetPagePoint();
|
||||
|
||||
@ -88,6 +146,10 @@ protected:
|
||||
// Screenpoint is mEvent->refPoint.
|
||||
nsIntPoint mLayerPoint;
|
||||
nsIntPoint mPagePoint;
|
||||
nsIntPoint mMovement;
|
||||
bool mIsPointerLocked;
|
||||
nsIntPoint mLastScreenPoint;
|
||||
nsIntPoint mLastClientPoint;
|
||||
};
|
||||
|
||||
#define NS_FORWARD_TO_NSDOMUIEVENT \
|
||||
|
@ -137,6 +137,8 @@
|
||||
#include "mozilla/LookAndFeel.h"
|
||||
#include "sampler.h"
|
||||
|
||||
#include "nsIDOMClientRect.h"
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
#import <ApplicationServices/ApplicationServices.h>
|
||||
#endif
|
||||
@ -159,6 +161,15 @@ bool nsEventStateManager::sNormalLMouseEventInProcess = false;
|
||||
nsEventStateManager* nsEventStateManager::sActiveESM = nsnull;
|
||||
nsIDocument* nsEventStateManager::sMouseOverDocument = nsnull;
|
||||
nsWeakFrame nsEventStateManager::sLastDragOverFrame = nsnull;
|
||||
nsIntPoint nsEventStateManager::sLastRefPoint = nsIntPoint(0,0);
|
||||
nsIntPoint nsEventStateManager::sLastScreenOffset = nsIntPoint(0,0);
|
||||
nsIntPoint nsEventStateManager::sLastScreenPoint = nsIntPoint(0,0);
|
||||
nsIntPoint nsEventStateManager::sLastClientPoint = nsIntPoint(0,0);
|
||||
bool nsEventStateManager::sIsPointerLocked = false;
|
||||
// Reference to the pointer locked element.
|
||||
nsWeakPtr nsEventStateManager::sPointerLockedElement;
|
||||
// Reference to the document which requested pointer lock.
|
||||
nsWeakPtr nsEventStateManager::sPointerLockedDoc;
|
||||
nsCOMPtr<nsIContent> nsEventStateManager::sDragOverContent = nsnull;
|
||||
|
||||
static PRUint32 gMouseOrKeyboardEventCounter = 0;
|
||||
@ -772,6 +783,7 @@ nsMouseWheelTransaction::LimitToOnePageScroll(PRInt32 aScrollLines,
|
||||
|
||||
nsEventStateManager::nsEventStateManager()
|
||||
: mLockCursor(0),
|
||||
mPreLockPoint(0,0),
|
||||
mCurrentTarget(nsnull),
|
||||
mLastMouseOverFrame(nsnull),
|
||||
// init d&d gesture state machine variables
|
||||
@ -1046,6 +1058,23 @@ nsEventStateManager::PreHandleEvent(nsPresContext* aPresContext,
|
||||
NS_ASSERTION(mCurrentTarget, "mCurrentTarget is null. this should not happen. see bug #13007");
|
||||
if (!mCurrentTarget) return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if (NS_IS_DRAG_EVENT(aEvent) && sIsPointerLocked) {
|
||||
NS_ASSERTION(sIsPointerLocked,
|
||||
"sIsPointerLocked is true. Drag events should be suppressed when the pointer is locked.");
|
||||
}
|
||||
#endif
|
||||
// Store last known screenPoint and clientPoint so pointer lock
|
||||
// can use these values as constants.
|
||||
if (NS_IS_TRUSTED_EVENT(aEvent) &&
|
||||
(NS_IS_MOUSE_EVENT_STRUCT(aEvent) &&
|
||||
IsMouseEventReal(aEvent)) ||
|
||||
aEvent->eventStructType == NS_MOUSE_SCROLL_EVENT) {
|
||||
if (!sIsPointerLocked) {
|
||||
sLastScreenPoint = nsDOMUIEvent::CalculateScreenPoint(aPresContext, aEvent);
|
||||
sLastClientPoint = nsDOMUIEvent::CalculateClientPoint(aPresContext, aEvent, nsnull);
|
||||
}
|
||||
}
|
||||
|
||||
// Do not take account NS_MOUSE_ENTER/EXIT so that loading a page
|
||||
// when user is not active doesn't change the state to active.
|
||||
@ -3779,6 +3808,25 @@ nsEventStateManager::DispatchMouseEvent(nsGUIEvent* aEvent, PRUint32 aMessage,
|
||||
nsIContent* aTargetContent,
|
||||
nsIContent* aRelatedContent)
|
||||
{
|
||||
// http://dvcs.w3.org/hg/webevents/raw-file/default/mouse-lock.html#methods
|
||||
// "[When the mouse is locked on an element...e]vents that require the concept
|
||||
// of a mouse cursor must not be dispatched (for example: mouseover, mouseout).
|
||||
if (sIsPointerLocked &&
|
||||
(aMessage == NS_MOUSELEAVE ||
|
||||
aMessage == NS_MOUSEENTER ||
|
||||
aMessage == NS_MOUSE_ENTER_SYNTH ||
|
||||
aMessage == NS_MOUSE_EXIT_SYNTH)) {
|
||||
mCurrentTargetContent = nsnull;
|
||||
nsCOMPtr<Element> pointerLockedElement =
|
||||
do_QueryReferent(nsEventStateManager::sPointerLockedElement);
|
||||
if (!pointerLockedElement) {
|
||||
NS_WARNING("Should have pointer locked element, but didn't.");
|
||||
return nsnull;
|
||||
}
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(pointerLockedElement);
|
||||
return mPresContext->GetPrimaryFrameFor(content);
|
||||
}
|
||||
|
||||
SAMPLE_LABEL("Input", "DispatchMouseEvent");
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsMouseEvent event(NS_IS_TRUSTED_EVENT(aEvent), aMessage, aEvent->widget,
|
||||
@ -3989,6 +4037,26 @@ nsEventStateManager::GenerateMouseEnterExit(nsGUIEvent* aEvent)
|
||||
switch(aEvent->message) {
|
||||
case NS_MOUSE_MOVE:
|
||||
{
|
||||
if (sIsPointerLocked && aEvent->widget) {
|
||||
// Perform mouse lock by recentering the mouse directly, then remembering the deltas.
|
||||
nsIntRect bounds;
|
||||
aEvent->widget->GetScreenBounds(bounds);
|
||||
aEvent->lastRefPoint = GetMouseCoords(bounds);
|
||||
|
||||
// refPoint should not be the centre on mousemove
|
||||
if (aEvent->refPoint.x == aEvent->lastRefPoint.x &&
|
||||
aEvent->refPoint.y == aEvent->lastRefPoint.y) {
|
||||
aEvent->refPoint = sLastRefPoint;
|
||||
} else {
|
||||
aEvent->widget->SynthesizeNativeMouseMove(aEvent->lastRefPoint);
|
||||
}
|
||||
} else {
|
||||
aEvent->lastRefPoint = nsIntPoint(sLastRefPoint.x, sLastRefPoint.y);
|
||||
}
|
||||
|
||||
// Update the last known refPoint with the current refPoint.
|
||||
sLastRefPoint = nsIntPoint(aEvent->refPoint.x, aEvent->refPoint.y);
|
||||
|
||||
// Get the target content target (mousemove target == mouseover target)
|
||||
nsCOMPtr<nsIContent> targetElement = GetEventTargetContent(aEvent);
|
||||
if (!targetElement) {
|
||||
@ -4024,6 +4092,79 @@ nsEventStateManager::GenerateMouseEnterExit(nsGUIEvent* aEvent)
|
||||
mCurrentTargetContent = targetBeforeEvent;
|
||||
}
|
||||
|
||||
void
|
||||
nsEventStateManager::SetPointerLock(nsIWidget* aWidget,
|
||||
nsIContent* aElement)
|
||||
{
|
||||
// NOTE: aElement will be nsnull when unlocking.
|
||||
sIsPointerLocked = !!aElement;
|
||||
|
||||
if (!aWidget) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Reset mouse wheel transaction
|
||||
nsMouseWheelTransaction::EndTransaction();
|
||||
|
||||
// Deal with DnD events
|
||||
nsCOMPtr<nsIDragService> dragService =
|
||||
do_GetService("@mozilla.org/widget/dragservice;1");
|
||||
|
||||
if (sIsPointerLocked) {
|
||||
// Store the last known ref point so we can reposition the pointer after unlock.
|
||||
mPreLockPoint = sLastRefPoint + sLastScreenOffset;
|
||||
|
||||
nsIntRect bounds;
|
||||
aWidget->GetScreenBounds(bounds);
|
||||
sLastRefPoint = GetMouseCoords(bounds);
|
||||
aWidget->SynthesizeNativeMouseMove(sLastRefPoint);
|
||||
|
||||
// Retarget all events to this element via capture.
|
||||
nsIPresShell::SetCapturingContent(aElement, CAPTURE_POINTERLOCK);
|
||||
|
||||
// Suppress DnD
|
||||
if (dragService) {
|
||||
dragService->Suppress();
|
||||
}
|
||||
} else {
|
||||
// Unlocking, so return pointer to the original position
|
||||
aWidget->SynthesizeNativeMouseMove(sLastScreenPoint);
|
||||
|
||||
// Don't retarget events to this element any more.
|
||||
nsIPresShell::SetCapturingContent(nsnull, CAPTURE_POINTERLOCK);
|
||||
|
||||
// Unsuppress DnD
|
||||
if (dragService) {
|
||||
dragService->Unsuppress();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsIntPoint
|
||||
nsEventStateManager::GetMouseCoords(nsIntRect aBounds)
|
||||
{
|
||||
NS_ASSERTION(sIsPointerLocked, "GetMouseCoords when not pointer locked!");
|
||||
|
||||
nsCOMPtr<nsIDocument> pointerLockedDoc =
|
||||
do_QueryReferent(nsEventStateManager::sPointerLockedDoc);
|
||||
if (!pointerLockedDoc) {
|
||||
NS_WARNING("GetMouseCoords(): No Document");
|
||||
return nsIntPoint(0, 0);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> domWin = pointerLockedDoc->GetInnerWindow();
|
||||
if (!domWin) {
|
||||
NS_WARNING("GetMouseCoords(): No Window");
|
||||
return nsIntPoint(0, 0);
|
||||
}
|
||||
|
||||
int innerHeight;
|
||||
domWin->GetInnerHeight(&innerHeight);
|
||||
|
||||
return nsIntPoint((aBounds.width / 2) + aBounds.x,
|
||||
(innerHeight / 2) + (aBounds.y + (aBounds.height - innerHeight)));
|
||||
}
|
||||
|
||||
void
|
||||
nsEventStateManager::GenerateDragDropEnterExit(nsPresContext* aPresContext,
|
||||
nsGUIEvent* aEvent)
|
||||
|
@ -228,6 +228,12 @@ public:
|
||||
|
||||
static bool IsRemoteTarget(nsIContent* aTarget);
|
||||
|
||||
static nsIntPoint sLastScreenPoint;
|
||||
static nsIntPoint sLastClientPoint;
|
||||
static bool sIsPointerLocked;
|
||||
static nsWeakPtr sPointerLockedElement;
|
||||
static nsWeakPtr sPointerLockedDoc;
|
||||
|
||||
protected:
|
||||
friend class MouseEnterLeaveDispatcher;
|
||||
|
||||
@ -480,11 +486,16 @@ private:
|
||||
|
||||
PRInt32 mLockCursor;
|
||||
|
||||
// Point when mouse was locked, used to reposition after unlocking.
|
||||
nsIntPoint mPreLockPoint;
|
||||
|
||||
nsWeakFrame mCurrentTarget;
|
||||
nsCOMPtr<nsIContent> mCurrentTargetContent;
|
||||
nsWeakFrame mLastMouseOverFrame;
|
||||
nsCOMPtr<nsIContent> mLastMouseOverElement;
|
||||
static nsWeakFrame sLastDragOverFrame;
|
||||
static nsIntPoint sLastRefPoint;
|
||||
static nsIntPoint sLastScreenOffset;
|
||||
|
||||
// member variables for the d&d gesture state machine
|
||||
nsIntPoint mGestureDownPoint; // screen coordinates
|
||||
@ -556,6 +567,9 @@ public:
|
||||
nsGUIEvent* inMouseDownEvent ) ;
|
||||
void KillClickHoldTimer ( ) ;
|
||||
void FireContextClick ( ) ;
|
||||
|
||||
void SetPointerLock(nsIWidget* aWidget, nsIContent* aElement) ;
|
||||
nsIntPoint GetMouseCoords(nsIntRect aBounds);
|
||||
static void sClickHoldCallback ( nsITimer* aTimer, void* aESM ) ;
|
||||
};
|
||||
|
||||
|
@ -66,7 +66,7 @@ interface nsIDOMLocation;
|
||||
* http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html
|
||||
*/
|
||||
|
||||
[scriptable, uuid(ac4942fe-1679-4000-aaa7-41dee590a120)]
|
||||
[scriptable, uuid(e8d73d0a-cbf6-4037-a565-32c8d64cc294)]
|
||||
interface nsIDOMDocument : nsIDOMNode
|
||||
{
|
||||
readonly attribute nsIDOMDocumentType doctype;
|
||||
@ -396,6 +396,21 @@ interface nsIDOMDocument : nsIDOMNode
|
||||
*/
|
||||
readonly attribute boolean mozFullScreenEnabled;
|
||||
|
||||
/**
|
||||
* The element to which the mouse pointer is locked, if any, as per the
|
||||
* DOM pointer lock api.
|
||||
*
|
||||
* @see <http://dvcs.w3.org/hg/pointerlock/raw-file/default/index.html>
|
||||
*/
|
||||
readonly attribute nsIDOMElement mozPointerLockElement;
|
||||
|
||||
/**
|
||||
* Exit pointer is lock if locked, as per the DOM pointer lock api.
|
||||
*
|
||||
* @see <http://dvcs.w3.org/hg/pointerlock/raw-file/default/index.html>
|
||||
*/
|
||||
void mozExitPointerLock();
|
||||
|
||||
/**
|
||||
* Inline event handler for readystatechange events.
|
||||
*/
|
||||
|
@ -49,7 +49,7 @@
|
||||
* http://dvcs.w3.org/hg/domcore/raw-file/tip/Overview.html#interface-element
|
||||
*/
|
||||
|
||||
[scriptable, uuid(295e05d9-9174-48ae-bc59-d7e6a8757726)]
|
||||
[scriptable, uuid(432a86dd-c0b8-4d21-8ac6-5ae57d28ea6b)]
|
||||
interface nsIDOMElement : nsIDOMNode
|
||||
{
|
||||
readonly attribute DOMString tagName;
|
||||
@ -228,4 +228,12 @@ interface nsIDOMElement : nsIDOMNode
|
||||
* @see <https://wiki.mozilla.org/index.php?title=Gecko:FullScreenAPI>
|
||||
*/
|
||||
void mozRequestFullScreen();
|
||||
|
||||
/**
|
||||
* Requests that this element be made the pointer-locked element, as per the DOM
|
||||
* pointer lock api.
|
||||
*
|
||||
* @see <http://dvcs.w3.org/hg/pointerlock/raw-file/default/index.html>
|
||||
*/
|
||||
void mozRequestPointerLock();
|
||||
};
|
||||
|
@ -82,6 +82,8 @@ interface nsIInlineEventHandlers : nsISupports
|
||||
// [implicit_jscontext] attribute jsval onmousewheel;
|
||||
[implicit_jscontext] attribute jsval onmozfullscreenchange;
|
||||
[implicit_jscontext] attribute jsval onmozfullscreenerror;
|
||||
[implicit_jscontext] attribute jsval onmozpointerlockchange;
|
||||
[implicit_jscontext] attribute jsval onmozpointerlockerror;
|
||||
[implicit_jscontext] attribute jsval onpause;
|
||||
[implicit_jscontext] attribute jsval onplay;
|
||||
[implicit_jscontext] attribute jsval onplaying;
|
||||
|
@ -48,12 +48,15 @@
|
||||
* http://www.w3.org/TR/DOM-Level-2-Events/
|
||||
*/
|
||||
|
||||
[scriptable, uuid(7f57aa45-6792-4d8b-ba5b-201533cf0b2f)]
|
||||
[scriptable, uuid(53E29996-F851-4032-B896-8AAFBD0BDF25)]
|
||||
interface nsIDOMMouseEvent : nsIDOMUIEvent
|
||||
{
|
||||
readonly attribute long screenX;
|
||||
readonly attribute long screenY;
|
||||
|
||||
readonly attribute long mozMovementX;
|
||||
readonly attribute long mozMovementY;
|
||||
|
||||
readonly attribute long clientX;
|
||||
readonly attribute long clientY;
|
||||
|
||||
|
@ -48,6 +48,7 @@ DIRS += \
|
||||
dom-level2-core \
|
||||
dom-level2-html \
|
||||
ajax \
|
||||
browser-frame \
|
||||
bugs \
|
||||
chrome \
|
||||
general \
|
||||
@ -55,9 +56,9 @@ DIRS += \
|
||||
geolocation \
|
||||
localstorage \
|
||||
orientation \
|
||||
pointerlock \
|
||||
sessionstorage \
|
||||
storageevent \
|
||||
browser-frame \
|
||||
$(NULL)
|
||||
|
||||
#needs IPC support, also tests do not run successfully in Firefox for now
|
||||
|
39
dom/tests/mochitest/pointerlock/Makefile.in
Normal file
39
dom/tests/mochitest/pointerlock/Makefile.in
Normal file
@ -0,0 +1,39 @@
|
||||
# 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/.
|
||||
|
||||
DEPTH = ../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
relativesrcdir = dom/tests/mochitest/pointerlock
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
_TEST_FILES = \
|
||||
test_pointerlock-api.html \
|
||||
pointerlock_utils.js \
|
||||
file_pointerlock-api.html \
|
||||
file_pointerlockerror.html \
|
||||
file_escapeKey.html \
|
||||
file_withoutDOM.html \
|
||||
file_removedFromDOM.html \
|
||||
file_pointerLockPref.html \
|
||||
file_nestedFullScreen.html \
|
||||
file_doubleLock.html \
|
||||
file_loseFocusWindow.html \
|
||||
file_childIframe.html \
|
||||
file_movementXY.html \
|
||||
file_infiniteMovement.html \
|
||||
file_retargetMouseEvents.html \
|
||||
file_targetOutOfFocus.html \
|
||||
file_screenClientXYConst.html \
|
||||
file_suppressSomeMouseEvents.html \
|
||||
file_locksvgelement.html \
|
||||
iframe_differentDOM.html \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
|
143
dom/tests/mochitest/pointerlock/file_childIframe.html
Normal file
143
dom/tests/mochitest/pointerlock/file_childIframe.html
Normal file
@ -0,0 +1,143 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=633602
|
||||
-->
|
||||
<head>
|
||||
<title>Bug 633602 - file_childIframe.html</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js">
|
||||
</script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<script type="application/javascript" src="pointerlock_utils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<style>
|
||||
#parent, #childDiv, #iframe, #table, #table td {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
border: none;
|
||||
}
|
||||
#iframe, #table {
|
||||
background-color: red;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
#childDiv, #table td {
|
||||
background-color: blue;
|
||||
width: 50%;
|
||||
height: 50%;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=633602">
|
||||
Mozilla Bug 633602
|
||||
</a>
|
||||
|
||||
<div id="parent">
|
||||
<table id="childTable">
|
||||
<tr>
|
||||
<td>
|
||||
<iframe id="iframe" src="iframe_differentDOM.html" onload="start();">
|
||||
</iframe>
|
||||
</td>
|
||||
<td>
|
||||
<div id="childDiv">
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
/*
|
||||
* Test for Bug 633602
|
||||
* Check if pointer is locked when over a child iframe of
|
||||
* the locked element
|
||||
* Check if pointer is being repositioned back to center of
|
||||
* the locked element even when pointer goes over a child ifame
|
||||
*/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var parent = document.getElementById("parent")
|
||||
, childDiv = document.getElementById("childDiv")
|
||||
, iframe = document.getElementById("iframe");
|
||||
|
||||
function MozMovementStats() {
|
||||
this.mozMovementX = false;
|
||||
this.mozMovementY = false;
|
||||
}
|
||||
|
||||
var firstMove = new MozMovementStats()
|
||||
, secondMove = new MozMovementStats()
|
||||
, hoverIframe = false;
|
||||
|
||||
function runTests () {
|
||||
ok(hoverIframe, "Pointer should be locked even when pointer " +
|
||||
"hovers over a child iframe");
|
||||
is(firstMove.mozMovementX, secondMove.mozMovementX, "MovementX of first " +
|
||||
"move to childDiv should be equal to movementX of second move " +
|
||||
"to child div");
|
||||
is(firstMove.mozMovementY, secondMove.mozMovementY, "MovementY of first " +
|
||||
"move to childDiv should be equal to movementY of second move " +
|
||||
"to child div");
|
||||
}
|
||||
|
||||
var firstMoveChild = function (e) {
|
||||
firstMove.mozMovementX = e.mozMovementX;
|
||||
firstMove.mozMovementY = e.mozMovementY;
|
||||
|
||||
parent.removeEventListener("mousemove", firstMoveChild);
|
||||
parent.addEventListener("mousemove", moveIframe);
|
||||
|
||||
synthesizeMouseAtCenter(iframe, {type: "mousemove"}, window);
|
||||
};
|
||||
|
||||
var moveIframe = function (e) {
|
||||
hoverIframe = !!document.mozPointerLockElement;
|
||||
|
||||
parent.removeEventListener("mousemove", moveIframe);
|
||||
parent.addEventListener("mousemove", secondMoveChild);
|
||||
|
||||
synthesizeMouseAtCenter(childDiv, {type: "mousemove"}, window);
|
||||
};
|
||||
|
||||
var secondMoveChild = function (e) {
|
||||
secondMove.mozMovementX = e.mozMovementX;
|
||||
secondMove.mozMovementY = e.mozMovementY;
|
||||
parent.removeEventListener("mousemove", secondMoveChild);
|
||||
|
||||
document.mozCancelFullScreen();
|
||||
};
|
||||
|
||||
document.addEventListener("mozpointerlockchange", function () {
|
||||
if (document.mozPointerLockElement === parent) {
|
||||
parent.addEventListener("mousemove", firstMoveChild);
|
||||
synthesizeMouseAtCenter(childDiv, {type: "mousemove"}, window);
|
||||
}
|
||||
}, false);
|
||||
|
||||
document.addEventListener("mozpointerlockerror", function () {
|
||||
document.mozCancelFullScreen();
|
||||
}, false);
|
||||
|
||||
document.addEventListener("mozfullscreenchange", function (e) {
|
||||
if (document.mozFullScreenElement === parent) {
|
||||
parent.mozRequestPointerLock();
|
||||
}
|
||||
else {
|
||||
runTests();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}, false);
|
||||
|
||||
function start() {
|
||||
SimpleTest.waitForFocus(function() {
|
||||
parent.mozRequestFullScreen();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
70
dom/tests/mochitest/pointerlock/file_doubleLock.html
Normal file
70
dom/tests/mochitest/pointerlock/file_doubleLock.html
Normal file
@ -0,0 +1,70 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=633602
|
||||
-->
|
||||
<head>
|
||||
<title>Bug 633602 - file_doubleLockCallBack.html</title>
|
||||
<script type="text/javascript"
|
||||
src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="text/javascript"
|
||||
src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<script type="application/javascript" src="pointerlock_utils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<style type="text/css">
|
||||
#test-element { background-color: #94E01B; width:100px; height:100px; }
|
||||
</style>
|
||||
</head>
|
||||
<body onload="start();">
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=633602">
|
||||
Mozilla Bug 633602</a>
|
||||
<div id="div"></div>
|
||||
<pre id="test">
|
||||
<script type="text/javascript">
|
||||
/*
|
||||
* Test for Bug 633602
|
||||
* If element requests pointerlock on itself while in pointerlock state
|
||||
* mozpointerlockchange event should be dispatched
|
||||
*/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var div = document.getElementById("div")
|
||||
, numberOfLocks = 0;
|
||||
|
||||
function runTests () {
|
||||
is(numberOfLocks, 2, "Requesting pointer lock on a locked element " +
|
||||
"should dispatch mozpointerlockchange event");
|
||||
}
|
||||
|
||||
document.addEventListener("mozpointerlockchange", function (e) {
|
||||
if (document.mozPointerLockElement === div) {
|
||||
if (numberOfLocks === 2) {
|
||||
document.mozCancelFullScreen();
|
||||
}
|
||||
else {
|
||||
numberOfLocks++;
|
||||
div.mozRequestPointerLock();
|
||||
}
|
||||
}
|
||||
}, false);
|
||||
|
||||
document.addEventListener("mozfullscreenchange", function (e) {
|
||||
if (document.mozFullScreenElement === div) {
|
||||
div.mozRequestPointerLock();
|
||||
}
|
||||
else {
|
||||
runTests();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}, false);
|
||||
|
||||
function start() {
|
||||
SimpleTest.waitForFocus(function() {
|
||||
div.mozRequestFullScreen();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
63
dom/tests/mochitest/pointerlock/file_escapeKey.html
Normal file
63
dom/tests/mochitest/pointerlock/file_escapeKey.html
Normal file
@ -0,0 +1,63 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--https://bugzilla.mozilla.org/show_bug.cgi?id=633602-->
|
||||
<head>
|
||||
<title>Bug 633602</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js">
|
||||
</script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js">
|
||||
</script>
|
||||
<script type="application/javascript" src="pointerlock_utils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body onload="start();">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=633602">
|
||||
Mozilla Bug 633602
|
||||
</a>
|
||||
<div id="div"></div>
|
||||
<pre id="test">
|
||||
<script type="text/javascript">
|
||||
/*
|
||||
* Test for Bug 633602
|
||||
* Escape key should unlock the pointer
|
||||
*/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var div = document.getElementById("div")
|
||||
, pointerUnLocked = false;
|
||||
|
||||
function runTests () {
|
||||
ok(pointerUnLocked, "Pressing Escape key should unlock the pointer");
|
||||
}
|
||||
|
||||
document.addEventListener("mozpointerlockchange", function (e) {
|
||||
if (document.mozPointerLockElement === div) {
|
||||
synthesizeKey("VK_ESCAPE", {});
|
||||
}
|
||||
else {
|
||||
pointerUnLocked = true;
|
||||
document.mozCancelFullScreen();
|
||||
}
|
||||
}, false);
|
||||
|
||||
document.addEventListener("mozfullscreenchange", function(e) {
|
||||
if (document.mozFullScreenElement === div) {
|
||||
div.mozRequestPointerLock();
|
||||
}
|
||||
else {
|
||||
runTests();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}, false);
|
||||
|
||||
function start() {
|
||||
SimpleTest.waitForFocus(function() {
|
||||
div.mozRequestFullScreen();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
100
dom/tests/mochitest/pointerlock/file_infiniteMovement.html
Normal file
100
dom/tests/mochitest/pointerlock/file_infiniteMovement.html
Normal file
@ -0,0 +1,100 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=633602
|
||||
-->
|
||||
<head>
|
||||
<title>Bug 633602 - file_movementXY.html</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js">
|
||||
</script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js">
|
||||
</script>
|
||||
<script type="application/javascript" src="pointerlock_utils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body onload="start();">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=633602">
|
||||
Mozilla Bug 633602
|
||||
</a>
|
||||
<div id="div"></div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
/*
|
||||
* Test for Bug 633602
|
||||
* This test checks if mozMovementX and mozMovementY
|
||||
* are present in a mouse event object.
|
||||
* It also checks the values for mozMovementXY.
|
||||
* They should be equal to the current screenXY minus
|
||||
* the last screenXY
|
||||
* This test will also test that the incremental movement is
|
||||
* not constrained to the width of the screen.
|
||||
*/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var div = document.getElementById("div")
|
||||
, divCenterWidth = 0
|
||||
, divCenterHeight = 0
|
||||
, totalMovementX = 0
|
||||
, totalMovementY = 0;
|
||||
|
||||
function runTests () {
|
||||
ok(totalMovementX > div.getBoundingClientRect().width,
|
||||
"Should have moved more than one screen's worth in width." +
|
||||
"TotalX: " + totalMovementX + " Screensize X: " + div.getBoundingClientRect().width);
|
||||
ok(totalMovementY > div.getBoundingClientRect().height,
|
||||
"Should have moved more than one screen's worth in height." +
|
||||
"TotalY: " + totalMovementY + " Screensize Y: " + div.getBoundingClientRect().height);
|
||||
}
|
||||
|
||||
var firstMoveListener = function (e) {
|
||||
div.removeEventListener("mousemove", firstMoveListener, false);
|
||||
div.addEventListener("mousemove", secondMoveListener, false);
|
||||
|
||||
synthesizeMouse(div,(divCenterWidth/2) * 3,
|
||||
(divCenterHeight/2) * 3, {
|
||||
type: "mousemove"
|
||||
}, window);
|
||||
}
|
||||
|
||||
var secondMoveListener = function (e) {
|
||||
totalMovementX = divCenterWidth + ((divCenterWidth / 2) * 3);
|
||||
totalMovementY = divCenterHeight + ((divCenterHeight / 2) * 3);
|
||||
|
||||
div.removeEventListener("mousemove", secondMoveListener, false);
|
||||
document.mozCancelFullScreen();
|
||||
}
|
||||
|
||||
document.addEventListener("mozpointerlockchange", function (e) {
|
||||
if (document.mozPointerLockElement === div) {
|
||||
div.addEventListener("mousemove", firstMoveListener, false);
|
||||
|
||||
divCenterWidth = Math.round(div.getBoundingClientRect().width / 2);
|
||||
divCenterHeight = Math.round(div.getBoundingClientRect().height / 2);
|
||||
|
||||
synthesizeMouse(div, divCenterWidth, divCenterHeight, {
|
||||
type: "mousemove"
|
||||
}, window);
|
||||
}
|
||||
}, false);
|
||||
|
||||
document.addEventListener("mozfullscreenchange", function() {
|
||||
if (document.mozFullScreenElement === div) {
|
||||
div.mozRequestPointerLock();
|
||||
}
|
||||
else {
|
||||
runTests();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}, false);
|
||||
|
||||
function start() {
|
||||
SimpleTest.waitForFocus(function() {
|
||||
div.mozRequestFullScreen();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
67
dom/tests/mochitest/pointerlock/file_locksvgelement.html
Normal file
67
dom/tests/mochitest/pointerlock/file_locksvgelement.html
Normal file
@ -0,0 +1,67 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=633602
|
||||
-->
|
||||
<head>
|
||||
<title>Bug 633602</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js">
|
||||
</script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js">
|
||||
</script>
|
||||
<script type="application/javascript" src="pointerlock_utils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body onload="start();">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=633602">
|
||||
Mozilla Bug 633602</a>
|
||||
<p id="display"></p>
|
||||
|
||||
<svg width="100" height="100" viewbox="0 0 100 100">
|
||||
<rect id="svg-elem" x="10" y="10" width="50" height="50"
|
||||
fill="black" stroke="blue" stroke-width="2"/>
|
||||
</svg>
|
||||
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
/*
|
||||
* Test for Bug 633602
|
||||
* Test locking non-html element.
|
||||
*/
|
||||
|
||||
SimpleTest.waitForExplicitFinish(1);
|
||||
|
||||
var elem,
|
||||
elemWasLocked = false;
|
||||
|
||||
document.addEventListener("mozpointerlockchange", function (e) {
|
||||
if (document.mozFullScreen &&
|
||||
document.mozPointerLockElement === elem) {
|
||||
elemWasLocked = true;
|
||||
document.mozExitPointerLock();
|
||||
} else {
|
||||
document.mozCancelFullScreen();
|
||||
}
|
||||
}, false);
|
||||
|
||||
document.addEventListener("mozfullscreenchange", function (e) {
|
||||
if (document.mozFullScreenElement === elem) {
|
||||
elem.mozRequestPointerLock();
|
||||
} else {
|
||||
ok(elemWasLocked, "Expected SVG elem to become locked.");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}, false);
|
||||
|
||||
function start() {
|
||||
elem = document.getElementById("svg-elem");
|
||||
|
||||
SimpleTest.waitForFocus(function() {
|
||||
elem.mozRequestFullScreen();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
71
dom/tests/mochitest/pointerlock/file_loseFocusWindow.html
Normal file
71
dom/tests/mochitest/pointerlock/file_loseFocusWindow.html
Normal file
@ -0,0 +1,71 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=633602
|
||||
-->
|
||||
<head>
|
||||
<title>Bug 633602 - file_exitMouseLockOnLoseFocus.html</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js">
|
||||
</script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js">
|
||||
</script>
|
||||
<script type="application/javascript" src="pointerlock_utils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body onload="start();">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=633602">
|
||||
Mozilla Bug 633602
|
||||
</a>
|
||||
<div id="div"></div>
|
||||
<pre id="test">
|
||||
<script type="text/javascript">
|
||||
/*
|
||||
* Test for Bug 633602
|
||||
* If element has the pointer locked and window loses focus
|
||||
* pointer should be unlocked
|
||||
*/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var div = document.getElementById("div")
|
||||
, newWindow = null
|
||||
, looseFocusUnlock = false
|
||||
, pointerLockLost = false;
|
||||
|
||||
function runTests () {
|
||||
ok(looseFocusUnlock, "Pointer should be unlocked if window " +
|
||||
"loses focus");
|
||||
}
|
||||
|
||||
document.addEventListener("mozpointerlockchange", function (e) {
|
||||
if (document.mozPointerLockElement === div) {
|
||||
divPointerLocked = true;
|
||||
newWindow = window.open(); // Open new window to blur current one
|
||||
}
|
||||
else {
|
||||
looseFocusUnlock = true;
|
||||
newWindow && newWindow.close();
|
||||
document.mozCancelFullScreen();
|
||||
}
|
||||
}, false);
|
||||
|
||||
document.addEventListener("mozfullscreenchange", function() {
|
||||
if (document.mozFullScreenElement === div) {
|
||||
div.mozRequestPointerLock();
|
||||
}
|
||||
else {
|
||||
runTests();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}, false);
|
||||
|
||||
function start() {
|
||||
SimpleTest.waitForFocus(function() {
|
||||
div.mozRequestFullScreen();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
105
dom/tests/mochitest/pointerlock/file_movementXY.html
Normal file
105
dom/tests/mochitest/pointerlock/file_movementXY.html
Normal file
@ -0,0 +1,105 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=633602
|
||||
-->
|
||||
<head>
|
||||
<title>Bug 633602 - file_movementXY.html</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js">
|
||||
</script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js">
|
||||
</script>
|
||||
<script type="application/javascript" src="pointerlock_utils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body onload="start();">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=633602">
|
||||
Mozilla Bug 633602
|
||||
</a>
|
||||
<div id="div"></div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
/*
|
||||
* Test for Bug 633602
|
||||
* Checks if mozMovementX and mozMovementY are present
|
||||
* in the mouse event object.
|
||||
* It also checks the values for mozMovementXY.
|
||||
* They should be equal to the current screenXY minus
|
||||
* the last screenXY
|
||||
*/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function MouseMovementStats() {
|
||||
this.screenX = false;
|
||||
this.screenY = false;
|
||||
this.mozMovementX = false;
|
||||
this.mozMovementY = false;
|
||||
}
|
||||
|
||||
var div = document.getElementById("div")
|
||||
, divCenterWidth = 0
|
||||
, divCenterHeight = 0
|
||||
, mozMovementX = false
|
||||
, mozMovementY = false
|
||||
, firstMove = new MouseMovementStats()
|
||||
, secondMove = new MouseMovementStats();
|
||||
|
||||
function runTests () {
|
||||
ok(mozMovementX && mozMovementY, "mozMovementX and " +
|
||||
"mozMovementY should exist in mouse events objects.");
|
||||
is(secondMove.mozMovementX, secondMove.screenX - firstMove.screenX,
|
||||
"mozMovementX should be equal to eNow.screenX-ePrevious.screenX");
|
||||
is(secondMove.mozMovementY, secondMove.screenY - firstMove.screenY,
|
||||
"mozMovementY should be equal to eNow.screenY-ePrevious.screenY");
|
||||
}
|
||||
|
||||
var moveMouse = function(e) {
|
||||
mozMovementX = ("mozMovementX" in e);
|
||||
mozMovementY = ("mozMovementY" in e);
|
||||
|
||||
div.removeEventListener("mousemove", moveMouse, false);
|
||||
div.addEventListener("mousemove", moveMouseAgain, false);
|
||||
|
||||
firstMove.screenX = e.screenX;
|
||||
firstMove.screenY = e.screenY;
|
||||
|
||||
divCenterWidth = Math.round(div.getBoundingClientRect().width / 2);
|
||||
divCenterHeight = Math.round(div.getBoundingClientRect().height / 2);
|
||||
|
||||
synthesizeMouse(div, (divCenterWidth + 10), (divCenterHeight + 10), {
|
||||
type: "mousemove"
|
||||
}, window);
|
||||
};
|
||||
|
||||
var moveMouseAgain = function(e) {
|
||||
secondMove.screenX = e.screenX;
|
||||
secondMove.screenY = e.screenY;
|
||||
secondMove.mozMovementX = e.mozMovementX;
|
||||
secondMove.mozMovementY = e.mozMovementY;
|
||||
|
||||
div.removeEventListener("mousemove", moveMouseAgain, false);
|
||||
document.mozCancelFullScreen();
|
||||
};
|
||||
|
||||
document.addEventListener("mozfullscreenchange", function() {
|
||||
if (document.mozFullScreenElement === div) {
|
||||
div.addEventListener("mousemove", moveMouse, false);
|
||||
synthesizeMouseAtCenter(div, {type: "mousemove"}, window);
|
||||
}
|
||||
else {
|
||||
runTests();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}, false);
|
||||
|
||||
function start() {
|
||||
SimpleTest.waitForFocus(function() {
|
||||
div.mozRequestFullScreen();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
81
dom/tests/mochitest/pointerlock/file_nestedFullScreen.html
Normal file
81
dom/tests/mochitest/pointerlock/file_nestedFullScreen.html
Normal file
@ -0,0 +1,81 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=633602
|
||||
-->
|
||||
<head>
|
||||
<title>Bug 633602 - file_nestedFullScreen.html</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js">
|
||||
</script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js">
|
||||
</script>
|
||||
<script type="application/javascript" src="pointerlock_utils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body onload="start();">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=633602">
|
||||
Mozilla Bug 633602
|
||||
</a>
|
||||
|
||||
<div id="parentDiv">
|
||||
<div id="childDiv"></div>
|
||||
</div>
|
||||
|
||||
<script type="application/javascript">
|
||||
/*
|
||||
* Test for Bug 633602
|
||||
* Requesting fullscreen on a child element of the element with
|
||||
* the pointer locked should unlock the pointer
|
||||
*/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var parentDiv = document.getElementById("parentDiv")
|
||||
, childDiv = document.getElementById("childDiv")
|
||||
, parentDivLocked = false
|
||||
, parentDivFullScreen = false
|
||||
, pointerLocked = false;
|
||||
|
||||
function runTests () {
|
||||
ok(parentDivLocked, "After requesting pointerlock on parentDiv " +
|
||||
"document.mozPointerLockElement should be equal to " +
|
||||
" parentDiv element");
|
||||
isnot(pointerLocked, true, "Requesting fullscreen on " +
|
||||
"childDiv while parentDiv still in fullscreen should " +
|
||||
"unlock the pointer");
|
||||
}
|
||||
|
||||
document.addEventListener("mozpointerlockchange", function (e) {
|
||||
if (document.mozPointerLockElement === parentDiv) {
|
||||
parentDivLocked = true;
|
||||
childDiv.mozRequestFullScreen();
|
||||
}
|
||||
}, false);
|
||||
|
||||
document.addEventListener("mozfullscreenchange", function() {
|
||||
if (document.mozFullScreenElement === parentDiv) {
|
||||
if (parentDivFullScreen === true) {
|
||||
document.mozCancelFullScreen();
|
||||
}
|
||||
parentDivFullScreen = true;
|
||||
parentDiv.mozRequestPointerLock();
|
||||
}
|
||||
else if (document.mozFullScreenElement === childDiv) {
|
||||
pointerLocked = !!document.mozPointerLockElement;
|
||||
document.mozCancelFullScreen();
|
||||
}
|
||||
else {
|
||||
runTests();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}, false);
|
||||
|
||||
function start() {
|
||||
SimpleTest.waitForFocus(function() {
|
||||
parentDiv.mozRequestFullScreen();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
80
dom/tests/mochitest/pointerlock/file_pointerLockPref.html
Normal file
80
dom/tests/mochitest/pointerlock/file_pointerLockPref.html
Normal file
@ -0,0 +1,80 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=633602
|
||||
-->
|
||||
<head>
|
||||
<title>Bug 633602</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js">
|
||||
</script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js">
|
||||
</script>
|
||||
<script type="application/javascript" src="pointerlock_utils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body onload="start();">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=633602">
|
||||
Mozilla Bug 633602</a>
|
||||
<p id="display"></p>
|
||||
<div id="div"></div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
/*
|
||||
* Test for Bug 633602
|
||||
* Tests full-screen-api.pointer-lock pref
|
||||
*/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var div = document.getElementById("div")
|
||||
, prefEnabled = false
|
||||
, prefDisabled = false;
|
||||
|
||||
function runTests () {
|
||||
ok(prefEnabled, "Element should be able to lock the pointer " +
|
||||
"if pointer-lock pref is set to TRUE");
|
||||
ok(prefDisabled, "Element should NOT be able to lock the pointer " +
|
||||
"if pointer-lock pref is set to FALSE");
|
||||
}
|
||||
|
||||
document.addEventListener("mozpointerlockchange", function (e) {
|
||||
if (document.mozPointerLockElement === div) {
|
||||
prefEnabled = true;
|
||||
document.mozExitPointerLock();
|
||||
}
|
||||
else {
|
||||
SpecialPowers.setBoolPref("full-screen-api.pointer-lock.enabled",
|
||||
false );
|
||||
div.mozRequestPointerLock();
|
||||
}
|
||||
}, false);
|
||||
|
||||
document.addEventListener("mozpointerlockerror", function (e) {
|
||||
prefDisabled = true;
|
||||
document.mozCancelFullScreen();
|
||||
}, false);
|
||||
|
||||
document.addEventListener("mozfullscreenchange", function (e) {
|
||||
if (document.mozFullScreenElement === div) {
|
||||
SpecialPowers.setBoolPref("full-screen-api.pointer-lock.enabled",
|
||||
true );
|
||||
div.mozRequestPointerLock();
|
||||
}
|
||||
else {
|
||||
SpecialPowers.setBoolPref("full-screen-api.pointer-lock.enabled",
|
||||
true );
|
||||
runTests();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}, false);
|
||||
|
||||
function start() {
|
||||
SimpleTest.waitForFocus(function() {
|
||||
div.mozRequestFullScreen();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
92
dom/tests/mochitest/pointerlock/file_pointerlock-api.html
Normal file
92
dom/tests/mochitest/pointerlock/file_pointerlock-api.html
Normal file
@ -0,0 +1,92 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--https://bugzilla.mozilla.org/show_bug.cgi?id=633602-->
|
||||
<head>
|
||||
<title>Bug 633602</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js">
|
||||
</script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js">
|
||||
</script>
|
||||
<script type="application/javascript" src="pointerlock_utils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body onload="start();">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=633602">
|
||||
Mozilla Bug 633602
|
||||
</a>
|
||||
<div id="div"></div>
|
||||
<pre id="test">
|
||||
<script type="text/javascript">
|
||||
/*
|
||||
* Test for Bug 633602
|
||||
* Make sure DOM API is correct.
|
||||
*/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var div,
|
||||
hasRequestPointerLock = false,
|
||||
pointerLockChangeEventFired = false,
|
||||
pointerUnlocked = false,
|
||||
pointerLocked = false,
|
||||
hasExitPointerLock = false,
|
||||
pointerLockElement = false,
|
||||
hasMovementX = false,
|
||||
hasMovementY = false;
|
||||
|
||||
function runTests () {
|
||||
ok(hasRequestPointerLock, "Element should have mozRequestPointerLock.");
|
||||
ok(pointerLockChangeEventFired, "pointerlockchange event should fire.");
|
||||
ok(pointerUnlocked, "Should be able to unlock pointer locked element.");
|
||||
ok(pointerLocked, "Requested element should be able to lock.");
|
||||
ok(hasExitPointerLock, "Document should have mozExitPointerLock");
|
||||
ok(pointerLockElement, "Document should keep track of correct pointer locked element");
|
||||
ok(hasMovementX, "Mouse Event should have mozMovementX.");
|
||||
ok(hasMovementY, "Mouse Event should have mozMovementY.");
|
||||
}
|
||||
|
||||
function mouseMoveHandler(e) {
|
||||
document.removeEventListener("mousemove", mouseMoveHandler, false);
|
||||
|
||||
hasMovementX = "mozMovementX" in e;
|
||||
hasMovementY = "mozMovementY" in e;
|
||||
|
||||
hasExitPointerLock = "mozExitPointerLock" in document;
|
||||
document.mozExitPointerLock();
|
||||
}
|
||||
|
||||
document.addEventListener("mozpointerlockchange", function (e) {
|
||||
pointerLockChangeEventFired = true;
|
||||
|
||||
if (document.mozPointerLockElement) {
|
||||
pointerLocked = true;
|
||||
pointerLockElement = document.mozPointerLockElement === div;
|
||||
document.addEventListener("mousemove", mouseMoveHandler, false);
|
||||
synthesizeMouseAtCenter(div, {type: "mousemove"}, window);
|
||||
} else {
|
||||
pointerUnlocked = true;
|
||||
document.mozCancelFullScreen();
|
||||
}
|
||||
}, false);
|
||||
|
||||
document.addEventListener("mozfullscreenchange", function(e) {
|
||||
if (document.mozFullScreenElement === div) {
|
||||
hasRequestPointerLock = "mozRequestPointerLock" in div;
|
||||
div.mozRequestPointerLock();
|
||||
} else {
|
||||
runTests();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}, false);
|
||||
|
||||
function start() {
|
||||
SimpleTest.waitForFocus(function() {
|
||||
div = document.getElementById("div");
|
||||
div.mozRequestFullScreen();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
43
dom/tests/mochitest/pointerlock/file_pointerlockerror.html
Normal file
43
dom/tests/mochitest/pointerlock/file_pointerlockerror.html
Normal file
@ -0,0 +1,43 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--https://bugzilla.mozilla.org/show_bug.cgi?id=633602-->
|
||||
<head>
|
||||
<title>Bug 633602</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js">
|
||||
</script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js">
|
||||
</script>
|
||||
<script type="application/javascript" src="pointerlock_utils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body onload="start();">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=633602">
|
||||
Mozilla Bug 633602
|
||||
</a>
|
||||
|
||||
<pre id="test">
|
||||
<script type="text/javascript">
|
||||
/*
|
||||
* Test for Bug 633602
|
||||
* Make sure pointerlockerror event fires.
|
||||
*/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
document.addEventListener("mozpointerlockerror", function (e) {
|
||||
ok(true, "pointerlockerror event should fire.");
|
||||
SimpleTest.finish();
|
||||
}, false);
|
||||
|
||||
function start() {
|
||||
SimpleTest.waitForFocus(function() {
|
||||
// element not in the DOM, not fullscreen, should fail to lock
|
||||
div = document.createElement("div");
|
||||
div.mozRequestPointerLock();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
70
dom/tests/mochitest/pointerlock/file_removedFromDOM.html
Normal file
70
dom/tests/mochitest/pointerlock/file_removedFromDOM.html
Normal file
@ -0,0 +1,70 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=633602
|
||||
|
||||
Test DOM tree in full screen
|
||||
-->
|
||||
<head>
|
||||
<title>Bug 633602 - file_DOMtree.html</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js">
|
||||
</script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js">
|
||||
</script>
|
||||
<script type="application/javascript" src="pointerlock_utils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<style>
|
||||
</style>
|
||||
</head>
|
||||
<body onload="start();">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=633602">
|
||||
Mozilla Bug 633602
|
||||
</a>
|
||||
<div id="div"></div>
|
||||
<pre id="test">
|
||||
<script type="text/javascript">
|
||||
/*
|
||||
* Test for Bug 633602
|
||||
* Checks if pointer is unlocked when element is removed from
|
||||
* the DOM Tree
|
||||
*/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var div = document.getElementById("div")
|
||||
, removedDOM = false;
|
||||
|
||||
function runTests() {
|
||||
ok(removedDOM, "Pointer should be unlocked when " +
|
||||
"an element is removed the DOM Tree");
|
||||
}
|
||||
|
||||
document.addEventListener("mozpointerlockchange", function (e) {
|
||||
if (document.mozPointerLockElement === div) {
|
||||
document.body.removeChild(div);
|
||||
removedDOM = !document.mozPointerLockElement;
|
||||
document.mozCancelFullScreen();
|
||||
}
|
||||
|
||||
}, false);
|
||||
|
||||
document.addEventListener("mozfullscreenchange", function (e) {
|
||||
if (document.mozFullScreenElement === div) {
|
||||
div.mozRequestPointerLock();
|
||||
}
|
||||
else {
|
||||
runTests();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}, false);
|
||||
|
||||
function start() {
|
||||
SimpleTest.waitForFocus(function() {
|
||||
div.mozRequestFullScreen();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
164
dom/tests/mochitest/pointerlock/file_retargetMouseEvents.html
Normal file
164
dom/tests/mochitest/pointerlock/file_retargetMouseEvents.html
Normal file
@ -0,0 +1,164 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=633602
|
||||
-->
|
||||
<head>
|
||||
<title>Bug 633602 - file_retargetMouseEvents.html</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js">
|
||||
</script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<script type="application/javascript" src="pointerlock_utils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body onload="start();">
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=633602">
|
||||
Mozilla Bug 633602
|
||||
</a>
|
||||
|
||||
<div id="parent">
|
||||
<div id="child" style="width: 100%; height: 100%;">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
/*
|
||||
* Test for Bug 633602
|
||||
* Retarget mouse events to the locked element
|
||||
*/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function MouseEventStats() {
|
||||
this.mouseMove = false;
|
||||
this.mouseDown = false;
|
||||
this.mouseUp = false;
|
||||
this.mouseClick = false;
|
||||
this.mouseScroll = false;
|
||||
}
|
||||
|
||||
var parent = document.getElementById("parent")
|
||||
, child = document.getElementById("child")
|
||||
, parentStats = new MouseEventStats()
|
||||
, childStats = new MouseEventStats();
|
||||
|
||||
function runTests () {
|
||||
is(childStats.mouseMove, false, "Child shound not receive mousemove event.");
|
||||
is(childStats.mouseDown, false, "Child should not receive mousedown event.");
|
||||
is(childStats.mouseUp, false, "Child should not receive mouseup event.");
|
||||
is(childStats.mouseClick, false, "Child should not receive click event.");
|
||||
is(childStats.mouseScroll, false, "Child should not receive DOMMouseScroll event.");
|
||||
|
||||
ok(parentStats.mouseMove, "Parent should receive mousemove event.");
|
||||
ok(parentStats.mouseDown, "Parent should receive mousedown event.");
|
||||
ok(parentStats.mouseUp, "Parent should receive mouseup event.");
|
||||
ok(parentStats.mouseClick, "Parent should receive click event.");
|
||||
ok(parentStats.mouseScroll, "Parent should receive DOMMouseScroll event.");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* The event listeners for the child element shouldn't be fired
|
||||
* Mouse events will only happen when the pointer is locked
|
||||
* and if the pointer is locked all the mouse events should be
|
||||
* retargetted to the locked element
|
||||
**/
|
||||
var childMoveTest = function() {
|
||||
childStats.mouseMove = true;
|
||||
}
|
||||
|
||||
var childDownTest = function() {
|
||||
childStats.mouseDown = true;
|
||||
};
|
||||
|
||||
var childUpTest = function() {
|
||||
childStats.mouseUp = true;
|
||||
};
|
||||
|
||||
var childClickTest = function() {
|
||||
childStats.mouseClick = true;
|
||||
};
|
||||
|
||||
var childScrollTest = function() {
|
||||
childStats.mouseScroll = true;
|
||||
};
|
||||
|
||||
// Event listeners for the parent element
|
||||
var startMouseTests = function() {
|
||||
parent.removeEventListener("mousemove", startMouseTests);
|
||||
parent.addEventListener("DOMMouseScroll", parentScrollTest);
|
||||
child.addEventListener("DOMMouseScroll", childScrollTest);
|
||||
synthesizeMouseScroll(child, 5, 5, {'delta': 10, 'type': "DOMMouseScroll"});
|
||||
};
|
||||
|
||||
var parentScrollTest = function (e) {
|
||||
parentStats.mouseScroll = true;
|
||||
parent.removeEventListener("DOMMouseScroll", parentScrollTest);
|
||||
child.removeEventListener("DOMMouseScroll", childScrollTest);
|
||||
parent.addEventListener("mousedown", parentDownTest);
|
||||
child.addEventListener("mousedown", childDownTest);
|
||||
synthesizeMouseAtCenter(child, {type: "mousedown"}, window);
|
||||
};
|
||||
|
||||
var parentDownTest = function (e) {
|
||||
parentStats.mouseDown = true;
|
||||
parent.removeEventListener("mousedown", parentDownTest);
|
||||
child.removeEventListener("mousedown", childDownTest);
|
||||
parent.addEventListener("mouseup", parentUpTest);
|
||||
child.addEventListener("mouseup", childUpTest);
|
||||
synthesizeMouseAtCenter(child, {type: "mouseup"}, window);
|
||||
};
|
||||
|
||||
var parentUpTest = function (e) {
|
||||
parentStats.mouseUp = true;
|
||||
parent.removeEventListener("mouseup", parentUpTest);
|
||||
child.removeEventListener("mouseup", childUpTest);
|
||||
parent.addEventListener("click", parentClickTest);
|
||||
child.addEventListener("click", childClickTest);
|
||||
synthesizeMouseAtCenter(child, {type: "click"}, window);
|
||||
};
|
||||
|
||||
var parentClickTest = function (e) {
|
||||
parentStats.mouseClick = true;
|
||||
parent.removeEventListener("click", parentClickTest);
|
||||
child.removeEventListener("click", childClickTest);
|
||||
parent.addEventListener("mousemove", parentMoveTest);
|
||||
child.addEventListener("mousemove", childMoveTest);
|
||||
synthesizeMouseAtCenter(child, {type: "mousemove"}, window);
|
||||
};
|
||||
|
||||
var parentMoveTest = function (e) {
|
||||
parentStats.mouseMove = true;
|
||||
parent.removeEventListener("mousemove", parentMoveTest);
|
||||
child.removeEventListener("mousemove", childMoveTest);
|
||||
document.mozCancelFullScreen();
|
||||
}
|
||||
|
||||
document.addEventListener("mozpointerlockchange", function (e) {
|
||||
if (document.mozPointerLockElement === parent) {
|
||||
parent.addEventListener("mousemove", startMouseTests);
|
||||
child.addEventListener("mousemove", childMoveTest);
|
||||
synthesizeMouseAtCenter(parent, {type: "mousemove"}, window);
|
||||
}
|
||||
}, false);
|
||||
|
||||
document.addEventListener("mozfullscreenchange", function (e) {
|
||||
if (document.mozFullScreenElement === parent) {
|
||||
parent.mozRequestPointerLock();
|
||||
}
|
||||
else {
|
||||
runTests();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}, false);
|
||||
|
||||
function start() {
|
||||
SimpleTest.waitForFocus(function() {
|
||||
parent.mozRequestFullScreen();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
106
dom/tests/mochitest/pointerlock/file_screenClientXYConst.html
Normal file
106
dom/tests/mochitest/pointerlock/file_screenClientXYConst.html
Normal file
@ -0,0 +1,106 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=633602
|
||||
-->
|
||||
<head>
|
||||
<title>Bug 633602 - constantXY.html</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js">
|
||||
</script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<script type="application/javascript" src="pointerlock_utils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body onload="start();">
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=633602">
|
||||
Mozilla Bug 633602
|
||||
</a>
|
||||
<div id="div"></div>
|
||||
<script type="application/javascript">
|
||||
/*
|
||||
* Test for Bug 633602
|
||||
* Confirm that screenX/Y and clientX/Y are constants when the pointer
|
||||
* is locked.
|
||||
*/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var div
|
||||
, divRect
|
||||
, unLockedCoords
|
||||
, lockedCoords
|
||||
, isUnlocked = false
|
||||
, isLocked = false;
|
||||
|
||||
function runTests () {
|
||||
ok(isUnlocked, "Pointer should be unlocked");
|
||||
ok(isLocked, "Pointer should be locked");
|
||||
|
||||
// Confirm that pointer coords are constant while locked
|
||||
is(unLockedCoords.clientX, lockedCoords.clientX,
|
||||
"clientX should be equal to where the mouse was originaly locked");
|
||||
is(unLockedCoords.clientY, lockedCoords.clientY,
|
||||
"clientY should be equal to where the mouse was originaly locked");
|
||||
is(unLockedCoords.screenX, lockedCoords.screenX,
|
||||
"screenX should be equal to where the mouse was originaly locked");
|
||||
is(unLockedCoords.screenY, lockedCoords.screenY,
|
||||
"screenY should be equal to where the mouse was originaly locked");
|
||||
}
|
||||
|
||||
function moveUnlocked(e) {
|
||||
div.removeEventListener("mousemove", moveUnlocked, false);
|
||||
|
||||
isUnlocked = !document.mozPointerLockElement;
|
||||
unLockedCoords = {
|
||||
screenX: e.screenX,
|
||||
screenY: e.screenY,
|
||||
clientX: e.clientX,
|
||||
clientY: e.clientY
|
||||
};
|
||||
|
||||
div.mozRequestPointerLock();
|
||||
}
|
||||
|
||||
function moveLocked(e) {
|
||||
div.removeEventListener("mousemove", moveLocked, false);
|
||||
|
||||
isLocked = !!document.mozPointerLockElement;
|
||||
lockedCoords = {
|
||||
screenX: e.screenX,
|
||||
screenY: e.screenY,
|
||||
clientX: e.clientX,
|
||||
clientY: e.clientY
|
||||
};
|
||||
|
||||
document.mozCancelFullScreen();
|
||||
}
|
||||
|
||||
document.addEventListener("mozpointerlockchange", function (e) {
|
||||
if (document.mozPointerLockElement === div) {
|
||||
div.addEventListener("mousemove", moveLocked, false);
|
||||
divRect = div.getBoundingClientRect();
|
||||
synthesizeMouse(div, (divRect.width / 4) * 3, (divRect.height / 4) * 3, {
|
||||
type: "mousemove"
|
||||
}, window);
|
||||
}
|
||||
}, false);
|
||||
|
||||
document.addEventListener("mozfullscreenchange", function() {
|
||||
if (document.mozFullScreenElement === div) {
|
||||
div.addEventListener("mousemove", moveUnlocked, false);
|
||||
synthesizeMouseAtCenter(div, { type: "mousemove" }, window);
|
||||
} else {
|
||||
runTests();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}, false);
|
||||
|
||||
function start() {
|
||||
SimpleTest.waitForFocus(function() {
|
||||
div = document.getElementById("div");
|
||||
div.mozRequestFullScreen();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,163 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=633602
|
||||
-->
|
||||
<head>
|
||||
<title>Bug 633602 - file_cursorPosEvents.html</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js">
|
||||
</script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<script type="application/javascript" src="pointerlock_utils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<style type="text/css">
|
||||
#child {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
background-color:Green;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body onload="start();">
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=633602">
|
||||
Mozilla Bug 633602</a>
|
||||
|
||||
<div id="parent">
|
||||
<div id="child"></div>
|
||||
</div>
|
||||
|
||||
<script type="application/javascript">
|
||||
/*
|
||||
* Test for Bug 633602
|
||||
* Test will check to make sure that the following mouse events are no
|
||||
* longer executed in pointer lock.
|
||||
* - mouseover, mouseout, mouseenter, mouseleave
|
||||
*/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
function PointerEventStats() {
|
||||
this.mouseEnter = false;
|
||||
this.mouseLeave = false;
|
||||
this.mouseOver = false;
|
||||
this.mouseOut = false;
|
||||
}
|
||||
|
||||
var parent
|
||||
, child
|
||||
, parentStats = new PointerEventStats()
|
||||
, childStats = new PointerEventStats()
|
||||
, isPointerLocked = false;
|
||||
|
||||
function runTests () {
|
||||
ok(isPointerLocked, "expected mouse to be locked, but wasn't.");
|
||||
|
||||
is(childStats.mouseEnter, false,
|
||||
"child's mouseenter should not be firing in Full Screen and Pointer Lock.");
|
||||
is(childStats.mouseOver, false,
|
||||
"child's mouseover should not be firing in Full Screen and Pointer Lock.");
|
||||
is(childStats.mouseLeave, false,
|
||||
"child's mouseleave should not be firing in Full Screen and Pointer Lock.");
|
||||
is(childStats.mouseOut, false,
|
||||
"child's mouseout should not be firing in Full Screen and Pointer Lock.");
|
||||
|
||||
is(parentStats.mouseEnter, false,
|
||||
"parent's mouseenter should not be firing in Full Screen and Pointer Lock.");
|
||||
is(parentStats.mouseOver, false,
|
||||
"parent's mouseover should not be firing in Full Screen and Pointer Lock.");
|
||||
is(parentStats.mouseLeave, false,
|
||||
"parent's mouseleave should not be firing in Full Screen and Pointer Lock.");
|
||||
is(parentStats.mouseOut, false,
|
||||
"parent's mouseout should not be firing in Full Screen and Pointer Lock.");
|
||||
}
|
||||
|
||||
var parentMoveListener = function () {
|
||||
isPointerLocked = !!document.mozPointerLockElement;
|
||||
removeEventListeners();
|
||||
document.mozExitPointerLock();
|
||||
};
|
||||
|
||||
var parentOutListener = function (e) {
|
||||
parentStats.mouseOut = true;
|
||||
};
|
||||
var parentLeaveListener = function (e) {
|
||||
parentStats.mouseLeave = true;
|
||||
};
|
||||
var parentOverListener = function (e) {
|
||||
parentStats.mouseOver = true;
|
||||
};
|
||||
var parentEnterListener = function (e) {
|
||||
parentStats.mouseEnter = true;
|
||||
};
|
||||
|
||||
var childOutListener = function (e) {
|
||||
childStats.mouseOut = true;
|
||||
};
|
||||
var childLeaveListener = function (e) {
|
||||
childStats.mouseLeave = true;
|
||||
};
|
||||
var childOverListener = function (e) {
|
||||
childStats.mouseOver = true;
|
||||
};
|
||||
var childEnterListener = function (e) {
|
||||
childStats.mouseEnter = true;
|
||||
};
|
||||
|
||||
function addEventListeners() {
|
||||
parent.addEventListener("mousemove", parentMoveListener, false);
|
||||
|
||||
parent.addEventListener("mouseout", parentOutListener, false);
|
||||
parent.addEventListener("mouseleave", parentLeaveListener, false);
|
||||
parent.addEventListener("mouseover", parentOverListener, false);
|
||||
parent.addEventListener("mouseenter", parentEnterListener, false);
|
||||
|
||||
child.addEventListener("mouseout", childOutListener, false);
|
||||
child.addEventListener("mouseleave", childLeaveListener, false);
|
||||
child.addEventListener("mouseover", childOverListener, false);
|
||||
child.addEventListener("mouseenter", childEnterListener, false);
|
||||
}
|
||||
|
||||
function removeEventListeners() {
|
||||
parent.removeEventListener("mousemove", parentMoveListener, false);
|
||||
|
||||
parent.removeEventListener("mouseout", parentOutListener, false);
|
||||
parent.removeEventListener("mouseleave", parentLeaveListener, false);
|
||||
parent.removeEventListener("mouseover", parentOverListener, false);
|
||||
parent.removeEventListener("mouseenter", parentEnterListener, false);
|
||||
|
||||
child.removeEventListener("mouseout", childOutListener, false);
|
||||
child.removeEventListener("mouseleave", childLeaveListener, false);
|
||||
child.removeEventListener("mouseover" , childOverListener, false);
|
||||
child.removeEventListener("mouseenter", childEnterListener, false);
|
||||
}
|
||||
|
||||
document.addEventListener("mozpointerlockchange", function (e) {
|
||||
if (document.mozPointerLockElement === parent) {
|
||||
addEventListeners();
|
||||
synthesizeMouseAtCenter(child, { type: "mousemove" }, window);
|
||||
}
|
||||
else {
|
||||
document.mozCancelFullScreen();
|
||||
}
|
||||
}, false);
|
||||
|
||||
document.addEventListener("mozfullscreenchange", function() {
|
||||
if (document.mozFullScreenElement === parent) {
|
||||
parent.mozRequestPointerLock();
|
||||
}
|
||||
else {
|
||||
runTests();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}, false);
|
||||
|
||||
function start() {
|
||||
SimpleTest.waitForFocus(function() {
|
||||
parent = document.getElementById("parent");
|
||||
child = document.getElementById("child");
|
||||
parent.mozRequestFullScreen();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
73
dom/tests/mochitest/pointerlock/file_targetOutOfFocus.html
Normal file
73
dom/tests/mochitest/pointerlock/file_targetOutOfFocus.html
Normal file
@ -0,0 +1,73 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=633602
|
||||
-->
|
||||
<head>
|
||||
<title>Bug 633602 - file_targetOutOfFocus.html</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js">
|
||||
</script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js">
|
||||
</script>
|
||||
<script type="application/javascript" src="pointerlock_utils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body onload="start();">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=633602">
|
||||
Mozilla Bug 633602
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content">
|
||||
</div>
|
||||
<div id="div"></div>
|
||||
<input id="input" type="text" />
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
/*
|
||||
* Test for Bug 633602
|
||||
* Element doesn't need to have focus to request
|
||||
* pointer lock
|
||||
*/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var div = document.getElementById("div")
|
||||
, input = document.getElementById("input")
|
||||
, divPointerLock = false;
|
||||
|
||||
function runTests () {
|
||||
ok(divPointerLock, "Pointer should be locked even if " +
|
||||
"the element being locked is not focused");
|
||||
}
|
||||
|
||||
input.addEventListener("focus", function() {
|
||||
div.mozRequestPointerLock();
|
||||
}, false);
|
||||
|
||||
document.addEventListener("mozpointerlockchange", function (e) {
|
||||
if (document.mozPointerLockElement === div) {
|
||||
divPointerLock = true;
|
||||
document.mozCancelFullScreen();
|
||||
}
|
||||
}, false);
|
||||
|
||||
document.addEventListener("mozfullscreenchange", function() {
|
||||
if (document.mozFullScreenElement === div) {
|
||||
input.focus();
|
||||
}
|
||||
else {
|
||||
runTests();
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}, false);
|
||||
|
||||
function start() {
|
||||
SimpleTest.waitForFocus(function() {
|
||||
div.mozRequestFullScreen();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
56
dom/tests/mochitest/pointerlock/file_withoutDOM.html
Normal file
56
dom/tests/mochitest/pointerlock/file_withoutDOM.html
Normal file
@ -0,0 +1,56 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=633602
|
||||
|
||||
Test DOM tree in full screen
|
||||
-->
|
||||
<head>
|
||||
<title>Bug 633602 - file_DOMtree.html</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js">
|
||||
</script>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js">
|
||||
</script>
|
||||
<script type="application/javascript" src="pointerlock_utils.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<style>
|
||||
</style>
|
||||
</head>
|
||||
<body onload="start();">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=633602">
|
||||
Mozilla Bug 633602
|
||||
</a>
|
||||
<pre id="test">
|
||||
<script type="text/javascript">
|
||||
/*
|
||||
* Test for Bug 633602
|
||||
* Checks if element is attached to the DOM Tree before locking
|
||||
* the pointer
|
||||
*/
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
var div = document.createElement("div")
|
||||
, withouthDOM = false;
|
||||
|
||||
function runTests () {
|
||||
ok(withouthDOM, "If an element is NOT in the " +
|
||||
"DOM Tree pointer should NOT be locked");
|
||||
}
|
||||
|
||||
document.addEventListener("mozpointerlockerror", function (e) {
|
||||
withouthDOM = true;
|
||||
runTests();
|
||||
SimpleTest.finish();
|
||||
}, false);
|
||||
|
||||
function start() {
|
||||
SimpleTest.waitForFocus(function() {
|
||||
div.mozRequestPointerLock();
|
||||
});
|
||||
}
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
7
dom/tests/mochitest/pointerlock/iframe_differentDOM.html
Normal file
7
dom/tests/mochitest/pointerlock/iframe_differentDOM.html
Normal file
@ -0,0 +1,7 @@
|
||||
<html>
|
||||
<head>
|
||||
</head>
|
||||
<body>
|
||||
<div id="div"></div>
|
||||
</body>
|
||||
</html>
|
34
dom/tests/mochitest/pointerlock/pointerlock_utils.js
Normal file
34
dom/tests/mochitest/pointerlock/pointerlock_utils.js
Normal file
@ -0,0 +1,34 @@
|
||||
// Get test filename for page being run in popup so errors are more useful
|
||||
var testName = location.pathname.split('/').pop();
|
||||
|
||||
// Wrap test functions and pass to parent window
|
||||
function ok(a, msg) {
|
||||
opener.ok(a, testName + ": " + msg);
|
||||
}
|
||||
|
||||
function is(a, b, msg) {
|
||||
opener.is(a, b, testName + ": " + msg);
|
||||
}
|
||||
|
||||
function isnot(a, b, msg) {
|
||||
opener.isnot(a, b, testName + ": " + msg);
|
||||
}
|
||||
|
||||
function todo(a, msg) {
|
||||
opener.todo(a, testName + ": " + msg);
|
||||
}
|
||||
|
||||
function todo_is(a, b, msg) {
|
||||
opener.todo_is(a, b, testName + ": " + msg);
|
||||
}
|
||||
|
||||
function todo_isnot(a, b, msg) {
|
||||
opener.todo_isnot(a, b, testName + ": " + msg);
|
||||
}
|
||||
|
||||
// Override SimpleTest so test files work stand-alone
|
||||
SimpleTest.finish = function () {
|
||||
opener.nextTest();
|
||||
};
|
||||
|
||||
SimpleTest.waitForExplicitFinish = function() {};
|
85
dom/tests/mochitest/pointerlock/test_pointerlock-api.html
Normal file
85
dom/tests/mochitest/pointerlock/test_pointerlock-api.html
Normal file
@ -0,0 +1,85 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=633602
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 633602</title>
|
||||
<script type="application/javascript"
|
||||
src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="/tests/SimpleTest/EventUtils.js"></script>
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=633602">
|
||||
Mozilla Bug 633602
|
||||
</a>
|
||||
<div id="content">
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script type="application/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
// Ensure the full-screen api is enabled,
|
||||
// and will be disabled on test exit.
|
||||
var prevEnabled = SpecialPowers.getBoolPref("full-screen-api.enabled");
|
||||
SpecialPowers.setBoolPref("full-screen-api.enabled", true);
|
||||
|
||||
// Disable the requirement for trusted contexts only,
|
||||
// so the tests are easier to write.
|
||||
var prevTrusted = SpecialPowers.getBoolPref(
|
||||
"full-screen-api.allow-trusted-requests-only");
|
||||
SpecialPowers.setBoolPref("full-screen-api.allow-trusted-requests-only",
|
||||
false);
|
||||
|
||||
// Run the tests which go full-screen in new window, as Mochitests
|
||||
// normally run in an iframe, which by default will not have the
|
||||
// mozallowfullscreen attribute set, so full-screen won't work.
|
||||
var gTestFiles = [
|
||||
"file_childIframe.html",
|
||||
"file_doubleLock.html",
|
||||
"file_escapeKey.html",
|
||||
"file_infiniteMovement.html",
|
||||
"file_locksvgelement.html",
|
||||
"file_loseFocusWindow.html",
|
||||
"file_movementXY.html",
|
||||
"file_nestedFullScreen.html",
|
||||
"file_pointerlock-api.html",
|
||||
"file_pointerlockerror.html",
|
||||
"file_pointerLockPref.html",
|
||||
"file_removedFromDOM.html",
|
||||
"file_retargetMouseEvents.html",
|
||||
"file_screenClientXYConst.html",
|
||||
"file_suppressSomeMouseEvents.html",
|
||||
"file_targetOutOfFocus.html",
|
||||
"file_withoutDOM.html"
|
||||
];
|
||||
|
||||
var testWindow = null;
|
||||
var gTestIndex = 0;
|
||||
|
||||
function nextTest() {
|
||||
if (testWindow) {
|
||||
testWindow.close();
|
||||
}
|
||||
if (gTestIndex < gTestFiles.length) {
|
||||
testWindow = window.open(gTestFiles[gTestIndex],
|
||||
"",
|
||||
"width=500,height=500");
|
||||
gTestIndex++;
|
||||
} else {
|
||||
SpecialPowers.setBoolPref("full-screen-api.enabled",
|
||||
prevEnabled);
|
||||
SpecialPowers.setBoolPref("full-screen-api.allow-trusted-requests-only",
|
||||
prevTrusted);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
}
|
||||
|
||||
addLoadEvent(nextTest);
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -134,10 +134,13 @@ class LayerManager;
|
||||
#define CAPTURE_RETARGETTOELEMENT 2
|
||||
// true if the current capture wants drags to be prevented
|
||||
#define CAPTURE_PREVENTDRAG 4
|
||||
// true when the mouse is pointer locked, and events are sent to locked elemnt
|
||||
#define CAPTURE_POINTERLOCK 8
|
||||
|
||||
typedef struct CapturingContentInfo {
|
||||
// capture should only be allowed during a mousedown event
|
||||
bool mAllowed;
|
||||
bool mPointerLock;
|
||||
bool mRetargetToElement;
|
||||
bool mPreventDrag;
|
||||
nsIContent* mContent;
|
||||
@ -1103,6 +1106,11 @@ public:
|
||||
*
|
||||
* If CAPTURE_PREVENTDRAG is set then drags are prevented from starting while
|
||||
* this capture is active.
|
||||
*
|
||||
* If CAPTURE_POINTERLOCK is set, similar to CAPTURE_RETARGETTOELEMENT, then
|
||||
* events are targeted at aContent, but capturing is held more strongly (i.e.,
|
||||
* calls to SetCapturingContent won't unlock unless CAPTURE_POINTERLOCK is
|
||||
* set again).
|
||||
*/
|
||||
static void SetCapturingContent(nsIContent* aContent, PRUint8 aFlags);
|
||||
|
||||
|
@ -228,7 +228,7 @@ using namespace mozilla::dom;
|
||||
using namespace mozilla::layers;
|
||||
|
||||
CapturingContentInfo nsIPresShell::gCaptureInfo =
|
||||
{ false /* mAllowed */, false /* mRetargetToElement */,
|
||||
{ false /* mAllowed */, false /* mPointerLock */, false /* mRetargetToElement */,
|
||||
false /* mPreventDrag */, nsnull /* mContent */ };
|
||||
nsIContent* nsIPresShell::gKeyDownTarget;
|
||||
nsInterfaceHashtable<nsUint32HashKey, nsIDOMTouch> nsIPresShell::gCaptureTouchList;
|
||||
@ -5447,16 +5447,27 @@ PresShell::Paint(nsIView* aViewToPaint,
|
||||
void
|
||||
nsIPresShell::SetCapturingContent(nsIContent* aContent, PRUint8 aFlags)
|
||||
{
|
||||
// If capture was set for pointer lock, don't unlock unless we are coming
|
||||
// out of pointer lock explicitly.
|
||||
if (!aContent && gCaptureInfo.mPointerLock &&
|
||||
!(aFlags & CAPTURE_POINTERLOCK)) {
|
||||
return;
|
||||
}
|
||||
|
||||
NS_IF_RELEASE(gCaptureInfo.mContent);
|
||||
|
||||
// only set capturing content if allowed or the CAPTURE_IGNOREALLOWED flag
|
||||
// is used
|
||||
if ((aFlags & CAPTURE_IGNOREALLOWED) || gCaptureInfo.mAllowed) {
|
||||
// only set capturing content if allowed or the CAPTURE_IGNOREALLOWED or
|
||||
// CAPTURE_POINTERLOCK flags are used.
|
||||
if ((aFlags & CAPTURE_IGNOREALLOWED) || gCaptureInfo.mAllowed ||
|
||||
(aFlags & CAPTURE_POINTERLOCK)) {
|
||||
if (aContent) {
|
||||
NS_ADDREF(gCaptureInfo.mContent = aContent);
|
||||
}
|
||||
gCaptureInfo.mRetargetToElement = (aFlags & CAPTURE_RETARGETTOELEMENT) != 0;
|
||||
// CAPTURE_POINTERLOCK is the same as CAPTURE_RETARGETTOELEMENT & CAPTURE_IGNOREALLOWED
|
||||
gCaptureInfo.mRetargetToElement = ((aFlags & CAPTURE_RETARGETTOELEMENT) != 0) ||
|
||||
((aFlags & CAPTURE_POINTERLOCK) != 0);
|
||||
gCaptureInfo.mPreventDrag = (aFlags & CAPTURE_PREVENTDRAG) != 0;
|
||||
gCaptureInfo.mPointerLock = (aFlags & CAPTURE_POINTERLOCK) != 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -5750,7 +5761,8 @@ PresShell::HandleEvent(nsIFrame *aFrame,
|
||||
NS_TIME_FUNCTION_MIN(1.0);
|
||||
|
||||
nsIContent* capturingContent =
|
||||
NS_IS_MOUSE_EVENT(aEvent) ? GetCapturingContent() : nsnull;
|
||||
NS_IS_MOUSE_EVENT(aEvent) || aEvent->eventStructType == NS_MOUSE_SCROLL_EVENT ?
|
||||
GetCapturingContent() : nsnull;
|
||||
|
||||
nsCOMPtr<nsIDocument> retargetEventDoc;
|
||||
if (!aDontRetargetEvents) {
|
||||
|
@ -3486,6 +3486,7 @@ pref("full-screen-api.allow-trusted-requests-only", true);
|
||||
pref("full-screen-api.key-input-restricted", true);
|
||||
pref("full-screen-api.warning.enabled", true);
|
||||
pref("full-screen-api.exit-on-deactivate", true);
|
||||
pref("full-screen-api.pointer-lock.enabled", true);
|
||||
|
||||
// Time limit, in milliseconds, for nsEventStateManager::IsHandlingUserInput().
|
||||
// Used to detect long running handlers of user-generated events.
|
||||
|
@ -488,7 +488,10 @@ public:
|
||||
virtual nsresult SynthesizeNativeMouseEvent(nsIntPoint aPoint,
|
||||
PRUint32 aNativeMessage,
|
||||
PRUint32 aModifierFlags);
|
||||
|
||||
|
||||
virtual nsresult SynthesizeNativeMouseMove(nsIntPoint aPoint)
|
||||
{ return SynthesizeNativeMouseEvent(aPoint, NSMouseMoved, 0); }
|
||||
|
||||
// Mac specific methods
|
||||
|
||||
virtual bool DispatchWindowEvent(nsGUIEvent& event);
|
||||
|
@ -6493,3 +6493,19 @@ nsWindow::ClearCachedResources()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsWindow::SynthesizeNativeMouseEvent(nsIntPoint aPoint,
|
||||
PRUint32 aNativeMessage,
|
||||
PRUint32 aModifierFlags)
|
||||
{
|
||||
if (!mGdkWindow) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
GdkDisplay* display = gdk_window_get_display(mGdkWindow);
|
||||
GdkScreen* screen = gdk_window_get_screen(mGdkWindow);
|
||||
gdk_display_warp_pointer(display, screen, aPoint.x, aPoint.y);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -347,6 +347,13 @@ public:
|
||||
#endif
|
||||
NS_IMETHOD ReparentNativeWidget(nsIWidget* aNewParent);
|
||||
|
||||
virtual nsresult SynthesizeNativeMouseEvent(nsIntPoint aPoint,
|
||||
PRUint32 aNativeMessage,
|
||||
PRUint32 aModifierFlags);
|
||||
|
||||
virtual nsresult SynthesizeNativeMouseMove(nsIntPoint aPoint)
|
||||
{ return SynthesizeNativeMouseEvent(aPoint, GDK_MOTION_NOTIFY, 0); }
|
||||
|
||||
protected:
|
||||
// Helper for SetParent and ReparentNativeWidget.
|
||||
void ReparentNativeWidgetInternal(nsIWidget* aNewParent,
|
||||
|
@ -558,6 +558,11 @@ class nsHashKey;
|
||||
#define NS_TOUCH_LEAVE (NS_TOUCH_EVENT_START+4)
|
||||
#define NS_TOUCH_CANCEL (NS_TOUCH_EVENT_START+5)
|
||||
|
||||
// Pointerlock DOM API
|
||||
#define NS_POINTERLOCK_START 5300
|
||||
#define NS_POINTERLOCKCHANGE (NS_POINTERLOCK_START)
|
||||
#define NS_POINTERLOCKERROR (NS_POINTERLOCK_START + 1)
|
||||
|
||||
/**
|
||||
* Return status for event processors, nsEventStatus, is defined in
|
||||
* nsEvent.h.
|
||||
@ -583,6 +588,7 @@ protected:
|
||||
: eventStructType(structType),
|
||||
message(msg),
|
||||
refPoint(0, 0),
|
||||
lastRefPoint(0, 0),
|
||||
time(0),
|
||||
flags(isTrusted ? NS_EVENT_FLAG_TRUSTED : NS_EVENT_FLAG_NONE),
|
||||
userType(0)
|
||||
@ -599,6 +605,7 @@ public:
|
||||
: eventStructType(NS_EVENT),
|
||||
message(msg),
|
||||
refPoint(0, 0),
|
||||
lastRefPoint(0, 0),
|
||||
time(0),
|
||||
flags(isTrusted ? NS_EVENT_FLAG_TRUSTED : NS_EVENT_FLAG_NONE),
|
||||
userType(0)
|
||||
@ -618,6 +625,8 @@ public:
|
||||
// Relative to the widget of the event, or if there is no widget then it is
|
||||
// in screen coordinates. Not modified by layout code.
|
||||
nsIntPoint refPoint;
|
||||
// The previous refPoint, if known, used to calculate mouse movement deltas.
|
||||
nsIntPoint lastRefPoint;
|
||||
// Elapsed time, in milliseconds, from a platform-specific zero time
|
||||
// to the time the message was created
|
||||
PRUint64 time;
|
||||
|
@ -118,8 +118,8 @@ typedef nsEventStatus (* EVENT_CALLBACK)(nsGUIEvent *event);
|
||||
#endif
|
||||
|
||||
#define NS_IWIDGET_IID \
|
||||
{ 0xe7af49c1, 0xd11b, 0x4070, \
|
||||
{ 0x99, 0x7a, 0x2d, 0x2b, 0x7, 0x4b, 0xea, 0xf4 } }
|
||||
{ 0xb5bb55c7, 0x9a50, 0x4fa8, \
|
||||
{ 0xa7, 0x6e, 0xbd, 0x31, 0x6f, 0x3e, 0x9c, 0x13 } }
|
||||
|
||||
/*
|
||||
* Window shadow styles
|
||||
@ -1376,6 +1376,11 @@ class nsIWidget : public nsISupports {
|
||||
PRUint32 aNativeMessage,
|
||||
PRUint32 aModifierFlags) = 0;
|
||||
|
||||
/**
|
||||
* A shortcut to SynthesizeNativeMouseEvent, abstracting away the native message.
|
||||
*/
|
||||
virtual nsresult SynthesizeNativeMouseMove(nsIntPoint aPoint) = 0;
|
||||
|
||||
/**
|
||||
* Utility method intended for testing. Dispatching native mouse scroll
|
||||
* events may move the mouse cursor.
|
||||
|
@ -177,6 +177,10 @@ public:
|
||||
virtual nsresult SynthesizeNativeMouseEvent(nsIntPoint aPoint,
|
||||
PRUint32 aNativeMessage,
|
||||
PRUint32 aModifierFlags);
|
||||
|
||||
virtual nsresult SynthesizeNativeMouseMove(nsIntPoint aPoint)
|
||||
{ return SynthesizeNativeMouseEvent(aPoint, MOUSEEVENTF_MOVE, 0); }
|
||||
|
||||
virtual nsresult SynthesizeNativeMouseScrollEvent(nsIntPoint aPoint,
|
||||
PRUint32 aNativeMessage,
|
||||
double aDeltaX,
|
||||
|
@ -270,6 +270,9 @@ protected:
|
||||
PRUint32 aModifierFlags)
|
||||
{ return NS_ERROR_UNEXPECTED; }
|
||||
|
||||
virtual nsresult SynthesizeNativeMouseMove(nsIntPoint aPoint)
|
||||
{ return NS_ERROR_UNEXPECTED; }
|
||||
|
||||
virtual nsresult SynthesizeNativeMouseScrollEvent(nsIntPoint aPoint,
|
||||
PRUint32 aNativeMessage,
|
||||
double aDeltaX,
|
||||
|
Loading…
Reference in New Issue
Block a user