From 179a368f9f771be23a5f203b1dea9d14a4561365 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 31 Jan 2024 16:35:40 +0800 Subject: [PATCH 01/22] Add option to do a fast enumeration of changes which ignores new, unexplored folders Signed-off-by: Claudio Cambra --- .../FileProviderEnumerator+SyncEngine.swift | 29 ++++++++++++------- .../FileProviderEnumerator.swift | 7 +++-- .../FileProviderExtension.swift | 19 +++++++++++- 3 files changed, 42 insertions(+), 13 deletions(-) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderEnumerator+SyncEngine.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderEnumerator+SyncEngine.swift index 0fed8a9a7..f9e0ab0c7 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderEnumerator+SyncEngine.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderEnumerator+SyncEngine.swift @@ -196,16 +196,22 @@ extension FileProviderEnumerator { dispatchGroup.wait() guard criticalError == nil else { + Logger.enumeration.error( + "Received critical error stopping further scanning: \(criticalError!.errorDescription, privacy: .public)" + ) return ([], [], [], [], error: criticalError) } var childDirectoriesToScan: [NextcloudItemMetadataTable] = [] - var candidateMetadatas: [NextcloudItemMetadataTable] = - if scanChangesOnly { - allUpdatedMetadatas + allNewMetadatas - } else { - allMetadatas - } + var candidateMetadatas: [NextcloudItemMetadataTable] + + if scanChangesOnly, fastEnumeration { + candidateMetadatas = allUpdatedMetadatas + } else if scanChangesOnly { + candidateMetadatas = allUpdatedMetadatas + allNewMetadatas + } else { + candidateMetadatas = allMetadatas + } for candidateMetadata in candidateMetadatas { if candidateMetadata.directory { @@ -213,6 +219,8 @@ extension FileProviderEnumerator { } } + Logger.enumeration.debug("Candidate metadatas for further scan: \(candidateMetadatas, privacy: .public)") + if childDirectoriesToScan.isEmpty { return ( metadatas: allMetadatas, newMetadatas: allNewMetadatas, @@ -221,11 +229,12 @@ extension FileProviderEnumerator { } for childDirectory in childDirectoriesToScan { + Logger.enumeration.debug( + "About to recursively scan: \(childDirectory.urlBase, privacy: .public) with etag: \(childDirectory.etag, privacy: .public)" + ) let childScanResult = scanRecursively( - childDirectory, - ncAccount: ncAccount, - ncKit: ncKit, - scanChangesOnly: scanChangesOnly) + childDirectory, ncAccount: ncAccount, ncKit: ncKit, scanChangesOnly: scanChangesOnly + ) allMetadatas += childScanResult.metadatas allNewMetadatas += childScanResult.newMetadatas diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderEnumerator.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderEnumerator.swift index dc6e30621..e74011e8f 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderEnumerator.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderEnumerator.swift @@ -28,21 +28,24 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator { private static let maxItemsPerFileProviderPage = 100 let ncAccount: NextcloudAccount let ncKit: NextcloudKit + let fastEnumeration: Bool var serverUrl: String = "" var isInvalidated = false private static func isSystemIdentifier(_ identifier: NSFileProviderItemIdentifier) -> Bool { identifier == .rootContainer || identifier == .trashContainer || identifier == .workingSet } - + init( enumeratedItemIdentifier: NSFileProviderItemIdentifier, ncAccount: NextcloudAccount, - ncKit: NextcloudKit + ncKit: NextcloudKit, + fastEnumeration: Bool = true ) { self.enumeratedItemIdentifier = enumeratedItemIdentifier self.ncAccount = ncAccount self.ncKit = ncKit + self.fastEnumeration = fastEnumeration if FileProviderEnumerator.isSystemIdentifier(enumeratedItemIdentifier) { Logger.enumeration.debug( diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift index 3bf161342..8a0d41fdf 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift @@ -51,6 +51,19 @@ import OSLog return session }() + // 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. + // We can instead do a fast enumeration where we only scan folders as the user navigates through + // them, thereby avoiding this issue; the trade-off is that we will be unable to detect + // materialised file moves to unexplored folders, therefore deleting the item when we could have + // just moved it instead. + // + // Since it's not desirable to cancel a long recursive enumeration half-way through, we do the + // fast enumeration by default. We prompt the user on the client side to run a proper, full + // enumeration if they want for safety. + var fastEnumeration = true + required init(domain: NSFileProviderDomain) { // The containing application must create a domain using // `NSFileProviderManager.add(_:, completionHandler:)`. The system will then launch the @@ -787,7 +800,11 @@ import OSLog } return FileProviderEnumerator( - enumeratedItemIdentifier: containerItemIdentifier, ncAccount: ncAccount, ncKit: ncKit) + enumeratedItemIdentifier: containerItemIdentifier, + ncAccount: ncAccount, + ncKit: ncKit, + fastEnumeration: fastEnumeration + ) } func materializedItemsDidChange(completionHandler: @escaping () -> Void) { From cac263f1746fea1ab297f50ddbdf5ad2c1a033eb Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Mon, 5 Feb 2024 16:56:12 +0800 Subject: [PATCH 02/22] Clean up properties and init/invalidate in FileProviderExtension Signed-off-by: Claudio Cambra --- .../FileProviderExtension.swift | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift index 8a0d41fdf..9c8ef65e9 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift @@ -25,16 +25,17 @@ import OSLog lazy var ncKitBackground = NKBackground(nkCommonInstance: ncKit.nkCommonInstance) lazy var socketClient: LocalSocketClient? = { guard let containerUrl = pathForAppGroupContainer() else { - Logger.fileProviderExtension.critical("Won't start client, no container url") - return nil + Logger.fileProviderExtension.critical("Won't start socket client, no container url") + return nil; } + let socketPath = containerUrl.appendingPathComponent( ".fileprovidersocket", conformingTo: .archive) let lineProcessor = FileProviderSocketLineProcessor(delegate: self) return LocalSocketClient(socketPath: socketPath.path, lineProcessor: lineProcessor) }() - let urlSessionIdentifier: String = "com.nextcloud.session.upload.fileproviderext" + let urlSessionIdentifier = "com.nextcloud.session.upload.fileproviderext" let urlSessionMaximumConnectionsPerHost = 5 lazy var urlSession: URLSession = { let configuration = URLSessionConfiguration.background(withIdentifier: urlSessionIdentifier) @@ -46,8 +47,10 @@ import OSLog configuration.sharedContainerIdentifier = appGroupIdentifier let session = URLSession( - configuration: configuration, delegate: ncKitBackground, - delegateQueue: OperationQueue.main) + configuration: configuration, + delegate: ncKitBackground, + delegateQueue: OperationQueue.main + ) return session }() @@ -65,7 +68,7 @@ import OSLog var fastEnumeration = true required init(domain: NSFileProviderDomain) { - // The containing application must create a domain using + // The containing application must create a domain using // `NSFileProviderManager.add(_:, completionHandler:)`. The system will then launch the // application extension process, call `FileProviderExtension.init(domain:)` to instantiate // the extension for that domain, and call methods on the instance. @@ -77,7 +80,8 @@ import OSLog func invalidate() { // TODO: cleanup any resources Logger.fileProviderExtension.debug( - "Extension for domain \(self.domain.displayName, privacy: .public) is being torn down") + "Extension for domain \(self.domain.displayName, privacy: .public) is being torn down" + ) } // MARK: NSFileProviderReplicatedExtension protocol methods From 1fc601423057e78043f78dda0b31fa5944ad485a Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Mon, 5 Feb 2024 16:57:52 +0800 Subject: [PATCH 03/22] Add a starter FileProviderConfig Signed-off-by: Claudio Cambra --- .../FileProviderExt/FileProviderConfig.swift | 18 ++++++++++++++++++ .../FileProviderExtension.swift | 1 + .../project.pbxproj | 6 +++++- 3 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderConfig.swift diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderConfig.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderConfig.swift new file mode 100644 index 000000000..3259d5659 --- /dev/null +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderConfig.swift @@ -0,0 +1,18 @@ +// +// FileProviderConfig.swift +// FileProviderExt +// +// Created by Claudio Cambra on 5/2/24. +// + +import FileProvider +import Foundation + +struct FileProviderConfig { + enum FileProviderConfigKey: String { + case fastEnumerationEnabled = "fastEnumerationEnabled" + } + + let domainIdentifier: NSFileProviderDomainIdentifier + +} diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift index 9c8ef65e9..1c422e114 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift @@ -66,6 +66,7 @@ import OSLog // fast enumeration by default. We prompt the user on the client side to run a proper, full // enumeration if they want for safety. var fastEnumeration = true + lazy var config = FileProviderConfig(domainIdentifier: domain.identifier) required init(domain: NSFileProviderDomain) { // The containing application must create a domain using diff --git a/shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj/project.pbxproj b/shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj/project.pbxproj index e93e15737..6149378d5 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj/project.pbxproj +++ b/shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj/project.pbxproj @@ -40,6 +40,7 @@ 53903D37295618A400D0B308 /* LineProcessor.h in Headers */ = {isa = PBXBuildFile; fileRef = 53903D36295618A400D0B308 /* LineProcessor.h */; settings = {ATTRIBUTES = (Public, ); }; }; 539158AC27BE71A900816F56 /* FinderSyncSocketLineProcessor.m in Sources */ = {isa = PBXBuildFile; fileRef = 539158AB27BE71A900816F56 /* FinderSyncSocketLineProcessor.m */; }; 53D056312970594F00988392 /* LocalFilesUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53D056302970594F00988392 /* LocalFilesUtils.swift */; }; + 53D666612B70C9A70042C03D /* FileProviderConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53D666602B70C9A70042C03D /* FileProviderConfig.swift */; }; 53ED472029C5E64200795DB1 /* FileProviderEnumerator+SyncEngine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53ED471F29C5E64200795DB1 /* FileProviderEnumerator+SyncEngine.swift */; }; 53ED472829C88E7000795DB1 /* NextcloudItemMetadataTable+NKFile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53ED472729C88E7000795DB1 /* NextcloudItemMetadataTable+NKFile.swift */; }; 53ED473029C9CE0B00795DB1 /* FileProviderExtension+ClientInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53ED472F29C9CE0B00795DB1 /* FileProviderExtension+ClientInterface.swift */; }; @@ -172,6 +173,7 @@ 539158B127BE891500816F56 /* LocalSocketClient.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LocalSocketClient.h; sourceTree = ""; }; 539158B227BEC98A00816F56 /* LocalSocketClient.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LocalSocketClient.m; sourceTree = ""; }; 53D056302970594F00988392 /* LocalFilesUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalFilesUtils.swift; sourceTree = ""; }; + 53D666602B70C9A70042C03D /* FileProviderConfig.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileProviderConfig.swift; sourceTree = ""; }; 53ED471F29C5E64200795DB1 /* FileProviderEnumerator+SyncEngine.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FileProviderEnumerator+SyncEngine.swift"; sourceTree = ""; }; 53ED472729C88E7000795DB1 /* NextcloudItemMetadataTable+NKFile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NextcloudItemMetadataTable+NKFile.swift"; sourceTree = ""; }; 53ED472F29C9CE0B00795DB1 /* FileProviderExtension+ClientInterface.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FileProviderExtension+ClientInterface.swift"; sourceTree = ""; }; @@ -272,9 +274,10 @@ 538E396B27F4765000FA63D5 /* FileProviderExt */ = { isa = PBXGroup; children = ( - 5350E4C72B0C368B00F276CB /* Services */, 5318AD8F29BF406500CBB71C /* Database */, 5352E85929B7BFB4002CE85C /* Extensions */, + 5350E4C72B0C368B00F276CB /* Services */, + 53D666602B70C9A70042C03D /* FileProviderConfig.swift */, 538E397027F4765000FA63D5 /* FileProviderEnumerator.swift */, 53ED471F29C5E64200795DB1 /* FileProviderEnumerator+SyncEngine.swift */, 538E396C27F4765000FA63D5 /* FileProviderExtension.swift */, @@ -592,6 +595,7 @@ buildActionMask = 2147483647; files = ( 5352E85B29B7BFE6002CE85C /* Progress+Extensions.swift in Sources */, + 53D666612B70C9A70042C03D /* FileProviderConfig.swift in Sources */, 536EFC36295E3C1100F4CB13 /* NextcloudAccount.swift in Sources */, 53ED473029C9CE0B00795DB1 /* FileProviderExtension+ClientInterface.swift in Sources */, 538E396D27F4765000FA63D5 /* FileProviderExtension.swift in Sources */, From f987bcd97aa58c12a6d785e2f221b76b6c7b0ede Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Mon, 5 Feb 2024 18:15:45 +0800 Subject: [PATCH 04/22] Add computed property to FileProviderConfig to get and set internal config Signed-off-by: Claudio Cambra --- .../FileProviderExt/FileProviderConfig.swift | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderConfig.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderConfig.swift index 3259d5659..3b827984d 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderConfig.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderConfig.swift @@ -15,4 +15,19 @@ struct FileProviderConfig { let domainIdentifier: NSFileProviderDomainIdentifier + private var internalConfig: [String: Any] { + get { + let defaults = UserDefaults.standard + if let settings = defaults.dictionary(forKey: domainIdentifier.rawValue) { + return settings + } + let dictionary: [String: Any] = [:] + defaults.setValue(dictionary, forKey: domainIdentifier.rawValue) + return dictionary + } + set { + let defaults = UserDefaults.standard + defaults.setValue(newValue, forKey: domainIdentifier.rawValue) + } + } } From 534b3a60d771f4af728609df154604d8f803abb9 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Mon, 5 Feb 2024 18:30:25 +0800 Subject: [PATCH 05/22] Add fastEnumerationEnabled property to config Signed-off-by: Claudio Cambra --- .../FileProviderExt/FileProviderConfig.swift | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderConfig.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderConfig.swift index 3b827984d..53e4d7890 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderConfig.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderConfig.swift @@ -9,7 +9,7 @@ import FileProvider import Foundation struct FileProviderConfig { - enum FileProviderConfigKey: String { + private enum ConfigKey: String { case fastEnumerationEnabled = "fastEnumerationEnabled" } @@ -30,4 +30,9 @@ struct FileProviderConfig { defaults.setValue(newValue, forKey: domainIdentifier.rawValue) } } + + var fastEnumerationEnabled: Bool { + get { internalConfig[ConfigKey.fastEnumerationEnabled.rawValue] as? Bool ?? true } + set { internalConfig[ConfigKey.fastEnumerationEnabled.rawValue] = newValue } + } } From a3e1d66707cd4ff9ef72e5291096aee85d36cc13 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Mon, 5 Feb 2024 18:30:41 +0800 Subject: [PATCH 06/22] Use value from config for fastEnumeration when creating enumerator Signed-off-by: Claudio Cambra --- .../FileProviderExt/FileProviderExtension.swift | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift index 1c422e114..2f93e8c47 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderExtension.swift @@ -65,7 +65,6 @@ import OSLog // Since it's not desirable to cancel a long recursive enumeration half-way through, we do the // fast enumeration by default. We prompt the user on the client side to run a proper, full // enumeration if they want for safety. - var fastEnumeration = true lazy var config = FileProviderConfig(domainIdentifier: domain.identifier) required init(domain: NSFileProviderDomain) { @@ -808,7 +807,7 @@ import OSLog enumeratedItemIdentifier: containerItemIdentifier, ncAccount: ncAccount, ncKit: ncKit, - fastEnumeration: fastEnumeration + fastEnumeration: config.fastEnumerationEnabled ) } From 9a8af68ddceb8c9009520e9bc683ef6f99a60292 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Mon, 5 Feb 2024 18:36:04 +0800 Subject: [PATCH 07/22] Add lazy var for whether the fastEnumeration value has actually been set in settings Signed-off-by: Claudio Cambra --- .../FileProviderExt/FileProviderConfig.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderConfig.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderConfig.swift index 53e4d7890..2e799c462 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderConfig.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderConfig.swift @@ -35,4 +35,6 @@ struct FileProviderConfig { get { internalConfig[ConfigKey.fastEnumerationEnabled.rawValue] as? Bool ?? true } set { internalConfig[ConfigKey.fastEnumerationEnabled.rawValue] = newValue } } + + lazy var fastEnumerationSet = internalConfig[ConfigKey.fastEnumerationEnabled.rawValue] != nil } From 8d3b676558035f8f9792d7c14f096ae9940e3462 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Mon, 5 Feb 2024 18:42:12 +0800 Subject: [PATCH 08/22] Add method to get state of fast enumeration setting Signed-off-by: Claudio Cambra --- .../FileProviderExt/Services/ClientCommunicationProtocol.h | 1 + .../Services/ClientCommunicationService.swift | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/Services/ClientCommunicationProtocol.h b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/Services/ClientCommunicationProtocol.h index 47eb6c95b..481f541c5 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/Services/ClientCommunicationProtocol.h +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/Services/ClientCommunicationProtocol.h @@ -25,6 +25,7 @@ password:(NSString *)password; - (void)removeAccountConfig; - (void)createDebugLogStringWithCompletionHandler:(void(^)(NSString *debugLogString, NSError *error))completionHandler; +- (void)getFastEnumerationStateWithCompletionHandler:(void(^)(BOOL enabled, BOOL set))completionHandler; @end diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/Services/ClientCommunicationService.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/Services/ClientCommunicationService.swift index ccdc1dc90..3b9364141 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/Services/ClientCommunicationService.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/Services/ClientCommunicationService.swift @@ -77,4 +77,10 @@ class ClientCommunicationService: NSObject, NSFileProviderServiceSource, NSXPCLi completionHandler(logs.joined(separator: "\n"), nil) } } + + func getFastEnumerationState(completionHandler: @escaping (Bool, Bool) -> Void) { + let enabled = fpExtension.config.fastEnumerationEnabled + let set = fpExtension.config.fastEnumerationSet + completionHandler(enabled, set) + } } From bbe48954be2c78d5a4f1eeb56a2500bf4068c16a Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Mon, 5 Feb 2024 18:50:29 +0800 Subject: [PATCH 09/22] Add method to set fast enumeration in client communication service Signed-off-by: Claudio Cambra --- .../Services/ClientCommunicationProtocol.h | 1 + .../Services/ClientCommunicationService.swift | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/Services/ClientCommunicationProtocol.h b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/Services/ClientCommunicationProtocol.h index 481f541c5..1ab5e8853 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/Services/ClientCommunicationProtocol.h +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/Services/ClientCommunicationProtocol.h @@ -26,6 +26,7 @@ - (void)removeAccountConfig; - (void)createDebugLogStringWithCompletionHandler:(void(^)(NSString *debugLogString, NSError *error))completionHandler; - (void)getFastEnumerationStateWithCompletionHandler:(void(^)(BOOL enabled, BOOL set))completionHandler; +- (void)setFastEnumerationEnabled:(BOOL)enabled; @end diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/Services/ClientCommunicationService.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/Services/ClientCommunicationService.swift index 3b9364141..648b686a1 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/Services/ClientCommunicationService.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/Services/ClientCommunicationService.swift @@ -83,4 +83,22 @@ class ClientCommunicationService: NSObject, NSFileProviderServiceSource, NSXPCLi let set = fpExtension.config.fastEnumerationSet completionHandler(enabled, set) } + + func setFastEnumerationEnabled(_ enabled: Bool) { + fpExtension.config.fastEnumerationEnabled = enabled + + guard enabled else { return } + // If enabled, start full enumeration + guard let fpManager = NSFileProviderManager(for: fpExtension.domain) else { + let domainName = self.fpExtension.domain.displayName + Logger.fileProviderExtension.error("Could not get file provider manager for domain \(domainName, privacy: .public), cannot run enumeration after fast enumeration setting change") + return + } + + fpManager.signalEnumerator(for: .workingSet) { error in + if error != nil { + Logger.fileProviderExtension.error("Error signalling enumerator for working set, received error: \(error!.localizedDescription, privacy: .public)") + } + } + } } From ae524c03467a177e06f1bde60b5a53e8590d55df Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 6 Feb 2024 13:34:47 +0800 Subject: [PATCH 10/22] Mark fileProviderAvailable as nodiscard Signed-off-by: Claudio Cambra --- src/gui/macOS/fileprovider.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/gui/macOS/fileprovider.h b/src/gui/macOS/fileprovider.h index 215a62dfb..8132c11b3 100644 --- a/src/gui/macOS/fileprovider.h +++ b/src/gui/macOS/fileprovider.h @@ -37,7 +37,7 @@ public: static FileProvider *instance(); ~FileProvider() override; - static bool fileProviderAvailable(); + [[nodiscard]] static bool fileProviderAvailable(); public slots: void createDebugArchiveForDomain(const QString &domainIdentifier, const QString &filename) const; From 90c26c3effd20c96c049f14098b2f4d23cba82cb Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 6 Feb 2024 13:35:01 +0800 Subject: [PATCH 11/22] Make XPC pointer publicly available Signed-off-by: Claudio Cambra --- src/gui/macOS/fileprovider.h | 2 ++ src/gui/macOS/fileprovider_mac.mm | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/src/gui/macOS/fileprovider.h b/src/gui/macOS/fileprovider.h index 8132c11b3..a76b29af8 100644 --- a/src/gui/macOS/fileprovider.h +++ b/src/gui/macOS/fileprovider.h @@ -39,6 +39,8 @@ public: [[nodiscard]] static bool fileProviderAvailable(); + [[nodiscard]] FileProviderXPC *xpc() const; + public slots: void createDebugArchiveForDomain(const QString &domainIdentifier, const QString &filename) const; diff --git a/src/gui/macOS/fileprovider_mac.mm b/src/gui/macOS/fileprovider_mac.mm index 94b1d9f01..d54608a6e 100644 --- a/src/gui/macOS/fileprovider_mac.mm +++ b/src/gui/macOS/fileprovider_mac.mm @@ -102,5 +102,10 @@ void FileProvider::createDebugArchiveForDomain(const QString &domainIdentifier, _xpc->createDebugArchiveForExtension(domainIdentifier, filename); } +FileProviderXPC *FileProvider::xpc() const +{ + return _xpc.get(); +} + } // namespace Mac } // namespace OCC From 913dcd70aec44183583ed088b8b408011556b148 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 6 Feb 2024 14:04:27 +0800 Subject: [PATCH 12/22] Remove wrapper method for creating debug archive, directly use FileProviderXPC Signed-off-by: Claudio Cambra --- src/gui/macOS/fileprovider.h | 3 --- src/gui/macOS/fileprovider_mac.mm | 5 ----- src/gui/macOS/fileprovidersettingscontroller_mac.mm | 8 +++++++- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/gui/macOS/fileprovider.h b/src/gui/macOS/fileprovider.h index a76b29af8..58d6fcc2b 100644 --- a/src/gui/macOS/fileprovider.h +++ b/src/gui/macOS/fileprovider.h @@ -41,9 +41,6 @@ public: [[nodiscard]] FileProviderXPC *xpc() const; -public slots: - void createDebugArchiveForDomain(const QString &domainIdentifier, const QString &filename) const; - private slots: void configureXPC(); diff --git a/src/gui/macOS/fileprovider_mac.mm b/src/gui/macOS/fileprovider_mac.mm index d54608a6e..807372b1a 100644 --- a/src/gui/macOS/fileprovider_mac.mm +++ b/src/gui/macOS/fileprovider_mac.mm @@ -97,11 +97,6 @@ void FileProvider::configureXPC() } } -void FileProvider::createDebugArchiveForDomain(const QString &domainIdentifier, const QString &filename) const -{ - _xpc->createDebugArchiveForExtension(domainIdentifier, filename); -} - FileProviderXPC *FileProvider::xpc() const { return _xpc.get(); diff --git a/src/gui/macOS/fileprovidersettingscontroller_mac.mm b/src/gui/macOS/fileprovidersettingscontroller_mac.mm index 17d277e5e..4c8e3d4c4 100644 --- a/src/gui/macOS/fileprovidersettingscontroller_mac.mm +++ b/src/gui/macOS/fileprovidersettingscontroller_mac.mm @@ -437,7 +437,13 @@ void FileProviderSettingsController::createDebugArchive(const QString &userIdAtH if (filename.isEmpty()) { return; } - FileProvider::instance()->createDebugArchiveForDomain(userIdAtHost, filename); + + const auto xpc = FileProvider::instance()->xpc(); + if (!xpc) { + qCWarning(lcFileProviderSettingsController) << "Could not create debug archive, FileProviderXPC is not available."; + return; + } + xpc->createDebugArchiveForExtension(userIdAtHost, filename); } FileProviderDomainSyncStatus *FileProviderSettingsController::domainSyncStatusForAccount(const QString &userIdAtHost) const From db9b9a64b4927fa1a2cdf2b7d8fda22aaf793bf3 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 6 Feb 2024 14:05:18 +0800 Subject: [PATCH 13/22] Add method to get fast enumeration state (if possible) in FileProviderXPC Signed-off-by: Claudio Cambra --- src/gui/macOS/fileproviderxpc.h | 3 +++ src/gui/macOS/fileproviderxpc_mac.mm | 21 +++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/gui/macOS/fileproviderxpc.h b/src/gui/macOS/fileproviderxpc.h index 9e234ae2e..af4a5fd7b 100644 --- a/src/gui/macOS/fileproviderxpc.h +++ b/src/gui/macOS/fileproviderxpc.h @@ -34,6 +34,9 @@ class FileProviderXPC : public QObject public: explicit FileProviderXPC(QObject *parent = nullptr); + // Returns enabled and set state of fast enumeration for the given extension + [[nodiscard]] std::optional> fastEnumerationStateForExtension(const QString &extensionAccountId) const; + public slots: void connectToExtensions(); void configureExtensions(); diff --git a/src/gui/macOS/fileproviderxpc_mac.mm b/src/gui/macOS/fileproviderxpc_mac.mm index 260804b71..5fb39debe 100644 --- a/src/gui/macOS/fileproviderxpc_mac.mm +++ b/src/gui/macOS/fileproviderxpc_mac.mm @@ -137,4 +137,25 @@ void FileProviderXPC::createDebugArchiveForExtension(const QString &extensionAcc } } +std::optional> FileProviderXPC::fastEnumerationStateForExtension(const QString &extensionAccountId) const +{ + qCInfo(lcFileProviderXPC) << "Checking if fast enumeration is enabled for extension" << extensionAccountId; + const auto service = (NSObject *)_clientCommServices.value(extensionAccountId); + if (service == nil) { + qCWarning(lcFileProviderXPC) << "Could not get service for extension" << extensionAccountId; + return std::nullopt; + } + + __block BOOL receivedFastEnumerationEnabled; // What is the value of the setting being used by the extension? + __block BOOL receivedFastEnumerationSet; // Has the setting been set by the user? + dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); + [service getFastEnumerationStateWithCompletionHandler:^(BOOL enabled, BOOL set) { + receivedFastEnumerationEnabled = enabled; + receivedFastEnumerationSet = set; + dispatch_semaphore_signal(semaphore); + }]; + dispatch_wait(semaphore, DISPATCH_TIME_FOREVER); + return std::optional>{{receivedFastEnumerationEnabled, receivedFastEnumerationSet}}; +} + } // namespace OCC::Mac From a02efd65f8771895080ea05e743e77c28ec219c1 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 6 Feb 2024 14:08:37 +0800 Subject: [PATCH 14/22] Add method in file provider xpc to set fast enumeration enabled state Signed-off-by: Claudio Cambra --- src/gui/macOS/fileproviderxpc.h | 2 ++ src/gui/macOS/fileproviderxpc_mac.mm | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/src/gui/macOS/fileproviderxpc.h b/src/gui/macOS/fileproviderxpc.h index af4a5fd7b..58c6a0211 100644 --- a/src/gui/macOS/fileproviderxpc.h +++ b/src/gui/macOS/fileproviderxpc.h @@ -44,6 +44,8 @@ public slots: void unauthenticateExtension(const QString &extensionAccountId) const; void createDebugArchiveForExtension(const QString &extensionAccountId, const QString &filename) const; + void setFastEnumerationEnabledForExtension(const QString &extensionAccountId, bool enabled) const; + private slots: void slotAccountStateChanged(AccountState::State state) const; diff --git a/src/gui/macOS/fileproviderxpc_mac.mm b/src/gui/macOS/fileproviderxpc_mac.mm index 5fb39debe..fb956030b 100644 --- a/src/gui/macOS/fileproviderxpc_mac.mm +++ b/src/gui/macOS/fileproviderxpc_mac.mm @@ -158,4 +158,11 @@ std::optional> FileProviderXPC::fastEnumerationStateForExt return std::optional>{{receivedFastEnumerationEnabled, receivedFastEnumerationSet}}; } +void FileProviderXPC::setFastEnumerationEnabledForExtension(const QString &extensionAccountId, bool enabled) const +{ + qCInfo(lcFileProviderXPC) << "Setting fast enumeration for extension" << extensionAccountId << "to" << enabled; + const auto service = (NSObject *)_clientCommServices.value(extensionAccountId); + [service setFastEnumerationEnabled:enabled]; +} + } // namespace OCC::Mac From 6db990183ef8f0ad624323a7c9ffc3fefaa63f31 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 6 Feb 2024 14:16:42 +0800 Subject: [PATCH 15/22] Add method to acquire fast enumeration enabled status in file provider settings controller Signed-off-by: Claudio Cambra --- src/gui/macOS/fileprovidersettingscontroller.h | 1 + src/gui/macOS/fileprovidersettingscontroller_mac.mm | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/src/gui/macOS/fileprovidersettingscontroller.h b/src/gui/macOS/fileprovidersettingscontroller.h index bf980fdf7..2db4ae883 100644 --- a/src/gui/macOS/fileprovidersettingscontroller.h +++ b/src/gui/macOS/fileprovidersettingscontroller.h @@ -44,6 +44,7 @@ public: [[nodiscard]] Q_INVOKABLE float localStorageUsageGbForAccount(const QString &userIdAtHost) const; [[nodiscard]] unsigned long long remoteStorageUsageForAccount(const QString &userIdAtHost) const; [[nodiscard]] Q_INVOKABLE float remoteStorageUsageGbForAccount(const QString &userIdAtHost) const; + [[nodiscard]] Q_INVOKABLE bool fastEnumerationEnabledForAccount(const QString &userIdAtHost) const; [[nodiscard]] Q_INVOKABLE QAbstractListModel *materialisedItemsModelForAccount(const QString &userIdAtHost); [[nodiscard]] Q_INVOKABLE FileProviderDomainSyncStatus *domainSyncStatusForAccount(const QString &userIdAtHost) const; diff --git a/src/gui/macOS/fileprovidersettingscontroller_mac.mm b/src/gui/macOS/fileprovidersettingscontroller_mac.mm index 4c8e3d4c4..b94224c7d 100644 --- a/src/gui/macOS/fileprovidersettingscontroller_mac.mm +++ b/src/gui/macOS/fileprovidersettingscontroller_mac.mm @@ -362,6 +362,18 @@ void FileProviderSettingsController::setVfsEnabledForAccount(const QString &user } } +bool FileProviderSettingsController::fastEnumerationEnabledForAccount(const QString &userIdAtHost) const +{ + const auto xpc = FileProvider::instance()->xpc(); + if (!xpc) { + return false; + } + if (const auto fastEnumerationState = xpc->fastEnumerationStateForExtension(userIdAtHost)) { + return fastEnumerationState->first; + } + return false; +} + unsigned long long FileProviderSettingsController::localStorageUsageForAccount(const QString &userIdAtHost) const { return d->localStorageUsageForAccount(userIdAtHost); From 5eb333cb8d3064f81db8196b7ba04467d69ff7bd Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 6 Feb 2024 14:30:25 +0800 Subject: [PATCH 16/22] Add method to set fast enumeration enabled in file provider settings controller Signed-off-by: Claudio Cambra --- src/gui/macOS/fileprovidersettingscontroller.h | 3 +++ .../macOS/fileprovidersettingscontroller_mac.mm | 14 ++++++++++++++ 2 files changed, 17 insertions(+) diff --git a/src/gui/macOS/fileprovidersettingscontroller.h b/src/gui/macOS/fileprovidersettingscontroller.h index 2db4ae883..6bc7fc010 100644 --- a/src/gui/macOS/fileprovidersettingscontroller.h +++ b/src/gui/macOS/fileprovidersettingscontroller.h @@ -51,6 +51,7 @@ public: public slots: void setVfsEnabledForAccount(const QString &userIdAtHost, const bool setEnabled); + void setFastEnumerationEnabledForAccount(const QString &userIdAtHost, const bool setEnabled); void createEvictionWindowForAccount(const QString &userIdAtHost); void signalFileProviderDomain(const QString &userIdAtHost); @@ -61,6 +62,8 @@ signals: void localStorageUsageForAccountChanged(const QString &userIdAtHost); void remoteStorageUsageForAccountChanged(const QString &userIdAtHost); void materialisedItemsForAccountChanged(const QString &userIdAtHost); + void fastEnumerationEnabledForAccountChanged(const QString &userIdAtHost); + void fastEnumerationSetForAccountChanged(const QString &userIdAtHost); private: explicit FileProviderSettingsController(QObject *parent = nullptr); diff --git a/src/gui/macOS/fileprovidersettingscontroller_mac.mm b/src/gui/macOS/fileprovidersettingscontroller_mac.mm index b94224c7d..3265f059b 100644 --- a/src/gui/macOS/fileprovidersettingscontroller_mac.mm +++ b/src/gui/macOS/fileprovidersettingscontroller_mac.mm @@ -374,6 +374,20 @@ bool FileProviderSettingsController::fastEnumerationEnabledForAccount(const QStr return false; } +void FileProviderSettingsController::setFastEnumerationEnabledForAccount(const QString &userIdAtHost, const bool setEnabled) +{ + const auto xpc = FileProvider::instance()->xpc(); + if (!xpc) { + // Reset state of UI elements + emit fastEnumerationEnabledForAccountChanged(userIdAtHost); + emit fastEnumerationSetForAccountChanged(userIdAtHost); + return; + } + xpc->setFastEnumerationEnabledForExtension(userIdAtHost, setEnabled); + emit fastEnumerationEnabledForAccountChanged(userIdAtHost); + emit fastEnumerationSetForAccountChanged(userIdAtHost); +} + unsigned long long FileProviderSettingsController::localStorageUsageForAccount(const QString &userIdAtHost) const { return d->localStorageUsageForAccount(userIdAtHost); From 23c1e554d0704989cabd1384158b1ccfaacafe76 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 6 Feb 2024 14:32:51 +0800 Subject: [PATCH 17/22] Add method to check if fast enumeration setting has been set in settings controller Signed-off-by: Claudio Cambra --- src/gui/macOS/fileprovidersettingscontroller.h | 1 + src/gui/macOS/fileprovidersettingscontroller_mac.mm | 12 ++++++++++++ 2 files changed, 13 insertions(+) diff --git a/src/gui/macOS/fileprovidersettingscontroller.h b/src/gui/macOS/fileprovidersettingscontroller.h index 6bc7fc010..43d17c043 100644 --- a/src/gui/macOS/fileprovidersettingscontroller.h +++ b/src/gui/macOS/fileprovidersettingscontroller.h @@ -45,6 +45,7 @@ public: [[nodiscard]] unsigned long long remoteStorageUsageForAccount(const QString &userIdAtHost) const; [[nodiscard]] Q_INVOKABLE float remoteStorageUsageGbForAccount(const QString &userIdAtHost) const; [[nodiscard]] Q_INVOKABLE bool fastEnumerationEnabledForAccount(const QString &userIdAtHost) const; + [[nodiscard]] Q_INVOKABLE bool fastEnumerationSetForAccount(const QString &userIdAtHost) const; [[nodiscard]] Q_INVOKABLE QAbstractListModel *materialisedItemsModelForAccount(const QString &userIdAtHost); [[nodiscard]] Q_INVOKABLE FileProviderDomainSyncStatus *domainSyncStatusForAccount(const QString &userIdAtHost) const; diff --git a/src/gui/macOS/fileprovidersettingscontroller_mac.mm b/src/gui/macOS/fileprovidersettingscontroller_mac.mm index 3265f059b..4a09b7a9f 100644 --- a/src/gui/macOS/fileprovidersettingscontroller_mac.mm +++ b/src/gui/macOS/fileprovidersettingscontroller_mac.mm @@ -362,6 +362,18 @@ void FileProviderSettingsController::setVfsEnabledForAccount(const QString &user } } +bool FileProviderSettingsController::fastEnumerationSetForAccount(const QString &userIdAtHost) const +{ + const auto xpc = FileProvider::instance()->xpc(); + if (!xpc) { + return false; + } + if (const auto state = xpc->fastEnumerationStateForExtension(userIdAtHost)) { + return state->second; + } + return false; +} + bool FileProviderSettingsController::fastEnumerationEnabledForAccount(const QString &userIdAtHost) const { const auto xpc = FileProvider::instance()->xpc(); From 1441a5e3a2e5eeabcf227259044ca472061bdfb5 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 6 Feb 2024 14:34:35 +0800 Subject: [PATCH 18/22] Make default of fast enumeration enabled method in file provider settings controller to be true Signed-off-by: Claudio Cambra --- src/gui/macOS/fileprovidersettingscontroller_mac.mm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/macOS/fileprovidersettingscontroller_mac.mm b/src/gui/macOS/fileprovidersettingscontroller_mac.mm index 4a09b7a9f..cd3749df5 100644 --- a/src/gui/macOS/fileprovidersettingscontroller_mac.mm +++ b/src/gui/macOS/fileprovidersettingscontroller_mac.mm @@ -378,12 +378,12 @@ bool FileProviderSettingsController::fastEnumerationEnabledForAccount(const QStr { const auto xpc = FileProvider::instance()->xpc(); if (!xpc) { - return false; + return true; } if (const auto fastEnumerationState = xpc->fastEnumerationStateForExtension(userIdAtHost)) { return fastEnumerationState->first; } - return false; + return true; } void FileProviderSettingsController::setFastEnumerationEnabledForAccount(const QString &userIdAtHost, const bool setEnabled) From 23ef72c4727a87ced7436d28c84257c947ff574a Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Tue, 6 Feb 2024 15:36:49 +0800 Subject: [PATCH 19/22] Add starter FileProviderFastEnumerationSettings QML component Signed-off-by: Claudio Cambra --- resources.qrc | 1 + .../FileProviderFastEnumerationSettings.qml | 42 +++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 src/gui/macOS/ui/FileProviderFastEnumerationSettings.qml diff --git a/resources.qrc b/resources.qrc index 79a38f1e6..7222e8c9f 100644 --- a/resources.qrc +++ b/resources.qrc @@ -67,5 +67,6 @@ src/gui/macOS/ui/FileProviderEvictionDialog.qml src/gui/macOS/ui/FileProviderSyncStatus.qml src/gui/macOS/ui/FileProviderStorageInfo.qml + src/gui/macOS/ui/FileProviderFastEnumerationSettings.qml diff --git a/src/gui/macOS/ui/FileProviderFastEnumerationSettings.qml b/src/gui/macOS/ui/FileProviderFastEnumerationSettings.qml new file mode 100644 index 000000000..f6b93595c --- /dev/null +++ b/src/gui/macOS/ui/FileProviderFastEnumerationSettings.qml @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2024 by Claudio Cambra + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +import QtQuick 2.15 +import QtQuick.Controls 2.15 +import QtQuick.Layouts 1.15 + +import Style 1.0 +import "../../filedetails" +import "../../tray" + +import com.nextcloud.desktopclient 1.0 + +Column { + id: root + + signal fastEnumerationEnabledToggled(bool enabled) + + property bool fastEnumerationSet: false + property bool fastEnumerationEnabled: true + + padding: 0 + + CheckBox { + id: fastEnumerationEnabledCheckBox + width: parent.width + text: qsTr("Enable fast sync") + checked: root.fastEnumerationEnabled + onClicked: root.fastEnumerationEnabledToggled(checked) + } +} From 6e55c84d188f10916fb9693a04d396f3565ce47a Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Mon, 19 Feb 2024 17:00:47 +0800 Subject: [PATCH 20/22] Instantiate and hook up FileProviderFastEnumerationSettings within FileProviderSettings Signed-off-by: Claudio Cambra --- src/gui/macOS/ui/FileProviderSettings.qml | 35 +++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/gui/macOS/ui/FileProviderSettings.qml b/src/gui/macOS/ui/FileProviderSettings.qml index f3844f245..c9fc2f23c 100644 --- a/src/gui/macOS/ui/FileProviderSettings.qml +++ b/src/gui/macOS/ui/FileProviderSettings.qml @@ -60,6 +60,8 @@ Page { padding: Style.standardSpacing ColumnLayout { + id: rootColumn + anchors { top: parent.top left: parent.left @@ -100,6 +102,39 @@ Page { syncStatus: root.controller.domainSyncStatusForAccount(root.accountUserIdAtHost) } + FileProviderFastEnumerationSettings { + id: fastEnumerationSettings + + Layout.fillWidth: true + + fastEnumerationSet: root.controller.fastEnumerationSetForAccount(root.accountUserIdAtHost) + fastEnumerationEnabled: root.controller.fastEnumerationEnabledForAccount(root.accountUserIdAtHost) + onFastEnumerationEnabledToggled: root.controller.setFastEnumerationEnabledForAccount(root.accountUserIdAtHost, enabled) + + padding: 0 + + Connections { + target: root.controller + + function updateFastEnumerationValues() { + fastEnumerationSettings.fastEnumerationEnabled = root.controller.fastEnumerationEnabledForAccount(root.accountUserIdAtHost); + fastEnumerationSettings.fastEnumerationSet = root.controller.fastEnumerationSetForAccount(root.accountUserIdAtHost); + } + + function onFastEnumerationEnabledForAccountChanged(accountUserIdAtHost) { + if (root.accountUserIdAtHost === accountUserIdAtHost) { + updateFastEnumerationValues(); + } + } + + function onFastEnumerationSetForAccountChanged(accountUserIdAtHost) { + if (root.accountUserIdAtHost === accountUserIdAtHost) { + updateFastEnumerationValues(); + } + } + } + } + FileProviderStorageInfo { id: storageInfo localUsedStorage: root.controller.localStorageUsageGbForAccount(root.accountUserIdAtHost) From 1a576a15d68d1b26d5610fd3484a09217262aa59 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Mon, 19 Feb 2024 17:01:03 +0800 Subject: [PATCH 21/22] Log setting change for fast enumeration in ClientCommunicationService Signed-off-by: Claudio Cambra --- .../FileProviderExt/Services/ClientCommunicationService.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/Services/ClientCommunicationService.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/Services/ClientCommunicationService.swift index 648b686a1..76a0f00ce 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/Services/ClientCommunicationService.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/Services/ClientCommunicationService.swift @@ -86,6 +86,7 @@ class ClientCommunicationService: NSObject, NSFileProviderServiceSource, NSXPCLi func setFastEnumerationEnabled(_ enabled: Bool) { fpExtension.config.fastEnumerationEnabled = enabled + Logger.fileProviderExtension.info("Fast enumeration setting changed to: \(enabled, privacy: .public)") guard enabled else { return } // If enabled, start full enumeration From d64d959b515677c05bdd9d7df69cb67814dc104c Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Mon, 19 Feb 2024 19:41:39 +0800 Subject: [PATCH 22/22] Add explainer about fast sync to file provider settings Signed-off-by: Claudio Cambra --- .../FileProviderFastEnumerationSettings.qml | 19 ++++++++++++++++++- theme/Style/Style.qml | 5 +++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/gui/macOS/ui/FileProviderFastEnumerationSettings.qml b/src/gui/macOS/ui/FileProviderFastEnumerationSettings.qml index f6b93595c..b40dad56b 100644 --- a/src/gui/macOS/ui/FileProviderFastEnumerationSettings.qml +++ b/src/gui/macOS/ui/FileProviderFastEnumerationSettings.qml @@ -30,7 +30,7 @@ Column { property bool fastEnumerationSet: false property bool fastEnumerationEnabled: true - padding: 0 + spacing: 0 CheckBox { id: fastEnumerationEnabledCheckBox @@ -39,4 +39,21 @@ Column { checked: root.fastEnumerationEnabled onClicked: root.fastEnumerationEnabledToggled(checked) } + + EnforcedPlainTextLabel { + id: fastEnumerationDescription + background: Rectangle { + color: Style.infoBoxBackgroundColor + border.width: Style.infoBoxBorderWidth + border.color: Style.infoBoxBorderColor + radius: Style.slightlyRoundedButtonRadius + } + width: parent.width + padding: Style.smallSpacing + text: qsTr("Fast sync will only sync changes in files and folders within folders that have been explored. " + + "This can significantly increase responsiveness on initial configuration of virtual files. " + + "However, it will cause redundant downloads of files moved to an unexplored folder. ") + wrapMode: Text.Wrap + visible: fastEnumerationEnabled + } } diff --git a/theme/Style/Style.qml b/theme/Style/Style.qml index 9dd321c4b..7410faa60 100644 --- a/theme/Style/Style.qml +++ b/theme/Style/Style.qml @@ -29,6 +29,11 @@ QtObject { readonly property color errorBoxBackgroundColor: Qt.rgba(0.89, 0.18, 0.18, 1) readonly property int errorBoxStripeWidth: 4 + // InfoBox colors + readonly property color infoBoxBackgroundColor: Qt.rgba(0, 0.51, 0.79, 0.1) + readonly property int infoBoxBorderWidth: 1 + readonly property color infoBoxBorderColor: Qt.rgba(0, 0.51, 0.79, 1) + // Fonts // We are using pixel size because this is cross platform comparable, point size isn't readonly property int topLinePixelSize: pixelSize