From da3a36eefda4152488981f9953a91c2b69aa6e4a Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 3 Dec 2021 19:11:58 +0100 Subject: [PATCH] Backport from docking branch: minor stuff. Fixed software mouse cursor being rendered multiple times if Render() is called more than once. --- docs/CHANGELOG.txt | 1 + imgui.cpp | 29 +++++++++++++++++++---------- imgui.h | 2 +- imgui_internal.h | 3 ++- 4 files changed, 23 insertions(+), 12 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index c90d3ce6..64ff179e 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -76,6 +76,7 @@ Other Changes: - Metrics: Added a node showing windows in submission order and showing the Begin() stack. - Misc: Added missing ImGuiMouseCursor_NotAllowed cursor for software rendering (when the io.MouseDrawCursor flag is enabled). (#4713) [@nobody-special666] +- Misc: Fixed software mouse cursor being rendered multiple times if Render() is called more than once. - Misc: Fix MinGW DLL build issue (when IMGUI_API is defined). [@rokups] - CI: Add MinGW DLL build to test suite. [@rokups] - Backends: Vulkan: Call vkCmdSetScissor() at the end of render with a full-viewport to reduce diff --git a/imgui.cpp b/imgui.cpp index f53bdafe..83800dd5 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3386,6 +3386,17 @@ bool ImGui::IsClippedEx(const ImRect& bb, ImGuiID id) return false; } +// This is also inlined in ItemAdd() +// Note: if ImGuiItemStatusFlags_HasDisplayRect is set, user needs to set window->DC.LastItemDisplayRect! +void ImGui::SetLastItemData(ImGuiID item_id, ImGuiItemFlags in_flags, ImGuiItemStatusFlags item_flags, const ImRect& item_rect) +{ + ImGuiContext& g = *GImGui; + g.LastItemData.ID = item_id; + g.LastItemData.InFlags = in_flags; + g.LastItemData.StatusFlags = item_flags; + g.LastItemData.Rect = item_rect; +} + float ImGui::CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x) { if (wrap_pos_x < 0.0f) @@ -4533,6 +4544,7 @@ void ImGui::Render() if (g.FrameCountEnded != g.FrameCount) EndFrame(); + const bool first_render_of_frame = (g.FrameCountRendered != g.FrameCount); g.FrameCountRendered = g.FrameCount; g.IO.MetricsRenderWindows = 0; @@ -4570,7 +4582,7 @@ void ImGui::Render() viewport->DrawDataBuilder.FlattenIntoSingleLayer(); // Draw software mouse cursor if requested by io.MouseDrawCursor flag - if (g.IO.MouseDrawCursor) + if (g.IO.MouseDrawCursor && first_render_of_frame) RenderMouseCursor(GetForegroundDrawList(viewport), g.IO.MousePos, g.Style.MouseCursorScale, g.MouseCursor, IM_COL32_WHITE, IM_COL32_BLACK, IM_COL32(0, 0, 0, 48)); // Add foreground ImDrawList (for each active viewport) @@ -5351,11 +5363,11 @@ ImVec2 ImGui::CalcWindowNextAutoFitSize(ImGuiWindow* window) return size_final; } -static ImGuiCol GetWindowBgColorIdxFromFlags(ImGuiWindowFlags flags) +static ImGuiCol GetWindowBgColorIdx(ImGuiWindow* window) { - if (flags & (ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_Popup)) + if (window->Flags & (ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_Popup)) return ImGuiCol_PopupBg; - if (flags & ImGuiWindowFlags_ChildWindow) + if (window->Flags & ImGuiWindowFlags_ChildWindow) return ImGuiCol_ChildBg; return ImGuiCol_WindowBg; } @@ -5633,7 +5645,7 @@ void ImGui::RenderWindowDecorations(ImGuiWindow* window, const ImRect& title_bar // Window background if (!(flags & ImGuiWindowFlags_NoBackground)) { - ImU32 bg_col = GetColorU32(GetWindowBgColorIdxFromFlags(flags)); + ImU32 bg_col = GetColorU32(GetWindowBgColorIdx(window)); bool override_alpha = false; float alpha = 1.0f; if (g.NextWindowData.Flags & ImGuiNextWindowDataFlags_HasBgAlpha) @@ -6386,10 +6398,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) // We fill last item data based on Title Bar/Tab, in order for IsItemHovered() and IsItemActive() to be usable after Begin(). // This is useful to allow creating context menus on title bar only, etc. - g.LastItemData.ID = window->MoveId; - g.LastItemData.InFlags = g.CurrentItemFlags; - g.LastItemData.StatusFlags = IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max, false) ? ImGuiItemStatusFlags_HoveredRect : 0; - g.LastItemData.Rect = title_bar_rect; + SetLastItemData(window->MoveId, g.CurrentItemFlags, IsMouseHoveringRect(title_bar_rect.Min, title_bar_rect.Max, false) ? ImGuiItemStatusFlags_HoveredRect : 0, title_bar_rect); #ifdef IMGUI_ENABLE_TEST_ENGINE if (!(window->Flags & ImGuiWindowFlags_NoTitleBar)) @@ -6837,8 +6846,8 @@ bool ImGui::IsWindowFocused(ImGuiFocusedFlags flags) return false; if (flags & ImGuiFocusedFlags_AnyWindow) return true; - IM_ASSERT(cur_window); // Not inside a Begin()/End() + IM_ASSERT(cur_window); // Not inside a Begin()/End() const bool popup_hierarchy = (flags & ImGuiFocusedFlags_NoPopupHierarchy) == 0; if (flags & ImGuiHoveredFlags_RootWindow) cur_window = GetCombinedRootWindow(cur_window, popup_hierarchy); diff --git a/imgui.h b/imgui.h index 1fcadcbb..848d6b57 100644 --- a/imgui.h +++ b/imgui.h @@ -954,7 +954,7 @@ enum ImGuiWindowFlags_ ImGuiWindowFlags_NoMove = 1 << 2, // Disable user moving the window ImGuiWindowFlags_NoScrollbar = 1 << 3, // Disable scrollbars (window can still scroll with mouse or programmatically) ImGuiWindowFlags_NoScrollWithMouse = 1 << 4, // Disable user vertically scrolling with mouse wheel. On child window, mouse wheel will be forwarded to the parent unless NoScrollbar is also set. - ImGuiWindowFlags_NoCollapse = 1 << 5, // Disable user collapsing window by double-clicking on it + ImGuiWindowFlags_NoCollapse = 1 << 5, // Disable user collapsing window by double-clicking on it. Also referred to as Window Menu Button (e.g. within a docking node). ImGuiWindowFlags_AlwaysAutoResize = 1 << 6, // Resize every window to its content every frame ImGuiWindowFlags_NoBackground = 1 << 7, // Disable drawing background color (WindowBg, etc.) and outside border. Similar as using SetNextWindowBgAlpha(0.0f). ImGuiWindowFlags_NoSavedSettings = 1 << 8, // Never load/save settings in .ini file diff --git a/imgui_internal.h b/imgui_internal.h index f624e707..c1111c87 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -2100,7 +2100,7 @@ struct ImGuiTabItem }; // Storage for a tab bar (sizeof() 152 bytes) -struct ImGuiTabBar +struct IMGUI_API ImGuiTabBar { ImVector Tabs; ImGuiTabBarFlags Flags; @@ -2499,6 +2499,7 @@ namespace ImGui IMGUI_API bool ItemAdd(const ImRect& bb, ImGuiID id, const ImRect* nav_bb = NULL, ImGuiItemFlags extra_flags = 0); IMGUI_API bool ItemHoverable(const ImRect& bb, ImGuiID id); IMGUI_API bool IsClippedEx(const ImRect& bb, ImGuiID id); + IMGUI_API void SetLastItemData(ImGuiID item_id, ImGuiItemFlags in_flags, ImGuiItemStatusFlags status_flags, const ImRect& item_rect); IMGUI_API ImVec2 CalcItemSize(ImVec2 size, float default_w, float default_h); IMGUI_API float CalcWrapWidthForPos(const ImVec2& pos, float wrap_pos_x); IMGUI_API void PushMultiItemsWidths(int components, float width_full);