InputText: reworked so that io.ConfigInputTextEnterKeepActive reactivate in order for e.g. IsItemDeactivatedAfterEdit() to work. Amends. (#9001, #9115)

Rework. Fixes dangling InputTextReactivateId in case of field being hidden on activation.
This commit is contained in:
ocornut
2026-03-11 20:33:18 +01:00
parent 03a9946a14
commit 5aa7d61139
5 changed files with 10 additions and 16 deletions

View File

@@ -4281,7 +4281,7 @@ ImGuiContext::ImGuiContext(ImFontAtlas* shared_font_atlas)
MouseStationaryTimer = 0.0f;
InputTextPasswordFontBackupFlags = ImFontFlags_None;
InputTextReactivateID = 0;
InputTextReactivateId = 0;
TempInputId = 0;
memset(&DataTypeZeroValue, 0, sizeof(DataTypeZeroValue));
BeginMenuDepth = BeginComboDepth = 0;
@@ -5573,6 +5573,8 @@ void ImGui::NewFrame()
g.ActiveIdIsJustActivated = false;
if (g.TempInputId != 0 && g.ActiveId != g.TempInputId)
g.TempInputId = 0;
if (g.InputTextReactivateId != 0 && g.InputTextReactivateId != g.DeactivatedItemData.ID)
g.InputTextReactivateId = 0;
if (g.ActiveId == 0)
{
g.ActiveIdUsingNavDirMask = 0x00;

View File

@@ -2428,7 +2428,7 @@ struct ImGuiIO
bool ConfigMacOSXBehaviors; // = defined(__APPLE__) // Swap Cmd<>Ctrl keys + OS X style text editing cursor movement using Alt instead of Ctrl, Shortcuts using Cmd/Super instead of Ctrl, Line/Text Start and End using Cmd+Arrows instead of Home/End, Double click selects by word instead of selecting whole text, Multi-selection in lists uses Cmd/Super instead of Ctrl.
bool ConfigInputTrickleEventQueue; // = true // Enable input queue trickling: some types of events submitted during the same frame (e.g. button down + up) will be spread over multiple frames, improving interactions with low framerates.
bool ConfigInputTextCursorBlink; // = true // Enable blinking cursor (optional as some users consider it to be distracting).
bool ConfigInputTextEnterKeepActive; // = false // [BETA] Pressing Enter will keep item active and select contents (single-line only).
bool ConfigInputTextEnterKeepActive; // = false // [BETA] Pressing Enter will reactivate item and select all text (single-line only).
bool ConfigDragClickToInputText; // = false // [BETA] Enable turning DragXXX widgets into text input with a simple mouse click-release (without moving). Not desirable on devices without a keyboard.
bool ConfigWindowsResizeFromEdges; // = true // Enable resizing of windows from their edges and from the lower-left corner. This requires ImGuiBackendFlags_HasMouseCursors for better mouse cursor feedback. (This used to be a per-window ImGuiWindowFlags_ResizeFromAnySide flag)
bool ConfigWindowsMoveFromTitleBarOnly; // = false // Enable allowing to move windows only when clicking on their title bar. Does not apply to windows without a title bar.

View File

@@ -526,7 +526,7 @@ void ImGui::ShowDemoWindow(bool* p_open)
ImGui::Checkbox("io.ConfigInputTextCursorBlink", &io.ConfigInputTextCursorBlink);
ImGui::SameLine(); HelpMarker("Enable blinking cursor (optional as some users consider it to be distracting).");
ImGui::Checkbox("io.ConfigInputTextEnterKeepActive", &io.ConfigInputTextEnterKeepActive);
ImGui::SameLine(); HelpMarker("Pressing Enter will keep item active and select contents (single-line only).");
ImGui::SameLine(); HelpMarker("Pressing Enter will reactivate item and select all text (single-line only).");
ImGui::Checkbox("io.ConfigDragClickToInputText", &io.ConfigDragClickToInputText);
ImGui::SameLine(); HelpMarker("Enable turning DragXXX widgets into text input with a simple mouse click-release (without moving).");
ImGui::Checkbox("io.ConfigMacOSXBehaviors", &io.ConfigMacOSXBehaviors);

View File

@@ -2461,7 +2461,7 @@ struct ImGuiContext
ImGuiInputTextDeactivatedState InputTextDeactivatedState;
ImFontBaked InputTextPasswordFontBackupBaked;
ImFontFlags InputTextPasswordFontBackupFlags;
ImGuiID InputTextReactivateID; // ID of InputText to reactivate on next frame (for ConfigInputTextEnterKeepActive behavior)
ImGuiID InputTextReactivateId; // ID of InputText to reactivate on next frame (for io.ConfigInputTextEnterKeepActive behavior)
ImGuiID TempInputId; // Temporary text input when using Ctrl+Click on a slider, etc.
ImGuiDataTypeStorage DataTypeZeroValue; // 0 for all data types
int BeginMenuDepth;

View File

@@ -4761,12 +4761,7 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
wrap_width = ImMax(1.0f, GetContentRegionAvail().x + (draw_window->ScrollbarY ? 0.0f : -g.Style.ScrollbarSize));
const bool input_requested_by_nav = (g.ActiveId != id) && ((g.NavActivateId == id) && ((g.NavActivateFlags & ImGuiActivateFlags_PreferInput) || (g.NavInputSource == ImGuiInputSource_Keyboard)));
// Check if this InputText should be reactivated (for ConfigInputTextEnterKeepActive)
const bool input_requested_by_reactivate = (g.InputTextReactivateID == id);
if (input_requested_by_reactivate)
g.InputTextReactivateID = 0; // Clear the flag
const bool input_requested_by_reactivate = (g.InputTextReactivateId == id); // for io.ConfigInputTextEnterKeepActive
const bool user_clicked = hovered && io.MouseClicked[0];
const bool user_scroll_finish = is_multiline && state != NULL && g.ActiveId == 0 && g.ActiveIdPreviousFrame == GetWindowScrollbarID(draw_window, ImGuiAxis_Y);
const bool user_scroll_active = is_multiline && state != NULL && g.ActiveId == GetWindowScrollbarID(draw_window, ImGuiAxis_Y);
@@ -5114,16 +5109,13 @@ bool ImGui::InputTextEx(const char* label, const char* hint, char* buf, int buf_
bool is_new_line = is_multiline && !is_gamepad_validate && (is_shift_enter || (is_enter && !ctrl_enter_for_new_line) || (is_ctrl_enter && ctrl_enter_for_new_line));
if (!is_new_line)
{
validated = true;
validated = clear_active_id = true;
if (io.ConfigInputTextEnterKeepActive && !is_multiline)
{
// Deactivate for one frame to trigger IsItemDeactivatedAfterEdit(), then reactivate
// Queue reactivation, so that e.g. IsItemDeactivatedAfterEdit() will work. (#9001)
state->SelectAll(); // No need to scroll
clear_active_id = true;
g.InputTextReactivateID = id; // Mark for reactivation on next frame
g.InputTextReactivateId = id; // Mark for reactivation on next frame
}
else
clear_active_id = true;
}
else if (!is_readonly)
{