Skip to content

Commit

Permalink
Merge branch 'master' into docking
Browse files Browse the repository at this point in the history
# Conflicts:
#	backends/imgui_impl_metal.mm
#	imgui.cpp
#	imgui.h
  • Loading branch information
ocornut committed Jun 10, 2022
2 parents 4789c7e + 076d8fc commit e900ca3
Show file tree
Hide file tree
Showing 9 changed files with 275 additions and 117 deletions.
8 changes: 6 additions & 2 deletions backends/imgui_impl_metal.mm
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
// CHANGELOG
// (minor and older changes stripped away, please see git history for details)
// 2022-XX-XX: Metal: Added support for multiple windows via the ImGuiPlatformIO interface.
// 2022-06-01: Metal: Fixed null dereference on exit inside command buffer completion handler.
// 2022-04-27: Misc: Store backend data in a per-context struct, allowing to use this backend with multiple contexts.
// 2022-01-03: Metal: Ignore ImDrawCmd where ElemCount == 0 (very rare but can technically be manufactured by user code).
// 2021-12-30: Metal: Added Metal C++ support. Enable with '#define IMGUI_IMPL_METAL_CPP' in your imconfig.h file.
Expand Down Expand Up @@ -306,8 +307,11 @@ void ImGui_ImplMetal_RenderDrawData(ImDrawData* drawData, id<MTLCommandBuffer> c
{
dispatch_async(dispatch_get_main_queue(), ^{
ImGui_ImplMetal_Data* bd = ImGui_ImplMetal_GetBackendData();
[bd->SharedMetalContext.bufferCache addObject:vertexBuffer];
[bd->SharedMetalContext.bufferCache addObject:indexBuffer];
if (bd != NULL)
{
[bd->SharedMetalContext.bufferCache addObject:vertexBuffer];
[bd->SharedMetalContext.bufferCache addObject:indexBuffer];
}
});
}];
}
Expand Down
14 changes: 14 additions & 0 deletions docs/CHANGELOG.txt
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,9 @@ Other Changes:
or interacting with a game/3D view).
- IO: Fixed input queue trickling of mouse wheel events: multiple wheel events are merged, while
a mouse pos followed by a mouse wheel are now trickled. (#4921, #4821)
- IO: Added io.SetAppAcceptingEvents() to set a master flag for accepting key/mouse/characters
events (default to true). Useful if you have native dialog boxes that are interrupting your
application loop/refresh, and you want to disable events being queued while your app is frozen.
- Windows: Fixed first-time windows appearing in negative coordinates from being initialized
with a wrong size. This would most often be noticeable in multi-viewport mode (docking branch)
when spawning a window in a monitor with negative coordinates. (#5215, #3414) [@DimaKoltun]
Expand All @@ -146,20 +149,29 @@ Other Changes:
- InputScalar: Automatically allow hexadecimal input when format is %X (without extra flag).
- InputScalar: Automatically allow scientific input when format is float/double (without extra flag).
- Nav: Fixed nav movement in a scope with only one disabled item from focusing the disabled item. (#5189)
- Nav: Fixed issues with nav request being transferred to another window when calling SetKeyboardFocusHere()
and simultaneous changing window focus. (#4449)
- IsItemHovered(): added ImGuiHoveredFlags_NoNavOverride to disable the behavior where the
return value is overriden by focus when gamepad/keyboard navigation is active.
- InputText: Fixed pressing Tab emitting two tabs characters because of dual Keys/Chars events being
trickled with the new input queue (happened on some backends only). (#2467, #1336)
- InputText: Fixed a one-frame display glitch where pressing Escape to revert after a deletion
would lead to small garbage being displayed for one frame. Curiously a rather old bug! (#3008)
- InputText: Fixed an undo-state corruption issue when editing main buffer before reactivating item. (#4947)
- InputText: Fixed an undo-state corruption issue when editing in-flight buffer in user callback.
(#4947, #4949] [@JoshuaWebb]
- Tables: Fixed incorrect border height used for logic when resizing one of several synchronized
instance of a same table ID, when instances have a different height. (#3955).
- Tables: Fixed incorrect auto-fit of parent windows when using non-resizable weighted columns. (#5276)
- Tables: Fixed drawcall merging of last column. Depending on some unrelated settings (e.g. BorderH)
merging drawcall of the last column didn't always work (regression since 1.87). (#4843, #4844) [@rokups]
- Inputs: Fixed IsMouseClicked() repeat mode rate being half of keyboard repeat rate.
- ColorEdit: Fixed text baseline alignment after a SameLine() after a ColorEdit() with visible label.
- Menus: Adjusted BeginMenu() closing logic so hovering void or non-MenuItem() in parent window
always lead to menu closure. Fixes using items that are not MenuItem() or BeginItem() at the root
level of a popup with a child menu opened.
- Menus: Menus emitted from the main/scrolling layer are not part of the same menuset as menus emitted
from the menu-bar, avoiding accidental hovering from one to the other. (#3496, #4797) [@rokups]
- Stack Tool: Added option to copy item path to clipboard. (#4631)
- Settings: Fixed out-of-bounds read when .ini file on disk is empty. (#5351) [@quantum5]
- DrawList: Fixed PathArcTo() emitting terminating vertices too close to arc vertices. (#4993) [@thedmd]
Expand All @@ -170,6 +182,7 @@ Other Changes:
you have a UTF-8 text encoding issue or a font loading issue. [@LaMarche05, @ocornut]
- Demo: Add better demo of how to use SetNextFrameWantCaptureMouse()/SetNextFrameWantCaptureKeyboard().
- Metrics: Added a "UTF-8 Encoding Viewer" section using the aforementioned DebugTextEncoding() function.
- Metrics: Added "InputText" section to visualize internal state (#4947, #4949).
- Misc: Fixed calling GetID("label") _before_ a widget emitting this item inside a group (such as InputInt())
from causing an assertion when closing the group. (#5181).
- Misc: Fixed IsAnyItemHovered() returning false when using navigation.
Expand All @@ -191,6 +204,7 @@ Other Changes:
- Backends: OSX: Monitor NSKeyUp events to catch missing keyUp for key when user press Cmd + key (#5128) [@thedmd]
- Backends: OSX, Metal: Store backend data in a per-context struct, allowing to use these backends with
multiple contexts. (#5203, #5221, #4141) [@noisewuwei]
- Backends: Metal: Fixed null dereference on exit inside command buffer completion handler. (#5363, #5365) [@warrenm]
- Backends: OpenGL3: Partially revert 1.86 change of using glBufferSubData(): now only done on Windows and
Intel GPU, based on querying glGetString(GL_VENDOR). Essentially we got report of accumulating leaks on Intel
with multi-viewports when using simple glBufferData() without orphaning, and report of corruptions on other
Expand Down
91 changes: 73 additions & 18 deletions imgui.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1205,6 +1205,7 @@ ImGuiIO::ImGuiIO()
for (int i = 0; i < IM_ARRAYSIZE(MouseDownDuration); i++) MouseDownDuration[i] = MouseDownDurationPrev[i] = -1.0f;
for (int i = 0; i < IM_ARRAYSIZE(KeysData); i++) { KeysData[i].DownDuration = KeysData[i].DownDurationPrev = -1.0f; }
for (int i = 0; i < IM_ARRAYSIZE(NavInputsDownDuration); i++) NavInputsDownDuration[i] = -1.0f;
AppAcceptingEvents = true;
BackendUsingLegacyKeyArrays = (ImS8)-1;
BackendUsingLegacyNavInputArray = true; // assume using legacy array until proven wrong
}
Expand All @@ -1217,7 +1218,7 @@ void ImGuiIO::AddInputCharacter(unsigned int c)
{
ImGuiContext& g = *GImGui;
IM_ASSERT(&g.IO == this && "Can only add events to current context.");
if (c == 0)
if (c == 0 || !AppAcceptingEvents)
return;

ImGuiInputEvent e;
Expand All @@ -1231,7 +1232,7 @@ void ImGuiIO::AddInputCharacter(unsigned int c)
// we should save the high surrogate.
void ImGuiIO::AddInputCharacterUTF16(ImWchar16 c)
{
if (c == 0 && InputQueueSurrogate == 0)
if ((c == 0 && InputQueueSurrogate == 0) || !AppAcceptingEvents)
return;

if ((c & 0xFC00) == 0xD800) // High surrogate, must save
Expand Down Expand Up @@ -1265,6 +1266,8 @@ void ImGuiIO::AddInputCharacterUTF16(ImWchar16 c)

void ImGuiIO::AddInputCharactersUTF8(const char* utf8_chars)
{
if (!AppAcceptingEvents)
return;
while (*utf8_chars != 0)
{
unsigned int c = 0;
Expand Down Expand Up @@ -1303,7 +1306,7 @@ void ImGuiIO::ClearInputKeys()
void ImGuiIO::AddKeyAnalogEvent(ImGuiKey key, bool down, float analog_value)
{
//if (e->Down) { IMGUI_DEBUG_LOG("AddKeyEvent() Key='%s' %d, NativeKeycode = %d, NativeScancode = %d\n", ImGui::GetKeyName(e->Key), e->Down, e->NativeKeycode, e->NativeScancode); }
if (key == ImGuiKey_None)
if (key == ImGuiKey_None || !AppAcceptingEvents)
return;
ImGuiContext& g = *GImGui;
IM_ASSERT(&g.IO == this && "Can only add events to current context.");
Expand Down Expand Up @@ -1344,6 +1347,8 @@ void ImGuiIO::AddKeyAnalogEvent(ImGuiKey key, bool down, float analog_value)

void ImGuiIO::AddKeyEvent(ImGuiKey key, bool down)
{
if (!AppAcceptingEvents)
return;
AddKeyAnalogEvent(key, down, down ? 1.0f : 0.0f);
}

Expand Down Expand Up @@ -1372,11 +1377,19 @@ void ImGuiIO::SetKeyEventNativeData(ImGuiKey key, int native_keycode, int native
#endif
}

// Set master flag for accepting key/mouse/text events (default to true). Useful if you have native dialog boxes that are interrupting your application loop/refresh, and you want to disable events being queued while your app is frozen.
void ImGuiIO::SetAppAcceptingEvents(bool accepting_events)
{
AppAcceptingEvents = accepting_events;
}

// Queue a mouse move event
void ImGuiIO::AddMousePosEvent(float x, float y)
{
ImGuiContext& g = *GImGui;
IM_ASSERT(&g.IO == this && "Can only add events to current context.");
if (!AppAcceptingEvents)
return;

ImGuiInputEvent e;
e.Type = ImGuiInputEventType_MousePos;
Expand All @@ -1391,6 +1404,8 @@ void ImGuiIO::AddMouseButtonEvent(int mouse_button, bool down)
ImGuiContext& g = *GImGui;
IM_ASSERT(&g.IO == this && "Can only add events to current context.");
IM_ASSERT(mouse_button >= 0 && mouse_button < ImGuiMouseButton_COUNT);
if (!AppAcceptingEvents)
return;

ImGuiInputEvent e;
e.Type = ImGuiInputEventType_MouseButton;
Expand All @@ -1405,7 +1420,7 @@ void ImGuiIO::AddMouseWheelEvent(float wheel_x, float wheel_y)
{
ImGuiContext& g = *GImGui;
IM_ASSERT(&g.IO == this && "Can only add events to current context.");
if (wheel_x == 0.0f && wheel_y == 0.0f)
if ((wheel_x == 0.0f && wheel_y == 0.0f) || !AppAcceptingEvents)
return;

ImGuiInputEvent e;
Expand Down Expand Up @@ -1738,6 +1753,25 @@ int ImFormatStringV(char* buf, size_t buf_size, const char* fmt, va_list args)
}
#endif // #ifdef IMGUI_DISABLE_DEFAULT_FORMAT_FUNCTIONS

void ImFormatStringToTempBuffer(const char** out_buf, const char** out_buf_end, const char* fmt, ...)
{
ImGuiContext& g = *GImGui;
va_list args;
va_start(args, fmt);
int buf_len = ImFormatStringV(g.TempBuffer.Data, g.TempBuffer.Size, fmt, args);
*out_buf = g.TempBuffer.Data;
if (out_buf_end) { *out_buf_end = g.TempBuffer.Data + buf_len; }
va_end(args);
}

void ImFormatStringToTempBufferV(const char** out_buf, const char** out_buf_end, const char* fmt, va_list args)
{
ImGuiContext& g = *GImGui;
int buf_len = ImFormatStringV(g.TempBuffer.Data, g.TempBuffer.Size, fmt, args);
*out_buf = g.TempBuffer.Data;
if (out_buf_end) { *out_buf_end = g.TempBuffer.Data + buf_len; }
}

// CRC32 needs a 1KB lookup table (not cache friendly)
// Although the code to generate the table is simple and shorter than the table itself, using a const table allows us to easily:
// - avoid an unnecessary branch/memory tap, - keep the ImHashXXX functions usable by static constructors, - make it thread-safe.
Expand Down Expand Up @@ -4640,6 +4674,7 @@ void ImGui::Initialize()
viewport->PlatformWindowCreated = true;
viewport->Flags = ImGuiViewportFlags_OwnedByApp;
g.Viewports.push_back(viewport);
g.TempBuffer.resize(1024 * 3 + 1, 0);
g.PlatformIO.Viewports.push_back(g.Viewports[0]);

#ifdef IMGUI_HAS_DOCK
Expand Down Expand Up @@ -5424,15 +5459,16 @@ bool ImGui::BeginChildEx(const char* name, ImGuiID id, const ImVec2& size_arg, b
SetNextWindowSize(size);

// Build up name. If you need to append to a same child from multiple location in the ID stack, use BeginChild(ImGuiID id) with a stable value.
const char* temp_window_name;
if (name)
ImFormatString(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), "%s/%s_%08X", parent_window->Name, name, id);
ImFormatStringToTempBuffer(&temp_window_name, NULL, "%s/%s_%08X", parent_window->Name, name, id);
else
ImFormatString(g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer), "%s/%08X", parent_window->Name, id);
ImFormatStringToTempBuffer(&temp_window_name, NULL, "%s/%08X", parent_window->Name, id);

const float backup_border_size = g.Style.ChildBorderSize;
if (!border)
g.Style.ChildBorderSize = 0.0f;
bool ret = Begin(g.TempBuffer, NULL, flags);
bool ret = Begin(temp_window_name, NULL, flags);
g.Style.ChildBorderSize = backup_border_size;

ImGuiWindow* child_window = g.CurrentWindow;
Expand Down Expand Up @@ -6432,6 +6468,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
{
ImGuiPopupData& popup_ref = g.OpenPopupStack[g.BeginPopupStack.Size];
popup_ref.Window = window;
popup_ref.ParentNavLayer = parent_window_in_stack->DC.NavLayerCurrent;
g.BeginPopupStack.push_back(popup_ref);
window->PopupId = popup_ref.PopupId;
}
Expand Down Expand Up @@ -7942,7 +7979,10 @@ void ImGui::SetKeyboardFocusHere(int offset)
ImGuiContext& g = *GImGui;
ImGuiWindow* window = g.CurrentWindow;
IM_ASSERT(offset >= -1); // -1 is allowed but not below

g.NavWindow = window;
g.NavInitRequest = g.NavMoveSubmitted = g.NavMoveScoringItems = false;

ImGuiScrollFlags scroll_flags = window->Appearing ? ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_AlwaysCenterY : ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_KeepVisibleEdgeY;
NavMoveRequestSubmit(ImGuiDir_None, offset < 0 ? ImGuiDir_Up : ImGuiDir_Down, ImGuiNavMoveFlags_Tabbing | ImGuiNavMoveFlags_FocusApi, scroll_flags); // FIXME-NAV: Once we refactor tabbing, add LegacyApi flag to not activate non-inputable.
if (offset == -1)
Expand Down Expand Up @@ -10190,8 +10230,11 @@ void ImGui::SetFocusID(ImGuiID id, ImGuiWindow* window)
// Note that window may be != g.CurrentWindow (e.g. SetFocusID call in InputTextEx for multi-line text)
const ImGuiNavLayer nav_layer = window->DC.NavLayerCurrent;
if (g.NavWindow != window)
g.NavInitRequest = false;
g.NavWindow = window;
{
g.NavWindow = window;
g.NavInitRequest = g.NavMoveSubmitted = g.NavMoveScoringItems = false;
NavUpdateAnyRequestFlag();
}
g.NavId = id;
g.NavLayer = nav_layer;
g.NavFocusScopeId = window->DC.NavFocusScopeIdCurrent;
Expand Down Expand Up @@ -10439,7 +10482,12 @@ static void ImGui::NavProcessItem()
// Update window-relative bounding box of navigated item
if (g.NavId == id)
{
g.NavWindow = window; // Always refresh g.NavWindow, because some operations such as FocusItem() don't have a window.
if (g.NavWindow != window)
{
g.NavWindow = window; // Always refresh g.NavWindow, because some operations such as FocusItem() don't have a window.
g.NavInitRequest = g.NavMoveSubmitted = g.NavMoveScoringItems = false;
NavUpdateAnyRequestFlag();
}
g.NavLayer = window->DC.NavLayerCurrent;
g.NavFocusScopeId = window->DC.NavFocusScopeIdCurrent;
g.NavIdIsAlive = true;
Expand Down Expand Up @@ -10517,10 +10565,11 @@ void ImGui::NavMoveRequestSubmit(ImGuiDir move_dir, ImGuiDir clip_dir, ImGuiNavM
g.NavMoveScrollFlags = scroll_flags;
g.NavMoveForwardToNextFrame = false;
g.NavMoveKeyMods = g.IO.KeyMods;
g.NavTabbingCounter = 0;
g.NavMoveResultLocal.Clear();
g.NavMoveResultLocalVisible.Clear();
g.NavMoveResultOther.Clear();
g.NavTabbingCounter = 0;
g.NavTabbingResultFirst.Clear();
NavUpdateAnyRequestFlag();
}

Expand Down Expand Up @@ -10590,7 +10639,7 @@ void ImGui::NavRestoreLayer(ImGuiNavLayer layer)
{
ImGuiContext& g = *GImGui;
if (layer == ImGuiNavLayer_Main)
g.NavWindow = NavRestoreLastChildNavWindow(g.NavWindow);
g.NavWindow = NavRestoreLastChildNavWindow(g.NavWindow); // FIXME-NAV: Should clear ongoing nav requests?
ImGuiWindow* window = g.NavWindow;
if (window->NavLastIds[layer] != 0)
{
Expand Down Expand Up @@ -11071,7 +11120,6 @@ void ImGui::NavUpdateCreateTabbingRequest()
ImGuiScrollFlags scroll_flags = window->Appearing ? ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_AlwaysCenterY : ImGuiScrollFlags_KeepVisibleEdgeX | ImGuiScrollFlags_KeepVisibleEdgeY;
ImGuiDir clip_dir = (g.NavTabbingDir < 0) ? ImGuiDir_Up : ImGuiDir_Down;
NavMoveRequestSubmit(ImGuiDir_None, clip_dir, ImGuiNavMoveFlags_Tabbing, scroll_flags); // FIXME-NAV: Once we refactor tabbing, add LegacyApi flag to not activate non-inputable.
g.NavTabbingResultFirst.Clear();
g.NavTabbingCounter = -1;
}

Expand Down Expand Up @@ -17954,6 +18002,13 @@ void ImGui::ShowMetricsWindow(bool* p_open)
TreePop();
}

// Details for InputText
if (TreeNode("InputText"))
{
DebugNodeInputTextState(&g.InputTextState);
TreePop();
}

// Details for Docking
#ifdef IMGUI_HAS_DOCK
if (TreeNode("Docking"))
Expand Down Expand Up @@ -18840,8 +18895,8 @@ void ImGui::ShowStackToolWindow(bool* p_open)
if (tool->CopyToClipboardOnCtrlC && IsKeyDown(ImGuiKey_ModCtrl) && IsKeyPressed(ImGuiKey_C))
{
tool->CopyToClipboardLastTime = (float)g.Time;
char* p = g.TempBuffer;
char* p_end = p + IM_ARRAYSIZE(g.TempBuffer);
char* p = g.TempBuffer.Data;
char* p_end = p + g.TempBuffer.Size;
for (int stack_n = 0; stack_n < tool->Results.Size && p + 3 < p_end; stack_n++)
{
*p++ = '/';
Expand All @@ -18855,7 +18910,7 @@ void ImGui::ShowStackToolWindow(bool* p_open)
}
}
*p = '\0';
SetClipboardText(g.TempBuffer);
SetClipboardText(g.TempBuffer.Data);
}

// Display decorated stack
Expand All @@ -18873,8 +18928,8 @@ void ImGui::ShowStackToolWindow(bool* p_open)
TableNextColumn();
Text("0x%08X", (n > 0) ? tool->Results[n - 1].ID : 0);
TableNextColumn();
StackToolFormatLevelInfo(tool, n, true, g.TempBuffer, IM_ARRAYSIZE(g.TempBuffer));
TextUnformatted(g.TempBuffer);
StackToolFormatLevelInfo(tool, n, true, g.TempBuffer.Data, g.TempBuffer.Size);
TextUnformatted(g.TempBuffer.Data);
TableNextColumn();
Text("0x%08X", info->ID);
if (n == tool->Results.Size - 1)
Expand Down
Loading

0 comments on commit e900ca3

Please sign in to comment.