/* * private unsafe Task<string?> OpenFolderNfd() * { * // Have to run it in the thread pool to avoid blocking the main thread. * return RunAsyncMaybe(() => * { * byte* outPath; * * var result = sw_NFD_PickFolder(null, &outPath); * * return HandleNfdResult(result, outPath); * }); * } */ // ReSharper disable once MemberCanBeMadeStatic.Local private Task <string?> RunAsyncMaybe(Func <string?> action) { if (OperatingSystem.IsMacOS()) { // macOS seems pretty annoying about having the file dialog opened from the main windowing thread. // So we are forced to execute this synchronously on the main windowing thread. // nativefiledialog doesn't provide any form of async API, so this WILL lock up half the client. var tcs = new TaskCompletionSource <string?>(); _clyde.RunOnWindowThread(() => tcs.SetResult(action())); return(tcs.Task); } else { // Luckily, GTK Linux and COM Windows are both happily threaded. Yay! // * Actual attempts to have multiple file dialogs up at the same time, and the resulting crashes, // have shown that at least for GTK+ (Linux), just because it can handle being on any thread doesn't mean it handle being on two at the same time. // Testing system was Ubuntu 20.04. // COM on Windows might handle this, but honestly, who exactly wants to risk it? // In particular this could very well be an swnfd issue. return(Task.Run(() => { lock (this) { return action(); } })); } }