Browse Source

Merge pull request #11564 from AvaloniaUI/platform-settings

Return PlatformSettings API after being previously hidden
pull/11585/head
Max Katz 3 years ago
committed by GitHub
parent
commit
1183ef69d7
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 10
      src/Avalonia.Base/Input/Gestures.cs
  2. 11
      src/Avalonia.Base/Input/IInputRoot.cs
  3. 17
      src/Avalonia.Base/Input/MouseDevice.cs
  4. 27
      src/Avalonia.Base/Input/PenDevice.cs
  5. 10
      src/Avalonia.Base/Input/Platform/PlatformHotkeyConfiguration.cs
  6. 29
      src/Avalonia.Base/Input/TouchDevice.cs
  7. 9
      src/Avalonia.Base/Platform/DefaultPlatformSettings.cs
  8. 12
      src/Avalonia.Base/Platform/IPlatformSettings.cs
  9. 24
      src/Avalonia.Base/Utilities/ThrowHelper.cs
  10. 19
      src/Avalonia.Base/VisualTree/VisualExtensions.cs
  11. 30
      src/Avalonia.Controls.DataGrid/DataGrid.cs
  12. 2
      src/Avalonia.Controls.DataGrid/DataGridColumn.cs
  13. 2
      src/Avalonia.Controls.DataGrid/DataGridColumnHeader.cs
  14. 16
      src/Avalonia.Controls.DataGrid/Utils/KeyboardHelper.cs
  15. 23
      src/Avalonia.Controls/Application.cs
  16. 2
      src/Avalonia.Controls/ContextMenu.cs
  17. 2
      src/Avalonia.Controls/Control.cs
  18. 3
      src/Avalonia.Controls/Flyouts/PopupFlyoutBase.cs
  19. 5
      src/Avalonia.Controls/ListBox.cs
  20. 2
      src/Avalonia.Controls/ListBoxItem.cs
  21. 3
      src/Avalonia.Controls/MaskedTextBox.cs
  22. 2
      src/Avalonia.Controls/SelectableTextBlock.cs
  23. 11
      src/Avalonia.Controls/TextBox.cs
  24. 5
      src/Avalonia.Controls/TopLevel.cs
  25. 5
      src/Avalonia.Controls/TreeView.cs
  26. 18
      src/Avalonia.Native/AvaloniaNativePlatform.cs
  27. 34
      src/Avalonia.Themes.Fluent/Accents/SystemAccentColors.cs
  28. 82
      tests/Avalonia.Base.UnitTests/Input/GesturesTests.cs
  29. 76
      tests/Avalonia.Controls.UnitTests/ButtonTests.cs
  30. 24
      tests/Avalonia.Controls.UnitTests/ListBoxTests_Multiple.cs
  31. 14
      tests/Avalonia.Controls.UnitTests/ListBoxTests_Single.cs
  32. 8
      tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs
  33. 6
      tests/Avalonia.Controls.UnitTests/TreeViewTests.cs
  34. 1
      tests/Avalonia.UnitTests/TestRoot.cs
  35. 3
      tests/Avalonia.UnitTests/UnitTestApplication.cs

10
src/Avalonia.Base/Input/Gestures.cs

@ -182,7 +182,7 @@ namespace Avalonia.Input
s_lastPressPoint = e.GetPosition((Visual)ev.Source);
s_holdCancellationToken = new CancellationTokenSource();
var token = s_holdCancellationToken.Token;
var settings = AvaloniaLocator.Current.GetService<IPlatformSettings>();
var settings = ((IInputRoot?)visual.GetVisualRoot())?.PlatformSettings;
if (settings != null)
{
@ -221,7 +221,7 @@ namespace Avalonia.Input
e.Source is Interactive i)
{
var point = e.GetCurrentPoint((Visual)target);
var settings = AvaloniaLocator.Current.GetService<IPlatformSettings>();
var settings = ((IInputRoot?)i.GetVisualRoot())?.PlatformSettings;
var tapSize = settings?.GetTapSize(point.Pointer.Type) ?? new Size(4, 4);
var tapRect = new Rect(s_lastPressPoint, new Size())
.Inflate(new Thickness(tapSize.Width, tapSize.Height));
@ -260,10 +260,10 @@ namespace Avalonia.Input
var e = (PointerEventArgs)ev;
if (s_lastPress.TryGetTarget(out var target))
{
if (e.Pointer == s_lastPointer)
if (e.Pointer == s_lastPointer && ev.Source is Interactive i)
{
var point = e.GetCurrentPoint((Visual)target);
var settings = AvaloniaLocator.Current.GetService<IPlatformSettings>();
var settings = ((IInputRoot?)i.GetVisualRoot())?.PlatformSettings;
var tapSize = settings?.GetTapSize(point.Pointer.Type) ?? new Size(4, 4);
var tapRect = new Rect(s_lastPressPoint, new Size())
.Inflate(new Thickness(tapSize.Width, tapSize.Height));
@ -273,7 +273,7 @@ namespace Avalonia.Input
return;
}
if (s_isHolding && ev.Source is Interactive i)
if (s_isHolding)
{
i.RaiseEvent(new HoldingRoutedEventArgs(HoldingState.Cancelled, s_lastPressPoint, s_lastPointer!.Type));
}

11
src/Avalonia.Base/Input/IInputRoot.cs

@ -1,4 +1,5 @@
using Avalonia.Metadata;
using Avalonia.Platform;
namespace Avalonia.Input
{
@ -17,10 +18,18 @@ namespace Avalonia.Input
/// Gets focus manager of the root.
/// </summary>
/// <remarks>
/// Focus manager can be null only if application wasn't initialized yet.
/// Focus manager can be null only if window wasn't initialized yet.
/// </remarks>
IFocusManager? FocusManager { get; }
/// <summary>
/// Represents a contract for accessing top-level platform-specific settings.
/// </summary>
/// <remarks>
/// PlatformSettings can be null only if window wasn't initialized yet.
/// </remarks>
IPlatformSettings? PlatformSettings { get; }
/// <summary>
/// Gets or sets the input element that the pointer is currently over.
/// </summary>

17
src/Avalonia.Base/Input/MouseDevice.cs

@ -2,9 +2,12 @@ using System;
using System.Collections.Generic;
using Avalonia.Reactive;
using Avalonia.Input.Raw;
using Avalonia.Interactivity;
using Avalonia.Metadata;
using Avalonia.Platform;
using Avalonia.Utilities;
using Avalonia.VisualTree;
#pragma warning disable CS0618
namespace Avalonia.Input
@ -126,9 +129,10 @@ namespace Avalonia.Input
if (source != null)
{
_pointer.Capture(source);
if (source != null)
var settings = ((IInputRoot?)(source as Interactive)?.GetVisualRoot())?.PlatformSettings;
if (settings is not null)
{
var settings = AvaloniaLocator.Current.GetRequiredService<IPlatformSettings>();
var doubleClickTime = settings.GetDoubleTapTime(PointerType.Mouse).TotalMilliseconds;
var doubleClickSize = settings.GetDoubleTapSize(PointerType.Mouse);
@ -141,11 +145,12 @@ namespace Avalonia.Input
_lastClickTime = timestamp;
_lastClickRect = new Rect(p, new Size())
.Inflate(new Thickness(doubleClickSize.Width / 2, doubleClickSize.Height / 2));
_lastMouseDownButton = properties.PointerUpdateKind.GetMouseButton();
var e = new PointerPressedEventArgs(source, _pointer, (Visual)root, p, timestamp, properties, inputModifiers, _clickCount);
source.RaiseEvent(e);
return e.Handled;
}
_lastMouseDownButton = properties.PointerUpdateKind.GetMouseButton();
var e = new PointerPressedEventArgs(source, _pointer, (Visual)root, p, timestamp, properties, inputModifiers, _clickCount);
source.RaiseEvent(e);
return e.Handled;
}
return false;

27
src/Avalonia.Base/Input/PenDevice.cs

@ -3,8 +3,11 @@ using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Avalonia.Input.Raw;
using Avalonia.Interactivity;
using Avalonia.Metadata;
using Avalonia.Platform;
using Avalonia.VisualTree;
#pragma warning disable CS0618
namespace Avalonia.Input
@ -80,19 +83,23 @@ namespace Avalonia.Input
if (source != null)
{
pointer.Capture(source);
var settings = AvaloniaLocator.Current.GetService<IPlatformSettings>();
var doubleClickTime = settings?.GetDoubleTapTime(PointerType.Pen).TotalMilliseconds ?? 500;
var doubleClickSize = settings?.GetDoubleTapSize(PointerType.Pen) ?? new Size(4, 4);
if (!_lastClickRect.Contains(p) || timestamp - _lastClickTime > doubleClickTime)
var settings = ((IInputRoot?)(source as Interactive)?.GetVisualRoot())?.PlatformSettings;
if (settings is not null)
{
_clickCount = 0;
var doubleClickTime = settings.GetDoubleTapTime(PointerType.Pen).TotalMilliseconds;
var doubleClickSize = settings.GetDoubleTapSize(PointerType.Pen);
if (!_lastClickRect.Contains(p) || timestamp - _lastClickTime > doubleClickTime)
{
_clickCount = 0;
}
++_clickCount;
_lastClickTime = timestamp;
_lastClickRect = new Rect(p, new Size())
.Inflate(new Thickness(doubleClickSize.Width / 2, doubleClickSize.Height / 2));
}
++_clickCount;
_lastClickTime = timestamp;
_lastClickRect = new Rect(p, new Size())
.Inflate(new Thickness(doubleClickSize.Width / 2, doubleClickSize.Height / 2));
_lastMouseDownButton = properties.PointerUpdateKind.GetMouseButton();
var e = new PointerPressedEventArgs(source, pointer, (Visual)root, p, timestamp, properties, inputModifiers, _clickCount);
source.RaiseEvent(e);

10
src/Avalonia.Base/Input/Platform/PlatformHotkeyConfiguration.cs

@ -1,16 +1,20 @@
using System.Collections.Generic;
#nullable enable
using Avalonia.Metadata;
namespace Avalonia.Input.Platform
{
public class PlatformHotkeyConfiguration
/// <summary>
/// The PlatformHotkeyConfiguration class represents a configuration for platform-specific hotkeys in an Avalonia application.
/// </summary>
public sealed class PlatformHotkeyConfiguration
{
[PrivateApi]
public PlatformHotkeyConfiguration() : this(KeyModifiers.Control)
{
}
[PrivateApi]
public PlatformHotkeyConfiguration(KeyModifiers commandModifiers,
KeyModifiers selectionModifiers = KeyModifiers.Shift,
KeyModifiers wholeWordTextActionModifiers = KeyModifiers.Control)

29
src/Avalonia.Base/Input/TouchDevice.cs

@ -3,8 +3,11 @@ using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Avalonia.Input.Raw;
using Avalonia.Interactivity;
using Avalonia.Metadata;
using Avalonia.Platform;
using Avalonia.VisualTree;
#pragma warning disable CS0618
namespace Avalonia.Input
@ -62,19 +65,23 @@ namespace Avalonia.Input
}
else
{
var settings = AvaloniaLocator.Current.GetRequiredService<IPlatformSettings>();
var doubleClickTime = settings.GetDoubleTapTime(PointerType.Touch).TotalMilliseconds;
var doubleClickSize = settings.GetDoubleTapSize(PointerType.Touch);
if (!_lastClickRect.Contains(args.Position)
|| ev.Timestamp - _lastClickTime > doubleClickTime)
var settings = ((IInputRoot?)(target as Interactive)?.GetVisualRoot())?.PlatformSettings;
if (settings is not null)
{
_clickCount = 0;
var doubleClickTime = settings.GetDoubleTapTime(PointerType.Touch).TotalMilliseconds;
var doubleClickSize = settings.GetDoubleTapSize(PointerType.Touch);
if (!_lastClickRect.Contains(args.Position)
|| ev.Timestamp - _lastClickTime > doubleClickTime)
{
_clickCount = 0;
}
++_clickCount;
_lastClickTime = ev.Timestamp;
_lastClickRect = new Rect(args.Position, new Size())
.Inflate(new Thickness(doubleClickSize.Width / 2, doubleClickSize.Height / 2));
}
++_clickCount;
_lastClickTime = ev.Timestamp;
_lastClickRect = new Rect(args.Position, new Size())
.Inflate(new Thickness(doubleClickSize.Width / 2, doubleClickSize.Height / 2));
}
target.RaiseEvent(new PointerPressedEventArgs(target, pointer,

9
src/Avalonia.Base/Platform/DefaultPlatformSettings.cs

@ -1,12 +1,16 @@
using System;
using Avalonia.Input;
using Avalonia.Input.Platform;
using Avalonia.Media;
using Avalonia.Metadata;
using Avalonia.VisualTree;
namespace Avalonia.Platform
{
/// <summary>
/// A default implementation of <see cref="IPlatformSettings"/> for platforms.
/// </summary>
[PrivateApi]
public class DefaultPlatformSettings : IPlatformSettings
{
public virtual Size GetTapSize(PointerType type)
@ -28,7 +32,10 @@ namespace Avalonia.Platform
public virtual TimeSpan GetDoubleTapTime(PointerType type) => TimeSpan.FromMilliseconds(500);
public virtual TimeSpan HoldWaitDuration => TimeSpan.FromMilliseconds(300);
public PlatformHotkeyConfiguration HotkeyConfiguration =>
AvaloniaLocator.Current.GetRequiredService<PlatformHotkeyConfiguration>();
public virtual PlatformColorValues GetColorValues()
{
return new PlatformColorValues

12
src/Avalonia.Base/Platform/IPlatformSettings.cs

@ -1,10 +1,15 @@
using System;
using Avalonia.Input;
using Avalonia.Input.Platform;
using Avalonia.Metadata;
namespace Avalonia.Platform
{
[Unstable]
/// <summary>
/// The <see cref="IPlatformSettings"/> interface represents a contract for accessing platform-specific settings and information.
/// Some of these settings might be changed by used globally in the OS in runtime.
/// </summary>
[NotClientImplementable]
public interface IPlatformSettings
{
/// <summary>
@ -33,6 +38,11 @@ namespace Avalonia.Platform
/// </summary>
TimeSpan HoldWaitDuration { get; }
/// <summary>
/// Get a configuration for platform-specific hotkeys in an Avalonia application.
/// </summary>
PlatformHotkeyConfiguration HotkeyConfiguration { get; }
/// <summary>
/// Gets current system color values including dark mode and accent colors.
/// </summary>

24
src/Avalonia.Base/Utilities/ThrowHelper.cs

@ -0,0 +1,24 @@
using System;
using System.Diagnostics.CodeAnalysis;
using System.Runtime.CompilerServices;
namespace Avalonia.Utilities;
/// <summary>
/// Helper method to help inlining methods that do a throw check.
/// Equivalent of .NET6+ ArgumentNullException.ThrowIfNull() for netstandard2.0+
/// </summary>
internal class ThrowHelper
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void ThrowIfNull([NotNull] object? argument, string paramName)
{
if (argument is null)
{
ThrowArgumentNullException(paramName);
}
}
[DoesNotReturn]
private static void ThrowArgumentNullException(string paramName) => throw new ArgumentNullException(paramName);
}

19
src/Avalonia.Base/VisualTree/VisualExtensions.cs

@ -1,7 +1,10 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Runtime.CompilerServices;
using Avalonia.Rendering;
using Avalonia.Utilities;
namespace Avalonia.VisualTree
{
@ -125,9 +128,9 @@ namespace Avalonia.VisualTree
/// <returns>The visual's ancestors.</returns>
public static IEnumerable<Visual> GetVisualAncestors(this Visual visual)
{
Visual? v = visual ?? throw new ArgumentNullException(nameof(visual));
ThrowHelper.ThrowIfNull(visual, nameof(visual));
v = v.VisualParent;
var v = visual.VisualParent;
while (v != null)
{
@ -194,7 +197,7 @@ namespace Avalonia.VisualTree
/// <returns>The visual and its ancestors.</returns>
public static IEnumerable<Visual> GetSelfAndVisualAncestors(this Visual visual)
{
_ = visual ?? throw new ArgumentNullException(nameof(visual));
ThrowHelper.ThrowIfNull(visual, nameof(visual));
yield return visual;
@ -275,7 +278,7 @@ namespace Avalonia.VisualTree
/// <returns>The visual at the requested point.</returns>
public static Visual? GetVisualAt(this Visual visual, Point p)
{
_ = visual ?? throw new ArgumentNullException(nameof(visual));
ThrowHelper.ThrowIfNull(visual, nameof(visual));
return visual.GetVisualAt(p, x => x.IsVisible);
}
@ -292,7 +295,7 @@ namespace Avalonia.VisualTree
/// <returns>The visual at the requested point.</returns>
public static Visual? GetVisualAt(this Visual visual, Point p, Func<Visual, bool> filter)
{
_ = visual ?? throw new ArgumentNullException(nameof(visual));
ThrowHelper.ThrowIfNull(visual, nameof(visual));
var root = visual.GetVisualRoot();
@ -321,7 +324,7 @@ namespace Avalonia.VisualTree
this Visual visual,
Point p)
{
_ = visual ?? throw new ArgumentNullException(nameof(visual));
ThrowHelper.ThrowIfNull(visual, nameof(visual));
return visual.GetVisualsAt(p, x => x.IsVisible);
}
@ -341,7 +344,7 @@ namespace Avalonia.VisualTree
Point p,
Func<Visual, bool> filter)
{
_ = visual ?? throw new ArgumentNullException(nameof(visual));
ThrowHelper.ThrowIfNull(visual, nameof(visual));
var root = visual.GetVisualRoot();
@ -435,7 +438,7 @@ namespace Avalonia.VisualTree
/// </returns>
public static IRenderRoot? GetVisualRoot(this Visual visual)
{
_ = visual ?? throw new ArgumentNullException(nameof(visual));
ThrowHelper.ThrowIfNull(visual, nameof(visual));
return visual as IRenderRoot ?? visual.VisualRoot;
}

30
src/Avalonia.Controls.DataGrid/DataGrid.cs

@ -2660,25 +2660,25 @@ namespace Avalonia.Controls
internal bool ProcessDownKey(KeyEventArgs e)
{
KeyboardHelper.GetMetaKeyState(e.KeyModifiers, out bool ctrl, out bool shift);
KeyboardHelper.GetMetaKeyState(this, e.KeyModifiers, out bool ctrl, out bool shift);
return ProcessDownKeyInternal(shift, ctrl);
}
internal bool ProcessEndKey(KeyEventArgs e)
{
KeyboardHelper.GetMetaKeyState(e.KeyModifiers, out bool ctrl, out bool shift);
KeyboardHelper.GetMetaKeyState(this, e.KeyModifiers, out bool ctrl, out bool shift);
return ProcessEndKey(shift, ctrl);
}
internal bool ProcessEnterKey(KeyEventArgs e)
{
KeyboardHelper.GetMetaKeyState(e.KeyModifiers, out bool ctrl, out bool shift);
KeyboardHelper.GetMetaKeyState(this, e.KeyModifiers, out bool ctrl, out bool shift);
return ProcessEnterKey(shift, ctrl);
}
internal bool ProcessHomeKey(KeyEventArgs e)
{
KeyboardHelper.GetMetaKeyState(e.KeyModifiers, out bool ctrl, out bool shift);
KeyboardHelper.GetMetaKeyState(this, e.KeyModifiers, out bool ctrl, out bool shift);
return ProcessHomeKey(shift, ctrl);
}
@ -2718,25 +2718,25 @@ namespace Avalonia.Controls
internal bool ProcessLeftKey(KeyEventArgs e)
{
KeyboardHelper.GetMetaKeyState(e.KeyModifiers, out bool ctrl, out bool shift);
KeyboardHelper.GetMetaKeyState(this, e.KeyModifiers, out bool ctrl, out bool shift);
return ProcessLeftKey(shift, ctrl);
}
internal bool ProcessNextKey(KeyEventArgs e)
{
KeyboardHelper.GetMetaKeyState(e.KeyModifiers, out bool ctrl, out bool shift);
KeyboardHelper.GetMetaKeyState(this, e.KeyModifiers, out bool ctrl, out bool shift);
return ProcessNextKey(shift, ctrl);
}
internal bool ProcessPriorKey(KeyEventArgs e)
{
KeyboardHelper.GetMetaKeyState(e.KeyModifiers, out bool ctrl, out bool shift);
KeyboardHelper.GetMetaKeyState(this, e.KeyModifiers, out bool ctrl, out bool shift);
return ProcessPriorKey(shift, ctrl);
}
internal bool ProcessRightKey(KeyEventArgs e)
{
KeyboardHelper.GetMetaKeyState(e.KeyModifiers, out bool ctrl, out bool shift);
KeyboardHelper.GetMetaKeyState(this, e.KeyModifiers, out bool ctrl, out bool shift);
return ProcessRightKey(shift, ctrl);
}
@ -2854,7 +2854,7 @@ namespace Avalonia.Controls
internal bool ProcessUpKey(KeyEventArgs e)
{
KeyboardHelper.GetMetaKeyState(e.KeyModifiers, out bool ctrl, out bool shift);
KeyboardHelper.GetMetaKeyState(this, e.KeyModifiers, out bool ctrl, out bool shift);
return ProcessUpKey(shift, ctrl);
}
@ -3124,13 +3124,13 @@ namespace Avalonia.Controls
//TODO: Ensure right button is checked for
internal bool UpdateStateOnMouseRightButtonDown(PointerPressedEventArgs pointerPressedEventArgs, int columnIndex, int slot, bool allowEdit)
{
KeyboardHelper.GetMetaKeyState(pointerPressedEventArgs.KeyModifiers, out bool ctrl, out bool shift);
KeyboardHelper.GetMetaKeyState(this, pointerPressedEventArgs.KeyModifiers, out bool ctrl, out bool shift);
return UpdateStateOnMouseRightButtonDown(pointerPressedEventArgs, columnIndex, slot, allowEdit, shift, ctrl);
}
//TODO: Ensure left button is checked for
internal bool UpdateStateOnMouseLeftButtonDown(PointerPressedEventArgs pointerPressedEventArgs, int columnIndex, int slot, bool allowEdit)
{
KeyboardHelper.GetMetaKeyState(pointerPressedEventArgs.KeyModifiers, out bool ctrl, out bool shift);
KeyboardHelper.GetMetaKeyState(this, pointerPressedEventArgs.KeyModifiers, out bool ctrl, out bool shift);
return UpdateStateOnMouseLeftButtonDown(pointerPressedEventArgs, columnIndex, slot, allowEdit, shift, ctrl);
}
@ -4654,7 +4654,7 @@ namespace Avalonia.Controls
private bool ProcessAKey(KeyEventArgs e)
{
KeyboardHelper.GetMetaKeyState(e.KeyModifiers, out bool ctrl, out bool shift, out bool alt);
KeyboardHelper.GetMetaKeyState(this, e.KeyModifiers, out bool ctrl, out bool shift, out bool alt);
if (ctrl && !shift && !alt && SelectionMode == DataGridSelectionMode.Extended)
{
@ -4923,7 +4923,7 @@ namespace Avalonia.Controls
private bool ProcessF2Key(KeyEventArgs e)
{
KeyboardHelper.GetMetaKeyState(e.KeyModifiers, out bool ctrl, out bool shift);
KeyboardHelper.GetMetaKeyState(this, e.KeyModifiers, out bool ctrl, out bool shift);
if (!shift && !ctrl &&
_editingColumnIndex == -1 && CurrentColumnIndex != -1 && GetRowSelection(CurrentSlot) &&
@ -5280,7 +5280,7 @@ namespace Avalonia.Controls
private bool ProcessTabKey(KeyEventArgs e)
{
KeyboardHelper.GetMetaKeyState(e.KeyModifiers, out bool ctrl, out bool shift);
KeyboardHelper.GetMetaKeyState(this, e.KeyModifiers, out bool ctrl, out bool shift);
return ProcessTabKey(e, shift, ctrl);
}
@ -6099,7 +6099,7 @@ namespace Avalonia.Controls
/// <returns>Whether or not the DataGrid handled the key press.</returns>
private bool ProcessCopyKey(KeyModifiers modifiers)
{
KeyboardHelper.GetMetaKeyState(modifiers, out bool ctrl, out bool shift, out bool alt);
KeyboardHelper.GetMetaKeyState(this, modifiers, out bool ctrl, out bool shift, out bool alt);
if (ctrl && !shift && !alt && ClipboardCopyMode != DataGridClipboardCopyMode.None && SelectedItems.Count > 0)
{

2
src/Avalonia.Controls.DataGrid/DataGridColumn.cs

@ -703,7 +703,7 @@ namespace Avalonia.Controls
public void ClearSort()
{
//InvokeProcessSort is already validating if sorting is possible
_headerCell?.InvokeProcessSort(KeyboardHelper.GetPlatformCtrlOrCmdKeyModifier());
_headerCell?.InvokeProcessSort(KeyboardHelper.GetPlatformCtrlOrCmdKeyModifier(OwningGrid));
}
/// <summary>

2
src/Avalonia.Controls.DataGrid/DataGridColumnHeader.cs

@ -241,7 +241,7 @@ namespace Avalonia.Controls
DataGrid owningGrid = OwningGrid;
DataGridSortDescription newSort;
KeyboardHelper.GetMetaKeyState(keyModifiers, out bool ctrl, out bool shift);
KeyboardHelper.GetMetaKeyState(this, keyModifiers, out bool ctrl, out bool shift);
DataGridSortDescription sort = OwningColumn.GetSortDescription();
IDataGridCollectionView collectionView = owningGrid.DataConnection.CollectionView;

16
src/Avalonia.Controls.DataGrid/Utils/KeyboardHelper.cs

@ -10,23 +10,23 @@ namespace Avalonia.Controls.Utils
{
internal static class KeyboardHelper
{
public static void GetMetaKeyState(KeyModifiers modifiers, out bool ctrlOrCmd, out bool shift)
public static void GetMetaKeyState(Control target, KeyModifiers modifiers, out bool ctrlOrCmd, out bool shift)
{
ctrlOrCmd = modifiers.HasFlag(GetPlatformCtrlOrCmdKeyModifier());
ctrlOrCmd = modifiers.HasFlag(GetPlatformCtrlOrCmdKeyModifier(target));
shift = modifiers.HasFlag(KeyModifiers.Shift);
}
public static void GetMetaKeyState(KeyModifiers modifiers, out bool ctrlOrCmd, out bool shift, out bool alt)
public static void GetMetaKeyState(Control target, KeyModifiers modifiers, out bool ctrlOrCmd, out bool shift, out bool alt)
{
ctrlOrCmd = modifiers.HasFlag(GetPlatformCtrlOrCmdKeyModifier());
ctrlOrCmd = modifiers.HasFlag(GetPlatformCtrlOrCmdKeyModifier(target));
shift = modifiers.HasFlag(KeyModifiers.Shift);
alt = modifiers.HasFlag(KeyModifiers.Alt);
}
public static KeyModifiers GetPlatformCtrlOrCmdKeyModifier()
{
var keymap = AvaloniaLocator.Current.GetService<PlatformHotkeyConfiguration>();
return keymap?.CommandModifiers ?? KeyModifiers.Control;
public static KeyModifiers GetPlatformCtrlOrCmdKeyModifier(Control target)
{
var keymap = TopLevel.GetTopLevel(target)!.PlatformSettings!.HotkeyConfiguration;
return keymap.CommandModifiers;
}
}
}

23
src/Avalonia.Controls/Application.cs

@ -180,6 +180,17 @@ namespace Avalonia
/// </summary>
public IApplicationLifetime? ApplicationLifetime { get; set; }
/// <summary>
/// Represents a contract for accessing global platform-specific settings.
/// </summary>
/// <remarks>
/// PlatformSettings can be null only if application wasn't initialized yet.
/// <see cref="TopLevel"/>'s <see cref="TopLevel.PlatformSettings"/> is an equivalent API
/// which should always be preferred over a global one,
/// as specific top levels might have different settings set-up.
/// </remarks>
public IPlatformSettings? PlatformSettings => AvaloniaLocator.Current.GetService<IPlatformSettings>();
event Action<IReadOnlyList<IStyle>>? IGlobalStyles.GlobalStylesAdded
{
add => _stylesAdded += value;
@ -229,10 +240,12 @@ namespace Avalonia
var focusManager = new FocusManager();
InputManager = new InputManager();
var settings = AvaloniaLocator.Current.GetRequiredService<IPlatformSettings>();
settings.ColorValuesChanged += OnColorValuesChanged;
OnColorValuesChanged(settings, settings.GetColorValues());
if (PlatformSettings is { } settings)
{
settings.ColorValuesChanged += OnColorValuesChanged;
OnColorValuesChanged(settings, settings.GetColorValues());
}
AvaloniaLocator.CurrentMutable
.Bind<IAccessKeyHandler>().ToTransient<AccessKeyHandler>()
.Bind<IGlobalDataTemplates>().ToConstant(this)
@ -242,7 +255,7 @@ namespace Avalonia
.Bind<IInputManager>().ToConstant(InputManager)
.Bind<IKeyboardNavigationHandler>().ToTransient<KeyboardNavigationHandler>()
.Bind<IDragDropDevice>().ToConstant(DragDropDevice.Instance);
// TODO: Fix this, for now we keep this behavior since someone might be relying on it in 0.9.x
if (AvaloniaLocator.Current.GetService<IPlatformDragSource>() == null)
AvaloniaLocator.CurrentMutable

2
src/Avalonia.Controls/ContextMenu.cs

@ -405,7 +405,7 @@ namespace Avalonia.Controls
{
if (IsOpen)
{
var keymap = AvaloniaLocator.Current.GetService<PlatformHotkeyConfiguration>();
var keymap = Application.Current!.PlatformSettings!.HotkeyConfiguration;
if (keymap?.OpenContextMenu.Any(k => k.Matches(e)) == true
&& !CancelClosing())

2
src/Avalonia.Controls/Control.cs

@ -480,7 +480,7 @@ namespace Avalonia.Controls
if (e.Source == this
&& !e.Handled)
{
var keymap = AvaloniaLocator.Current.GetService<PlatformHotkeyConfiguration>()?.OpenContextMenu;
var keymap = Application.Current!.PlatformSettings?.HotkeyConfiguration.OpenContextMenu;
if (keymap is null)
{

3
src/Avalonia.Controls/Flyouts/PopupFlyoutBase.cs

@ -9,6 +9,7 @@ using Avalonia.Input.Raw;
using Avalonia.Layout;
using Avalonia.Logging;
using Avalonia.Reactive;
using Avalonia.VisualTree;
namespace Avalonia.Controls.Primitives
{
@ -392,7 +393,7 @@ namespace Avalonia.Controls.Primitives
&& IsOpen
&& Target?.ContextFlyout == this)
{
var keymap = AvaloniaLocator.Current.GetService<PlatformHotkeyConfiguration>();
var keymap = Application.Current!.PlatformSettings?.HotkeyConfiguration;
if (keymap?.OpenContextMenu.Any(k => k.Matches(e)) == true)
{

5
src/Avalonia.Controls/ListBox.cs

@ -9,6 +9,7 @@ using Avalonia.Controls.Selection;
using Avalonia.Controls.Templates;
using Avalonia.Input;
using Avalonia.Input.Platform;
using Avalonia.VisualTree;
namespace Avalonia.Controls
{
@ -127,7 +128,7 @@ namespace Avalonia.Controls
protected override void OnKeyDown(KeyEventArgs e)
{
var hotkeys = AvaloniaLocator.Current.GetService<PlatformHotkeyConfiguration>();
var hotkeys = Application.Current!.PlatformSettings?.HotkeyConfiguration;
var ctrl = hotkeys is not null && e.KeyModifiers.HasAllFlags(hotkeys.CommandModifiers);
if (!ctrl &&
@ -165,7 +166,7 @@ namespace Avalonia.Controls
internal bool UpdateSelectionFromPointerEvent(Control source, PointerEventArgs e)
{
var hotkeys = AvaloniaLocator.Current.GetService<PlatformHotkeyConfiguration>();
var hotkeys = Application.Current!.PlatformSettings?.HotkeyConfiguration;
var toggle = hotkeys is not null && e.KeyModifiers.HasAllFlags(hotkeys.CommandModifiers);
return UpdateSelectionFromEventSource(

2
src/Avalonia.Controls/ListBoxItem.cs

@ -90,7 +90,7 @@ namespace Avalonia.Controls
e.InitialPressMouseButton is MouseButton.Left or MouseButton.Right)
{
var point = e.GetCurrentPoint(this);
var settings = AvaloniaLocator.Current.GetService<IPlatformSettings>();
var settings = TopLevel.GetTopLevel(e.Source as Visual)?.PlatformSettings;
var tapSize = settings?.GetTapSize(point.Pointer.Type) ?? new Size(4, 4);
var tapRect = new Rect(_pointerDownPoint, new Size())
.Inflate(new Thickness(tapSize.Width, tapSize.Height));

3
src/Avalonia.Controls/MaskedTextBox.cs

@ -7,6 +7,7 @@ using Avalonia.Input;
using Avalonia.Input.Platform;
using Avalonia.Interactivity;
using Avalonia.Styling;
using Avalonia.VisualTree;
namespace Avalonia.Controls
{
@ -204,7 +205,7 @@ namespace Avalonia.Controls
return;
}
var keymap = AvaloniaLocator.Current.GetService<PlatformHotkeyConfiguration>();
var keymap = Application.Current!.PlatformSettings?.HotkeyConfiguration;
bool Match(List<KeyGesture> gestures) => gestures.Any(g => g.Matches(e));

2
src/Avalonia.Controls/SelectableTextBlock.cs

@ -198,7 +198,7 @@ namespace Avalonia.Controls
var handled = false;
var modifiers = e.KeyModifiers;
var keymap = AvaloniaLocator.Current.GetRequiredService<PlatformHotkeyConfiguration>();
var keymap = Application.Current!.PlatformSettings!.HotkeyConfiguration;
bool Match(List<KeyGesture> gestures) => gestures.Any(g => g.Matches(e));

11
src/Avalonia.Controls/TextBox.cs

@ -32,20 +32,17 @@ namespace Avalonia.Controls
/// <summary>
/// Gets a platform-specific <see cref="KeyGesture"/> for the Cut action
/// </summary>
public static KeyGesture? CutGesture { get; } = AvaloniaLocator.Current
.GetService<PlatformHotkeyConfiguration>()?.Cut.FirstOrDefault();
public static KeyGesture? CutGesture => Application.Current?.PlatformSettings?.HotkeyConfiguration.Cut.FirstOrDefault();
/// <summary>
/// Gets a platform-specific <see cref="KeyGesture"/> for the Copy action
/// </summary>
public static KeyGesture? CopyGesture { get; } = AvaloniaLocator.Current
.GetService<PlatformHotkeyConfiguration>()?.Copy.FirstOrDefault();
public static KeyGesture? CopyGesture => Application.Current?.PlatformSettings?.HotkeyConfiguration.Copy.FirstOrDefault();
/// <summary>
/// Gets a platform-specific <see cref="KeyGesture"/> for the Paste action
/// </summary>
public static KeyGesture? PasteGesture { get; } = AvaloniaLocator.Current
.GetService<PlatformHotkeyConfiguration>()?.Paste.FirstOrDefault();
public static KeyGesture? PasteGesture => Application.Current?.PlatformSettings?.HotkeyConfiguration.Paste.FirstOrDefault();
/// <summary>
/// Defines the <see cref="AcceptsReturn"/> property
@ -1103,7 +1100,7 @@ namespace Avalonia.Controls
var handled = false;
var modifiers = e.KeyModifiers;
var keymap = AvaloniaLocator.Current.GetRequiredService<PlatformHotkeyConfiguration>();
var keymap = Application.Current!.PlatformSettings!.HotkeyConfiguration;
bool Match(List<KeyGesture> gestures) => gestures.Any(g => g.Matches(e));
bool DetectSelection() => e.KeyModifiers.HasAllFlags(keymap.SelectionModifiers);

5
src/Avalonia.Controls/TopLevel.cs

@ -250,7 +250,7 @@ namespace Avalonia.Controls
if (e is RawKeyEventArgs rawKeyEventArgs && rawKeyEventArgs.Type == RawKeyEventType.KeyDown)
{
var keymap = AvaloniaLocator.Current.GetService<PlatformHotkeyConfiguration>()?.Back;
var keymap = PlatformSettings?.HotkeyConfiguration.Back;
if (keymap != null)
{
@ -487,6 +487,9 @@ namespace Avalonia.Controls
/// <inheritdoc />
public IFocusManager? FocusManager => AvaloniaLocator.Current.GetService<IFocusManager>();
/// <inheritdoc />
public IPlatformSettings? PlatformSettings => AvaloniaLocator.Current.GetService<IPlatformSettings>();
/// <inheritdoc/>
Point IRenderRoot.PointToClient(PixelPoint p)
{

5
src/Avalonia.Controls/TreeView.cs

@ -571,7 +571,7 @@ namespace Avalonia.Controls
if (!e.Handled)
{
var keymap = AvaloniaLocator.Current.GetService<PlatformHotkeyConfiguration>();
var keymap = Application.Current!.PlatformSettings!.HotkeyConfiguration;
bool Match(List<KeyGesture>? gestures) => gestures?.Any(g => g.Matches(e)) ?? false;
if (this.SelectionMode == SelectionMode.Multiple && Match(keymap?.SelectAll))
@ -652,11 +652,12 @@ namespace Avalonia.Controls
if (point.Properties.IsLeftButtonPressed || point.Properties.IsRightButtonPressed)
{
var keymap = Application.Current!.PlatformSettings!.HotkeyConfiguration;
e.Handled = UpdateSelectionFromEventSource(
e.Source,
true,
e.KeyModifiers.HasAllFlags(KeyModifiers.Shift),
e.KeyModifiers.HasAllFlags(AvaloniaLocator.Current.GetRequiredService<PlatformHotkeyConfiguration>().CommandModifiers),
e.KeyModifiers.HasAllFlags(keymap.CommandModifiers),
point.Properties.IsRightButtonPressed);
}
}

18
src/Avalonia.Native/AvaloniaNativePlatform.cs

@ -108,20 +108,18 @@ namespace Avalonia.Native
.Bind<IWindowingPlatform>().ToConstant(this)
.Bind<IClipboard>().ToConstant(new ClipboardImpl(_factory.CreateClipboard()))
.Bind<IRenderTimer>().ToConstant(new DefaultRenderTimer(60))
.Bind<PlatformHotkeyConfiguration>().ToConstant(new PlatformHotkeyConfiguration(KeyModifiers.Meta, wholeWordTextActionModifiers: KeyModifiers.Alt))
.Bind<IMountedVolumeInfoProvider>().ToConstant(new MacOSMountedVolumeInfoProvider())
.Bind<IPlatformDragSource>().ToConstant(new AvaloniaNativeDragSource(_factory))
.Bind<IPlatformLifetimeEventsImpl>().ToConstant(applicationPlatform)
.Bind<INativeApplicationCommands>().ToConstant(new MacOSNativeMenuCommands(_factory.CreateApplicationCommands()));
var hotkeys = AvaloniaLocator.Current.GetService<PlatformHotkeyConfiguration>();
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));
}
var hotkeys = new PlatformHotkeyConfiguration(KeyModifiers.Meta, wholeWordTextActionModifiers: KeyModifiers.Alt);
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));
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(hotkeys);
if (_options.UseGpu)
{

34
src/Avalonia.Themes.Fluent/Accents/SystemAccentColors.cs

@ -16,18 +16,12 @@ internal class SystemAccentColors : IResourceProvider
public const string AccentLight2Key = "SystemAccentColorLight2";
public const string AccentLight3Key = "SystemAccentColorLight3";
private static readonly Color s_defaultSystemAccentColor = Color.FromRgb(0, 120, 215);
private readonly IPlatformSettings? _platformSettings;
private static readonly Color s_defaultSystemAccentColor = Color.FromRgb(0, 120, 215);
private bool _invalidateColors = true;
private Color _systemAccentColor;
private Color _systemAccentColorDark1, _systemAccentColorDark2, _systemAccentColorDark3;
private Color _systemAccentColorLight1, _systemAccentColorLight2, _systemAccentColorLight3;
public SystemAccentColors()
{
_platformSettings = AvaloniaLocator.Current.GetService<IPlatformSettings>();
}
public bool HasResources => true;
public bool TryGetResource(object key, ThemeVariant? theme, out object? value)
{
@ -96,10 +90,12 @@ internal class SystemAccentColors : IResourceProvider
Owner = owner;
OwnerChanged?.Invoke(this, EventArgs.Empty);
if (_platformSettings is not null)
if (GetFromOwner(owner) is { } platformSettings)
{
_platformSettings.ColorValuesChanged += PlatformSettingsOnColorValuesChanged;
platformSettings.ColorValuesChanged += PlatformSettingsOnColorValuesChanged;
}
_invalidateColors = true;
}
}
@ -110,10 +106,12 @@ internal class SystemAccentColors : IResourceProvider
Owner = null;
OwnerChanged?.Invoke(this, EventArgs.Empty);
if (_platformSettings is not null)
if (GetFromOwner(owner) is { } platformSettings)
{
_platformSettings.ColorValuesChanged -= PlatformSettingsOnColorValuesChanged;
platformSettings.ColorValuesChanged -= PlatformSettingsOnColorValuesChanged;
}
_invalidateColors = true;
}
}
@ -122,13 +120,25 @@ internal class SystemAccentColors : IResourceProvider
if (_invalidateColors)
{
_invalidateColors = false;
var platformSettings = GetFromOwner(Owner);
_systemAccentColor = _platformSettings?.GetColorValues().AccentColor1 ?? s_defaultSystemAccentColor;
_systemAccentColor = platformSettings?.GetColorValues().AccentColor1 ?? s_defaultSystemAccentColor;
(_systemAccentColorDark1,_systemAccentColorDark2, _systemAccentColorDark3,
_systemAccentColorLight1, _systemAccentColorLight2, _systemAccentColorLight3) = CalculateAccentShades(_systemAccentColor);
}
}
private static IPlatformSettings? GetFromOwner(IResourceHost? owner)
{
return owner switch
{
Application app => app.PlatformSettings,
Visual visual => TopLevel.GetTopLevel(visual)?.PlatformSettings,
_ => null
};
}
public static (Color d1, Color d2, Color d3, Color l1, Color l2, Color l3) CalculateAccentShades(Color accentColor)
{
// dark1step = (hslAccent.L - SystemAccentColorDark1.L) * 255

82
tests/Avalonia.Base.UnitTests/Input/GesturesTests.cs

@ -24,13 +24,13 @@ namespace Avalonia.Base.UnitTests.Input
public void Tapped_Should_Follow_Pointer_Pressed_Released()
{
Border border = new Border();
var decorator = new Decorator
var root = new TestRoot
{
Child = border
};
var result = new List<string>();
AddHandlers(decorator, border, result, false);
AddHandlers(root, border, result, false);
_mouse.Click(border);
@ -41,13 +41,13 @@ namespace Avalonia.Base.UnitTests.Input
public void Tapped_Should_Be_Raised_Even_When_Pressed_Released_Handled()
{
Border border = new Border();
var decorator = new Decorator
var root = new TestRoot
{
Child = border
};
var result = new List<string>();
AddHandlers(decorator, border, result, true);
AddHandlers(root, border, result, true);
_mouse.Click(border);
@ -58,13 +58,13 @@ namespace Avalonia.Base.UnitTests.Input
public void Tapped_Should_Not_Be_Raised_For_Middle_Button()
{
Border border = new Border();
var decorator = new Decorator
var root = new TestRoot
{
Child = border
};
var raised = false;
decorator.AddHandler(Gestures.TappedEvent, (_, _) => raised = true);
root.AddHandler(Gestures.TappedEvent, (_, _) => raised = true);
_mouse.Click(border, MouseButton.Middle);
@ -75,13 +75,13 @@ namespace Avalonia.Base.UnitTests.Input
public void Tapped_Should_Not_Be_Raised_For_Right_Button()
{
Border border = new Border();
var decorator = new Decorator
var root = new TestRoot
{
Child = border
};
var raised = false;
decorator.AddHandler(Gestures.TappedEvent, (_, _) => raised = true);
root.AddHandler(Gestures.TappedEvent, (_, _) => raised = true);
_mouse.Click(border, MouseButton.Right);
@ -92,13 +92,13 @@ namespace Avalonia.Base.UnitTests.Input
public void RightTapped_Should_Be_Raised_For_Right_Button()
{
Border border = new Border();
var decorator = new Decorator
var root = new TestRoot
{
Child = border
};
var raised = false;
decorator.AddHandler(Gestures.RightTappedEvent, (_, _) => raised = true);
root.AddHandler(Gestures.RightTappedEvent, (_, _) => raised = true);
_mouse.Click(border, MouseButton.Right);
@ -109,13 +109,13 @@ namespace Avalonia.Base.UnitTests.Input
public void DoubleTapped_Should_Follow_Pointer_Pressed_Released_Pressed()
{
Border border = new Border();
var decorator = new Decorator
var root = new TestRoot
{
Child = border
};
var result = new List<string>();
AddHandlers(decorator, border, result, false);
AddHandlers(root, border, result, false);
_mouse.Click(border);
_mouse.Down(border, clickCount: 2);
@ -127,13 +127,13 @@ namespace Avalonia.Base.UnitTests.Input
public void DoubleTapped_Should_Be_Raised_Even_When_Pressed_Released_Handled()
{
Border border = new Border();
var decorator = new Decorator
var root = new TestRoot
{
Child = border
};
var result = new List<string>();
AddHandlers(decorator, border, result, true);
AddHandlers(root, border, result, true);
_mouse.Click(border);
_mouse.Down(border, clickCount: 2);
@ -145,13 +145,13 @@ namespace Avalonia.Base.UnitTests.Input
public void DoubleTapped_Should_Not_Be_Raised_For_Middle_Button()
{
Border border = new Border();
var decorator = new Decorator
var root = new TestRoot
{
Child = border
};
var raised = false;
decorator.AddHandler(Gestures.DoubleTappedEvent, (_, _) => raised = true);
root.AddHandler(Gestures.DoubleTappedEvent, (_, _) => raised = true);
_mouse.Click(border, MouseButton.Middle);
_mouse.Down(border, MouseButton.Middle, clickCount: 2);
@ -163,13 +163,13 @@ namespace Avalonia.Base.UnitTests.Input
public void DoubleTapped_Should_Not_Be_Raised_For_Right_Button()
{
Border border = new Border();
var decorator = new Decorator
var root = new TestRoot
{
Child = border
};
var raised = false;
decorator.AddHandler(Gestures.DoubleTappedEvent, (_, _) => raised = true);
root.AddHandler(Gestures.DoubleTappedEvent, (_, _) => raised = true);
_mouse.Click(border, MouseButton.Right);
_mouse.Down(border, MouseButton.Right, clickCount: 2);
@ -191,13 +191,13 @@ namespace Avalonia.Base.UnitTests.Input
Border border = new Border();
Gestures.SetIsHoldWithMouseEnabled(border, true);
var decorator = new Decorator
var root = new TestRoot
{
Child = border
};
HoldingState holding = HoldingState.Cancelled;
decorator.AddHandler(Gestures.HoldingEvent, (_, e) => holding = e.HoldingState);
root.AddHandler(Gestures.HoldingEvent, (_, e) => holding = e.HoldingState);
_mouse.Down(border);
Assert.False(holding != HoldingState.Cancelled);
@ -227,13 +227,13 @@ namespace Avalonia.Base.UnitTests.Input
Border border = new Border();
Gestures.SetIsHoldWithMouseEnabled(border, true);
var decorator = new Decorator
var root = new TestRoot
{
Child = border
};
var raised = false;
decorator.AddHandler(Gestures.HoldingEvent, (_, e) => raised = e.HoldingState == HoldingState.Started);
root.AddHandler(Gestures.HoldingEvent, (_, e) => raised = e.HoldingState == HoldingState.Started);
_mouse.Down(border);
Assert.False(raised);
@ -262,13 +262,13 @@ namespace Avalonia.Base.UnitTests.Input
Border border = new Border();
Gestures.SetIsHoldWithMouseEnabled(border, true);
var decorator = new Decorator
var root = new TestRoot
{
Child = border
};
var raised = false;
decorator.AddHandler(Gestures.HoldingEvent, (_, e) => raised = e.HoldingState == HoldingState.Completed);
root.AddHandler(Gestures.HoldingEvent, (_, e) => raised = e.HoldingState == HoldingState.Completed);
_mouse.Down(border);
Assert.False(raised);
@ -297,13 +297,13 @@ namespace Avalonia.Base.UnitTests.Input
Border border = new Border();
Gestures.SetIsHoldWithMouseEnabled(border, true);
var decorator = new Decorator
var root = new TestRoot
{
Child = border
};
var cancelled = false;
decorator.AddHandler(Gestures.HoldingEvent, (_, e) => cancelled = e.HoldingState == HoldingState.Cancelled);
root.AddHandler(Gestures.HoldingEvent, (_, e) => cancelled = e.HoldingState == HoldingState.Cancelled);
_mouse.Down(border);
Assert.False(cancelled);
@ -333,13 +333,13 @@ namespace Avalonia.Base.UnitTests.Input
Border border = new Border();
Gestures.SetIsHoldWithMouseEnabled(border, true);
var decorator = new Decorator
var root = new TestRoot()
{
Child = border
};
var cancelled = false;
decorator.AddHandler(Gestures.HoldingEvent, (_, e) => cancelled = e.HoldingState == HoldingState.Cancelled);
root.AddHandler(Gestures.HoldingEvent, (_, e) => cancelled = e.HoldingState == HoldingState.Cancelled);
_mouse.Down(border);
@ -369,13 +369,13 @@ namespace Avalonia.Base.UnitTests.Input
Border border = new Border();
Gestures.SetIsHoldWithMouseEnabled(border, true);
var decorator = new Decorator
var testRoot = new TestRoot
{
Child = border
};
var raised = false;
decorator.AddHandler(Gestures.HoldingEvent, (_, e) => raised = e.HoldingState == HoldingState.Completed);
testRoot.AddHandler(Gestures.HoldingEvent, (_, e) => raised = e.HoldingState == HoldingState.Completed);
var secondMouse = new MouseTestHelper();
@ -392,12 +392,12 @@ namespace Avalonia.Base.UnitTests.Input
}
private static void AddHandlers(
Decorator decorator,
TestRoot root,
Border border,
IList<string> result,
bool markHandled)
{
decorator.AddHandler(InputElement.PointerPressedEvent, (_, e) =>
root.AddHandler(InputElement.PointerPressedEvent, (_, e) =>
{
result.Add("dp");
@ -407,7 +407,7 @@ namespace Avalonia.Base.UnitTests.Input
}
});
decorator.AddHandler(InputElement.PointerReleasedEvent, (_, e) =>
root.AddHandler(InputElement.PointerReleasedEvent, (_, e) =>
{
result.Add("dr");
@ -420,8 +420,8 @@ namespace Avalonia.Base.UnitTests.Input
border.AddHandler(InputElement.PointerPressedEvent, (_, _) => result.Add("bp"));
border.AddHandler(InputElement.PointerReleasedEvent, (_, _) => result.Add("br"));
decorator.AddHandler(Gestures.TappedEvent, (_, _) => result.Add("dt"));
decorator.AddHandler(Gestures.DoubleTappedEvent, (_, _) => result.Add("ddt"));
root.AddHandler(Gestures.TappedEvent, (_, _) => result.Add("dt"));
root.AddHandler(Gestures.DoubleTappedEvent, (_, _) => result.Add("ddt"));
border.AddHandler(Gestures.TappedEvent, (_, _) => result.Add("bt"));
border.AddHandler(Gestures.DoubleTappedEvent, (_, _) => result.Add("bdt"));
}
@ -438,13 +438,13 @@ namespace Avalonia.Base.UnitTests.Input
Background = new SolidColorBrush(Colors.Red)
};
border.GestureRecognizers.Add(new PinchGestureRecognizer());
var decorator = new Decorator
var root = new TestRoot
{
Child = border
};
var raised = false;
decorator.AddHandler(Gestures.PinchEvent, (_, _) => raised = true);
root.AddHandler(Gestures.PinchEvent, (_, _) => raised = true);
var firstPoint = new Point(5, 5);
var secondPoint = new Point(10, 10);
@ -466,13 +466,13 @@ namespace Avalonia.Base.UnitTests.Input
Background = new SolidColorBrush(Colors.Red)
};
border.GestureRecognizers.Add(new PinchGestureRecognizer());
var decorator = new Decorator
var root = new TestRoot
{
Child = border
};
var raised = false;
decorator.AddHandler(Gestures.PinchEvent, (_, _) => raised = true);
root.AddHandler(Gestures.PinchEvent, (_, _) => raised = true);
var firstPoint = new Point(5, 5);
var secondPoint = new Point(10, 10);
@ -502,13 +502,13 @@ namespace Avalonia.Base.UnitTests.Input
CanVerticallyScroll = true,
ScrollStartDistance = 50
});
var decorator = new Decorator
var root = new TestRoot
{
Child = border
};
var raised = false;
decorator.AddHandler(Gestures.ScrollGestureEvent, (_, _) => raised = true);
root.AddHandler(Gestures.ScrollGestureEvent, (_, _) => raised = true);
var firstTouch = new TouchTestHelper();

76
tests/Avalonia.Controls.UnitTests/ButtonTests.cs

@ -3,9 +3,11 @@ using System.Windows.Input;
using Avalonia.Data;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Layout;
using Avalonia.Media;
using Avalonia.Platform;
using Avalonia.Rendering;
using Avalonia.Threading;
using Avalonia.UnitTests;
using Avalonia.VisualTree;
using Moq;
@ -14,7 +16,7 @@ using MouseButton = Avalonia.Input.MouseButton;
namespace Avalonia.Controls.UnitTests
{
public class ButtonTests
public class ButtonTests : ScopedTestBase
{
private MouseTestHelper _helper = new MouseTestHelper();
@ -139,11 +141,19 @@ namespace Avalonia.Controls.UnitTests
renderer.Setup(r => r.HitTest(It.IsAny<Point>(), It.IsAny<Visual>(), It.IsAny<Func<Visual, bool>>()))
.Returns<Point, Visual, Func<Visual, bool>>((p, r, f) =>
r.Bounds.Contains(p) ? new Visual[] { r } : new Visual[0]);
var target = new TestButton(renderer.Object)
using var _ = UnitTestApplication.Start(TestServices.StyledWindow);
var root = new Window() { HitTesterOverride = renderer.Object };
var target = new Button()
{
Bounds = new Rect(0, 0, 100, 100)
Width = 100,
Height = 100,
VerticalAlignment = VerticalAlignment.Top,
HorizontalAlignment = HorizontalAlignment.Left
};
root.Content = target;
root.Show();
bool clicked = false;
@ -165,16 +175,13 @@ namespace Avalonia.Controls.UnitTests
[Fact]
public void Button_Does_Not_Raise_Click_When_PointerReleased_Outside()
{
var renderer = new Mock<IHitTester>();
renderer.Setup(r => r.HitTest(It.IsAny<Point>(), It.IsAny<Visual>(), It.IsAny<Func<Visual, bool>>()))
.Returns<Point, Visual, Func<Visual, bool>>((p, r, f) =>
r.Bounds.Contains(p) ? new Visual[] { r } : new Visual[0]);
var target = new TestButton(renderer.Object)
var root = new TestRoot();
var target = new Button()
{
Bounds = new Rect(0, 0, 100, 100)
Width = 100,
Height = 100
};
root.Child = target;
bool clicked = false;
@ -203,12 +210,20 @@ namespace Avalonia.Controls.UnitTests
.Returns<Point, Visual, Func<Visual, bool>>((p, r, f) =>
r.Bounds.Contains(p.Transform(r.RenderTransform.Value.Invert())) ?
new Visual[] { r } : new Visual[0]);
var target = new TestButton(renderer.Object)
using var _ = UnitTestApplication.Start(TestServices.StyledWindow);
var root = new Window() { HitTesterOverride = renderer.Object };
var target = new Button()
{
Bounds = new Rect(0, 0, 100, 100),
Width = 100,
Height = 100,
VerticalAlignment = VerticalAlignment.Top,
HorizontalAlignment = HorizontalAlignment.Left,
RenderTransform = new TranslateTransform { X = 100, Y = 0 }
};
root.Content = target;
root.Show();
//actual bounds of button should be 100,0,100,100 x -> translated 100 pixels
//so mouse with x=150 coordinates should trigger click
@ -381,37 +396,6 @@ namespace Avalonia.Controls.UnitTests
return new KeyEventArgs { RoutedEvent = InputElement.KeyDownEvent, Key = key, Source = source };
}
private class TestButton : Button, IRenderRoot
{
public TestButton(IHitTester hit)
{
IsVisible = true;
HitTester = hit;
Renderer = new NullRenderer();
}
public new Rect Bounds
{
get => base.Bounds;
set => base.Bounds = value;
}
public Size ClientSize => throw new NotImplementedException();
public IRenderer Renderer { get; }
public IHitTester HitTester { get; }
public double RenderScaling => throw new NotImplementedException();
public IRenderTarget CreateRenderTarget() => throw new NotImplementedException();
public void Invalidate(Rect rect) => throw new NotImplementedException();
public Point PointToClient(PixelPoint p) => throw new NotImplementedException();
public PixelPoint PointToScreen(Point p) => throw new NotImplementedException();
}
private void RaisePointerPressed(Button button, int clickCount, MouseButton mouseButton, Point position)
{
_helper.Down(button, mouseButton, position, clickCount: clickCount);

24
tests/Avalonia.Controls.UnitTests/ListBoxTests_Multiple.cs

@ -34,7 +34,7 @@ namespace Avalonia.Controls.UnitTests
var root = new TestRoot(target);
root.LayoutManager.ExecuteInitialLayoutPass();
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new Mock<PlatformHotkeyConfiguration>().Object);
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new PlatformHotkeyConfiguration());
_helper.Click(target.Presenter.Panel.Children[2], modifiers: KeyModifiers.Shift);
Assert.Equal(new[] { "Foo", "Bar", "Baz" }, target.SelectedItems);
@ -60,7 +60,7 @@ namespace Avalonia.Controls.UnitTests
var root = new TestRoot(target);
root.LayoutManager.ExecuteInitialLayoutPass();
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new Mock<PlatformHotkeyConfiguration>().Object);
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new PlatformHotkeyConfiguration());
SelectionChangedEventArgs receivedArgs = null;
@ -118,7 +118,7 @@ namespace Avalonia.Controls.UnitTests
var root = new TestRoot(target);
root.LayoutManager.ExecuteInitialLayoutPass();
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new Mock<PlatformHotkeyConfiguration>().Object);
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new PlatformHotkeyConfiguration());
_helper.Click(target.Presenter.Panel.Children[1]);
_helper.Click(target.Presenter.Panel.Children[2], modifiers: KeyModifiers.Control);
_helper.Click(target.Presenter.Panel.Children[3], modifiers: KeyModifiers.Control);
@ -152,7 +152,7 @@ namespace Avalonia.Controls.UnitTests
var root = new TestRoot(target);
root.LayoutManager.ExecuteInitialLayoutPass();
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new Mock<PlatformHotkeyConfiguration>().Object);
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new PlatformHotkeyConfiguration());
_helper.Click(target.Presenter.Panel.Children[1]);
_helper.Click(target.Presenter.Panel.Children[2], modifiers: KeyModifiers.Control);
@ -183,7 +183,7 @@ namespace Avalonia.Controls.UnitTests
var root = new TestRoot(target);
root.LayoutManager.ExecuteInitialLayoutPass();
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new Mock<PlatformHotkeyConfiguration>().Object);
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new PlatformHotkeyConfiguration());
_helper.Click(target.Presenter.Panel.Children[3]);
_helper.Click(target.Presenter.Panel.Children[4], modifiers: KeyModifiers.Control);
@ -211,7 +211,7 @@ namespace Avalonia.Controls.UnitTests
var root = new TestRoot(target);
root.LayoutManager.ExecuteInitialLayoutPass();
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new Mock<PlatformHotkeyConfiguration>().Object);
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new PlatformHotkeyConfiguration());
_helper.Click(target.Presenter.Panel.Children[3]);
_helper.Click(target.Presenter.Panel.Children[5], modifiers: KeyModifiers.Shift);
@ -239,7 +239,7 @@ namespace Avalonia.Controls.UnitTests
var root = new TestRoot(target);
root.LayoutManager.ExecuteInitialLayoutPass();
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new Mock<PlatformHotkeyConfiguration>().Object);
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new PlatformHotkeyConfiguration());
_helper.Click(target.Presenter.Panel.Children[0]);
_helper.Click(target.Presenter.Panel.Children[5], modifiers: KeyModifiers.Shift);
@ -266,7 +266,7 @@ namespace Avalonia.Controls.UnitTests
var root = new TestRoot(target);
root.LayoutManager.ExecuteInitialLayoutPass();
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new Mock<PlatformHotkeyConfiguration>().Object);
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new PlatformHotkeyConfiguration());
SelectionChangedEventArgs receivedArgs = null;
@ -319,7 +319,7 @@ namespace Avalonia.Controls.UnitTests
var root = new TestRoot(target);
root.LayoutManager.ExecuteInitialLayoutPass();
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new Mock<PlatformHotkeyConfiguration>().Object);
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new PlatformHotkeyConfiguration());
_helper.Click(target.Presenter.Panel.Children[0]);
Assert.Equal(new[] { "Foo" }, target.SelectedItems);
@ -414,7 +414,7 @@ namespace Avalonia.Controls.UnitTests
var root = new TestRoot(target);
root.LayoutManager.ExecuteInitialLayoutPass();
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new Mock<PlatformHotkeyConfiguration>().Object);
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new PlatformHotkeyConfiguration());
_helper.Click(target.Presenter.Panel.Children[0]);
_helper.Click(target.Presenter.Panel.Children[1], modifiers: KeyModifiers.Shift);
@ -444,7 +444,7 @@ namespace Avalonia.Controls.UnitTests
var root = new TestRoot(target);
root.LayoutManager.ExecuteInitialLayoutPass();
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new Mock<PlatformHotkeyConfiguration>().Object);
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new PlatformHotkeyConfiguration());
_helper.Click(target.Presenter.Panel.Children[0]);
_helper.Click(target.Presenter.Panel.Children[2], MouseButton.Right, modifiers: KeyModifiers.Shift);
@ -471,7 +471,7 @@ namespace Avalonia.Controls.UnitTests
var root = new TestRoot(target);
root.LayoutManager.ExecuteInitialLayoutPass();
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new Mock<PlatformHotkeyConfiguration>().Object);
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new PlatformHotkeyConfiguration());
_helper.Click(target.Presenter.Panel.Children[0]);
_helper.Click(target.Presenter.Panel.Children[2], MouseButton.Right, modifiers: KeyModifiers.Control);

14
tests/Avalonia.Controls.UnitTests/ListBoxTests_Single.cs

@ -49,7 +49,7 @@ namespace Avalonia.Controls.UnitTests
Template = new FuncControlTemplate(CreateListBoxTemplate),
ItemsSource = new[] { "Foo", "Bar", "Baz " },
};
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new Mock<PlatformHotkeyConfiguration>().Object);
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new PlatformHotkeyConfiguration());
ApplyTemplate(target);
target.Presenter.Panel.Children[0].RaiseEvent(new GotFocusEventArgs
@ -79,7 +79,7 @@ namespace Avalonia.Controls.UnitTests
Template = new FuncControlTemplate(CreateListBoxTemplate),
ItemsSource = new[] { "Foo", "Bar", "Baz " },
};
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new Mock<PlatformHotkeyConfiguration>().Object);
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new PlatformHotkeyConfiguration());
ApplyTemplate(target);
_mouse.Click(target.Presenter.Panel.Children[0]);
@ -97,7 +97,7 @@ namespace Avalonia.Controls.UnitTests
Template = new FuncControlTemplate(CreateListBoxTemplate),
ItemsSource = new[] { "Foo", "Bar", "Baz " },
};
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new Mock<PlatformHotkeyConfiguration>().Object);
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new PlatformHotkeyConfiguration());
ApplyTemplate(target);
target.SelectedIndex = 0;
@ -118,7 +118,7 @@ namespace Avalonia.Controls.UnitTests
ItemsSource = new[] { "Foo", "Bar", "Baz " },
SelectionMode = SelectionMode.Single | SelectionMode.Toggle,
};
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new Mock<PlatformHotkeyConfiguration>().Object);
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new PlatformHotkeyConfiguration());
ApplyTemplate(target);
_mouse.Click(target.Presenter.Panel.Children[0]);
@ -139,7 +139,7 @@ namespace Avalonia.Controls.UnitTests
SelectionMode = SelectionMode.Toggle,
};
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new Mock<PlatformHotkeyConfiguration>().Object);
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new PlatformHotkeyConfiguration());
ApplyTemplate(target);
target.SelectedIndex = 0;
@ -160,7 +160,7 @@ namespace Avalonia.Controls.UnitTests
ItemsSource = new[] { "Foo", "Bar", "Baz " },
SelectionMode = SelectionMode.Toggle | SelectionMode.AlwaysSelected,
};
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new Mock<PlatformHotkeyConfiguration>().Object);
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new PlatformHotkeyConfiguration());
ApplyTemplate(target);
target.SelectedIndex = 0;
@ -181,7 +181,7 @@ namespace Avalonia.Controls.UnitTests
ItemsSource = new[] { "Foo", "Bar", "Baz " },
SelectionMode = SelectionMode.Single | SelectionMode.Toggle,
};
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new Mock<PlatformHotkeyConfiguration>().Object);
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new PlatformHotkeyConfiguration());
ApplyTemplate(target);
target.SelectedIndex = 1;

8
tests/Avalonia.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs

@ -1234,7 +1234,7 @@ namespace Avalonia.Controls.UnitTests.Primitives
Template = Template(),
ItemsSource = new[] { "Foo", "Bar", "Baz " },
};
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new Mock<PlatformHotkeyConfiguration>().Object);
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new PlatformHotkeyConfiguration());
Prepare(target);
var container = target.ContainerFromIndex(1)!;
@ -1258,7 +1258,7 @@ namespace Avalonia.Controls.UnitTests.Primitives
Template = Template(),
ItemsSource = items,
};
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new Mock<PlatformHotkeyConfiguration>().Object);
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new PlatformHotkeyConfiguration());
Prepare(target);
_helper.Down(target.Presenter.Panel.Children[1]);
@ -1355,7 +1355,7 @@ namespace Avalonia.Controls.UnitTests.Primitives
Template = Template(),
ItemsSource = new[] { "Foo", "Bar", "Baz", "Foo", "Bar", "Baz" },
};
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new Mock<PlatformHotkeyConfiguration>().Object);
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new PlatformHotkeyConfiguration());
Prepare(target);
_helper.Down((Interactive)target.Presenter.Panel.Children[3]);
@ -1373,7 +1373,7 @@ namespace Avalonia.Controls.UnitTests.Primitives
Template = Template(),
ItemsSource = new[] { "Foo", "Bar", "Baz", "Foo", "Bar", "Baz" },
};
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new Mock<PlatformHotkeyConfiguration>().Object);
AvaloniaLocator.CurrentMutable.Bind<PlatformHotkeyConfiguration>().ToConstant(new PlatformHotkeyConfiguration());
Prepare(target);
_helper.Down((Interactive)target.Presenter.Panel.Children[3]);

6
tests/Avalonia.Controls.UnitTests/TreeViewTests.cs

@ -1045,7 +1045,7 @@ namespace Avalonia.Controls.UnitTests
var data = CreateTestTreeData();
var target = CreateTarget(data: data, multiSelect: true);
var rootNode = data[0];
var keymap = AvaloniaLocator.Current.GetRequiredService<PlatformHotkeyConfiguration>();
var keymap = Application.Current!.PlatformSettings!.HotkeyConfiguration;
var selectAllGesture = keymap.SelectAll.First();
var keyEvent = new KeyEventArgs
@ -1075,7 +1075,7 @@ namespace Avalonia.Controls.UnitTests
ClickContainer(fromContainer, KeyModifiers.None);
ClickContainer(toContainer, KeyModifiers.Shift);
var keymap = AvaloniaLocator.Current.GetRequiredService<PlatformHotkeyConfiguration>();
var keymap = Application.Current!.PlatformSettings!.HotkeyConfiguration;
var selectAllGesture = keymap.SelectAll.First();
var keyEvent = new KeyEventArgs
@ -1105,7 +1105,7 @@ namespace Avalonia.Controls.UnitTests
ClickContainer(fromContainer, KeyModifiers.None);
ClickContainer(toContainer, KeyModifiers.Shift);
var keymap = AvaloniaLocator.Current.GetRequiredService<PlatformHotkeyConfiguration>();
var keymap = Application.Current!.PlatformSettings!.HotkeyConfiguration;
var selectAllGesture = keymap.SelectAll.First();
var keyEvent = new KeyEventArgs

1
tests/Avalonia.UnitTests/TestRoot.cs

@ -67,6 +67,7 @@ namespace Avalonia.UnitTests
public IKeyboardNavigationHandler KeyboardNavigationHandler => null;
public IFocusManager FocusManager => AvaloniaLocator.Current.GetService<IFocusManager>();
public IPlatformSettings PlatformSettings => AvaloniaLocator.Current.GetService<IPlatformSettings>();
public IInputElement PointerOverElement { get; set; }

3
tests/Avalonia.UnitTests/UnitTestApplication.cs

@ -77,7 +77,8 @@ namespace Avalonia.UnitTests
.Bind<IDispatcherImpl>().ToConstant(Services.DispatcherImpl)
.Bind<ICursorFactory>().ToConstant(Services.StandardCursorFactory)
.Bind<IWindowingPlatform>().ToConstant(Services.WindowingPlatform)
.Bind<PlatformHotkeyConfiguration>().ToSingleton<PlatformHotkeyConfiguration>();
.Bind<PlatformHotkeyConfiguration>().ToSingleton<PlatformHotkeyConfiguration>()
.Bind<IPlatformSettings>().ToSingleton<DefaultPlatformSettings>();
// This is a hack to make tests work, we need to refactor the way font manager is registered
// See https://github.com/AvaloniaUI/Avalonia/issues/10081

Loading…
Cancel
Save