Bug 1323983 part 1 - Ensure to release the pointer even if the document has been detached. r=smaug

MozReview-Commit-ID: FY5lDQBYl6U

--HG--
extra : rebase_source : a4d8540f9d22de86549660e173b5a0dc52835b75
This commit is contained in:
Xidorn Quan 2016-12-19 15:28:31 +11:00
parent 78a33f04df
commit 5c12d2debc
3 changed files with 14 additions and 8 deletions

View File

@ -11703,6 +11703,12 @@ nsDocument::SetPointerLock(Element* aElement, int aCursorStyle)
nsIPresShell* shell = GetShell();
if (!shell) {
NS_WARNING("SetPointerLock(): No PresShell");
if (!aElement) {
// If we are unlocking pointer lock, but for some reason the doc
// has already detached from the presshell, just ask the event
// state manager to release the pointer.
EventStateManager::SetPointerLock(nullptr, nullptr);
}
return false;
}
nsPresContext* presContext = shell->GetPresContext();
@ -11728,7 +11734,7 @@ nsDocument::SetPointerLock(Element* aElement, int aCursorStyle)
RefPtr<EventStateManager> esm = presContext->EventStateManager();
esm->SetCursor(aCursorStyle, nullptr, false,
0.0f, 0.0f, widget, true);
esm->SetPointerLock(widget, aElement);
EventStateManager::SetPointerLock(widget, aElement);
return true;
}

View File

@ -268,6 +268,7 @@ bool EventStateManager::sNormalLMouseEventInProcess = false;
EventStateManager* EventStateManager::sActiveESM = nullptr;
nsIDocument* EventStateManager::sMouseOverDocument = nullptr;
nsWeakFrame EventStateManager::sLastDragOverFrame = nullptr;
LayoutDeviceIntPoint EventStateManager::sPreLockPoint = LayoutDeviceIntPoint(0, 0);
LayoutDeviceIntPoint EventStateManager::sLastRefPoint = kInvalidRefPoint;
CSSIntPoint EventStateManager::sLastScreenPoint = CSSIntPoint(0, 0);
LayoutDeviceIntPoint EventStateManager::sSynthCenteringPoint = kInvalidRefPoint;
@ -290,7 +291,6 @@ EventStateManager::DeltaAccumulator*
EventStateManager::EventStateManager()
: mLockCursor(0)
, mLastFrameConsumedSetCursor(false)
, mPreLockPoint(0,0)
, mCurrentTarget(nullptr)
// init d&d gesture state machine variables
, mGestureDownPoint(0,0)
@ -4349,7 +4349,7 @@ EventStateManager::GetWrapperByEventID(WidgetMouseEvent* aEvent)
return helper;
}
void
/* static */ void
EventStateManager::SetPointerLock(nsIWidget* aWidget,
nsIContent* aElement)
{
@ -4367,7 +4367,7 @@ EventStateManager::SetPointerLock(nsIWidget* aWidget,
MOZ_ASSERT(aWidget, "Locking pointer requires a widget");
// Store the last known ref point so we can reposition the pointer after unlock.
mPreLockPoint = sLastRefPoint;
sPreLockPoint = sLastRefPoint;
// Fire a synthetic mouse move to ensure event state is updated. We first
// set the mouse to the center of the window, so that the mouse event
@ -4385,13 +4385,13 @@ EventStateManager::SetPointerLock(nsIWidget* aWidget,
// synthetic mouse event. We first reset sLastRefPoint to its
// pre-pointerlock position, so that the synthetic mouse event reports
// no movement.
sLastRefPoint = mPreLockPoint;
sLastRefPoint = sPreLockPoint;
// Reset SynthCenteringPoint to invalid so that next time we start
// locking pointer, it has its initial value.
sSynthCenteringPoint = kInvalidRefPoint;
if (aWidget) {
aWidget->SynthesizeNativeMouseMove(
mPreLockPoint + aWidget->WidgetToScreenOffset(), nullptr);
sPreLockPoint + aWidget->WidgetToScreenOffset(), nullptr);
}
// Unsuppress DnD

View File

@ -921,7 +921,7 @@ private:
// Last mouse event mRefPoint (the offset from the widget's origin in
// device pixels) when mouse was locked, used to restore mouse position
// after unlocking.
LayoutDeviceIntPoint mPreLockPoint;
static LayoutDeviceIntPoint sPreLockPoint;
// Stores the mRefPoint of the last synthetic mouse move we dispatched
// to re-center the mouse when we were pointer locked. If this is (-1,-1) it
@ -1015,7 +1015,7 @@ public:
void KillClickHoldTimer();
void FireContextClick();
void SetPointerLock(nsIWidget* aWidget, nsIContent* aElement) ;
static void SetPointerLock(nsIWidget* aWidget, nsIContent* aElement) ;
static void sClickHoldCallback ( nsITimer* aTimer, void* aESM ) ;
};