Browse Source

Xdnd: add trace logging

pull/20926/head
Julien Lebosquain 6 months ago
parent
commit
656598c735
No known key found for this signature in database GPG Key ID: 1833CAD10ACC46FD
  1. 78
      src/Avalonia.X11/Selections/DragDrop/X11DragSource.cs

78
src/Avalonia.X11/Selections/DragDrop/X11DragSource.cs

@ -1,10 +1,10 @@
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Input.Platform;
using Avalonia.Input.Raw;
using Avalonia.Logging;
using Avalonia.Platform;
using Avalonia.Threading;
using static Avalonia.X11.Selections.DragDrop.XdndConstants;
@ -51,6 +51,7 @@ internal sealed class X11DragSource(AvaloniaX11Platform platform) : IPlatformDra
private readonly DragDropEffects _allowedEffects;
private readonly X11CursorFactory? _cursorFactory;
private readonly DragDropDataProvider _dataProvider;
private readonly ParametrizedLogger? _logger;
private readonly TaskCompletionSource<DragDropEffects> _completionSource = new();
private readonly IntPtr[] _formatAtoms;
private X11WindowInfo? _originalSourceWindowInfo;
@ -73,6 +74,7 @@ internal sealed class X11DragSource(AvaloniaX11Platform platform) : IPlatformDra
_allowedEffects = allowedEffects;
_cursorFactory = cursorFactory;
_currentEffects = allowedEffects;
_logger = Logger.TryGet(LogEventLevel.Verbose, LogArea.X11Platform);
_dataProvider = new DragDropDataProvider(platform, dataTransfer.ToAsynchronous());
if (!platform.Windows.TryGetValue(sourceWindow, out var sourceWindowInfo))
@ -177,6 +179,12 @@ internal sealed class X11DragSource(AvaloniaX11Platform platform) : IPlatformDra
// Handle new target.
if (_targetState.Target != target)
{
_logger?.Log(
this,
"Pointer moved from window {OldTarget} to window {NewTarget}.",
_targetState.Target?.TargetWindow,
target?.TargetWindow);
if (_targetState.Target is { } lastTarget)
{
if (lastTarget.InProcessWindow is { } window)
@ -219,6 +227,12 @@ internal sealed class X11DragSource(AvaloniaX11Platform platform) : IPlatformDra
{
// We already sent a position previously and are waiting for a response. Don't flood.
_targetState.PendingPosition = positionRequest;
_logger?.Log(
this,
"Pointer moved to point {Position} on window {Window} while waiting for XdndStatus. XdndPosition will be sent later.",
rootPosition,
currentTarget.TargetWindow);
}
else
{
@ -232,22 +246,22 @@ internal sealed class X11DragSource(AvaloniaX11Platform platform) : IPlatformDra
{
UngrabPointer();
if (_targetState.Target is not { } lastTarget || _targetState.PendingDrop is not null)
if (_targetState.Target is not { } target || _targetState.PendingDrop is not null)
return;
if (lastTarget.InProcessWindow is not null)
if (target.InProcessWindow is not null)
{
var rootPosition = new PixelPoint(button.x_root, button.y_root);
var modifiers = button.state.ToRawInputModifiers();
if (_targetState.AllowsDrop)
{
var effects = ProcessRawDragEvent(lastTarget.InProcessWindow, RawDragEventType.Drop, rootPosition, modifiers);
var effects = ProcessRawDragEvent(target.InProcessWindow, RawDragEventType.Drop, rootPosition, modifiers);
UpdateCurrentEffects(effects);
}
else
{
ProcessRawDragEvent(lastTarget.InProcessWindow, RawDragEventType.DragLeave, rootPosition, modifiers);
ProcessRawDragEvent(target.InProcessWindow, RawDragEventType.DragLeave, rootPosition, modifiers);
UpdateCurrentEffects(DragDropEffects.None);
}
@ -258,20 +272,25 @@ internal sealed class X11DragSource(AvaloniaX11Platform platform) : IPlatformDra
{
var dropRequest = new DropRequest(button.time);
if (_targetState.IsWaitingForStatus || _targetState.PendingPosition is not null)
if (_targetState.IsWaitingForStatus)
{
// We're still waiting for a XdndStatus response for the last position, defer the drop.
_targetState.PendingDrop = dropRequest;
_logger?.Log(
this,
"Pointer released on window {Window} while waiting for XdndStatus. XdndDrop will be sent later.",
target.TargetWindow);
}
else if (_targetState.AllowsDrop)
{
SendDropRequest(dropRequest, lastTarget);
SendDropRequest(dropRequest, target);
}
else
{
_targetState = default;
UpdateCurrentEffects(DragDropEffects.None);
SendXdndLeave(lastTarget);
SendXdndLeave(target);
Complete(DragDropEffects.None);
}
}
@ -279,7 +298,7 @@ internal sealed class X11DragSource(AvaloniaX11Platform platform) : IPlatformDra
private void OnXdndStatus(in XClientMessageEvent message)
{
if (_targetState.Target is not { } lastTarget || message.ptr1 != lastTarget.TargetWindow)
if (_targetState.Target is not { } target || message.ptr1 != target.TargetWindow)
return;
TimeoutManager.Stop();
@ -293,28 +312,36 @@ internal sealed class X11DragSource(AvaloniaX11Platform platform) : IPlatformDra
UpdateCurrentEffects(effects & _allowedEffects);
_logger?.Log(
this,
"Received XdndStatus with effects {Effects} for window {Window}.",
effects,
target.TargetWindow);
// If we have any pending XdndPosition or XdndDrop to send, now is the time.
if (_targetState.PendingPosition is { } position)
{
_targetState.PendingPosition = null;
SendPositionRequest(position, lastTarget);
SendPositionRequest(position, target);
}
else if (_targetState.PendingDrop is { } drop)
{
SendDropRequest(drop, lastTarget);
SendDropRequest(drop, target);
}
}
private void OnXdndFinished(in XClientMessageEvent message)
{
if (_targetState.Target is not { } lastTarget || message.ptr1 != lastTarget.TargetWindow)
if (_targetState.Target is not { } target || message.ptr1 != target.TargetWindow)
return;
_logger?.Log(this, "Received XdndFinished for window {Window}.", target.TargetWindow);
_targetState = default;
_dataProvider.Activity = null;
_timeoutManager?.Stop();
if (lastTarget.Version >= 5)
if (target.Version >= 5)
{
var accepted = (message.ptr2 & 1) == 1;
var action = accepted ? message.ptr3 : 0;
@ -398,6 +425,12 @@ internal sealed class X11DragSource(AvaloniaX11Platform platform) : IPlatformDra
var version = Math.Min(target.Version, XdndVersion);
var hasMoreFormats = _formatAtoms.Length > 3;
_logger?.Log(
this,
"Sending XdndEnter with version {Version} to window {Window}.",
version,
target.TargetWindow);
SendXdndMessage(
_platform.Info.Atoms.XdndEnter,
target.MessageWindow,
@ -409,6 +442,12 @@ internal sealed class X11DragSource(AvaloniaX11Platform platform) : IPlatformDra
private void SendXdndPosition(XdndTargetInfo target, PixelPoint rootPosition, IntPtr timestamp, IntPtr action)
{
_logger?.Log(
this,
"Sending XdndPosition at point {Position} to window {Window}.",
rootPosition,
target.TargetWindow);
SendXdndMessage(
_platform.Info.Atoms.XdndPosition,
target.MessageWindow,
@ -419,10 +458,18 @@ internal sealed class X11DragSource(AvaloniaX11Platform platform) : IPlatformDra
}
private void SendXdndLeave(XdndTargetInfo target)
=> SendXdndMessage(_platform.Info.Atoms.XdndLeave, target.MessageWindow, 0, 0, 0, 0);
{
_logger?.Log(this, "Sending XdndLeave to window {Window}.", target.TargetWindow);
SendXdndMessage(_platform.Info.Atoms.XdndLeave, target.MessageWindow, 0, 0, 0, 0);
}
private void SendXdndDrop(XdndTargetInfo target, IntPtr timestamp)
=> SendXdndMessage(_platform.Info.Atoms.XdndDrop, target.MessageWindow, 0, timestamp, 0, 0);
{
_logger?.Log(this, "Sending XdndDrop to window {Window}.", target.TargetWindow);
SendXdndMessage(_platform.Info.Atoms.XdndDrop, target.MessageWindow, 0, timestamp, 0, 0);
}
private void SendXdndMessage(
IntPtr messageType,
@ -465,6 +512,7 @@ internal sealed class X11DragSource(AvaloniaX11Platform platform) : IPlatformDra
{
TimeoutManager.Restart();
_dataProvider.Activity = TimeoutManager.Restart;
SendXdndDrop(target, dropRequest.Timestamp);
}

Loading…
Cancel
Save