From 234ad2222c97334ffa284b59e2ea2d00e1cb4adf Mon Sep 17 00:00:00 2001 From: Bogdan Mart Date: Thu, 2 Jan 2020 00:33:06 +0200 Subject: [PATCH 1/3] Fix UI scaling issue in Plasma DE Fixes for issues lupoDharkael/flameshot#564 , lupoDharkael/flameshot#265 and lupoDharkael/flameshot#650 need to be tested. Possibly also works for lupoDharkael/flameshot#227 I don't know how to reproduce mixed DPI screen. --- src/widgets/capture/capturewidget.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/widgets/capture/capturewidget.cpp b/src/widgets/capture/capturewidget.cpp index 1db615bb6f..9db1a89f4f 100644 --- a/src/widgets/capture/capturewidget.cpp +++ b/src/widgets/capture/capturewidget.cpp @@ -894,7 +894,9 @@ QRect CaptureWidget::extendedSelection() const { } QRect CaptureWidget::extendedRect(QRect *r) const { - auto devicePixelRatio = m_context.screenshot.devicePixelRatio(); + // We need to scale screen back so applying reverse scaling, + // Before fix code was multiplying + auto devicePixelRatio = qreal(1.0) / m_context.screenshot.devicePixelRatio(); return QRect(r->left() * devicePixelRatio, r->top() * devicePixelRatio, r->width() * devicePixelRatio, From f1fea79c96c62978b5369fd1798777a415321a49 Mon Sep 17 00:00:00 2001 From: Bogdan Mart Date: Thu, 2 Jan 2020 03:49:00 +0200 Subject: [PATCH 2/3] Real fix for scale ratio lupoDharkael/flameshot#678 We don't need to resize pixmap as it is rendered correctly with devicePixelRatio detected by QT. I took decision to inline setScaledPixmap as we do not need to mess around with image scale, and this scaling thing is crippling image pixels due to approximation. My first approach was to use `size() / scale` instead of `size()*scale` it actually worked, but was distorting pixels etc. This seems more clear solution. --- src/widgets/capture/capturewidget.cpp | 4 +--- src/widgets/imagelabel.cpp | 12 ++---------- src/widgets/imagelabel.h | 1 - 3 files changed, 3 insertions(+), 14 deletions(-) diff --git a/src/widgets/capture/capturewidget.cpp b/src/widgets/capture/capturewidget.cpp index 9db1a89f4f..1db615bb6f 100644 --- a/src/widgets/capture/capturewidget.cpp +++ b/src/widgets/capture/capturewidget.cpp @@ -894,9 +894,7 @@ QRect CaptureWidget::extendedSelection() const { } QRect CaptureWidget::extendedRect(QRect *r) const { - // We need to scale screen back so applying reverse scaling, - // Before fix code was multiplying - auto devicePixelRatio = qreal(1.0) / m_context.screenshot.devicePixelRatio(); + auto devicePixelRatio = m_context.screenshot.devicePixelRatio(); return QRect(r->left() * devicePixelRatio, r->top() * devicePixelRatio, r->width() * devicePixelRatio, diff --git a/src/widgets/imagelabel.cpp b/src/widgets/imagelabel.cpp index c64cead4b5..675b18829b 100644 --- a/src/widgets/imagelabel.cpp +++ b/src/widgets/imagelabel.cpp @@ -40,15 +40,7 @@ void ImageLabel::setScreenshot(const QPixmap &pixmap) { const QString tooltip = QStringLiteral("%1x%2 px").arg(m_pixmap.width()) .arg(m_pixmap.height()); setToolTip(tooltip); - setScaledPixmap(); -} - -void ImageLabel::setScaledPixmap() { - const qreal scale = qApp->devicePixelRatio(); - QPixmap scaledPixmap = m_pixmap.scaled(size() * scale, Qt::KeepAspectRatio, - Qt::SmoothTransformation); - scaledPixmap.setDevicePixelRatio(scale); - setPixmap(scaledPixmap); + setPixmap(m_pixmap); } // drag handlers @@ -82,5 +74,5 @@ void ImageLabel::mouseMoveEvent(QMouseEvent *event) { // resize handler void ImageLabel::resizeEvent(QResizeEvent *event) { Q_UNUSED(event); - setScaledPixmap(); + setPixmap(m_pixmap); } diff --git a/src/widgets/imagelabel.h b/src/widgets/imagelabel.h index 36983b67c7..be9f49e816 100644 --- a/src/widgets/imagelabel.h +++ b/src/widgets/imagelabel.h @@ -46,7 +46,6 @@ class ImageLabel : public QLabel { void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE; private: - void setScaledPixmap(); QGraphicsDropShadowEffect *m_DSEffect; QPixmap m_pixmap; From c3d0377a84facd2fa5741a03cf2264545605a261 Mon Sep 17 00:00:00 2001 From: Bogdan Mart Date: Fri, 3 Jan 2020 21:53:29 +0200 Subject: [PATCH 3/3] Second take to fix scaling problem lupoDharkael/flameshot#678 After receiving feedback from lupoDharkael/flameshot#227 Not sure about mixed DPI but for same scaling for all displays it works. Tested with different screens positioning on both sides of each other. --- src/widgets/capture/capturewidget.cpp | 34 ++++++++++++++++++++++++++- src/widgets/imagelabel.cpp | 15 ++++++++++-- src/widgets/imagelabel.h | 1 + 3 files changed, 47 insertions(+), 3 deletions(-) diff --git a/src/widgets/capture/capturewidget.cpp b/src/widgets/capture/capturewidget.cpp index 1db615bb6f..9790f2d498 100644 --- a/src/widgets/capture/capturewidget.cpp +++ b/src/widgets/capture/capturewidget.cpp @@ -102,20 +102,52 @@ CaptureWidget::CaptureWidget(const uint id, const QString &savePath, | Qt::FramelessWindowHint | Qt::Tool); #endif - resize(pixmap().size()); + auto ratio = pixmap().devicePixelRatio(); + auto oldSize = pixmap().size(); + auto newSize = oldSize / ratio; + resize(newSize); } // Create buttons m_buttonHandler = new ButtonHandler(this); updateButtons(); QVector areas; if (m_context.fullscreen) { +#ifdef Q_OS_LINUX + int xFixup = 0; +#endif for (QScreen *const screen : QGuiApplication::screens()) { QRect r = screen->geometry(); #ifdef Q_OS_WIN r.moveTo(r.topLeft() - topLeft); +#endif +#ifdef Q_OS_LINUX + // On Linux (confirmed on Xorg & kubuntu, not tested on wayland) + // Top left point is in device pixels, not scaled, + // but height+width is scaled to device independednt pixels + // this code performs fixup for top left point to device independent pixels! + + // this fixup helps for button location layout around selected area on multymonitor setups + + auto topLeft = r.topLeft(); + auto fixedTopLeft = topLeft / screen->devicePixelRatio(); + + if (topLeft.x() !=0 && topLeft != fixedTopLeft) { + // We need to fix x ccordinate and shift window left. + // Some wierd idiocity for multydisplay setups on Linux. + // not needed fot y, only for horizontal placement of monitors. + // https://github.com/lupoDharkael/flameshot/issues/227#issuecomment-570147808 + xFixup += topLeft.x() - fixedTopLeft.x(); + } + r.moveTo(fixedTopLeft); #endif areas.append(r); } +#ifdef Q_OS_LINUX + if (xFixup) { + move(xFixup, 0); + } +#endif + } else { areas.append(rect()); } diff --git a/src/widgets/imagelabel.cpp b/src/widgets/imagelabel.cpp index 675b18829b..489749717f 100644 --- a/src/widgets/imagelabel.cpp +++ b/src/widgets/imagelabel.cpp @@ -40,7 +40,18 @@ void ImageLabel::setScreenshot(const QPixmap &pixmap) { const QString tooltip = QStringLiteral("%1x%2 px").arg(m_pixmap.width()) .arg(m_pixmap.height()); setToolTip(tooltip); - setPixmap(m_pixmap); + setScaledPixmap(); +} + +void ImageLabel::setScaledPixmap() { + const qreal scale = qApp->devicePixelRatio(); + // divide it by scale so image would be normalized to screen + // if we bultiply we get image of double size (scale*scale) as captured image + // is pixels with scale applyed. + QPixmap scaledPixmap = m_pixmap.scaled(size() / scale, Qt::KeepAspectRatio, + Qt::SmoothTransformation); + scaledPixmap.setDevicePixelRatio(scale); + setPixmap(scaledPixmap); } // drag handlers @@ -74,5 +85,5 @@ void ImageLabel::mouseMoveEvent(QMouseEvent *event) { // resize handler void ImageLabel::resizeEvent(QResizeEvent *event) { Q_UNUSED(event); - setPixmap(m_pixmap); + setScaledPixmap(); } diff --git a/src/widgets/imagelabel.h b/src/widgets/imagelabel.h index be9f49e816..36983b67c7 100644 --- a/src/widgets/imagelabel.h +++ b/src/widgets/imagelabel.h @@ -46,6 +46,7 @@ class ImageLabel : public QLabel { void resizeEvent(QResizeEvent *event) Q_DECL_OVERRIDE; private: + void setScaledPixmap(); QGraphicsDropShadowEffect *m_DSEffect; QPixmap m_pixmap;