From d70a388511a72ee4aa82291f56a8016bc0b56db4 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 16 Jul 2024 18:57:00 +0800 Subject: [PATCH 01/34] Modernise slotComputeOverallSyncStatus Signed-off-by: Claudio Cambra --- src/gui/owncloudgui.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/gui/owncloudgui.cpp b/src/gui/owncloudgui.cpp index f55b60f14fc64..05971cc159e35 100644 --- a/src/gui/owncloudgui.cpp +++ b/src/gui/owncloudgui.cpp @@ -290,18 +290,18 @@ void ownCloudGui::slotComputeOverallSyncStatus() //_actionStatus->setText(text); }; - foreach (auto a, AccountManager::instance()->accounts()) { - if (!a->isSignedOut()) { + for (const auto &account : AccountManager::instance()->accounts()) { + if (!account->isSignedOut()) { allSignedOut = false; } - if (!a->isConnected()) { - problemAccounts.append(a); + if (!account->isConnected()) { + problemAccounts.append(account); } else { allDisconnected = false; } } - foreach (Folder *f, FolderMan::instance()->map()) { - if (!f->syncPaused()) { + for (const auto folder : FolderMan::instance()->map()) { + if (!folder->syncPaused()) { allPaused = false; } } From 744ac540db54e2f12341b8c3db7cbeb34a9d4612 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 16 Jul 2024 18:57:52 +0800 Subject: [PATCH 02/34] Add support for FILE_PROVIDER_DOMAIN_SYNC_STATE_CHANGE socket messages in client file provider socket controller Signed-off-by: Claudio Cambra --- .../macOS/fileprovidersocketcontroller.cpp | 23 ++++++++++++++++++- src/gui/macOS/fileprovidersocketcontroller.h | 8 +++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/src/gui/macOS/fileprovidersocketcontroller.cpp b/src/gui/macOS/fileprovidersocketcontroller.cpp index 0b34a9962ad61..4faf1404400f0 100644 --- a/src/gui/macOS/fileprovidersocketcontroller.cpp +++ b/src/gui/macOS/fileprovidersocketcontroller.cpp @@ -89,6 +89,9 @@ void FileProviderSocketController::parseReceivedLine(const QString &receivedLine _accountState = FileProviderDomainManager::accountStateFromFileProviderDomainIdentifier(argument); sendAccountDetails(); return; + } else if (command == "FILE_PROVIDER_DOMAIN_SYNC_STATE_CHANGE") { + reportSyncState(argument); + return; } qCWarning(lcFileProviderSocketController) << "Unknown command or reply:" << receivedLine; @@ -216,6 +219,24 @@ void FileProviderSocketController::sendAccountDetails() const sendMessage(message); } -} +void FileProviderSocketController::reportSyncState(const QString &receivedState) const +{ + auto syncState = SyncResult::Status::Undefined; + if (receivedState == QStringLiteral("SYNC_STARTED")) { + syncState = SyncResult::Status::SyncRunning; + } else if (receivedState == QStringLiteral("SYNC_FINISHED")) { + syncState = SyncResult::Status::Success; + } else if (receivedState == QStringLiteral("SYNC_FAILED")) { + syncState = SyncResult::Status::Problem; + } else if (receivedState == QStringLiteral("SYNC_PAUSED")) { + syncState = SyncResult::Status::Paused; + } else { + qCWarning(lcFileProviderSocketController) << "Unknown sync state received:" << receivedState; + } + emit syncStateChanged(_accountState->account(), syncState); } + +} // namespace Mac + +} // namespace OCC diff --git a/src/gui/macOS/fileprovidersocketcontroller.h b/src/gui/macOS/fileprovidersocketcontroller.h index ca7c353343237..0906216b66b33 100644 --- a/src/gui/macOS/fileprovidersocketcontroller.h +++ b/src/gui/macOS/fileprovidersocketcontroller.h @@ -16,7 +16,8 @@ #include -#include "accountstate.h" +#include "gui/accountstate.h" +#include "libsync/syncresult.h" class QLocalSocket; @@ -32,7 +33,8 @@ class FileProviderSocketController : public QObject explicit FileProviderSocketController(QLocalSocket * const socket, QObject * const parent = nullptr); signals: - void socketDestroyed(const QLocalSocket * const socket); + void socketDestroyed(const QLocalSocket * const socket);signals: + void syncStateChanged(const AccountPtr &account, SyncResult::Status state) const; public slots: void sendMessage(const QString &message) const; @@ -50,6 +52,8 @@ private slots: void sendAccountDetails() const; void sendNotAuthenticated() const; + void reportSyncState(const QString &receivedState) const; + private: QPointer _socket; AccountStatePtr _accountState; From 87066c8bb57c359e41522070ff6720bf8ebb3ee3 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 16 Jul 2024 18:58:12 +0800 Subject: [PATCH 03/34] Bounce sync state change signals from socket controller in socket server Signed-off-by: Claudio Cambra --- src/gui/macOS/fileprovidersocketserver.cpp | 2 ++ src/gui/macOS/fileprovidersocketserver.h | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/src/gui/macOS/fileprovidersocketserver.cpp b/src/gui/macOS/fileprovidersocketserver.cpp index 70b01615705fd..8e73d2d89ce52 100644 --- a/src/gui/macOS/fileprovidersocketserver.cpp +++ b/src/gui/macOS/fileprovidersocketserver.cpp @@ -62,6 +62,8 @@ void FileProviderSocketServer::slotNewConnection() } const FileProviderSocketControllerPtr socketController(new FileProviderSocketController(socket, this)); + connect(socketController.data(), &FileProviderSocketController::syncStateChanged, + this, &FileProviderSocketServer::syncStateChanged); connect(socketController.data(), &FileProviderSocketController::socketDestroyed, this, &FileProviderSocketServer::slotSocketDestroyed); _socketControllers.insert(socket, socketController); diff --git a/src/gui/macOS/fileprovidersocketserver.h b/src/gui/macOS/fileprovidersocketserver.h index e650e0ca2b4ac..c41544add70d1 100644 --- a/src/gui/macOS/fileprovidersocketserver.h +++ b/src/gui/macOS/fileprovidersocketserver.h @@ -17,6 +17,9 @@ #include #include +#include "libsync/accountfwd.h" +#include "libsync/syncresult.h" + namespace OCC { namespace Mac { @@ -46,6 +49,9 @@ class FileProviderSocketServer : public QObject public: explicit FileProviderSocketServer(QObject *parent = nullptr); +signals: + void syncStateChanged(const AccountPtr &account, SyncResult::Status state) const; + private slots: void startListening(); void slotNewConnection(); From 5237822221a75fe3c5829490242989927e49e2a5 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 16 Jul 2024 19:17:15 +0800 Subject: [PATCH 04/34] Add sets for actions, to be able to track multiple actions Signed-off-by: Claudio Cambra --- .../FileProviderExt/FileProviderExtension.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift index 7d952f24e72b6..1023ae21d7a7e 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift @@ -37,6 +37,9 @@ import OSLog return LocalSocketClient(socketPath: socketPath.path, lineProcessor: lineProcessor) }() + var syncActions = Set() + var errorActions = Set() + // Whether or not we are going to recursively scan new folders when they are discovered. // Apple's recommendation is that we should always scan the file hierarchy fully. // This does lead to long load times when a file provider domain is initially configured. From 885d9f3566578ae1948e8f6a529f73f50b0bec0e Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 16 Jul 2024 19:19:58 +0800 Subject: [PATCH 05/34] Add method to report a change in sync state if applicable in FileProviderExt Signed-off-by: Claudio Cambra --- ...FileProviderExtension+ClientInterface.swift | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension+ClientInterface.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension+ClientInterface.swift index e9f60607a5de6..a4b60a407ee0a 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension+ClientInterface.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension+ClientInterface.swift @@ -132,4 +132,22 @@ extension FileProviderExtension: NSFileProviderServicing, ChangeNotificationInte ) ncAccount = nil } + + func updatedSyncStateReporting(oldActions: Set) { + guard oldActions.isEmpty != syncActions.isEmpty else { return } + + let command = "FILE_PROVIDER_DOMAIN_SYNC_STATE_CHANGE" + var argument: String? + if oldActions.isEmpty, !syncActions.isEmpty { + argument = "SYNC_STARTED" + } else if !oldActions.isEmpty, syncActions.isEmpty { + argument = errorActions.isEmpty ? "SYNC_FINISHED" : "SYNC_FAILED" + errorActions = [] + } + + guard let argument else { return } + Logger.fileProviderExtension.debug("Reporting sync \(argument)") + let message = command + ":" + argument + "\n" + socketClient?.sendMessage(message) + } } From 3e6b20713e913a78606c48ecc9e6fefe7598e594 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 16 Jul 2024 19:18:00 +0800 Subject: [PATCH 06/34] Add method to insert new sync action in FileProviderExt Signed-off-by: Claudio Cambra --- .../FileProviderExt/FileProviderExtension.swift | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift index 1023ae21d7a7e..e77d4e4df86a6 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift @@ -70,6 +70,12 @@ import OSLog ) } + func insertSyncAction(_ actionId: UUID) { + let oldActions = syncActions + syncActions.insert(actionId) + updatedSyncStateReporting(oldActions: oldActions) + } + // MARK: - NSFileProviderReplicatedExtension protocol methods func item( From c189f2952fb530ab148fa0a4983a5b82898b6632 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 16 Jul 2024 19:18:16 +0800 Subject: [PATCH 07/34] Add method to mark action as error sync action in FileProviderExt Signed-off-by: Claudio Cambra --- .../FileProviderExt/FileProviderExtension.swift | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift index e77d4e4df86a6..2a47f37e2dfd1 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift @@ -76,6 +76,13 @@ import OSLog updatedSyncStateReporting(oldActions: oldActions) } + func insertErrorAction(_ actionId: UUID) { + let oldActions = syncActions + syncActions.remove(actionId) + errorActions.insert(actionId) + updatedSyncStateReporting(oldActions: oldActions) + } + // MARK: - NSFileProviderReplicatedExtension protocol methods func item( From 3f3f478f6a6aeeb38fb31cbf0d4ef3ea53f0a2aa Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 16 Jul 2024 19:18:25 +0800 Subject: [PATCH 08/34] Add method to remove finished sync action in FileProviderExt Signed-off-by: Claudio Cambra --- .../FileProviderExt/FileProviderExtension.swift | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift index 2a47f37e2dfd1..bd4c5b33f77b1 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift @@ -83,6 +83,13 @@ import OSLog updatedSyncStateReporting(oldActions: oldActions) } + func removeSyncAction(_ actionId: UUID) { + let oldActions = syncActions + syncActions.remove(actionId) + errorActions.remove(actionId) + updatedSyncStateReporting(oldActions: oldActions) + } + // MARK: - NSFileProviderReplicatedExtension protocol methods func item( From 0c78594481537de3ff688e5eefe634555c8116a8 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 16 Jul 2024 19:21:26 +0800 Subject: [PATCH 09/34] Track sync actions in main FileProviderExt procedures Signed-off-by: Claudio Cambra --- .../FileProviderExtension.swift | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift index bd4c5b33f77b1..c4bcfd14534fc 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift @@ -111,6 +111,9 @@ import OSLog request: NSFileProviderRequest, completionHandler: @escaping (URL?, NSFileProviderItem?, Error?) -> Void ) -> Progress { + let actionId = UUID() + insertSyncAction(actionId) + Logger.fileProviderExtension.debug( "Received request to fetch contents of item with identifier: \(itemIdentifier.rawValue, privacy: .public)" ) @@ -120,6 +123,7 @@ import OSLog Logger.fileProviderExtension.error( "Can't return contents for a specific version as this is not supported." ) + insertErrorAction(actionId) completionHandler( nil, nil, @@ -135,6 +139,7 @@ import OSLog as account not set up yet. """ ) + insertErrorAction(actionId) completionHandler(nil, nil, NSFileProviderError(.notAuthenticated)) return Progress() } @@ -147,6 +152,7 @@ import OSLog """ ) completionHandler(nil, nil, NSFileProviderError(.noSuchItem)) + insertErrorAction(actionId) return Progress() } @@ -155,6 +161,7 @@ import OSLog let (localUrl, updatedItem, error) = await item.fetchContents( domain: self.domain, progress: progress ) + removeSyncAction(actionId) completionHandler(localUrl, updatedItem, error) } return progress @@ -170,6 +177,8 @@ import OSLog NSFileProviderItem?, NSFileProviderItemFields, Bool, Error? ) -> Void ) -> Progress { + let actionId = UUID() + insertSyncAction(actionId) let tempId = itemTemplate.itemIdentifier.rawValue Logger.fileProviderExtension.debug( @@ -186,6 +195,7 @@ import OSLog as account not set up yet """ ) + insertErrorAction(actionId) completionHandler( itemTemplate, NSFileProviderItemFields(), @@ -207,9 +217,14 @@ import OSLog ncAccount: ncAccount, progress: progress ) + if error != nil { + insertErrorAction(actionId) signalEnumerator(completionHandler: { _ in }) + } else { + removeSyncAction(actionId) } + completionHandler( item ?? itemTemplate, NSFileProviderItemFields(), @@ -233,6 +248,8 @@ import OSLog ) -> Progress { // An item was modified on disk, process the item's modification // TODO: Handle finder things like tags, other possible item changed fields + let actionId = UUID() + insertSyncAction(actionId) let identifier = item.itemIdentifier let ocId = identifier.rawValue @@ -247,6 +264,7 @@ import OSLog Logger.fileProviderExtension.error( "Not modifying item: \(ocId, privacy: .public) as account not set up yet." ) + insertErrorAction(actionId) completionHandler(item, [], false, NSFileProviderError(.notAuthenticated)) return Progress() } @@ -255,6 +273,7 @@ import OSLog Logger.fileProviderExtension.error( "Not modifying item: \(ocId, privacy: .public) as item not found." ) + insertErrorAction(actionId) completionHandler(item, [], false, NSFileProviderError(.noSuchItem)) return Progress() } @@ -272,9 +291,14 @@ import OSLog domain: domain, progress: progress ) + if error != nil { + insertErrorAction(actionId) signalEnumerator(completionHandler: { _ in }) + } else { + removeSyncAction(actionId) } + completionHandler(modifiedItem ?? item, [], false, error) } return progress @@ -287,6 +311,9 @@ import OSLog request _: NSFileProviderRequest, completionHandler: @escaping (Error?) -> Void ) -> Progress { + let actionId = UUID() + insertSyncAction(actionId) + Logger.fileProviderExtension.debug( "Received delete request for item: \(identifier.rawValue, privacy: .public)" ) @@ -295,6 +322,7 @@ import OSLog Logger.fileProviderExtension.error( "Not deleting item \(identifier.rawValue, privacy: .public), account not set up yet" ) + insertErrorAction(actionId) completionHandler(NSFileProviderError(.notAuthenticated)) return Progress() } @@ -303,6 +331,7 @@ import OSLog Logger.fileProviderExtension.error( "Not deleting item \(identifier.rawValue, privacy: .public), item not found" ) + insertErrorAction(actionId) completionHandler(NSFileProviderError(.noSuchItem)) return Progress() } @@ -311,7 +340,10 @@ import OSLog Task { let error = await item.delete() if error != nil { + insertErrorAction(actionId) signalEnumerator(completionHandler: { _ in }) + } else { + removeSyncAction(actionId) } progress.completedUnitCount = 1 completionHandler(await item.delete()) From 617ca1a1530b24a8b59cc52140ce2659ef1c3b2d Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 16 Jul 2024 19:23:53 +0800 Subject: [PATCH 10/34] Add conformance to NextcloudFileProviderKit's EnumerationListener protocol in FileProviderExt Signed-off-by: Claudio Cambra --- ...roviderExtension+EnumerationListener.swift | 23 +++++++++++++++++++ .../FileProviderExtension.swift | 2 ++ .../project.pbxproj | 4 ++++ 3 files changed, 29 insertions(+) create mode 100644 shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension+EnumerationListener.swift diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension+EnumerationListener.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension+EnumerationListener.swift new file mode 100644 index 0000000000000..00a3fb2df5652 --- /dev/null +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension+EnumerationListener.swift @@ -0,0 +1,23 @@ +// +// FileProviderExtension+EnumerationListener.swift +// FileProviderExt +// +// Created by Claudio Cambra on 16/7/24. +// + +import Foundation +import NextcloudFileProviderKit + +extension FileProviderExtension: EnumerationListener { + func enumerationActionStarted(actionId: UUID) { + insertSyncAction(actionId) + } + + func enumerationActionFinished(actionId: UUID) { + removeSyncAction(actionId) + } + + func enumerationActionFailed(actionId: UUID, error: Error) { + insertErrorAction(actionId) + } +} diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift index c4bcfd14534fc..6e27f9e84682d 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift @@ -397,6 +397,8 @@ import OSLog materialisedEnumerator.enumerateItems(for: materialisedObserver, startingAt: startingPage) } + // MARK: - Helper functions + func signalEnumerator(completionHandler: @escaping (_ error: Error?) -> Void) { guard let fpManager = NSFileProviderManager(for: domain) else { Logger.fileProviderExtension.error( diff --git a/shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj/project.pbxproj b/shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj/project.pbxproj index a150d71c4053d..7162acf23b440 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj/project.pbxproj +++ b/shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj/project.pbxproj @@ -10,6 +10,7 @@ 5307A6E62965C6FA001E0C6A /* NextcloudKit in Frameworks */ = {isa = PBXBuildFile; productRef = 5307A6E52965C6FA001E0C6A /* NextcloudKit */; }; 5307A6E82965DAD8001E0C6A /* NextcloudKit in Frameworks */ = {isa = PBXBuildFile; productRef = 5307A6E72965DAD8001E0C6A /* NextcloudKit */; }; 531522822B8E01C6002E31BE /* ShareTableItemView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 531522812B8E01C6002E31BE /* ShareTableItemView.xib */; }; + 532572082C4690340068DEC3 /* FileProviderExtension+EnumerationListener.swift in Sources */ = {isa = PBXBuildFile; fileRef = 532572072C4690340068DEC3 /* FileProviderExtension+EnumerationListener.swift */; }; 5350E4E92B0C534A00F276CB /* ClientCommunicationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5350E4E82B0C534A00F276CB /* ClientCommunicationService.swift */; }; 5352B36C29DC44B50011CE03 /* FileProviderExtension+Thumbnailing.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5352B36B29DC44B50011CE03 /* FileProviderExtension+Thumbnailing.swift */; }; 5358F2B92BAA0F5300E3C729 /* NextcloudCapabilitiesKit in Frameworks */ = {isa = PBXBuildFile; productRef = 5358F2B82BAA0F5300E3C729 /* NextcloudCapabilitiesKit */; }; @@ -148,6 +149,7 @@ /* Begin PBXFileReference section */ 531522812B8E01C6002E31BE /* ShareTableItemView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ShareTableItemView.xib; sourceTree = ""; }; + 532572072C4690340068DEC3 /* FileProviderExtension+EnumerationListener.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FileProviderExtension+EnumerationListener.swift"; sourceTree = ""; }; 5350E4E72B0C514400F276CB /* ClientCommunicationProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ClientCommunicationProtocol.h; sourceTree = ""; }; 5350E4E82B0C534A00F276CB /* ClientCommunicationService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClientCommunicationService.swift; sourceTree = ""; }; 5350E4EA2B0C9CE100F276CB /* FileProviderExt-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "FileProviderExt-Bridging-Header.h"; sourceTree = ""; }; @@ -294,6 +296,7 @@ 53D666602B70C9A70042C03D /* FileProviderConfig.swift */, 538E396C27F4765000FA63D5 /* FileProviderExtension.swift */, 53ED472F29C9CE0B00795DB1 /* FileProviderExtension+ClientInterface.swift */, + 532572072C4690340068DEC3 /* FileProviderExtension+EnumerationListener.swift */, 5352B36B29DC44B50011CE03 /* FileProviderExtension+Thumbnailing.swift */, 536EFBF6295CF58100F4CB13 /* FileProviderSocketLineProcessor.swift */, 538E397327F4765000FA63D5 /* FileProviderExt.entitlements */, @@ -671,6 +674,7 @@ 535AE30E29C0A2CC0042A9BA /* Logger+Extensions.swift in Sources */, 537630952B860D560026BFAB /* FPUIExtensionServiceSource.swift in Sources */, 5350E4E92B0C534A00F276CB /* ClientCommunicationService.swift in Sources */, + 532572082C4690340068DEC3 /* FileProviderExtension+EnumerationListener.swift in Sources */, 5352B36C29DC44B50011CE03 /* FileProviderExtension+Thumbnailing.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; From 939d67bfccec7edb4d6fffbf232ab23d2f5b716b Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 16 Jul 2024 19:24:09 +0800 Subject: [PATCH 11/34] Set self as listener for Enumerator in FileProviderExt Signed-off-by: Claudio Cambra --- .../FileProviderExt/FileProviderExtension.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift index 6e27f9e84682d..1e648a244f1d4 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift @@ -366,7 +366,8 @@ import OSLog ncAccount: ncAccount, remoteInterface: ncKit, domain: domain, - fastEnumeration: config.fastEnumerationEnabled + fastEnumeration: config.fastEnumerationEnabled, + listener: self ) } From 92f42bc16d6bb05930d67154d79555ef086de237 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 16 Jul 2024 19:35:09 +0800 Subject: [PATCH 12/34] Lock and unlock when accessing sync actions in FileProviderExt to protect against possible races Signed-off-by: Claudio Cambra --- .../FileProviderExtension+ClientInterface.swift | 9 ++++++++- .../FileProviderExt/FileProviderExtension.swift | 7 +++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension+ClientInterface.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension+ClientInterface.swift index a4b60a407ee0a..61f0a06052fb5 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension+ClientInterface.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension+ClientInterface.swift @@ -134,7 +134,12 @@ extension FileProviderExtension: NSFileProviderServicing, ChangeNotificationInte } func updatedSyncStateReporting(oldActions: Set) { - guard oldActions.isEmpty != syncActions.isEmpty else { return } + actionsLock.lock() + + guard oldActions.isEmpty != syncActions.isEmpty else { + actionsLock.unlock() + return + } let command = "FILE_PROVIDER_DOMAIN_SYNC_STATE_CHANGE" var argument: String? @@ -144,6 +149,8 @@ extension FileProviderExtension: NSFileProviderServicing, ChangeNotificationInte argument = errorActions.isEmpty ? "SYNC_FINISHED" : "SYNC_FAILED" errorActions = [] } + + actionsLock.unlock() guard let argument else { return } Logger.fileProviderExtension.debug("Reporting sync \(argument)") diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift index 1e648a244f1d4..533d20d569e47 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift @@ -39,6 +39,7 @@ import OSLog var syncActions = Set() var errorActions = Set() + var actionsLock = NSLock() // Whether or not we are going to recursively scan new folders when they are discovered. // Apple's recommendation is that we should always scan the file hierarchy fully. @@ -71,22 +72,28 @@ import OSLog } func insertSyncAction(_ actionId: UUID) { + actionsLock.lock() let oldActions = syncActions syncActions.insert(actionId) + actionsLock.unlock() updatedSyncStateReporting(oldActions: oldActions) } func insertErrorAction(_ actionId: UUID) { + actionsLock.lock() let oldActions = syncActions syncActions.remove(actionId) errorActions.insert(actionId) + actionsLock.unlock() updatedSyncStateReporting(oldActions: oldActions) } func removeSyncAction(_ actionId: UUID) { + actionsLock.lock() let oldActions = syncActions syncActions.remove(actionId) errorActions.remove(actionId) + actionsLock.unlock() updatedSyncStateReporting(oldActions: oldActions) } From 449092747b9028e2edf0a0adc6b020a2883378e7 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 17 Jul 2024 15:46:03 +0800 Subject: [PATCH 13/34] Remove pointless setStatusText in slotComputeOverallStatus Signed-off-by: Claudio Cambra --- src/gui/owncloudgui.cpp | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/src/gui/owncloudgui.cpp b/src/gui/owncloudgui.cpp index 05971cc159e35..c2004942bc204 100644 --- a/src/gui/owncloudgui.cpp +++ b/src/gui/owncloudgui.cpp @@ -279,16 +279,7 @@ void ownCloudGui::slotComputeOverallSyncStatus() { bool allSignedOut = true; bool allPaused = true; - bool allDisconnected = true; QVector problemAccounts; - auto setStatusText = [&](const QString &text) { - // FIXME: So this doesn't do anything? Needs to be revisited - Q_UNUSED(text) - // Don't overwrite the status if we're currently syncing - if (FolderMan::instance()->isAnySyncRunning()) - return; - //_actionStatus->setText(text); - }; for (const auto &account : AccountManager::instance()->accounts()) { if (!account->isSignedOut()) { @@ -296,8 +287,6 @@ void ownCloudGui::slotComputeOverallSyncStatus() } if (!account->isConnected()) { problemAccounts.append(account); - } else { - allDisconnected = false; } } for (const auto folder : FolderMan::instance()->map()) { @@ -308,11 +297,6 @@ void ownCloudGui::slotComputeOverallSyncStatus() if (!problemAccounts.empty()) { _tray->setIcon(Theme::instance()->folderOfflineIcon(true)); - if (allDisconnected) { - setStatusText(tr("Disconnected")); - } else { - setStatusText(tr("Disconnected from some accounts")); - } #ifdef Q_OS_WIN // Windows has a 128-char tray tooltip length limit. QStringList accountNames; @@ -339,12 +323,10 @@ void ownCloudGui::slotComputeOverallSyncStatus() if (allSignedOut) { _tray->setIcon(Theme::instance()->folderOfflineIcon(true)); _tray->setToolTip(tr("Please sign in")); - setStatusText(tr("Signed out")); return; } else if (allPaused) { _tray->setIcon(Theme::instance()->syncStateIcon(SyncResult::Paused, true)); _tray->setToolTip(tr("Account synchronization is disabled")); - setStatusText(tr("Synchronization is paused")); return; } @@ -389,21 +371,8 @@ void ownCloudGui::slotComputeOverallSyncStatus() trayMessage = allStatusStrings.join(QLatin1String("\n")); #endif _tray->setToolTip(trayMessage); - - if (overallStatus == SyncResult::Success || overallStatus == SyncResult::Problem) { - if (hasUnresolvedConflicts) { - setStatusText(tr("Unresolved conflicts")); - } else { - setStatusText(tr("Up to date")); - } - } else if (overallStatus == SyncResult::Paused) { - setStatusText(tr("Synchronization is paused")); - } else { - setStatusText(tr("Error during synchronization")); - } } else { _tray->setToolTip(tr("There are no sync folders configured.")); - setStatusText(tr("No sync folders configured")); } } From 8bc1fce88e8111c4129bedc902a91ed30d1ede47 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 17 Jul 2024 17:24:11 +0800 Subject: [PATCH 14/34] Expose socket server in FileProvider class Signed-off-by: Claudio Cambra --- src/gui/macOS/fileprovider.h | 1 + src/gui/macOS/fileprovider_mac.mm | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/src/gui/macOS/fileprovider.h b/src/gui/macOS/fileprovider.h index d4ddcf596d30a..d3ebb62737316 100644 --- a/src/gui/macOS/fileprovider.h +++ b/src/gui/macOS/fileprovider.h @@ -41,6 +41,7 @@ class FileProvider : public QObject [[nodiscard]] FileProviderXPC *xpc() const; [[nodiscard]] FileProviderDomainManager *domainManager() const; + [[nodiscard]] FileProviderSocketServer *socketServer() const; private slots: void configureXPC(); diff --git a/src/gui/macOS/fileprovider_mac.mm b/src/gui/macOS/fileprovider_mac.mm index 73c2e0d259f95..194d1da6d129f 100644 --- a/src/gui/macOS/fileprovider_mac.mm +++ b/src/gui/macOS/fileprovider_mac.mm @@ -107,5 +107,10 @@ return _domainManager.get(); } +FileProviderSocketServer *FileProvider::socketServer() const +{ + return _socketServer.get(); +} + } // namespace Mac } // namespace OCC From 3415f39c16470eeb3f90fcef071f7ba22d9935ef Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 17 Jul 2024 17:27:38 +0800 Subject: [PATCH 15/34] Expose account state in file provider socket controller Signed-off-by: Claudio Cambra --- src/gui/macOS/fileprovidersocketcontroller.cpp | 5 +++++ src/gui/macOS/fileprovidersocketcontroller.h | 2 ++ 2 files changed, 7 insertions(+) diff --git a/src/gui/macOS/fileprovidersocketcontroller.cpp b/src/gui/macOS/fileprovidersocketcontroller.cpp index 4faf1404400f0..a5a5b3385e9e4 100644 --- a/src/gui/macOS/fileprovidersocketcontroller.cpp +++ b/src/gui/macOS/fileprovidersocketcontroller.cpp @@ -171,6 +171,11 @@ void FileProviderSocketController::slotAccountStateChanged(const AccountState::S } } +AccountStatePtr FileProviderSocketController::accountState() const +{ + return _accountState; +} + void FileProviderSocketController::sendNotAuthenticated() const { Q_ASSERT(_accountState); diff --git a/src/gui/macOS/fileprovidersocketcontroller.h b/src/gui/macOS/fileprovidersocketcontroller.h index 0906216b66b33..30741228d8758 100644 --- a/src/gui/macOS/fileprovidersocketcontroller.h +++ b/src/gui/macOS/fileprovidersocketcontroller.h @@ -32,6 +32,8 @@ class FileProviderSocketController : public QObject public: explicit FileProviderSocketController(QLocalSocket * const socket, QObject * const parent = nullptr); + [[nodiscard]] AccountStatePtr accountState() const; + signals: void socketDestroyed(const QLocalSocket * const socket);signals: void syncStateChanged(const AccountPtr &account, SyncResult::Status state) const; From 3877efba5e8d8739766b705d7caef2e3f9bf07dc Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 17 Jul 2024 17:28:11 +0800 Subject: [PATCH 16/34] Store latest sync state in file provider socket controller Signed-off-by: Claudio Cambra --- src/gui/macOS/fileprovidersocketcontroller.cpp | 4 ++-- src/gui/macOS/fileprovidersocketcontroller.h | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/gui/macOS/fileprovidersocketcontroller.cpp b/src/gui/macOS/fileprovidersocketcontroller.cpp index a5a5b3385e9e4..56cbdb338b671 100644 --- a/src/gui/macOS/fileprovidersocketcontroller.cpp +++ b/src/gui/macOS/fileprovidersocketcontroller.cpp @@ -224,7 +224,7 @@ void FileProviderSocketController::sendAccountDetails() const sendMessage(message); } -void FileProviderSocketController::reportSyncState(const QString &receivedState) const +void FileProviderSocketController::reportSyncState(const QString &receivedState) { auto syncState = SyncResult::Status::Undefined; if (receivedState == QStringLiteral("SYNC_STARTED")) { @@ -238,7 +238,7 @@ void FileProviderSocketController::reportSyncState(const QString &receivedState) } else { qCWarning(lcFileProviderSocketController) << "Unknown sync state received:" << receivedState; } - + _latestStatus = syncState; emit syncStateChanged(_accountState->account(), syncState); } diff --git a/src/gui/macOS/fileprovidersocketcontroller.h b/src/gui/macOS/fileprovidersocketcontroller.h index 30741228d8758..a1c76b7301e10 100644 --- a/src/gui/macOS/fileprovidersocketcontroller.h +++ b/src/gui/macOS/fileprovidersocketcontroller.h @@ -54,11 +54,12 @@ private slots: void sendAccountDetails() const; void sendNotAuthenticated() const; - void reportSyncState(const QString &receivedState) const; + void reportSyncState(const QString &receivedState); private: QPointer _socket; AccountStatePtr _accountState; + SyncResult::Status _latestStatus = SyncResult::Undefined; }; } // namespace Mac From b290611471a1fb2d6a3d882c8376d6727b422ea0 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 17 Jul 2024 17:28:27 +0800 Subject: [PATCH 17/34] Expose latest sync state in file provider socket controller Signed-off-by: Claudio Cambra --- src/gui/macOS/fileprovidersocketcontroller.cpp | 5 +++++ src/gui/macOS/fileprovidersocketcontroller.h | 1 + 2 files changed, 6 insertions(+) diff --git a/src/gui/macOS/fileprovidersocketcontroller.cpp b/src/gui/macOS/fileprovidersocketcontroller.cpp index 56cbdb338b671..8b258d0d35cbe 100644 --- a/src/gui/macOS/fileprovidersocketcontroller.cpp +++ b/src/gui/macOS/fileprovidersocketcontroller.cpp @@ -242,6 +242,11 @@ void FileProviderSocketController::reportSyncState(const QString &receivedState) emit syncStateChanged(_accountState->account(), syncState); } +SyncResult::Status FileProviderSocketController::latestStatus() const +{ + return _latestStatus; +} + } // namespace Mac } // namespace OCC diff --git a/src/gui/macOS/fileprovidersocketcontroller.h b/src/gui/macOS/fileprovidersocketcontroller.h index a1c76b7301e10..7e8cb92388b21 100644 --- a/src/gui/macOS/fileprovidersocketcontroller.h +++ b/src/gui/macOS/fileprovidersocketcontroller.h @@ -33,6 +33,7 @@ class FileProviderSocketController : public QObject explicit FileProviderSocketController(QLocalSocket * const socket, QObject * const parent = nullptr); [[nodiscard]] AccountStatePtr accountState() const; + [[nodiscard]] SyncResult::Status latestStatus() const; signals: void socketDestroyed(const QLocalSocket * const socket);signals: From a434e656fd9c2a46fe78d7247c615cb1c6e8853c Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 17 Jul 2024 17:29:03 +0800 Subject: [PATCH 18/34] Add support for SYNC_PREPARING arg in socket controller reportsyncstate Signed-off-by: Claudio Cambra --- src/gui/macOS/fileprovidersocketcontroller.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/gui/macOS/fileprovidersocketcontroller.cpp b/src/gui/macOS/fileprovidersocketcontroller.cpp index 8b258d0d35cbe..eaa904bdf072c 100644 --- a/src/gui/macOS/fileprovidersocketcontroller.cpp +++ b/src/gui/macOS/fileprovidersocketcontroller.cpp @@ -227,13 +227,15 @@ void FileProviderSocketController::sendAccountDetails() const void FileProviderSocketController::reportSyncState(const QString &receivedState) { auto syncState = SyncResult::Status::Undefined; - if (receivedState == QStringLiteral("SYNC_STARTED")) { + if (receivedState == "SYNC_PREPARING") { + syncState = SyncResult::Status::SyncPrepare; + } else if (receivedState == "SYNC_STARTED") { syncState = SyncResult::Status::SyncRunning; - } else if (receivedState == QStringLiteral("SYNC_FINISHED")) { + } else if (receivedState == "SYNC_FINISHED") { syncState = SyncResult::Status::Success; - } else if (receivedState == QStringLiteral("SYNC_FAILED")) { + } else if (receivedState == "SYNC_FAILED") { syncState = SyncResult::Status::Problem; - } else if (receivedState == QStringLiteral("SYNC_PAUSED")) { + } else if (receivedState == "SYNC_PAUSED") { syncState = SyncResult::Status::Paused; } else { qCWarning(lcFileProviderSocketController) << "Unknown sync state received:" << receivedState; From da7c511a8e5a0e509b48c299780fa1c770292c64 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 17 Jul 2024 17:29:18 +0800 Subject: [PATCH 19/34] Report sync state after initial connection of socket in socket controller Signed-off-by: Claudio Cambra --- src/gui/macOS/fileprovidersocketcontroller.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gui/macOS/fileprovidersocketcontroller.cpp b/src/gui/macOS/fileprovidersocketcontroller.cpp index eaa904bdf072c..2383ddd24c7b0 100644 --- a/src/gui/macOS/fileprovidersocketcontroller.cpp +++ b/src/gui/macOS/fileprovidersocketcontroller.cpp @@ -88,6 +88,7 @@ void FileProviderSocketController::parseReceivedLine(const QString &receivedLine if (command == QStringLiteral("FILE_PROVIDER_DOMAIN_IDENTIFIER_REQUEST_REPLY")) { _accountState = FileProviderDomainManager::accountStateFromFileProviderDomainIdentifier(argument); sendAccountDetails(); + reportSyncState("SYNC_PREPARING"); return; } else if (command == "FILE_PROVIDER_DOMAIN_SYNC_STATE_CHANGE") { reportSyncState(argument); From fd7f1ce0fc78d6df014753a76f2832bdfd8ea3cb Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 17 Jul 2024 17:29:38 +0800 Subject: [PATCH 20/34] Add file provider socket state struct Signed-off-by: Claudio Cambra --- src/gui/macOS/fileprovidersocketserver.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/gui/macOS/fileprovidersocketserver.h b/src/gui/macOS/fileprovidersocketserver.h index c41544add70d1..eee03173421eb 100644 --- a/src/gui/macOS/fileprovidersocketserver.h +++ b/src/gui/macOS/fileprovidersocketserver.h @@ -29,6 +29,11 @@ using FileProviderSocketControllerPtr = QPointer; QString fileProviderSocketPath(); +struct FileProviderSocketState { + bool connected; + SyncResult::Status latestStatus; +} typedef FileProviderSocketState; + /* * Establishes communication between the app and the file provider extension. * This is done via a local socket server. From 034fbb8245a7bb24e2c45025e685a9587f35ec78 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 17 Jul 2024 17:30:01 +0800 Subject: [PATCH 21/34] Add file provider socket state provider method in socket server Signed-off-by: Claudio Cambra --- src/gui/macOS/fileprovidersocketserver.cpp | 18 ++++++++++++++++++ src/gui/macOS/fileprovidersocketserver.h | 2 ++ 2 files changed, 20 insertions(+) diff --git a/src/gui/macOS/fileprovidersocketserver.cpp b/src/gui/macOS/fileprovidersocketserver.cpp index 8e73d2d89ce52..d2abaa806522d 100644 --- a/src/gui/macOS/fileprovidersocketserver.cpp +++ b/src/gui/macOS/fileprovidersocketserver.cpp @@ -17,6 +17,8 @@ #include #include +#include "libsync/account.h" + #include "fileprovidersocketcontroller.h" namespace OCC { @@ -81,6 +83,22 @@ void FileProviderSocketServer::slotSocketDestroyed(const QLocalSocket * const so } } +FileProviderSocketState FileProviderSocketServer::socketStateForAccount(const QString &userIdAtHost) const +{ + auto connected = false; + auto latestStatus = SyncResult::Undefined; + + for (const auto &controller : _socketControllers) { + if (controller->accountState()->account()->userIdAtHostWithPort() == userIdAtHost) { + connected = true; + latestStatus = controller->latestStatus(); + break; + } + } + + return { .connected = connected, .latestStatus = latestStatus }; +} + } // namespace Mac } // namespace OCC diff --git a/src/gui/macOS/fileprovidersocketserver.h b/src/gui/macOS/fileprovidersocketserver.h index eee03173421eb..0aecddc89df7f 100644 --- a/src/gui/macOS/fileprovidersocketserver.h +++ b/src/gui/macOS/fileprovidersocketserver.h @@ -54,6 +54,8 @@ class FileProviderSocketServer : public QObject public: explicit FileProviderSocketServer(QObject *parent = nullptr); + [[nodiscard]] FileProviderSocketState socketStateForAccount(const QString &userIdAtHost) const; + signals: void syncStateChanged(const AccountPtr &account, SyncResult::Status state) const; From 98dba86f58c3e7f3b7a5aa252677ac90886f7a91 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 17 Jul 2024 17:31:49 +0800 Subject: [PATCH 22/34] Connect sync state changed signal in file provider socket server to compute overall sync status slot in owncloudgui Signed-off-by: Claudio Cambra --- src/gui/owncloudgui.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/gui/owncloudgui.cpp b/src/gui/owncloudgui.cpp index c2004942bc204..5a1f2168444a4 100644 --- a/src/gui/owncloudgui.cpp +++ b/src/gui/owncloudgui.cpp @@ -64,6 +64,7 @@ #include #ifdef BUILD_FILE_PROVIDER_MODULE +#include "macOS/fileprovider.h" #include "macOS/fileprovidersettingscontroller.h" #endif @@ -110,8 +111,11 @@ ownCloudGui::ownCloudGui(Application *parent) &ownCloudGui::slotUpdateProgress); FolderMan *folderMan = FolderMan::instance(); - connect(folderMan, &FolderMan::folderSyncStateChange, - this, &ownCloudGui::slotSyncStateChange); + connect(folderMan, &FolderMan::folderSyncStateChange, this, &ownCloudGui::slotSyncStateChange); + +#ifdef BUILD_FILE_PROVIDER_MODULE + connect(Mac::FileProvider::instance()->socketServer(), &Mac::FileProviderSocketServer::syncStateChanged, this, &ownCloudGui::slotComputeOverallSyncStatus); +#endif connect(Logger::instance(), &Logger::guiLog, this, &ownCloudGui::slotShowTrayMessage); connect(Logger::instance(), &Logger::guiMessage, this, &ownCloudGui::slotShowGuiMessage); From 84d74bc5abbdfe90b4807f56ad13097eb20e1794 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 17 Jul 2024 17:32:35 +0800 Subject: [PATCH 23/34] Process state of file provider account domains in slotComputeOverallSyncStatus Signed-off-by: Claudio Cambra --- src/gui/owncloudgui.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/gui/owncloudgui.cpp b/src/gui/owncloudgui.cpp index 5a1f2168444a4..bb5e68aab7508 100644 --- a/src/gui/owncloudgui.cpp +++ b/src/gui/owncloudgui.cpp @@ -65,6 +65,7 @@ #ifdef BUILD_FILE_PROVIDER_MODULE #include "macOS/fileprovider.h" +#include "macOS/fileproviderdomainmanager.h" #include "macOS/fileprovidersettingscontroller.h" #endif @@ -299,6 +300,25 @@ void ownCloudGui::slotComputeOverallSyncStatus() } } +#ifdef BUILD_FILE_PROVIDER_MODULE + QList syncingFileProviderAccounts; + + if (Mac::FileProvider::fileProviderAvailable()) { + for (const auto &accountState : AccountManager::instance()->accounts()) { + const auto accountFpId = Mac::FileProviderDomainManager::fileProviderDomainIdentifierFromAccountState(accountState); + if (!Mac::FileProviderSettingsController::instance()->vfsEnabledForAccount(accountFpId)) { + continue; + } + const auto socketState = Mac::FileProvider::instance()->socketServer()->socketStateForAccount(accountFpId); + if (!socketState.connected || socketState.latestStatus == SyncResult::Problem || socketState.latestStatus == SyncResult::Error) { + problemAccounts.append(accountState); + } else if (socketState.latestStatus == SyncResult::SyncRunning) { + syncingFileProviderAccounts.append(accountFpId); + } + } + } +#endif + if (!problemAccounts.empty()) { _tray->setIcon(Theme::instance()->folderOfflineIcon(true)); #ifdef Q_OS_WIN From d2b569157ef646166308c47be4370131f9737a5f Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 17 Jul 2024 17:33:01 +0800 Subject: [PATCH 24/34] Append macOS vfs environment state strings to tray message when computing sync status Signed-off-by: Claudio Cambra --- src/gui/owncloudgui.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/gui/owncloudgui.cpp b/src/gui/owncloudgui.cpp index bb5e68aab7508..7fcd29f49aecb 100644 --- a/src/gui/owncloudgui.cpp +++ b/src/gui/owncloudgui.cpp @@ -379,19 +379,29 @@ void ownCloudGui::slotComputeOverallSyncStatus() _tray->setIcon(statusIcon); // create the tray blob message, check if we have an defined state +#ifdef BUILD_FILE_PROVIDER_MODULE + if (!map.isEmpty() || !syncingFileProviderAccounts.isEmpty()) { +#else if (map.count() > 0) { +#endif #ifdef Q_OS_WIN // Windows has a 128-char tray tooltip length limit. trayMessage = folderMan->trayTooltipStatusString(overallStatus, hasUnresolvedConflicts, false); #else QStringList allStatusStrings; - foreach (Folder *folder, map.values()) { + const auto folders = map.values(); + for (const auto folder : folders) { QString folderMessage = FolderMan::trayTooltipStatusString( folder->syncResult().status(), folder->syncResult().hasUnresolvedConflicts(), folder->syncPaused()); allStatusStrings += tr("Folder %1: %2").arg(folder->shortGuiLocalPath(), folderMessage); } +#ifdef BUILD_FILE_PROVIDER_MODULE + for (const auto &accountId : syncingFileProviderAccounts) { + allStatusStrings += tr("macOS VFS for %1: Syncing").arg(accountId); + } +#endif trayMessage = allStatusStrings.join(QLatin1String("\n")); #endif _tray->setToolTip(trayMessage); From 6e03e6a6379936db823d556828bd367c08185e8a Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 17 Jul 2024 17:39:15 +0800 Subject: [PATCH 25/34] Account for file provider states when setting tray icon Signed-off-by: Claudio Cambra --- src/gui/owncloudgui.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/gui/owncloudgui.cpp b/src/gui/owncloudgui.cpp index 7fcd29f49aecb..230066ac6bd09 100644 --- a/src/gui/owncloudgui.cpp +++ b/src/gui/owncloudgui.cpp @@ -301,6 +301,7 @@ void ownCloudGui::slotComputeOverallSyncStatus() } #ifdef BUILD_FILE_PROVIDER_MODULE + QList problemFileProviderAccounts; QList syncingFileProviderAccounts; if (Mac::FileProvider::fileProviderAvailable()) { @@ -311,7 +312,7 @@ void ownCloudGui::slotComputeOverallSyncStatus() } const auto socketState = Mac::FileProvider::instance()->socketServer()->socketStateForAccount(accountFpId); if (!socketState.connected || socketState.latestStatus == SyncResult::Problem || socketState.latestStatus == SyncResult::Error) { - problemAccounts.append(accountState); + problemFileProviderAccounts.append(accountFpId); } else if (socketState.latestStatus == SyncResult::SyncRunning) { syncingFileProviderAccounts.append(accountFpId); } @@ -363,6 +364,18 @@ void ownCloudGui::slotComputeOverallSyncStatus() bool hasUnresolvedConflicts = false; FolderMan::trayOverallStatus(map.values(), &overallStatus, &hasUnresolvedConflicts); +#ifdef BUILD_FILE_PROVIDER_MODULE + if (!problemFileProviderAccounts.isEmpty()) { + overallStatus = SyncResult::Problem; + } else if (!syncingFileProviderAccounts.isEmpty() && + overallStatus != SyncResult::SyncRunning && + overallStatus != SyncResult::Problem && + overallStatus != SyncResult::Error && + overallStatus != SyncResult::SetupError) { + overallStatus = SyncResult::SyncRunning; + } +#endif + // If the sync succeeded but there are unresolved conflicts, // show the problem icon! auto iconStatus = overallStatus; From ee59bea65a202427f4704f33bb4eb9f65e3679c5 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Thu, 18 Jul 2024 19:27:00 +0800 Subject: [PATCH 26/34] Do not report account sync state on socket controller if we haven't received account info yet Signed-off-by: Claudio Cambra --- src/gui/macOS/fileprovidersocketcontroller.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/gui/macOS/fileprovidersocketcontroller.cpp b/src/gui/macOS/fileprovidersocketcontroller.cpp index 2383ddd24c7b0..2c655271afede 100644 --- a/src/gui/macOS/fileprovidersocketcontroller.cpp +++ b/src/gui/macOS/fileprovidersocketcontroller.cpp @@ -227,6 +227,11 @@ void FileProviderSocketController::sendAccountDetails() const void FileProviderSocketController::reportSyncState(const QString &receivedState) { + if (!accountState()) { + qCWarning(lcFileProviderSocketController) << "No account state available to report sync state"; + return; + } + auto syncState = SyncResult::Status::Undefined; if (receivedState == "SYNC_PREPARING") { syncState = SyncResult::Status::SyncPrepare; From 6b14eed6aa6e62a7f21e8438284b7cba827d43d3 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Thu, 18 Jul 2024 19:27:49 +0800 Subject: [PATCH 27/34] Store and provide latest account's file provider sync state as there is no guarantee (nor should we ensure) the socket with the extension stays alive Signed-off-by: Claudio Cambra --- src/gui/macOS/fileprovidersocketserver.cpp | 25 +++++++++++----------- src/gui/macOS/fileprovidersocketserver.h | 9 +++----- src/gui/owncloudgui.cpp | 6 +++--- 3 files changed, 18 insertions(+), 22 deletions(-) diff --git a/src/gui/macOS/fileprovidersocketserver.cpp b/src/gui/macOS/fileprovidersocketserver.cpp index d2abaa806522d..aeebb23ff053b 100644 --- a/src/gui/macOS/fileprovidersocketserver.cpp +++ b/src/gui/macOS/fileprovidersocketserver.cpp @@ -65,7 +65,7 @@ void FileProviderSocketServer::slotNewConnection() const FileProviderSocketControllerPtr socketController(new FileProviderSocketController(socket, this)); connect(socketController.data(), &FileProviderSocketController::syncStateChanged, - this, &FileProviderSocketServer::syncStateChanged); + this, &FileProviderSocketServer::slotSyncStateChanged); connect(socketController.data(), &FileProviderSocketController::socketDestroyed, this, &FileProviderSocketServer::slotSocketDestroyed); _socketControllers.insert(socket, socketController); @@ -83,20 +83,19 @@ void FileProviderSocketServer::slotSocketDestroyed(const QLocalSocket * const so } } -FileProviderSocketState FileProviderSocketServer::socketStateForAccount(const QString &userIdAtHost) const +void FileProviderSocketServer::slotSyncStateChanged(const AccountPtr &account, SyncResult::Status state) { - auto connected = false; - auto latestStatus = SyncResult::Undefined; - - for (const auto &controller : _socketControllers) { - if (controller->accountState()->account()->userIdAtHostWithPort() == userIdAtHost) { - connected = true; - latestStatus = controller->latestStatus(); - break; - } - } + Q_ASSERT(account); + const auto userId = account->userIdAtHostWithPort(); + qCDebug(lcFileProviderSocketServer) << "Received sync state change for account" << userId << "state" << state; + _latestReceivedSyncStatus.insert(userId, state); + Q_EMIT syncStateChanged(account, state); +} - return { .connected = connected, .latestStatus = latestStatus }; +SyncResult::Status FileProviderSocketServer::latestReceivedSyncStatusForAccount(const AccountPtr &account) const +{ + Q_ASSERT(account); + return _latestReceivedSyncStatus.value(account->userIdAtHostWithPort(), SyncResult::Undefined); } } // namespace Mac diff --git a/src/gui/macOS/fileprovidersocketserver.h b/src/gui/macOS/fileprovidersocketserver.h index 0aecddc89df7f..d1c14b7fa08f4 100644 --- a/src/gui/macOS/fileprovidersocketserver.h +++ b/src/gui/macOS/fileprovidersocketserver.h @@ -29,11 +29,6 @@ using FileProviderSocketControllerPtr = QPointer; QString fileProviderSocketPath(); -struct FileProviderSocketState { - bool connected; - SyncResult::Status latestStatus; -} typedef FileProviderSocketState; - /* * Establishes communication between the app and the file provider extension. * This is done via a local socket server. @@ -54,7 +49,7 @@ class FileProviderSocketServer : public QObject public: explicit FileProviderSocketServer(QObject *parent = nullptr); - [[nodiscard]] FileProviderSocketState socketStateForAccount(const QString &userIdAtHost) const; + [[nodiscard]] SyncResult::Status latestReceivedSyncStatusForAccount(const AccountPtr &account) const; signals: void syncStateChanged(const AccountPtr &account, SyncResult::Status state) const; @@ -63,11 +58,13 @@ private slots: void startListening(); void slotNewConnection(); void slotSocketDestroyed(const QLocalSocket * const socket); + void slotSyncStateChanged(const AccountPtr &account, SyncResult::Status state); private: QString _socketPath; QLocalServer _socketServer; QHash _socketControllers; + QHash _latestReceivedSyncStatus; }; } // namespace Mac diff --git a/src/gui/owncloudgui.cpp b/src/gui/owncloudgui.cpp index 230066ac6bd09..ef1e385b9d7eb 100644 --- a/src/gui/owncloudgui.cpp +++ b/src/gui/owncloudgui.cpp @@ -310,10 +310,10 @@ void ownCloudGui::slotComputeOverallSyncStatus() if (!Mac::FileProviderSettingsController::instance()->vfsEnabledForAccount(accountFpId)) { continue; } - const auto socketState = Mac::FileProvider::instance()->socketServer()->socketStateForAccount(accountFpId); - if (!socketState.connected || socketState.latestStatus == SyncResult::Problem || socketState.latestStatus == SyncResult::Error) { + const auto latestStatus = Mac::FileProvider::instance()->socketServer()->latestReceivedSyncStatusForAccount(accountState->account()); + if (latestStatus == SyncResult::Problem || latestStatus == SyncResult::Error) { problemFileProviderAccounts.append(accountFpId); - } else if (socketState.latestStatus == SyncResult::SyncRunning) { + } else if (latestStatus == SyncResult::SyncRunning) { syncingFileProviderAccounts.append(accountFpId); } } From d3d19fd2bf3545359d1031ab9939cb7d8453388c Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Thu, 18 Jul 2024 19:30:25 +0800 Subject: [PATCH 28/34] Modernise problem account handling in slot compute overall sync state Signed-off-by: Claudio Cambra --- src/gui/owncloudgui.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/gui/owncloudgui.cpp b/src/gui/owncloudgui.cpp index ef1e385b9d7eb..8cb28a317dca7 100644 --- a/src/gui/owncloudgui.cpp +++ b/src/gui/owncloudgui.cpp @@ -332,11 +332,11 @@ void ownCloudGui::slotComputeOverallSyncStatus() #else QStringList messages; messages.append(tr("Disconnected from accounts:")); - foreach (AccountStatePtr a, problemAccounts) { - QString message = tr("Account %1: %2").arg(a->account()->displayName(), a->stateString(a->state())); - if (!a->connectionErrors().empty()) { + for (const auto &accountState : problemAccounts) { + QString message = tr("Account %1: %2").arg(accountState->account()->displayName(), accountState->stateString(accountState->state())); + if (!accountState->connectionErrors().empty()) { message += QLatin1String("\n"); - message += a->connectionErrors().join(QLatin1String("\n")); + message += accountState->connectionErrors().join(QLatin1String("\n")); } messages.append(message); } From ea0ae333d946d7316920b37e0e146faa4011c048 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Fri, 19 Jul 2024 14:51:37 +0800 Subject: [PATCH 29/34] Add method to fileproviderxpc to check if the file provider extension is reachable Signed-off-by: Claudio Cambra --- src/gui/macOS/fileproviderxpc.h | 2 ++ src/gui/macOS/fileproviderxpc_mac.mm | 16 ++++++++++++++++ 2 files changed, 18 insertions(+) diff --git a/src/gui/macOS/fileproviderxpc.h b/src/gui/macOS/fileproviderxpc.h index 58c6a0211b309..4ca88c03bd5be 100644 --- a/src/gui/macOS/fileproviderxpc.h +++ b/src/gui/macOS/fileproviderxpc.h @@ -34,6 +34,8 @@ class FileProviderXPC : public QObject public: explicit FileProviderXPC(QObject *parent = nullptr); + [[nodiscard]] bool fileProviderExtReachable(const QString &extensionAccountId) const; + // Returns enabled and set state of fast enumeration for the given extension [[nodiscard]] std::optional> fastEnumerationStateForExtension(const QString &extensionAccountId) const; diff --git a/src/gui/macOS/fileproviderxpc_mac.mm b/src/gui/macOS/fileproviderxpc_mac.mm index cc0b7b4679230..e94dc2cbcca48 100644 --- a/src/gui/macOS/fileproviderxpc_mac.mm +++ b/src/gui/macOS/fileproviderxpc_mac.mm @@ -141,6 +141,22 @@ } } +bool FileProviderXPC::fileProviderExtReachable(const QString &extensionAccountId) const +{ + const auto service = (NSObject *)_clientCommServices.value(extensionAccountId); + if (service == nil) { + return false; + } + __block auto response = false; + dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); + [service getExtensionAccountIdWithCompletionHandler:^(NSString *const, NSError *const) { + response = true; + dispatch_semaphore_signal(semaphore); + }]; + dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, semaphoreWaitDelta)); + return response; +} + std::optional> FileProviderXPC::fastEnumerationStateForExtension(const QString &extensionAccountId) const { qCInfo(lcFileProviderXPC) << "Checking if fast enumeration is enabled for extension" << extensionAccountId; From 3194edb063a5f55462d3dd36c332329e6b4945d8 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Fri, 19 Jul 2024 14:51:55 +0800 Subject: [PATCH 30/34] Check if the extension is reachable in owncloudgui compute sync status Signed-off-by: Claudio Cambra --- src/gui/owncloudgui.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/gui/owncloudgui.cpp b/src/gui/owncloudgui.cpp index 8cb28a317dca7..7b0d2fae5b3c5 100644 --- a/src/gui/owncloudgui.cpp +++ b/src/gui/owncloudgui.cpp @@ -310,8 +310,9 @@ void ownCloudGui::slotComputeOverallSyncStatus() if (!Mac::FileProviderSettingsController::instance()->vfsEnabledForAccount(accountFpId)) { continue; } - const auto latestStatus = Mac::FileProvider::instance()->socketServer()->latestReceivedSyncStatusForAccount(accountState->account()); - if (latestStatus == SyncResult::Problem || latestStatus == SyncResult::Error) { + const auto fileProvider = Mac::FileProvider::instance(); + const auto latestStatus = fileProvider->socketServer()->latestReceivedSyncStatusForAccount(accountState->account()); + if (latestStatus == SyncResult::Problem || latestStatus == SyncResult::Error || !fileProvider->xpc()->fileProviderExtReachable(accountFpId)) { problemFileProviderAccounts.append(accountFpId); } else if (latestStatus == SyncResult::SyncRunning) { syncingFileProviderAccounts.append(accountFpId); From 1128d9d668d217619fd34b03b0bf9662df64eea6 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Fri, 19 Jul 2024 15:06:20 +0800 Subject: [PATCH 31/34] Ensure all sync result status types are handled for file provider in owncloudgui Signed-off-by: Claudio Cambra --- src/gui/owncloudgui.cpp | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/gui/owncloudgui.cpp b/src/gui/owncloudgui.cpp index 7b0d2fae5b3c5..d7047e28bb95d 100644 --- a/src/gui/owncloudgui.cpp +++ b/src/gui/owncloudgui.cpp @@ -311,11 +311,28 @@ void ownCloudGui::slotComputeOverallSyncStatus() continue; } const auto fileProvider = Mac::FileProvider::instance(); - const auto latestStatus = fileProvider->socketServer()->latestReceivedSyncStatusForAccount(accountState->account()); - if (latestStatus == SyncResult::Problem || latestStatus == SyncResult::Error || !fileProvider->xpc()->fileProviderExtReachable(accountFpId)) { + + if (!fileProvider->xpc()->fileProviderExtReachable(accountFpId)) { problemFileProviderAccounts.append(accountFpId); - } else if (latestStatus == SyncResult::SyncRunning) { - syncingFileProviderAccounts.append(accountFpId); + } else { + switch (const auto latestStatus = fileProvider->socketServer()->latestReceivedSyncStatusForAccount(accountState->account())) { + case SyncResult::Undefined: + case SyncResult::NotYetStarted: + break; + case SyncResult::SyncPrepare: + case SyncResult::SyncRunning: + case SyncResult::SyncAbortRequested: + case SyncResult::Success: + syncingFileProviderAccounts.append(accountFpId); + break; + case SyncResult::Problem: + case SyncResult::Error: + case SyncResult::SetupError: + problemFileProviderAccounts.append(accountFpId); + break; + case SyncResult::Paused: + break; + } } } } From 58e6cdd0deecc87967d143c603c6310d1200cece Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Fri, 19 Jul 2024 15:32:55 +0800 Subject: [PATCH 32/34] Provide state message in popup for vfs accounts that synced successfully or had an issue Signed-off-by: Claudio Cambra --- src/gui/owncloudgui.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/gui/owncloudgui.cpp b/src/gui/owncloudgui.cpp index d7047e28bb95d..9cc24ef7ae617 100644 --- a/src/gui/owncloudgui.cpp +++ b/src/gui/owncloudgui.cpp @@ -303,6 +303,7 @@ void ownCloudGui::slotComputeOverallSyncStatus() #ifdef BUILD_FILE_PROVIDER_MODULE QList problemFileProviderAccounts; QList syncingFileProviderAccounts; + QList successFileProviderAccounts; if (Mac::FileProvider::fileProviderAvailable()) { for (const auto &accountState : AccountManager::instance()->accounts()) { @@ -322,9 +323,11 @@ void ownCloudGui::slotComputeOverallSyncStatus() case SyncResult::SyncPrepare: case SyncResult::SyncRunning: case SyncResult::SyncAbortRequested: - case SyncResult::Success: syncingFileProviderAccounts.append(accountFpId); break; + case SyncResult::Success: + successFileProviderAccounts.append(accountFpId); + break; case SyncResult::Problem: case SyncResult::Error: case SyncResult::SetupError: @@ -411,7 +414,7 @@ void ownCloudGui::slotComputeOverallSyncStatus() // create the tray blob message, check if we have an defined state #ifdef BUILD_FILE_PROVIDER_MODULE - if (!map.isEmpty() || !syncingFileProviderAccounts.isEmpty()) { + if (!map.isEmpty() || !syncingFileProviderAccounts.isEmpty() || !successFileProviderAccounts.isEmpty() || !problemFileProviderAccounts.isEmpty()) { #else if (map.count() > 0) { #endif @@ -430,7 +433,13 @@ void ownCloudGui::slotComputeOverallSyncStatus() } #ifdef BUILD_FILE_PROVIDER_MODULE for (const auto &accountId : syncingFileProviderAccounts) { - allStatusStrings += tr("macOS VFS for %1: Syncing").arg(accountId); + allStatusStrings += tr("macOS VFS for %1: Sync is running.").arg(accountId); + } + for (const auto &accountId : successFileProviderAccounts) { + allStatusStrings += tr("macOS VFS for %1: Last sync was successful.").arg(accountId); + } + for (const auto &accountId : problemFileProviderAccounts) { + allStatusStrings += tr("macOS VFS for %1: A problem was encountered.").arg(accountId); } #endif trayMessage = allStatusStrings.join(QLatin1String("\n")); From 87b2a84303ca0ce1aa0fbb287e8cf8c452cbdc7a Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Fri, 19 Jul 2024 16:10:31 +0800 Subject: [PATCH 33/34] Clean up unused components in file provider socket controller Signed-off-by: Claudio Cambra --- src/gui/macOS/fileprovidersocketcontroller.cpp | 6 ------ src/gui/macOS/fileprovidersocketcontroller.h | 6 ++---- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/gui/macOS/fileprovidersocketcontroller.cpp b/src/gui/macOS/fileprovidersocketcontroller.cpp index 2c655271afede..fcd5517b77de6 100644 --- a/src/gui/macOS/fileprovidersocketcontroller.cpp +++ b/src/gui/macOS/fileprovidersocketcontroller.cpp @@ -246,15 +246,9 @@ void FileProviderSocketController::reportSyncState(const QString &receivedState) } else { qCWarning(lcFileProviderSocketController) << "Unknown sync state received:" << receivedState; } - _latestStatus = syncState; emit syncStateChanged(_accountState->account(), syncState); } -SyncResult::Status FileProviderSocketController::latestStatus() const -{ - return _latestStatus; -} - } // namespace Mac } // namespace OCC diff --git a/src/gui/macOS/fileprovidersocketcontroller.h b/src/gui/macOS/fileprovidersocketcontroller.h index 7e8cb92388b21..30fc8251a8285 100644 --- a/src/gui/macOS/fileprovidersocketcontroller.h +++ b/src/gui/macOS/fileprovidersocketcontroller.h @@ -33,10 +33,9 @@ class FileProviderSocketController : public QObject explicit FileProviderSocketController(QLocalSocket * const socket, QObject * const parent = nullptr); [[nodiscard]] AccountStatePtr accountState() const; - [[nodiscard]] SyncResult::Status latestStatus() const; - + signals: - void socketDestroyed(const QLocalSocket * const socket);signals: + void socketDestroyed(const QLocalSocket * const socket); void syncStateChanged(const AccountPtr &account, SyncResult::Status state) const; public slots: @@ -60,7 +59,6 @@ private slots: private: QPointer _socket; AccountStatePtr _accountState; - SyncResult::Status _latestStatus = SyncResult::Undefined; }; } // namespace Mac From 23a8f0878b7ba2e8e459cf803818eb54c36e4c97 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Fri, 19 Jul 2024 18:21:00 +0800 Subject: [PATCH 34/34] Ensure file provider instance gets initialised at app launch WITHOUT creating a separate instance from expected singleton Signed-off-by: Claudio Cambra --- src/gui/application.cpp | 2 +- src/gui/application.h | 8 -------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/src/gui/application.cpp b/src/gui/application.cpp index 083f58a978b09..6fdfb07ff9b1b 100644 --- a/src/gui/application.cpp +++ b/src/gui/application.cpp @@ -461,7 +461,7 @@ Application::Application(int &argc, char **argv) AccountSetupCommandLineManager::destroy(); #if defined(BUILD_FILE_PROVIDER_MODULE) - _fileProvider.reset(new Mac::FileProvider); + Mac::FileProvider::instance(); #endif } diff --git a/src/gui/application.h b/src/gui/application.h index 879ae51efede4..9ec6e121bda39 100644 --- a/src/gui/application.h +++ b/src/gui/application.h @@ -49,12 +49,6 @@ class Folder; class ShellExtensionsServer; class SslErrorDialog; -#ifdef Q_OS_MACOS -namespace Mac { -class FileProvider; -} -#endif - /** * @brief The Application class * @ingroup gui @@ -163,8 +157,6 @@ protected slots: QScopedPointer _folderManager; #if defined(Q_OS_WIN) QScopedPointer _shellExtensionsServer; -#elif defined(Q_OS_MACOS) - QScopedPointer _fileProvider; #endif };