From c761bcbaaba95d4910025e028a825f3f82983ceb46839e23b52df86c03f78184 Mon Sep 17 00:00:00 2001 From: Luca Beltrame Date: Fri, 12 Apr 2019 05:37:26 +0000 Subject: [PATCH] - Add upstream patch for HiDPI support in thumbnails (kde#373178): * 0001-Add-HiDPI-support-for-thumbnails.patch OBS-URL: https://build.opensuse.org/package/show/KDE:Applications/gwenview5?expand=0&rev=133 --- 0001-Add-HiDPI-support-for-thumbnails.patch | 239 ++++++++++++++++++++ gwenview5.changes | 2 + gwenview5.spec | 2 + 3 files changed, 243 insertions(+) create mode 100644 0001-Add-HiDPI-support-for-thumbnails.patch diff --git a/0001-Add-HiDPI-support-for-thumbnails.patch b/0001-Add-HiDPI-support-for-thumbnails.patch new file mode 100644 index 0000000..63bf863 --- /dev/null +++ b/0001-Add-HiDPI-support-for-thumbnails.patch @@ -0,0 +1,239 @@ +From 968c411a99576aa9e7784812e26e054ab290ae27 Mon Sep 17 00:00:00 2001 +From: Alexander Volkov +Date: Sun, 7 Apr 2019 08:01:19 -0600 +Subject: [PATCH] Add HiDPI support for thumbnails + +Summary: +The idea is to localize changes in ThumbnailView as much as possible: +ThumbnailView::thumbnailSize() returns the size in device independent +pixels, i.e. it seems from the outside that ThumbnailView behaves as +well as before this change. But, of course, item delegates must take +into account that ThumbnailView::thumbnailForIndex() will return +a pixmap with the devicePixelRatio set. + +CCBUG: 373178 + +Reviewers: #gwenview, ngraham + +Reviewed By: #gwenview, ngraham + +Subscribers: ngraham + +Tags: #gwenview + +Differential Revision: https://phabricator.kde.org/D20267 +--- + lib/thumbnailview/previewitemdelegate.cpp | 18 ++++++++++------ + lib/thumbnailview/thumbnailbarview.cpp | 17 +++++++++------ + lib/thumbnailview/thumbnailslider.cpp | 2 +- + lib/thumbnailview/thumbnailview.cpp | 26 ++++++++++++++--------- + 4 files changed, 38 insertions(+), 25 deletions(-) + +diff --git a/lib/thumbnailview/previewitemdelegate.cpp b/lib/thumbnailview/previewitemdelegate.cpp +index 974053b8..f910b0c1 100644 +--- a/lib/thumbnailview/previewitemdelegate.cpp ++++ b/lib/thumbnailview/previewitemdelegate.cpp +@@ -164,7 +164,8 @@ struct PreviewItemDelegatePrivate + const int posX = mContextBarActions == PreviewItemDelegate::SelectionAction + ? 0 + : (rect.width() - mContextBar->width()) / 2; +- const int posY = qMax(CONTEXTBAR_MARGIN, mThumbnailSize.height() - thumbnailPix.height() - mContextBar->height()); ++ const int thumbnailPixHeight = qRound(thumbnailPix.height() / thumbnailPix.devicePixelRatio()); ++ const int posY = qMax(CONTEXTBAR_MARGIN, mThumbnailSize.height() - thumbnailPixHeight - mContextBar->height()); + mContextBar->move(rect.topLeft() + QPoint(posX, posY)); + mContextBar->show(); + } +@@ -317,13 +318,15 @@ struct PreviewItemDelegatePrivate + { + const QPoint shadowOffset(-SHADOW_SIZE, -SHADOW_SIZE + 1); + +- int key = rect.height() * 1000 + rect.width(); ++ const auto dpr = painter->device()->devicePixelRatioF(); ++ int key = qRound((rect.height() * 1000 + rect.width()) * dpr); + + ShadowCache::Iterator it = mShadowCache.find(key); + if (it == mShadowCache.end()) { + QSize size = QSize(rect.width() + 2 * SHADOW_SIZE, rect.height() + 2 * SHADOW_SIZE); + QColor color(0, 0, 0, SHADOW_STRENGTH); +- QPixmap shadow = PaintUtils::generateFuzzyRect(size, color, SHADOW_SIZE); ++ QPixmap shadow = PaintUtils::generateFuzzyRect(size * dpr, color, qRound(SHADOW_SIZE * dpr)); ++ shadow.setDevicePixelRatio(dpr); + it = mShadowCache.insert(key, shadow); + } + painter->drawPixmap(rect.topLeft() + shadowOffset, it.value()); +@@ -688,6 +691,7 @@ void PreviewItemDelegate::paint(QPainter * painter, const QStyleOptionViewItem & + int thumbnailHeight = d->mThumbnailSize.height(); + QSize fullSize; + QPixmap thumbnailPix = d->mView->thumbnailForIndex(index, &fullSize); ++ QSize thumbnailSize = thumbnailPix.size() / thumbnailPix.devicePixelRatio(); + const KFileItem fileItem = fileItemForIndex(index); + const bool opaque = !thumbnailPix.hasAlphaChannel(); + const bool isDirOrArchive = ArchiveUtils::fileItemIsDirOrArchive(fileItem); +@@ -739,10 +743,10 @@ void PreviewItemDelegate::paint(QPainter * painter, const QStyleOptionViewItem & + + // Compute thumbnailRect + QRect thumbnailRect = QRect( +- rect.left() + (rect.width() - thumbnailPix.width()) / 2, +- rect.top() + (thumbnailHeight - thumbnailPix.height()) + ITEM_MARGIN, +- thumbnailPix.width(), +- thumbnailPix.height()); ++ rect.left() + (rect.width() - thumbnailSize.width()) / 2, ++ rect.top() + (thumbnailHeight - thumbnailSize.height()) + ITEM_MARGIN, ++ thumbnailSize.width(), ++ thumbnailSize.height()); + + // Draw background + const QRect backgroundRect = thumbnailRect.adjusted(-ITEM_MARGIN, -ITEM_MARGIN, ITEM_MARGIN, ITEM_MARGIN); +diff --git a/lib/thumbnailview/thumbnailbarview.cpp b/lib/thumbnailview/thumbnailbarview.cpp +index f7e6e9a0..a3cc1930 100644 +--- a/lib/thumbnailview/thumbnailbarview.cpp ++++ b/lib/thumbnailview/thumbnailbarview.cpp +@@ -102,13 +102,15 @@ struct ThumbnailBarItemDelegatePrivate + { + const QPoint shadowOffset(-SHADOW_SIZE, -SHADOW_SIZE + 1); + +- int key = rect.height() * 1000 + rect.width(); ++ const auto dpr = painter->device()->devicePixelRatioF(); ++ int key = qRound((rect.height() * 1000 + rect.width()) * dpr); + + ShadowCache::Iterator it = mShadowCache.find(key); + if (it == mShadowCache.end()) { + QSize size = QSize(rect.width() + 2 * SHADOW_SIZE, rect.height() + 2 * SHADOW_SIZE); + QColor color(0, 0, 0, SHADOW_STRENGTH); +- QPixmap shadow = PaintUtils::generateFuzzyRect(size, color, SHADOW_SIZE); ++ QPixmap shadow = PaintUtils::generateFuzzyRect(size * dpr, color, qRound(SHADOW_SIZE * dpr)); ++ shadow.setDevicePixelRatio(dpr); + it = mShadowCache.insert(key, shadow); + } + painter->drawPixmap(rect.topLeft() + shadowOffset, it.value()); +@@ -175,7 +177,7 @@ QSize ThumbnailBarItemDelegate::sizeHint(const QStyleOptionViewItem & /*option*/ + size = d->mView->gridSize(); + } else { + QPixmap thumbnailPix = d->mView->thumbnailForIndex(index); +- size = thumbnailPix.size(); ++ size = thumbnailPix.size() / thumbnailPix.devicePixelRatio(); + size.rwidth() += ITEM_MARGIN * 2; + size.rheight() += ITEM_MARGIN * 2; + } +@@ -203,6 +205,7 @@ void ThumbnailBarItemDelegate::paint(QPainter * painter, const QStyleOptionViewI + bool isSelected = option.state & QStyle::State_Selected; + bool isCurrent = d->mView->selectionModel()->currentIndex() == index; + QPixmap thumbnailPix = d->mView->thumbnailForIndex(index); ++ QSize thumbnailSize = thumbnailPix.size() / thumbnailPix.devicePixelRatio(); + QRect rect = option.rect; + + QStyleOptionViewItem opt = option; +@@ -219,10 +222,10 @@ void ThumbnailBarItemDelegate::paint(QPainter * painter, const QStyleOptionViewI + // Draw thumbnail + if (!thumbnailPix.isNull()) { + QRect thumbnailRect = QRect( +- rect.left() + (rect.width() - thumbnailPix.width()) / 2, +- rect.top() + (rect.height() - thumbnailPix.height()) / 2 - 1, +- thumbnailPix.width(), +- thumbnailPix.height()); ++ rect.left() + (rect.width() - thumbnailSize.width()) / 2, ++ rect.top() + (rect.height() - thumbnailSize.height()) / 2 - 1, ++ thumbnailSize.width(), ++ thumbnailSize.height()); + + if (!thumbnailPix.hasAlphaChannel()) { + d->drawShadow(painter, thumbnailRect); +diff --git a/lib/thumbnailview/thumbnailslider.cpp b/lib/thumbnailview/thumbnailslider.cpp +index 2c7fa2c9..03fabe26 100644 +--- a/lib/thumbnailview/thumbnailslider.cpp ++++ b/lib/thumbnailview/thumbnailslider.cpp +@@ -65,7 +65,7 @@ void ThumbnailSlider::slotActionTriggered(int actionTriggered) + void ThumbnailSlider::updateToolTip() + { + // FIXME: i18n? +- const int size = slider()->sliderPosition(); ++ const int size = qRound(slider()->sliderPosition() * devicePixelRatioF()); + const QString text = QStringLiteral("%1 x %2").arg(size).arg(size); + slider()->setToolTip(text); + } +diff --git a/lib/thumbnailview/thumbnailview.cpp b/lib/thumbnailview/thumbnailview.cpp +index a076dd1e..072a4479 100644 +--- a/lib/thumbnailview/thumbnailview.cpp ++++ b/lib/thumbnailview/thumbnailview.cpp +@@ -379,11 +379,12 @@ void ThumbnailView::updateThumbnailSize() + { + QSize value = d->mThumbnailSize; + // mWaitingThumbnail ++ const auto dpr = devicePixelRatioF(); + int waitingThumbnailSize; +- if (value.width() > 64) { +- waitingThumbnailSize = 48; ++ if (value.width() > 64 * dpr) { ++ waitingThumbnailSize = qRound(48 * dpr); + } else { +- waitingThumbnailSize = 32; ++ waitingThumbnailSize = qRound(32 * dpr); + } + QPixmap icon = DesktopIcon(QStringLiteral("chronometer"), waitingThumbnailSize); + QPixmap pix(value); +@@ -393,6 +394,7 @@ void ThumbnailView::updateThumbnailSize() + painter.drawPixmap((value.width() - icon.width()) / 2, (value.height() - icon.height()) / 2, icon); + painter.end(); + d->mWaitingThumbnail = pix; ++ d->mWaitingThumbnail.setDevicePixelRatio(dpr); + + // Stop smoothing + d->mSmoothThumbnailTimer.stop(); +@@ -406,8 +408,8 @@ void ThumbnailView::updateThumbnailSize() + it.value().mAdjustedPix = QPixmap(); + } + +- emit thumbnailSizeChanged(value); +- emit thumbnailWidthChanged(value.width()); ++ emit thumbnailSizeChanged(value / dpr); ++ emit thumbnailWidthChanged(qRound(value.width() / dpr)); + if (d->mScaleMode != ScaleToFit) { + scheduleDelayedItemsLayout(); + } +@@ -416,11 +418,14 @@ void ThumbnailView::updateThumbnailSize() + + void ThumbnailView::setThumbnailWidth(int width) + { +- if(d->mThumbnailSize.width() == width) { ++ const auto dpr = devicePixelRatioF(); ++ const qreal newWidthF = width * dpr; ++ const int newWidth = qRound(newWidthF); ++ if(d->mThumbnailSize.width() == newWidth) { + return; + } +- int height = round((qreal)width / d->mThumbnailAspectRatio); +- d->mThumbnailSize = QSize(width, height); ++ int height = qRound(newWidthF / d->mThumbnailAspectRatio); ++ d->mThumbnailSize = QSize(newWidth, height); + updateThumbnailSize(); + } + +@@ -443,7 +448,7 @@ qreal ThumbnailView::thumbnailAspectRatio() const + + QSize ThumbnailView::thumbnailSize() const + { +- return d->mThumbnailSize; ++ return d->mThumbnailSize / devicePixelRatioF(); + } + + void ThumbnailView::setThumbnailViewHelper(AbstractThumbnailViewHelper* helper) +@@ -670,6 +675,7 @@ QPixmap ThumbnailView::thumbnailForIndex(const QModelIndex& index, QSize* fullSi + if (fullSize) { + *fullSize = thumbnail.mRealFullSize; + } ++ thumbnail.mAdjustedPix.setDevicePixelRatio(devicePixelRatioF()); + return thumbnail.mAdjustedPix; + } + +@@ -810,7 +816,7 @@ void ThumbnailView::wheelEvent(QWheelEvent* event) + // setThumbnailSize() does not work + //verticalScrollBar()->setSingleStep(d->mThumbnailSize / 5); + if (event->modifiers() == Qt::ControlModifier) { +- int width = d->mThumbnailSize.width() + (event->delta() > 0 ? 1 : -1) * WHEEL_ZOOM_MULTIPLIER; ++ int width = thumbnailSize().width() + (event->delta() > 0 ? 1 : -1) * WHEEL_ZOOM_MULTIPLIER; + width = qMax(int(MinThumbnailSize), qMin(width, int(MaxThumbnailSize))); + setThumbnailWidth(width); + } else { +-- +2.21.0 + diff --git a/gwenview5.changes b/gwenview5.changes index a06310b..e9d88f8 100644 --- a/gwenview5.changes +++ b/gwenview5.changes @@ -8,6 +8,8 @@ Tue Apr 09 20:54:38 UTC 2019 - lbeltrame@kde.org - Changes since 19.03.80: * HiDPI Support for Gwenview (kde#373178) * Fix -Wreturn-type warning for jpeg version check +- Add upstream patch for HiDPI support in thumbnails (kde#373178): + * 0001-Add-HiDPI-support-for-thumbnails.patch ------------------------------------------------------------------- Wed Mar 27 06:40:56 UTC 2019 - lbeltrame@kde.org diff --git a/gwenview5.spec b/gwenview5.spec index 7f4c4c9..8dd2bbf 100644 --- a/gwenview5.spec +++ b/gwenview5.spec @@ -28,6 +28,7 @@ License: GPL-2.0-or-later Group: Productivity/Graphics/Viewers URL: http://www.kde.org Source: gwenview-%{version}.tar.xz +Patch0: 0001-Add-HiDPI-support-for-thumbnails.patch BuildRequires: baloo5-devel BuildRequires: cfitsio-devel BuildRequires: extra-cmake-modules >= %{kf5_version} @@ -81,6 +82,7 @@ hierarchies. %prep %setup -q -n gwenview-%{version} +%autopatch -p1 %build %if 0%{?suse_version} < 1330