Skip to content

Instantly share code, notes, and snippets.

@amuTBKT
Last active January 2, 2026 04:08
Show Gist options
  • Select an option

  • Save amuTBKT/421bc81e616fcae041602df78c77db5f to your computer and use it in GitHub Desktop.

Select an option

Save amuTBKT/421bc81e616fcae041602df78c77db5f to your computer and use it in GitHub Desktop.
Tying out shortcuts + auto focus items for a ImGui widget.
// code for: https://x.com/amu_mhr/status/2006940064711053355?s=20
extern int ImFormatString(char* buf, size_t buf_size, const char* fmt, ...);
// dubious function to focus `InputText` widgets with nav cursor, this avoid having to press enter to edit them
// NOTE: `ImGui::Shortcut` handles focusing but not sure how to replicate that when using arrow keys (i.e no shortcut just navigation)
// This has a downside that items to the left/right of the input box cannot be reached using arrow keys (only up/down nav will work!)
auto AutoFocusNextItem = [](const char* item_label)
{
const ImGuiID item_id = ImGui::GetCurrentWindow()->GetID(item_label);
ImGui::PushID(item_id);
const ImGuiID StorageId = ImGui::GetCurrentWindow()->GetID("AutoActivate");
const bool had_focus = ImGui::GetStateStorage()->GetBool(StorageId);
const bool has_focus = (ImGui::GetFocusID() == item_id);
if (has_focus && !had_focus)
{
ImGui::SetKeyboardFocusHere();
}
ImGui::GetStateStorage()->SetBool(StorageId, has_focus);
ImGui::PopID();
};
if (ImGui::Begin("Test"))
{
// keep track of childb focus state in order to register shortcuts
static bool childb_has_focus = false;
static int childb_last_focused_item = -1;
if (ImGui::BeginChild("ChildA", ImVec2(0, 0), ImGuiChildFlags_FrameStyle | ImGuiChildFlags_NavFlattened | ImGuiChildFlags_AutoResizeY))
{
static char buff0[64], buff1[64];
if (childb_has_focus) //shortcut mapping
{
ImGui::SetNextItemShortcut(ImGuiKey_Tab, ImGuiInputFlags_Repeat);
}
AutoFocusNextItem("Text0");
ImGui::InputText("Text0", buff0, sizeof(buff0));
if (childb_has_focus && childb_last_focused_item == 0) //shortcut mapping
{
ImGui::SetNextItemShortcut(ImGuiKey_UpArrow, ImGuiInputFlags_Repeat);
}
AutoFocusNextItem("Text1");
ImGui::InputText("Text1", buff1, sizeof(buff1));
}
ImGui::EndChild();
if (ImGui::BeginChild("ChildB", ImVec2(0,0), ImGuiChildFlags_FrameStyle))
{
childb_has_focus = ImGui::IsWindowFocused();
// auto activate the window once it has has nav cursor (don't have to press enter to focus)
// this however draws the child window nav cursor for one frame, appears as a flicker :(
const bool had_nav_focus = childb_has_focus;
const bool has_nav_focus = (ImGui::GetCurrentContext()->NavId == ImGui::GetCurrentWindow()->ChildId);
const bool trigger_auto_activate = has_nav_focus && !had_nav_focus;
if (trigger_auto_activate && childb_last_focused_item == -1)
{
// make sure to select the first item as we don't have flattened nav which automatically handles this.
childb_last_focused_item = 0;
}
for (int i = 0; i < 64; ++i)
{
char labelBuff[32];
ImFormatString(labelBuff, sizeof(labelBuff), "Item %i", i);
if (trigger_auto_activate && (childb_last_focused_item == i))
{
ImGui::SetKeyboardFocusHere();
}
if (ImGui::Selectable(labelBuff, childb_last_focused_item == i)) { /* do something */ }
if (ImGui::IsItemFocused())
{
childb_last_focused_item = i;
}
}
}
ImGui::EndChild();
}
ImGui::End();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment