Bug 1288760 - Fix point conversion in nsDragService::StartInvokingDragSession. r=jfkthame

MozReview-Commit-ID: DgNtnsvEPnR

--HG--
extra : rebase_source : 0c2c077cd36047bdce5f74b6a4672682e8120073
This commit is contained in:
Masatoshi Kimura 2016-07-28 19:57:28 +09:00
Родитель da1ba5c6ef
Коммит 0ce2b1771e
1 изменённых файлов: 51 добавлений и 6 удалений

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

@ -26,6 +26,7 @@
#include "nsString.h"
#include "nsEscape.h"
#include "nsIScreenManager.h"
#include "nsISupportsPrimitives.h"
#include "nsIURL.h"
#include "nsCWebBrowserPersist.h"
@ -252,6 +253,40 @@ nsDragService::InvokeDragSessionImpl(nsISupportsArray* anArrayTransferables,
return StartInvokingDragSession(itemToDrag, aActionType);
}
static bool
LayoutDevicePointToCSSPoint(const LayoutDevicePoint& aDevPos,
CSSPoint& aCSSPos)
{
nsCOMPtr<nsIScreenManager> screenMgr =
do_GetService("@mozilla.org/gfx/screenmanager;1");
if (!screenMgr) {
return false;
}
nsCOMPtr<nsIScreen> screen;
screenMgr->ScreenForRect(NSToIntRound(aDevPos.x), NSToIntRound(aDevPos.y),
1, 1, getter_AddRefs(screen));
if (!screen) {
return false;
}
int32_t w,h; // unused
LayoutDeviceIntPoint screenOriginDev;
screen->GetRect(&screenOriginDev.x, &screenOriginDev.y, &w, &h);
double scale;
screen->GetDefaultCSSScaleFactor(&scale);
LayoutDeviceToCSSScale devToCSSScale =
CSSToLayoutDeviceScale(scale).Inverse();
// Desktop pixels and CSS pixels share the same screen origin.
CSSIntPoint screenOriginCSS;
screen->GetRectDisplayPix(&screenOriginCSS.x, &screenOriginCSS.y, &w, &h);
aCSSPos = (aDevPos - screenOriginDev) * devToCSSScale + screenOriginCSS;
return true;
}
//-------------------------------------------------------------------------
NS_IMETHODIMP
nsDragService::StartInvokingDragSession(IDataObject * aDataObj,
@ -326,12 +361,22 @@ nsDragService::StartInvokingDragSession(IDataObject * aDataObj,
// Note that we must convert this from device pixels back to Windows logical
// pixels (bug 818927).
DWORD pos = ::GetMessagePos();
POINT pt = { GET_X_LPARAM(pos), GET_Y_LPARAM(pos) };
HMONITOR monitor = ::MonitorFromPoint(pt, MONITOR_DEFAULTTOPRIMARY);
double dpiScale = widget::WinUtils::LogToPhysFactor(monitor);
nsIntPoint logPos(NSToIntRound(GET_X_LPARAM(pos) / dpiScale),
NSToIntRound(GET_Y_LPARAM(pos) / dpiScale));
SetDragEndPoint(logPos);
CSSPoint cssPos;
if (!LayoutDevicePointToCSSPoint(LayoutDevicePoint(GET_X_LPARAM(pos),
GET_Y_LPARAM(pos)),
cssPos)) {
// fallback to the simple scaling
POINT pt = { GET_X_LPARAM(pos), GET_Y_LPARAM(pos) };
HMONITOR monitor = ::MonitorFromPoint(pt, MONITOR_DEFAULTTOPRIMARY);
double dpiScale = widget::WinUtils::LogToPhysFactor(monitor);
cssPos.x = GET_X_LPARAM(pos) / dpiScale;
cssPos.y = GET_Y_LPARAM(pos) / dpiScale;
}
// We have to abuse SetDragEndPoint to pass CSS pixels because
// Event::GetScreenCoords will not convert pixels for dragend events
// until bug 1224754 is fixed.
SetDragEndPoint(LayoutDeviceIntPoint(NSToIntRound(cssPos.x),
NSToIntRound(cssPos.y)));
EndDragSession(true);
mDoingDrag = false;