Skip to content
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

Hot Reload doesn't work on ARM devices #17

Closed
StefanKoell opened this issue Dec 2, 2024 · 33 comments
Closed

Hot Reload doesn't work on ARM devices #17

StefanKoell opened this issue Dec 2, 2024 · 33 comments

Comments

@StefanKoell
Copy link

Hi!

I was just trying out the version 2 with .net 9 in my project. For me it seems it doesn't work on my projects. Is there anything I can do to investigate/trouble shoot the issue. I don't see any errors or output - it just doesn't do anything.

@Kir-Antipov
Copy link
Owner

That's new! :D

First, you can check whether the HotReloadDemo from this repo works for you. If it does, you can create a debug build of HotAvalonia via dotnet pack -c Debug. After that, place the resulting artifacts in a local NuGet repository so you can reference and actually debug those from your project. Alternatively, you could directly wire HotAvalonia to your project using ProjectReference, however this approach might be a bit more time-consuming, in my opinion.

That said, could you provide a bit more details about your situation? Did it work previously, and did it stop functioning after upgrading to version 2.0.0? Which version of Avalonia are you using? Are there any HotAvalonia-related logs in the debug output at all?

@StefanKoell
Copy link
Author

Just tried the demo and get an exception when I start the project:

System.TypeInitializationException: The type initializer for 'HotAvalonia.Helpers.AvaloniaControlHelper' threw an exception.
 ---> System.InvalidOperationException: Method injection is not available in the current runtime environment.
   at HotAvalonia.Reflection.Inject.MethodInjector.ThrowNotSupportedException() in D:\src\3rdParty\HotAvalonia\src\HotAvalonia\Reflection\Inject\MethodInjector.cs:line 71
   at HotAvalonia.Reflection.Inject.MethodInjector.ThrowIfNotSupported() in D:\src\3rdParty\HotAvalonia\src\HotAvalonia\Reflection\Inject\MethodInjector.cs:line 62
   at HotAvalonia.Reflection.Inject.CallbackInjector.ThrowIfNotSupported() in D:\src\3rdParty\HotAvalonia\src\HotAvalonia\Reflection\Inject\CallbackInjector.cs:line 26
   at HotAvalonia.Reflection.Inject.CallbackInjector.Inject(MethodBase target, MethodBase callback, Object thisArg) in D:\src\3rdParty\HotAvalonia\src\HotAvalonia\Reflection\Inject\CallbackInjector.cs:line 56
   at HotAvalonia.Reflection.Inject.CallbackInjector.Inject(MethodBase target, Delegate callback) in D:\src\3rdParty\HotAvalonia\src\HotAvalonia\Reflection\Inject\CallbackInjector.cs:line 33
   at HotAvalonia.Helpers.AvaloniaControlHelper..cctor() in D:\src\3rdParty\HotAvalonia\src\HotAvalonia\Helpers\AvaloniaControlHelper.cs:line 60
   --- End of inner exception stack trace ---
   at HotAvalonia.Helpers.AvaloniaControlHelper.TryInjectPopulateOverride(FieldInfo populateOverride, Action`2 populate, IInjection& injection) in D:\src\3rdParty\HotAvalonia\src\HotAvalonia\Helpers\AvaloniaControlHelper.cs:line 181
   at HotAvalonia.AvaloniaControlInfo.TryInjectPopulateOverride(Action`2 populate, IInjection& injection) in D:\src\3rdParty\HotAvalonia\src\HotAvalonia\AvaloniaControlInfo.cs:line 178
   at HotAvalonia.AvaloniaControlManager.TryInjectPopulateCallback(AvaloniaControlInfo controlInfo, Func`3 onPopulate, IInjection& injection) in D:\src\3rdParty\HotAvalonia\src\HotAvalonia\AvaloniaControlManager.cs:line 185
   at HotAvalonia.AvaloniaControlManager..ctor(AvaloniaControlInfo controlInfo, String fileName) in D:\src\3rdParty\HotAvalonia\src\HotAvalonia\AvaloniaControlManager.cs:line 54
   at HotAvalonia.<AvaloniaHotReloadContext>FCFB87BCD535448D215DB8934D7FE21969B7ED1E758FBAB0D5F07728AF2E5BA04__AvaloniaProjectHotReloadContext.ResolveControlManager(AvaloniaControlInfo controlInfo, String rootPath) in D:\src\3rdParty\HotAvalonia\src\HotAvalonia\AvaloniaHotReloadContext.cs:line 328
   at HotAvalonia.<AvaloniaHotReloadContext>FCFB87BCD535448D215DB8934D7FE21969B7ED1E758FBAB0D5F07728AF2E5BA04__AvaloniaProjectHotReloadContext.<>c__DisplayClass3_0.<.ctor>b__0(AvaloniaControlInfo x) in D:\src\3rdParty\HotAvalonia\src\HotAvalonia\AvaloniaHotReloadContext.cs:line 210
   at System.Linq.Enumerable.ArraySelectIterator`2.MoveNext()
   at System.Linq.Enumerable.ToDictionary[TSource,TKey](IEnumerable`1 source, Func`2 keySelector, IEqualityComparer`1 comparer)
   at HotAvalonia.<AvaloniaHotReloadContext>FCFB87BCD535448D215DB8934D7FE21969B7ED1E758FBAB0D5F07728AF2E5BA04__AvaloniaProjectHotReloadContext..ctor(String rootPath, IEnumerable`1 controls) in D:\src\3rdParty\HotAvalonia\src\HotAvalonia\AvaloniaHotReloadContext.cs:line 209
   at HotAvalonia.AvaloniaHotReloadContext.FromUnverifiedAssembly(Assembly assembly) in D:\src\3rdParty\HotAvalonia\src\HotAvalonia\AvaloniaHotReloadContext.cs:line 98
   at HotAvalonia.AvaloniaHotReloadContext.<>c.<FromAppDomain>b__3_0(AppDomain _, Assembly asm) in D:\src\3rdParty\HotAvalonia\src\HotAvalonia\AvaloniaHotReloadContext.cs:line 53
   at HotAvalonia.<IHotReloadContext>FA614932B277A8AB8C28B128DB57ABBD7A321DA3554EB96F5C28D0FD1A657E5E4__AppDomainHotReloadContext.<.ctor>b__4_0(Assembly x) in D:\src\3rdParty\HotAvalonia\src\HotAvalonia\IHotReloadContext.cs:line 185
   at System.Linq.Enumerable.ArraySelectIterator`2.MoveNext()
   at System.Linq.Enumerable.IEnumerableWhereIterator`1.MoveNext()
   at System.Linq.Enumerable.SelectManySingleSelectorIterator`2.MoveNext()
   at System.Linq.Enumerable.IEnumerableWhereIterator`1.ToArray()
   at HotAvalonia.HotReloadContext.Combine(IEnumerable`1 contexts) in D:\src\3rdParty\HotAvalonia\src\HotAvalonia\IHotReloadContext.cs:line 82
   at HotAvalonia.<IHotReloadContext>FA614932B277A8AB8C28B128DB57ABBD7A321DA3554EB96F5C28D0FD1A657E5E4__AppDomainHotReloadContext..ctor(AppDomain appDomain, Func`3 contextFactory) in D:\src\3rdParty\HotAvalonia\src\HotAvalonia\IHotReloadContext.cs:line 184
   at HotAvalonia.HotReloadContext.FromAppDomain(AppDomain appDomain, Func`3 contextFactory) in D:\src\3rdParty\HotAvalonia\src\HotAvalonia\IHotReloadContext.cs:line 50
   at HotAvalonia.AvaloniaHotReloadContext.FromAppDomain(AppDomain appDomain) in D:\src\3rdParty\HotAvalonia\src\HotAvalonia\AvaloniaHotReloadContext.cs:line 53
   at HotAvalonia.AvaloniaHotReloadContext.FromAppDomain() in D:\src\3rdParty\HotAvalonia\src\HotAvalonia\AvaloniaHotReloadContext.cs:line 37
   at HotAvalonia.AvaloniaHotReloadExtensions.EnableHotReload(Application app, String appFilePath) in D:\src\3rdParty\HotAvalonia\src\HotAvalonia.Extensions\AvaloniaHotReloadExtensions.cs:line 112
   at HotReloadDemo.App.Initialize() in D:\src\3rdParty\HotAvalonia\samples\HotReloadDemo\App.axaml.cs:line 14
   at Avalonia.AppBuilder.SetupUnsafe() in /_/src/Avalonia.Controls/AppBuilder.cs:line 321
   at Avalonia.AppBuilder.Setup() in /_/src/Avalonia.Controls/AppBuilder.cs:line 303
   at Avalonia.AppBuilder.SetupWithLifetime(IApplicationLifetime lifetime) in /_/src/Avalonia.Controls/AppBuilder.cs:line 187
   at Avalonia.ClassicDesktopStyleApplicationLifetimeExtensions.StartWithClassicDesktopLifetime(AppBuilder builder, String[] args, ShutdownMode shutdownMode) in /_/src/Avalonia.Controls/ApplicationLifetimes/ClassicDesktopStyleApplicationLifetime.cs:line 219
   at HotReloadDemo.Program.Main(String[] args) in D:\src\3rdParty\HotAvalonia\samples\HotReloadDemo\Program.cs:line 9

One thing which may be at play here is the fact that I'm running Windows on ARM64 (Windows 11 24H2). Maybe it's related to that.

To answer your other questions: I did not use the previous version of HotAvalonia with that project. I tried it a while back on a different project.

Running my application (not the demo app) with HotAvalonia 2, I don't see anything in the console and debug output related to HotAvalonia.

@Kir-Antipov
Copy link
Owner

One thing which may be at play here is the fact that I'm running Windows on ARM64 (Windows 11 24H2). Maybe it's related to that.

Yup, it is. Anything non-x86_64 (except for x86 Windows) is not really supported. I need a reliable method for performing method injections to enable HotAvalonia to operate at its fullest potential. Previously, I relied on a homebrewed cross-platform injection method for that, but it had quite a few pretty annoying limitations: firstly, it only supported unoptimized assemblies; secondly, since .NET 7, it required a debugger to be attached to the application. To address these issues, I decided to switch to MonoMod for a bit more competent injection capabilities. And just in time! As .NET 9 rendered my homebrewed injection method completely obsolete (which is quite sad, because I've been using it since the .NET Framework era). However, MonoMod only supports x86_64 Linux, macOS, and Windows, along with x86 Windows. While this covers most users, it doesn't accommodate your scenario. Unfortunately, I have no control over this.

Running my application (not the demo app) with HotAvalonia 2, I don't see anything in the console and debug output related to HotAvalonia.

It should have at least blown up just like the demo app did. Did you forget to define the ENABLE_XAML_HOT_RELOAD constant maybe?

@StefanKoell
Copy link
Author

That's too bad 😞

I went over to MonoMod and see if there's already an issue for that but could only find a Linux and macOS issue with ARM CPUs. The one issue with Windows on ARM is closed. I would like to open an issue over there in hope the issue can be addressed but I'm clearly not a good fit as I have no idea what's actually needed or what the real problem/root cause is. Would you be able to submit an issue for that?

@Kir-Antipov
Copy link
Owner

MonoMod needs the ability to create ARM-specific stubs. There are requests for this functionality from users of ARM-based Macs and Linux machines, and many people are even willing to subsidize its development. However, progress has stalled because the main maintainer does not appear particularly interested in dedicating their time to it. So, unless someone steps up, implements and tests the necessary logic, and submits a PR, I don't think this is moving forward anytime soon.

That said, I can reintroduce injection-less hot reload for now. It's possible to hot reload controls (and controls only) without requiring any injections. I had actually already supported this scenario but got carried away with the new and improved functionality, which inadvertently broke that part of the codebase (whoops). Unfortunately, while controls will become hot-reloadable again, assets (such as images and icons) and resources (like styles and resource dictionaries) will not. Still, it's better than having nothing at all, I suppose.

@Kir-Antipov
Copy link
Owner

I'll update the issue title to reflect that we're primarily focusing on ARM support here, if that's alright with you. In the meantime, let me know if you've been able to get any sign of life from HotAvalonia for your existing projects (once again, I suspect that you forgot to specify the ENABLE_XAML_HOT_RELOAD constant) while I work on reintroducing injection-less support :)

@Kir-Antipov Kir-Antipov changed the title Troubleshooting Hot Reload doesn't work on ARM devices Dec 3, 2024
@StefanKoell
Copy link
Author

Btw, I checked the const ENABLE_XAML_HOT_RELOAD and can confirm that I have set it in the csproj file.

@Kir-Antipov
Copy link
Owner

The development branch should work on your machine now. I would greatly appreciate it if you could check out the demo once again :)

Btw, I checked the const ENABLE_XAML_HOT_RELOAD and can confirm that I have set it in the csproj file.

That's really strange. I either need an MRE, or it would be helpful if you could debug the app yourself. With the current information, I don't see how this could even ever happen.

@Kir-Antipov
Copy link
Owner

I don't see how this could even ever happen.

No, wait - it's practically impossible! At the very least, you should see the following message:

[HotReload] Enabling hot reload for assets...

Add this code somewhere in your project:

#if ENABLE_XAML_HOT_RELOAD && !DISABLE_XAML_HOT_RELOAD
    Debug.WriteLine("Hot reload should be enabled!");
#else
    Debug.WriteLine("Hot reload is disabled.");
#endif

Then, let me know what the output is.

@StefanKoell
Copy link
Author

Hi again! One mystery solved: hot reload wasn't active because the I put the DefineConstant in the wrong project. I put it in the startup project but I should have put it in the project where App.cs resides. After fixing that, I get debug outputs from HotReload. Sorry for hiccup!

I also tested the development branch and I'm afraid it's still not working for me :(

When the app starts up, I get the following:

[HotReload]Found an assembly containing Avalonia controls ('UI.Desktop') with its source project located at 'D:\src\...'.
[2]MonoMod.Utils: [MonoMod.Utils] Info: Version 25.0.7
[2]MonoMod.Core: [MonoMod.Core] Info: Version 1.2.1
[2]MonoMod.Utils: [MonoMod.Utils] Info: Platform info: Windows Arm64
[HotReload]Failed to subscribe to the 'Populate' event of 'avares://UI.Desktop/_Styles.axaml'. The control won't be reloaded upon file changes.
[HotReload]Failed to subscribe to the 'Populate' event of 'avares://UI.Desktop/Controls/Common/ColorDot.Styles.axaml'. The control won't be reloaded upon file changes.
...
...
...
[HotReload] Failed to subscribe to asset loading events. Icons and images won't be reloaded upon file changes. (AvaloniaAssetManager #20490669)
[HotReload] Enabling hot reload for assets...
[HotReload]Enabling hot reload for the project located at 'D:\src\...\UI.Desktop'...
[HotReload]Enabling hot reload for the project located at 'D:\src\...\UI.Common'...

I then tested a couple of axaml files to see if something is reloaded and saw the following errors:

[HotReload]Reloading 'avares://UI.Desktop/Shell/ShellContent.axaml'...
[HotReload]Failed to reload 'avares://UI.Desktop/Shell/ShellContent.axaml': 'System.MethodAccessException: Attempt by method 'Builder_3432b653938d49adb5908ead45b9a0db_avares___..._UI_Desktop_Shell_ShellContent_axaml.__AvaloniaXamlIlPopulate(System.IServiceProvider, UI.Desktop.Shell.ShellContent)' to access method 'UI.Desktop.Shell.UsageHintsView..ctor()' failed.
   at Builder_3432b653938d49adb5908ead45b9a0db_avares___..._UI_Desktop_Shell_ShellContent_axaml.__AvaloniaXamlIlPopulate(IServiceProvider, ShellContent)
   at lambda_method7(Closure, IServiceProvider, Object)
   at Avalonia.Markup.Xaml.XamlIl.AvaloniaXamlIlRuntimeCompiler.LoadOrPopulate(Type created, Object rootInstance, IServiceProvider parentServiceProvider)
   at Avalonia.Markup.Xaml.XamlIl.AvaloniaXamlIlRuntimeCompiler.<>c.<LoadGroupSreCore>b__16_2(ValueTuple`2 t)
   at System.Linq.Enumerable.IEnumerableSelectIterator`2.ToArray()
   at Avalonia.Markup.Xaml.XamlIl.AvaloniaXamlIlRuntimeCompiler.LoadGroupSreCore(IReadOnlyCollection`1 documents, RuntimeXamlLoaderConfiguration configuration)
   at Avalonia.Markup.Xaml.XamlIl.AvaloniaXamlIlRuntimeCompiler.LoadSreCore(RuntimeXamlLoaderDocument document, RuntimeXamlLoaderConfiguration configuration)
   at Avalonia.Markup.Xaml.XamlIl.AvaloniaXamlIlRuntimeCompiler.LoadSre(RuntimeXamlLoaderDocument document, RuntimeXamlLoaderConfiguration configuration)
   at Avalonia.Markup.Xaml.XamlIl.AvaloniaXamlIlRuntimeCompiler.Load(RuntimeXamlLoaderDocument document, RuntimeXamlLoaderConfiguration configuration)
   at Avalonia.Markup.Xaml.AvaloniaRuntimeXamlLoader.Load(Stream stream, Assembly localAssembly, Object rootInstance, Uri uri, Boolean designMode)
   at Avalonia.Markup.Xaml.AvaloniaRuntimeXamlLoader.Load(String xaml, Assembly localAssembly, Object rootInstance, Uri uri, Boolean designMode)
   at HotAvalonia.Helpers.AvaloniaControlHelper.Load(String xaml, Uri uri, Object control, MethodInfo& compiledPopulateMethod) in D:\src\3rdParty\HotAvalonia\src\HotAvalonia\Helpers\AvaloniaControlHelper.cs:line 118
   at HotAvalonia.AvaloniaControlInfo.Load(String xaml, Object control, MethodInfo& compiledPopulateMethod) in D:\src\3rdParty\HotAvalonia\src\HotAvalonia\AvaloniaControlInfo.cs:line 124
   at HotAvalonia.AvaloniaControlManager.ReloadAsync(String xaml, CancellationToken cancellationToken) in D:\src\3rdParty\HotAvalonia\src\HotAvalonia\AvaloniaControlManager.cs:line 109
   at HotAvalonia.AvaloniaControlManager.ReloadAsync(CancellationToken cancellationToken) in D:\src\3rdParty\HotAvalonia\src\HotAvalonia\AvaloniaControlManager.cs:line 92
   at HotAvalonia.<AvaloniaHotReloadContext>FCFB87BCD535448D215DB8934D7FE21969B7ED1E758FBAB0D5F07728AF2E5BA04__AvaloniaProjectHotReloadContext.OnChanged(Object sender, FileSystemEventArgs args) in D:\src\3rdParty\HotAvalonia\src\HotAvalonia\AvaloniaHotReloadContext.cs:line 279'
[HotReload]Reloading 'avares://UI.Desktop/Shell/ShellContent.axaml'...
[HotReload]Failed to reload 'avares://UI.Desktop/Shell/ShellContent.axaml': 'System.MethodAccessException: Attempt by method 'Builder_e33fea11a08e49c9bd575d973a991e68_avares___..._UI_Desktop_Shell_ShellContent_axaml.__AvaloniaXamlIlPopulate(System.IServiceProvider, UI.Desktop.Shell.ShellContent)' to access method 'UI.Desktop.Shell.UsageHintsView..ctor()' failed.
   at Builder_e33fea11a08e49c9bd575d973a991e68_avares___..._UI_Desktop_Shell_ShellContent_axaml.__AvaloniaXamlIlPopulate(IServiceProvider, ShellContent)
   at lambda_method8(Closure, IServiceProvider, Object)
   at Avalonia.Markup.Xaml.XamlIl.AvaloniaXamlIlRuntimeCompiler.LoadOrPopulate(Type created, Object rootInstance, IServiceProvider parentServiceProvider)
   at Avalonia.Markup.Xaml.XamlIl.AvaloniaXamlIlRuntimeCompiler.<>c.<LoadGroupSreCore>b__16_2(ValueTuple`2 t)
   at System.Linq.Enumerable.IEnumerableSelectIterator`2.ToArray()
   at Avalonia.Markup.Xaml.XamlIl.AvaloniaXamlIlRuntimeCompiler.LoadGroupSreCore(IReadOnlyCollection`1 documents, RuntimeXamlLoaderConfiguration configuration)
   at Avalonia.Markup.Xaml.XamlIl.AvaloniaXamlIlRuntimeCompiler.LoadSreCore(RuntimeXamlLoaderDocument document, RuntimeXamlLoaderConfiguration configuration)
   at Avalonia.Markup.Xaml.XamlIl.AvaloniaXamlIlRuntimeCompiler.LoadSre(RuntimeXamlLoaderDocument document, RuntimeXamlLoaderConfiguration configuration)
   at Avalonia.Markup.Xaml.XamlIl.AvaloniaXamlIlRuntimeCompiler.Load(RuntimeXamlLoaderDocument document, RuntimeXamlLoaderConfiguration configuration)
   at Avalonia.Markup.Xaml.AvaloniaRuntimeXamlLoader.Load(Stream stream, Assembly localAssembly, Object rootInstance, Uri uri, Boolean designMode)
   at Avalonia.Markup.Xaml.AvaloniaRuntimeXamlLoader.Load(String xaml, Assembly localAssembly, Object rootInstance, Uri uri, Boolean designMode)
   at HotAvalonia.Helpers.AvaloniaControlHelper.Load(String xaml, Uri uri, Object control, MethodInfo& compiledPopulateMethod) in D:\src\3rdParty\HotAvalonia\src\HotAvalonia\Helpers\AvaloniaControlHelper.cs:line 118
   at HotAvalonia.AvaloniaControlInfo.Load(String xaml, Object control, MethodInfo& compiledPopulateMethod) in D:\src\3rdParty\HotAvalonia\src\HotAvalonia\AvaloniaControlInfo.cs:line 124
   at HotAvalonia.AvaloniaControlManager.ReloadAsync(String xaml, CancellationToken cancellationToken) in D:\src\3rdParty\HotAvalonia\src\HotAvalonia\AvaloniaControlManager.cs:line 109
   at HotAvalonia.AvaloniaControlManager.ReloadAsync(CancellationToken cancellationToken) in D:\src\3rdParty\HotAvalonia\src\HotAvalonia\AvaloniaControlManager.cs:line 92
   at HotAvalonia.<AvaloniaHotReloadContext>FCFB87BCD535448D215DB8934D7FE21969B7ED1E758FBAB0D5F07728AF2E5BA04__AvaloniaProjectHotReloadContext.OnChanged(Object sender, FileSystemEventArgs args) in D:\src\3rdParty\HotAvalonia\src\HotAvalonia\AvaloniaHotReloadContext.cs:line 279'
[HotReload]Reloading 'avares://UI.Desktop/Shell/ShellContent.axaml'...
[HotReload]Failed to reload 'avares://UI.Desktop/Shell/ShellContent.axaml': 'System.MethodAccessException: Attempt by method 'Builder_06e77bca51ae496dbe3f6cac09e41d6a_avares___..._UI_Desktop_Shell_ShellContent_axaml.__AvaloniaXamlIlPopulate(System.IServiceProvider, UI.Desktop.Shell.ShellContent)' to access method 'UI.Desktop.Shell.UsageHintsView..ctor()' failed.
   at Builder_06e77bca51ae496dbe3f6cac09e41d6a_avares___..._UI_Desktop_Shell_ShellContent_axaml.__AvaloniaXamlIlPopulate(IServiceProvider, ShellContent)
   at lambda_method9(Closure, IServiceProvider, Object)
   at Avalonia.Markup.Xaml.XamlIl.AvaloniaXamlIlRuntimeCompiler.LoadOrPopulate(Type created, Object rootInstance, IServiceProvider parentServiceProvider)
   at Avalonia.Markup.Xaml.XamlIl.AvaloniaXamlIlRuntimeCompiler.<>c.<LoadGroupSreCore>b__16_2(ValueTuple`2 t)
   at System.Linq.Enumerable.IEnumerableSelectIterator`2.ToArray()
   at Avalonia.Markup.Xaml.XamlIl.AvaloniaXamlIlRuntimeCompiler.LoadGroupSreCore(IReadOnlyCollection`1 documents, RuntimeXamlLoaderConfiguration configuration)
   at Avalonia.Markup.Xaml.XamlIl.AvaloniaXamlIlRuntimeCompiler.LoadSreCore(RuntimeXamlLoaderDocument document, RuntimeXamlLoaderConfiguration configuration)
   at Avalonia.Markup.Xaml.XamlIl.AvaloniaXamlIlRuntimeCompiler.LoadSre(RuntimeXamlLoaderDocument document, RuntimeXamlLoaderConfiguration configuration)
   at Avalonia.Markup.Xaml.XamlIl.AvaloniaXamlIlRuntimeCompiler.Load(RuntimeXamlLoaderDocument document, RuntimeXamlLoaderConfiguration configuration)
   at Avalonia.Markup.Xaml.AvaloniaRuntimeXamlLoader.Load(Stream stream, Assembly localAssembly, Object rootInstance, Uri uri, Boolean designMode)
   at Avalonia.Markup.Xaml.AvaloniaRuntimeXamlLoader.Load(String xaml, Assembly localAssembly, Object rootInstance, Uri uri, Boolean designMode)
   at HotAvalonia.Helpers.AvaloniaControlHelper.Load(String xaml, Uri uri, Object control, MethodInfo& compiledPopulateMethod) in D:\src\3rdParty\HotAvalonia\src\HotAvalonia\Helpers\AvaloniaControlHelper.cs:line 118
   at HotAvalonia.AvaloniaControlInfo.Load(String xaml, Object control, MethodInfo& compiledPopulateMethod) in D:\src\3rdParty\HotAvalonia\src\HotAvalonia\AvaloniaControlInfo.cs:line 124
   at HotAvalonia.AvaloniaControlManager.ReloadAsync(String xaml, CancellationToken cancellationToken) in D:\src\3rdParty\HotAvalonia\src\HotAvalonia\AvaloniaControlManager.cs:line 109
   at HotAvalonia.AvaloniaControlManager.ReloadAsync(CancellationToken cancellationToken) in D:\src\3rdParty\HotAvalonia\src\HotAvalonia\AvaloniaControlManager.cs:line 92
   at HotAvalonia.<AvaloniaHotReloadContext>FCFB87BCD535448D215DB8934D7FE21969B7ED1E758FBAB0D5F07728AF2E5BA04__AvaloniaProjectHotReloadContext.OnChanged(Object sender, FileSystemEventArgs args) in D:\src\3rdParty\HotAvalonia\src\HotAvalonia\AvaloniaHotReloadContext.cs:line 279'

Then there's another question I hope you could answer:
There are some controls/view in my project which aren't loaded via axaml per se. Those views are instantiated using code and put as Content in a TransitioningContentControl. So loading/unloading is done using code and I was wondering if this is also a reason HotReload may not work. If so, maybe there's a way for me to make this hot reloadable?

Thanks again for your help and patience! I really appreciate it.

@Kir-Antipov
Copy link
Owner

One mystery solved: hot reload wasn't active because the I put the DefineConstant in the wrong project. I put it in the startup project but I should have put it in the project where App.cs resides. After fixing that, I get debug outputs from HotReload. Sorry for hiccup!

Happens to the best of us! :) At least it's sorted out now - that's great news.

Regarding the exceptions you're encountering, see #11. The UsageHintsView..ctor() appears to be private/internal, and because the newly compiled control population logic resides in a different assembly, it doesn't have access to it. I worked around this problem by injecting into Avalonia.Markup.Xaml.Loader to patch a few things here and there. However, since injections are not an option in your environment, the issue has never been resolved for you.

That said, I just pushed 4edc9b8, which should mostly solve the problem even without injections. You can give it a try and see if it finally works in your scenario! :D

@StefanKoell
Copy link
Author

I pulled the latest development branch and created new nugets. Unfortunately it still won't work. I guess you don't have an ARM machine to test this, right? I will see if I can get an x64 machine to check if it's working there as expected.

@Kir-Antipov
Copy link
Owner

I guess you don't have an ARM machine to test this, right?

Yup, I don't. However, I did test the demo with injections disabled, and it seems to work fine - at least as much as it can in that state. As I mentioned earlier, styles, resource dictionaries, images, icons, and similar assets do require injections to support hot reloading.

Unfortunately it still won't work.

What's the current problem? Are you still encountering those same exceptions as before? If so, I have a sneaky suspicion it might be a caching issue. dotnet puts NuGet packages, even the local ones, in its global cache. So, if you build new packages using a version number you've already used before, they won't actually take effect because they'll be overshadowed by the existing cache.

@StefanKoell
Copy link
Author

I can rule out a nuget caching issue. I actually created nuget packages from source (2.0.1-beta1 and 2.0.1-beta2) and uploaded it to my private nuget feed. I'm 100% sure the right nuget is used here.

What I see in the Debug Output is:

  • [HotReload]Found an assembly containing Avalonia controls ...
  • [HotReload]Failed to subscribe to the 'Populate' event of ...
  • [HotReload]Enabling hot reload for the project located at ...

When I change something in a axaml file I see this
[HotReload]Reloading 'avares://UI.Desktop/Shell/ShellContent.axaml'...

But whatever I change (a font size, a margin, whatever), it doesn't really hot reload

I don't see any exceptions or any other output.

Also, a lot of my pages (the sample above with the ShellContent.axaml is not affected) are instantiated and loaded by code. I'm not sure if this affects hot reload but if I edit something in such a page, I don't even get the [HotReload]Reloading ... output.

Any ideas what eIse I can do?

@Kir-Antipov
Copy link
Owner

I don't see any exceptions or any other output.

That's the important part: if there are no exceptions, it works (or rather doesn't) the same way it would on an x64 machine. However, it's unclear to me why you aren't seeing any changes. It shouldn't matter how you instantiate the control, it should still be re-populated successfully.

Also, a lot of my pages (the sample above with the ShellContent.axaml is not affected) are instantiated and loaded by code. I'm not sure if this affects hot reload but if I edit something in such a page, I don't even get the [HotReload]Reloading ... output.

I would greatly appreciate an MRE I could dig through, as it's very hard to determine what went wrong based solely on this brief description.

At the moment, HotAvalonia doesn't blow itself up on ARM devices and seems to work as expected, so I'm going to push a new release. However, there are additional issues related to your use case that break hot reload, and these require further investigation.

@StefanKoell
Copy link
Author

So, I pulled the 2.0.1 from the main brunch and used the HotAvaloniaDemo app to test it out and it seems to work great. So, I think the platform specific issue for ARM64 has been resolved.

My project still doesn't work.

When I start the app and modify any of the XAML files, nothing happens (either visibly in the app or in the debug output).

So I guess it has something to do the way the project is set up (multiple projects where the App.axaml is not located in the startup project). I tried to tweak the HotAvaloniaDemo app to reflect a similar project structure like mine but it still works after those changes. Something weird must be going on in my setup and was wondering if you have any other suggestions on how to go to the bottom of this.

Thanks!

@Kir-Antipov
Copy link
Owner

So, I think the platform specific issue for ARM64 has been resolved.

Yes, the parts of HotAvalonia that don't rely on method injections are functioning correctly now. This means the issue you're facing now is platform-independent :D

So I guess it has something to do the way the project is set up (multiple projects where the App.axaml is not located in the startup project).

While I initially wanted to say that your project organization doesn't really matter, it got me thinking: how - and more importantly, when - do you enable hot reload? For HotAvalonia to hot reload existing control instances, it needs to be aware of their existence. However, it only starts tracking the creation of new controls after hot reload is enabled. This means that if your controls are populated before that, they won't be reloaded.

If you call .EnableHotReload() too late, this could explain why you see [HotReload]Reloading 'avares://UI.Desktop/Shell/ShellContent.axaml'... without any visible changes. HotAvalonia successfully loads the new XAML, but it has no known targets to apply the changes to.

@StefanKoell
Copy link
Author

I did some more testing and the results are... weird. Here's the current state:

  • I have a couple of controls which can be hot reloaded. Changing the padding or so seems to work for some controls. I do see the following entry in the Debug Output:
    [HotReload]Reloading 'avares://Desktop/Shell/ShellContent.axaml'...
    but I don't see something like this from the HotReloadDemo app:
    Initializing HotReloadDemo.Controls.ToDoItemControl#34085817...
    Not sure if that's important but I thought I mention it. As stated before, HotReload seems to work though.

Then I have controls I mentioned before which are instantiated manually. I think the culprit here is that I control the lifetime of these controls. Once I instantiated the control, I put it on the Content property of a TransitioningContentControl and also cache the instance. The cache is accessed when switching pages and if one of the page has already been instantiated, I take the instance from the cache. But I think as long as I don't switch pages and the one page I'm looking at has been changed, it should be replaced - again, I'm not sure how this works under the hood.

But: when I change the XAML of such a page, I don't even get the [HotReload] Reloading 'avares://...axaml'... line in the Debug Output. It seems to me that those changes aren't picked up in the first place.

So, we are making progress but I'm not sure what exactly the issue is with my pages in the TransitioningContentControl. Is there some verbose logging or so where I can see if the file change is registered? Any idea why these files are not monitored?

@Kir-Antipov
Copy link
Owner

I don't see something like this from the HotReloadDemo app: Initializing HotReloadDemo.Controls.ToDoItemControl#34085817...

This isn't part of HotAvalonia. All HotAvalonia logs are prefixed with [HotReload]. What you're seeing is related to the [AvaloniaHotReload] attribute showcased within the demo app (see ToDoItemControl.axaml.cs for details).

I think the culprit here is that I control the lifetime of these controls. Once I instantiated the control, I put it on the Content property of a TransitioningContentControl and also cache the instance.

Nothing described here should cause an issue. HotAvalonia doesn't particularly care about the lifetime of your controls (though this can occasionally lead to some funny side effects, such as reloading controls that are about to be garbage collected, but oh well). Additionally, I see nothing inherently unusual about TransitioningContentControl that could break hot reload. When I replicate all the same stuff in the demo app, the controls remain hot-reloadable.

As I mentioned earlier, my current suspicion is that you're calling .EnableHotReload() after these controls are already populated, so HotAvalonia just doesn't know that they exist in the first place.

But: when I change the XAML of such a page, I don't even get the [HotReload] Reloading 'avares://...axaml'... line in the Debug Output. It seems to me that those changes aren't picked up in the first place.

Correct. This means that the file changes aren't being monitored at all for some reason. That's interesting.

Is there some verbose logging or so where I can see if the file change is registered?

Welp, not really, it's already as verbose as it gets :D

Any idea why these files are not monitored?

Not at this point. Are these pages listed in the output of AvaloniaRuntimeXamlScanner.FindAvaloniaControls(Assembly)?

@StefanKoell
Copy link
Author

Hi again! I'm sorry I missed to answer the question before. I can confirm that the EnableHotReload call is done at the very beginning, before any XAML content is loaded.

I made some progress during debugging and found out that all controls/pages which are internal (sealed) are the ones which do not work. I've created a repro project which shows the effect. I already tried to provide the correct binding flags for the reflection calls and also set the InternalsVisibleTo but it's still not working.

HotAvalonia.zip

@StefanKoell
Copy link
Author

I just figured out that controls marked as internals are not listed in the TryLoad method which is looked at in order to locate controls. Not sure if HotAvalonia can look at something else in order to get internal controls as well or what the impact might be if I change all my internal controls to public.

@Kir-Antipov
Copy link
Owner

I can confirm that the EnableHotReload call is done at the very beginning, before any XAML content is loaded.

It was worth a shot! If you're initializing your cached components statically somewhere, they might have been effectively created before the .EnableHotReload() call. Alas, this part of the problem remains a mystery :D

I just figured out that controls marked as internals are not listed in the TryLoad method which is looked at in order to locate controls.

Great job! That's unfortunate, really - it was incredibly convenient to grab all (or so I thought) the controls from that method. Sadly, it seems I'll need to resort to assembly scanning to reliably locate all available user controls.

The main issue, however, isn't just finding an alternative way to detect the controls. The real problem is that Avalonia.Markup.Xaml.Loader specifically filters out all non-public types when initializing its type system wrapper. As a result, internal types essentially don't exist for it, so it throws if you attempt to load XAML referencing one of those. Sigh. Let me deal with that.

By the way, I really appreciate your dedication and ongoing debugging efforts to improve HotAvalonia. Big preesh! :D

@StefanKoell
Copy link
Author

For now I changed all my controls from internal to public in order to make HotReload work. Having HotReload (even the more basic ARM64 support) is really awesome and I appreciate all you've done with this project. It's really really helpful already! Now that I got a taste of it, I want more, of course ;)

So, changing a templated control markup is not picked up by HotReload on ARM64 and I guess it would be picked up on x64 (which I can't really test). Is this true?

If so, I'm wondering what exactly needs to be done on the MonoCicil side and maybe on your side to make the full feature set of HotReload work for ARM64. If you can help me to submit a proper issue on their side I would really appreciate it. I'm willing to put up a donation to get this work properly on ARM64. I've seen you haven't setup sponsorship for your account. Would be great if you can set it up. The least I can do is buy you a coffee, or 17...

@Kir-Antipov
Copy link
Owner

For now I changed all my controls from internal to public in order to make HotReload work.

So, about that... I just released v2.0.2, which fixes the issue with internal controls 😅

Having HotReload (even the more basic ARM64 support) is really awesome and I appreciate all you've done with this project. It's really really helpful already! Now that I got a taste of it, I want more, of course ;)

Thanks a ton! It's always amazingly heartwarming to know that my work has made a difference for someone ❤️

So, changing a templated control markup is not picked up by HotReload on ARM64 and I guess it would be picked up on x64 (which I can't really test). Is this true?

A general rule of thumb is that controls with the x:Class property set should be hot-reloadable. If your templated controls are defined within a <Style>, for example, which usually isn't paired with a custom user-defined type, unfortunately, those cannot be hot-reloaded without method injections.

If so, I'm wondering what exactly needs to be done on the MonoCicil side and maybe on your side to make the full feature set of HotReload work for ARM64.

Essentially, MonoMod requires an IArchitecture implementation for ARM64, and lots of testing :) You can look at the x86_64Arch implementation as an example.

If you can help me to submit a proper issue on their side I would really appreciate it.

Maybe I'll throw something together a bit later!

I've seen you haven't setup sponsorship for your account. Would be great if you can set it up. The least I can do is buy you a coffee, or 17...

That's very kind of you! I've been thinking about it lately, especially as several of my projects have somewhat gained traction among fellow developers. So, if someone wants to sponsor my evenings working on these projects, why not? :D

@StefanKoell
Copy link
Author

So, about that... I just released v2.0.2, which fixes the issue with internal controls 😅

No worries, I reverted that commit and it wasn't that much of a hassle. I tested with internal controls and v2.0.2 and it works. Thanks for fixing that!

Essentially, MonoMod requires an IArchitecture implementation for ARM64, and lots of testing :) You can look at the x86_64Arch implementation as an example.

Woah! That's way out of my league 😅 So as a first step I would open an issue on their repo to see if they can provide ARM64 support as well. Would it be sufficient to just ask for the ARM64 implementation of the IArchitecture interface or is there something else required I should mention?

@StefanKoell
Copy link
Author

Sorry for spamming on this thread again (a chat or maybe enabling discussions would be better?)

I've found this:
https://github.com/vprodan/MonoMod/blob/reorganize-arm64/src/MonoMod.Core/Platforms/Architectures/Arm64Arch.cs

Discussed here:
MonoMod/MonoMod#90

Looks like ARM64 is actually quite in demand and there is some movement at least.

@Kir-Antipov
Copy link
Owner

Thanks for fixing that!

Always glad to help! :)

Woah! That's way out of my league 😅

It looks scarier than it actually is. It's not that hard - just a lot of meticulous work scavenging through poorly written (if any) documentation for various platforms xD

Would it be sufficient to just ask for the ARM64 implementation of the IArchitecture interface or is there something else required I should mention?

They know what needs to be done, so even a simple "Windows ARM support when?" would be sufficient. It's really just about showing that there's demand for it now.

Sorry for spamming on this thread again (a chat or maybe enabling discussions would be better?)

No problem at all! It's all relevant to the issue at hand. And even if it weren't, I'm not one of those on-topic-only, keep-it-short purists :)
I've enabled Discussions for one of my other repos, but, honestly, it hasn't been great. People started posting issues as discussions, while questions that would fit perfectly as discussions still end up being filed as issues. So, for now, I'm sticking with good old-fashioned issues - it seems to work better, at least for me.

Looks like ARM64 is actually quite in demand and there is some movement at least.

It is but, as far as I know, the lead (and essentially the only active) developer of MonoMod is not interested in dealing with it - even if someone were to fund the work. Moreover, there simply aren't enough developers out there who simultaneously (1) have an ARM-like MacBook (since Apple deviates from the spec, because of course they do, requiring separate testing for MacBooks and similar devices), (2) own a more conventional ARM-based laptop, (3) are interested in MonoMod, (4) know C#, and (5) possess the skills required to bring ARM support to MonoMod.

Currently, the only relevant work is a single, stale commit that brought ARM support to the "somewhat works on my machine, sometimes" stage. Perhaps if we leave Apple out of the picture, it might be easier to focus on supporting more conventional devices first?

Anyways, I've been thinking about this for the past few days. I still need a way to provide hot reload functionality without relying on injections because there's still an entire market for Avalonia apps developed for mobile devices. And let me tell you, MonoMod support for those isn't likely to materialize anytime this century. Back in the day, I proposed AvaloniaUI/Avalonia#13085, which, admittedly, is a crutchy solution. However, it kinda makes sense and it would have enabled HotAvalonia to work without requiring injections already.

Unfortunately, the proposal was met with responses like, "Well, this is a crutch; we'd prefer a perfect solution instead [which, of course, would take too much time and resources to actually develop, so no one is going to bother]." As a result, we now have neither the simple crutch solution nor any progress on "the perfect one," which hasn't even been discussed over a year later.

Finally, I decided: Fine, I'll do it myself. Yesterday, I implemented a weaver that does exactly what I proposed to the Avalonia team. Now, I can run the HotReloadDemo completely injection-free.

The only downside is that, since weaving is done on a per-project basis, users will need to define the HotAvalonia.Fody dependency in each project that contains controls (or, more realistically, include it somewhere in a shared .props file). Even so, this is still better than having only partially functional hot reload support, IMHO.

@StefanKoell
Copy link
Author

Finally, I decided: Fine, I'll do it myself. Yesterday, I implemented a weaver that does exactly what I proposed to the Avalonia team. Now, I can run the HotReloadDemo completely injection-free.

So you're trying to make it work without MonoMod? That would be fantastic, especially since MonoMod seems like it's "dead" already.

The only downside is that, since weaving is done on a per-project basis, users will need to define the HotAvalonia.Fody dependency in each project that contains controls (or, more realistically, include it somewhere in a shared .props file). Even so, this is still better than having only partially functional hot reload support, IMHO.

I can live with putting the deps in a shared props file. The Fody dependency would only be relevant in debug builds when HotAvalonia is enabled, right? Release builds won't be affected by this, correct? If so, I can't think of any reason/downside to not use it. I also guess there's no caveats when using ARM64 for that, so I think it's good news 😅

If you want me to test something, feel free to ping me. I'm happy to look at it.

@Kir-Antipov
Copy link
Owner

So you're trying to make it work without MonoMod? That would be fantastic, especially since MonoMod seems like it's "dead" already.

Welp, "dead" might be a bit too harsh of a word here, honestly. I'd say it's more accurate to describe it as being in maintenance mode. And I don't think MonoMod will ever truly die, though, because the entire modding scene for Unity games (and more) depends solely on it.

That said, it would be great to move away from relying on it, especially since I want HotAvalonia to be supported in environments where MonoMod likely will never work.

The Fody dependency would only be relevant in debug builds when HotAvalonia is enabled, right? Release builds won't be affected by this, correct?

Of course! One of the core principles I've developed HotAvalonia around is that no hot reload-related logic slips into the production build of your app. If I weren't concerned about this, I could have packed HotAvalonia as a single package and skipped all this conditional setup :)

Anyways, v2.1.0 is up and running, and you can now make use of HotAvalonia.Fody. I haven't updated the README with instructions on how to use it yet because, honestly, not a lot of people need it right now. I'll probably save that for v3.0.0, which will bring support for mobile devices. For now, let me guide you through the setup here.

Current Setup

Currently, for a single project, your .csproj should look something like this:

<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
  <DefineConstants>$(DefineConstants);ENABLE_XAML_HOT_RELOAD</DefineConstants>
</PropertyGroup>

<ItemGroup>
  <PackageReference Condition="$(DefineConstants.Contains(ENABLE_XAML_HOT_RELOAD))" Include="Avalonia.Markup.Xaml.Loader" Version="$(AvaloniaVersion)" />
  <PackageReference Condition="$(DefineConstants.Contains(ENABLE_XAML_HOT_RELOAD))" Include="HotAvalonia" Version="2.1.0" />
  <PackageReference Include="HotAvalonia.Extensions" Version="2.1.0" PrivateAssets="All" />
</ItemGroup>

With HotAvalonia.Fody, this changes to:

  <PropertyGroup Condition="'$(Configuration)' == 'Debug'">
    <DefineConstants>$(DefineConstants);ENABLE_XAML_HOT_RELOAD</DefineConstants>
+   <WeaverConfiguration><Weavers><HotAvalonia/></Weavers></WeaverConfiguration>
+   <FodyDependsOnTargets>CompileAvaloniaXaml</FodyDependsOnTargets>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Condition="$(DefineConstants.Contains(ENABLE_XAML_HOT_RELOAD))" Include="Avalonia.Markup.Xaml.Loader" Version="$(AvaloniaVersion)" />
    <PackageReference Condition="$(DefineConstants.Contains(ENABLE_XAML_HOT_RELOAD))" Include="HotAvalonia" Version="2.1.0" />
+   <PackageReference Condition="$(DefineConstants.Contains(ENABLE_XAML_HOT_RELOAD))" Include="HotAvalonia.Fody" Version="2.1.0" PrivateAssets="All" />
    <PackageReference Include="HotAvalonia.Extensions" Version="2.1.0" PrivateAssets="All" />
  </ItemGroup>

Essentially, you need to:

  1. Add a dependency on HotAvalonia.Fody.
  2. Configure Fody to run it.
  3. Ensure it runs after the CompileAvaloniaXaml task.

And that's all there is to it!

Multi-Project Setup

Since assembly weaving is done on a per-project basis, you'll need to set up HotAvalonia.Fody for every project that contains Avalonia controls. To simplify this process, you can move part of the configuration to the good ol' Directory.Build.props. With that, the setup becomes something like this:

Directory.Build.props:

<PropertyGroup Condition="'$(Configuration)' == 'Debug'">
  <DefineConstants>$(DefineConstants);ENABLE_XAML_HOT_RELOAD</DefineConstants>
  <WeaverConfiguration><Weavers><HotAvalonia/></Weavers></WeaverConfiguration>
  <FodyDependsOnTargets>CompileAvaloniaXaml</FodyDependsOnTargets>
</PropertyGroup>

<ItemGroup>
  <PackageReference Condition="$(DefineConstants.Contains(ENABLE_XAML_HOT_RELOAD))" Include="HotAvalonia.Fody" Version="2.1.0" PrivateAssets="All" />
</ItemGroup>

Your entrypoint project's .csproj:

<ItemGroup>
  <PackageReference Condition="$(DefineConstants.Contains(ENABLE_XAML_HOT_RELOAD))" Include="Avalonia.Markup.Xaml.Loader" Version="$(AvaloniaVersion)" />
  <PackageReference Condition="$(DefineConstants.Contains(ENABLE_XAML_HOT_RELOAD))" Include="HotAvalonia" Version="2.1.0" />
  <PackageReference Include="HotAvalonia.Extensions" Version="2.1.0" PrivateAssets="All" />
</ItemGroup>

With that, your experience should be pretty much the same as if you were on AMD64. Hope this helps! :)

@StefanKoell
Copy link
Author

Wow! I just tried 2.1.0 and also added Fody.

So far, I tested the following and this seems to work quite well:

  • Modifying XAML directly
  • Modifying user controls
  • Modifying resources like colors

What kind of worked but needed a "manual reload":

  • Modifying custom content controls (ControlTemplate)
    What I mean by manual is that if I change the ControlTemplate, it doesn't seem to be applied when saved. I have to switch to a different view and back in order to see the changes.

What didn't work:

  • Modifying a global style
    I have something like this:
<Style Selector=":is(TextBox)">
    <Setter Property="BorderBrush" Value="{StaticResource TextBoxBorderBrushInactive}" />
</Style>

If I change this style to:

<Style Selector=":is(TextBox)">
    <Setter Property="BorderBrush" Value="Red" />
</Style>

I get the following crash:

14:25:48 FTL] Application terminated unexpectedly
System.InvalidOperationException: The control ItemsPresenter (Name = PART_ItemsPresenter) already has a visual parent ScrollContentPresenter (Name = PART_ContentPresenter) while trying to add it as a child of ContentPresenter (Name = PART_ContentPresenter, Host = ScrollViewer (Name = PART_ScrollViewer)).
   at Avalonia.Visual.Avalonia.Collections.IAvaloniaListItemValidator<Avalonia.Visual>.Validate(Visual item)
   at Avalonia.Collections.AvaloniaList`1.Add(T item)
   at Avalonia.Controls.Presenters.ContentPresenter.UpdateChild(Object content)
   at Avalonia.Controls.Presenters.ContentPresenter.UpdateChild()
...

Overall, this is a huge improvement and works much better for me on my ARM64 machine! If you want me to open separate issues and dig deeper regarding the two issues I encountered so far, let me know.

Again, thanks for all the great work. This is a game changer for Avalonia!

@Kir-Antipov
Copy link
Owner

Again, thanks for all the great work. This is a game changer for Avalonia!

Really appreciate the kind words as always! :D

Overall, this is a huge improvement and works much better for me on my ARM64 machine! If you want me to open separate issues and dig deeper regarding the two issues I encountered so far, let me know.

The problems you're encountering now are not architecture-specific anymore. So feel free to open new issues so I can address them for you and other users. MREs (and maybe even PRs for the demo app, which I use for manual testing) are more than welcome! ;)

@StefanKoell
Copy link
Author

Understood! I see what I can come up with and file another issue or PR for the demo with the issue. Thanks again and a happy new year!

@Kir-Antipov
Copy link
Owner

Thanks a bunch and a happy New Year to you too! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants