From b38af0f52279e7066c9cd653ea89e22925b5a609 Mon Sep 17 00:00:00 2001 From: Rokas Kupstys Date: Tue, 27 Jul 2021 16:47:18 +0300 Subject: [PATCH 1/7] Popups: Fix popups being closed by newly appearing windows. (#4317) * Popups/modals now remain open when new windows are created from within popup/modal begin stack. * Modals are not closed when new window appears behind active modal. Tested by "window_popup_interruptions" --- docs/CHANGELOG.txt | 4 ++ imgui.cpp | 114 +++++++++++++++++++++++++++++++++++++++++++-- imgui.h | 2 +- imgui_internal.h | 4 ++ 4 files changed, 119 insertions(+), 5 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index a3de7b03..3a9b36a0 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -45,6 +45,10 @@ Other Changes: (so IsMouseDoubleClicked(ImGuiMouseButton_Left) is same as GetMouseClickedCount(ImGuiMouseButton_Left) == 2, but it allows testing for triple clicks and more). - Modals: fixed issue hovering popups inside a child inside a modal. (#4676, #4527) +- Modals, Popups, Windows: changes how appearing windows are interrupting popups and modals. (#4317) [@rokups] + - appearing windows created from within the begin stack of a popup/modal will no longer close it. + - appearing windows created not within the begin stack of a modal will no longer close the modal, + and automatically appear behind it. - Fixed IsWindowFocused()/IsWindowHovered() issues with childs inside popups. (#4676) - Nav: Ctrl+tabbing to cycle through windows is now enabled regardless of using the _NavEnableKeyboard configuration flag. This is part of an effort to generalize the use of keyboard inputs. (#4023, #787). diff --git a/imgui.cpp b/imgui.cpp index 4366aef1..46fea469 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -948,6 +948,7 @@ static void RenderWindowDecorations(ImGuiWindow* window, const ImRec static void RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& title_bar_rect, const char* name, bool* p_open); static void RenderDimmedBackgroundBehindWindow(ImGuiWindow* window, ImU32 col); static void RenderDimmedBackgrounds(); +static ImGuiWindow* FindBlockingModal(ImGuiWindow* window); // Viewports static void UpdateViewportsNewFrame(); @@ -3910,7 +3911,7 @@ void ImGui::UpdateHoveredWindowAndCaptureFlags() // Modal windows prevents mouse from hovering behind them. ImGuiWindow* modal_window = GetTopMostPopupModal(); - if (modal_window && g.HoveredWindow && !IsWindowChildOf(g.HoveredWindow->RootWindow, modal_window, true)) + if (modal_window && g.HoveredWindow && !IsWindowWithinBeginStackOf(g.HoveredWindow->RootWindow, modal_window)) clear_hovered_windows = true; // Disabled mouse? @@ -4466,6 +4467,23 @@ static void ImGui::RenderDimmedBackgroundBehindWindow(ImGuiWindow* window, ImU32 } } +ImGuiWindow* ImGui::FindBottomMostVisibleWindowWithinBeginStack(ImGuiWindow* parent_window) +{ + ImGuiContext& g = *GImGui; + ImGuiWindow* bottom_most_visible_window = parent_window; + for (int i = FindWindowDisplayIndex(parent_window); i >= 0; i--) + { + ImGuiWindow* window = g.Windows[i]; + if (window->Flags & ImGuiWindowFlags_ChildWindow) + continue; + if (!IsWindowWithinBeginStackOf(window, parent_window)) + break; + if (IsWindowActiveAndVisible(window)) + bottom_most_visible_window = window; + } + return bottom_most_visible_window; +} + static void ImGui::RenderDimmedBackgrounds() { ImGuiContext& g = *GImGui; @@ -4477,8 +4495,9 @@ static void ImGui::RenderDimmedBackgrounds() if (dim_bg_for_modal) { - // Draw dimming behind modal - RenderDimmedBackgroundBehindWindow(modal_window, GetColorU32(ImGuiCol_ModalWindowDimBg, g.DimBgRatio)); + // Draw dimming behind modal or a begin stack child, whichever comes first in draw order. + ImGuiWindow* dim_behind_window = FindBottomMostVisibleWindowWithinBeginStack(modal_window); + RenderDimmedBackgroundBehindWindow(dim_behind_window, GetColorU32(ImGuiCol_ModalWindowDimBg, g.DimBgRatio)); } else if (dim_bg_for_window_list) { @@ -5859,6 +5878,36 @@ void ImGui::UpdateWindowParentAndRootLinks(ImGuiWindow* window, ImGuiWindowFlags } } +// When a modal popup is open, newly created windows that want focus (i.e. are not popups and do not specify ImGuiWindowFlags_NoFocusOnAppearing) +// should be positioned behind that modal window, unless the window was created inside the modal begin-stack. +// In case of multiple stacked modals newly created window honors begin stack order and does not go below its own modal parent. +// - Window // FindBlockingModal() returns Modal1 +// - Window // .. returns Modal1 +// - Modal1 // .. returns Modal2 +// - Window // .. returns Modal2 +// - Window // .. returns Modal2 +// - Modal2 // .. returns Modal2 +static ImGuiWindow* ImGui::FindBlockingModal(ImGuiWindow* window) +{ + ImGuiContext& g = *GImGui; + if (g.OpenPopupStack.Size <= 0) + return NULL; + + // Find a modal that has common parent with specified window. Specified window should be positioned behind that modal. + for (int i = g.OpenPopupStack.Size - 1; i >= 0; i--) + { + ImGuiWindow* popup_window = g.OpenPopupStack.Data[i].Window; + if (popup_window == NULL || !popup_window->WasActive || !(popup_window->Flags & ImGuiWindowFlags_Modal)) // Check WasActive, because this code may run before popup renders on current frame. + continue; + if (IsWindowWithinBeginStackOf(window, popup_window)) // Window is rendered over last modal, no render order change needed. + break; + for (ImGuiWindow* parent = popup_window->ParentWindowInBeginStack->RootWindow; parent != NULL; parent = parent->ParentWindowInBeginStack->RootWindow) + if (IsWindowWithinBeginStackOf(window, parent)) + return popup_window; // Place window above its begin stack parent. + } + return NULL; +} + // Push a new Dear ImGui window to add widgets to. // - A default window called "Debug" is automatically stacked at the beginning of every frame so you can use widgets without explicitly calling a Begin/End pair. // - Begin/End can be called multiple times during the frame with the same window name to append content. @@ -6204,6 +6253,22 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) want_focus = true; else if ((flags & (ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_Tooltip)) == 0) want_focus = true; + + ImGuiWindow* modal = GetTopMostPopupModal(); + if (modal != NULL && !IsWindowWithinBeginStackOf(window, modal)) + { + // Avoid focusing a window that is created outside of active modal. This will prevent active modal from being closed. + // Since window is not focused it would reappear at the same display position like the last time it was visible. + // In case of completely new windows it would go to the top (over current modal), but input to such window would still be blocked by modal. + // Position window behind a modal that is not a begin-parent of this window. + want_focus = false; + if (window == window->RootWindow) + { + ImGuiWindow* blocking_modal = FindBlockingModal(window); + IM_ASSERT(blocking_modal != NULL); + BringWindowToDisplayBehind(window, blocking_modal); + } + } } // Handle manual resize: Resize Grips, Borders, Gamepad @@ -6581,6 +6646,34 @@ void ImGui::BringWindowToDisplayBack(ImGuiWindow* window) } } +void ImGui::BringWindowToDisplayBehind(ImGuiWindow* window, ImGuiWindow* behind_window) +{ + IM_ASSERT(window != NULL && behind_window != NULL); + ImGuiContext& g = *GImGui; + window = window->RootWindow; + behind_window = behind_window->RootWindow; + int pos_wnd = FindWindowDisplayIndex(window); + int pos_beh = FindWindowDisplayIndex(behind_window); + if (pos_wnd < pos_beh) + { + size_t copy_bytes = (pos_beh - pos_wnd - 1) * sizeof(ImGuiWindow*); + memmove(&g.Windows.Data[pos_wnd], &g.Windows.Data[pos_wnd + 1], copy_bytes); + g.Windows[pos_beh - 1] = window; + } + else + { + size_t copy_bytes = (pos_wnd - pos_beh) * sizeof(ImGuiWindow*); + memmove(&g.Windows.Data[pos_beh + 1], &g.Windows.Data[pos_beh], copy_bytes); + g.Windows[pos_beh] = window; + } +} + +int ImGui::FindWindowDisplayIndex(ImGuiWindow* window) +{ + ImGuiContext& g = *GImGui; + return g.Windows.index_from_ptr(g.Windows.find(window)); +} + // Moving window to front of display and set focus (which happens to be back of our sorted list) void ImGui::FocusWindow(ImGuiWindow* window) { @@ -6810,6 +6903,19 @@ bool ImGui::IsWindowChildOf(ImGuiWindow* window, ImGuiWindow* potential_parent, return false; } +bool ImGui::IsWindowWithinBeginStackOf(ImGuiWindow* window, ImGuiWindow* potential_parent) +{ + if (window->RootWindow == potential_parent) + return true; + while (window != NULL) + { + if (window == potential_parent) + return true; + window = window->ParentWindowInBeginStack; + } + return false; +} + bool ImGui::IsWindowAbove(ImGuiWindow* potential_above, ImGuiWindow* potential_below) { ImGuiContext& g = *GImGui; @@ -8492,7 +8598,7 @@ void ImGui::ClosePopupsOverWindow(ImGuiWindow* ref_window, bool restore_focus_to bool ref_window_is_descendent_of_popup = false; for (int n = popup_count_to_keep; n < g.OpenPopupStack.Size; n++) if (ImGuiWindow* popup_window = g.OpenPopupStack[n].Window) - if (popup_window->RootWindow == ref_window->RootWindow) + if (IsWindowWithinBeginStackOf(ref_window, popup_window)) { ref_window_is_descendent_of_popup = true; break; diff --git a/imgui.h b/imgui.h index 215106ea..d9c29ab4 100644 --- a/imgui.h +++ b/imgui.h @@ -64,7 +64,7 @@ Index of this file: // Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens) #define IMGUI_VERSION "1.86 WIP" -#define IMGUI_VERSION_NUM 18516 +#define IMGUI_VERSION_NUM 18517 #define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx)) #define IMGUI_HAS_TABLE diff --git a/imgui_internal.h b/imgui_internal.h index d56204d3..0a1cc100 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -2418,6 +2418,7 @@ namespace ImGui IMGUI_API void UpdateWindowParentAndRootLinks(ImGuiWindow* window, ImGuiWindowFlags flags, ImGuiWindow* parent_window); IMGUI_API ImVec2 CalcWindowNextAutoFitSize(ImGuiWindow* window); IMGUI_API bool IsWindowChildOf(ImGuiWindow* window, ImGuiWindow* potential_parent, bool popup_hierarchy); + IMGUI_API bool IsWindowWithinBeginStackOf(ImGuiWindow* window, ImGuiWindow* potential_parent); IMGUI_API bool IsWindowAbove(ImGuiWindow* potential_above, ImGuiWindow* potential_below); IMGUI_API bool IsWindowNavFocusable(ImGuiWindow* window); IMGUI_API void SetWindowPos(ImGuiWindow* window, const ImVec2& pos, ImGuiCond cond = 0); @@ -2433,6 +2434,9 @@ namespace ImGui IMGUI_API void BringWindowToFocusFront(ImGuiWindow* window); IMGUI_API void BringWindowToDisplayFront(ImGuiWindow* window); IMGUI_API void BringWindowToDisplayBack(ImGuiWindow* window); + IMGUI_API void BringWindowToDisplayBehind(ImGuiWindow* window, ImGuiWindow* above_window); + IMGUI_API int FindWindowDisplayIndex(ImGuiWindow* window); + IMGUI_API ImGuiWindow* FindBottomMostVisibleWindowWithinBeginStack(ImGuiWindow* window); // Fonts, drawing IMGUI_API void SetCurrentFont(ImFont* font); From c80e8b964cbb75c4202949ad86f4b0bb3ea6aa44 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 8 Dec 2021 16:26:52 +0100 Subject: [PATCH 2/7] Backends: OpenGL2, Marmalade: Fixed mishandling of the ImDrawCmd::IdxOffset field. (#4790) --- backends/imgui_impl_marmalade.cpp | 6 +++--- backends/imgui_impl_opengl2.cpp | 4 ++-- docs/CHANGELOG.txt | 3 +++ 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/backends/imgui_impl_marmalade.cpp b/backends/imgui_impl_marmalade.cpp index aa6b3206..6e9b8f80 100644 --- a/backends/imgui_impl_marmalade.cpp +++ b/backends/imgui_impl_marmalade.cpp @@ -6,13 +6,14 @@ // Missing features: // [ ] Renderer: Clipping rectangles are not honored. -// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. +// You can use unmodified imgui_impl_* files in your project. See examples/ folder for examples of using this. // Prefer including the entire imgui/ repository into your project (either as a copy or as a submodule), and only build the backends you need. // If you are new to Dear ImGui, read documentation from the docs/ folder + read the top of imgui.cpp. // Read online: https://github.com/ocornut/imgui/tree/master/docs // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2021-12-08: Renderer: Fixed mishandling of the the ImDrawCmd::IdxOffset field! This is an old bug but it never had an effect until some internal rendering changes in 1.86. // 2021-05-19: Renderer: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement) // 2019-07-21: Inputs: Added mapping for ImGuiKey_KeyPadEnter. // 2019-05-11: Inputs: Don't filter value from character callback before calling AddInputCharacter(). @@ -91,9 +92,8 @@ void ImGui_Marmalade_RenderDrawData(ImDrawData* draw_data) pCurrentMaterial->SetAlphaTestMode(CIwMaterial::ALPHATEST_DISABLED); pCurrentMaterial->SetTexture((CIwTexture*)pcmd->GetTexID()); IwGxSetMaterial(pCurrentMaterial); - IwGxDrawPrims(IW_GX_TRI_LIST, (uint16*)idx_buffer, pcmd->ElemCount); + IwGxDrawPrims(IW_GX_TRI_LIST, (uint16*)(idx_buffer + pcmd->IdxOffset), pcmd->ElemCount); } - idx_buffer += pcmd->ElemCount; } IwGxFlush(); } diff --git a/backends/imgui_impl_opengl2.cpp b/backends/imgui_impl_opengl2.cpp index 65e778f5..17a6faeb 100644 --- a/backends/imgui_impl_opengl2.cpp +++ b/backends/imgui_impl_opengl2.cpp @@ -19,6 +19,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2021-12-08: OpenGL: Fixed mishandling of the the ImDrawCmd::IdxOffset field! This is an old bug but it never had an effect until some internal rendering changes in 1.86. // 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX). // 2021-05-19: OpenGL: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement) // 2021-01-03: OpenGL: Backup, setup and restore GL_SHADE_MODEL state, disable GL_STENCIL_TEST and disable GL_NORMAL_ARRAY client state to increase compatibility with legacy OpenGL applications. @@ -211,9 +212,8 @@ void ImGui_ImplOpenGL2_RenderDrawData(ImDrawData* draw_data) // Bind texture, Draw glBindTexture(GL_TEXTURE_2D, (GLuint)(intptr_t)pcmd->GetTexID()); - glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer); + glDrawElements(GL_TRIANGLES, (GLsizei)pcmd->ElemCount, sizeof(ImDrawIdx) == 2 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, idx_buffer + pcmd->IdxOffset); } - idx_buffer += pcmd->ElemCount; } } diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 3a9b36a0..9aa7f2b4 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -90,6 +90,9 @@ Other Changes: - Backends: Vulkan: Call vkCmdSetScissor() at the end of render with a full-viewport to reduce likehood of issues with people using VK_DYNAMIC_STATE_SCISSOR in their app without calling vkCmdSetScissor() explicitly every frame. (#4644) +- Backends: OpenGL2, Marmalade: Fixed mishandling of the ImDrawCmd::IdxOffset field. This is an old bug, + but due to the way we created drawlists, it never had any visible side-effect before. + The new code for handling Modal and CTRL+Tab dimming/whitening recently made the bug surface. (#4790) - Backends: DX12: Fixed DRAW_EMPTY_SCISSOR_RECTANGLE warnings. (#4775) - Backends: SDL_Renderer: Added support for large meshes (64k+ vertices) with 16-bit indices, enabling 'ImGuiBackendFlags_RendererHasVtxOffset' in the backend. (#3926) [@rokups] From a19815dc6bb6ca03941f213424a59a362cfd8158 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 8 Dec 2021 16:34:57 +0100 Subject: [PATCH 3/7] Backends: Allegro5: Fixed mishandling of the ImDrawCmd::IdxOffset field. (#4790) --- backends/imgui_impl_allegro5.cpp | 5 ++--- docs/CHANGELOG.txt | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/backends/imgui_impl_allegro5.cpp b/backends/imgui_impl_allegro5.cpp index 43b04f6b..8eb63614 100644 --- a/backends/imgui_impl_allegro5.cpp +++ b/backends/imgui_impl_allegro5.cpp @@ -16,6 +16,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2021-12-08: Renderer: Fixed mishandling of the the ImDrawCmd::IdxOffset field! This is an old bug but it never had an effect until some internal rendering changes in 1.86. // 2021-08-17: Calling io.AddFocusEvent() on ALLEGRO_EVENT_DISPLAY_SWITCH_OUT/ALLEGRO_EVENT_DISPLAY_SWITCH_IN events. // 2021-06-29: Reorganized backend to pull data from a single structure to facilitate usage with multiple-contexts (all g_XXXX access changed to bd->XXXX). // 2021-05-19: Renderer: Replaced direct access to ImDrawCmd::TextureId with a call to ImDrawCmd::GetTexID(). (will become a requirement) @@ -155,7 +156,6 @@ void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data) } // Render command lists - int idx_offset = 0; ImVec2 clip_off = draw_data->DisplayPos; for (int cmd_i = 0; cmd_i < cmd_list->CmdBuffer.Size; cmd_i++) { @@ -180,9 +180,8 @@ void ImGui_ImplAllegro5_RenderDrawData(ImDrawData* draw_data) // Apply scissor/clipping rectangle, Draw ALLEGRO_BITMAP* texture = (ALLEGRO_BITMAP*)pcmd->GetTexID(); al_set_clipping_rectangle(clip_min.x, clip_min.y, clip_max.x - clip_min.x, clip_max.y - clip_min.y); - al_draw_prim(&vertices[0], bd->VertexDecl, texture, idx_offset, idx_offset + pcmd->ElemCount, ALLEGRO_PRIM_TRIANGLE_LIST); + al_draw_prim(&vertices[0], bd->VertexDecl, texture, pcmd->IdxOffset, pcmd->IdxOffset + pcmd->ElemCount, ALLEGRO_PRIM_TRIANGLE_LIST); } - idx_offset += pcmd->ElemCount; } } diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 9aa7f2b4..6f7553e9 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -90,8 +90,8 @@ Other Changes: - Backends: Vulkan: Call vkCmdSetScissor() at the end of render with a full-viewport to reduce likehood of issues with people using VK_DYNAMIC_STATE_SCISSOR in their app without calling vkCmdSetScissor() explicitly every frame. (#4644) -- Backends: OpenGL2, Marmalade: Fixed mishandling of the ImDrawCmd::IdxOffset field. This is an old bug, - but due to the way we created drawlists, it never had any visible side-effect before. +- Backends: OpenGL2, Allegro5, Marmalade: Fixed mishandling of the ImDrawCmd::IdxOffset field. + This is an old bug, but due to the way we created drawlists, it never had any visible side-effect before. The new code for handling Modal and CTRL+Tab dimming/whitening recently made the bug surface. (#4790) - Backends: DX12: Fixed DRAW_EMPTY_SCISSOR_RECTANGLE warnings. (#4775) - Backends: SDL_Renderer: Added support for large meshes (64k+ vertices) with 16-bit indices, From 270d4d0855ea3b2f66833ab1124ec475abe9df9c Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 8 Dec 2021 17:02:24 +0100 Subject: [PATCH 4/7] Nav, Docking: Fix crash on dimming docked window and DockSpaceOverViewport() with PassthruCentralNode. (amend 1dc3af3, 23ef6c1, 657073a) # Conflicts: # imgui.cpp --- imgui.cpp | 6 ++++++ imgui_draw.cpp | 5 +++++ 2 files changed, 11 insertions(+) diff --git a/imgui.cpp b/imgui.cpp index 46fea469..da8c6df2 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4456,7 +4456,11 @@ static void ImGui::RenderDimmedBackgroundBehindWindow(ImGuiWindow* window, ImU32 // Draw behind window by moving the draw command at the FRONT of the draw list { + // We've already called AddWindowToDrawData() which called DrawList->ChannelsMerge() on DockNodeHost windows, + // and draw list have been trimmed already, hence the explicit recreation of a draw command if missing. ImDrawList* draw_list = window->RootWindow->DrawList; + if (draw_list->CmdBuffer.Size == 0) + draw_list->AddDrawCmd(); draw_list->PushClipRect(viewport_rect.Min - ImVec2(1, 1), viewport_rect.Max + ImVec2(1, 1), false); // Ensure ImDrawCmd are not merged draw_list->AddRectFilled(viewport_rect.Min, viewport_rect.Max, col); ImDrawCmd cmd = draw_list->CmdBuffer.back(); @@ -4512,6 +4516,8 @@ static void ImGui::RenderDimmedBackgrounds() bb.Expand(distance); if (bb.GetWidth() >= viewport->Size.x && bb.GetHeight() >= viewport->Size.y) bb.Expand(-distance - 1.0f); // If a window fits the entire viewport, adjust its highlight inward + if (window->DrawList->CmdBuffer.Size == 0) + window->DrawList->AddDrawCmd(); window->DrawList->PushClipRect(viewport->Pos, viewport->Pos + viewport->Size); window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_NavWindowingHighlight, g.NavWindowingHighlightAlpha), window->WindowRounding, 0, 3.0f); window->DrawList->PopClipRect(); diff --git a/imgui_draw.cpp b/imgui_draw.cpp index f76dc2dc..6b5e70e5 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -473,6 +473,7 @@ void ImDrawList::_PopUnusedDrawCmd() void ImDrawList::AddCallback(ImDrawCallback callback, void* callback_data) { + IM_ASSERT_PARANOID(CmdBuffer.Size > 0); ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1]; IM_ASSERT(curr_cmd->UserCallback == NULL); if (curr_cmd->ElemCount != 0) @@ -494,6 +495,7 @@ void ImDrawList::AddCallback(ImDrawCallback callback, void* callback_data) // Try to merge two last draw commands void ImDrawList::_TryMergeDrawCmds() { + IM_ASSERT_PARANOID(CmdBuffer.Size > 0); ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1]; ImDrawCmd* prev_cmd = curr_cmd - 1; if (ImDrawCmd_HeaderCompare(curr_cmd, prev_cmd) == 0 && curr_cmd->UserCallback == NULL && prev_cmd->UserCallback == NULL) @@ -508,6 +510,7 @@ void ImDrawList::_TryMergeDrawCmds() void ImDrawList::_OnChangedClipRect() { // If current command is used with different settings we need to add a new command + IM_ASSERT_PARANOID(CmdBuffer.Size > 0); ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1]; if (curr_cmd->ElemCount != 0 && memcmp(&curr_cmd->ClipRect, &_CmdHeader.ClipRect, sizeof(ImVec4)) != 0) { @@ -530,6 +533,7 @@ void ImDrawList::_OnChangedClipRect() void ImDrawList::_OnChangedTextureID() { // If current command is used with different settings we need to add a new command + IM_ASSERT_PARANOID(CmdBuffer.Size > 0); ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1]; if (curr_cmd->ElemCount != 0 && curr_cmd->TextureId != _CmdHeader.TextureId) { @@ -553,6 +557,7 @@ void ImDrawList::_OnChangedVtxOffset() { // We don't need to compare curr_cmd->VtxOffset != _CmdHeader.VtxOffset because we know it'll be different at the time we call this. _VtxCurrentIdx = 0; + IM_ASSERT_PARANOID(CmdBuffer.Size > 0); ImDrawCmd* curr_cmd = &CmdBuffer.Data[CmdBuffer.Size - 1]; //IM_ASSERT(curr_cmd->VtxOffset != _CmdHeader.VtxOffset); // See #3349 if (curr_cmd->ElemCount != 0) From 072caa4a9068b93070567879afc5fbcbb772c5ae Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 9 Dec 2021 11:25:58 +0100 Subject: [PATCH 5/7] InputText: fixed incorrect padding when FrameBorder > 0. (#4794, #3781) --- docs/CHANGELOG.txt | 1 + imgui_widgets.cpp | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 6f7553e9..610bd212 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -66,6 +66,7 @@ Other Changes: - InputText: made double-click select word, triple-line select line. Word delimitation logic differs slightly from the one used by CTRL+arrows. (#2244) - InputText: fixed ReadOnly flag preventing callbacks from receiving the text buffer. (#4762) [@actondev] +- InputText: fixed incorrect padding when FrameBorder > 0. (#4794, #3781) - Separator: fixed cover all columns while called inside a table. (#4787) - Clipper: currently focused item is automatically included in clipper range. Fixes issue where e.g. drag and dropping an item and scrolling ensure the item source location is diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 9d73d7dc..c084b0d8 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -4009,8 +4009,9 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ PushStyleColor(ImGuiCol_ChildBg, style.Colors[ImGuiCol_FrameBg]); PushStyleVar(ImGuiStyleVar_ChildRounding, style.FrameRounding); PushStyleVar(ImGuiStyleVar_ChildBorderSize, style.FrameBorderSize); + PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0)); // Ensure no clip rect so mouse hover can reach FramePadding edges bool child_visible = BeginChildEx(label, id, frame_bb.GetSize(), true, ImGuiWindowFlags_NoMove); - PopStyleVar(2); + PopStyleVar(3); PopStyleColor(); if (!child_visible) { From bdd2a943150628fdc827c285eafaced6005a2f64 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 9 Dec 2021 11:30:42 +0100 Subject: [PATCH 6/7] InputTextMultiline: fixed vertical tracking with large values of FramePadding.y. (#3781, #4794) --- docs/CHANGELOG.txt | 3 ++- imgui_widgets.cpp | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 610bd212..66e0926e 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -66,7 +66,8 @@ Other Changes: - InputText: made double-click select word, triple-line select line. Word delimitation logic differs slightly from the one used by CTRL+arrows. (#2244) - InputText: fixed ReadOnly flag preventing callbacks from receiving the text buffer. (#4762) [@actondev] -- InputText: fixed incorrect padding when FrameBorder > 0. (#4794, #3781) +- InputTextMultiline: fixed incorrect padding when FrameBorder > 0. (#3781, #4794) +- InputTextMultiline: fixed vertical tracking with large values of FramePadding.y. (#3781, #4794) - Separator: fixed cover all columns while called inside a table. (#4787) - Clipper: currently focused item is automatically included in clipper range. Fixes issue where e.g. drag and dropping an item and scrolling ensure the item source location is diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index c084b0d8..dbdc0e5c 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -4693,7 +4693,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_ // Test if cursor is vertically visible if (cursor_offset.y - g.FontSize < scroll_y) scroll_y = ImMax(0.0f, cursor_offset.y - g.FontSize); - else if (cursor_offset.y - inner_size.y >= scroll_y) + else if (cursor_offset.y - (inner_size.y - style.FramePadding.y * 2.0f) >= scroll_y) scroll_y = cursor_offset.y - inner_size.y + style.FramePadding.y * 2.0f; const float scroll_max_y = ImMax((text_size.y + style.FramePadding.y * 2.0f) - inner_size.y, 0.0f); scroll_y = ImClamp(scroll_y, 0.0f, scroll_max_y); From e03383d088fbfd8fc5b6a34864caf9e808dc2412 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 9 Dec 2021 11:50:23 +0100 Subject: [PATCH 7/7] Fixes for tooltip over modals leading to incorrect modal dimming. (#4729) Amend 23ef6c1. Should rework tooltip to be in a consistent position in g.Windows[] --- imgui.cpp | 2 +- imgui.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index da8c6df2..5b2a6830 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -4482,7 +4482,7 @@ ImGuiWindow* ImGui::FindBottomMostVisibleWindowWithinBeginStack(ImGuiWindow* par continue; if (!IsWindowWithinBeginStackOf(window, parent_window)) break; - if (IsWindowActiveAndVisible(window)) + if (IsWindowActiveAndVisible(window) && GetWindowDisplayLayer(window) <= GetWindowDisplayLayer(parent_window)) bottom_most_visible_window = window; } return bottom_most_visible_window; diff --git a/imgui.h b/imgui.h index d9c29ab4..60e57820 100644 --- a/imgui.h +++ b/imgui.h @@ -64,7 +64,7 @@ Index of this file: // Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens) #define IMGUI_VERSION "1.86 WIP" -#define IMGUI_VERSION_NUM 18517 +#define IMGUI_VERSION_NUM 18518 #define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx)) #define IMGUI_HAS_TABLE