Bug 1244546 part 2 - Align the center point for pointerlock to meet widget's requirement. draft
authorXidorn Quan <quanxunzhen@gmail.com>
Thu, 10 Mar 2016 17:46:53 +0800
changeset 338982 7305da141428dcb9c953d395acd76e3916bf63b2
parent 338981 9d558262caffed0858121b7a68ca7d9c5a660176
child 515896 ec13eb6f3b88ea30c4d717f3dfa2e02778cad32a
push id12624
push userxquan@mozilla.com
push dateThu, 10 Mar 2016 09:47:19 +0000
bugs1244546
milestone48.0a1
Bug 1244546 part 2 - Align the center point for pointerlock to meet widget's requirement. MozReview-Commit-ID: I4BS1pfyMLD
dom/events/EventStateManager.cpp
--- a/dom/events/EventStateManager.cpp
+++ b/dom/events/EventStateManager.cpp
@@ -4159,58 +4159,34 @@ EventStateManager::NotifyMouseOver(Widge
     wrapper->mLastOverFrame = nullptr;
     wrapper->mLastOverElement = nullptr;
   }
 
   // Turn recursion protection back off
   wrapper->mFirstOverEventElement = nullptr;
 }
 
-// Returns the center point of the window's inner content area.
-// This is in widget coordinates, i.e. relative to the widget's top
-// left corner, not in screen coordinates, the same units that
-// UIEvent::refPoint is in.
-//
-// XXX Hack alert: XXX
-// However, we do the computation in integer CSS pixels, NOT device pix,
-// in order to fudge around the one-pixel error in innerHeight in fullscreen
-// mode (see bug 799523 comment 35, and bug 729011). Using integer CSS pix
-// makes us throw away the fractional error that results, rather than having
-// it manifest as a potential one-device-pix discrepancy.
+// Returns the center point of the window's client area. This is
+// in widget coordinates, i.e. relative to the widget's top-left
+// corner, not in screen coordinates, the same units that UIEvent::
+// refpoint is in. It may not be the exact center of the window if
+// the platform requires rounding the coordinate.
 static LayoutDeviceIntPoint
-GetWindowInnerRectCenter(nsPIDOMWindowOuter* aWindow,
-                         nsIWidget* aWidget,
-                         nsPresContext* aContext)
+GetWindowClientRectCenter(nsIWidget* aWidget)
 {
-  NS_ENSURE_TRUE(aWindow && aWidget && aContext, LayoutDeviceIntPoint(0, 0));
-
-  nsGlobalWindow* window = nsGlobalWindow::Cast(aWindow);
-
-  float cssInnerX = window->GetMozInnerScreenXOuter();
-  int32_t innerX = int32_t(NS_round(cssInnerX));
-
-  float cssInnerY = window->GetMozInnerScreenYOuter();
-  int32_t innerY = int32_t(NS_round(cssInnerY));
-
-  ErrorResult dummy;
-  int32_t innerWidth = window->GetInnerWidthOuter(dummy);
-  dummy.SuppressException();
-
-  int32_t innerHeight = window->GetInnerHeightOuter(dummy);
-  dummy.SuppressException();
-
-  LayoutDeviceIntRect screen;
-  aWidget->GetScreenBounds(screen);
-
-  int32_t cssScreenX = aContext->DevPixelsToIntCSSPixels(screen.x);
-  int32_t cssScreenY = aContext->DevPixelsToIntCSSPixels(screen.y);
-
-  return LayoutDeviceIntPoint(
-    aContext->CSSPixelsToDevPixels(innerX - cssScreenX + innerWidth / 2),
-    aContext->CSSPixelsToDevPixels(innerY - cssScreenY + innerHeight / 2));
+  NS_ENSURE_TRUE(aWidget, LayoutDeviceIntPoint(0, 0));
+
+  LayoutDeviceIntRect rect;
+  aWidget->GetClientBounds(rect);
+  auto point = LayoutDeviceIntPoint(rect.x + rect.width / 2,
+                                    rect.y + rect.height / 2);
+  int32_t round = aWidget->RoundsWidgetCoordinatesTo();
+  point.x = point.x / round * round;
+  point.y = point.y / round * round;
+  return point - aWidget->WidgetToScreenOffset();
 }
 
 void
 EventStateManager::GeneratePointerEnterExit(EventMessage aMessage,
                                             WidgetMouseEvent* aEvent)
 {
   WidgetPointerEvent pointerEvent(*aEvent);
   pointerEvent.mMessage = aMessage;
@@ -4236,18 +4212,17 @@ EventStateManager::GenerateMouseEnterExi
       if (sIsPointerLocked && aMouseEvent->widget) {
         // The pointer is locked. If the pointer is not located at the center of
         // the window, dispatch a synthetic mousemove to return the pointer there.
         // Doing this between "real" pointer moves gives the impression that the
         // (locked) pointer can continue moving and won't stop at the screen
         // boundary. We cancel the synthetic event so that we don't end up
         // dispatching the centering move event to content.
         LayoutDeviceIntPoint center =
-          GetWindowInnerRectCenter(mDocument->GetWindow(), aMouseEvent->widget,
-                                   mPresContext);
+          GetWindowClientRectCenter(aMouseEvent->widget);
         aMouseEvent->lastRefPoint = center;
         if (aMouseEvent->refPoint != center) {
           // Mouse move doesn't finish at the center of the window. Dispatch a
           // synthetic native mouse event to move the pointer back to the center
           // of the window, to faciliate more movement. But first, record that
           // we've dispatched a synthetic mouse movement, so we can cancel it
           // in the other branch here.
           sSynthCenteringPoint = center;
@@ -4381,19 +4356,17 @@ EventStateManager::SetPointerLock(nsIWid
 
   if (sIsPointerLocked) {
     // Store the last known ref point so we can reposition the pointer after unlock.
     mPreLockPoint = 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
     // doesn't report any movement.
-    sLastRefPoint = GetWindowInnerRectCenter(aElement->OwnerDoc()->GetWindow(),
-                                             aWidget,
-                                             mPresContext);
+    sLastRefPoint = GetWindowClientRectCenter(aWidget);
     aWidget->SynthesizeNativeMouseMove(sLastRefPoint + aWidget->WidgetToScreenOffset(),
                                        nullptr);
 
     // Retarget all events to this element via capture.
     nsIPresShell::SetCapturingContent(aElement, CAPTURE_POINTERLOCK);
 
     // Suppress DnD
     if (dragService) {