diff options
author | Friedemann Kleint <Friedemann.Kleint@qt.io> | 2023-11-16 10:50:30 +0100 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2023-11-20 22:03:10 +0000 |
commit | b639e73cc113df71fb579c41e6cfabe8c29b6f09 (patch) | |
tree | 91bc0d74b6f1b6ca7b9dd488489703666a0b4279 | |
parent | dcec70a7c09bb87de5a86f5ccf79cc252466b7ac (diff) |
pixeltool: Fix black display when grabbing other screens
- Pass a position relative to the screen origin for grabbing.
- Scale the grabbed pixmap such that it can be rendered
with the DPR of the widget.
Pick-to: 6.5
Change-Id: Iaecfc1cccb2f4b18067370bdedcefdc5a0fcf557
Reviewed-by: Jøger Hansegård <joger.hansegard@qt.io>
Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
(cherry picked from commit eb672bc3f1b99ca4a19237de28ea72f33514e7f1)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r-- | src/pixeltool/qpixeltool.cpp | 45 |
1 files changed, 23 insertions, 22 deletions
diff --git a/src/pixeltool/qpixeltool.cpp b/src/pixeltool/qpixeltool.cpp index b75790b0f..e15e9b9cd 100644 --- a/src/pixeltool/qpixeltool.cpp +++ b/src/pixeltool/qpixeltool.cpp @@ -26,6 +26,8 @@ #include <qdebug.h> +#include <cmath> + QT_BEGIN_NAMESPACE using namespace Qt::StringLiterals; @@ -471,12 +473,10 @@ QSize QPixelTool::sizeHint() const return m_initialSize; } -static inline QString pixelToolTitle(QPoint pos, const QColor ¤tColor) +static inline QString pixelToolTitle(QPoint pos, const QScreen *screen, const QColor ¤tColor) { - if (QHighDpiScaling::isActive()) { - if (auto screen = QGuiApplication::screenAt(pos)) - pos = QHighDpi::toNativePixels(pos, screen); - } + if (screen != nullptr) + pos = QHighDpi::toNativePixels(pos, screen); return QCoreApplication::applicationName() + QLatin1String(" [") + QString::number(pos.x()) + QLatin1String(", ") + QString::number(pos.y()) + QLatin1String("] ") @@ -497,37 +497,38 @@ void QPixelTool::grabScreen() if (mousePos == m_lastMousePos && !m_autoUpdate) return; - if (m_lastMousePos != mousePos) - setWindowTitle(pixelToolTitle(mousePos, m_currentColor)); - - int w = int(width() / float(m_zoom)); - int h = int(height() / float(m_zoom)); + QScreen *screen = QGuiApplication::screenAt(mousePos); - if (width() % m_zoom > 0) - ++w; - if (height() % m_zoom > 0) - ++h; + if (m_lastMousePos != mousePos) + setWindowTitle(pixelToolTitle(mousePos, screen, m_currentColor)); - int x = mousePos.x() - w/2; - int y = mousePos.y() - h/2; + const auto widgetDpr = devicePixelRatioF(); + const auto screenDpr = screen != nullptr ? screen->devicePixelRatio() : widgetDpr; + // When grabbing from another screen, we grab an area fitting our size using our DPR. + const auto factor = widgetDpr / screenDpr / qreal(m_zoom); + const QSize size{int(std::ceil(width() * factor)), int(std::ceil(height() * factor))}; + const QPoint pos = mousePos - QPoint{size.width(), size.height()} / 2; const QBrush darkBrush = palette().color(QPalette::Dark); - if (QScreen *screen = this->screen()) { - m_buffer = screen->grabWindow(0, x, y, w, h); + if (screen != nullptr) { + const QPoint screenPos = pos - screen->geometry().topLeft(); + m_buffer = screen->grabWindow(0, screenPos.x(), screenPos.y(), size.width(), size.height()); } else { - m_buffer = QPixmap(w, h); + m_buffer = QPixmap(size); m_buffer.fill(darkBrush.color()); } - QRegion geom(x, y, w, h); + m_buffer.setDevicePixelRatio(widgetDpr); + + QRegion geom(QRect{pos, size}); QRect screenRect; const auto screens = QGuiApplication::screens(); for (auto screen : screens) screenRect |= screen->geometry(); geom -= screenRect; const auto rectsInRegion = geom.rectCount(); - if (rectsInRegion > 0) { + if (!geom.isEmpty()) { QPainter p(&m_buffer); - p.translate(-x, -y); + p.translate(-pos); p.setPen(Qt::NoPen); p.setBrush(darkBrush); p.drawRects(geom.begin(), rectsInRegion); |