Bug 1860065 - Use sLastScreenPoint to restore mouse position after releasing pointer lock; r=smaug

Differential Revision: https://phabricator.services.mozilla.com/D196544
This commit is contained in:
Edgar Chen 2024-01-25 22:48:07 +00:00
parent f0be219b00
commit c2b42175e7
3 changed files with 17 additions and 17 deletions

View File

@ -265,7 +265,7 @@ bool PointerLockManager::SetPointerLock(Element* aElement, Document* aDocument,
}
return false;
}
nsPresContext* presContext = presShell->GetPresContext();
RefPtr<nsPresContext> presContext = presShell->GetPresContext();
if (!presContext) {
NS_WARNING("SetPointerLock(): Unable to get PresContext");
return false;
@ -288,7 +288,7 @@ bool PointerLockManager::SetPointerLock(Element* aElement, Document* aDocument,
// Hide the cursor and set pointer lock for future mouse events
RefPtr<EventStateManager> esm = presContext->EventStateManager();
esm->SetCursor(aCursorStyle, nullptr, {}, Nothing(), widget, true);
EventStateManager::SetPointerLock(widget, aElement);
EventStateManager::SetPointerLock(widget, presContext);
return true;
}

View File

@ -306,7 +306,7 @@ int16_t EventStateManager::sCurrentMouseBtn = MouseButton::eNotPressed;
EventStateManager* EventStateManager::sActiveESM = nullptr;
EventStateManager* EventStateManager::sCursorSettingManager = nullptr;
AutoWeakFrame EventStateManager::sLastDragOverFrame = nullptr;
LayoutDeviceIntPoint EventStateManager::sPreLockPoint =
LayoutDeviceIntPoint EventStateManager::sPreLockScreenPoint =
LayoutDeviceIntPoint(0, 0);
LayoutDeviceIntPoint EventStateManager::sLastRefPoint = kInvalidRefPoint;
CSSIntPoint EventStateManager::sLastScreenPoint = CSSIntPoint(0, 0);
@ -5128,7 +5128,7 @@ OverOutElementsWrapper* EventStateManager::GetWrapperByEventID(
/* static */
void EventStateManager::SetPointerLock(nsIWidget* aWidget,
nsIContent* aElement) {
nsPresContext* aPresContext) {
// Reset mouse wheel transaction
WheelTransaction::EndTransaction();
@ -5138,6 +5138,7 @@ void EventStateManager::SetPointerLock(nsIWidget* aWidget,
if (PointerLockManager::IsLocked()) {
MOZ_ASSERT(aWidget, "Locking pointer requires a widget");
MOZ_ASSERT(aPresContext, "Locking pointer requires a presContext");
// Release all pointer capture when a pointer lock is successfully applied
// on an element.
@ -5145,7 +5146,8 @@ void EventStateManager::SetPointerLock(nsIWidget* aWidget,
// Store the last known ref point so we can reposition the pointer after
// unlock.
sPreLockPoint = sLastRefPoint;
sPreLockScreenPoint = LayoutDeviceIntPoint::Round(
sLastScreenPoint * aPresContext->CSSToDevPixelScale());
// 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
@ -5170,20 +5172,19 @@ void EventStateManager::SetPointerLock(nsIWidget* aWidget,
aWidget->UnlockNativePointer();
}
// Unlocking, so return pointer to the original position by firing a
// synthetic mouse event. We first reset sLastRefPoint to its
// pre-pointerlock position, so that the synthetic mouse event reports
// no movement.
sLastRefPoint = sPreLockPoint;
// Reset SynthCenteringPoint to invalid so that next time we start
// locking pointer, it has its initial value.
sSynthCenteringPoint = kInvalidRefPoint;
if (aWidget) {
// Unlocking, so return pointer to the original position by firing a
// synthetic mouse event. We first reset sLastRefPoint to its
// pre-pointerlock position, so that the synthetic mouse event reports
// no movement.
sLastRefPoint = sPreLockScreenPoint - aWidget->WidgetToScreenOffset();
// XXX Cannot we do synthesize the native mousemove in the parent process
// with calling `UnlockNativePointer` above? Then, we could make this
// API work only in the automation mode.
aWidget->SynthesizeNativeMouseMove(
sPreLockPoint + aWidget->WidgetToScreenOffset(), nullptr);
aWidget->SynthesizeNativeMouseMove(sPreLockScreenPoint, nullptr);
}
// Unsuppress DnD

View File

@ -1174,10 +1174,9 @@ class EventStateManager : public nsSupportsWeakReference, public nsIObserver {
bool mLastFrameConsumedSetCursor = false;
bool mHidingCursorWhileTyping = false;
// 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.
static LayoutDeviceIntPoint sPreLockPoint;
// Last mouse event screen point (in device pixel) when mouse was locked, used
// to restore mouse position after unlocking.
static LayoutDeviceIntPoint sPreLockScreenPoint;
// 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
@ -1259,7 +1258,7 @@ class EventStateManager : public nsSupportsWeakReference, public nsIObserver {
MOZ_CAN_RUN_SCRIPT_BOUNDARY void FireContextClick();
MOZ_CAN_RUN_SCRIPT static void SetPointerLock(nsIWidget* aWidget,
nsIContent* aElement);
nsPresContext* aPresContext);
static void sClickHoldCallback(nsITimer* aTimer, void* aESM);
};