diff --git a/src/Avalonia.Controls/ApplicationLifetimes/IActivatableApplicationLifetime.cs b/src/Avalonia.Controls/ApplicationLifetimes/IActivatableApplicationLifetime.cs index fbdfe3aa7d..b04397f1c6 100644 --- a/src/Avalonia.Controls/ApplicationLifetimes/IActivatableApplicationLifetime.cs +++ b/src/Avalonia.Controls/ApplicationLifetimes/IActivatableApplicationLifetime.cs @@ -11,13 +11,13 @@ public interface IActivatableApplicationLifetime /// An event that is raised when the application is Activated for various reasons /// as described by the enumeration. /// - event EventHandler Activated; + event EventHandler? Activated; /// /// An event that is raised when the application is Deactivated for various reasons /// as described by the enumeration. /// - event EventHandler Deactivated; + event EventHandler? Deactivated; /// /// Tells the application that it should attempt to leave its background state. diff --git a/src/iOS/Avalonia.iOS/Avalonia.iOS.csproj b/src/iOS/Avalonia.iOS/Avalonia.iOS.csproj index eb4938c13f..4201ae0ad3 100644 --- a/src/iOS/Avalonia.iOS/Avalonia.iOS.csproj +++ b/src/iOS/Avalonia.iOS/Avalonia.iOS.csproj @@ -1,9 +1,15 @@  net7.0-ios16.0 - 13.0 + 13.0 + 13.0 + 13.1 true true + + + + $(NoWarn);CA1416 @@ -12,4 +18,5 @@ + diff --git a/src/iOS/Avalonia.iOS/AvaloniaAppDelegate.cs b/src/iOS/Avalonia.iOS/AvaloniaAppDelegate.cs index ecb9e56aa9..e4ec20bbbd 100644 --- a/src/iOS/Avalonia.iOS/AvaloniaAppDelegate.cs +++ b/src/iOS/Avalonia.iOS/AvaloniaAppDelegate.cs @@ -15,7 +15,7 @@ namespace Avalonia.iOS public class AvaloniaAppDelegate : UIResponder, IUIApplicationDelegate, IAvaloniaAppDelegate where TApp : Application, new() { - private EventHandler _onActivated, _onDeactivated; + private EventHandler? _onActivated, _onDeactivated; public AvaloniaAppDelegate() { @@ -37,7 +37,7 @@ namespace Avalonia.iOS protected virtual AppBuilder CustomizeAppBuilder(AppBuilder builder) => builder; [Export("window")] - public UIWindow Window { get; set; } + public UIWindow? Window { get; set; } [Export("application:didFinishLaunchingWithOptions:")] public bool FinishedLaunching(UIApplication application, NSDictionary launchOptions) @@ -64,7 +64,7 @@ namespace Avalonia.iOS builder.SetupWithLifetime(lifetime); - Window.MakeKeyAndVisible(); + Window!.MakeKeyAndVisible(); return true; } diff --git a/src/iOS/Avalonia.iOS/AvaloniaView.Text.cs b/src/iOS/Avalonia.iOS/AvaloniaView.Text.cs index 0b0e169e8a..dbdddd2cc5 100644 --- a/src/iOS/Avalonia.iOS/AvaloniaView.Text.cs +++ b/src/iOS/Avalonia.iOS/AvaloniaView.Text.cs @@ -1,4 +1,3 @@ -#nullable enable using Avalonia.Input.TextInput; using UIKit; diff --git a/src/iOS/Avalonia.iOS/AvaloniaView.cs b/src/iOS/Avalonia.iOS/AvaloniaView.cs index f44202c240..b6cde47c7a 100644 --- a/src/iOS/Avalonia.iOS/AvaloniaView.cs +++ b/src/iOS/Avalonia.iOS/AvaloniaView.cs @@ -1,7 +1,6 @@ -#nullable enable - using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Runtime.Versioning; using Avalonia.Controls; using Avalonia.Controls.Embedding; @@ -12,7 +11,6 @@ using Avalonia.Input; using Avalonia.Input.Platform; using Avalonia.Input.Raw; using Avalonia.Input.TextInput; -using Avalonia.iOS.Storage; using Avalonia.Platform; using Avalonia.Platform.Storage; using Avalonia.Rendering.Composition; @@ -24,6 +22,9 @@ using IInsetsManager = Avalonia.Controls.Platform.IInsetsManager; namespace Avalonia.iOS { + /// + /// Root view container for Avalonia content, that can be embedded into iOS visual tree. + /// public partial class AvaloniaView : UIView, ITextInputMethodImpl { internal IInputRoot InputRoot @@ -35,7 +36,7 @@ namespace Avalonia.iOS private TextInputMethodClient? _client; private IAvaloniaViewController? _controller; private IInputRoot? _inputRoot; - private MetalRenderTarget? _currentRenderTarget; + private Metal.MetalRenderTarget? _currentRenderTarget; public AvaloniaView() { @@ -49,13 +50,14 @@ namespace Avalonia.iOS InitLayerSurface(); #if !TVOS - MultipleTouchEnabled = true; + if (OperatingSystem.IsIOS() || OperatingSystem.IsMacCatalyst()) + { + MultipleTouchEnabled = true; + } #endif } - [ObsoletedOSPlatform("ios12.0", "Use 'Metal' instead.")] - [SupportedOSPlatform("ios")] - [UnsupportedOSPlatform("maccatalyst")] + [SuppressMessage("Interoperability", "CA1422:Validate platform compatibility")] private void InitLayerSurface() { var l = Layer; @@ -68,13 +70,13 @@ namespace Avalonia.iOS OpenGLES.EAGLDrawableProperty.RetainedBacking, false, OpenGLES.EAGLDrawableProperty.ColorFormat, OpenGLES.EAGLColorFormat.RGBA8 ); - _topLevelImpl.Surfaces = new[] { new EaglLayerSurface(eaglLayer) }; + _topLevelImpl.Surfaces = new[] { new Eagl.EaglLayerSurface(eaglLayer) }; } else #endif if (l is CAMetalLayer metalLayer) { - _topLevelImpl.Surfaces = new[] { new MetalPlatformSurface(metalLayer, this) }; + _topLevelImpl.Surfaces = new[] { new Metal.MetalPlatformSurface(metalLayer, this) }; } } @@ -85,6 +87,12 @@ namespace Avalonia.iOS public override bool CanResignFirstResponder => true; /// + [ObsoletedOSPlatform("ios17.0", "Use the 'UITraitChangeObservable' protocol instead.")] + [ObsoletedOSPlatform("maccatalyst17.0", "Use the 'UITraitChangeObservable' protocol instead.")] + [ObsoletedOSPlatform("tvos17.0", "Use the 'UITraitChangeObservable' protocol instead.")] + [SupportedOSPlatform("ios")] + [SupportedOSPlatform("tvos")] + [SupportedOSPlatform("maccatalyst")] public override void TraitCollectionDidChange(UITraitCollection? previousTraitCollection) { base.TraitCollectionDidChange(previousTraitCollection); @@ -125,8 +133,12 @@ namespace Avalonia.iOS { _view = view; _nativeControlHost = new NativeControlHostImpl(view); -#if !TVOS - _storageProvider = new IOSStorageProvider(view); +#if TVOS + _storageProvider = null; + _clipboard = null; + _inputPane = null; +#else + _storageProvider = new Storage.IOSStorageProvider(view); _clipboard = new ClipboardImpl(); _inputPane = UIKitInputPane.Instance; #endif @@ -152,7 +164,8 @@ namespace Avalonia.iOS // No-op } - public Compositor Compositor => Platform.Compositor; + public Compositor Compositor => Platform.Compositor + ?? throw new InvalidOperationException("iOS backend wasn't initialized. Make sure UseiOS was called."); public void Invalidate(Rect rect) { @@ -237,7 +250,6 @@ namespace Avalonia.iOS return _insetsManager; } -#if !TVOS if (featureType == typeof(IClipboard)) { return _clipboard; @@ -252,7 +264,6 @@ namespace Avalonia.iOS { return _inputPane; } -#endif return null; } @@ -262,7 +273,7 @@ namespace Avalonia.iOS public static Class LayerClass() { #if !MACCATALYST - if (Platform.Graphics is EaglPlatformGraphics) + if (Platform.Graphics is Eagl.EaglPlatformGraphics) { return new Class(typeof(CAEAGLLayer)); } @@ -299,7 +310,7 @@ namespace Avalonia.iOS set => _topLevel.Content = value; } - internal void SetRenderTarget(MetalRenderTarget target) + internal void SetRenderTarget(Metal.MetalRenderTarget target) { _currentRenderTarget = target; } diff --git a/src/iOS/Avalonia.iOS/ClipboardImpl.cs b/src/iOS/Avalonia.iOS/ClipboardImpl.cs index 0bc03e9160..27cbc0246c 100644 --- a/src/iOS/Avalonia.iOS/ClipboardImpl.cs +++ b/src/iOS/Avalonia.iOS/ClipboardImpl.cs @@ -1,20 +1,22 @@ #if !TVOS using System; +using System.Collections.Generic; using System.Threading.Tasks; using Avalonia.Input; using Avalonia.Input.Platform; +using Foundation; using UIKit; namespace Avalonia.iOS { internal class ClipboardImpl : IClipboard { - public Task GetTextAsync() + public Task GetTextAsync() { return Task.FromResult(UIPasteboard.General.String); } - public Task SetTextAsync(string text) + public Task SetTextAsync(string? text) { UIPasteboard.General.String = text; return Task.CompletedTask; @@ -22,15 +24,40 @@ namespace Avalonia.iOS public Task ClearAsync() { - UIPasteboard.General.String = ""; + UIPasteboard.General.Items = Array.Empty(); return Task.CompletedTask; } - public Task SetDataObjectAsync(IDataObject data) => Task.CompletedTask; + public Task SetDataObjectAsync(IDataObject data) + { + if (data.Contains(DataFormats.Text)) + { + UIPasteboard.General.String = data.GetText(); + } + + return Task.CompletedTask; + } + + public Task GetFormatsAsync() + { + var formats = new List(); + if (UIPasteboard.General.HasStrings) + { + formats.Add(DataFormats.Text); + } - public Task GetFormatsAsync() => Task.FromResult(Array.Empty()); + return Task.FromResult(formats.ToArray()); + } - public Task GetDataAsync(string format) => Task.FromResult(null); + public Task GetDataAsync(string format) + { + if (format == DataFormats.Text) + { + return Task.FromResult(UIPasteboard.General.String); + } + + return Task.FromResult(null); + } } } #endif diff --git a/src/iOS/Avalonia.iOS/DispatcherImpl.cs b/src/iOS/Avalonia.iOS/DispatcherImpl.cs index 9933126133..b39ba1a85a 100644 --- a/src/iOS/Avalonia.iOS/DispatcherImpl.cs +++ b/src/iOS/Avalonia.iOS/DispatcherImpl.cs @@ -1,5 +1,3 @@ -#nullable enable - using System; using System.Diagnostics; using System.Runtime.InteropServices; diff --git a/src/iOS/Avalonia.iOS/DisplayLinkTimer.cs b/src/iOS/Avalonia.iOS/DisplayLinkTimer.cs index eb124fd450..676554811e 100644 --- a/src/iOS/Avalonia.iOS/DisplayLinkTimer.cs +++ b/src/iOS/Avalonia.iOS/DisplayLinkTimer.cs @@ -11,7 +11,7 @@ namespace Avalonia.iOS { class DisplayLinkTimer : IRenderTimer { - public event Action Tick; + public event Action? Tick; private Stopwatch _st = Stopwatch.StartNew(); public DisplayLinkTimer() @@ -36,4 +36,4 @@ namespace Avalonia.iOS Tick?.Invoke(_st.Elapsed); } } -} \ No newline at end of file +} diff --git a/src/iOS/Avalonia.iOS/Eagl/EaglDisplay.cs b/src/iOS/Avalonia.iOS/Eagl/EaglDisplay.cs index cbd7089f4c..696a1a1561 100644 --- a/src/iOS/Avalonia.iOS/Eagl/EaglDisplay.cs +++ b/src/iOS/Avalonia.iOS/Eagl/EaglDisplay.cs @@ -8,10 +8,13 @@ using Avalonia.Platform; using Avalonia.Reactive; using OpenGLES; -namespace Avalonia.iOS +namespace Avalonia.iOS.Eagl { [ObsoletedOSPlatform("ios12.0", "Use 'Metal' instead.")] + [ObsoletedOSPlatform("tvos12.0", "Use 'Metal' instead.")] + [UnsupportedOSPlatform("maccatalyst")] [SupportedOSPlatform("ios")] + [SupportedOSPlatform("tvos")] class EaglPlatformGraphics : IPlatformGraphics { public IPlatformGraphicsContext GetSharedContext() => Context; @@ -32,7 +35,7 @@ namespace Avalonia.iOS Context = new(iface, null); } - public static EaglPlatformGraphics TryCreate() + public static EaglPlatformGraphics? TryCreate() { try { @@ -47,12 +50,14 @@ namespace Avalonia.iOS } [ObsoletedOSPlatform("ios12.0", "Use 'Metal' instead.")] + [ObsoletedOSPlatform("tvos12.0", "Use 'Metal' instead.")] [SupportedOSPlatform("ios")] + [SupportedOSPlatform("tvos")] class GlContext : IGlContext { - public EAGLContext Context { get; private set; } + public EAGLContext? Context { get; private set; } - public GlContext(GlInterface glInterface, EAGLSharegroup sharegroup) + public GlContext(GlInterface glInterface, EAGLSharegroup? sharegroup) { GlInterface = glInterface; Context = sharegroup == null ? @@ -68,10 +73,10 @@ namespace Avalonia.iOS class ResetContext : IDisposable { - private EAGLContext _old; + private EAGLContext? _old; private bool _disposed; - public ResetContext(EAGLContext old) + public ResetContext(EAGLContext? old) { _old = old; } @@ -102,7 +107,7 @@ namespace Avalonia.iOS { if (Context == null) throw new PlatformGraphicsContextLostException(); - if(EAGLContext.CurrentContext == Context) + if (EAGLContext.CurrentContext == Context) return Disposable.Empty; return MakeCurrent(); } @@ -110,8 +115,10 @@ namespace Avalonia.iOS public bool IsSharedWith(IGlContext context) => context is GlContext other && ReferenceEquals(other.Context?.ShareGroup, Context?.ShareGroup); public bool CanCreateSharedContext => true; - public IGlContext CreateSharedContext(IEnumerable preferredVersions = null) + public IGlContext CreateSharedContext(IEnumerable? preferredVersions = null) { + if (Context == null) + throw new PlatformGraphicsContextLostException(); return new GlContext(GlInterface, Context.ShareGroup); } @@ -134,7 +141,7 @@ namespace Avalonia.iOS } } - public object TryGetFeature(Type featureType) => null; + public object? TryGetFeature(Type featureType) => null; } } #endif diff --git a/src/iOS/Avalonia.iOS/Eagl/EaglLayerSurface.cs b/src/iOS/Avalonia.iOS/Eagl/EaglLayerSurface.cs index e62395c985..f010dd8f13 100644 --- a/src/iOS/Avalonia.iOS/Eagl/EaglLayerSurface.cs +++ b/src/iOS/Avalonia.iOS/Eagl/EaglLayerSurface.cs @@ -5,14 +5,14 @@ using System.Threading; using Avalonia.OpenGL; using Avalonia.OpenGL.Surfaces; using CoreAnimation; -using Foundation; -using OpenGLES; -using UIKit; -namespace Avalonia.iOS +namespace Avalonia.iOS.Eagl { [ObsoletedOSPlatform("ios12.0", "Use 'Metal' instead.")] + [ObsoletedOSPlatform("tvos12.0", "Use 'Metal' instead.")] [SupportedOSPlatform("ios")] + [SupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("maccatalyst")] class EaglLayerSurface : IGlPlatformSurface { private readonly CAEAGLLayer _layer; @@ -80,19 +80,19 @@ namespace Avalonia.iOS static void CheckThread() { - if (Platform.Timer.TimerThread != Thread.CurrentThread) + if (Platform.Timer!.TimerThread != Thread.CurrentThread) throw new InvalidOperationException("Invalid thread, go away"); } public IGlPlatformSurfaceRenderTarget CreateGlRenderTarget(IGlContext context) { CheckThread(); - var ctx = ((EaglPlatformGraphics)Platform.Graphics).Context; + var ctx = ((EaglPlatformGraphics)Platform.Graphics!).Context; if (ctx != context) throw new InvalidOperationException("Platform surface is only usable with tha main context"); using (ctx.MakeCurrent()) { - var fbo = new SizeSynchronizedLayerFbo(ctx.Context, ctx.GlInterface, _layer); + var fbo = new SizeSynchronizedLayerFbo(ctx.Context!, ctx.GlInterface, _layer); if (!fbo.Sync()) throw new InvalidOperationException("Unable to create render target"); return new RenderTarget(ctx, fbo); diff --git a/src/iOS/Avalonia.iOS/Eagl/LayerFbo.cs b/src/iOS/Avalonia.iOS/Eagl/LayerFbo.cs index 97a9692d1c..d986e380d8 100644 --- a/src/iOS/Avalonia.iOS/Eagl/LayerFbo.cs +++ b/src/iOS/Avalonia.iOS/Eagl/LayerFbo.cs @@ -5,10 +5,13 @@ using Avalonia.OpenGL; using CoreAnimation; using OpenGLES; -namespace Avalonia.iOS +namespace Avalonia.iOS.Eagl { [ObsoletedOSPlatform("ios12.0", "Use 'Metal' instead.")] + [ObsoletedOSPlatform("tvos12.0", "Use 'Metal' instead.")] [SupportedOSPlatform("ios")] + [SupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("maccatalyst")] internal class LayerFbo { private readonly EAGLContext _context; @@ -29,7 +32,7 @@ namespace Avalonia.iOS _depthBuffer = depthBuffer; } - public static LayerFbo TryCreate(EAGLContext context, GlInterface gl, CAEAGLLayer layer) + public static LayerFbo? TryCreate(EAGLContext context, GlInterface gl, CAEAGLLayer layer) { if (context != EAGLContext.CurrentContext) return null; @@ -78,7 +81,7 @@ namespace Avalonia.iOS public void Present() { Bind(); - var success = _context.PresentRenderBuffer(GlConsts.GL_RENDERBUFFER); + _context.PresentRenderBuffer(GlConsts.GL_RENDERBUFFER); } public void Dispose() @@ -95,13 +98,16 @@ namespace Avalonia.iOS } [ObsoletedOSPlatform("ios12.0", "Use 'Metal' instead.")] + [ObsoletedOSPlatform("tvos12.0", "Use 'Metal' instead.")] [SupportedOSPlatform("ios")] + [SupportedOSPlatform("tvos")] + [UnsupportedOSPlatform("maccatalyst")] class SizeSynchronizedLayerFbo : IDisposable { private readonly EAGLContext _context; private readonly GlInterface _gl; private readonly CAEAGLLayer _layer; - private LayerFbo _fbo; + private LayerFbo? _fbo; private double _oldLayerWidth, _oldLayerHeight, _oldLayerScale; public SizeSynchronizedLayerFbo(EAGLContext context, GlInterface gl, CAEAGLLayer layer) @@ -139,10 +145,10 @@ namespace Avalonia.iOS { if(!Sync()) throw new InvalidOperationException("Unable to create a render target"); - _fbo.Bind(); + _fbo!.Bind(); } - public void Present() => _fbo.Present(); + public void Present() => _fbo!.Present(); public int Width => _fbo?.Width ?? 0; public int Height => _fbo?.Height ?? 0; diff --git a/src/iOS/Avalonia.iOS/InsetsManager.cs b/src/iOS/Avalonia.iOS/InsetsManager.cs index c746644532..d1439fcd3f 100644 --- a/src/iOS/Avalonia.iOS/InsetsManager.cs +++ b/src/iOS/Avalonia.iOS/InsetsManager.cs @@ -3,7 +3,6 @@ using Avalonia.Controls.Platform; using Avalonia.Media; namespace Avalonia.iOS; -#nullable enable internal class InsetsManager : IInsetsManager { diff --git a/src/iOS/Avalonia.iOS/Metal/MetalDevice.cs b/src/iOS/Avalonia.iOS/Metal/MetalDevice.cs index 796cc2a613..03123a8801 100644 --- a/src/iOS/Avalonia.iOS/Metal/MetalDevice.cs +++ b/src/iOS/Avalonia.iOS/Metal/MetalDevice.cs @@ -1,9 +1,10 @@ using System; +using System.Runtime.Versioning; using Avalonia.Metal; using Avalonia.Utilities; using Metal; -namespace Avalonia.iOS; +namespace Avalonia.iOS.Metal; internal class MetalDevice : IMetalDevice { @@ -12,7 +13,8 @@ internal class MetalDevice : IMetalDevice public MetalDevice(IMTLDevice device) { Device = device; - Queue = device.CreateCommandQueue(); + Queue = device.CreateCommandQueue() + ?? throw new InvalidOperationException("IMTLCommandQueue is not available"); } public IMTLDevice Device { get; } @@ -23,7 +25,7 @@ internal class MetalDevice : IMetalDevice public bool IsLost => false; public IDisposable EnsureCurrent() => _syncRoot.Lock(); - public object TryGetFeature(Type featureType) => null; + public object? TryGetFeature(Type featureType) => null; public void Dispose() { diff --git a/src/iOS/Avalonia.iOS/Metal/MetalDrawingSession.cs b/src/iOS/Avalonia.iOS/Metal/MetalDrawingSession.cs index 1587377fbd..0233922025 100644 --- a/src/iOS/Avalonia.iOS/Metal/MetalDrawingSession.cs +++ b/src/iOS/Avalonia.iOS/Metal/MetalDrawingSession.cs @@ -2,7 +2,7 @@ using System; using Avalonia.Metal; using CoreAnimation; -namespace Avalonia.iOS; +namespace Avalonia.iOS.Metal; internal class MetalDrawingSession : IMetalPlatformSurfaceRenderingSession { @@ -21,7 +21,7 @@ internal class MetalDrawingSession : IMetalPlatformSurfaceRenderingSession public void Dispose() { var buffer = _device.Queue.CommandBuffer(); - buffer.PresentDrawable(_drawable); + buffer!.PresentDrawable(_drawable); buffer.Commit(); } diff --git a/src/iOS/Avalonia.iOS/Metal/MetalPlatformGraphics.cs b/src/iOS/Avalonia.iOS/Metal/MetalPlatformGraphics.cs index 5947a13b0a..fb5ffc862c 100644 --- a/src/iOS/Avalonia.iOS/Metal/MetalPlatformGraphics.cs +++ b/src/iOS/Avalonia.iOS/Metal/MetalPlatformGraphics.cs @@ -1,20 +1,26 @@ using System; +using System.Runtime.Versioning; using Avalonia.Platform; using Metal; using SkiaSharp; -namespace Avalonia.iOS; -#nullable enable +namespace Avalonia.iOS.Metal; +[SupportedOSPlatform("ios")] +[SupportedOSPlatform("macos")] +[SupportedOSPlatform("maccatalyst")] +[SupportedOSPlatform("tvos")] internal class MetalPlatformGraphics : IPlatformGraphics { - private MetalPlatformGraphics() + private readonly IMTLDevice _defaultDevice; + + private MetalPlatformGraphics(IMTLDevice defaultDevice) { - + _defaultDevice = defaultDevice; } public bool UsesSharedContext => false; - public IPlatformGraphicsContext CreateContext() => new MetalDevice(MTLDevice.SystemDefault); + public IPlatformGraphicsContext CreateContext() => new MetalDevice(_defaultDevice); public IPlatformGraphicsContext GetSharedContext() => throw new NotSupportedException(); @@ -38,6 +44,6 @@ internal class MetalPlatformGraphics : IPlatformGraphics } #endif - return new MetalPlatformGraphics(); + return new MetalPlatformGraphics(device); } } diff --git a/src/iOS/Avalonia.iOS/Metal/MetalPlatformSurface.cs b/src/iOS/Avalonia.iOS/Metal/MetalPlatformSurface.cs index 453c9992c9..285ba95e48 100644 --- a/src/iOS/Avalonia.iOS/Metal/MetalPlatformSurface.cs +++ b/src/iOS/Avalonia.iOS/Metal/MetalPlatformSurface.cs @@ -1,7 +1,7 @@ using Avalonia.Metal; using CoreAnimation; -namespace Avalonia.iOS; +namespace Avalonia.iOS.Metal; internal class MetalPlatformSurface : IMetalPlatformSurface { diff --git a/src/iOS/Avalonia.iOS/Metal/MetalRenderTarget.cs b/src/iOS/Avalonia.iOS/Metal/MetalRenderTarget.cs index f8a28154df..bb2d74235e 100644 --- a/src/iOS/Avalonia.iOS/Metal/MetalRenderTarget.cs +++ b/src/iOS/Avalonia.iOS/Metal/MetalRenderTarget.cs @@ -2,9 +2,8 @@ using Avalonia.Metal; using Avalonia.Platform; using CoreAnimation; using CoreGraphics; -using Foundation; -namespace Avalonia.iOS; +namespace Avalonia.iOS.Metal; internal class MetalRenderTarget : IMetalPlatformSurfaceRenderTarget { @@ -28,7 +27,7 @@ internal class MetalRenderTarget : IMetalPlatformSurfaceRenderTarget public IMetalPlatformSurfaceRenderingSession BeginRendering() { // Flush all existing rendering - var buffer = _device.Queue.CommandBuffer(); + var buffer = _device.Queue.CommandBuffer()!; buffer.Commit(); buffer.WaitUntilCompleted(); _size = PendingSize; diff --git a/src/iOS/Avalonia.iOS/NativeControlHostImpl.cs b/src/iOS/Avalonia.iOS/NativeControlHostImpl.cs index f752936dc8..2c03c13592 100644 --- a/src/iOS/Avalonia.iOS/NativeControlHostImpl.cs +++ b/src/iOS/Avalonia.iOS/NativeControlHostImpl.cs @@ -1,6 +1,4 @@ -#nullable enable - -using System; +using System; using System.Diagnostics.CodeAnalysis; using Avalonia.Controls.Platform; using Avalonia.Platform; diff --git a/src/iOS/Avalonia.iOS/Platform.cs b/src/iOS/Avalonia.iOS/Platform.cs index e586052087..8cda5a02e2 100644 --- a/src/iOS/Avalonia.iOS/Platform.cs +++ b/src/iOS/Avalonia.iOS/Platform.cs @@ -46,10 +46,10 @@ namespace Avalonia.iOS { static class Platform { - public static iOSPlatformOptions Options; - public static IPlatformGraphics Graphics; - public static DisplayLinkTimer Timer; - internal static Compositor Compositor { get; private set; } + public static iOSPlatformOptions? Options; + public static IPlatformGraphics? Graphics; + public static DisplayLinkTimer? Timer; + internal static Compositor? Compositor { get; private set; } public static void Register() { @@ -84,14 +84,17 @@ namespace Avalonia.iOS { #if !MACCATALYST if (renderingMode == iOSRenderingMode.OpenGl - && EaglPlatformGraphics.TryCreate() is { } eaglGraphics) + && !OperatingSystem.IsMacCatalyst() +#pragma warning disable CA1422 + && Eagl.EaglPlatformGraphics.TryCreate() is { } eaglGraphics) +#pragma warning restore CA1422 { return eaglGraphics; } #endif if (renderingMode == iOSRenderingMode.Metal - && MetalPlatformGraphics.TryCreate() is { } metalGraphics) + && Metal.MetalPlatformGraphics.TryCreate() is { } metalGraphics) { return metalGraphics; } diff --git a/src/iOS/Avalonia.iOS/PlatformSettings.cs b/src/iOS/Avalonia.iOS/PlatformSettings.cs index 07e366e79e..43cd731701 100644 --- a/src/iOS/Avalonia.iOS/PlatformSettings.cs +++ b/src/iOS/Avalonia.iOS/PlatformSettings.cs @@ -1,4 +1,3 @@ -#nullable enable using System; using Avalonia.Media; using Avalonia.Platform; diff --git a/src/iOS/Avalonia.iOS/SingleViewLifetime.cs b/src/iOS/Avalonia.iOS/SingleViewLifetime.cs index d3924482e4..9627700c7f 100644 --- a/src/iOS/Avalonia.iOS/SingleViewLifetime.cs +++ b/src/iOS/Avalonia.iOS/SingleViewLifetime.cs @@ -12,16 +12,16 @@ internal class SingleViewLifetime : ISingleViewApplicationLifetime, IActivatable avaloniaAppDelegate.Deactivated += (_, args) => Deactivated?.Invoke(this, args); } - public AvaloniaView View; + public AvaloniaView? View; - public Control MainView + public Control? MainView { - get => View.Content; - set => View.Content = value; + get => View!.Content; + set => View!.Content = value; } - public event EventHandler Activated; - public event EventHandler Deactivated; + public event EventHandler? Activated; + public event EventHandler? Deactivated; public bool TryLeaveBackground() => false; public bool TryEnterBackground() => false; } diff --git a/src/iOS/Avalonia.iOS/Storage/IOSStorageItem.cs b/src/iOS/Avalonia.iOS/Storage/IOSStorageItem.cs index 74fd9b7273..9819eea382 100644 --- a/src/iOS/Avalonia.iOS/Storage/IOSStorageItem.cs +++ b/src/iOS/Avalonia.iOS/Storage/IOSStorageItem.cs @@ -10,8 +10,6 @@ using Foundation; using UIKit; -#nullable enable - namespace Avalonia.iOS.Storage; internal abstract class IOSStorageItem : IStorageBookmarkItem @@ -57,7 +55,10 @@ internal abstract class IOSStorageItem : IStorageBookmarkItem var properties = attributes is null ? new StorageItemProperties() : - new StorageItemProperties(attributes.Size, (DateTime)attributes.CreationDate, (DateTime)attributes.ModificationDate); + new StorageItemProperties( + attributes.Size, + attributes.CreationDate is { } creationDate ? (DateTime)creationDate : null, + attributes.ModificationDate is { } modificationDate ? (DateTime)modificationDate : null); return Task.FromResult(properties); } diff --git a/src/iOS/Avalonia.iOS/Storage/IOSStorageProvider.cs b/src/iOS/Avalonia.iOS/Storage/IOSStorageProvider.cs index 2848bfaba0..9b4f2611b1 100644 --- a/src/iOS/Avalonia.iOS/Storage/IOSStorageProvider.cs +++ b/src/iOS/Avalonia.iOS/Storage/IOSStorageProvider.cs @@ -13,8 +13,6 @@ using UniformTypeIdentifiers; using UTTypeLegacy = MobileCoreServices.UTType; using UTType = UniformTypeIdentifiers.UTType; -#nullable enable - namespace Avalonia.iOS.Storage; internal class IOSStorageProvider : IStorageProvider @@ -69,8 +67,10 @@ internal class IOSStorageProvider : IStorageProvider var allowedUtils = options.FileTypeFilter?.SelectMany(f => f.AppleUniformTypeIdentifiers ?? Array.Empty()) .ToArray() ?? new[] { +#pragma warning disable CA1422 UTTypeLegacy.Content, UTTypeLegacy.Item, +#pragma warning restore CA1422 "public.data" }; documentPicker = new UIDocumentPickerViewController(allowedUtils, UIDocumentPickerMode.Open); @@ -149,7 +149,9 @@ internal class IOSStorageProvider : IStorageProvider { using var documentPicker = OperatingSystem.IsIOSVersionAtLeast(14) ? new UIDocumentPickerViewController(new[] { UTTypes.Folder }, false) : +#pragma warning disable CA1422 new UIDocumentPickerViewController(new string[] { UTTypeLegacy.Folder }, UIDocumentPickerMode.Open); +#pragma warning restore CA1422 if (OperatingSystem.IsIOSVersionAtLeast(13)) { diff --git a/src/iOS/Avalonia.iOS/Stubs.cs b/src/iOS/Avalonia.iOS/Stubs.cs index 6ac89fcab2..a5dbff7797 100644 --- a/src/iOS/Avalonia.iOS/Stubs.cs +++ b/src/iOS/Avalonia.iOS/Stubs.cs @@ -12,6 +12,7 @@ namespace Avalonia.iOS private class CursorImplStub : ICursorImpl { + public CursorImplStub(){} public void Dispose() { } } } @@ -22,7 +23,7 @@ namespace Avalonia.iOS public IWindowImpl CreateEmbeddableWindow() => throw new NotSupportedException(); - public ITrayIconImpl CreateTrayIcon() => null; + public ITrayIconImpl? CreateTrayIcon() => null; } internal class PlatformIconLoaderStub : IPlatformIconLoader diff --git a/src/iOS/Avalonia.iOS/TextInputResponder.Properties.cs b/src/iOS/Avalonia.iOS/TextInputResponder.Properties.cs index 5298be107c..ab0d92e5fa 100644 --- a/src/iOS/Avalonia.iOS/TextInputResponder.Properties.cs +++ b/src/iOS/Avalonia.iOS/TextInputResponder.Properties.cs @@ -1,4 +1,3 @@ -#nullable enable using Avalonia.Input.TextInput; using Foundation; using UIKit; diff --git a/src/iOS/Avalonia.iOS/TextInputResponder.cs b/src/iOS/Avalonia.iOS/TextInputResponder.cs index d3b518ae65..97b104b918 100644 --- a/src/iOS/Avalonia.iOS/TextInputResponder.cs +++ b/src/iOS/Avalonia.iOS/TextInputResponder.cs @@ -14,8 +14,6 @@ using UIKit; namespace Avalonia.iOS; -#nullable enable - partial class AvaloniaView { @@ -110,7 +108,9 @@ partial class AvaloniaView { UITextInputMode? mode = null; #if !TVOS +#pragma warning disable CA1422 mode = UITextInputMode.CurrentInputMode; +#pragma warning restore CA1422 #endif // Can be empty see https://developer.apple.com/documentation/uikit/uitextinputmode/1614522-activeinputmodes if (mode is null && UITextInputMode.ActiveInputModes.Length > 0) diff --git a/src/iOS/Avalonia.iOS/TouchHandler.cs b/src/iOS/Avalonia.iOS/TouchHandler.cs index 44bf08365f..b85affbce5 100644 --- a/src/iOS/Avalonia.iOS/TouchHandler.cs +++ b/src/iOS/Avalonia.iOS/TouchHandler.cs @@ -11,7 +11,7 @@ namespace Avalonia.iOS { private readonly AvaloniaView _view; private readonly ITopLevelImpl _tl; - public TouchDevice _device = new TouchDevice(); + public TouchDevice _device = new(); public TouchHandler(AvaloniaView view, ITopLevelImpl tl) { @@ -19,12 +19,12 @@ namespace Avalonia.iOS _tl = tl; } - static ulong Ts(UIEvent evt) => (ulong) (evt.Timestamp * 1000); + static ulong Ts(UIEvent? evt) => evt is null ? 0 : (ulong) (evt.Timestamp * 1000); private IInputRoot Root => _view.InputRoot; private static long _nextTouchPointId = 1; private Dictionary _knownTouches = new Dictionary(); - public void Handle(NSSet touches, UIEvent evt) + public void Handle(NSSet touches, UIEvent? evt) { foreach (UITouch t in touches) { diff --git a/src/iOS/Avalonia.iOS/UIKitInputPane.cs b/src/iOS/Avalonia.iOS/UIKitInputPane.cs index 7ba6f8eb77..8db7f1b364 100644 --- a/src/iOS/Avalonia.iOS/UIKitInputPane.cs +++ b/src/iOS/Avalonia.iOS/UIKitInputPane.cs @@ -7,7 +7,6 @@ using Avalonia.Controls.Platform; using Foundation; using UIKit; -#nullable enable namespace Avalonia.iOS; [UnsupportedOSPlatform("tvos")] diff --git a/src/iOS/Avalonia.iOS/ViewController.cs b/src/iOS/Avalonia.iOS/ViewController.cs index 5f901fcf01..b083cd6c90 100644 --- a/src/iOS/Avalonia.iOS/ViewController.cs +++ b/src/iOS/Avalonia.iOS/ViewController.cs @@ -12,7 +12,7 @@ public interface IAvaloniaViewController #endif bool PrefersStatusBarHidden { get; set; } Thickness SafeAreaPadding { get; } - event EventHandler SafeAreaPaddingChanged; + event EventHandler? SafeAreaPaddingChanged; } /// @@ -78,5 +78,5 @@ public class DefaultAvaloniaViewController : UIViewController, IAvaloniaViewCont public Thickness SafeAreaPadding { get; private set; } /// - public event EventHandler SafeAreaPaddingChanged; + public event EventHandler? SafeAreaPaddingChanged; }