summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Marcos Oltra <pablo.marcos.oltra@gmail.com>2018-02-21 19:44:34 +0100
committerPablo Marcos Oltra <pablo.marcos.oltra@gmail.com>2018-02-22 10:28:08 +0000
commit17b73b0d2b8e0d643bdf13b543cc23d657a4b330 (patch)
tree45cb9c0ee778150208b496b5e031db98bc627b2f
parent8ef9a0ae8968036e92f47e9e7c0e271f9fecaceb (diff)
Cocoa: fix grabWindow when mixing highDPI and non-highDPI screens
CGDisplayCreateImageForRect seems to have a weird behavior when mixing highDPI and non-highDPI screens since it may take part of the non-highDPI screen when the highDPI display is at the left or at the top of the main monitor. To workaround this issue, we capture the whole screen and then crop the image to the desired size. Task-number: QTBUG-47643 Change-Id: Ib2a3850a0a549964c7fe272abb563bd23518c234 Reviewed-by: Morten Johan Sørvig <morten.sorvig@qt.io>
-rw-r--r--src/plugins/platforms/cocoa/qcocoascreen.mm29
1 files changed, 16 insertions, 13 deletions
diff --git a/src/plugins/platforms/cocoa/qcocoascreen.mm b/src/plugins/platforms/cocoa/qcocoascreen.mm
index ed1b19cd53..a17a02b629 100644
--- a/src/plugins/platforms/cocoa/qcocoascreen.mm
+++ b/src/plugins/platforms/cocoa/qcocoascreen.mm
@@ -233,25 +233,28 @@ QPixmap QCocoaScreen::grabWindow(WId window, int x, int y, int width, int height
windowSize.setHeight(windowRect.height());
}
- QPixmap windowPixmap(windowSize * devicePixelRatio());
+ const qreal dpr = devicePixelRatio();
+ QPixmap windowPixmap(windowSize * dpr);
windowPixmap.fill(Qt::transparent);
for (uint i = 0; i < displayCount; ++i) {
const CGRect bounds = CGDisplayBounds(displays[i]);
- int w = (width < 0 ? bounds.size.width : width) * devicePixelRatio();
- int h = (height < 0 ? bounds.size.height : height) * devicePixelRatio();
- QRect displayRect = QRect(x, y, w, h);
- displayRect = displayRect.translated(qRound(-bounds.origin.x), qRound(-bounds.origin.y));
- QCFType<CGImageRef> image = CGDisplayCreateImageForRect(displays[i],
- CGRectMake(displayRect.x(), displayRect.y(), displayRect.width(), displayRect.height()));
- QPixmap pix(w, h);
- pix.fill(Qt::transparent);
- CGRect rect = CGRectMake(0, 0, w, h);
- QMacCGContext ctx(&pix);
- qt_mac_drawCGImage(ctx, &rect, image);
+ // Calculate the position and size of the requested area
+ QPoint pos(qAbs(bounds.origin.x - x), qAbs(bounds.origin.y - y));
+ QSize size(qMin(pos.x() + width, qRound(bounds.size.width)),
+ qMin(pos.y() + height, qRound(bounds.size.height)));
+ pos *= dpr;
+ size *= dpr;
+
+ // Take the whole screen and crop it afterwards, because CGDisplayCreateImageForRect
+ // has a strange behavior when mixing highDPI and non-highDPI displays
+ QCFType<CGImageRef> cgImage = CGDisplayCreateImage(displays[i]);
+ const QImage image = qt_mac_toQImage(cgImage);
+
+ // Draw into windowPixmap only the requested size
QPainter painter(&windowPixmap);
- painter.drawPixmap(0, 0, pix);
+ painter.drawImage(windowPixmap.rect(), image, QRect(pos, size));
}
return windowPixmap;
}