diff --git a/widget/cocoa/nsChildView.h b/widget/cocoa/nsChildView.h index 8f07c70ddae..4b175f6f98a 100644 --- a/widget/cocoa/nsChildView.h +++ b/widget/cocoa/nsChildView.h @@ -390,6 +390,10 @@ public: // pixels" and the Cocoa "points" coordinate system. CGFloat BackingScaleFactor() const; + mozilla::DesktopToLayoutDeviceScale GetDesktopToDeviceScale() final { + return mozilla::DesktopToLayoutDeviceScale(BackingScaleFactor()); + } + // Call if the window's backing scale factor changes - i.e., it is moved // between HiDPI and non-HiDPI screens void BackingScaleFactorChanged(); diff --git a/widget/cocoa/nsCocoaWindow.h b/widget/cocoa/nsCocoaWindow.h index f1c9227a572..9a4608d1b63 100644 --- a/widget/cocoa/nsCocoaWindow.h +++ b/widget/cocoa/nsCocoaWindow.h @@ -324,6 +324,10 @@ public: virtual double GetDefaultScaleInternal() override; virtual int32_t RoundsWidgetCoordinatesTo() override; + mozilla::DesktopToLayoutDeviceScale GetDesktopToDeviceScale() final { + return mozilla::DesktopToLayoutDeviceScale(BackingScaleFactor()); + } + NS_IMETHOD SetTitle(const nsAString& aTitle) override; NS_IMETHOD Invalidate(const LayoutDeviceIntRect& aRect) override; diff --git a/widget/cocoa/nsCocoaWindow.mm b/widget/cocoa/nsCocoaWindow.mm index 87dfe38df66..1fce279b21e 100644 --- a/widget/cocoa/nsCocoaWindow.mm +++ b/widget/cocoa/nsCocoaWindow.mm @@ -291,8 +291,9 @@ nsresult nsCocoaWindow::Create(nsIWidget* aParent, } // 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 - DesktopToLayoutDeviceScale scale(BackingScaleFactor()); - return CreatePopupContentView(RoundedToInt(newBounds * scale)); + LayoutDeviceIntRect devRect = + RoundedToInt(newBounds * GetDesktopToDeviceScale()); + return CreatePopupContentView(devRect); } mIsAnimationSuppressed = aInitData->mIsAnimationSuppressed; @@ -307,8 +308,8 @@ nsresult nsCocoaWindow::Create(nsIWidget* aParent, const LayoutDeviceIntRect& aRect, nsWidgetInitData* aInitData) { - DesktopToLayoutDeviceScale scale(GetDefaultScaleInternal()); - DesktopIntRect desktopRect = RoundedToInt(aRect / scale); + DesktopIntRect desktopRect = + RoundedToInt(aRect / GetDesktopToDeviceScale()); return Create(aParent, aNativeParent, desktopRect, aInitData); } diff --git a/widget/nsBaseWidget.cpp b/widget/nsBaseWidget.cpp index 8d03648e40a..b5963803c39 100644 --- a/widget/nsBaseWidget.cpp +++ b/widget/nsBaseWidget.cpp @@ -831,9 +831,9 @@ NS_IMETHODIMP nsBaseWidget::MakeFullScreen(bool aFullScreen, nsIScreen* aScreen) if (aFullScreen) { if (!mOriginalBounds) { - mOriginalBounds = new CSSIntRect(); + mOriginalBounds = new LayoutDeviceIntRect(); } - *mOriginalBounds = GetScaledScreenBounds(); + GetScreenBounds(*mOriginalBounds); // Move to top-left corner of screen and size to the screen dimensions nsCOMPtr screen = aScreen; @@ -847,8 +847,13 @@ NS_IMETHODIMP nsBaseWidget::MakeFullScreen(bool aFullScreen, nsIScreen* aScreen) } } } else if (mOriginalBounds) { - Resize(mOriginalBounds->x, mOriginalBounds->y, mOriginalBounds->width, - mOriginalBounds->height, true); + if (BoundsUseDesktopPixels()) { + DesktopRect deskRect = *mOriginalBounds / GetDesktopToDeviceScale(); + Resize(deskRect.x, deskRect.y, deskRect.width, deskRect.height, true); + } else { + Resize(mOriginalBounds->x, mOriginalBounds->y, mOriginalBounds->width, + mOriginalBounds->height, true); + } } return NS_OK; diff --git a/widget/nsBaseWidget.h b/widget/nsBaseWidget.h index 5fc502befa8..5461dc62cdc 100644 --- a/widget/nsBaseWidget.h +++ b/widget/nsBaseWidget.h @@ -186,6 +186,11 @@ public: bool BoundsUseDesktopPixels() const { return mWindowType <= eWindowType_popup; } + // Default implementation, to be overridden by platforms where desktop coords + // are virtualized and may not correspond to device pixels on the screen. + mozilla::DesktopToLayoutDeviceScale GetDesktopToDeviceScale() override { + return mozilla::DesktopToLayoutDeviceScale(1.0); + } NS_IMETHOD MoveClient(double aX, double aY) override; NS_IMETHOD ResizeClient(double aWidth, double aHeight, bool aRepaint) override; NS_IMETHOD ResizeClient(double aX, double aY, double aWidth, double aHeight, bool aRepaint) override; @@ -514,7 +519,7 @@ protected: nsCursor mCursor; nsBorderStyle mBorderStyle; nsIntRect mBounds; - CSSIntRect* mOriginalBounds; + LayoutDeviceIntRect* mOriginalBounds; // When this pointer is null, the widget is not clipped mozilla::UniquePtr mClipRects; uint32_t mClipRectCount; diff --git a/widget/nsIWidget.h b/widget/nsIWidget.h index 6377fb5d2e5..b2da2ade51b 100644 --- a/widget/nsIWidget.h +++ b/widget/nsIWidget.h @@ -429,10 +429,8 @@ class nsIWidget : public nsISupports { 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); + LayoutDeviceIntRect devPixRect = + RoundedToInt(aRect * GetDesktopToDeviceScale()); return Create(aParent, aNativeParent, devPixRect, aInitData); } @@ -546,6 +544,13 @@ class nsIWidget : public nsISupports { */ virtual float GetDPI() = 0; + /** + * Return the scaling factor between device pixels and the platform- + * dependent "desktop pixels" used to manage window positions on a + * potentially multi-screen, mixed-resolution desktop. + */ + virtual mozilla::DesktopToLayoutDeviceScale GetDesktopToDeviceScale() = 0; + /** * Returns the CompositorVsyncDispatcher associated with this widget */ @@ -858,7 +863,7 @@ class nsIWidget : public nsISupports { NS_IMETHOD GetBounds(LayoutDeviceIntRect& aRect) = 0; /** - * Get this widget's outside dimensions in global coordinates. This + * Get this widget's outside dimensions in device coordinates. This * includes any title bar on the window. * * @param aRect On return it holds the x, y, width and height of @@ -878,7 +883,7 @@ class nsIWidget : public nsISupports { * @param aRect On return it holds the x, y, width and height of * this widget. */ - NS_IMETHOD GetRestoredBounds(mozilla::LayoutDeviceIntRect& aRect) = 0; + NS_IMETHOD GetRestoredBounds(LayoutDeviceIntRect& aRect) = 0; /** * Get this widget's client area bounds, if the window has a 3D border @@ -889,7 +894,7 @@ class nsIWidget : public nsISupports { * @param aRect On return it holds the x. y, width and height of * the client area of this widget. */ - NS_IMETHOD GetClientBounds(mozilla::LayoutDeviceIntRect& aRect) = 0; + NS_IMETHOD GetClientBounds(LayoutDeviceIntRect& aRect) = 0; /** * Get the non-client area dimensions of the window.