diff --git a/.editorconfig b/.editorconfig index 30edee1633..128b6f1712 100644 --- a/.editorconfig +++ b/.editorconfig @@ -137,6 +137,9 @@ space_within_single_line_array_initializer_braces = true # Wrapping preferences csharp_wrap_before_ternary_opsigns = false +# Avalonia DevAnalyzer preferences +dotnet_diagnostic.AVADEV2001.severity = error + # Xaml files [*.{xaml,axaml}] indent_size = 2 diff --git a/src/Avalonia.Base/Layout/StackLayout.cs b/src/Avalonia.Base/Layout/StackLayout.cs index 00ac4a37f0..e3c2ab3817 100644 --- a/src/Avalonia.Base/Layout/StackLayout.cs +++ b/src/Avalonia.Base/Layout/StackLayout.cs @@ -322,6 +322,7 @@ namespace Avalonia.Layout protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) { + base.OnPropertyChanged(change); if (change.Property == OrientationProperty) { var orientation = change.GetNewValue(); diff --git a/src/Avalonia.Base/Layout/UniformGridLayout.cs b/src/Avalonia.Base/Layout/UniformGridLayout.cs index 47c994a350..a7880a1545 100644 --- a/src/Avalonia.Base/Layout/UniformGridLayout.cs +++ b/src/Avalonia.Base/Layout/UniformGridLayout.cs @@ -473,6 +473,7 @@ namespace Avalonia.Layout protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) { + base.OnPropertyChanged(change); if (change.Property == OrientationProperty) { var orientation = change.GetNewValue(); diff --git a/src/Avalonia.Base/Rotate3DTransform.cs b/src/Avalonia.Base/Rotate3DTransform.cs index 2c4e515861..2de33889c8 100644 --- a/src/Avalonia.Base/Rotate3DTransform.cs +++ b/src/Avalonia.Base/Rotate3DTransform.cs @@ -205,6 +205,7 @@ public class Rotate3DTransform : Transform protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) { + base.OnPropertyChanged(change); if (!_isInitializing) RaiseChanged(); } } diff --git a/src/Avalonia.Controls/Primitives/Popup.cs b/src/Avalonia.Controls/Primitives/Popup.cs index f71a0c6f48..ccb81ba276 100644 --- a/src/Avalonia.Controls/Primitives/Popup.cs +++ b/src/Avalonia.Controls/Primitives/Popup.cs @@ -524,6 +524,7 @@ namespace Avalonia.Controls.Primitives protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) { + base.OnPropertyChanged(change); if (_openState is not null) { if (change.Property == WidthProperty || diff --git a/src/Avalonia.Controls/SplitButton/ToggleSplitButton.cs b/src/Avalonia.Controls/SplitButton/ToggleSplitButton.cs index cd34f8060a..83bc9851c1 100644 --- a/src/Avalonia.Controls/SplitButton/ToggleSplitButton.cs +++ b/src/Avalonia.Controls/SplitButton/ToggleSplitButton.cs @@ -92,6 +92,7 @@ namespace Avalonia.Controls /// protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs e) { + base.OnPropertyChanged(e); if (e.Property == IsCheckedProperty) { OnIsCheckedChanged(); diff --git a/src/Web/Avalonia.Web.Blazor/AvaloniaView.razor b/src/Web/Avalonia.Web.Blazor/AvaloniaView.razor index 27a6acd0de..8bfa1d6014 100644 --- a/src/Web/Avalonia.Web.Blazor/AvaloniaView.razor +++ b/src/Web/Avalonia.Web.Blazor/AvaloniaView.razor @@ -3,9 +3,9 @@ tabindex="0" oncontextmenu="return false;" @onwheel="OnWheel" @onkeydown="OnKeyDown" - @onkeydown:preventDefault="true" @onkeyup="OnKeyUp" - @onkeyup:preventDefault="true" + @onkeyup:preventDefault="@KeyPreventDefault" + @onkeydown:preventDefault="@KeyPreventDefault" @onpointerdown="OnPointerDown" @onpointerup="OnPointerUp" @onpointermove="OnPointerMove" @@ -20,8 +20,6 @@ onpaste="return false;" oncopy="return false;" oncut="return false;" - @onkeydown:preventDefault="true" - @onkeyup:preventDefault="true" autocapitalize="none"/> diff --git a/src/Web/Avalonia.Web.Blazor/AvaloniaView.razor.cs b/src/Web/Avalonia.Web.Blazor/AvaloniaView.razor.cs index cda3a7597d..87245a201a 100644 --- a/src/Web/Avalonia.Web.Blazor/AvaloniaView.razor.cs +++ b/src/Web/Avalonia.Web.Blazor/AvaloniaView.razor.cs @@ -63,6 +63,8 @@ namespace Avalonia.Web.Blazor } } + public bool KeyPreventDefault { get; set; } + internal INativeControlHostImpl GetNativeControlHostImpl() { return _nativeControlHost ?? throw new InvalidOperationException("Blazor View wasn't initialized yet"); @@ -203,12 +205,12 @@ namespace Avalonia.Web.Blazor private void OnKeyDown(KeyboardEventArgs e) { - _topLevelImpl.RawKeyboardEvent(RawKeyEventType.KeyDown, e.Code, e.Key, GetModifiers(e)); + KeyPreventDefault = _topLevelImpl.RawKeyboardEvent(RawKeyEventType.KeyDown, e.Code, e.Key, GetModifiers(e)); } private void OnKeyUp(KeyboardEventArgs e) { - _topLevelImpl.RawKeyboardEvent(RawKeyEventType.KeyUp, e.Code, e.Key, GetModifiers(e)); + KeyPreventDefault = _topLevelImpl.RawKeyboardEvent(RawKeyEventType.KeyUp, e.Code, e.Key, GetModifiers(e)); } private void OnFocus(FocusEventArgs e) diff --git a/src/Web/Avalonia.Web.Blazor/RazorViewTopLevelImpl.cs b/src/Web/Avalonia.Web.Blazor/RazorViewTopLevelImpl.cs index 86860ebd58..3a09c16932 100644 --- a/src/Web/Avalonia.Web.Blazor/RazorViewTopLevelImpl.cs +++ b/src/Web/Avalonia.Web.Blazor/RazorViewTopLevelImpl.cs @@ -113,22 +113,32 @@ namespace Avalonia.Web.Blazor } } - public void RawKeyboardEvent(RawKeyEventType type, string code, string key, RawInputModifiers modifiers) + public bool RawKeyboardEvent(RawKeyEventType type, string code, string key, RawInputModifiers modifiers) { if (Keycodes.KeyCodes.TryGetValue(code, out var avkey)) { if (_inputRoot is { }) { - Input?.Invoke(new RawKeyEventArgs(KeyboardDevice, Timestamp, _inputRoot, type, avkey, modifiers)); + var args = new RawKeyEventArgs(KeyboardDevice, Timestamp, _inputRoot, type, avkey, modifiers); + + Input?.Invoke(args); + + return args.Handled; } } else if (Keycodes.KeyCodes.TryGetValue(key, out avkey)) { if (_inputRoot is { }) { - Input?.Invoke(new RawKeyEventArgs(KeyboardDevice, Timestamp, _inputRoot, type, avkey, modifiers)); + var args = new RawKeyEventArgs(KeyboardDevice, Timestamp, _inputRoot, type, avkey, modifiers); + + Input?.Invoke(args); + + return args.Handled; } } + + return false; } public void RawTextEvent(string text) diff --git a/src/tools/DevAnalyzers/OnPropertyChangedOverrideAnalyzer.cs b/src/tools/DevAnalyzers/OnPropertyChangedOverrideAnalyzer.cs index a16542fdc0..8534ed4a66 100644 --- a/src/tools/DevAnalyzers/OnPropertyChangedOverrideAnalyzer.cs +++ b/src/tools/DevAnalyzers/OnPropertyChangedOverrideAnalyzer.cs @@ -1,6 +1,7 @@ using System.Collections.Immutable; using System.Linq; using Microsoft.CodeAnalysis; +using Microsoft.CodeAnalysis.CSharp; using Microsoft.CodeAnalysis.CSharp.Syntax; using Microsoft.CodeAnalysis.Diagnostics; @@ -26,37 +27,32 @@ namespace DevAnalyzers { context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None); context.EnableConcurrentExecution(); - context.RegisterSymbolAction(AnalyzeMethod, SymbolKind.Method); + context.RegisterSyntaxNodeAction(AnalyzeMethod, SyntaxKind.MethodDeclaration); } - private static void AnalyzeMethod(SymbolAnalysisContext context) + private static void AnalyzeMethod(SyntaxNodeAnalysisContext context) { - if (context.Symbol is IMethodSymbol currentMethod + var method = (MethodDeclarationSyntax)context.Node; + if (context.SemanticModel.GetDeclaredSymbol(method, context.CancellationToken) is IMethodSymbol currentMethod && currentMethod.Name == "OnPropertyChanged" && currentMethod.OverriddenMethod is IMethodSymbol originalMethod) { - var declaration = currentMethod.DeclaringSyntaxReferences.FirstOrDefault() - ?.GetSyntax(context.CancellationToken); - if (declaration is not null && context.Compilation.GetSemanticModel(declaration!.SyntaxTree) is { } semanticModel) + var baseInvocations = method.Body?.DescendantNodes().OfType(); + if (baseInvocations?.Any() == true) { - if (declaration.SyntaxTree.TryGetRoot(out var root)) + foreach (var baseInvocation in baseInvocations) { - var baseInvocations = root.DescendantNodes().OfType(); - if (baseInvocations.Any()) + if (baseInvocation.Parent is SyntaxNode parent) { - foreach (var baseInvocation in baseInvocations) + var targetSymbol = context.SemanticModel.GetSymbolInfo(parent, context.CancellationToken); + if (SymbolEqualityComparer.Default.Equals(targetSymbol.Symbol, originalMethod)) { - var parent = baseInvocation.Parent; - var targetSymbol = semanticModel.GetSymbolInfo(parent, context.CancellationToken); - if (SymbolEqualityComparer.Default.Equals(targetSymbol.Symbol, originalMethod)) - { - return; - } + return; } } - context.ReportDiagnostic(Diagnostic.Create(Rule, currentMethod.Locations[0], currentMethod.Name)); } } + context.ReportDiagnostic(Diagnostic.Create(Rule, currentMethod.Locations[0], currentMethod.Name)); } }