@@ -946,7 +946,8 @@ static bool UpdateWindowManualResize(ImGuiWindow* window, const ImVe
946
946
static void RenderWindowOuterBorders(ImGuiWindow* window);
947
947
static void RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar_rect, bool title_bar_is_highlight, int resize_grip_count, const ImU32 resize_grip_col[4], float resize_grip_draw_size);
948
948
static void RenderWindowTitleBarContents(ImGuiWindow* window, const ImRect& title_bar_rect, const char* name, bool* p_open);
949
- static void EndFrameDrawDimmedBackgrounds();
949
+ static void RenderDimmedBackgroundBehindWindow(ImGuiWindow* window, ImU32 col);
950
+ static void RenderDimmedBackgrounds();
950
951
951
952
// Viewports
952
953
static void UpdateViewportsNewFrame();
@@ -4442,9 +4443,58 @@ void ImGui::PopClipRect()
4442
4443
window->ClipRect = window->DrawList->_ClipRectStack.back();
4443
4444
}
4444
4445
4445
- static void ImGui::EndFrameDrawDimmedBackgrounds( )
4446
+ static void ImGui::RenderDimmedBackgroundBehindWindow(ImGuiWindow* window, ImU32 col )
4446
4447
{
4447
- // (This is currently empty, left here to facilitate sync/merge with docking branch)
4448
+ if ((col & IM_COL32_A_MASK) == 0)
4449
+ return;
4450
+
4451
+ ImGuiViewportP* viewport = (ImGuiViewportP*)GetMainViewport();
4452
+ ImRect viewport_rect = viewport->GetMainRect();
4453
+
4454
+ // Draw behind window by moving the draw command at the FRONT of the draw list
4455
+ {
4456
+ ImDrawList* draw_list = window->RootWindow->DrawList;
4457
+ draw_list->AddDrawCmd();
4458
+ draw_list->PushClipRect(viewport_rect.Min - ImVec2(1, 1), viewport_rect.Max + ImVec2(1, 1), false); // Ensure ImDrawCmd are not merged
4459
+ draw_list->AddRectFilled(viewport_rect.Min, viewport_rect.Max, col);
4460
+ ImDrawCmd cmd = draw_list->CmdBuffer.back();
4461
+ IM_ASSERT(cmd.ElemCount == 6);
4462
+ draw_list->CmdBuffer.pop_back();
4463
+ draw_list->CmdBuffer.push_front(cmd);
4464
+ }
4465
+ }
4466
+
4467
+ static void ImGui::RenderDimmedBackgrounds()
4468
+ {
4469
+ ImGuiContext& g = *GImGui;
4470
+ ImGuiWindow* modal_window = GetTopMostAndVisiblePopupModal();
4471
+ const bool dim_bg_for_modal = (modal_window != NULL);
4472
+ const bool dim_bg_for_window_list = (g.NavWindowingTargetAnim != NULL && g.NavWindowingTargetAnim->Active);
4473
+ if (!dim_bg_for_modal && !dim_bg_for_window_list)
4474
+ return;
4475
+
4476
+ if (dim_bg_for_modal)
4477
+ {
4478
+ // Draw dimming behind modal
4479
+ RenderDimmedBackgroundBehindWindow(modal_window, GetColorU32(ImGuiCol_ModalWindowDimBg, g.DimBgRatio));
4480
+ }
4481
+ else if (dim_bg_for_window_list)
4482
+ {
4483
+ // Draw dimming behind CTRL+Tab target window
4484
+ RenderDimmedBackgroundBehindWindow(g.NavWindowingTargetAnim, GetColorU32(ImGuiCol_NavWindowingDimBg, g.DimBgRatio));
4485
+
4486
+ // Draw border around CTRL+Tab target window
4487
+ ImGuiWindow* window = g.NavWindowingTargetAnim;
4488
+ ImGuiViewport* viewport = GetMainViewport();
4489
+ float distance = g.FontSize;
4490
+ ImRect bb = window->Rect();
4491
+ bb.Expand(distance);
4492
+ if (bb.GetWidth() >= viewport->Size.x && bb.GetHeight() >= viewport->Size.y)
4493
+ bb.Expand(-distance - 1.0f); // If a window fits the entire viewport, adjust its highlight inward
4494
+ window->DrawList->PushClipRect(viewport->Pos, viewport->Pos + viewport->Size);
4495
+ window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_NavWindowingHighlight, g.NavWindowingHighlightAlpha), window->WindowRounding, 0, 3.0f);
4496
+ window->DrawList->PopClipRect();
4497
+ }
4448
4498
}
4449
4499
4450
4500
// This is normally called by Render(). You may want to call it directly if you want to avoid calling Render() but the gain will be very minimal.
@@ -4502,9 +4552,6 @@ void ImGui::EndFrame()
4502
4552
// Initiate moving window + handle left-click and right-click focus
4503
4553
UpdateMouseMovingWindowEndFrame();
4504
4554
4505
- // Draw modal/window whitening backgrounds
4506
- EndFrameDrawDimmedBackgrounds();
4507
-
4508
4555
// Sort the window list so that all child windows are after their parent
4509
4556
// We cannot do that on FocusWindow() because children may not exist yet
4510
4557
g.WindowsTempSortBuffer.resize(0);
@@ -4574,6 +4621,10 @@ void ImGui::Render()
4574
4621
if (windows_to_render_top_most[n] && IsWindowActiveAndVisible(windows_to_render_top_most[n])) // NavWindowingTarget is always temporarily displayed as the top-most window
4575
4622
AddRootWindowToDrawData(windows_to_render_top_most[n]);
4576
4623
4624
+ // Draw modal/window whitening backgrounds
4625
+ if (first_render_of_frame)
4626
+ RenderDimmedBackgrounds();
4627
+
4577
4628
// Setup ImDrawData structures for end-user
4578
4629
g.IO.MetricsRenderVertices = g.IO.MetricsRenderIndices = 0;
4579
4630
for (int n = 0; n < g.Viewports.Size; n++)
@@ -6248,24 +6299,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
6248
6299
window->DrawList->PushTextureID(g.Font->ContainerAtlas->TexID);
6249
6300
PushClipRect(host_rect.Min, host_rect.Max, false);
6250
6301
6251
- // Draw modal window background (darkens what is behind them, all viewports)
6252
- const bool dim_bg_for_modal = (flags & ImGuiWindowFlags_Modal) && window == GetTopMostPopupModal() && window->HiddenFramesCannotSkipItems <= 0;
6253
- const bool dim_bg_for_window_list = g.NavWindowingTargetAnim && (window == g.NavWindowingTargetAnim->RootWindow);
6254
- if (dim_bg_for_modal || dim_bg_for_window_list)
6255
- {
6256
- const ImU32 dim_bg_col = GetColorU32(dim_bg_for_modal ? ImGuiCol_ModalWindowDimBg : ImGuiCol_NavWindowingDimBg, g.DimBgRatio);
6257
- window->DrawList->AddRectFilled(viewport_rect.Min, viewport_rect.Max, dim_bg_col);
6258
- }
6259
-
6260
- // Draw navigation selection/windowing rectangle background
6261
- if (dim_bg_for_window_list && window == g.NavWindowingTargetAnim)
6262
- {
6263
- ImRect bb = window->Rect();
6264
- bb.Expand(g.FontSize);
6265
- if (!bb.Contains(viewport_rect)) // Avoid drawing if the window covers all the viewport anyway
6266
- window->DrawList->AddRectFilled(bb.Min, bb.Max, GetColorU32(ImGuiCol_NavWindowingHighlight, g.NavWindowingHighlightAlpha * 0.25f), g.Style.WindowRounding);
6267
- }
6268
-
6269
6302
// Child windows can render their decoration (bg color, border, scrollbars, etc.) within their parent to save a draw call (since 1.71)
6270
6303
// When using overlapping child windows, this will break the assumption that child z-order is mapped to submission order.
6271
6304
// FIXME: User code may rely on explicit sorting of overlapping child window and would need to disable this somehow. Please get in contact if you are affected (github #4493)
@@ -6293,20 +6326,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
6293
6326
window->DrawList = &window->DrawListInst;
6294
6327
}
6295
6328
6296
- // Draw navigation selection/windowing rectangle border
6297
- if (g.NavWindowingTargetAnim == window)
6298
- {
6299
- float rounding = ImMax(window->WindowRounding, g.Style.WindowRounding);
6300
- ImRect bb = window->Rect();
6301
- bb.Expand(g.FontSize);
6302
- if (bb.Contains(viewport_rect)) // If a window fits the entire viewport, adjust its highlight inward
6303
- {
6304
- bb.Expand(-g.FontSize - 1.0f);
6305
- rounding = window->WindowRounding;
6306
- }
6307
- window->DrawList->AddRect(bb.Min, bb.Max, GetColorU32(ImGuiCol_NavWindowingHighlight, g.NavWindowingHighlightAlpha), rounding, 0, 3.0f);
6308
- }
6309
-
6310
6329
// UPDATE RECTANGLES (2- THOSE AFFECTED BY SCROLLING)
6311
6330
6312
6331
// Work rectangle.
@@ -8363,6 +8382,16 @@ ImGuiWindow* ImGui::GetTopMostPopupModal()
8363
8382
return NULL;
8364
8383
}
8365
8384
8385
+ ImGuiWindow* ImGui::GetTopMostAndVisiblePopupModal()
8386
+ {
8387
+ ImGuiContext& g = *GImGui;
8388
+ for (int n = g.OpenPopupStack.Size - 1; n >= 0; n--)
8389
+ if (ImGuiWindow* popup = g.OpenPopupStack.Data[n].Window)
8390
+ if ((popup->Flags & ImGuiWindowFlags_Modal) && IsWindowActiveAndVisible(popup))
8391
+ return popup;
8392
+ return NULL;
8393
+ }
8394
+
8366
8395
void ImGui::OpenPopup(const char* str_id, ImGuiPopupFlags popup_flags)
8367
8396
{
8368
8397
ImGuiContext& g = *GImGui;
0 commit comments