Browse Source

Merge branch 'master' into docking

# Conflicts:
#	imgui.cpp
#	imgui_demo.cpp
ocornut 1 year ago
parent
commit
2a6d7b1eaa
6 changed files with 155 additions and 117 deletions
  1. 37 26
      docs/CHANGELOG.txt
  2. 70 73
      imgui.cpp
  3. 8 9
      imgui.h
  4. 14 1
      imgui_demo.cpp
  5. 8 5
      imgui_internal.h
  6. 18 3
      imgui_tables.cpp

+ 37 - 26
docs/CHANGELOG.txt

@@ -67,15 +67,17 @@ Breaking changes:
 
 
 Other changes:
 Other changes:
 
 
-- Tooltips: made using SetItemTooltip()/IsItemHovered(ImGuiHoveredFlags_ForTooltip) defaults to
-  activate tooltips on disabled items. This is done by adding ImGuiHoveredFlags_AllowWhenDisabled
-  to the default value of style.HoverFlagsForTooltipMouse/HoverFlagsForTooltipNav. (#1485)
 - Nav: Tabbing always enable nav highlight when ImGuiConfigFlags_NavEnableKeyboard is set.
 - Nav: Tabbing always enable nav highlight when ImGuiConfigFlags_NavEnableKeyboard is set.
   Previously was inconsistent and only enabled when stepping through a non-input item.
   Previously was inconsistent and only enabled when stepping through a non-input item.
   (#6802, #3092, #5759, #787)
   (#6802, #3092, #5759, #787)
-- Separator(): Altered end-points to use more standard boundaries. (#205, #4787, #1643)
-  - Left position is always current cursor X position.
-  - Right position is always work-rect rightmost edge.
+- Windows:
+  - Popups: clarified meaning of 'p_open != NULL' in BeginPopupModal() + set back user value
+    to false when popup is closed in ways other than clicking the close button. (#6900)
+  - Can also auto-resize by double-clicking lower-left resize grip (not only lower-right one).
+- Separators:
+  - Altered end-points to use more standard boundaries. (#205, #4787, #1643)
+    Left position is always current cursor X position.
+    Right position is always work-rect rightmost edge.
   - Effectively means that:
   - Effectively means that:
     - A separator in the root of a window will end up a little more distant from edges
     - A separator in the root of a window will end up a little more distant from edges
       than previously (essentially following WindowPadding instead of clipping edges).
       than previously (essentially following WindowPadding instead of clipping edges).
@@ -87,13 +89,17 @@ Other changes:
   - Mostly legacy behavior when used inside old Columns(), as we favored that idiom back then,
   - Mostly legacy behavior when used inside old Columns(), as we favored that idiom back then,
     only different is left position follows indentation level, to match calling a Separator()
     only different is left position follows indentation level, to match calling a Separator()
     inside or outside Columns().
     inside or outside Columns().
-- Popups: clarified meaning of 'p_open != NULL' in BeginPopupModal() + set back user value
-  to false when popup is closed in ways other than clicking the close button. (#6900)
-- Drag and Drop: Rework drop target highlight: reduce rectangle to its visible portion, and
-  then expand slightly. A full rectangle is always visible and it may protrude slightly. (#4281, #3272)
-- Drag and Drop: Fixed submitting a tooltip from drop target location when using AcceptDragDropPayload()
-  with ImGuiDragDropFlags_AcceptNoPreviewTooltip and submitting a tooltip manually.
-- TreeNode: Added ImGuiTreeNodeFlags_SpanAllColumns for use in tables. (#3151, #3565, #2451, #2438)
+- Tooltips:
+  - Made using SetItemTooltip()/IsItemHovered(ImGuiHoveredFlags_ForTooltip) defaults to
+    activate tooltips on disabled items. This is done by adding ImGuiHoveredFlags_AllowWhenDisabled
+    to the default value of style.HoverFlagsForTooltipMouse/HoverFlagsForTooltipNav. (#1485)
+  - Made is possible to combine ImGuiHoveredFlags_ForTooltip with a ImGuiHoveredFlags_DelayXXX
+    override. (#1485)
+- Drag and Drop:
+  - Reworked drop target highlight: reduce rectangle to its visible portion, and
+    then expand slightly. A full rectangle is always visible and it may protrude slightly. (#4281, #3272)
+  - Fixed submitting a tooltip from drop target location when using AcceptDragDropPayload()
+    with ImGuiDragDropFlags_AcceptNoPreviewTooltip and submitting a tooltip manually.
 - Tables:
 - Tables:
   - Added angled headers support. You need to set ImGuiTableColumnFlags_AngledHeader on selected
   - Added angled headers support. You need to set ImGuiTableColumnFlags_AngledHeader on selected
     columns and call TableAngledHeadersRow(). Added style.TableAngledHeadersAngle style option.
     columns and call TableAngledHeadersRow(). Added style.TableAngledHeadersAngle style option.
@@ -105,18 +111,20 @@ Other changes:
     so a scrolling table can contribute to initial window size. (#6510)
     so a scrolling table can contribute to initial window size. (#6510)
   - Fixed subtle drawing overlap between borders in some situations.
   - Fixed subtle drawing overlap between borders in some situations.
   - Fixed bottom-most and right-most outer border offset by one. (#6765, #3752) [@v-ein]
   - Fixed bottom-most and right-most outer border offset by one. (#6765, #3752) [@v-ein]
+  - Fixed top-most and left-most outer border overlapping inner clip-rect when scrolling. (#6765)
   - Fixed top-most outer border being drawn with both TableBorderLight and TableBorderStrong
   - Fixed top-most outer border being drawn with both TableBorderLight and TableBorderStrong
     in some situations, causing the earlier to be visible underneath when alpha is not 1.0f.
     in some situations, causing the earlier to be visible underneath when alpha is not 1.0f.
-  - fixed right-clicking right-most section (past right-most column) from highlighting a column.
+  - Fixed right-clicking right-most section (past right-most column) from highlighting a column.
+  - Fixed an issue with ScrollX enabled where an extraneous draw command would be created.
+- Menus:
+  - Menus: Fixed a bug where activating an item in a child-menu and dragging mouse over the
+    parent-menu would erroneously close the child-menu. (Regression from 1.88). (#6869)
+  - MenuBar: Fixed an issue where layouting an item in the menu-bar would erroneously
+    register contents size in a way that would affect the scrolling layer.
+    Was most often noticable when using an horizontal scrollbar. (#6789)
+- TreeNode: Added ImGuiTreeNodeFlags_SpanAllColumns for use in tables. (#3151, #3565, #2451, #2438)
 - TabBar: Fixed position of unsaved document marker (ImGuiTabItemFlags_UnsavedDocument) which was
 - TabBar: Fixed position of unsaved document marker (ImGuiTabItemFlags_UnsavedDocument) which was
   accidentally offset in 1.89.9. (#6862) [@alektron]
   accidentally offset in 1.89.9. (#6862) [@alektron]
-- Fonts: 'float size_pixels' passed to AddFontXXX() functions is now rounded to lowest integer.
-  This is because our layout/font system currently doesn't fully support non-integer sizes. Until
-  it does, this has been a common pitfall leading to more or less subtle issues. (#3164, #3309, #6800)
-- Fonts: Better assert during load when passing truncated font data or wrong data size. (#6822)
-- Fonts: Ensure calling AddFontXXX function doesn't invalidates ImFont's ConfigData pointers
-  prior to building again. (#6825)
-- Fonts, imgui_freetype: Fixed a warning and leak in IMGUI_ENABLE_FREETYPE_LUNASVG support. (#6842, #6591)
 - InputTextMultiline: Fixed a crash pressing Down on last empty line of a multiline buffer.
 - InputTextMultiline: Fixed a crash pressing Down on last empty line of a multiline buffer.
   (regression from 1.89.2, only happened in some states). (#6783, #6000)
   (regression from 1.89.2, only happened in some states). (#6783, #6000)
 - InputTextMultiline: Fixed Tabbing cycle leading to a situation where Enter key wouldn't
 - InputTextMultiline: Fixed Tabbing cycle leading to a situation where Enter key wouldn't
@@ -125,11 +133,14 @@ Other changes:
   to SameLine() followed by manual cursor manipulation.
   to SameLine() followed by manual cursor manipulation.
 - BeginCombo(): Added ImGuiComboFlags_WidthFitPreview flag. (#6881) [@mpv-enjoyer]
 - BeginCombo(): Added ImGuiComboFlags_WidthFitPreview flag. (#6881) [@mpv-enjoyer]
 - BeginListBox(): Fixed not consuming SetNextWindowXXX data when returning false.
 - BeginListBox(): Fixed not consuming SetNextWindowXXX data when returning false.
-- Menus: Fixed a bug where activating an item in a child-menu and dragging mouse over the
-  parent-menu would erroneously close the child-menu. (Regression from 1.88). (#6869)
-- MenuBar: Fixed an issue where layouting an item in the menu-bar would erroneously
-  register contents size in a way that would affect the scrolling layer.
-  Was most often noticable when using an horizontal scrollbar. (#6789)
+- Fonts:
+  - Arument 'float size_pixels' passed to AddFontXXX() functions is now rounded to lowest integer.
+    This is because our layout/font system currently doesn't fully support non-integer sizes. Until
+    it does, this has been a common pitfall leading to more or less subtle issues. (#3164, #3309, #6800)
+  - Better assert during load when passing truncated font data or wrong data size. (#6822)
+  - Ensure calling AddFontXXX function doesn't invalidates ImFont's ConfigData pointers
+    prior to building again. (#6825)
+  - imgui_freetype: Fixed a warning and leak in IMGUI_ENABLE_FREETYPE_LUNASVG support. (#6842, #6591)
 - Misc: Most text functions also treat "%.*s" (along with "%s") specially to avoid formatting. (#3466, #6846)
 - Misc: Most text functions also treat "%.*s" (along with "%s") specially to avoid formatting. (#3466, #6846)
 - IO: Add extra keys to ImGuiKey enum: ImGuiKey_F13 to ImGuiKey_F24. (#6891, #4921)
 - IO: Add extra keys to ImGuiKey enum: ImGuiKey_F13 to ImGuiKey_F24. (#6891, #4921)
 - IO: Add extra keys to ImGuiKey enum: ImGuiKey_AppBack, ImGuiKey_AppForward. (#4921)
 - IO: Add extra keys to ImGuiKey enum: ImGuiKey_AppBack, ImGuiKey_AppForward. (#4921)

+ 70 - 73
imgui.cpp

@@ -2538,11 +2538,9 @@ void ImGuiStorage::SetInt(ImGuiID key, int val)
 {
 {
     ImGuiStoragePair* it = LowerBound(Data, key);
     ImGuiStoragePair* it = LowerBound(Data, key);
     if (it == Data.end() || it->key != key)
     if (it == Data.end() || it->key != key)
-    {
         Data.insert(it, ImGuiStoragePair(key, val));
         Data.insert(it, ImGuiStoragePair(key, val));
-        return;
-    }
-    it->val_i = val;
+    else
+        it->val_i = val;
 }
 }
 
 
 void ImGuiStorage::SetBool(ImGuiID key, bool val)
 void ImGuiStorage::SetBool(ImGuiID key, bool val)
@@ -2554,22 +2552,18 @@ void ImGuiStorage::SetFloat(ImGuiID key, float val)
 {
 {
     ImGuiStoragePair* it = LowerBound(Data, key);
     ImGuiStoragePair* it = LowerBound(Data, key);
     if (it == Data.end() || it->key != key)
     if (it == Data.end() || it->key != key)
-    {
         Data.insert(it, ImGuiStoragePair(key, val));
         Data.insert(it, ImGuiStoragePair(key, val));
-        return;
-    }
-    it->val_f = val;
+    else
+        it->val_f = val;
 }
 }
 
 
 void ImGuiStorage::SetVoidPtr(ImGuiID key, void* val)
 void ImGuiStorage::SetVoidPtr(ImGuiID key, void* val)
 {
 {
     ImGuiStoragePair* it = LowerBound(Data, key);
     ImGuiStoragePair* it = LowerBound(Data, key);
     if (it == Data.end() || it->key != key)
     if (it == Data.end() || it->key != key)
-    {
         Data.insert(it, ImGuiStoragePair(key, val));
         Data.insert(it, ImGuiStoragePair(key, val));
-        return;
-    }
-    it->val_p = val;
+    else
+        it->val_p = val;
 }
 }
 
 
 void ImGuiStorage::SetAllInt(int v)
 void ImGuiStorage::SetAllInt(int v)
@@ -4098,13 +4092,21 @@ bool ImGui::IsWindowContentHoverable(ImGuiWindow* window, ImGuiHoveredFlags flag
 static inline float CalcDelayFromHoveredFlags(ImGuiHoveredFlags flags)
 static inline float CalcDelayFromHoveredFlags(ImGuiHoveredFlags flags)
 {
 {
     ImGuiContext& g = *GImGui;
     ImGuiContext& g = *GImGui;
-    if (flags & ImGuiHoveredFlags_DelayShort)
-        return g.Style.HoverDelayShort;
     if (flags & ImGuiHoveredFlags_DelayNormal)
     if (flags & ImGuiHoveredFlags_DelayNormal)
         return g.Style.HoverDelayNormal;
         return g.Style.HoverDelayNormal;
+    if (flags & ImGuiHoveredFlags_DelayShort)
+        return g.Style.HoverDelayShort;
     return 0.0f;
     return 0.0f;
 }
 }
 
 
+static ImGuiHoveredFlags ApplyHoverFlagsForTooltip(ImGuiHoveredFlags user_flags, ImGuiHoveredFlags shared_flags)
+{
+    // Allow instance flags to override shared flags
+    if (user_flags & (ImGuiHoveredFlags_DelayNone | ImGuiHoveredFlags_DelayShort | ImGuiHoveredFlags_DelayNormal))
+        shared_flags &= ~(ImGuiHoveredFlags_DelayNone | ImGuiHoveredFlags_DelayShort | ImGuiHoveredFlags_DelayNormal);
+    return user_flags | shared_flags;
+}
+
 // This is roughly matching the behavior of internal-facing ItemHoverable()
 // This is roughly matching the behavior of internal-facing ItemHoverable()
 // - we allow hovering to be true when ActiveId==window->MoveID, so that clicking on non-interactive items such as a Text() item still returns true with IsItemHovered()
 // - we allow hovering to be true when ActiveId==window->MoveID, so that clicking on non-interactive items such as a Text() item still returns true with IsItemHovered()
 // - this should work even for non-interactive items that have no ID, so we cannot use LastItemId
 // - this should work even for non-interactive items that have no ID, so we cannot use LastItemId
@@ -4122,7 +4124,7 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags)
             return false;
             return false;
 
 
         if (flags & ImGuiHoveredFlags_ForTooltip)
         if (flags & ImGuiHoveredFlags_ForTooltip)
-            flags |= g.Style.HoverFlagsForTooltipNav;
+            flags = ApplyHoverFlagsForTooltip(flags, g.Style.HoverFlagsForTooltipNav);
     }
     }
     else
     else
     {
     {
@@ -4132,7 +4134,7 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags)
             return false;
             return false;
 
 
         if (flags & ImGuiHoveredFlags_ForTooltip)
         if (flags & ImGuiHoveredFlags_ForTooltip)
-            flags |= g.Style.HoverFlagsForTooltipMouse;
+            flags = ApplyHoverFlagsForTooltip(flags, g.Style.HoverFlagsForTooltipMouse);
 
 
         IM_ASSERT((flags & (ImGuiHoveredFlags_AnyWindow | ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_NoPopupHierarchy | ImGuiHoveredFlags_DockHierarchy)) == 0);   // Flags not supported by this function
         IM_ASSERT((flags & (ImGuiHoveredFlags_AnyWindow | ImGuiHoveredFlags_RootWindow | ImGuiHoveredFlags_ChildWindows | ImGuiHoveredFlags_NoPopupHierarchy | ImGuiHoveredFlags_DockHierarchy)) == 0);   // Flags not supported by this function
 
 
@@ -5686,18 +5688,28 @@ ImVec2 ImGui::GetItemRectSize()
     return g.LastItemData.Rect.GetSize();
     return g.LastItemData.Rect.GetSize();
 }
 }
 
 
-bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags flags)
+bool ImGui::BeginChild(const char* str_id, const ImVec2& size_arg, bool border, ImGuiWindowFlags window_flags)
+{
+    ImGuiID id = GetCurrentWindow()->GetID(str_id);
+    return BeginChildEx(str_id, id, size_arg, border, window_flags);
+}
+
+bool ImGui::BeginChild(ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags window_flags)
+{
+    IM_ASSERT(id != 0);
+    return BeginChildEx(NULL, id, size_arg, border, window_flags);
+}
+
+bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags window_flags)
 {
 {
     ImGuiContext& g = *GImGui;
     ImGuiContext& g = *GImGui;
     ImGuiWindow* parent_window = g.CurrentWindow;
     ImGuiWindow* parent_window = g.CurrentWindow;
-
-    flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_NoDocking;
-    flags |= (parent_window->Flags & ImGuiWindowFlags_NoMove);  // Inherit the NoMove flag
+    window_flags |= ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_NoDocking;
+    window_flags |= (parent_window->Flags & ImGuiWindowFlags_NoMove);  // Inherit the NoMove flag
 
 
     // Size
     // Size
     const ImVec2 content_avail = GetContentRegionAvail();
     const ImVec2 content_avail = GetContentRegionAvail();
     ImVec2 size = ImTrunc(size_arg);
     ImVec2 size = ImTrunc(size_arg);
-    const int auto_fit_axises = ((size.x == 0.0f) ? (1 << ImGuiAxis_X) : 0x00) | ((size.y == 0.0f) ? (1 << ImGuiAxis_Y) : 0x00);
     if (size.x <= 0.0f)
     if (size.x <= 0.0f)
         size.x = ImMax(content_avail.x + size.x, 4.0f); // Arbitrary minimum child size (0.0f causing too many issues)
         size.x = ImMax(content_avail.x + size.x, 4.0f); // Arbitrary minimum child size (0.0f causing too many issues)
     if (size.y <= 0.0f)
     if (size.y <= 0.0f)
@@ -5714,12 +5726,13 @@ bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, b
     const float backup_border_size = g.Style.ChildBorderSize;
     const float backup_border_size = g.Style.ChildBorderSize;
     if (!border)
     if (!border)
         g.Style.ChildBorderSize = 0.0f;
         g.Style.ChildBorderSize = 0.0f;
-    bool ret = Begin(temp_window_name, NULL, flags);
+
+    // Begin into window
+    const bool ret = Begin(temp_window_name, NULL, window_flags);
     g.Style.ChildBorderSize = backup_border_size;
     g.Style.ChildBorderSize = backup_border_size;
 
 
     ImGuiWindow* child_window = g.CurrentWindow;
     ImGuiWindow* child_window = g.CurrentWindow;
     child_window->ChildId = id;
     child_window->ChildId = id;
-    child_window->AutoFitChildAxises = (ImS8)auto_fit_axises;
 
 
     // Set the cursor to handle case where the user called SetNextWindowPos()+BeginChild() manually.
     // Set the cursor to handle case where the user called SetNextWindowPos()+BeginChild() manually.
     // While this is not really documented/defined, it seems that the expected thing to do.
     // While this is not really documented/defined, it seems that the expected thing to do.
@@ -5727,11 +5740,11 @@ bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, b
         parent_window->DC.CursorPos = child_window->Pos;
         parent_window->DC.CursorPos = child_window->Pos;
 
 
     // Process navigation-in immediately so NavInit can run on first frame
     // Process navigation-in immediately so NavInit can run on first frame
-    // Can enter a child if (A) it has navigatable items or (B) it can be scrolled.
+    // Can enter a child if (A) it has navigable items or (B) it can be scrolled.
     const ImGuiID temp_id_for_activation = ImHashStr("##Child", 0, id);
     const ImGuiID temp_id_for_activation = ImHashStr("##Child", 0, id);
     if (g.ActiveId == temp_id_for_activation)
     if (g.ActiveId == temp_id_for_activation)
         ClearActiveID();
         ClearActiveID();
-    if (g.NavActivateId == id && !(flags & ImGuiWindowFlags_NavFlattened) && (child_window->DC.NavLayersActiveMask != 0 || child_window->DC.NavWindowHasScrollY))
+    if (g.NavActivateId == id && !(window_flags & ImGuiWindowFlags_NavFlattened) && (child_window->DC.NavLayersActiveMask != 0 || child_window->DC.NavWindowHasScrollY))
     {
     {
         FocusWindow(child_window);
         FocusWindow(child_window);
         NavInitWindow(child_window, false);
         NavInitWindow(child_window, false);
@@ -5741,50 +5754,29 @@ bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, b
     return ret;
     return ret;
 }
 }
 
 
-bool ImGui::BeginChild(const char* str_id, const ImVec2& size_arg, bool border, ImGuiWindowFlags extra_flags)
-{
-    ImGuiWindow* window = GetCurrentWindow();
-    return BeginChildEx(str_id, window->GetID(str_id), size_arg, border, extra_flags);
-}
-
-bool ImGui::BeginChild(ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags extra_flags)
-{
-    IM_ASSERT(id != 0);
-    return BeginChildEx(NULL, id, size_arg, border, extra_flags);
-}
-
 void ImGui::EndChild()
 void ImGui::EndChild()
 {
 {
     ImGuiContext& g = *GImGui;
     ImGuiContext& g = *GImGui;
-    ImGuiWindow* window = g.CurrentWindow;
+    ImGuiWindow* child_window = g.CurrentWindow;
 
 
     IM_ASSERT(g.WithinEndChild == false);
     IM_ASSERT(g.WithinEndChild == false);
-    IM_ASSERT(window->Flags & ImGuiWindowFlags_ChildWindow);   // Mismatched BeginChild()/EndChild() calls
+    IM_ASSERT(child_window->Flags & ImGuiWindowFlags_ChildWindow);   // Mismatched BeginChild()/EndChild() calls
 
 
     g.WithinEndChild = true;
     g.WithinEndChild = true;
-    if (window->BeginCount > 1)
-    {
-        End();
-    }
-    else
+    ImVec2 child_size = child_window->Size;
+    End();
+    if (child_window->BeginCount == 1)
     {
     {
-        ImVec2 sz = window->Size;
-        if (window->AutoFitChildAxises & (1 << ImGuiAxis_X)) // Arbitrary minimum zero-ish child size of 4.0f causes less trouble than a 0.0f
-            sz.x = ImMax(4.0f, sz.x);
-        if (window->AutoFitChildAxises & (1 << ImGuiAxis_Y))
-            sz.y = ImMax(4.0f, sz.y);
-        End();
-
         ImGuiWindow* parent_window = g.CurrentWindow;
         ImGuiWindow* parent_window = g.CurrentWindow;
-        ImRect bb(parent_window->DC.CursorPos, parent_window->DC.CursorPos + sz);
-        ItemSize(sz);
-        if ((window->DC.NavLayersActiveMask != 0 || window->DC.NavWindowHasScrollY) && !(window->Flags & ImGuiWindowFlags_NavFlattened))
+        ImRect bb(parent_window->DC.CursorPos, parent_window->DC.CursorPos + child_size);
+        ItemSize(child_size);
+        if ((child_window->DC.NavLayersActiveMask != 0 || child_window->DC.NavWindowHasScrollY) && !(child_window->Flags & ImGuiWindowFlags_NavFlattened))
         {
         {
-            ItemAdd(bb, window->ChildId);
-            RenderNavHighlight(bb, window->ChildId);
+            ItemAdd(bb, child_window->ChildId);
+            RenderNavHighlight(bb, child_window->ChildId);
 
 
             // When browsing a window that has no activable items (scroll only) we keep a highlight on the child (pass g.NavId to trick into always displaying)
             // When browsing a window that has no activable items (scroll only) we keep a highlight on the child (pass g.NavId to trick into always displaying)
-            if (window->DC.NavLayersActiveMask == 0 && window == g.NavWindow)
+            if (child_window->DC.NavLayersActiveMask == 0 && child_window == g.NavWindow)
                 RenderNavHighlight(ImRect(bb.Min - ImVec2(2, 2), bb.Max + ImVec2(2, 2)), g.NavId, ImGuiNavHighlightFlags_TypeThin);
                 RenderNavHighlight(ImRect(bb.Min - ImVec2(2, 2), bb.Max + ImVec2(2, 2)), g.NavId, ImGuiNavHighlightFlags_TypeThin);
         }
         }
         else
         else
@@ -5793,10 +5785,10 @@ void ImGui::EndChild()
             ItemAdd(bb, 0);
             ItemAdd(bb, 0);
 
 
             // But when flattened we directly reach items, adjust active layer mask accordingly
             // But when flattened we directly reach items, adjust active layer mask accordingly
-            if (window->Flags & ImGuiWindowFlags_NavFlattened)
-                parent_window->DC.NavLayersActiveMaskNext |= window->DC.NavLayersActiveMaskNext;
+            if (child_window->Flags & ImGuiWindowFlags_NavFlattened)
+                parent_window->DC.NavLayersActiveMaskNext |= child_window->DC.NavLayersActiveMaskNext;
         }
         }
-        if (g.HoveredWindow == window)
+        if (g.HoveredWindow == child_window)
             g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HoveredWindow;
             g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_HoveredWindow;
     }
     }
     g.WithinEndChild = false;
     g.WithinEndChild = false;
@@ -6202,7 +6194,7 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s
         if (hovered || held)
         if (hovered || held)
             g.MouseCursor = (resize_grip_n & 1) ? ImGuiMouseCursor_ResizeNESW : ImGuiMouseCursor_ResizeNWSE;
             g.MouseCursor = (resize_grip_n & 1) ? ImGuiMouseCursor_ResizeNESW : ImGuiMouseCursor_ResizeNWSE;
 
 
-        if (held && g.IO.MouseClickedCount[0] == 2 && resize_grip_n == 0)
+        if (held && g.IO.MouseClickedCount[0] == 2)
         {
         {
             // Manual auto-fit when double-clicking
             // Manual auto-fit when double-clicking
             size_target = CalcWindowSizeAfterConstraint(window, size_auto_fit);
             size_target = CalcWindowSizeAfterConstraint(window, size_auto_fit);
@@ -6731,7 +6723,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
         window->IDStack.push_back(window->ID);
         window->IDStack.push_back(window->ID);
 
 
     // Add to stack
     // Add to stack
-    // We intentionally set g.CurrentWindow to NULL to prevent usage until when the viewport is set, then will call SetCurrentWindow()
     g.CurrentWindow = window;
     g.CurrentWindow = window;
     ImGuiWindowStackData window_stack_data;
     ImGuiWindowStackData window_stack_data;
     window_stack_data.Window = window;
     window_stack_data.Window = window;
@@ -6749,6 +6740,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
     }
     }
 
 
     // Add to focus scope stack
     // Add to focus scope stack
+    // We intentionally set g.CurrentWindow to NULL to prevent usage until when the viewport is set, then will call SetCurrentWindow()
     PushFocusScope(window->ID);
     PushFocusScope(window->ID);
     window->NavRootFocusScopeId = g.CurrentFocusScopeId;
     window->NavRootFocusScopeId = g.CurrentFocusScopeId;
     g.CurrentWindow = NULL;
     g.CurrentWindow = NULL;
@@ -7934,7 +7926,7 @@ bool ImGui::IsWindowHovered(ImGuiHoveredFlags flags)
     // for different windows of the hierarchy. Possibly need a Hash(Current+Flags) ==> (Timer) cache.
     // for different windows of the hierarchy. Possibly need a Hash(Current+Flags) ==> (Timer) cache.
     // We can implement this for _Stationary because the data is linked to HoveredWindow rather than CurrentWindow.
     // We can implement this for _Stationary because the data is linked to HoveredWindow rather than CurrentWindow.
     if (flags & ImGuiHoveredFlags_ForTooltip)
     if (flags & ImGuiHoveredFlags_ForTooltip)
-        flags |= g.Style.HoverFlagsForTooltipMouse;
+        flags = ApplyHoverFlagsForTooltip(flags, g.Style.HoverFlagsForTooltipMouse);
     if ((flags & ImGuiHoveredFlags_Stationary) != 0 && g.HoverWindowUnlockedStationaryId != ref_window->ID)
     if ((flags & ImGuiHoveredFlags_Stationary) != 0 && g.HoverWindowUnlockedStationaryId != ref_window->ID)
         return false;
         return false;
 
 
@@ -9758,16 +9750,10 @@ void ImGui::SetItemKeyOwner(ImGuiKey key, ImGuiInputFlags flags)
     }
     }
 }
 }
 
 
-bool ImGui::Shortcut(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiInputFlags flags)
+// This is equivalent to comparing KeyMods + doing a IsKeyPressed()
+bool ImGui::IsKeyChordPressed(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiInputFlags flags)
 {
 {
     ImGuiContext& g = *GImGui;
     ImGuiContext& g = *GImGui;
-
-    // When using (owner_id == 0/Any): SetShortcutRouting() will use CurrentFocusScopeId and filter with this, so IsKeyPressed() is fine with he 0/Any.
-    if ((flags & ImGuiInputFlags_RouteMask_) == 0)
-        flags |= ImGuiInputFlags_RouteFocused;
-    if (!SetShortcutRouting(key_chord, owner_id, flags))
-        return false;
-
     if (key_chord & ImGuiMod_Shortcut)
     if (key_chord & ImGuiMod_Shortcut)
         key_chord = ConvertShortcutMod(key_chord);
         key_chord = ConvertShortcutMod(key_chord);
     ImGuiKey mods = (ImGuiKey)(key_chord & ImGuiMod_Mask_);
     ImGuiKey mods = (ImGuiKey)(key_chord & ImGuiMod_Mask_);
@@ -9778,11 +9764,22 @@ bool ImGui::Shortcut(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiInputFlags
     ImGuiKey key = (ImGuiKey)(key_chord & ~ImGuiMod_Mask_);
     ImGuiKey key = (ImGuiKey)(key_chord & ~ImGuiMod_Mask_);
     if (key == ImGuiKey_None)
     if (key == ImGuiKey_None)
         key = ConvertSingleModFlagToKey(&g, mods);
         key = ConvertSingleModFlagToKey(&g, mods);
-
     if (!IsKeyPressed(key, owner_id, (flags & (ImGuiInputFlags_Repeat | (ImGuiInputFlags)ImGuiInputFlags_RepeatRateMask_))))
     if (!IsKeyPressed(key, owner_id, (flags & (ImGuiInputFlags_Repeat | (ImGuiInputFlags)ImGuiInputFlags_RepeatRateMask_))))
         return false;
         return false;
-    IM_ASSERT((flags & ~ImGuiInputFlags_SupportedByShortcut) == 0); // Passing flags not supported by this function!
+    return true;
+}
 
 
+bool ImGui::Shortcut(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiInputFlags flags)
+{
+    // When using (owner_id == 0/Any): SetShortcutRouting() will use CurrentFocusScopeId and filter with this, so IsKeyPressed() is fine with he 0/Any.
+    if ((flags & ImGuiInputFlags_RouteMask_) == 0)
+        flags |= ImGuiInputFlags_RouteFocused;
+    if (!SetShortcutRouting(key_chord, owner_id, flags))
+        return false;
+
+    if (!IsKeyChordPressed(key_chord, owner_id, flags))
+        return false;
+    IM_ASSERT((flags & ~ImGuiInputFlags_SupportedByShortcut) == 0); // Passing flags not supported by this function!
     return true;
     return true;
 }
 }
 
 

+ 8 - 9
imgui.h

@@ -349,8 +349,8 @@ namespace ImGui
     //   [Important: due to legacy reason, this is inconsistent with most other functions such as BeginMenu/EndMenu,
     //   [Important: due to legacy reason, this is inconsistent with most other functions such as BeginMenu/EndMenu,
     //    BeginPopup/EndPopup, etc. where the EndXXX call should only be called if the corresponding BeginXXX function
     //    BeginPopup/EndPopup, etc. where the EndXXX call should only be called if the corresponding BeginXXX function
     //    returned true. Begin and BeginChild are the only odd ones out. Will be fixed in a future update.]
     //    returned true. Begin and BeginChild are the only odd ones out. Will be fixed in a future update.]
-    IMGUI_API bool          BeginChild(const char* str_id, const ImVec2& size = ImVec2(0, 0), bool border = false, ImGuiWindowFlags flags = 0);
-    IMGUI_API bool          BeginChild(ImGuiID id, const ImVec2& size = ImVec2(0, 0), bool border = false, ImGuiWindowFlags flags = 0);
+    IMGUI_API bool          BeginChild(const char* str_id, const ImVec2& size = ImVec2(0, 0), bool border = false, ImGuiWindowFlags window_flags = 0);
+    IMGUI_API bool          BeginChild(ImGuiID id, const ImVec2& size = ImVec2(0, 0), bool border = false, ImGuiWindowFlags window_flags = 0);
     IMGUI_API void          EndChild();
     IMGUI_API void          EndChild();
 
 
     // Windows Utilities
     // Windows Utilities
@@ -2465,9 +2465,9 @@ struct ImGuiStorage
     {
     {
         ImGuiID key;
         ImGuiID key;
         union { int val_i; float val_f; void* val_p; };
         union { int val_i; float val_f; void* val_p; };
-        ImGuiStoragePair(ImGuiID _key, int _val_i)      { key = _key; val_i = _val_i; }
-        ImGuiStoragePair(ImGuiID _key, float _val_f)    { key = _key; val_f = _val_f; }
-        ImGuiStoragePair(ImGuiID _key, void* _val_p)    { key = _key; val_p = _val_p; }
+        ImGuiStoragePair(ImGuiID _key, int _val)    { key = _key; val_i = _val; }
+        ImGuiStoragePair(ImGuiID _key, float _val)  { key = _key; val_f = _val; }
+        ImGuiStoragePair(ImGuiID _key, void* _val)  { key = _key; val_p = _val; }
     };
     };
 
 
     ImVector<ImGuiStoragePair>      Data;
     ImVector<ImGuiStoragePair>      Data;
@@ -2494,11 +2494,10 @@ struct ImGuiStorage
     IMGUI_API float*    GetFloatRef(ImGuiID key, float default_val = 0.0f);
     IMGUI_API float*    GetFloatRef(ImGuiID key, float default_val = 0.0f);
     IMGUI_API void**    GetVoidPtrRef(ImGuiID key, void* default_val = NULL);
     IMGUI_API void**    GetVoidPtrRef(ImGuiID key, void* default_val = NULL);
 
 
-    // Use on your own storage if you know only integer are being stored (open/close all tree nodes)
-    IMGUI_API void      SetAllInt(int val);
-
-    // For quicker full rebuild of a storage (instead of an incremental one), you may add all your contents and then sort once.
+    // Advanced: for quicker full rebuild of a storage (instead of an incremental one), you may add all your contents and then sort once.
     IMGUI_API void      BuildSortByKey();
     IMGUI_API void      BuildSortByKey();
+    // Obsolete: use on your own storage if you know only integer are being stored (open/close all tree nodes)
+    IMGUI_API void      SetAllInt(int val);
 };
 };
 
 
 // Helper: Manually clip large list of items.
 // Helper: Manually clip large list of items.

+ 14 - 1
imgui_demo.cpp

@@ -1256,6 +1256,14 @@ static void ShowDemoWindowWidgets()
         if (ImGui::CheckboxFlags("ImGuiComboFlags_WidthFitPreview", &flags, ImGuiComboFlags_WidthFitPreview))
         if (ImGui::CheckboxFlags("ImGuiComboFlags_WidthFitPreview", &flags, ImGuiComboFlags_WidthFitPreview))
             flags &= ~ImGuiComboFlags_NoPreview;
             flags &= ~ImGuiComboFlags_NoPreview;
 
 
+        // Override default popup height
+        if (ImGui::CheckboxFlags("ImGuiComboFlags_HeightSmall", &flags, ImGuiComboFlags_HeightSmall))
+            flags &= ~(ImGuiComboFlags_HeightMask_ & ~ImGuiComboFlags_HeightSmall);
+        if (ImGui::CheckboxFlags("ImGuiComboFlags_HeightRegular", &flags, ImGuiComboFlags_HeightRegular))
+            flags &= ~(ImGuiComboFlags_HeightMask_ & ~ImGuiComboFlags_HeightRegular);
+        if (ImGui::CheckboxFlags("ImGuiComboFlags_HeightLargest", &flags, ImGuiComboFlags_HeightLargest))
+            flags &= ~(ImGuiComboFlags_HeightMask_ & ~ImGuiComboFlags_HeightLargest);
+
         // Using the generic BeginCombo() API, you have full control over how to display the combo contents.
         // Using the generic BeginCombo() API, you have full control over how to display the combo contents.
         // (your selection data could be an index, a pointer to the object, an id for the object, a flag intrusively
         // (your selection data could be an index, a pointer to the object, an id for the object, a flag intrusively
         // stored in the object itself, etc.)
         // stored in the object itself, etc.)
@@ -1277,6 +1285,10 @@ static void ShowDemoWindowWidgets()
             ImGui::EndCombo();
             ImGui::EndCombo();
         }
         }
 
 
+        ImGui::Spacing();
+        ImGui::SeparatorText("One-liner variants");
+        HelpMarker("Flags above don't apply to this section.");
+
         // Simplified one-liner Combo() API, using values packed in a single constant string
         // Simplified one-liner Combo() API, using values packed in a single constant string
         // This is a convenience for when the selection set is small and known at compile-time.
         // This is a convenience for when the selection set is small and known at compile-time.
         static int item_current_2 = 0;
         static int item_current_2 = 0;
@@ -5283,6 +5295,7 @@ static void ShowDemoWindowTables()
         ImGui::CheckboxFlags("_HighlightHoveredColumn", &table_flags, ImGuiTableFlags_HighlightHoveredColumn);
         ImGui::CheckboxFlags("_HighlightHoveredColumn", &table_flags, ImGuiTableFlags_HighlightHoveredColumn);
         ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8);
         ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8);
         ImGui::SliderInt("Frozen columns", &frozen_cols, 0, 2);
         ImGui::SliderInt("Frozen columns", &frozen_cols, 0, 2);
+        ImGui::SetNextItemWidth(ImGui::GetFontSize() * 8);
         ImGui::SliderInt("Frozen rows", &frozen_rows, 0, 2);
         ImGui::SliderInt("Frozen rows", &frozen_rows, 0, 2);
 
 
         if (ImGui::BeginTable("table_angled_headers", columns_count, table_flags, ImVec2(0.0f, TEXT_BASE_HEIGHT * 12)))
         if (ImGui::BeginTable("table_angled_headers", columns_count, table_flags, ImVec2(0.0f, TEXT_BASE_HEIGHT * 12)))
@@ -6661,7 +6674,7 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
                 "Right-click to open edit options menu.");
                 "Right-click to open edit options menu.");
 
 
             ImGui::BeginChild("##colors", ImVec2(0, 0), true, ImGuiWindowFlags_AlwaysVerticalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar | ImGuiWindowFlags_NavFlattened);
             ImGui::BeginChild("##colors", ImVec2(0, 0), true, ImGuiWindowFlags_AlwaysVerticalScrollbar | ImGuiWindowFlags_AlwaysHorizontalScrollbar | ImGuiWindowFlags_NavFlattened);
-            ImGui::PushItemWidth(-160);
+            ImGui::PushItemWidth(ImGui::GetFontSize() * -12);
             for (int i = 0; i < ImGuiCol_COUNT; i++)
             for (int i = 0; i < ImGuiCol_COUNT; i++)
             {
             {
                 const char* name = ImGui::GetStyleColorName(i);
                 const char* name = ImGui::GetStyleColorName(i);

+ 8 - 5
imgui_internal.h

@@ -1272,9 +1272,9 @@ struct IMGUI_API ImGuiStackSizes
 // Data saved for each window pushed into the stack
 // Data saved for each window pushed into the stack
 struct ImGuiWindowStackData
 struct ImGuiWindowStackData
 {
 {
-    ImGuiWindow*            Window;
-    ImGuiLastItemData       ParentLastItemDataBackup;
-    ImGuiStackSizes         StackSizesOnBegin;      // Store size of various stacks for asserting
+    ImGuiWindow*        Window;
+    ImGuiLastItemData   ParentLastItemDataBackup;
+    ImGuiStackSizes     StackSizesOnBegin;      // Store size of various stacks for asserting
 };
 };
 
 
 struct ImGuiShrinkWidthItem
 struct ImGuiShrinkWidthItem
@@ -2660,7 +2660,6 @@ struct IMGUI_API ImGuiWindow
     short                   FocusOrder;                         // Order within WindowsFocusOrder[], altered when windows are focused.
     short                   FocusOrder;                         // Order within WindowsFocusOrder[], altered when windows are focused.
     ImGuiID                 PopupId;                            // ID in the popup stack when this window is used as a popup/menu (because we use generic Name/ID for recycling)
     ImGuiID                 PopupId;                            // ID in the popup stack when this window is used as a popup/menu (because we use generic Name/ID for recycling)
     ImS8                    AutoFitFramesX, AutoFitFramesY;
     ImS8                    AutoFitFramesX, AutoFitFramesY;
-    ImS8                    AutoFitChildAxises;
     bool                    AutoFitOnlyGrows;
     bool                    AutoFitOnlyGrows;
     ImGuiDir                AutoPosLastDirection;
     ImGuiDir                AutoPosLastDirection;
     ImS8                    HiddenFramesCanSkipItems;           // Hide the window for N frames
     ImS8                    HiddenFramesCanSkipItems;           // Hide the window for N frames
@@ -3256,7 +3255,7 @@ namespace ImGui
     IMGUI_API void          LogSetNextTextDecoration(const char* prefix, const char* suffix);
     IMGUI_API void          LogSetNextTextDecoration(const char* prefix, const char* suffix);
 
 
     // Popups, Modals, Tooltips
     // Popups, Modals, Tooltips
-    IMGUI_API bool          BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags flags);
+    IMGUI_API bool          BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, bool border, ImGuiWindowFlags window_flags);
     IMGUI_API void          OpenPopupEx(ImGuiID id, ImGuiPopupFlags popup_flags = ImGuiPopupFlags_None);
     IMGUI_API void          OpenPopupEx(ImGuiID id, ImGuiPopupFlags popup_flags = ImGuiPopupFlags_None);
     IMGUI_API void          ClosePopupToLevel(int remaining, bool restore_focus_to_window_under_popup);
     IMGUI_API void          ClosePopupToLevel(int remaining, bool restore_focus_to_window_under_popup);
     IMGUI_API void          ClosePopupsOverWindow(ImGuiWindow* ref_window, bool restore_focus_to_window_under_popup);
     IMGUI_API void          ClosePopupsOverWindow(ImGuiWindow* ref_window, bool restore_focus_to_window_under_popup);
@@ -3380,6 +3379,10 @@ namespace ImGui
     // - Route is granted to a single owner. When multiple requests are made we have policies to select the winning route.
     // - Route is granted to a single owner. When multiple requests are made we have policies to select the winning route.
     // - Multiple read sites may use the same owner id and will all get the granted route.
     // - Multiple read sites may use the same owner id and will all get the granted route.
     // - For routing: when owner_id is 0 we use the current Focus Scope ID as a default owner in order to identify our location.
     // - For routing: when owner_id is 0 we use the current Focus Scope ID as a default owner in order to identify our location.
+    // - TL;DR;
+    //   - IsKeyChordPressed() compares mods + call IsKeyPressed() -> function has no side-effect.
+    //   - Shortcut() submits a route then if currently can be routed calls IsKeyChordPressed() -> function has (desirable) side-effects.
+    IMGUI_API bool              IsKeyChordPressed(ImGuiKeyChord key_chord, ImGuiID owner_id, ImGuiInputFlags flags = 0);
     IMGUI_API bool              Shortcut(ImGuiKeyChord key_chord, ImGuiID owner_id = 0, ImGuiInputFlags flags = 0);
     IMGUI_API bool              Shortcut(ImGuiKeyChord key_chord, ImGuiID owner_id = 0, ImGuiInputFlags flags = 0);
     IMGUI_API bool              SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id = 0, ImGuiInputFlags flags = 0);
     IMGUI_API bool              SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id = 0, ImGuiInputFlags flags = 0);
     IMGUI_API bool              TestShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id);
     IMGUI_API bool              TestShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id);

+ 18 - 3
imgui_tables.cpp

@@ -445,6 +445,18 @@ bool    ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
     temp_data->HostBackupItemWidthStackSize = outer_window->DC.ItemWidthStack.Size;
     temp_data->HostBackupItemWidthStackSize = outer_window->DC.ItemWidthStack.Size;
     inner_window->DC.PrevLineSize = inner_window->DC.CurrLineSize = ImVec2(0.0f, 0.0f);
     inner_window->DC.PrevLineSize = inner_window->DC.CurrLineSize = ImVec2(0.0f, 0.0f);
 
 
+    // Make left and top borders not overlap our contents by offsetting HostClipRect (#6765)
+    // (we normally shouldn't alter HostClipRect as we rely on TableMergeDrawChannels() expanding non-clipped column toward the
+    // limits of that rectangle, in order for ImDrawListSplitter::Merge() to merge the draw commands. However since the overlap
+    // problem only affect scrolling tables in this case we can get away with doing it without extra cost).
+    if (inner_window != outer_window)
+    {
+        if (flags & ImGuiTableFlags_BordersOuterV)
+            table->HostClipRect.Min.x = ImMin(table->HostClipRect.Min.x + TABLE_BORDER_SIZE, table->HostClipRect.Max.x);
+        if (flags & ImGuiTableFlags_BordersOuterH)
+            table->HostClipRect.Min.y = ImMin(table->HostClipRect.Min.y + TABLE_BORDER_SIZE, table->HostClipRect.Max.y);
+    }
+
     // Padding and Spacing
     // Padding and Spacing
     // - None               ........Content..... Pad .....Content........
     // - None               ........Content..... Pad .....Content........
     // - PadOuter           | Pad ..Content..... Pad .....Content.. Pad |
     // - PadOuter           | Pad ..Content..... Pad .....Content.. Pad |
@@ -1149,7 +1161,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
         table->InnerClipRect.Max.x = ImMin(table->InnerClipRect.Max.x, unused_x1);
         table->InnerClipRect.Max.x = ImMin(table->InnerClipRect.Max.x, unused_x1);
     }
     }
     table->InnerWindow->ParentWorkRect = table->WorkRect;
     table->InnerWindow->ParentWorkRect = table->WorkRect;
-    table->BorderX1 = table->InnerClipRect.Min.x + ((table->Flags & ImGuiTableFlags_BordersOuterV) ? 1.0f : 0.0f);
+    table->BorderX1 = table->InnerClipRect.Min.x;
     table->BorderX2 = table->InnerClipRect.Max.x;
     table->BorderX2 = table->InnerClipRect.Max.x;
 
 
     // Setup window's WorkRect.Max.y for GetContentRegionAvail(). Other values will be updated in each TableBeginCell() call.
     // Setup window's WorkRect.Max.y for GetContentRegionAvail(). Other values will be updated in each TableBeginCell() call.
@@ -3015,11 +3027,14 @@ void ImGui::TableHeader(const char* label)
     // Calculate ideal size for sort order arrow
     // Calculate ideal size for sort order arrow
     float w_arrow = 0.0f;
     float w_arrow = 0.0f;
     float w_sort_text = 0.0f;
     float w_sort_text = 0.0f;
+    bool sort_arrow = false;
     char sort_order_suf[4] = "";
     char sort_order_suf[4] = "";
     const float ARROW_SCALE = 0.65f;
     const float ARROW_SCALE = 0.65f;
     if ((table->Flags & ImGuiTableFlags_Sortable) && !(column->Flags & ImGuiTableColumnFlags_NoSort))
     if ((table->Flags & ImGuiTableFlags_Sortable) && !(column->Flags & ImGuiTableColumnFlags_NoSort))
     {
     {
         w_arrow = ImTrunc(g.FontSize * ARROW_SCALE + g.Style.FramePadding.x);
         w_arrow = ImTrunc(g.FontSize * ARROW_SCALE + g.Style.FramePadding.x);
+        if (column->SortOrder != -1)
+            sort_arrow = true;
         if (column->SortOrder > 0)
         if (column->SortOrder > 0)
         {
         {
             ImFormatString(sort_order_suf, IM_ARRAYSIZE(sort_order_suf), "%d", column->SortOrder + 1);
             ImFormatString(sort_order_suf, IM_ARRAYSIZE(sort_order_suf), "%d", column->SortOrder + 1);
@@ -3027,9 +3042,9 @@ void ImGui::TableHeader(const char* label)
         }
         }
     }
     }
 
 
-    // We feed our unclipped width to the column without writing on CursorMaxPos, so that column is still considering for merging.
+    // We feed our unclipped width to the column without writing on CursorMaxPos, so that column is still considered for merging.
     float max_pos_x = label_pos.x + label_size.x + w_sort_text + w_arrow;
     float max_pos_x = label_pos.x + label_size.x + w_sort_text + w_arrow;
-    column->ContentMaxXHeadersUsed = ImMax(column->ContentMaxXHeadersUsed, column->WorkMaxX);
+    column->ContentMaxXHeadersUsed = ImMax(column->ContentMaxXHeadersUsed, sort_arrow ? cell_r.Max.x : ImMin(max_pos_x, cell_r.Max.x));
     column->ContentMaxXHeadersIdeal = ImMax(column->ContentMaxXHeadersIdeal, max_pos_x);
     column->ContentMaxXHeadersIdeal = ImMax(column->ContentMaxXHeadersIdeal, max_pos_x);
 
 
     // Keep header highlighted when context menu is open.
     // Keep header highlighted when context menu is open.