123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278 |
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.IO;
- using System.Linq;
- using System.Text.RegularExpressions;
- using System.Threading;
- using System.Threading.Tasks;
- using Avalonia;
- using Avalonia.Controls;
- using Avalonia.Controls.ApplicationLifetimes;
- using Avalonia.Threading;
- using PixiEditor.Extensions.Common.Localization;
- using PixiEditor.Extensions.Runtime;
- using PixiEditor.Helpers;
- using PixiEditor.Models.Controllers;
- using PixiEditor.Models.Dialogs;
- using PixiEditor.Models.ExceptionHandling;
- using PixiEditor.Models.IO;
- using PixiEditor.OperatingSystem;
- using PixiEditor.PixiAuth;
- using PixiEditor.Platform;
- using PixiEditor.Views;
- using PixiEditor.Views.Dialogs;
- using ViewModelMain = PixiEditor.ViewModels.ViewModelMain;
- using ViewModels_ViewModelMain = PixiEditor.ViewModels.ViewModelMain;
- namespace PixiEditor.Initialization;
- internal class ClassicDesktopEntry
- {
- public static ClassicDesktopEntry? Active { get; private set; }
- private bool restartQueued;
- private IClassicDesktopStyleApplicationLifetime desktop;
- public ClassicDesktopEntry(IClassicDesktopStyleApplicationLifetime desktop)
- {
- this.desktop = desktop;
- IActivatableLifetime? activable =
- (IActivatableLifetime?)App.Current.TryGetFeature(typeof(IActivatableLifetime));
- Active = this;
- if (activable != null)
- {
- activable.Activated += ActivableOnActivated;
- }
- desktop.Startup += Start;
- desktop.ShutdownRequested += ShutdownRequested;
- }
- private void ActivableOnActivated(object? sender, ActivatedEventArgs e)
- {
- if (e.Kind == ActivationKind.File && e is FileActivatedEventArgs fileActivatedEventArgs)
- {
- IOperatingSystem.Current.HandleActivatedWithFile(fileActivatedEventArgs);
- }
- else if (e.Kind == ActivationKind.OpenUri && e is ProtocolActivatedEventArgs openUriEventArgs)
- {
- IOperatingSystem.Current.HandleActivatedWithUri(openUriEventArgs);
- }
- }
- private void Start(object? sender, ControlledApplicationLifetimeStartupEventArgs e)
- {
- StartupArgs.Args = e.Args.ToList();
- string arguments = string.Join(' ', e.Args);
- InitOperatingSystem();
- bool safeMode = arguments.Contains("--safeMode", StringComparison.OrdinalIgnoreCase);
- if (ParseArgument(@"--crash (""?)([\w:\/\ -_.]+)\1", arguments, out Group[] groups))
- {
- try
- {
- CrashReport report = CrashReport.Parse(groups[2].Value);
- desktop.MainWindow = new CrashReportDialog(report);
- desktop.MainWindow.Show();
- }
- catch (Exception exception)
- {
- try
- {
- CrashHelper.SendExceptionInfo(exception, true);
- }
- finally
- {
- // TODO: find an avalonia replacement for messagebox
- //MessageBox.Show("Fatal error", $"Fatal error while trying to open crash report in App.OnStartup()\n{exception}");
- }
- }
- return;
- }
- #if !STEAM && !DEBUG
- if (!HandleNewInstance(Dispatcher.UIThread))
- {
- return;
- }
- #endif
- var extensionLoader = InitApp(safeMode);
- desktop.MainWindow = new MainWindow(extensionLoader);
- desktop.MainWindow.Show();
- }
- private void InitPlatform()
- {
- var platform = GetActivePlatform();
- IPlatform.RegisterPlatform(platform);
- platform.PerformHandshake();
- }
- public ExtensionLoader InitApp(bool safeMode)
- {
- LoadingWindow.ShowInNewThread();
- InitPlatform();
- ExtensionLoader extensionLoader = new ExtensionLoader(Paths.ExtensionPackagesPath, Paths.UserExtensionsPath);
- if (!safeMode)
- {
- extensionLoader.LoadExtensions();
- }
- return extensionLoader;
- }
- public void Restart()
- {
- restartQueued = true;
- desktop.TryShutdown();
- }
- private IPlatform GetActivePlatform()
- {
- #if STEAM || DEV_STEAM
- return new PixiEditor.Platform.Steam.SteamPlatform();
- #elif MSIX || MSIX_DEBUG
- return new PixiEditor.Platform.MSStore.MicrosoftStorePlatform();
- #else
- return new PixiEditor.Platform.Standalone.StandalonePlatform(Paths.ExtensionPackagesPath, GetApiUrl());
- #endif
- }
- private void InitOperatingSystem()
- {
- IOperatingSystem.RegisterOS(GetActiveOperatingSystem());
- }
- private IOperatingSystem GetActiveOperatingSystem()
- {
- #if WINDOWS
- return new PixiEditor.Windows.WindowsOperatingSystem();
- #elif LINUX
- return new PixiEditor.Linux.LinuxOperatingSystem();
- #elif MACOS
- return new PixiEditor.MacOs.MacOperatingSystem();
- #else
- throw new PlatformNotSupportedException("This platform is not supported");
- #endif
- }
- private bool HandleNewInstance(Dispatcher? dispatcher)
- {
- return IOperatingSystem.Current.HandleNewInstance(dispatcher, OpenInExisting, desktop);
- }
- private void OpenInExisting(string passedArgs, bool isInline)
- {
- if (desktop.MainWindow is MainWindow mainWindow)
- {
- mainWindow.BringIntoView();
- List<string> args = new List<string>();
- if (isInline)
- {
- args = CommandLineHelpers.SplitCommandLine(passedArgs)
- .ToList();
- }
- else if (File.Exists(passedArgs))
- {
- args = CommandLineHelpers.SplitCommandLine(File.ReadAllText(passedArgs))
- .ToList();
- File.Delete(passedArgs);
- }
- StartupArgs.Args = args;
- StartupArgs.Args.Add("--openedInExisting");
- ViewModels_ViewModelMain viewModel = (ViewModels_ViewModelMain)mainWindow.DataContext;
- viewModel.OnStartup();
- }
- }
- private bool ParseArgument(string pattern, string args, out Group[] groups)
- {
- Match match = Regex.Match(args, pattern, RegexOptions.IgnoreCase);
- groups = null;
- if (match.Success)
- {
- groups = match.Groups.Values.ToArray();
- }
- return match.Success;
- }
- private void ShutdownRequested(object? sender, ShutdownRequestedEventArgs e)
- {
- // TODO: Make sure this works
- var vm = ViewModels_ViewModelMain.Current;
- if (vm is null)
- return;
- e.Cancel = true;
- Dispatcher.UIThread.InvokeAsync(async () =>
- {
- await vm.CloseWindow();
- if (vm.DocumentManagerSubViewModel.Documents.Any(x => !x.AllChangesSaved))
- {
- await Dispatcher.UIThread.InvokeAsync(async () =>
- {
- ConfirmationType confirmation = await ConfirmationDialog.Show(
- new LocalizedString("SESSION_UNSAVED_DATA", "Shutdown"),
- $"Shutdown");
- if (confirmation == ConfirmationType.Yes)
- {
- if (restartQueued)
- {
- var process = Process.GetCurrentProcess().MainModule.FileName;
- desktop.Exit += (_, _) =>
- {
- Process.Start(process);
- };
- }
- desktop.Shutdown();
- }
- else
- {
- restartQueued = false;
- }
- });
- }
- else
- {
- if (restartQueued)
- {
- var process = Process.GetCurrentProcess().MainModule.FileName;
- desktop.Exit += (_, _) =>
- {
- Process.Start(process);
- };
- }
- desktop.Shutdown();
- }
- });
- }
- private string GetApiUrl()
- {
- string baseUrl = BuildConstants.PixiEditorApiUrl;
- #if DEBUG
- if (baseUrl.Contains('{') && baseUrl.Contains('}'))
- {
- string? envUrl = Environment.GetEnvironmentVariable("PIXIAUTH_API_URL");
- if (envUrl != null)
- {
- baseUrl = envUrl;
- }
- }
- #endif
- return baseUrl;
- }
- }
|