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\TrimmingEnable.props" />
<Import Project="..\..\build\NullableEnable.props" />
</Project>

6
src/Avalonia.Native/AvaloniaNativeApplicationPlatform.cs

@ -12,11 +12,11 @@ namespace Avalonia.Native
{
internal class AvaloniaNativeApplicationPlatform : NativeCallbackBase, IAvnApplicationEvents, IPlatformLifetimeEventsImpl
{
public event EventHandler<ShutdownRequestedEventArgs> ShutdownRequested;
public event EventHandler<ShutdownRequestedEventArgs>? ShutdownRequested;
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
&& AvaloniaLocator.Current.GetService<IStorageProviderFactory>() 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<IActivatableLifetime>() is ActivatableLifetimeBase lifetime
&& AvaloniaLocator.Current.GetService<IStorageProviderFactory>() is StorageProviderApi storageApi)

2
src/Avalonia.Native/AvaloniaNativeDragSource.cs

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

52
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<GlVersion> preferredVersions = null) =>
public IGlContext CreateSharedContext(IEnumerable<GlVersion>? 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(&registryId) != 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

19
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<MacOSPlatformOptions>() ?? 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);

3
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()

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
/// and make your Avalonia app run with it. The default value is null.
/// </summary>
public string AvaloniaNativeLibraryPath { get; set; }
public string? AvaloniaNativeLibraryPath { get; set; }
/// <summary>
/// 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.Diagnostics;
using System.Runtime.InteropServices;
using Avalonia.Native.Interop;
using Avalonia.Rendering;
#nullable enable
namespace Avalonia.Native;

3
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

11
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<IValueProvider>();
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")]

14
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<arr.Length;c++)
using (var s = Get(c))
arr[c] = s.String;
arr[c] = s.String ?? string.Empty;
return arr;
}
}

4
src/Avalonia.Native/ClipboardDataFormatHelper.cs

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

2
src/Avalonia.Native/ClipboardDataTransferItem.cs

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

4
src/Avalonia.Native/ClipboardImpl.cs

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

2
src/Avalonia.Native/ClipboardReadSession.cs

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

4
src/Avalonia.Native/Cursor.cs

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

3
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;

2
src/Avalonia.Native/DataTransferToAvnClipboardDataSourceWrapper.cs

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

1
src/Avalonia.Native/DispatcherImpl.cs

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

2
src/Avalonia.Native/GpuHandleWrapFeature.cs

@ -1,5 +1,3 @@
#nullable enable
using System;
using Avalonia.Native.Interop;
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
{
@ -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;
}

10
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<NativeMenuItemBase, __MicroComIAvnMenuItemProxy> _menuItemLookup = new Dictionary<NativeMenuItemBase, __MicroComIAvnMenuItemProxy>();
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();
}

18
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();
}

4
src/Avalonia.Native/IconLoader.cs

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

3
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()

56
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<string> 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;
}

53
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<IPlatformHandle, IPlatformHandle> 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);
}
}
}

2
src/Avalonia.Native/NativeOwned.cs

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

2
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)
{

2
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)

2
src/Avalonia.Native/StorageItem.cs

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

2
src/Avalonia.Native/StorageProviderApi.cs

@ -1,5 +1,3 @@
#nullable enable
using System;
using System.Collections.Generic;
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.Threading.Tasks;
using Avalonia.Platform.Storage;

6
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;

2
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

22
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<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; }
@ -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<WindowCloseReason, bool> Closing { get; set; }
public Func<WindowCloseReason, bool>? 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))
{

4
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()

Loading…
Cancel
Save