diff --git a/readme.md b/readme.md index c2be487af3..2600cf83cc 100644 --- a/readme.md +++ b/readme.md @@ -1,3 +1,5 @@ +[![GH_Banner](https://user-images.githubusercontent.com/552074/218457976-92e76834-9e22-4e35-acfa-aa50281bc0f9.png)](https://avaloniaui.net/xpf) + [![Telegram](https://raw.githubusercontent.com/Patrolavia/telegram-badge/master/chat.svg)](https://t.me/Avalonia) [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/AvaloniaUI/Avalonia?utm_campaign=pr-badge&utm_content=badge&utm_medium=badge&utm_source=badge) [![Discord](https://img.shields.io/badge/discord-join%20chat-46BC99)]( https://aka.ms/dotnet-discord) [![Build Status](https://dev.azure.com/AvaloniaUI/AvaloniaUI/_apis/build/status/AvaloniaUI.Avalonia)](https://dev.azure.com/AvaloniaUI/AvaloniaUI/_build/latest?definitionId=4) [![Backers on Open Collective](https://opencollective.com/Avalonia/backers/badge.svg)](#backers) [![Sponsors on Open Collective](https://opencollective.com/Avalonia/sponsors/badge.svg)](#sponsors) ![License](https://img.shields.io/github/license/avaloniaui/avalonia.svg)
diff --git a/samples/GpuInterop/VulkanDemo/D3DMemoryHelper.cs b/samples/GpuInterop/VulkanDemo/D3DMemoryHelper.cs index a0b7d32d3b..ac09c48ccd 100644 --- a/samples/GpuInterop/VulkanDemo/D3DMemoryHelper.cs +++ b/samples/GpuInterop/VulkanDemo/D3DMemoryHelper.cs @@ -47,7 +47,7 @@ public class D3DMemoryHelper MipLevels = 1, SampleDescription = new SampleDescription { Count = 1, Quality = 0 }, CpuAccessFlags = default, - OptionFlags = ResourceOptionFlags.SharedKeyedmutex, + OptionFlags = ResourceOptionFlags.SharedKeyedmutex|ResourceOptionFlags.SharedNthandle, BindFlags = BindFlags.RenderTarget | BindFlags.ShaderResource }); } diff --git a/samples/GpuInterop/VulkanDemo/VulkanContext.cs b/samples/GpuInterop/VulkanDemo/VulkanContext.cs index 3fdd9695f2..1d44549089 100644 --- a/samples/GpuInterop/VulkanDemo/VulkanContext.cs +++ b/samples/GpuInterop/VulkanDemo/VulkanContext.cs @@ -173,7 +173,7 @@ public unsafe class VulkanContext : IDisposable api.GetPhysicalDeviceQueueFamilyProperties(physicalDevice, ref queueFamilyCount, familyProperties); for (uint queueFamilyIndex = 0; queueFamilyIndex < queueFamilyCount; queueFamilyIndex++) { - var family = familyProperties[c]; + var family = familyProperties[queueFamilyIndex]; if (!family.QueueFlags.HasAllFlags(QueueFlags.GraphicsBit)) continue; diff --git a/samples/GpuInterop/VulkanDemo/VulkanImage.cs b/samples/GpuInterop/VulkanDemo/VulkanImage.cs index 59b2ef7e30..c1865a817d 100644 --- a/samples/GpuInterop/VulkanDemo/VulkanImage.cs +++ b/samples/GpuInterop/VulkanDemo/VulkanImage.cs @@ -4,10 +4,13 @@ using System.Runtime.InteropServices; using Avalonia; using Avalonia.Platform; using Avalonia.Vulkan; +using SharpDX.DXGI; using Silk.NET.Vulkan; using Silk.NET.Vulkan.Extensions.KHR; using SilkNetDemo; using SkiaSharp; +using Device = Silk.NET.Vulkan.Device; +using Format = Silk.NET.Vulkan.Format; namespace GpuInterop.VulkanDemo; @@ -24,7 +27,6 @@ public unsafe class VulkanImage : IDisposable private ImageView? _imageView { get; set; } private DeviceMemory _imageMemory { get; set; } private SharpDX.Direct3D11.Texture2D? _d3dTexture2D; - private IntPtr _win32ShareHandle; internal Image? InternalHandle { get; private set; } internal Format Format { get; } @@ -60,7 +62,7 @@ public unsafe class VulkanImage : IDisposable //MipLevels = MipLevels != 0 ? MipLevels : (uint)Math.Floor(Math.Log(Math.Max(Size.Width, Size.Height), 2)); var handleType = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? - ExternalMemoryHandleTypeFlags.D3D11TextureKmtBit : + ExternalMemoryHandleTypeFlags.D3D11TextureBit : ExternalMemoryHandleTypeFlags.OpaqueFDBit; var externalMemoryCreateInfo = new ExternalMemoryImageCreateInfo { @@ -108,14 +110,14 @@ public unsafe class VulkanImage : IDisposable if (exportable && RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { _d3dTexture2D = D3DMemoryHelper.CreateMemoryHandle(vk.D3DDevice, size, Format); - using var dxgi = _d3dTexture2D.QueryInterface(); - _win32ShareHandle = dxgi.SharedHandle; + using var dxgi = _d3dTexture2D.QueryInterface(); + handleImport = new ImportMemoryWin32HandleInfoKHR { PNext = &dedicatedAllocation, SType = StructureType.ImportMemoryWin32HandleInfoKhr, - HandleType = ExternalMemoryHandleTypeFlags.D3D11TextureKmtBit, - Handle = _win32ShareHandle, + HandleType = ExternalMemoryHandleTypeFlags.D3D11TextureBit, + Handle = dxgi.CreateSharedHandle(null, SharedResourceFlags.Read | SharedResourceFlags.Write), }; } @@ -185,11 +187,19 @@ public unsafe class VulkanImage : IDisposable return fd; } - public IPlatformHandle Export() => RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? - new PlatformHandle(_win32ShareHandle, - KnownPlatformGraphicsExternalImageHandleTypes.D3D11TextureGlobalSharedHandle) : - new PlatformHandle(new IntPtr(ExportFd()), - KnownPlatformGraphicsExternalImageHandleTypes.VulkanOpaquePosixFileDescriptor); + public IPlatformHandle Export() + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + using var dxgi = _d3dTexture2D!.QueryInterface(); + return new PlatformHandle( + dxgi.CreateSharedHandle(null, SharedResourceFlags.Read | SharedResourceFlags.Write), + KnownPlatformGraphicsExternalImageHandleTypes.D3D11TextureNtHandle); + } + else + return new PlatformHandle(new IntPtr(ExportFd()), + KnownPlatformGraphicsExternalImageHandleTypes.VulkanOpaquePosixFileDescriptor); + } public ImageTiling Tiling => ImageTiling.Optimal; diff --git a/src/Android/Avalonia.Android/AndroidInputMethod.cs b/src/Android/Avalonia.Android/AndroidInputMethod.cs index c885a7768c..df0c494648 100644 --- a/src/Android/Avalonia.Android/AndroidInputMethod.cs +++ b/src/Android/Avalonia.Android/AndroidInputMethod.cs @@ -32,7 +32,7 @@ namespace Avalonia.Android ActionPrevious = 0x00000007, } - class AndroidInputMethod : ITextInputMethodImpl, IAndroidInputMethod + internal class AndroidInputMethod : ITextInputMethodImpl, IAndroidInputMethod where TView : View, IInitEditorInfo { private readonly TView _host; @@ -167,7 +167,7 @@ namespace Avalonia.Android } } - public readonly record struct ComposingRegion + internal readonly record struct ComposingRegion { private readonly int _start = -1; private readonly int _end = -1; diff --git a/src/Android/Avalonia.Android/Avalonia.Android.csproj b/src/Android/Avalonia.Android/Avalonia.Android.csproj index 66557418dd..2533016e9f 100644 --- a/src/Android/Avalonia.Android/Avalonia.Android.csproj +++ b/src/Android/Avalonia.Android/Avalonia.Android.csproj @@ -5,6 +5,7 @@ true true portable + Avalonia.Android.Internal diff --git a/src/Android/Avalonia.Android/Platform/Input/AndroidKeyboardDevice.cs b/src/Android/Avalonia.Android/Platform/Input/AndroidKeyboardDevice.cs index 726ccdbbdd..ab84801e57 100644 --- a/src/Android/Avalonia.Android/Platform/Input/AndroidKeyboardDevice.cs +++ b/src/Android/Avalonia.Android/Platform/Input/AndroidKeyboardDevice.cs @@ -5,7 +5,7 @@ using Avalonia.Input; namespace Avalonia.Android.Platform.Input { - public class AndroidKeyboardDevice : KeyboardDevice, IKeyboardDevice { + internal class AndroidKeyboardDevice : KeyboardDevice, IKeyboardDevice { private static readonly Dictionary KeyDic = new Dictionary { // { Keycode.Cancel?, Key.Cancel }, diff --git a/src/Android/Avalonia.Android/Platform/SkiaPlatform/InvalidationAwareSurfaceView.cs b/src/Android/Avalonia.Android/Platform/SkiaPlatform/InvalidationAwareSurfaceView.cs index f205458f0e..47297a4f76 100644 --- a/src/Android/Avalonia.Android/Platform/SkiaPlatform/InvalidationAwareSurfaceView.cs +++ b/src/Android/Avalonia.Android/Platform/SkiaPlatform/InvalidationAwareSurfaceView.cs @@ -10,7 +10,7 @@ using Avalonia.Platform; namespace Avalonia.Android { - public abstract class InvalidationAwareSurfaceView : SurfaceView, ISurfaceHolderCallback, IPlatformNativeSurfaceHandle + internal abstract class InvalidationAwareSurfaceView : SurfaceView, ISurfaceHolderCallback, IPlatformNativeSurfaceHandle { bool _invalidateQueued; readonly object _lock = new object(); diff --git a/src/Android/Avalonia.Android/PlatformIconLoader.cs b/src/Android/Avalonia.Android/PlatformIconLoader.cs index 88677a9375..f557685dd2 100644 --- a/src/Android/Avalonia.Android/PlatformIconLoader.cs +++ b/src/Android/Avalonia.Android/PlatformIconLoader.cs @@ -3,7 +3,7 @@ using Avalonia.Platform; namespace Avalonia.Android { - class PlatformIconLoader : IPlatformIconLoader + internal class PlatformIconLoader : IPlatformIconLoader { public IWindowIconImpl LoadIcon(IBitmapImpl bitmap) { @@ -29,7 +29,7 @@ namespace Avalonia.Android } // Stores the icon created as a stream to support saving even though an icon is never shown - public class FakeIcon : IWindowIconImpl + internal class FakeIcon : IWindowIconImpl { private Stream stream = new MemoryStream(); diff --git a/src/Android/Avalonia.Android/Stubs.cs b/src/Android/Avalonia.Android/Stubs.cs index f36c01dbc8..05638cdf88 100644 --- a/src/Android/Avalonia.Android/Stubs.cs +++ b/src/Android/Avalonia.Android/Stubs.cs @@ -4,7 +4,7 @@ using Avalonia.Platform; namespace Avalonia.Android { - class WindowingPlatformStub : IWindowingPlatform + internal class WindowingPlatformStub : IWindowingPlatform { public IWindowImpl CreateWindow() => throw new NotSupportedException(); @@ -13,7 +13,7 @@ namespace Avalonia.Android public ITrayIconImpl CreateTrayIcon() => null; } - class PlatformIconLoaderStub : IPlatformIconLoader + internal class PlatformIconLoaderStub : IPlatformIconLoader { public IWindowIconImpl LoadIcon(IBitmapImpl bitmap) { @@ -38,7 +38,7 @@ namespace Avalonia.Android } } - public class IconStub : IWindowIconImpl + internal class IconStub : IWindowIconImpl { private readonly MemoryStream _ms; diff --git a/src/Avalonia.Base/AvaloniaProperty.cs b/src/Avalonia.Base/AvaloniaProperty.cs index 1c1d09c3f5..45ab293a89 100644 --- a/src/Avalonia.Base/AvaloniaProperty.cs +++ b/src/Avalonia.Base/AvaloniaProperty.cs @@ -225,13 +225,8 @@ namespace Avalonia /// The default value of the property. /// Whether the property inherits its value. /// The default binding mode for the property. - /// A value validation callback. + /// A value validation callback. /// A value coercion callback. - /// - /// A method that gets called before and after the property starts being notified on an - /// object; the bool argument will be true before and false afterwards. This callback is - /// intended to support IsDataContextChanging. - /// /// A public static StyledProperty Register( string name, @@ -239,8 +234,40 @@ namespace Avalonia bool inherits = false, BindingMode defaultBindingMode = BindingMode.OneWay, Func? validate = null, - Func? coerce = null, - Action? notifying = null) + Func? coerce = null) + where TOwner : AvaloniaObject + { + _ = name ?? throw new ArgumentNullException(nameof(name)); + + var metadata = new StyledPropertyMetadata( + defaultValue, + defaultBindingMode: defaultBindingMode, + coerce: coerce); + + var result = new StyledProperty( + name, + typeof(TOwner), + metadata, + inherits, + validate); + AvaloniaPropertyRegistry.Instance.Register(typeof(TOwner), result); + return result; + } + + /// + /// + /// A method that gets called before and after the property starts being notified on an + /// object; the bool argument will be true before and false afterwards. This callback is + /// intended to support IsDataContextChanging. + /// + internal static StyledProperty Register( + string name, + TValue defaultValue, + bool inherits, + BindingMode defaultBindingMode, + Func? validate, + Func? coerce, + Action? notifying) where TOwner : AvaloniaObject { _ = name ?? throw new ArgumentNullException(nameof(name)); diff --git a/src/Avalonia.Base/Platform/IPlatformThreadingInterface.cs b/src/Avalonia.Base/Platform/IPlatformThreadingInterface.cs index bf18a7da5b..3dbc7c1bb2 100644 --- a/src/Avalonia.Base/Platform/IPlatformThreadingInterface.cs +++ b/src/Avalonia.Base/Platform/IPlatformThreadingInterface.cs @@ -26,6 +26,6 @@ namespace Avalonia.Platform bool CurrentThreadIsLoopThread { get; } - event Action Signaled; + event Action? Signaled; } } diff --git a/src/Avalonia.Base/Platform/Storage/FilePickerFileType.cs b/src/Avalonia.Base/Platform/Storage/FilePickerFileType.cs index 75076e2bb8..f9c7f9685d 100644 --- a/src/Avalonia.Base/Platform/Storage/FilePickerFileType.cs +++ b/src/Avalonia.Base/Platform/Storage/FilePickerFileType.cs @@ -7,9 +7,9 @@ namespace Avalonia.Platform.Storage; /// public sealed class FilePickerFileType { - public FilePickerFileType(string name) + public FilePickerFileType(string? name) { - Name = name; + Name = name ?? string.Empty; } /// diff --git a/src/Avalonia.Base/Rendering/IRenderTimer.cs b/src/Avalonia.Base/Rendering/IRenderTimer.cs index 07af7eeec8..14fcffd6a9 100644 --- a/src/Avalonia.Base/Rendering/IRenderTimer.cs +++ b/src/Avalonia.Base/Rendering/IRenderTimer.cs @@ -1,5 +1,4 @@ using System; -using System.Threading.Tasks; using Avalonia.Metadata; namespace Avalonia.Rendering diff --git a/src/Avalonia.Base/StyledElement.cs b/src/Avalonia.Base/StyledElement.cs index 5bf022cd51..2cdb973174 100644 --- a/src/Avalonia.Base/StyledElement.cs +++ b/src/Avalonia.Base/StyledElement.cs @@ -41,7 +41,11 @@ namespace Avalonia public static readonly StyledProperty DataContextProperty = AvaloniaProperty.Register( nameof(DataContext), + defaultValue: null, inherits: true, + defaultBindingMode: BindingMode.OneWay, + validate: null, + coerce: null, notifying: DataContextNotifying); /// diff --git a/src/Avalonia.Controls/ItemsControl.cs b/src/Avalonia.Controls/ItemsControl.cs index 2f02a48d55..ce12d5f2bf 100644 --- a/src/Avalonia.Controls/ItemsControl.cs +++ b/src/Avalonia.Controls/ItemsControl.cs @@ -559,7 +559,12 @@ namespace Avalonia.Controls return new ItemContainerGenerator(this); } - internal void AddLogicalChild(Control c) => LogicalChildren.Add(c); + internal void AddLogicalChild(Control c) + { + if (!LogicalChildren.Contains(c)) + LogicalChildren.Add(c); + } + internal void RemoveLogicalChild(Control c) => LogicalChildren.Remove(c); /// diff --git a/src/Avalonia.Controls/Platform/IPlatformLifetimeEventsImpl.cs b/src/Avalonia.Controls/Platform/IPlatformLifetimeEventsImpl.cs index 0658f9211c..d609dd94c8 100644 --- a/src/Avalonia.Controls/Platform/IPlatformLifetimeEventsImpl.cs +++ b/src/Avalonia.Controls/Platform/IPlatformLifetimeEventsImpl.cs @@ -13,6 +13,6 @@ namespace Avalonia.Platform /// /// Raised on on OSX via the Quit menu or right-clicking on the application icon and selecting Quit. /// - event EventHandler ShutdownRequested; + event EventHandler? ShutdownRequested; } } diff --git a/src/Avalonia.Controls/Platform/IWindowImpl.cs b/src/Avalonia.Controls/Platform/IWindowImpl.cs index 8d9d8e0e7b..31b144ce00 100644 --- a/src/Avalonia.Controls/Platform/IWindowImpl.cs +++ b/src/Avalonia.Controls/Platform/IWindowImpl.cs @@ -19,7 +19,7 @@ namespace Avalonia.Platform /// /// Gets or sets a method called when the minimized/maximized state of the window changes. /// - Action WindowStateChanged { get; set; } + Action? WindowStateChanged { get; set; } /// /// Sets the title of the window. @@ -42,7 +42,7 @@ namespace Avalonia.Platform /// /// Called when a disabled window received input. Can be used to activate child windows. /// - Action GotInputWhenDisabled { get; set; } + Action? GotInputWhenDisabled { get; set; } /// /// Enables or disables system window decorations (title bar, buttons, etc) @@ -68,7 +68,7 @@ namespace Avalonia.Platform /// Gets or sets a method called before the underlying implementation is destroyed. /// Return true to prevent the underlying implementation from closing. /// - Func Closing { get; set; } + Func? Closing { get; set; } /// /// Gets a value to indicate if the platform was able to extend client area to non-client area. @@ -78,7 +78,7 @@ namespace Avalonia.Platform /// /// Gets or Sets an action that is called whenever one of the extend client area properties changed. /// - Action ExtendClientAreaToDecorationsChanged { get; set; } + Action? ExtendClientAreaToDecorationsChanged { get; set; } /// /// Gets a flag that indicates if Managed decorations i.e. caption buttons are required. diff --git a/src/Avalonia.Controls/WindowBase.cs b/src/Avalonia.Controls/WindowBase.cs index 0c9a91148b..26e11f0d4a 100644 --- a/src/Avalonia.Controls/WindowBase.cs +++ b/src/Avalonia.Controls/WindowBase.cs @@ -94,7 +94,7 @@ namespace Avalonia.Controls private set { SetAndRaise(IsActiveProperty, ref _isActive, value); } } - public Screens Screens { get; private set; } + public Screens Screens { get; } /// /// Gets or sets the owner of the window. diff --git a/src/Avalonia.FreeDesktop/DBusHelper.cs b/src/Avalonia.FreeDesktop/DBusHelper.cs index ef99838208..fac77521dc 100644 --- a/src/Avalonia.FreeDesktop/DBusHelper.cs +++ b/src/Avalonia.FreeDesktop/DBusHelper.cs @@ -6,7 +6,7 @@ using Tmds.DBus; namespace Avalonia.FreeDesktop { - public static class DBusHelper + internal static class DBusHelper { /// /// This class uses synchronous execution at DBus connection establishment stage diff --git a/src/Avalonia.FreeDesktop/DBusIme/X11DBusImeHelper.cs b/src/Avalonia.FreeDesktop/DBusIme/X11DBusImeHelper.cs index 86978c8b60..d8874b6fae 100644 --- a/src/Avalonia.FreeDesktop/DBusIme/X11DBusImeHelper.cs +++ b/src/Avalonia.FreeDesktop/DBusIme/X11DBusImeHelper.cs @@ -6,7 +6,7 @@ using Tmds.DBus; namespace Avalonia.FreeDesktop.DBusIme { - public class X11DBusImeHelper + internal class X11DBusImeHelper { private static readonly Dictionary> KnownMethods = new Dictionary> diff --git a/src/Avalonia.FreeDesktop/DBusMenuExporter.cs b/src/Avalonia.FreeDesktop/DBusMenuExporter.cs index 0e6bee5f24..cfbafc53e5 100644 --- a/src/Avalonia.FreeDesktop/DBusMenuExporter.cs +++ b/src/Avalonia.FreeDesktop/DBusMenuExporter.cs @@ -15,7 +15,7 @@ using Tmds.DBus; namespace Avalonia.FreeDesktop { - public class DBusMenuExporter + internal class DBusMenuExporter { public static ITopLevelNativeMenuExporter? TryCreateTopLevelNativeMenu(IntPtr xid) { diff --git a/src/Avalonia.FreeDesktop/IX11InputMethod.cs b/src/Avalonia.FreeDesktop/IX11InputMethod.cs index 9fa9c1809e..7274b58876 100644 --- a/src/Avalonia.FreeDesktop/IX11InputMethod.cs +++ b/src/Avalonia.FreeDesktop/IX11InputMethod.cs @@ -6,13 +6,13 @@ using Avalonia.Input.TextInput; namespace Avalonia.FreeDesktop { - public interface IX11InputMethodFactory + internal interface IX11InputMethodFactory { (ITextInputMethodImpl method, IX11InputMethodControl control) CreateClient(IntPtr xid); } #pragma warning disable CA1815 // Override equals and operator equals on value types - public struct X11InputMethodForwardedKey + internal struct X11InputMethodForwardedKey #pragma warning restore CA1815 // Override equals and operator equals on value types { public int KeyVal { get; set; } @@ -20,7 +20,7 @@ namespace Avalonia.FreeDesktop public RawKeyEventType Type { get; set; } } - public interface IX11InputMethodControl : IDisposable + internal interface IX11InputMethodControl : IDisposable { void SetWindowActive(bool active); bool IsEnabled { get; } diff --git a/src/Avalonia.FreeDesktop/LinuxMountedVolumeInfoProvider.cs b/src/Avalonia.FreeDesktop/LinuxMountedVolumeInfoProvider.cs index 4624a9c340..4aa6bed329 100644 --- a/src/Avalonia.FreeDesktop/LinuxMountedVolumeInfoProvider.cs +++ b/src/Avalonia.FreeDesktop/LinuxMountedVolumeInfoProvider.cs @@ -5,7 +5,7 @@ using Avalonia.Controls.Platform; namespace Avalonia.FreeDesktop { - public class LinuxMountedVolumeInfoProvider : IMountedVolumeInfoProvider + internal class LinuxMountedVolumeInfoProvider : IMountedVolumeInfoProvider { public IDisposable Listen(ObservableCollection mountedDrives) { diff --git a/src/Avalonia.Native/CallbackBase.cs b/src/Avalonia.Native/CallbackBase.cs index 2d875dbc0e..9f59c97f9b 100644 --- a/src/Avalonia.Native/CallbackBase.cs +++ b/src/Avalonia.Native/CallbackBase.cs @@ -6,7 +6,7 @@ using MicroCom.Runtime; namespace Avalonia.Native { - public abstract class NativeCallbackBase : CallbackBase, IMicroComExceptionCallback + internal abstract class NativeCallbackBase : CallbackBase, IMicroComExceptionCallback { public void RaiseException(Exception e) { diff --git a/src/Avalonia.Native/MacOSMountedVolumeInfoProvider.cs b/src/Avalonia.Native/MacOSMountedVolumeInfoProvider.cs index e79c7a40d3..1170a6fd9b 100644 --- a/src/Avalonia.Native/MacOSMountedVolumeInfoProvider.cs +++ b/src/Avalonia.Native/MacOSMountedVolumeInfoProvider.cs @@ -64,7 +64,7 @@ namespace Avalonia.Native } } - public class MacOSMountedVolumeInfoProvider : IMountedVolumeInfoProvider + internal class MacOSMountedVolumeInfoProvider : IMountedVolumeInfoProvider { public IDisposable Listen(ObservableCollection mountedDrives) { diff --git a/src/Avalonia.Native/MenuActionCallback.cs b/src/Avalonia.Native/MenuActionCallback.cs index 3acbb9c19c..e9446e2da1 100644 --- a/src/Avalonia.Native/MenuActionCallback.cs +++ b/src/Avalonia.Native/MenuActionCallback.cs @@ -3,7 +3,7 @@ using Avalonia.Native.Interop; namespace Avalonia.Native { - public class MenuActionCallback : NativeCallbackBase, IAvnActionCallback + internal class MenuActionCallback : NativeCallbackBase, IAvnActionCallback { private Action _action; diff --git a/src/Avalonia.Native/PredicateCallback.cs b/src/Avalonia.Native/PredicateCallback.cs index dbb65791f0..1ff71063af 100644 --- a/src/Avalonia.Native/PredicateCallback.cs +++ b/src/Avalonia.Native/PredicateCallback.cs @@ -3,7 +3,7 @@ using Avalonia.Native.Interop; namespace Avalonia.Native { - public class PredicateCallback : NativeCallbackBase, IAvnPredicateCallback + internal class PredicateCallback : NativeCallbackBase, IAvnPredicateCallback { private Func _predicate; diff --git a/src/Avalonia.Native/ScreenImpl.cs b/src/Avalonia.Native/ScreenImpl.cs index 53bd12cde1..c64d1378e8 100644 --- a/src/Avalonia.Native/ScreenImpl.cs +++ b/src/Avalonia.Native/ScreenImpl.cs @@ -5,7 +5,7 @@ using Avalonia.Platform; namespace Avalonia.Native { - class ScreenImpl : IScreenImpl, IDisposable + internal class ScreenImpl : IScreenImpl, IDisposable { private IAvnScreens _native; diff --git a/src/Avalonia.X11/Glx/Glx.cs b/src/Avalonia.X11/Glx/Glx.cs index 1a26d7d5f5..fceea3718c 100644 --- a/src/Avalonia.X11/Glx/Glx.cs +++ b/src/Avalonia.X11/Glx/Glx.cs @@ -10,7 +10,7 @@ using Avalonia.SourceGenerator; namespace Avalonia.X11.Glx { - unsafe partial class GlxInterface + internal unsafe partial class GlxInterface { private const string libGL = "libGL.so.1"; [GetProcAddress("glXMakeContextCurrent")] diff --git a/src/Avalonia.X11/Glx/GlxConsts.cs b/src/Avalonia.X11/Glx/GlxConsts.cs index 9d153a6ade..0d1383420d 100644 --- a/src/Avalonia.X11/Glx/GlxConsts.cs +++ b/src/Avalonia.X11/Glx/GlxConsts.cs @@ -4,7 +4,7 @@ #pragma warning disable 414 namespace Avalonia.X11.Glx { - class GlxConsts + internal class GlxConsts { public const int GLX_USE_GL = 1; public const int GLX_BUFFER_SIZE = 2; diff --git a/src/Avalonia.X11/Glx/GlxContext.cs b/src/Avalonia.X11/Glx/GlxContext.cs index 572e4a6077..b1cb330b00 100644 --- a/src/Avalonia.X11/Glx/GlxContext.cs +++ b/src/Avalonia.X11/Glx/GlxContext.cs @@ -7,7 +7,7 @@ using Avalonia.Reactive; namespace Avalonia.X11.Glx { - class GlxContext : IGlContext + internal class GlxContext : IGlContext { public IntPtr Handle { get; } public GlxInterface Glx { get; } @@ -46,8 +46,8 @@ namespace Avalonia.X11.Glx public GlInterface GlInterface { get; } public int SampleCount { get; } public int StencilSize { get; } - - class RestoreContext : IDisposable + + private class RestoreContext : IDisposable { private GlxInterface _glx; private IntPtr _defaultDisplay; diff --git a/src/Avalonia.X11/Glx/GlxDisplay.cs b/src/Avalonia.X11/Glx/GlxDisplay.cs index 9b8a8f0b5b..7749749eaa 100644 --- a/src/Avalonia.X11/Glx/GlxDisplay.cs +++ b/src/Avalonia.X11/Glx/GlxDisplay.cs @@ -6,7 +6,7 @@ using static Avalonia.X11.Glx.GlxConsts; namespace Avalonia.X11.Glx { - unsafe class GlxDisplay + internal unsafe class GlxDisplay { private readonly X11Info _x11; private readonly GlVersion[] _probeProfiles; @@ -106,7 +106,7 @@ namespace Avalonia.X11.Glx } } - IntPtr CreatePBuffer() + private IntPtr CreatePBuffer() { return Glx.CreatePbuffer(_x11.Display, _fbconfig, new[] { GLX_PBUFFER_WIDTH, 1, GLX_PBUFFER_HEIGHT, 1, 0 }); } @@ -116,8 +116,8 @@ namespace Avalonia.X11.Glx public GlxContext CreateContext(IGlContext share) => CreateContext(CreatePBuffer(), share, share.SampleCount, share.StencilSize, true); - - GlxContext CreateContext(IntPtr defaultXid, IGlContext share, + + private GlxContext CreateContext(IntPtr defaultXid, IGlContext share, int sampleCount, int stencilSize, bool ownsPBuffer) { var sharelist = ((GlxContext)share)?.Handle ?? IntPtr.Zero; diff --git a/src/Avalonia.X11/Glx/GlxGlPlatformSurface.cs b/src/Avalonia.X11/Glx/GlxGlPlatformSurface.cs index ebb1e18723..17c5909a39 100644 --- a/src/Avalonia.X11/Glx/GlxGlPlatformSurface.cs +++ b/src/Avalonia.X11/Glx/GlxGlPlatformSurface.cs @@ -6,7 +6,7 @@ using static Avalonia.OpenGL.GlConsts; namespace Avalonia.X11.Glx { - class GlxGlPlatformSurface: IGlPlatformSurface + internal class GlxGlPlatformSurface: IGlPlatformSurface { private readonly EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo _info; @@ -21,7 +21,7 @@ namespace Avalonia.X11.Glx return new RenderTarget((GlxContext)context, _info); } - class RenderTarget : IGlPlatformSurfaceRenderTarget + private class RenderTarget : IGlPlatformSurfaceRenderTarget { private readonly GlxContext _context; private readonly EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo _info; @@ -46,8 +46,8 @@ namespace Avalonia.X11.Glx return new Session(_context, _info, oldContext); } - - class Session : IGlPlatformSurfaceRenderingSession + + private class Session : IGlPlatformSurfaceRenderingSession { private readonly GlxContext _context; private readonly EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo _info; diff --git a/src/Avalonia.X11/Glx/GlxPlatformFeature.cs b/src/Avalonia.X11/Glx/GlxPlatformFeature.cs index bc50fa61aa..06766e0963 100644 --- a/src/Avalonia.X11/Glx/GlxPlatformFeature.cs +++ b/src/Avalonia.X11/Glx/GlxPlatformFeature.cs @@ -6,7 +6,7 @@ using Avalonia.Platform; namespace Avalonia.X11.Glx { - class GlxPlatformGraphics : IPlatformGraphics + internal class GlxPlatformGraphics : IPlatformGraphics { public GlxDisplay Display { get; private set; } public bool CanCreateContexts => true; diff --git a/src/Avalonia.X11/Keysyms.cs b/src/Avalonia.X11/Keysyms.cs index 651a06f574..970cf5ad4d 100644 --- a/src/Avalonia.X11/Keysyms.cs +++ b/src/Avalonia.X11/Keysyms.cs @@ -3,7 +3,7 @@ // ReSharper disable CommentTypo namespace Avalonia.X11 { - enum X11Key + internal enum X11Key { VoidSymbol = 0xffffff /* Void symbol */, BackSpace = 0xff08 /* Back space, back char */, diff --git a/src/Avalonia.X11/NativeDialogs/Gtk.cs b/src/Avalonia.X11/NativeDialogs/Gtk.cs index 4e56ae73cf..3f225dc6bc 100644 --- a/src/Avalonia.X11/NativeDialogs/Gtk.cs +++ b/src/Avalonia.X11/NativeDialogs/Gtk.cs @@ -7,8 +7,7 @@ using Avalonia.Platform.Interop; // ReSharper disable IdentifierTypo namespace Avalonia.X11.NativeDialogs { - - static unsafe class Glib + internal static unsafe class Glib { private const string GlibName = "libglib-2.0.so.0"; private const string GObjectName = "libgobject-2.0.so.0"; @@ -36,7 +35,7 @@ namespace Avalonia.X11.NativeDialogs IntPtr destroy); - class ConnectedSignal : IDisposable + private class ConnectedSignal : IDisposable { private readonly IntPtr _instance; private GCHandle _handle; @@ -75,7 +74,7 @@ namespace Avalonia.X11.NativeDialogs } - static bool TimeoutHandler(IntPtr data) + private static bool TimeoutHandler(IntPtr data) { var handle = GCHandle.FromIntPtr(data); var cb = (Func)handle.Target; @@ -95,7 +94,7 @@ namespace Avalonia.X11.NativeDialogs s_pinnedHandler = TimeoutHandler; } - static void AddTimeout(int priority, uint interval, Func callback) + private static void AddTimeout(int priority, uint interval, Func callback) { var handle = GCHandle.Alloc(callback); g_timeout_add_full(priority, interval, s_pinnedHandler, GCHandle.ToIntPtr(handle), IntPtr.Zero); @@ -123,13 +122,13 @@ namespace Avalonia.X11.NativeDialogs } [StructLayout(LayoutKind.Sequential)] - unsafe struct GSList + internal unsafe struct GSList { public readonly IntPtr Data; public readonly GSList* Next; } - enum GtkFileChooserAction + internal enum GtkFileChooserAction { Open, Save, @@ -137,7 +136,7 @@ namespace Avalonia.X11.NativeDialogs } // ReSharper disable UnusedMember.Global - enum GtkResponseType + internal enum GtkResponseType { Help = -11, Apply = -10, @@ -153,14 +152,14 @@ namespace Avalonia.X11.NativeDialogs } // ReSharper restore UnusedMember.Global - static unsafe class Gtk + internal static unsafe class Gtk { private static IntPtr s_display; private const string GdkName = "libgdk-3.so.0"; private const string GtkName = "libgtk-3.so.0"; [DllImport(GtkName)] - static extern void gtk_main_iteration(); + private static extern void gtk_main_iteration(); [DllImport(GtkName)] @@ -231,10 +230,10 @@ namespace Avalonia.X11.NativeDialogs public static extern void gtk_widget_hide(IntPtr gtkWidget); [DllImport(GtkName)] - static extern bool gtk_init_check(int argc, IntPtr argv); + private static extern bool gtk_init_check(int argc, IntPtr argv); [DllImport(GdkName)] - static extern IntPtr gdk_x11_window_foreign_new_for_display(IntPtr display, IntPtr xid); + private static extern IntPtr gdk_x11_window_foreign_new_for_display(IntPtr display, IntPtr xid); [DllImport(GdkName)] public static extern IntPtr gdk_x11_window_get_xid(IntPtr window); @@ -244,13 +243,13 @@ namespace Avalonia.X11.NativeDialogs public static extern IntPtr gtk_container_add(IntPtr container, IntPtr widget); [DllImport(GdkName)] - static extern IntPtr gdk_set_allowed_backends(Utf8Buffer backends); + private static extern IntPtr gdk_set_allowed_backends(Utf8Buffer backends); [DllImport(GdkName)] - static extern IntPtr gdk_display_get_default(); + private static extern IntPtr gdk_display_get_default(); [DllImport(GtkName)] - static extern IntPtr gtk_application_new(Utf8Buffer appId, int flags); + private static extern IntPtr gtk_application_new(Utf8Buffer appId, int flags); [DllImport(GdkName)] public static extern void gdk_window_set_transient_for(IntPtr window, IntPtr parent); diff --git a/src/Avalonia.X11/TransparencyHelper.cs b/src/Avalonia.X11/TransparencyHelper.cs index 2140b61b6f..5ca2d1d337 100644 --- a/src/Avalonia.X11/TransparencyHelper.cs +++ b/src/Avalonia.X11/TransparencyHelper.cs @@ -3,7 +3,7 @@ using Avalonia.Controls; namespace Avalonia.X11 { - class TransparencyHelper : IDisposable, X11Globals.IGlobalsSubscriber + internal class TransparencyHelper : IDisposable, X11Globals.IGlobalsSubscriber { private readonly X11Info _x11; private readonly IntPtr _window; diff --git a/src/Avalonia.X11/X11Clipboard.cs b/src/Avalonia.X11/X11Clipboard.cs index 2aa7797067..04d1aae194 100644 --- a/src/Avalonia.X11/X11Clipboard.cs +++ b/src/Avalonia.X11/X11Clipboard.cs @@ -9,7 +9,7 @@ using Avalonia.Input.Platform; using static Avalonia.X11.XLib; namespace Avalonia.X11 { - class X11Clipboard : IClipboard + internal class X11Clipboard : IClipboard { private readonly X11Info _x11; private IDataObject _storedDataObject; @@ -33,12 +33,12 @@ namespace Avalonia.X11 }.Where(a => a != IntPtr.Zero).ToArray(); } - bool IsStringAtom(IntPtr atom) + private bool IsStringAtom(IntPtr atom) { return _textAtoms.Contains(atom); } - - Encoding GetStringEncoding(IntPtr atom) + + private Encoding GetStringEncoding(IntPtr atom) { return (atom == _x11.Atoms.XA_STRING || atom == _x11.Atoms.OEMTEXT) @@ -213,7 +213,7 @@ namespace Avalonia.X11 } } - Task SendFormatRequest() + private Task SendFormatRequest() { if (_requestedFormatsTcs == null || _requestedFormatsTcs.Task.IsCompleted) _requestedFormatsTcs = new TaskCompletionSource(); @@ -222,7 +222,7 @@ namespace Avalonia.X11 return _requestedFormatsTcs.Task; } - Task SendDataRequest(IntPtr format) + private Task SendDataRequest(IntPtr format) { if (_requestedDataTcs == null || _requestedFormatsTcs.Task.IsCompleted) _requestedDataTcs = new TaskCompletionSource(); @@ -230,7 +230,7 @@ namespace Avalonia.X11 return _requestedDataTcs.Task; } - bool HasOwner => XGetSelectionOwner(_x11.Display, _x11.Atoms.CLIPBOARD) != IntPtr.Zero; + private bool HasOwner => XGetSelectionOwner(_x11.Display, _x11.Atoms.CLIPBOARD) != IntPtr.Zero; public async Task GetTextAsync() { @@ -252,7 +252,7 @@ namespace Avalonia.X11 return (string)await SendDataRequest(target); } - void StoreAtomsInClipboardManager(IntPtr[] atoms) + private void StoreAtomsInClipboardManager(IntPtr[] atoms) { if (_x11.Atoms.CLIPBOARD_MANAGER != IntPtr.Zero && _x11.Atoms.SAVE_TARGETS != IntPtr.Zero) { diff --git a/src/Avalonia.X11/X11CursorFactory.cs b/src/Avalonia.X11/X11CursorFactory.cs index 16de10e163..56fd2f14ef 100644 --- a/src/Avalonia.X11/X11CursorFactory.cs +++ b/src/Avalonia.X11/X11CursorFactory.cs @@ -12,7 +12,7 @@ using Avalonia.Utilities; namespace Avalonia.X11 { - partial class X11CursorFactory : ICursorFactory + internal partial class X11CursorFactory : ICursorFactory { private static readonly byte[] NullCursorData = new byte[] { 0 }; @@ -142,7 +142,7 @@ namespace Avalonia.X11 } } - class CursorImpl : ICursorImpl + internal class CursorImpl : ICursorImpl { public CursorImpl() { } public CursorImpl(IntPtr handle) => Handle = handle; diff --git a/src/Avalonia.X11/X11Enums.cs b/src/Avalonia.X11/X11Enums.cs index d97e1c42bb..9d671ae6d2 100644 --- a/src/Avalonia.X11/X11Enums.cs +++ b/src/Avalonia.X11/X11Enums.cs @@ -3,7 +3,7 @@ using System; namespace Avalonia.X11 { - public enum Status + internal enum Status { Success = 0, /* everything's okay */ BadRequest = 1, /* bad request code */ @@ -38,7 +38,7 @@ namespace Avalonia.X11 } [Flags] - public enum XEventMask : int + internal enum XEventMask : int { NoEventMask = 0, KeyPressMask = (1 << 0), @@ -69,7 +69,7 @@ namespace Avalonia.X11 } [Flags] - public enum XModifierMask + internal enum XModifierMask { ShiftMask = (1 << 0), LockMask = (1 << 1), @@ -89,7 +89,7 @@ namespace Avalonia.X11 } [Flags] - public enum XCreateWindowFlags + internal enum XCreateWindowFlags { CWBackPixmap = (1 << 0), CWBackPixel = (1 << 1), diff --git a/src/Avalonia.X11/X11Exception.cs b/src/Avalonia.X11/X11Exception.cs index 2ac5a31d9b..231ece497b 100644 --- a/src/Avalonia.X11/X11Exception.cs +++ b/src/Avalonia.X11/X11Exception.cs @@ -2,7 +2,7 @@ using System; namespace Avalonia.X11 { - public class X11Exception : Exception + internal class X11Exception : Exception { public X11Exception(string message) : base(message) { diff --git a/src/Avalonia.X11/X11Framebuffer.cs b/src/Avalonia.X11/X11Framebuffer.cs index a9fedff8b5..90e4b18571 100644 --- a/src/Avalonia.X11/X11Framebuffer.cs +++ b/src/Avalonia.X11/X11Framebuffer.cs @@ -5,7 +5,7 @@ using SkiaSharp; using static Avalonia.X11.XLib; namespace Avalonia.X11 { - class X11Framebuffer : ILockedFramebuffer + internal class X11Framebuffer : ILockedFramebuffer { private readonly IntPtr _display; private readonly IntPtr _xid; diff --git a/src/Avalonia.X11/X11FramebufferSurface.cs b/src/Avalonia.X11/X11FramebufferSurface.cs index 07c88b51a8..05885d1a25 100644 --- a/src/Avalonia.X11/X11FramebufferSurface.cs +++ b/src/Avalonia.X11/X11FramebufferSurface.cs @@ -4,7 +4,7 @@ using Avalonia.Platform; using static Avalonia.X11.XLib; namespace Avalonia.X11 { - public class X11FramebufferSurface : IFramebufferPlatformSurface + internal class X11FramebufferSurface : IFramebufferPlatformSurface { private readonly IntPtr _display; private readonly IntPtr _xid; diff --git a/src/Avalonia.X11/X11Globals.cs b/src/Avalonia.X11/X11Globals.cs index 39834a44b3..1ae0544724 100644 --- a/src/Avalonia.X11/X11Globals.cs +++ b/src/Avalonia.X11/X11Globals.cs @@ -5,7 +5,7 @@ using System.Runtime.InteropServices; using static Avalonia.X11.XLib; namespace Avalonia.X11 { - unsafe class X11Globals + internal unsafe class X11Globals { private readonly AvaloniaX11Platform _plat; private readonly int _screenNumber; @@ -75,7 +75,7 @@ namespace Avalonia.X11 } } - IntPtr GetSupportingWmCheck(IntPtr window) + private IntPtr GetSupportingWmCheck(IntPtr window) { XGetWindowProperty(_x11.Display, _rootWindow, _x11.Atoms._NET_SUPPORTING_WM_CHECK, IntPtr.Zero, new IntPtr(IntPtr.Size), false, @@ -95,7 +95,7 @@ namespace Avalonia.X11 } } - void UpdateCompositingAtomOwner() + private void UpdateCompositingAtomOwner() { // This procedure is described in https://tronche.com/gui/x/icccm/sec-2.html#s-2.8 @@ -128,10 +128,10 @@ namespace Avalonia.X11 if(ev.type == XEventName.DestroyNotify) UpdateCompositingAtomOwner(); } - - void UpdateWmName() => WmName = GetWmName(); - string GetWmName() + private void UpdateWmName() => WmName = GetWmName(); + + private string GetWmName() { var wm = GetSupportingWmCheck(_rootWindow); if (wm == IntPtr.Zero || wm != GetSupportingWmCheck(wm)) diff --git a/src/Avalonia.X11/X11IconLoader.cs b/src/Avalonia.X11/X11IconLoader.cs index bf59d72c0f..51db815b31 100644 --- a/src/Avalonia.X11/X11IconLoader.cs +++ b/src/Avalonia.X11/X11IconLoader.cs @@ -7,9 +7,9 @@ using Avalonia.Platform; namespace Avalonia.X11 { - class X11IconLoader : IPlatformIconLoader + internal class X11IconLoader : IPlatformIconLoader { - static IWindowIconImpl LoadIcon(Bitmap bitmap) + private static IWindowIconImpl LoadIcon(Bitmap bitmap) { var rv = new X11IconData(bitmap); bitmap.Dispose(); @@ -28,8 +28,8 @@ namespace Avalonia.X11 return LoadIcon(ms); } } - - unsafe class X11IconData : IWindowIconImpl, IFramebufferPlatformSurface + + internal unsafe class X11IconData : IWindowIconImpl, IFramebufferPlatformSurface { private int _width; private int _height; diff --git a/src/Avalonia.X11/X11Info.cs b/src/Avalonia.X11/X11Info.cs index 72f3bf3137..17cd6b12c6 100644 --- a/src/Avalonia.X11/X11Info.cs +++ b/src/Avalonia.X11/X11Info.cs @@ -6,7 +6,7 @@ using static Avalonia.X11.XLib; // ReSharper disable UnusedAutoPropertyAccessor.Local namespace Avalonia.X11 { - unsafe class X11Info + internal unsafe class X11Info { public IntPtr Display { get; } public IntPtr DeferredDisplay { get; } diff --git a/src/Avalonia.X11/X11KeyTransform.cs b/src/Avalonia.X11/X11KeyTransform.cs index 59f1da564c..6732a0f448 100644 --- a/src/Avalonia.X11/X11KeyTransform.cs +++ b/src/Avalonia.X11/X11KeyTransform.cs @@ -4,7 +4,7 @@ using Avalonia.Input; namespace Avalonia.X11 { - static class X11KeyTransform + internal static class X11KeyTransform { private static readonly Dictionary KeyDic = new Dictionary { diff --git a/src/Avalonia.X11/X11NativeControlHost.cs b/src/Avalonia.X11/X11NativeControlHost.cs index 6c4eb81c84..e8710580eb 100644 --- a/src/Avalonia.X11/X11NativeControlHost.cs +++ b/src/Avalonia.X11/X11NativeControlHost.cs @@ -6,7 +6,7 @@ using static Avalonia.X11.XLib; namespace Avalonia.X11 { // TODO: Actually implement XEmbed instead of simply using XReparentWindow - class X11NativeControlHost : INativeControlHostImpl + internal class X11NativeControlHost : INativeControlHostImpl { private readonly AvaloniaX11Platform _platform; public X11Window Window { get; } @@ -57,7 +57,7 @@ namespace Avalonia.X11 public bool IsCompatibleWith(IPlatformHandle handle) => handle.HandleDescriptor == "XID"; - class DumbWindow : INativeControlHostDestroyableControlHandle + private class DumbWindow : INativeControlHostDestroyableControlHandle { private readonly IntPtr _display; @@ -96,8 +96,8 @@ namespace Avalonia.X11 } } } - - class Attachment : INativeControlHostControlTopLevelAttachment + + private class Attachment : INativeControlHostControlTopLevelAttachment { private readonly IntPtr _display; private readonly IntPtr _orphanedWindow; @@ -129,7 +129,7 @@ namespace Avalonia.X11 _attachedTo = null; } - void CheckDisposed() + private void CheckDisposed() { if (_child == null) throw new ObjectDisposedException("X11 INativeControlHostControlTopLevelAttachment"); diff --git a/src/Avalonia.X11/X11Platform.cs b/src/Avalonia.X11/X11Platform.cs index c5ae327c2f..170c6ce6b3 100644 --- a/src/Avalonia.X11/X11Platform.cs +++ b/src/Avalonia.X11/X11Platform.cs @@ -20,7 +20,7 @@ using static Avalonia.X11.XLib; namespace Avalonia.X11 { - class AvaloniaX11Platform : IWindowingPlatform + internal class AvaloniaX11Platform : IWindowingPlatform { private Lazy _keyboardDevice = new Lazy(() => new KeyboardDevice()); public KeyboardDevice KeyboardDevice => _keyboardDevice.Value; @@ -35,7 +35,7 @@ namespace Avalonia.X11 public IntPtr OrphanedWindow { get; private set; } public X11Globals Globals { get; private set; } [DllImport("libc")] - static extern void setlocale(int type, string s); + private static extern void setlocale(int type, string s); public void Initialize(X11PlatformOptions options) { Options = options; @@ -138,7 +138,7 @@ namespace Avalonia.X11 throw new NotSupportedException(); } - static bool EnableIme(X11PlatformOptions options) + private static bool EnableIme(X11PlatformOptions options) { // Disable if explicitly asked by user var avaloniaImModule = Environment.GetEnvironmentVariable("AVALONIA_IM_MODULE"); @@ -160,7 +160,7 @@ namespace Avalonia.X11 return isCjkLocale; } - static bool ShouldUseXim() + private static bool ShouldUseXim() { // Check if we are forbidden from using IME if (Environment.GetEnvironmentVariable("AVALONIA_IM_MODULE") == "none" diff --git a/src/Avalonia.X11/X11PlatformThreading.cs b/src/Avalonia.X11/X11PlatformThreading.cs index d724cd2aed..1946642de3 100644 --- a/src/Avalonia.X11/X11PlatformThreading.cs +++ b/src/Avalonia.X11/X11PlatformThreading.cs @@ -9,7 +9,7 @@ using static Avalonia.X11.XLib; namespace Avalonia.X11 { - unsafe class X11PlatformThreading : IPlatformThreadingInterface + internal unsafe class X11PlatformThreading : IPlatformThreadingInterface { private readonly AvaloniaX11Platform _platform; private readonly IntPtr _display; @@ -19,7 +19,7 @@ namespace Avalonia.X11 private Thread _mainThread; [StructLayout(LayoutKind.Explicit)] - struct epoll_data + private struct epoll_data { [FieldOffset(0)] public IntPtr ptr; @@ -36,30 +36,30 @@ namespace Avalonia.X11 private const int O_NONBLOCK = 2048; [StructLayout(LayoutKind.Sequential)] - struct epoll_event + private struct epoll_event { public uint events; public epoll_data data; } [DllImport("libc")] - extern static int epoll_create1(int size); + private extern static int epoll_create1(int size); [DllImport("libc")] - extern static int epoll_ctl(int epfd, int op, int fd, ref epoll_event __event); + private extern static int epoll_ctl(int epfd, int op, int fd, ref epoll_event __event); [DllImport("libc")] - extern static int epoll_wait(int epfd, epoll_event* events, int maxevents, int timeout); + private extern static int epoll_wait(int epfd, epoll_event* events, int maxevents, int timeout); [DllImport("libc")] - extern static int pipe2(int* fds, int flags); + private extern static int pipe2(int* fds, int flags); [DllImport("libc")] - extern static IntPtr write(int fd, void* buf, IntPtr count); + private extern static IntPtr write(int fd, void* buf, IntPtr count); [DllImport("libc")] - extern static IntPtr read(int fd, void* buf, IntPtr count); - - enum EventCodes + private extern static IntPtr read(int fd, void* buf, IntPtr count); + + private enum EventCodes { X11 = 1, Signal =2 @@ -72,7 +72,7 @@ namespace Avalonia.X11 private int _epoll; private Stopwatch _clock = Stopwatch.StartNew(); - class X11Timer : IDisposable + private class X11Timer : IDisposable { private readonly X11PlatformThreading _parent; @@ -104,7 +104,7 @@ namespace Avalonia.X11 } } - List _timers = new List(); + private List _timers = new List(); public X11PlatformThreading(AvaloniaX11Platform platform) { @@ -139,12 +139,12 @@ namespace Avalonia.X11 throw new X11Exception("Unable to attach signal pipe to epoll"); } - int TimerComparer(X11Timer t1, X11Timer t2) + private int TimerComparer(X11Timer t1, X11Timer t2) { return t2.Priority - t1.Priority; } - void CheckSignaled() + private void CheckSignaled() { int buf = 0; while (read(_sigread, &buf, new IntPtr(4)).ToInt64() > 0) @@ -164,7 +164,7 @@ namespace Avalonia.X11 Signaled?.Invoke(prio); } - unsafe void HandleX11(CancellationToken cancellationToken) + private unsafe void HandleX11(CancellationToken cancellationToken) { while (XPending(_display) != 0) { diff --git a/src/Avalonia.X11/X11Screens.cs b/src/Avalonia.X11/X11Screens.cs index 87899b11ed..6c7283952d 100644 --- a/src/Avalonia.X11/X11Screens.cs +++ b/src/Avalonia.X11/X11Screens.cs @@ -8,7 +8,7 @@ using static Avalonia.X11.XLib; namespace Avalonia.X11 { - class X11Screens : IScreenImpl + internal class X11Screens : IScreenImpl { private IX11Screens _impl; @@ -17,7 +17,7 @@ namespace Avalonia.X11 _impl = impl; } - static unsafe X11Screen[] UpdateWorkArea(X11Info info, X11Screen[] screens) + private static unsafe X11Screen[] UpdateWorkArea(X11Info info, X11Screen[] screens) { var rect = default(PixelRect); foreach (var s in screens) @@ -58,14 +58,14 @@ namespace Avalonia.X11 XFree(prop); return screens; } - - class Randr15ScreensImpl : IX11Screens + + private class Randr15ScreensImpl : IX11Screens { private readonly X11ScreensUserSettings _settings; private X11Screen[] _cache; private X11Info _x11; private IntPtr _window; - const int EDIDStructureLength = 32; // Length of a EDID-Block-Length(128 bytes), XRRGetOutputProperty multiplies offset and length by 4 + private const int EDIDStructureLength = 32; // Length of a EDID-Block-Length(128 bytes), XRRGetOutputProperty multiplies offset and length by 4 public Randr15ScreensImpl(AvaloniaX11Platform platform, X11ScreensUserSettings settings) { @@ -160,7 +160,7 @@ namespace Avalonia.X11 } } - class FallbackScreensImpl : IX11Screens + private class FallbackScreensImpl : IX11Screens { public FallbackScreensImpl(X11Info info, X11ScreensUserSettings settings) { @@ -220,17 +220,17 @@ namespace Avalonia.X11 _impl.Screens.Select(s => new Screen(s.Scaling, s.Bounds, s.WorkingArea, s.IsPrimary)).ToArray(); } - interface IX11Screens + internal interface IX11Screens { X11Screen[] Screens { get; } } - class X11ScreensUserSettings + internal class X11ScreensUserSettings { public double GlobalScaleFactor { get; set; } = 1; public Dictionary NamedScaleFactors { get; set; } - static double? TryParse(string s) + private static double? TryParse(string s) { if (s == null) return null; @@ -276,7 +276,7 @@ namespace Avalonia.X11 } } - class X11Screen + internal class X11Screen { private const int FullHDWidth = 1920; private const int FullHDHeight = 1080; diff --git a/src/Avalonia.X11/X11Structs.cs b/src/Avalonia.X11/X11Structs.cs index 26515762b4..18f860a1a8 100644 --- a/src/Avalonia.X11/X11Structs.cs +++ b/src/Avalonia.X11/X11Structs.cs @@ -1751,8 +1751,7 @@ namespace Avalonia.X11 { { public IntPtr client_data; public XIMProc callback; - [NonSerialized] - GCHandle gch; + [NonSerialized] private GCHandle gch; public XIMCallback (IntPtr clientData, XIMProc proc) { @@ -1769,7 +1768,7 @@ namespace Avalonia.X11 { [StructLayout(LayoutKind.Sequential)] #pragma warning disable CA1815 // Override equals and operator equals on value types - public unsafe struct XImage + internal unsafe struct XImage #pragma warning restore CA1815 // Override equals and operator equals on value types { public int width, height; /* size of image */ @@ -1896,8 +1895,8 @@ namespace Avalonia.X11 { public const string XNSpotLocation = "spotLocation"; public const string XNFontSet = "fontSet"; } - - unsafe struct XRRMonitorInfo { + + internal unsafe struct XRRMonitorInfo { public IntPtr Name; public int Primary; public int Automatic; diff --git a/src/Avalonia.X11/X11Window.Ime.cs b/src/Avalonia.X11/X11Window.Ime.cs index e6066c7964..26ead5e6b8 100644 --- a/src/Avalonia.X11/X11Window.Ime.cs +++ b/src/Avalonia.X11/X11Window.Ime.cs @@ -11,7 +11,7 @@ using static Avalonia.X11.XLib; namespace Avalonia.X11 { - partial class X11Window + internal partial class X11Window { private ITextInputMethodImpl _ime; private IX11InputMethodControl _imeControl; @@ -20,7 +20,7 @@ namespace Avalonia.X11 private Queue<(RawKeyEventArgs args, XEvent xev, int keyval, int keycode)> _imeQueue = new Queue<(RawKeyEventArgs args, XEvent xev, int keyVal, int keyCode)>(); - unsafe void CreateIC() + private unsafe void CreateIC() { if (_x11.HasXim) { @@ -65,8 +65,8 @@ namespace Avalonia.X11 new IntPtr((int)(XIMProperties.XIMPreeditNothing | XIMProperties.XIMStatusNothing)), XNames.XNClientWindow, _handle, XNames.XNFocusWindow, _handle, IntPtr.Zero); } - - void InitializeIme() + + private void InitializeIme() { var ime = AvaloniaLocator.Current.GetService()?.CreateClient(_handle); if (ime == null && _x11.HasXim) @@ -89,9 +89,9 @@ namespace Avalonia.X11 } } - void UpdateImePosition() => _imeControl?.UpdateWindowInfo(Position, RenderScaling); + private void UpdateImePosition() => _imeControl?.UpdateWindowInfo(Position, RenderScaling); - void HandleKeyEvent(ref XEvent ev) + private void HandleKeyEvent(ref XEvent ev) { var index = ev.KeyEvent.state.HasAllFlags(XModifierMask.ShiftMask); @@ -117,7 +117,7 @@ namespace Avalonia.X11 ScheduleKeyInput(args, ref ev, (int)key, ev.KeyEvent.keycode); } - void TriggerClassicTextInputEvent(ref XEvent ev) + private void TriggerClassicTextInputEvent(ref XEvent ev) { var text = TranslateEventToString(ref ev); if (text != null) @@ -128,8 +128,8 @@ namespace Avalonia.X11 private const int ImeBufferSize = 64 * 1024; [ThreadStatic] private static IntPtr ImeBuffer; - - unsafe string TranslateEventToString(ref XEvent ev) + + private unsafe string TranslateEventToString(ref XEvent ev) { if (ImeBuffer == IntPtr.Zero) ImeBuffer = Marshal.AllocHGlobal(ImeBufferSize); @@ -158,9 +158,9 @@ namespace Avalonia.X11 return text; } - - - void ScheduleKeyInput(RawKeyEventArgs args, ref XEvent xev, int keyval, int keycode) + + + private void ScheduleKeyInput(RawKeyEventArgs args, ref XEvent xev, int keyval, int keycode) { _x11.LastActivityTimestamp = xev.ButtonEvent.time; @@ -170,8 +170,8 @@ namespace Avalonia.X11 ScheduleInput(args); } - - bool FilterIme(RawKeyEventArgs args, XEvent xev, int keyval, int keycode) + + private bool FilterIme(RawKeyEventArgs args, XEvent xev, int keyval, int keycode) { if (_ime == null) return false; @@ -182,7 +182,7 @@ namespace Avalonia.X11 return true; } - async void ProcessNextImeEvent() + private async void ProcessNextImeEvent() { if(_processingIme) return; @@ -203,7 +203,7 @@ namespace Avalonia.X11 } // This class is used to attach the text value of the key to an asynchronously dispatched KeyDown event - class RawKeyEventArgsWithText : RawKeyEventArgs + private class RawKeyEventArgsWithText : RawKeyEventArgs { public RawKeyEventArgsWithText(IKeyboardDevice device, ulong timestamp, IInputRoot root, RawKeyEventType type, Key key, RawInputModifiers modifiers, string text) : diff --git a/src/Avalonia.X11/X11Window.Xim.cs b/src/Avalonia.X11/X11Window.Xim.cs index 8446d35cc6..cc5ecad09f 100644 --- a/src/Avalonia.X11/X11Window.Xim.cs +++ b/src/Avalonia.X11/X11Window.Xim.cs @@ -8,9 +8,9 @@ using Avalonia.Threading; using static Avalonia.X11.XLib; namespace Avalonia.X11 { - partial class X11Window + internal partial class X11Window { - class XimInputMethod : ITextInputMethodImpl, IX11InputMethodControl + private class XimInputMethod : ITextInputMethodImpl, IX11InputMethodControl { private readonly X11Window _parent; private bool _windowActive, _imeActive; diff --git a/src/Avalonia.X11/X11Window.cs b/src/Avalonia.X11/X11Window.cs index c78ef2350e..9f09212814 100644 --- a/src/Avalonia.X11/X11Window.cs +++ b/src/Avalonia.X11/X11Window.cs @@ -27,7 +27,7 @@ using static Avalonia.X11.XLib; // ReSharper disable StringLiteralTypo namespace Avalonia.X11 { - unsafe partial class X11Window : IWindowImpl, IPopupImpl, IXI2Client + internal unsafe partial class X11Window : IWindowImpl, IPopupImpl, IXI2Client { private readonly AvaloniaX11Platform _platform; private readonly bool _popup; @@ -59,7 +59,7 @@ namespace Avalonia.X11 private bool _useRenderWindow = false; private bool _usePositioningFlags = false; - enum XSyncState + private enum XSyncState { None, WaitConfigure, @@ -219,7 +219,7 @@ namespace Avalonia.X11 }); } - class SurfaceInfo : EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo + private class SurfaceInfo : EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo { private readonly X11Window _window; private readonly IntPtr _display; @@ -249,7 +249,7 @@ namespace Avalonia.X11 public double Scaling => _window.RenderScaling; } - void UpdateMotifHints() + private void UpdateMotifHints() { var functions = MotifFunctions.Move | MotifFunctions.Close | MotifFunctions.Resize | MotifFunctions.Minimize | MotifFunctions.Maximize; @@ -278,7 +278,7 @@ namespace Avalonia.X11 PropertyMode.Replace, ref hints, 5); } - void UpdateSizeHints(PixelSize? preResize) + private void UpdateSizeHints(PixelSize? preResize) { var min = _minMaxSize.minSize; var max = _minMaxSize.maxSize; @@ -386,7 +386,7 @@ namespace Avalonia.X11 public IRenderer CreateRenderer(IRenderRoot root) => new CompositingRenderer(root, _platform.Compositor, () => Surfaces); - void OnEvent(ref XEvent ev) + private void OnEvent(ref XEvent ev) { if (ev.type == XEventName.MapNotify) { @@ -668,7 +668,7 @@ namespace Avalonia.X11 } - static RawInputModifiers TranslateModifiers(XModifierMask state) + private static RawInputModifiers TranslateModifiers(XModifierMask state) { var rv = default(RawInputModifiers); if (state.HasAllFlags(XModifierMask.Button1Mask)) @@ -704,13 +704,13 @@ namespace Avalonia.X11 private double _scaling = 1; - void ScheduleInput(RawInputEventArgs args, ref XEvent xev) + private void ScheduleInput(RawInputEventArgs args, ref XEvent xev) { _x11.LastActivityTimestamp = xev.ButtonEvent.time; ScheduleInput(args); } - void DispatchInput(RawInputEventArgs args) + private void DispatchInput(RawInputEventArgs args) { Input?.Invoke(args); if (!args.Handled && args is RawKeyEventArgsWithText text && !string.IsNullOrEmpty(text.Text)) @@ -746,8 +746,8 @@ namespace Avalonia.X11 _rawEventGrouper.HandleEvent(args); } - - void MouseEvent(RawPointerEventType type, ref XEvent ev, XModifierMask mods) + + private void MouseEvent(RawPointerEventType type, ref XEvent ev, XModifierMask mods) { var mev = new RawPointerEventArgs( _mouse, (ulong)ev.ButtonEvent.time.ToInt64(), _inputRoot, @@ -755,7 +755,7 @@ namespace Avalonia.X11 ScheduleInput(mev, ref ev); } - void EnqueuePaint() + private void EnqueuePaint() { if (!_triggeredExpose) { @@ -767,8 +767,8 @@ namespace Avalonia.X11 }, DispatcherPriority.Render); } } - - void DoPaint() + + private void DoPaint() { Paint?.Invoke(new Rect()); if (_xSyncCounter != IntPtr.Zero && _xSyncState == XSyncState.WaitPaint) @@ -819,8 +819,8 @@ namespace Avalonia.X11 return null; } - - void Cleanup() + + private void Cleanup() { if (_rawEventGrouper != null) { @@ -871,7 +871,7 @@ namespace Avalonia.X11 } } - bool ActivateTransientChildIfNeeded() + private bool ActivateTransientChildIfNeeded() { if (_disabled) { @@ -923,9 +923,9 @@ namespace Avalonia.X11 Resize(size, true, PlatformResizeReason.Layout); } - PixelSize ToPixelSize(Size size) => new PixelSize((int)(size.Width * RenderScaling), (int)(size.Height * RenderScaling)); - - void Resize(Size clientSize, bool force, PlatformResizeReason reason) + private PixelSize ToPixelSize(Size size) => new PixelSize((int)(size.Width * RenderScaling), (int)(size.Height * RenderScaling)); + + private void Resize(Size clientSize, bool force, PlatformResizeReason reason) { if (!force && clientSize == ClientSize) return; @@ -1020,7 +1020,7 @@ namespace Avalonia.X11 .OrderByDescending(x => x.Width + x.Height).FirstOrDefault(); - void SendNetWMMessage(IntPtr message_type, IntPtr l0, + private void SendNetWMMessage(IntPtr message_type, IntPtr l0, IntPtr? l1 = null, IntPtr? l2 = null, IntPtr? l3 = null, IntPtr? l4 = null) { var xev = new XEvent @@ -1044,7 +1044,7 @@ namespace Avalonia.X11 } - void BeginMoveResize(NetWmMoveResize side, PointerPressedEventArgs e) + private void BeginMoveResize(NetWmMoveResize side, PointerPressedEventArgs e) { var pos = GetCursorPos(_x11); XUngrabPointer(_x11.Display, new IntPtr(0)); @@ -1184,7 +1184,7 @@ namespace Avalonia.X11 ChangeWMAtoms(!value, _x11.Atoms._NET_WM_STATE_SKIP_TASKBAR); } - void ChangeWMAtoms(bool enable, params IntPtr[] atoms) + private void ChangeWMAtoms(bool enable, params IntPtr[] atoms) { if (atoms.Length != 1 && atoms.Length != 2) throw new ArgumentException(); diff --git a/src/Avalonia.X11/XError.cs b/src/Avalonia.X11/XError.cs index 2cc8f63c96..fbe9c34686 100644 --- a/src/Avalonia.X11/XError.cs +++ b/src/Avalonia.X11/XError.cs @@ -2,11 +2,12 @@ using System; namespace Avalonia.X11 { - static class XError + internal static class XError { private static readonly XErrorHandler s_errorHandlerDelegate = Handler; public static XErrorEvent LastError; - static int Handler(IntPtr display, ref XErrorEvent error) + + private static int Handler(IntPtr display, ref XErrorEvent error) { LastError = error; return 0; diff --git a/src/Avalonia.X11/XI2Manager.cs b/src/Avalonia.X11/XI2Manager.cs index 7bf1df41b6..f66616f2aa 100644 --- a/src/Avalonia.X11/XI2Manager.cs +++ b/src/Avalonia.X11/XI2Manager.cs @@ -7,7 +7,7 @@ using static Avalonia.X11.XLib; namespace Avalonia.X11 { - unsafe class XI2Manager + internal unsafe class XI2Manager { private static readonly XiEventType[] DefaultEventTypes = new XiEventType[] { @@ -30,7 +30,7 @@ namespace Avalonia.X11 private bool _multitouch; private Dictionary _clients = new Dictionary(); - class DeviceInfo + private class DeviceInfo { public int Id { get; } public XIValuatorClassInfo[] Valuators { get; private set; } @@ -67,7 +67,7 @@ namespace Avalonia.X11 } } - class PointerDeviceInfo : DeviceInfo + private class PointerDeviceInfo : DeviceInfo { public PointerDeviceInfo(XIDeviceInfo info) : base(info) { @@ -197,7 +197,7 @@ namespace Avalonia.X11 } } - void OnEnterLeaveEvent(IXI2Client client, ref XIEnterLeaveEvent ev) + private void OnEnterLeaveEvent(IXI2Client client, ref XIEnterLeaveEvent ev) { if (ev.evtype == XiEventType.XI_Leave) { @@ -215,7 +215,7 @@ namespace Avalonia.X11 } } - void OnDeviceEvent(IXI2Client client, ParsedDeviceEvent ev) + private void OnDeviceEvent(IXI2Client client, ParsedDeviceEvent ev) { if (ev.Type == XiEventType.XI_TouchBegin || ev.Type == XiEventType.XI_TouchUpdate @@ -304,7 +304,7 @@ namespace Avalonia.X11 } } - unsafe class ParsedDeviceEvent + internal unsafe class ParsedDeviceEvent { public XiEventType Type { get; } public RawInputModifiers Modifiers { get; } @@ -367,8 +367,8 @@ namespace Avalonia.X11 Emulated = ev->flags.HasAllFlags(XiDeviceEventFlags.XIPointerEmulated); } } - - interface IXI2Client + + internal interface IXI2Client { IInputRoot InputRoot { get; } void ScheduleXI2Input(RawInputEventArgs args); diff --git a/src/Avalonia.X11/XIStructs.cs b/src/Avalonia.X11/XIStructs.cs index f4581a99ba..9a1ed01764 100644 --- a/src/Avalonia.X11/XIStructs.cs +++ b/src/Avalonia.X11/XIStructs.cs @@ -10,7 +10,7 @@ using Atom = System.IntPtr; namespace Avalonia.X11 { [StructLayout(LayoutKind.Sequential)] - struct XIAddMasterInfo + internal struct XIAddMasterInfo { public int Type; public IntPtr Name; @@ -19,7 +19,7 @@ namespace Avalonia.X11 } [StructLayout(LayoutKind.Sequential)] - struct XIRemoveMasterInfo + internal struct XIRemoveMasterInfo { public int Type; public int Deviceid; @@ -29,7 +29,7 @@ namespace Avalonia.X11 }; [StructLayout(LayoutKind.Sequential)] - struct XIAttachSlaveInfo + internal struct XIAttachSlaveInfo { public int Type; public int Deviceid; @@ -37,14 +37,14 @@ namespace Avalonia.X11 }; [StructLayout(LayoutKind.Sequential)] - struct XIDetachSlaveInfo + internal struct XIDetachSlaveInfo { public int Type; public int Deviceid; }; [StructLayout(LayoutKind.Explicit)] - struct XIAnyHierarchyChangeInfo + internal struct XIAnyHierarchyChangeInfo { [FieldOffset(0)] public int type; /* must be first element */ @@ -59,7 +59,7 @@ namespace Avalonia.X11 }; [StructLayout(LayoutKind.Sequential)] - struct XIModifierState + internal struct XIModifierState { public int Base; public int Latched; @@ -68,14 +68,14 @@ namespace Avalonia.X11 }; [StructLayout(LayoutKind.Sequential)] - unsafe struct XIButtonState + internal unsafe struct XIButtonState { public int MaskLen; public byte* Mask; }; [StructLayout(LayoutKind.Sequential)] - unsafe struct XIValuatorState + internal unsafe struct XIValuatorState { public int MaskLen; public byte* Mask; @@ -83,7 +83,7 @@ namespace Avalonia.X11 }; [StructLayout(LayoutKind.Sequential)] - unsafe struct XIEventMask + internal unsafe struct XIEventMask { public int Deviceid; public int MaskLen; @@ -91,14 +91,14 @@ namespace Avalonia.X11 }; [StructLayout(LayoutKind.Sequential)] - struct XIAnyClassInfo + internal struct XIAnyClassInfo { public XiDeviceClass Type; public int Sourceid; }; [StructLayout(LayoutKind.Sequential)] - unsafe struct XIButtonClassInfo + internal unsafe struct XIButtonClassInfo { public int Type; public int Sourceid; @@ -108,7 +108,7 @@ namespace Avalonia.X11 }; [StructLayout(LayoutKind.Sequential)] - unsafe struct XIKeyClassInfo + internal unsafe struct XIKeyClassInfo { public int Type; public int Sourceid; @@ -117,7 +117,7 @@ namespace Avalonia.X11 }; [StructLayout(LayoutKind.Sequential)] - struct XIValuatorClassInfo + internal struct XIValuatorClassInfo { public int Type; public int Sourceid; @@ -132,7 +132,7 @@ namespace Avalonia.X11 /* new in XI 2.1 */ [StructLayout(LayoutKind.Sequential)] - struct XIScrollClassInfo + internal struct XIScrollClassInfo { public int Type; public int Sourceid; @@ -142,14 +142,14 @@ namespace Avalonia.X11 public int Flags; }; - enum XiScrollType + internal enum XiScrollType { Vertical = 1, Horizontal = 2 } [StructLayout(LayoutKind.Sequential)] - struct XITouchClassInfo + internal struct XITouchClassInfo { public int Type; public int Sourceid; @@ -158,7 +158,7 @@ namespace Avalonia.X11 }; [StructLayout(LayoutKind.Sequential)] - unsafe struct XIDeviceInfo + internal unsafe struct XIDeviceInfo { public int Deviceid; public IntPtr Name; @@ -169,7 +169,7 @@ namespace Avalonia.X11 public XIAnyClassInfo** Classes; } - enum XiDeviceType + internal enum XiDeviceType { XIMasterPointer = 1, XIMasterKeyboard = 2, @@ -178,13 +178,13 @@ namespace Avalonia.X11 XIFloatingSlave = 5 } - enum XiPredefinedDeviceId : int + internal enum XiPredefinedDeviceId : int { XIAllDevices = 0, XIAllMasterDevices = 1 } - enum XiDeviceClass + internal enum XiDeviceClass { XIKeyClass = 0, XIButtonClass = 1, @@ -194,7 +194,7 @@ namespace Avalonia.X11 } [StructLayout(LayoutKind.Sequential)] - unsafe struct XIDeviceChangedEvent + internal unsafe struct XIDeviceChangedEvent { public int Type; /* GenericEvent */ public UIntPtr Serial; /* # of last request processed by server */ @@ -211,7 +211,7 @@ namespace Avalonia.X11 } [StructLayout(LayoutKind.Sequential)] - struct XIDeviceEvent + internal struct XIDeviceEvent { public XEventName type; /* GenericEvent */ public UIntPtr serial; /* # of last request processed by server */ @@ -238,7 +238,7 @@ namespace Avalonia.X11 } [StructLayout(LayoutKind.Sequential)] - unsafe struct XIEnterLeaveEvent + internal unsafe struct XIEnterLeaveEvent { public XEventName type; /* GenericEvent */ public UIntPtr serial; /* # of last request processed by server */ @@ -266,14 +266,14 @@ namespace Avalonia.X11 } [Flags] - public enum XiDeviceEventFlags : int + internal enum XiDeviceEventFlags : int { None = 0, XIPointerEmulated = (1 << 16) } [StructLayout(LayoutKind.Sequential)] - unsafe struct XIEvent + internal unsafe struct XIEvent { public int type; /* GenericEvent */ public UIntPtr serial; /* # of last request processed by server */ @@ -284,7 +284,7 @@ namespace Avalonia.X11 public IntPtr time; } - enum XiEventType + internal enum XiEventType { XI_DeviceChanged = 1, XI_KeyPress = 2, @@ -315,7 +315,7 @@ namespace Avalonia.X11 XI_LASTEVENT = XI_BarrierLeave, } - enum XiEnterLeaveDetail + internal enum XiEnterLeaveDetail { XINotifyAncestor = 0, XINotifyVirtual = 1, diff --git a/src/Avalonia.X11/XLib.cs b/src/Avalonia.X11/XLib.cs index 753d5f530c..7a43cd378b 100644 --- a/src/Avalonia.X11/XLib.cs +++ b/src/Avalonia.X11/XLib.cs @@ -16,11 +16,11 @@ namespace Avalonia.X11 { internal unsafe static class XLib { - const string libX11 = "libX11.so.6"; - const string libX11Randr = "libXrandr.so.2"; - const string libX11Ext = "libXext.so.6"; - const string libXInput = "libXi.so.6"; - const string libXCursor = "libXcursor.so.1"; + private const string libX11 = "libX11.so.6"; + private const string libX11Randr = "libXrandr.so.2"; + private const string libX11Ext = "libXext.so.6"; + private const string libXInput = "libXi.so.6"; + private const string libXCursor = "libXcursor.so.1"; [DllImport(libX11)] public static extern IntPtr XOpenDisplay(IntPtr display); diff --git a/src/Browser/Avalonia.Browser/Skia/BrowserSkiaGpu.cs b/src/Browser/Avalonia.Browser/Skia/BrowserSkiaGpu.cs index 4d3d8dcd97..3c04935f0d 100644 --- a/src/Browser/Avalonia.Browser/Skia/BrowserSkiaGpu.cs +++ b/src/Browser/Avalonia.Browser/Skia/BrowserSkiaGpu.cs @@ -6,7 +6,7 @@ using Avalonia.Reactive; namespace Avalonia.Browser.Skia { - public class BrowserSkiaGpu : ISkiaGpu + internal class BrowserSkiaGpu : ISkiaGpu { public ISkiaGpuRenderTarget? TryCreateRenderTarget(IEnumerable surfaces) { diff --git a/src/Shared/RawEventGrouping.cs b/src/Shared/RawEventGrouping.cs index 966744888c..c4772db820 100644 --- a/src/Shared/RawEventGrouping.cs +++ b/src/Shared/RawEventGrouping.cs @@ -17,8 +17,8 @@ internal class RawEventGrouper : IDisposable private readonly Action _eventCallback; private readonly Queue _inputQueue = new(); private readonly Action _dispatchFromQueue; - readonly Dictionary _lastTouchPoints = new(); - RawInputEventArgs? _lastEvent; + private readonly Dictionary _lastTouchPoints = new(); + private RawInputEventArgs? _lastEvent; public RawEventGrouper(Action eventCallback) { diff --git a/src/Skia/Avalonia.Skia/GlyphRunImpl.cs b/src/Skia/Avalonia.Skia/GlyphRunImpl.cs index cc669f9aaa..cfd6fc12f8 100644 --- a/src/Skia/Avalonia.Skia/GlyphRunImpl.cs +++ b/src/Skia/Avalonia.Skia/GlyphRunImpl.cs @@ -1,15 +1,12 @@ using System; using System.Collections.Generic; -using Avalonia.Metadata; using Avalonia.Platform; using SkiaSharp; #nullable enable namespace Avalonia.Skia { - /// - [Unstable] - public class GlyphRunImpl : IGlyphRunImpl + internal class GlyphRunImpl : IGlyphRunImpl { public GlyphRunImpl(SKTextBlob textBlob, Size size, Point baselineOrigin) { diff --git a/src/Skia/Avalonia.Skia/GlyphTypefaceImpl.cs b/src/Skia/Avalonia.Skia/GlyphTypefaceImpl.cs index 71bdc1bd6b..a8dd289a13 100644 --- a/src/Skia/Avalonia.Skia/GlyphTypefaceImpl.cs +++ b/src/Skia/Avalonia.Skia/GlyphTypefaceImpl.cs @@ -1,14 +1,12 @@ using System; using System.Runtime.InteropServices; using Avalonia.Media; -using Avalonia.Metadata; using HarfBuzzSharp; using SkiaSharp; namespace Avalonia.Skia { - [Unstable] - public class GlyphTypefaceImpl : IGlyphTypeface + internal class GlyphTypefaceImpl : IGlyphTypeface { private bool _isDisposed; diff --git a/src/Skia/Avalonia.Skia/SKTypefaceCollection.cs b/src/Skia/Avalonia.Skia/SKTypefaceCollection.cs index 1f3f20730f..73f58e66bc 100644 --- a/src/Skia/Avalonia.Skia/SKTypefaceCollection.cs +++ b/src/Skia/Avalonia.Skia/SKTypefaceCollection.cs @@ -4,7 +4,7 @@ using SkiaSharp; namespace Avalonia.Skia { - public class SKTypefaceCollection + internal class SKTypefaceCollection { private readonly ConcurrentDictionary _typefaces = new ConcurrentDictionary(); diff --git a/src/Skia/Avalonia.Skia/SKTypefaceCollectionCache.cs b/src/Skia/Avalonia.Skia/SKTypefaceCollectionCache.cs index f7a86c11ff..b49efd59cd 100644 --- a/src/Skia/Avalonia.Skia/SKTypefaceCollectionCache.cs +++ b/src/Skia/Avalonia.Skia/SKTypefaceCollectionCache.cs @@ -7,7 +7,7 @@ using SkiaSharp; namespace Avalonia.Skia { - public static class SKTypefaceCollectionCache + internal static class SKTypefaceCollectionCache { private static readonly ConcurrentDictionary s_cachedCollections; diff --git a/src/Skia/Avalonia.Skia/readme.md b/src/Skia/Avalonia.Skia/readme.md deleted file mode 100644 index 7ed92c5453..0000000000 --- a/src/Skia/Avalonia.Skia/readme.md +++ /dev/null @@ -1,22 +0,0 @@ -DrawingContextImpl -- Alpha support missing as SkiaSharp does not expose this -- Gradient Shader caching? -- Pen Dash styles - -Formatted Text Rendering -- Minor polish - -Linux -- Need gpu platform implementation - -macOS -- Need gpu platform implementation - -Android -- Not tested at all yet - -iOS -- Not tested at all yet - -General -- Get Skia Unit Tests passing (most of the issues are related to antialiasing) \ No newline at end of file diff --git a/src/Windows/Avalonia.Direct2D1/Avalonia.Direct2D1.csproj b/src/Windows/Avalonia.Direct2D1/Avalonia.Direct2D1.csproj index 32bcdba758..3c2d7b3322 100644 --- a/src/Windows/Avalonia.Direct2D1/Avalonia.Direct2D1.csproj +++ b/src/Windows/Avalonia.Direct2D1/Avalonia.Direct2D1.csproj @@ -5,11 +5,6 @@ Avalonia.Direct2D1 true - - - UnmanagedMethods.cs - - @@ -22,6 +17,7 @@ + diff --git a/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs b/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs index 99c01dd111..57379d1878 100644 --- a/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs +++ b/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs @@ -27,7 +27,7 @@ namespace Avalonia namespace Avalonia.Direct2D1 { - public class Direct2D1Platform : IPlatformRenderInterface + internal class Direct2D1Platform : IPlatformRenderInterface { private static readonly Direct2D1Platform s_instance = new Direct2D1Platform(); diff --git a/src/Windows/Avalonia.Direct2D1/Disposable.cs b/src/Windows/Avalonia.Direct2D1/Disposable.cs deleted file mode 100644 index 63dfeb2e0b..0000000000 --- a/src/Windows/Avalonia.Direct2D1/Disposable.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; - -namespace Avalonia.Direct2D1 -{ - public class Disposable : IDisposable where T : IDisposable - { - private readonly IDisposable _extra; - - public Disposable(T inner) - { - Inner = inner; - } - - public Disposable(T inner, IDisposable extra) - { - Inner = inner; - _extra = extra; - } - - public T Inner { get; } - - public static implicit operator T(Disposable i) - { - return i.Inner; - } - - public void Dispose() - { - Inner.Dispose(); - _extra?.Dispose(); - } - } -} diff --git a/src/Windows/Avalonia.Direct2D1/ILayerFactory.cs b/src/Windows/Avalonia.Direct2D1/ILayerFactory.cs index a15bc0056a..504f4981f7 100644 --- a/src/Windows/Avalonia.Direct2D1/ILayerFactory.cs +++ b/src/Windows/Avalonia.Direct2D1/ILayerFactory.cs @@ -2,7 +2,7 @@ namespace Avalonia.Direct2D1 { - public interface ILayerFactory + internal interface ILayerFactory { IDrawingContextLayerImpl CreateLayer(Size size); } diff --git a/src/Windows/Avalonia.Direct2D1/Media/BrushImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/BrushImpl.cs index 602ea9b568..9fac86e0d2 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/BrushImpl.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/BrushImpl.cs @@ -1,10 +1,8 @@ using System; -using Avalonia.Metadata; namespace Avalonia.Direct2D1.Media { - [Unstable] - public abstract class BrushImpl : IDisposable + internal abstract class BrushImpl : IDisposable { public SharpDX.Direct2D1.Brush PlatformBrush { get; set; } diff --git a/src/Windows/Avalonia.Direct2D1/Media/DWriteResourceFontFileEnumerator.cs b/src/Windows/Avalonia.Direct2D1/Media/DWriteResourceFontFileEnumerator.cs index c144e12aea..42cc969b66 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/DWriteResourceFontFileEnumerator.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/DWriteResourceFontFileEnumerator.cs @@ -6,7 +6,7 @@ namespace Avalonia.Direct2D1.Media /// /// Resource FontFileEnumerator. /// - public class DWriteResourceFontFileEnumerator : CallbackBase, FontFileEnumerator + internal class DWriteResourceFontFileEnumerator : CallbackBase, FontFileEnumerator { private readonly Factory _factory; private readonly FontFileLoader _loader; @@ -64,4 +64,4 @@ namespace Avalonia.Direct2D1.Media } } } -} \ No newline at end of file +} diff --git a/src/Windows/Avalonia.Direct2D1/Media/DWriteResourceFontFileStream.cs b/src/Windows/Avalonia.Direct2D1/Media/DWriteResourceFontFileStream.cs index 1802ef4d21..bd2e9ab8c3 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/DWriteResourceFontFileStream.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/DWriteResourceFontFileStream.cs @@ -7,7 +7,7 @@ namespace Avalonia.Direct2D1.Media /// /// This FontFileStream implementation is reading data from a . /// - public class DWriteResourceFontFileStream : CallbackBase, FontFileStream + internal class DWriteResourceFontFileStream : CallbackBase, FontFileStream { private readonly DataStream _stream; diff --git a/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs index d5d6cd8c29..3506abc63b 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs @@ -11,15 +11,13 @@ using SharpDX; using SharpDX.Direct2D1; using SharpDX.Mathematics.Interop; using BitmapInterpolationMode = Avalonia.Media.Imaging.BitmapInterpolationMode; -using Avalonia.Metadata; namespace Avalonia.Direct2D1.Media { /// /// Draws using Direct2D1. /// - [Unstable] - public class DrawingContextImpl : IDrawingContextImpl + internal class DrawingContextImpl : IDrawingContextImpl { private readonly IVisualBrushRenderer _visualBrushRenderer; private readonly ILayerFactory _layerFactory; diff --git a/src/Windows/Avalonia.Direct2D1/Media/GeometryImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/GeometryImpl.cs index c84c14daac..9a93d1afd3 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/GeometryImpl.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/GeometryImpl.cs @@ -1,5 +1,4 @@ using Avalonia.Logging; -using Avalonia.Metadata; using Avalonia.Platform; using SharpDX.Direct2D1; @@ -8,8 +7,7 @@ namespace Avalonia.Direct2D1.Media /// /// The platform-specific interface for . /// - [Unstable] - public abstract class GeometryImpl : IGeometryImpl + internal abstract class GeometryImpl : IGeometryImpl { private const float ContourApproximation = 0.0001f; diff --git a/src/Windows/Avalonia.Direct2D1/Media/GlyphTypefaceImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/GlyphTypefaceImpl.cs index 705c715455..e4988322e7 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/GlyphTypefaceImpl.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/GlyphTypefaceImpl.cs @@ -1,6 +1,5 @@ using System; using Avalonia.Media; -using Avalonia.Metadata; using HarfBuzzSharp; using SharpDX.DirectWrite; using FontMetrics = Avalonia.Media.FontMetrics; @@ -9,8 +8,7 @@ using GlyphMetrics = Avalonia.Media.GlyphMetrics; namespace Avalonia.Direct2D1.Media { - [Unstable] - public class GlyphTypefaceImpl : IGlyphTypeface + internal class GlyphTypefaceImpl : IGlyphTypeface { private bool _isDisposed; diff --git a/src/Windows/Avalonia.Direct2D1/Media/ImageBrushImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/ImageBrushImpl.cs index 17dc359ed7..829b887d9d 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/ImageBrushImpl.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/ImageBrushImpl.cs @@ -1,13 +1,11 @@ using Avalonia.Media; -using Avalonia.Metadata; using Avalonia.Rendering.Utilities; using Avalonia.Utilities; using SharpDX.Direct2D1; namespace Avalonia.Direct2D1.Media { - [Unstable] - public sealed class ImageBrushImpl : BrushImpl + internal sealed class ImageBrushImpl : BrushImpl { private readonly OptionalDispose _bitmap; diff --git a/src/Windows/Avalonia.Direct2D1/Media/Imaging/BitmapImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/Imaging/BitmapImpl.cs index 059105c112..740efe833f 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/Imaging/BitmapImpl.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/Imaging/BitmapImpl.cs @@ -1,13 +1,11 @@ using System; using System.IO; -using Avalonia.Metadata; using Avalonia.Platform; using D2DBitmap = SharpDX.Direct2D1.Bitmap; namespace Avalonia.Direct2D1.Media { - [Unstable] - public abstract class BitmapImpl : IBitmapImpl, IDisposable + internal abstract class BitmapImpl : IBitmapImpl, IDisposable { public abstract Vector Dpi { get; } public abstract PixelSize PixelSize { get; } diff --git a/src/Windows/Avalonia.Direct2D1/Media/Imaging/D2DBitmapImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/Imaging/D2DBitmapImpl.cs index a321b225a0..940d4673b5 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/Imaging/D2DBitmapImpl.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/Imaging/D2DBitmapImpl.cs @@ -1,6 +1,5 @@ using System; using System.IO; -using Avalonia.Metadata; using SharpDX.WIC; using Bitmap = SharpDX.Direct2D1.Bitmap; @@ -9,8 +8,7 @@ namespace Avalonia.Direct2D1.Media /// /// A Direct2D Bitmap implementation that uses a GPU memory bitmap as its image. /// - [Unstable] - public class D2DBitmapImpl : BitmapImpl + internal class D2DBitmapImpl : BitmapImpl { private readonly Bitmap _direct2DBitmap; diff --git a/src/Windows/Avalonia.Direct2D1/Media/Imaging/D2DRenderTargetBitmapImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/Imaging/D2DRenderTargetBitmapImpl.cs index 84f11acdd7..2dbc1d67d1 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/Imaging/D2DRenderTargetBitmapImpl.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/Imaging/D2DRenderTargetBitmapImpl.cs @@ -1,6 +1,5 @@ using System; using System.IO; -using Avalonia.Metadata; using Avalonia.Platform; using Avalonia.Rendering; using Avalonia.Utilities; @@ -10,8 +9,7 @@ using D2DBitmap = SharpDX.Direct2D1.Bitmap; namespace Avalonia.Direct2D1.Media.Imaging { - [Unstable] - public class D2DRenderTargetBitmapImpl : D2DBitmapImpl, IDrawingContextLayerImpl, ILayerFactory + internal class D2DRenderTargetBitmapImpl : D2DBitmapImpl, IDrawingContextLayerImpl, ILayerFactory { private readonly BitmapRenderTarget _renderTarget; diff --git a/src/Windows/Avalonia.Direct2D1/Media/Imaging/WicBitmapImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/Imaging/WicBitmapImpl.cs index 72a48aca0c..533a29f68c 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/Imaging/WicBitmapImpl.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/Imaging/WicBitmapImpl.cs @@ -6,7 +6,6 @@ using SharpDX.WIC; using APixelFormat = Avalonia.Platform.PixelFormat; using AlphaFormat = Avalonia.Platform.AlphaFormat; using D2DBitmap = SharpDX.Direct2D1.Bitmap; -using Avalonia.Metadata; using Avalonia.Platform; using PixelFormat = SharpDX.WIC.PixelFormat; @@ -15,8 +14,7 @@ namespace Avalonia.Direct2D1.Media /// /// A WIC implementation of a . /// - [Unstable] - public class WicBitmapImpl : BitmapImpl, IReadableBitmapImpl + internal class WicBitmapImpl : BitmapImpl, IReadableBitmapImpl { private readonly BitmapDecoder _decoder; diff --git a/src/Windows/Avalonia.Direct2D1/Media/Imaging/WicRenderTargetBitmapImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/Imaging/WicRenderTargetBitmapImpl.cs index 9f0d48dbc7..d6b1e618e5 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/Imaging/WicRenderTargetBitmapImpl.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/Imaging/WicRenderTargetBitmapImpl.cs @@ -1,13 +1,11 @@ using System; -using Avalonia.Metadata; using Avalonia.Platform; using Avalonia.Rendering; using SharpDX.Direct2D1; namespace Avalonia.Direct2D1.Media { - [Unstable] - public class WicRenderTargetBitmapImpl : WicBitmapImpl, IDrawingContextLayerImpl + internal class WicRenderTargetBitmapImpl : WicBitmapImpl, IDrawingContextLayerImpl { private readonly WicRenderTarget _renderTarget; diff --git a/src/Windows/Avalonia.Direct2D1/Media/Imaging/WriteableWicBitmapImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/Imaging/WriteableWicBitmapImpl.cs index 5f4c033cf7..0bdf901613 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/Imaging/WriteableWicBitmapImpl.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/Imaging/WriteableWicBitmapImpl.cs @@ -6,7 +6,7 @@ using PixelFormat = Avalonia.Platform.PixelFormat; namespace Avalonia.Direct2D1.Media.Imaging { - class WriteableWicBitmapImpl : WicBitmapImpl, IWriteableBitmapImpl + internal class WriteableWicBitmapImpl : WicBitmapImpl, IWriteableBitmapImpl { public WriteableWicBitmapImpl(Stream stream, int decodeSize, bool horizontal, Avalonia.Media.Imaging.BitmapInterpolationMode interpolationMode) diff --git a/src/Windows/Avalonia.Direct2D1/Media/LinearGradientBrushImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/LinearGradientBrushImpl.cs index 5dfe683f59..5de988c30e 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/LinearGradientBrushImpl.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/LinearGradientBrushImpl.cs @@ -1,11 +1,9 @@ using System.Linq; using Avalonia.Media; -using Avalonia.Metadata; namespace Avalonia.Direct2D1.Media { - [Unstable] - public class LinearGradientBrushImpl : BrushImpl + internal class LinearGradientBrushImpl : BrushImpl { public LinearGradientBrushImpl( ILinearGradientBrush brush, diff --git a/src/Windows/Avalonia.Direct2D1/Media/RadialGradientBrushImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/RadialGradientBrushImpl.cs index 0069e47001..bbb34651c5 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/RadialGradientBrushImpl.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/RadialGradientBrushImpl.cs @@ -1,11 +1,9 @@ using System.Linq; using Avalonia.Media; -using Avalonia.Metadata; namespace Avalonia.Direct2D1.Media { - [Unstable] - public class RadialGradientBrushImpl : BrushImpl + internal class RadialGradientBrushImpl : BrushImpl { public RadialGradientBrushImpl( IRadialGradientBrush brush, diff --git a/src/Windows/Avalonia.Direct2D1/Media/SolidColorBrushImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/SolidColorBrushImpl.cs index b85494e2c1..bf974798a2 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/SolidColorBrushImpl.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/SolidColorBrushImpl.cs @@ -1,10 +1,8 @@ using Avalonia.Media; -using Avalonia.Metadata; namespace Avalonia.Direct2D1.Media { - [Unstable] - public class SolidColorBrushImpl : BrushImpl + internal class SolidColorBrushImpl : BrushImpl { public SolidColorBrushImpl(ISolidColorBrush brush, SharpDX.Direct2D1.RenderTarget target) { diff --git a/src/Windows/Avalonia.Direct2D1/Media/StreamGeometryContextImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/StreamGeometryContextImpl.cs index ec8f82556d..5ffe331ca2 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/StreamGeometryContextImpl.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/StreamGeometryContextImpl.cs @@ -9,8 +9,7 @@ using SweepDirection = SharpDX.Direct2D1.SweepDirection; namespace Avalonia.Direct2D1.Media { - [Unstable] - public class StreamGeometryContextImpl : IStreamGeometryContextImpl + internal class StreamGeometryContextImpl : IStreamGeometryContextImpl { private readonly GeometrySink _sink; diff --git a/src/Windows/Avalonia.Direct2D1/Media/StreamGeometryImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/StreamGeometryImpl.cs index e1677c0ed1..684460916e 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/StreamGeometryImpl.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/StreamGeometryImpl.cs @@ -1,4 +1,3 @@ -using Avalonia.Metadata; using Avalonia.Platform; using SharpDX.Direct2D1; @@ -7,8 +6,7 @@ namespace Avalonia.Direct2D1.Media /// /// A Direct2D implementation of a . /// - [Unstable] - public class StreamGeometryImpl : GeometryImpl, IStreamGeometryImpl + internal class StreamGeometryImpl : GeometryImpl, IStreamGeometryImpl { /// /// Initializes a new instance of the class. diff --git a/src/Windows/Avalonia.Direct2D1/Media/TransformedGeometryImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/TransformedGeometryImpl.cs index 3ecdb49e46..64aaea6f0a 100644 --- a/src/Windows/Avalonia.Direct2D1/Media/TransformedGeometryImpl.cs +++ b/src/Windows/Avalonia.Direct2D1/Media/TransformedGeometryImpl.cs @@ -1,11 +1,9 @@ -using Avalonia.Metadata; using Avalonia.Platform; using SharpDX.Direct2D1; namespace Avalonia.Direct2D1.Media { - [Unstable] - public class TransformedGeometryImpl : GeometryImpl, ITransformedGeometryImpl + internal class TransformedGeometryImpl : GeometryImpl, ITransformedGeometryImpl { /// /// Initializes a new instance of the class. diff --git a/src/Windows/Avalonia.Direct2D1/OptionalDispose.cs b/src/Windows/Avalonia.Direct2D1/OptionalDispose.cs index 1cdf7661df..d526da2b5d 100644 --- a/src/Windows/Avalonia.Direct2D1/OptionalDispose.cs +++ b/src/Windows/Avalonia.Direct2D1/OptionalDispose.cs @@ -2,7 +2,7 @@ namespace Avalonia.Direct2D1 { - public readonly record struct OptionalDispose : IDisposable where T : IDisposable + internal readonly record struct OptionalDispose : IDisposable where T : IDisposable { private readonly bool _dispose; diff --git a/src/Windows/Avalonia.Direct2D1/PrimitiveExtensions.cs b/src/Windows/Avalonia.Direct2D1/PrimitiveExtensions.cs index 669e139d8f..d042d56160 100644 --- a/src/Windows/Avalonia.Direct2D1/PrimitiveExtensions.cs +++ b/src/Windows/Avalonia.Direct2D1/PrimitiveExtensions.cs @@ -8,7 +8,7 @@ using DWrite = SharpDX.DirectWrite; namespace Avalonia.Direct2D1 { - public static class PrimitiveExtensions + internal static class PrimitiveExtensions { /// /// The value for which all absolute numbers smaller than are considered equal to zero. diff --git a/src/Windows/Avalonia.Direct2D1/RenderTarget.cs b/src/Windows/Avalonia.Direct2D1/RenderTarget.cs index 1a749c1a7f..8d5062336c 100644 --- a/src/Windows/Avalonia.Direct2D1/RenderTarget.cs +++ b/src/Windows/Avalonia.Direct2D1/RenderTarget.cs @@ -5,7 +5,7 @@ using Avalonia.Rendering; namespace Avalonia.Direct2D1 { - public class RenderTarget : IRenderTarget, ILayerFactory + internal class RenderTarget : IRenderTarget, ILayerFactory { /// /// The render target. diff --git a/src/Windows/Avalonia.Direct2D1/SwapChainRenderTarget.cs b/src/Windows/Avalonia.Direct2D1/SwapChainRenderTarget.cs index 4935e3db48..531c4119af 100644 --- a/src/Windows/Avalonia.Direct2D1/SwapChainRenderTarget.cs +++ b/src/Windows/Avalonia.Direct2D1/SwapChainRenderTarget.cs @@ -8,7 +8,7 @@ using SharpDX.DXGI; namespace Avalonia.Direct2D1 { - public abstract class SwapChainRenderTarget : IRenderTarget, ILayerFactory + internal abstract class SwapChainRenderTarget : IRenderTarget, ILayerFactory { private Size2 _savedSize; private Size2F _savedDpi; diff --git a/src/Windows/Avalonia.Win32/AngleOptions.cs b/src/Windows/Avalonia.Win32/AngleOptions.cs index 076ddd2a5d..94c67120df 100644 --- a/src/Windows/Avalonia.Win32/AngleOptions.cs +++ b/src/Windows/Avalonia.Win32/AngleOptions.cs @@ -17,6 +17,6 @@ namespace Avalonia.Win32 new GlVersion(GlProfileType.OpenGLES, 2, 0) }; - public IList AllowedPlatformApis { get; set; } = null; + public IList? AllowedPlatformApis { get; set; } = null; } } diff --git a/src/Windows/Avalonia.Win32/Automation/AutomationNode.ExpandCollapse.cs b/src/Windows/Avalonia.Win32/Automation/AutomationNode.ExpandCollapse.cs index 5f3f863493..aaad9cb3ba 100644 --- a/src/Windows/Avalonia.Win32/Automation/AutomationNode.ExpandCollapse.cs +++ b/src/Windows/Avalonia.Win32/Automation/AutomationNode.ExpandCollapse.cs @@ -2,8 +2,6 @@ using Avalonia.Automation.Provider; using UIA = Avalonia.Win32.Interop.Automation; -#nullable enable - namespace Avalonia.Win32.Automation { internal partial class AutomationNode : UIA.IExpandCollapseProvider diff --git a/src/Windows/Avalonia.Win32/Automation/AutomationNode.RangeValue.cs b/src/Windows/Avalonia.Win32/Automation/AutomationNode.RangeValue.cs index b91cb76888..518c945aa9 100644 --- a/src/Windows/Avalonia.Win32/Automation/AutomationNode.RangeValue.cs +++ b/src/Windows/Avalonia.Win32/Automation/AutomationNode.RangeValue.cs @@ -1,8 +1,6 @@ using Avalonia.Automation.Provider; using UIA = Avalonia.Win32.Interop.Automation; -#nullable enable - namespace Avalonia.Win32.Automation { internal partial class AutomationNode : UIA.IRangeValueProvider diff --git a/src/Windows/Avalonia.Win32/Automation/AutomationNode.Scroll.cs b/src/Windows/Avalonia.Win32/Automation/AutomationNode.Scroll.cs index 4f2d4ae269..0248a8d6a7 100644 --- a/src/Windows/Avalonia.Win32/Automation/AutomationNode.Scroll.cs +++ b/src/Windows/Avalonia.Win32/Automation/AutomationNode.Scroll.cs @@ -1,8 +1,6 @@ using Avalonia.Automation.Provider; using UIA = Avalonia.Win32.Interop.Automation; -#nullable enable - namespace Avalonia.Win32.Automation { internal partial class AutomationNode : UIA.IScrollProvider, UIA.IScrollItemProvider diff --git a/src/Windows/Avalonia.Win32/Automation/AutomationNode.Selection.cs b/src/Windows/Avalonia.Win32/Automation/AutomationNode.Selection.cs index 61903ab5b0..3751bb6476 100644 --- a/src/Windows/Avalonia.Win32/Automation/AutomationNode.Selection.cs +++ b/src/Windows/Avalonia.Win32/Automation/AutomationNode.Selection.cs @@ -1,12 +1,9 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; using Avalonia.Automation.Peers; using Avalonia.Automation.Provider; using UIA = Avalonia.Win32.Interop.Automation; -#nullable enable - namespace Avalonia.Win32.Automation { internal partial class AutomationNode : UIA.ISelectionProvider, UIA.ISelectionItemProvider @@ -27,8 +24,7 @@ namespace Avalonia.Win32.Automation UIA.IRawElementProviderSimple[] UIA.ISelectionProvider.GetSelection() { var peers = InvokeSync>(x => x.GetSelection()); - return peers?.Select(x => (UIA.IRawElementProviderSimple)GetOrCreate(x)!).ToArray() ?? - Array.Empty(); + return peers.Select(x => (UIA.IRawElementProviderSimple)GetOrCreate(x)).ToArray(); } void UIA.ISelectionItemProvider.AddToSelection() => InvokeSync(x => x.AddToSelection()); diff --git a/src/Windows/Avalonia.Win32/Automation/AutomationNode.Toggle.cs b/src/Windows/Avalonia.Win32/Automation/AutomationNode.Toggle.cs index 38f4d80946..08f4b62d83 100644 --- a/src/Windows/Avalonia.Win32/Automation/AutomationNode.Toggle.cs +++ b/src/Windows/Avalonia.Win32/Automation/AutomationNode.Toggle.cs @@ -1,8 +1,6 @@ using Avalonia.Automation.Provider; using UIA = Avalonia.Win32.Interop.Automation; -#nullable enable - namespace Avalonia.Win32.Automation { internal partial class AutomationNode : UIA.IToggleProvider diff --git a/src/Windows/Avalonia.Win32/Automation/AutomationNode.Value.cs b/src/Windows/Avalonia.Win32/Automation/AutomationNode.Value.cs index 34f5dfe0b9..204e159049 100644 --- a/src/Windows/Avalonia.Win32/Automation/AutomationNode.Value.cs +++ b/src/Windows/Avalonia.Win32/Automation/AutomationNode.Value.cs @@ -2,8 +2,6 @@ using Avalonia.Automation.Provider; using UIA = Avalonia.Win32.Interop.Automation; -#nullable enable - namespace Avalonia.Win32.Automation { internal partial class AutomationNode : UIA.IValueProvider diff --git a/src/Windows/Avalonia.Win32/Automation/AutomationNode.cs b/src/Windows/Avalonia.Win32/Automation/AutomationNode.cs index 29ab2cea3a..5ca4ef63bf 100644 --- a/src/Windows/Avalonia.Win32/Automation/AutomationNode.cs +++ b/src/Windows/Avalonia.Win32/Automation/AutomationNode.cs @@ -12,8 +12,6 @@ using Avalonia.Threading; using Avalonia.Win32.Interop.Automation; using AAP = Avalonia.Automation.Provider; -#nullable enable - namespace Avalonia.Win32.Automation { [ComVisible(true)] @@ -25,7 +23,7 @@ namespace Avalonia.Win32.Automation IRawElementProviderAdviseEvents, IInvokeProvider { - private static Dictionary s_propertyMap = new Dictionary() + private static Dictionary s_propertyMap = new() { { AutomationElementIdentifiers.BoundingRectangleProperty, UiaPropertyId.BoundingRectangle }, { AutomationElementIdentifiers.ClassNameProperty, UiaPropertyId.ClassName }, @@ -46,8 +44,7 @@ namespace Avalonia.Win32.Automation { SelectionPatternIdentifiers.SelectionProperty, UiaPropertyId.SelectionSelection }, }; - private static ConditionalWeakTable s_nodes = - new ConditionalWeakTable(); + private static ConditionalWeakTable s_nodes = new(); private readonly int[] _runtimeId; private int _raiseFocusChanged; @@ -174,11 +171,12 @@ namespace Avalonia.Win32.Automation NavigateDirection.LastChild => GetOrCreate(Peer.GetChildren().LastOrDefault()), _ => null, }; - }) as IRawElementProviderFragment; + }); } public void SetFocus() => InvokeSync(() => Peer.SetFocus()); + [return: NotNullIfNotNull(nameof(peer))] public static AutomationNode? GetOrCreate(AutomationPeer? peer) { return peer is null ? null : s_nodes.GetValue(peer, Create); diff --git a/src/Windows/Avalonia.Win32/Automation/RootAutomationNode.cs b/src/Windows/Avalonia.Win32/Automation/RootAutomationNode.cs index b732c4169f..3d8b4995ad 100644 --- a/src/Windows/Avalonia.Win32/Automation/RootAutomationNode.cs +++ b/src/Windows/Avalonia.Win32/Automation/RootAutomationNode.cs @@ -6,8 +6,6 @@ using Avalonia.Automation.Provider; using Avalonia.Platform; using Avalonia.Win32.Interop.Automation; -#nullable enable - namespace Avalonia.Win32.Automation { [RequiresUnreferencedCode("Requires .NET COM interop")] diff --git a/src/Windows/Avalonia.Win32/Avalonia.Win32.csproj b/src/Windows/Avalonia.Win32/Avalonia.Win32.csproj index a24fe31df8..92ebbd57b8 100644 --- a/src/Windows/Avalonia.Win32/Avalonia.Win32.csproj +++ b/src/Windows/Avalonia.Win32/Avalonia.Win32.csproj @@ -6,7 +6,6 @@ - @@ -16,7 +15,8 @@ - + + @@ -29,5 +29,6 @@ + diff --git a/src/Windows/Avalonia.Win32/ClipboardFormats.cs b/src/Windows/Avalonia.Win32/ClipboardFormats.cs index 7bd7765f8c..5fc4f21b2e 100644 --- a/src/Windows/Avalonia.Win32/ClipboardFormats.cs +++ b/src/Windows/Avalonia.Win32/ClipboardFormats.cs @@ -8,15 +8,15 @@ using Avalonia.Utilities; namespace Avalonia.Win32 { - static class ClipboardFormats + internal static class ClipboardFormats { private const int MAX_FORMAT_NAME_LENGTH = 260; - class ClipboardFormat + private class ClipboardFormat { - public ushort Format { get; private set; } - public string Name { get; private set; } - public ushort[] Synthesized { get; private set; } + public ushort Format { get; } + public string Name { get; } + public ushort[] Synthesized { get; } public ClipboardFormat(string name, ushort format, params ushort[] synthesized) { @@ -26,14 +26,14 @@ namespace Avalonia.Win32 } } - private static readonly List FormatList = new List() + private static readonly List s_formatList = new() { new ClipboardFormat(DataFormats.Text, (ushort)UnmanagedMethods.ClipboardFormat.CF_UNICODETEXT, (ushort)UnmanagedMethods.ClipboardFormat.CF_TEXT), new ClipboardFormat(DataFormats.FileNames, (ushort)UnmanagedMethods.ClipboardFormat.CF_HDROP), }; - private static string QueryFormatName(ushort format) + private static string? QueryFormatName(ushort format) { var sb = StringBuilderCache.Acquire(MAX_FORMAT_NAME_LENGTH); if (UnmanagedMethods.GetClipboardFormatName(format, sb, sb.Capacity) > 0) @@ -43,16 +43,16 @@ namespace Avalonia.Win32 public static string GetFormat(ushort format) { - lock (FormatList) + lock (s_formatList) { - var pd = FormatList.FirstOrDefault(f => f.Format == format || Array.IndexOf(f.Synthesized, format) >= 0); + var pd = s_formatList.FirstOrDefault(f => f.Format == format || Array.IndexOf(f.Synthesized, format) >= 0); if (pd == null) { - string name = QueryFormatName(format); + string? name = QueryFormatName(format); if (string.IsNullOrEmpty(name)) - name = string.Format("Unknown_Format_{0}", format); + name = $"Unknown_Format_{format}"; pd = new ClipboardFormat(name, format); - FormatList.Add(pd); + s_formatList.Add(pd); } return pd.Name; } @@ -60,16 +60,16 @@ namespace Avalonia.Win32 public static ushort GetFormat(string format) { - lock (FormatList) + lock (s_formatList) { - var pd = FormatList.FirstOrDefault(f => StringComparer.OrdinalIgnoreCase.Equals(f.Name, format)); + var pd = s_formatList.FirstOrDefault(f => StringComparer.OrdinalIgnoreCase.Equals(f.Name, format)); if (pd == null) { int id = UnmanagedMethods.RegisterClipboardFormat(format); if (id == 0) throw new Win32Exception(); pd = new ClipboardFormat(format, (ushort)id); - FormatList.Add(pd); + s_formatList.Add(pd); } return pd.Format; } diff --git a/src/Windows/Avalonia.Win32/ClipboardImpl.cs b/src/Windows/Avalonia.Win32/ClipboardImpl.cs index 82fd1109f4..1a760aeab8 100644 --- a/src/Windows/Avalonia.Win32/ClipboardImpl.cs +++ b/src/Windows/Avalonia.Win32/ClipboardImpl.cs @@ -30,7 +30,7 @@ namespace Avalonia.Win32 return Disposable.Create(() => UnmanagedMethods.CloseClipboard()); } - public async Task GetTextAsync() + public async Task GetTextAsync() { using(await OpenClipboard()) { @@ -52,19 +52,17 @@ namespace Avalonia.Win32 } } - public async Task SetTextAsync(string text) + public async Task SetTextAsync(string? text) { - if (text == null) - { - throw new ArgumentNullException(nameof(text)); - } - using(await OpenClipboard()) { UnmanagedMethods.EmptyClipboard(); - var hGlobal = Marshal.StringToHGlobalUni(text); - UnmanagedMethods.SetClipboardData(UnmanagedMethods.ClipboardFormat.CF_UNICODETEXT, hGlobal); + if (text is not null) + { + var hGlobal = Marshal.StringToHGlobalUni(text); + UnmanagedMethods.SetClipboardData(UnmanagedMethods.ClipboardFormat.CF_UNICODETEXT, hGlobal); + } } } @@ -121,7 +119,7 @@ namespace Avalonia.Win32 } } - public async Task GetDataAsync(string format) + public async Task GetDataAsync(string format) { Dispatcher.UIThread.VerifyAccess(); var i = OleRetryCount; diff --git a/src/Windows/Avalonia.Win32/DataObject.cs b/src/Windows/Avalonia.Win32/DataObject.cs index 7d22e57a30..272300cbf3 100644 --- a/src/Windows/Avalonia.Win32/DataObject.cs +++ b/src/Windows/Avalonia.Win32/DataObject.cs @@ -22,9 +22,9 @@ namespace Avalonia.Win32 // Compatibility with WinForms + WPF... internal static readonly byte[] SerializedObjectGUID = new Guid("FD9EA796-3B13-4370-A679-56106BB288FB").ToByteArray(); - class FormatEnumerator : CallbackBase, Win32Com.IEnumFORMATETC + private class FormatEnumerator : CallbackBase, Win32Com.IEnumFORMATETC { - private FORMATETC[] _formats; + private readonly FORMATETC[] _formats; private uint _current; private FormatEnumerator(FORMATETC[] formats, uint current) @@ -105,16 +105,12 @@ namespace Avalonia.Win32 public DataObject(IDataObject wrapped) { - if (wrapped == null) + _wrapped = wrapped switch { - throw new ArgumentNullException(nameof(wrapped)); - } - if (_wrapped is DataObject || _wrapped is OleDataObject) - { - throw new InvalidOperationException(); - } - - _wrapped = wrapped; + null => throw new ArgumentNullException(nameof(wrapped)), + DataObject or OleDataObject => throw new ArgumentException($"Cannot wrap a {wrapped.GetType()}"), + _ => wrapped + }; } #region IDataObject @@ -128,17 +124,17 @@ namespace Avalonia.Win32 return _wrapped.GetDataFormats(); } - IEnumerable IDataObject.GetFileNames() + IEnumerable? IDataObject.GetFileNames() { return _wrapped.GetFileNames(); } - string IDataObject.GetText() + string? IDataObject.GetText() { return _wrapped.GetText(); } - object IDataObject.Get(string dataFormat) + object? IDataObject.Get(string dataFormat) { return _wrapped.Get(dataFormat); } @@ -182,9 +178,6 @@ namespace Avalonia.Win32 if (_wrapped is Win32Com.IDataObject ole) return ole.GetCanonicalFormatEtc(formatIn); - var formatOut = new FORMATETC(); - formatOut.ptd = IntPtr.Zero; - throw new COMException(nameof(UnmanagedMethods.HRESULT.E_NOTIMPL), unchecked((int)UnmanagedMethods.HRESULT.E_NOTIMPL)); } @@ -264,9 +257,9 @@ namespace Avalonia.Win32 private uint WriteDataToHGlobal(string dataFormat, ref IntPtr hGlobal) { - object data = _wrapped.Get(dataFormat); + object data = _wrapped.Get(dataFormat)!; if (dataFormat == DataFormats.Text || data is string) - return WriteStringToHGlobal(ref hGlobal, Convert.ToString(data)); + return WriteStringToHGlobal(ref hGlobal, Convert.ToString(data) ?? string.Empty); if (dataFormat == DataFormats.FileNames && data is IEnumerable files) return WriteFileListToHGlobal(ref hGlobal, files); if (data is Stream stream) @@ -286,7 +279,7 @@ namespace Avalonia.Win32 } if (data is IEnumerable bytes) { - var byteArr = bytes is byte[] ? (byte[])bytes : bytes.ToArray(); + var byteArr = bytes as byte[] ?? bytes.ToArray(); return WriteBytesToHGlobal(ref hGlobal, byteArr); } return WriteBytesToHGlobal(ref hGlobal, SerializeObject(data)); @@ -332,7 +325,7 @@ namespace Avalonia.Win32 private static uint WriteFileListToHGlobal(ref IntPtr hGlobal, IEnumerable files) { - if (!files?.Any() ?? false) + if (!files.Any()) return unchecked((int)UnmanagedMethods.HRESULT.S_OK); char[] filesStr = (string.Join("\0", files) + "\0\0").ToCharArray(); @@ -392,7 +385,7 @@ namespace Avalonia.Win32 public void ReleaseWrapped() { - _wrapped = null; + _wrapped = null!; } #endregion } diff --git a/src/Windows/Avalonia.Win32/DirectX/DirectXStructs.cs b/src/Windows/Avalonia.Win32/DirectX/DirectXStructs.cs index c11a6026e7..af8168d564 100644 --- a/src/Windows/Avalonia.Win32/DirectX/DirectXStructs.cs +++ b/src/Windows/Avalonia.Win32/DirectX/DirectXStructs.cs @@ -1,18 +1,11 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; -using System.Text; -using System.Threading.Tasks; using static Avalonia.Win32.Interop.UnmanagedMethods; // ReSharper disable InconsistentNaming #pragma warning disable CS0649 namespace Avalonia.Win32.DirectX { -#nullable enable - public unsafe struct HANDLE + internal unsafe struct HANDLE { public readonly void* Value; @@ -288,5 +281,4 @@ namespace Avalonia.Win32.DirectX public D3D11_RESOURCE_MISC_FLAG MiscFlags; } -#nullable restore } diff --git a/src/Windows/Avalonia.Win32/DirectX/DxgiConnection.cs b/src/Windows/Avalonia.Win32/DirectX/DxgiConnection.cs index e82f7633be..07fb3169cb 100644 --- a/src/Windows/Avalonia.Win32/DirectX/DxgiConnection.cs +++ b/src/Windows/Avalonia.Win32/DirectX/DxgiConnection.cs @@ -1,36 +1,26 @@ using System; -using System.Collections.Generic; -using System.ComponentModel; using System.Diagnostics; -using System.Linq; -using System.Runtime.InteropServices; -using System.Text; using System.Threading.Tasks; using Avalonia.Logging; -using Avalonia.OpenGL.Angle; -using Avalonia.OpenGL.Egl; using Avalonia.Rendering; -using Avalonia.Win32.OpenGl.Angle; using static Avalonia.Win32.Interop.UnmanagedMethods; using static Avalonia.Win32.DirectX.DirectXUnmanagedMethods; using MicroCom.Runtime; namespace Avalonia.Win32.DirectX { -#pragma warning disable CA1416 // This should only be reachable on Windows -#nullable enable - public unsafe class DxgiConnection : IRenderTimer + internal unsafe class DxgiConnection : IRenderTimer { public const uint ENUM_CURRENT_SETTINGS = unchecked((uint)(-1)); public bool RunsInBackground => true; public event Action? Tick; - private object _syncLock; + private readonly object _syncLock; - private IDXGIOutput? _output = null; + private IDXGIOutput? _output; - private Stopwatch? _stopwatch = null; + private Stopwatch? _stopwatch; private const string LogArea = "DXGI"; public DxgiConnection(object syncLock) @@ -51,9 +41,9 @@ namespace Avalonia.Win32.DirectX } } - private unsafe void RunLoop() + private void RunLoop() { - _stopwatch = System.Diagnostics.Stopwatch.StartNew(); + _stopwatch = Stopwatch.StartNew(); try { GetBestOutputToVWaitOn(); @@ -162,7 +152,7 @@ namespace Avalonia.Win32.DirectX } // Used the windows composition as a blueprint for this startup/creation - static private bool TryCreateAndRegisterCore() + private static bool TryCreateAndRegisterCore() { var tcs = new TaskCompletionSource(); var pumpLock = new object(); @@ -170,9 +160,7 @@ namespace Avalonia.Win32.DirectX { try { - DxgiConnection connection; - - connection = new DxgiConnection(pumpLock); + var connection = new DxgiConnection(pumpLock); AvaloniaLocator.CurrentMutable.BindToSelf(connection); AvaloniaLocator.CurrentMutable.Bind().ToConstant(connection); @@ -191,6 +179,4 @@ namespace Avalonia.Win32.DirectX return tcs.Task.Result; } } -#nullable restore -#pragma warning restore CA1416 // Validate platform compatibility } diff --git a/src/Windows/Avalonia.Win32/DirectX/DxgiRenderTarget.cs b/src/Windows/Avalonia.Win32/DirectX/DxgiRenderTarget.cs index cb7826e185..513aba4f20 100644 --- a/src/Windows/Avalonia.Win32/DirectX/DxgiRenderTarget.cs +++ b/src/Windows/Avalonia.Win32/DirectX/DxgiRenderTarget.cs @@ -1,40 +1,28 @@ using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Linq; -using System.Runtime.InteropServices; -using System.Text; -using System.Threading.Tasks; -using Avalonia.OpenGL.Angle; using Avalonia.OpenGL.Egl; using Avalonia.OpenGL.Surfaces; using Avalonia.Win32.OpenGl.Angle; using MicroCom.Runtime; -using static Avalonia.OpenGL.Egl.EglGlPlatformSurfaceBase; using static Avalonia.Win32.Interop.UnmanagedMethods; namespace Avalonia.Win32.DirectX { -#pragma warning disable CA1416 // Validate platform compatibility, if you enter this not on windows you have messed up badly -#nullable enable - public unsafe class DxgiRenderTarget : EglPlatformSurfaceRenderTargetBase + internal unsafe class DxgiRenderTarget : EglPlatformSurfaceRenderTargetBase { // DXGI_FORMAT_B8G8R8A8_UNORM is target texture format as per ANGLE documentation public const uint DXGI_USAGE_RENDER_TARGET_OUTPUT = 0x00000020U; + private readonly Guid ID3D11Texture2DGuid = Guid.Parse("6F15AAF2-D208-4E89-9AB4-489535D34F9C"); - private EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo _window; - private DxgiConnection _connection; - private IDXGIDevice? _dxgiDevice = null; - private IDXGIFactory2? _dxgiFactory = null; - private IDXGISwapChain1? _swapChain = null; - private IUnknown? _renderTexture = null; + private readonly EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo _window; + private readonly DxgiConnection _connection; + private readonly IDXGIDevice? _dxgiDevice; + private readonly IDXGIFactory2? _dxgiFactory; + private readonly IDXGISwapChain1? _swapChain; + private readonly uint _flagsUsed; - private Interop.UnmanagedMethods.RECT _clientRect = default; - - private uint _flagsUsed; - - private Guid ID3D11Texture2DGuid = Guid.Parse("6F15AAF2-D208-4E89-9AB4-489535D34F9C"); + private IUnknown? _renderTexture; + private RECT _clientRect; public DxgiRenderTarget(EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo window, EglContext context, DxgiConnection connection) : base(context) { @@ -80,11 +68,11 @@ namespace Avalonia.Win32.DirectX null ); - Interop.UnmanagedMethods.RECT pClientRect; - GetClientRect(_window.Handle, out pClientRect); + GetClientRect(_window.Handle, out var pClientRect); _clientRect = pClientRect; } + /// public override IGlPlatformSurfaceRenderingSession BeginDrawCore() { if (_swapChain is null) @@ -98,8 +86,7 @@ namespace Avalonia.Win32.DirectX var success = false; try { - Interop.UnmanagedMethods.RECT pClientRect; - GetClientRect(_window.Handle, out pClientRect); + GetClientRect(_window.Handle, out var pClientRect); if (!RectsEqual(pClientRect, _clientRect)) { // we gotta resize @@ -137,7 +124,7 @@ namespace Avalonia.Win32.DirectX var res = base.BeginDraw(surface, _window.Size, _window.Scaling, () => { _swapChain.Present((ushort)0U, (ushort)0U); - surface?.Dispose(); + surface.Dispose(); transaction?.Dispose(); contextLock?.Dispose(); }, true); @@ -178,6 +165,4 @@ namespace Avalonia.Win32.DirectX } } -#pragma warning restore CA1416 // Validate platform compatibility -#nullable restore } diff --git a/src/Windows/Avalonia.Win32/DirectX/DxgiSwapchainWindow.cs b/src/Windows/Avalonia.Win32/DirectX/DxgiSwapchainWindow.cs index 88226c5c89..a4c6598473 100644 --- a/src/Windows/Avalonia.Win32/DirectX/DxgiSwapchainWindow.cs +++ b/src/Windows/Avalonia.Win32/DirectX/DxgiSwapchainWindow.cs @@ -9,7 +9,7 @@ using Avalonia.OpenGL.Surfaces; namespace Avalonia.Win32.DirectX { - public class DxgiSwapchainWindow : EglGlPlatformSurfaceBase + internal class DxgiSwapchainWindow : EglGlPlatformSurfaceBase { private DxgiConnection _connection; private EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo _window; diff --git a/src/Windows/Avalonia.Win32/DirectX/directx.idl b/src/Windows/Avalonia.Win32/DirectX/directx.idl index 1d66c898db..120d1d5159 100644 --- a/src/Windows/Avalonia.Win32/DirectX/directx.idl +++ b/src/Windows/Avalonia.Win32/DirectX/directx.idl @@ -36,6 +36,8 @@ @clr-map DXGI_SHARED_RESOURCE void* @clr-map LUID ulong @clr-map LPSTR ushort* +@clr-map LPWSTR ushort* +@clr-map LPCWSTR ushort* enum DXGI_FORMAT @@ -501,6 +503,44 @@ interface ID3D11Device : IUnknown UINT GetExceptionMode(); } +[uuid(a04bfb29-08ef-43d6-a49c-a9bdbdcbe686)] +interface ID3D11Device1 : ID3D11Device +{ + void GetImmediateContext1( void** ppImmediateContext ); + + HRESULT CreateDeferredContext1( + UINT ContextFlags, // Reserved parameter; must be 0 + [out, retval] IUnknown** ppDeferredContext ); + + HRESULT CreateBlendState1( + void* pBlendStateDesc, + [out, retval] IUnknown** ppBlendState ); + + HRESULT CreateRasterizerState1( + void* pRasterizerDesc, + [out, retval] IUnknown** ppRasterizerState ); + + HRESULT CreateDeviceContextState( + UINT Flags, + void* pFeatureLevels, + UINT FeatureLevels, + UINT SDKVersion, + GUID* EmulatedInterface, + void* pChosenFeatureLevel, + [out, retval] IUnknown** ppContextState); + + HRESULT OpenSharedResource1( + IntPtr hResource, + Guid* ReturnedInterface, + [out, retval] IUnknown** ppResource); + + HRESULT OpenSharedResourceByName( + LPCWSTR lpName, + DWORD dwDesiredAccess, + REFIID returnedInterface, + void** ppResource); +}; + [uuid( 6f15aaf2-d208-4e89-9ab4-489535d34f9c)] interface ID3D11Texture2D : IUnknown diff --git a/src/Windows/Avalonia.Win32/FramebufferManager.cs b/src/Windows/Avalonia.Win32/FramebufferManager.cs index 8feecab4dd..cba4879f5b 100644 --- a/src/Windows/Avalonia.Win32/FramebufferManager.cs +++ b/src/Windows/Avalonia.Win32/FramebufferManager.cs @@ -4,8 +4,6 @@ using Avalonia.Controls.Platform.Surfaces; using Avalonia.Platform; using Avalonia.Win32.Interop; -#nullable enable - namespace Avalonia.Win32 { internal class FramebufferManager : IFramebufferPlatformSurface, IDisposable diff --git a/src/Windows/Avalonia.Win32/Input/Imm32InputMethod.cs b/src/Windows/Avalonia.Win32/Input/Imm32InputMethod.cs index 7ef1cb1d1c..41417dd950 100644 --- a/src/Windows/Avalonia.Win32/Input/Imm32InputMethod.cs +++ b/src/Windows/Avalonia.Win32/Input/Imm32InputMethod.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics.CodeAnalysis; using System.Text; using Avalonia.Input.TextInput; using Avalonia.Threading; @@ -10,21 +11,21 @@ namespace Avalonia.Win32.Input /// /// A Windows input method editor based on Windows Input Method Manager (IMM32). /// - class Imm32InputMethod : ITextInputMethodImpl + internal class Imm32InputMethod : ITextInputMethodImpl { - public IntPtr HWND { get; private set; } + public IntPtr Hwnd { get; private set; } private IntPtr _currentHimc; - private WindowImpl _parent; - private ITextInputMethodClient _client; + private WindowImpl? _parent; - private Imm32CaretManager _caretManager = new(); + private Imm32CaretManager _caretManager; private ushort _langId; - private const int _caretMargin = 1; + private const int CaretMargin = 1; - public ITextInputMethodClient Client => _client; + public ITextInputMethodClient? Client { get; private set; } - public bool IsActive => _client != null; + [MemberNotNullWhen(true, nameof(Client))] + public bool IsActive => Client != null; public bool IsComposing { get; set; } @@ -32,12 +33,12 @@ namespace Avalonia.Win32.Input public void CreateCaret() { - _caretManager.TryCreate(HWND); + _caretManager.TryCreate(Hwnd); } public void EnableImm() { - var himc = ImmGetContext(HWND); + var himc = ImmGetContext(Hwnd); if(himc == IntPtr.Zero) { @@ -51,13 +52,13 @@ namespace Avalonia.Win32.Input DisableImm(); } - ImmAssociateContext(HWND, himc); + ImmAssociateContext(Hwnd, himc); - ImmReleaseContext(HWND, himc); + ImmReleaseContext(Hwnd, himc); _currentHimc = himc; - _caretManager.TryCreate(HWND); + _caretManager.TryCreate(Hwnd); } } @@ -67,7 +68,7 @@ namespace Avalonia.Win32.Input Reset(); - ImmAssociateContext(HWND, IntPtr.Zero); + ImmAssociateContext(Hwnd, IntPtr.Zero); _caretManager.TryDestroy(); @@ -76,7 +77,7 @@ namespace Avalonia.Win32.Input public void SetLanguageAndWindow(WindowImpl parent, IntPtr hwnd, IntPtr HKL) { - HWND = hwnd; + Hwnd = hwnd; _parent = parent; _langId = PRIMARYLANGID(LGID(HKL)); @@ -98,9 +99,9 @@ namespace Avalonia.Win32.Input { DisableImm(); - HWND = IntPtr.Zero; + Hwnd = IntPtr.Zero; _parent = null; - _client = null; + Client = null; _langId = 0; IsComposing = false; @@ -108,13 +109,13 @@ namespace Avalonia.Win32.Input //Dependant on CurrentThread. When Avalonia will support Multiple Dispatchers - //every Dispatcher should have their own InputMethod. - public static Imm32InputMethod Current { get; } = new Imm32InputMethod(); + public static Imm32InputMethod Current { get; } = new(); public void Reset() { Dispatcher.UIThread.Post(() => { - var himc = ImmGetContext(HWND); + var himc = ImmGetContext(Hwnd); if (IsComposing) { @@ -123,13 +124,13 @@ namespace Avalonia.Win32.Input IsComposing = false; } - ImmReleaseContext(HWND, himc); + ImmReleaseContext(Hwnd, himc); }); } - public void SetClient(ITextInputMethodClient client) + public void SetClient(ITextInputMethodClient? client) { - _client = client; + Client = client; Dispatcher.UIThread.Post(() => { @@ -152,7 +153,7 @@ namespace Avalonia.Win32.Input public void SetCursorRect(Rect rect) { - var focused = GetActiveWindow() == HWND; + var focused = GetActiveWindow() == Hwnd; if (!focused) { @@ -161,7 +162,7 @@ namespace Avalonia.Win32.Input Dispatcher.UIThread.Post(() => { - var himc = ImmGetContext(HWND); + var himc = ImmGetContext(Hwnd); if (himc == IntPtr.Zero) { @@ -170,7 +171,7 @@ namespace Avalonia.Win32.Input MoveImeWindow(rect, himc); - ImmReleaseContext(HWND, himc); + ImmReleaseContext(Hwnd, himc); }); } @@ -219,7 +220,7 @@ namespace Avalonia.Win32.Input // the caret to move the position of their candidate windows. // On the other hand, Korean IMEs require the lower-left corner of the // caret to move their candidate windows. - y2 += _caretMargin; + y2 += CaretMargin; } // Need to return here since some Chinese IMEs would stuck if set @@ -238,7 +239,7 @@ namespace Avalonia.Win32.Input dwIndex = 0, dwStyle = CFS_EXCLUDE, ptCurrentPos = new POINT {X = x1, Y = y1}, - rcArea = new RECT {left = x1, top = y1, right = x2, bottom = y2 + _caretMargin} + rcArea = new RECT {left = x1, top = y1, right = x2, bottom = y2 + CaretMargin} }; ImmSetCandidateWindow(himc, ref excludeRectangle); @@ -275,34 +276,21 @@ namespace Avalonia.Win32.Input return; } - if(!IsActive || !_client.SupportsPreedit) + if(!IsActive || !Client.SupportsPreedit) { return; } var composition = GetCompositionString(); - _client.SetPreeditText(composition); + Client.SetPreeditText(composition); } - private string GetCompositionString() + private string? GetCompositionString() { - var himc = ImmGetContext(HWND); + var himc = ImmGetContext(Hwnd); - var length = ImmGetCompositionString(himc, GCS.GCS_COMPSTR, IntPtr.Zero, 0); - - var buffer = new byte[length]; - - unsafe - { - fixed (byte* bufferPtr = buffer) - { - var error = ImmGetCompositionString(himc, GCS.GCS_COMPSTR, (IntPtr)bufferPtr, (uint)length); - - return Encoding.Unicode.GetString(buffer, 0, buffer.Length); - } - } - + return ImmGetCompositionString(himc, GCS.GCS_COMPSTR); } ~Imm32InputMethod() diff --git a/src/Windows/Avalonia.Win32/Input/WindowsMouseDevice.cs b/src/Windows/Avalonia.Win32/Input/WindowsMouseDevice.cs index 998ff4a427..c7bc511b99 100644 --- a/src/Windows/Avalonia.Win32/Input/WindowsMouseDevice.cs +++ b/src/Windows/Avalonia.Win32/Input/WindowsMouseDevice.cs @@ -5,9 +5,10 @@ using Avalonia.Win32.Interop; namespace Avalonia.Win32.Input { - class WindowsMouseDevice : MouseDevice + internal class WindowsMouseDevice : MouseDevice { private readonly IPointer _pointer; + public WindowsMouseDevice() : base(WindowsMousePointer.CreatePointer(out var pointer)) { _pointer = pointer; @@ -15,14 +16,14 @@ namespace Avalonia.Win32.Input // Normally user should use IPointer.Capture instead of MouseDevice.Capture, // But on Windows we need to handle WM_MOUSE capture manually without having access to the Pointer. - internal void Capture(IInputElement control) + internal void Capture(IInputElement? control) { _pointer.Capture(control); } internal class WindowsMousePointer : Pointer { - private WindowsMousePointer() : base(Pointer.GetNextFreeId(),PointerType.Mouse, true) + private WindowsMousePointer() : base(GetNextFreeId(),PointerType.Mouse, true) { } @@ -31,7 +32,7 @@ namespace Avalonia.Win32.Input return pointer = new WindowsMousePointer(); } - protected override void PlatformCapture(IInputElement element) + protected override void PlatformCapture(IInputElement? element) { var hwnd = (TopLevel.GetTopLevel(element as Visual)?.PlatformImpl as WindowImpl) ?.Handle.Handle; diff --git a/src/Windows/Avalonia.Win32/Interop/Automation/IGridProvider.cs b/src/Windows/Avalonia.Win32/Interop/Automation/IGridProvider.cs index a8caf26524..be8b998a9e 100644 --- a/src/Windows/Avalonia.Win32/Interop/Automation/IGridProvider.cs +++ b/src/Windows/Avalonia.Win32/Interop/Automation/IGridProvider.cs @@ -1,4 +1,3 @@ -using System; using System.Runtime.InteropServices; namespace Avalonia.Win32.Interop.Automation @@ -8,7 +7,7 @@ namespace Avalonia.Win32.Interop.Automation [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IGridProvider { - IRawElementProviderSimple GetItem(int row, int column); + IRawElementProviderSimple? GetItem(int row, int column); int RowCount { get; } int ColumnCount { get; } } diff --git a/src/Windows/Avalonia.Win32/Interop/Automation/IRawElementProviderFragment.cs b/src/Windows/Avalonia.Win32/Interop/Automation/IRawElementProviderFragment.cs index a62aa842cb..46d8dc6cdb 100644 --- a/src/Windows/Avalonia.Win32/Interop/Automation/IRawElementProviderFragment.cs +++ b/src/Windows/Avalonia.Win32/Interop/Automation/IRawElementProviderFragment.cs @@ -1,8 +1,6 @@ using System; using System.Runtime.InteropServices; -#nullable enable - namespace Avalonia.Win32.Interop.Automation { [ComVisible(true)] diff --git a/src/Windows/Avalonia.Win32/Interop/Automation/IRawElementProviderFragmentRoot.cs b/src/Windows/Avalonia.Win32/Interop/Automation/IRawElementProviderFragmentRoot.cs index 71d1bdce60..1fd0cb13ba 100644 --- a/src/Windows/Avalonia.Win32/Interop/Automation/IRawElementProviderFragmentRoot.cs +++ b/src/Windows/Avalonia.Win32/Interop/Automation/IRawElementProviderFragmentRoot.cs @@ -1,4 +1,3 @@ -using System; using System.Runtime.InteropServices; namespace Avalonia.Win32.Interop.Automation @@ -8,7 +7,7 @@ namespace Avalonia.Win32.Interop.Automation [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IRawElementProviderFragmentRoot : IRawElementProviderFragment { - IRawElementProviderFragment ElementProviderFromPoint(double x, double y); - IRawElementProviderFragment GetFocus(); + IRawElementProviderFragment? ElementProviderFromPoint(double x, double y); + IRawElementProviderFragment? GetFocus(); } } diff --git a/src/Windows/Avalonia.Win32/Interop/Automation/IRawElementProviderSimple.cs b/src/Windows/Avalonia.Win32/Interop/Automation/IRawElementProviderSimple.cs index 439036290e..5b67d10206 100644 --- a/src/Windows/Avalonia.Win32/Interop/Automation/IRawElementProviderSimple.cs +++ b/src/Windows/Avalonia.Win32/Interop/Automation/IRawElementProviderSimple.cs @@ -1,8 +1,6 @@ using System; using System.Runtime.InteropServices; -#nullable enable - namespace Avalonia.Win32.Interop.Automation { [Flags] diff --git a/src/Windows/Avalonia.Win32/Interop/Automation/IRawElementProviderSimple2.cs b/src/Windows/Avalonia.Win32/Interop/Automation/IRawElementProviderSimple2.cs index f3504b8d77..c2e8a42f87 100644 --- a/src/Windows/Avalonia.Win32/Interop/Automation/IRawElementProviderSimple2.cs +++ b/src/Windows/Avalonia.Win32/Interop/Automation/IRawElementProviderSimple2.cs @@ -1,7 +1,4 @@ -using System; -using System.Runtime.InteropServices; - -#nullable enable +using System.Runtime.InteropServices; namespace Avalonia.Win32.Interop.Automation { diff --git a/src/Windows/Avalonia.Win32/Interop/Automation/ISelectionItemProvider.cs b/src/Windows/Avalonia.Win32/Interop/Automation/ISelectionItemProvider.cs index 8d6677315c..072e210027 100644 --- a/src/Windows/Avalonia.Win32/Interop/Automation/ISelectionItemProvider.cs +++ b/src/Windows/Avalonia.Win32/Interop/Automation/ISelectionItemProvider.cs @@ -1,5 +1,3 @@ -#nullable enable -using System; using System.Runtime.InteropServices; namespace Avalonia.Win32.Interop.Automation diff --git a/src/Windows/Avalonia.Win32/Interop/Automation/IValueProvider.cs b/src/Windows/Avalonia.Win32/Interop/Automation/IValueProvider.cs index 919be647f8..0356f93ab8 100644 --- a/src/Windows/Avalonia.Win32/Interop/Automation/IValueProvider.cs +++ b/src/Windows/Avalonia.Win32/Interop/Automation/IValueProvider.cs @@ -1,8 +1,5 @@ -using System; using System.Runtime.InteropServices; -#nullable enable - namespace Avalonia.Win32.Interop.Automation { [ComVisible(true)] diff --git a/src/Windows/Avalonia.Win32/Interop/Automation/UiaCoreProviderApi.cs b/src/Windows/Avalonia.Win32/Interop/Automation/UiaCoreProviderApi.cs index 4ba7a710d4..bd939c56b7 100644 --- a/src/Windows/Avalonia.Win32/Interop/Automation/UiaCoreProviderApi.cs +++ b/src/Windows/Avalonia.Win32/Interop/Automation/UiaCoreProviderApi.cs @@ -71,21 +71,21 @@ namespace Avalonia.Win32.Interop.Automation public static extern bool UiaClientsAreListening(); [DllImport("UIAutomationCore.dll", CharSet = CharSet.Unicode)] - public static extern IntPtr UiaReturnRawElementProvider(IntPtr hwnd, IntPtr wParam, IntPtr lParam, IRawElementProviderSimple el); + public static extern IntPtr UiaReturnRawElementProvider(IntPtr hwnd, IntPtr wParam, IntPtr lParam, IRawElementProviderSimple? el); [DllImport("UIAutomationCore.dll", CharSet = CharSet.Unicode)] public static extern int UiaHostProviderFromHwnd(IntPtr hwnd, [MarshalAs(UnmanagedType.Interface)] out IRawElementProviderSimple provider); [DllImport("UIAutomationCore.dll", CharSet = CharSet.Unicode)] - public static extern int UiaRaiseAutomationEvent(IRawElementProviderSimple provider, int id); + public static extern int UiaRaiseAutomationEvent(IRawElementProviderSimple? provider, int id); [DllImport("UIAutomationCore.dll", CharSet = CharSet.Unicode)] - public static extern int UiaRaiseAutomationPropertyChangedEvent(IRawElementProviderSimple provider, int id, object oldValue, object newValue); + public static extern int UiaRaiseAutomationPropertyChangedEvent(IRawElementProviderSimple? provider, int id, object? oldValue, object? newValue); [DllImport("UIAutomationCore.dll", CharSet = CharSet.Unicode)] - public static extern int UiaRaiseStructureChangedEvent(IRawElementProviderSimple provider, StructureChangeType structureChangeType, int[] runtimeId, int runtimeIdLen); + public static extern int UiaRaiseStructureChangedEvent(IRawElementProviderSimple? provider, StructureChangeType structureChangeType, int[]? runtimeId, int runtimeIdLen); [DllImport("UIAutomationCore.dll", CharSet = CharSet.Unicode)] - public static extern int UiaDisconnectProvider(IRawElementProviderSimple provider); + public static extern int UiaDisconnectProvider(IRawElementProviderSimple? provider); } } diff --git a/src/Windows/Avalonia.Win32/Interop/Automation/UiaCoreTypesApi.cs b/src/Windows/Avalonia.Win32/Interop/Automation/UiaCoreTypesApi.cs index 08b3ee32fa..b6b069ac37 100644 --- a/src/Windows/Avalonia.Win32/Interop/Automation/UiaCoreTypesApi.cs +++ b/src/Windows/Avalonia.Win32/Interop/Automation/UiaCoreTypesApi.cs @@ -63,8 +63,8 @@ namespace Avalonia.Win32.Interop.Automation } #endif - var comConfig = AppContext.GetData("System.Runtime.InteropServices.BuiltInComInterop.IsSupported"); - return comConfig == null || bool.Parse(comConfig.ToString()); + var comConfig = AppContext.GetData("System.Runtime.InteropServices.BuiltInComInterop.IsSupported") as string; + return comConfig == null || bool.Parse(comConfig); } [DllImport("UIAutomationCore.dll", EntryPoint = "UiaLookupId", CharSet = CharSet.Unicode)] diff --git a/src/Windows/Avalonia.Win32/Interop/TaskBarList.cs b/src/Windows/Avalonia.Win32/Interop/TaskBarList.cs index 88b907aeec..7eb457480b 100644 --- a/src/Windows/Avalonia.Win32/Interop/TaskBarList.cs +++ b/src/Windows/Avalonia.Win32/Interop/TaskBarList.cs @@ -7,8 +7,8 @@ namespace Avalonia.Win32.Interop internal class TaskBarList { private static IntPtr s_taskBarList; - private static HrInit s_hrInitDelegate; - private static MarkFullscreenWindow s_markFullscreenWindowDelegate; + private static HrInit? s_hrInitDelegate; + private static MarkFullscreenWindow? s_markFullscreenWindowDelegate; /// /// Ported from https://github.com/chromium/chromium/blob/master/ui/views/win/fullscreen_handler.cc @@ -28,10 +28,7 @@ namespace Avalonia.Win32.Interop { var ptr = (ITaskBarList2VTable**)s_taskBarList.ToPointer(); - if (s_hrInitDelegate is null) - { - s_hrInitDelegate = Marshal.GetDelegateForFunctionPointer((*ptr)->HrInit); - } + s_hrInitDelegate ??= Marshal.GetDelegateForFunctionPointer((*ptr)->HrInit); if (s_hrInitDelegate(s_taskBarList) != HRESULT.S_OK) { @@ -44,10 +41,8 @@ namespace Avalonia.Win32.Interop { var ptr = (ITaskBarList2VTable**)s_taskBarList.ToPointer(); - if (s_markFullscreenWindowDelegate is null) - { - s_markFullscreenWindowDelegate = Marshal.GetDelegateForFunctionPointer((*ptr)->MarkFullscreenWindow); - } + s_markFullscreenWindowDelegate ??= + Marshal.GetDelegateForFunctionPointer((*ptr)->MarkFullscreenWindow); s_markFullscreenWindowDelegate(s_taskBarList, hwnd, fullscreen); } diff --git a/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs b/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs index 672f3a781a..1dd2ef20c7 100644 --- a/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs +++ b/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs @@ -1,14 +1,12 @@ +#nullable enable + using System; using System.ComponentModel; using System.Diagnostics.CodeAnalysis; -using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; using System.Text; - -using Avalonia.MicroCom; using MicroCom.Runtime; -using Avalonia.Win32.Win32Com; // ReSharper disable InconsistentNaming #pragma warning disable 169, 649 @@ -1092,7 +1090,7 @@ namespace Avalonia.Win32.Interop public const int SizeOf_BITMAPINFOHEADER = 40; [DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto, SetLastError = true)] - unsafe internal static extern int GetMouseMovePointsEx( + internal static extern int GetMouseMovePointsEx( uint cbSize, MOUSEMOVEPOINT* pointsIn, MOUSEMOVEPOINT* pointsBufferOut, int nBufPoints, uint resolution); @@ -1167,7 +1165,7 @@ namespace Avalonia.Win32.Interop public static extern IntPtr CreateWindowEx( int dwExStyle, uint lpClassName, - string lpWindowName, + string? lpWindowName, uint dwStyle, int x, int y, @@ -1218,7 +1216,7 @@ namespace Avalonia.Win32.Interop public static extern int GetMessageTime(); [DllImport("kernel32.dll")] - public static extern IntPtr GetModuleHandle(string lpModuleName); + public static extern IntPtr GetModuleHandle(string? lpModuleName); [DllImport("user32.dll")] public static extern int GetSystemMetrics(SystemMetric smIndex); @@ -1255,7 +1253,7 @@ namespace Avalonia.Win32.Interop } else { - return (uint)SetWindowLong64b(hWnd, nIndex, new IntPtr((uint)value)).ToInt32(); + return (uint)SetWindowLong64b(hWnd, nIndex, new IntPtr(value)).ToInt32(); } } @@ -1421,7 +1419,7 @@ namespace Avalonia.Win32.Interop public static extern bool UnregisterClass(string lpClassName, IntPtr hInstance); [DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Unicode, EntryPoint = "SetWindowTextW")] - public static extern bool SetWindowText(IntPtr hwnd, string lpString); + public static extern bool SetWindowText(IntPtr hwnd, string? lpString); public enum ClassLongIndex : int { @@ -1482,7 +1480,7 @@ namespace Avalonia.Win32.Interop internal static extern int CoCreateInstance(ref Guid clsid, IntPtr ignore1, int ignore2, ref Guid iid, [Out] out IntPtr pUnkOuter); - internal unsafe static T CreateInstance(ref Guid clsid, ref Guid iid) where T : IUnknown + internal static T CreateInstance(ref Guid clsid, ref Guid iid) where T : IUnknown { var hresult = CoCreateInstance(ref clsid, IntPtr.Zero, 1, ref iid, out IntPtr pUnk); if (hresult != 0) @@ -1490,7 +1488,7 @@ namespace Avalonia.Win32.Interop throw new COMException("CreateInstance", hresult); } using var unk = MicroComRuntime.CreateProxyFor(pUnk, true); - return MicroComRuntime.QueryInterface(unk); + return unk.QueryInterface(); } [DllImport("shell32.dll", CharSet = CharSet.Unicode, SetLastError = true)] @@ -1581,7 +1579,7 @@ namespace Avalonia.Win32.Interop public static extern bool GetMonitorInfo([In] IntPtr hMonitor, ref MONITORINFO lpmi); [DllImport("user32")] - public static extern unsafe bool GetTouchInputInfo( + public static extern bool GetTouchInputInfo( IntPtr hTouchInput, uint cInputs, TOUCHINPUT* pInputs, @@ -1680,7 +1678,7 @@ namespace Avalonia.Win32.Interop public static extern IntPtr GlobalSize(IntPtr hGlobal); [DllImport("shell32.dll", BestFitMapping = false, CharSet = CharSet.Auto)] - public static extern int DragQueryFile(IntPtr hDrop, int iFile, StringBuilder lpszFile, int cch); + public static extern int DragQueryFile(IntPtr hDrop, int iFile, StringBuilder? lpszFile, int cch); [DllImport("ole32.dll", CharSet = CharSet.Auto, ExactSpelling = true, PreserveSig = false)] internal static extern void DoDragDrop(IntPtr dataObject, IntPtr dropSource, int allowedEffects, [Out] out int finalEffect); @@ -1734,7 +1732,7 @@ namespace Avalonia.Win32.Interop public DWM_BLURBEHIND(bool enabled) { - fEnable = enabled ? true : false; + fEnable = enabled; hRgnBlur = IntPtr.Zero; fTransitionOnMaximized = false; dwFlags = DWM_BB.Enable; @@ -1855,20 +1853,22 @@ namespace Avalonia.Win32.Interop [DllImport("imm32.dll", SetLastError = false, CharSet = CharSet.Unicode)] public static extern int ImmGetCompositionString(IntPtr hIMC, GCS dwIndex, [Out, Optional] IntPtr lpBuf, uint dwBufLen); - public static string ImmGetCompositionString(IntPtr hIMC, GCS dwIndex) + public static string? ImmGetCompositionString(IntPtr hIMC, GCS dwIndex) { int bufferLength = ImmGetCompositionString(hIMC, dwIndex, IntPtr.Zero, 0); if (bufferLength > 0) { - var buffer = new byte[bufferLength]; + var buffer = bufferLength <= 64 ? stackalloc byte[bufferLength] : new byte[bufferLength]; - fixed(byte* bufferPtr = buffer) + fixed (byte* bufferPtr = buffer) { - var error = ImmGetCompositionString(hIMC, dwIndex, (IntPtr)bufferPtr, (uint)bufferLength); - - return Marshal.PtrToStringUni((IntPtr)bufferPtr); - } + var result = ImmGetCompositionString(hIMC, dwIndex, (IntPtr)bufferPtr, (uint)bufferLength); + if (result >= 0) + { + return Marshal.PtrToStringUni((IntPtr)bufferPtr); + } + } } return null; @@ -2380,7 +2380,7 @@ namespace Avalonia.Win32.Interop } } - [StructLayoutAttribute(LayoutKind.Sequential)] + [StructLayout(LayoutKind.Sequential)] internal struct _DROPFILES { public Int32 pFiles; @@ -2390,7 +2390,7 @@ namespace Avalonia.Win32.Interop public bool fWide; } - [StructLayoutAttribute(LayoutKind.Sequential)] + [StructLayout(LayoutKind.Sequential)] internal struct STGMEDIUM { public TYMED tymed; @@ -2398,7 +2398,7 @@ namespace Avalonia.Win32.Interop public IntPtr pUnkForRelease; } - [StructLayoutAttribute(LayoutKind.Sequential)] + [StructLayout(LayoutKind.Sequential)] internal struct FORMATETC { public ushort cfFormat; @@ -2507,14 +2507,14 @@ namespace Avalonia.Win32.Interop public int uCallbackMessage; public IntPtr hIcon; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)] - public string szTip; + public string? szTip; public int dwState = 0; public int dwStateMask = 0; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)] - public string szInfo; + public string? szInfo; public int uTimeoutOrVersion; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] - public string szInfoTitle; + public string? szInfoTitle; public NIIF dwInfoFlags; } } diff --git a/src/Windows/Avalonia.Win32/NonPumpingSyncContext.cs b/src/Windows/Avalonia.Win32/NonPumpingSyncContext.cs index f295dd7394..2c4d2c9468 100644 --- a/src/Windows/Avalonia.Win32/NonPumpingSyncContext.cs +++ b/src/Windows/Avalonia.Win32/NonPumpingSyncContext.cs @@ -1,7 +1,6 @@ using System; using System.Runtime.ConstrainedExecution; using System.Threading; -using Avalonia.Threading; using Avalonia.Utilities; using Avalonia.Win32.Interop; @@ -9,17 +8,42 @@ namespace Avalonia.Win32 { internal class NonPumpingSyncContext : SynchronizationContext, IDisposable { - private readonly SynchronizationContext _inner; + private readonly SynchronizationContext? _inner; - private NonPumpingSyncContext(SynchronizationContext inner) + private NonPumpingSyncContext(SynchronizationContext? inner) { _inner = inner; SetWaitNotificationRequired(); SetSynchronizationContext(this); } - public override void Post(SendOrPostCallback d, object state) => _inner.Post(d, state); - public override void Send(SendOrPostCallback d, object state) => _inner.Send(d, state); + public override void Post(SendOrPostCallback d, object? state) + { + if (_inner is null) + { +#if NET6_0_OR_GREATER + ThreadPool.QueueUserWorkItem(static x => x.d(x.state), (d, state), false); +#else + ThreadPool.QueueUserWorkItem(_ => d(state)); +#endif + } + else + { + _inner.Post(d, state); + } + } + + public override void Send(SendOrPostCallback d, object? state) + { + if (_inner is null) + { + d(state); + } + else + { + _inner.Send(d, state); + } + } #if !NET6_0_OR_GREATER [PrePrepareMethod] @@ -32,7 +56,7 @@ namespace Avalonia.Win32 public void Dispose() => SetSynchronizationContext(_inner); - public static IDisposable Use() + public static IDisposable? Use() { var current = Current; if (current == null) @@ -42,13 +66,13 @@ namespace Avalonia.Win32 } if (current is NonPumpingSyncContext) return null; - + return new NonPumpingSyncContext(current); } internal class HelperImpl : NonPumpingLockHelper.IHelperImpl { - IDisposable NonPumpingLockHelper.IHelperImpl.Use() => NonPumpingSyncContext.Use(); + IDisposable? NonPumpingLockHelper.IHelperImpl.Use() => NonPumpingSyncContext.Use(); } } } diff --git a/src/Windows/Avalonia.Win32/OffscreenParentWindow.cs b/src/Windows/Avalonia.Win32/OffscreenParentWindow.cs index 9de105a3d5..7253b3c0ed 100644 --- a/src/Windows/Avalonia.Win32/OffscreenParentWindow.cs +++ b/src/Windows/Avalonia.Win32/OffscreenParentWindow.cs @@ -1,17 +1,18 @@ using System; using System.ComponentModel; using System.Runtime.InteropServices; -using Avalonia.Platform; using Avalonia.Win32.Interop; namespace Avalonia.Win32 { - class OffscreenParentWindow + internal class OffscreenParentWindow { public static IntPtr Handle { get; } = CreateParentWindow(); - private static UnmanagedMethods.WndProc s_wndProcDelegate; + + private static UnmanagedMethods.WndProc? s_wndProcDelegate; + private static IntPtr CreateParentWindow() { - s_wndProcDelegate = new UnmanagedMethods.WndProc(ParentWndProc); + s_wndProcDelegate = ParentWndProc; var wndClassEx = new UnmanagedMethods.WNDCLASSEX { diff --git a/src/Windows/Avalonia.Win32/OleContext.cs b/src/Windows/Avalonia.Win32/OleContext.cs index e41423a334..897033e835 100644 --- a/src/Windows/Avalonia.Win32/OleContext.cs +++ b/src/Windows/Avalonia.Win32/OleContext.cs @@ -11,18 +11,16 @@ namespace Avalonia.Win32 { internal class OleContext { - private static OleContext s_current; + private static OleContext? s_current; - internal static OleContext Current + internal static OleContext? Current { get { if (!IsValidOleThread()) return null; - if (s_current == null) - s_current = new OleContext(); - return s_current; + return s_current ??= new OleContext(); } } @@ -41,7 +39,7 @@ namespace Avalonia.Win32 Thread.CurrentThread.GetApartmentState() == ApartmentState.STA; } - internal bool RegisterDragDrop(IPlatformHandle hwnd, IDropTarget target) + internal bool RegisterDragDrop(IPlatformHandle? hwnd, IDropTarget? target) { if (hwnd?.HandleDescriptor != "HWND" || target == null) { @@ -52,7 +50,7 @@ namespace Avalonia.Win32 return UnmanagedMethods.RegisterDragDrop(hwnd.Handle, trgPtr) == UnmanagedMethods.HRESULT.S_OK; } - internal bool UnregisterDragDrop(IPlatformHandle hwnd) + internal bool UnregisterDragDrop(IPlatformHandle? hwnd) { if (hwnd?.HandleDescriptor != "HWND") { diff --git a/src/Windows/Avalonia.Win32/OleDataObject.cs b/src/Windows/Avalonia.Win32/OleDataObject.cs index 79b55e4f77..247d0340c3 100644 --- a/src/Windows/Avalonia.Win32/OleDataObject.cs +++ b/src/Windows/Avalonia.Win32/OleDataObject.cs @@ -8,7 +8,6 @@ using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; using System.Runtime.Serialization.Formatters.Binary; using Avalonia.Input; -using Avalonia.MicroCom; using Avalonia.Utilities; using Avalonia.Win32.Interop; using MicroCom.Runtime; @@ -35,23 +34,23 @@ namespace Avalonia.Win32 return GetDataFormatsCore().Distinct(); } - public string GetText() + public string? GetText() { - return (string)GetDataFromOleHGLOBAL(DataFormats.Text, DVASPECT.DVASPECT_CONTENT); + return (string?)GetDataFromOleHGLOBAL(DataFormats.Text, DVASPECT.DVASPECT_CONTENT); } - public IEnumerable GetFileNames() + public IEnumerable? GetFileNames() { - return (IEnumerable)GetDataFromOleHGLOBAL(DataFormats.FileNames, DVASPECT.DVASPECT_CONTENT); + return (IEnumerable?)GetDataFromOleHGLOBAL(DataFormats.FileNames, DVASPECT.DVASPECT_CONTENT); } - public object Get(string dataFormat) + public object? Get(string dataFormat) { return GetDataFromOleHGLOBAL(dataFormat, DVASPECT.DVASPECT_CONTENT); } [UnconditionalSuppressMessage("Trimming", "IL2026", Justification = "We still use BinaryFormatter for WinForms dragndrop compatability")] - private unsafe object GetDataFromOleHGLOBAL(string format, DVASPECT aspect) + private unsafe object? GetDataFromOleHGLOBAL(string format, DVASPECT aspect) { var formatEtc = new Interop.FORMATETC(); formatEtc.cfFormat = ClipboardFormats.GetFormat(format); @@ -100,7 +99,7 @@ namespace Avalonia.Win32 private static IEnumerable ReadFileNamesFromHGlobal(IntPtr hGlobal) { - List files = new List(); + var files = new List(); int fileCount = UnmanagedMethods.DragQueryFile(hGlobal, -1, null, 0); if (fileCount > 0) { @@ -118,7 +117,7 @@ namespace Avalonia.Win32 return files; } - private static string ReadStringFromHGlobal(IntPtr hGlobal) + private static string? ReadStringFromHGlobal(IntPtr hGlobal) { IntPtr ptr = UnmanagedMethods.GlobalLock(hGlobal); try diff --git a/src/Windows/Avalonia.Win32/OleDropTarget.cs b/src/Windows/Avalonia.Win32/OleDropTarget.cs index 8bbdfe5fd9..a81652ffc2 100644 --- a/src/Windows/Avalonia.Win32/OleDropTarget.cs +++ b/src/Windows/Avalonia.Win32/OleDropTarget.cs @@ -1,5 +1,5 @@ using System; - +using System.Diagnostics.CodeAnalysis; using Avalonia.Input; using Avalonia.Input.Raw; using Avalonia.MicroCom; @@ -13,16 +13,16 @@ namespace Avalonia.Win32 internal class OleDropTarget : CallbackBase, Win32Com.IDropTarget { private readonly IInputRoot _target; - private readonly ITopLevelImpl _tl; + private readonly ITopLevelImpl _topLevel; private readonly IDragDropDevice _dragDevice; - private IDataObject _currentDrag = null; + private IDataObject? _currentDrag; - public OleDropTarget(ITopLevelImpl tl, IInputRoot target) + public OleDropTarget(ITopLevelImpl topLevel, IInputRoot target, IDragDropDevice dragDevice) { - _dragDevice = AvaloniaLocator.Current.GetService(); - _tl = tl; + _topLevel = topLevel; _target = target; + _dragDevice = dragDevice; } public static DropEffect ConvertDropEffect(DragDropEffects operation) @@ -71,10 +71,11 @@ namespace Avalonia.Win32 unsafe void Win32Com.IDropTarget.DragEnter(Win32Com.IDataObject pDataObj, int grfKeyState, UnmanagedMethods.POINT pt, DropEffect* pdwEffect) { - var dispatch = _tl?.Input; + var dispatch = _topLevel.Input; if (dispatch == null) { *pdwEffect= (int)DropEffect.None; + return; } SetDataObject(pDataObj); @@ -94,10 +95,11 @@ namespace Avalonia.Win32 unsafe void Win32Com.IDropTarget.DragOver(int grfKeyState, UnmanagedMethods.POINT pt, DropEffect* pdwEffect) { - var dispatch = _tl?.Input; - if (dispatch == null) + var dispatch = _topLevel.Input; + if (dispatch == null || _currentDrag is null) { *pdwEffect = (int)DropEffect.None; + return; } var args = new RawDragEvent( @@ -115,14 +117,20 @@ namespace Avalonia.Win32 void Win32Com.IDropTarget.DragLeave() { + var dispatch = _topLevel.Input; + if (dispatch == null || _currentDrag is null) + { + return; + } + try { - _tl?.Input(new RawDragEvent( + dispatch(new RawDragEvent( _dragDevice, RawDragEventType.DragLeave, _target, default, - null, + _currentDrag, DragDropEffects.None, RawInputModifiers.None )); @@ -137,10 +145,11 @@ namespace Avalonia.Win32 { try { - var dispatch = _tl?.Input; + var dispatch = _topLevel.Input; if (dispatch == null) { *pdwEffect = (int)DropEffect.None; + return; } SetDataObject(pDataObj); @@ -163,6 +172,7 @@ namespace Avalonia.Win32 } } + [MemberNotNull(nameof(_currentDrag))] private void SetDataObject(Win32Com.IDataObject pDataObj) { var newDrag = GetAvaloniaObjectFromCOM(pDataObj); @@ -178,9 +188,9 @@ namespace Avalonia.Win32 // OleDataObject keeps COM reference, so it should be disposed. if (_currentDrag is OleDataObject oleDragSource) { - oleDragSource?.Dispose(); - _currentDrag = null; + oleDragSource.Dispose(); } + _currentDrag = null; } private Point GetDragLocation(UnmanagedMethods.POINT dragPoint) @@ -194,7 +204,7 @@ namespace Avalonia.Win32 ReleaseDataObject(); } - public static unsafe IDataObject GetAvaloniaObjectFromCOM(Win32Com.IDataObject pDataObj) + public static IDataObject GetAvaloniaObjectFromCOM(Win32Com.IDataObject pDataObj) { if (pDataObj is null) { @@ -205,8 +215,7 @@ namespace Avalonia.Win32 return disposableDataObject; } - var dataObject = MicroComRuntime.TryUnwrapManagedObject(pDataObj) as DataObject; - if (dataObject is not null) + if (MicroComRuntime.TryUnwrapManagedObject(pDataObj) is DataObject dataObject) { return dataObject; } diff --git a/src/Windows/Avalonia.Win32/OpenGl/Angle/AngleD3DTextureFeature.cs b/src/Windows/Avalonia.Win32/OpenGl/Angle/AngleD3DTextureFeature.cs index 6c951010c8..ffdd4fdfd6 100644 --- a/src/Windows/Avalonia.Win32/OpenGl/Angle/AngleD3DTextureFeature.cs +++ b/src/Windows/Avalonia.Win32/OpenGl/Angle/AngleD3DTextureFeature.cs @@ -14,7 +14,7 @@ internal class AngleD3DTextureFeature : IGlPlatformSurfaceRenderTargetFactory Display: AngleWin32EglDisplay { PlatformApi: AngleOptions.PlatformApi.DirectX11 } } && surface is IDirect3D11TexturePlatformSurface; - class RenderTargetWrapper : EglPlatformSurfaceRenderTargetBase + private class RenderTargetWrapper : EglPlatformSurfaceRenderTargetBase { private readonly AngleWin32EglDisplay _angle; private readonly IDirect3D11TextureRenderTarget _target; @@ -31,8 +31,8 @@ internal class AngleD3DTextureFeature : IGlPlatformSurfaceRenderTargetFactory { var success = false; var contextLock = Context.EnsureCurrent(); - IDirect3D11TextureRenderTargetRenderSession session = null; - EglSurface surface = null; + IDirect3D11TextureRenderTargetRenderSession? session = null; + EglSurface? surface = null; try { try diff --git a/src/Windows/Avalonia.Win32/OpenGl/Angle/AngleEglInterface.cs b/src/Windows/Avalonia.Win32/OpenGl/Angle/AngleEglInterface.cs index 4e00bc2c72..2fd2e0f33c 100644 --- a/src/Windows/Avalonia.Win32/OpenGl/Angle/AngleEglInterface.cs +++ b/src/Windows/Avalonia.Win32/OpenGl/Angle/AngleEglInterface.cs @@ -22,7 +22,7 @@ namespace Avalonia.OpenGL.Angle } [GetProcAddress("eglCreateDeviceANGLE", true)] - public partial IntPtr CreateDeviceANGLE(int deviceType, IntPtr nativeDevice, int[] attribs); + public partial IntPtr CreateDeviceANGLE(int deviceType, IntPtr nativeDevice, int[]? attribs); [GetProcAddress("eglReleaseDeviceANGLE", true)] public partial void ReleaseDeviceANGLE(IntPtr device); diff --git a/src/Windows/Avalonia.Win32/OpenGl/Angle/AngleExternalD3D11Texture2D.cs b/src/Windows/Avalonia.Win32/OpenGl/Angle/AngleExternalD3D11Texture2D.cs index b0fa76fda2..6bbfde35e1 100644 --- a/src/Windows/Avalonia.Win32/OpenGl/Angle/AngleExternalD3D11Texture2D.cs +++ b/src/Windows/Avalonia.Win32/OpenGl/Angle/AngleExternalD3D11Texture2D.cs @@ -1,8 +1,5 @@ -#nullable enable using System; -using System.Threading; using Avalonia.OpenGL; -using Avalonia.OpenGL.Angle; using Avalonia.OpenGL.Egl; using Avalonia.Platform; using Avalonia.Win32.DirectX; @@ -15,9 +12,12 @@ namespace Avalonia.Win32.OpenGl.Angle; internal class AngleExternalMemoryD3D11Texture2D : IGlExternalImageTexture { private readonly EglContext _context; - private ID3D11Texture2D _texture2D; - private EglSurface _eglSurface; - private IDXGIKeyedMutex _mutex; + private ID3D11Texture2D? _texture2D; + private EglSurface? _eglSurface; + private IDXGIKeyedMutex? _mutex; + + private IDXGIKeyedMutex Mutex + => _mutex ?? throw new ObjectDisposedException(nameof(AngleExternalMemoryD3D11Texture2D)); public unsafe AngleExternalMemoryD3D11Texture2D(EglContext context, ID3D11Texture2D texture2D, PlatformGraphicsExternalImageProperties props) { @@ -40,14 +40,14 @@ internal class AngleExternalMemoryD3D11Texture2D : IGlExternalImageTexture int temp = 0; gl.GenTextures(1, &temp); TextureId = temp; - gl.BindTexture(GlConsts.GL_TEXTURE_2D, TextureId); + gl.BindTexture(GL_TEXTURE_2D, TextureId); if (_context.Display.EglInterface.BindTexImage(_context.Display.Handle, _eglSurface.DangerousGetHandle(), EGL_BACK_BUFFER) == 0) throw OpenGlException.GetFormattedException("eglBindTexImage", _context.Display.EglInterface); } - + public void Dispose() { @@ -56,17 +56,15 @@ internal class AngleExternalMemoryD3D11Texture2D : IGlExternalImageTexture _context.GlInterface.DeleteTexture(TextureId); TextureId = 0; _eglSurface?.Dispose(); - _eglSurface = null!; + _eglSurface = null; _texture2D?.Dispose(); - _texture2D = null!; + _texture2D = null; _mutex?.Dispose(); - _mutex = null!; + _mutex = null; } - - public void AcquireKeyedMutex(uint key) => _mutex.AcquireSync(key, int.MaxValue); - - public void ReleaseKeyedMutex(uint key) => _mutex.ReleaseSync(key); + public void AcquireKeyedMutex(uint key) => Mutex.AcquireSync(key, int.MaxValue); + public void ReleaseKeyedMutex(uint key) => Mutex.ReleaseSync(key); public int TextureId { get; private set; } public int InternalFormat { get; } @@ -75,7 +73,7 @@ internal class AngleExternalMemoryD3D11Texture2D : IGlExternalImageTexture internal class AngleExternalMemoryD3D11ExportedTexture2D : AngleExternalMemoryD3D11Texture2D, IGlExportableExternalImageTexture { - static IPlatformHandle GetHandle(ID3D11Texture2D texture2D) + private static IPlatformHandle GetHandle(ID3D11Texture2D texture2D) { using var resource = texture2D.QueryInterface(); return new PlatformHandle(resource.SharedHandle, diff --git a/src/Windows/Avalonia.Win32/OpenGl/Angle/AngleExternalObjectsFeature.cs b/src/Windows/Avalonia.Win32/OpenGl/Angle/AngleExternalObjectsFeature.cs index a7b52e953e..4526e0e793 100644 --- a/src/Windows/Avalonia.Win32/OpenGl/Angle/AngleExternalObjectsFeature.cs +++ b/src/Windows/Avalonia.Win32/OpenGl/Angle/AngleExternalObjectsFeature.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; -using System.Runtime.CompilerServices; -using Avalonia.Controls.Documents; +using System.Linq; using Avalonia.OpenGL; using Avalonia.OpenGL.Egl; using Avalonia.Platform; @@ -15,12 +14,14 @@ internal class AngleExternalObjectsFeature : IGlContextExternalObjectsFeature, I { private readonly EglContext _context; private readonly ID3D11Device _device; + private readonly ID3D11Device1 _device1; public AngleExternalObjectsFeature(EglContext context) { _context = context; var angle = (AngleWin32EglDisplay)context.Display; _device = MicroComRuntime.CreateProxyFor(angle.GetDirect3DDevice(), false).CloneReference(); + _device1 = _device.QueryInterface(); using var dxgiDevice = _device.QueryInterface(); using var adapter = dxgiDevice.Adapter; DeviceLuid = BitConverter.GetBytes(adapter.Desc.AdapterLuid); @@ -28,7 +29,8 @@ internal class AngleExternalObjectsFeature : IGlContextExternalObjectsFeature, I public IReadOnlyList SupportedImportableExternalImageTypes { get; } = new[] { - KnownPlatformGraphicsExternalImageHandleTypes.D3D11TextureGlobalSharedHandle + KnownPlatformGraphicsExternalImageHandleTypes.D3D11TextureGlobalSharedHandle, + KnownPlatformGraphicsExternalImageHandleTypes.D3D11TextureNtHandle, }; public IReadOnlyList SupportedExportableExternalImageTypes => SupportedImportableExternalImageTypes; @@ -72,13 +74,17 @@ internal class AngleExternalObjectsFeature : IGlContextExternalObjectsFeature, I public unsafe IGlExternalImageTexture ImportImage(IPlatformHandle handle, PlatformGraphicsExternalImageProperties properties) { - if (handle.HandleDescriptor != KnownPlatformGraphicsExternalImageHandleTypes.D3D11TextureGlobalSharedHandle) + if (!SupportedImportableExternalImageTypes.Contains(handle.HandleDescriptor)) throw new NotSupportedException("Unsupported external memory type"); using (_context.EnsureCurrent()) { var guid = MicroComRuntime.GetGuidFor(typeof(ID3D11Texture2D)); - using var opened = _device.OpenSharedResource(handle.Handle, &guid); + using var opened = + handle.HandleDescriptor == + KnownPlatformGraphicsExternalImageHandleTypes.D3D11TextureGlobalSharedHandle ? + _device.OpenSharedResource(handle.Handle, &guid) : + _device1.OpenSharedResource1(handle.Handle, &guid); using var texture = opened.QueryInterface(); return new AngleExternalMemoryD3D11Texture2D(_context, texture, properties); } @@ -93,8 +99,8 @@ internal class AngleExternalObjectsFeature : IGlContextExternalObjectsFeature, I return default; } - public byte[] DeviceLuid { get; } - public byte[] DeviceUuid { get; } + public byte[]? DeviceLuid { get; } + public byte[]? DeviceUuid => null; public void Dispose() { diff --git a/src/Windows/Avalonia.Win32/OpenGl/Angle/AngleWin32EglDisplay.cs b/src/Windows/Avalonia.Win32/OpenGl/Angle/AngleWin32EglDisplay.cs index 53bf2fb8b1..770a27386f 100644 --- a/src/Windows/Avalonia.Win32/OpenGl/Angle/AngleWin32EglDisplay.cs +++ b/src/Windows/Avalonia.Win32/OpenGl/Angle/AngleWin32EglDisplay.cs @@ -1,4 +1,3 @@ -#nullable enable annotations using System; using System.Collections.Generic; using System.ComponentModel; @@ -97,7 +96,7 @@ namespace Avalonia.Win32.OpenGl.Angle DirectXUnmanagedMethods.D3D11CreateDevice(chosenAdapter?.GetNativeIntPtr() ?? IntPtr.Zero, D3D_DRIVER_TYPE.D3D_DRIVER_TYPE_UNKNOWN, IntPtr.Zero, 0, featureLevels, (uint)featureLevels.Length, - 7, out pD3dDevice, out var featureLevel, null); + 7, out pD3dDevice, out _, null); if (pD3dDevice == IntPtr.Zero) diff --git a/src/Windows/Avalonia.Win32/OpenGl/Angle/AngleWin32PlatformGraphics.cs b/src/Windows/Avalonia.Win32/OpenGl/Angle/AngleWin32PlatformGraphics.cs index a4d1ea457a..8ee6d286d1 100644 --- a/src/Windows/Avalonia.Win32/OpenGl/Angle/AngleWin32PlatformGraphics.cs +++ b/src/Windows/Avalonia.Win32/OpenGl/Angle/AngleWin32PlatformGraphics.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using Avalonia.Logging; using Avalonia.OpenGL; @@ -12,11 +13,14 @@ namespace Avalonia.Win32.OpenGl.Angle; internal class AngleWin32PlatformGraphics : IPlatformGraphics, IPlatformGraphicsOpenGlContextFactory { private readonly Win32AngleEglInterface _egl; - private AngleWin32EglDisplay _sharedDisplay; - private EglContext _sharedContext; - public bool UsesSharedContext => PlatformApi == AngleOptions.PlatformApi.DirectX9; + private readonly AngleWin32EglDisplay? _sharedDisplay; + private EglContext? _sharedContext; + + [MemberNotNullWhen(true, nameof(_sharedDisplay))] + public bool UsesSharedContext => _sharedDisplay is not null; + + public AngleOptions.PlatformApi PlatformApi { get; } - public AngleOptions.PlatformApi PlatformApi { get; } = AngleOptions.PlatformApi.DirectX11; public IPlatformGraphicsContext CreateContext() { if (UsesSharedContext) @@ -72,7 +76,7 @@ internal class AngleWin32PlatformGraphics : IPlatformGraphics, IPlatformGraphics } - public static AngleWin32PlatformGraphics TryCreate(AngleOptions options) + public static AngleWin32PlatformGraphics? TryCreate(AngleOptions? options) { Win32AngleEglInterface egl; try @@ -109,7 +113,7 @@ internal class AngleWin32PlatformGraphics : IPlatformGraphics, IPlatformGraphics } else { - AngleWin32EglDisplay sharedDisplay = null; + AngleWin32EglDisplay? sharedDisplay = null; try { sharedDisplay = AngleWin32EglDisplay.CreateD3D9Display(egl); diff --git a/src/Windows/Avalonia.Win32/OpenGl/WglContext.cs b/src/Windows/Avalonia.Win32/OpenGl/WglContext.cs index b4002d8bc7..999818d709 100644 --- a/src/Windows/Avalonia.Win32/OpenGl/WglContext.cs +++ b/src/Windows/Avalonia.Win32/OpenGl/WglContext.cs @@ -7,22 +7,22 @@ using Avalonia.Platform; using Avalonia.Reactive; using Avalonia.Win32.Interop; using static Avalonia.Win32.Interop.UnmanagedMethods; -using static Avalonia.Win32.OpenGl.WglConsts; namespace Avalonia.Win32.OpenGl { - class WglContext : IGlContext + internal class WglContext : IGlContext { - private object _lock = new object(); - private readonly WglContext _sharedWith; + private readonly object _lock = new(); + private readonly WglContext? _sharedWith; private readonly IntPtr _context; private readonly IntPtr _hWnd; private readonly IntPtr _dc; private readonly int _pixelFormat; private readonly PixelFormatDescriptor _formatDescriptor; + public IntPtr Handle => _context; - public WglContext(WglContext sharedWith, GlVersion version, IntPtr context, IntPtr hWnd, IntPtr dc, int pixelFormat, + public WglContext(WglContext? sharedWith, GlVersion version, IntPtr context, IntPtr hWnd, IntPtr dc, int pixelFormat, PixelFormatDescriptor formatDescriptor) { Version = version; @@ -54,7 +54,7 @@ namespace Avalonia.Win32.OpenGl public GlVersion Version { get; } public GlInterface GlInterface { get; } - public int SampleCount { get; } + public int SampleCount => 0; public int StencilSize { get; } private bool IsCurrent => wglGetCurrentContext() == _context && wglGetCurrentDC() == _dc; @@ -97,12 +97,12 @@ namespace Avalonia.Win32.OpenGl } public bool CanCreateSharedContext => true; - public IGlContext CreateSharedContext(IEnumerable preferredVersions = null) + public IGlContext? CreateSharedContext(IEnumerable? preferredVersions = null) { var versions = preferredVersions?.Append(Version).ToArray() ?? new[] { Version }; return WglDisplay.CreateContext(versions, _sharedWith ?? this); } - public object TryGetFeature(Type featureType) => null; + public object? TryGetFeature(Type featureType) => null; } } diff --git a/src/Windows/Avalonia.Win32/OpenGl/WglDisplay.cs b/src/Windows/Avalonia.Win32/OpenGl/WglDisplay.cs index 9a1963a97a..e207bc23ab 100644 --- a/src/Windows/Avalonia.Win32/OpenGl/WglDisplay.cs +++ b/src/Windows/Avalonia.Win32/OpenGl/WglDisplay.cs @@ -1,4 +1,5 @@ using System; +using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using Avalonia.OpenGL; using Avalonia.Threading; @@ -19,29 +20,31 @@ namespace Avalonia.Win32.OpenGl private static int _defaultPixelFormat; public static IntPtr OpenGl32Handle = LoadLibrary("opengl32"); - private delegate bool WglChoosePixelFormatARBDelegate(IntPtr hdc, int[] piAttribIList, float[] pfAttribFList, + private delegate bool WglChoosePixelFormatARBDelegate(IntPtr hdc, int[]? piAttribIList, float[]? pfAttribFList, int nMaxFormats, int[] piFormats, out int nNumFormats); - private static WglChoosePixelFormatARBDelegate WglChoosePixelFormatArb; + private static WglChoosePixelFormatARBDelegate? s_wglChoosePixelFormatArb; - private delegate IntPtr WglCreateContextAttribsARBDelegate(IntPtr hDC, IntPtr hShareContext, int[] attribList); + private delegate IntPtr WglCreateContextAttribsARBDelegate(IntPtr hDC, IntPtr hShareContext, int[]? attribList); - private static WglCreateContextAttribsARBDelegate WglCreateContextAttribsArb; + private static WglCreateContextAttribsARBDelegate? s_wglCreateContextAttribsArb; private delegate void GlDebugMessageCallbackDelegate(IntPtr callback, IntPtr userParam); - private static GlDebugMessageCallbackDelegate GlDebugMessageCallback; + private static GlDebugMessageCallbackDelegate? s_glDebugMessageCallback; private delegate void DebugCallbackDelegate(int source, int type, int id, int severity, int len, IntPtr message, IntPtr userParam); - - static bool Initialize() - { - if (!_initialized.HasValue) - _initialized = InitializeCore(); - return _initialized.Value; - } - static bool InitializeCore() + + [MemberNotNullWhen(true, nameof(s_wglChoosePixelFormatArb))] + [MemberNotNullWhen(true, nameof(s_wglCreateContextAttribsArb))] + [MemberNotNullWhen(true, nameof(s_glDebugMessageCallback))] + private static bool Initialize() => _initialized ??= InitializeCore(); + + [MemberNotNullWhen(true, nameof(s_wglChoosePixelFormatArb))] + [MemberNotNullWhen(true, nameof(s_wglCreateContextAttribsArb))] + [MemberNotNullWhen(true, nameof(s_glDebugMessageCallback))] + private static bool InitializeCore() { Dispatcher.UIThread.VerifyAccess(); _bootstrapWindow = WglGdiResourceManager.CreateOffscreenWindow(); @@ -64,20 +67,20 @@ namespace Avalonia.Win32.OpenGl return false; wglMakeCurrent(_bootstrapDc, _bootstrapContext); - WglCreateContextAttribsArb = Marshal.GetDelegateForFunctionPointer( + s_wglCreateContextAttribsArb = Marshal.GetDelegateForFunctionPointer( wglGetProcAddress("wglCreateContextAttribsARB")); - WglChoosePixelFormatArb = + s_wglChoosePixelFormatArb = Marshal.GetDelegateForFunctionPointer( wglGetProcAddress("wglChoosePixelFormatARB")); - GlDebugMessageCallback = + s_glDebugMessageCallback = Marshal.GetDelegateForFunctionPointer( wglGetProcAddress("glDebugMessageCallback")); var formats = new int[1]; - WglChoosePixelFormatArb(_bootstrapDc, new int[] + s_wglChoosePixelFormatArb(_bootstrapDc, new int[] { WGL_DRAW_TO_WINDOW_ARB, 1, WGL_ACCELERATION_ARB, WGL_FULL_ACCELERATION_ARB, @@ -106,12 +109,12 @@ namespace Avalonia.Win32.OpenGl Console.Error.WriteLine(err); } - public static WglContext CreateContext(GlVersion[] versions, IGlContext share) + public static WglContext? CreateContext(GlVersion[] versions, IGlContext? share) { if (!Initialize()) return null; - var shareContext = (WglContext)share; + var shareContext = share as WglContext; using (new WglRestoreContext(_bootstrapDc, _bootstrapContext, null)) { @@ -125,7 +128,7 @@ namespace Avalonia.Win32.OpenGl IntPtr context; using (shareContext?.Lock()) { - context = WglCreateContextAttribsArb(dc, shareContext?.Handle ?? IntPtr.Zero, + context = s_wglCreateContextAttribsArb(dc, shareContext?.Handle ?? IntPtr.Zero, new[] { // major @@ -142,7 +145,7 @@ namespace Avalonia.Win32.OpenGl } using(new WglRestoreContext(dc, context, null)) - GlDebugMessageCallback(Marshal.GetFunctionPointerForDelegate(_debugCallback), IntPtr.Zero); + s_glDebugMessageCallback(Marshal.GetFunctionPointerForDelegate(_debugCallback), IntPtr.Zero); if (context != IntPtr.Zero) return new WglContext(shareContext, version, context, window, dc, _defaultPixelFormat, _defaultPfd); diff --git a/src/Windows/Avalonia.Win32/OpenGl/WglGdiResourceManager.cs b/src/Windows/Avalonia.Win32/OpenGl/WglGdiResourceManager.cs index ed40488c70..86143d078d 100644 --- a/src/Windows/Avalonia.Win32/OpenGl/WglGdiResourceManager.cs +++ b/src/Windows/Avalonia.Win32/OpenGl/WglGdiResourceManager.cs @@ -17,45 +17,69 @@ namespace Avalonia.Win32.OpenGl; internal class WglGdiResourceManager { - class GetDCOp + private class GetDCOp { - public IntPtr Window; - public TaskCompletionSource Result; + public readonly IntPtr Window; + public readonly TaskCompletionSource Result; + + public GetDCOp(IntPtr window, TaskCompletionSource result) + { + Window = window; + Result = result; + } } - class ReleaseDCOp + private class ReleaseDCOp { - public IntPtr Window; - public IntPtr DC; - public TaskCompletionSource Result; + public readonly IntPtr Window; + public readonly IntPtr DC; + public readonly TaskCompletionSource Result; + + public ReleaseDCOp(IntPtr window, IntPtr dc, TaskCompletionSource result) + { + Window = window; + DC = dc; + Result = result; + } } - - class CreateWindowOp + + private class CreateWindowOp { - public TaskCompletionSource Result; + public readonly TaskCompletionSource Result; + + public CreateWindowOp(TaskCompletionSource result) + { + Result = result; + } } - class DestroyWindowOp + private class DestroyWindowOp { - public IntPtr Window; - public TaskCompletionSource Result; + public readonly IntPtr Window; + public readonly TaskCompletionSource Result; + + public DestroyWindowOp(IntPtr window, TaskCompletionSource result) + { + Window = window; + Result = result; + } } - private static readonly Queue s_Queue = new(); - private static readonly AutoResetEvent s_Event = new(false); - private static readonly ushort s_WindowClass; + private static readonly Queue s_queue = new(); + private static readonly AutoResetEvent s_event = new(false); + private static readonly ushort s_windowClass; private static readonly UnmanagedMethods.WndProc s_wndProcDelegate = WndProc; - static void Worker() + private static void Worker() { while (true) { - s_Event.WaitOne(); - lock (s_Queue) + s_event.WaitOne(); + lock (s_queue) { - if(s_Queue.Count == 0) + if(s_queue.Count == 0) continue; - var job = s_Queue.Dequeue(); + var job = s_queue.Dequeue(); if (job is GetDCOp getDc) getDc.Result.TrySetResult(UnmanagedMethods.GetDC(getDc.Window)); else if (job is ReleaseDCOp releaseDc) @@ -66,7 +90,7 @@ internal class WglGdiResourceManager else if (job is CreateWindowOp createWindow) createWindow.Result.TrySetResult(UnmanagedMethods.CreateWindowEx( 0, - s_WindowClass, + s_windowClass, null, (int)UnmanagedMethods.WindowStyles.WS_OVERLAPPEDWINDOW, 0, @@ -97,16 +121,15 @@ internal class WglGdiResourceManager style = (int)UnmanagedMethods.ClassStyles.CS_OWNDC }; - s_WindowClass = UnmanagedMethods.RegisterClassEx(ref wndClassEx); + s_windowClass = UnmanagedMethods.RegisterClassEx(ref wndClassEx); var th = new Thread(Worker) { IsBackground = true, Name = "Win32 OpenGL HDC manager" }; // This makes CLR to automatically pump the event queue from WaitOne th.SetApartmentState(ApartmentState.STA); th.Start(); } - - - - static IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam) + + + private static IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam) { return UnmanagedMethods.DefWindowProc(hWnd, msg, wParam, lParam); } @@ -114,53 +137,36 @@ internal class WglGdiResourceManager public static IntPtr CreateOffscreenWindow() { var tcs = new TaskCompletionSource(); - lock(s_Queue) - s_Queue.Enqueue(new CreateWindowOp() - { - Result = tcs - }); - s_Event.Set(); + lock (s_queue) + s_queue.Enqueue(new CreateWindowOp(tcs)); + s_event.Set(); return tcs.Task.Result; } public static IntPtr GetDC(IntPtr hWnd) { var tcs = new TaskCompletionSource(); - lock(s_Queue) - s_Queue.Enqueue(new GetDCOp - { - Window = hWnd, - Result = tcs - }); - s_Event.Set(); + lock (s_queue) + s_queue.Enqueue(new GetDCOp(hWnd, tcs)); + s_event.Set(); return tcs.Task.Result; } public static void ReleaseDC(IntPtr hWnd, IntPtr hDC) { - var tcs = new TaskCompletionSource(); - lock(s_Queue) - s_Queue.Enqueue(new ReleaseDCOp() - { - Window = hWnd, - DC = hDC, - Result = tcs - }); - s_Event.Set(); + var tcs = new TaskCompletionSource(); + lock (s_queue) + s_queue.Enqueue(new ReleaseDCOp(hWnd, hDC, tcs)); + s_event.Set(); tcs.Task.Wait(); } public static void DestroyWindow(IntPtr hWnd) { - var tcs = new TaskCompletionSource(); - lock(s_Queue) - s_Queue.Enqueue(new DestroyWindowOp() - { - Window = hWnd, - Result = tcs - }); - s_Event.Set(); + var tcs = new TaskCompletionSource(); + lock (s_queue) + s_queue.Enqueue(new DestroyWindowOp(hWnd, tcs)); + s_event.Set(); tcs.Task.Wait(); - } } diff --git a/src/Windows/Avalonia.Win32/OpenGl/WglPlatformOpenGlInterface.cs b/src/Windows/Avalonia.Win32/OpenGl/WglPlatformOpenGlInterface.cs index 39dd330d52..61b932e9c7 100644 --- a/src/Windows/Avalonia.Win32/OpenGl/WglPlatformOpenGlInterface.cs +++ b/src/Windows/Avalonia.Win32/OpenGl/WglPlatformOpenGlInterface.cs @@ -6,27 +6,31 @@ using Avalonia.Platform; namespace Avalonia.Win32.OpenGl { - class WglPlatformOpenGlInterface : IPlatformGraphics + internal class WglPlatformOpenGlInterface : IPlatformGraphics { public WglContext PrimaryContext { get; } public bool UsesSharedContext => false; IPlatformGraphicsContext IPlatformGraphics.CreateContext() => CreateContext(); public IPlatformGraphicsContext GetSharedContext() => throw new NotSupportedException(); - - public IGlContext CreateContext() => WglDisplay.CreateContext(new[] { PrimaryContext.Version }, null); - private WglPlatformOpenGlInterface(WglContext primary) + public IGlContext CreateContext() + => WglDisplay.CreateContext(new[] { PrimaryContext.Version }, null) + ?? throw new OpenGlException("Unable to create additional WGL context"); + + private WglPlatformOpenGlInterface(WglContext primary) { PrimaryContext = primary; } - public static WglPlatformOpenGlInterface TryCreate() + public static WglPlatformOpenGlInterface? TryCreate() { try { var opts = AvaloniaLocator.Current.GetService() ?? new Win32PlatformOptions(); - var primary = WglDisplay.CreateContext(opts.WglProfiles.ToArray(), null); - return new WglPlatformOpenGlInterface(primary); + if (WglDisplay.CreateContext(opts.WglProfiles.ToArray(), null) is { } primary) + { + return new WglPlatformOpenGlInterface(primary); + } } catch (Exception e) { diff --git a/src/Windows/Avalonia.Win32/OpenGl/WglRestoreContext.cs b/src/Windows/Avalonia.Win32/OpenGl/WglRestoreContext.cs index b145ffbb37..ee0934af7d 100644 --- a/src/Windows/Avalonia.Win32/OpenGl/WglRestoreContext.cs +++ b/src/Windows/Avalonia.Win32/OpenGl/WglRestoreContext.cs @@ -8,11 +8,11 @@ namespace Avalonia.Win32.OpenGl { internal class WglRestoreContext : IDisposable { - private readonly object _monitor; + private readonly object? _monitor; private readonly IntPtr _oldDc; private readonly IntPtr _oldContext; - public WglRestoreContext(IntPtr gc, IntPtr context, object monitor, bool takeMonitor = true) + public WglRestoreContext(IntPtr gc, IntPtr context, object? monitor, bool takeMonitor = true) { _monitor = monitor; _oldDc = wglGetCurrentDC(); diff --git a/src/Windows/Avalonia.Win32/PlatformConstants.cs b/src/Windows/Avalonia.Win32/PlatformConstants.cs index 9dd4780637..48dd9f45da 100644 --- a/src/Windows/Avalonia.Win32/PlatformConstants.cs +++ b/src/Windows/Avalonia.Win32/PlatformConstants.cs @@ -7,7 +7,7 @@ namespace Avalonia.Win32 public const string WindowHandleType = "HWND"; public const string CursorHandleType = "HCURSOR"; - public static readonly Version Windows8 = new Version(6, 2); - public static readonly Version Windows7 = new Version(6, 1); + internal static readonly Version Windows8 = new Version(6, 2); + internal static readonly Version Windows7 = new Version(6, 1); } } diff --git a/src/Windows/Avalonia.Win32/PopupImpl.cs b/src/Windows/Avalonia.Win32/PopupImpl.cs index 3a56af12f0..75c1a2d564 100644 --- a/src/Windows/Avalonia.Win32/PopupImpl.cs +++ b/src/Windows/Avalonia.Win32/PopupImpl.cs @@ -5,9 +5,9 @@ using Avalonia.Win32.Interop; namespace Avalonia.Win32 { - class PopupImpl : WindowImpl, IPopupImpl + internal class PopupImpl : WindowImpl, IPopupImpl { - private readonly IWindowBaseImpl _parent; + private readonly IWindowBaseImpl? _parent; private bool _dropShadowHint = true; private Size? _maxAutoSize; @@ -92,7 +92,7 @@ namespace Avalonia.Win32 IntPtr.Zero); s_parentHandle = IntPtr.Zero; - PopupImpl.EnableBoxShadow(result, _dropShadowHint); + EnableBoxShadow(result, _dropShadowHint); return result; } @@ -113,7 +113,7 @@ namespace Avalonia.Win32 // This is needed because we are calling virtual methods from constructors // One fabulous design decision leads to another, I guess - static IWindowBaseImpl SaveParentHandle(IWindowBaseImpl parent) + private static IWindowBaseImpl SaveParentHandle(IWindowBaseImpl parent) { s_parentHandle = parent.Handle.Handle; return parent; @@ -126,7 +126,7 @@ namespace Avalonia.Win32 } - private PopupImpl(IWindowBaseImpl parent, bool dummy) : base() + private PopupImpl(IWindowBaseImpl parent, bool dummy) { _parent = parent; PopupPositioner = new ManagedPopupPositioner(new ManagedPopupPositionerPopupImplHelper(parent, MoveResize)); @@ -159,10 +159,7 @@ namespace Avalonia.Win32 { _dropShadowHint = enabled; - if (Handle != null) - { - PopupImpl.EnableBoxShadow(Handle.Handle, enabled); - } + EnableBoxShadow(Handle.Handle, enabled); } public IPopupPositioner PopupPositioner { get; } diff --git a/src/Windows/Avalonia.Win32/ScreenImpl.cs b/src/Windows/Avalonia.Win32/ScreenImpl.cs index f3754cd58f..6154dff307 100644 --- a/src/Windows/Avalonia.Win32/ScreenImpl.cs +++ b/src/Windows/Avalonia.Win32/ScreenImpl.cs @@ -3,20 +3,21 @@ using System.Collections.Generic; using System.Linq; using Avalonia.Metadata; using Avalonia.Platform; -using Avalonia.Win32.Interop; using static Avalonia.Win32.Interop.UnmanagedMethods; namespace Avalonia.Win32 { - [Unstable] - public class ScreenImpl : IScreenImpl + internal class ScreenImpl : IScreenImpl { + private Screen[]? _allScreens; + + /// public int ScreenCount { get => GetSystemMetrics(SystemMetric.SM_CMONITORS); } - private Screen[] _allScreens; + /// public IReadOnlyList AllScreens { get @@ -38,7 +39,7 @@ namespace Avalonia.Win32 if (method != IntPtr.Zero) { GetDpiForMonitor(monitor, MONITOR_DPI_TYPE.MDT_EFFECTIVE_DPI, out var x, out _); - dpi = (double)x; + dpi = x; } else { @@ -74,7 +75,8 @@ namespace Avalonia.Win32 _allScreens = null; } - public Screen ScreenFromWindow(IWindowBaseImpl window) + /// + public Screen? ScreenFromWindow(IWindowBaseImpl window) { var handle = window.Handle.Handle; @@ -83,7 +85,8 @@ namespace Avalonia.Win32 return FindScreenByHandle(monitor); } - public Screen ScreenFromPoint(PixelPoint point) + /// + public Screen? ScreenFromPoint(PixelPoint point) { var monitor = MonitorFromPoint(new POINT { @@ -94,7 +97,8 @@ namespace Avalonia.Win32 return FindScreenByHandle(monitor); } - public Screen ScreenFromRect(PixelRect rect) + /// + public Screen? ScreenFromRect(PixelRect rect) { var monitor = MonitorFromRect(new RECT { @@ -107,7 +111,7 @@ namespace Avalonia.Win32 return FindScreenByHandle(monitor); } - private Screen FindScreenByHandle(IntPtr handle) + private Screen? FindScreenByHandle(IntPtr handle) { return AllScreens.Cast().FirstOrDefault(m => m.Handle == handle); } diff --git a/src/Windows/Avalonia.Win32/TrayIconImpl.cs b/src/Windows/Avalonia.Win32/TrayIconImpl.cs index fe920ff1a1..c19439c09e 100644 --- a/src/Windows/Avalonia.Win32/TrayIconImpl.cs +++ b/src/Windows/Avalonia.Win32/TrayIconImpl.cs @@ -11,12 +11,9 @@ using Avalonia.Styling; using Avalonia.Win32.Interop; using static Avalonia.Win32.Interop.UnmanagedMethods; -#nullable enable - namespace Avalonia.Win32 { - [Unstable] - public class TrayIconImpl : ITrayIconImpl + internal class TrayIconImpl : ITrayIconImpl { private static readonly IntPtr s_emptyIcon = new System.Drawing.Bitmap(32, 32).GetHicon(); private readonly int _uniqueId; @@ -25,9 +22,9 @@ namespace Avalonia.Win32 private IconImpl? _icon; private string? _tooltipText; private readonly Win32NativeToManagedMenuExporter _exporter; - private static readonly Dictionary s_trayIcons = new Dictionary(); + private static readonly Dictionary s_trayIcons = new(); private bool _disposedValue; - private static readonly uint WM_TASKBARCREATED = UnmanagedMethods.RegisterWindowMessage("TaskbarCreated"); + private static readonly uint WM_TASKBARCREATED = RegisterWindowMessage("TaskbarCreated"); public TrayIconImpl() { @@ -62,17 +59,20 @@ namespace Avalonia.Win32 } } + /// public void SetIcon(IWindowIconImpl? icon) { _icon = icon as IconImpl; UpdateIcon(); } + /// public void SetIsVisible(bool visible) { UpdateIcon(!visible); } + /// public void SetToolTipText(string? text) { _tooltipText = text; @@ -209,8 +209,11 @@ namespace Avalonia.Win32 private void MoveResize(PixelPoint position, Size size, double scaling) { - PlatformImpl!.Move(position); - PlatformImpl!.Resize(size, PlatformResizeReason.Layout); + if (PlatformImpl is { } platformImpl) + { + platformImpl.Move(position); + platformImpl.Resize(size, PlatformResizeReason.Layout); + } } protected override void ArrangeCore(Rect finalRect) @@ -221,7 +224,7 @@ namespace Avalonia.Win32 { Anchor = PopupAnchor.TopLeft, Gravity = PopupGravity.BottomRight, - AnchorRectangle = new Rect(Position.ToPoint(1) / Screens.Primary.Scaling, new Size(1, 1)), + AnchorRectangle = new Rect(Position.ToPoint(Screens.Primary?.Scaling ?? 1.0), new Size(1, 1)), Size = finalRect.Size, ConstraintAdjustment = PopupPositionerConstraintAdjustment.FlipX | PopupPositionerConstraintAdjustment.FlipY, }); @@ -247,18 +250,22 @@ namespace Avalonia.Win32 { get { - var point = _hiddenWindow.Screens.Primary.Bounds.TopLeft; - var size = _hiddenWindow.Screens.Primary.Bounds.Size; - return new Rect(point.X, point.Y, size.Width * _hiddenWindow.Screens.Primary.Scaling, size.Height * _hiddenWindow.Screens.Primary.Scaling); + if (_hiddenWindow.Screens.Primary is { } screen) + { + var point = screen.Bounds.TopLeft; + var size = screen.Bounds.Size; + return new Rect(point.X, point.Y, size.Width * screen.Scaling, size.Height * screen.Scaling); + } + return default; } } public void MoveAndResize(Point devicePoint, Size virtualSize) { - _moveResize(new PixelPoint((int)devicePoint.X, (int)devicePoint.Y), virtualSize, _hiddenWindow.Screens.Primary.Scaling); + _moveResize(new PixelPoint((int)devicePoint.X, (int)devicePoint.Y), virtualSize, Scaling); } - public double Scaling => _hiddenWindow.Screens.Primary.Scaling; + public double Scaling => _hiddenWindow.Screens.Primary?.Scaling ?? 1.0; } } diff --git a/src/Windows/Avalonia.Win32/Win32GlManager.cs b/src/Windows/Avalonia.Win32/Win32GlManager.cs index ab6de1a027..c26ce5fd45 100644 --- a/src/Windows/Avalonia.Win32/Win32GlManager.cs +++ b/src/Windows/Avalonia.Win32/Win32GlManager.cs @@ -1,6 +1,4 @@ using Avalonia.OpenGL; -using Avalonia.OpenGL.Angle; -using Avalonia.OpenGL.Egl; using Avalonia.Platform; using Avalonia.Win32.DirectX; using Avalonia.Win32.OpenGl; @@ -11,16 +9,19 @@ namespace Avalonia.Win32 { static class Win32GlManager { - - public static IPlatformGraphics Initialize() + public static IPlatformGraphics? Initialize() { var gl = InitializeCore(); - AvaloniaLocator.CurrentMutable.Bind().ToConstant(gl); - AvaloniaLocator.CurrentMutable.Bind().ToConstant(gl); + + if (gl is not null) + { + AvaloniaLocator.CurrentMutable.Bind().ToConstant(gl); + } + return gl; } - static IPlatformGraphics InitializeCore() + private static IPlatformGraphics? InitializeCore() { var opts = AvaloniaLocator.Current.GetService() ?? new Win32PlatformOptions(); @@ -55,7 +56,5 @@ namespace Avalonia.Win32 return null; } - - } } diff --git a/src/Windows/Avalonia.Win32/Win32NativeControlHost.cs b/src/Windows/Avalonia.Win32/Win32NativeControlHost.cs index fd05e780bf..620cd64e79 100644 --- a/src/Windows/Avalonia.Win32/Win32NativeControlHost.cs +++ b/src/Windows/Avalonia.Win32/Win32NativeControlHost.cs @@ -1,13 +1,13 @@ using System; +using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using Avalonia.Controls.Platform; using Avalonia.Platform; -using Avalonia.VisualTree; using Avalonia.Win32.Interop; namespace Avalonia.Win32 { - class Win32NativeControlHost : INativeControlHostImpl + internal class Win32NativeControlHost : INativeControlHostImpl { private readonly bool _useLayeredWindow; public WindowImpl Window { get; } @@ -18,7 +18,7 @@ namespace Avalonia.Win32 Window = window; } - void AssertCompatible(IPlatformHandle handle) + private void AssertCompatible(IPlatformHandle handle) { if (!IsCompatibleWith(handle)) throw new ArgumentException($"Don't know what to do with {handle.HandleDescriptor}"); @@ -33,7 +33,7 @@ namespace Avalonia.Win32 public INativeControlHostControlTopLevelAttachment CreateNewAttachment(Func create) { var holder = new DumbWindow(_useLayeredWindow, Window.Handle.Handle); - Win32NativeControlAttachment attachment = null; + Win32NativeControlAttachment? attachment = null; try { var child = create(holder); @@ -46,7 +46,7 @@ namespace Avalonia.Win32 catch { attachment?.Dispose(); - holder?.Destroy(); + holder.Destroy(); throw; } } @@ -60,13 +60,13 @@ namespace Avalonia.Win32 public bool IsCompatibleWith(IPlatformHandle handle) => handle.HandleDescriptor == "HWND"; - class DumbWindow : IDisposable, INativeControlHostDestroyableControlHandle + private class DumbWindow : IDisposable, INativeControlHostDestroyableControlHandle { public IntPtr Handle { get;} public string HandleDescriptor => "HWND"; public void Destroy() => Dispose(); - UnmanagedMethods.WndProc _wndProcDelegate; + private readonly UnmanagedMethods.WndProc _wndProcDelegate; private readonly string _className; public DumbWindow(bool layered = false, IntPtr? parent = null) @@ -103,9 +103,7 @@ namespace Avalonia.Win32 UnmanagedMethods.LayeredWindowFlags.LWA_ALPHA); } - - - protected virtual unsafe IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam) + private static IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam) { return UnmanagedMethods.DefWindowProc(hWnd, msg, wParam, lParam); } @@ -128,11 +126,11 @@ namespace Avalonia.Win32 } } - class Win32NativeControlAttachment : INativeControlHostControlTopLevelAttachment + private class Win32NativeControlAttachment : INativeControlHostControlTopLevelAttachment { - private DumbWindow _holder; - private IPlatformHandle _child; - private Win32NativeControlHost _attachedTo; + private DumbWindow? _holder; + private IPlatformHandle? _child; + private Win32NativeControlHost? _attachedTo; public Win32NativeControlAttachment(DumbWindow holder, IPlatformHandle child) { @@ -142,7 +140,8 @@ namespace Avalonia.Win32 UnmanagedMethods.ShowWindow(child.Handle, UnmanagedMethods.ShowWindowCommand.Show); } - void CheckDisposed() + [MemberNotNull(nameof(_holder))] + private void CheckDisposed() { if (_holder == null) throw new ObjectDisposedException(nameof(Win32NativeControlAttachment)); @@ -158,13 +157,13 @@ namespace Avalonia.Win32 _attachedTo = null; } - public INativeControlHostImpl AttachedTo + public INativeControlHostImpl? AttachedTo { get => _attachedTo; set { CheckDisposed(); - _attachedTo = (Win32NativeControlHost) value; + _attachedTo = value as Win32NativeControlHost; if (_attachedTo == null) { UnmanagedMethods.ShowWindow(_holder.Handle, UnmanagedMethods.ShowWindowCommand.Hide); @@ -179,6 +178,7 @@ namespace Avalonia.Win32 public void HideWithSize(Size size) { + CheckDisposed(); UnmanagedMethods.SetWindowPos(_holder.Handle, IntPtr.Zero, -100, -100, 1, 1, UnmanagedMethods.SetWindowPosFlags.SWP_HIDEWINDOW | @@ -198,8 +198,12 @@ namespace Avalonia.Win32 bounds *= _attachedTo.Window.RenderScaling; var pixelRect = new PixelRect((int)bounds.X, (int)bounds.Y, Math.Max(1, (int)bounds.Width), Math.Max(1, (int)bounds.Height)); - - UnmanagedMethods.MoveWindow(_child.Handle, 0, 0, pixelRect.Width, pixelRect.Height, true); + + if (_child is not null) + { + UnmanagedMethods.MoveWindow(_child.Handle, 0, 0, pixelRect.Width, pixelRect.Height, true); + } + UnmanagedMethods.SetWindowPos(_holder.Handle, IntPtr.Zero, pixelRect.X, pixelRect.Y, pixelRect.Width, pixelRect.Height, UnmanagedMethods.SetWindowPosFlags.SWP_SHOWWINDOW diff --git a/src/Windows/Avalonia.Win32/Win32NativeToManagedMenuExporter.cs b/src/Windows/Avalonia.Win32/Win32NativeToManagedMenuExporter.cs index fdf36206d0..46cdf66653 100644 --- a/src/Windows/Avalonia.Win32/Win32NativeToManagedMenuExporter.cs +++ b/src/Windows/Avalonia.Win32/Win32NativeToManagedMenuExporter.cs @@ -1,12 +1,7 @@ -using System.Collections.Generic; -using Avalonia.Reactive; +using Avalonia.Reactive; using Avalonia.Collections; using Avalonia.Controls; using Avalonia.Controls.Platform; -using Avalonia.Media.Imaging; -using Avalonia.Utilities; - -#nullable enable namespace Avalonia.Win32 { @@ -19,7 +14,7 @@ namespace Avalonia.Win32 _nativeMenu = nativeMenu; } - private AvaloniaList Populate(NativeMenu nativeMenu) + private static AvaloniaList Populate(NativeMenu nativeMenu) { var result = new AvaloniaList(); diff --git a/src/Windows/Avalonia.Win32/Win32Platform.cs b/src/Windows/Avalonia.Win32/Win32Platform.cs index c34be9008a..7a9f2bb814 100644 --- a/src/Windows/Avalonia.Win32/Win32Platform.cs +++ b/src/Windows/Avalonia.Win32/Win32Platform.cs @@ -17,12 +17,10 @@ using Avalonia.Rendering.Composition; using Avalonia.Threading; using Avalonia.Utilities; using Avalonia.Win32.Input; -using Avalonia.Win32.Interop; using static Avalonia.Win32.Interop.UnmanagedMethods; namespace Avalonia { -#nullable enable public static class Win32ApplicationExtensions { public static AppBuilder UseWin32(this AppBuilder builder) @@ -106,17 +104,19 @@ namespace Avalonia public IPlatformGraphics? CustomPlatformGraphics { get; set; } } } -#nullable restore namespace Avalonia.Win32 { - public class Win32Platform : IPlatformThreadingInterface, IWindowingPlatform, IPlatformIconLoader, IPlatformLifetimeEventsImpl + internal class Win32Platform : IPlatformThreadingInterface, IWindowingPlatform, IPlatformIconLoader, IPlatformLifetimeEventsImpl { - private static readonly Win32Platform s_instance = new Win32Platform(); - private static Thread _uiThread; - private UnmanagedMethods.WndProc _wndProcDelegate; + private static readonly Win32Platform s_instance = new(); + private static Thread? s_uiThread; + private static Win32PlatformOptions? s_options; + private static Compositor? s_compositor; + + private WndProc? _wndProcDelegate; private IntPtr _hwnd; - private readonly List _delegates = new List(); + private readonly List _delegates = new(); public Win32Platform() { @@ -135,9 +135,12 @@ namespace Avalonia.Win32 public static Version WindowsVersion { get; } = RtlGetVersion(); internal static bool UseOverlayPopups => Options.OverlayPopups; - public static Win32PlatformOptions Options { get; private set; } - internal static Compositor Compositor { get; private set; } + public static Win32PlatformOptions Options + => s_options ?? throw new InvalidOperationException($"{nameof(Win32Platform)} hasn't been initialized"); + + internal static Compositor Compositor + => s_compositor ?? throw new InvalidOperationException($"{nameof(Win32Platform)} hasn't been initialized"); public static void Initialize() { @@ -146,7 +149,7 @@ namespace Avalonia.Win32 public static void Initialize(Win32PlatformOptions options) { - Options = options; + s_options = options; var renderTimer = options.ShouldRenderOnUIThread ? new UiThreadRenderTimer(60) : new DefaultRenderTimer(60); AvaloniaLocator.CurrentMutable @@ -171,26 +174,24 @@ namespace Avalonia.Win32 .Bind().ToConstant(new WindowsMountedVolumeInfoProvider()) .Bind().ToConstant(s_instance); - _uiThread = Thread.CurrentThread; + s_uiThread = Thread.CurrentThread; - var platformGraphics = options?.CustomPlatformGraphics + var platformGraphics = options.CustomPlatformGraphics ?? Win32GlManager.Initialize(); if (OleContext.Current != null) AvaloniaLocator.CurrentMutable.Bind().ToSingleton(); - Compositor = new Compositor(AvaloniaLocator.Current.GetRequiredService(), platformGraphics); + s_compositor = new Compositor(AvaloniaLocator.Current.GetRequiredService(), platformGraphics); } public bool HasMessages() { - UnmanagedMethods.MSG msg; - return PeekMessage(out msg, IntPtr.Zero, 0, 0, 0); + return PeekMessage(out _, IntPtr.Zero, 0, 0, 0); } public void ProcessMessage() { - if (GetMessage(out var msg, IntPtr.Zero, 0, 0) > -1) { TranslateMessage(ref msg); @@ -222,8 +223,7 @@ namespace Avalonia.Win32 public IDisposable StartTimer(DispatcherPriority priority, TimeSpan interval, Action callback) { - UnmanagedMethods.TimerProc timerDelegate = - (hWnd, uMsg, nIDEvent, dwTime) => callback(); + TimerProc timerDelegate = (_, _, _, _) => callback(); IntPtr handle = SetTimer( IntPtr.Zero, @@ -253,11 +253,11 @@ namespace Avalonia.Win32 new IntPtr(SignalL)); } - public bool CurrentThreadIsLoopThread => _uiThread == Thread.CurrentThread; + public bool CurrentThreadIsLoopThread => s_uiThread == Thread.CurrentThread; - public event Action Signaled; + public event Action? Signaled; - public event EventHandler ShutdownRequested; + public event EventHandler? ShutdownRequested; [SuppressMessage("Microsoft.StyleCop.CSharp.NamingRules", "SA1305:FieldNamesMustNotUseHungarianNotation", Justification = "Using Win32 naming for consistency.")] private IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam) @@ -301,11 +301,11 @@ namespace Avalonia.Win32 private void CreateMessageWindow() { // Ensure that the delegate doesn't get garbage collected by storing it as a field. - _wndProcDelegate = new UnmanagedMethods.WndProc(WndProc); + _wndProcDelegate = WndProc; - UnmanagedMethods.WNDCLASSEX wndClassEx = new UnmanagedMethods.WNDCLASSEX + WNDCLASSEX wndClassEx = new WNDCLASSEX { - cbSize = Marshal.SizeOf(), + cbSize = Marshal.SizeOf(), lpfnWndProc = _wndProcDelegate, hInstance = GetModuleHandle(null), lpszClassName = "AvaloniaMessageWindow " + Guid.NewGuid(), @@ -326,7 +326,7 @@ namespace Avalonia.Win32 } } - public ITrayIconImpl CreateTrayIcon () + public ITrayIconImpl CreateTrayIcon() { return new TrayIconImpl(); } diff --git a/src/Windows/Avalonia.Win32/Win32PlatformSettings.cs b/src/Windows/Avalonia.Win32/Win32PlatformSettings.cs index 0310c4bfad..c5f7f17b32 100644 --- a/src/Windows/Avalonia.Win32/Win32PlatformSettings.cs +++ b/src/Windows/Avalonia.Win32/Win32PlatformSettings.cs @@ -1,8 +1,6 @@ using System; -using System.Runtime.InteropServices; using Avalonia.Input; using Avalonia.Platform; -using Avalonia.Win32.Interop; using Avalonia.Win32.WinRT; using static Avalonia.Win32.Interop.UnmanagedMethods; @@ -10,14 +8,14 @@ namespace Avalonia.Win32; internal class Win32PlatformSettings : DefaultPlatformSettings { - private PlatformColorValues _lastColorValues; + private PlatformColorValues? _lastColorValues; public override Size GetTapSize(PointerType type) { return type switch { PointerType.Touch => new(10, 10), - _ => new(GetSystemMetrics(UnmanagedMethods.SystemMetric.SM_CXDRAG), GetSystemMetrics(UnmanagedMethods.SystemMetric.SM_CYDRAG)), + _ => new(GetSystemMetrics(SystemMetric.SM_CXDRAG), GetSystemMetrics(SystemMetric.SM_CYDRAG)), }; } @@ -26,7 +24,7 @@ internal class Win32PlatformSettings : DefaultPlatformSettings return type switch { PointerType.Touch => new(16, 16), - _ => new(GetSystemMetrics(UnmanagedMethods.SystemMetric.SM_CXDOUBLECLK), GetSystemMetrics(UnmanagedMethods.SystemMetric.SM_CYDOUBLECLK)), + _ => new(GetSystemMetrics(SystemMetric.SM_CXDOUBLECLK), GetSystemMetrics(SystemMetric.SM_CYDOUBLECLK)), }; } diff --git a/src/Windows/Avalonia.Win32/Win32StorageProvider.cs b/src/Windows/Avalonia.Win32/Win32StorageProvider.cs index 2da642bd19..2fd49c8b09 100644 --- a/src/Windows/Avalonia.Win32/Win32StorageProvider.cs +++ b/src/Windows/Avalonia.Win32/Win32StorageProvider.cs @@ -1,13 +1,10 @@ -#nullable enable - -using System; +using System; using System.Linq; using System.Collections.Generic; using System.IO; using System.ComponentModel; using System.Runtime.InteropServices; using System.Threading.Tasks; -using Avalonia.MicroCom; using Avalonia.Platform.Storage; using Avalonia.Platform.Storage.FileIO; using Avalonia.Win32.Interop; @@ -146,7 +143,7 @@ namespace Avalonia.Win32 } } - var showResult = frm.Show(_windowImpl.Handle!.Handle); + var showResult = frm.Show(_windowImpl.Handle.Handle); if ((uint)showResult == (uint)UnmanagedMethods.HRESULT.E_CANCELLED) { @@ -188,7 +185,7 @@ namespace Avalonia.Win32 var message = new Win32Exception(ex.HResult).Message; throw new COMException(message, ex); } - })!; + }); } @@ -220,7 +217,6 @@ namespace Avalonia.Win32 } var size = Marshal.SizeOf(); - var arr = new byte[size]; var resultArr = new byte[size * filters.Count]; for (int i = 0; i < filters.Count; i++) @@ -236,7 +232,7 @@ namespace Avalonia.Win32 { var filterStr = new UnmanagedMethods.COMDLG_FILTERSPEC { - pszName = filter.Name ?? string.Empty, + pszName = filter.Name, pszSpec = string.Join(";", filter.Patterns) }; diff --git a/src/Windows/Avalonia.Win32/WinRT/Composition/WinUIEffectBase.cs b/src/Windows/Avalonia.Win32/WinRT/Composition/WinUIEffectBase.cs index 32f44842f8..1a922b4acd 100644 --- a/src/Windows/Avalonia.Win32/WinRT/Composition/WinUIEffectBase.cs +++ b/src/Windows/Avalonia.Win32/WinRT/Composition/WinUIEffectBase.cs @@ -1,14 +1,13 @@ using System; using System.Linq; using System.Runtime.InteropServices; -using Avalonia.MicroCom; using MicroCom.Runtime; namespace Avalonia.Win32.WinRT.Composition { - abstract class WinUIEffectBase : WinRTInspectable, IGraphicsEffect, IGraphicsEffectSource, IGraphicsEffectD2D1Interop + internal abstract class WinUIEffectBase : WinRTInspectable, IGraphicsEffect, IGraphicsEffectSource, IGraphicsEffectD2D1Interop { - private IGraphicsEffectSource[] _sources; + private IGraphicsEffectSource[]? _sources; public WinUIEffectBase(params IGraphicsEffectSource[] _sources) { @@ -32,7 +31,7 @@ namespace Avalonia.Win32.WinRT.Composition throw new COMException("Not supported", unchecked((int)0x80004001)); public abstract uint PropertyCount { get; } - public abstract IPropertyValue GetProperty(uint index); + public abstract IPropertyValue? GetProperty(uint index); public IGraphicsEffectSource GetSource(uint index) { @@ -53,14 +52,14 @@ namespace Avalonia.Win32.WinRT.Composition _sources = null; } } - - class WinUIGaussianBlurEffect : WinUIEffectBase + + internal class WinUIGaussianBlurEffect : WinUIEffectBase { public WinUIGaussianBlurEffect(IGraphicsEffectSource source) : base(source) { } - enum D2D1_GAUSSIANBLUR_OPTIMIZATION + private enum D2D1_GAUSSIANBLUR_OPTIMIZATION { D2D1_GAUSSIANBLUR_OPTIMIZATION_SPEED, D2D1_GAUSSIANBLUR_OPTIMIZATION_BALANCED, @@ -68,14 +67,14 @@ namespace Avalonia.Win32.WinRT.Composition D2D1_GAUSSIANBLUR_OPTIMIZATION_FORCE_DWORD }; - enum D2D1_BORDER_MODE + private enum D2D1_BORDER_MODE { D2D1_BORDER_MODE_SOFT, D2D1_BORDER_MODE_HARD, D2D1_BORDER_MODE_FORCE_DWORD }; - enum D2D1GaussianBlurProp + private enum D2D1GaussianBlurProp { D2D1_GAUSSIANBLUR_PROP_STANDARD_DEVIATION, D2D1_GAUSSIANBLUR_PROP_OPTIMIZATION, @@ -87,7 +86,7 @@ namespace Avalonia.Win32.WinRT.Composition public override uint PropertyCount => 3; - public override IPropertyValue GetProperty(uint index) + public override IPropertyValue? GetProperty(uint index) { switch ((D2D1GaussianBlurProp)index) { @@ -105,14 +104,14 @@ namespace Avalonia.Win32.WinRT.Composition return null; } } - - class SaturationEffect : WinUIEffectBase + + internal class SaturationEffect : WinUIEffectBase { public SaturationEffect(IGraphicsEffectSource source) : base(source) { } - enum D2D1_SATURATION_PROP + private enum D2D1_SATURATION_PROP { D2D1_SATURATION_PROP_SATURATION, D2D1_SATURATION_PROP_FORCE_DWORD @@ -122,7 +121,7 @@ namespace Avalonia.Win32.WinRT.Composition public override uint PropertyCount => 1; - public override IPropertyValue GetProperty(uint index) + public override IPropertyValue? GetProperty(uint index) { switch ((D2D1_SATURATION_PROP)index) { diff --git a/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositedWindow.cs b/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositedWindow.cs index 5be25a3d4b..2f22ba99f9 100644 --- a/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositedWindow.cs +++ b/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositedWindow.cs @@ -3,7 +3,6 @@ using System.Numerics; using System.Threading; using Avalonia.OpenGL.Egl; using Avalonia.Reactive; -using Avalonia.Win32.Interop; using MicroCom.Runtime; namespace Avalonia.Win32.WinRT.Composition; @@ -12,8 +11,8 @@ internal class WinUiCompositedWindow : IDisposable { public EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo WindowInfo { get; } private readonly WinUiCompositionShared _shared; - private readonly ICompositionRoundedRectangleGeometry _compositionRoundedRectangleGeometry; - private readonly IVisual _mica; + private readonly ICompositionRoundedRectangleGeometry? _compositionRoundedRectangleGeometry; + private readonly IVisual? _mica; private readonly IVisual _blur; private readonly IVisual _visual; private PixelSize _size; @@ -25,7 +24,7 @@ internal class WinUiCompositedWindow : IDisposable lock (_shared.SyncRoot) { _compositionRoundedRectangleGeometry?.Dispose(); - _blur?.Dispose(); + _blur.Dispose(); _mica?.Dispose(); _visual.Dispose(); _surfaceBrush.Dispose(); diff --git a/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositedWindowSurface.cs b/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositedWindowSurface.cs index 9ee024f9ad..95ef338f08 100644 --- a/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositedWindowSurface.cs +++ b/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositedWindowSurface.cs @@ -1,15 +1,8 @@ using System; -using System.Runtime.InteropServices; -using Avalonia.MicroCom; -using Avalonia.OpenGL; -using Avalonia.OpenGL.Angle; using Avalonia.OpenGL.Egl; -using Avalonia.OpenGL.Surfaces; using Avalonia.Platform; -using Avalonia.Utilities; using Avalonia.Win32.DirectX; using Avalonia.Win32.Interop; -using Avalonia.Win32.OpenGl.Angle; using MicroCom.Runtime; namespace Avalonia.Win32.WinRT.Composition @@ -18,7 +11,7 @@ namespace Avalonia.Win32.WinRT.Composition { private readonly WinUiCompositionShared _shared; private readonly EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo _info; - private WinUiCompositedWindow _window; + private WinUiCompositedWindow? _window; private BlurEffect _blurEffect; public WinUiCompositedWindowSurface(WinUiCompositionShared shared, EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo info) @@ -52,6 +45,8 @@ namespace Avalonia.Win32.WinRT.Composition internal class WinUiCompositedWindowRenderTarget : IDirect3D11TextureRenderTarget { + private static readonly Guid IID_ID3D11Texture2D = Guid.Parse("6f15aaf2-d208-4e89-9ab4-489535d34f9c"); + private readonly IPlatformGraphicsContext _context; private readonly WinUiCompositedWindow _window; private readonly IUnknown _d3dDevice; @@ -63,6 +58,7 @@ namespace Avalonia.Win32.WinRT.Composition private PixelSize _size; private bool _lost; private readonly ICompositionDrawingSurfaceInterop _surfaceInterop; + private readonly ICompositionDrawingSurface _drawingSurface; public WinUiCompositedWindowRenderTarget(IPlatformGraphicsContext context, WinUiCompositedWindow window, IntPtr device, @@ -83,28 +79,33 @@ namespace Avalonia.Win32.WinRT.Composition _surface = _drawingSurface.QueryInterface(); _surfaceInterop = _drawingSurface.QueryInterface(); } - finally + catch { - if (_surfaceInterop == null) - Dispose(); + _surface?.Dispose(); + _surfaceInterop?.Dispose(); + _drawingSurface?.Dispose(); + _compositionDevice2?.Dispose(); + _compositionDevice?.Dispose(); + _interop?.Dispose(); + _compositor?.Dispose(); + _d3dDevice?.Dispose(); + throw; } } public void Dispose() { - _surface?.Dispose(); - _surfaceInterop?.Dispose(); - _drawingSurface?.Dispose(); - _compositionDevice2?.Dispose(); - _compositionDevice?.Dispose(); - _interop?.Dispose(); - _compositor?.Dispose(); - _d3dDevice?.Dispose(); + _surface.Dispose(); + _surfaceInterop.Dispose(); + _drawingSurface.Dispose(); + _compositionDevice2.Dispose(); + _compositionDevice.Dispose(); + _interop.Dispose(); + _compositor.Dispose(); + _d3dDevice.Dispose(); } public bool IsCorrupted => _context.IsLost || _lost; - private static Guid IID_ID3D11Texture2D = Guid.Parse("6f15aaf2-d208-4e89-9ab4-489535d34f9c"); - private readonly ICompositionDrawingSurface _drawingSurface; public unsafe IDirect3D11TextureRenderTargetRenderSession BeginDraw() { @@ -155,12 +156,12 @@ namespace Avalonia.Win32.WinRT.Composition { if (needsEndDraw) _surfaceInterop.EndDraw(); - transaction?.Dispose(); + transaction.Dispose(); } } } - class Session : IDirect3D11TextureRenderTargetRenderSession + private class Session : IDirect3D11TextureRenderTargetRenderSession { private readonly IDisposable _transaction; private readonly PixelSize _size; @@ -200,4 +201,4 @@ namespace Avalonia.Win32.WinRT.Composition public double Scaling => _scaling; } } -} \ No newline at end of file +} diff --git a/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositionShared.cs b/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositionShared.cs index 301e605e7a..602d0a3f8a 100644 --- a/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositionShared.cs +++ b/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositionShared.cs @@ -8,11 +8,11 @@ internal class WinUiCompositionShared : IDisposable public ICompositor Compositor { get; } public ICompositor5 Compositor5 { get; } public ICompositorDesktopInterop DesktopInterop { get; } - public ICompositionBrush BlurBrush; - public ICompositionBrush MicaBrush; + public ICompositionBrush BlurBrush { get; } + public ICompositionBrush? MicaBrush { get; } public object SyncRoot { get; } = new(); - public static readonly Version MinHostBackdropVersion = new Version(10, 0, 22000); + public static readonly Version MinHostBackdropVersion = new(10, 0, 22000); public WinUiCompositionShared(ICompositor compositor) { @@ -26,9 +26,9 @@ internal class WinUiCompositionShared : IDisposable public void Dispose() { BlurBrush.Dispose(); - MicaBrush.Dispose(); + MicaBrush?.Dispose(); DesktopInterop.Dispose(); Compositor.Dispose(); Compositor5.Dispose(); } -} \ No newline at end of file +} diff --git a/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositionUtils.cs b/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositionUtils.cs index e7af4046d6..7b970868df 100644 --- a/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositionUtils.cs +++ b/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositionUtils.cs @@ -1,4 +1,3 @@ -using System; using System.Numerics; using MicroCom.Runtime; @@ -6,7 +5,7 @@ namespace Avalonia.Win32.WinRT.Composition; internal static class WinUiCompositionUtils { - public static ICompositionBrush CreateMicaBackdropBrush(ICompositor compositor) + public static ICompositionBrush? CreateMicaBackdropBrush(ICompositor compositor) { if (Win32Platform.WindowsVersion.Build < 22000) return null; @@ -18,7 +17,7 @@ internal static class WinUiCompositionUtils return blurredWallpaperBackdropBrush?.QueryInterface(); } - public static unsafe ICompositionBrush CreateAcrylicBlurBackdropBrush(ICompositor compositor) + public static ICompositionBrush CreateAcrylicBlurBackdropBrush(ICompositor compositor) { using var backDropParameterFactory = NativeWinRTMethods.CreateActivationFactory( @@ -39,7 +38,7 @@ internal static class WinUiCompositionUtils return compositionEffectBrush.QueryInterface(); } - public static ICompositionRoundedRectangleGeometry ClipVisual(ICompositor compositor, float? _backdropCornerRadius, params IVisual[] containerVisuals) + public static ICompositionRoundedRectangleGeometry? ClipVisual(ICompositor compositor, float? _backdropCornerRadius, params IVisual?[] containerVisuals) { if (!_backdropCornerRadius.HasValue) return null; @@ -77,7 +76,7 @@ internal static class WinUiCompositionUtils public static ICompositionBrush CreateBackdropBrush(ICompositor compositor) { - ICompositionBackdropBrush brush = null; + ICompositionBackdropBrush? brush = null; try { if (Win32Platform.WindowsVersion >= WinUiCompositionShared.MinHostBackdropVersion) @@ -98,4 +97,4 @@ internal static class WinUiCompositionUtils brush?.Dispose(); } } -} \ No newline at end of file +} diff --git a/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositorConnection.cs b/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositorConnection.cs index a1408baae0..754af86c06 100644 --- a/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositorConnection.cs +++ b/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositorConnection.cs @@ -7,20 +7,17 @@ using Avalonia.Logging; using Avalonia.MicroCom; using Avalonia.OpenGL.Egl; using Avalonia.Rendering; -using Avalonia.Win32.DirectX; using Avalonia.Win32.Interop; -using Avalonia.Win32.OpenGl.Angle; -using MicroCom.Runtime; namespace Avalonia.Win32.WinRT.Composition; internal class WinUiCompositorConnection : IRenderTimer { private readonly WinUiCompositionShared _shared; - public event Action Tick; + public event Action? Tick; public bool RunsInBackground => true; - public unsafe WinUiCompositorConnection() + public WinUiCompositorConnection() { using var compositor = NativeWinRTMethods.CreateInstance("Windows.UI.Composition.Compositor"); /* @@ -42,10 +39,9 @@ internal class WinUiCompositorConnection : IRenderTimer _shared = new WinUiCompositionShared(compositor); } - static bool TryCreateAndRegisterCore() + private static bool TryCreateAndRegisterCore() { var tcs = new TaskCompletionSource(); - var pumpLock = new object(); var th = new Thread(() => { WinUiCompositorConnection connect; @@ -80,10 +76,10 @@ internal class WinUiCompositorConnection : IRenderTimer return tcs.Task.Result; } - class RunLoopHandler : CallbackBase, IAsyncActionCompletedHandler + private class RunLoopHandler : CallbackBase, IAsyncActionCompletedHandler { private readonly WinUiCompositorConnection _parent; - private Stopwatch _st = Stopwatch.StartNew(); + private readonly Stopwatch _st = Stopwatch.StartNew(); public RunLoopHandler(WinUiCompositorConnection parent) { @@ -101,7 +97,7 @@ internal class WinUiCompositorConnection : IRenderTimer private void RunLoop() { var cts = new CancellationTokenSource(); - AppDomain.CurrentDomain.ProcessExit += (sender, args) => + AppDomain.CurrentDomain.ProcessExit += (_, _) => cts.Cancel(); lock (_shared.SyncRoot) diff --git a/src/Windows/Avalonia.Win32/WinRT/IBlurHost.cs b/src/Windows/Avalonia.Win32/WinRT/IBlurHost.cs index 526be6e0f0..a3918d9ae6 100644 --- a/src/Windows/Avalonia.Win32/WinRT/IBlurHost.cs +++ b/src/Windows/Avalonia.Win32/WinRT/IBlurHost.cs @@ -1,6 +1,6 @@ namespace Avalonia.Win32.WinRT { - public enum BlurEffect + internal enum BlurEffect { None, Acrylic, diff --git a/src/Windows/Avalonia.Win32/WinRT/NativeWinRTMethods.cs b/src/Windows/Avalonia.Win32/WinRT/NativeWinRTMethods.cs index 01b45f3df2..21f83addeb 100644 --- a/src/Windows/Avalonia.Win32/WinRT/NativeWinRTMethods.cs +++ b/src/Windows/Avalonia.Win32/WinRT/NativeWinRTMethods.cs @@ -1,12 +1,6 @@ using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.IO; -using System.Reflection; using System.Runtime.InteropServices; using System.Threading; -using Avalonia.MicroCom; -using Avalonia.Win32.Interop; using MicroCom.Runtime; namespace Avalonia.Win32.WinRT @@ -108,24 +102,24 @@ namespace Avalonia.Win32.WinRT [DllImport("combase.dll", PreserveSig = false)] private static extern IntPtr RoGetActivationFactory(IntPtr activatableClassId, ref Guid iid); - private static bool _initialized; + private static bool s_initialized; private static void EnsureRoInitialized() { - if (_initialized) + if (s_initialized) return; RoInitialize(Thread.CurrentThread.GetApartmentState() == ApartmentState.STA ? RO_INIT_TYPE.RO_INIT_SINGLETHREADED : RO_INIT_TYPE.RO_INIT_MULTITHREADED); - _initialized = true; + s_initialized = true; } } - class HStringInterop : IDisposable + internal class HStringInterop : IDisposable { private IntPtr _s; - private bool _owns; + private readonly bool _owns; - public HStringInterop(string s) + public HStringInterop(string? s) { _s = s == null ? IntPtr.Zero : NativeWinRTMethods.WindowsCreateString(s); _owns = true; @@ -139,7 +133,7 @@ namespace Avalonia.Win32.WinRT public IntPtr Handle => _s; - public unsafe string Value + public unsafe string? Value { get { diff --git a/src/Windows/Avalonia.Win32/WinRT/WinRTColor.cs b/src/Windows/Avalonia.Win32/WinRT/WinRTColor.cs index 90b2022054..67769b7533 100644 --- a/src/Windows/Avalonia.Win32/WinRT/WinRTColor.cs +++ b/src/Windows/Avalonia.Win32/WinRT/WinRTColor.cs @@ -4,7 +4,7 @@ using Avalonia.Media; namespace Avalonia.Win32.WinRT { [StructLayout(LayoutKind.Sequential, Pack = 1)] - public record struct WinRTColor + internal record struct WinRTColor { public byte A; public byte R; diff --git a/src/Windows/Avalonia.Win32/WinRT/WinRTInspectable.cs b/src/Windows/Avalonia.Win32/WinRT/WinRTInspectable.cs index 1fde57fe38..aabf148e75 100644 --- a/src/Windows/Avalonia.Win32/WinRT/WinRTInspectable.cs +++ b/src/Windows/Avalonia.Win32/WinRT/WinRTInspectable.cs @@ -2,12 +2,11 @@ using System.Linq; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -using Avalonia.MicroCom; using MicroCom.Runtime; namespace Avalonia.Win32.WinRT { - class WinRTInspectable : IInspectable, IMicroComShadowContainer + internal class WinRTInspectable : IInspectable, IMicroComShadowContainer { public virtual void Dispose() { @@ -25,9 +24,9 @@ namespace Avalonia.Win32.WinRT *iidCount = (ulong) interfaces.Length; } - public IntPtr RuntimeClassName => NativeWinRTMethods.WindowsCreateString(GetType().FullName); + public IntPtr RuntimeClassName => NativeWinRTMethods.WindowsCreateString(GetType().FullName!); public TrustLevel TrustLevel => TrustLevel.BaseTrust; - public MicroComShadow Shadow { get; set; } + public MicroComShadow? Shadow { get; set; } public virtual void OnReferencedFromNative() { } diff --git a/src/Windows/Avalonia.Win32/WinScreen.cs b/src/Windows/Avalonia.Win32/WinScreen.cs index 1038f41a17..10e0b3b8b1 100644 --- a/src/Windows/Avalonia.Win32/WinScreen.cs +++ b/src/Windows/Avalonia.Win32/WinScreen.cs @@ -3,7 +3,7 @@ using Avalonia.Platform; namespace Avalonia.Win32 { - public class WinScreen : Screen + internal class WinScreen : Screen { private readonly IntPtr _hMonitor; @@ -15,14 +15,16 @@ namespace Avalonia.Win32 public IntPtr Handle => _hMonitor; + /// public override int GetHashCode() { - return (int)_hMonitor; + return _hMonitor.GetHashCode(); } - public override bool Equals(object obj) + /// + public override bool Equals(object? obj) { - return (obj is WinScreen screen) ? _hMonitor == screen._hMonitor : base.Equals(obj); + return obj is WinScreen screen && _hMonitor == screen._hMonitor; } } } diff --git a/src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs b/src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs index 8c362b0c29..d169ccfc1e 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs @@ -1,12 +1,9 @@ using System; -using System.Buffers; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; -using System.Text; using Avalonia.Automation.Peers; using Avalonia.Controls; -using Avalonia.Controls.Remote; using Avalonia.Input; using Avalonia.Input.Raw; using Avalonia.Platform; @@ -18,7 +15,7 @@ using static Avalonia.Win32.Interop.UnmanagedMethods; namespace Avalonia.Win32 { - public partial class WindowImpl + internal partial class WindowImpl { [SuppressMessage("Microsoft.StyleCop.CSharp.NamingRules", "SA1305:FieldNamesMustNotUseHungarianNotation", Justification = "Using Win32 naming for consistency.")] @@ -27,9 +24,9 @@ namespace Avalonia.Win32 protected virtual unsafe IntPtr AppWndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam) { const double wheelDelta = 120.0; - const long UiaRootObjectId = -25; + const long uiaRootObjectId = -25; uint timestamp = unchecked((uint)GetMessageTime()); - RawInputEventArgs e = null; + RawInputEventArgs? e = null; var shouldTakeFocus = false; var message = (WindowsMessage)msg; switch (message) @@ -92,7 +89,7 @@ namespace Avalonia.Win32 } // We need to release IMM context and state to avoid leaks. - if (Imm32InputMethod.Current.HWND == _hwnd) + if (Imm32InputMethod.Current.Hwnd == _hwnd) { Imm32InputMethod.Current.ClearLanguageAndWindow(); } @@ -104,7 +101,7 @@ namespace Avalonia.Win32 Closed?.Invoke(); _mouseDevice.Dispose(); - _touchDevice?.Dispose(); + _touchDevice.Dispose(); //Free other resources Dispose(); @@ -145,7 +142,7 @@ namespace Avalonia.Win32 e = new RawKeyEventArgs( WindowsKeyboardDevice.Instance, timestamp, - _owner, + Owner, RawKeyEventType.KeyDown, key, WindowsKeyboardDevice.Instance.Modifiers); @@ -175,7 +172,7 @@ namespace Avalonia.Win32 e = new RawKeyEventArgs( WindowsKeyboardDevice.Instance, timestamp, - _owner, + Owner, RawKeyEventType.KeyUp, key, WindowsKeyboardDevice.Instance.Modifiers); @@ -187,7 +184,7 @@ namespace Avalonia.Win32 // Ignore control chars and chars that were handled in WM_KEYDOWN. if (ToInt32(wParam) >= 32 && !_ignoreWmChar) { - e = new RawTextInputEventArgs(WindowsKeyboardDevice.Instance, timestamp, _owner, + e = new RawTextInputEventArgs(WindowsKeyboardDevice.Instance, timestamp, Owner, new string((char)ToInt32(wParam), 1)); } @@ -212,8 +209,10 @@ namespace Avalonia.Win32 e = new RawPointerEventArgs( _mouseDevice, timestamp, - _owner, + Owner, +#pragma warning disable CS8509 message switch +#pragma warning restore CS8509 { WindowsMessage.WM_LBUTTONDOWN => RawPointerEventType.LeftButtonDown, WindowsMessage.WM_RBUTTONDOWN => RawPointerEventType.RightButtonDown, @@ -221,7 +220,7 @@ namespace Avalonia.Win32 WindowsMessage.WM_XBUTTONDOWN => HighWord(ToInt32(wParam)) == 1 ? RawPointerEventType.XButton1Down : - RawPointerEventType.XButton2Down + RawPointerEventType.XButton2Down, }, DipFromLParam(lParam), GetMouseModifiers(wParam)); break; @@ -244,8 +243,10 @@ namespace Avalonia.Win32 e = new RawPointerEventArgs( _mouseDevice, timestamp, - _owner, + Owner, +#pragma warning disable CS8509 message switch +#pragma warning restore CS8509 { WindowsMessage.WM_LBUTTONUP => RawPointerEventType.LeftButtonUp, WindowsMessage.WM_RBUTTONUP => RawPointerEventType.RightButtonUp, @@ -312,12 +313,12 @@ namespace Avalonia.Win32 e = new RawPointerEventArgs( _mouseDevice, timestamp, - _owner, + Owner, RawPointerEventType.Move, point, GetMouseModifiers(wParam)) { - IntermediatePoints = new Lazy>(() => CreateLazyIntermediatePoints(currPoint, prevPoint)) + IntermediatePoints = new Lazy?>(() => CreateIntermediatePoints(currPoint, prevPoint)) }; break; @@ -332,7 +333,7 @@ namespace Avalonia.Win32 e = new RawMouseWheelEventArgs( _mouseDevice, timestamp, - _owner, + Owner, PointToClient(PointFromLParam(lParam)), new Vector(0, (ToInt32(wParam) >> 16) / wheelDelta), GetMouseModifiers(wParam)); @@ -348,7 +349,7 @@ namespace Avalonia.Win32 e = new RawMouseWheelEventArgs( _mouseDevice, timestamp, - _owner, + Owner, PointToClient(PointFromLParam(lParam)), new Vector(-(ToInt32(wParam) >> 16) / wheelDelta, 0), GetMouseModifiers(wParam)); @@ -365,7 +366,7 @@ namespace Avalonia.Win32 e = new RawPointerEventArgs( _mouseDevice, timestamp, - _owner, + Owner, RawPointerEventType.LeaveWindow, new Point(-1, -1), WindowsKeyboardDevice.Instance.Modifiers); @@ -384,8 +385,10 @@ namespace Avalonia.Win32 e = new RawPointerEventArgs( _mouseDevice, timestamp, - _owner, + Owner, +#pragma warning disable CS8509 message switch +#pragma warning restore CS8509 { WindowsMessage.WM_NCLBUTTONDOWN => RawPointerEventType .NonClientLeftButtonDown, @@ -396,12 +399,12 @@ namespace Avalonia.Win32 RawPointerEventType.XButton1Down : RawPointerEventType.XButton2Down, }, - PointToClient(WindowImpl.PointFromLParam(lParam)), GetMouseModifiers(wParam)); + PointToClient(PointFromLParam(lParam)), GetMouseModifiers(wParam)); break; } case WindowsMessage.WM_TOUCH: { - if (_wmPointerEnabled) + if (_wmPointerEnabled || Input is not { } input) { break; } @@ -414,8 +417,8 @@ namespace Avalonia.Win32 { foreach (var touchInput in touchInputs) { - Input?.Invoke(new RawTouchEventArgs(_touchDevice, touchInput.Time, - _owner, + input.Invoke(new RawTouchEventArgs(_touchDevice, touchInput.Time, + Owner, touchInput.Flags.HasAllFlags(TouchInputFlags.TOUCHEVENTF_UP) ? RawPointerEventType.TouchEnd : touchInput.Flags.HasAllFlags(TouchInputFlags.TOUCHEVENTF_DOWN) ? @@ -474,7 +477,7 @@ namespace Avalonia.Win32 var val = (ToInt32(wParam) >> 16) / wheelDelta; var delta = message == WindowsMessage.WM_POINTERWHEEL ? new Vector(0, val) : new Vector(val, 0); - e = new RawMouseWheelEventArgs(device, timestamp, _owner, point.Position, delta, modifiers) + e = new RawMouseWheelEventArgs(device, timestamp, Owner, point.Position, delta, modifiers) { RawPointerId = info.pointerId }; @@ -488,7 +491,7 @@ namespace Avalonia.Win32 } // Do not generate events, but release mouse capture on any other device input. - GetDevicePointerInfo(wParam, out var device, out var info, out var point, out var modifiers, ref timestamp); + GetDevicePointerInfo(wParam, out var device, out _, out _, out _, ref timestamp); if (device != _mouseDevice) { _mouseDevice.Capture(null); @@ -726,9 +729,9 @@ namespace Avalonia.Win32 break; case WindowsMessage.WM_GETOBJECT: - if ((long)lParam == UiaRootObjectId && UiaCoreTypesApi.IsNetComInteropAvailable) + if ((long)lParam == uiaRootObjectId && UiaCoreTypesApi.IsNetComInteropAvailable && _owner is Control control) { - var peer = ControlAutomationPeer.CreatePeerForElement((Control)_owner); + var peer = ControlAutomationPeer.CreatePeerForElement(control); var node = AutomationNode.GetOrCreate(peer); return UiaCoreProviderApi.UiaReturnRawElementProvider(_hwnd, wParam, lParam, node); } @@ -775,12 +778,12 @@ namespace Avalonia.Win32 } } - private unsafe Lazy> CreateLazyIntermediatePoints(POINTER_INFO info) + private Lazy?>? CreateLazyIntermediatePoints(POINTER_INFO info) { var historyCount = Math.Min((int)info.historyCount, MaxPointerHistorySize); if (historyCount > 1) { - return new Lazy>(() => + return new Lazy?>(() => { s_intermediatePointsPooledList.Clear(); s_intermediatePointsPooledList.Capacity = historyCount; @@ -829,7 +832,7 @@ namespace Avalonia.Win32 return null; } - private unsafe IReadOnlyList CreateLazyIntermediatePoints(MOUSEMOVEPOINT movePoint, MOUSEMOVEPOINT prevMovePoint) + private unsafe IReadOnlyList CreateIntermediatePoints(MOUSEMOVEPOINT movePoint, MOUSEMOVEPOINT prevMovePoint) { // To understand some of this code, please check MS docs: // https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getmousemovepointsex#remarks @@ -891,8 +894,8 @@ namespace Avalonia.Win32 private RawPointerEventArgs CreatePointerArgs(IInputDevice device, ulong timestamp, RawPointerEventType eventType, RawPointerPoint point, RawInputModifiers modifiers, uint rawPointerId) { return device is TouchDevice - ? new RawTouchEventArgs(device, timestamp, _owner, eventType, point, modifiers, rawPointerId) - : new RawPointerEventArgs(device, timestamp, _owner, eventType, point, modifiers) + ? new RawTouchEventArgs(device, timestamp, Owner, eventType, point, modifiers, rawPointerId) + : new RawPointerEventArgs(device, timestamp, Owner, eventType, point, modifiers) { RawPointerId = rawPointerId }; @@ -1029,7 +1032,7 @@ namespace Avalonia.Win32 // note: for non-ime language, also create it so that emoji panel tracks cursor var langid = LGID(hkl); - if (langid == _langid && Imm32InputMethod.Current.HWND == Hwnd) + if (langid == _langid && Imm32InputMethod.Current.Hwnd == Hwnd) { return; } diff --git a/src/Windows/Avalonia.Win32/WindowImpl.CustomCaptionProc.cs b/src/Windows/Avalonia.Win32/WindowImpl.CustomCaptionProc.cs index fb27ab7856..4a4565a443 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.CustomCaptionProc.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.CustomCaptionProc.cs @@ -3,17 +3,15 @@ using Avalonia.Controls; using Avalonia.Input; using static Avalonia.Win32.Interop.UnmanagedMethods; -#nullable enable - namespace Avalonia.Win32 { - public partial class WindowImpl + internal partial class WindowImpl { // Hit test the frame for resizing and moving. private HitTestValues HitTestNCA(IntPtr hWnd, IntPtr wParam, IntPtr lParam) { // Get the point coordinates for the hit test (screen space). - var ptMouse = WindowImpl.PointFromLParam(lParam); + var ptMouse = PointFromLParam(lParam); // Get the window rectangle. GetWindowRect(hWnd, out var rcWindow); @@ -101,11 +99,9 @@ namespace Avalonia.Win32 lRet = (IntPtr)hittestResult; - uint timestamp = unchecked((uint)GetMessageTime()); - if (hittestResult == HitTestValues.HTCAPTION) { - var position = PointToClient(WindowImpl.PointFromLParam(lParam)); + var position = PointToClient(PointFromLParam(lParam)); if (_owner is Window window) { diff --git a/src/Windows/Avalonia.Win32/WindowImpl.WndProc.cs b/src/Windows/Avalonia.Win32/WindowImpl.WndProc.cs index 07f2311be8..e92272c079 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.WndProc.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.WndProc.cs @@ -2,18 +2,11 @@ // Licensed under the MIT license. See licence.md file in the project root for full license information. using System; -using System.Diagnostics.CodeAnalysis; -using System.Runtime.InteropServices; -using Avalonia.Controls; using Avalonia.Controls.Platform; -using Avalonia.Input; -using Avalonia.Input.Raw; -using Avalonia.Win32.Input; -using static Avalonia.Win32.Interop.UnmanagedMethods; namespace Avalonia.Win32 { - public partial class WindowImpl + internal partial class WindowImpl { protected virtual unsafe IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam) { diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index 1e0d92d442..14344f34cf 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -1,49 +1,44 @@ using System; using System.Collections.Generic; using System.ComponentModel; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Runtime.InteropServices; -using Avalonia.Controls; -using Avalonia.Automation.Peers; +using Avalonia.Collections.Pooled; using Avalonia.Controls.Platform; -using Avalonia.Input; +using Avalonia.Controls; using Avalonia.Input.Raw; using Avalonia.Input.TextInput; -using Avalonia.OpenGL; -using Avalonia.OpenGL.Angle; +using Avalonia.Input; +using Avalonia.Metadata; using Avalonia.OpenGL.Egl; -using Avalonia.OpenGL.Surfaces; +using Avalonia.Platform.Storage; using Avalonia.Platform; -using Avalonia.Rendering; using Avalonia.Rendering.Composition; -using Avalonia.Win32.Automation; +using Avalonia.Rendering; +using Avalonia.Win32.DirectX; using Avalonia.Win32.Input; using Avalonia.Win32.Interop; +using Avalonia.Win32.OpenGl.Angle; using Avalonia.Win32.OpenGl; -using Avalonia.Win32.WinRT; using Avalonia.Win32.WinRT.Composition; +using Avalonia.Win32.WinRT; using static Avalonia.Win32.Interop.UnmanagedMethods; -using Avalonia.Collections.Pooled; -using Avalonia.Metadata; -using Avalonia.Platform.Storage; -using Avalonia.Win32.DirectX; -using Avalonia.Win32.OpenGl.Angle; namespace Avalonia.Win32 { /// /// Window implementation for Win32 platform. /// - [Unstable] - public partial class WindowImpl : IWindowImpl, EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo + internal partial class WindowImpl : IWindowImpl, EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo { - private static readonly List s_instances = new List(); + private static readonly List s_instances = new(); - private static readonly IntPtr DefaultCursor = LoadCursor( + private static readonly IntPtr s_defaultCursor = LoadCursor( IntPtr.Zero, new IntPtr((int)UnmanagedMethods.Cursor.IDC_ARROW)); private static readonly Dictionary s_edgeLookup = - new Dictionary + new() { { WindowEdge.East, HitTestValues.HTRIGHT }, { WindowEdge.North, HitTestValues.HTTOP }, @@ -61,8 +56,8 @@ namespace Avalonia.Win32 private Thickness _extendedMargins; private Thickness _offScreenMargin; private double _extendTitleBarHint = -1; - private bool _isUsingComposition; - private IBlurHost _blurHost; + private readonly bool _isUsingComposition; + private readonly IBlurHost? _blurHost; private PlatformResizeReason _resizeReason; private MOUSEMOVEPOINT _lastWmMousePoint; @@ -76,26 +71,26 @@ namespace Avalonia.Win32 private readonly PenDevice _penDevice; private readonly ManagedDeferredRendererLock _rendererLock; private readonly FramebufferManager _framebuffer; - private readonly object _gl; + private readonly object? _gl; private readonly bool _wmPointerEnabled; - private Win32NativeControlHost _nativeControlHost; - private IStorageProvider _storageProvider; + private readonly Win32NativeControlHost _nativeControlHost; + private readonly IStorageProvider _storageProvider; private WndProc _wndProcDelegate; - private string _className; + private string? _className; private IntPtr _hwnd; - private IInputRoot _owner; + private IInputRoot? _owner; private WindowProperties _windowProperties; private bool _trackingMouse;//ToDo - there is something missed. Needs investigation @Steven Kirk private bool _topmost; private double _scaling = 1; private WindowState _showWindowState; private WindowState _lastWindowState; - private OleDropTarget _dropTarget; + private OleDropTarget? _dropTarget; private Size _minSize; private Size _maxSize; private POINT _maxTrackSize; - private WindowImpl _parent; + private WindowImpl? _parent; private ExtendClientAreaChromeHints _extendChromeHints = ExtendClientAreaChromeHints.Default; private bool _isCloseRequested; private bool _shown; @@ -142,7 +137,7 @@ namespace Avalonia.Win32 angle.PlatformApi == AngleOptions.PlatformApi.DirectX11; _isUsingComposition = compositionConnector is { } && isUsingAngleDX11; - DxgiConnection dxgiConnection = null; + DxgiConnection? dxgiConnection = null; var isUsingDxgiSwapchain = false; if (!_isUsingComposition) { @@ -159,23 +154,20 @@ namespace Avalonia.Win32 { if (_isUsingComposition) { - var cgl = compositionConnector.CreateSurface(this); + var cgl = compositionConnector!.CreateSurface(this); _blurHost = cgl; - _gl = cgl; - - _isUsingComposition = true; } else if (isUsingDxgiSwapchain) { - var dxgigl = new DxgiSwapchainWindow(dxgiConnection, this); + var dxgigl = new DxgiSwapchainWindow(dxgiConnection!, this); _gl = dxgigl; } else { - if (glPlatform is AngleWin32PlatformGraphics egl2) + if (glPlatform is AngleWin32PlatformGraphics) _gl = new EglGlPlatformSurface(this); - else if (glPlatform is WglPlatformOpenGlInterface wgl) + else if (glPlatform is WglPlatformOpenGlInterface) _gl = new WglGlPlatformSurface(this); } } @@ -187,29 +179,32 @@ namespace Avalonia.Win32 s_instances.Add(this); } - public Action Activated { get; set; } + private IInputRoot Owner + => _owner ?? throw new InvalidOperationException($"{nameof(SetInputRoot)} must have been called"); - public Func Closing { get; set; } + public Action? Activated { get; set; } - public Action Closed { get; set; } + public Func? Closing { get; set; } - public Action Deactivated { get; set; } + public Action? Closed { get; set; } - public Action Input { get; set; } + public Action? Deactivated { get; set; } - public Action Paint { get; set; } + public Action? Input { get; set; } - public Action Resized { get; set; } + public Action? Paint { get; set; } - public Action ScalingChanged { get; set; } + public Action? Resized { get; set; } - public Action PositionChanged { get; set; } + public Action? ScalingChanged { get; set; } - public Action WindowStateChanged { get; set; } + public Action? PositionChanged { get; set; } - public Action LostFocus { get; set; } + public Action? WindowStateChanged { get; set; } - public Action TransparencyLevelChanged { get; set; } + public Action? LostFocus { get; set; } + + public Action? TransparencyLevelChanged { get; set; } public Thickness BorderThickness { @@ -320,7 +315,7 @@ namespace Avalonia.Win32 private bool IsMouseInPointerEnabled => _wmPointerEnabled && IsMouseInPointerEnabled(); - public object TryGetFeature(Type featureType) + public object? TryGetFeature(Type featureType) { if (featureType == typeof(ITextInputMethodImpl)) { @@ -339,7 +334,7 @@ namespace Avalonia.Win32 return null; } - + public void SetTransparencyLevelHint(WindowTransparencyLevel transparencyLevel) { TransparencyLevel = EnableBlur(transparencyLevel); @@ -521,7 +516,10 @@ namespace Avalonia.Win32 } } - public IEnumerable Surfaces => new object[] { (IPlatformNativeSurfaceHandle)Handle, _gl, _framebuffer }; + public IEnumerable Surfaces + => _gl is null ? + new object[] { Handle, _framebuffer } : + new object[] { Handle, _gl, _framebuffer }; public PixelPoint Position { @@ -611,7 +609,7 @@ namespace Avalonia.Win32 SetForegroundWindow(_hwnd); } - public IPopupImpl CreatePopup() => Win32Platform.UseOverlayPopups ? null : new PopupImpl(this); + public IPopupImpl? CreatePopup() => Win32Platform.UseOverlayPopups ? null : new PopupImpl(this); public void Dispose() { @@ -672,7 +670,7 @@ namespace Avalonia.Win32 public void SetInputRoot(IInputRoot inputRoot) { _owner = inputRoot; - CreateDropTarget(); + CreateDropTarget(inputRoot); } public void Hide() @@ -687,11 +685,11 @@ namespace Avalonia.Win32 ShowWindow(_showWindowState, activate); } - public Action GotInputWhenDisabled { get; set; } + public Action? GotInputWhenDisabled { get; set; } - public void SetParent(IWindowImpl parent) + public void SetParent(IWindowImpl? parent) { - _parent = (WindowImpl)parent; + _parent = parent as WindowImpl; var parentHwnd = _parent?._hwnd ?? IntPtr.Zero; @@ -727,30 +725,28 @@ namespace Avalonia.Win32 } } - public void SetTitle(string title) + public void SetTitle(string? title) { SetWindowText(_hwnd, title); } - public void SetCursor(ICursorImpl cursor) + public void SetCursor(ICursorImpl? cursor) { var impl = cursor as CursorImpl; - if (cursor is null || impl is object) - { - var hCursor = impl?.Handle ?? DefaultCursor; - SetClassLong(_hwnd, ClassLongIndex.GCLP_HCURSOR, hCursor); + var hCursor = impl?.Handle ?? s_defaultCursor; + SetClassLong(_hwnd, ClassLongIndex.GCLP_HCURSOR, hCursor); - if (_owner.IsPointerOver) - { - UnmanagedMethods.SetCursor(hCursor); - } + if (Owner.IsPointerOver) + { + UnmanagedMethods.SetCursor(hCursor); } } - public void SetIcon(IWindowIconImpl icon) + public void SetIcon(IWindowIconImpl? icon) { - var impl = (IconImpl)icon; + var impl = icon as IconImpl; + var hIcon = impl?.HIcon ?? IntPtr.Zero; PostMessage(_hwnd, (int)WindowsMessage.WM_SETICON, new IntPtr((int)Icons.ICON_BIG), hIcon); @@ -829,6 +825,9 @@ namespace Avalonia.Win32 IntPtr.Zero); } + [MemberNotNull(nameof(_wndProcDelegate))] + [MemberNotNull(nameof(_className))] + [MemberNotNull(nameof(Handle))] private void CreateWindow() { // Ensure that the delegate doesn't get garbage collected by storing it as a field. @@ -845,7 +844,7 @@ namespace Avalonia.Win32 style = (int)windowClassStyle, lpfnWndProc = _wndProcDelegate, hInstance = GetModuleHandle(null), - hCursor = DefaultCursor, + hCursor = s_defaultCursor, hbrBackground = IntPtr.Zero, lpszClassName = _className }; @@ -878,20 +877,23 @@ namespace Avalonia.Win32 monitor, MONITOR_DPI_TYPE.MDT_EFFECTIVE_DPI, out var dpix, - out var dpiy) == 0) + out _) == 0) { _scaling = dpix / 96.0; } } } - private void CreateDropTarget() + private void CreateDropTarget(IInputRoot inputRoot) { - var odt = new OleDropTarget(this, _owner); - - if (OleContext.Current?.RegisterDragDrop(Handle, odt) ?? false) + if (AvaloniaLocator.Current.GetService() is { } dragDropDevice) { - _dropTarget = odt; + var odt = new OleDropTarget(this, inputRoot, dragDropDevice); + + if (OleContext.Current?.RegisterDragDrop(Handle, odt) ?? false) + { + _dropTarget = odt; + } } } @@ -1105,7 +1107,7 @@ namespace Avalonia.Win32 case WindowState.FullScreen: newWindowProperties.IsFullScreen = true; - command = IsWindowVisible(_hwnd) ? (ShowWindowCommand?)null : ShowWindowCommand.Restore; + command = IsWindowVisible(_hwnd) ? null : ShowWindowCommand.Restore; break; default: @@ -1370,13 +1372,13 @@ namespace Avalonia.Win32 private const int MF_DISABLED = 0x2; private const int SC_CLOSE = 0xF060; - static void DisableCloseButton(IntPtr hwnd) + private static void DisableCloseButton(IntPtr hwnd) { EnableMenuItem(GetSystemMenu(hwnd, false), SC_CLOSE, MF_BYCOMMAND | MF_DISABLED | MF_GRAYED); } - static void EnableCloseButton(IntPtr hwnd) + private static void EnableCloseButton(IntPtr hwnd) { EnableMenuItem(GetSystemMenu(hwnd, false), SC_CLOSE, MF_BYCOMMAND | MF_ENABLED); @@ -1433,7 +1435,7 @@ namespace Avalonia.Win32 public bool IsClientAreaExtendedToDecorations => _isClientAreaExtended; /// - public Action ExtendClientAreaToDecorationsChanged { get; set; } + public Action? ExtendClientAreaToDecorationsChanged { get; set; } /// public bool NeedsManagedDecorations => _isClientAreaExtended && _extendChromeHints.HasAllFlags(ExtendClientAreaChromeHints.PreferSystemChrome); diff --git a/src/Windows/Avalonia.Win32/WindowsMountedVolumeInfoListener.cs b/src/Windows/Avalonia.Win32/WindowsMountedVolumeInfoListener.cs index 3244e75a34..f2da804107 100644 --- a/src/Windows/Avalonia.Win32/WindowsMountedVolumeInfoListener.cs +++ b/src/Windows/Avalonia.Win32/WindowsMountedVolumeInfoListener.cs @@ -2,7 +2,6 @@ using System; using System.Collections.ObjectModel; using System.IO; using System.Linq; -using Avalonia.Reactive; using Avalonia.Controls.Platform; using Avalonia.Logging; using Avalonia.Threading; @@ -12,12 +11,12 @@ namespace Avalonia.Win32 internal class WindowsMountedVolumeInfoListener : IDisposable { private readonly IDisposable _disposable; - private bool _beenDisposed = false; - private ObservableCollection mountedDrives; + private bool _beenDisposed; + private readonly ObservableCollection _mountedDrives; public WindowsMountedVolumeInfoListener(ObservableCollection mountedDrives) { - this.mountedDrives = mountedDrives; + _mountedDrives = mountedDrives; _disposable = DispatcherTimer.Run(Poll, TimeSpan.FromSeconds(1)); @@ -51,14 +50,14 @@ namespace Avalonia.Win32 }) .ToArray(); - if (mountedDrives.SequenceEqual(mountVolInfos)) + if (_mountedDrives.SequenceEqual(mountVolInfos)) return true; else { - mountedDrives.Clear(); + _mountedDrives.Clear(); foreach (var i in mountVolInfos) - mountedDrives.Add(i); + _mountedDrives.Add(i); return true; } } diff --git a/src/Windows/Avalonia.Win32/WindowsMountedVolumeInfoProvider.cs b/src/Windows/Avalonia.Win32/WindowsMountedVolumeInfoProvider.cs index 4f4e0b9293..0731097804 100644 --- a/src/Windows/Avalonia.Win32/WindowsMountedVolumeInfoProvider.cs +++ b/src/Windows/Avalonia.Win32/WindowsMountedVolumeInfoProvider.cs @@ -4,7 +4,7 @@ using Avalonia.Controls.Platform; namespace Avalonia.Win32 { - public class WindowsMountedVolumeInfoProvider : IMountedVolumeInfoProvider + internal class WindowsMountedVolumeInfoProvider : IMountedVolumeInfoProvider { public IDisposable Listen(ObservableCollection mountedDrives) { diff --git a/src/iOS/Avalonia.iOS/ClipboardImpl.cs b/src/iOS/Avalonia.iOS/ClipboardImpl.cs index b9f74d69c6..150f3424e3 100644 --- a/src/iOS/Avalonia.iOS/ClipboardImpl.cs +++ b/src/iOS/Avalonia.iOS/ClipboardImpl.cs @@ -6,7 +6,7 @@ using UIKit; namespace Avalonia.iOS { - public class ClipboardImpl : IClipboard + internal class ClipboardImpl : IClipboard { public Task GetTextAsync() { @@ -16,19 +16,19 @@ namespace Avalonia.iOS public Task SetTextAsync(string text) { UIPasteboard.General.String = text; - return Task.FromResult(0); + return Task.CompletedTask; } public Task ClearAsync() { UIPasteboard.General.String = ""; - return Task.FromResult(0); + return Task.CompletedTask; } - public Task SetDataObjectAsync(IDataObject data) => throw new PlatformNotSupportedException(); + public Task SetDataObjectAsync(IDataObject data) => Task.CompletedTask; - public Task GetFormatsAsync() => throw new PlatformNotSupportedException(); + public Task GetFormatsAsync() => Task.FromResult(Array.Empty()); - public Task GetDataAsync(string format) => throw new PlatformNotSupportedException(); + public Task GetDataAsync(string format) => Task.FromResult(null); } -} \ No newline at end of file +} diff --git a/src/iOS/Avalonia.iOS/LayerFbo.cs b/src/iOS/Avalonia.iOS/LayerFbo.cs index 9a93cdfb22..c19fb2ee8d 100644 --- a/src/iOS/Avalonia.iOS/LayerFbo.cs +++ b/src/iOS/Avalonia.iOS/LayerFbo.cs @@ -5,7 +5,7 @@ using OpenGLES; namespace Avalonia.iOS { - public class LayerFbo + internal class LayerFbo { private readonly EAGLContext _context; private readonly GlInterface _gl; diff --git a/src/iOS/Avalonia.iOS/Stubs.cs b/src/iOS/Avalonia.iOS/Stubs.cs index 9c46aa78cc..6ac89fcab2 100644 --- a/src/iOS/Avalonia.iOS/Stubs.cs +++ b/src/iOS/Avalonia.iOS/Stubs.cs @@ -5,7 +5,7 @@ using Avalonia.Platform; namespace Avalonia.iOS { - class CursorFactoryStub : ICursorFactory + internal class CursorFactoryStub : ICursorFactory { public ICursorImpl CreateCursor(IBitmapImpl cursor, PixelPoint hotSpot) => new CursorImplStub(); ICursorImpl ICursorFactory.GetCursor(StandardCursorType cursorType) => new CursorImplStub(); @@ -16,7 +16,7 @@ namespace Avalonia.iOS } } - class WindowingPlatformStub : IWindowingPlatform + internal class WindowingPlatformStub : IWindowingPlatform { public IWindowImpl CreateWindow() => throw new NotSupportedException(); @@ -25,7 +25,7 @@ namespace Avalonia.iOS public ITrayIconImpl CreateTrayIcon() => null; } - class PlatformIconLoaderStub : IPlatformIconLoader + internal class PlatformIconLoaderStub : IPlatformIconLoader { public IWindowIconImpl LoadIcon(IBitmapImpl bitmap) { @@ -50,7 +50,7 @@ namespace Avalonia.iOS } } - public class IconStub : IWindowIconImpl + internal class IconStub : IWindowIconImpl { private readonly MemoryStream _ms; diff --git a/src/tools/DevGenerators/Helpers.cs b/src/tools/DevGenerators/Helpers.cs index 3da89d2d0e..9cebf6daea 100644 --- a/src/tools/DevGenerators/Helpers.cs +++ b/src/tools/DevGenerators/Helpers.cs @@ -6,16 +6,21 @@ namespace Generator; static class Helpers { + private static readonly SymbolDisplayFormat s_symbolDisplayFormat = + SymbolDisplayFormat.FullyQualifiedFormat.WithMiscellaneousOptions( + SymbolDisplayFormat.FullyQualifiedFormat.MiscellaneousOptions | + SymbolDisplayMiscellaneousOptions.IncludeNullableReferenceTypeModifier); + public static StringBuilder Pad(this StringBuilder sb, int count) => sb.Append(' ', count * 4); public static string GetFullyQualifiedName(this ISymbol symbol) { - return symbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat); + return symbol.ToDisplayString(s_symbolDisplayFormat); } public static bool HasFullyQualifiedName(this ISymbol symbol, string name) { - return symbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat) == name; + return symbol.ToDisplayString(s_symbolDisplayFormat) == name; } public static bool HasAttributeWithFullyQualifiedName(this ISymbol symbol, string name) @@ -28,4 +33,4 @@ static class Helpers return false; } -} \ No newline at end of file +} diff --git a/tests/Avalonia.Base.UnitTests/AvaloniaPropertyTests.cs b/tests/Avalonia.Base.UnitTests/AvaloniaPropertyTests.cs index a9b8a5f21b..7e932373c2 100644 --- a/tests/Avalonia.Base.UnitTests/AvaloniaPropertyTests.cs +++ b/tests/Avalonia.Base.UnitTests/AvaloniaPropertyTests.cs @@ -193,7 +193,12 @@ namespace Avalonia.Base.UnitTests private class Class1 : AvaloniaObject { public static readonly StyledProperty FooProperty = - AvaloniaProperty.Register("Foo", "default", notifying: FooNotifying); + AvaloniaProperty.Register("Foo", "default", + inherits: true, + defaultBindingMode: BindingMode.OneWay, + validate: null, + coerce: null, + notifying: FooNotifying); public int NotifyCount { get; private set; } diff --git a/tests/Avalonia.Controls.UnitTests/ItemsControlTests.cs b/tests/Avalonia.Controls.UnitTests/ItemsControlTests.cs index 28e88d1e71..f074972cef 100644 --- a/tests/Avalonia.Controls.UnitTests/ItemsControlTests.cs +++ b/tests/Avalonia.Controls.UnitTests/ItemsControlTests.cs @@ -147,6 +147,25 @@ namespace Avalonia.Controls.UnitTests Assert.Equal(new[] { child }, target.GetLogicalChildren()); } + [Fact] + public void Control_Item_Should_Be_Logical_Child_After_Layout() + { + var target = new ItemsControl + { + Template = GetTemplate(), + }; + var root = new TestRoot(target); + var child = new Control(); + + target.Template = GetTemplate(); + target.Items = new[] { child }; + root.LayoutManager.ExecuteInitialLayoutPass(); + + Assert.Equal(target, child.Parent); + Assert.Equal(target, child.GetLogicalParent()); + Assert.Equal(new[] { child }, target.GetLogicalChildren()); + } + [Fact] public void Added_Container_Should_Have_LogicalParent_Set_To_ItemsControl() {