diff --git a/Dalamud/Interface/DragDrop/DragDropManager.cs b/Dalamud/Interface/DragDrop/DragDropManager.cs index 2b1f79ed1..0bb7eac12 100644 --- a/Dalamud/Interface/DragDrop/DragDropManager.cs +++ b/Dalamud/Interface/DragDrop/DragDropManager.cs @@ -35,16 +35,17 @@ internal partial class DragDropManager : IDisposable, IDragDropManager, IService /// Gets a value indicating whether a valid external drag and drop is currently active and hovering over any FFXIV-related viewport. public bool IsDragging { get; private set; } - /// Gets a value indicating whether there are any files or directories currently being dragged. - public bool HasPaths { get; private set; } + /// Gets a value indicating whether there are any files or directories currently being dragged, or stored from the last drop. + public bool HasPaths + => this.Files.Count + this.Directories.Count > 0; - /// Gets the list of file paths currently being dragged from an external application over any FFXIV-related viewport. + /// Gets the list of file paths currently being dragged from an external application over any FFXIV-related viewport, or stored from the last drop. public IReadOnlyList Files { get; private set; } = Array.Empty(); - /// Gets a set of all extensions available in the paths currently being dragged from an external application over any FFXIV-related viewport. + /// Gets a set of all extensions available in the paths currently being dragged from an external application over any FFXIV-related viewport or stored from the last drop. public IReadOnlySet Extensions { get; private set; } = new HashSet(); - /// Gets the list of directory paths currently being dragged from an external application over any FFXIV-related viewport. + /// Gets the list of directory paths currently being dragged from an external application over any FFXIV-related viewport or stored from the last drop. public IReadOnlyList Directories { get; private set; } = Array.Empty(); /// Enable external drag and drop. @@ -96,7 +97,7 @@ internal partial class DragDropManager : IDisposable, IDragDropManager, IService /// public void CreateImGuiSource(string label, Func validityCheck, Func tooltipBuilder) { - if (!this.HasPaths && !this.IsDropping()) + if (!this.IsDragging && !this.IsDropping()) { return; } @@ -120,7 +121,7 @@ internal partial class DragDropManager : IDisposable, IDragDropManager, IService { files = Array.Empty(); directories = Array.Empty(); - if (!this.IsDragging || !ImGui.BeginDragDropTarget()) + if (!this.HasPaths || !ImGui.BeginDragDropTarget()) { return false; } diff --git a/Dalamud/Interface/DragDrop/DragDropTarget.cs b/Dalamud/Interface/DragDrop/DragDropTarget.cs index a592991dd..b6bb9d237 100644 --- a/Dalamud/Interface/DragDrop/DragDropTarget.cs +++ b/Dalamud/Interface/DragDrop/DragDropTarget.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.IO; using System.Linq; +using System.Runtime.CompilerServices; using System.Runtime.InteropServices.ComTypes; using System.Text; @@ -15,6 +16,7 @@ namespace Dalamud.Interface.DragDrop; internal partial class DragDropManager : DragDropManager.IDropTarget { private int lastUpdateFrame = -1; + private DragDropInterop.ModifierKeys lastKeyState = DragDropInterop.ModifierKeys.MK_NONE; /// Create the drag and drop formats we accept. private static FORMATETC FormatEtc = @@ -37,7 +39,7 @@ internal partial class DragDropManager : DragDropManager.IDropTarget public void DragEnter(IDataObject pDataObj, uint grfKeyState, POINTL pt, ref uint pdwEffect) { this.IsDragging = true; - UpdateIo((DragDropInterop.ModifierKeys)grfKeyState, true); + this.lastKeyState = UpdateIo((DragDropInterop.ModifierKeys)grfKeyState, true); if (pDataObj.QueryGetData(ref FormatEtc) != 0) { @@ -47,9 +49,9 @@ internal partial class DragDropManager : DragDropManager.IDropTarget { pdwEffect &= (uint)DragDropInterop.DropEffects.Copy; (this.Files, this.Directories) = this.GetPaths(pDataObj); - this.HasPaths = this.Files.Count + this.Directories.Count > 0; this.Extensions = this.Files.Select(Path.GetExtension).Where(p => !p.IsNullOrEmpty()).Distinct().ToHashSet(); } + Log.Debug("[DragDrop] Entering external Drag and Drop with {KeyState} at {PtX}, {PtY} and with {N} files.", (DragDropInterop.ModifierKeys)grfKeyState, pt.x, pt.y, this.Files.Count + this.Directories.Count); } @@ -64,7 +66,7 @@ internal partial class DragDropManager : DragDropManager.IDropTarget if (frame != this.lastUpdateFrame) { this.lastUpdateFrame = frame; - UpdateIo((DragDropInterop.ModifierKeys)grfKeyState, false); + this.lastKeyState = UpdateIo((DragDropInterop.ModifierKeys)grfKeyState, false); pdwEffect &= (uint)DragDropInterop.DropEffects.Copy; Log.Verbose("[DragDrop] External Drag and Drop with {KeyState} at {PtX}, {PtY}.", (DragDropInterop.ModifierKeys)grfKeyState, pt.x, pt.y); } @@ -87,10 +89,10 @@ internal partial class DragDropManager : DragDropManager.IDropTarget /// Effects that can be used with this drag and drop process. public void Drop(IDataObject pDataObj, uint grfKeyState, POINTL pt, ref uint pdwEffect) { - MouseDrop((DragDropInterop.ModifierKeys)grfKeyState); + MouseDrop(this.lastKeyState); this.lastDropFrame = ImGui.GetFrameCount(); this.IsDragging = false; - if (this.Files.Count > 0 || this.Directories.Count > 0) + if (this.HasPaths) { pdwEffect &= (uint)DragDropInterop.DropEffects.Copy; } @@ -102,7 +104,7 @@ internal partial class DragDropManager : DragDropManager.IDropTarget Log.Debug("[DragDrop] Dropping {N} files with {KeyState} at {PtX}, {PtY}.", this.Files.Count + this.Directories.Count, (DragDropInterop.ModifierKeys)grfKeyState, pt.x, pt.y); } - private static void UpdateIo(DragDropInterop.ModifierKeys keys, bool entering) + private static DragDropInterop.ModifierKeys UpdateIo(DragDropInterop.ModifierKeys keys, bool entering) { var io = ImGui.GetIO(); void UpdateMouse(int mouseIdx) @@ -163,6 +165,8 @@ internal partial class DragDropManager : DragDropManager.IDropTarget io.KeyShift = false; io.AddKeyEvent(ImGuiKey.LeftShift, false); } + + return keys; } private static void MouseDrop(DragDropInterop.ModifierKeys keys)