Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "implot"]
path = implot
url = https://github.com/StudioCherno/implot
31 changes: 31 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
add_library(ImGui STATIC
imconfig.h
imgui.h
imgui.cpp
imgui_draw.cpp
imgui_internal.h
imgui_tables.cpp
imgui_widgets.cpp
imgui_demo.cpp
imstb_rectpack.h
imstb_textedit.h
imstb_truetype.h

# ImPlot lives in this fork (added on the SimpleUX/Wayland lineage); compiled
# into ImGui to match the premake source split. implot_demo.cpp is excluded.
implot/implot.cpp
implot/implot_items.cpp
)

# Bare <imgui.h> / "imgui.h" and implot's relative "implot.h". The <imgui/...>
# style used across the engine is a vendor-layout convention and is exposed by
# Hazel/vendor/CMakeLists.txt, not assumed by this fork.
target_include_directories(ImGui SYSTEM PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_compile_features(ImGui PUBLIC cxx_std_20)

target_compile_definitions(ImGui PUBLIC IMGUI_USE_WCHAR32)
target_compile_definitions(ImGui PUBLIC
$<$<CONFIG:Dist>:NDEBUG IMGUI_DISABLE_DEMO_WINDOWS IMGUI_DISABLE_DEBUG_TOOLS>
)
Comment on lines +27 to +29

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🔴 Critical | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== CMakeLists.txt excerpt ==="
nl -ba CMakeLists.txt | sed -n '20,35p'

echo
echo "=== cmake availability ==="
command -v cmake >/dev/null && cmake --version | head -n 1 || echo "cmake not available"

echo
echo "=== target_compile_definitions help (if available) ==="
if command -v cmake >/dev/null; then
  cmake --help-command target_compile_definitions | sed -n '1,220p'
fi

Repository: StudioCherno/imgui

Length of output: 227


🏁 Script executed:

#!/bin/bash
set -euo pipefail

python3 - <<'PY'
from pathlib import Path
p = Path("CMakeLists.txt")
text = p.read_text()
for i, line in enumerate(text.splitlines(), 1):
    if 20 <= i <= 35:
        print(f"{i:4}: {line}")
PY

Repository: StudioCherno/imgui

Length of output: 844


Quote the generator expression and use semicolons
target_compile_definitions() splits unquoted spaces before generator-expression evaluation, so this becomes broken arguments. Wrap it in quotes and keep the macros in a semicolon list:

Proposed fix
 target_compile_definitions(ImGui PUBLIC IMGUI_USE_WCHAR32)
 target_compile_definitions(ImGui PUBLIC
-    $<$<CONFIG:Dist>:NDEBUG IMGUI_DISABLE_DEMO_WINDOWS IMGUI_DISABLE_DEBUG_TOOLS>
+    "$<$<CONFIG:Dist>:NDEBUG;IMGUI_DISABLE_DEMO_WINDOWS;IMGUI_DISABLE_DEBUG_TOOLS>"
 )
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
target_compile_definitions(ImGui PUBLIC
$<$<CONFIG:Dist>:NDEBUG IMGUI_DISABLE_DEMO_WINDOWS IMGUI_DISABLE_DEBUG_TOOLS>
)
target_compile_definitions(ImGui PUBLIC
"$<$<CONFIG:Dist>:NDEBUG;IMGUI_DISABLE_DEMO_WINDOWS;IMGUI_DISABLE_DEBUG_TOOLS>"
)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@CMakeLists.txt` around lines 27 - 29, The target_compile_definitions call for
ImGui is passing a generator expression with space-separated macros, which CMake
splits into broken arguments before evaluation. Update the
target_compile_definitions invocation for ImGui so the $<$<CONFIG:Dist>:...>
expression is quoted and the definitions inside it are expressed as a
semicolon-separated list, keeping the macros grouped correctly.


set_target_properties(ImGui PROPERTIES POSITION_INDEPENDENT_CODE ON FOLDER "Dependencies")
18 changes: 0 additions & 18 deletions backends/imgui_impl_glfw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -703,10 +703,6 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw
bool has_viewports = false;
#ifndef __EMSCRIPTEN__
has_viewports = true;
#if GLFW_HAS_GETPLATFORM
if (glfwGetPlatform() == GLFW_PLATFORM_WAYLAND)
has_viewports = false;
#endif
if (has_viewports)
io.BackendFlags |= ImGuiBackendFlags_PlatformHasViewports; // We can create multi-viewports on the Platform side (optional)
#endif
Expand Down Expand Up @@ -1068,11 +1064,6 @@ static void ImGui_ImplGlfw_UpdateMonitors()
// - Some accessibility applications are declaring virtual monitors with a DPI of 0.0f, see #7902. We preserve this value for caller to handle.
float ImGui_ImplGlfw_GetContentScaleForWindow(GLFWwindow* window)
{
#if GLFW_HAS_WAYLAND
if (ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(window))
if (bd->IsWayland)
return 1.0f;
#endif
#if GLFW_HAS_PER_MONITOR_DPI && !(defined(__APPLE__) || defined(__EMSCRIPTEN__) || defined(__ANDROID__))
float x_scale, y_scale;
glfwGetWindowContentScale(window, &x_scale, &y_scale);
Expand All @@ -1085,10 +1076,6 @@ float ImGui_ImplGlfw_GetContentScaleForWindow(GLFWwindow* window)

float ImGui_ImplGlfw_GetContentScaleForMonitor(GLFWmonitor* monitor)
{
#if GLFW_HAS_WAYLAND
if (ImGui_ImplGlfw_IsWayland()) // We can't access our bd->IsWayland cache for a monitor.
return 1.0f;
#endif
#if GLFW_HAS_PER_MONITOR_DPI && !(defined(__APPLE__) || defined(__EMSCRIPTEN__) || defined(__ANDROID__))
float x_scale, y_scale;
glfwGetMonitorContentScale(monitor, &x_scale, &y_scale);
Expand All @@ -1107,11 +1094,6 @@ static void ImGui_ImplGlfw_GetWindowSizeAndFramebufferScale(GLFWwindow* window,
glfwGetFramebufferSize(window, &display_w, &display_h);
float fb_scale_x = (w > 0) ? (float)display_w / (float)w : 1.0f;
float fb_scale_y = (h > 0) ? (float)display_h / (float)h : 1.0f;
#if GLFW_HAS_WAYLAND
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(window);
if (!bd->IsWayland)
fb_scale_x = fb_scale_y = 1.0f;
#endif
if (out_size != nullptr)
*out_size = ImVec2((float)w, (float)h);
if (out_framebuffer_scale != nullptr)
Expand Down
60 changes: 51 additions & 9 deletions imgui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1637,6 +1637,7 @@ ImGuiIO::ImGuiIO()
ConfigViewportsNoTaskBarIcon = false;
ConfigViewportsNoDecoration = true;
ConfigViewportsNoDefaultParent = true;
ConfigViewportsNoFloatingWindows = false;
ConfigViewportsPlatformFocusSetsImGuiFocus = true;

// Miscellaneous options
Expand Down Expand Up @@ -5418,10 +5419,28 @@ void ImGui::UpdateMouseMovingWindowNewFrame()
ImVec2 pos = g.IO.MousePos - g.ActiveIdClickOffset;
if (moving_window->Pos.x != pos.x || moving_window->Pos.y != pos.y)
{
SetWindowPos(moving_window, pos, ImGuiCond_Always);
// Use the actual window location returned by the window system if possible,
// since windows can snap to borders and things like that which result in a final
// window location that is not exactly the same as what was requested.
ImVec2 actual = pos;
if (moving_window->Viewport && moving_window->ViewportOwned
&& g.PlatformIO.Platform_SetWindowPos && g.PlatformIO.Platform_GetWindowPos)
{
g.PlatformIO.Platform_SetWindowPos(moving_window->Viewport, pos);
actual = g.PlatformIO.Platform_GetWindowPos(moving_window->Viewport);
}
SetWindowPos(moving_window, actual, ImGuiCond_Always);
if (moving_window->Viewport && moving_window->ViewportOwned) // Synchronize viewport immediately because some overlays may relies on clipping rectangle before we Begin() into the window.
{
moving_window->Viewport->Pos = pos;
// Use moving_window->Pos (which SetWindowPos truncated via
// ImTrunc) rather than raw `actual`. If viewport->Pos kept
// the untruncated value, a later sync site would overwrite it
// with window->Pos (truncated), and UpdatePlatformWindows
// would see the mismatch against LastPlatformPos and push the
// truncated position to the OS — which maps to a different
// OS-pixel than what we just set, causing oscillation.
moving_window->Viewport->Pos = moving_window->Pos;
moving_window->Viewport->LastPlatformPos = moving_window->Pos;
Comment on lines +5422 to +5443

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

glfwGetWindowPos stale value immediately after glfwSetWindowPos X11 Wayland asynchronous

💡 Result:

The observation that glfwGetWindowPos returns a stale value immediately after calling glfwSetWindowPos is a known consequence of the asynchronous nature of window management on X11 and the structural limitations on Wayland [1][2][3]. On X11, window positioning requests are asynchronous [2][4]. When you call glfwSetWindowPos, GLFW sends a request to the X Window Manager (WM) [2][4]. The application does not immediately move; instead, it must wait for the WM to process the request and send a ConfigureNotify event back to the application to confirm the new position [2][5]. Because glfwGetWindowPos reads the state currently tracked by the GLFW window object, it will report the "old" position until that event is received and processed, which typically happens during the next event-polling cycle (e.g., glfwPollEvents or glfwWaitEvents) [2][3]. Additionally, window managers may clamp, override, or ignore these requests (e.g., if a window is snapped to an edge or if decorations interfere), causing the "actual" final position to differ from what you requested [1][5][4]. On Wayland, this behavior is fundamentally different because the Wayland protocol restricts an application's ability to control its own position [6]. Applications generally cannot set their global screen position, and attempting to do so is often unsupported [7][6]. Consequently, glfwGetWindowPos and glfwSetWindowPos may be effectively non-functional or report static/default values depending on the specific compositor implementation [7][6]. To mitigate these issues in your application: 1. Allow the event loop to process: Ensure you call glfwPollEvents or glfwWaitEvents after calling glfwSetWindowPos to allow the platform to update the window state [3]. 2. Account for WM interference: Recognize that the window manager is the final authority on window placement [1][4]. If you are implementing features like draggable windows, consider tracking position changes relative to cursor input rather than relying on querying the window position after a set command [3]. 3. Use window callbacks: Instead of querying the position immediately, rely on the GLFW window position callback (glfwSetWindowPosCallback) to receive the authoritative, updated position once the window manager has finished the move [1][2].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Map the relevant symbols and find their usages/backends.
printf '\n== imgui.cpp outline ==\n'
ast-grep outline imgui.cpp --view expanded | sed -n '1,220p'

printf '\n== Platform_SetWindowPos / Platform_GetWindowPos usages ==\n'
rg -n "Platform_SetWindowPos|Platform_GetWindowPos|LastPlatformPos|SetWindowPos\\(" -S . --glob '!**/build/**' --glob '!**/dist/**'

printf '\n== Candidate backend files mentioning glfwGetWindowPos / glfwSetWindowPos ==\n'
rg -n "glfwGetWindowPos|glfwSetWindowPos|Platform_GetWindowPos|Platform_SetWindowPos" -S . --glob '!**/build/**' --glob '!**/dist/**'

Repository: StudioCherno/imgui

Length of output: 29464


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Read the relevant region of imgui.cpp with line numbers.
sed -n '5400,5465p' imgui.cpp | cat -n

Repository: StudioCherno/imgui

Length of output: 4455


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '\n== imgui.cpp outline ==\n'
ast-grep outline imgui.cpp --view expanded | sed -n '1,220p'

printf '\n== Platform_SetWindowPos / Platform_GetWindowPos usages ==\n'
rg -n "Platform_SetWindowPos|Platform_GetWindowPos|LastPlatformPos|SetWindowPos\\(" -S . --glob '!**/build/**' --glob '!**/dist/**'

printf '\n== Candidate backend files mentioning glfwGetWindowPos / glfwSetWindowPos ==\n'
rg -n "glfwGetWindowPos|glfwSetWindowPos|Platform_GetWindowPos|Platform_SetWindowPos" -S . --glob '!**/build/**' --glob '!**/dist/**'

printf '\n== imgui.cpp region ==\n'
sed -n '5400,5465p' imgui.cpp | cat -n

Repository: StudioCherno/imgui

Length of output: 33787


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the GLFW backend implementation around the platform position handlers.
sed -n '1200,1555p' backends/imgui_impl_glfw.cpp | cat -n

Repository: StudioCherno/imgui

Length of output: 18770


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Inspect the GLFW header docs for the semantics around window position callbacks.
sed -n '1970,2555p' examples/libs/glfw/include/GLFW/glfw3.h | cat -n | sed -n '1,180p'

Repository: StudioCherno/imgui

Length of output: 8240


Avoid the immediate glfwGetWindowPos() readback here. GLFW can queue window-pos updates until glfwPollEvents() on Linux, so this round-trip can return the previous position and make the drag lag or jitter. Use the requested pos unless the backend guarantees synchronous updates.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@imgui.cpp` around lines 5422 - 5443, The position sync in the moving-window
path should not rely on an immediate Platform_GetWindowPos/readback after
Platform_SetWindowPos, since GLFW can return a stale value and cause drag lag or
jitter. Update the logic in the moving_window viewport handling to use the
requested pos directly unless the backend is known to apply window moves
synchronously, and keep the SetWindowPos/Viewport->Pos synchronization in sync
with that choice.

moving_window->Viewport->UpdateWorkRect();
}
}
Expand Down Expand Up @@ -8052,7 +8071,8 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
// Lock menu offset so size calculation can use it as menu-bar windows need a minimum size.
window->DC.MenuBarOffset.x = ImMax(ImMax(window->WindowPadding.x, style.ItemSpacing.x), g.NextWindowData.MenuBarOffsetMinVal.x);
window->DC.MenuBarOffset.y = g.NextWindowData.MenuBarOffsetMinVal.y;
window->TitleBarHeight = (flags & ImGuiWindowFlags_NoTitleBar) ? 0.0f : g.FontSize + g.Style.FramePadding.y * 2.0f;
const float title_bar_padding = (window->DockIsActive) ? 8.0f : g.Style.FramePadding.y;
window->TitleBarHeight = (flags & ImGuiWindowFlags_NoTitleBar) ? 0.0f : g.FontSize + title_bar_padding * 2.0f;
window->MenuBarHeight = (flags & ImGuiWindowFlags_MenuBar) ? window->DC.MenuBarOffset.y + g.FontSize + g.Style.FramePadding.y * 2.0f : 0.0f;
window->FontRefSize = g.FontSize; // Lock this to discourage calling window->CalcFontSize() outside of current window.

Expand Down Expand Up @@ -17837,6 +17857,18 @@ static void ImGui::WindowSelectViewport(ImGuiWindow* window)
SetWindowViewport(window, main_viewport);
return;
}

// When ConfigViewportsNoFloatingWindows is set, only popups/tooltips/menus
// may create their own viewport. All other windows stay in the main viewport.
if (g.IO.ConfigViewportsNoFloatingWindows)
{
if ((flags & (ImGuiWindowFlags_Popup | ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_ChildWindow | ImGuiWindowFlags_ChildMenu)) == 0)
{
SetWindowViewport(window, main_viewport);
return;
}
}

window->ViewportOwned = false;

// Appearing popups reset their viewport so they can inherit again
Expand Down Expand Up @@ -20011,12 +20043,16 @@ static void ImGui::DockNodeWindowMenuUpdate(ImGuiDockNode* node, ImGuiTabBar* ta
SetNextWindowPos(ImVec2(node->Pos.x, node->Pos.y + GetFrameHeight()), ImGuiCond_Always, ImVec2(0.0f, 0.0f));
else
SetNextWindowPos(ImVec2(node->Pos.x + node->Size.x, node->Pos.y + GetFrameHeight()), ImGuiCond_Always, ImVec2(1.0f, 0.0f));
ImVec4 popupBg = g.Style.Colors[ImGuiCol_PopupBg];
popupBg.w = 1.0f;
PushStyleColor(ImGuiCol_PopupBg, popupBg);
if (BeginPopup("#WindowMenu"))
{
node->IsFocused = true;
g.DockNodeWindowMenuHandler(&g, node, tab_bar);
EndPopup();
}
PopStyleColor();
}

// User helper to append/amend into a dock node tab bar. Most commonly used to add e.g. a "+" button.
Expand Down Expand Up @@ -20414,28 +20450,30 @@ static void ImGui::DockNodeCalcTabBarLayout(const ImGuiDockNode* node, ImRect* o
ImGuiContext& g = *GImGui;
ImGuiStyle& style = g.Style;

ImRect r = ImRect(node->Pos.x, node->Pos.y, node->Pos.x + node->Size.x, node->Pos.y + g.FontSize + g.Style.FramePadding.y * 2.0f);
const float tab_padding_y = 8.0f;
ImRect r = ImRect(node->Pos.x, node->Pos.y, node->Pos.x + node->Size.x, node->Pos.y + g.FontSize + tab_padding_y * 2.0f);
if (out_title_rect) { *out_title_rect = r; }

r.Min.x += style.WindowBorderSize;
r.Max.x -= style.WindowBorderSize;

float button_sz = g.FontSize;
float button_y = r.Min.y + (r.GetHeight() - button_sz) * 0.5f;
r.Min.x += style.FramePadding.x;
r.Max.x -= style.FramePadding.x;
ImVec2 window_menu_button_pos = ImVec2(r.Min.x, r.Min.y + style.FramePadding.y);
ImVec2 window_menu_button_pos = ImVec2(r.Min.x, button_y);
if (node->HasCloseButton)
{
if (out_close_button_pos) *out_close_button_pos = ImVec2(r.Max.x - button_sz, r.Min.y + style.FramePadding.y);
if (out_close_button_pos) *out_close_button_pos = ImVec2(r.Max.x - button_sz, button_y);
r.Max.x -= button_sz + style.ItemInnerSpacing.x;
}
if (node->HasWindowMenuButton && style.WindowMenuButtonPosition == ImGuiDir_Left)
{
r.Min.x += button_sz + style.ItemInnerSpacing.x;
r.Min.x += button_sz + style.FramePadding.x;
}
else if (node->HasWindowMenuButton && style.WindowMenuButtonPosition == ImGuiDir_Right)
{
window_menu_button_pos = ImVec2(r.Max.x - button_sz, r.Min.y + style.FramePadding.y);
window_menu_button_pos = ImVec2(r.Max.x - button_sz, button_y);
r.Max.x -= button_sz + style.ItemInnerSpacing.x;
}
if (out_tab_bar_rect) { *out_tab_bar_rect = r; }
Expand Down Expand Up @@ -21955,7 +21993,11 @@ void ImGui::BeginDockableDragDropSource(ImGuiWindow* window)
g.LastItemData.ID = window->MoveId;
window = window->RootWindowDockTree;
IM_ASSERT((window->Flags & ImGuiWindowFlags_NoDocking) == 0);
bool is_drag_docking = (g.IO.ConfigDockingWithShift) || ImRect(0, 0, window->SizeFull.x, GetFrameHeight()).Contains(g.ActiveIdClickOffset); // FIXME-DOCKING: Need to make this stateful and explicit
// LuckyEngine: mirrors the custom tab_padding_y in TabItemCalcSize - without this,
// clicks in the lower half of a tall tab fall outside GetFrameHeight() and tear-away
// drags never turn into a drag-drop source (no docking overlay until re-grab).
const float tab_drag_height = ImMax(GetFrameHeight(), g.FontSize + 8.0f * 2.0f);
bool is_drag_docking = (g.IO.ConfigDockingWithShift) || ImRect(0, 0, window->SizeFull.x, tab_drag_height).Contains(g.ActiveIdClickOffset); // FIXME-DOCKING: Need to make this stateful and explicit
ImGuiDragDropFlags drag_drop_flags = ImGuiDragDropFlags_SourceNoPreviewTooltip | ImGuiDragDropFlags_SourceNoHoldToOpenOthers | ImGuiDragDropFlags_PayloadAutoExpire | ImGuiDragDropFlags_PayloadNoCrossContext | ImGuiDragDropFlags_PayloadNoCrossProcess;
if (is_drag_docking && BeginDragDropSource(drag_drop_flags))
{
Expand Down
1 change: 1 addition & 0 deletions imgui.h
Original file line number Diff line number Diff line change
Expand Up @@ -2521,6 +2521,7 @@ struct ImGuiIO
bool ConfigViewportsNoTaskBarIcon; // = false // Disable default OS task bar icon flag for secondary viewports. When a viewport doesn't want a task bar icon, ImGuiViewportFlags_NoTaskBarIcon will be set on it.
bool ConfigViewportsNoDecoration; // = true // Disable default OS window decoration flag for secondary viewports. When a viewport doesn't want window decorations, ImGuiViewportFlags_NoDecoration will be set on it. Enabling decoration can create subsequent issues at OS levels (e.g. minimum window size).
bool ConfigViewportsNoDefaultParent; // = true // When false: set secondary viewports' ParentViewportId to main viewport ID by default. Expects the platform backend to setup a parent/child relationship between the OS windows based on this value. Some backend may ignore this. Set to true if you want viewports to automatically be parent of main viewport, otherwise all viewports will be top-level OS windows.
bool ConfigViewportsNoFloatingWindows;// = false // When set, only popups, tooltips and menus may create their own viewport. Undocked/floating windows stay inside the main viewport. Useful on platforms (e.g. Wayland) where secondary OS windows for docked panels are problematic.
bool ConfigViewportsPlatformFocusSetsImGuiFocus;//= true // When a platform window is focused (e.g. using Alt+Tab, clicking Platform Title Bar), apply corresponding focus on imgui windows (may clear focus/active id from imgui windows location in other platform windows). In principle this is better enabled but we provide an opt-out, because some Linux window managers tend to eagerly focus windows (e.g. on mouse hover, or even a simple window pos/size change).

// DPI/Scaling options
Expand Down
11 changes: 9 additions & 2 deletions imgui_draw.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5923,8 +5923,15 @@ void ImGui::RenderArrowPointingAt(ImDrawList* draw_list, ImVec2 pos, ImVec2 half
// and because the saved space means that the left-most tab label can stay at exactly the same position as the label of a loose window.
void ImGui::RenderArrowDockMenu(ImDrawList* draw_list, ImVec2 p_min, float sz, ImU32 col)
{
draw_list->AddRectFilled(p_min + ImVec2(sz * 0.20f, sz * 0.15f), p_min + ImVec2(sz * 0.80f, sz * 0.30f), col);
RenderArrowPointingAt(draw_list, p_min + ImVec2(sz * 0.50f, sz * 0.85f), ImVec2(sz * 0.30f, sz * 0.40f), ImGuiDir_Down, col);
// Draw a hamburger menu icon (three horizontal lines)
float cx = p_min.x + sz * 0.5f;
float cy = p_min.y + sz * 0.5f;
float half = sz * 0.30f;
float spacing = sz * 0.22f;
float thickness = ImMax(sz * 0.12f, 1.0f);
draw_list->AddLine(ImVec2(cx - half, cy - spacing), ImVec2(cx + half, cy - spacing), col, thickness);
draw_list->AddLine(ImVec2(cx - half, cy), ImVec2(cx + half, cy), col, thickness);
draw_list->AddLine(ImVec2(cx - half, cy + spacing), ImVec2(cx + half, cy + spacing), col, thickness);
}

static inline float ImAcos01(float x)
Expand Down
Loading