Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion samples/interop/Direct3DInteropSample/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ class Program
{
static void Main(string[] args)
{
AppBuilder.Configure<App>().UseWin32(deferredRendering: false).UseDirect2D1().Start<MainWindow>();
AppBuilder.Configure<App>()
.With(new Win32PlatformOptions {UseDeferredRendering = false})
.UseWin32().UseDirect2D1().Start<MainWindow>();
}
}
}
21 changes: 20 additions & 1 deletion src/Avalonia.Controls/AppBuilderBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ namespace Avalonia.Controls
public abstract class AppBuilderBase<TAppBuilder> where TAppBuilder : AppBuilderBase<TAppBuilder>, new()
{
private static bool s_setupWasAlreadyCalled;
private Action _optionsInitializers;

/// <summary>
/// Gets or sets the <see cref="IRuntimePlatform"/> instance.
Expand Down Expand Up @@ -249,6 +250,24 @@ where constructor.GetParameters().Length == 0 && !constructor.IsStatic
Delegate.Combine(moduleInitializers.ToArray()).DynamicInvoke();
}

/// <summary>
/// Configures platform-specific options
/// </summary>
public TAppBuilder With<T>(T options)
{
_optionsInitializers += () => { AvaloniaLocator.CurrentMutable.Bind<T>().ToConstant(options); };
return Self;
}

/// <summary>
/// Configures platform-specific options
/// </summary>
public TAppBuilder With<T>(Func<T> options)
{
_optionsInitializers += () => { AvaloniaLocator.CurrentMutable.Bind<T>().ToFunc(options); };
return Self;
}

/// <summary>
/// Sets up the platform-speciic services for the <see cref="Application"/>.
/// </summary>
Expand Down Expand Up @@ -280,7 +299,7 @@ private void Setup()
}

s_setupWasAlreadyCalled = true;

_optionsInitializers?.Invoke();
RuntimePlatformServicesInitializer();
WindowingSubsystemInitializer();
RenderingSubsystemInitializer();
Expand Down
65 changes: 30 additions & 35 deletions src/Avalonia.Native/AvaloniaNativePlatform.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ namespace Avalonia.Native
class AvaloniaNativePlatform : IPlatformSettings, IWindowingPlatform
{
private readonly IAvaloniaNativeFactory _factory;
private AvaloniaNativePlatformOptions _options;

[DllImport("libAvaloniaNative")]
static extern IntPtr CreateAvaloniaNative();
Expand All @@ -27,44 +28,52 @@ class AvaloniaNativePlatform : IPlatformSettings, IWindowingPlatform

public TimeSpan DoubleClickTime => TimeSpan.FromMilliseconds(500); //TODO

public static void Initialize(IntPtr factory, Action<AvaloniaNativeOptions> configure)
public static void Initialize(IntPtr factory, AvaloniaNativePlatformOptions options)
{
new AvaloniaNativePlatform(new IAvaloniaNativeFactory(factory))
.DoInitialize(configure);
.DoInitialize(options);
}

delegate IntPtr CreateAvaloniaNativeDelegate();

public static void Initialize(string library, Action<AvaloniaNativeOptions> configure)
public static void Initialize(AvaloniaNativePlatformOptions options)
{
var loader = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
? (IDynLoader)new Win32Loader() : new UnixLoader();
var lib = loader.LoadLibrary(library);
var proc = loader.GetProcAddress(lib, "CreateAvaloniaNative", false);
var d = Marshal.GetDelegateForFunctionPointer<CreateAvaloniaNativeDelegate>(proc);
if (options.AvaloniaNativeLibraryPath != null)
{
var loader = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ?
(IDynLoader)new Win32Loader() :
new UnixLoader();

var lib = loader.LoadLibrary(options.AvaloniaNativeLibraryPath);
var proc = loader.GetProcAddress(lib, "CreateAvaloniaNative", false);
var d = Marshal.GetDelegateForFunctionPointer<CreateAvaloniaNativeDelegate>(proc);

Initialize(d(), configure);
}

public static void Initialize(Action<AvaloniaNativeOptions> configure)
{
Initialize(CreateAvaloniaNative(), configure);
Initialize(d(), options);
}
else
Initialize(CreateAvaloniaNative(), options);
}

private AvaloniaNativePlatform(IAvaloniaNativeFactory factory)
{
_factory = factory;
}

void DoInitialize(Action<AvaloniaNativeOptions> configure)
void DoInitialize(AvaloniaNativePlatformOptions options)
{
var opts = new AvaloniaNativeOptions(_factory);
configure?.Invoke(opts);
_options = options;
_factory.Initialize();
if (_factory.MacOptions != null)
{
var macOpts = AvaloniaLocator.Current.GetService<MacOSPlatformOptions>();
if (macOpts != null)
_factory.MacOptions.ShowInDock = macOpts.ShowInDock ? 1 : 0;
}

AvaloniaLocator.CurrentMutable
.Bind<IPlatformThreadingInterface>().ToConstant(new PlatformThreadingInterface(_factory.CreatePlatformThreadingInterface()))
.Bind<IPlatformThreadingInterface>()
.ToConstant(new PlatformThreadingInterface(_factory.CreatePlatformThreadingInterface()))
.Bind<IStandardCursorFactory>().ToConstant(new CursorFactory(_factory.CreateCursorFactory()))
.Bind<IPlatformIconLoader>().ToSingleton<IconLoader>()
.Bind<IKeyboardDevice>().ToConstant(KeyboardDevice)
Expand All @@ -76,13 +85,13 @@ void DoInitialize(Action<AvaloniaNativeOptions> configure)
.Bind<IRenderTimer>().ToConstant(new DefaultRenderTimer(60))
.Bind<ISystemDialogImpl>().ToConstant(new SystemDialogs(_factory.CreateSystemDialogs()))
.Bind<IWindowingPlatformGlFeature>().ToConstant(new GlPlatformFeature(_factory.ObtainGlFeature()))
.Bind<PlatformHotkeyConfiguration>().ToConstant(new PlatformHotkeyConfiguration(InputModifiers.Windows))
.Bind<AvaloniaNativeOptions>().ToConstant(opts);
.Bind<PlatformHotkeyConfiguration>()
.ToConstant(new PlatformHotkeyConfiguration(InputModifiers.Windows));
}

public IWindowImpl CreateWindow()
{
return new WindowImpl(_factory);
return new WindowImpl(_factory, _options);
}

public IEmbeddableWindowImpl CreateEmbeddableWindow()
Expand All @@ -92,7 +101,7 @@ public IEmbeddableWindowImpl CreateEmbeddableWindow()

public IPopupImpl CreatePopup()
{
return new PopupImpl(_factory);
return new PopupImpl(_factory, _options);
}
}

Expand All @@ -116,18 +125,4 @@ public bool ShowInDock
}
}
}

public class AvaloniaNativeOptions
{
public AvaloniaNativeMacOptions MacOptions { get; set; }
public bool UseDeferredRendering { get; set; } = true;
public bool UseGpu { get; set; } = true;
internal AvaloniaNativeOptions(IAvaloniaNativeFactory factory)
{
var mac = factory.GetMacOptions();
if (mac != null)
MacOptions = new AvaloniaNativeMacOptions(mac);
}

}
}
32 changes: 19 additions & 13 deletions src/Avalonia.Native/AvaloniaNativePlatformExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,21 +9,27 @@ namespace Avalonia
{
public static class AvaloniaNativePlatformExtensions
{
public static T UseAvaloniaNative<T>(this T builder,
string libraryPath = null,
Action<AvaloniaNativeOptions> configure = null)
where T : AppBuilderBase<T>, new()
public static T UseAvaloniaNative<T>(this T builder)
where T : AppBuilderBase<T>, new()
{
if (libraryPath == null)
{
builder.UseWindowingSubsystem(() => AvaloniaNativePlatform.Initialize(configure));
}
else
{
builder.UseWindowingSubsystem(() => AvaloniaNativePlatform.Initialize(libraryPath, configure));
}

builder.UseWindowingSubsystem(() =>
AvaloniaNativePlatform.Initialize(
AvaloniaLocator.Current.GetService<AvaloniaNativePlatformOptions>() ??
new AvaloniaNativePlatformOptions()));
return builder;
}
}

public class AvaloniaNativePlatformOptions
{
public bool UseDeferredRendering { get; set; } = true;
public bool UseGpu { get; set; } = true;
public string AvaloniaNativeLibraryPath { get; set; }
}

// ReSharper disable once InconsistentNaming
public class MacOSPlatformOptions
{
public bool ShowInDock { get; set; } = true;
}
}
2 changes: 1 addition & 1 deletion src/Avalonia.Native/PopupImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Avalonia.Native
{
public class PopupImpl : WindowBaseImpl, IPopupImpl
{
public PopupImpl(IAvaloniaNativeFactory factory)
public PopupImpl(IAvaloniaNativeFactory factory, AvaloniaNativePlatformOptions opts) : base(opts)
{
using (var e = new PopupEvents(this))
{
Expand Down
2 changes: 1 addition & 1 deletion src/Avalonia.Native/WindowImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace Avalonia.Native
public class WindowImpl : WindowBaseImpl, IWindowImpl
{
IAvnWindow _native;
public WindowImpl(IAvaloniaNativeFactory factory)
public WindowImpl(IAvaloniaNativeFactory factory, AvaloniaNativePlatformOptions opts) : base(opts)
{
using (var e = new WindowEvents(this))
{
Expand Down
4 changes: 1 addition & 3 deletions src/Avalonia.Native/WindowImplBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,8 @@ public class WindowBaseImpl : IWindowBaseImpl,
private double _savedScaling;
private GlPlatformSurface _glSurface;

public WindowBaseImpl()
public WindowBaseImpl(AvaloniaNativePlatformOptions opts)
{
var opts = AvaloniaLocator.Current.GetService<AvaloniaNativeOptions>();

_gpu = opts.UseGpu;
_deferredRendering = opts.UseDeferredRendering;

Expand Down
6 changes: 4 additions & 2 deletions src/Avalonia.X11/X11Platform.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,11 @@ public class X11PlatformOptions
}
public static class AvaloniaX11PlatformExtensions
{
public static T UseX11<T>(this T builder, X11PlatformOptions options = null) where T : AppBuilderBase<T>, new()
public static T UseX11<T>(this T builder) where T : AppBuilderBase<T>, new()
{
builder.UseWindowingSubsystem(() => new AvaloniaX11Platform().Initialize(options ?? new X11PlatformOptions()));
builder.UseWindowingSubsystem(() =>
new AvaloniaX11Platform().Initialize(AvaloniaLocator.Current.GetService<X11PlatformOptions>() ??
new X11PlatformOptions()));
return builder;
}

Expand Down
20 changes: 13 additions & 7 deletions src/Windows/Avalonia.Win32/Win32Platform.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,21 @@ namespace Avalonia
public static class Win32ApplicationExtensions
{
public static T UseWin32<T>(
this T builder,
bool deferredRendering = true, bool allowEgl = false)
this T builder)
where T : AppBuilderBase<T>, new()
{
return builder.UseWindowingSubsystem(
() => Win32.Win32Platform.Initialize(deferredRendering, allowEgl),
() => Win32.Win32Platform.Initialize(
AvaloniaLocator.Current.GetService<Win32PlatformOptions>() ?? new Win32PlatformOptions()),
"Win32");
}
}

public class Win32PlatformOptions
{
public bool UseDeferredRendering { get; set; } = true;
public bool AllowEglInitialization { get; set; }
}
}

namespace Avalonia.Win32
Expand Down Expand Up @@ -63,10 +69,10 @@ public Win32Platform()

public static void Initialize()
{
Initialize(true);
Initialize(new Win32PlatformOptions());
}

public static void Initialize(bool deferredRendering = true, bool allowEgl = false)
public static void Initialize(Win32PlatformOptions options)
{
AvaloniaLocator.CurrentMutable
.Bind<IClipboard>().ToSingleton<ClipboardImpl>()
Expand All @@ -80,9 +86,9 @@ public static void Initialize(bool deferredRendering = true, bool allowEgl = fal
.Bind<IWindowingPlatform>().ToConstant(s_instance)
.Bind<PlatformHotkeyConfiguration>().ToSingleton<PlatformHotkeyConfiguration>()
.Bind<IPlatformIconLoader>().ToConstant(s_instance);
if (allowEgl)
if (options.AllowEglInitialization)
Win32GlManager.Initialize();
UseDeferredRendering = deferredRendering;
UseDeferredRendering = options.UseDeferredRendering;
_uiThread = Thread.CurrentThread;

if (OleContext.Current != null)
Expand Down