Drag and Drop: Added a mechanism to allow widgets with no identifiers (such as Text/Image) to be used with BeginDragDropSource() given the explicit ImGuiDragDropFlags_SourceAllowNullID flag.
diff --git a/imgui.cpp b/imgui.cpp
index b11a28d..de89f4f 100644
--- a/imgui.cpp
+++ b/imgui.cpp
@@ -1860,6 +1860,16 @@
     return ImHash(str, str_end ? (int)(str_end - str) : 0, seed);
 }
 
+// This is particularly dodgy and used in extremely rare situation.
+ImGuiID ImGuiWindow::GetIDFromRectangle(const ImRect& r_abs)
+{
+    ImGuiID seed = IDStack.back();
+    const int r_rel[4] = { (int)(r_abs.Min.x - Pos.x), (int)(r_abs.Min.y - Pos.y), (int)(r_abs.Max.x - Pos.x), (int)(r_abs.Max.y - Pos.y) };
+    ImGuiID id = ImHash(&r_rel, sizeof(r_rel), seed);
+    ImGui::KeepAliveID(id);
+    return id;
+}
+
 //-----------------------------------------------------------------------------
 // Internal API exposed in imgui_internal.h
 //-----------------------------------------------------------------------------
@@ -10606,16 +10616,48 @@
     ImGuiWindow* window = g.CurrentWindow;
     if (g.IO.MouseDown[mouse_button] == false)
         return false;
-    if (g.ActiveId != window->DC.LastItemId)
+
+    ImGuiID id = window->DC.LastItemId;
+    if (id == 0)
+    {
+        // If you want to use BeginDragDropSource() on an item with no unique identifier for interaction, such as Text() or Image(), you need to:
+        // A) Read the explanation below, B) Use the ImGuiDragDropFlags_SourceAllowNullID flag, C) Swallow your programmer pride.
+        if (!(flags & ImGuiDragDropFlags_SourceAllowNullID))
+        {
+            IM_ASSERT(0);
+            return false;
+        }
+
+        // Magic fallback (=somehow reprehensible) to handle items with no assigned ID, e.g. Text(), Image().
+        // We build a throwaway ID based on current ID stack + relative AABB of items in window. 
+        // THE IDENTIFIER WON'T SURVIVE ANY REPOSITIONING OF THE WIDGET, so if your widget moves your dragging operation will be canceled. 
+        // If you want fail-proof dragging,
+        // We don't need to maintain/call ClearActiveID() as releasing the button will early out this function and trigger !ActiveIdIsAlive.
+        bool is_hovered = window->DC.LastItemRectHoveredRect;
+        if (!is_hovered && (g.ActiveId == 0 || g.ActiveIdWindow != window))
+            return false;
+        id = window->DC.LastItemId = window->GetIDFromRectangle(window->DC.LastItemRect);
+        if (is_hovered)
+            SetHoveredID(id);
+        if (is_hovered && g.IO.MouseClicked[mouse_button])
+        {
+            SetActiveID(id, window);
+            FocusWindow(window);
+        }
+        if (g.ActiveId == id) // Allow the underlying widget to display/return hovered during the mouse release frame, else we would get a flicker.
+            g.ActiveIdAllowOverlap = is_hovered;
+    }
+    if (g.ActiveId != id)
         return false;
 
     if (IsMouseDragging(mouse_button))
     {
         if (!g.DragDropActive)
         {
+            IM_ASSERT(id != 0);
             ImGuiPayload& payload = g.DragDropPayload;
             payload.Clear();
-            payload.SourceId = g.ActiveId;
+            payload.SourceId = id;
             payload.SourceParentId = window->IDStack.back();
             g.DragDropActive = true;
             g.DragDropSourceFlags = flags;
diff --git a/imgui.h b/imgui.h
index 7f1baa9..25a9c5a 100644
--- a/imgui.h
+++ b/imgui.h
@@ -599,6 +599,7 @@
     // BeginDragDropSource() flags
     ImGuiDragDropFlags_SourceNoAutoTooltip      = 1 << 0,
     ImGuiDragDropFlags_SourceNoDisableHover     = 1 << 1,       // By default, when dragging we clear data so that IsItemHovered() will return true, to avoid subsequent user code submitting tooltips.
+    ImGuiDragDropFlags_SourceAllowNullID        = 1 << 2,       // Allow items such as Text(), Image() that have no unique identifier to be used as drag source, by manufacturing a temporary identifier based on their window-relative position. This is extremely unusual within the dear imgui ecosystem and so we made it explicit.
     // BeginDragDropTarget() flags
     ImGuiDragDropFlags_AcceptBeforeDelivery     = 1 << 10,      // AcceptDragDropPayload() returns true even before the mouse button is released. You can then call IsDelivery() to test if the payload needs to be delivered.
     ImGuiDragDropFlags_AcceptNoDrawDefaultRect  = 1 << 11,      // Do not draw the default highlight rectangle when hovering over target.
diff --git a/imgui_internal.h b/imgui_internal.h
index 666b449..dafb3ae 100644
--- a/imgui_internal.h
+++ b/imgui_internal.h
@@ -754,6 +754,7 @@
     ImGuiID     GetID(const char* str, const char* str_end = NULL);
     ImGuiID     GetID(const void* ptr);
     ImGuiID     GetIDNoKeepAlive(const char* str, const char* str_end = NULL);
+    ImGuiID     GetIDFromRectangle(const ImRect& r_abs);
 
     ImRect      Rect() const                            { return ImRect(Pos.x, Pos.y, Pos.x+Size.x, Pos.y+Size.y); }
     float       CalcFontSize() const                    { return GImGui->FontBaseSize * FontWindowScale; }