diff --git a/src/Avalonia.Native/Avalonia.Native.csproj b/src/Avalonia.Native/Avalonia.Native.csproj
index 123ac83c65..2eb67fe5dd 100644
--- a/src/Avalonia.Native/Avalonia.Native.csproj
+++ b/src/Avalonia.Native/Avalonia.Native.csproj
@@ -27,4 +27,5 @@
+
diff --git a/src/Avalonia.Native/AvaloniaNativeApplicationPlatform.cs b/src/Avalonia.Native/AvaloniaNativeApplicationPlatform.cs
index ea64f0d93b..68e0c5dce6 100644
--- a/src/Avalonia.Native/AvaloniaNativeApplicationPlatform.cs
+++ b/src/Avalonia.Native/AvaloniaNativeApplicationPlatform.cs
@@ -12,11 +12,11 @@ namespace Avalonia.Native
{
internal class AvaloniaNativeApplicationPlatform : NativeCallbackBase, IAvnApplicationEvents, IPlatformLifetimeEventsImpl
{
- public event EventHandler ShutdownRequested;
+ public event EventHandler? ShutdownRequested;
void IAvnApplicationEvents.FilesOpened(IAvnStringArray urls)
{
- ((IApplicationPlatformEvents)Application.Current)?.RaiseUrlsOpened(urls.ToStringArray());
+ ((IApplicationPlatformEvents?)Application.Current)?.RaiseUrlsOpened(urls.ToStringArray());
if (AvaloniaLocator.Current.GetService() is ActivatableLifetimeBase lifetime
&& AvaloniaLocator.Current.GetService() is StorageProviderApi storageApi)
@@ -42,7 +42,7 @@ namespace Avalonia.Native
void IAvnApplicationEvents.UrlsOpened(IAvnStringArray urls)
{
// 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() is ActivatableLifetimeBase lifetime
&& AvaloniaLocator.Current.GetService() is StorageProviderApi storageApi)
diff --git a/src/Avalonia.Native/AvaloniaNativeDragSource.cs b/src/Avalonia.Native/AvaloniaNativeDragSource.cs
index 3bccdeac73..3c9397f8cc 100644
--- a/src/Avalonia.Native/AvaloniaNativeDragSource.cs
+++ b/src/Avalonia.Native/AvaloniaNativeDragSource.cs
@@ -19,7 +19,7 @@ namespace Avalonia.Native
class DndCallback : NativeCallbackBase, IAvnDndResultCallback
{
- private TaskCompletionSource _tcs;
+ private TaskCompletionSource? _tcs;
public DndCallback(TaskCompletionSource tcs)
{
diff --git a/src/Avalonia.Native/AvaloniaNativeGlPlatformGraphics.cs b/src/Avalonia.Native/AvaloniaNativeGlPlatformGraphics.cs
index ae5abf2655..2a6a1f16c7 100644
--- a/src/Avalonia.Native/AvaloniaNativeGlPlatformGraphics.cs
+++ b/src/Avalonia.Native/AvaloniaNativeGlPlatformGraphics.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Avalonia.OpenGL;
using Avalonia.Native.Interop;
@@ -90,12 +91,12 @@ namespace Avalonia.Native
class GlContext : IGlContext
{
private readonly GlDisplay _display;
- private readonly GlContext _sharedWith;
+ private readonly GlContext? _sharedWith;
private readonly GpuHandleWrapFeature _handleWrapFeature;
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;
_sharedWith = sharedWith;
@@ -109,14 +110,25 @@ namespace Avalonia.Native
public GlInterface GlInterface => _display.GlInterface;
public int SampleCount => _display.SampleCount;
public int StencilSize => _display.StencilSize;
- public IDisposable MakeCurrent()
+
+ [MemberNotNull(nameof(Context))]
+ public void ThrowIfLost()
{
if (IsLost)
throw new PlatformGraphicsContextLostException();
+ }
+
+ [MemberNotNull(nameof(Context))]
+ public IDisposable MakeCurrent()
+ {
+ ThrowIfLost();
return Context.MakeCurrent();
}
+ [MemberNotNullWhen(false, nameof(Context))]
public bool IsLost => Context == null;
+
+ [MemberNotNull(nameof(Context))]
public IDisposable EnsureCurrent() => MakeCurrent();
public bool IsSharedWith(IGlContext context)
@@ -130,16 +142,16 @@ namespace Avalonia.Native
public bool CanCreateSharedContext => true;
- public IGlContext CreateSharedContext(IEnumerable preferredVersions = null) =>
+ public IGlContext CreateSharedContext(IEnumerable? preferredVersions = null) =>
_display.CreateSharedContext(_sharedWith ?? this);
public void Dispose()
{
- Context.Dispose();
+ Context?.Dispose();
Context = null;
}
- public object TryGetFeature(Type featureType)
+ public object? TryGetFeature(Type featureType)
{
if (featureType == typeof(IExternalObjectsHandleWrapRenderInterfaceContextFeature))
return _handleWrapFeature;
@@ -152,7 +164,7 @@ namespace Avalonia.Native
class GlPlatformSurfaceRenderTarget : IGlPlatformSurfaceRenderTarget
{
- private IAvnGlSurfaceRenderTarget _target;
+ private IAvnGlSurfaceRenderTarget? _target;
private readonly IGlContext _context;
public GlPlatformSurfaceRenderTarget(IAvnGlSurfaceRenderTarget target, IGlContext context)
@@ -163,6 +175,7 @@ namespace Avalonia.Native
public IGlPlatformSurfaceRenderingSession BeginDraw()
{
+ ObjectDisposedException.ThrowIf(_target is null, this);
return new GlPlatformSurfaceRenderingSession(_context, _target.BeginDrawing());
}
@@ -175,7 +188,7 @@ namespace Avalonia.Native
class GlPlatformSurfaceRenderingSession : IGlPlatformSurfaceRenderingSession
{
- private IAvnGlSurfaceRenderingSession _session;
+ private IAvnGlSurfaceRenderingSession? _session;
public GlPlatformSurfaceRenderingSession(IGlContext context, IAvnGlSurfaceRenderingSession session)
{
@@ -185,17 +198,25 @@ namespace Avalonia.Native
public IGlContext Context { get; }
+ private IAvnGlSurfaceRenderingSession Session
+ {
+ get
+ {
+ ObjectDisposedException.ThrowIf(_session is null, this);
+ return _session;
+ }
+ }
+
public PixelSize Size
{
get
{
- var s = _session.PixelSize;
+ var s = Session.PixelSize;
return new PixelSize(s.Width, s.Height);
}
}
- public double Scaling => _session.Scaling;
-
+ public double Scaling => Session.Scaling;
public bool IsYFlipped => true;
@@ -230,9 +251,12 @@ namespace Avalonia.Native
public unsafe GlExternalObjectsFeature(GlContext context, GlDisplay display)
{
+ context.ThrowIfLost();
+
_context = context;
_display = display;
ulong registryId = 0;
+
if (context.Context.GetIOKitRegistryId(®istryId) != 0)
{
// We are reversing bytes to match MoltenVK (LUID is a Vulkan term after all)
@@ -306,8 +330,8 @@ namespace Avalonia.Native
CompositionGpuImportedImageSynchronizationCapabilities.TimelineSemaphores;
}
- public byte[] DeviceLuid { get; }
- public byte[] DeviceUuid { get; }
+ public byte[]? DeviceLuid { get; }
+ public byte[]? DeviceUuid { get; }
}
class MtlEventSemaphore(IAvnMTLSharedEvent inner) : IGlExternalSemaphore
diff --git a/src/Avalonia.Native/AvaloniaNativeMenuExporter.cs b/src/Avalonia.Native/AvaloniaNativeMenuExporter.cs
index 241528a9ac..75251ee0a1 100644
--- a/src/Avalonia.Native/AvaloniaNativeMenuExporter.cs
+++ b/src/Avalonia.Native/AvaloniaNativeMenuExporter.cs
@@ -15,10 +15,10 @@ namespace Avalonia.Native
private readonly IAvaloniaNativeFactory _factory;
private bool _resetQueued = true;
private bool _exported;
- private readonly IAvnWindow _nativeWindow;
- private NativeMenu _menu;
- private __MicroComIAvnMenuProxy _nativeMenu;
- private readonly IAvnTrayIcon _trayIcon;
+ private readonly IAvnWindow? _nativeWindow;
+ private NativeMenu? _menu;
+ private __MicroComIAvnMenuProxy? _nativeMenu;
+ private readonly IAvnTrayIcon? _trayIcon;
private readonly IAvnApplicationCommands _applicationCommands;
public AvaloniaNativeMenuExporter(IAvnWindow nativeWindow, IAvaloniaNativeFactory factory)
@@ -51,7 +51,7 @@ namespace Avalonia.Native
public event EventHandler OnIsNativeMenuExportedChanged { add { } remove { } }
- public void SetNativeMenu(NativeMenu menu)
+ public void SetNativeMenu(NativeMenu? menu)
{
_menu = menu ?? new NativeMenu();
DoLayoutReset(true);
@@ -152,7 +152,7 @@ namespace Avalonia.Native
private void DoLayoutReset() => DoLayoutReset(false);
- private void DoLayoutReset(bool forceUpdate = false)
+ private void DoLayoutReset(bool forceUpdate)
{
var macOpts = AvaloniaLocator.Current.GetService() ?? new MacOSPlatformOptions();
@@ -169,12 +169,15 @@ namespace Avalonia.Native
{
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)
{
appMenu = CreateDefaultAppMenu();
- NativeMenu.SetMenu(Application.Current, appMenu);
+
+ if (app is not null)
+ NativeMenu.SetMenu(app, appMenu);
}
SetMenu(appMenu);
diff --git a/src/Avalonia.Native/AvaloniaNativePlatform.cs b/src/Avalonia.Native/AvaloniaNativePlatform.cs
index 99edfd9d29..4ad0814283 100644
--- a/src/Avalonia.Native/AvaloniaNativePlatform.cs
+++ b/src/Avalonia.Native/AvaloniaNativePlatform.cs
@@ -12,7 +12,6 @@ using Avalonia.Rendering;
using Avalonia.Rendering.Composition;
using Avalonia.Threading;
using MicroCom.Runtime;
-#nullable enable
namespace Avalonia.Native
{
@@ -199,7 +198,7 @@ namespace Avalonia.Native
public IWindowImpl CreateWindow()
{
- return new WindowImpl(_factory, _options);
+ return new WindowImpl(_factory, _options ?? new AvaloniaNativePlatformOptions());
}
public IWindowImpl CreateEmbeddableWindow()
diff --git a/src/Avalonia.Native/AvaloniaNativePlatformExtensions.cs b/src/Avalonia.Native/AvaloniaNativePlatformExtensions.cs
index f8974865a7..40985a56e3 100644
--- a/src/Avalonia.Native/AvaloniaNativePlatformExtensions.cs
+++ b/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
/// and make your Avalonia app run with it. The default value is null.
///
- public string AvaloniaNativeLibraryPath { get; set; }
+ public string? AvaloniaNativeLibraryPath { get; set; }
///
/// If you distribute your app in App Store - it should be with sandbox enabled.
diff --git a/src/Avalonia.Native/AvaloniaNativeRenderTimer.cs b/src/Avalonia.Native/AvaloniaNativeRenderTimer.cs
index e8c32f62f4..625de5d6bc 100644
--- a/src/Avalonia.Native/AvaloniaNativeRenderTimer.cs
+++ b/src/Avalonia.Native/AvaloniaNativeRenderTimer.cs
@@ -1,9 +1,7 @@
using System;
using System.Diagnostics;
-using System.Runtime.InteropServices;
using Avalonia.Native.Interop;
using Avalonia.Rendering;
-#nullable enable
namespace Avalonia.Native;
diff --git a/src/Avalonia.Native/AvaloniaNativeTextInputMethod.cs b/src/Avalonia.Native/AvaloniaNativeTextInputMethod.cs
index a3abccd2b4..3df0a0ef4a 100644
--- a/src/Avalonia.Native/AvaloniaNativeTextInputMethod.cs
+++ b/src/Avalonia.Native/AvaloniaNativeTextInputMethod.cs
@@ -1,10 +1,7 @@
using System;
using Avalonia.Input.TextInput;
-using Avalonia.Media.TextFormatting;
using Avalonia.Native.Interop;
-#nullable enable
-
namespace Avalonia.Native
{
internal class AvaloniaNativeTextInputMethod : ITextInputMethodImpl, IDisposable
diff --git a/src/Avalonia.Native/AvnAutomationPeer.cs b/src/Avalonia.Native/AvnAutomationPeer.cs
index c666ffc695..e178febd42 100644
--- a/src/Avalonia.Native/AvnAutomationPeer.cs
+++ b/src/Avalonia.Native/AvnAutomationPeer.cs
@@ -6,12 +6,9 @@ using System.Runtime.CompilerServices;
using Avalonia.Automation;
using Avalonia.Automation.Peers;
using Avalonia.Automation.Provider;
-using Avalonia.Controls;
using Avalonia.Controls.Automation.Peers;
using Avalonia.Native.Interop;
-#nullable enable
-
namespace Avalonia.Native
{
internal class AvnAutomationPeer : NativeCallbackBase, IAvnAutomationPeer
@@ -36,10 +33,10 @@ namespace Avalonia.Native
public IAvnString? AutomationId => _inner.GetAutomationId().ToAvnString();
public AvnRect BoundingRectangle => _inner.GetBoundingRectangle().ToAvnRect();
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 IAvnString Name => _inner.GetName().ToAvnString();
- public IAvnString HelpText => _inner.GetHelpText().ToAvnString();
+ public IAvnString? Name => _inner.GetName().ToAvnString();
+ public IAvnString? HelpText => _inner.GetHelpText().ToAvnString();
public AvnLandmarkType LandmarkType => (AvnLandmarkType?)_inner.GetLandmarkType() ?? AvnLandmarkType.LandmarkNone;
public int HeadingLevel => _inner.GetHeadingLevel();
public IAvnAutomationPeer? Parent => Wrap(_inner.GetParent());
@@ -173,7 +170,7 @@ namespace Avalonia.Native
public void ToggleProvider_Toggle() => ToggleProvider.Toggle();
public int IsValueProvider() => IsProvider();
- public IAvnString ValueProvider_GetValue() => ValueProvider.Value.ToAvnString();
+ public IAvnString? ValueProvider_GetValue() => ValueProvider.Value.ToAvnString();
public void ValueProvider_SetValue(string value) => ValueProvider.SetValue(value);
[return: NotNullIfNotNull("peer")]
diff --git a/src/Avalonia.Native/AvnString.cs b/src/Avalonia.Native/AvnString.cs
index b0cb9a3a86..3ff484117e 100644
--- a/src/Avalonia.Native/AvnString.cs
+++ b/src/Avalonia.Native/AvnString.cs
@@ -8,7 +8,7 @@ namespace Avalonia.Native.Interop
{
partial interface IAvnString
{
- public string String { get; }
+ public string? String { get; }
public byte[] Bytes { get; }
}
@@ -73,7 +73,7 @@ namespace Avalonia.Native.Interop
_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 IAvnString Get(uint index) => _items[(int)index];
@@ -91,10 +91,10 @@ namespace Avalonia.Native.Interop.Impl
{
unsafe partial class __MicroComIAvnStringProxy
{
- private string _managed;
- private byte[] _bytes;
+ private string? _managed;
+ private byte[]? _bytes;
- public string String
+ public string? String
{
get
{
@@ -124,7 +124,7 @@ namespace Avalonia.Native.Interop.Impl
}
}
- public override string ToString() => String;
+ public override string? ToString() => String;
}
partial class __MicroComIAvnStringArrayProxy
@@ -134,7 +134,7 @@ namespace Avalonia.Native.Interop.Impl
var arr = new string[Count];
for(uint c = 0; c IntPtr.Zero;
public string HandleDescriptor => "";
@@ -20,7 +20,7 @@ namespace Avalonia.Native
public void Dispose()
{
- Cursor.Dispose();
+ Cursor?.Dispose();
Cursor = null;
}
}
diff --git a/src/Avalonia.Native/DataTransferItemToAvnClipboardDataItemWrapper.cs b/src/Avalonia.Native/DataTransferItemToAvnClipboardDataItemWrapper.cs
index 7c64e1a987..e9be474598 100644
--- a/src/Avalonia.Native/DataTransferItemToAvnClipboardDataItemWrapper.cs
+++ b/src/Avalonia.Native/DataTransferItemToAvnClipboardDataItemWrapper.cs
@@ -1,12 +1,9 @@
-#nullable enable
-
using System;
using System.IO;
using System.Linq;
using Avalonia.Input;
using Avalonia.Logging;
using Avalonia.Native.Interop;
-using Avalonia.Utilities;
namespace Avalonia.Native;
diff --git a/src/Avalonia.Native/DataTransferToAvnClipboardDataSourceWrapper.cs b/src/Avalonia.Native/DataTransferToAvnClipboardDataSourceWrapper.cs
index 3cec91b829..19301d05ad 100644
--- a/src/Avalonia.Native/DataTransferToAvnClipboardDataSourceWrapper.cs
+++ b/src/Avalonia.Native/DataTransferToAvnClipboardDataSourceWrapper.cs
@@ -1,5 +1,3 @@
-#nullable enable
-
using System;
using System.Linq;
using Avalonia.Input;
diff --git a/src/Avalonia.Native/DispatcherImpl.cs b/src/Avalonia.Native/DispatcherImpl.cs
index 16ec0f7ba6..fa80c2ffc7 100644
--- a/src/Avalonia.Native/DispatcherImpl.cs
+++ b/src/Avalonia.Native/DispatcherImpl.cs
@@ -1,4 +1,3 @@
-#nullable enable
using System;
using System.Collections.Generic;
using System.Diagnostics;
diff --git a/src/Avalonia.Native/GpuHandleWrapFeature.cs b/src/Avalonia.Native/GpuHandleWrapFeature.cs
index b490e6c9c1..feb394f460 100644
--- a/src/Avalonia.Native/GpuHandleWrapFeature.cs
+++ b/src/Avalonia.Native/GpuHandleWrapFeature.cs
@@ -1,5 +1,3 @@
-#nullable enable
-
using System;
using Avalonia.Native.Interop;
using Avalonia.Platform;
diff --git a/src/Avalonia.Native/Helpers.cs b/src/Avalonia.Native/Helpers.cs
index 6270cd30a0..60a45c2cbd 100644
--- a/src/Avalonia.Native/Helpers.cs
+++ b/src/Avalonia.Native/Helpers.cs
@@ -1,4 +1,5 @@
-using Avalonia.Native.Interop;
+using System.Diagnostics.CodeAnalysis;
+using Avalonia.Native.Interop;
namespace Avalonia.Native
{
@@ -34,7 +35,8 @@ namespace Avalonia.Native
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;
}
diff --git a/src/Avalonia.Native/IAvnMenu.cs b/src/Avalonia.Native/IAvnMenu.cs
index dc0176a8ad..b526d91924 100644
--- a/src/Avalonia.Native/IAvnMenu.cs
+++ b/src/Avalonia.Native/IAvnMenu.cs
@@ -10,7 +10,7 @@ namespace Avalonia.Native.Interop
{
class MenuEvents : NativeCallbackBase, IAvnMenuEvents
{
- private IAvnMenu _parent;
+ private IAvnMenu? _parent;
public void Initialise(IAvnMenu parent)
{
@@ -49,7 +49,7 @@ namespace Avalonia.Native.Interop.Impl
private List<__MicroComIAvnMenuItemProxy> _menuItems = new List<__MicroComIAvnMenuItemProxy>();
private Dictionary _menuItemLookup = new Dictionary();
- private void UpdateTitle(string title)
+ private void UpdateTitle(string? title)
{
if (OperatingSystemEx.IsMacOS())
{
@@ -136,7 +136,7 @@ namespace Avalonia.Native.Interop.Impl
return nativeItem;
}
- internal void Initialize(AvaloniaNativeMenuExporter exporter, NativeMenu managedMenu, string title)
+ internal void Initialize(AvaloniaNativeMenuExporter exporter, NativeMenu managedMenu, string? title)
{
_exporter = exporter;
ManagedMenu = managedMenu;
@@ -166,7 +166,7 @@ namespace Avalonia.Native.Interop.Impl
for (int i = 0; i < menu.Items.Count; i++)
{
- __MicroComIAvnMenuItemProxy nativeItem;
+ __MicroComIAvnMenuItemProxy? nativeItem;
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();
}
diff --git a/src/Avalonia.Native/IAvnMenuItem.cs b/src/Avalonia.Native/IAvnMenuItem.cs
index 275a088821..fd851122f2 100644
--- a/src/Avalonia.Native/IAvnMenuItem.cs
+++ b/src/Avalonia.Native/IAvnMenuItem.cs
@@ -18,13 +18,13 @@ namespace Avalonia.Native.Interop.Impl
{
partial class __MicroComIAvnMenuItemProxy
{
- private __MicroComIAvnMenuProxy _subMenu;
+ private __MicroComIAvnMenuProxy? _subMenu;
private CompositeDisposable _propertyDisposables = new CompositeDisposable();
- private IDisposable _currentActionDisposable;
+ private IDisposable? _currentActionDisposable;
public NativeMenuItemBase ManagedMenuItem { get; set; }
- private void UpdateTitle(string title)
+ private void UpdateTitle(string? title)
{
if (OperatingSystemEx.IsMacOS())
{
@@ -38,7 +38,7 @@ namespace Avalonia.Native.Interop.Impl
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 UpdateIsChecked(bool isChecked) => SetIsChecked(isChecked.AsComBool());
@@ -48,7 +48,7 @@ namespace Avalonia.Native.Interop.Impl
SetToggleType((AvnMenuItemToggleType)toggleType);
}
- private unsafe void UpdateIcon (IBitmap icon)
+ private unsafe void UpdateIcon (IBitmap? icon)
{
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 key = gesture == null ? AvnKey.AvnKeyNone : (AvnKey)gesture.Key;
SetGesture(key, modifiers);
}
- private void UpdateAction(NativeMenuItem item)
+ private void UpdateAction(NativeMenuItem? item)
{
_currentActionDisposable?.Dispose();
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;
}
@@ -160,7 +160,7 @@ namespace Avalonia.Native.Interop.Impl
_subMenu = null;
}
- _propertyDisposables?.Dispose();
+ _propertyDisposables.Dispose();
_currentActionDisposable?.Dispose();
}
diff --git a/src/Avalonia.Native/IconLoader.cs b/src/Avalonia.Native/IconLoader.cs
index 04779a43aa..dbc6379bd8 100644
--- a/src/Avalonia.Native/IconLoader.cs
+++ b/src/Avalonia.Native/IconLoader.cs
@@ -27,13 +27,13 @@ namespace Avalonia.Native
public IWindowIconImpl LoadIcon(string fileName)
{
return new IconStub(
- AvaloniaLocator.Current.GetService().LoadBitmap(fileName));
+ AvaloniaLocator.Current.GetRequiredService().LoadBitmap(fileName));
}
public IWindowIconImpl LoadIcon(Stream stream)
{
return new IconStub(
- AvaloniaLocator.Current.GetService().LoadBitmap(stream));
+ AvaloniaLocator.Current.GetRequiredService().LoadBitmap(stream));
}
public IWindowIconImpl LoadIcon(IBitmapImpl bitmap)
diff --git a/src/Avalonia.Native/MacOSActivatableLifetime.cs b/src/Avalonia.Native/MacOSActivatableLifetime.cs
index c96e43f724..f3db4a032f 100644
--- a/src/Avalonia.Native/MacOSActivatableLifetime.cs
+++ b/src/Avalonia.Native/MacOSActivatableLifetime.cs
@@ -1,11 +1,8 @@
-using System;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Controls.Platform;
namespace Avalonia.Native;
-#nullable enable
-
internal class MacOSActivatableLifetime : ActivatableLifetimeBase
{
public override bool TryLeaveBackground()
diff --git a/src/Avalonia.Native/Metal.cs b/src/Avalonia.Native/Metal.cs
index 6c5f6331a8..3137ce1b6b 100644
--- a/src/Avalonia.Native/Metal.cs
+++ b/src/Avalonia.Native/Metal.cs
@@ -28,26 +28,34 @@ class MetalPlatformGraphics : IPlatformGraphics
class MetalDevice : IMetalDevice
{
- public IAvnMetalDevice Native { get; private set; }
- private DisposableLock _syncRoot = new();
+ private readonly DisposableLock _syncRoot = new();
private readonly GpuHandleWrapFeature _handleWrapFeature;
private readonly MetalExternalObjectsFeature _externalObjectsFeature;
-
+ private IAvnMetalDevice? _native;
public MetalDevice(IAvaloniaNativeFactory factory, IAvnMetalDevice native)
{
- Native = native;
+ _native = native;
_handleWrapFeature = new GpuHandleWrapFeature(factory);
_externalObjectsFeature = new MetalExternalObjectsFeature(native);
}
+ public IAvnMetalDevice Native
+ {
+ get
+ {
+ ObjectDisposedException.ThrowIf(_native is null, this);
+ return _native;
+ }
+ }
+
public void Dispose()
{
- Native?.Dispose();
- Native = null;
+ _native?.Dispose();
+ _native = null;
}
- public object TryGetFeature(Type featureType)
+ public object? TryGetFeature(Type featureType)
{
if (featureType == typeof(IExternalObjectsHandleWrapRenderInterfaceContextFeature))
return _handleWrapFeature;
@@ -105,7 +113,7 @@ internal class MetalExternalObjectsFeature : IMetalExternalObjectsFeature
public IReadOnlyList SupportedSemaphoreTypes { get; } =
[KnownPlatformGraphicsExternalSemaphoreHandleTypes.MetalSharedEvent];
- public byte[] DeviceLuid { get; }
+ public byte[]? DeviceLuid { get; }
public CompositionGpuImportedImageSynchronizationCapabilities
GetSynchronizationCapabilities(string imageHandleType) =>
@@ -166,13 +174,22 @@ internal class MetalExternalObjectsFeature : IMetalExternalObjectsFeature
internal class MetalRenderTarget : IMetalPlatformSurfaceRenderTarget
{
- private IAvnMetalRenderTarget _native;
+ private IAvnMetalRenderTarget? _native;
public MetalRenderTarget(IAvnMetalRenderTarget native)
{
_native = native;
}
+ private IAvnMetalRenderTarget Native
+ {
+ get
+ {
+ ObjectDisposedException.ThrowIf(_native is null, this);
+ return _native;
+ }
+ }
+
public void Dispose()
{
_native?.Dispose();
@@ -181,36 +198,47 @@ internal class MetalRenderTarget : IMetalPlatformSurfaceRenderTarget
public IMetalPlatformSurfaceRenderingSession BeginRendering()
{
- var session = _native.BeginDrawing();
+ var session = Native.BeginDrawing();
return new MetalDrawingSession(session);
}
}
internal class MetalDrawingSession : IMetalPlatformSurfaceRenderingSession
{
- private IAvnMetalRenderingSession _session;
+ private IAvnMetalRenderingSession? _session;
public MetalDrawingSession(IAvnMetalRenderingSession session)
{
_session = session;
}
+ public IAvnMetalRenderingSession Session
+ {
+ get
+ {
+ ObjectDisposedException.ThrowIf(_session is null, this);
+ return _session;
+ }
+ }
+
public void Dispose()
{
_session?.Dispose();
_session = null;
}
- public IntPtr Texture => _session.Texture;
+ public IntPtr Texture => Session.Texture;
+
public PixelSize Size
{
get
{
- var size = _session.PixelSize;
+ var size = Session.PixelSize;
return new(size.Width, size.Height);
}
}
- public double Scaling => _session.Scaling;
+ public double Scaling => Session.Scaling;
+
public bool IsYFlipped => false;
}
diff --git a/src/Avalonia.Native/NativeControlHostImpl.cs b/src/Avalonia.Native/NativeControlHostImpl.cs
index 8a3488d95e..134eb2bb70 100644
--- a/src/Avalonia.Native/NativeControlHostImpl.cs
+++ b/src/Avalonia.Native/NativeControlHostImpl.cs
@@ -10,13 +10,22 @@ namespace Avalonia.Native
{
class NativeControlHostImpl : IDisposable, INativeControlHostImpl
{
- private IAvnNativeControlHost _host;
+ private IAvnNativeControlHost? _host;
public NativeControlHostImpl(IAvnNativeControlHost host)
{
_host = host;
}
+ private IAvnNativeControlHost Host
+ {
+ get
+ {
+ ObjectDisposedException.ThrowIf(_host is null, this);
+ return _host;
+ }
+ }
+
public void Dispose()
{
_host?.Dispose();
@@ -25,7 +34,7 @@ namespace Avalonia.Native
class DestroyableNSView : INativeControlHostDestroyableControlHandle
{
- private IAvnNativeControlHost _impl;
+ private IAvnNativeControlHost? _impl;
private IntPtr _nsView;
public DestroyableNSView(IAvnNativeControlHost impl)
@@ -49,12 +58,12 @@ namespace Avalonia.Native
}
public INativeControlHostDestroyableControlHandle CreateDefaultChild(IPlatformHandle parent)
- => new DestroyableNSView(_host);
+ => new DestroyableNSView(Host);
public INativeControlHostControlTopLevelAttachment CreateNewAttachment(
Func create)
{
- var a = new Attachment(_host.CreateAttachment());
+ var a = new Attachment(Host.CreateAttachment());
try
{
var child = create(a.GetParentHandle());
@@ -71,7 +80,7 @@ namespace Avalonia.Native
public INativeControlHostControlTopLevelAttachment CreateNewAttachment(IPlatformHandle handle)
{
- var a = new Attachment(_host.CreateAttachment());
+ var a = new Attachment(Host.CreateAttachment());
a.InitWithChild(handle);
a.AttachedTo = this;
return a;
@@ -81,14 +90,25 @@ namespace Avalonia.Native
class Attachment : INativeControlHostControlTopLevelAttachment
{
- private IAvnNativeControlHostTopLevelAttachment _native;
- private NativeControlHostImpl _attachedTo;
- public IPlatformHandle GetParentHandle() => new PlatformHandle(_native.ParentHandle, "NSView");
+ private IAvnNativeControlHostTopLevelAttachment? _native;
+ private NativeControlHostImpl? _attachedTo;
+
public Attachment(IAvnNativeControlHostTopLevelAttachment 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()
{
if (_native != null)
@@ -99,16 +119,13 @@ namespace Avalonia.Native
}
}
- public INativeControlHostImpl AttachedTo
+ public INativeControlHostImpl? AttachedTo
{
get => _attachedTo;
set
{
- var host = (NativeControlHostImpl)value;
- if(host == null)
- _native.AttachTo(null);
- else
- _native.AttachTo(host._host);
+ var host = (NativeControlHostImpl?)value;
+ Native.AttachTo(host?._host);
_attachedTo = host;
}
}
@@ -117,7 +134,7 @@ namespace Avalonia.Native
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)
@@ -126,11 +143,11 @@ namespace Avalonia.Native
throw new InvalidOperationException("Native control isn't attached to a toplevel");
bounds = new Rect(bounds.X, bounds.Y, Math.Max(1, bounds.Width),
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)
- => _native.InitializeWithChildHandle(handle.Handle);
+ => Native.InitializeWithChildHandle(handle.Handle);
}
}
}
diff --git a/src/Avalonia.Native/NativeOwned.cs b/src/Avalonia.Native/NativeOwned.cs
index b89a422fa9..2bc6891343 100644
--- a/src/Avalonia.Native/NativeOwned.cs
+++ b/src/Avalonia.Native/NativeOwned.cs
@@ -1,5 +1,3 @@
-#nullable enable
-
using System;
using System.Runtime.ExceptionServices;
using Avalonia.Threading;
diff --git a/src/Avalonia.Native/NativePlatformSettings.cs b/src/Avalonia.Native/NativePlatformSettings.cs
index 42d05d831c..5e3ee0cfc2 100644
--- a/src/Avalonia.Native/NativePlatformSettings.cs
+++ b/src/Avalonia.Native/NativePlatformSettings.cs
@@ -8,7 +8,7 @@ namespace Avalonia.Native;
internal class NativePlatformSettings : DefaultPlatformSettings
{
private readonly IAvnPlatformSettings _platformSettings;
- private PlatformColorValues _lastColorValues;
+ private PlatformColorValues? _lastColorValues;
public NativePlatformSettings(IAvnPlatformSettings platformSettings)
{
diff --git a/src/Avalonia.Native/ScreenImpl.cs b/src/Avalonia.Native/ScreenImpl.cs
index 65fa19dab5..1f9815733b 100644
--- a/src/Avalonia.Native/ScreenImpl.cs
+++ b/src/Avalonia.Native/ScreenImpl.cs
@@ -4,8 +4,6 @@ using Avalonia.Native.Interop;
using Avalonia.Platform;
using MicroCom.Runtime;
-#nullable enable
-
namespace Avalonia.Native
{
internal sealed class AvnScreen(uint displayId)
diff --git a/src/Avalonia.Native/StorageItem.cs b/src/Avalonia.Native/StorageItem.cs
index efa0404a34..268fe2965d 100644
--- a/src/Avalonia.Native/StorageItem.cs
+++ b/src/Avalonia.Native/StorageItem.cs
@@ -1,5 +1,3 @@
-#nullable enable
-
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
diff --git a/src/Avalonia.Native/StorageProviderApi.cs b/src/Avalonia.Native/StorageProviderApi.cs
index 8c737336b2..819623c0da 100644
--- a/src/Avalonia.Native/StorageProviderApi.cs
+++ b/src/Avalonia.Native/StorageProviderApi.cs
@@ -1,5 +1,3 @@
-#nullable enable
-
using System;
using System.Collections.Generic;
using System.IO;
diff --git a/src/Avalonia.Native/StorageProviderImpl.cs b/src/Avalonia.Native/StorageProviderImpl.cs
index e6e1fd7257..d3062715c8 100644
--- a/src/Avalonia.Native/StorageProviderImpl.cs
+++ b/src/Avalonia.Native/StorageProviderImpl.cs
@@ -1,6 +1,4 @@
-#nullable enable
-
-using System;
+using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Avalonia.Platform.Storage;
diff --git a/src/Avalonia.Native/TopLevelImpl.cs b/src/Avalonia.Native/TopLevelImpl.cs
index 05cbb15765..d45e50d5c6 100644
--- a/src/Avalonia.Native/TopLevelImpl.cs
+++ b/src/Avalonia.Native/TopLevelImpl.cs
@@ -1,5 +1,3 @@
-#nullable enable
-
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
@@ -311,7 +309,7 @@ internal class TopLevelImpl : ITopLevelImpl, IFramebufferPlatformSurface
Native.SetCursor(newCursor?.Cursor);
}
- public virtual IPopupImpl CreatePopup()
+ public virtual IPopupImpl? CreatePopup()
{
return new PopupImpl(Factory, this);
}
@@ -554,6 +552,8 @@ internal class TopLevelImpl : ITopLevelImpl, IFramebufferPlatformSurface
public ILockedFramebuffer Lock()
{
+ ObjectDisposedException.ThrowIf(_target is null, this);
+
var w = _parent._savedLogicalSize.Width * _parent._savedScaling;
var h = _parent._savedLogicalSize.Height * _parent._savedScaling;
var dpi = _parent._savedScaling * 96;
diff --git a/src/Avalonia.Native/TrayIconImpl.cs b/src/Avalonia.Native/TrayIconImpl.cs
index 4c9bed0e7c..6e08131c92 100644
--- a/src/Avalonia.Native/TrayIconImpl.cs
+++ b/src/Avalonia.Native/TrayIconImpl.cs
@@ -4,8 +4,6 @@ using Avalonia.Controls.Platform;
using Avalonia.Native.Interop;
using Avalonia.Platform;
-#nullable enable
-
namespace Avalonia.Native
{
internal class TrayIconImpl : ITrayIconWithIsTemplateImpl
diff --git a/src/Avalonia.Native/WindowImpl.cs b/src/Avalonia.Native/WindowImpl.cs
index 08aaae669f..2f35231b4f 100644
--- a/src/Avalonia.Native/WindowImpl.cs
+++ b/src/Avalonia.Native/WindowImpl.cs
@@ -13,7 +13,7 @@ namespace Avalonia.Native
internal class WindowImpl : WindowBaseImpl, IWindowImpl
{
private readonly AvaloniaNativePlatformOptions _opts;
- IAvnWindow _native;
+ private readonly IAvnWindow _native;
private double _extendTitleBarHeight = -1;
private DoubleClickHelper _doubleClickHelper;
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 });
}
- public void SetTitle(string title)
+ public void SetTitle(string? title)
{
_native.SetTitle(title ?? "");
}
@@ -110,9 +110,9 @@ namespace Avalonia.Native
set => _native.SetWindowState((AvnWindowState)value);
}
- public Action WindowStateChanged { get; set; }
+ public Action? WindowStateChanged { get; set; }
- public Action ExtendClientAreaToDecorationsChanged { get; set; }
+ public Action? ExtendClientAreaToDecorationsChanged { get; set; }
public Thickness ExtendedMargins { get; private set; }
@@ -226,23 +226,23 @@ namespace Avalonia.Native
// NO OP On OSX
}
- public void SetIcon(IWindowIconImpl icon)
+ public void SetIcon(IWindowIconImpl? icon)
{
// NO OP on OSX
}
- public Func Closing { get; set; }
+ public Func? Closing { get; set; }
public void Move(PixelPoint point) => Position = point;
- public override IPopupImpl CreatePopup() =>
+ public override IPopupImpl? CreatePopup() =>
_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)
@@ -257,7 +257,7 @@ namespace Avalonia.Native
mouse.PlatformCaptureLost();
}
- public override object TryGetFeature(Type featureType)
+ public override object? TryGetFeature(Type featureType)
{
if(featureType == typeof(ITextInputMethodImpl))
{
diff --git a/src/Avalonia.Native/WindowImplBase.cs b/src/Avalonia.Native/WindowImplBase.cs
index 8aaea611ab..852317a793 100644
--- a/src/Avalonia.Native/WindowImplBase.cs
+++ b/src/Avalonia.Native/WindowImplBase.cs
@@ -1,5 +1,3 @@
-#nullable enable
-
using System;
using System.Linq;
using Avalonia.Controls;
@@ -57,7 +55,7 @@ namespace Avalonia.Native
.OrderBy(x => x.Scaling)
.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()