Bug 978913 - Dragging e10s window between HiDPI and non-HiDPI displays causes text to be scaled incorrectly. r=smaug.
authorMike Conley <mconley@mozilla.com>
Fri, 23 May 2014 10:36:50 -0400
changeset 184622 a40b1e15ae8b711fa94d8bc52fe82e6b8c61b180
parent 184621 315b244f4e903c349de5834e8c4bb46038e3ca52
child 184623 c745965a2213baf4dd857e7ba22af544a2c09f97
push id43902
push usermconley@mozilla.com
push dateFri, 23 May 2014 14:37:24 +0000
treeherdermozilla-inbound@a40b1e15ae8b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs978913
milestone32.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 978913 - Dragging e10s window between HiDPI and non-HiDPI displays causes text to be scaled incorrectly. r=smaug.
dom/ipc/PBrowser.ipdl
dom/ipc/TabChild.cpp
dom/ipc/TabChild.h
dom/ipc/TabParent.cpp
dom/ipc/TabParent.h
layout/base/nsPresContext.cpp
widget/xpwidgets/PuppetWidget.h
--- a/dom/ipc/PBrowser.ipdl
+++ b/dom/ipc/PBrowser.ipdl
@@ -498,16 +498,22 @@ child:
      */
     SetUpdateHitRegion(bool aEnabled);
 
     /**
      * Tell the child to update its docShell's active state.
      */
     SetIsDocShellActive(bool aIsActive);
 
+    /**
+     * Tell the child that the UI resolution changed for the containing
+     * window.
+     */
+    UIResolutionChanged();
+
 /*
  * FIXME: write protocol!
 
 state LIVE:
     send LoadURL goto LIVE;
 //etc.
     send Destroy goto DYING;
 
--- a/dom/ipc/TabChild.cpp
+++ b/dom/ipc/TabChild.cpp
@@ -2728,16 +2728,27 @@ TabChild::OnShowTooltip(int32_t aXCoords
 
 NS_IMETHODIMP
 TabChild::OnHideTooltip()
 {
     SendHideTooltip();
     return NS_OK;
 }
 
+bool
+TabChild::RecvUIResolutionChanged()
+{
+  static_cast<PuppetWidget*>(mWidget.get())->ClearBackingScaleCache();
+  nsCOMPtr<nsIDocument> document(GetDocument());
+  nsCOMPtr<nsIPresShell> presShell = document->GetShell();
+  nsRefPtr<nsPresContext> presContext = presShell->GetPresContext();
+  presContext->UIResolutionChanged();
+  return true;
+}
+
 TabChildGlobal::TabChildGlobal(TabChildBase* aTabChild)
 : mTabChild(aTabChild)
 {
 }
 
 void
 TabChildGlobal::Init()
 {
--- a/dom/ipc/TabChild.h
+++ b/dom/ipc/TabChild.h
@@ -451,16 +451,18 @@ 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() MOZ_OVERRIDE;
+
 protected:
     virtual PRenderFrameChild* AllocPRenderFrameChild(ScrollingBehavior* aScrolling,
                                                       TextureFactoryIdentifier* aTextureFactoryIdentifier,
                                                       uint64_t* aLayersId,
                                                       bool* aSuccess) MOZ_OVERRIDE;
     virtual bool DeallocPRenderFrameChild(PRenderFrameChild* aFrame) MOZ_OVERRIDE;
     virtual bool RecvDestroy() MOZ_OVERRIDE;
     virtual bool RecvSetUpdateHitRegion(const bool& aEnabled) MOZ_OVERRIDE;
--- a/dom/ipc/TabParent.cpp
+++ b/dom/ipc/TabParent.cpp
@@ -505,16 +505,27 @@ void
 TabParent::UpdateFrame(const FrameMetrics& aFrameMetrics)
 {
   if (!mIsDestroyed) {
     unused << SendUpdateFrame(aFrameMetrics);
   }
 }
 
 void
+TabParent::UIResolutionChanged()
+{
+  if (!mIsDestroyed) {
+    // TryCacheDPIAndScale()'s cache is keyed off of
+    // mDPI being greater than 0, so this invalidates it.
+    mDPI = -1;
+    unused << SendUIResolutionChanged();
+  }
+}
+
+void
 TabParent::AcknowledgeScrollUpdate(const ViewID& aScrollId, const uint32_t& aScrollGeneration)
 {
   if (!mIsDestroyed) {
     unused << SendAcknowledgeScrollUpdate(aScrollId, aScrollGeneration);
   }
 }
 
 void TabParent::HandleDoubleTap(const CSSPoint& aPoint,
--- a/dom/ipc/TabParent.h
+++ b/dom/ipc/TabParent.h
@@ -193,16 +193,17 @@ public:
 
     void LoadURL(nsIURI* aURI);
     // XXX/cjones: it's not clear what we gain by hiding these
     // message-sending functions under a layer of indirection and
     // eating the return values
     void Show(const nsIntSize& size);
     void UpdateDimensions(const nsRect& rect, const nsIntSize& size);
     void UpdateFrame(const layers::FrameMetrics& aFrameMetrics);
+    void UIResolutionChanged();
     void AcknowledgeScrollUpdate(const ViewID& aScrollId, const uint32_t& aScrollGeneration);
     void HandleDoubleTap(const CSSPoint& aPoint,
                          int32_t aModifiers,
                          const ScrollableLayerGuid& aGuid);
     void HandleSingleTap(const CSSPoint& aPoint,
                          int32_t aModifiers,
                          const ScrollableLayerGuid& aGuid);
     void HandleLongTap(const CSSPoint& aPoint,
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -44,21 +44,25 @@
 #include "nsTransitionManager.h"
 #include "nsAnimationManager.h"
 #include "mozilla/MemoryReporting.h"
 #include "mozilla/dom/Element.h"
 #include "nsIMessageManager.h"
 #include "mozilla/dom/MediaQueryList.h"
 #include "nsSMILAnimationController.h"
 #include "mozilla/css/ImageLoader.h"
+#include "mozilla/dom/PBrowserParent.h"
 #include "mozilla/dom/TabChild.h"
+#include "mozilla/dom/TabParent.h"
 #include "nsRefreshDriver.h"
 #include "Layers.h"
 #include "nsIDOMEvent.h"
 #include "gfxPrefs.h"
+#include "nsIDOMChromeWindow.h"
+#include "nsFrameLoader.h"
 
 #include "nsContentUtils.h"
 #include "nsCxPusher.h"
 #include "nsPIWindowRoot.h"
 #include "mozilla/Preferences.h"
 
 // Needed for Start/Stop of Image Animation
 #include "imgIContainer.h"
@@ -1763,16 +1767,45 @@ nsPresContext::UIResolutionChangedIntern
 {
   mPendingUIResolutionChanged = false;
 
   mDeviceContext->CheckDPIChange();
   if (mCurAppUnitsPerDevPixel != AppUnitsPerDevPixel()) {
     AppUnitsPerDevPixelChanged();
   }
 
+  nsCOMPtr<nsIDOMChromeWindow> chromeWindow(do_QueryInterface(mDocument->GetWindow()));
+  nsCOMPtr<nsIMessageBroadcaster> windowMM;
+  if (chromeWindow) {
+    chromeWindow->GetMessageManager(getter_AddRefs(windowMM));
+  }
+  if (windowMM) {
+    uint32_t tabChildCount = 0;
+    windowMM->GetChildCount(&tabChildCount);
+    for (uint32_t j = 0; j < tabChildCount; ++j) {
+      nsCOMPtr<nsIMessageListenerManager> childMM;
+      windowMM->GetChildAt(j, getter_AddRefs(childMM));
+      if (!childMM) {
+        continue;
+      }
+      nsCOMPtr<nsIMessageSender> tabMM = do_QueryInterface(childMM);
+
+      mozilla::dom::ipc::MessageManagerCallback* cb =
+       static_cast<nsFrameMessageManager*>(tabMM.get())->GetCallback();
+      if (cb) {
+        nsFrameLoader* fl = static_cast<nsFrameLoader*>(cb);
+        PBrowserParent* remoteBrowser = fl->GetRemoteBrowser();
+        TabParent* remote = static_cast<TabParent*>(remoteBrowser);
+        if (remote) {
+          remote->UIResolutionChanged();
+        }
+      }
+    }
+  }
+
   mDocument->EnumerateSubDocuments(UIResolutionChangedSubdocumentCallback,
                                    nullptr);
 }
 
 void
 nsPresContext::EmulateMedium(const nsAString& aMediaType)
 {
   nsIAtom* previousMedium = Medium();
--- a/widget/xpwidgets/PuppetWidget.h
+++ b/widget/xpwidgets/PuppetWidget.h
@@ -178,16 +178,21 @@ public:
   // proper widget there. TODO: Handle DPI changes that happen
   // later on.
   virtual float GetDPI();
   virtual double GetDefaultScaleInternal();
 
   virtual bool NeedsPaint() MOZ_OVERRIDE;
 
   virtual TabChild* GetOwningTabChild() MOZ_OVERRIDE { return mTabChild; }
+  virtual void ClearBackingScaleCache()
+  {
+    mDPI = -1;
+    mDefaultScale = -1;
+  }
 
 private:
   nsresult Paint();
 
   void SetChild(PuppetWidget* aChild);
 
   nsresult IMEEndComposition(bool aCancel);
   nsresult NotifyIMEOfFocusChange(bool aFocus);