bug 821679 - handle display-to-device pixel scaling of mouse-click position when creating drag image. r=roc

This commit is contained in:
Jonathan Kew 2012-12-14 20:25:51 +00:00
parent 57c363c76d
commit 32056fc79c
3 changed files with 22 additions and 14 deletions

View File

@ -140,19 +140,19 @@ nsDragService::ConstructDragImage(nsIDOMNode* aDOMNode,
screenPoint.y = nsCocoaUtils::FlippedScreenY(screenPoint.y);
CGFloat scaleFactor = nsCocoaUtils::GetBackingScaleFactor(gLastDragView);
nsIntPoint pt =
nsCocoaUtils::CocoaPointsToDevPixels(NSMakePoint(screenPoint.x,
screenPoint.y),
scaleFactor);
nsRefPtr<gfxASurface> surface;
nsPresContext* pc;
nsresult rv = DrawDrag(aDOMNode, aRegion, pt.x, pt.y,
nsresult rv = DrawDrag(aDOMNode, aRegion,
NSToIntRound(screenPoint.x),
NSToIntRound(screenPoint.y),
aDragRect, getter_AddRefs(surface), &pc);
if (!aDragRect->width || !aDragRect->height) {
// just use some suitable defaults
int32_t size = nsCocoaUtils::CocoaPointsToDevPixels(20, scaleFactor);
aDragRect->SetRect(pt.x, pt.y, size, size);
aDragRect->SetRect(nsCocoaUtils::CocoaPointsToDevPixels(screenPoint.x, scaleFactor),
nsCocoaUtils::CocoaPointsToDevPixels(screenPoint.y, scaleFactor),
size, size);
}
if (NS_FAILED(rv) || !surface)

View File

@ -450,6 +450,13 @@ nsBaseDragService::DrawDrag(nsIDOMNode* aDOMNode,
*aPresContext = presShell->GetPresContext();
// convert mouse position to dev pixels of the prescontext
int32_t sx = aScreenX, sy = aScreenY;
ConvertToUnscaledDevPixels(*aPresContext, &sx, &sy);
aScreenDragRect->x = sx - mImageX;
aScreenDragRect->y = sy - mImageY;
// check if drag images are disabled
bool enableDragImages = Preferences::GetBool(DRAGIMAGES_PREF, true);
@ -501,15 +508,15 @@ nsBaseDragService::DrawDrag(nsIDOMNode* aDOMNode,
if (mImage) {
nsCOMPtr<nsICanvasElementExternal> canvas = do_QueryInterface(dragNode);
if (canvas) {
return DrawDragForImage(*aPresContext, nullptr, canvas, aScreenX,
aScreenY, aScreenDragRect, aSurface);
return DrawDragForImage(*aPresContext, nullptr, canvas, sx, sy,
aScreenDragRect, aSurface);
}
nsCOMPtr<nsIImageLoadingContent> imageLoader = do_QueryInterface(dragNode);
// for image nodes, create the drag image from the actual image data
if (imageLoader) {
return DrawDragForImage(*aPresContext, imageLoader, nullptr, aScreenX,
aScreenY, aScreenDragRect, aSurface);
return DrawDragForImage(*aPresContext, imageLoader, nullptr, sx, sy,
aScreenDragRect, aSurface);
}
// If the image is a popup, use that as the image. This allows custom drag
@ -540,8 +547,8 @@ nsBaseDragService::DrawDrag(nsIDOMNode* aDOMNode,
// if an image was specified, reposition the drag rectangle to
// the supplied offset in mImageX and mImageY.
if (mImage) {
aScreenDragRect->x = aScreenX - mImageX;
aScreenDragRect->y = aScreenY - mImageY;
aScreenDragRect->x = sx - mImageX;
aScreenDragRect->y = sy - mImageY;
}
*aSurface = surface;

View File

@ -61,11 +61,12 @@ protected:
* that are relative to the upper-left corner of the window.
*
* aScreenX and aScreenY should be the screen coordinates of the mouse click
* for the drag.
* for the drag. These are in global display pixels.
*
* On return, aScreenDragRect will contain the screen coordinates of the
* area being dragged. This is used by the platform-specific part of the
* drag service to determine the drag feedback.
* drag service to determine the drag feedback. This rect will be in the
* device pixels of the presContext.
*
* If there is no drag image, the returned surface will be null, but
* aScreenDragRect will still be set to the drag area.