You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
pcmanfm-qt-packaging/debian/patches/scaling-pr-1596.patch

216 lines
12 KiB

From c84434e576ec37208237f143ad5ef8f37ce25a24 Mon Sep 17 00:00:00 2001
From: tsujan <tsujan2000@gmail.com>
Date: Fri, 3 Jun 2022 05:16:58 +0430
Subject: [PATCH] Consider device pixel ratio when drawing wallpaper (#1596)
Previously, wallpapers weren't sharp with scale factors > 1.
Also, an old problem is fixed in centering per-screen wallpapers with multi-screen setups. Previously, if the centered wallpaper was smaller than the screen size, the dektop background color would be removed from the screen part to its right and bottom.
Fixes https://github.com/lxqt/pcmanfm-qt/issues/1595
---
pcmanfm/desktopwindow.cpp | 93 ++++++++++++++++++++++++---------------
1 file changed, 58 insertions(+), 35 deletions(-)
diff --git a/pcmanfm/desktopwindow.cpp b/pcmanfm/desktopwindow.cpp
index b0734582..d69b660e 100644
--- a/pcmanfm/desktopwindow.cpp
+++ b/pcmanfm/desktopwindow.cpp
@@ -644,88 +644,107 @@ QImage DesktopWindow::loadWallpaperFile(QSize requiredSize) {
// really generate the background pixmap according to current settings and apply it.
void DesktopWindow::updateWallpaper() {
if(wallpaperMode_ != WallpaperNone) { // use wallpaper
+ auto screen = getDesktopScreen();
+ if(screen == nullptr) {
+ return;
+ }
QPixmap pixmap;
QImage image;
Settings& settings = static_cast<Application* >(qApp)->settings();
- auto screen = getDesktopScreen();
- bool perScreenWallpaper(screen != nullptr && screen->virtualSiblings().size() > 1 && settings.perScreenWallpaper());
+ const auto screens = screen->virtualSiblings();
+ bool perScreenWallpaper(screens.size() > 1 && settings.perScreenWallpaper());
+
+ // the pixmap's size should be calculated by considering
+ // the positions and device pixel ratios of all screens
+ QRect pixmapRect;
+ for(const auto& scr : screens) {
+ pixmapRect |= QRect(scr->geometry().topLeft(), scr->size() * scr->devicePixelRatio());
+ }
+ const QSize pixmapSize = pixmapRect.size();
+
+ // the pixmap's device pixel ratio
+ qreal DPRatio = windowHandle() ? windowHandle()->devicePixelRatio() : qApp->devicePixelRatio();
+
if(wallpaperMode_ == WallpaperTile) { // use the original size
image = getWallpaperImage();
if(!image.isNull()) {
// Note: We can't use the QPainter::drawTiledPixmap(), because it doesn't tile
// correctly for background pixmaps bigger than the current screen size.
- const QSize s = size();
- pixmap = QPixmap{s};
+ pixmap = QPixmap{pixmapSize};
QPainter painter{&pixmap};
- for (int x = 0; x < s.width(); x += image.width()) {
- for (int y = 0; y < s.height(); y += image.height()) {
+ for (int x = 0; x < pixmapSize.width(); x += image.width()) {
+ for (int y = 0; y < pixmapSize.height(); y += image.height()) {
painter.drawImage(x, y, image);
}
}
+ pixmap.setDevicePixelRatio(DPRatio);
}
}
else if(wallpaperMode_ == WallpaperStretch) {
if(perScreenWallpaper) {
- const QSize s = size();
- pixmap = QPixmap{s};
+ pixmap = QPixmap{pixmapSize};
QPainter painter{&pixmap};
pixmap.fill(bgColor_);
image = getWallpaperImage();
if(!image.isNull()) {
QImage scaled;
- const auto screens = screen->virtualSiblings();
for(const auto& scr : screens) {
- scaled = image.scaled(scr->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
+ scaled = image.scaled(scr->size() * scr->devicePixelRatio(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation);
painter.drawImage(scr->geometry().x(), scr->geometry().y(), scaled);
}
}
+ pixmap.setDevicePixelRatio(DPRatio);
}
else {
- image = loadWallpaperFile(size());
+ image = loadWallpaperFile(pixmapSize);
pixmap = QPixmap::fromImage(image);
+ pixmap.setDevicePixelRatio(DPRatio);
}
}
else { // WallpaperCenter || WallpaperFit
if(perScreenWallpaper) {
- const QSize s = size();
- pixmap = QPixmap{s};
+ pixmap = QPixmap{pixmapSize};
QPainter painter{&pixmap};
pixmap.fill(bgColor_);
image = getWallpaperImage();
if(!image.isNull()) {
QImage scaled;
int x, y;
- const auto screens = screen->virtualSiblings();
if(wallpaperMode_ == WallpaperCenter) {
for(const auto& scr : screens) {
+ const auto scrSize = scr->size() * scr->devicePixelRatio();
// get the gap between image and screen to avoid overlapping and displacement
- int x_gap = (image.width() - scr->geometry().width()) / 2;
- int y_gap = (image.height() - scr->geometry().height()) / 2;
- scaled = image.copy(qMax(x_gap, 0), qMax(y_gap, 0), scr->geometry().width(), scr->geometry().height());
+ int x_gap = (image.width() - scrSize.width()) / 2;
+ int y_gap = (image.height() - scrSize.height()) / 2;
+ scaled = image.copy(qMax(x_gap, 0), qMax(y_gap, 0), scrSize.width(), scrSize.height());
x = scr->geometry().x() + qMax(0, -x_gap);
- y = scr->geometry().y() + qMax(0, - y_gap);
+ y = scr->geometry().y() + qMax(0, -y_gap);
+ painter.save();
+ painter.setClipRect(QRect(x, y, image.width(), image.height()));
painter.drawImage(x, y, scaled);
+ painter.restore();
}
}
else if((wallpaperMode_ == WallpaperFit || wallpaperMode_ == WallpaperZoom)
&& image.width() > 0 && image.height() > 0) {
for(const auto& scr : screens) {
+ const auto scrSize = scr->size() * scr->devicePixelRatio();
// get the screen-to-image ratio to calculate the scale factors
- const qreal w_ratio = static_cast<qreal>(scr->geometry().width()) / image.width();
- const qreal h_ratio = static_cast<qreal>(scr->geometry().height()) / image.height();
+ const qreal w_ratio = static_cast<qreal>(scrSize.width()) / image.width();
+ const qreal h_ratio = static_cast<qreal>(scrSize.height()) / image.height();
if(w_ratio <= h_ratio) {
if(wallpaperMode_ == WallpaperFit) {
// fit horizontally
- scaled = image.scaledToWidth(scr->geometry().width(), Qt::SmoothTransformation);
+ scaled = image.scaledToWidth(scrSize.width(), Qt::SmoothTransformation);
x = scr->geometry().x();
- y = scr->geometry().y() + (scr->geometry().height() - scaled.height()) / 2;
+ y = scr->geometry().y() + (scrSize.height() - scaled.height()) / 2;
}
else { // zoom
// fit vertically
- scaled = image.scaledToHeight(scr->geometry().height(), Qt::SmoothTransformation);
+ scaled = image.scaledToHeight(scrSize.height(), Qt::SmoothTransformation);
// crop to avoid overlapping
- int x_gap = (scaled.width() - scr->geometry().width()) / 2;
- scaled = scaled.copy(x_gap, 0, scr->geometry().width(), scaled.height());
+ int x_gap = (scaled.width() - scrSize.width()) / 2;
+ scaled = scaled.copy(x_gap, 0, scrSize.width(), scaled.height());
x = scr->geometry().x();
y = scr->geometry().y();
}
@@ -733,16 +752,16 @@ void DesktopWindow::updateWallpaper() {
else { // w_ratio > h_ratio
if(wallpaperMode_ == WallpaperFit) {
// fit vertically
- scaled = image.scaledToHeight(scr->geometry().height(), Qt::SmoothTransformation);
- x = scr->geometry().x() + (scr->geometry().width() - scaled.width()) / 2;
+ scaled = image.scaledToHeight(scrSize.height(), Qt::SmoothTransformation);
+ x = scr->geometry().x() + (scrSize.width() - scaled.width()) / 2;
y = scr->geometry().y();
}
else { // zoom
// fit horizonatally
- scaled = image.scaledToWidth(scr->geometry().width(), Qt::SmoothTransformation);
+ scaled = image.scaledToWidth(scrSize.width(), Qt::SmoothTransformation);
// crop to avoid overlapping
- int y_gap = (scaled.height() - scr->geometry().height()) / 2;
- scaled = scaled.copy(0, y_gap, scaled.width(), scr->geometry().height());
+ int y_gap = (scaled.height() - scrSize.height()) / 2;
+ scaled = scaled.copy(0, y_gap, scaled.width(), scrSize.height());
x = scr->geometry().x();
y = scr->geometry().y();
}
@@ -751,6 +770,7 @@ void DesktopWindow::updateWallpaper() {
}
}
}
+ pixmap.setDevicePixelRatio(DPRatio);
}
else {
if(wallpaperMode_ == WallpaperCenter) {
@@ -770,17 +790,18 @@ void DesktopWindow::updateWallpaper() {
if(origSize.isValid()) {
QSize desiredSize = origSize;
Qt::AspectRatioMode mode = (wallpaperMode_ == WallpaperFit ? Qt::KeepAspectRatio : Qt::KeepAspectRatioByExpanding);
- desiredSize.scale(width(), height(), mode);
+ desiredSize.scale(pixmapSize, mode);
image = loadWallpaperFile(desiredSize); // load the scaled image
}
}
if(!image.isNull()) {
- pixmap = QPixmap(size());
+ pixmap = QPixmap{pixmapSize};
QPainter painter(&pixmap);
pixmap.fill(bgColor_);
- int x = (width() - image.width()) / 2;
- int y = (height() - image.height()) / 2;
+ int x = (pixmapSize.width() - image.width()) / 2;
+ int y = (pixmapSize.height() - image.height()) / 2;
painter.drawImage(x, y, image);
+ pixmap.setDevicePixelRatio(DPRatio);
}
}
}
@@ -1239,7 +1260,9 @@ void DesktopWindow::paintBackground(QPaintEvent* event) {
painter.fillRect(event->rect(), QBrush(bgColor_));
}
else {
- painter.drawPixmap(event->rect(), wallpaperPixmap_, event->rect());
+ QRectF r(QPointF(event->rect().topLeft()) * wallpaperPixmap_.devicePixelRatio(),
+ QSizeF(event->rect().size()) * wallpaperPixmap_.devicePixelRatio());
+ painter.drawPixmap(event->rect(), wallpaperPixmap_, r.toRect());
}
}