From 95249e1a07cc2b5ae23ea53131d9b279cd822eac Mon Sep 17 00:00:00 2001 From: Camila Ayres Date: Thu, 3 Apr 2025 19:10:15 +0200 Subject: [PATCH 1/2] fix(PinState): don't trigger sync when file's PinState changed to Unspecified. LibreOffice/Microsoft office might touch the files for unknown reasons, creating a constant sync state (icon) visible in the parent folder. This fix excludes PinState changes from a new sync if the trigger might have been an external application. Signed-off-by: Camila Ayres --- src/gui/folder.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/gui/folder.cpp b/src/gui/folder.cpp index 62aa980cd2..f0454c97fb 100644 --- a/src/gui/folder.cpp +++ b/src/gui/folder.cpp @@ -652,8 +652,11 @@ void Folder::slotWatchedPathChanged(const QStringView &path, const ChangeReason if (record.isValid() && !FileSystem::fileChanged(path.toString(), record._fileSize, record._modtime) && _vfs) { spurious = true; - if (auto pinState = _vfs->pinState(relativePath.toString())) { + qCDebug(lcFolder) << "PinState for" << relativePath << "is" << *pinState; + if (*pinState == PinState::Unspecified) { + spurious = false; + } if (*pinState == PinState::AlwaysLocal && record.isVirtualFile()) { spurious = false; } From 2bd2162ed1750076d23cba54fe5903b0612e9472 Mon Sep 17 00:00:00 2001 From: Camila Ayres Date: Tue, 8 Apr 2025 15:35:55 +0200 Subject: [PATCH 2/2] test(cfapi): check for spurious attribute changes. Signed-off-by: Camila Ayres --- test/testsynccfapi.cpp | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/test/testsynccfapi.cpp b/test/testsynccfapi.cpp index d1ef2994e2..20f509cb64 100644 --- a/test/testsynccfapi.cpp +++ b/test/testsynccfapi.cpp @@ -1449,6 +1449,43 @@ private slots: QVERIFY(fakeFolder.syncOnce()); QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); } + + void testDetectSpuriousNotification() { +#if !defined Q_OS_WIN + QSKIP("not applicable"); +#endif + FakeFolder fakeFolder{FileInfo{}}; + auto vfs = setupVfs(fakeFolder); + + QVERIFY(fakeFolder.syncOnce()); + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + + const QString odpFile("odp/presentation.odp"); + const QString odtFile("odt/document.odt"); + fakeFolder.localModifier().mkdir("odp"); + fakeFolder.localModifier().insert(odpFile); + fakeFolder.localModifier().mkdir("odt"); + fakeFolder.localModifier().insert(odtFile); + + QVERIFY(fakeFolder.syncOnce()); + QCOMPARE(fakeFolder.currentLocalState(), fakeFolder.currentRemoteState()); + ItemCompletedSpy completeSpy(fakeFolder); + + QFile odp(fakeFolder.localPath() + odpFile); + QVERIFY(odp.open(QIODevice::ReadWrite)); + odp.write(odpFile.toLatin1(), qstrlen(odpFile.toLatin1())); + odp.close(); + QVERIFY(fakeFolder.syncOnce()); + QVERIFY(itemInstruction(completeSpy, odpFile, CSYNC_INSTRUCTION_SYNC)); + QCOMPARE(*vfs->pinState(odpFile), PinState::Unspecified); + + QFile odt(fakeFolder.localPath() + odtFile); + QVERIFY(odt.open(QIODevice::ReadWrite)); + odt.close(); + QVERIFY(fakeFolder.syncOnce()); + QVERIFY(itemInstruction(completeSpy, odtFile, CSYNC_INSTRUCTION_UPDATE_METADATA)); + QCOMPARE(*vfs->pinState(odtFile), PinState::Unspecified); + } }; QTEST_GUILESS_MAIN(TestSyncCfApi)