using Avalonia.Controls.Platform; using Avalonia.Input; using Avalonia.Input.Platform; using Avalonia.Platform; using Avalonia.Rendering; using Avalonia.Threading; #nullable enable namespace Avalonia.Web.Blazor { public class BlazorWindowingPlatform : IWindowingPlatform, IPlatformSettings, IPlatformThreadingInterface { private bool _signaled; private static KeyboardDevice? s_keyboard; public IWindowImpl CreateWindow() => throw new NotSupportedException(); IWindowImpl IWindowingPlatform.CreateEmbeddableWindow() { throw new NotImplementedException(); } public ITrayIconImpl? CreateTrayIcon() { return null; } public static KeyboardDevice Keyboard => s_keyboard ?? throw new InvalidOperationException("BlazorWindowingPlatform not registered."); public static void Register() { var instance = new BlazorWindowingPlatform(); s_keyboard = new KeyboardDevice(); AvaloniaLocator.CurrentMutable .Bind().ToSingleton() .Bind().ToSingleton() .Bind().ToConstant(s_keyboard) .Bind().ToConstant(instance) .Bind().ToConstant(instance) .Bind().ToConstant(new RenderLoop()) .Bind().ToConstant(ManualTriggerRenderTimer.Instance) .Bind().ToConstant(instance) .Bind().ToSingleton() .Bind().ToSingleton(); } public Size DoubleClickSize { get; } = new Size(2, 2); public TimeSpan DoubleClickTime { get; } = TimeSpan.FromMilliseconds(500); public Size TouchDoubleClickSize => new Size(16, 16); public TimeSpan TouchDoubleClickTime => DoubleClickTime; public void RunLoop(CancellationToken cancellationToken) { throw new NotSupportedException(); } public IDisposable StartTimer(DispatcherPriority priority, TimeSpan interval, Action tick) { return GetRuntimePlatform() .StartSystemTimer(interval, () => { Dispatcher.UIThread.RunJobs(priority); tick(); }); } public void Signal(DispatcherPriority priority) { if (_signaled) return; _signaled = true; IDisposable? disp = null; disp = GetRuntimePlatform() .StartSystemTimer(TimeSpan.FromMilliseconds(1), () => { _signaled = false; disp?.Dispose(); Signaled?.Invoke(null); }); } public bool CurrentThreadIsLoopThread { get { return true; // Blazor is single threaded. } } public event Action? Signaled; private static IRuntimePlatform GetRuntimePlatform() { return AvaloniaLocator.Current.GetRequiredService(); } } }