[PATCH] Avoid unnecessary sequencing jobs in PreviewGenerator
authorAkseli Lahtinen <akselmo@akselmo.dev>
Tue, 13 May 2025 10:01:07 +0000 (13:01 +0300)
committerAurélien COUDERC <coucouf@debian.org>
Sun, 8 Jun 2025 12:42:29 +0000 (14:42 +0200)
Currently we keep constantly asking if the current item has sequences
support or not.

By sequences we mean things like hovering mouse over a folder thumbnail
and it goes through the files in it.

This MR will always run for the first sequence (the initial thumbnail)
but for the rest, then toggles a flag for the node with
Qt::DecorationPropertyRole. If the propertyrole is false, it skips any
further updates to avoid any unnecessary previewjob runs.

Gbp-Pq: Name upstream_c747fa0f_Avoid-unnecessary-sequencing-jobs-in-PreviewGenerator.patch

src/filewidgets/kfilepreviewgenerator.cpp
src/gui/previewjob.cpp
src/widgets/delegateanimationhandler.cpp
src/widgets/kdirmodel.cpp
src/widgets/kdirmodel.h

index 481d324f1a080af206358ba78824b8cbee223b60..3b5dc32aa91c04ba1d1bac486378d827bb4d67d2 100644 (file)
@@ -1015,6 +1015,11 @@ void KFilePreviewGeneratorPrivate::startPreviewJob(const KFileItemList &items, i
 
     q->connect(job, &KIO::PreviewJob::gotPreview, q, [this, job](const KFileItem &item, const QPixmap &pixmap) {
         addToPreviewQueue(item, pixmap, job);
+        m_dirModel->setData(m_dirModel->indexForItem(item), job->handlesSequences(), KDirModel::HandleSequencesRole);
+    });
+
+    q->connect(job, &KIO::PreviewJob::failed, q, [this, job](const KFileItem &item) {
+        m_dirModel->setData(m_dirModel->indexForItem(item), job->handlesSequences(), KDirModel::HandleSequencesRole);
     });
 
     q->connect(job, &KIO::PreviewJob::finished, q, [this, job]() {
index 0841189617edf30c6ef8189f78e6ce9e352333b1..65902ea232cc9e9ea4bc769d221bb3c994aeed1c 100644 (file)
@@ -395,6 +395,8 @@ void PreviewJobPrivate::startPreview()
             item.standardThumbnailer = plugin.description() == QStringLiteral("standardthumbnailer");
             item.plugin = plugin;
             items.push_back(item);
+            bool handlesSequencesValue = item.plugin.value(QStringLiteral("HandleSequences"), false);
+            thumbnailWorkerMetaData.insert(QStringLiteral("handlesSequences"), QString::number(handlesSequencesValue));
 
             if (!bNeedCache && bSave && plugin.value(QStringLiteral("CacheThumbnail"), true)) {
                 const QUrl url = fileItem.targetUrl();
index 9d8f81beb8c6ffddb2cce1e6d91282ef4481984f..741416a944b14ed946749f42651b0fda9e1ddf2a 100644 (file)
@@ -200,8 +200,11 @@ void DelegateAnimationHandler::sequenceTimerTimeout()
     KDirModel *dirModel = dynamic_cast<KDirModel *>(model);
     if (dirModel) {
         // qDebug() << "requesting" << currentSequenceIndex;
-        dirModel->requestSequenceIcon(index, currentSequenceIndex);
-        iconSequenceTimer.start(); // Some upper-bound interval is needed, in case items are not generated
+        // Only request sequence icons for items that have them
+        if (dirModel->data(index, KDirModel::HandleSequencesRole).toBool()) {
+            dirModel->requestSequenceIcon(index, currentSequenceIndex);
+            iconSequenceTimer.start(); // Some upper-bound interval is needed, in case items are not generated
+        }
     }
 }
 
index 1aff865758a82bafb2c3c811f986701cea9c3d3b..da479e5e55542117f13a011bc5d61fbfc0a9ec45 100644 (file)
@@ -101,10 +101,21 @@ public:
         m_preview = icn;
     }
 
+    bool previewHandlesSequences()
+    {
+        return m_previewHandlesSequences;
+    }
+
+    void setPreviewHandlesSequences(bool handlesSequences)
+    {
+        m_previewHandlesSequences = handlesSequences;
+    }
+
 private:
     KFileItem m_item;
     KDirModelDirNode *const m_parent;
     QIcon m_preview;
+    bool m_previewHandlesSequences = true; // First sequence is always allowed
 };
 
 // Specialization for directory nodes
@@ -915,6 +926,11 @@ QVariant KDirModel::data(const QModelIndex &index, int role) const
                 }
             }
             break;
+        case HandleSequencesRole:
+            if (index.column() == Name) {
+                return node->previewHandlesSequences();
+            }
+            break;
         case Qt::TextAlignmentRole:
             if (index.column() == Size) {
                 // use a right alignment for L2R and R2L languages
@@ -1034,6 +1050,14 @@ bool KDirModel::setData(const QModelIndex &index, const QVariant &value, int rol
             return true;
         }
         break;
+    case HandleSequencesRole:
+        if (index.column() == Name) {
+            KDirModelNode *node = static_cast<KDirModelNode *>(index.internalPointer());
+            Q_ASSERT(node);
+            node->setPreviewHandlesSequences(value.toBool());
+            return true;
+        }
+        break;
     default:
         break;
     }
index e28767484f53b99625ef05d7431d54e146716704..118a2c4c0cb44275eb4901b9034acbab0dd3a5f2 100644 (file)
@@ -160,6 +160,7 @@ public:
         FileItemRole = 0x07A263FF, ///< returns the KFileItem for a given index. roleName is "fileItem".
         ChildCountRole = 0x2C4D0A40, ///< returns the number of items in a directory, or ChildCountUnknown. roleName is "childCount".
         HasJobRole = 0x01E555A5, ///< returns whether or not there is a job on an item (file/directory). roleName is "hasJob".
+        HandleSequencesRole = 0x1E642272,
     };
 
     /**