|
|
@@ -6,6 +6,7 @@ using System.Reactive.Concurrency;
|
|
|
using System.Threading;
|
|
|
using Avalonia.Animation;
|
|
|
using Avalonia.Controls;
|
|
|
+using Avalonia.Controls.ApplicationLifetimes;
|
|
|
using Avalonia.Controls.Templates;
|
|
|
using Avalonia.Input;
|
|
|
using Avalonia.Input.Platform;
|
|
|
@@ -31,7 +32,7 @@ namespace Avalonia
|
|
|
/// method.
|
|
|
/// - Tracks the lifetime of the application.
|
|
|
/// </remarks>
|
|
|
- public class Application : IApplicationLifecycle, IGlobalDataTemplates, IGlobalStyles, IStyleRoot, IResourceNode
|
|
|
+ public class Application : IGlobalDataTemplates, IGlobalStyles, IStyleRoot, IResourceNode
|
|
|
{
|
|
|
/// <summary>
|
|
|
/// The application-global data templates.
|
|
|
@@ -43,8 +44,6 @@ namespace Avalonia
|
|
|
private readonly Styler _styler = new Styler();
|
|
|
private Styles _styles;
|
|
|
private IResourceDictionary _resources;
|
|
|
- private CancellationTokenSource _mainLoopCancellationTokenSource;
|
|
|
- private int _exitCode;
|
|
|
|
|
|
/// <summary>
|
|
|
/// Initializes a new instance of the <see cref="Application"/> class.
|
|
|
@@ -54,12 +53,6 @@ namespace Avalonia
|
|
|
Windows = new WindowCollection(this);
|
|
|
}
|
|
|
|
|
|
- /// <inheritdoc/>
|
|
|
- public event EventHandler<StartupEventArgs> Startup;
|
|
|
-
|
|
|
- /// <inheritdoc/>
|
|
|
- public event EventHandler<ExitEventArgs> Exit;
|
|
|
-
|
|
|
/// <inheritdoc/>
|
|
|
public event EventHandler<ResourcesChangedEventArgs> ResourcesChanged;
|
|
|
|
|
|
@@ -167,24 +160,6 @@ namespace Avalonia
|
|
|
/// <inheritdoc/>
|
|
|
IResourceNode IResourceNode.ResourceParent => null;
|
|
|
|
|
|
- /// <summary>
|
|
|
- /// Gets or sets the <see cref="ShutdownMode"/>. This property indicates whether the application is shutdown explicitly or implicitly.
|
|
|
- /// If <see cref="ShutdownMode"/> is set to OnExplicitShutdown the application is only closes if Shutdown is called.
|
|
|
- /// The default is OnLastWindowClose
|
|
|
- /// </summary>
|
|
|
- /// <value>
|
|
|
- /// The shutdown mode.
|
|
|
- /// </value>
|
|
|
- public ShutdownMode ShutdownMode { get; set; }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// Gets or sets the main window of the application.
|
|
|
- /// </summary>
|
|
|
- /// <value>
|
|
|
- /// The main window.
|
|
|
- /// </value>
|
|
|
- public Window MainWindow { get; set; }
|
|
|
-
|
|
|
/// <summary>
|
|
|
/// Gets the open windows of the application.
|
|
|
/// </summary>
|
|
|
@@ -192,172 +167,21 @@ namespace Avalonia
|
|
|
/// The windows.
|
|
|
/// </value>
|
|
|
public WindowCollection Windows { get; }
|
|
|
-
|
|
|
+
|
|
|
/// <summary>
|
|
|
- /// Gets or sets a value indicating whether this instance is shutting down.
|
|
|
+ /// Application lifetime, use it for things like setting the main window and exiting the app from code
|
|
|
+ /// Currently supported lifetimes are:
|
|
|
+ /// - <see cref="IClassicDesktopStyleApplicationLifetime"/>
|
|
|
+ /// - <see cref="ISingleViewLifetime"/>
|
|
|
+ /// - <see cref="IControlledApplicationLifetime"/>
|
|
|
/// </summary>
|
|
|
- /// <value>
|
|
|
- /// <c>true</c> if this instance is shutting down; otherwise, <c>false</c>.
|
|
|
- /// </value>
|
|
|
- internal bool IsShuttingDown { get; private set; }
|
|
|
+ public IApplicationLifetime ApplicationLifetime { get; set; }
|
|
|
|
|
|
/// <summary>
|
|
|
/// Initializes the application by loading XAML etc.
|
|
|
/// </summary>
|
|
|
public virtual void Initialize() { }
|
|
|
|
|
|
- /// <summary>
|
|
|
- /// Runs the application's main loop.
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// This will return when the <see cref="Avalonia.Controls.ShutdownMode"/> condition is met
|
|
|
- /// or <see cref="Shutdown(int)"/> was called.
|
|
|
- /// </remarks>
|
|
|
- /// <returns>The application's exit code that is returned to the operating system on termination.</returns>
|
|
|
- public int Run()
|
|
|
- {
|
|
|
- return Run(new CancellationTokenSource());
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// Runs the application's main loop.
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// This will return when the <see cref="Avalonia.Controls.ShutdownMode"/> condition is met
|
|
|
- /// or <see cref="Shutdown(int)"/> was called.
|
|
|
- /// This also returns when <see cref="ICloseable"/> is closed.
|
|
|
- /// </remarks>
|
|
|
- /// <param name="closable">The closable to track.</param>
|
|
|
- /// <returns>The application's exit code that is returned to the operating system on termination.</returns>
|
|
|
- public int Run(ICloseable closable)
|
|
|
- {
|
|
|
- closable.Closed += (s, e) => _mainLoopCancellationTokenSource?.Cancel();
|
|
|
-
|
|
|
- return Run(new CancellationTokenSource());
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// Runs the application's main loop.
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// This will return when the <see cref="Avalonia.Controls.ShutdownMode"/> condition is met
|
|
|
- /// or <see cref="Shutdown(int)"/> was called.
|
|
|
- /// </remarks>
|
|
|
- /// <param name="mainWindow">The window that is used as <see cref="MainWindow"/>
|
|
|
- /// when the <see cref="MainWindow"/> isn't already set.</param>
|
|
|
- /// <returns>The application's exit code that is returned to the operating system on termination.</returns>
|
|
|
- public int Run(Window mainWindow)
|
|
|
- {
|
|
|
- if (mainWindow == null)
|
|
|
- {
|
|
|
- throw new ArgumentNullException(nameof(mainWindow));
|
|
|
- }
|
|
|
-
|
|
|
- if (MainWindow == null)
|
|
|
- {
|
|
|
- if (!mainWindow.IsVisible)
|
|
|
- {
|
|
|
- mainWindow.Show();
|
|
|
- }
|
|
|
-
|
|
|
- MainWindow = mainWindow;
|
|
|
- }
|
|
|
-
|
|
|
- return Run(new CancellationTokenSource());
|
|
|
- }
|
|
|
- /// <summary>
|
|
|
- /// Runs the application's main loop.
|
|
|
- /// </summary>
|
|
|
- /// <remarks>
|
|
|
- /// This will return when the <see cref="Avalonia.Controls.ShutdownMode"/> condition is met
|
|
|
- /// or <see cref="Shutdown(int)"/> was called.
|
|
|
- /// This also returns when the <see cref="CancellationToken"/> is canceled.
|
|
|
- /// </remarks>
|
|
|
- /// <returns>The application's exit code that is returned to the operating system on termination.</returns>
|
|
|
- /// <param name="token">The token to track.</param>
|
|
|
- public int Run(CancellationToken token)
|
|
|
- {
|
|
|
- return Run(CancellationTokenSource.CreateLinkedTokenSource(token));
|
|
|
- }
|
|
|
-
|
|
|
- private int Run(CancellationTokenSource tokenSource)
|
|
|
- {
|
|
|
- if (IsShuttingDown)
|
|
|
- {
|
|
|
- throw new InvalidOperationException("Application is shutting down.");
|
|
|
- }
|
|
|
-
|
|
|
- if (_mainLoopCancellationTokenSource != null)
|
|
|
- {
|
|
|
- throw new InvalidOperationException("Application is already running.");
|
|
|
- }
|
|
|
-
|
|
|
- _mainLoopCancellationTokenSource = tokenSource;
|
|
|
-
|
|
|
- Dispatcher.UIThread.Post(() => OnStartup(new StartupEventArgs()), DispatcherPriority.Send);
|
|
|
-
|
|
|
- Dispatcher.UIThread.MainLoop(_mainLoopCancellationTokenSource.Token);
|
|
|
-
|
|
|
- if (!IsShuttingDown)
|
|
|
- {
|
|
|
- Shutdown(_exitCode);
|
|
|
- }
|
|
|
-
|
|
|
- return _exitCode;
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// Raises the <see cref="Startup"/> event.
|
|
|
- /// </summary>
|
|
|
- /// <param name="e">A <see cref="StartupEventArgs"/> that contains the event data.</param>
|
|
|
- protected virtual void OnStartup(StartupEventArgs e)
|
|
|
- {
|
|
|
- Startup?.Invoke(this, e);
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// Raises the <see cref="Exit"/> event.
|
|
|
- /// </summary>
|
|
|
- /// <param name="e">A <see cref="ExitEventArgs"/> that contains the event data.</param>
|
|
|
- protected virtual void OnExit(ExitEventArgs e)
|
|
|
- {
|
|
|
- Exit?.Invoke(this, e);
|
|
|
- }
|
|
|
-
|
|
|
- /// <inheritdoc/>
|
|
|
- public void Shutdown(int exitCode = 0)
|
|
|
- {
|
|
|
- if (IsShuttingDown)
|
|
|
- {
|
|
|
- throw new InvalidOperationException("Application is already shutting down.");
|
|
|
- }
|
|
|
-
|
|
|
- _exitCode = exitCode;
|
|
|
-
|
|
|
- IsShuttingDown = true;
|
|
|
-
|
|
|
- Windows.Clear();
|
|
|
-
|
|
|
- try
|
|
|
- {
|
|
|
- var e = new ExitEventArgs { ApplicationExitCode = _exitCode };
|
|
|
-
|
|
|
- OnExit(e);
|
|
|
-
|
|
|
- _exitCode = e.ApplicationExitCode;
|
|
|
- }
|
|
|
- finally
|
|
|
- {
|
|
|
- _mainLoopCancellationTokenSource?.Cancel();
|
|
|
-
|
|
|
- _mainLoopCancellationTokenSource = null;
|
|
|
-
|
|
|
- IsShuttingDown = false;
|
|
|
-
|
|
|
- Environment.ExitCode = _exitCode;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
/// <inheritdoc/>
|
|
|
bool IResourceProvider.TryGetResource(object key, out object value)
|
|
|
{
|
|
|
@@ -383,7 +207,6 @@ namespace Avalonia
|
|
|
.Bind<IInputManager>().ToConstant(InputManager)
|
|
|
.Bind<IKeyboardNavigationHandler>().ToTransient<KeyboardNavigationHandler>()
|
|
|
.Bind<IStyler>().ToConstant(_styler)
|
|
|
- .Bind<IApplicationLifecycle>().ToConstant(this)
|
|
|
.Bind<IScheduler>().ToConstant(AvaloniaScheduler.Instance)
|
|
|
.Bind<IDragDropDevice>().ToConstant(DragDropDevice.Instance)
|
|
|
.Bind<IPlatformDragSource>().ToTransient<InProcessDragSource>();
|
|
|
@@ -394,6 +217,11 @@ namespace Avalonia
|
|
|
.GetService<IRenderLoop>()?.Add(clock);
|
|
|
}
|
|
|
|
|
|
+ public virtual void OnFrameworkInitializationCompleted()
|
|
|
+ {
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
private void ThisResourcesChanged(object sender, ResourcesChangedEventArgs e)
|
|
|
{
|
|
|
ResourcesChanged?.Invoke(this, e);
|