Browse Source

Merge branch 'master' into use-esbuild

pull/8934/head
Dan Walmsley 4 years ago
committed by GitHub
parent
commit
c1605c68bc
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      src/Avalonia.Base/Data/Core/Plugins/ObservableStreamPlugin.cs
  2. 2
      src/Avalonia.Base/Input/GestureRecognizers/ScrollGestureRecognizer.cs
  3. 1
      src/Avalonia.Base/Input/PointerEventArgs.cs
  4. 17
      src/Avalonia.Base/Input/PointerOverPreProcessor.cs
  5. 2
      src/Avalonia.Base/Layout/FlowLayoutAlgorithm.cs
  6. 10
      src/Avalonia.Base/Media/TextTrimming.cs
  7. 2
      src/Avalonia.Base/Media/UnicodeRange.cs
  8. 2
      src/Avalonia.Base/Utilities/IWeakSubscriber.cs
  9. 2
      src/Avalonia.Controls/Window.cs
  10. 2
      src/Avalonia.MicroCom/MicroComProxyBase.cs
  11. 6
      src/Linux/Avalonia.LinuxFramebuffer/Input/LibInput/LibInputBackend.cs
  12. 16
      src/Linux/Avalonia.LinuxFramebuffer/Input/NullInput/NullInputBackend.cs
  13. 40
      src/Linux/Avalonia.LinuxFramebuffer/LinuxFramebufferPlatform.cs
  14. 4
      src/tools/DevGenerators/CompositionGenerator/Generator.cs
  15. 58
      tests/Avalonia.Base.UnitTests/Input/PointerOverTests.cs
  16. 2
      tests/Avalonia.Base.UnitTests/Input/PointerTests.cs
  17. 2
      tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextFormatterTests.cs

2
src/Avalonia.Base/Data/Core/Plugins/ObservableStreamPlugin.cs

@ -42,7 +42,7 @@ namespace Avalonia.Data.Core.Plugins
if (target is IObservable<object?> result) if (target is IObservable<object?> result)
{ {
return result; return result;
}; }
// If the observable returns a value type then we need to call Observable.Select on it. // If the observable returns a value type then we need to call Observable.Select on it.
// First get the type of T in `IObservable<T>`. // First get the type of T in `IObservable<T>`.

2
src/Avalonia.Base/Input/GestureRecognizers/ScrollGestureRecognizer.cs

@ -71,7 +71,7 @@ namespace Avalonia.Input.GestureRecognizers
{ {
EndGesture(); EndGesture();
_tracking = e.Pointer; _tracking = e.Pointer;
_gestureId = ScrollGestureEventArgs.GetNextFreeId();; _gestureId = ScrollGestureEventArgs.GetNextFreeId();
_trackedRootPoint = e.GetPosition(_target); _trackedRootPoint = e.GetPosition(_target);
} }
} }

1
src/Avalonia.Base/Input/PointerEventArgs.cs

@ -65,6 +65,7 @@ namespace Avalonia.Input
return default; return default;
if (relativeTo == null) if (relativeTo == null)
return pt; return pt;
return pt * _rootVisual.TransformToVisual(relativeTo) ?? default; return pt * _rootVisual.TransformToVisual(relativeTo) ?? default;
} }

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

@ -68,27 +68,29 @@ namespace Avalonia.Input
if (dirtyRect.Contains(clientPoint)) if (dirtyRect.Contains(clientPoint))
{ {
SetPointerOver(pointer, _inputRoot, _inputRoot.InputHitTest(clientPoint), 0, clientPoint, PointerPointProperties.None, KeyModifiers.None); var element = pointer.Captured ?? _inputRoot.InputHitTest(clientPoint);
SetPointerOver(pointer, _inputRoot, element, 0, clientPoint, PointerPointProperties.None, KeyModifiers.None);
} }
else if (!_inputRoot.Bounds.Contains(clientPoint)) else if (!_inputRoot.Bounds.Contains(clientPoint))
{ {
ClearPointerOver(pointer, _inputRoot, 0, new Point(-1, -1), PointerPointProperties.None, KeyModifiers.None); ClearPointerOver(pointer, _inputRoot, 0, clientPoint, PointerPointProperties.None, KeyModifiers.None);
} }
} }
} }
private void ClearPointerOver() private void ClearPointerOver()
{ {
if (_lastPointer is (var pointer, var _)) if (_lastPointer is (var pointer, var position))
{ {
ClearPointerOver(pointer, _inputRoot, 0, new Point(-1, -1), PointerPointProperties.None, KeyModifiers.None); var clientPoint = _inputRoot.PointToClient(position);
ClearPointerOver(pointer, _inputRoot, 0, clientPoint, PointerPointProperties.None, KeyModifiers.None);
} }
_lastPointer = null; _lastPointer = null;
_lastActivePointerDevice = null; _lastActivePointerDevice = null;
} }
private void ClearPointerOver(IPointer pointer, IInputRoot root, private void ClearPointerOver(IPointer pointer, IInputRoot root,
ulong timestamp, Point position, PointerPointProperties properties, KeyModifiers inputModifiers) ulong timestamp, Point? position, PointerPointProperties properties, KeyModifiers inputModifiers)
{ {
var element = root.PointerOverElement; var element = root.PointerOverElement;
if (element is null) if (element is null)
@ -96,11 +98,10 @@ namespace Avalonia.Input
return; return;
} }
// Do not pass rootVisual, when we have unknown (negative) position, // Do not pass rootVisual, when we have unknown position,
// so GetPosition won't return invalid values. // so GetPosition won't return invalid values.
var hasPosition = position.X >= 0 && position.Y >= 0;
var e = new PointerEventArgs(InputElement.PointerExitedEvent, element, pointer, var e = new PointerEventArgs(InputElement.PointerExitedEvent, element, pointer,
hasPosition ? root : null, hasPosition ? position : default, position.HasValue ? root : null, position.HasValue ? position.Value : default,
timestamp, properties, inputModifiers); timestamp, properties, inputModifiers);
if (element != null && !element.IsAttachedToVisualTree) if (element != null && !element.IsAttachedToVisualTree)

2
src/Avalonia.Base/Layout/FlowLayoutAlgorithm.cs

@ -523,7 +523,7 @@ namespace Avalonia.Layout
{ {
firstRealizedElement = _elementManager.GetAt(0); firstRealizedElement = _elementManager.GetAt(0);
firstBounds = _elementManager.GetLayoutBoundsForRealizedIndex(0); firstBounds = _elementManager.GetLayoutBoundsForRealizedIndex(0);
firstDataIndex = _elementManager.GetDataIndexFromRealizedRangeIndex(0);; firstDataIndex = _elementManager.GetDataIndexFromRealizedRangeIndex(0);
int last = _elementManager.GetRealizedElementCount() - 1; int last = _elementManager.GetRealizedElementCount() - 1;
lastRealizedElement = _elementManager.GetAt(last); lastRealizedElement = _elementManager.GetAt(last);

10
src/Avalonia.Base/Media/TextTrimming.cs

@ -8,7 +8,7 @@ namespace Avalonia.Media
/// </summary> /// </summary>
public abstract class TextTrimming public abstract class TextTrimming
{ {
public static char s_defaultEllipsisChar = '\u2026'; internal const char DefaultEllipsisChar = '\u2026';
/// <summary> /// <summary>
/// Text is not trimmed. /// Text is not trimmed.
@ -18,22 +18,22 @@ namespace Avalonia.Media
/// <summary> /// <summary>
/// Text is trimmed at a character boundary. An ellipsis (...) is drawn in place of remaining text. /// Text is trimmed at a character boundary. An ellipsis (...) is drawn in place of remaining text.
/// </summary> /// </summary>
public static TextTrimming CharacterEllipsis { get; } = new TextTrailingTrimming(s_defaultEllipsisChar, false); public static TextTrimming CharacterEllipsis { get; } = new TextTrailingTrimming(DefaultEllipsisChar, false);
/// <summary> /// <summary>
/// Text is trimmed at a word boundary. An ellipsis (...) is drawn in place of remaining text. /// Text is trimmed at a word boundary. An ellipsis (...) is drawn in place of remaining text.
/// </summary> /// </summary>
public static TextTrimming WordEllipsis { get; } = new TextTrailingTrimming(s_defaultEllipsisChar, true); public static TextTrimming WordEllipsis { get; } = new TextTrailingTrimming(DefaultEllipsisChar, true);
/// <summary> /// <summary>
/// Text is trimmed after a given prefix length. An ellipsis (...) is drawn in between prefix and suffix and represents remaining text. /// Text is trimmed after a given prefix length. An ellipsis (...) is drawn in between prefix and suffix and represents remaining text.
/// </summary> /// </summary>
public static TextTrimming PrefixCharacterEllipsis { get; } = new TextLeadingPrefixTrimming(s_defaultEllipsisChar, 8); public static TextTrimming PrefixCharacterEllipsis { get; } = new TextLeadingPrefixTrimming(DefaultEllipsisChar, 8);
/// <summary> /// <summary>
/// Text is trimmed at a character boundary starting from the beginning. An ellipsis (...) is drawn in place of remaining text. /// Text is trimmed at a character boundary starting from the beginning. An ellipsis (...) is drawn in place of remaining text.
/// </summary> /// </summary>
public static TextTrimming LeadingCharacterEllipsis { get; } = new TextLeadingPrefixTrimming(s_defaultEllipsisChar, 0); public static TextTrimming LeadingCharacterEllipsis { get; } = new TextLeadingPrefixTrimming(DefaultEllipsisChar, 0);
/// <summary> /// <summary>
/// Creates properties that will be used for collapsing lines of text. /// Creates properties that will be used for collapsing lines of text.

2
src/Avalonia.Base/Media/UnicodeRange.cs

@ -9,7 +9,7 @@ namespace Avalonia.Media
/// </summary> /// </summary>
public readonly struct UnicodeRange public readonly struct UnicodeRange
{ {
public static UnicodeRange Default = Parse("0-10FFFD"); public readonly static UnicodeRange Default = Parse("0-10FFFD");
private readonly UnicodeRangeSegment _single; private readonly UnicodeRangeSegment _single;
private readonly IReadOnlyList<UnicodeRangeSegment>? _segments = null; private readonly IReadOnlyList<UnicodeRangeSegment>? _segments = null;

2
src/Avalonia.Base/Utilities/IWeakSubscriber.cs

@ -3,7 +3,7 @@ using System;
namespace Avalonia.Utilities namespace Avalonia.Utilities
{ {
/// <summary> /// <summary>
/// Defines a listener to a event subscribed vis the <see cref="WeakSubscriptionManager"/>. /// Defines a listener to a event subscribed vis the <see cref="WeakObservable"/>.
/// </summary> /// </summary>
/// <typeparam name="T">The type of the event arguments.</typeparam> /// <typeparam name="T">The type of the event arguments.</typeparam>
public interface IWeakSubscriber<T> where T : EventArgs public interface IWeakSubscriber<T> where T : EventArgs

2
src/Avalonia.Controls/Window.cs

@ -378,8 +378,6 @@ namespace Avalonia.Controls
/// <summary> /// <summary>
/// Enables or disables resizing of the window. /// Enables or disables resizing of the window.
/// Note that if <see cref="HasSystemDecorations"/> is set to False then this property
/// has no effect and should be treated as a recommendation for the user setting HasSystemDecorations.
/// </summary> /// </summary>
public bool CanResize public bool CanResize
{ {

2
src/Avalonia.MicroCom/MicroComProxyBase.cs

@ -65,7 +65,7 @@ namespace Avalonia.MicroCom
protected virtual void Dispose(bool disposing) protected virtual void Dispose(bool disposing)
{ {
if(_nativePointer == null) if(_nativePointer == IntPtr.Zero)
return; return;
if (_ownsHandle) if (_ownsHandle)
{ {

6
src/Linux/Avalonia.LinuxFramebuffer/Input/LibInput/LibInputBackend.cs

@ -1,11 +1,9 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.IO; using System.IO;
using System.Threading; using System.Threading;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Input.Raw; using Avalonia.Input.Raw;
using Avalonia.Threading;
using static Avalonia.LinuxFramebuffer.Input.LibInput.LibInputNativeUnsafeMethods; using static Avalonia.LinuxFramebuffer.Input.LibInput.LibInputNativeUnsafeMethods;
namespace Avalonia.LinuxFramebuffer.Input.LibInput namespace Avalonia.LinuxFramebuffer.Input.LibInput
{ {
@ -29,8 +27,6 @@ namespace Avalonia.LinuxFramebuffer.Input.LibInput
new Thread(()=>InputThread(ctx)).Start(); new Thread(()=>InputThread(ctx)).Start();
} }
private unsafe void InputThread(IntPtr ctx) private unsafe void InputThread(IntPtr ctx)
{ {
var fd = libinput_get_fd(ctx); var fd = libinput_get_fd(ctx);
@ -143,8 +139,6 @@ namespace Avalonia.LinuxFramebuffer.Input.LibInput
} }
} }
public void Initialize(IScreenInfoProvider screen, Action<RawInputEventArgs> onInput) public void Initialize(IScreenInfoProvider screen, Action<RawInputEventArgs> onInput)
{ {

16
src/Linux/Avalonia.LinuxFramebuffer/Input/NullInput/NullInputBackend.cs

@ -0,0 +1,16 @@
using System;
using Avalonia.Input;
using Avalonia.Input.Raw;
namespace Avalonia.LinuxFramebuffer.Input.NullInput;
public class NullInputBackend : IInputBackend
{
public void Initialize(IScreenInfoProvider screen, Action<RawInputEventArgs> onInput)
{
}
public void SetInputRoot(IInputRoot root)
{
}
}

40
src/Linux/Avalonia.LinuxFramebuffer/LinuxFramebufferPlatform.cs

@ -42,9 +42,9 @@ namespace Avalonia.LinuxFramebuffer
Threading = new InternalPlatformThreadingInterface(); Threading = new InternalPlatformThreadingInterface();
if (_fb is IGlOutputBackend gl) if (_fb is IGlOutputBackend gl)
AvaloniaLocator.CurrentMutable.Bind<IPlatformOpenGlInterface>().ToConstant(gl.PlatformOpenGlInterface); AvaloniaLocator.CurrentMutable.Bind<IPlatformOpenGlInterface>().ToConstant(gl.PlatformOpenGlInterface);
var opts = AvaloniaLocator.Current.GetService<LinuxFramebufferPlatformOptions>() ?? new LinuxFramebufferPlatformOptions(); var opts = AvaloniaLocator.Current.GetService<LinuxFramebufferPlatformOptions>() ?? new LinuxFramebufferPlatformOptions();
AvaloniaLocator.CurrentMutable AvaloniaLocator.CurrentMutable
.Bind<IPlatformThreadingInterface>().ToConstant(Threading) .Bind<IPlatformThreadingInterface>().ToConstant(Threading)
.Bind<IRenderTimer>().ToConstant(new DefaultRenderTimer(opts.Fps)) .Bind<IRenderTimer>().ToConstant(new DefaultRenderTimer(opts.Fps))
@ -59,12 +59,12 @@ namespace Avalonia.LinuxFramebuffer
AvaloniaLocator.Current.GetService<IPlatformOpenGlInterface>()); AvaloniaLocator.Current.GetService<IPlatformOpenGlInterface>());
} }
internal static LinuxFramebufferLifetime Initialize<T>(T builder, IOutputBackend outputBackend) where T : AppBuilderBase<T>, new() internal static LinuxFramebufferLifetime Initialize<T>(T builder, IOutputBackend outputBackend, IInputBackend inputBackend) where T : AppBuilderBase<T>, new()
{ {
var platform = new LinuxFramebufferPlatform(outputBackend); var platform = new LinuxFramebufferPlatform(outputBackend);
builder.UseSkia().UseWindowingSubsystem(platform.Initialize, "fbdev"); builder.UseSkia().UseWindowingSubsystem(platform.Initialize, "fbdev");
return new LinuxFramebufferLifetime(platform._fb); return new LinuxFramebufferLifetime(platform._fb, inputBackend);
} }
} }
@ -80,13 +80,13 @@ namespace Avalonia.LinuxFramebuffer
{ {
_fb = fb; _fb = fb;
} }
public LinuxFramebufferLifetime(IOutputBackend fb, IInputBackend input) public LinuxFramebufferLifetime(IOutputBackend fb, IInputBackend input)
{ {
_fb = fb; _fb = fb;
_inputBackend = input; _inputBackend = input;
} }
public Control MainView public Control MainView
{ {
get => (Control)_topLevel?.Content; get => (Control)_topLevel?.Content;
@ -126,7 +126,7 @@ namespace Avalonia.LinuxFramebuffer
{ {
Startup?.Invoke(this, new ControlledApplicationLifetimeStartupEventArgs(args)); Startup?.Invoke(this, new ControlledApplicationLifetimeStartupEventArgs(args));
} }
public void Shutdown(int exitCode) public void Shutdown(int exitCode)
{ {
ExitCode = exitCode; ExitCode = exitCode;
@ -140,22 +140,22 @@ namespace Avalonia.LinuxFramebuffer
public static class LinuxFramebufferPlatformExtensions public static class LinuxFramebufferPlatformExtensions
{ {
public static int StartLinuxFbDev<T>(this T builder, string[] args, string fbdev = null, double scaling = 1) public static int StartLinuxFbDev<T>(this T builder, string[] args, string fbdev = null, double scaling = 1, IInputBackend inputBackend = default)
where T : AppBuilderBase<T>, new() => where T : AppBuilderBase<T>, new() =>
StartLinuxDirect(builder, args, new FbdevOutput(fileName: fbdev, format: null) { Scaling = scaling }); StartLinuxDirect(builder, args, new FbdevOutput(fileName: fbdev, format: null) { Scaling = scaling }, inputBackend);
public static int StartLinuxFbDev<T>(this T builder, string[] args, string fbdev, PixelFormat? format, double scaling) public static int StartLinuxFbDev<T>(this T builder, string[] args, string fbdev, PixelFormat? format, double scaling, IInputBackend inputBackend = default)
where T : AppBuilderBase<T>, new() => where T : AppBuilderBase<T>, new() =>
StartLinuxDirect(builder, args, new FbdevOutput(fileName: fbdev, format: format) { Scaling = scaling }); StartLinuxDirect(builder, args, new FbdevOutput(fileName: fbdev, format: format) { Scaling = scaling }, inputBackend);
public static int StartLinuxDrm<T>(this T builder, string[] args, string card = null, double scaling = 1) public static int StartLinuxDrm<T>(this T builder, string[] args, string card = null, double scaling = 1, IInputBackend inputBackend = default)
where T : AppBuilderBase<T>, new() => StartLinuxDirect(builder, args, new DrmOutput(card) {Scaling = scaling}); where T : AppBuilderBase<T>, new() => StartLinuxDirect(builder, args, new DrmOutput(card) { Scaling = scaling }, inputBackend);
public static int StartLinuxDrm<T>(this T builder, string[] args, string card = null, bool connectorsForceProbe = false, [CanBeNull] DrmOutputOptions options = null) public static int StartLinuxDrm<T>(this T builder, string[] args, string card = null, bool connectorsForceProbe = false, [CanBeNull] DrmOutputOptions options = null, IInputBackend inputBackend = default)
where T : AppBuilderBase<T>, new() => StartLinuxDirect(builder, args, new DrmOutput(card, connectorsForceProbe, options)); where T : AppBuilderBase<T>, new() => StartLinuxDirect(builder, args, new DrmOutput(card, connectorsForceProbe, options), inputBackend);
public static int StartLinuxDirect<T>(this T builder, string[] args, IOutputBackend backend) public static int StartLinuxDirect<T>(this T builder, string[] args, IOutputBackend outputBackend, IInputBackend inputBackend = default)
where T : AppBuilderBase<T>, new() where T : AppBuilderBase<T>, new()
{ {
var lifetime = LinuxFramebufferPlatform.Initialize(builder, backend); var lifetime = LinuxFramebufferPlatform.Initialize(builder, outputBackend, inputBackend);
builder.SetupWithLifetime(lifetime); builder.SetupWithLifetime(lifetime);
lifetime.Start(args); lifetime.Start(args);
builder.Instance.Run(lifetime.Token); builder.Instance.Run(lifetime.Token);

4
src/tools/DevGenerators/CompositionGenerator/Generator.cs

@ -133,10 +133,6 @@ namespace Avalonia.SourceGenerator.CompositionGenerator
MethodDeclaration(ParseTypeName("void"), "Initialize") MethodDeclaration(ParseTypeName("void"), "Initialize")
.AddModifiers(SyntaxKind.PartialKeyword).WithSemicolonToken(Semicolon())); .AddModifiers(SyntaxKind.PartialKeyword).WithSemicolonToken(Semicolon()));
var changesVarName = "c";
var changesVar = IdentifierName(changesVarName);
server = server.AddMembers( server = server.AddMembers(
MethodDeclaration(ParseTypeName("void"), "DeserializeChangesExtra") MethodDeclaration(ParseTypeName("void"), "DeserializeChangesExtra")
.AddParameterListParameters(Parameter(Identifier("c")).WithType(ParseTypeName("BatchStreamReader"))) .AddParameterListParameters(Parameter(Identifier("c")).WithType(ParseTypeName("BatchStreamReader")))

58
tests/Avalonia.Base.UnitTests/Input/PointerOverTests.cs

@ -356,20 +356,28 @@ namespace Avalonia.Base.UnitTests.Input
var impl = CreateTopLevelImplMock(renderer.Object); var impl = CreateTopLevelImplMock(renderer.Object);
var invalidateRect = new Rect(0, 0, 15, 15); var invalidateRect = new Rect(0, 0, 15, 15);
var lastClientPosition = new Point(1, 5);
var result = new List<(object?, string, Point)>();
void HandleEvent(object? sender, PointerEventArgs e)
{
result.Add((sender, e.RoutedEvent!.Name, e.GetPosition(null)));
}
Canvas canvas; Canvas canvas;
var root = CreateInputRoot(impl.Object, new Panel var root = (Window)CreateInputRoot(impl.Object, new Panel
{ {
Children = Children =
{ {
(canvas = new Canvas()) (canvas = new Canvas())
} }
}); });
AddEnteredExitedHandlers(HandleEvent, root, canvas);
// Let input know about latest device. // Let input know about latest device.
SetHit(renderer, canvas); SetHit(renderer, canvas);
impl.Object.Input!(CreateRawPointerMovedArgs(deviceMock.Object, root)); impl.Object.Input!(CreateRawPointerMovedArgs(deviceMock.Object, root, lastClientPosition));
Assert.True(canvas.IsPointerOver); Assert.True(canvas.IsPointerOver);
SetHit(renderer, canvas); SetHit(renderer, canvas);
@ -380,6 +388,52 @@ namespace Avalonia.Base.UnitTests.Input
SetHit(renderer, null); SetHit(renderer, null);
renderer.Raise(r => r.SceneInvalidated += null, new SceneInvalidatedEventArgs((IRenderRoot)root, invalidateRect)); renderer.Raise(r => r.SceneInvalidated += null, new SceneInvalidatedEventArgs((IRenderRoot)root, invalidateRect));
Assert.False(canvas.IsPointerOver); Assert.False(canvas.IsPointerOver);
Assert.Equal(
new[]
{
((object?)canvas, nameof(InputElement.PointerEntered), lastClientPosition),
(root, nameof(InputElement.PointerEntered), lastClientPosition),
(canvas, nameof(InputElement.PointerExited), lastClientPosition),
(root, nameof(InputElement.PointerExited), lastClientPosition),
},
result);
}
[Fact]
public void PointerOver_Invalidation_Should_Use_Previously_Captured_Element()
{
using var app = UnitTestApplication.Start(new TestServices(inputManager: new InputManager()));
var renderer = new Mock<IRenderer>();
var deviceMock = CreatePointerDeviceMock();
var impl = CreateTopLevelImplMock(renderer.Object);
var invalidateRect = new Rect(0, 0, 15, 15);
Canvas canvas1, canvas2;
var root = CreateInputRoot(impl.Object, new Panel
{
Children =
{
(canvas1 = new Canvas()),
(canvas2 = new Canvas())
}
});
canvas1.PointerMoved += (s, a) => a.Pointer.Capture(canvas1);
// Let input know about latest device.
SetHit(renderer, canvas1);
impl.Object.Input!(CreateRawPointerMovedArgs(deviceMock.Object, root));
Assert.True(canvas1.IsPointerOver);
Assert.False(canvas2.IsPointerOver);
SetHit(renderer, canvas2);
renderer.Raise(r => r.SceneInvalidated += null, new SceneInvalidatedEventArgs((IRenderRoot)root, invalidateRect));
Assert.False(canvas1.IsPointerOver);
Assert.True(canvas2.IsPointerOver);
} }
// https://github.com/AvaloniaUI/Avalonia/issues/7748 // https://github.com/AvaloniaUI/Avalonia/issues/7748

2
tests/Avalonia.Base.UnitTests/Input/PointerTests.cs

@ -8,7 +8,7 @@ using Xunit;
namespace Avalonia.Base.UnitTests.Input namespace Avalonia.Base.UnitTests.Input
{ {
public class PointerTests public class PointerTests : PointerTestsBase
{ {
[Fact] [Fact]
public void On_Capture_Transfer_PointerCaptureLost_Should_Propagate_Up_To_The_Common_Parent() public void On_Capture_Transfer_PointerCaptureLost_Should_Propagate_Up_To_The_Common_Parent()

2
tests/Avalonia.Skia.UnitTests/Media/TextFormatting/TextFormatterTests.cs

@ -389,7 +389,7 @@ namespace Avalonia.Skia.UnitTests.Media.TextFormatting
if (textLine.Width > 300 || currentHeight + textLine.Height > 240) if (textLine.Width > 300 || currentHeight + textLine.Height > 240)
{ {
textLine = textLine.Collapse(new TextTrailingWordEllipsis(new ReadOnlySlice<char>(new[] { TextTrimming.s_defaultEllipsisChar }), 300, defaultProperties)); textLine = textLine.Collapse(new TextTrailingWordEllipsis(new ReadOnlySlice<char>(new[] { TextTrimming.DefaultEllipsisChar }), 300, defaultProperties));
} }
currentHeight += textLine.Height; currentHeight += textLine.Height;

Loading…
Cancel
Save