changeset: 312091:a3fff31b8b70 user: Xidorn Quan Date: Thu Apr 14 17:38:13 2016 +1000 summary: Bug 1261933 - Continue unlocking pointer even if the widget has gone. r=smaug a=lizzard MozReview-Commit-ID: 1siQhemFf9O diff -r f5e862ea4a72 -r a3fff31b8b70 dom/base/nsDocument.cpp --- a/dom/base/nsDocument.cpp Tue May 31 18:35:26 2016 -0700 +++ b/dom/base/nsDocument.cpp Thu Apr 14 17:38:13 2016 +1000 @@ -12315,49 +12315,37 @@ bool nsDocument::SetPointerLock(Element* aElement, int aCursorStyle) { - // NOTE: aElement will be nullptr when unlocking. - nsCOMPtr 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 presContext; - docShell->GetPresContext(getter_AddRefs(presContext)); - if (!presContext) { - NS_WARNING("SetPointerLock(): Unable to get presContext in \ - domWindow->GetDocShell()->GetPresContext()"); + MOZ_ASSERT(!aElement || aElement->OwnerDoc() == this, + "We should be either unlocking pointer (aElement is nullptr), " + "or locking pointer to an element in this document"); +#ifdef DEBUG + if (!aElement) { + nsCOMPtr pointerLockedDoc = + do_QueryReferent(EventStateManager::sPointerLockedDoc); + MOZ_ASSERT(pointerLockedDoc == this); + } +#endif + + nsIPresShell* shell = GetShell(); + if (!shell) { + NS_WARNING("SetPointerLock(): No PresShell"); return false; } - - nsCOMPtr 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"); + nsPresContext* presContext = shell->GetPresContext(); + if (!presContext) { + NS_WARNING("SetPointerLock(): Unable to get PresContext"); return false; } - nsCOMPtr 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; + nsCOMPtr widget; + nsIFrame* rootFrame = shell->GetRootFrame(); + if (!NS_WARN_IF(!rootFrame)) { + widget = rootFrame->GetNearestWidget(); + NS_WARN_IF_FALSE(widget, "SetPointerLock(): Unable to find widget " + "in shell->GetRootFrame()->GetNearestWidget();"); + if (aElement && !widget) { + return false; + } } // Hide the cursor and set pointer lock for future mouse events diff -r f5e862ea4a72 -r a3fff31b8b70 dom/events/EventStateManager.cpp --- a/dom/events/EventStateManager.cpp Tue May 31 18:35:26 2016 -0700 +++ b/dom/events/EventStateManager.cpp Thu Apr 14 17:38:13 2016 +1000 @@ -4128,10 +4128,6 @@ // NOTE: aElement will be nullptr when unlocking. sIsPointerLocked = !!aElement; - if (!aWidget) { - return; - } - // Reset mouse wheel transaction WheelTransaction::EndTransaction(); @@ -4140,6 +4136,8 @@ do_GetService("@mozilla.org/widget/dragservice;1"); if (sIsPointerLocked) { + MOZ_ASSERT(aWidget, "Locking pointer requires a widget"); + // Store the last known ref point so we can reposition the pointer after unlock. mPreLockPoint = sLastRefPoint; @@ -4164,7 +4162,9 @@ // pre-pointerlock position, so that the synthetic mouse event reports // no movement. sLastRefPoint = mPreLockPoint; - aWidget->SynthesizeNativeMouseMove(mPreLockPoint + aWidget->WidgetToScreenOffset()); + if (aWidget) { + aWidget->SynthesizeNativeMouseMove(mPreLockPoint + aWidget->WidgetToScreenOffset()); + } // Don't retarget events to this element any more. nsIPresShell::SetCapturingContent(nullptr, CAPTURE_POINTERLOCK);