New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactored lifetime control into separate lifetime classes #2676
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like these changes a lot. It is now clear how a specific platform handles lifetime and there should be less confusion when Application is used.
If we really need a public collection of active windows we should think about maintaining this collection somewhere else.
src/Avalonia.Controls/Application.cs
Outdated
/// The main window. | ||
/// </value> | ||
public Window MainWindow { get; set; } | ||
|
||
/// <summary> | ||
/// Gets the open windows of the application. | ||
/// </summary> | ||
/// <value> | ||
/// The windows. | ||
/// </value> | ||
public WindowCollection Windows { get; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should think about moving this back to Window
itself or make this a member of IClassicDesktopStyleApplicationLifetime
. If Application.Current.ApplicationLifetime
is of that interface we can access this otherwise we don't need it anyways.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking about adding Created
and Closed
routed events, so a class like WindowsCollection
can be implemented without actually touching the Window
code and without mandatory global state. Then we can make it an opt-in feature that is enabled with UseGlobalWindowsCollection()
while desktop lifetime keeps its own window list.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the idea of driving it via events instead of it being a global list.
} | ||
|
||
/// <inheritdoc/> | ||
public event EventHandler<ControlledApplicationLifetimeStartupEventArgs> Startup; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How do I subscribe to this event before it is being raised? This should be possible within the AppBuilder. A Startup, Exit action would be enough I guess. Maybe I have missed something here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess we could move it to an earlier point of application initialization, so even platform initialization callbacks would have access to it via AppBuilder.Instance.ApplicationLifetime
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, actually, it's already set before calling SetupWithoutStarting()
here: https://github.com/AvaloniaUI/Avalonia/pull/2676/files#diff-01bc1e09e99bb7c8853294c6b0b206a2R94
Added some docs: https://github.com/AvaloniaUI/Avalonia/wiki/Application-lifetimes |
This has broken a number of the samples (e.g. BindingDemo, RenderDemo). I think we need to update #2499 with the changes required by this PR and get that merged. |
|
Those samples hadn't even been updated for the changes to |
There was a missing Setup() call in |
See: #2564
The basic idea is to remove the lifetime control from Application class and make it something platform dependent.
Currently implemented lifetimes with interface hierarchy:
ClassicDesktopStyleApplicationLifetime
IClassicDesktopStyleApplicationLifetime
IControlledApplicationLifetime
LinuxFramebufferApplicationLifetime
IControlledApplicationLifetime
ISingleViewApplicationLifetime
Later we can add
MobileStyleDesktopApplicationLifetime
that implementsISingleViewApplicationLifetime
and shows that view in a single Window. That would improve the portability of x-plat applications that don't need multiple independent windows. We could also implement a navigation stack that uses overlays on mobile and native window dialogs on desktop.So, the initialization from the app perspective would look like this:
Application.Initialize
- load XAML and stuffApplication.OnFrameworkInitializationCompleted - we can do pretty much everything at this point,
ApplicationLifetime
property contains a valid value if application lifetime was configured. This is the most convenient place to setup the main window or the main view.IControlledApplicationLifetime.Started
- just before starting the main loop