Skip to content

Commit

Permalink
Don't alter any InputElement properties from in-process dnd handler (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
kekekeks authored and MrJul committed Feb 28, 2025
1 parent 3a97c6a commit 719f1c3
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 30 deletions.
38 changes: 10 additions & 28 deletions src/Avalonia.Controls/Platform/InProcessDragSource.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,9 @@ class InProcessDragSource : IPlatformDragSource

private DragDropEffects _allowedEffects;
private IDataObject? _draggedData;
private IInputRoot? _lastRoot;
private TopLevel? _lastRoot;
private Point _lastPosition;
private StandardCursorType _lastCursorType;
private object? _originalCursor;
private StandardCursorType? _lastCursorType;
private RawInputModifiers? _initialInputModifiers;

public InProcessDragSource()
Expand Down Expand Up @@ -77,7 +76,7 @@ private DragDropEffects RaiseEventAndUpdateCursor(RawDragEventType type, IInputR
tl?.PlatformImpl?.Input?.Invoke(rawEvent);

var effect = GetPreferredEffect(rawEvent.Effects & _allowedEffects, modifiers);
UpdateCursor(root, effect);
UpdateCursor(tl, effect);
return effect;
}

Expand All @@ -103,41 +102,24 @@ private static StandardCursorType GetCursorForDropEffect(DragDropEffects effects
return StandardCursorType.No;
}

private void UpdateCursor(IInputRoot? root, DragDropEffects effect)
private void UpdateCursor(TopLevel? root, DragDropEffects effect)
{
if (_lastRoot != root)
{
if (_lastRoot is InputElement ieLast)
{
if (_originalCursor == AvaloniaProperty.UnsetValue)
ieLast.ClearValue(InputElement.CursorProperty);
else
ieLast.Cursor = _originalCursor as Cursor;
}

if (root is InputElement ieNew)
{
if (!ieNew.IsSet(InputElement.CursorProperty))
_originalCursor = AvaloniaProperty.UnsetValue;
else
_originalCursor = root.Cursor;
}
else
_originalCursor = null;

_lastCursorType = StandardCursorType.Arrow;
_lastRoot?.SetCursorOverride(null);
_lastRoot = root;
_lastCursorType = null;
}

if (root is InputElement ie)
if (root != null)
{
var ct = GetCursorForDropEffect(effect);
if (ct != _lastCursorType)
if (_lastCursorType != ct)
{
_lastCursorType = ct;
ie.Cursor = new Cursor(ct);
root.SetCursorOverride(new Cursor(ct));
}
}
}
}

private void CancelDragging()
Expand Down
23 changes: 21 additions & 2 deletions src/Avalonia.Controls/TopLevel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ private static readonly WeakEvent<IResourceHost, ResourcesChangedEventArgs>
private IStorageProvider? _storageProvider;
private Screens? _screens;
private LayoutDiagnosticBridge? _layoutDiagnosticBridge;
private Cursor? _cursor;
private Cursor? _cursorOverride;

/// <summary>
/// Initializes static members of the <see cref="TopLevel"/> class.
Expand Down Expand Up @@ -179,7 +181,7 @@ static TopLevel()

if (e.NewValue is InputElement newInputElement)
{
topLevel.PlatformImpl?.SetCursor(newInputElement.Cursor?.PlatformImpl);
topLevel.SetCursor(newInputElement.Cursor);
newInputElement.PropertyChanged += topLevel.PointerOverElementOnPropertyChanged;
}
});
Expand Down Expand Up @@ -867,11 +869,28 @@ private void HandleInput(RawInputEventArgs e)
return candidate;
}

private void UpdateCursor() => PlatformImpl?.SetCursor(_cursorOverride?.PlatformImpl ?? _cursor?.PlatformImpl);

private void SetCursor(Cursor? cursor)
{
_cursor = cursor;
UpdateCursor();
}

/// <summary>
/// This should only be used by InProcessDragSource
/// </summary>
internal void SetCursorOverride(Cursor? cursor)
{
_cursorOverride = cursor;
UpdateCursor();
}

private void PointerOverElementOnPropertyChanged(object? sender, AvaloniaPropertyChangedEventArgs e)
{
if (e.Property == CursorProperty && sender is InputElement inputElement)
{
PlatformImpl?.SetCursor(inputElement.Cursor?.PlatformImpl);
SetCursor(inputElement.Cursor);
}
}

Expand Down

0 comments on commit 719f1c3

Please sign in to comment.