Thank you for evaluating our Docking/MDI controls, and we appreciate you sharing the experience you are having on Linux. We can confirm that we are reproducing the same behavior.
Any docking solution that supports floating windows needs to be able to track the position of the pointer during a window drag. Windows OS makes that easy. Linux OS, unfortunately, does not expose any pointer events during a drag. We are forced to work around this by not using native Linux drag and, instead, manually emulating a window drag by tracking change in pointer position and moving the window with the pointer.
What we discovered, and what you are seeing, is that the Linux window managers simply do not allow you to manually position a window that is not fully visible in the working area. Native dragging allows it (which we can't use), but if you attempt to just set the window location it will always shift the window to be fully visible. It's a great idea in principle, but clearly causing issues with our specific use case. We reached out to the Avalonia team and they confirmed this is an issue with Linux.
We are going to continue to investigate to see if we can find a solution that improves this experience on Linux.
In the meantime, the good news is that even though the dragged window is blocking your view of what is behind it, our docking controls are still properly tracking the pointer location and you can successfully dock the window. One option make it easier to know where the pointer is positioned is to make the dragged window semi-transparent.
You can actually test that out today by updating our the Simple IDE demo of our Sample Browser. The DockSite control has a "WindowsDragging" event that is raised when drag begins and a "WindowsDragged" event that is raised at the end. Update the OnDockSiteWindowsDragging event handler to insert this code at the top of the method. It finds the parent Window that is being dragged and makes it semi-transparent.
/// <summary>
/// Occurs before one or more docking windows are dragged by the end user.
/// </summary>
/// <param name="sender">The sender of the event.</param>
/// <param name="e">The <c>DockingWindowsEventArgs</c> that contains data related to this event.</param>
private void OnDockSiteWindowsDragging(object sender, DockingWindowsEventArgs e) {
if (((DockSite)sender).UseHostedFloatingWindows == false) {
// Find the native window containing the docking window(s) being dragged
var containerWindow = e.Windows.Select(w => w.GetVisualRoot() as Window).FirstOrDefault();
if (containerWindow is not null)
containerWindow.Opacity = 0.3;
}
// Additional logic here
}
Then update the OnDockSiteWindowsDragged event handler to restore the opacity:
/// <summary>
/// Occurs after one or more docking windows are dragged by the end user.
/// </summary>
/// <param name="sender">The sender of the event.</param>
/// <param name="e">The <c>DockingWindowsEventArgs</c> that contains data related to this event.</param>
private void OnDockSiteWindowsDragged(object sender, DockingWindowsEventArgs e) {
if (((DockSite)sender).UseHostedFloatingWindows == false) {
// Find the native window containing the docking window(s) being dragged
var containerWindow = e.Windows.Select(w => w.GetVisualRoot() as Window).FirstOrDefault();
if (containerWindow is not null)
containerWindow.Opacity = 1.0;
}
// Additional logic here
}
This concept should help make the Linux issue less of an issue, and is a built-in feature we will plan on adding to the next release. For Linux, we'll make sure this is turned on by default.