diff --git a/Avalonia.sln b/Avalonia.sln index e6898131b0..fc42a5d63b 100644 --- a/Avalonia.sln +++ b/Avalonia.sln @@ -100,7 +100,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Props", "Props", "{F3AC8BC1 build\EmbedXaml.props = build\EmbedXaml.props build\HarfBuzzSharp.props = build\HarfBuzzSharp.props build\ImageSharp.props = build\ImageSharp.props - build\JetBrains.Annotations.props = build\JetBrains.Annotations.props build\JetBrains.dotMemoryUnit.props = build\JetBrains.dotMemoryUnit.props build\Microsoft.CSharp.props = build\Microsoft.CSharp.props build\Microsoft.Reactive.Testing.props = build\Microsoft.Reactive.Testing.props diff --git a/build/JetBrains.Annotations.props b/build/JetBrains.Annotations.props deleted file mode 100644 index 7bc12cbd84..0000000000 --- a/build/JetBrains.Annotations.props +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/nukebuild/DotNetConfigHelper.cs b/nukebuild/DotNetConfigHelper.cs index eca1e2684d..9d43261616 100644 --- a/nukebuild/DotNetConfigHelper.cs +++ b/nukebuild/DotNetConfigHelper.cs @@ -1,5 +1,4 @@ using System.Globalization; -using JetBrains.Annotations; using Nuke.Common.Tools.DotNet; // ReSharper disable ReturnValueOfPureMethodIsNotUsed diff --git a/src/Avalonia.Base/Animation/AnimationInstance`1.cs b/src/Avalonia.Base/Animation/AnimationInstance`1.cs index 0881fde988..6a6e69894b 100644 --- a/src/Avalonia.Base/Animation/AnimationInstance`1.cs +++ b/src/Avalonia.Base/Animation/AnimationInstance`1.cs @@ -5,7 +5,6 @@ using Avalonia.Animation.Animators; using Avalonia.Animation.Utils; using Avalonia.Data; using Avalonia.Reactive; -using JetBrains.Annotations; namespace Avalonia.Animation { diff --git a/src/Avalonia.Base/Avalonia.Base.csproj b/src/Avalonia.Base/Avalonia.Base.csproj index 0d3da66f7a..94a9ea8352 100644 --- a/src/Avalonia.Base/Avalonia.Base.csproj +++ b/src/Avalonia.Base/Avalonia.Base.csproj @@ -15,7 +15,6 @@ - diff --git a/src/Avalonia.Base/Contract.cs b/src/Avalonia.Base/Contract.cs deleted file mode 100644 index 27427700ac..0000000000 --- a/src/Avalonia.Base/Contract.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using System.Runtime.CompilerServices; -using JetBrains.Annotations; - -namespace Avalonia -{ - /// - /// A stub of Code Contract's Contract class. - /// - /// - /// It would be nice to use Code Contracts on Avalonia but last time I tried it slowed things - /// to a crawl and often crashed. Instead use the same signature for checking preconditions - /// in the hope that it might become usable at some point. - /// - public static class Contract - { - /// - /// Specifies a precondition. - /// - /// - /// The exception to throw if is false. - /// - /// The precondition. - [MethodImpl(MethodImplOptions.AggressiveInlining)] - [ContractAnnotation("condition:false=>stop")] - public static void Requires(bool condition) where TException : Exception, new() - { - if (!condition) - { - throw new TException(); - } - } - } -} diff --git a/src/Avalonia.Base/Data/InstancedBinding.cs b/src/Avalonia.Base/Data/InstancedBinding.cs index a349486bf8..4a1e2660de 100644 --- a/src/Avalonia.Base/Data/InstancedBinding.cs +++ b/src/Avalonia.Base/Data/InstancedBinding.cs @@ -28,11 +28,9 @@ namespace Avalonia.Data /// public InstancedBinding(ISubject subject, BindingMode mode, BindingPriority priority) { - Contract.Requires(subject != null); - Mode = mode; Priority = priority; - Value = subject; + Value = subject ?? throw new ArgumentNullException(nameof(subject)); } private InstancedBinding(object? value, BindingMode mode, BindingPriority priority) diff --git a/src/Avalonia.Base/Input/Raw/RawInputEventArgs.cs b/src/Avalonia.Base/Input/Raw/RawInputEventArgs.cs index 3a5ae1340f..cf4d37b6da 100644 --- a/src/Avalonia.Base/Input/Raw/RawInputEventArgs.cs +++ b/src/Avalonia.Base/Input/Raw/RawInputEventArgs.cs @@ -21,11 +21,9 @@ namespace Avalonia.Input.Raw /// The root from which the event originates. public RawInputEventArgs(IInputDevice device, ulong timestamp, IInputRoot root) { - device = device ?? throw new ArgumentNullException(nameof(device)); - - Device = device; + Device = device ?? throw new ArgumentNullException(nameof(device)); Timestamp = timestamp; - Root = root; + Root = root ?? throw new ArgumentNullException(nameof(root)); } /// diff --git a/src/Avalonia.Base/Input/Raw/RawPointerEventArgs.cs b/src/Avalonia.Base/Input/Raw/RawPointerEventArgs.cs index 854dd4b83b..ebedc9e6e8 100644 --- a/src/Avalonia.Base/Input/Raw/RawPointerEventArgs.cs +++ b/src/Avalonia.Base/Input/Raw/RawPointerEventArgs.cs @@ -53,9 +53,6 @@ namespace Avalonia.Input.Raw RawInputModifiers inputModifiers) : base(device, timestamp, root) { - Contract.Requires(device != null); - Contract.Requires(root != null); - Point = new RawPointerPoint(); Position = position; Type = type; @@ -80,9 +77,6 @@ namespace Avalonia.Input.Raw RawInputModifiers inputModifiers) : base(device, timestamp, root) { - Contract.Requires(device != null); - Contract.Requires(root != null); - Point = point; Type = type; InputModifiers = inputModifiers; diff --git a/src/Avalonia.Base/Media/DrawingGroup.cs b/src/Avalonia.Base/Media/DrawingGroup.cs index e71f568207..4a46d89153 100644 --- a/src/Avalonia.Base/Media/DrawingGroup.cs +++ b/src/Avalonia.Base/Media/DrawingGroup.cs @@ -461,9 +461,10 @@ namespace Avalonia.Media if (_rootDrawing == null) { - // When a DrawingGroup is set, it should be made the root if - // a root drawing didnt exist. - Contract.Requires(_currentDrawingGroup == null); + if (_currentDrawingGroup != null) + { + throw new NotSupportedException("When a DrawingGroup is set, it should be made the root if a root drawing didnt exist."); + } // If this is the first Drawing being added, avoid creating a DrawingGroup // and set this drawing as the root drawing. This optimizes the common diff --git a/src/Avalonia.Base/Media/Typeface.cs b/src/Avalonia.Base/Media/Typeface.cs index e6047bf96c..1e744c30c8 100644 --- a/src/Avalonia.Base/Media/Typeface.cs +++ b/src/Avalonia.Base/Media/Typeface.cs @@ -1,6 +1,5 @@ using System; using System.Diagnostics; -using JetBrains.Annotations; namespace Avalonia.Media { @@ -17,7 +16,7 @@ namespace Avalonia.Media /// The font style. /// The font weight. /// The font stretch. - public Typeface([NotNull] FontFamily fontFamily, + public Typeface(FontFamily fontFamily, FontStyle style = FontStyle.Normal, FontWeight weight = FontWeight.Normal, FontStretch stretch = FontStretch.Normal) diff --git a/src/Avalonia.Base/PixelVector.cs b/src/Avalonia.Base/PixelVector.cs index 79e7b94c21..0e156190a4 100644 --- a/src/Avalonia.Base/PixelVector.cs +++ b/src/Avalonia.Base/PixelVector.cs @@ -1,7 +1,6 @@ using System; using System.Globalization; using Avalonia.Animation.Animators; -using JetBrains.Annotations; namespace Avalonia { @@ -135,7 +134,6 @@ namespace Avalonia /// /// The other vector. /// True if vectors are nearly equal. - [Pure] public bool NearlyEquals(PixelVector other) { const float tolerance = float.Epsilon; diff --git a/src/Avalonia.Base/Visual.cs b/src/Avalonia.Base/Visual.cs index ddaea01b05..5930df5483 100644 --- a/src/Avalonia.Base/Visual.cs +++ b/src/Avalonia.Base/Visual.cs @@ -367,7 +367,10 @@ namespace Avalonia /// The drawing context. public virtual void Render(DrawingContext context) { - Contract.Requires(context != null); + if (context is null) + { + throw new ArgumentNullException(nameof(context)); + } } /// diff --git a/src/Avalonia.Controls.ColorPicker/Avalonia.Controls.ColorPicker.csproj b/src/Avalonia.Controls.ColorPicker/Avalonia.Controls.ColorPicker.csproj index f3f8e4c82c..97f9efe8fa 100644 --- a/src/Avalonia.Controls.ColorPicker/Avalonia.Controls.ColorPicker.csproj +++ b/src/Avalonia.Controls.ColorPicker/Avalonia.Controls.ColorPicker.csproj @@ -17,7 +17,6 @@ - diff --git a/src/Avalonia.Controls.DataGrid/Avalonia.Controls.DataGrid.csproj b/src/Avalonia.Controls.DataGrid/Avalonia.Controls.DataGrid.csproj index 6369961f0f..efa38e49a7 100644 --- a/src/Avalonia.Controls.DataGrid/Avalonia.Controls.DataGrid.csproj +++ b/src/Avalonia.Controls.DataGrid/Avalonia.Controls.DataGrid.csproj @@ -14,7 +14,6 @@ - diff --git a/src/Avalonia.Controls.DataGrid/DataGridColumn.cs b/src/Avalonia.Controls.DataGrid/DataGridColumn.cs index 2b715d6a9f..75101dc487 100644 --- a/src/Avalonia.Controls.DataGrid/DataGridColumn.cs +++ b/src/Avalonia.Controls.DataGrid/DataGridColumn.cs @@ -641,7 +641,7 @@ namespace Avalonia.Controls public Control GetCellContent(DataGridRow dataGridRow) { - Contract.Requires(dataGridRow != null); + dataGridRow = dataGridRow ?? throw new ArgumentNullException(nameof(dataGridRow)); if (OwningGrid == null) { throw DataGridError.DataGrid.NoOwningGrid(GetType()); @@ -659,7 +659,7 @@ namespace Avalonia.Controls public Control GetCellContent(object dataItem) { - Contract.Requires(dataItem != null); + dataItem = dataItem ?? throw new ArgumentNullException(nameof(dataItem)); if (OwningGrid == null) { throw DataGridError.DataGrid.NoOwningGrid(GetType()); diff --git a/src/Avalonia.Controls.DataGrid/DataGridRows.cs b/src/Avalonia.Controls.DataGrid/DataGridRows.cs index 6c997f62c1..4d3bccee70 100644 --- a/src/Avalonia.Controls.DataGrid/DataGridRows.cs +++ b/src/Avalonia.Controls.DataGrid/DataGridRows.cs @@ -16,7 +16,6 @@ using System.Diagnostics; using System.Linq; using Avalonia.Data; using Avalonia.Styling; -using JetBrains.Annotations; namespace Avalonia.Controls { diff --git a/src/Avalonia.Controls.DataGrid/Primitives/DataGridFrozenGrid.cs b/src/Avalonia.Controls.DataGrid/Primitives/DataGridFrozenGrid.cs index 9feca71cda..4fd0ca3d26 100644 --- a/src/Avalonia.Controls.DataGrid/Primitives/DataGridFrozenGrid.cs +++ b/src/Avalonia.Controls.DataGrid/Primitives/DataGridFrozenGrid.cs @@ -26,7 +26,6 @@ namespace Avalonia.Controls.Primitives /// true if the grid is frozen; otherwise, false. The default is true. public static bool GetIsFrozen(Control element) { - Contract.Requires(element != null); return element.GetValue(IsFrozenProperty); } @@ -38,7 +37,6 @@ namespace Avalonia.Controls.Primitives /// is null. public static void SetIsFrozen(Control element, bool value) { - Contract.Requires(element != null); element.SetValue(IsFrozenProperty, value); } } diff --git a/src/Avalonia.Controls/Avalonia.Controls.csproj b/src/Avalonia.Controls/Avalonia.Controls.csproj index 2710ac5cc2..cf4beab6d4 100644 --- a/src/Avalonia.Controls/Avalonia.Controls.csproj +++ b/src/Avalonia.Controls/Avalonia.Controls.csproj @@ -7,7 +7,6 @@ - diff --git a/src/Avalonia.Controls/ComboBox.cs b/src/Avalonia.Controls/ComboBox.cs index a0085c92ca..a96cfe4690 100644 --- a/src/Avalonia.Controls/ComboBox.cs +++ b/src/Avalonia.Controls/ComboBox.cs @@ -95,19 +95,26 @@ namespace Avalonia.Controls { ItemsPanelProperty.OverrideDefaultValue(DefaultPanel); FocusableProperty.OverrideDefaultValue(true); - SelectedItemProperty.Changed.AddClassHandler((x, e) => x.SelectedItemChanged(e)); - KeyDownEvent.AddClassHandler((x, e) => x.OnKeyDown(e), Interactivity.RoutingStrategies.Tunnel); IsTextSearchEnabledProperty.OverrideDefaultValue(true); - IsDropDownOpenProperty.Changed.AddClassHandler((x, e) => x.DropdownChanged(e)); } + /// + /// Occurs after the drop-down (popup) list of the closes. + /// + public event EventHandler? DropDownClosed; + + /// + /// Occurs after the drop-down (popup) list of the opens. + /// + public event EventHandler? DropDownOpened; + /// /// Gets or sets a value indicating whether the dropdown is currently open. /// public bool IsDropDownOpen { - get { return _isDropDownOpen; } - set { SetAndRaise(IsDropDownOpenProperty, ref _isDropDownOpen, value); } + get => _isDropDownOpen; + set => SetAndRaise(IsDropDownOpenProperty, ref _isDropDownOpen, value); } /// @@ -115,8 +122,8 @@ namespace Avalonia.Controls /// public double MaxDropDownHeight { - get { return GetValue(MaxDropDownHeightProperty); } - set { SetValue(MaxDropDownHeightProperty, value); } + get => GetValue(MaxDropDownHeightProperty); + set => SetValue(MaxDropDownHeightProperty, value); } /// @@ -124,8 +131,8 @@ namespace Avalonia.Controls /// protected object? SelectionBoxItem { - get { return _selectionBoxItem; } - set { SetAndRaise(SelectionBoxItemProperty, ref _selectionBoxItem, value); } + get => _selectionBoxItem; + set => SetAndRaise(SelectionBoxItemProperty, ref _selectionBoxItem, value); } /// @@ -133,8 +140,8 @@ namespace Avalonia.Controls /// public string? PlaceholderText { - get { return GetValue(PlaceholderTextProperty); } - set { SetValue(PlaceholderTextProperty, value); } + get => GetValue(PlaceholderTextProperty); + set => SetValue(PlaceholderTextProperty, value); } /// @@ -142,8 +149,8 @@ namespace Avalonia.Controls /// public IBrush? PlaceholderForeground { - get { return GetValue(PlaceholderForegroundProperty); } - set { SetValue(PlaceholderForegroundProperty, value); } + get => GetValue(PlaceholderForegroundProperty); + set => SetValue(PlaceholderForegroundProperty, value); } /// @@ -151,8 +158,8 @@ namespace Avalonia.Controls /// public ItemVirtualizationMode VirtualizationMode { - get { return GetValue(VirtualizationModeProperty); } - set { SetValue(VirtualizationModeProperty, value); } + get => GetValue(VirtualizationModeProperty); + set => SetValue(VirtualizationModeProperty, value); } /// @@ -160,8 +167,8 @@ namespace Avalonia.Controls /// public HorizontalAlignment HorizontalContentAlignment { - get { return GetValue(HorizontalContentAlignmentProperty); } - set { SetValue(HorizontalContentAlignmentProperty, value); } + get => GetValue(HorizontalContentAlignmentProperty); + set => SetValue(HorizontalContentAlignmentProperty, value); } /// @@ -169,8 +176,8 @@ namespace Avalonia.Controls /// public VerticalAlignment VerticalContentAlignment { - get { return GetValue(VerticalContentAlignmentProperty); } - set { SetValue(VerticalContentAlignmentProperty, value); } + get => GetValue(VerticalContentAlignmentProperty); + set => SetValue(VerticalContentAlignmentProperty, value); } /// @@ -182,6 +189,7 @@ namespace Avalonia.Controls ComboBoxItem.ContentTemplateProperty); } + /// protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) { base.OnAttachedToVisualTree(e); @@ -239,7 +247,7 @@ namespace Avalonia.Controls } // This part of code is needed just to acquire initial focus, subsequent focus navigation will be done by ItemsControl. else if (IsDropDownOpen && SelectedIndex < 0 && ItemCount > 0 && - (e.Key == Key.Up || e.Key == Key.Down) && IsFocused == true) + (e.Key == Key.Up || e.Key == Key.Down) && IsFocused == true) { var firstChild = Presenter?.Panel?.Children.FirstOrDefault(c => CanFocus(c)); if (firstChild != null) @@ -309,12 +317,11 @@ namespace Avalonia.Controls e.Handled = true; } } + PseudoClasses.Set(pcPressed, false); base.OnPointerReleased(e); - } - /// protected override void OnApplyTemplate(TemplateAppliedEventArgs e) { @@ -329,6 +336,22 @@ namespace Avalonia.Controls _popup.Closed += PopupClosed; } + /// + protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) + { + if (change.Property == SelectedItemProperty) + { + UpdateSelectionBoxItem(change.NewValue); + TryFocusSelectedItem(); + } + else if (change.Property == IsDropDownOpenProperty) + { + PseudoClasses.Set(pcDropdownOpen, change.GetNewValue()); + } + + base.OnPropertyChanged(change); + } + protected override AutomationPeer OnCreateAutomationPeer() { return new ComboBoxAutomationPeer(this); @@ -350,6 +373,8 @@ namespace Avalonia.Controls { Focus(); } + + DropDownClosed?.Invoke(this, EventArgs.Empty); } private void PopupOpened(object? sender, EventArgs e) @@ -379,6 +404,8 @@ namespace Avalonia.Controls } UpdateFlowDirection(); + + DropDownOpened?.Invoke(this, EventArgs.Empty); } private void IsVisibleChanged(bool isVisible) @@ -389,12 +416,6 @@ namespace Avalonia.Controls } } - private void SelectedItemChanged(AvaloniaPropertyChangedEventArgs e) - { - UpdateSelectionBoxItem(e.NewValue); - TryFocusSelectedItem(); - } - private void TryFocusSelectedItem() { var selectedIndex = SelectedIndex; @@ -494,11 +515,5 @@ namespace Avalonia.Controls MoveSelection(NavigationDirection.Previous, WrapSelection); } } - - private void DropdownChanged(AvaloniaPropertyChangedEventArgs e) - { - bool newValue = e.GetNewValue(); - PseudoClasses.Set(pcDropdownOpen, newValue); - } } } diff --git a/src/Avalonia.Controls/Utils/BorderRenderHelper.cs b/src/Avalonia.Controls/Utils/BorderRenderHelper.cs index eb9f38894d..6239a5120d 100644 --- a/src/Avalonia.Controls/Utils/BorderRenderHelper.cs +++ b/src/Avalonia.Controls/Utils/BorderRenderHelper.cs @@ -4,7 +4,6 @@ using Avalonia.Media; using Avalonia.Media.Immutable; using Avalonia.Platform; using Avalonia.Utilities; -using JetBrains.Annotations; namespace Avalonia.Controls.Utils { diff --git a/src/Avalonia.Controls/WindowBase.cs b/src/Avalonia.Controls/WindowBase.cs index b71dc6df44..65325aac92 100644 --- a/src/Avalonia.Controls/WindowBase.cs +++ b/src/Avalonia.Controls/WindowBase.cs @@ -8,7 +8,6 @@ using Avalonia.Controls.Primitives; using Avalonia.Input; using Avalonia.Layout; using Avalonia.Platform; -using JetBrains.Annotations; namespace Avalonia.Controls { diff --git a/src/Avalonia.FreeDesktop/LinuxMountedVolumeInfoProvider.cs b/src/Avalonia.FreeDesktop/LinuxMountedVolumeInfoProvider.cs index b69ea68a76..4624a9c340 100644 --- a/src/Avalonia.FreeDesktop/LinuxMountedVolumeInfoProvider.cs +++ b/src/Avalonia.FreeDesktop/LinuxMountedVolumeInfoProvider.cs @@ -9,8 +9,7 @@ namespace Avalonia.FreeDesktop { public IDisposable Listen(ObservableCollection mountedDrives) { - Contract.Requires(mountedDrives != null); - return new LinuxMountedVolumeInfoListener(ref mountedDrives!); + return new LinuxMountedVolumeInfoListener(ref mountedDrives); } } } diff --git a/src/Avalonia.Native/AvaloniaNativePlatform.cs b/src/Avalonia.Native/AvaloniaNativePlatform.cs index a5b2ea30cc..6d5925c0ae 100644 --- a/src/Avalonia.Native/AvaloniaNativePlatform.cs +++ b/src/Avalonia.Native/AvaloniaNativePlatform.cs @@ -9,23 +9,23 @@ using Avalonia.OpenGL; using Avalonia.Platform; using Avalonia.Rendering; using Avalonia.Rendering.Composition; -using JetBrains.Annotations; using MicroCom.Runtime; +#nullable enable namespace Avalonia.Native { class AvaloniaNativePlatform : IWindowingPlatform { private readonly IAvaloniaNativeFactory _factory; - private AvaloniaNativePlatformOptions _options; - private AvaloniaNativeGlPlatformGraphics _platformGl; + private AvaloniaNativePlatformOptions? _options; + private AvaloniaNativeGlPlatformGraphics? _platformGl; [DllImport("libAvaloniaNative")] static extern IntPtr CreateAvaloniaNative(); internal static readonly KeyboardDevice KeyboardDevice = new KeyboardDevice(); - [CanBeNull] internal static Compositor Compositor { get; private set; } - [CanBeNull] internal static PlatformRenderInterfaceContextManager RenderInterface { get; private set; } + internal static Compositor? Compositor { get; private set; } + internal static PlatformRenderInterfaceContextManager? RenderInterface { get; private set; } public static AvaloniaNativePlatform Initialize(IntPtr factory, AvaloniaNativePlatformOptions options) { @@ -63,7 +63,7 @@ namespace Avalonia.Native public void SetupApplicationName() { - if (!string.IsNullOrWhiteSpace(Application.Current.Name)) + if (!string.IsNullOrWhiteSpace(Application.Current!.Name)) { _factory.MacOptions.SetApplicationTitle(Application.Current.Name); } @@ -118,10 +118,13 @@ namespace Avalonia.Native AvaloniaLocator.CurrentMutable.Bind().ToConstant(renderLoop); var hotkeys = AvaloniaLocator.Current.GetService(); - hotkeys.MoveCursorToTheStartOfLine.Add(new KeyGesture(Key.Left, hotkeys.CommandModifiers)); - hotkeys.MoveCursorToTheStartOfLineWithSelection.Add(new KeyGesture(Key.Left, hotkeys.CommandModifiers | hotkeys.SelectionModifiers)); - hotkeys.MoveCursorToTheEndOfLine.Add(new KeyGesture(Key.Right, hotkeys.CommandModifiers)); - hotkeys.MoveCursorToTheEndOfLineWithSelection.Add(new KeyGesture(Key.Right, hotkeys.CommandModifiers | hotkeys.SelectionModifiers)); + if (hotkeys is not null) + { + hotkeys.MoveCursorToTheStartOfLine.Add(new KeyGesture(Key.Left, hotkeys.CommandModifiers)); + hotkeys.MoveCursorToTheStartOfLineWithSelection.Add(new KeyGesture(Key.Left, hotkeys.CommandModifiers | hotkeys.SelectionModifiers)); + hotkeys.MoveCursorToTheEndOfLine.Add(new KeyGesture(Key.Right, hotkeys.CommandModifiers)); + hotkeys.MoveCursorToTheEndOfLineWithSelection.Add(new KeyGesture(Key.Right, hotkeys.CommandModifiers | hotkeys.SelectionModifiers)); + } if (_options.UseGpu) { diff --git a/src/Avalonia.Native/Helpers.cs b/src/Avalonia.Native/Helpers.cs index 764ff789dc..6270cd30a0 100644 --- a/src/Avalonia.Native/Helpers.cs +++ b/src/Avalonia.Native/Helpers.cs @@ -1,5 +1,4 @@ using Avalonia.Native.Interop; -using JetBrains.Annotations; namespace Avalonia.Native { diff --git a/src/Avalonia.Native/MacOSMountedVolumeInfoProvider.cs b/src/Avalonia.Native/MacOSMountedVolumeInfoProvider.cs index 92b2915e2e..1907a3d129 100644 --- a/src/Avalonia.Native/MacOSMountedVolumeInfoProvider.cs +++ b/src/Avalonia.Native/MacOSMountedVolumeInfoProvider.cs @@ -72,7 +72,6 @@ namespace Avalonia.Native { public IDisposable Listen(ObservableCollection mountedDrives) { - Contract.Requires(mountedDrives != null); return new MacOSMountedVolumeInfoListener(mountedDrives); } } diff --git a/src/Avalonia.X11/NativeDialogs/Gtk.cs b/src/Avalonia.X11/NativeDialogs/Gtk.cs index d5eae037a9..4e56ae73cf 100644 --- a/src/Avalonia.X11/NativeDialogs/Gtk.cs +++ b/src/Avalonia.X11/NativeDialogs/Gtk.cs @@ -3,7 +3,6 @@ using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; using Avalonia.Platform.Interop; -using JetBrains.Annotations; // ReSharper disable IdentifierTypo namespace Avalonia.X11.NativeDialogs diff --git a/src/Avalonia.X11/X11Info.cs b/src/Avalonia.X11/X11Info.cs index 13dc460f45..72f3bf3137 100644 --- a/src/Avalonia.X11/X11Info.cs +++ b/src/Avalonia.X11/X11Info.cs @@ -2,7 +2,6 @@ using System; using System.Linq; using System.Reflection; using System.Runtime.InteropServices; -using JetBrains.Annotations; using static Avalonia.X11.XLib; // ReSharper disable UnusedAutoPropertyAccessor.Local namespace Avalonia.X11 diff --git a/src/Avalonia.X11/X11Screens.cs b/src/Avalonia.X11/X11Screens.cs index ba6029b350..87899b11ed 100644 --- a/src/Avalonia.X11/X11Screens.cs +++ b/src/Avalonia.X11/X11Screens.cs @@ -5,7 +5,6 @@ using System.Linq; using System.Runtime.InteropServices; using Avalonia.Platform; using static Avalonia.X11.XLib; -using JetBrains.Annotations; namespace Avalonia.X11 { diff --git a/src/Avalonia.X11/X11Window.Ime.cs b/src/Avalonia.X11/X11Window.Ime.cs index 257580a5ec..e6066c7964 100644 --- a/src/Avalonia.X11/X11Window.Ime.cs +++ b/src/Avalonia.X11/X11Window.Ime.cs @@ -7,7 +7,6 @@ using Avalonia.Input; using Avalonia.Input.Raw; using Avalonia.Input.TextInput; using Avalonia.Platform.Interop; -using JetBrains.Annotations; using static Avalonia.X11.XLib; namespace Avalonia.X11 @@ -206,7 +205,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 { - public RawKeyEventArgsWithText([NotNull] IKeyboardDevice device, ulong timestamp, [NotNull] IInputRoot root, + public RawKeyEventArgsWithText(IKeyboardDevice device, ulong timestamp, IInputRoot root, RawKeyEventType type, Key key, RawInputModifiers modifiers, string text) : base(device, timestamp, root, type, key, modifiers) { diff --git a/src/Linux/Avalonia.LinuxFramebuffer/DrmOutputOptions.cs b/src/Linux/Avalonia.LinuxFramebuffer/DrmOutputOptions.cs index ce843952e7..3439f0edae 100644 --- a/src/Linux/Avalonia.LinuxFramebuffer/DrmOutputOptions.cs +++ b/src/Linux/Avalonia.LinuxFramebuffer/DrmOutputOptions.cs @@ -1,6 +1,5 @@ using Avalonia.LinuxFramebuffer.Output; using Avalonia.Media; -using JetBrains.Annotations; namespace Avalonia.LinuxFramebuffer { diff --git a/src/Linux/Avalonia.LinuxFramebuffer/LinuxFramebufferPlatform.cs b/src/Linux/Avalonia.LinuxFramebuffer/LinuxFramebufferPlatform.cs index 38498951f8..e2e9ec8fb3 100644 --- a/src/Linux/Avalonia.LinuxFramebuffer/LinuxFramebufferPlatform.cs +++ b/src/Linux/Avalonia.LinuxFramebuffer/LinuxFramebufferPlatform.cs @@ -17,7 +17,7 @@ using Avalonia.Platform; using Avalonia.Rendering; using Avalonia.Rendering.Composition; using Avalonia.Threading; -using JetBrains.Annotations; +#nullable enable namespace Avalonia.LinuxFramebuffer { @@ -26,9 +26,9 @@ namespace Avalonia.LinuxFramebuffer IOutputBackend _fb; private static readonly Stopwatch St = Stopwatch.StartNew(); internal static uint Timestamp => (uint)St.ElapsedTicks; - public static InternalPlatformThreadingInterface Threading; + public static InternalPlatformThreadingInterface? Threading; - internal static Compositor Compositor { get; private set; } + internal static Compositor? Compositor { get; private set; } LinuxFramebufferPlatform(IOutputBackend backend) @@ -60,7 +60,7 @@ namespace Avalonia.LinuxFramebuffer } - internal static LinuxFramebufferLifetime Initialize(T builder, IOutputBackend outputBackend, IInputBackend inputBackend) where T : AppBuilderBase, new() + internal static LinuxFramebufferLifetime Initialize(T builder, IOutputBackend outputBackend, IInputBackend? inputBackend) where T : AppBuilderBase, new() { var platform = new LinuxFramebufferPlatform(outputBackend); builder.UseSkia().UseWindowingSubsystem(platform.Initialize, "fbdev"); @@ -71,8 +71,8 @@ namespace Avalonia.LinuxFramebuffer class LinuxFramebufferLifetime : IControlledApplicationLifetime, ISingleViewApplicationLifetime { private readonly IOutputBackend _fb; - [CanBeNull] private readonly IInputBackend _inputBackend; - private TopLevel _topLevel; + private readonly IInputBackend? _inputBackend; + private TopLevel? _topLevel; private readonly CancellationTokenSource _cts = new CancellationTokenSource(); public CancellationToken Token => _cts.Token; @@ -81,15 +81,15 @@ namespace Avalonia.LinuxFramebuffer _fb = fb; } - public LinuxFramebufferLifetime(IOutputBackend fb, IInputBackend input) + public LinuxFramebufferLifetime(IOutputBackend fb, IInputBackend? input) { _fb = fb; _inputBackend = input; } - public Control MainView + public Control? MainView { - get => (Control)_topLevel?.Content; + get => (Control?)_topLevel?.Content; set { if (_topLevel == null) @@ -119,8 +119,8 @@ namespace Avalonia.LinuxFramebuffer } public int ExitCode { get; private set; } - public event EventHandler Startup; - public event EventHandler Exit; + public event EventHandler? Startup; + public event EventHandler? Exit; public void Start(string[] args) { @@ -140,19 +140,19 @@ namespace Avalonia.LinuxFramebuffer public static class LinuxFramebufferPlatformExtensions { - public static int StartLinuxFbDev(this T builder, string[] args, string fbdev = null, double scaling = 1, IInputBackend inputBackend = default) + public static int StartLinuxFbDev(this T builder, string[] args, string? fbdev = null, double scaling = 1, IInputBackend? inputBackend = default) where T : AppBuilderBase, new() => StartLinuxDirect(builder, args, new FbdevOutput(fileName: fbdev, format: null) { Scaling = scaling }, inputBackend); - public static int StartLinuxFbDev(this T builder, string[] args, string fbdev, PixelFormat? format, double scaling, IInputBackend inputBackend = default) + public static int StartLinuxFbDev(this T builder, string[] args, string fbdev, PixelFormat? format, double scaling, IInputBackend? inputBackend = default) where T : AppBuilderBase, new() => StartLinuxDirect(builder, args, new FbdevOutput(fileName: fbdev, format: format) { Scaling = scaling }, inputBackend); - public static int StartLinuxDrm(this T builder, string[] args, string card = null, double scaling = 1, IInputBackend inputBackend = default) + public static int StartLinuxDrm(this T builder, string[] args, string? card = null, double scaling = 1, IInputBackend? inputBackend = default) where T : AppBuilderBase, new() => StartLinuxDirect(builder, args, new DrmOutput(card) { Scaling = scaling }, inputBackend); - public static int StartLinuxDrm(this T builder, string[] args, string card = null, bool connectorsForceProbe = false, [CanBeNull] DrmOutputOptions options = null, IInputBackend inputBackend = default) + public static int StartLinuxDrm(this T builder, string[] args, string? card = null, bool connectorsForceProbe = false, DrmOutputOptions? options = null, IInputBackend? inputBackend = default) where T : AppBuilderBase, new() => StartLinuxDirect(builder, args, new DrmOutput(card, connectorsForceProbe, options), inputBackend); - public static int StartLinuxDirect(this T builder, string[] args, IOutputBackend outputBackend, IInputBackend inputBackend = default) + public static int StartLinuxDirect(this T builder, string[] args, IOutputBackend outputBackend, IInputBackend? inputBackend = default) where T : AppBuilderBase, new() { var lifetime = LinuxFramebufferPlatform.Initialize(builder, outputBackend, inputBackend); diff --git a/src/Linux/Avalonia.LinuxFramebuffer/Output/DrmOutput.cs b/src/Linux/Avalonia.LinuxFramebuffer/Output/DrmOutput.cs index 22dd407791..d61dcd4f91 100644 --- a/src/Linux/Avalonia.LinuxFramebuffer/Output/DrmOutput.cs +++ b/src/Linux/Avalonia.LinuxFramebuffer/Output/DrmOutput.cs @@ -8,7 +8,6 @@ using Avalonia.OpenGL.Egl; using Avalonia.OpenGL.Surfaces; using Avalonia.Platform; using Avalonia.Platform.Interop; -using JetBrains.Annotations; using static Avalonia.LinuxFramebuffer.NativeUnsafeMethods; using static Avalonia.LinuxFramebuffer.Output.LibDrm; using static Avalonia.LinuxFramebuffer.Output.LibDrm.GbmColorFormats; @@ -50,7 +49,7 @@ namespace Avalonia.LinuxFramebuffer.Output _outputOptions = options; Init(card, resources, connector, modeInfo); } - public DrmOutput(string path = null, bool connectorsForceProbe = false, [CanBeNull] DrmOutputOptions options = null) + public DrmOutput(string path = null, bool connectorsForceProbe = false, DrmOutputOptions? options = null) { if(options != null) _outputOptions = options; diff --git a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/CommandAccessorPlugin.cs b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/CommandAccessorPlugin.cs index 3084964d44..4478a79d27 100644 --- a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/CommandAccessorPlugin.cs +++ b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/CommandAccessorPlugin.cs @@ -44,9 +44,7 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings public CommandAccessor(WeakReference reference, Action execute, Func canExecute, ISet dependsOnProperties) { - Contract.Requires(reference != null); - - _reference = reference; + _reference = reference ?? throw new ArgumentNullException(nameof(reference)); _dependsOnProperties = dependsOnProperties; _command = new Command(reference, execute, canExecute); diff --git a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/PropertyInfoAccessorFactory.cs b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/PropertyInfoAccessorFactory.cs index ef11b06369..81f1224650 100644 --- a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/PropertyInfoAccessorFactory.cs +++ b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/CompiledBindings/PropertyInfoAccessorFactory.cs @@ -28,11 +28,8 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings public AvaloniaPropertyAccessor(WeakReference reference, AvaloniaProperty property) { - Contract.Requires(reference != null); - Contract.Requires(property != null); - - _reference = reference; - _property = property; + _reference = reference ?? throw new ArgumentNullException(nameof(reference));; + _property = property ?? throw new ArgumentNullException(nameof(property));; } public AvaloniaObject Instance @@ -77,11 +74,8 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions.CompiledBindings public InpcPropertyAccessor(WeakReference reference, IPropertyInfo property) { - Contract.Requires(reference != null); - Contract.Requires(property != null); - - _reference = reference; - _property = property; + _reference = reference ?? throw new ArgumentNullException(nameof(reference)); + _property = property ?? throw new ArgumentNullException(nameof(property)); } public override Type PropertyType => _property.PropertyType; diff --git a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs index a7bec62366..48e8c761eb 100644 --- a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs +++ b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs @@ -10,7 +10,6 @@ using Avalonia.Rendering.SceneGraph; using Avalonia.Rendering.Utilities; using Avalonia.Utilities; using Avalonia.Media.Imaging; -using JetBrains.Annotations; using SkiaSharp; namespace Avalonia.Skia @@ -675,13 +674,14 @@ namespace Avalonia.Skia } } - [CanBeNull] - public object GetFeature(Type t) +#nullable enable + public object? GetFeature(Type t) { if (t == typeof(ISkiaSharpApiLeaseFeature)) return new SkiaLeaseFeature(this); return null; } +#nullable restore /// /// Configure paint wrapper for using gradient brush. diff --git a/src/Skia/Avalonia.Skia/GlyphRunImpl.cs b/src/Skia/Avalonia.Skia/GlyphRunImpl.cs index bdc3d075cf..484fd9f219 100644 --- a/src/Skia/Avalonia.Skia/GlyphRunImpl.cs +++ b/src/Skia/Avalonia.Skia/GlyphRunImpl.cs @@ -1,8 +1,8 @@ using System; using Avalonia.Metadata; using Avalonia.Platform; -using JetBrains.Annotations; using SkiaSharp; +#nullable enable namespace Avalonia.Skia { @@ -10,7 +10,7 @@ namespace Avalonia.Skia [Unstable] public class GlyphRunImpl : IGlyphRunImpl { - public GlyphRunImpl([NotNull] SKTextBlob textBlob) + public GlyphRunImpl(SKTextBlob textBlob) { TextBlob = textBlob ?? throw new ArgumentNullException (nameof (textBlob)); } diff --git a/src/Windows/Avalonia.Direct2D1/Avalonia.Direct2D1.csproj b/src/Windows/Avalonia.Direct2D1/Avalonia.Direct2D1.csproj index fb7831415d..5fecaef100 100644 --- a/src/Windows/Avalonia.Direct2D1/Avalonia.Direct2D1.csproj +++ b/src/Windows/Avalonia.Direct2D1/Avalonia.Direct2D1.csproj @@ -17,7 +17,6 @@ - diff --git a/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs b/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs index f828b156da..672f3a781a 100644 --- a/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs +++ b/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs @@ -820,6 +820,14 @@ namespace Avalonia.Win32.Interop DWMWA_LAST }; + public enum DwmWindowCornerPreference : uint + { + DWMWCP_DEFAULT = 0, + DWMWCP_DONOTROUND, + DWMWCP_ROUND, + DWMWCP_ROUNDSMALL + } + public enum MapVirtualKeyMapTypes : uint { MAPVK_VK_TO_VSC = 0x00, diff --git a/src/Windows/Avalonia.Win32/Win32Platform.cs b/src/Windows/Avalonia.Win32/Win32Platform.cs index 3f220f0f09..3f16b49772 100644 --- a/src/Windows/Avalonia.Win32/Win32Platform.cs +++ b/src/Windows/Avalonia.Win32/Win32Platform.cs @@ -19,11 +19,11 @@ using Avalonia.Threading; using Avalonia.Utilities; using Avalonia.Win32.Input; using Avalonia.Win32.Interop; -using JetBrains.Annotations; using static Avalonia.Win32.Interop.UnmanagedMethods; namespace Avalonia { +#nullable enable public static class Win32ApplicationExtensions { public static T UseWin32( @@ -106,9 +106,10 @@ namespace Avalonia /// /// Provides a way to use a custom-implemented graphics context such as a custom ISkiaGpu /// - [CanBeNull] public IPlatformGraphics CustomPlatformGraphics { get; set; } + public IPlatformGraphics? CustomPlatformGraphics { get; set; } } } +#nullable restore namespace Avalonia.Win32 { diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index b2ce68ee83..dbcc31c5f5 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -1029,6 +1029,12 @@ namespace Avalonia.Win32 { var margins = UpdateExtendMargins(); DwmExtendFrameIntoClientArea(_hwnd, ref margins); + + unsafe + { + int cornerPreference = (int)DwmWindowCornerPreference.DWMWCP_ROUND; + DwmSetWindowAttribute(_hwnd, (int)DwmWindowAttribute.DWMWA_WINDOW_CORNER_PREFERENCE, &cornerPreference, sizeof(int)); + } } else { @@ -1039,6 +1045,12 @@ namespace Avalonia.Win32 _extendedMargins = new Thickness(); Resize(new Size(rcWindow.Width / RenderScaling, rcWindow.Height / RenderScaling), PlatformResizeReason.Layout); + + unsafe + { + int cornerPreference = (int)DwmWindowCornerPreference.DWMWCP_DEFAULT; + DwmSetWindowAttribute(_hwnd, (int)DwmWindowAttribute.DWMWA_WINDOW_CORNER_PREFERENCE, &cornerPreference, sizeof(int)); + } } if (!_isClientAreaExtended || (_extendChromeHints.HasAllFlags(ExtendClientAreaChromeHints.SystemChrome) && diff --git a/src/Windows/Avalonia.Win32/WindowsMountedVolumeInfoProvider.cs b/src/Windows/Avalonia.Win32/WindowsMountedVolumeInfoProvider.cs index e1b5f5a3a0..4f4e0b9293 100644 --- a/src/Windows/Avalonia.Win32/WindowsMountedVolumeInfoProvider.cs +++ b/src/Windows/Avalonia.Win32/WindowsMountedVolumeInfoProvider.cs @@ -8,7 +8,6 @@ namespace Avalonia.Win32 { public IDisposable Listen(ObservableCollection mountedDrives) { - Contract.Requires(mountedDrives != null); return new WindowsMountedVolumeInfoListener(mountedDrives); } } diff --git a/src/iOS/Avalonia.iOS/AvaloniaView.Text.cs b/src/iOS/Avalonia.iOS/AvaloniaView.Text.cs index fb0857e472..a1836f3ce4 100644 --- a/src/iOS/Avalonia.iOS/AvaloniaView.Text.cs +++ b/src/iOS/Avalonia.iOS/AvaloniaView.Text.cs @@ -1,6 +1,5 @@ #nullable enable using Avalonia.Input.TextInput; -using JetBrains.Annotations; using UIKit; namespace Avalonia.iOS; diff --git a/tests/Avalonia.Base.UnitTests/Rendering/CompositorTestsBase.cs b/tests/Avalonia.Base.UnitTests/Rendering/CompositorTestsBase.cs index d407a09b06..7f4e160000 100644 --- a/tests/Avalonia.Base.UnitTests/Rendering/CompositorTestsBase.cs +++ b/tests/Avalonia.Base.UnitTests/Rendering/CompositorTestsBase.cs @@ -18,7 +18,6 @@ using Avalonia.Rendering.Composition; using Avalonia.Threading; using Avalonia.UnitTests; using Avalonia.VisualTree; -using JetBrains.Annotations; using Xunit; namespace Avalonia.Base.UnitTests.Rendering; diff --git a/tests/Avalonia.Benchmarks/Data/AccessorTestObject.cs b/tests/Avalonia.Benchmarks/Data/AccessorTestObject.cs index 0039f5670c..cd323ededb 100644 --- a/tests/Avalonia.Benchmarks/Data/AccessorTestObject.cs +++ b/tests/Avalonia.Benchmarks/Data/AccessorTestObject.cs @@ -1,6 +1,5 @@ using System.ComponentModel; using System.Runtime.CompilerServices; -using JetBrains.Annotations; namespace Avalonia.Benchmarks.Data { @@ -38,7 +37,6 @@ namespace Avalonia.Benchmarks.Data { } - [NotifyPropertyChangedInvocator] protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); diff --git a/tests/Avalonia.Benchmarks/Utilities/AvaloniaPropertyDictionaryBenchmarks.cs b/tests/Avalonia.Benchmarks/Utilities/AvaloniaPropertyDictionaryBenchmarks.cs index d43d6bd48b..e160c8dfa8 100644 --- a/tests/Avalonia.Benchmarks/Utilities/AvaloniaPropertyDictionaryBenchmarks.cs +++ b/tests/Avalonia.Benchmarks/Utilities/AvaloniaPropertyDictionaryBenchmarks.cs @@ -172,7 +172,7 @@ internal sealed class AvaloniaPropertyValueStoreOld internal class MockProperty : StyledProperty { - public MockProperty([JetBrains.Annotations.NotNull] string name) : base(name, typeof(object), new StyledPropertyMetadata()) + public MockProperty(string name) : base(name, typeof(object), new StyledPropertyMetadata()) { } } diff --git a/tests/Avalonia.Controls.UnitTests/TreeViewTests.cs b/tests/Avalonia.Controls.UnitTests/TreeViewTests.cs index cd38bf556a..81936711ef 100644 --- a/tests/Avalonia.Controls.UnitTests/TreeViewTests.cs +++ b/tests/Avalonia.Controls.UnitTests/TreeViewTests.cs @@ -17,7 +17,6 @@ using Avalonia.Interactivity; using Avalonia.LogicalTree; using Avalonia.Styling; using Avalonia.UnitTests; -using JetBrains.Annotations; using Moq; using Xunit; diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlIlTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlIlTests.cs index 4b32a8cdca..f42f787117 100644 --- a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlIlTests.cs +++ b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlIlTests.cs @@ -15,7 +15,6 @@ using Avalonia.Styling; using Avalonia.Threading; using Avalonia.UnitTests; using Avalonia.VisualTree; -using JetBrains.Annotations; using Xunit; namespace Avalonia.Markup.Xaml.UnitTests @@ -389,7 +388,6 @@ namespace Avalonia.Markup.Xaml.UnitTests public bool IsPressed { get; set; } public event PropertyChangedEventHandler PropertyChanged; - [NotifyPropertyChangedInvocator] protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));