diff --git a/widget/windows/nsScreenManagerWin.cpp b/widget/windows/nsScreenManagerWin.cpp index 67bd7a03527d..3e2319ff319f 100644 --- a/widget/windows/nsScreenManagerWin.cpp +++ b/widget/windows/nsScreenManagerWin.cpp @@ -5,6 +5,7 @@ #include "nsScreenManagerWin.h" #include "nsScreenWin.h" +#include "gfxWindowsPlatform.h" BOOL CALLBACK CountMonitors ( HMONITOR, HDC, LPRECT, LPARAM ioCount ) ; @@ -64,7 +65,7 @@ nsScreenManagerWin :: CreateNewScreenObject ( HMONITOR inScreen ) // Returns the screen that contains the rectangle. If the rect overlaps // multiple screens, it picks the screen with the greatest area of intersection. // -// The coordinates are in pixels (not twips) and in screen coordinates. +// The coordinates are in pixels (not twips) and in logical screen coordinates. // NS_IMETHODIMP nsScreenManagerWin :: ScreenForRect ( int32_t inLeft, int32_t inTop, int32_t inWidth, int32_t inHeight, @@ -76,7 +77,14 @@ nsScreenManagerWin :: ScreenForRect ( int32_t inLeft, int32_t inTop, int32_t inW return NS_OK; } - RECT globalWindowBounds = { inLeft, inTop, inLeft + inWidth, inTop + inHeight }; + // convert coordinates from logical to device pixels for MonitorFromRect + FLOAT dpiScale = gfxWindowsPlatform::GetPlatform()->GetDPIScale(); + RECT globalWindowBounds = { + NSToIntRound(dpiScale * inLeft), + NSToIntRound(dpiScale * inTop), + NSToIntRound(dpiScale * (inLeft + inWidth)), + NSToIntRound(dpiScale * (inTop + inHeight)) + }; HMONITOR genScreen = ::MonitorFromRect( &globalWindowBounds, MONITOR_DEFAULTTOPRIMARY ); diff --git a/widget/windows/nsWindow.cpp b/widget/windows/nsWindow.cpp index 132d7d21e8ab..09d64b8f5678 100644 --- a/widget/windows/nsWindow.cpp +++ b/widget/windows/nsWindow.cpp @@ -1624,12 +1624,19 @@ NS_IMETHODIMP nsWindow::SetSizeMode(int32_t aMode) { } // Constrain a potential move to fit onscreen +// Position (aX, aY) is specified in Windows screen (logical) pixels NS_METHOD nsWindow::ConstrainPosition(bool aAllowSlop, int32_t *aX, int32_t *aY) { if (!mIsTopWidgetWindow) // only a problem for top-level windows return NS_OK; + float dpiScale = gfxWindowsPlatform::GetPlatform()->GetDPIScale(); + + // we need to use the window size in logical screen pixels + int32_t logWidth = std::max(NSToIntRound(mBounds.width / dpiScale), 1); + int32_t logHeight = std::max(NSToIntRound(mBounds.height / dpiScale), 1); + bool doConstrain = false; // whether we have enough info to do anything /* get our playing field. use the current screen, or failing that @@ -1641,23 +1648,20 @@ NS_METHOD nsWindow::ConstrainPosition(bool aAllowSlop, nsCOMPtr screen; int32_t left, top, width, height; - // zero size rects confuse the screen manager - width = mBounds.width > 0 ? mBounds.width : 1; - height = mBounds.height > 0 ? mBounds.height : 1; - screenmgr->ScreenForRect(*aX, *aY, width, height, + screenmgr->ScreenForRect(*aX, *aY, logWidth, logHeight, getter_AddRefs(screen)); if (screen) { if (mSizeMode != nsSizeMode_Fullscreen) { // For normalized windows, use the desktop work area. - screen->GetAvailRect(&left, &top, &width, &height); + screen->GetAvailRectDisplayPix(&left, &top, &width, &height); } else { // For full screen windows, use the desktop. - screen->GetRect(&left, &top, &width, &height); + screen->GetRectDisplayPix(&left, &top, &width, &height); } screenRect.left = left; - screenRect.right = left+width; + screenRect.right = left + width; screenRect.top = top; - screenRect.bottom = top+height; + screenRect.bottom = top + height; doConstrain = true; } } else { @@ -1680,13 +1684,13 @@ NS_METHOD nsWindow::ConstrainPosition(bool aAllowSlop, } if (aAllowSlop) { - if (*aX < screenRect.left - mBounds.width + kWindowPositionSlop) - *aX = screenRect.left - mBounds.width + kWindowPositionSlop; + if (*aX < screenRect.left - logWidth + kWindowPositionSlop) + *aX = screenRect.left - logWidth + kWindowPositionSlop; else if (*aX >= screenRect.right - kWindowPositionSlop) *aX = screenRect.right - kWindowPositionSlop; - if (*aY < screenRect.top - mBounds.height + kWindowPositionSlop) - *aY = screenRect.top - mBounds.height + kWindowPositionSlop; + if (*aY < screenRect.top - logHeight + kWindowPositionSlop) + *aY = screenRect.top - logHeight + kWindowPositionSlop; else if (*aY >= screenRect.bottom - kWindowPositionSlop) *aY = screenRect.bottom - kWindowPositionSlop; @@ -1694,13 +1698,13 @@ NS_METHOD nsWindow::ConstrainPosition(bool aAllowSlop, if (*aX < screenRect.left) *aX = screenRect.left; - else if (*aX >= screenRect.right - mBounds.width) - *aX = screenRect.right - mBounds.width; + else if (*aX >= screenRect.right - logWidth) + *aX = screenRect.right - logWidth; if (*aY < screenRect.top) *aY = screenRect.top; - else if (*aY >= screenRect.bottom - mBounds.height) - *aY = screenRect.bottom - mBounds.height; + else if (*aY >= screenRect.bottom - logHeight) + *aY = screenRect.bottom - logHeight; } return NS_OK;