@@ -3264,6 +3264,7 @@ ImGuiWindow::ImGuiWindow(ImGuiContext* context, const char* name) : DrawListInst
32643264 ViewportAllowPlatformMonitorExtend = -1;
32653265 ViewportPos = ImVec2(FLT_MAX, FLT_MAX);
32663266 MoveId = GetID("#MOVE");
3267+ TabId = GetID("#TAB");
32673268 ScrollTarget = ImVec2(FLT_MAX, FLT_MAX);
32683269 ScrollTargetCenterRatio = ImVec2(0.5f, 0.5f);
32693270 AutoFitFramesX = AutoFitFramesY = -1;
@@ -3541,8 +3542,9 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags)
35413542
35423543 // Test if another item is active (e.g. being dragged)
35433544 if ((flags & ImGuiHoveredFlags_AllowWhenBlockedByActiveItem) == 0)
3544- if (g.ActiveId != 0 && g.ActiveId != g.LastItemData.ID && !g.ActiveIdAllowOverlap && g.ActiveId != window->MoveId)
3545- return false;
3545+ if (g.ActiveId != 0 && g.ActiveId != g.LastItemData.ID && !g.ActiveIdAllowOverlap)
3546+ if (g.ActiveId != window->MoveId && g.ActiveId != window->TabId)
3547+ return false;
35463548
35473549 // Test if interactions on this window are blocked by an active popup or modal.
35483550 // The ImGuiHoveredFlags_AllowWhenBlockedByPopup flag will be tested here.
@@ -3554,7 +3556,8 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags)
35543556 return false;
35553557
35563558 // Special handling for calling after Begin() which represent the title bar or tab.
3557- // When the window is collapsed (SkipItems==true) that last item will never be overwritten so we need to detect the case.
3559+ // When the window is skipped/collapsed (SkipItems==true) that last item (always ->MoveId submitted by Begin)
3560+ // will never be overwritten so we need to detect the case.
35583561 if (g.LastItemData.ID == window->MoveId && window->WriteAccessed)
35593562 return false;
35603563 }
@@ -7299,7 +7302,7 @@ void ImGui::FocusWindow(ImGuiWindow* window)
72997302
73007303 // Select in dock node
73017304 if (dock_node && dock_node->TabBar)
7302- dock_node->TabBar->SelectedTabId = dock_node->TabBar->NextSelectedTabId = window->ID ;
7305+ dock_node->TabBar->SelectedTabId = dock_node->TabBar->NextSelectedTabId = window->TabId ;
73037306
73047307 // Bring to front
73057308 BringWindowToFocusFront(focus_front_window);
@@ -12456,6 +12459,7 @@ static void WindowSettingsHandler_WriteAll(ImGuiContext* ctx, ImGuiSettingsHandl
1245612459 buf->appendf("Collapsed=%d\n", settings->Collapsed);
1245712460 if (settings->DockId != 0)
1245812461 {
12462+ //buf->appendf("TabId=0x%08X\n", ImHashStr("#TAB", 4, settings->ID)); // window->TabId: this is not read back but writing it makes "debugging" the .ini data easier.
1245912463 if (settings->DockOrder == -1)
1246012464 buf->appendf("DockId=0x%08X\n", settings->DockId);
1246112465 else
@@ -14063,7 +14067,7 @@ void ImGui::DockContextProcessDock(ImGuiContext* ctx, ImGuiDockRequest* req)
1406314067 if (payload_node && payload_node->IsLeafNode())
1406414068 next_selected_id = payload_node->TabBar->NextSelectedTabId ? payload_node->TabBar->NextSelectedTabId : payload_node->TabBar->SelectedTabId;
1406514069 if (payload_node == NULL)
14066- next_selected_id = payload_window->ID ;
14070+ next_selected_id = payload_window->TabId ;
1406714071 }
1406814072
1406914073 // FIXME-DOCK: When we are trying to dock an existing single-window node into a loose window, transfer Node ID as well
@@ -14340,7 +14344,7 @@ int ImGui::DockNodeGetTabOrder(ImGuiWindow* window)
1434014344 ImGuiTabBar* tab_bar = window->DockNode->TabBar;
1434114345 if (tab_bar == NULL)
1434214346 return -1;
14343- ImGuiTabItem* tab = TabBarFindTabByID(tab_bar, window->ID );
14347+ ImGuiTabItem* tab = TabBarFindTabByID(tab_bar, window->TabId );
1434414348 return tab ? tab_bar->GetTabOrder(tab) : -1;
1434514349}
1434614350
@@ -14444,7 +14448,7 @@ static void ImGui::DockNodeRemoveWindow(ImGuiDockNode* node, ImGuiWindow* window
1444414448 node->WantHiddenTabBarUpdate = true;
1444514449 if (node->TabBar)
1444614450 {
14447- TabBarRemoveTab(node->TabBar, window->ID );
14451+ TabBarRemoveTab(node->TabBar, window->TabId );
1444814452 const int tab_count_threshold_for_tab_bar = node->IsCentralNode() ? 1 : 2;
1444914453 if (node->Windows.Size < tab_count_threshold_for_tab_bar)
1445014454 DockNodeRemoveTabBar(node);
@@ -14627,7 +14631,7 @@ static void ImGui::DockNodeUpdateFlagsAndCollapse(ImGuiDockNode* node)
1462714631 bool node_was_active = (node->LastFrameActive + 1 == g.FrameCount);
1462814632 bool remove = false;
1462914633 remove |= node_was_active && (window->LastFrameActive + 1 < g.FrameCount);
14630- remove |= node_was_active && (node->WantCloseAll || node->WantCloseTabId == window->ID ) && window->HasCloseButton && !(window->Flags & ImGuiWindowFlags_UnsavedDocument); // Submit all _expected_ closure from last frame
14634+ remove |= node_was_active && (node->WantCloseAll || node->WantCloseTabId == window->TabId ) && window->HasCloseButton && !(window->Flags & ImGuiWindowFlags_UnsavedDocument); // Submit all _expected_ closure from last frame
1463114635 remove |= (window->DockTabWantClose);
1463214636 if (remove)
1463314637 {
@@ -15159,7 +15163,7 @@ static void ImGui::DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_w
1515915163 if (is_focused || root_node->VisibleWindow == NULL)
1516015164 root_node->VisibleWindow = node->VisibleWindow;
1516115165 if (node->TabBar)
15162- node->TabBar->VisibleTabId = node->VisibleWindow->ID ;
15166+ node->TabBar->VisibleTabId = node->VisibleWindow->TabId ;
1516315167 }
1516415168 return;
1516515169 }
@@ -15210,7 +15214,7 @@ static void ImGui::DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_w
1521015214 for (int window_n = 0; window_n < node->Windows.Size; window_n++)
1521115215 {
1521215216 ImGuiWindow* window = node->Windows[window_n];
15213- if (TabBarFindTabByID(tab_bar, window->ID ) == NULL)
15217+ if (TabBarFindTabByID(tab_bar, window->TabId ) == NULL)
1521415218 TabBarAddTab(tab_bar, ImGuiTabItemFlags_Unsorted, window);
1521515219 }
1521615220
@@ -15255,7 +15259,7 @@ static void ImGui::DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_w
1525515259 if (tab_bar_is_recreated && TabBarFindTabByID(tab_bar, node->SelectedTabId) != NULL)
1525615260 tab_bar->SelectedTabId = tab_bar->NextSelectedTabId = node->SelectedTabId;
1525715261 else if (tab_bar->Tabs.Size > tabs_count_old)
15258- tab_bar->SelectedTabId = tab_bar->NextSelectedTabId = tab_bar->Tabs.back().Window->ID ;
15262+ tab_bar->SelectedTabId = tab_bar->NextSelectedTabId = tab_bar->Tabs.back().Window->TabId ;
1525915263
1526015264 // Begin tab bar
1526115265 ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_Reorderable | ImGuiTabBarFlags_AutoSelectNewTabs; // | ImGuiTabBarFlags_NoTabListScrollingButtons);
@@ -15275,7 +15279,7 @@ static void ImGui::DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_w
1527515279 for (int window_n = 0; window_n < node->Windows.Size; window_n++)
1527615280 {
1527715281 ImGuiWindow* window = node->Windows[window_n];
15278- if ((closed_all || closed_one == window->ID ) && window->HasCloseButton && !(window->Flags & ImGuiWindowFlags_UnsavedDocument))
15282+ if ((closed_all || closed_one == window->TabId ) && window->HasCloseButton && !(window->Flags & ImGuiWindowFlags_UnsavedDocument))
1527915283 continue;
1528015284 if (window->LastFrameActive + 1 >= g.FrameCount || !node_was_active)
1528115285 {
@@ -15290,11 +15294,12 @@ static void ImGui::DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_w
1529015294 for (int color_n = 0; color_n < ImGuiWindowDockStyleCol_COUNT; color_n++)
1529115295 g.Style.Colors[GWindowDockStyleColors[color_n]] = ColorConvertU32ToFloat4(window->DockStyle.Colors[color_n]);
1529215296
15297+ // Note that TabItemEx() calls TabBarCalcTabID() so our tab item ID will ignore the current ID stack (rightly so)
1529315298 bool tab_open = true;
1529415299 TabItemEx(tab_bar, window->Name, window->HasCloseButton ? &tab_open : NULL, tab_item_flags, window);
1529515300 if (!tab_open)
15296- node->WantCloseTabId = window->ID ;
15297- if (tab_bar->VisibleTabId == window->ID )
15301+ node->WantCloseTabId = window->TabId ;
15302+ if (tab_bar->VisibleTabId == window->TabId )
1529815303 node->VisibleWindow = window;
1529915304
1530015305 // Store last item data so it can be queried with IsItemXXX functions after the user Begin() call
@@ -15303,7 +15308,7 @@ static void ImGui::DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_w
1530315308
1530415309 // Update navigation ID on menu layer
1530515310 if (g.NavWindow && g.NavWindow->RootWindow == window && (window->DC.NavLayersActiveMask & (1 << ImGuiNavLayer_Menu)) == 0)
15306- host_window->NavLastIds[1] = window->ID ;
15311+ host_window->NavLastIds[1] = window->TabId ;
1530715312 }
1530815313 }
1530915314
@@ -15317,7 +15322,7 @@ static void ImGui::DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_w
1531715322 root_node->VisibleWindow = node->VisibleWindow;
1531815323
1531915324 // Close button (after VisibleWindow was updated)
15320- // Note that VisibleWindow may have been overrided by CTRL+Tabbing, so VisibleWindow->ID may be != from tab_bar->SelectedTabId
15325+ // Note that VisibleWindow may have been overrided by CTRL+Tabbing, so VisibleWindow->TabId may be != from tab_bar->SelectedTabId
1532115326 const bool close_button_is_enabled = node->HasCloseButton && node->VisibleWindow && node->VisibleWindow->HasCloseButton;
1532215327 const bool close_button_is_visible = node->HasCloseButton;
1532315328 //const bool close_button_is_visible = close_button_is_enabled; // Most people would expect this behavior of not even showing the button (leaving a hole since we can't claim that space as other windows in the tba bar have one)
@@ -16931,7 +16936,7 @@ void ImGui::BeginDocked(ImGuiWindow* window, bool* p_open)
1693116936 if (node->TabBar && window->WasActive)
1693216937 window->DockOrder = (short)DockNodeGetTabOrder(window);
1693316938
16934- if ((node->WantCloseAll || node->WantCloseTabId == window->ID ) && p_open != NULL)
16939+ if ((node->WantCloseAll || node->WantCloseTabId == window->TabId ) && p_open != NULL)
1693516940 *p_open = false;
1693616941
1693716942 // Update ChildId to allow returning from Child to Parent with Escape
0 commit comments