Skip to content

Commit

Permalink
Fixed SetKeyboardFocusHere() focusing wrong widget when target widget…
Browse files Browse the repository at this point in the history
… disappears. (ocornut#432)
  • Loading branch information
rokups committed Jul 15, 2020
1 parent eefae08 commit a9ebcec
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 4 deletions.
1 change: 1 addition & 0 deletions docs/CHANGELOG.txt
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ Other Changes:
- ImDrawList: Fixed minor bug introduced in 1.75 where AddCircle() with 12 segments would generate
an extra vertex. (This bug was mistakenly marked as fixed in earlier 1.77 release). [@ShironekoBen]
- Backends: OpenGL3: Added support for glad2 loader. (#3330) [@moritz-h]
- Misc: Fixed SetKeyboardFocusHere() focusing wrong widget when target widget disappears. (#432) [@rokups]


-----------------------------------------------------------------------
Expand Down
28 changes: 24 additions & 4 deletions imgui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3118,7 +3118,7 @@ bool ImGui::FocusableItemRegister(ImGuiWindow* window, ImGuiID id)
// Handle focus requests
if (g.FocusRequestCurrWindow == window)
{
if (window->DC.FocusCounterRegular == g.FocusRequestCurrCounterRegular)
if (window->DC.FocusCounterRegular == g.FocusRequestCurrCounterRegular && (g.FocusRequestCurrItemId == 0 || g.FocusRequestCurrItemId == id))
return true;
if (is_tab_stop && window->DC.FocusCounterTabStop == g.FocusRequestCurrCounterTabStop)
{
Expand Down Expand Up @@ -3566,6 +3566,7 @@ void ImGui::UpdateTabFocus()
// Turn queued focus request into current one
g.FocusRequestCurrWindow = NULL;
g.FocusRequestCurrCounterRegular = g.FocusRequestCurrCounterTabStop = INT_MAX;
g.FocusRequestCurrItemId = 0;
if (g.FocusRequestNextWindow != NULL)
{
ImGuiWindow* window = g.FocusRequestNextWindow;
Expand All @@ -3574,6 +3575,8 @@ void ImGui::UpdateTabFocus()
g.FocusRequestCurrCounterRegular = ImModPositive(g.FocusRequestNextCounterRegular, window->DC.FocusCounterRegular + 1);
if (g.FocusRequestNextCounterTabStop != INT_MAX && window->DC.FocusCounterTabStop != -1)
g.FocusRequestCurrCounterTabStop = ImModPositive(g.FocusRequestNextCounterTabStop, window->DC.FocusCounterTabStop + 1);
if (g.FocusRequestNextItemId != 0)
g.FocusRequestCurrItemId = g.FocusRequestNextItemId;
g.FocusRequestNextWindow = NULL;
g.FocusRequestNextCounterRegular = g.FocusRequestNextCounterTabStop = INT_MAX;
}
Expand Down Expand Up @@ -6594,9 +6597,26 @@ void ImGui::SetKeyboardFocusHere(int offset)
IM_ASSERT(offset >= -1); // -1 is allowed but not below
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
g.FocusRequestNextWindow = window;
g.FocusRequestNextCounterRegular = window->DC.FocusCounterRegular + 1 + offset;
g.FocusRequestNextCounterTabStop = INT_MAX;
int focus_counter = window->DC.FocusCounterRegular + 1 + offset;

// We could handle non-negative offset immediately, so focus change is effective immediately, however that would
// change current behavior, therefore we probably should not.
//if (offset < 0)
{
// Handle negative offset on next frame, but only focus previous item if it does not disappear
g.FocusRequestNextItemId = window->DC.LastItemId;
g.FocusRequestNextWindow = window;
g.FocusRequestNextCounterRegular = focus_counter;
g.FocusRequestNextCounterTabStop = INT_MAX;
}
//else
//{
// // Handle non-negative offset on current frame, it is ok if next element disappears on next frame
// g.FocusRequestCurrWindow = window;
// g.FocusRequestCurrItemId = 0;
// g.FocusRequestCurrCounterRegular = focus_counter;
// g.FocusRequestCurrCounterTabStop = INT_MAX;
//}
}

void ImGui::SetItemDefaultFocus()
Expand Down
3 changes: 3 additions & 0 deletions imgui_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -1228,8 +1228,10 @@ struct ImGuiContext
ImGuiWindow* FocusRequestNextWindow; //
int FocusRequestCurrCounterRegular; // Any item being requested for focus, stored as an index (we on layout to be stable between the frame pressing TAB and the next frame, semi-ouch)
int FocusRequestCurrCounterTabStop; // Tab item being requested for focus, stored as an index
ImGuiID FocusRequestCurrItemId; //
int FocusRequestNextCounterRegular; // Stored for next frame
int FocusRequestNextCounterTabStop; // "
ImGuiID FocusRequestNextItemId; //
bool FocusTabPressed; //

// Render
Expand Down Expand Up @@ -1400,6 +1402,7 @@ struct ImGuiContext
FocusRequestCurrWindow = FocusRequestNextWindow = NULL;
FocusRequestCurrCounterRegular = FocusRequestCurrCounterTabStop = INT_MAX;
FocusRequestNextCounterRegular = FocusRequestNextCounterTabStop = INT_MAX;
FocusRequestCurrItemId = FocusRequestNextItemId = 0;
FocusTabPressed = false;

DimBgRatio = 0.0f;
Expand Down

0 comments on commit a9ebcec

Please sign in to comment.