diff --git a/OpenUtau/FilePicker.cs b/OpenUtau/FilePicker.cs index 4ffdceaa4..0044a9692 100644 --- a/OpenUtau/FilePicker.cs +++ b/OpenUtau/FilePicker.cs @@ -1,13 +1,22 @@ -using System.IO; +using System; +using System.IO; using System.Linq; using System.Threading.Tasks; using Avalonia.Controls; using Avalonia.Platform.Storage; +using Avalonia.Threading; using OpenUtau.Core; using OpenUtau.Core.Util; +#if MACOS +using MonoMac.Foundation; +using MonoMac.AppKit; +#endif namespace OpenUtau.App { internal class FilePicker { + #if MACOS + private static int NSAppInitState; + #endif public static FilePickerFileType ProjectFiles { get; } = new("Project Files") { Patterns = new[] { "*.ustx", "*.vsqx", "*.ust", "*.mid", "*.midi", "*.ufdata", "*.musicxml" }, }; @@ -45,6 +54,11 @@ internal class FilePicker { Patterns = new[] { "*.exe" }, }; public static FilePickerFileType APP { get; } = new("APP") { + AppleUniformTypeIdentifiers = new[] { + "com.apple.application-bundle", + "com.apple.package", + "public.executable" + }, Patterns = new[] { "*.app" }, }; public static FilePickerFileType PrefixMap { get; } = new("Prefix Map") { @@ -93,6 +107,45 @@ internal class FilePicker { var location = startLocation == null ? null : await window.StorageProvider.TryGetFolderFromPathAsync(startLocation); + #if MACOS + // Due to an avalonia bug, we need to call the native API for looking for APP + if (types.Contains(APP)) { + var tcs = new TaskCompletionSource(); + var title = ThemeManager.GetString(titleKey); + if (NSAppInitState.Equals(0)) { + NSAppInitState = 1; + NSApplication.Init(); + } + + NSApplication.SharedApplication.InvokeOnMainThread(() => { + try { + var panel = new NSOpenPanel(); + panel.Title = title; + panel.CanChooseFiles = true; + panel.CanChooseDirectories = false; + panel.AllowsMultipleSelection = false; + panel.TreatsFilePackagesAsDirectories = false; + + if (!string.IsNullOrEmpty(startLocation)) { + panel.DirectoryUrl = NSUrl.FromFilename(startLocation); + } + + var result = panel.RunModal(); + if (result == 1) { + tcs.SetResult(panel.Urls.FirstOrDefault()?.Path); + } else { + tcs.SetResult(null); + } + } catch (Exception ex) { + Console.WriteLine($"Exception: {ex}"); + tcs.SetException(ex); + } + }); + + return await tcs.Task; + } + #endif + var files = await window.StorageProvider.OpenFilePickerAsync( new FilePickerOpenOptions() { Title = ThemeManager.GetString(titleKey), diff --git a/OpenUtau/OpenUtau.csproj b/OpenUtau/OpenUtau.csproj index c04b628fd..48b5756ab 100644 --- a/OpenUtau/OpenUtau.csproj +++ b/OpenUtau/OpenUtau.csproj @@ -53,9 +53,11 @@ + + @@ -125,4 +127,7 @@ Resources.Designer.cs + + $(DefineConstants);MACOS + \ No newline at end of file