From 2b88fab8c1a196c97851b81fd21e217f858028da Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Fri, 28 May 2021 17:33:26 +0300 Subject: [PATCH] effects/screenshot: Add support for HiDPI window screenshots In general, on Wayland, there is no such a thing as "window scale factor" because sub-surfaces can have different buffer scales. However, we know the scale factor of the output where the window is considered to be on. So we can use the screen's scale factor as the window's scale factor. In most cases, it will produce the correct result. --- src/effects/screenshot/screenshot.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/effects/screenshot/screenshot.cpp b/src/effects/screenshot/screenshot.cpp index ee6d985c5f..658b327640 100644 --- a/src/effects/screenshot/screenshot.cpp +++ b/src/effects/screenshot/screenshot.cpp @@ -239,14 +239,20 @@ void ScreenShotEffect::takeScreenShot(ScreenShotWindowData *screenshot) WindowPaintData d(window); QRect geometry = window->expandedGeometry(); + qreal devicePixelRatio = 1; if (window->hasDecoration() && !(screenshot->flags & ScreenShotIncludeDecoration)) { geometry = window->clientGeometry(); } + if (screenshot->flags & ScreenShotNativeResolution) { + if (const EffectScreen *screen = effects->findScreen(window->screen())) { + devicePixelRatio = screen->devicePixelRatio(); + } + } bool validTarget = true; QScopedPointer offscreenTexture; QScopedPointer target; if (effects->isOpenGLCompositing()) { - offscreenTexture.reset(new GLTexture(GL_RGBA8, geometry.size())); + offscreenTexture.reset(new GLTexture(GL_RGBA8, geometry.size() * devicePixelRatio)); offscreenTexture->setFilter(GL_LINEAR); offscreenTexture->setWrapMode(GL_CLAMP_TO_EDGE); target.reset(new GLRenderTarget(*offscreenTexture)); @@ -273,6 +279,7 @@ void ScreenShotEffect::takeScreenShot(ScreenShotWindowData *screenshot) // copy content from framebuffer into image img = QImage(offscreenTexture->size(), QImage::Format_ARGB32); + img.setDevicePixelRatio(devicePixelRatio); glReadnPixels(0, 0, img.width(), img.height(), GL_RGBA, GL_UNSIGNED_BYTE, img.sizeInBytes(), static_cast(img.bits())); GLRenderTarget::popRenderTarget();