Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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