diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 92d41dac1..1c9e8dcdb 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -61,7 +61,7 @@ jobs:
echo '#define IMGUI_IMPLEMENTATION' >> example_single_file.cpp
echo '#include "misc/single_file/imgui_single_file.h"' >> example_single_file.cpp
g++ -I. -Wall -Wformat -shared -o libimgui.dll -Wl,--out-implib,libimgui.a example_single_file.cpp -limm32
- g++ -I. -Wall -Wformat -DIMGUI_API='__declspec(dllimport)' -o example_null.exe examples/example_null/main.cpp -L. -limgui
+ g++ -I. -Wall -Wformat -DIMGUI_API='__declspec(dllimport)' -DIMGUI_IMPL_API= -o example_null.exe examples/example_null/main.cpp -L. -limgui
rm -f example_null.exe libimgui.* example_single_file.*
- name: Build example_null (extra warnings, msvc 64-bit)
@@ -106,7 +106,7 @@ jobs:
echo #include "misc/single_file/imgui_single_file.h" >> example_single_file.cpp
cl.exe /D_USRDLL /D_WINDLL /I. example_single_file.cpp /LD /FeImGui.dll /link
- cl.exe /DIMGUI_API=__declspec(dllimport) /I. ImGui.lib /Feexample_null.exe examples/example_null/main.cpp
+ cl.exe /DIMGUI_API=__declspec(dllimport) -DIMGUI_IMPL_API= /I. ImGui.lib /Feexample_null.exe examples/example_null/main.cpp
# Win64 examples are more frequently compilted than the Win32 examples.
# More of the Win32 examples requires 'workflow_run' to reduce waste.
diff --git a/backends/imgui_impl_dx12.h b/backends/imgui_impl_dx12.h
index 7d4c04378..83f6fb156 100644
--- a/backends/imgui_impl_dx12.h
+++ b/backends/imgui_impl_dx12.h
@@ -45,7 +45,7 @@ struct ImGui_ImplDX12_InitInfo
D3D12_GPU_DESCRIPTOR_HANDLE LegacySingleSrvGpuDescriptor;
#endif
- ImGui_ImplDX12_InitInfo() { memset((void*)this, 0, sizeof(*this)); }
+ ImGui_ImplDX12_InitInfo() { memset(this, 0, sizeof(*this)); }
};
// Follow "Getting Started" link and check examples/ folder to learn about using backends!
diff --git a/backends/imgui_impl_glfw.cpp b/backends/imgui_impl_glfw.cpp
index 15c0aa55a..c9dbafa14 100644
--- a/backends/imgui_impl_glfw.cpp
+++ b/backends/imgui_impl_glfw.cpp
@@ -110,10 +110,12 @@
// Clang warnings with -Weverything
#if defined(__clang__)
#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast
-#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
+#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast
+#pragma clang diagnostic ignored "-Wsign-conversion" // warning: implicit conversion changes signedness
+#pragma clang diagnostic ignored "-Wexit-time-destructors" // warning: declaration requires an exit-time destructor // exit-time destruction order is undefined. if MemFree() leads to users code that has been disabled before exit it might cause problems. ImGui coding style welcomes static/globals.
+#pragma clang diagnostic ignored "-Wglobal-constructors" // warning: declaration requires a global destructor // similar to above, not sure what the exact difference is.
#elif defined(__GNUC__)
-#pragma GCC diagnostic ignored "-Wfloat-equal" // warning: comparing floating-point with '==' or '!=' is unsafe
+#pragma GCC diagnostic ignored "-Wfloat-equal" // warning: comparing floating-point with '==' or '!=' is unsafe
#endif
// GLFW
@@ -1086,8 +1088,8 @@ static void ImGui_ImplGlfw_GetWindowSizeAndFramebufferScale(GLFWwindow* window,
int display_w, display_h;
glfwGetWindowSize(window, &w, &h);
glfwGetFramebufferSize(window, &display_w, &display_h);
- float fb_scale_x = (w > 0) ? (float)display_w / w : 1.0f;
- float fb_scale_y = (h > 0) ? (float)display_h / h : 1.0f;
+ 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_X11_OR_WAYLAND
ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(window);
if (!bd->IsWayland)
diff --git a/backends/imgui_impl_null.cpp b/backends/imgui_impl_null.cpp
index eb99f5313..6bf3ddb22 100644
--- a/backends/imgui_impl_null.cpp
+++ b/backends/imgui_impl_null.cpp
@@ -17,46 +17,51 @@
#ifndef IMGUI_DISABLE
#include "imgui_impl_null.h"
-bool ImGui_ImplNull_Init()
+// Clang/GCC warnings with -Weverything
+#if defined(__clang__)
+#pragma clang diagnostic ignored "-Wold-style-cast" // warning: use of old-style cast // yes, they are more terse.
+#endif
+
+IMGUI_IMPL_API bool ImGui_ImplNull_Init()
{
ImGui_ImplNullPlatform_Init();
ImGui_ImplNullRender_Init();
return true;
}
-void ImGui_ImplNull_Shutdown()
+IMGUI_IMPL_API void ImGui_ImplNull_Shutdown()
{
ImGui_ImplNullRender_Shutdown();
ImGui_ImplNullPlatform_Shutdown();
}
-void ImGui_ImplNull_NewFrame()
+IMGUI_IMPL_API void ImGui_ImplNull_NewFrame()
{
ImGui_ImplNullPlatform_NewFrame();
ImGui_ImplNullRender_NewFrame();
}
-bool ImGui_ImplNullPlatform_Init()
+IMGUI_IMPL_API bool ImGui_ImplNullPlatform_Init()
{
ImGuiIO& io = ImGui::GetIO();
io.BackendFlags |= ImGuiBackendFlags_HasMouseCursors;
return true;
}
-void ImGui_ImplNullPlatform_Shutdown()
+IMGUI_IMPL_API void ImGui_ImplNullPlatform_Shutdown()
{
ImGuiIO& io = ImGui::GetIO();
io.BackendFlags &= ~ImGuiBackendFlags_HasMouseCursors;
}
-void ImGui_ImplNullPlatform_NewFrame()
+IMGUI_IMPL_API void ImGui_ImplNullPlatform_NewFrame()
{
ImGuiIO& io = ImGui::GetIO();
io.DisplaySize = ImVec2(1920, 1080);
io.DeltaTime = 1.0f / 60.0f;
}
-bool ImGui_ImplNullRender_Init()
+IMGUI_IMPL_API bool ImGui_ImplNullRender_Init()
{
ImGuiIO& io = ImGui::GetIO();
io.BackendFlags |= ImGuiBackendFlags_RendererHasVtxOffset;
@@ -64,18 +69,18 @@ bool ImGui_ImplNullRender_Init()
return true;
}
-void ImGui_ImplNullRender_Shutdown()
+IMGUI_IMPL_API void ImGui_ImplNullRender_Shutdown()
{
ImGuiIO& io = ImGui::GetIO();
io.BackendFlags &= ~ImGuiBackendFlags_RendererHasVtxOffset;
io.BackendFlags &= ~ImGuiBackendFlags_RendererHasTextures;
}
-void ImGui_ImplNullRender_NewFrame()
+IMGUI_IMPL_API void ImGui_ImplNullRender_NewFrame()
{
}
-void ImGui_ImplNullRender_UpdateTexture(ImTextureData* tex)
+static void ImGui_ImplNullRender_UpdateTexture(ImTextureData* tex)
{
if (tex->Status == ImTextureStatus_WantCreate || tex->Status == ImTextureStatus_WantDestroy)
tex->SetStatus(ImTextureStatus_OK);
@@ -86,7 +91,7 @@ void ImGui_ImplNullRender_UpdateTexture(ImTextureData* tex)
}
}
-void ImGui_ImplNullRender_RenderDrawData(ImDrawData* draw_data)
+IMGUI_IMPL_API void ImGui_ImplNullRender_RenderDrawData(ImDrawData* draw_data)
{
if (draw_data->Textures != nullptr)
for (ImTextureData* tex : *draw_data->Textures)
diff --git a/backends/imgui_impl_sdl3.cpp b/backends/imgui_impl_sdl3.cpp
index 9c36984e7..3f60ce4a8 100644
--- a/backends/imgui_impl_sdl3.cpp
+++ b/backends/imgui_impl_sdl3.cpp
@@ -957,8 +957,8 @@ static void ImGui_ImplSDL3_GetWindowSizeAndFramebufferScale(SDL_Window* window,
#else
int display_w, display_h;
SDL_GetWindowSizeInPixels(window, &display_w, &display_h);
- float fb_scale_x = (w > 0) ? (float)display_w / w : 1.0f;
- float fb_scale_y = (h > 0) ? (float)display_h / h : 1.0f;
+ 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;
#endif
if (out_size != nullptr)
diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt
index a907bf6bc..9366fdf52 100644
--- a/docs/CHANGELOG.txt
+++ b/docs/CHANGELOG.txt
@@ -87,10 +87,23 @@ Other Changes:
keys in order to allow e.g. external Shortcut override behavior. (#9004)
- When using a callback to reduce/manipulate the value of BufTextLen,
we do not require anymore that CursorPos be clamped by user code. (#9029)
+ - Fixed an assert when using ImGuiInputTextFlags_ReadOnly and making
+ underlying contents shorter while text is selected. (#9069, #3237)
+ (regression from 1.92.3)
- InputTextMultiline: fixed a crash when using ImGuiInputTextFlags_WordWrap and
resizing the parent window while keeping the multi-line field active (which is
most typically achieved when resizing programmatically or via a docking layout
reacting to a platform window resize). (#3237, #9007) [@anton-kl, @ocornut]
+- Nav:
+ - Reworked PageUp/PageDown to pick same-page top/bottom page based
+ on inner rectangle rather than clipping rectangle, ensuring consistent
+ (but occasionally less practical) navigation result when a window is
+ partially out of screen. (#787)
+ - Improved/clarified behavior when requesting PageUp/PageDown from a
+ focused item which is outside of visible boundaries: now ends up one
+ page away from focused item. (#9079)
+ - Clipper: fixed an issue when using up/down from an item outside of
+ visible bound and using the clipper. (#9079)
- Fonts:
- Calling ImFontAtlas::Clear() mid-frame without re-adding a font will
lead to a more explicit crash.
@@ -109,6 +122,8 @@ Other Changes:
- Drag and Drop:
- Added ImGuiDragDropFlags_AcceptDrawAsHovered to make accepting item render
as hovered, which can allow using e.g. Button() as drop target. (#8632)
+ - Pressing Escape while carrying a payload automatically cancel the
+ active drag and drop. (#9071)
- Style: added ImGuiCol_DragDropTargetBg, style.DragDropTargetRounding,
style.DragDropTargetBorderSize and style.DragDropTargetPadding to configure
the drop target highlight. (#9056) [@aaronkirkham]
@@ -151,6 +166,8 @@ Other Changes:
- Win32: Revert 1.92.4 change of comparing dwPacketNumber, which prevents
refreshing accurate gamepad info after focus-out + io.ClearInputKeys(). (#8556)
- Examples:
+ - Null: update examples_null to use imgui_impl_null (which is a bit overengineering
+ but somehow consistent).
- GLFW+WebGPU: update example for latest specs, to work on Emscripten 4.0.10+,
latest Dawn-Native and WGPU-Native. (#8381, #8567, #8191, #7435) [@brutpitt]
- GLFW+WebGPU: removed unnecessary ImGui_ImplWGPU_InvalidateDeviceObjects() call
diff --git a/docs/TODO.txt b/docs/TODO.txt
index dbeee1db4..91d5bb509 100644
--- a/docs/TODO.txt
+++ b/docs/TODO.txt
@@ -351,7 +351,7 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i
- examples: window minimize, maximize (#583)
- examples: provide a zero frame-rate/idle example.
- - examples: dx11/dx12: try to use new swapchain blit models (#2970)
+ - examples: dx11/dx12: try to use new swapchain blit models (#2970, #9031)
- backends: report it better when not able to create texture?
- backends: glfw: could go idle when minimized? if (glfwGetWindowAttrib(window, GLFW_ICONIFIED)) { glfwWaitEvents(); continue; } // issue: DeltaTime will be super high on resume, perhaps provide a way to let impl know (#440)
- backends: opengl: rename imgui_impl_opengl2 to impl_opengl_legacy and imgui_impl_opengl3 to imgui_impl_opengl? (#1900)
diff --git a/examples/example_null/build_win32.bat b/examples/example_null/build_win32.bat
index 3a07d8f8d..be81d8093 100644
--- a/examples/example_null/build_win32.bat
+++ b/examples/example_null/build_win32.bat
@@ -1,3 +1,3 @@
@REM Build for Visual Studio compiler. Run your copy of vcvars32.bat or vcvarsall.bat to setup command-line compiler.
mkdir Debug
-cl /nologo /Zi /MD /utf-8 /I ..\.. %* *.cpp ..\..\*.cpp ..\..\backends\imgui_impl_null.cpp /FeDebug/example_null.exe /FoDebug/ /link gdi32.lib shell32.lib imm32.lib
+cl /nologo /Zi /MD /utf-8 /I ..\.. %* *.cpp ..\..\*.cpp /FeDebug/example_null.exe /FoDebug/ /link gdi32.lib shell32.lib imm32.lib
diff --git a/examples/example_null/example_null.vcxproj b/examples/example_null/example_null.vcxproj
index 7d0d59279..c8836c7e4 100644
--- a/examples/example_null/example_null.vcxproj
+++ b/examples/example_null/example_null.vcxproj
@@ -151,7 +151,6 @@
-
diff --git a/examples/example_null/example_null.vcxproj.filters b/examples/example_null/example_null.vcxproj.filters
index f5dd02f2d..9b485d5f4 100644
--- a/examples/example_null/example_null.vcxproj.filters
+++ b/examples/example_null/example_null.vcxproj.filters
@@ -18,9 +18,6 @@
imgui
-
- sources
-
@@ -54,4 +51,4 @@
imgui
-
+
\ No newline at end of file
diff --git a/examples/example_null/main.cpp b/examples/example_null/main.cpp
index 5e94a6fb6..eba675670 100644
--- a/examples/example_null/main.cpp
+++ b/examples/example_null/main.cpp
@@ -3,7 +3,11 @@
// This is useful to test building, but you cannot interact with anything here!
#include "imgui.h"
#include
-#include "imgui_impl_null.h"
+
+// For imgui_impl_null: use relative filename + embed implementation directly by including the .cpp file.
+// This is to simplify casual building of this example from all sorts of test scripts.
+#include "../../backends/imgui_impl_null.h"
+#include "../../backends/imgui_impl_null.cpp"
int main(int, char**)
{
diff --git a/imgui.cpp b/imgui.cpp
index 727ac1f9c..ad22162ee 100644
--- a/imgui.cpp
+++ b/imgui.cpp
@@ -3413,10 +3413,12 @@ static bool ImGuiListClipper_StepInternal(ImGuiListClipper* clipper)
{
// Add range selected to be included for navigation
const bool is_nav_request = (g.NavMoveScoringItems && g.NavWindow && g.NavWindow->RootWindowForNav == window->RootWindowForNav);
+ const int nav_off_min = (is_nav_request && g.NavMoveClipDir == ImGuiDir_Up) ? -1 : 0;
+ const int nav_off_max = (is_nav_request && g.NavMoveClipDir == ImGuiDir_Down) ? 1 : 0;
if (is_nav_request)
{
- data->Ranges.push_back(ImGuiListClipperRange::FromPositions(g.NavScoringRect.Min.y, g.NavScoringRect.Max.y, 0, 0));
- data->Ranges.push_back(ImGuiListClipperRange::FromPositions(g.NavScoringNoClipRect.Min.y, g.NavScoringNoClipRect.Max.y, 0, 0));
+ data->Ranges.push_back(ImGuiListClipperRange::FromPositions(g.NavScoringRect.Min.y, g.NavScoringRect.Max.y, nav_off_min, nav_off_max));
+ data->Ranges.push_back(ImGuiListClipperRange::FromPositions(g.NavScoringNoClipRect.Min.y, g.NavScoringNoClipRect.Max.y, nav_off_min, nav_off_max));
}
if (is_nav_request && (g.NavMoveFlags & ImGuiNavMoveFlags_IsTabbing) && g.NavTabbingDir == -1)
data->Ranges.push_back(ImGuiListClipperRange::FromIndices(clipper->ItemsCount - 1, clipper->ItemsCount));
@@ -3445,9 +3447,7 @@ static bool ImGuiListClipper_StepInternal(ImGuiListClipper* clipper)
}
// Add main visible range
- const int off_min = (is_nav_request && g.NavMoveClipDir == ImGuiDir_Up) ? -1 : 0;
- const int off_max = (is_nav_request && g.NavMoveClipDir == ImGuiDir_Down) ? 1 : 0;
- data->Ranges.push_back(ImGuiListClipperRange::FromPositions(min_y, max_y, off_min, off_max));
+ data->Ranges.push_back(ImGuiListClipperRange::FromPositions(min_y, max_y, nav_off_min, nav_off_max));
}
// Convert position ranges to item index ranges
@@ -5729,6 +5729,11 @@ void ImGui::NewFrame()
g.DragDropWithinSource = false;
g.DragDropWithinTarget = false;
g.DragDropHoldJustPressedId = 0;
+ if (g.DragDropActive && IsKeyPressed(ImGuiKey_Escape, ImGuiInputFlags_None, g.ActiveId)) // Also works when g.ActiveId==0 (aka leftover payload in progress, no active id)
+ {
+ ClearActiveID();
+ ClearDragDrop();
+ }
g.TooltipPreviousWindow = NULL;
// Close popups on focus lost (currently wip/opt-in)
@@ -13914,10 +13919,14 @@ static void ImGui::NavProcessItem()
// Features like PageUp/PageDown need to maintain a separate score for the visible set of items.
const float VISIBLE_RATIO = 0.70f;
- if ((g.NavMoveFlags & ImGuiNavMoveFlags_AlsoScoreVisibleSet) && window->ClipRect.Overlaps(nav_bb))
- if (ImClamp(nav_bb.Max.y, window->ClipRect.Min.y, window->ClipRect.Max.y) - ImClamp(nav_bb.Min.y, window->ClipRect.Min.y, window->ClipRect.Max.y) >= (nav_bb.Max.y - nav_bb.Min.y) * VISIBLE_RATIO)
- if (NavScoreItem(&g.NavMoveResultLocalVisible, nav_bb))
- NavApplyItemToResult(&g.NavMoveResultLocalVisible);
+ if (g.NavMoveFlags & ImGuiNavMoveFlags_AlsoScoreVisibleSet)
+ {
+ const ImRect& r = window->InnerRect; // window->ClipRect
+ if (r.Overlaps(nav_bb))
+ if (ImClamp(nav_bb.Max.y, r.Min.y, r.Max.y) - ImClamp(nav_bb.Min.y, r.Min.y, r.Max.y) >= (nav_bb.Max.y - nav_bb.Min.y) * VISIBLE_RATIO)
+ if (NavScoreItem(&g.NavMoveResultLocalVisible, nav_bb))
+ NavApplyItemToResult(&g.NavMoveResultLocalVisible);
+ }
}
}
}
@@ -14521,14 +14530,9 @@ void ImGui::NavUpdateCreateMoveRequest()
// Update PageUp/PageDown/Home/End scroll
// FIXME-NAV: Consider enabling those keys even without the master ImGuiConfigFlags_NavEnableKeyboard flag?
- float scoring_rect_offset_y = 0.0f;
+ float scoring_page_offset_y = 0.0f;
if (window && g.NavMoveDir == ImGuiDir_None && nav_keyboard_active)
- scoring_rect_offset_y = NavUpdatePageUpPageDown();
- if (scoring_rect_offset_y != 0.0f)
- {
- g.NavScoringNoClipRect = window->InnerRect;
- g.NavScoringNoClipRect.TranslateY(scoring_rect_offset_y);
- }
+ scoring_page_offset_y = NavUpdatePageUpPageDown();
// [DEBUG] Always send a request when holding Ctrl. Hold Ctrl + Arrow change the direction.
#if IMGUI_DEBUG_NAV_SCORING
@@ -14592,12 +14596,17 @@ void ImGui::NavUpdateCreateMoveRequest()
{
ImRect nav_rect_rel = !window->NavRectRel[g.NavLayer].IsInverted() ? window->NavRectRel[g.NavLayer] : ImRect(0, 0, 0, 0);
scoring_rect = WindowRectRelToAbs(window, nav_rect_rel);
- scoring_rect.TranslateY(scoring_rect_offset_y);
+ if (scoring_page_offset_y != 0.0f)
+ g.NavScoringNoClipRect = scoring_rect;
+ scoring_rect.TranslateY(scoring_page_offset_y);
+ if (scoring_page_offset_y != 0.0f)
+ g.NavScoringNoClipRect.Add(scoring_rect);
+ //GetForegroundDrawList()->AddRectFilled(scoring_rect.Min - ImVec2(1, 1), scoring_rect.Max + ImVec2(1, 1), IM_COL32(255, 100, 0, 80)); // [DEBUG] Pre-bias
if (g.NavMoveSubmitted)
NavBiasScoringRect(scoring_rect, window->RootWindowForNav->NavPreferredScoringPosRel[g.NavLayer], g.NavMoveDir, g.NavMoveFlags);
IM_ASSERT(!scoring_rect.IsInverted()); // Ensure we have a non-inverted bounding box here will allow us to remove extraneous ImFabs() calls in NavScoreItem().
- //GetForegroundDrawList()->AddRect(scoring_rect.Min, scoring_rect.Max, IM_COL32(255,200,0,255)); // [DEBUG]
- //if (!g.NavScoringNoClipRect.IsInverted()) { GetForegroundDrawList()->AddRect(g.NavScoringNoClipRect.Min, g.NavScoringNoClipRect.Max, IM_COL32(255, 200, 0, 255)); } // [DEBUG]
+ //GetForegroundDrawList()->AddRectFilled(scoring_rect.Min - ImVec2(1, 1), scoring_rect.Max + ImVec2(1, 1), IM_COL32(255, 100, 0, 80)); // [DEBUG] Post-bias
+ //if (!g.NavScoringNoClipRect.IsInverted()) { GetForegroundDrawList()->AddRectFilled(g.NavScoringNoClipRect.Min, g.NavScoringNoClipRect.Max, IM_COL32(100, 255, 0, 80)); } // [DEBUG]
}
g.NavScoringRect = scoring_rect;
//g.NavScoringNoClipRect.Add(scoring_rect);
diff --git a/imgui.h b/imgui.h
index 2b3d10160..544709d95 100644
--- a/imgui.h
+++ b/imgui.h
@@ -29,7 +29,7 @@
// Library Version
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
#define IMGUI_VERSION "1.92.5 WIP"
-#define IMGUI_VERSION_NUM 19246
+#define IMGUI_VERSION_NUM 19247
#define IMGUI_HAS_TABLE // Added BeginTable() - from IMGUI_VERSION_NUM >= 18000
#define IMGUI_HAS_TEXTURES // Added ImGuiBackendFlags_RendererHasTextures - from IMGUI_VERSION_NUM >= 19198
#define IMGUI_HAS_VIEWPORT // In 'docking' WIP branch.
diff --git a/imgui_internal.h b/imgui_internal.h
index 400aa31d2..e2d96e3e2 100644
--- a/imgui_internal.h
+++ b/imgui_internal.h
@@ -1744,7 +1744,7 @@ enum ImGuiNavMoveFlags_
ImGuiNavMoveFlags_WrapMask_ = ImGuiNavMoveFlags_LoopX | ImGuiNavMoveFlags_LoopY | ImGuiNavMoveFlags_WrapX | ImGuiNavMoveFlags_WrapY,
ImGuiNavMoveFlags_AllowCurrentNavId = 1 << 4, // Allow scoring and considering the current NavId as a move target candidate. This is used when the move source is offset (e.g. pressing PageDown actually needs to send a Up move request, if we are pressing PageDown from the bottom-most item we need to stay in place)
ImGuiNavMoveFlags_AlsoScoreVisibleSet = 1 << 5, // Store alternate result in NavMoveResultLocalVisible that only comprise elements that are already fully visible (used by PageUp/PageDown)
- ImGuiNavMoveFlags_ScrollToEdgeY = 1 << 6, // Force scrolling to min/max (used by Home/End) // FIXME-NAV: Aim to remove or reword, probably unnecessary
+ ImGuiNavMoveFlags_ScrollToEdgeY = 1 << 6, // Force scrolling to min/max (used by Home/End) // FIXME-NAV: Aim to remove or reword as ImGuiScrollFlags
ImGuiNavMoveFlags_Forwarded = 1 << 7,
ImGuiNavMoveFlags_DebugNoResult = 1 << 8, // Dummy scoring for debug purpose, don't apply result
ImGuiNavMoveFlags_FocusApi = 1 << 9, // Requests from focus API can land/focus/activate items even if they are marked with _NoTabStop (see NavProcessItemForTabbingRequest() for details)
diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp
index afb39e4ef..5182e2ff5 100644
--- a/imgui_widgets.cpp
+++ b/imgui_widgets.cpp
@@ -4768,8 +4768,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
state->TextLen = new_len;
memcpy(state->TextA.Data, buf, state->TextLen + 1);
state->Stb->select_start = state->ReloadSelectionStart;
- state->Stb->cursor = state->Stb->select_end = state->ReloadSelectionEnd;
- state->CursorClamp();
+ state->Stb->cursor = state->Stb->select_end = state->ReloadSelectionEnd; // will be clamped to bounds below
}
else if ((init_state && g.ActiveId != id) || init_changed_specs)
{
@@ -4809,9 +4808,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
// Recycle existing cursor/selection/undo stack but clamp position
// Note a single mouse click will override the cursor/position immediately by calling stb_textedit_click handler.
- if (recycle_state)
- state->CursorClamp();
- else
+ if (!recycle_state)
stb_textedit_initialize_state(state->Stb, !is_multiline);
if (!is_multiline)
@@ -4868,6 +4865,8 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
// Read-only mode always ever read from source buffer. Refresh TextLen when active.
if (is_readonly && state != NULL)
state->TextLen = (int)ImStrlen(buf);
+ if (state != NULL)
+ state->CursorClamp();
//if (is_readonly && state != NULL)
// state->TextA.clear(); // Uncomment to facilitate debugging, but we otherwise prefer to keep/amortize th allocation.
}