From 84b8c3a0a4f82d198157344e467ed8c00dbc7015 Mon Sep 17 00:00:00 2001 From: Jonathan Kew Date: Wed, 13 Jan 2016 07:32:55 +0000 Subject: [PATCH] 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 | 4 ++++ widget/PluginWidgetProxy.h | 1 + widget/PuppetWidget.h | 1 + widget/android/nsWindow.h | 1 + widget/cocoa/nsCocoaWindow.h | 5 ++++ widget/cocoa/nsCocoaWindow.mm | 38 +++++++++++++++++------------- widget/gonk/nsWindow.h | 3 ++- widget/gtk/nsWindow.h | 1 + widget/nsIWidget.h | 27 +++++++++++++++++++-- widget/windows/nsWindow.h | 1 + xpfe/appshell/nsWebShellWindow.cpp | 6 +++-- 11 files changed, 67 insertions(+), 21 deletions(-) diff --git a/gfx/tests/gtest/TestCompositor.cpp b/gfx/tests/gtest/TestCompositor.cpp index f5153f73c839..c39f65ce4a40 100644 --- a/gfx/tests/gtest/TestCompositor.cpp +++ b/gfx/tests/gtest/TestCompositor.cpp @@ -59,6 +59,10 @@ public: 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, diff --git a/widget/PluginWidgetProxy.h b/widget/PluginWidgetProxy.h index 0b6b5d304f91..bcac94c83860 100644 --- a/widget/PluginWidgetProxy.h +++ b/widget/PluginWidgetProxy.h @@ -34,6 +34,7 @@ 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; diff --git a/widget/PuppetWidget.h b/widget/PuppetWidget.h index 288941d8ac9f..6c9a5a5e0668 100644 --- a/widget/PuppetWidget.h +++ b/widget/PuppetWidget.h @@ -53,6 +53,7 @@ protected: public: NS_DECL_ISUPPORTS_INHERITED + using nsBaseWidget::Create; // for Create signature not overridden here NS_IMETHOD Create(nsIWidget* aParent, nsNativeWidget aNativeParent, const LayoutDeviceIntRect& aRect, diff --git a/widget/android/nsWindow.h b/widget/android/nsWindow.h index f04a13154aff..782baccd3869 100644 --- a/widget/android/nsWindow.h +++ b/widget/android/nsWindow.h @@ -77,6 +77,7 @@ public: // nsIWidget // + using nsBaseWidget::Create; // for Create signature not overridden here NS_IMETHOD Create(nsIWidget* aParent, nsNativeWidget aNativeParent, const LayoutDeviceIntRect& aRect, diff --git a/widget/cocoa/nsCocoaWindow.h b/widget/cocoa/nsCocoaWindow.h index 4b75ffac6890..f1c9227a5725 100644 --- a/widget/cocoa/nsCocoaWindow.h +++ b/widget/cocoa/nsCocoaWindow.h @@ -255,6 +255,11 @@ public: 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, diff --git a/widget/cocoa/nsCocoaWindow.mm b/widget/cocoa/nsCocoaWindow.mm index a7a1eb942afb..87dfe38df663 100644 --- a/widget/cocoa/nsCocoaWindow.mm +++ b/widget/cocoa/nsCocoaWindow.mm @@ -183,14 +183,14 @@ nsCocoaWindow::~nsCocoaWindow() // 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; @@ -206,7 +206,7 @@ FindTargetScreenForRect(const LayoutDeviceIntRect& aRect) // 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); @@ -252,7 +252,7 @@ static bool UseNativePopupWindows() // 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; @@ -261,7 +261,7 @@ nsresult nsCocoaWindow::Create(nsIWidget* aParent, // 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 @@ -291,12 +291,8 @@ 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 - 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; @@ -306,6 +302,16 @@ nsresult nsCocoaWindow::Create(nsIWidget* aParent, 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 || @@ -1535,9 +1541,9 @@ nsresult nsCocoaWindow::DoResize(double aX, double aY, 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 ? @@ -1682,7 +1688,7 @@ GetBackingScaleFactor(NSWindow* aWindow) // 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); } diff --git a/widget/gonk/nsWindow.h b/widget/gonk/nsWindow.h index 57c81a7c0b92..8ac865eba3b4 100644 --- a/widget/gonk/nsWindow.h +++ b/widget/gonk/nsWindow.h @@ -46,10 +46,11 @@ public: 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); diff --git a/widget/gtk/nsWindow.h b/widget/gtk/nsWindow.h index 663006ca5fcb..9db666549f62 100644 --- a/widget/gtk/nsWindow.h +++ b/widget/gtk/nsWindow.h @@ -95,6 +95,7 @@ public: bool AreBoundsSane(void); // nsIWidget + using nsBaseWidget::Create; // for Create signature not overridden here NS_IMETHOD Create(nsIWidget* aParent, nsNativeWidget aNativeParent, const LayoutDeviceIntRect& aRect, diff --git a/widget/nsIWidget.h b/widget/nsIWidget.h index 01f8e4b375c9..6377fb5d2e54 100644 --- a/widget/nsIWidget.h +++ b/widget/nsIWidget.h @@ -349,6 +349,7 @@ class nsIWidget : public nsISupports { typedef mozilla::LayoutDeviceIntRegion LayoutDeviceIntRegion; typedef mozilla::LayoutDeviceIntSize LayoutDeviceIntSize; typedef mozilla::ScreenIntPoint ScreenIntPoint; + typedef mozilla::DesktopIntRect DesktopIntRect; // Used in UpdateThemeGeometries. struct ThemeGeometry { @@ -399,8 +400,10 @@ class nsIWidget : public nsISupports { * 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 @@ -413,6 +416,26 @@ class nsIWidget : public nsISupports { 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 diff --git a/widget/windows/nsWindow.h b/widget/windows/nsWindow.h index 7d6ce5e90537..3c5ac56c6a0b 100644 --- a/widget/windows/nsWindow.h +++ b/widget/windows/nsWindow.h @@ -95,6 +95,7 @@ public: using nsWindowBase::DispatchPluginEvent; // nsIWidget interface + using nsWindowBase::Create; // for Create signature not overridden here NS_IMETHOD Create(nsIWidget* aParent, nsNativeWidget aNativeParent, const LayoutDeviceIntRect& aRect, diff --git a/xpfe/appshell/nsWebShellWindow.cpp b/xpfe/appshell/nsWebShellWindow.cpp index 424e5c9dd431..d51fe95eada7 100644 --- a/xpfe/appshell/nsWebShellWindow.cpp +++ b/xpfe/appshell/nsWebShellWindow.cpp @@ -145,7 +145,7 @@ nsresult nsWebShellWindow::Initialize(nsIXULWindow* aParent, // 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); @@ -173,8 +173,10 @@ nsresult nsWebShellWindow::Initialize(nsIXULWindow* 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.