RangeSelect/MultiScope: Transition to use FocusScope bits merged in master.

Preserve ability to shift+arrow into an item that is part of FocusScope but doesn't carry a selection without breaking selection.
diff --git a/imgui.cpp b/imgui.cpp
index 8c8287d..6a3a3fc 100644
--- a/imgui.cpp
+++ b/imgui.cpp
@@ -3914,7 +3914,6 @@
 
     g.PrivateClipboard.clear();
     g.InputTextState.ClearFreeMemory();
-    g.MultiSelectScopeWindow = NULL;
 
     g.SettingsWindows.clear();
     g.SettingsHandlers.clear();
@@ -8085,6 +8084,7 @@
             result->ID = id;
             result->FocusScopeId = window->DC.NavFocusScopeIdCurrent;
             result->RectRel = nav_bb_rel;
+            result->HasSelectionData = (g.NextItemData.Flags & ImGuiNextItemDataFlags_HasSelectionData) != 0;
         }
 
         // Features like PageUp/PageDown need to maintain a separate score for the visible set of items.
@@ -8098,6 +8098,7 @@
                     result->ID = id;
                     result->FocusScopeId = window->DC.NavFocusScopeIdCurrent;
                     result->RectRel = nav_bb_rel;
+                    result->HasSelectionData = (g.NextItemData.Flags & ImGuiNextItemDataFlags_HasSelectionData) != 0;
                 }
     }
 
@@ -8634,7 +8635,7 @@
         // Don't set NavJustMovedToId if just landed on the same spot (which may happen with ImGuiNavMoveFlags_AllowCurrentNavId)
         g.NavJustMovedToId = result->ID;
         g.NavJustMovedToFocusScopeId = result->FocusScopeId;
-
+        g.NavJustMovedToHasSelectionData = result->HasSelectionData;
     }
     SetNavIDWithRectRel(result->ID, g.NavLayer, result->FocusScopeId, result->RectRel);
     g.NavMoveFromClampedRefRect = false;
diff --git a/imgui_internal.h b/imgui_internal.h
index 69a4545..bb1523c 100644
--- a/imgui_internal.h
+++ b/imgui_internal.h
@@ -866,13 +866,15 @@
 
 struct IMGUI_API ImGuiMultiSelectState
 {
+    ImGuiID                 FocusScopeId;           // Same as CurrentWindow->DC.FocusScopeIdCurrent (unless another selection scope was pushed manually)
+    ImGuiID                 BackupFocusScopeId;
     ImGuiMultiSelectData    In;                     // The In requests are set and returned by BeginMultiSelect()
     ImGuiMultiSelectData    Out;                    // The Out requests are finalized and returned by EndMultiSelect()
     bool                    InRangeDstPassedBy;     // (Internal) set by the the item that match NavJustMovedToId when InRequestRangeSetNav is set.
     bool                    InRequestSetRangeNav;   // (Internal) set by BeginMultiSelect() when using Shift+Navigation. Because scrolling may be affected we can't afford a frame of lag with Shift+Navigation.
 
     ImGuiMultiSelectState() { Clear(); }
-    void Clear()            { In.Clear(); Out.Clear(); InRangeDstPassedBy = InRequestSetRangeNav = false; }
+    void Clear()            { FocusScopeId = BackupFocusScopeId = 0; In.Clear(); Out.Clear(); InRangeDstPassedBy = InRequestSetRangeNav = false; }
 };
 
 // Helper function to calculate a circle's segment count given its radius and a "maximum error" value.
@@ -918,9 +920,10 @@
     float           DistCenter;         // Best candidate center distance to current NavId
     float           DistAxial;
     ImRect          RectRel;            // Best candidate bounding box in window relative space
+    bool            HasSelectionData;   // Copy of (NextItemData.Flags & ImGuiNextItemDataFlags_HasSelection)
 
     ImGuiNavMoveResult() { Clear(); }
-    void Clear()         { Window = NULL; ID = FocusScopeId = 0; DistBox = DistCenter = DistAxial = FLT_MAX; RectRel = ImRect(); }
+    void Clear()         { Window = NULL; ID = FocusScopeId = 0; DistBox = DistCenter = DistAxial = FLT_MAX; RectRel = ImRect(); HasSelectionData = false; }
 };
 
 enum ImGuiNextWindowDataFlags_
@@ -959,9 +962,10 @@
 
 enum ImGuiNextItemDataFlags_
 {
-    ImGuiNextItemDataFlags_None     = 0,
-    ImGuiNextItemDataFlags_HasWidth = 1 << 0,
-    ImGuiNextItemDataFlags_HasOpen  = 1 << 1
+    ImGuiNextItemDataFlags_None                 = 0,
+    ImGuiNextItemDataFlags_HasWidth             = 1 << 0,
+    ImGuiNextItemDataFlags_HasOpen              = 1 << 1,
+    ImGuiNextItemDataFlags_HasSelectionData     = 1 << 2
 };
 
 struct ImGuiNextItemData
@@ -971,7 +975,6 @@
     ImGuiID                     FocusScopeId;           // Set by SetNextItemMultiSelectData() (!= 0 signify value has been set, so it's an alternate version of HasSelectionData, we don't use Flags for this because they are cleared too early. This is mostly used for debugging)
     ImGuiCond                   OpenCond;
     bool                        OpenVal;                // Set by SetNextItemOpen()
-    ImGuiID                     MultiSelectScopeId;     // Set by SetNextItemMultiSelectData()
     void*                       SelectionData;          // Set by SetNextItemSelectionData() (note that NULL/0 is a valid value)
 
     ImGuiNextItemData()         { memset(this, 0, sizeof(*this)); }
@@ -1084,6 +1087,7 @@
     ImGuiID                 NavJustTabbedId;                    // Just tabbed to this id.
     ImGuiID                 NavJustMovedToId;                   // Just navigated to this id (result of a successfully MoveRequest).
     ImGuiID                 NavJustMovedToFocusScopeId;         // Just navigated to this focus scope id (result of a successfully MoveRequest).
+    bool                    NavJustMovedToHasSelectionData;     // " (FIXME-NAV: We should maybe just store ImGuiNavMoveResult)
     ImGuiID                 NavNextActivateId;                  // Set by ActivateItem(), queued until next frame.
     ImGuiInputSource        NavInputSource;                     // Keyboard or Gamepad mode? THIS WILL ONLY BE None or NavGamepad or NavKeyboard.
     ImRect                  NavScoringRectScreen;               // Rectangle used for scoring, in screen space. Based of window->DC.NavRefRectRel[], modified for directional navigation scoring.
@@ -1127,10 +1131,9 @@
     bool                    FocusTabPressed;                    //
 
     // Range-Select/Multi-Select
-    ImGuiID                 MultiSelectScopeId;
-    ImGuiWindow*            MultiSelectScopeWindow;
+    bool                    MultiSelectEnabled;
     ImGuiMultiSelectFlags   MultiSelectFlags;
-    ImGuiMultiSelectState   MultiSelectState;
+    ImGuiMultiSelectState   MultiSelectState;                   // We currently don't support recursing/stacking multi-select
 
     // Render
     ImDrawData              DrawData;                           // Main ImDrawData instance to pass render information to the user
@@ -1264,6 +1267,7 @@
         NavWindow = NULL;
         NavId = NavFocusScopeId = NavActivateId = NavActivateDownId = NavActivatePressedId = NavInputId = 0;
         NavJustTabbedId = NavJustMovedToId = NavJustMovedToFocusScopeId = NavNextActivateId = 0;
+        NavJustMovedToHasSelectionData = false;
         NavInputSource = ImGuiInputSource_None;
         NavScoringRectScreen = ImRect();
         NavScoringCount = 0;
@@ -1292,9 +1296,8 @@
         FocusRequestNextCounterRegular = FocusRequestNextCounterTabStop = INT_MAX;
         FocusTabPressed = false;
 
-        MultiSelectScopeId = 0;
-        MultiSelectScopeWindow = NULL;
-        MultiSelectFlags = 0;
+        MultiSelectEnabled = false;
+        MultiSelectFlags = ImGuiMultiSelectFlags_None;
 
         DimBgRatio = 0.0f;
         BackgroundDrawList._OwnerName = "##Background"; // Give it a name for debugging
diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp
index 39052c1..64893d9 100644
--- a/imgui_widgets.cpp
+++ b/imgui_widgets.cpp
@@ -5379,7 +5379,7 @@
     const bool was_selected = selected;
 
     // Multi-selection support (header)
-    const bool is_multi_select = (g.MultiSelectScopeWindow == window);
+    const bool is_multi_select = g.MultiSelectEnabled;
     if (is_multi_select)
     {
         flags |= ImGuiTreeNodeFlags_OpenOnArrow;
@@ -5688,10 +5688,10 @@
 
     if (flags & ImGuiSelectableFlags_Disabled)
         selected = false;
+    const bool was_selected = selected;
 
     // Multi-selection support (header)
-    const bool is_multi_select = (g.MultiSelectScopeWindow == window);
-    const bool was_selected = selected;
+    const bool is_multi_select = g.MultiSelectEnabled;
     if (is_multi_select)
     {
         MultiSelectItemHeader(id, &selected);
@@ -5792,17 +5792,20 @@
 
 ImGuiMultiSelectData* ImGui::BeginMultiSelect(ImGuiMultiSelectFlags flags, void* range_ref, bool range_ref_is_selected)
 {
-    ImGuiContext& g = *ImGui::GetCurrentContext();
+    ImGuiContext& g = *GImGui;
     ImGuiWindow* window = g.CurrentWindow;
 
-    IM_ASSERT(g.MultiSelectScopeId == 0);    // No recursion allowed yet (we could allow it if we deem it useful)
+    IM_ASSERT(g.MultiSelectEnabled == false);   // No recursion allowed yet (we could allow it if we deem it useful)
     IM_ASSERT(g.MultiSelectFlags == 0);
+    IM_ASSERT(g.MultiSelectState.FocusScopeId == 0);    
 
+    // FIXME: BeginFocusScope()
     ImGuiMultiSelectState* state = &g.MultiSelectState;
-    g.MultiSelectScopeId = window->IDStack.back();
-    g.MultiSelectScopeWindow = window;
-    g.MultiSelectFlags = flags;
     state->Clear();
+    state->BackupFocusScopeId = window->DC.NavFocusScopeIdCurrent;
+    state->FocusScopeId = window->DC.NavFocusScopeIdCurrent = window->IDStack.back();
+    g.MultiSelectEnabled = true;
+    g.MultiSelectFlags = flags;
 
     if ((flags & ImGuiMultiSelectFlags_NoMultiSelect) == 0)
     {
@@ -5811,7 +5814,7 @@
     }
 
     // Auto clear when using Navigation to move within the selection (we compare SelectScopeId so it possible to use multiple lists inside a same window)
-    if (g.NavJustMovedToId != 0 && g.NavJustMovedToFocusScopeId == g.MultiSelectScopeId)
+    if (g.NavJustMovedToId != 0 && g.NavJustMovedToFocusScopeId == state->FocusScopeId && g.NavJustMovedToHasSelectionData)
     {
         if (g.IO.KeyShift)
             state->InRequestSetRangeNav = true;
@@ -5834,14 +5837,19 @@
 
 ImGuiMultiSelectData* ImGui::EndMultiSelect()
 {
-    ImGuiContext& g = *ImGui::GetCurrentContext();
+    ImGuiContext& g = *GImGui;
+    ImGuiWindow* window = g.CurrentWindow;
     ImGuiMultiSelectState* state = &g.MultiSelectState;
-    IM_ASSERT(g.MultiSelectScopeId != 0);
+
+    IM_ASSERT(g.MultiSelectState.FocusScopeId != 0);
+    IM_ASSERT(g.MultiSelectState.FocusScopeId == window->DC.NavFocusScopeIdCurrent);
+
     if (g.MultiSelectFlags & ImGuiMultiSelectFlags_NoUnselect)
         state->Out.RangeValue = true;
-    g.MultiSelectScopeId = 0;
-    g.MultiSelectScopeWindow = NULL;
-    g.MultiSelectFlags = 0;
+    g.MultiSelectState.FocusScopeId = 0;
+    window->DC.NavFocusScopeIdCurrent = g.MultiSelectState.BackupFocusScopeId;
+    g.MultiSelectEnabled = false;
+    g.MultiSelectFlags = ImGuiMultiSelectFlags_None;
 
 #ifdef IMGUI_DEBUG_MULTISELECT
     if (state->Out.RequestClear)     printf("[%05d] EndMultiSelect: RequestClear\n", g.FrameCount);
@@ -5855,17 +5863,23 @@
 void ImGui::SetNextItemSelectionData(void* item_data)
 {
     ImGuiContext& g = *GImGui;
-    IM_ASSERT(g.MultiSelectScopeId != 0);
+    ImGuiWindow* window = g.CurrentWindow;
+    IM_ASSERT(window->DC.NavFocusScopeIdCurrent != 0);
     g.NextItemData.SelectionData = item_data;
-    g.NextItemData.MultiSelectScopeId = g.MultiSelectScopeId;
+    g.NextItemData.FocusScopeId = window->DC.NavFocusScopeIdCurrent;
+    
+    // Note that the flag will be cleared by ItemAdd(), so it's only useful for Navigation code!
+    // This designed so widgets can also cheaply set this before calling ItemAdd(), so we are not tied to MultiSelect api.
+    g.NextItemData.Flags |= ImGuiNextItemDataFlags_HasSelectionData;
 }
 
 void ImGui::MultiSelectItemHeader(ImGuiID id, bool* p_selected)
 {
     ImGuiContext& g = *GImGui;
+    ImGuiWindow* window = g.CurrentWindow;
     ImGuiMultiSelectState* state = &g.MultiSelectState;
 
-    IM_ASSERT(g.NextItemData.MultiSelectScopeId == g.MultiSelectScopeId && "Forgot to call SetNextItemSelectionData() prior to item, required in BeginMultiSelect()/EndMultiSelect() scope");
+    IM_ASSERT(g.NextItemData.FocusScopeId == window->DC.NavFocusScopeIdCurrent && "Forgot to call SetNextItemSelectionData() prior to item, required in BeginMultiSelect()/EndMultiSelect() scope");
     void* item_data = g.NextItemData.SelectionData;
 
     // Apply Clear/SelectAll requests requested by BeginMultiSelect().
@@ -5906,7 +5920,7 @@
     ImGuiMultiSelectState* state = &g.MultiSelectState;
 
     void* item_data = g.NextItemData.SelectionData;
-    g.NextItemData.MultiSelectScopeId = 0;
+    g.NextItemData.FocusScopeId = 0;
 
     bool selected = *p_selected;
     bool pressed = *p_pressed;