bug 851952 - handle conversion between logical and device pixels in Windows screen-manager and window position-constraint code. r=jimm

This commit is contained in:
Jonathan Kew 2013-04-01 10:10:33 +01:00
Родитель 0f5958303f
Коммит 5aa31382f8
2 изменённых файлов: 30 добавлений и 18 удалений

Просмотреть файл

@ -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 );

Просмотреть файл

@ -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<int32_t>(NSToIntRound(mBounds.width / dpiScale), 1);
int32_t logHeight = std::max<int32_t>(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<nsIScreen> 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;