From 5813931ccf4af071f1732fe9f35ab18847c1c57a Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 26 Mar 2025 13:21:30 +0100 Subject: [PATCH 01/14] gui/macOS: Avoid leaking objc objects added to arrays and dicts The array/dict will retain them Signed-off-by: Claudio Cambra --- src/gui/macOS/fileproviderxpc_mac_utils.mm | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/gui/macOS/fileproviderxpc_mac_utils.mm b/src/gui/macOS/fileproviderxpc_mac_utils.mm index eb385d1c42..fe33492ad4 100644 --- a/src/gui/macOS/fileproviderxpc_mac_utils.mm +++ b/src/gui/macOS/fileproviderxpc_mac_utils.mm @@ -78,7 +78,6 @@ NSArray *> *get } else if (service == nil) { qCWarning(lcFileProviderXPCUtils) << "Service is nil"; } else { - [service retain]; [fpServices addObject:@{service.name: service}]; } dispatch_group_leave(group); @@ -191,7 +190,6 @@ NSArray *connectToFileProviderServices(NSArray Date: Wed, 26 Mar 2025 13:24:05 +0100 Subject: [PATCH 02/14] gui/macOS: Avoid unnecessary retain on alloced objects Fixes leaks Signed-off-by: Claudio Cambra --- src/gui/macOS/fileproviderdomainmanager_mac.mm | 1 - src/gui/macOS/fileprovidersettingscontroller_mac.mm | 1 - src/gui/updater/sparkleupdater_mac.mm | 3 --- 3 files changed, 5 deletions(-) diff --git a/src/gui/macOS/fileproviderdomainmanager_mac.mm b/src/gui/macOS/fileproviderdomainmanager_mac.mm index 233d5adac6..1e4807cd4b 100644 --- a/src/gui/macOS/fileproviderdomainmanager_mac.mm +++ b/src/gui/macOS/fileproviderdomainmanager_mac.mm @@ -275,7 +275,6 @@ public: NSFileProviderDomain * const fileProviderDomain = [[NSFileProviderDomain alloc] initWithIdentifier:domainId.toNSString() displayName:domainDisplayName.toNSString()]; - [fileProviderDomain retain]; [NSFileProviderManager addDomain:fileProviderDomain completionHandler:^(NSError * const error) { if(error) { diff --git a/src/gui/macOS/fileprovidersettingscontroller_mac.mm b/src/gui/macOS/fileprovidersettingscontroller_mac.mm index 9d083300c6..d1fd68e69c 100644 --- a/src/gui/macOS/fileprovidersettingscontroller_mac.mm +++ b/src/gui/macOS/fileprovidersettingscontroller_mac.mm @@ -194,7 +194,6 @@ public slots: [enumerator retain]; FileProviderStorageUseEnumerationObserver *const storageUseObserver = [[FileProviderStorageUseEnumerationObserver alloc] init]; - [storageUseObserver retain]; storageUseObserver.enumerationFinishedHandler = ^(NSError *const error) { qCInfo(lcFileProviderSettingsController) << "Enumeration finished for" << domain.identifier; if (error != nil) { diff --git a/src/gui/updater/sparkleupdater_mac.mm b/src/gui/updater/sparkleupdater_mac.mm index 05c868e1e8..7197ae807b 100644 --- a/src/gui/updater/sparkleupdater_mac.mm +++ b/src/gui/updater/sparkleupdater_mac.mm @@ -248,13 +248,10 @@ SparkleUpdater::SparkleUpdater(const QUrl& appCastUrl) , _interface(std::make_unique(this)) { _interface->delegate = [[NCSparkleUpdaterDelegate alloc] initWithOwner:_interface.get()]; - [_interface->delegate retain]; - _interface->updaterController = [[SPUStandardUpdaterController alloc] initWithStartingUpdater:YES updaterDelegate:_interface->delegate userDriverDelegate:nil]; - [_interface->updaterController retain]; setUpdateUrl(appCastUrl); From 74949beeab06db84d0ec030cf385c23edb3cb17d Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 26 Mar 2025 13:24:47 +0100 Subject: [PATCH 03/14] gui/macOS: Constify some Obj-C pointers Signed-off-by: Claudio Cambra --- src/gui/macOS/fileprovideritemmetadata_mac.mm | 2 +- src/gui/macOS/fileprovidermaterialiseditemsmodel_mac.mm | 2 +- src/gui/macOS/fileproviderxpc_mac_utils.mm | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/gui/macOS/fileprovideritemmetadata_mac.mm b/src/gui/macOS/fileprovideritemmetadata_mac.mm index d8e64abb68..ec96674709 100644 --- a/src/gui/macOS/fileprovideritemmetadata_mac.mm +++ b/src/gui/macOS/fileprovideritemmetadata_mac.mm @@ -120,7 +120,7 @@ QString FileProviderItemMetadata::getUserVisiblePath() const } __block QString returnPath = QObject::tr("Unknown"); - NSFileProviderManager *manager = FileProviderUtils::managerForDomainIdentifier(domainId); + NSFileProviderManager *const manager = FileProviderUtils::managerForDomainIdentifier(domainId); if (manager == nil) { qCWarning(lcMacImplFileProviderItemMetadata) << "Null manager, cannot get item path"; diff --git a/src/gui/macOS/fileprovidermaterialiseditemsmodel_mac.mm b/src/gui/macOS/fileprovidermaterialiseditemsmodel_mac.mm index ec1dd2ce0c..646f583b45 100644 --- a/src/gui/macOS/fileprovidermaterialiseditemsmodel_mac.mm +++ b/src/gui/macOS/fileprovidermaterialiseditemsmodel_mac.mm @@ -30,7 +30,7 @@ Q_LOGGING_CATEGORY(lcMacImplFileProviderMaterialisedItemsModelMac, "nextcloud.gu void FileProviderMaterialisedItemsModel::evictItem(const QString &identifier, const QString &domainIdentifier) { - NSFileProviderManager * const manager = FileProviderUtils::managerForDomainIdentifier(domainIdentifier); + NSFileProviderManager *const manager = FileProviderUtils::managerForDomainIdentifier(domainIdentifier); if (manager == nil) { qCWarning(lcMacImplFileProviderMaterialisedItemsModelMac) << "Received null manager for domain" << domainIdentifier diff --git a/src/gui/macOS/fileproviderxpc_mac_utils.mm b/src/gui/macOS/fileproviderxpc_mac_utils.mm index fe33492ad4..2d94f1f217 100644 --- a/src/gui/macOS/fileproviderxpc_mac_utils.mm +++ b/src/gui/macOS/fileproviderxpc_mac_utils.mm @@ -94,7 +94,7 @@ NSArray *> *get NSArray *getDomainUrlsForManagers(NSArray *managers) { dispatch_group_t group = dispatch_group_create(); - __block NSMutableArray *urls = NSMutableArray.array; + __block NSMutableArray *const urls = NSMutableArray.array; for (NSFileProviderManager *const manager in managers) { From ac96e80f04e2af00b84e48f3e0aaaaac08e7dc7b Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 26 Mar 2025 13:25:34 +0100 Subject: [PATCH 04/14] gui/macOS: Correctly retain/release manager and domain in sync status object Signed-off-by: Claudio Cambra --- src/gui/macOS/fileproviderdomainsyncstatus_mac.mm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gui/macOS/fileproviderdomainsyncstatus_mac.mm b/src/gui/macOS/fileproviderdomainsyncstatus_mac.mm index 17e77a680d..76e88d1fa8 100644 --- a/src/gui/macOS/fileproviderdomainsyncstatus_mac.mm +++ b/src/gui/macOS/fileproviderdomainsyncstatus_mac.mm @@ -41,6 +41,7 @@ public: qCWarning(lcMacFileProviderDomainSyncStatus) << "Could not get manager for domain" << domainIdentifier; return; } + [_manager retain]; if (@available(macOS 11.3, *)) { NSProgress *const downloadProgress = [_manager globalProgressForKind:NSProgressFileOperationKindDownloading]; @@ -61,6 +62,8 @@ public: { [_downloadProgressObserver release]; [_uploadProgressObserver release]; + [_domain release]; + [_manager release]; } void updateDownload(NSProgress *const progress) const From 6733adb2e883f8d79d2e34903596431f1dd9b70b Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 26 Mar 2025 13:26:38 +0100 Subject: [PATCH 05/14] gui/macOS: Do not leak local url and error objects in edit locally job Signed-off-by: Claudio Cambra --- src/gui/macOS/fileprovidereditlocallyjob_mac.mm | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/gui/macOS/fileprovidereditlocallyjob_mac.mm b/src/gui/macOS/fileprovidereditlocallyjob_mac.mm index f7ebd1d281..28ff7fd5b2 100644 --- a/src/gui/macOS/fileprovidereditlocallyjob_mac.mm +++ b/src/gui/macOS/fileprovidereditlocallyjob_mac.mm @@ -87,6 +87,9 @@ void FileProviderEditLocallyJob::openFileProviderFile(const QString &ocId) << ocId; emit notAvailable(); } + + [itemLocalUrl release]; + [receivedError release]; } } // namespace OCC::Mac From 8e95e97921bd483b78b71f2f7d4ab62c062b9ad2 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 26 Mar 2025 13:28:37 +0100 Subject: [PATCH 06/14] gui/macOS: Properly wait for eviction result in materialised items model Signed-off-by: Claudio Cambra --- src/gui/macOS/fileprovidermaterialiseditemsmodel_mac.mm | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/gui/macOS/fileprovidermaterialiseditemsmodel_mac.mm b/src/gui/macOS/fileprovidermaterialiseditemsmodel_mac.mm index 646f583b45..b2fe54011e 100644 --- a/src/gui/macOS/fileprovidermaterialiseditemsmodel_mac.mm +++ b/src/gui/macOS/fileprovidermaterialiseditemsmodel_mac.mm @@ -42,7 +42,8 @@ void FileProviderMaterialisedItemsModel::evictItem(const QString &identifier, co return; } - __block BOOL successfullyDeleted = YES; + __block BOOL successfullyDeleted = NO; + dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); [manager evictItemWithIdentifier:identifier.toNSString() completionHandler:^(NSError *error) { if (error != nil) { @@ -51,10 +52,13 @@ void FileProviderMaterialisedItemsModel::evictItem(const QString &identifier, co Systray::instance()->showMessage(tr("Error"), tr("An error occurred while trying to delete the local copy of this item: %1").arg(errorDesc), QSystemTrayIcon::Warning); - successfullyDeleted = NO; + } else { + successfullyDeleted = YES; } + dispatch_semaphore_signal(semaphore); }]; + dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, 3 * NSEC_PER_SEC)); if (successfullyDeleted == NO) { return; } From d1fbbf64f04ed3fc8d8c9962fe2df1943654928e Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 26 Mar 2025 13:31:00 +0100 Subject: [PATCH 07/14] gui/macOS: Correctly release objects received via FileProviderUtils functions Signed-off-by: Claudio Cambra --- src/gui/macOS/fileprovideritemmetadata_mac.mm | 2 ++ src/gui/macOS/fileprovidermaterialiseditemsmodel_mac.mm | 2 ++ src/gui/macOS/fileprovidersettingscontroller_mac.mm | 8 +++++++- src/gui/macOS/fileproviderutils.h | 4 ++++ 4 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/gui/macOS/fileprovideritemmetadata_mac.mm b/src/gui/macOS/fileprovideritemmetadata_mac.mm index ec96674709..8ff39979f9 100644 --- a/src/gui/macOS/fileprovideritemmetadata_mac.mm +++ b/src/gui/macOS/fileprovideritemmetadata_mac.mm @@ -147,6 +147,8 @@ QString FileProviderItemMetadata::getUserVisiblePath() const dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); dispatch_release(semaphore); + [manager release]; + return returnPath; } diff --git a/src/gui/macOS/fileprovidermaterialiseditemsmodel_mac.mm b/src/gui/macOS/fileprovidermaterialiseditemsmodel_mac.mm index b2fe54011e..cfa73a14a4 100644 --- a/src/gui/macOS/fileprovidermaterialiseditemsmodel_mac.mm +++ b/src/gui/macOS/fileprovidermaterialiseditemsmodel_mac.mm @@ -59,6 +59,8 @@ void FileProviderMaterialisedItemsModel::evictItem(const QString &identifier, co }]; dispatch_semaphore_wait(semaphore, dispatch_time(DISPATCH_TIME_NOW, 3 * NSEC_PER_SEC)); + [manager release]; + if (successfullyDeleted == NO) { return; } diff --git a/src/gui/macOS/fileprovidersettingscontroller_mac.mm b/src/gui/macOS/fileprovidersettingscontroller_mac.mm index d1fd68e69c..89e1b76e2b 100644 --- a/src/gui/macOS/fileprovidersettingscontroller_mac.mm +++ b/src/gui/macOS/fileprovidersettingscontroller_mac.mm @@ -167,6 +167,7 @@ public: qCInfo(lcFileProviderSettingsController) << "Signalling file provider domain" << userIdAtHost; NSFileProviderDomain * const domain = FileProviderUtils::domainForIdentifier(userIdAtHost); NSFileProviderManager * const manager = [NSFileProviderManager managerForDomain:domain]; + [domain release]; [manager signalEnumeratorForContainerItemIdentifier:NSFileProviderRootContainerItemIdentifier completionHandler:^(NSError *const error) { if (error != nil) { @@ -186,6 +187,7 @@ public: } public slots: + // NOTE: This method will release the provided args so make sure to retain them beforehand void enumerateMaterialisedFilesForDomainManager(NSFileProviderManager * const managerForDomain, NSFileProviderDomain * const domain) { @@ -228,6 +230,9 @@ public slots: [storageUseObserver release]; [enumerator release]; + + [managerForDomain release]; + [domain release]; }; [enumerator enumerateItemsForObserver:storageUseObserver startingAtPage:NSFileProviderInitialPageSortedByName]; } @@ -283,7 +288,8 @@ private: << ", returning early."; return; } - + [managerForDomain retain]; + [domain retain]; enumerateMaterialisedFilesForDomainManager(managerForDomain, domain); } }]; diff --git a/src/gui/macOS/fileproviderutils.h b/src/gui/macOS/fileproviderutils.h index 063be6d6d4..8a710fccf9 100644 --- a/src/gui/macOS/fileproviderutils.h +++ b/src/gui/macOS/fileproviderutils.h @@ -29,6 +29,10 @@ class QString; * * You should threfore try to avoid using this in C++ code wherever possible * and only use this in *_mac.mm implementation files. + * + * IMPORTANT: All Objective-C objects returned here need to be released! + * They have been internally retained due to the async nature of the + * FileProvider API. */ namespace OCC { From 09c8af737180b96960202f83d29cd6514549180c Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 26 Mar 2025 13:34:59 +0100 Subject: [PATCH 08/14] gui/macOS: Use explicit type in connections array arg Signed-off-by: Claudio Cambra --- src/gui/macOS/fileproviderxpc_mac_utils.h | 2 +- src/gui/macOS/fileproviderxpc_mac_utils.mm | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gui/macOS/fileproviderxpc_mac_utils.h b/src/gui/macOS/fileproviderxpc_mac_utils.h index f66d585f63..00b70c9e09 100644 --- a/src/gui/macOS/fileproviderxpc_mac_utils.h +++ b/src/gui/macOS/fileproviderxpc_mac_utils.h @@ -29,6 +29,6 @@ NSArray *connectToFileProviderServices(NSArray *clientCommService); -QHash processClientCommunicationConnections(NSArray *connections); +QHash processClientCommunicationConnections(NSArray *connections); } \ No newline at end of file diff --git a/src/gui/macOS/fileproviderxpc_mac_utils.mm b/src/gui/macOS/fileproviderxpc_mac_utils.mm index 2d94f1f217..4549f4853a 100644 --- a/src/gui/macOS/fileproviderxpc_mac_utils.mm +++ b/src/gui/macOS/fileproviderxpc_mac_utils.mm @@ -249,7 +249,7 @@ NSString *getExtensionAccountId(NSObject *const cli return extensionNcAccount; } -QHash processClientCommunicationConnections(NSArray *const connections) +QHash processClientCommunicationConnections(NSArray *const connections) { QHash clientCommServices; From 9d07744752b4d1ab06272067e8af44be0113ae84 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 26 Mar 2025 13:35:41 +0100 Subject: [PATCH 09/14] gui/macOS: Do not leak debug log string after use Signed-off-by: Claudio Cambra --- src/gui/macOS/fileproviderxpc_mac.mm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/gui/macOS/fileproviderxpc_mac.mm b/src/gui/macOS/fileproviderxpc_mac.mm index 60fe7c2a54..227e48d653 100644 --- a/src/gui/macOS/fileproviderxpc_mac.mm +++ b/src/gui/macOS/fileproviderxpc_mac.mm @@ -148,6 +148,8 @@ void FileProviderXPC::createDebugArchiveForExtension(const QString &extensionAcc } else { qCWarning(lcFileProviderXPC) << "Could not open debug log file" << filename; } + + [rcvdDebugLogString release]; } bool FileProviderXPC::fileProviderExtReachable(const QString &extensionAccountId, const bool retry, const bool reconfigureOnFail) From 16a59fcd19c46a757749d29632336d0afe3701d4 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 26 Mar 2025 13:44:03 +0100 Subject: [PATCH 10/14] gui/macOS: Improve overall memory management in XPCUtils::getDomainManagers Signed-off-by: Claudio Cambra --- src/gui/macOS/fileproviderxpc_mac_utils.mm | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/gui/macOS/fileproviderxpc_mac_utils.mm b/src/gui/macOS/fileproviderxpc_mac_utils.mm index 4549f4853a..344031144f 100644 --- a/src/gui/macOS/fileproviderxpc_mac_utils.mm +++ b/src/gui/macOS/fileproviderxpc_mac_utils.mm @@ -30,7 +30,7 @@ Q_LOGGING_CATEGORY(lcFileProviderXPCUtils, "nextcloud.gui.macos.fileprovider.xpc NSArray *getDomainManagers() { dispatch_group_t group = dispatch_group_create(); - __block NSMutableArray *managers = NSMutableArray.array; + __block NSMutableArray *const managers = NSMutableArray.array; dispatch_group_enter(group); @@ -45,8 +45,11 @@ NSArray *getDomainManagers() for (NSFileProviderDomain *const domain in domains) { qCInfo(lcFileProviderXPCUtils) << "Got domain" << domain.identifier; NSFileProviderManager *const manager = [NSFileProviderManager managerForDomain:domain]; - [manager retain]; - [managers addObject:manager]; + if (manager) { + [managers addObject:manager]; + } else { + qCWarning(lcFileProviderXPCUtils) << "Could not get manager for domain" << domain.identifier; + } } dispatch_group_leave(group); From 2ee5c2628b8c3d299cad4d2c056728e9f52b58ea Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 26 Mar 2025 13:44:28 +0100 Subject: [PATCH 11/14] gui/macOS: Avoid retain call on extensionNcAccount by allocing new string Signed-off-by: Claudio Cambra --- src/gui/macOS/fileproviderxpc_mac_utils.mm | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/gui/macOS/fileproviderxpc_mac_utils.mm b/src/gui/macOS/fileproviderxpc_mac_utils.mm index 344031144f..42aefe9a30 100644 --- a/src/gui/macOS/fileproviderxpc_mac_utils.mm +++ b/src/gui/macOS/fileproviderxpc_mac_utils.mm @@ -244,8 +244,7 @@ NSString *getExtensionAccountId(NSObject *const cli dispatch_group_leave(group); return; } - extensionNcAccount = [NSString stringWithString:extensionAccountId]; - [extensionNcAccount retain]; + extensionNcAccount = [[NSString alloc] initWithString:extensionAccountId]; dispatch_group_leave(group); }]; dispatch_group_wait(group, DISPATCH_TIME_FOREVER); From 3a55aba2d321201545972d623d0225ba99c4a599 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 26 Mar 2025 17:53:42 +0100 Subject: [PATCH 12/14] gui/macOS: Avoid crash from bad manager release Signed-off-by: Claudio Cambra --- src/gui/macOS/fileprovideritemmetadata_mac.mm | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/gui/macOS/fileprovideritemmetadata_mac.mm b/src/gui/macOS/fileprovideritemmetadata_mac.mm index 8ff39979f9..9a4e00c89b 100644 --- a/src/gui/macOS/fileprovideritemmetadata_mac.mm +++ b/src/gui/macOS/fileprovideritemmetadata_mac.mm @@ -122,7 +122,7 @@ QString FileProviderItemMetadata::getUserVisiblePath() const __block QString returnPath = QObject::tr("Unknown"); NSFileProviderManager *const manager = FileProviderUtils::managerForDomainIdentifier(domainId); - if (manager == nil) { + if (manager == nil) { qCWarning(lcMacImplFileProviderItemMetadata) << "Null manager, cannot get item path"; return returnPath; } @@ -147,8 +147,6 @@ QString FileProviderItemMetadata::getUserVisiblePath() const dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); dispatch_release(semaphore); - [manager release]; - return returnPath; } From 0c57f0c45ac8e13b2fec62ae16b57923ba2f748f Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Thu, 27 Mar 2025 11:45:13 +0100 Subject: [PATCH 13/14] gui/macOS: Avoid need to retain/release things in file provider edit locally Signed-off-by: Claudio Cambra --- .../macOS/fileprovidereditlocallyjob_mac.mm | 58 ++++++++----------- 1 file changed, 25 insertions(+), 33 deletions(-) diff --git a/src/gui/macOS/fileprovidereditlocallyjob_mac.mm b/src/gui/macOS/fileprovidereditlocallyjob_mac.mm index 28ff7fd5b2..ec5ffcc755 100644 --- a/src/gui/macOS/fileprovidereditlocallyjob_mac.mm +++ b/src/gui/macOS/fileprovidereditlocallyjob_mac.mm @@ -44,8 +44,7 @@ void FileProviderEditLocallyJob::openFileProviderFile(const QString &ocId) NSFileProviderDomain *const domain = (NSFileProviderDomain *)voidDomain; if (domain == nil) { - qCWarning(lcFileProviderEditLocallyMacJob) << "Could not get domain for account:" - << userId; + qCWarning(lcFileProviderEditLocallyMacJob) << "Could not get domain for account:" << userId; emit notAvailable(); } @@ -56,40 +55,33 @@ void FileProviderEditLocallyJob::openFileProviderFile(const QString &ocId) emit notAvailable(); } - dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); - __block NSError *receivedError; - __block NSURL *itemLocalUrl; [manager getUserVisibleURLForItemIdentifier:nsOcId completionHandler:^(NSURL *const url, NSError *const error) { - [url retain]; - [error retain]; - itemLocalUrl = url; - receivedError = error; - dispatch_semaphore_signal(semaphore); + + dispatch_async(dispatch_get_main_queue(), ^{ + Systray::instance()->destroyEditFileLocallyLoadingDialog(); + }); + + if (error != nil) { + const auto errorMessage = QString::fromNSString(error.localizedDescription); + qCWarning(lcFileProviderEditLocallyMacJob) << "Error getting user visible URL for item:" << errorMessage; + dispatch_async(dispatch_get_main_queue(), ^{ + emit notAvailable(); + }); + } else if (url != nil) { + const auto itemLocalPath = QString::fromNSString(url.path); + qCDebug(lcFileProviderEditLocallyMacJob) << "Got user visible URL for item:" << itemLocalPath; + [NSWorkspace.sharedWorkspace openURL:url]; + dispatch_async(dispatch_get_main_queue(), ^{ + emit finished(); + }); + } else { + qCWarning(lcFileProviderEditLocallyMacJob) << "Got nil user visible URL for item" << ocId; + dispatch_async(dispatch_get_main_queue(), ^{ + emit notAvailable(); + }); + } }]; - dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); - - Systray::instance()->destroyEditFileLocallyLoadingDialog(); - - if (receivedError != nil) { - const auto errorMessage = QString::fromNSString(receivedError.localizedDescription); - qCWarning(lcFileProviderEditLocallyMacJob) << "Error getting user visible URL for item" - << ocId << ":" << errorMessage; - emit notAvailable(); - } else if (itemLocalUrl != nil) { - const auto itemLocalPath = QString::fromNSString(itemLocalUrl.path); - qCDebug(lcFileProviderEditLocallyMacJob) << "Got user visible URL for item" - << ocId << ":" << itemLocalPath; - [NSWorkspace.sharedWorkspace openURL:itemLocalUrl]; - emit finished(); - } else { - qCWarning(lcFileProviderEditLocallyMacJob) << "Got nil user visible URL for item" - << ocId; - emit notAvailable(); - } - - [itemLocalUrl release]; - [receivedError release]; } } // namespace OCC::Mac From 499ca78f687b8a053a32df4a379a2c5876f2e86f Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Thu, 27 Mar 2025 13:07:37 +0100 Subject: [PATCH 14/14] gui/macOS: Properly retain/release NSFileProviderManager(s) Signed-off-by: Claudio Cambra --- src/gui/macOS/fileprovidereditlocallyjob_mac.mm | 2 ++ src/gui/macOS/fileprovideritemmetadata_mac.mm | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/gui/macOS/fileprovidereditlocallyjob_mac.mm b/src/gui/macOS/fileprovidereditlocallyjob_mac.mm index ec5ffcc755..483fc08ece 100644 --- a/src/gui/macOS/fileprovidereditlocallyjob_mac.mm +++ b/src/gui/macOS/fileprovidereditlocallyjob_mac.mm @@ -55,6 +55,7 @@ void FileProviderEditLocallyJob::openFileProviderFile(const QString &ocId) emit notAvailable(); } + [manager retain]; [manager getUserVisibleURLForItemIdentifier:nsOcId completionHandler:^(NSURL *const url, NSError *const error) { @@ -81,6 +82,7 @@ void FileProviderEditLocallyJob::openFileProviderFile(const QString &ocId) emit notAvailable(); }); } + [manager release]; }]; } diff --git a/src/gui/macOS/fileprovideritemmetadata_mac.mm b/src/gui/macOS/fileprovideritemmetadata_mac.mm index 9a4e00c89b..8b79a60bd3 100644 --- a/src/gui/macOS/fileprovideritemmetadata_mac.mm +++ b/src/gui/macOS/fileprovideritemmetadata_mac.mm @@ -132,6 +132,7 @@ QString FileProviderItemMetadata::getUserVisiblePath() const // getUserVisibleUrl is async, so wait here + [manager retain]; [manager getUserVisibleURLForItemIdentifier:nsItemIdentifier completionHandler:^(NSURL *const userVisibleFile, NSError *const error) { @@ -141,6 +142,7 @@ QString FileProviderItemMetadata::getUserVisiblePath() const returnPath = QString::fromNSString(userVisibleFile.path); } + [manager release]; dispatch_semaphore_signal(semaphore); }];