From 80b0c3d54c8247a6b87170a2b288e86e8cb42838 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Thu, 3 Nov 2022 00:24:17 +0100 Subject: [PATCH 01/22] Allow AccessibilityView to override peer. Setting `AutomationProperties.AccessibilityView` can now override the `IsControlElementCore` and `IsContentElementCore` settings returned from the automation peer. --- .../Automation/AutomationProperties.cs | 8 ++++++-- .../Automation/Peers/AutomationPeer.cs | 14 ++++++++++++-- .../Automation/Peers/ControlAutomationPeer.cs | 16 ++++++++++++++-- 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/src/Avalonia.Controls/Automation/AutomationProperties.cs b/src/Avalonia.Controls/Automation/AutomationProperties.cs index c20af148b8..a192ef6420 100644 --- a/src/Avalonia.Controls/Automation/AutomationProperties.cs +++ b/src/Avalonia.Controls/Automation/AutomationProperties.cs @@ -9,6 +9,11 @@ namespace Avalonia.Automation /// public enum AccessibilityView { + /// + /// The control's view is defined by its automation peer. + /// + Default, + /// /// The control is included in the Raw view of the automation tree. /// @@ -44,8 +49,7 @@ namespace Avalonia.Automation public static readonly AttachedProperty AccessibilityViewProperty = AvaloniaProperty.RegisterAttached( "AccessibilityView", - typeof(AutomationProperties), - defaultValue: AccessibilityView.Content); + typeof(AutomationProperties)); /// /// Defines the AutomationProperties.AccessKey attached property diff --git a/src/Avalonia.Controls/Automation/Peers/AutomationPeer.cs b/src/Avalonia.Controls/Automation/Peers/AutomationPeer.cs index 71421ac136..3d3fe35d29 100644 --- a/src/Avalonia.Controls/Automation/Peers/AutomationPeer.cs +++ b/src/Avalonia.Controls/Automation/Peers/AutomationPeer.cs @@ -128,13 +128,13 @@ namespace Avalonia.Automation.Peers /// Gets a value that indicates whether the element that is associated with this automation /// peer contains data that is presented to the user. /// - public bool IsContentElement() => IsControlElement() && IsContentElementCore(); + public bool IsContentElement() => IsContentElementOverrideCore(); /// /// Gets a value that indicates whether the element is understood by the user as /// interactive or as contributing to the logical structure of the control in the GUI. /// - public bool IsControlElement() => IsControlElementCore(); + public bool IsControlElement() => IsControlElementOverrideCore(); /// /// Gets a value indicating whether the control is enabled for user interaction. @@ -247,6 +247,16 @@ namespace Avalonia.Automation.Peers return GetAutomationControlTypeCore(); } + protected virtual bool IsContentElementOverrideCore() + { + return IsControlElement() && IsContentElementCore(); + } + + protected virtual bool IsControlElementOverrideCore() + { + return IsControlElementCore(); + } + protected virtual object? GetProviderCore(Type providerType) { return providerType.IsAssignableFrom(this.GetType()) ? this : null; diff --git a/src/Avalonia.Controls/Automation/Peers/ControlAutomationPeer.cs b/src/Avalonia.Controls/Automation/Peers/ControlAutomationPeer.cs index a93d3fa7dd..25172b2d1c 100644 --- a/src/Avalonia.Controls/Automation/Peers/ControlAutomationPeer.cs +++ b/src/Avalonia.Controls/Automation/Peers/ControlAutomationPeer.cs @@ -149,8 +149,8 @@ namespace Avalonia.Automation.Peers protected override Rect GetBoundingRectangleCore() => GetBounds(Owner); protected override string GetClassNameCore() => Owner.GetType().Name; protected override bool HasKeyboardFocusCore() => Owner.IsFocused; - protected override bool IsContentElementCore() => AutomationProperties.GetAccessibilityView(Owner) >= AccessibilityView.Content; - protected override bool IsControlElementCore() => AutomationProperties.GetAccessibilityView(Owner) >= AccessibilityView.Control; + protected override bool IsContentElementCore() => true; + protected override bool IsControlElementCore() => true; protected override bool IsEnabledCore() => Owner.IsEnabled; protected override bool IsKeyboardFocusableCore() => Owner.Focusable; protected override void SetFocusCore() => Owner.Focus(); @@ -160,6 +160,18 @@ namespace Avalonia.Automation.Peers return AutomationProperties.GetControlTypeOverride(Owner) ?? GetAutomationControlTypeCore(); } + protected override bool IsContentElementOverrideCore() + { + var view = AutomationProperties.GetAccessibilityView(Owner); + return view == AccessibilityView.Default ? IsContentElementCore() : view >= AccessibilityView.Content; + } + + protected override bool IsControlElementOverrideCore() + { + var view = AutomationProperties.GetAccessibilityView(Owner); + return view == AccessibilityView.Default ? IsControlElementCore() : view >= AccessibilityView.Control; + } + private static Rect GetBounds(Control control) { var root = control.GetVisualRoot(); From 9a50b9ee0ccab7d96bac6e144c55aa0422303f02 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Thu, 3 Nov 2022 15:36:02 +0100 Subject: [PATCH 02/22] Added integration tests for tapped gestures. Some skipped on Windows as right button actions aren't supported by WinAppDriver. --- samples/IntegrationTestApp/MainWindow.axaml | 12 ++ .../IntegrationTestApp/MainWindow.axaml.cs | 10 ++ .../GestureTests.cs | 151 ++++++++++++++++++ 3 files changed, 173 insertions(+) create mode 100644 tests/Avalonia.IntegrationTests.Appium/GestureTests.cs diff --git a/samples/IntegrationTestApp/MainWindow.axaml b/samples/IntegrationTestApp/MainWindow.axaml index 3377979199..2a0a758852 100644 --- a/samples/IntegrationTestApp/MainWindow.axaml +++ b/samples/IntegrationTestApp/MainWindow.axaml @@ -69,6 +69,18 @@ + + + + + + + + + + diff --git a/samples/IntegrationTestApp/MainWindow.axaml.cs b/samples/IntegrationTestApp/MainWindow.axaml.cs index f72f83fcb8..791e221d50 100644 --- a/samples/IntegrationTestApp/MainWindow.axaml.cs +++ b/samples/IntegrationTestApp/MainWindow.axaml.cs @@ -4,6 +4,7 @@ using Avalonia; using Avalonia.Automation; using Avalonia.Controls; using Avalonia.Controls.ApplicationLifetimes; +using Avalonia.Input; using Avalonia.Interactivity; using Avalonia.Markup.Xaml; using Avalonia.VisualTree; @@ -20,6 +21,15 @@ namespace IntegrationTestApp this.AttachDevTools(); AddHandler(Button.ClickEvent, OnButtonClick); ListBoxItems = Enumerable.Range(0, 100).Select(x => "Item " + x).ToList(); + + var gestureBorder = this.GetControl("GestureBorder"); + var lastGesture = this.GetControl("LastGesture"); + var clearLastGesture = this.GetControl + - + + + + diff --git a/samples/IntegrationTestApp/MainWindow.axaml.cs b/samples/IntegrationTestApp/MainWindow.axaml.cs index 791e221d50..e8fb455c35 100644 --- a/samples/IntegrationTestApp/MainWindow.axaml.cs +++ b/samples/IntegrationTestApp/MainWindow.axaml.cs @@ -18,18 +18,10 @@ namespace IntegrationTestApp { InitializeComponent(); InitializeViewMenu(); + InitializeGesturesTab(); this.AttachDevTools(); AddHandler(Button.ClickEvent, OnButtonClick); ListBoxItems = Enumerable.Range(0, 100).Select(x => "Item " + x).ToList(); - - var gestureBorder = this.GetControl("GestureBorder"); - var lastGesture = this.GetControl("LastGesture"); - var clearLastGesture = this.GetControl void SetPreeditText(string? text); + + void SetComposingRegion(ComposingRegion? region); /// /// Indicates if text input client is capable of providing the text around the cursor /// @@ -51,4 +53,26 @@ namespace Avalonia.Input.TextInput public int CursorOffset { get; set; } public int AnchorOffset { get; set; } } + + public readonly struct ComposingRegion + { + private readonly int _start = -1; + private readonly int _end = -1; + + public ComposingRegion(int start, int end) + { + _start = start; + _end = end; + } + + public int Start => _start; + public int End => _end; + + public bool Intersects(ComposingRegion region) + { + return _start <= region.Start && _end >= region.Start || + _end >= region.End && _start <= region.End || + _start >= region.Start && _end <= region.End; + } + } } diff --git a/src/Avalonia.Base/Media/TextFormatting/FormattedTextSource.cs b/src/Avalonia.Base/Media/TextFormatting/FormattedTextSource.cs index 7ab67ea34d..fb8e699d8e 100644 --- a/src/Avalonia.Base/Media/TextFormatting/FormattedTextSource.cs +++ b/src/Avalonia.Base/Media/TextFormatting/FormattedTextSource.cs @@ -140,7 +140,7 @@ namespace Avalonia.Media.TextFormatting } } - return length; + return Math.Min(length, text.Length); } } } diff --git a/src/Avalonia.Base/Media/TextFormatting/TextCharacters.cs b/src/Avalonia.Base/Media/TextFormatting/TextCharacters.cs index bcfa35ae30..efe6a94856 100644 --- a/src/Avalonia.Base/Media/TextFormatting/TextCharacters.cs +++ b/src/Avalonia.Base/Media/TextFormatting/TextCharacters.cs @@ -74,15 +74,6 @@ namespace Avalonia.Media.TextFormatting if (TryGetShapeableLength(text, currentTypeface, null, out var count, out var script)) { - if (script == Script.Common && previousTypeface is not null) - { - if (TryGetShapeableLength(text, previousTypeface.Value, null, out var fallbackCount, out _)) - { - return new ShapeableTextCharacters(text.Take(fallbackCount), - defaultProperties.WithTypeface(previousTypeface.Value), biDiLevel); - } - } - return new ShapeableTextCharacters(text.Take(count), defaultProperties.WithTypeface(currentTypeface), biDiLevel); } @@ -182,7 +173,7 @@ namespace Avalonia.Media.TextFormatting var currentScript = currentGrapheme.FirstCodepoint.Script; - if (!currentGrapheme.FirstCodepoint.IsWhiteSpace && defaultFont != null && defaultFont.TryGetGlyph(currentGrapheme.FirstCodepoint, out _)) + if (defaultFont != null && defaultFont.TryGetGlyph(currentGrapheme.FirstCodepoint, out _)) { break; } diff --git a/src/Avalonia.Controls/Presenters/TextPresenter.cs b/src/Avalonia.Controls/Presenters/TextPresenter.cs index adf0569551..230c57d34b 100644 --- a/src/Avalonia.Controls/Presenters/TextPresenter.cs +++ b/src/Avalonia.Controls/Presenters/TextPresenter.cs @@ -9,6 +9,7 @@ using Avalonia.VisualTree; using Avalonia.Layout; using Avalonia.Media.Immutable; using Avalonia.Controls.Documents; +using Avalonia.Input.TextInput; namespace Avalonia.Controls.Presenters { @@ -331,6 +332,8 @@ namespace Avalonia.Controls.Presenters protected override bool BypassFlowDirectionPolicies => true; + public ComposingRegion? ComposingRegion { get; internal set; } + /// /// Creates the used to render the text. /// @@ -514,7 +517,12 @@ namespace Avalonia.Controls.Presenters { if (!string.IsNullOrEmpty(_preeditText)) { - var text = _text?.Substring(0, _caretIndex) + _preeditText + _text?.Substring(_caretIndex); + if (string.IsNullOrEmpty(_text) || _caretIndex > _text.Length) + { + return _preeditText; + } + + var text = _text.Substring(0, _caretIndex) + _preeditText + _text.Substring(_caretIndex); return text; } @@ -545,7 +553,7 @@ namespace Avalonia.Controls.Presenters if (!string.IsNullOrEmpty(_preeditText)) { - var preeditHighlight = new ValueSpan(_caretIndex, _preeditText.Length, + var preeditHighlight = new ValueSpan(ComposingRegion.HasValue ? ComposingRegion.Value.Start : _caretIndex, _preeditText.Length, new GenericTextRunProperties(typeface, FontSize, foregroundBrush: foreground, textDecorations: TextDecorations.Underline)); @@ -868,28 +876,11 @@ namespace Avalonia.Controls.Presenters if (string.IsNullOrEmpty(newValue)) { - if (!string.IsNullOrEmpty(oldValue)) - { - var textPosition = _compositionStartHit.FirstCharacterIndex + _compositionStartHit.TrailingLength + newValue?.Length ?? 0; - - var characterHit = GetCharacterHitFromTextPosition(textPosition); - - UpdateCaret(characterHit, true); - } - - _compositionStartHit = new CharacterHit(-1); + UpdateCaret(_lastCharacterHit); } else { - if (_compositionStartHit.FirstCharacterIndex == -1) - { - _compositionStartHit = _lastCharacterHit; - } - } - - if (_compositionStartHit.FirstCharacterIndex != -1) - { - var textPosition = _compositionStartHit.FirstCharacterIndex + _compositionStartHit.TrailingLength + newValue?.Length ?? 0; + var textPosition = (ComposingRegion.HasValue? ComposingRegion.Value.Start : _caretIndex) + newValue?.Length ?? 0; var characterHit = GetCharacterHitFromTextPosition(textPosition); diff --git a/src/Avalonia.Controls/TextBox.cs b/src/Avalonia.Controls/TextBox.cs index 85c1c9a9d1..d5b45398e7 100644 --- a/src/Avalonia.Controls/TextBox.cs +++ b/src/Avalonia.Controls/TextBox.cs @@ -1212,7 +1212,7 @@ namespace Avalonia.Controls protected override void OnPointerPressed(PointerPressedEventArgs e) { - if (_presenter == null || !string.IsNullOrEmpty(_presenter.PreeditText)) + if (_presenter == null ) { return; } diff --git a/src/Avalonia.Controls/TextBoxTextInputMethodClient.cs b/src/Avalonia.Controls/TextBoxTextInputMethodClient.cs index 5d5ffcc381..61ac1d3c1f 100644 --- a/src/Avalonia.Controls/TextBoxTextInputMethodClient.cs +++ b/src/Avalonia.Controls/TextBoxTextInputMethodClient.cs @@ -108,6 +108,11 @@ namespace Avalonia.Controls } _presenter.PreeditText = text; + + if(text == null) + { + _presenter.ComposingRegion = null; + } } public void SelectInSurroundingText(int start, int end) @@ -182,5 +187,15 @@ namespace Avalonia.Controls }, DispatcherPriority.Input); } + + public void SetComposingRegion(ComposingRegion? region) + { + if(_presenter == null) + { + return; + } + + _presenter.ComposingRegion = region; + } } } From a589d2e43b762a1d51c8be4142c85a57bb3e5fc2 Mon Sep 17 00:00:00 2001 From: Benedikt Stebner Date: Mon, 7 Nov 2022 18:17:09 +0100 Subject: [PATCH 10/22] Relocate CompositionRegion --- .../Avalonia.Android/AndroidInputMethod.cs | 15 ++++++++++++ .../Platform/SkiaPlatform/TopLevelImpl.cs | 2 -- .../Input/TextInput/ITextInputMethodClient.cs | 23 ------------------- .../TextBoxTextInputMethodClient.cs | 10 -------- 4 files changed, 15 insertions(+), 35 deletions(-) diff --git a/src/Android/Avalonia.Android/AndroidInputMethod.cs b/src/Android/Avalonia.Android/AndroidInputMethod.cs index 22d2f812bc..b6adbde738 100644 --- a/src/Android/Avalonia.Android/AndroidInputMethod.cs +++ b/src/Android/Avalonia.Android/AndroidInputMethod.cs @@ -162,4 +162,19 @@ namespace Avalonia.Android }); } } + + public readonly struct ComposingRegion + { + private readonly int _start = -1; + private readonly int _end = -1; + + public ComposingRegion(int start, int end) + { + _start = start; + _end = end; + } + + public int Start => _start; + public int End => _end; + } } diff --git a/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs b/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs index e69780b1b3..932dc185ff 100644 --- a/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs +++ b/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs @@ -287,8 +287,6 @@ namespace Avalonia.Android.Platform.SkiaPlatform ComposingRegion = new ComposingRegion(start, end); - _inputMethod.Client?.SetComposingRegion(ComposingRegion); - return base.SetComposingRegion(start, end); } diff --git a/src/Avalonia.Base/Input/TextInput/ITextInputMethodClient.cs b/src/Avalonia.Base/Input/TextInput/ITextInputMethodClient.cs index 0ff9299873..325d745782 100644 --- a/src/Avalonia.Base/Input/TextInput/ITextInputMethodClient.cs +++ b/src/Avalonia.Base/Input/TextInput/ITextInputMethodClient.cs @@ -30,7 +30,6 @@ namespace Avalonia.Input.TextInput /// void SetPreeditText(string? text); - void SetComposingRegion(ComposingRegion? region); /// /// Indicates if text input client is capable of providing the text around the cursor /// @@ -53,26 +52,4 @@ namespace Avalonia.Input.TextInput public int CursorOffset { get; set; } public int AnchorOffset { get; set; } } - - public readonly struct ComposingRegion - { - private readonly int _start = -1; - private readonly int _end = -1; - - public ComposingRegion(int start, int end) - { - _start = start; - _end = end; - } - - public int Start => _start; - public int End => _end; - - public bool Intersects(ComposingRegion region) - { - return _start <= region.Start && _end >= region.Start || - _end >= region.End && _start <= region.End || - _start >= region.Start && _end <= region.End; - } - } } diff --git a/src/Avalonia.Controls/TextBoxTextInputMethodClient.cs b/src/Avalonia.Controls/TextBoxTextInputMethodClient.cs index 61ac1d3c1f..79a16281cd 100644 --- a/src/Avalonia.Controls/TextBoxTextInputMethodClient.cs +++ b/src/Avalonia.Controls/TextBoxTextInputMethodClient.cs @@ -187,15 +187,5 @@ namespace Avalonia.Controls }, DispatcherPriority.Input); } - - public void SetComposingRegion(ComposingRegion? region) - { - if(_presenter == null) - { - return; - } - - _presenter.ComposingRegion = region; - } } } From 7e3024ede20490eadb0511a50a7059f8bd436ab2 Mon Sep 17 00:00:00 2001 From: Benedikt Stebner Date: Mon, 7 Nov 2022 19:46:02 +0100 Subject: [PATCH 11/22] Fix fallback handling --- .../Media/TextFormatting/TextCharacters.cs | 11 ++++++++++- src/Avalonia.Controls/Presenters/TextPresenter.cs | 6 ++---- src/Avalonia.Controls/TextBoxTextInputMethodClient.cs | 5 ----- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/src/Avalonia.Base/Media/TextFormatting/TextCharacters.cs b/src/Avalonia.Base/Media/TextFormatting/TextCharacters.cs index efe6a94856..bcfa35ae30 100644 --- a/src/Avalonia.Base/Media/TextFormatting/TextCharacters.cs +++ b/src/Avalonia.Base/Media/TextFormatting/TextCharacters.cs @@ -74,6 +74,15 @@ namespace Avalonia.Media.TextFormatting if (TryGetShapeableLength(text, currentTypeface, null, out var count, out var script)) { + if (script == Script.Common && previousTypeface is not null) + { + if (TryGetShapeableLength(text, previousTypeface.Value, null, out var fallbackCount, out _)) + { + return new ShapeableTextCharacters(text.Take(fallbackCount), + defaultProperties.WithTypeface(previousTypeface.Value), biDiLevel); + } + } + return new ShapeableTextCharacters(text.Take(count), defaultProperties.WithTypeface(currentTypeface), biDiLevel); } @@ -173,7 +182,7 @@ namespace Avalonia.Media.TextFormatting var currentScript = currentGrapheme.FirstCodepoint.Script; - if (defaultFont != null && defaultFont.TryGetGlyph(currentGrapheme.FirstCodepoint, out _)) + if (!currentGrapheme.FirstCodepoint.IsWhiteSpace && defaultFont != null && defaultFont.TryGetGlyph(currentGrapheme.FirstCodepoint, out _)) { break; } diff --git a/src/Avalonia.Controls/Presenters/TextPresenter.cs b/src/Avalonia.Controls/Presenters/TextPresenter.cs index 230c57d34b..cc1fa6c513 100644 --- a/src/Avalonia.Controls/Presenters/TextPresenter.cs +++ b/src/Avalonia.Controls/Presenters/TextPresenter.cs @@ -332,8 +332,6 @@ namespace Avalonia.Controls.Presenters protected override bool BypassFlowDirectionPolicies => true; - public ComposingRegion? ComposingRegion { get; internal set; } - /// /// Creates the used to render the text. /// @@ -553,7 +551,7 @@ namespace Avalonia.Controls.Presenters if (!string.IsNullOrEmpty(_preeditText)) { - var preeditHighlight = new ValueSpan(ComposingRegion.HasValue ? ComposingRegion.Value.Start : _caretIndex, _preeditText.Length, + var preeditHighlight = new ValueSpan(_caretIndex, _preeditText.Length, new GenericTextRunProperties(typeface, FontSize, foregroundBrush: foreground, textDecorations: TextDecorations.Underline)); @@ -880,7 +878,7 @@ namespace Avalonia.Controls.Presenters } else { - var textPosition = (ComposingRegion.HasValue? ComposingRegion.Value.Start : _caretIndex) + newValue?.Length ?? 0; + var textPosition = _caretIndex + newValue?.Length ?? 0; var characterHit = GetCharacterHitFromTextPosition(textPosition); diff --git a/src/Avalonia.Controls/TextBoxTextInputMethodClient.cs b/src/Avalonia.Controls/TextBoxTextInputMethodClient.cs index 79a16281cd..5d5ffcc381 100644 --- a/src/Avalonia.Controls/TextBoxTextInputMethodClient.cs +++ b/src/Avalonia.Controls/TextBoxTextInputMethodClient.cs @@ -108,11 +108,6 @@ namespace Avalonia.Controls } _presenter.PreeditText = text; - - if(text == null) - { - _presenter.ComposingRegion = null; - } } public void SelectInSurroundingText(int start, int end) From f6f89f4e33b86f8a9ae0f6ccb5ade9ac8d69e20e Mon Sep 17 00:00:00 2001 From: Benedikt Stebner Date: Tue, 8 Nov 2022 06:59:16 +0100 Subject: [PATCH 12/22] Remove redundant method call --- .../Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs b/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs index 932dc185ff..24ee418480 100644 --- a/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs +++ b/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs @@ -268,8 +268,6 @@ namespace Avalonia.Android.Platform.SkiaPlatform { _topLevel = topLevel; _inputMethod = inputMethod; - - _inputMethod.Client?.SetComposingRegion(null); } public TextInputMethodSurroundingText SurroundingText { get; set; } From 4808846d82c0cae6ae572495e4e6b725f99cd48a Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Tue, 8 Nov 2022 22:37:57 +0000 Subject: [PATCH 13/22] Update Avalonia.Web.targets --- src/Web/Avalonia.Web/Avalonia.Web.targets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Web/Avalonia.Web/Avalonia.Web.targets b/src/Web/Avalonia.Web/Avalonia.Web.targets index b6a09b33ef..b5db8e5dd3 100644 --- a/src/Web/Avalonia.Web/Avalonia.Web.targets +++ b/src/Web/Avalonia.Web/Avalonia.Web.targets @@ -12,7 +12,7 @@ true - + true full true From ace159369ef6313d4b65e0284bf30c9f099a7d30 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Wed, 9 Nov 2022 09:56:47 +0100 Subject: [PATCH 14/22] Update ncrunch config due to recent changes. --- .ncrunch/Avalonia.Web.Blazor.v3.ncrunchproject | 5 +++++ .ncrunch/Avalonia.Web.v3.ncrunchproject | 5 +++++ .ncrunch/Avalonia.Win32.net6.0.v3.ncrunchproject | 6 +----- .ncrunch/Avalonia.Win32.netstandard2.0.v3.ncrunchproject | 6 +----- .ncrunch/ControlCatalog.Blazor.Web.v3.ncrunchproject | 5 +++++ .ncrunch/MobileSandbox.Android.v3.ncrunchproject | 5 +++++ .ncrunch/MobileSandbox.Desktop.v3.ncrunchproject | 5 +++++ .ncrunch/MobileSandbox.iOS.v3.ncrunchproject | 5 +++++ .ncrunch/MobileSandbox.net6.0.v3.ncrunchproject | 5 +++++ .ncrunch/MobileSandbox.netstandard2.0.v3.ncrunchproject | 5 +++++ .ncrunch/_build.v3.ncrunchproject | 5 +++++ 11 files changed, 47 insertions(+), 10 deletions(-) create mode 100644 .ncrunch/Avalonia.Web.Blazor.v3.ncrunchproject create mode 100644 .ncrunch/Avalonia.Web.v3.ncrunchproject create mode 100644 .ncrunch/ControlCatalog.Blazor.Web.v3.ncrunchproject create mode 100644 .ncrunch/MobileSandbox.Android.v3.ncrunchproject create mode 100644 .ncrunch/MobileSandbox.Desktop.v3.ncrunchproject create mode 100644 .ncrunch/MobileSandbox.iOS.v3.ncrunchproject create mode 100644 .ncrunch/MobileSandbox.net6.0.v3.ncrunchproject create mode 100644 .ncrunch/MobileSandbox.netstandard2.0.v3.ncrunchproject create mode 100644 .ncrunch/_build.v3.ncrunchproject diff --git a/.ncrunch/Avalonia.Web.Blazor.v3.ncrunchproject b/.ncrunch/Avalonia.Web.Blazor.v3.ncrunchproject new file mode 100644 index 0000000000..319cd523ce --- /dev/null +++ b/.ncrunch/Avalonia.Web.Blazor.v3.ncrunchproject @@ -0,0 +1,5 @@ + + + True + + \ No newline at end of file diff --git a/.ncrunch/Avalonia.Web.v3.ncrunchproject b/.ncrunch/Avalonia.Web.v3.ncrunchproject new file mode 100644 index 0000000000..319cd523ce --- /dev/null +++ b/.ncrunch/Avalonia.Web.v3.ncrunchproject @@ -0,0 +1,5 @@ + + + True + + \ No newline at end of file diff --git a/.ncrunch/Avalonia.Win32.net6.0.v3.ncrunchproject b/.ncrunch/Avalonia.Win32.net6.0.v3.ncrunchproject index 28b692bb51..95a483b433 100644 --- a/.ncrunch/Avalonia.Win32.net6.0.v3.ncrunchproject +++ b/.ncrunch/Avalonia.Win32.net6.0.v3.ncrunchproject @@ -1,7 +1,3 @@  - - - ..\..\tools\MicroComGenerator\bin\Debug\net6.0\**.* - - + \ No newline at end of file diff --git a/.ncrunch/Avalonia.Win32.netstandard2.0.v3.ncrunchproject b/.ncrunch/Avalonia.Win32.netstandard2.0.v3.ncrunchproject index 28b692bb51..95a483b433 100644 --- a/.ncrunch/Avalonia.Win32.netstandard2.0.v3.ncrunchproject +++ b/.ncrunch/Avalonia.Win32.netstandard2.0.v3.ncrunchproject @@ -1,7 +1,3 @@  - - - ..\..\tools\MicroComGenerator\bin\Debug\net6.0\**.* - - + \ No newline at end of file diff --git a/.ncrunch/ControlCatalog.Blazor.Web.v3.ncrunchproject b/.ncrunch/ControlCatalog.Blazor.Web.v3.ncrunchproject new file mode 100644 index 0000000000..319cd523ce --- /dev/null +++ b/.ncrunch/ControlCatalog.Blazor.Web.v3.ncrunchproject @@ -0,0 +1,5 @@ + + + True + + \ No newline at end of file diff --git a/.ncrunch/MobileSandbox.Android.v3.ncrunchproject b/.ncrunch/MobileSandbox.Android.v3.ncrunchproject new file mode 100644 index 0000000000..319cd523ce --- /dev/null +++ b/.ncrunch/MobileSandbox.Android.v3.ncrunchproject @@ -0,0 +1,5 @@ + + + True + + \ No newline at end of file diff --git a/.ncrunch/MobileSandbox.Desktop.v3.ncrunchproject b/.ncrunch/MobileSandbox.Desktop.v3.ncrunchproject new file mode 100644 index 0000000000..319cd523ce --- /dev/null +++ b/.ncrunch/MobileSandbox.Desktop.v3.ncrunchproject @@ -0,0 +1,5 @@ + + + True + + \ No newline at end of file diff --git a/.ncrunch/MobileSandbox.iOS.v3.ncrunchproject b/.ncrunch/MobileSandbox.iOS.v3.ncrunchproject new file mode 100644 index 0000000000..319cd523ce --- /dev/null +++ b/.ncrunch/MobileSandbox.iOS.v3.ncrunchproject @@ -0,0 +1,5 @@ + + + True + + \ No newline at end of file diff --git a/.ncrunch/MobileSandbox.net6.0.v3.ncrunchproject b/.ncrunch/MobileSandbox.net6.0.v3.ncrunchproject new file mode 100644 index 0000000000..319cd523ce --- /dev/null +++ b/.ncrunch/MobileSandbox.net6.0.v3.ncrunchproject @@ -0,0 +1,5 @@ + + + True + + \ No newline at end of file diff --git a/.ncrunch/MobileSandbox.netstandard2.0.v3.ncrunchproject b/.ncrunch/MobileSandbox.netstandard2.0.v3.ncrunchproject new file mode 100644 index 0000000000..319cd523ce --- /dev/null +++ b/.ncrunch/MobileSandbox.netstandard2.0.v3.ncrunchproject @@ -0,0 +1,5 @@ + + + True + + \ No newline at end of file diff --git a/.ncrunch/_build.v3.ncrunchproject b/.ncrunch/_build.v3.ncrunchproject new file mode 100644 index 0000000000..319cd523ce --- /dev/null +++ b/.ncrunch/_build.v3.ncrunchproject @@ -0,0 +1,5 @@ + + + True + + \ No newline at end of file From cbf072efb6454b0725d6cdcd1dcb936833ee7497 Mon Sep 17 00:00:00 2001 From: Dan Walmsley Date: Wed, 9 Nov 2022 12:50:10 +0000 Subject: [PATCH 15/22] fix condition in targets file. --- src/Web/Avalonia.Web/Avalonia.Web.targets | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Web/Avalonia.Web/Avalonia.Web.targets b/src/Web/Avalonia.Web/Avalonia.Web.targets index b5db8e5dd3..22363b33d8 100644 --- a/src/Web/Avalonia.Web/Avalonia.Web.targets +++ b/src/Web/Avalonia.Web/Avalonia.Web.targets @@ -12,7 +12,7 @@ true - + true full true From a62c56186fef420cb6326c862a218ac172aaaf30 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Wed, 9 Nov 2022 15:22:30 +0100 Subject: [PATCH 16/22] Use GetRequiredService in touch/mouse device. --- src/Avalonia.Base/Input/MouseDevice.cs | 6 +++--- src/Avalonia.Base/Input/TouchDevice.cs | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Avalonia.Base/Input/MouseDevice.cs b/src/Avalonia.Base/Input/MouseDevice.cs index 808efb3931..b4bc419223 100644 --- a/src/Avalonia.Base/Input/MouseDevice.cs +++ b/src/Avalonia.Base/Input/MouseDevice.cs @@ -127,9 +127,9 @@ namespace Avalonia.Input _pointer.Capture(source); if (source != null) { - var settings = AvaloniaLocator.Current.GetService(); - var doubleClickTime = settings?.GetDoubleTapTime(PointerType.Mouse).TotalMilliseconds ?? 500; - var doubleClickSize = settings?.GetDoubleTapSize(PointerType.Mouse) ?? new Size(4, 4); + var settings = AvaloniaLocator.Current.GetRequiredService(); + var doubleClickTime = settings.GetDoubleTapTime(PointerType.Mouse).TotalMilliseconds; + var doubleClickSize = settings.GetDoubleTapSize(PointerType.Mouse); if (!_lastClickRect.Contains(p) || timestamp - _lastClickTime > doubleClickTime) { diff --git a/src/Avalonia.Base/Input/TouchDevice.cs b/src/Avalonia.Base/Input/TouchDevice.cs index 05b0a89e01..c98944359d 100644 --- a/src/Avalonia.Base/Input/TouchDevice.cs +++ b/src/Avalonia.Base/Input/TouchDevice.cs @@ -60,8 +60,8 @@ namespace Avalonia.Input else { var settings = AvaloniaLocator.Current.GetRequiredService(); - var doubleClickTime = settings?.GetDoubleTapTime(PointerType.Touch).TotalMilliseconds ?? 500; - var doubleClickSize = settings?.GetDoubleTapSize(PointerType.Touch) ?? new Size(4, 4); + var doubleClickTime = settings.GetDoubleTapTime(PointerType.Touch).TotalMilliseconds; + var doubleClickSize = settings.GetDoubleTapSize(PointerType.Touch); if (!_lastClickRect.Contains(args.Position) || ev.Timestamp - _lastClickTime > doubleClickTime) From 0e951befdf45cb66422fb31a10d8193b57b4fc21 Mon Sep 17 00:00:00 2001 From: Steven Kirk Date: Wed, 9 Nov 2022 15:27:46 +0100 Subject: [PATCH 17/22] Use DefaultPlatformSettings in Web platform. --- src/Web/Avalonia.Web/WindowingPlatform.cs | 24 ++--------------------- 1 file changed, 2 insertions(+), 22 deletions(-) diff --git a/src/Web/Avalonia.Web/WindowingPlatform.cs b/src/Web/Avalonia.Web/WindowingPlatform.cs index 29c797660f..c399c22c61 100644 --- a/src/Web/Avalonia.Web/WindowingPlatform.cs +++ b/src/Web/Avalonia.Web/WindowingPlatform.cs @@ -8,7 +8,7 @@ using Avalonia.Threading; namespace Avalonia.Web { - internal class BrowserWindowingPlatform : IWindowingPlatform, IPlatformSettings, IPlatformThreadingInterface + internal class BrowserWindowingPlatform : IWindowingPlatform, IPlatformThreadingInterface { private bool _signaled; private static KeyboardDevice? s_keyboard; @@ -36,7 +36,7 @@ namespace Avalonia.Web .Bind().ToSingleton() .Bind().ToSingleton() .Bind().ToConstant(s_keyboard) - .Bind().ToConstant(instance) + .Bind().ToSingleton() .Bind().ToConstant(instance) .Bind().ToConstant(new RenderLoop()) .Bind().ToConstant(ManualTriggerRenderTimer.Instance) @@ -94,25 +94,5 @@ namespace Avalonia.Web { return AvaloniaLocator.Current.GetRequiredService(); } - - Size IPlatformSettings.GetTapSize(PointerType type) - { - return type switch - { - PointerType.Touch => new(10, 10), - _ => new(4, 4), - }; - } - - Size IPlatformSettings.GetDoubleTapSize(PointerType type) - { - return type switch - { - PointerType.Touch => new(16, 16), - _ => new(4, 4), - }; - } - - TimeSpan IPlatformSettings.GetDoubleTapTime(PointerType type) => TimeSpan.FromMilliseconds(500); } } From e1f9809de6338f68aba3ca83cffc3a94ff4d65d0 Mon Sep 17 00:00:00 2001 From: Tim Date: Wed, 9 Nov 2022 15:32:11 +0100 Subject: [PATCH 18/22] Add missing ClipToBounds="True" --- src/Avalonia.Themes.Fluent/Controls/TextBox.xaml | 6 ++++-- src/Avalonia.Themes.Simple/Controls/TextBox.xaml | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/Avalonia.Themes.Fluent/Controls/TextBox.xaml b/src/Avalonia.Themes.Fluent/Controls/TextBox.xaml index db487ef76b..224264b51d 100644 --- a/src/Avalonia.Themes.Fluent/Controls/TextBox.xaml +++ b/src/Avalonia.Themes.Fluent/Controls/TextBox.xaml @@ -235,7 +235,8 @@ From 1fc811f82c0d31ae956effe9e4017307d6120b14 Mon Sep 17 00:00:00 2001 From: Max Katz Date: Wed, 9 Nov 2022 18:55:14 -0500 Subject: [PATCH 19/22] Fix touch tests --- tests/Avalonia.Base.UnitTests/Input/TouchDeviceTests.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/Avalonia.Base.UnitTests/Input/TouchDeviceTests.cs b/tests/Avalonia.Base.UnitTests/Input/TouchDeviceTests.cs index 1070138221..c0c0182622 100644 --- a/tests/Avalonia.Base.UnitTests/Input/TouchDeviceTests.cs +++ b/tests/Avalonia.Base.UnitTests/Input/TouchDeviceTests.cs @@ -210,6 +210,8 @@ namespace Avalonia.Input.UnitTests new TestServices(inputManager: new InputManager())); var iSettingsMock = new Mock(); iSettingsMock.Setup(x => x.GetDoubleTapTime(It.IsAny())).Returns(doubleClickTime); + iSettingsMock.Setup(x => x.GetDoubleTapSize(It.IsAny())).Returns(new Size(16, 16)); + iSettingsMock.Setup(x => x.GetTapSize(It.IsAny())).Returns(new Size(16, 16)); AvaloniaLocator.CurrentMutable.BindToSelf(this) .Bind().ToConstant(iSettingsMock.Object); return unitTestApp; From 0b3f2adce91af8e732b7dd8fc8af19afb70d76a7 Mon Sep 17 00:00:00 2001 From: Max Katz Date: Wed, 9 Nov 2022 18:55:27 -0500 Subject: [PATCH 20/22] Use DefaultPlatformSettings for android too, fix build error --- src/Android/Avalonia.Android/AndroidPlatform.cs | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/src/Android/Avalonia.Android/AndroidPlatform.cs b/src/Android/Avalonia.Android/AndroidPlatform.cs index ed5b46d398..0d77a4c905 100644 --- a/src/Android/Avalonia.Android/AndroidPlatform.cs +++ b/src/Android/Avalonia.Android/AndroidPlatform.cs @@ -31,16 +31,6 @@ namespace Avalonia.Android public static readonly AndroidPlatform Instance = new AndroidPlatform(); public static AndroidPlatformOptions Options { get; private set; } - /// - public Size TouchDoubleClickSize => new Size(4, 4); - - /// - public TimeSpan TouchDoubleClickTime => TimeSpan.FromMilliseconds(200); - - public Size DoubleClickSize => TouchDoubleClickSize; - - public TimeSpan DoubleClickTime => TimeSpan.FromMilliseconds(500); - internal static Compositor Compositor { get; private set; } public static void Initialize() @@ -52,7 +42,7 @@ namespace Avalonia.Android .Bind().ToTransient() .Bind().ToConstant(new WindowingPlatformStub()) .Bind().ToSingleton() - .Bind().ToConstant(Instance) + .Bind().ToSingleton() .Bind().ToConstant(new AndroidThreadingInterface()) .Bind().ToSingleton() .Bind().ToConstant(new ChoreographerTimer()) From bb0c4d399b11fc69cb9dea4b78532e73ea398bd4 Mon Sep 17 00:00:00 2001 From: Max Katz Date: Wed, 9 Nov 2022 19:02:00 -0500 Subject: [PATCH 21/22] Remove missed interface --- src/Android/Avalonia.Android/AndroidPlatform.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Android/Avalonia.Android/AndroidPlatform.cs b/src/Android/Avalonia.Android/AndroidPlatform.cs index 0d77a4c905..2b6d29e7c5 100644 --- a/src/Android/Avalonia.Android/AndroidPlatform.cs +++ b/src/Android/Avalonia.Android/AndroidPlatform.cs @@ -26,7 +26,7 @@ namespace Avalonia namespace Avalonia.Android { - class AndroidPlatform : IPlatformSettings + class AndroidPlatform { public static readonly AndroidPlatform Instance = new AndroidPlatform(); public static AndroidPlatformOptions Options { get; private set; } From 58cc00898fd115215c7cc075a8530ba22ff33d29 Mon Sep 17 00:00:00 2001 From: Max Katz Date: Wed, 9 Nov 2022 19:28:25 -0500 Subject: [PATCH 22/22] Fix IME overflow on x86 --- src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs b/src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs index c4136a239e..8aa4746b5a 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.AppWndProc.cs @@ -672,7 +672,10 @@ namespace Avalonia.Win32 } case WindowsMessage.WM_IME_SETCONTEXT: { - DefWindowProc(Hwnd, msg, wParam, (IntPtr)(lParam.ToInt64() & ~ISC_SHOWUICOMPOSITIONWINDOW)); + unchecked + { + DefWindowProc(Hwnd, msg, wParam, lParam & ~(nint)ISC_SHOWUICOMPOSITIONWINDOW); + } UpdateInputMethod(GetKeyboardLayout(0));