Bug 890156 - patch 0.3 - Create a version of nsIWidget::Create that takes Desktop pixels, because that's what we actually need to pass in some cases. r=mstange
authorJonathan Kew <jkew@mozilla.com>
Wed, 13 Jan 2016 07:32:55 +0000
changeset 279688 f4b5097c00c6373b07ec3140a1c0741732beaeda
parent 279687 87b35034828d7c4fc4f1cfd0e6cba4e9ce0b1f92
child 279689 cc09fb02f2c9191098ff2ab9ba97ed57162e806b
push id70188
push userjkew@mozilla.com
push dateWed, 13 Jan 2016 08:42:41 +0000
treeherdermozilla-inbound@a9f9b36c1a2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange
bugs890156
milestone46.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 890156 - patch 0.3 - Create a version of nsIWidget::Create that takes Desktop pixels, because that's what we actually need to pass in some cases. r=mstange
gfx/tests/gtest/TestCompositor.cpp
widget/PluginWidgetProxy.h
widget/PuppetWidget.h
widget/android/nsWindow.h
widget/cocoa/nsCocoaWindow.h
widget/cocoa/nsCocoaWindow.mm
widget/gonk/nsWindow.h
widget/gtk/nsWindow.h
widget/nsIWidget.h
widget/windows/nsWindow.h
xpfe/appshell/nsWebShellWindow.cpp
--- a/gfx/tests/gtest/TestCompositor.cpp
+++ b/gfx/tests/gtest/TestCompositor.cpp
@@ -54,16 +54,20 @@ public:
     }
     return nullptr;
   }
 
   NS_IMETHOD              Create(nsIWidget* aParent,
                                  nsNativeWidget aNativeParent,
                                  const LayoutDeviceIntRect& aRect,
                                  nsWidgetInitData* aInitData = nullptr) override { return NS_OK; }
+  NS_IMETHOD              Create(nsIWidget* aParent,
+                                 nsNativeWidget aNativeParent,
+                                 const DesktopIntRect& aRect,
+                                 nsWidgetInitData* aInitData = nullptr) override { return NS_OK; }
   NS_IMETHOD              Show(bool aState) override { return NS_OK; }
   virtual bool            IsVisible() const override { return true; }
   NS_IMETHOD              ConstrainPosition(bool aAllowSlop,
                                             int32_t *aX, int32_t *aY) override { return NS_OK; }
   NS_IMETHOD              Move(double aX, double aY) override { return NS_OK; }
   NS_IMETHOD              Resize(double aWidth, double aHeight, bool aRepaint) override { return NS_OK; }
   NS_IMETHOD              Resize(double aX, double aY,
                                  double aWidth, double aHeight, bool aRepaint) override { return NS_OK; }
--- a/widget/PluginWidgetProxy.h
+++ b/widget/PluginWidgetProxy.h
@@ -29,16 +29,17 @@ public:
 
 protected:
   virtual ~PluginWidgetProxy();
 
 public:
   NS_DECL_ISUPPORTS_INHERITED
 
   // nsIWidget
+  using PuppetWidget::Create; // for Create signature not overridden here
   NS_IMETHOD Create(nsIWidget* aParent, nsNativeWidget aNativeParent,
                     const LayoutDeviceIntRect& aRect,
                     nsWidgetInitData* aInitData = nullptr) override;
   NS_IMETHOD Destroy() override;
   NS_IMETHOD SetFocus(bool aRaise = false) override;
   NS_IMETHOD SetParent(nsIWidget* aNewParent) override;
 
   virtual nsIWidget* GetParent(void) override;
--- a/widget/PuppetWidget.h
+++ b/widget/PuppetWidget.h
@@ -48,16 +48,17 @@ public:
   explicit PuppetWidget(TabChild* aTabChild);
 
 protected:
   virtual ~PuppetWidget();
 
 public:
   NS_DECL_ISUPPORTS_INHERITED
 
+  using nsBaseWidget::Create; // for Create signature not overridden here
   NS_IMETHOD Create(nsIWidget* aParent,
                     nsNativeWidget aNativeParent,
                     const LayoutDeviceIntRect& aRect,
                     nsWidgetInitData* aInitData = nullptr) override;
 
   void InitIMEState();
 
   virtual already_AddRefed<nsIWidget>
--- a/widget/android/nsWindow.h
+++ b/widget/android/nsWindow.h
@@ -72,16 +72,17 @@ public:
 
     void InitEvent(mozilla::WidgetGUIEvent& event,
                    LayoutDeviceIntPoint* aPoint = 0);
 
     //
     // nsIWidget
     //
 
+    using nsBaseWidget::Create; // for Create signature not overridden here
     NS_IMETHOD Create(nsIWidget* aParent,
                       nsNativeWidget aNativeParent,
                       const LayoutDeviceIntRect& aRect,
                       nsWidgetInitData* aInitData) override;
     NS_IMETHOD Destroy(void) override;
     NS_IMETHOD ConfigureChildren(const nsTArray<nsIWidget::Configuration>&) override;
     NS_IMETHOD SetParent(nsIWidget* aNewParent) override;
     virtual nsIWidget *GetParent(void) override;
--- a/widget/cocoa/nsCocoaWindow.h
+++ b/widget/cocoa/nsCocoaWindow.h
@@ -252,16 +252,21 @@ public:
 
     nsCocoaWindow();
 
     NS_DECL_ISUPPORTS_INHERITED
     NS_DECL_NSPIWIDGETCOCOA
 
     NS_IMETHOD              Create(nsIWidget* aParent,
                                    nsNativeWidget aNativeParent,
+                                   const DesktopIntRect& aRect,
+                                   nsWidgetInitData* aInitData = nullptr) override;
+
+    NS_IMETHOD              Create(nsIWidget* aParent,
+                                   nsNativeWidget aNativeParent,
                                    const LayoutDeviceIntRect& aRect,
                                    nsWidgetInitData* aInitData = nullptr) override;
 
     NS_IMETHOD              Destroy() override;
 
     NS_IMETHOD              Show(bool aState) override;
     virtual nsIWidget*      GetSheetWindowParent(void) override;
     NS_IMETHOD              Enable(bool aState) override;
--- a/widget/cocoa/nsCocoaWindow.mm
+++ b/widget/cocoa/nsCocoaWindow.mm
@@ -178,40 +178,40 @@ nsCocoaWindow::~nsCocoaWindow()
   }
 
   NS_OBJC_END_TRY_ABORT_BLOCK;
 }
 
 // Find the screen that overlaps aRect the most,
 // if none are found default to the mainScreen.
 static NSScreen*
-FindTargetScreenForRect(const LayoutDeviceIntRect& aRect)
+FindTargetScreenForRect(const DesktopIntRect& aRect)
 {
   NSScreen *targetScreen = [NSScreen mainScreen];
   NSEnumerator *screenEnum = [[NSScreen screens] objectEnumerator];
   int largestIntersectArea = 0;
   while (NSScreen *screen = [screenEnum nextObject]) {
-    LayoutDeviceIntRect screenRect =
-      LayoutDeviceIntRect::FromUnknownRect(
+    DesktopIntRect screenRect =
+      DesktopIntRect::FromUnknownRect(
         nsCocoaUtils::CocoaRectToGeckoRect([screen visibleFrame]));
     screenRect = screenRect.Intersect(aRect);
     int area = screenRect.width * screenRect.height;
     if (area > largestIntersectArea) {
       largestIntersectArea = area;
       targetScreen = screen;
     }
   }
   return targetScreen;
 }
 
 // fits the rect to the screen that contains the largest area of it,
 // or to aScreen if a screen is passed in
 // NB: this operates with aRect in desktop pixels
 static void
-FitRectToVisibleAreaForScreen(LayoutDeviceIntRect& aRect, NSScreen* aScreen)
+FitRectToVisibleAreaForScreen(DesktopIntRect& aRect, NSScreen* aScreen)
 {
   if (!aScreen) {
     aScreen = FindTargetScreenForRect(aRect);
   }
 
   nsIntRect screenBounds(nsCocoaUtils::CocoaRectToGeckoRect([aScreen visibleFrame]));
 
   if (aRect.width > screenBounds.width) {
@@ -247,26 +247,26 @@ static bool UseNativePopupWindows()
 #else
   return false;
 #endif /* MOZ_USE_NATIVE_POPUP_WINDOWS */
 }
 
 // aRect here is specified in desktop pixels
 nsresult nsCocoaWindow::Create(nsIWidget* aParent,
                                nsNativeWidget aNativeParent,
-                               const LayoutDeviceIntRect& aRect,
+                               const DesktopIntRect& aRect,
                                nsWidgetInitData* aInitData)
 {
   NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
 
   // Because the hidden window is created outside of an event loop,
   // we have to provide an autorelease pool (see bug 559075).
   nsAutoreleasePool localPool;
 
-  LayoutDeviceIntRect newBounds = aRect;
+  DesktopIntRect newBounds = aRect;
   FitRectToVisibleAreaForScreen(newBounds, nullptr);
 
   // Set defaults which can be overriden from aInitData in BaseCreate
   mWindowType = eWindowType_toplevel;
   mBorderStyle = eBorderStyle_default;
 
   // Ensure that the toolkit is created.
   nsToolkit::GetToolkit();
@@ -286,31 +286,37 @@ nsresult nsCocoaWindow::Create(nsIWidget
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (mWindowType == eWindowType_popup) {
     if (aInitData->mMouseTransparent) {
       [mWindow setIgnoresMouseEvents:YES];
     }
     // now we can convert newBounds to device pixels for the window we created,
     // as the child view expects a rect expressed in the dev pix of its parent
-    double scale = BackingScaleFactor();
-    newBounds.x *= scale;
-    newBounds.y *= scale;
-    newBounds.width *= scale;
-    newBounds.height *= scale;
-    return CreatePopupContentView(newBounds);
+    DesktopToLayoutDeviceScale scale(BackingScaleFactor());
+    return CreatePopupContentView(RoundedToInt(newBounds * scale));
   }
 
   mIsAnimationSuppressed = aInitData->mIsAnimationSuppressed;
 
   return NS_OK;
 
   NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
 }
 
+nsresult nsCocoaWindow::Create(nsIWidget* aParent,
+                               nsNativeWidget aNativeParent,
+                               const LayoutDeviceIntRect& aRect,
+                               nsWidgetInitData* aInitData)
+{
+  DesktopToLayoutDeviceScale scale(GetDefaultScaleInternal());
+  DesktopIntRect desktopRect = RoundedToInt(aRect / scale);
+  return Create(aParent, aNativeParent, desktopRect, aInitData);
+}
+
 static unsigned int WindowMaskForBorderStyle(nsBorderStyle aBorderStyle)
 {
   bool allOrDefault = (aBorderStyle == eBorderStyle_all ||
                          aBorderStyle == eBorderStyle_default);
 
   /* Apple's docs on NSWindow styles say that "a window's style mask should
    * include NSTitledWindowMask if it includes any of the others [besides
    * NSBorderlessWindowMask]".  This implies that a borderless window
@@ -1530,19 +1536,19 @@ nsresult nsCocoaWindow::DoResize(double 
 
   // ConstrainSize operates in device pixels, so we need to convert using
   // the backing scale factor here
   CGFloat scale = BackingScaleFactor();
   int32_t width = NSToIntRound(aWidth * scale);
   int32_t height = NSToIntRound(aHeight * scale);
   ConstrainSize(&width, &height);
 
-  LayoutDeviceIntRect newBounds(NSToIntRound(aX), NSToIntRound(aY),
-                                NSToIntRound(width / scale),
-                                NSToIntRound(height / scale));
+  DesktopIntRect newBounds(NSToIntRound(aX), NSToIntRound(aY),
+                           NSToIntRound(width / scale),
+                           NSToIntRound(height / scale));
 
   // constrain to the screen that contains the largest area of the new rect
   FitRectToVisibleAreaForScreen(newBounds, aConstrainToCurrentScreen ?
                                            [mWindow screen] : nullptr);
 
   // convert requested bounds into Cocoa coordinate system
   NSRect newFrame =
     nsCocoaUtils::GeckoRectToCocoaRect(newBounds.ToUnknownRect());
@@ -1677,17 +1683,17 @@ GetBackingScaleFactor(NSWindow* aWindow)
   }
   if (frame.size.height == 0) {
     frame.size.height = 1;
   }
 
   // Then identify the screen it belongs to, and return its scale factor.
   NSScreen *screen =
     FindTargetScreenForRect(
-      LayoutDeviceIntRect::FromUnknownRect(nsCocoaUtils::CocoaRectToGeckoRect(frame)));
+      DesktopIntRect::FromUnknownRect(nsCocoaUtils::CocoaRectToGeckoRect(frame)));
   return nsCocoaUtils::GetBackingScaleFactor(screen);
 }
 
 CGFloat
 nsCocoaWindow::BackingScaleFactor()
 {
   if (mBackingScaleFactor > 0.0) {
     return mBackingScaleFactor;
--- a/widget/gonk/nsWindow.h
+++ b/widget/gonk/nsWindow.h
@@ -41,20 +41,21 @@ public:
     nsWindow();
 
     NS_DECL_ISUPPORTS_INHERITED
 
     static void DoDraw(void);
     static nsEventStatus DispatchKeyInput(mozilla::WidgetKeyboardEvent& aEvent);
     static void DispatchTouchInput(mozilla::MultiTouchInput& aInput);
 
+    using nsBaseWidget::Create; // for Create signature not overridden here
     NS_IMETHOD Create(nsIWidget* aParent,
                       void* aNativeParent,
                       const LayoutDeviceIntRect& aRect,
-                      nsWidgetInitData* aInitData);
+                      nsWidgetInitData* aInitData) override;
     NS_IMETHOD Destroy(void);
 
     NS_IMETHOD Show(bool aState);
     virtual bool IsVisible() const;
     NS_IMETHOD ConstrainPosition(bool aAllowSlop,
                                  int32_t *aX,
                                  int32_t *aY);
     NS_IMETHOD Move(double aX,
--- a/widget/gtk/nsWindow.h
+++ b/widget/gtk/nsWindow.h
@@ -90,16 +90,17 @@ public:
     
     // called when we are destroyed
     virtual void OnDestroy(void) override;
 
     // called to check and see if a widget's dimensions are sane
     bool AreBoundsSane(void);
 
     // nsIWidget
+    using nsBaseWidget::Create; // for Create signature not overridden here
     NS_IMETHOD         Create(nsIWidget* aParent,
                               nsNativeWidget aNativeParent,
                               const LayoutDeviceIntRect& aRect,
                               nsWidgetInitData* aInitData) override;
     NS_IMETHOD         Destroy(void) override;
     virtual nsIWidget *GetParent() override;
     virtual float      GetDPI() override;
     virtual double     GetDefaultScaleInternal() override; 
--- a/widget/nsIWidget.h
+++ b/widget/nsIWidget.h
@@ -344,16 +344,17 @@ class nsIWidget : public nsISupports {
     typedef mozilla::widget::TextEventDispatcher TextEventDispatcher;
     typedef mozilla::CompositorVsyncDispatcher CompositorVsyncDispatcher;
     typedef mozilla::LayoutDeviceIntMargin LayoutDeviceIntMargin;
     typedef mozilla::LayoutDeviceIntPoint LayoutDeviceIntPoint;
     typedef mozilla::LayoutDeviceIntRect LayoutDeviceIntRect;
     typedef mozilla::LayoutDeviceIntRegion LayoutDeviceIntRegion;
     typedef mozilla::LayoutDeviceIntSize LayoutDeviceIntSize;
     typedef mozilla::ScreenIntPoint ScreenIntPoint;
+    typedef mozilla::DesktopIntRect DesktopIntRect;
 
     // Used in UpdateThemeGeometries.
     struct ThemeGeometry {
       // The ThemeGeometryType value for the themed widget, see
       // nsITheme::ThemeGeometryTypeForWidget.
       nsITheme::ThemeGeometryType mType;
       // The device-pixel rect within the window for the themed widget
       LayoutDeviceIntRect mRect;
@@ -394,30 +395,52 @@ class nsIWidget : public nsISupports {
      * calling code must handle paint messages and clear the background 
      * itself. 
      *
      * In practice at least one of aParent and aNativeParent will be null. If
      * both are null the widget isn't parented (e.g. context menus or
      * independent top level windows).
      *
      * The dimensions given in aRect are specified in the parent's
-     * coordinate system, or for parentless widgets such as top-level
-     * windows, in global CSS pixels.
+     * device coordinate system.
+     * This must not be called for parentless widgets such as top-level
+     * windows, which use the desktop pixel coordinate system; a separate
+     * method is provided for these.
      *
      * @param     aParent       parent nsIWidget
      * @param     aNativeParent native parent widget
      * @param     aRect         the widget dimension
      * @param     aInitData     data that is used for widget initialization
      *
      */
     NS_IMETHOD Create(nsIWidget* aParent,
                       nsNativeWidget aNativeParent,
                       const LayoutDeviceIntRect& aRect,
                       nsWidgetInitData* aInitData = nullptr) = 0;
 
+    /*
+     * As above, but with aRect specified in DesktopPixel units (for top-level
+     * widgets).
+     * Default implementation just converts aRect to device pixels and calls
+     * through to device-pixel Create, but platforms may override this if the
+     * mapping is not straightforward or the native platform needs to use the
+     * desktop pixel values directly.
+     */
+    NS_IMETHOD Create(nsIWidget* aParent,
+                      nsNativeWidget aNativeParent,
+                      const DesktopIntRect& aRect,
+                      nsWidgetInitData* aInitData = nullptr)
+    {
+        // GetDefaultScaleInternal() here is a placeholder, to be replaced by
+        // GetDesktopToDeviceScale in a later patch
+        mozilla::DesktopToLayoutDeviceScale scale(GetDefaultScaleInternal());
+        LayoutDeviceIntRect devPixRect = RoundedToInt(aRect * scale);
+        return Create(aParent, aNativeParent, devPixRect, aInitData);
+    }
+
     /**
      * Allocate, initialize, and return a widget that is a child of
      * |this|.  The returned widget (if nonnull) has gone through the
      * equivalent of CreateInstance(widgetCID) + Create(...).
      *
      * |CreateChild()| lets widget backends decide whether to parent
      * the new child widget to this, nonnatively parent it, or both.
      * This interface exists to support the PuppetWidget backend,
--- a/widget/windows/nsWindow.h
+++ b/widget/windows/nsWindow.h
@@ -90,16 +90,17 @@ public:
   virtual bool DispatchWheelEvent(mozilla::WidgetWheelEvent* aEvent) override;
   virtual bool DispatchContentCommandEvent(mozilla::WidgetContentCommandEvent* aEvent) override;
   virtual nsWindowBase* GetParentWindowBase(bool aIncludeOwner) override;
   virtual bool IsTopLevelWidget() override { return mIsTopWidgetWindow; }
 
   using nsWindowBase::DispatchPluginEvent;
 
   // nsIWidget interface
+  using nsWindowBase::Create; // for Create signature not overridden here
   NS_IMETHOD              Create(nsIWidget* aParent,
                                  nsNativeWidget aNativeParent,
                                  const LayoutDeviceIntRect& aRect,
                                  nsWidgetInitData* aInitData = nullptr) override;
   NS_IMETHOD              Destroy() override;
   NS_IMETHOD              SetParent(nsIWidget *aNewParent) override;
   virtual nsIWidget*      GetParent(void) override;
   virtual float           GetDPI() override;
--- a/xpfe/appshell/nsWebShellWindow.cpp
+++ b/xpfe/appshell/nsWebShellWindow.cpp
@@ -140,17 +140,17 @@ nsresult nsWebShellWindow::Initialize(ns
       initialX = mOpenerScreenRect.x;
       initialY = mOpenerScreenRect.y;
       ConstrainToOpenerScreen(&initialX, &initialY);
     }
   }
 
   // XXX: need to get the default window size from prefs...
   // Doesn't come from prefs... will come from CSS/XUL/RDF
-  LayoutDeviceIntRect r(initialX, initialY, aInitialWidth, aInitialHeight);
+  DesktopIntRect deskRect(initialX, initialY, aInitialWidth, aInitialHeight);
 
   // Create top level window
   mWindow = do_CreateInstance(kWindowCID, &rv);
   if (NS_OK != rv) {
     return rv;
   }
 
   /* This next bit is troublesome. We carry two different versions of a pointer
@@ -168,18 +168,20 @@ nsresult nsWebShellWindow::Initialize(ns
   if (parentAsWin) {
     parentAsWin->GetMainWidget(getter_AddRefs(parentWidget));
     mParentWindow = do_GetWeakReference(aParent);
   }
 
   mWindow->SetWidgetListener(this);
   mWindow->Create((nsIWidget *)parentWidget,          // Parent nsIWidget
                   nullptr,                            // Native parent widget
-                  r,                                  // Widget dimensions
+                  deskRect,                           // Widget dimensions
                   &widgetInitData);                   // Widget initialization data
+
+  LayoutDeviceIntRect r;
   mWindow->GetClientBounds(r);
   // Match the default background color of content. Important on windows
   // since we no longer use content child widgets.
   mWindow->SetBackgroundColor(NS_RGB(255,255,255));
 
   // Create web shell
   mDocShell = do_CreateInstance("@mozilla.org/docshell;1");
   NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE);