Browse Source

Added Win32PlatformOptions.ShouldRenderOnUIThread

Fixes WPF interop
pull/10295/head
Julien Lebosquain 3 years ago
parent
commit
7d879cf6fe
No known key found for this signature in database GPG Key ID: 1833CAD10ACC46FD
  1. 11
      samples/interop/WindowsInteropTest/Program.cs
  2. 5
      src/Avalonia.Base/Rendering/DefaultRenderTimer.cs
  3. 5
      src/Avalonia.Base/Rendering/IRenderLoop.cs
  4. 1
      src/Avalonia.Base/Rendering/RenderLoop.cs
  5. 9
      src/Avalonia.Base/Rendering/UiThreadRenderTimer.cs
  6. 9
      src/Windows/Avalonia.Win32.Interop/Wpf/WpfTopLevelImpl.cs
  7. 24
      src/Windows/Avalonia.Win32/Win32Platform.cs

11
samples/interop/WindowsInteropTest/Program.cs

@ -1,5 +1,4 @@
using System;
using Avalonia.Controls;
using ControlCatalog;
using Avalonia;
@ -15,7 +14,15 @@ namespace WindowsInteropTest
{
System.Windows.Forms.Application.EnableVisualStyles();
System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(false);
AppBuilder.Configure<App>().UseWin32().UseDirect2D1().SetupWithoutStarting();
AppBuilder.Configure<App>()
.UseWin32()
.UseDirect2D1()
.With(new Win32PlatformOptions
{
UseWindowsUIComposition = false,
ShouldRenderOnUIThread = true // necessary for WPF
})
.SetupWithoutStarting();
System.Windows.Forms.Application.Run(new SelectorForm());
}
}

5
src/Avalonia.Base/Rendering/DefaultRenderTimer.cs

@ -1,6 +1,4 @@
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using Avalonia.Platform;
namespace Avalonia.Rendering
@ -59,7 +57,8 @@ namespace Avalonia.Rendering
}
}
public bool RunsInBackground => true;
/// <inheritdoc />
public virtual bool RunsInBackground => true;
/// <summary>
/// Starts the timer.

5
src/Avalonia.Base/Rendering/IRenderLoop.cs

@ -27,7 +27,10 @@ namespace Avalonia.Rendering
/// </summary>
/// <param name="i">The update task.</param>
void Remove(IRenderLoopTask i);
/// <summary>
/// Indicates if the rendering is done on a non-UI thread.
/// </summary>
bool RunsInBackground { get; }
}
}

1
src/Avalonia.Base/Rendering/RenderLoop.cs

@ -87,6 +87,7 @@ namespace Avalonia.Rendering
}
}
/// <inheritdoc />
public bool RunsInBackground => Timer.RunsInBackground;
private void TimerTick(TimeSpan time)

9
src/Avalonia.Base/Rendering/UiThreadRenderTimer.cs

@ -8,13 +8,20 @@ namespace Avalonia.Rendering
/// <summary>
/// Render timer that ticks on UI thread. Useful for debugging or bootstrapping on new platforms
/// </summary>
public class UiThreadRenderTimer : DefaultRenderTimer
{
/// <summary>
/// Initializes a new instance of the <see cref="UiThreadRenderTimer"/> class.
/// </summary>
/// <param name="framesPerSecond">The number of frames per second at which the loop should run.</param>
public UiThreadRenderTimer(int framesPerSecond) : base(framesPerSecond)
{
}
/// <inheritdoc />
public override bool RunsInBackground => false;
/// <inheritdoc />
protected override IDisposable StartCore(Action<TimeSpan> tick)
{
bool cancelled = false;

9
src/Windows/Avalonia.Win32.Interop/Wpf/WpfTopLevelImpl.cs

@ -45,13 +45,6 @@ namespace Avalonia.Win32.Interop.Wpf
((FrameworkElement)PlatformImpl)?.InvalidateMeasure();
}
protected override void HandleResized(Size clientSize, PlatformResizeReason reason)
{
ClientSize = clientSize;
LayoutManager.ExecuteLayoutPass();
Renderer?.Resized(clientSize);
}
public Size AllocatedSize => ClientSize;
}
@ -223,7 +216,7 @@ namespace Avalonia.Win32.Interop.Wpf
(Key)e.Key,
GetModifiers(null)));
protected override void OnTextInput(TextCompositionEventArgs e)
protected override void OnTextInput(TextCompositionEventArgs e)
=> _ttl.Input?.Invoke(new RawTextInputEventArgs(_keyboard, (uint) e.Timestamp, _inputRoot, e.Text));
void ITopLevelImpl.SetCursor(ICursorImpl cursor)

24
src/Windows/Avalonia.Win32/Win32Platform.cs

@ -6,12 +6,10 @@ using System.IO;
using Avalonia.Reactive;
using System.Runtime.InteropServices;
using System.Threading;
using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Controls.Platform;
using Avalonia.Input;
using Avalonia.Input.Platform;
using Avalonia.Media;
using Avalonia.OpenGL;
using Avalonia.Platform;
using Avalonia.Rendering;
@ -20,7 +18,6 @@ using Avalonia.Threading;
using Avalonia.Utilities;
using Avalonia.Win32.Input;
using Avalonia.Win32.Interop;
using Avalonia.Win32.WinRT;
using static Avalonia.Win32.Interop.UnmanagedMethods;
namespace Avalonia
@ -68,6 +65,7 @@ namespace Avalonia
/// <summary>
/// Render Avalonia to a Texture inside the Windows.UI.Composition tree.
/// This setting is true by default.
/// </summary>
/// <remarks>
/// Supported on Windows 10 build 16299 and above. Ignored on other versions.
@ -88,9 +86,19 @@ namespace Avalonia
/// This is only recommended if low input latency is desirable, and there is no need for the transparency
/// and stylings / blurrings offered by <see cref="UseWindowsUIComposition"/><br/>
/// This is mutually exclusive with
/// <see cref="UseWindowsUIComposition"/> which if active will override this setting.
/// <see cref="UseWindowsUIComposition"/> which if active will override this setting.
/// This setting is false by default.
/// </summary>
public bool UseLowLatencyDxgiSwapChain { get; set; } = false;
public bool UseLowLatencyDxgiSwapChain { get; set; }
/// <summary>
/// Render directly on the UI thread instead of using a dedicated render thread.
/// Only applicable if both <see cref="UseWindowsUIComposition"/> and <see cref="UseLowLatencyDxgiSwapChain"/>
/// are false.
/// This setting is only recommended for interop with systems that must render on the UI thread, such as WPF.
/// This setting is false by default.
/// </summary>
public bool ShouldRenderOnUIThread { get; set; }
/// <summary>
/// Provides a way to use a custom-implemented graphics context such as a custom ISkiaGpu
@ -128,7 +136,7 @@ namespace Avalonia.Win32
internal static bool UseOverlayPopups => Options.OverlayPopups;
public static Win32PlatformOptions Options { get; private set; }
internal static Compositor Compositor { get; private set; }
public static void Initialize()
@ -139,6 +147,8 @@ namespace Avalonia.Win32
public static void Initialize(Win32PlatformOptions options)
{
Options = options;
var renderTimer = options.ShouldRenderOnUIThread ? new UiThreadRenderTimer(60) : new DefaultRenderTimer(60);
AvaloniaLocator.CurrentMutable
.Bind<IClipboard>().ToSingleton<ClipboardImpl>()
.Bind<ICursorFactory>().ToConstant(CursorFactory.Instance)
@ -146,7 +156,7 @@ namespace Avalonia.Win32
.Bind<IPlatformSettings>().ToSingleton<Win32PlatformSettings>()
.Bind<IPlatformThreadingInterface>().ToConstant(s_instance)
.Bind<IRenderLoop>().ToConstant(new RenderLoop())
.Bind<IRenderTimer>().ToConstant(new DefaultRenderTimer(60))
.Bind<IRenderTimer>().ToConstant(renderTimer)
.Bind<IWindowingPlatform>().ToConstant(s_instance)
.Bind<PlatformHotkeyConfiguration>().ToConstant(new PlatformHotkeyConfiguration(KeyModifiers.Control)
{

Loading…
Cancel
Save