Skip to content

Commit

Permalink
IO: Fixed backward-compatibility accesses to io.KeysDown[]. (ocornut#…
Browse files Browse the repository at this point in the history
…4921, ocornut#4858)

+ Snuck in unrelated comments and removed the "fill once" comment (ocornut#5043)
  • Loading branch information
ocornut authored and sergeyn committed Mar 19, 2022
1 parent 047850b commit 6d31a2d
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 12 deletions.
4 changes: 4 additions & 0 deletions docs/CHANGELOG.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ Breaking changes:

Other Changes:

- IO: Fixed backward-compatibility regression introduced in 1.87: (#4921, #4858)
- Direct accesses to io.KeysDown[] with legacy indices didn't work (with new backends).
- Direct accesses to io.KeysDown[GetKeyIndex(XXX)] would access invalid data (with old/new backends).
- Calling IsKeyDown() didn't have those problems, and is recommended as io.KeysDown[] is obsolete.
- Clipper: Fixed a regression in 1.86 when not calling clipper.End() and late destructing the
clipper instance. High-level languages (Lua,Rust etc.) would typically be affected. (#4822)
- IsItemHovered(): added ImGuiHoveredFlags_NoNavOverride to disable the behavior where the
Expand Down
23 changes: 17 additions & 6 deletions imgui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1321,8 +1321,10 @@ void ImGuiIO::SetKeyEventNativeData(ImGuiKey key, int native_keycode, int native
// Build native->imgui map so old user code can still call key functions with native 0..511 values.
#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
const int legacy_key = (native_legacy_index != -1) ? native_legacy_index : native_keycode;
if (ImGui::IsLegacyKey(legacy_key))
KeyMap[legacy_key] = key;
if (!ImGui::IsLegacyKey(legacy_key))
return;
KeyMap[legacy_key] = key;
KeyMap[key] = legacy_key;
#else
IM_UNUSED(key);
IM_UNUSED(native_legacy_index);
Expand Down Expand Up @@ -3944,9 +3946,9 @@ static void ImGui::UpdateKeyboardInputs()
#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
if (io.BackendUsingLegacyKeyArrays == 0)
{
// Backend used new io.AddKeyEvent() API: Good! Verify that old arrays are never written too.
for (int n = 0; n < IM_ARRAYSIZE(io.KeysDown); n++)
IM_ASSERT(io.KeysDown[n] == false && "Backend needs to either only use io.AddKeyEvent(), either only fill legacy io.KeysDown[] + io.KeyMap[]. Not both!");
// Backend used new io.AddKeyEvent() API: Good! Verify that old arrays are never written to externally.
for (int n = 0; n < ImGuiKey_LegacyNativeKey_END; n++)
IM_ASSERT((io.KeysDown[n] == false || IsKeyDown(n)) && "Backend needs to either only use io.AddKeyEvent(), either only fill legacy io.KeysDown[] + io.KeyMap[]. Not both!");
}
else
{
Expand All @@ -3969,6 +3971,8 @@ static void ImGui::UpdateKeyboardInputs()
const ImGuiKey key = (ImGuiKey)(io.KeyMap[n] != -1 ? io.KeyMap[n] : n);
IM_ASSERT(io.KeyMap[n] == -1 || IsNamedKey(key));
io.KeysData[key].Down = io.KeysDown[n];
if (key != n)
io.KeysDown[key] = io.KeysDown[n]; // Allow legacy code using io.KeysDown[GetKeyIndex()] with old backends
io.BackendUsingLegacyKeyArrays = 1;
}
if (io.BackendUsingLegacyKeyArrays == 1)
Expand Down Expand Up @@ -7875,6 +7879,13 @@ void ImGui::UpdateInputEvents(bool trickle_fast_inputs)
if (key == ImGuiKey_ModSuper) { io.KeySuper = keydata->Down; }
io.KeyMods = GetMergedKeyModFlags();
}

// Allow legacy code using io.KeysDown[GetKeyIndex()] with new backends
#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
io.KeysDown[key] = keydata->Down;
if (io.KeyMap[key] != -1)
io.KeysDown[io.KeyMap[key]] = keydata->Down;
#endif
}
}
else if (e->Type == ImGuiInputEventType_Text)
Expand Down Expand Up @@ -7967,7 +7978,7 @@ static void ImGui::ErrorCheckNewFrameSanityChecks()
IM_ASSERT(g.Style.WindowMenuButtonPosition == ImGuiDir_None || g.Style.WindowMenuButtonPosition == ImGuiDir_Left || g.Style.WindowMenuButtonPosition == ImGuiDir_Right);
#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
for (int n = ImGuiKey_NamedKey_BEGIN; n < ImGuiKey_COUNT; n++)
IM_ASSERT(g.IO.KeyMap[n] >= -1 && g.IO.KeyMap[n] < IM_ARRAYSIZE(g.IO.KeysDown) && "io.KeyMap[] contains an out of bound value (need to be 0..511, or -1 for unmapped key)");
IM_ASSERT(g.IO.KeyMap[n] >= -1 && g.IO.KeyMap[n] < ImGuiKey_LegacyNativeKey_END && "io.KeyMap[] contains an out of bound value (need to be 0..511, or -1 for unmapped key)");

// Check: required key mapping (we intentionally do NOT check all keys to not pressure user into setting up everything, but Space is required and was only added in 1.60 WIP)
if ((g.IO.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard) && g.IO.BackendUsingLegacyKeyArrays == 1)
Expand Down
12 changes: 6 additions & 6 deletions imgui.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ Index of this file:
// Version
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens)
#define IMGUI_VERSION "1.88 WIP"
#define IMGUI_VERSION_NUM 18707
#define IMGUI_VERSION_NUM 18708
#define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx))
#define IMGUI_HAS_TABLE

Expand Down Expand Up @@ -1902,13 +1902,13 @@ struct ImGuiKeyData
struct ImGuiIO
{
//------------------------------------------------------------------
// Configuration (fill once) // Default value
// Configuration // Default value
//------------------------------------------------------------------

ImGuiConfigFlags ConfigFlags; // = 0 // See ImGuiConfigFlags_ enum. Set by user/application. Gamepad/keyboard navigation options, etc.
ImGuiBackendFlags BackendFlags; // = 0 // See ImGuiBackendFlags_ enum. Set by backend (imgui_impl_xxx files or custom backend) to communicate features supported by the backend.
ImVec2 DisplaySize; // <unset> // Main display size, in pixels (generally == GetMainViewport()->Size)
float DeltaTime; // = 1.0f/60.0f // Time elapsed since last frame, in seconds.
ImVec2 DisplaySize; // <unset> // Main display size, in pixels (generally == GetMainViewport()->Size). May change every frame.
float DeltaTime; // = 1.0f/60.0f // Time elapsed since last frame, in seconds. May change every frame.
float IniSavingRate; // = 5.0f // Minimum time between saving positions/sizes to .ini file, in seconds.
const char* IniFilename; // = "imgui.ini" // Path to .ini file (important: default "imgui.ini" is relative to current working dir!). Set NULL to disable automatic .ini loading/saving or if you want to manually call LoadIniSettingsXXX() / SaveIniSettingsXXX() functions.
const char* LogFilename; // = "imgui_log.txt"// Path to .log file (default parameter to ImGui::LogToFile when no file is specified).
Expand Down Expand Up @@ -2006,7 +2006,7 @@ struct ImGuiIO
// This is still temporarily supported as a legacy feature. However the new preferred scheme is for backend to call io.AddKeyEvent().
#ifndef IMGUI_DISABLE_OBSOLETE_KEYIO
int KeyMap[ImGuiKey_COUNT]; // [LEGACY] Input: map of indices into the KeysDown[512] entries array which represent your "native" keyboard state. The first 512 are now unused and should be kept zero. Legacy backend will write into KeyMap[] using ImGuiKey_ indices which are always >512.
bool KeysDown[512]; // [LEGACY] Input: Keyboard keys that are pressed (ideally left in the "native" order your engine has access to keyboard keys, so you can use your own defines/enums for keys).
bool KeysDown[ImGuiKey_COUNT]; // [LEGACY] Input: Keyboard keys that are pressed (ideally left in the "native" order your engine has access to keyboard keys, so you can use your own defines/enums for keys). This used to be [512] sized. It is now ImGuiKey_COUNT to allow legacy io.KeysDown[GetKeyIndex(...)] to work without an overflow.
#endif

//------------------------------------------------------------------
Expand Down Expand Up @@ -2039,7 +2039,7 @@ struct ImGuiIO
ImU16 MouseClickedLastCount[5]; // Count successive number of clicks. Stays valid after mouse release. Reset after another click is done.
bool MouseReleased[5]; // Mouse button went from Down to !Down
bool MouseDownOwned[5]; // Track if button was clicked inside a dear imgui window or over void blocked by a popup. We don't request mouse capture from the application if click started outside ImGui bounds.
bool MouseDownOwnedUnlessPopupClose[5]; //Track if button was clicked inside a dear imgui window.
bool MouseDownOwnedUnlessPopupClose[5]; // Track if button was clicked inside a dear imgui window.
float MouseDownDuration[5]; // Duration the mouse button has been down (0.0f == just clicked)
float MouseDownDurationPrev[5]; // Previous time the mouse button has been down
float MouseDragMaxDistanceSqr[5]; // Squared maximum distance of how much mouse has traveled from the clicking point (used for moving thresholds)
Expand Down
1 change: 1 addition & 0 deletions imgui_demo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5710,6 +5710,7 @@ static void ShowDemoWindowMisc()
#else
struct funcs { static bool IsLegacyNativeDupe(ImGuiKey key) { return key < 512 && ImGui::GetIO().KeyMap[key] != -1; } }; // Hide Native<>ImGuiKey duplicates when both exists in the array
const ImGuiKey key_first = 0;
//ImGui::Text("Legacy raw:"); for (ImGuiKey key = key_first; key < ImGuiKey_COUNT; key++) { if (io.KeysDown[key]) { ImGui::SameLine(); ImGui::Text("\"%s\" %d", ImGui::GetKeyName(key), key); } }
#endif
ImGui::Text("Keys down:"); for (ImGuiKey key = key_first; key < ImGuiKey_COUNT; key++) { if (funcs::IsLegacyNativeDupe(key)) continue; if (ImGui::IsKeyDown(key)) { ImGui::SameLine(); ImGui::Text("\"%s\" %d (%.02f secs)", ImGui::GetKeyName(key), key, ImGui::GetKeyData(key)->DownDuration); } }
ImGui::Text("Keys pressed:"); for (ImGuiKey key = key_first; key < ImGuiKey_COUNT; key++) { if (funcs::IsLegacyNativeDupe(key)) continue; if (ImGui::IsKeyPressed(key)) { ImGui::SameLine(); ImGui::Text("\"%s\" %d", ImGui::GetKeyName(key), key); } }
Expand Down

0 comments on commit 6d31a2d

Please sign in to comment.