MultiSelect: Added ImGuiMultiSelectFlags_SelectOnClickRelease to allow dragging an unselected item without altering selection + update drag and drop demo.
diff --git a/imgui.h b/imgui.h
index 177db86..f7f01a4 100644
--- a/imgui.h
+++ b/imgui.h
@@ -2736,6 +2736,8 @@
     ImGuiMultiSelectFlags_ClearOnEscape         = 1 << 2,   // Clear selection when pressing Escape while scope is focused.
     ImGuiMultiSelectFlags_ClearOnClickWindowVoid= 1 << 3,   // Clear selection when clicking on empty location within host window (use if BeginMultiSelect() covers a whole window)
     //ImGuiMultiSelectFlags_ClearOnClickRectVoid= 1 << 4,   // Clear selection when clicking on empty location within rectangle covered by selection scope (use if multiple BeginMultiSelect() are used in the same host window)
+    ImGuiMultiSelectFlags_SelectOnClick         = 1 << 5,   // Apply selection on mouse down when clicking on unselected item. (Default)
+    ImGuiMultiSelectFlags_SelectOnClickRelease  = 1 << 6,   // Apply selection on mouse release when clicking an unselected item. Allow dragging an unselected item without altering selection.
 };
 
 // Multi-selection system
diff --git a/imgui_demo.cpp b/imgui_demo.cpp
index ac0ddc2..6192b63 100644
--- a/imgui_demo.cpp
+++ b/imgui_demo.cpp
@@ -3338,6 +3338,7 @@
             ImGui::CheckboxFlags("ImGuiMultiSelectFlags_NoSelectAll", &flags, ImGuiMultiSelectFlags_NoSelectAll);
             ImGui::CheckboxFlags("ImGuiMultiSelectFlags_ClearOnEscape", &flags, ImGuiMultiSelectFlags_ClearOnEscape);
             ImGui::CheckboxFlags("ImGuiMultiSelectFlags_ClearOnClickWindowVoid", &flags, ImGuiMultiSelectFlags_ClearOnClickWindowVoid);
+            ImGui::CheckboxFlags("ImGuiMultiSelectFlags_SelectOnClickRelease", &flags, ImGuiMultiSelectFlags_SelectOnClickRelease); ImGui::SameLine();  HelpMarker("Allow dragging an unselected item without altering selection.");
 
             // Initialize default list with 1000 items.
             static ImVector<int> items;
@@ -3403,11 +3404,11 @@
                         // IMPORTANT: for deletion refocus to work we need object ID to be stable,
                         // aka not depend on their index in the list. Here we use our persistent item_id
                         // instead of index to build a unique ID that will persist.
-                        // (If we used PushID(n) instead, focus wouldn't be restored correctly after deletion).
+                        // (If we used PushID(index) instead, focus wouldn't be restored correctly after deletion).
                         ImGui::PushID(item_id);
 
                         // Emit a color button, to test that Shift+LeftArrow landing on an item that is not part
-                        // of the selection scope doesn't erroneously alter our selection (FIXME-TESTS: Add a test for that!).
+                        // of the selection scope doesn't erroneously alter our selection.
                         if (show_color_button)
                         {
                             ImU32 dummy_col = (ImU32)((unsigned int)n * 0xC250B74B) | IM_COL32_A_MASK;
@@ -3415,39 +3416,57 @@
                             ImGui::SameLine();
                         }
 
+                        // Submit item
                         bool item_is_selected = selection.Contains((ImGuiID)n);
+                        bool item_is_open = false;
                         ImGui::SetNextItemSelectionUserData(n);
                         if (widget_type == WidgetType_Selectable)
                         {
-                            ImGuiSelectableFlags selectable_flags = ImGuiSelectableFlags_None;
-                            ImGui::Selectable(label, item_is_selected, selectable_flags);
-                            if (item_curr_idx_to_focus == n)
-                                ImGui::SetKeyboardFocusHere(-1);
-
-                            if (use_drag_drop && ImGui::BeginDragDropSource())
-                            {
-                                ImGui::Text("(Dragging %d items)", selection.GetSize());
-                                ImGui::EndDragDropSource();
-                            }
+                            ImGui::Selectable(label, item_is_selected, ImGuiSelectableFlags_None);
                         }
                         else if (widget_type == WidgetType_TreeNode)
                         {
-                            ImGuiTreeNodeFlags tree_node_flags = ImGuiTreeNodeFlags_SpanAvailWidth;
-                            tree_node_flags |= ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick;
+                            ImGuiTreeNodeFlags tree_node_flags = ImGuiTreeNodeFlags_SpanAvailWidth | ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick;
                             if (item_is_selected)
                                 tree_node_flags |= ImGuiTreeNodeFlags_Selected;
-                            bool open = ImGui::TreeNodeEx(label, tree_node_flags);
-                            if (item_curr_idx_to_focus == n)
-                                ImGui::SetKeyboardFocusHere(-1);
-                            if (use_drag_drop && ImGui::BeginDragDropSource())
-                            {
-                                ImGui::Text("(Dragging %d items)", selection.GetSize());
-                                ImGui::EndDragDropSource();
-                            }
-                            if (open)
-                                ImGui::TreePop();
+                            item_is_open = ImGui::TreeNodeEx(label, tree_node_flags);
                         }
 
+                        // Focus (for after deletion)
+                        if (item_curr_idx_to_focus == n)
+                            ImGui::SetKeyboardFocusHere(-1);
+
+                        // Drag and Drop
+                        if (use_drag_drop && ImGui::BeginDragDropSource())
+                        {
+                            // Write payload with full selection OR single unselected item (only possible with ImGuiMultiSelectFlags_SelectOnClickRelease)
+                            if (ImGui::GetDragDropPayload() == NULL)
+                            {
+                                ImVector<int> payload_items;
+                                if (!item_is_selected)
+                                    payload_items.push_back(item_id);
+                                else
+                                    for (const ImGuiStoragePair& pair : selection.Storage.Data)
+                                        if (pair.val_i)
+                                            payload_items.push_back((int)pair.key);
+                                ImGui::SetDragDropPayload("MULTISELECT_DEMO_ITEMS", payload_items.Data, (size_t)payload_items.size_in_bytes());
+                            }
+
+                            // Display payload content in tooltip
+                            const ImGuiPayload* payload = ImGui::GetDragDropPayload();
+                            const int* payload_items = (int*)payload->Data;
+                            const int payload_count = (int)payload->DataSize / (int)sizeof(payload_items[0]);
+                            if (payload_count == 1)
+                                ImGui::Text("Object %05d: %s", payload_items[0], ExampleNames[payload_items[0] % IM_ARRAYSIZE(ExampleNames)]);
+                            else
+                                ImGui::Text("Dragging %d objects", payload_count);
+
+                            ImGui::EndDragDropSource();
+                        }
+
+                        if (widget_type == WidgetType_TreeNode && item_is_open)
+                            ImGui::TreePop();
+
                         // Right-click: context menu
                         if (ImGui::BeginPopupContextItem())
                         {
diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp
index 69c758d..102fa16 100644
--- a/imgui_widgets.cpp
+++ b/imgui_widgets.cpp
@@ -7306,10 +7306,9 @@
     // Alter button behavior flags
     // To handle drag and drop of multiple items we need to avoid clearing selection on click.
     // Enabling this test makes actions using CTRL+SHIFT delay their effect on MouseUp which is annoying, but it allows drag and drop of multiple items.
-    // FIXME-MULTISELECT: Consider opt-in for drag and drop behavior in ImGuiMultiSelectFlags?
     ImGuiButtonFlags button_flags = *p_button_flags;
     button_flags |= ImGuiButtonFlags_NoHoveredOnFocus;
-    if (!selected || (g.ActiveId == id && g.ActiveIdHasBeenPressedBefore))
+    if ((!selected || (g.ActiveId == id && g.ActiveIdHasBeenPressedBefore)) && !(ms->Flags & ImGuiMultiSelectFlags_SelectOnClickRelease))
         button_flags = (button_flags | ImGuiButtonFlags_PressedOnClick) & ~ImGuiButtonFlags_PressedOnClickRelease;
     else
         button_flags |= ImGuiButtonFlags_PressedOnClickRelease;