Bug 1304692 - Make puppet widget get coordinate rounding from parent. r=smaug
authorXidorn Quan <me@upsuper.org>
Tue, 27 Sep 2016 16:37:07 +1000
changeset 358357 853d4b8a9fde261131ad00286c010fd299ab4e61
parent 358356 a376f49314e3dab3ace4f7f14b310ef3e64dd1fd
child 358358 b2750ecaa0b5496277801a7f8c63220677f68ce0
push id6795
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 14:19:46 +0000
treeherdermozilla-beta@76101b503191 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1304692
milestone52.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1304692 - Make puppet widget get coordinate rounding from parent. r=smaug MozReview-Commit-ID: A3ornUMDmt8
dom/ipc/ContentChild.cpp
dom/ipc/PBrowser.ipdl
dom/ipc/TabChild.cpp
dom/ipc/TabChild.h
dom/ipc/TabParent.cpp
dom/ipc/TabParent.h
widget/PuppetWidget.cpp
widget/PuppetWidget.h
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -817,24 +817,25 @@ ContentChild::ProvideWindowCommon(TabChi
     return NS_ERROR_ABORT;
   }
 
   if (layersId == 0) { // if renderFrame is invalid.
     PRenderFrameChild::Send__delete__(renderFrame);
     renderFrame = nullptr;
   }
 
-  ShowInfo showInfo(EmptyString(), false, false, true, false, 0, 0);
+  ShowInfo showInfo(EmptyString(), false, false, true, false, 0, 0, 0);
   auto* opener = nsPIDOMWindowOuter::From(aParent);
   nsIDocShell* openerShell;
   if (opener && (openerShell = opener->GetDocShell())) {
     nsCOMPtr<nsILoadContext> context = do_QueryInterface(openerShell);
     showInfo = ShowInfo(EmptyString(), false,
                         context->UsePrivateBrowsing(), true, false,
-                        aTabOpener->mDPI, aTabOpener->mDefaultScale);
+                        aTabOpener->mDPI, aTabOpener->mRounding,
+                        aTabOpener->mDefaultScale);
   }
 
   // Unfortunately we don't get a window unless we've shown the frame.  That's
   // pretty bogus; see bug 763602.
   newChild->DoFakeShow(textureFactoryIdentifier, layersId, renderFrame,
                        showInfo);
 
   for (size_t i = 0; i < frameScripts.Length(); i++) {
--- a/dom/ipc/PBrowser.ipdl
+++ b/dom/ipc/PBrowser.ipdl
@@ -96,16 +96,17 @@ union MaybeNativeKeyBinding
 struct ShowInfo
 {
   nsString name;
   bool fullscreenAllowed;
   bool isPrivate;
   bool fakeShowInfo;
   bool isTransparent;
   float dpi;
+  int32_t widgetRounding;
   double defaultScale;
 };
 
 union OptionalShmem
 {
   void_t;
   Shmem;
 };
@@ -371,16 +372,21 @@ parent:
     sync GetDPI() returns (float value);
 
     /**
      * Gets the default scaling factor of the screen corresponding to this browser.
      */
     sync GetDefaultScale() returns (double value);
 
     /**
+     * Gets the rounding of coordinates in the widget.
+     */
+    sync GetWidgetRounding() returns (int32_t value);
+
+    /**
      * Gets maximum of touch points at current device.
      */
     sync GetMaxTouchPoints() returns (uint32_t value);
 
     /**
      * Set the native cursor.
      * @param value
      *   The widget cursor to set.
@@ -788,17 +794,17 @@ child:
      * Tell the child that the UI resolution changed for the containing
      * window.
      * To avoid some sync messages from child to parent, we also send the dpi
      * and default scale with the notification.
      * If we don't know the dpi and default scale, we just pass in a negative
      * value (-1) but in the majority of the cases this saves us from two
      * sync requests from the child to the parent.
      */
-    async UIResolutionChanged(float dpi, double scale);
+    async UIResolutionChanged(float dpi, int32_t rounding, double scale);
 
     /**
      * Tell the child that the system theme has changed, and that a repaint
      * is necessary.
      */
     async ThemeChanged(LookAndFeelInt[] lookAndFeelIntCache);
 
     /**
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -536,16 +536,17 @@ TabChild::TabChild(nsIContentChild* aMan
   , mTriedBrowserInit(false)
   , mOrientation(eScreenOrientation_PortraitPrimary)
   , mUpdateHitRegion(false)
   , mIgnoreKeyPressEvent(false)
   , mHasValidInnerSize(false)
   , mDestroyed(false)
   , mUniqueId(aTabId)
   , mDPI(0)
+  , mRounding(0)
   , mDefaultScale(0)
   , mIsTransparent(false)
   , mIPCOpen(false)
   , mParentIsActive(false)
   , mDidSetRealShowInfo(false)
   , mDidLoadURLInit(false)
   , mAPZChild(nullptr)
   , mLayerObserverEpoch(0)
@@ -1544,16 +1545,17 @@ TabChild::ApplyShowInfo(const ShowInfo& 
           DocShellOriginAttributes attrs(nsDocShell::Cast(docShell)->GetOriginAttributes());
           attrs.SyncAttributesWithPrivateBrowsing(true);
           nsDocShell::Cast(docShell)->SetOriginAttributes(attrs);
         }
       }
     }
   }
   mDPI = aInfo.dpi();
+  mRounding = aInfo.widgetRounding();
   mDefaultScale = aInfo.defaultScale();
   mIsTransparent = aInfo.isTransparent();
 }
 
 #ifdef MOZ_WIDGET_GONK
 void
 TabChild::MaybeRequestPreinitCamera()
 {
@@ -2938,16 +2940,32 @@ TabChild::GetDefaultScale(double* aScale
       return;
     }
 
     // Fallback to a sync call if needed.
     SendGetDefaultScale(aScale);
 }
 
 void
+TabChild::GetWidgetRounding(int32_t* aRounding)
+{
+  *aRounding = 1;
+  if (!mRemoteFrame) {
+    return;
+  }
+  if (mRounding > 0) {
+    *aRounding = mRounding;
+    return;
+  }
+
+  // Fallback to a sync call if needed.
+  SendGetWidgetRounding(aRounding);
+}
+
+void
 TabChild::GetMaxTouchPoints(uint32_t* aTouchPoints)
 {
   // Fallback to a sync call.
   SendGetMaxTouchPoints(aTouchPoints);
 }
 
 void
 TabChild::NotifyPainted()
@@ -3280,22 +3298,25 @@ TabChild::RecvRequestNotifyAfterRemotePa
   // Tell the CompositorBridgeChild that, when it gets a RemotePaintIsReady
   // message that it should forward it us so that we can bounce it to our
   // RenderFrameParent.
   compositor->RequestNotifyAfterRemotePaint(this);
   return true;
 }
 
 bool
-TabChild::RecvUIResolutionChanged(const float& aDpi, const double& aScale)
+TabChild::RecvUIResolutionChanged(const float& aDpi,
+                                  const int32_t& aRounding,
+                                  const double& aScale)
 {
   ScreenIntSize oldScreenSize = GetInnerSize();
   mDPI = 0;
+  mRounding = 0;
   mDefaultScale = 0;
-  static_cast<PuppetWidget*>(mPuppetWidget.get())->UpdateBackingScaleCache(aDpi, aScale);
+  static_cast<PuppetWidget*>(mPuppetWidget.get())->UpdateBackingScaleCache(aDpi, aRounding, aScale);
   nsCOMPtr<nsIDocument> document(GetDocument());
   nsCOMPtr<nsIPresShell> presShell = document->GetShell();
   if (presShell) {
     RefPtr<nsPresContext> presContext = presShell->GetPresContext();
     if (presContext) {
       presContext->UIResolutionChangedSync();
     }
   }
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -479,16 +479,18 @@ public:
 
   virtual PuppetWidget* WebWidget() override { return mPuppetWidget; }
 
   /** Return the DPI of the widget this TabChild draws to. */
   void GetDPI(float* aDPI);
 
   void GetDefaultScale(double *aScale);
 
+  void GetWidgetRounding(int32_t* aRounding);
+
   bool IsTransparent() const { return mIsTransparent; }
 
   void GetMaxTouchPoints(uint32_t* aTouchPoints);
 
   ScreenOrientationInternal GetOrientation() const { return mOrientation; }
 
   void SetBackgroundColor(const nscolor& aColor);
 
@@ -567,16 +569,17 @@ public:
   static inline TabChild* GetFrom(nsIDOMWindow* aWindow)
   {
     nsCOMPtr<nsIWebNavigation> webNav = do_GetInterface(aWindow);
     nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(webNav);
     return GetFrom(docShell);
   }
 
   virtual bool RecvUIResolutionChanged(const float& aDpi,
+                                       const int32_t& aRounding,
                                        const double& aScale) override;
 
   virtual bool
   RecvThemeChanged(nsTArray<LookAndFeelInt>&& aLookAndFeelIntCache) override;
 
   virtual bool RecvHandleAccessKey(const WidgetKeyboardEvent& aEvent,
                                    nsTArray<uint32_t>&& aCharCodes,
                                    const int32_t& aModifierMask) override;
@@ -772,16 +775,17 @@ private:
   // Position of client area relative to the outer window
   LayoutDeviceIntPoint mClientOffset;
   // Position of tab, relative to parent widget (typically the window)
   LayoutDeviceIntPoint mChromeDisp;
   TabId mUniqueId;
 
   friend class ContentChild;
   float mDPI;
+  int32_t mRounding;
   double mDefaultScale;
 
   bool mIsTransparent;
 
   bool mIPCOpen;
   bool mParentIsActive;
   bool mAsyncPanZoomEnabled;
   CSSSize mUnscaledInnerSize;
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -272,16 +272,17 @@ TabParent::TabParent(nsIContentParent* a
                      const TabContext& aContext,
                      uint32_t aChromeFlags)
   : TabContext(aContext)
   , mFrameElement(nullptr)
   , mRect(0, 0, 0, 0)
   , mDimensions(0, 0)
   , mOrientation(0)
   , mDPI(0)
+  , mRounding(0)
   , mDefaultScale(0)
   , mUpdatedDimensions(false)
   , mSizeMode(nsSizeMode_Normal)
   , mManager(aManager)
   , mDocShellIsActive(false)
   , mMarkedDestroying(false)
   , mIsDestroyed(false)
   , mIsDetached(true)
@@ -1025,17 +1026,18 @@ TabParent::UIResolutionChanged()
     // TryCacheDPIAndScale()'s cache is keyed off of
     // mDPI being greater than 0, so this invalidates it.
     mDPI = -1;
     TryCacheDPIAndScale();
     // If mDPI was set to -1 to invalidate it and then TryCacheDPIAndScale
     // fails to cache the values, then mDefaultScale.scale might be invalid.
     // We don't want to send that value to content. Just send -1 for it too in
     // that case.
-    Unused << SendUIResolutionChanged(mDPI, mDPI < 0 ? -1.0 : mDefaultScale.scale);
+    Unused << SendUIResolutionChanged(mDPI, mRounding,
+                                      mDPI < 0 ? -1.0 : mDefaultScale.scale);
   }
 }
 
 void
 TabParent::ThemeChanged()
 {
   if (!mIsDestroyed) {
     // The theme has changed, and any cached values we had sent down
@@ -2495,16 +2497,27 @@ TabParent::RecvGetDefaultScale(double* a
 
   MOZ_ASSERT(mDefaultScale.scale > 0,
              "Must not ask for scale before OwnerElement is received!");
   *aValue = mDefaultScale.scale;
   return true;
 }
 
 bool
+TabParent::RecvGetWidgetRounding(int32_t* aValue)
+{
+  TryCacheDPIAndScale();
+
+  MOZ_ASSERT(mRounding > 0,
+             "Must not ask for rounding before OwnerElement is received!");
+  *aValue = mRounding;
+  return true;
+}
+
+bool
 TabParent::RecvGetMaxTouchPoints(uint32_t* aTouchPoints)
 {
   nsCOMPtr<nsIWidget> widget = GetWidget();
   if (widget) {
     *aTouchPoints = widget->GetMaxTouchPoints();
   } else {
     *aTouchPoints = 0;
   }
@@ -2761,16 +2774,17 @@ TabParent::TryCacheDPIAndScale()
   if (mDPI > 0) {
     return;
   }
 
   nsCOMPtr<nsIWidget> widget = GetWidget();
 
   if (widget) {
     mDPI = widget->GetDPI();
+    mRounding = widget->RoundsWidgetCoordinatesTo();
     mDefaultScale = widget->GetDefaultScale();
   }
 }
 
 already_AddRefed<nsIWidget>
 TabParent::GetWidget() const
 {
   if (!mFrameElement) {
@@ -3369,21 +3383,21 @@ TabParent::GetShowInfo()
     bool allowFullscreen =
       mFrameElement->HasAttr(kNameSpaceID_None, nsGkAtoms::allowfullscreen) ||
       mFrameElement->HasAttr(kNameSpaceID_None, nsGkAtoms::mozallowfullscreen);
     bool isPrivate = mFrameElement->HasAttr(kNameSpaceID_None, nsGkAtoms::mozprivatebrowsing);
     bool isTransparent =
       nsContentUtils::IsChromeDoc(mFrameElement->OwnerDoc()) &&
       mFrameElement->HasAttr(kNameSpaceID_None, nsGkAtoms::transparent);
     return ShowInfo(name, allowFullscreen, isPrivate, false,
-                    isTransparent, mDPI, mDefaultScale.scale);
+                    isTransparent, mDPI, mRounding, mDefaultScale.scale);
   }
 
   return ShowInfo(EmptyString(), false, false, false,
-                  false, mDPI, mDefaultScale.scale);
+                  false, mDPI, mRounding, mDefaultScale.scale);
 }
 
 void
 TabParent::AudioChannelChangeNotification(nsPIDOMWindowOuter* aWindow,
                                           AudioChannel aAudioChannel,
                                           float aVolume,
                                           bool aMuted)
 {
--- a/dom/ipc/TabParent.h
+++ b/dom/ipc/TabParent.h
@@ -316,16 +316,18 @@ public:
                                const nsString& aDirection) override;
 
   virtual bool RecvHideTooltip() override;
 
   virtual bool RecvGetDPI(float* aValue) override;
 
   virtual bool RecvGetDefaultScale(double* aValue) override;
 
+  virtual bool RecvGetWidgetRounding(int32_t* aValue) override;
+
   virtual bool RecvGetMaxTouchPoints(uint32_t* aTouchPoints) override;
 
   virtual bool RecvGetWidgetNativeData(WindowsHandle* aValue) override;
 
   virtual bool RecvSetNativeChildOfShareableWindow(const uintptr_t& childWindow) override;
 
   virtual bool RecvDispatchFocusToTopLevelWindow() override;
 
@@ -630,16 +632,17 @@ protected:
                                                     const bool& aActive) override;
 
   ContentCacheInParent mContentCache;
 
   nsIntRect mRect;
   ScreenIntSize mDimensions;
   ScreenOrientationInternal mOrientation;
   float mDPI;
+  int32_t mRounding;
   CSSToLayoutDeviceScale mDefaultScale;
   bool mUpdatedDimensions;
   nsSizeMode mSizeMode;
   LayoutDeviceIntPoint mClientOffset;
   LayoutDeviceIntPoint mChromeOffset;
 
 private:
   void DestroyInternal();
--- a/widget/PuppetWidget.cpp
+++ b/widget/PuppetWidget.cpp
@@ -74,16 +74,17 @@ MightNeedIMEFocus(const nsWidgetInitData
 const size_t PuppetWidget::kMaxDimension = 4000;
 
 NS_IMPL_ISUPPORTS_INHERITED0(PuppetWidget, nsBaseWidget)
 
 PuppetWidget::PuppetWidget(TabChild* aTabChild)
   : mTabChild(aTabChild)
   , mMemoryPressureObserver(nullptr)
   , mDPI(-1)
+  , mRounding(-1)
   , mDefaultScale(-1)
   , mCursorHotspotX(0)
   , mCursorHotspotY(0)
   , mNativeKeyCommandsValid(false)
 {
   MOZ_COUNT_CTOR(PuppetWidget);
 
   mSingleLineCommands.SetCapacity(4);
@@ -1189,16 +1190,30 @@ PuppetWidget::GetDefaultScaleInternal()
     } else {
       mDefaultScale = 1;
     }
   }
 
   return mDefaultScale;
 }
 
+int32_t
+PuppetWidget::RoundsWidgetCoordinatesTo()
+{
+  if (mRounding < 0) {
+    if (mTabChild) {
+      mTabChild->GetWidgetRounding(&mRounding);
+    } else {
+      mRounding = 1;
+    }
+  }
+
+  return mRounding;
+}
+
 void*
 PuppetWidget::GetNativeData(uint32_t aDataType)
 {
   switch (aDataType) {
   case NS_NATIVE_SHAREABLE_WINDOW: {
     MOZ_ASSERT(mTabChild, "Need TabChild to get the nativeWindow from!");
     mozilla::WindowsHandle nativeData = 0;
     if (mTabChild) {
--- a/widget/PuppetWidget.h
+++ b/widget/PuppetWidget.h
@@ -130,16 +130,18 @@ public:
 
   // PuppetWidgets don't have any concept of titles.
   NS_IMETHOD SetTitle(const nsAString& aTitle) override
   { return NS_ERROR_UNEXPECTED; }
 
   virtual LayoutDeviceIntPoint WidgetToScreenOffset() override
   { return LayoutDeviceIntPoint::FromUnknownPoint(GetWindowPosition() + GetChromeDimensions()); }
 
+  int32_t RoundsWidgetCoordinatesTo() override;
+
   void InitEvent(WidgetGUIEvent& aEvent,
                  LayoutDeviceIntPoint* aPoint = nullptr);
 
   NS_IMETHOD DispatchEvent(WidgetGUIEvent* aEvent, nsEventStatus& aStatus) override;
   nsEventStatus DispatchInputEvent(WidgetInputEvent* aEvent) override;
   void SetConfirmedTargetAPZC(uint64_t aInputBlockId,
                               const nsTArray<ScrollableLayerGuid>& aTargets) const override;
   void UpdateZoomConstraints(const uint32_t& aPresShellId,
@@ -197,19 +199,20 @@ public:
 
   virtual bool NeedsPaint() override;
 
   // Paint the widget immediately if any paints are queued up.
   void PaintNowIfNeeded();
 
   virtual TabChild* GetOwningTabChild() override { return mTabChild; }
 
-  void UpdateBackingScaleCache(float aDpi, double aScale)
+  void UpdateBackingScaleCache(float aDpi, int32_t aRounding, double aScale)
   {
     mDPI = aDpi;
+    mRounding = aRounding;
     mDefaultScale = aScale;
   }
 
   nsIntSize GetScreenDimensions();
 
   // Get the size of the chrome of the window that this tab belongs to.
   nsIntPoint GetChromeDimensions();
 
@@ -353,16 +356,17 @@ private:
   // process.  If it hasn't been started composition yet, this isn't necessary
   // for XP code since there is no TextComposition instance which is caused by
   // the PuppetWidget instance.
   NativeIMEContext mNativeIMEContext;
   ContentCacheInChild mContentCache;
 
   // The DPI of the screen corresponding to this widget
   float mDPI;
+  int32_t mRounding;
   double mDefaultScale;
 
   // Precomputed answers for ExecuteNativeKeyBinding
   InfallibleTArray<mozilla::CommandInt> mSingleLineCommands;
   InfallibleTArray<mozilla::CommandInt> mMultiLineCommands;
   InfallibleTArray<mozilla::CommandInt> mRichTextCommands;
 
   nsCOMPtr<imgIContainer> mCustomCursor;