Package: libfm-qt6
Version: 0.14.2~36-g06d8d31-2
Severity: important
Tags: patch

Dear Maintainer,

in some rare cases libfm-qt ignore creation/deletion sequences resulting in 
displaying non-existing files.

Upstream-Bug: https://github.com/lxqt/pcmanfm-qt/issues/944
Upstream-Fix: https://github.com/lxqt/libfm-qt/pull/408

Thanks to Walter Lapchynski (w...@polka.bike) for spotting this.

Cheers Alf


Patch:

>From 7e79e591eb536603da92ee537bf949490b1259fc Mon Sep 17 00:00:00 2001
From: Tsu Jan <tsujan2...@gmail.com>
Date: Sun, 21 Apr 2019 14:11:14 +0430
Subject: [PATCH] Don't ignore creation-deletion sequences

Fixes https://github.com/lxqt/pcmanfm-qt/issues/944

Previously, if a file was in addition queue and then it came into the deletion 
queue, its addition and deletion were both ignored. That was wrong and could 
result in showing nonexistent files because addition can also happen in 
directory list job before being processed by file info job.

Also process accumulated changes only after finishing the current info job and 
don't clear all deletion paths after processing them (because, logically, only 
those paths that can be deleted should be removed).
---
 src/core/folder.cpp | 60 +++++++++++++++++++++++----------------------
 1 file changed, 31 insertions(+), 29 deletions(-)

diff --git a/src/core/folder.cpp b/src/core/folder.cpp
index 6c2b27d..2385a8b 100644
--- a/src/core/folder.cpp
+++ b/src/core/folder.cpp
@@ -228,16 +228,6 @@ void Folder::onFileInfoFinished() {
         return;
     }
 
-    // process the changes accumulated during this info job
-    if(filesystem_info_pending // means a pending change; see 
"onFileSystemInfoFinished()"
-       || !paths_to_update.empty() || !paths_to_add.empty() || 
!paths_to_del.empty()) {
-        QTimer::singleShot(0, this, &Folder::processPendingChanges);
-    }
-    // there's no pending change at the moment; let the next one be processed
-    else {
-        has_idle_update_handler = false;
-    }
-
     FileInfoList files_to_add;
     FileInfoList files_to_delete;
     std::vector<FileInfoPair> files_to_update;
@@ -271,6 +261,16 @@ void Folder::onFileInfoFinished() {
         Q_EMIT filesChanged(files_to_update);
     }
     Q_EMIT contentChanged();
+
+    // process the changes accumulated during this info job
+    if(filesystem_info_pending // means a pending change; see 
"onFileSystemInfoFinished()"
+       || !paths_to_update.empty() || !paths_to_add.empty() || 
!paths_to_del.empty()) {
+        QTimer::singleShot(0, this, &Folder::processPendingChanges);
+    }
+    // there's no pending change at the moment; let the next one be processed
+    else {
+        has_idle_update_handler = false;
+    }
 }
 
 void Folder::processPendingChanges() {
@@ -314,21 +314,24 @@ void Folder::processPendingChanges() {
     }
 
     // process deletion
-    if(!paths_to_del.empty()) {
-        FileInfoList deleted_files;
-        for(const auto &path: paths_to_del) {
-            auto name = path.baseName();
-            auto it = files_.find(name.get());
-            if(it != files_.end()) {
-                deleted_files.push_back(it->second);
-                files_.erase(it);
-            }
+    FileInfoList deleted_files;
+    auto path_it = paths_to_del.begin();
+    while(path_it != paths_to_del.end()) {
+        const auto& path = *path_it;
+        auto name = path.baseName();
+        auto it = files_.find(name.get());
+        if(it != files_.end()) {
+            deleted_files.push_back(it->second);
+            files_.erase(it);
+            path_it = paths_to_del.erase(path_it);
         }
-        if(!deleted_files.empty()) {
-            Q_EMIT filesRemoved(deleted_files);
-            Q_EMIT contentChanged();
+        else {
+            ++path_it;
         }
-        paths_to_del.clear();
+    }
+    if(!deleted_files.empty()) {
+        Q_EMIT filesRemoved(deleted_files);
+        Q_EMIT contentChanged();
     }
 
     if(pending_change_notify) {
@@ -404,13 +407,12 @@ void Folder::eventFileDeleted(const FilePath& path) {
     bool deleted = true;
     // qDebug() << "delete " << path.baseName().get();
     // G_LOCK(lists);
-    if(std::find(paths_to_add.cbegin(), paths_to_add.cend(), path) != 
paths_to_add.cend()) {
-        // if the file was going to be added, just remove it from the addition 
queue
-        paths_to_add.erase(std::remove(paths_to_add.begin(), 
paths_to_add.end(), path), paths_to_add.cend());
-    }
-    else if(std::find(paths_to_del.cbegin(), paths_to_del.cend(), path) == 
paths_to_del.cend()) {
+    /* WARNING: If the file is in the addition queue, we shouldn not remove it 
from that queue
+       and ignore its deletion because it may have been added by the directory 
list job, in
+       which case, ignoring an addition-deletion sequence would result in a 
nonexistent file. */
+    if(std::find(paths_to_del.cbegin(), paths_to_del.cend(), path) == 
paths_to_del.cend()) {
         paths_to_del.push_back(path);
-        // the update queue should be cancelled for a file that is going to be 
deleted
+        // the update queue can be cancelled for a file that is going to be 
deleted
         paths_to_update.erase(std::remove(paths_to_update.begin(), 
paths_to_update.end(), path), paths_to_update.cend());
     }
     else {




-- System Information:
Debian Release: 10.0
  APT prefers unstable-debug
  APT policy: (500, 'unstable-debug'), (500, 'testing-debug'), (500, 
'buildd-unstable'), (500, 'unstable'), (500, 'testing'), (500, 'stable'), (1, 
'experimental')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 5.0.7-towo.4-siduction-amd64 (SMP w/8 CPU cores; PREEMPT)
Kernel taint flags: TAINT_PROPRIETARY_MODULE, TAINT_OOT_MODULE
Locale: LANG=de_DE.utf8, LC_CTYPE=de_DE.utf8 (charmap=UTF-8), LANGUAGE= 
(charmap=UTF-8)
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)

Versions of packages libfm-qt6 depends on:
ii  libc6                             2.28-8
ii  libexif12                         0.6.21-5.1
ii  libglib2.0-0                      2.60.0-1.1
ii  libglib2.0-bin                    2.60.0-1.1
ii  libmenu-cache3                    1.1.1~2-g583c190-1
ii  libqt5core5a [qtbase-abi-5-11-3]  5.11.3+dfsg1-1
ii  libqt5gui5                        5.11.3+dfsg1-1
ii  libqt5widgets5                    5.11.3+dfsg1-1
ii  libqt5x11extras5                  5.11.3-2
ii  libstdc++6                        8.3.0-6
ii  libxcb1                           1.13.1-2
ii  shared-mime-info                  1.10-1

Versions of packages libfm-qt6 recommends:
ii  libfm-qt-l10n  0.14.2~36-g06d8d31-2

libfm-qt6 suggests no packages.

-- no debconf information

Reply via email to