Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion src/Dock.Avalonia/Controls/DocumentTabStrip.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
using Avalonia.Styling;
using Dock.Avalonia.Contract;
using Dock.Avalonia.Automation.Peers;
using Dock.Settings;

namespace Dock.Avalonia.Controls;

Expand Down Expand Up @@ -631,7 +632,8 @@ private WindowDragHelper CreateDragHelper()
DataContext is Dock.Model.Core.IDock { CanCloseLastDockable: false };

return baseAllow || overrideAllow;
});
},
getDockScope: _ => DockSettings.DocumentWindowDragScope);
}

private void AttachToWindow()
Expand Down
2 changes: 2 additions & 0 deletions src/Dock.Avalonia/Controls/HostWindow.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ public bool DocumentChromeControlsWholeWindow
/// <inheritdoc/>
public IHostWindowState HostWindowState => _hostWindowState;

internal WindowDragDockScope WindowDragDockScope { get; set; } = WindowDragDockScope.FullWindow;

/// <inheritdoc/>
public bool IsTracked { get; set; }

Expand Down
5 changes: 5 additions & 0 deletions src/Dock.Avalonia/Internal/DockHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,11 @@ public static void LogDropAreas(Visual? root, string context)
return localHit;
}

return GetExternalControl(dockControl, point, property);
}

public static Control? GetExternalControl(DockControl dockControl, Point point, StyledProperty<bool> property)
{
if (dockControl.GetVisualRoot() is not Visual visualRoot)
{
return null;
Expand Down
4 changes: 3 additions & 1 deletion src/Dock.Avalonia/Internal/HostWindowState.cs
Original file line number Diff line number Diff line change
Expand Up @@ -396,7 +396,9 @@ public void Process(PixelPoint point, EventType eventType)
}

var dockControlPoint = dockControl.PointToClient(screenPoint);
var dropControl = DockHelpers.GetControlIncludingExternal(dockControl, dockControlPoint, DockProperties.IsDropAreaProperty);
var dropControl = _hostWindow.WindowDragDockScope == WindowDragDockScope.WindowChrome
? DockHelpers.GetExternalControl(dockControl, dockControlPoint, DockProperties.IsDropAreaProperty)
: DockHelpers.GetControlIncludingExternal(dockControl, dockControlPoint, DockProperties.IsDropAreaProperty);
if (dropControl is { })
{
var isDropEnabled = dropControl.GetValue(DockProperties.IsDropEnabledProperty);
Expand Down
16 changes: 15 additions & 1 deletion src/Dock.Avalonia/Internal/WindowDragHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,23 +20,31 @@ internal class WindowDragHelper
private readonly Control _owner;
private readonly Func<bool> _isEnabled;
private readonly Func<Control?, bool> _canStartDrag;
private readonly Func<Control?, WindowDragDockScope> _getDockScope;
private readonly bool _handlePointerPressed;
private bool _handledPointerPressed;
private Point _dragStartPoint;
private bool _pointerPressed;
private bool _isDragging;
private WindowDragDockScope _dockScope = WindowDragDockScope.FullWindow;
private PointerPressedEventArgs? _lastPointerPressedArgs;
private Window? _dragWindow;
private EventHandler<PixelPointEventArgs>? _positionChangedHandler;
private IDisposable[]? _disposables;
private IDisposable? _releasedEventDisposable;

public WindowDragHelper(Control owner, Func<bool> isEnabled, Func<Control?, bool> canStartDrag, bool handlePointerPressed = true)
public WindowDragHelper(
Control owner,
Func<bool> isEnabled,
Func<Control?, bool> canStartDrag,
bool handlePointerPressed = true,
Func<Control?, WindowDragDockScope>? getDockScope = null)
{
_owner = owner;
_isEnabled = isEnabled;
_canStartDrag = canStartDrag;
_handlePointerPressed = handlePointerPressed;
_getDockScope = getDockScope ?? (_ => WindowDragDockScope.FullWindow);
}

public void Attach()
Expand Down Expand Up @@ -74,6 +82,7 @@ public void Detach()
_pointerPressed = false;
_isDragging = false;
_handledPointerPressed = false;
_dockScope = WindowDragDockScope.FullWindow;
_lastPointerPressedArgs = null;
}

Expand All @@ -97,6 +106,7 @@ private void OnPointerPressed(object? sender, PointerPressedEventArgs e)
{
_dragStartPoint = e.GetPosition(_owner);
_pointerPressed = true;
_dockScope = _getDockScope(source);
if (_handlePointerPressed)
{
e.Handled = true;
Expand Down Expand Up @@ -135,6 +145,8 @@ private void OnPointerReleased(object? sender, PointerReleasedEventArgs e)

if (_dragWindow is HostWindow hostWindow)
{
hostWindow.WindowDragDockScope = WindowDragDockScope.FullWindow;

if (hostWindow.HostWindowState is HostWindowState state)
{
var point = hostWindow.PointToScreen(e.GetPosition(hostWindow)) -
Expand All @@ -147,6 +159,7 @@ private void OnPointerReleased(object? sender, PointerReleasedEventArgs e)
}

_dragWindow = null;
_dockScope = WindowDragDockScope.FullWindow;

if (shouldHandleRelease)
{
Expand Down Expand Up @@ -221,6 +234,7 @@ private void OnPointerMoved(object? sender, PointerEventArgs e)
}

_dragWindow = hostWindow;
hostWindow.WindowDragDockScope = _dockScope;

_positionChangedHandler = (_, _) =>
{
Expand Down
22 changes: 22 additions & 0 deletions src/Dock.Settings/DockSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,12 @@ public static class DockSettings
/// </summary>
public static bool BringWindowsToFrontOnDrag = true;

/// <summary>
/// Controls which background-window docking targets are considered when a floating document
/// window is dragged by its document tab strip.
/// </summary>
public static WindowDragDockScope DocumentWindowDragScope = WindowDragDockScope.WindowChrome;

/// <summary>
/// Close all floating windows when the main (non-host) window closes.
/// </summary>
Expand Down Expand Up @@ -262,3 +268,19 @@ public enum DockCommandBarMergingScope
/// </summary>
ActiveDockable
}

/// <summary>
/// Controls which docking targets are considered during window move-drag operations.
/// </summary>
public enum WindowDragDockScope
{
/// <summary>
/// Consider all window docking targets, including the main dock area.
/// </summary>
FullWindow,

/// <summary>
/// Consider only chrome-like targets such as external tab strips and titlebars.
/// </summary>
WindowChrome
}
Loading