From 50709454b3f62c0c12bf56a89ca8bab90fcd16be Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 19 Jun 2024 19:02:51 -0700 Subject: [PATCH] Drag and Drop: BeginDragDropSource() with ImGuiDragDropFlags_SourceExtern assume a mouse button being pressed. (#143) --- docs/CHANGELOG.txt | 4 +++- imgui.cpp | 8 ++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index e42e5d6ce..252f954a1 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -62,9 +62,11 @@ Other changes: Added corresponding ImGuiCol_TabSelectedOverline and ImGuiCol_TabDimmedSelectedOverline colors. - Drag and Drop: BeginDragDropSource() with ImGuiDragDropFlags_SourceExtern sets active id so a multi-frame extern source doesn't interfere with hovered widgets. (#143) +- Drag and Drop: BeginDragDropSource() with ImGuiDragDropFlags_SourceExtern does not assume + a mouse button being pressed. Facilitate implementing cross-context drag and drop. (#143) - Drag and Drop: Fixes an issue when elapsing payload would be based on last payload frame instead of last drag source frame, which makes a difference if not resubmitting - payload every frame. + payload every frame. (#143) - Examples: GLFW+Vulkan, SDL+Vulkan: handle swap chain resize even without Vulkan returning VK_SUBOPTIMAL_KHR, which doesn't seem to happen on Wayland. (#7671) [@AndreiNego, @ocornut] diff --git a/imgui.cpp b/imgui.cpp index 505afa030..01beb6bf4 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5136,7 +5136,7 @@ void ImGui::EndFrame() if (g.DragDropActive) { bool is_delivered = g.DragDropPayload.Delivery; - bool is_elapsed = (g.DragDropSourceFrameCount + 1 < g.FrameCount) && ((g.DragDropSourceFlags & ImGuiDragDropFlags_SourceAutoExpirePayload) || !IsMouseDown(g.DragDropMouseButton)); + bool is_elapsed = (g.DragDropSourceFrameCount + 1 < g.FrameCount) && ((g.DragDropSourceFlags & ImGuiDragDropFlags_SourceAutoExpirePayload) || g.DragDropMouseButton == -1 || !IsMouseDown(g.DragDropMouseButton)); if (is_delivered || is_elapsed) ClearDragDrop(); } @@ -13239,6 +13239,7 @@ bool ImGui::BeginDragDropSource(ImGuiDragDropFlags flags) window = NULL; source_id = ImHashStr("#SourceExtern"); source_drag_active = true; + mouse_button = g.IO.MouseDown[0] ? 0 : -1; KeepAliveID(source_id); SetActiveID(source_id, NULL); } @@ -13439,7 +13440,10 @@ const ImGuiPayload* ImGui::AcceptDragDropPayload(const char* type, ImGuiDragDrop RenderDragDropTargetRect(r, g.DragDropTargetClipRect); g.DragDropAcceptFrameCount = g.FrameCount; - payload.Delivery = was_accepted_previously && !IsMouseDown(g.DragDropMouseButton); // For extern drag sources affecting OS window focus, it's easier to just test !IsMouseDown() instead of IsMouseReleased() + if ((g.DragDropSourceFlags & ImGuiDragDropFlags_SourceExtern) && g.DragDropMouseButton == -1) + payload.Delivery = was_accepted_previously && (g.DragDropSourceFrameCount < g.FrameCount); + else + payload.Delivery = was_accepted_previously && !IsMouseDown(g.DragDropMouseButton); // For extern drag sources affecting OS window focus, it's easier to just test !IsMouseDown() instead of IsMouseReleased() if (!payload.Delivery && !(flags & ImGuiDragDropFlags_AcceptBeforeDelivery)) return NULL;