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. }