Browse Source

Enable nullability in Avalonia.Native (#20378)

pull/20404/head
Julien Lebosquain 1 month ago
committed by GitHub
parent
commit
cf5b12e700
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 1
      src/Avalonia.Native/Avalonia.Native.csproj
  2. 6
      src/Avalonia.Native/AvaloniaNativeApplicationPlatform.cs
  3. 2
      src/Avalonia.Native/AvaloniaNativeDragSource.cs
  4. 52
      src/Avalonia.Native/AvaloniaNativeGlPlatformGraphics.cs
  5. 19
      src/Avalonia.Native/AvaloniaNativeMenuExporter.cs
  6. 3
      src/Avalonia.Native/AvaloniaNativePlatform.cs
  7. 2
      src/Avalonia.Native/AvaloniaNativePlatformExtensions.cs
  8. 2
      src/Avalonia.Native/AvaloniaNativeRenderTimer.cs
  9. 3
      src/Avalonia.Native/AvaloniaNativeTextInputMethod.cs
  10. 11
      src/Avalonia.Native/AvnAutomationPeer.cs
  11. 14
      src/Avalonia.Native/AvnString.cs
  12. 4
      src/Avalonia.Native/ClipboardDataFormatHelper.cs
  13. 4
      src/Avalonia.Native/ClipboardDataTransfer.cs
  14. 2
      src/Avalonia.Native/ClipboardDataTransferItem.cs
  15. 4
      src/Avalonia.Native/ClipboardImpl.cs
  16. 2
      src/Avalonia.Native/ClipboardReadSession.cs
  17. 4
      src/Avalonia.Native/Cursor.cs
  18. 3
      src/Avalonia.Native/DataTransferItemToAvnClipboardDataItemWrapper.cs
  19. 2
      src/Avalonia.Native/DataTransferToAvnClipboardDataSourceWrapper.cs
  20. 1
      src/Avalonia.Native/DispatcherImpl.cs
  21. 2
      src/Avalonia.Native/GpuHandleWrapFeature.cs
  22. 6
      src/Avalonia.Native/Helpers.cs
  23. 10
      src/Avalonia.Native/IAvnMenu.cs
  24. 18
      src/Avalonia.Native/IAvnMenuItem.cs
  25. 4
      src/Avalonia.Native/IconLoader.cs
  26. 3
      src/Avalonia.Native/MacOSActivatableLifetime.cs
  27. 56
      src/Avalonia.Native/Metal.cs
  28. 53
      src/Avalonia.Native/NativeControlHostImpl.cs
  29. 2
      src/Avalonia.Native/NativeOwned.cs
  30. 2
      src/Avalonia.Native/NativePlatformSettings.cs
  31. 2
      src/Avalonia.Native/ScreenImpl.cs
  32. 2
      src/Avalonia.Native/StorageItem.cs
  33. 2
      src/Avalonia.Native/StorageProviderApi.cs
  34. 4
      src/Avalonia.Native/StorageProviderImpl.cs
  35. 6
      src/Avalonia.Native/TopLevelImpl.cs
  36. 2
      src/Avalonia.Native/TrayIconImpl.cs
  37. 22
      src/Avalonia.Native/WindowImpl.cs
  38. 4
      src/Avalonia.Native/WindowImplBase.cs

1
src/Avalonia.Native/Avalonia.Native.csproj

@ -27,4 +27,5 @@
<Import Project="..\..\build\DevAnalyzers.props" /> <Import Project="..\..\build\DevAnalyzers.props" />
<Import Project="..\..\build\TrimmingEnable.props" /> <Import Project="..\..\build\TrimmingEnable.props" />
<Import Project="..\..\build\NullableEnable.props" />
</Project> </Project>

6
src/Avalonia.Native/AvaloniaNativeApplicationPlatform.cs

@ -12,11 +12,11 @@ namespace Avalonia.Native
{ {
internal class AvaloniaNativeApplicationPlatform : NativeCallbackBase, IAvnApplicationEvents, IPlatformLifetimeEventsImpl internal class AvaloniaNativeApplicationPlatform : NativeCallbackBase, IAvnApplicationEvents, IPlatformLifetimeEventsImpl
{ {
public event EventHandler<ShutdownRequestedEventArgs> ShutdownRequested; public event EventHandler<ShutdownRequestedEventArgs>? ShutdownRequested;
void IAvnApplicationEvents.FilesOpened(IAvnStringArray urls) void IAvnApplicationEvents.FilesOpened(IAvnStringArray urls)
{ {
((IApplicationPlatformEvents)Application.Current)?.RaiseUrlsOpened(urls.ToStringArray()); ((IApplicationPlatformEvents?)Application.Current)?.RaiseUrlsOpened(urls.ToStringArray());
if (AvaloniaLocator.Current.GetService<IActivatableLifetime>() is ActivatableLifetimeBase lifetime if (AvaloniaLocator.Current.GetService<IActivatableLifetime>() is ActivatableLifetimeBase lifetime
&& AvaloniaLocator.Current.GetService<IStorageProviderFactory>() is StorageProviderApi storageApi) && AvaloniaLocator.Current.GetService<IStorageProviderFactory>() is StorageProviderApi storageApi)
@ -42,7 +42,7 @@ namespace Avalonia.Native
void IAvnApplicationEvents.UrlsOpened(IAvnStringArray urls) void IAvnApplicationEvents.UrlsOpened(IAvnStringArray urls)
{ {
// Raise the urls opened event to be compatible with legacy behavior. // Raise the urls opened event to be compatible with legacy behavior.
((IApplicationPlatformEvents)Application.Current)?.RaiseUrlsOpened(urls.ToStringArray()); ((IApplicationPlatformEvents?)Application.Current)?.RaiseUrlsOpened(urls.ToStringArray());
if (AvaloniaLocator.Current.GetService<IActivatableLifetime>() is ActivatableLifetimeBase lifetime if (AvaloniaLocator.Current.GetService<IActivatableLifetime>() is ActivatableLifetimeBase lifetime
&& AvaloniaLocator.Current.GetService<IStorageProviderFactory>() is StorageProviderApi storageApi) && AvaloniaLocator.Current.GetService<IStorageProviderFactory>() is StorageProviderApi storageApi)

2
src/Avalonia.Native/AvaloniaNativeDragSource.cs

@ -19,7 +19,7 @@ namespace Avalonia.Native
class DndCallback : NativeCallbackBase, IAvnDndResultCallback class DndCallback : NativeCallbackBase, IAvnDndResultCallback
{ {
private TaskCompletionSource<DragDropEffects> _tcs; private TaskCompletionSource<DragDropEffects>? _tcs;
public DndCallback(TaskCompletionSource<DragDropEffects> tcs) public DndCallback(TaskCompletionSource<DragDropEffects> tcs)
{ {

52
src/Avalonia.Native/AvaloniaNativeGlPlatformGraphics.cs

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq; using System.Linq;
using Avalonia.OpenGL; using Avalonia.OpenGL;
using Avalonia.Native.Interop; using Avalonia.Native.Interop;
@ -90,12 +91,12 @@ namespace Avalonia.Native
class GlContext : IGlContext class GlContext : IGlContext
{ {
private readonly GlDisplay _display; private readonly GlDisplay _display;
private readonly GlContext _sharedWith; private readonly GlContext? _sharedWith;
private readonly GpuHandleWrapFeature _handleWrapFeature; private readonly GpuHandleWrapFeature _handleWrapFeature;
private readonly GlExternalObjectsFeature _externalObjects; private readonly GlExternalObjectsFeature _externalObjects;
public IAvnGlContext Context { get; private set; } public IAvnGlContext? Context { get; private set; }
public GlContext(GlDisplay display, GlContext sharedWith, IAvnGlContext context, GlVersion version) public GlContext(GlDisplay display, GlContext? sharedWith, IAvnGlContext context, GlVersion version)
{ {
_display = display; _display = display;
_sharedWith = sharedWith; _sharedWith = sharedWith;
@ -109,14 +110,25 @@ namespace Avalonia.Native
public GlInterface GlInterface => _display.GlInterface; public GlInterface GlInterface => _display.GlInterface;
public int SampleCount => _display.SampleCount; public int SampleCount => _display.SampleCount;
public int StencilSize => _display.StencilSize; public int StencilSize => _display.StencilSize;
public IDisposable MakeCurrent()
[MemberNotNull(nameof(Context))]
public void ThrowIfLost()
{ {
if (IsLost) if (IsLost)
throw new PlatformGraphicsContextLostException(); throw new PlatformGraphicsContextLostException();
}
[MemberNotNull(nameof(Context))]
public IDisposable MakeCurrent()
{
ThrowIfLost();
return Context.MakeCurrent(); return Context.MakeCurrent();
} }
[MemberNotNullWhen(false, nameof(Context))]
public bool IsLost => Context == null; public bool IsLost => Context == null;
[MemberNotNull(nameof(Context))]
public IDisposable EnsureCurrent() => MakeCurrent(); public IDisposable EnsureCurrent() => MakeCurrent();
public bool IsSharedWith(IGlContext context) public bool IsSharedWith(IGlContext context)
@ -130,16 +142,16 @@ namespace Avalonia.Native
public bool CanCreateSharedContext => true; public bool CanCreateSharedContext => true;
public IGlContext CreateSharedContext(IEnumerable<GlVersion> preferredVersions = null) => public IGlContext CreateSharedContext(IEnumerable<GlVersion>? preferredVersions = null) =>
_display.CreateSharedContext(_sharedWith ?? this); _display.CreateSharedContext(_sharedWith ?? this);
public void Dispose() public void Dispose()
{ {
Context.Dispose(); Context?.Dispose();
Context = null; Context = null;
} }
public object TryGetFeature(Type featureType) public object? TryGetFeature(Type featureType)
{ {
if (featureType == typeof(IExternalObjectsHandleWrapRenderInterfaceContextFeature)) if (featureType == typeof(IExternalObjectsHandleWrapRenderInterfaceContextFeature))
return _handleWrapFeature; return _handleWrapFeature;
@ -152,7 +164,7 @@ namespace Avalonia.Native
class GlPlatformSurfaceRenderTarget : IGlPlatformSurfaceRenderTarget class GlPlatformSurfaceRenderTarget : IGlPlatformSurfaceRenderTarget
{ {
private IAvnGlSurfaceRenderTarget _target; private IAvnGlSurfaceRenderTarget? _target;
private readonly IGlContext _context; private readonly IGlContext _context;
public GlPlatformSurfaceRenderTarget(IAvnGlSurfaceRenderTarget target, IGlContext context) public GlPlatformSurfaceRenderTarget(IAvnGlSurfaceRenderTarget target, IGlContext context)
@ -163,6 +175,7 @@ namespace Avalonia.Native
public IGlPlatformSurfaceRenderingSession BeginDraw() public IGlPlatformSurfaceRenderingSession BeginDraw()
{ {
ObjectDisposedException.ThrowIf(_target is null, this);
return new GlPlatformSurfaceRenderingSession(_context, _target.BeginDrawing()); return new GlPlatformSurfaceRenderingSession(_context, _target.BeginDrawing());
} }
@ -175,7 +188,7 @@ namespace Avalonia.Native
class GlPlatformSurfaceRenderingSession : IGlPlatformSurfaceRenderingSession class GlPlatformSurfaceRenderingSession : IGlPlatformSurfaceRenderingSession
{ {
private IAvnGlSurfaceRenderingSession _session; private IAvnGlSurfaceRenderingSession? _session;
public GlPlatformSurfaceRenderingSession(IGlContext context, IAvnGlSurfaceRenderingSession session) public GlPlatformSurfaceRenderingSession(IGlContext context, IAvnGlSurfaceRenderingSession session)
{ {
@ -185,17 +198,25 @@ namespace Avalonia.Native
public IGlContext Context { get; } public IGlContext Context { get; }
private IAvnGlSurfaceRenderingSession Session
{
get
{
ObjectDisposedException.ThrowIf(_session is null, this);
return _session;
}
}
public PixelSize Size public PixelSize Size
{ {
get get
{ {
var s = _session.PixelSize; var s = Session.PixelSize;
return new PixelSize(s.Width, s.Height); return new PixelSize(s.Width, s.Height);
} }
} }
public double Scaling => _session.Scaling; public double Scaling => Session.Scaling;
public bool IsYFlipped => true; public bool IsYFlipped => true;
@ -230,9 +251,12 @@ namespace Avalonia.Native
public unsafe GlExternalObjectsFeature(GlContext context, GlDisplay display) public unsafe GlExternalObjectsFeature(GlContext context, GlDisplay display)
{ {
context.ThrowIfLost();
_context = context; _context = context;
_display = display; _display = display;
ulong registryId = 0; ulong registryId = 0;
if (context.Context.GetIOKitRegistryId(&registryId) != 0) if (context.Context.GetIOKitRegistryId(&registryId) != 0)
{ {
// We are reversing bytes to match MoltenVK (LUID is a Vulkan term after all) // We are reversing bytes to match MoltenVK (LUID is a Vulkan term after all)
@ -306,8 +330,8 @@ namespace Avalonia.Native
CompositionGpuImportedImageSynchronizationCapabilities.TimelineSemaphores; CompositionGpuImportedImageSynchronizationCapabilities.TimelineSemaphores;
} }
public byte[] DeviceLuid { get; } public byte[]? DeviceLuid { get; }
public byte[] DeviceUuid { get; } public byte[]? DeviceUuid { get; }
} }
class MtlEventSemaphore(IAvnMTLSharedEvent inner) : IGlExternalSemaphore class MtlEventSemaphore(IAvnMTLSharedEvent inner) : IGlExternalSemaphore

19
src/Avalonia.Native/AvaloniaNativeMenuExporter.cs

@ -15,10 +15,10 @@ namespace Avalonia.Native
private readonly IAvaloniaNativeFactory _factory; private readonly IAvaloniaNativeFactory _factory;
private bool _resetQueued = true; private bool _resetQueued = true;
private bool _exported; private bool _exported;
private readonly IAvnWindow _nativeWindow; private readonly IAvnWindow? _nativeWindow;
private NativeMenu _menu; private NativeMenu? _menu;
private __MicroComIAvnMenuProxy _nativeMenu; private __MicroComIAvnMenuProxy? _nativeMenu;
private readonly IAvnTrayIcon _trayIcon; private readonly IAvnTrayIcon? _trayIcon;
private readonly IAvnApplicationCommands _applicationCommands; private readonly IAvnApplicationCommands _applicationCommands;
public AvaloniaNativeMenuExporter(IAvnWindow nativeWindow, IAvaloniaNativeFactory factory) public AvaloniaNativeMenuExporter(IAvnWindow nativeWindow, IAvaloniaNativeFactory factory)
@ -51,7 +51,7 @@ namespace Avalonia.Native
public event EventHandler OnIsNativeMenuExportedChanged { add { } remove { } } public event EventHandler OnIsNativeMenuExportedChanged { add { } remove { } }
public void SetNativeMenu(NativeMenu menu) public void SetNativeMenu(NativeMenu? menu)
{ {
_menu = menu ?? new NativeMenu(); _menu = menu ?? new NativeMenu();
DoLayoutReset(true); DoLayoutReset(true);
@ -152,7 +152,7 @@ namespace Avalonia.Native
private void DoLayoutReset() => DoLayoutReset(false); private void DoLayoutReset() => DoLayoutReset(false);
private void DoLayoutReset(bool forceUpdate = false) private void DoLayoutReset(bool forceUpdate)
{ {
var macOpts = AvaloniaLocator.Current.GetService<MacOSPlatformOptions>() ?? new MacOSPlatformOptions(); var macOpts = AvaloniaLocator.Current.GetService<MacOSPlatformOptions>() ?? new MacOSPlatformOptions();
@ -169,12 +169,15 @@ namespace Avalonia.Native
{ {
if (_trayIcon is null) if (_trayIcon is null)
{ {
var appMenu = NativeMenu.GetMenu(Application.Current); var app = Application.Current;
var appMenu = app is null ? null : NativeMenu.GetMenu(app);
if (appMenu == null) if (appMenu == null)
{ {
appMenu = CreateDefaultAppMenu(); appMenu = CreateDefaultAppMenu();
NativeMenu.SetMenu(Application.Current, appMenu);
if (app is not null)
NativeMenu.SetMenu(app, appMenu);
} }
SetMenu(appMenu); SetMenu(appMenu);

3
src/Avalonia.Native/AvaloniaNativePlatform.cs

@ -12,7 +12,6 @@ using Avalonia.Rendering;
using Avalonia.Rendering.Composition; using Avalonia.Rendering.Composition;
using Avalonia.Threading; using Avalonia.Threading;
using MicroCom.Runtime; using MicroCom.Runtime;
#nullable enable
namespace Avalonia.Native namespace Avalonia.Native
{ {
@ -199,7 +198,7 @@ namespace Avalonia.Native
public IWindowImpl CreateWindow() public IWindowImpl CreateWindow()
{ {
return new WindowImpl(_factory, _options); return new WindowImpl(_factory, _options ?? new AvaloniaNativePlatformOptions());
} }
public IWindowImpl CreateEmbeddableWindow() public IWindowImpl CreateEmbeddableWindow()

2
src/Avalonia.Native/AvaloniaNativePlatformExtensions.cs

@ -79,7 +79,7 @@ namespace Avalonia
/// This property should be used in case you want to build Avalonia OSX native part by yourself /// This property should be used in case you want to build Avalonia OSX native part by yourself
/// and make your Avalonia app run with it. The default value is null. /// and make your Avalonia app run with it. The default value is null.
/// </summary> /// </summary>
public string AvaloniaNativeLibraryPath { get; set; } public string? AvaloniaNativeLibraryPath { get; set; }
/// <summary> /// <summary>
/// If you distribute your app in App Store - it should be with sandbox enabled. /// If you distribute your app in App Store - it should be with sandbox enabled.

2
src/Avalonia.Native/AvaloniaNativeRenderTimer.cs

@ -1,9 +1,7 @@
using System; using System;
using System.Diagnostics; using System.Diagnostics;
using System.Runtime.InteropServices;
using Avalonia.Native.Interop; using Avalonia.Native.Interop;
using Avalonia.Rendering; using Avalonia.Rendering;
#nullable enable
namespace Avalonia.Native; namespace Avalonia.Native;

3
src/Avalonia.Native/AvaloniaNativeTextInputMethod.cs

@ -1,10 +1,7 @@
using System; using System;
using Avalonia.Input.TextInput; using Avalonia.Input.TextInput;
using Avalonia.Media.TextFormatting;
using Avalonia.Native.Interop; using Avalonia.Native.Interop;
#nullable enable
namespace Avalonia.Native namespace Avalonia.Native
{ {
internal class AvaloniaNativeTextInputMethod : ITextInputMethodImpl, IDisposable internal class AvaloniaNativeTextInputMethod : ITextInputMethodImpl, IDisposable

11
src/Avalonia.Native/AvnAutomationPeer.cs

@ -6,12 +6,9 @@ using System.Runtime.CompilerServices;
using Avalonia.Automation; using Avalonia.Automation;
using Avalonia.Automation.Peers; using Avalonia.Automation.Peers;
using Avalonia.Automation.Provider; using Avalonia.Automation.Provider;
using Avalonia.Controls;
using Avalonia.Controls.Automation.Peers; using Avalonia.Controls.Automation.Peers;
using Avalonia.Native.Interop; using Avalonia.Native.Interop;
#nullable enable
namespace Avalonia.Native namespace Avalonia.Native
{ {
internal class AvnAutomationPeer : NativeCallbackBase, IAvnAutomationPeer internal class AvnAutomationPeer : NativeCallbackBase, IAvnAutomationPeer
@ -36,10 +33,10 @@ namespace Avalonia.Native
public IAvnString? AutomationId => _inner.GetAutomationId().ToAvnString(); public IAvnString? AutomationId => _inner.GetAutomationId().ToAvnString();
public AvnRect BoundingRectangle => _inner.GetBoundingRectangle().ToAvnRect(); public AvnRect BoundingRectangle => _inner.GetBoundingRectangle().ToAvnRect();
public IAvnAutomationPeerArray Children => new AvnAutomationPeerArray(_inner.GetChildren()); public IAvnAutomationPeerArray Children => new AvnAutomationPeerArray(_inner.GetChildren());
public IAvnString ClassName => _inner.GetClassName().ToAvnString(); public IAvnString? ClassName => _inner.GetClassName().ToAvnString();
public IAvnAutomationPeer? LabeledBy => Wrap(_inner.GetLabeledBy()); public IAvnAutomationPeer? LabeledBy => Wrap(_inner.GetLabeledBy());
public IAvnString Name => _inner.GetName().ToAvnString(); public IAvnString? Name => _inner.GetName().ToAvnString();
public IAvnString HelpText => _inner.GetHelpText().ToAvnString(); public IAvnString? HelpText => _inner.GetHelpText().ToAvnString();
public AvnLandmarkType LandmarkType => (AvnLandmarkType?)_inner.GetLandmarkType() ?? AvnLandmarkType.LandmarkNone; public AvnLandmarkType LandmarkType => (AvnLandmarkType?)_inner.GetLandmarkType() ?? AvnLandmarkType.LandmarkNone;
public int HeadingLevel => _inner.GetHeadingLevel(); public int HeadingLevel => _inner.GetHeadingLevel();
public IAvnAutomationPeer? Parent => Wrap(_inner.GetParent()); public IAvnAutomationPeer? Parent => Wrap(_inner.GetParent());
@ -173,7 +170,7 @@ namespace Avalonia.Native
public void ToggleProvider_Toggle() => ToggleProvider.Toggle(); public void ToggleProvider_Toggle() => ToggleProvider.Toggle();
public int IsValueProvider() => IsProvider<IValueProvider>(); public int IsValueProvider() => IsProvider<IValueProvider>();
public IAvnString ValueProvider_GetValue() => ValueProvider.Value.ToAvnString(); public IAvnString? ValueProvider_GetValue() => ValueProvider.Value.ToAvnString();
public void ValueProvider_SetValue(string value) => ValueProvider.SetValue(value); public void ValueProvider_SetValue(string value) => ValueProvider.SetValue(value);
[return: NotNullIfNotNull("peer")] [return: NotNullIfNotNull("peer")]

14
src/Avalonia.Native/AvnString.cs

@ -8,7 +8,7 @@ namespace Avalonia.Native.Interop
{ {
partial interface IAvnString partial interface IAvnString
{ {
public string String { get; } public string? String { get; }
public byte[] Bytes { get; } public byte[] Bytes { get; }
} }
@ -73,7 +73,7 @@ namespace Avalonia.Native.Interop
_items = items.Select(s => s.ToAvnString()).ToArray(); _items = items.Select(s => s.ToAvnString()).ToArray();
} }
public string[] ToStringArray() => _items.Select(n => n.String).ToArray(); public string[] ToStringArray() => _items.Select(n => n.String ?? string.Empty).ToArray();
public uint Count => (uint)_items.Length; public uint Count => (uint)_items.Length;
public IAvnString Get(uint index) => _items[(int)index]; public IAvnString Get(uint index) => _items[(int)index];
@ -91,10 +91,10 @@ namespace Avalonia.Native.Interop.Impl
{ {
unsafe partial class __MicroComIAvnStringProxy unsafe partial class __MicroComIAvnStringProxy
{ {
private string _managed; private string? _managed;
private byte[] _bytes; private byte[]? _bytes;
public string String public string? String
{ {
get get
{ {
@ -124,7 +124,7 @@ namespace Avalonia.Native.Interop.Impl
} }
} }
public override string ToString() => String; public override string? ToString() => String;
} }
partial class __MicroComIAvnStringArrayProxy partial class __MicroComIAvnStringArrayProxy
@ -134,7 +134,7 @@ namespace Avalonia.Native.Interop.Impl
var arr = new string[Count]; var arr = new string[Count];
for(uint c = 0; c<arr.Length;c++) for(uint c = 0; c<arr.Length;c++)
using (var s = Get(c)) using (var s = Get(c))
arr[c] = s.String; arr[c] = s.String ?? string.Empty;
return arr; return arr;
} }
} }

4
src/Avalonia.Native/ClipboardDataFormatHelper.cs

@ -1,5 +1,3 @@
#nullable enable
using System; using System;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Native.Interop; using Avalonia.Native.Interop;
@ -28,7 +26,7 @@ internal static class ClipboardDataFormatHelper
for (var c = 0u; c < count; c++) for (var c = 0u; c < count; c++)
{ {
using var nativeFormat = nativeFormats.Get(c); using var nativeFormat = nativeFormats.Get(c);
results[c] = ToDataFormat(nativeFormat.String, isTextFormat); results[c] = ToDataFormat(nativeFormat.String ?? string.Empty, isTextFormat);
} }
return results; return results;

4
src/Avalonia.Native/ClipboardDataTransfer.cs

@ -1,6 +1,4 @@
#nullable enable using System.Collections.Generic;
using System.Collections.Generic;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Input.Platform; using Avalonia.Input.Platform;

2
src/Avalonia.Native/ClipboardDataTransferItem.cs

@ -1,5 +1,3 @@
#nullable enable
using System; using System;
using System.IO; using System.IO;
using System.Text; using System.Text;

4
src/Avalonia.Native/ClipboardImpl.cs

@ -1,6 +1,4 @@
#nullable enable using System;
using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Input.Platform; using Avalonia.Input.Platform;

2
src/Avalonia.Native/ClipboardReadSession.cs

@ -1,5 +1,3 @@
#nullable enable
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using Avalonia.Native.Interop; using Avalonia.Native.Interop;

4
src/Avalonia.Native/Cursor.cs

@ -8,7 +8,7 @@ namespace Avalonia.Native
{ {
class AvaloniaNativeCursor : ICursorImpl, IDisposable class AvaloniaNativeCursor : ICursorImpl, IDisposable
{ {
public IAvnCursor Cursor { get; private set; } public IAvnCursor? Cursor { get; private set; }
public IntPtr Handle => IntPtr.Zero; public IntPtr Handle => IntPtr.Zero;
public string HandleDescriptor => "<none>"; public string HandleDescriptor => "<none>";
@ -20,7 +20,7 @@ namespace Avalonia.Native
public void Dispose() public void Dispose()
{ {
Cursor.Dispose(); Cursor?.Dispose();
Cursor = null; Cursor = null;
} }
} }

3
src/Avalonia.Native/DataTransferItemToAvnClipboardDataItemWrapper.cs

@ -1,12 +1,9 @@
#nullable enable
using System; using System;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Logging; using Avalonia.Logging;
using Avalonia.Native.Interop; using Avalonia.Native.Interop;
using Avalonia.Utilities;
namespace Avalonia.Native; namespace Avalonia.Native;

2
src/Avalonia.Native/DataTransferToAvnClipboardDataSourceWrapper.cs

@ -1,5 +1,3 @@
#nullable enable
using System; using System;
using System.Linq; using System.Linq;
using Avalonia.Input; using Avalonia.Input;

1
src/Avalonia.Native/DispatcherImpl.cs

@ -1,4 +1,3 @@
#nullable enable
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;

2
src/Avalonia.Native/GpuHandleWrapFeature.cs

@ -1,5 +1,3 @@
#nullable enable
using System; using System;
using Avalonia.Native.Interop; using Avalonia.Native.Interop;
using Avalonia.Platform; using Avalonia.Platform;

6
src/Avalonia.Native/Helpers.cs

@ -1,4 +1,5 @@
using Avalonia.Native.Interop; using System.Diagnostics.CodeAnalysis;
using Avalonia.Native.Interop;
namespace Avalonia.Native namespace Avalonia.Native
{ {
@ -34,7 +35,8 @@ namespace Avalonia.Native
return new AvnSize { Height = size.Height, Width = size.Width }; return new AvnSize { Height = size.Height, Width = size.Width };
} }
public static IAvnString ToAvnString(this string s) [return: NotNullIfNotNull(nameof(s))]
public static IAvnString? ToAvnString(this string? s)
{ {
return s != null ? new AvnString(s) : null; return s != null ? new AvnString(s) : null;
} }

10
src/Avalonia.Native/IAvnMenu.cs

@ -10,7 +10,7 @@ namespace Avalonia.Native.Interop
{ {
class MenuEvents : NativeCallbackBase, IAvnMenuEvents class MenuEvents : NativeCallbackBase, IAvnMenuEvents
{ {
private IAvnMenu _parent; private IAvnMenu? _parent;
public void Initialise(IAvnMenu parent) public void Initialise(IAvnMenu parent)
{ {
@ -49,7 +49,7 @@ namespace Avalonia.Native.Interop.Impl
private List<__MicroComIAvnMenuItemProxy> _menuItems = new List<__MicroComIAvnMenuItemProxy>(); private List<__MicroComIAvnMenuItemProxy> _menuItems = new List<__MicroComIAvnMenuItemProxy>();
private Dictionary<NativeMenuItemBase, __MicroComIAvnMenuItemProxy> _menuItemLookup = new Dictionary<NativeMenuItemBase, __MicroComIAvnMenuItemProxy>(); private Dictionary<NativeMenuItemBase, __MicroComIAvnMenuItemProxy> _menuItemLookup = new Dictionary<NativeMenuItemBase, __MicroComIAvnMenuItemProxy>();
private void UpdateTitle(string title) private void UpdateTitle(string? title)
{ {
if (OperatingSystemEx.IsMacOS()) if (OperatingSystemEx.IsMacOS())
{ {
@ -136,7 +136,7 @@ namespace Avalonia.Native.Interop.Impl
return nativeItem; return nativeItem;
} }
internal void Initialize(AvaloniaNativeMenuExporter exporter, NativeMenu managedMenu, string title) internal void Initialize(AvaloniaNativeMenuExporter exporter, NativeMenu managedMenu, string? title)
{ {
_exporter = exporter; _exporter = exporter;
ManagedMenu = managedMenu; ManagedMenu = managedMenu;
@ -166,7 +166,7 @@ namespace Avalonia.Native.Interop.Impl
for (int i = 0; i < menu.Items.Count; i++) for (int i = 0; i < menu.Items.Count; i++)
{ {
__MicroComIAvnMenuItemProxy nativeItem; __MicroComIAvnMenuItemProxy? nativeItem;
if (i >= _menuItems.Count) if (i >= _menuItems.Count)
{ {
@ -197,7 +197,7 @@ namespace Avalonia.Native.Interop.Impl
} }
} }
private void OnMenuItemsChanged(object sender, NotifyCollectionChangedEventArgs e) private void OnMenuItemsChanged(object? sender, NotifyCollectionChangedEventArgs e)
{ {
_exporter.QueueReset(); _exporter.QueueReset();
} }

18
src/Avalonia.Native/IAvnMenuItem.cs

@ -18,13 +18,13 @@ namespace Avalonia.Native.Interop.Impl
{ {
partial class __MicroComIAvnMenuItemProxy partial class __MicroComIAvnMenuItemProxy
{ {
private __MicroComIAvnMenuProxy _subMenu; private __MicroComIAvnMenuProxy? _subMenu;
private CompositeDisposable _propertyDisposables = new CompositeDisposable(); private CompositeDisposable _propertyDisposables = new CompositeDisposable();
private IDisposable _currentActionDisposable; private IDisposable? _currentActionDisposable;
public NativeMenuItemBase ManagedMenuItem { get; set; } public NativeMenuItemBase ManagedMenuItem { get; set; }
private void UpdateTitle(string title) private void UpdateTitle(string? title)
{ {
if (OperatingSystemEx.IsMacOS()) if (OperatingSystemEx.IsMacOS())
{ {
@ -38,7 +38,7 @@ namespace Avalonia.Native.Interop.Impl
SetTitle(title); SetTitle(title);
} }
private void UpdateToolTip(string toolTip) => SetToolTip(toolTip ?? ""); private void UpdateToolTip(string? toolTip) => SetToolTip(toolTip ?? "");
private void UpdateIsVisible(bool isVisible) => SetIsVisible(isVisible.AsComBool()); private void UpdateIsVisible(bool isVisible) => SetIsVisible(isVisible.AsComBool());
private void UpdateIsChecked(bool isChecked) => SetIsChecked(isChecked.AsComBool()); private void UpdateIsChecked(bool isChecked) => SetIsChecked(isChecked.AsComBool());
@ -48,7 +48,7 @@ namespace Avalonia.Native.Interop.Impl
SetToggleType((AvnMenuItemToggleType)toggleType); SetToggleType((AvnMenuItemToggleType)toggleType);
} }
private unsafe void UpdateIcon (IBitmap icon) private unsafe void UpdateIcon (IBitmap? icon)
{ {
if(icon is null) if(icon is null)
{ {
@ -70,20 +70,20 @@ namespace Avalonia.Native.Interop.Impl
} }
} }
private void UpdateGesture(Input.KeyGesture gesture) private void UpdateGesture(Input.KeyGesture? gesture)
{ {
var modifiers = gesture == null ? AvnInputModifiers.AvnInputModifiersNone : (AvnInputModifiers)gesture.KeyModifiers; var modifiers = gesture == null ? AvnInputModifiers.AvnInputModifiersNone : (AvnInputModifiers)gesture.KeyModifiers;
var key = gesture == null ? AvnKey.AvnKeyNone : (AvnKey)gesture.Key; var key = gesture == null ? AvnKey.AvnKeyNone : (AvnKey)gesture.Key;
SetGesture(key, modifiers); SetGesture(key, modifiers);
} }
private void UpdateAction(NativeMenuItem item) private void UpdateAction(NativeMenuItem? item)
{ {
_currentActionDisposable?.Dispose(); _currentActionDisposable?.Dispose();
var action = new PredicateCallback(() => var action = new PredicateCallback(() =>
{ {
if (item.Command != null || item.HasClickHandlers) if (item is not null && (item.Command is not null || item.HasClickHandlers))
{ {
return item.IsEnabled; return item.IsEnabled;
} }
@ -160,7 +160,7 @@ namespace Avalonia.Native.Interop.Impl
_subMenu = null; _subMenu = null;
} }
_propertyDisposables?.Dispose(); _propertyDisposables.Dispose();
_currentActionDisposable?.Dispose(); _currentActionDisposable?.Dispose();
} }

4
src/Avalonia.Native/IconLoader.cs

@ -27,13 +27,13 @@ namespace Avalonia.Native
public IWindowIconImpl LoadIcon(string fileName) public IWindowIconImpl LoadIcon(string fileName)
{ {
return new IconStub( return new IconStub(
AvaloniaLocator.Current.GetService<IPlatformRenderInterface>().LoadBitmap(fileName)); AvaloniaLocator.Current.GetRequiredService<IPlatformRenderInterface>().LoadBitmap(fileName));
} }
public IWindowIconImpl LoadIcon(Stream stream) public IWindowIconImpl LoadIcon(Stream stream)
{ {
return new IconStub( return new IconStub(
AvaloniaLocator.Current.GetService<IPlatformRenderInterface>().LoadBitmap(stream)); AvaloniaLocator.Current.GetRequiredService<IPlatformRenderInterface>().LoadBitmap(stream));
} }
public IWindowIconImpl LoadIcon(IBitmapImpl bitmap) public IWindowIconImpl LoadIcon(IBitmapImpl bitmap)

3
src/Avalonia.Native/MacOSActivatableLifetime.cs

@ -1,11 +1,8 @@
using System;
using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Controls.Platform; using Avalonia.Controls.Platform;
namespace Avalonia.Native; namespace Avalonia.Native;
#nullable enable
internal class MacOSActivatableLifetime : ActivatableLifetimeBase internal class MacOSActivatableLifetime : ActivatableLifetimeBase
{ {
public override bool TryLeaveBackground() public override bool TryLeaveBackground()

56
src/Avalonia.Native/Metal.cs

@ -28,26 +28,34 @@ class MetalPlatformGraphics : IPlatformGraphics
class MetalDevice : IMetalDevice class MetalDevice : IMetalDevice
{ {
public IAvnMetalDevice Native { get; private set; } private readonly DisposableLock _syncRoot = new();
private DisposableLock _syncRoot = new();
private readonly GpuHandleWrapFeature _handleWrapFeature; private readonly GpuHandleWrapFeature _handleWrapFeature;
private readonly MetalExternalObjectsFeature _externalObjectsFeature; private readonly MetalExternalObjectsFeature _externalObjectsFeature;
private IAvnMetalDevice? _native;
public MetalDevice(IAvaloniaNativeFactory factory, IAvnMetalDevice native) public MetalDevice(IAvaloniaNativeFactory factory, IAvnMetalDevice native)
{ {
Native = native; _native = native;
_handleWrapFeature = new GpuHandleWrapFeature(factory); _handleWrapFeature = new GpuHandleWrapFeature(factory);
_externalObjectsFeature = new MetalExternalObjectsFeature(native); _externalObjectsFeature = new MetalExternalObjectsFeature(native);
} }
public IAvnMetalDevice Native
{
get
{
ObjectDisposedException.ThrowIf(_native is null, this);
return _native;
}
}
public void Dispose() public void Dispose()
{ {
Native?.Dispose(); _native?.Dispose();
Native = null; _native = null;
} }
public object TryGetFeature(Type featureType) public object? TryGetFeature(Type featureType)
{ {
if (featureType == typeof(IExternalObjectsHandleWrapRenderInterfaceContextFeature)) if (featureType == typeof(IExternalObjectsHandleWrapRenderInterfaceContextFeature))
return _handleWrapFeature; return _handleWrapFeature;
@ -105,7 +113,7 @@ internal class MetalExternalObjectsFeature : IMetalExternalObjectsFeature
public IReadOnlyList<string> SupportedSemaphoreTypes { get; } = public IReadOnlyList<string> SupportedSemaphoreTypes { get; } =
[KnownPlatformGraphicsExternalSemaphoreHandleTypes.MetalSharedEvent]; [KnownPlatformGraphicsExternalSemaphoreHandleTypes.MetalSharedEvent];
public byte[] DeviceLuid { get; } public byte[]? DeviceLuid { get; }
public CompositionGpuImportedImageSynchronizationCapabilities public CompositionGpuImportedImageSynchronizationCapabilities
GetSynchronizationCapabilities(string imageHandleType) => GetSynchronizationCapabilities(string imageHandleType) =>
@ -166,13 +174,22 @@ internal class MetalExternalObjectsFeature : IMetalExternalObjectsFeature
internal class MetalRenderTarget : IMetalPlatformSurfaceRenderTarget internal class MetalRenderTarget : IMetalPlatformSurfaceRenderTarget
{ {
private IAvnMetalRenderTarget _native; private IAvnMetalRenderTarget? _native;
public MetalRenderTarget(IAvnMetalRenderTarget native) public MetalRenderTarget(IAvnMetalRenderTarget native)
{ {
_native = native; _native = native;
} }
private IAvnMetalRenderTarget Native
{
get
{
ObjectDisposedException.ThrowIf(_native is null, this);
return _native;
}
}
public void Dispose() public void Dispose()
{ {
_native?.Dispose(); _native?.Dispose();
@ -181,36 +198,47 @@ internal class MetalRenderTarget : IMetalPlatformSurfaceRenderTarget
public IMetalPlatformSurfaceRenderingSession BeginRendering() public IMetalPlatformSurfaceRenderingSession BeginRendering()
{ {
var session = _native.BeginDrawing(); var session = Native.BeginDrawing();
return new MetalDrawingSession(session); return new MetalDrawingSession(session);
} }
} }
internal class MetalDrawingSession : IMetalPlatformSurfaceRenderingSession internal class MetalDrawingSession : IMetalPlatformSurfaceRenderingSession
{ {
private IAvnMetalRenderingSession _session; private IAvnMetalRenderingSession? _session;
public MetalDrawingSession(IAvnMetalRenderingSession session) public MetalDrawingSession(IAvnMetalRenderingSession session)
{ {
_session = session; _session = session;
} }
public IAvnMetalRenderingSession Session
{
get
{
ObjectDisposedException.ThrowIf(_session is null, this);
return _session;
}
}
public void Dispose() public void Dispose()
{ {
_session?.Dispose(); _session?.Dispose();
_session = null; _session = null;
} }
public IntPtr Texture => _session.Texture; public IntPtr Texture => Session.Texture;
public PixelSize Size public PixelSize Size
{ {
get get
{ {
var size = _session.PixelSize; var size = Session.PixelSize;
return new(size.Width, size.Height); return new(size.Width, size.Height);
} }
} }
public double Scaling => _session.Scaling; public double Scaling => Session.Scaling;
public bool IsYFlipped => false; public bool IsYFlipped => false;
} }

53
src/Avalonia.Native/NativeControlHostImpl.cs

@ -10,13 +10,22 @@ namespace Avalonia.Native
{ {
class NativeControlHostImpl : IDisposable, INativeControlHostImpl class NativeControlHostImpl : IDisposable, INativeControlHostImpl
{ {
private IAvnNativeControlHost _host; private IAvnNativeControlHost? _host;
public NativeControlHostImpl(IAvnNativeControlHost host) public NativeControlHostImpl(IAvnNativeControlHost host)
{ {
_host = host; _host = host;
} }
private IAvnNativeControlHost Host
{
get
{
ObjectDisposedException.ThrowIf(_host is null, this);
return _host;
}
}
public void Dispose() public void Dispose()
{ {
_host?.Dispose(); _host?.Dispose();
@ -25,7 +34,7 @@ namespace Avalonia.Native
class DestroyableNSView : INativeControlHostDestroyableControlHandle class DestroyableNSView : INativeControlHostDestroyableControlHandle
{ {
private IAvnNativeControlHost _impl; private IAvnNativeControlHost? _impl;
private IntPtr _nsView; private IntPtr _nsView;
public DestroyableNSView(IAvnNativeControlHost impl) public DestroyableNSView(IAvnNativeControlHost impl)
@ -49,12 +58,12 @@ namespace Avalonia.Native
} }
public INativeControlHostDestroyableControlHandle CreateDefaultChild(IPlatformHandle parent) public INativeControlHostDestroyableControlHandle CreateDefaultChild(IPlatformHandle parent)
=> new DestroyableNSView(_host); => new DestroyableNSView(Host);
public INativeControlHostControlTopLevelAttachment CreateNewAttachment( public INativeControlHostControlTopLevelAttachment CreateNewAttachment(
Func<IPlatformHandle, IPlatformHandle> create) Func<IPlatformHandle, IPlatformHandle> create)
{ {
var a = new Attachment(_host.CreateAttachment()); var a = new Attachment(Host.CreateAttachment());
try try
{ {
var child = create(a.GetParentHandle()); var child = create(a.GetParentHandle());
@ -71,7 +80,7 @@ namespace Avalonia.Native
public INativeControlHostControlTopLevelAttachment CreateNewAttachment(IPlatformHandle handle) public INativeControlHostControlTopLevelAttachment CreateNewAttachment(IPlatformHandle handle)
{ {
var a = new Attachment(_host.CreateAttachment()); var a = new Attachment(Host.CreateAttachment());
a.InitWithChild(handle); a.InitWithChild(handle);
a.AttachedTo = this; a.AttachedTo = this;
return a; return a;
@ -81,14 +90,25 @@ namespace Avalonia.Native
class Attachment : INativeControlHostControlTopLevelAttachment class Attachment : INativeControlHostControlTopLevelAttachment
{ {
private IAvnNativeControlHostTopLevelAttachment _native; private IAvnNativeControlHostTopLevelAttachment? _native;
private NativeControlHostImpl _attachedTo; private NativeControlHostImpl? _attachedTo;
public IPlatformHandle GetParentHandle() => new PlatformHandle(_native.ParentHandle, "NSView");
public Attachment(IAvnNativeControlHostTopLevelAttachment native) public Attachment(IAvnNativeControlHostTopLevelAttachment native)
{ {
_native = native; _native = native;
} }
private IAvnNativeControlHostTopLevelAttachment Native
{
get
{
ObjectDisposedException.ThrowIf(_native is null, this);
return _native;
}
}
public IPlatformHandle GetParentHandle() => new PlatformHandle(Native.ParentHandle, "NSView");
public void Dispose() public void Dispose()
{ {
if (_native != null) if (_native != null)
@ -99,16 +119,13 @@ namespace Avalonia.Native
} }
} }
public INativeControlHostImpl AttachedTo public INativeControlHostImpl? AttachedTo
{ {
get => _attachedTo; get => _attachedTo;
set set
{ {
var host = (NativeControlHostImpl)value; var host = (NativeControlHostImpl?)value;
if(host == null) Native.AttachTo(host?._host);
_native.AttachTo(null);
else
_native.AttachTo(host._host);
_attachedTo = host; _attachedTo = host;
} }
} }
@ -117,7 +134,7 @@ namespace Avalonia.Native
public void HideWithSize(Size size) public void HideWithSize(Size size)
{ {
_native.HideWithSize(Math.Max(1, (float)size.Width), Math.Max(1, (float)size.Height)); Native.HideWithSize(Math.Max(1, (float)size.Width), Math.Max(1, (float)size.Height));
} }
public void ShowInBounds(Rect bounds) public void ShowInBounds(Rect bounds)
@ -126,11 +143,11 @@ namespace Avalonia.Native
throw new InvalidOperationException("Native control isn't attached to a toplevel"); throw new InvalidOperationException("Native control isn't attached to a toplevel");
bounds = new Rect(bounds.X, bounds.Y, Math.Max(1, bounds.Width), bounds = new Rect(bounds.X, bounds.Y, Math.Max(1, bounds.Width),
Math.Max(1, bounds.Height)); Math.Max(1, bounds.Height));
_native.ShowInBounds((float) bounds.X, (float) bounds.Y, (float) bounds.Width, (float) bounds.Height); Native.ShowInBounds((float) bounds.X, (float) bounds.Y, (float) bounds.Width, (float) bounds.Height);
} }
public void InitWithChild(IPlatformHandle handle) public void InitWithChild(IPlatformHandle handle)
=> _native.InitializeWithChildHandle(handle.Handle); => Native.InitializeWithChildHandle(handle.Handle);
} }
} }
} }

2
src/Avalonia.Native/NativeOwned.cs

@ -1,5 +1,3 @@
#nullable enable
using System; using System;
using System.Runtime.ExceptionServices; using System.Runtime.ExceptionServices;
using Avalonia.Threading; using Avalonia.Threading;

2
src/Avalonia.Native/NativePlatformSettings.cs

@ -8,7 +8,7 @@ namespace Avalonia.Native;
internal class NativePlatformSettings : DefaultPlatformSettings internal class NativePlatformSettings : DefaultPlatformSettings
{ {
private readonly IAvnPlatformSettings _platformSettings; private readonly IAvnPlatformSettings _platformSettings;
private PlatformColorValues _lastColorValues; private PlatformColorValues? _lastColorValues;
public NativePlatformSettings(IAvnPlatformSettings platformSettings) public NativePlatformSettings(IAvnPlatformSettings platformSettings)
{ {

2
src/Avalonia.Native/ScreenImpl.cs

@ -4,8 +4,6 @@ using Avalonia.Native.Interop;
using Avalonia.Platform; using Avalonia.Platform;
using MicroCom.Runtime; using MicroCom.Runtime;
#nullable enable
namespace Avalonia.Native namespace Avalonia.Native
{ {
internal sealed class AvnScreen(uint displayId) internal sealed class AvnScreen(uint displayId)

2
src/Avalonia.Native/StorageItem.cs

@ -1,5 +1,3 @@
#nullable enable
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;

2
src/Avalonia.Native/StorageProviderApi.cs

@ -1,5 +1,3 @@
#nullable enable
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;

4
src/Avalonia.Native/StorageProviderImpl.cs

@ -1,6 +1,4 @@
#nullable enable using System;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Avalonia.Platform.Storage; using Avalonia.Platform.Storage;

6
src/Avalonia.Native/TopLevelImpl.cs

@ -1,5 +1,3 @@
#nullable enable
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
@ -311,7 +309,7 @@ internal class TopLevelImpl : ITopLevelImpl, IFramebufferPlatformSurface
Native.SetCursor(newCursor?.Cursor); Native.SetCursor(newCursor?.Cursor);
} }
public virtual IPopupImpl CreatePopup() public virtual IPopupImpl? CreatePopup()
{ {
return new PopupImpl(Factory, this); return new PopupImpl(Factory, this);
} }
@ -554,6 +552,8 @@ internal class TopLevelImpl : ITopLevelImpl, IFramebufferPlatformSurface
public ILockedFramebuffer Lock() public ILockedFramebuffer Lock()
{ {
ObjectDisposedException.ThrowIf(_target is null, this);
var w = _parent._savedLogicalSize.Width * _parent._savedScaling; var w = _parent._savedLogicalSize.Width * _parent._savedScaling;
var h = _parent._savedLogicalSize.Height * _parent._savedScaling; var h = _parent._savedLogicalSize.Height * _parent._savedScaling;
var dpi = _parent._savedScaling * 96; var dpi = _parent._savedScaling * 96;

2
src/Avalonia.Native/TrayIconImpl.cs

@ -4,8 +4,6 @@ using Avalonia.Controls.Platform;
using Avalonia.Native.Interop; using Avalonia.Native.Interop;
using Avalonia.Platform; using Avalonia.Platform;
#nullable enable
namespace Avalonia.Native namespace Avalonia.Native
{ {
internal class TrayIconImpl : ITrayIconWithIsTemplateImpl internal class TrayIconImpl : ITrayIconWithIsTemplateImpl

22
src/Avalonia.Native/WindowImpl.cs

@ -13,7 +13,7 @@ namespace Avalonia.Native
internal class WindowImpl : WindowBaseImpl, IWindowImpl internal class WindowImpl : WindowBaseImpl, IWindowImpl
{ {
private readonly AvaloniaNativePlatformOptions _opts; private readonly AvaloniaNativePlatformOptions _opts;
IAvnWindow _native; private readonly IAvnWindow _native;
private double _extendTitleBarHeight = -1; private double _extendTitleBarHeight = -1;
private DoubleClickHelper _doubleClickHelper; private DoubleClickHelper _doubleClickHelper;
private readonly ITopLevelNativeMenuExporter _nativeMenuExporter; private readonly ITopLevelNativeMenuExporter _nativeMenuExporter;
@ -99,7 +99,7 @@ namespace Avalonia.Native
_native.SetTitleBarColor(new AvnColor { Alpha = color.A, Red = color.R, Green = color.G, Blue = color.B }); _native.SetTitleBarColor(new AvnColor { Alpha = color.A, Red = color.R, Green = color.G, Blue = color.B });
} }
public void SetTitle(string title) public void SetTitle(string? title)
{ {
_native.SetTitle(title ?? ""); _native.SetTitle(title ?? "");
} }
@ -110,9 +110,9 @@ namespace Avalonia.Native
set => _native.SetWindowState((AvnWindowState)value); set => _native.SetWindowState((AvnWindowState)value);
} }
public Action<WindowState> WindowStateChanged { get; set; } public Action<WindowState>? WindowStateChanged { get; set; }
public Action<bool> ExtendClientAreaToDecorationsChanged { get; set; } public Action<bool>? ExtendClientAreaToDecorationsChanged { get; set; }
public Thickness ExtendedMargins { get; private set; } public Thickness ExtendedMargins { get; private set; }
@ -226,23 +226,23 @@ namespace Avalonia.Native
// NO OP On OSX // NO OP On OSX
} }
public void SetIcon(IWindowIconImpl icon) public void SetIcon(IWindowIconImpl? icon)
{ {
// NO OP on OSX // NO OP on OSX
} }
public Func<WindowCloseReason, bool> Closing { get; set; } public Func<WindowCloseReason, bool>? Closing { get; set; }
public void Move(PixelPoint point) => Position = point; public void Move(PixelPoint point) => Position = point;
public override IPopupImpl CreatePopup() => public override IPopupImpl? CreatePopup() =>
_opts.OverlayPopups ? null : new PopupImpl(Factory, this); _opts.OverlayPopups ? null : new PopupImpl(Factory, this);
public Action GotInputWhenDisabled { get; set; } public Action? GotInputWhenDisabled { get; set; }
public void SetParent(IWindowImpl parent) public void SetParent(IWindowImpl? parent)
{ {
_native.SetParent(((WindowImpl)parent)?.Native); _native.SetParent(((WindowImpl?)parent)?.Native);
} }
public void SetEnabled(bool enable) public void SetEnabled(bool enable)
@ -257,7 +257,7 @@ namespace Avalonia.Native
mouse.PlatformCaptureLost(); mouse.PlatformCaptureLost();
} }
public override object TryGetFeature(Type featureType) public override object? TryGetFeature(Type featureType)
{ {
if(featureType == typeof(ITextInputMethodImpl)) if(featureType == typeof(ITextInputMethodImpl))
{ {

4
src/Avalonia.Native/WindowImplBase.cs

@ -1,5 +1,3 @@
#nullable enable
using System; using System;
using System.Linq; using System.Linq;
using Avalonia.Controls; using Avalonia.Controls;
@ -57,7 +55,7 @@ namespace Avalonia.Native
.OrderBy(x => x.Scaling) .OrderBy(x => x.Scaling)
.First(m => m.Bounds.Contains(Position)); .First(m => m.Bounds.Contains(Position));
Resize(new Size(monitor!.WorkingArea.Width * 0.75d, monitor.WorkingArea.Height * 0.7d), WindowResizeReason.Layout); Resize(new Size(monitor.WorkingArea.Width * 0.75d, monitor.WorkingArea.Height * 0.7d), WindowResizeReason.Layout);
} }
public void Activate() public void Activate()

Loading…
Cancel
Save