From 9c1dac3ff0c476a998a56b015682f09a3ccb4f74 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 4 Jan 2023 12:14:53 +0100 Subject: [PATCH 1/8] Examples: DirectX10, DirectX11: try WARP software driver if hardware driver is not available. (#5924, #5562) --- docs/CHANGELOG.txt | 1 + examples/example_win32_directx10/main.cpp | 5 ++++- examples/example_win32_directx11/main.cpp | 5 ++++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 6f9c433f99d1..6f94e5981e7d 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -75,6 +75,7 @@ Other changes: - Misc: fixed parameters to IMGUI_DEBUG_LOG() not being dead-stripped when building with IMGUI_DISABLE_DEBUG_TOOLS is used. (#5901) [@Teselka] - Misc: fixed compile-time detection of SSE features on MSVC 32-bits builds. (#5943) [@TheMostDiligent] +- Examples: DirectX10, DirectX11: try WARP software driver if hardware driver is not available. (#5924, #5562) - Backends: Allegro5: restoring using al_draw_indexed_prim() when Allegro version is >= 5.2.5. (#5937) [@Espyo] - Backends: Vulkan: Fixed sampler passed to ImGui_ImplVulkan_AddTexture() not being honored as we were using an immutable sampler. (#5502, #6001, #914) [@martin-ejdestig, @rytisss] diff --git a/examples/example_win32_directx10/main.cpp b/examples/example_win32_directx10/main.cpp index e2ec2f041736..03af619ea06f 100644 --- a/examples/example_win32_directx10/main.cpp +++ b/examples/example_win32_directx10/main.cpp @@ -182,7 +182,10 @@ bool CreateDeviceD3D(HWND hWnd) UINT createDeviceFlags = 0; //createDeviceFlags |= D3D10_CREATE_DEVICE_DEBUG; - if (D3D10CreateDeviceAndSwapChain(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, D3D10_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice) != S_OK) + HRESULT res = D3D10CreateDeviceAndSwapChain(NULL, D3D10_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, D3D10_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice); + if (res == DXGI_ERROR_UNSUPPORTED) // Try high-performance WARP software driver if hardware is not available. + res = D3D10CreateDeviceAndSwapChain(NULL, D3D10_DRIVER_TYPE_WARP, NULL, createDeviceFlags, D3D10_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice); + if (res != S_OK) return false; CreateRenderTarget(); diff --git a/examples/example_win32_directx11/main.cpp b/examples/example_win32_directx11/main.cpp index d2e31c4f96a5..d7e5738dfa7c 100644 --- a/examples/example_win32_directx11/main.cpp +++ b/examples/example_win32_directx11/main.cpp @@ -185,7 +185,10 @@ bool CreateDeviceD3D(HWND hWnd) //createDeviceFlags |= D3D11_CREATE_DEVICE_DEBUG; D3D_FEATURE_LEVEL featureLevel; const D3D_FEATURE_LEVEL featureLevelArray[2] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_0, }; - if (D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, featureLevelArray, 2, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext) != S_OK) + HRESULT res = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, createDeviceFlags, featureLevelArray, 2, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext); + if (res == DXGI_ERROR_UNSUPPORTED) // Try high-performance WARP software driver if hardware is not available. + res = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_WARP, NULL, createDeviceFlags, featureLevelArray, 2, D3D11_SDK_VERSION, &sd, &g_pSwapChain, &g_pd3dDevice, &featureLevel, &g_pd3dDeviceContext); + if (res != S_OK) return false; CreateRenderTarget(); From 9150c23c0446fba375714437b90e31603cf28c23 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 4 Jan 2023 15:17:21 +0100 Subject: [PATCH 2/8] imgui_freetype: fixed a packing issue which in some occurrences would prevent large amount of glyphs from being packed correctly. (#5788, #5829) This seemingly innocuous change sursingly had very large side-effects of completly breaking packing for the test font mentioned in above issue. Not even sure why tbh. New code matches what stb_truetype's stbtt_PackBegin() does. --- docs/CHANGELOG.txt | 2 ++ misc/freetype/imgui_freetype.cpp | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 6f94e5981e7d..03a5248bc647 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -67,6 +67,8 @@ Other changes: - Misc: added GetItemID() in public API. It is not often expected that you would use this, but it is useful for Shortcut() and upcoming owner-aware input functions which wants to be implemented with public API. +- Fonts: imgui_freetype: fixed a packing issue which in some occurrences would prevent large + amount of glyphs from being packed correctly. (#5788, #5829) - Fonts: added a 'void* UserData' field in ImFontAtlas, as a convenience for use by applications using multiple font atlases. - Demo: added "Inputs->Shortcut Routing" section. diff --git a/misc/freetype/imgui_freetype.cpp b/misc/freetype/imgui_freetype.cpp index 03255326b2b6..78ef293979ad 100644 --- a/misc/freetype/imgui_freetype.cpp +++ b/misc/freetype/imgui_freetype.cpp @@ -6,6 +6,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2023/01/04: fixed a packing issue which in some occurrences would prevent large amount of glyphs from being packed correctly. // 2021/08/23: fixed crash when FT_Render_Glyph() fails to render a glyph and returns NULL. // 2021/03/05: added ImGuiFreeTypeBuilderFlags_Bitmap to load bitmap glyphs. // 2021/03/02: set 'atlas->TexPixelsUseColors = true' to help some backends with deciding of a prefered texture format. @@ -586,7 +587,7 @@ bool ImFontAtlasBuildWithFreeTypeEx(FT_Library ft_library, ImFontAtlas* atlas, u ImVector pack_nodes; pack_nodes.resize(num_nodes_for_packing_algorithm); stbrp_context pack_context; - stbrp_init_target(&pack_context, atlas->TexWidth, TEX_HEIGHT_MAX, pack_nodes.Data, pack_nodes.Size); + stbrp_init_target(&pack_context, atlas->TexWidth - atlas->TexGlyphPadding, TEX_HEIGHT_MAX - atlas->TexGlyphPadding, pack_nodes.Data, pack_nodes.Size); ImFontAtlasBuildPackCustomRects(atlas, &pack_context); // 6. Pack each source font. No rendering yet, we are working with rectangles in an infinitely tall texture at this point. From 1f6e62a4ae31d807ddf3e8f86567442e6c49f36d Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 4 Jan 2023 15:42:20 +0100 Subject: [PATCH 3/8] Backends: GLFW: Fixed mods state on Linux with Alt-GR text input (e.g. German keyboard layout), (#6034) Amend 07557674, 1ad8ad62 Ref maybe https://github.com/glfw/glfw/issues/1630 --- backends/imgui_impl_glfw.cpp | 34 +++++++++++----------------------- docs/CHANGELOG.txt | 3 +++ 2 files changed, 14 insertions(+), 23 deletions(-) diff --git a/backends/imgui_impl_glfw.cpp b/backends/imgui_impl_glfw.cpp index dfde0331e223..d0dedf643536 100644 --- a/backends/imgui_impl_glfw.cpp +++ b/backends/imgui_impl_glfw.cpp @@ -16,6 +16,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2023-01-04: Inputs: Fixed mods state on Linux when using Alt-GR text input (e.g. German keyboard layout), could lead to broken text input. Revert a 2022/01/17 change were we resumed using mods provided by GLFW, turns out they were faulty. // 2022-11-22: Perform a dummy glfwGetError() read to cancel missing names with glfwGetKeyName(). (#5908) // 2022-10-18: Perform a dummy glfwGetError() read to cancel missing mouse cursors errors. Using GLFW_VERSION_COMBINED directly. (#5785) // 2022-10-11: Using 'nullptr' instead of 'NULL' as per our switch to C++11. @@ -251,26 +252,16 @@ static ImGuiKey ImGui_ImplGlfw_KeyToImGuiKey(int key) } } -static int ImGui_ImplGlfw_KeyToModifier(int key) -{ - if (key == GLFW_KEY_LEFT_CONTROL || key == GLFW_KEY_RIGHT_CONTROL) - return GLFW_MOD_CONTROL; - if (key == GLFW_KEY_LEFT_SHIFT || key == GLFW_KEY_RIGHT_SHIFT) - return GLFW_MOD_SHIFT; - if (key == GLFW_KEY_LEFT_ALT || key == GLFW_KEY_RIGHT_ALT) - return GLFW_MOD_ALT; - if (key == GLFW_KEY_LEFT_SUPER || key == GLFW_KEY_RIGHT_SUPER) - return GLFW_MOD_SUPER; - return 0; -} - -static void ImGui_ImplGlfw_UpdateKeyModifiers(int mods) +// X11 does not include current pressed/released modifier key in 'mods' flags submitted by GLFW +// See https://github.com/ocornut/imgui/issues/6034 and https://github.com/glfw/glfw/issues/1630 +static void ImGui_ImplGlfw_UpdateKeyModifiers() { ImGuiIO& io = ImGui::GetIO(); - io.AddKeyEvent(ImGuiMod_Ctrl, (mods & GLFW_MOD_CONTROL) != 0); - io.AddKeyEvent(ImGuiMod_Shift, (mods & GLFW_MOD_SHIFT) != 0); - io.AddKeyEvent(ImGuiMod_Alt, (mods & GLFW_MOD_ALT) != 0); - io.AddKeyEvent(ImGuiMod_Super, (mods & GLFW_MOD_SUPER) != 0); + ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); + io.AddKeyEvent(ImGuiMod_Ctrl, (glfwGetKey(bd->Window, GLFW_KEY_LEFT_CONTROL) == GLFW_PRESS) || (glfwGetKey(bd->Window, GLFW_KEY_RIGHT_CONTROL) == GLFW_PRESS)); + io.AddKeyEvent(ImGuiMod_Shift, (glfwGetKey(bd->Window, GLFW_KEY_LEFT_SHIFT) == GLFW_PRESS) || (glfwGetKey(bd->Window, GLFW_KEY_RIGHT_SHIFT) == GLFW_PRESS)); + io.AddKeyEvent(ImGuiMod_Alt, (glfwGetKey(bd->Window, GLFW_KEY_LEFT_ALT) == GLFW_PRESS) || (glfwGetKey(bd->Window, GLFW_KEY_RIGHT_ALT) == GLFW_PRESS)); + io.AddKeyEvent(ImGuiMod_Super, (glfwGetKey(bd->Window, GLFW_KEY_LEFT_SUPER) == GLFW_PRESS) || (glfwGetKey(bd->Window, GLFW_KEY_RIGHT_SUPER) == GLFW_PRESS)); } void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int action, int mods) @@ -279,7 +270,7 @@ void ImGui_ImplGlfw_MouseButtonCallback(GLFWwindow* window, int button, int acti if (bd->PrevUserCallbackMousebutton != nullptr && window == bd->Window) bd->PrevUserCallbackMousebutton(window, button, action, mods); - ImGui_ImplGlfw_UpdateKeyModifiers(mods); + ImGui_ImplGlfw_UpdateKeyModifiers(); ImGuiIO& io = ImGui::GetIO(); if (button >= 0 && button < ImGuiMouseButton_COUNT) @@ -338,10 +329,7 @@ void ImGui_ImplGlfw_KeyCallback(GLFWwindow* window, int keycode, int scancode, i if (action != GLFW_PRESS && action != GLFW_RELEASE) return; - // Workaround: X11 does not include current pressed/released modifier key in 'mods' flags. https://github.com/glfw/glfw/issues/1630 - if (int keycode_to_mod = ImGui_ImplGlfw_KeyToModifier(keycode)) - mods = (action == GLFW_PRESS) ? (mods | keycode_to_mod) : (mods & ~keycode_to_mod); - ImGui_ImplGlfw_UpdateKeyModifiers(mods); + ImGui_ImplGlfw_UpdateKeyModifiers(); keycode = ImGui_ImplGlfw_TranslateUntranslatedKey(keycode, scancode); diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 03a5248bc647..bd6f8c18753d 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -78,6 +78,9 @@ Other changes: with IMGUI_DISABLE_DEBUG_TOOLS is used. (#5901) [@Teselka] - Misc: fixed compile-time detection of SSE features on MSVC 32-bits builds. (#5943) [@TheMostDiligent] - Examples: DirectX10, DirectX11: try WARP software driver if hardware driver is not available. (#5924, #5562) +- Backends: GLFW: Fixed mods state on Linux when using Alt-GR text input (e.g. German keyboard layout), which + could lead to broken text input. Revert a 2022/01/17 change were we resumed using mods provided by GLFW, + turns out they are faulty in this specific situation. (#6034) - Backends: Allegro5: restoring using al_draw_indexed_prim() when Allegro version is >= 5.2.5. (#5937) [@Espyo] - Backends: Vulkan: Fixed sampler passed to ImGui_ImplVulkan_AddTexture() not being honored as we were using an immutable sampler. (#5502, #6001, #914) [@martin-ejdestig, @rytisss] From 57a5b73a4cd86ec8f7d4295010d7d082a07b806c Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 4 Jan 2023 17:58:07 +0100 Subject: [PATCH 4/8] InputText: fixed cursor navigation when pressing Up Arrow on the last character of a multiline buffer which doesn't end with a carriage return. (#6000) Simplify stb_textedit_find_charpos(). Leaving that to simmer for a while before attempting an upstream PR. --- docs/CHANGELOG.txt | 2 ++ imgui.h | 2 +- imgui_widgets.cpp | 1 + imstb_textedit.h | 36 +++++++++++++----------------------- 4 files changed, 17 insertions(+), 24 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index bd6f8c18753d..51763f2b372d 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -62,6 +62,8 @@ Other changes: and when backend/OS is emitting dual-axis wheeling inputs (typically touch pads on macOS). We now select a primary axis based on recent events, and select a target window based on it. We expect this behavior to be further improved/tweaked. (#3795, #4559) [@ocornut, @folays] +- InputText: fixed cursor navigation when pressing Up Arrow on the last character of a + multiline buffer which doesn't end with a carriage return. (#6000) - Text: fixed layouting of wrapped-text block when the last source line is above the clipping region. Regression added in 1.89. (#5720, #5919) - Misc: added GetItemID() in public API. It is not often expected that you would use this, diff --git a/imgui.h b/imgui.h index 60385137bb7d..fe49f7f0cf53 100644 --- a/imgui.h +++ b/imgui.h @@ -23,7 +23,7 @@ // Library Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM > 12345') #define IMGUI_VERSION "1.89.2 WIP" -#define IMGUI_VERSION_NUM 18916 +#define IMGUI_VERSION_NUM 18917 #define IMGUI_HAS_TABLE /* diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 0cdac0ad32b4..7893fab095d0 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -4858,6 +4858,7 @@ void ImGui::DebugNodeInputTextState(ImGuiInputTextState* state) Text("ID: 0x%08X, ActiveID: 0x%08X", state->ID, g.ActiveId); DebugLocateItemOnHover(state->ID); Text("CurLenW: %d, CurLenA: %d, Cursor: %d, Selection: %d..%d", state->CurLenA, state->CurLenW, stb_state->cursor, stb_state->select_start, stb_state->select_end); + Text("has_preferred_x: %d (%.2f)", stb_state->has_preferred_x, stb_state->preferred_x); Text("undo_point: %d, redo_point: %d, undo_char_point: %d, redo_char_point: %d", undo_state->undo_point, undo_state->redo_point, undo_state->undo_char_point, undo_state->redo_char_point); if (BeginChild("undopoints", ImVec2(0.0f, GetTextLineHeight() * 15), true)) // Visualize undo state { diff --git a/imstb_textedit.h b/imstb_textedit.h index 75a159dac736..a8a823110b0d 100644 --- a/imstb_textedit.h +++ b/imstb_textedit.h @@ -2,6 +2,7 @@ // This is a slightly modified version of stb_textedit.h 1.14. // Those changes would need to be pushed into nothings/stb: // - Fix in stb_textedit_discard_redo (see https://github.com/nothings/stb/issues/321) +// - Fix in stb_textedit_find_charpos to handle last line (see https://github.com/ocornut/imgui/issues/6000) // Grep for [DEAR IMGUI] to find the changes. // stb_textedit.h - v1.14 - public domain - Sean Barrett @@ -524,29 +525,14 @@ static void stb_textedit_find_charpos(StbFindState *find, STB_TEXTEDIT_STRING *s int z = STB_TEXTEDIT_STRINGLEN(str); int i=0, first; - if (n == z) { - // if it's at the end, then find the last line -- simpler than trying to - // explicitly handle this case in the regular code - if (single_line) { - STB_TEXTEDIT_LAYOUTROW(&r, str, 0); - find->y = 0; - find->first_char = 0; - find->length = z; - find->height = r.ymax - r.ymin; - find->x = r.x1; - } else { - find->y = 0; - find->x = 0; - find->height = 1; - while (i < z) { - STB_TEXTEDIT_LAYOUTROW(&r, str, i); - prev_start = i; - i += r.num_chars; - } - find->first_char = i; - find->length = 0; - find->prev_first = prev_start; - } + if (n == z && single_line) { + // special case if it's at the end (may not be needed?) + STB_TEXTEDIT_LAYOUTROW(&r, str, 0); + find->y = 0; + find->first_char = 0; + find->length = z; + find->height = r.ymax - r.ymin; + find->x = r.x1; return; } @@ -557,9 +543,13 @@ static void stb_textedit_find_charpos(StbFindState *find, STB_TEXTEDIT_STRING *s STB_TEXTEDIT_LAYOUTROW(&r, str, i); if (n < i + r.num_chars) break; + if (i + r.num_chars == z && z > 0 && STB_TEXTEDIT_GETCHAR(str, z - 1) != STB_TEXTEDIT_NEWLINE) // [DEAR IMGUI] special handling for last line + break; // [DEAR IMGUI] prev_start = i; i += r.num_chars; find->y += r.baseline_y_delta; + if (i == z) // [DEAR IMGUI] + break; // [DEAR IMGUI] } find->first_char = first = i; From 03add24acfc790de66434ac1a333bb8cd015cff7 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 5 Jan 2023 11:28:05 +0100 Subject: [PATCH 5/8] Selectable: Internals: removed unused ImGuiSelectableFlags_DrawHoveredWhenHeld flag. Needlessly introduced in baae057a from WIP tables branch at the time, ended up unused by Tables. A comment "I find it counter intuitive that hovering supersedes activation." in #3516 led me to this however this is not the cause of said issue. --- imgui_internal.h | 7 +++---- imgui_widgets.cpp | 2 -- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/imgui_internal.h b/imgui_internal.h index 4dc34427430d..4e6ede9509e8 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -890,10 +890,9 @@ enum ImGuiSelectableFlagsPrivate_ ImGuiSelectableFlags_SelectOnClick = 1 << 22, // Override button behavior to react on Click (default is Click+Release) ImGuiSelectableFlags_SelectOnRelease = 1 << 23, // Override button behavior to react on Release (default is Click+Release) ImGuiSelectableFlags_SpanAvailWidth = 1 << 24, // Span all avail width even if we declared less for layout purpose. FIXME: We may be able to remove this (added in 6251d379, 2bcafc86 for menus) - ImGuiSelectableFlags_DrawHoveredWhenHeld = 1 << 25, // Always show active when held, even is not hovered. This concept could probably be renamed/formalized somehow. - ImGuiSelectableFlags_SetNavIdOnHover = 1 << 26, // Set Nav/Focus ID on mouse hover (used by MenuItem) - ImGuiSelectableFlags_NoPadWithHalfSpacing = 1 << 27, // Disable padding each side with ItemSpacing * 0.5f - ImGuiSelectableFlags_NoSetKeyOwner = 1 << 28, // Don't set key/input owner on the initial click (note: mouse buttons are keys! often, the key in question will be ImGuiKey_MouseLeft!) + ImGuiSelectableFlags_SetNavIdOnHover = 1 << 25, // Set Nav/Focus ID on mouse hover (used by MenuItem) + ImGuiSelectableFlags_NoPadWithHalfSpacing = 1 << 26, // Disable padding each side with ItemSpacing * 0.5f + ImGuiSelectableFlags_NoSetKeyOwner = 1 << 27, // Don't set key/input owner on the initial click (note: mouse buttons are keys! often, the key in question will be ImGuiKey_MouseLeft!) }; // Extend ImGuiTreeNodeFlags_ diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 7893fab095d0..f0673c6f19ef 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -6370,8 +6370,6 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl g.LastItemData.StatusFlags |= ImGuiItemStatusFlags_ToggledSelection; // Render - if (held && (flags & ImGuiSelectableFlags_DrawHoveredWhenHeld)) - hovered = true; if (hovered || selected) { const ImU32 col = GetColorU32((held && hovered) ? ImGuiCol_HeaderActive : hovered ? ImGuiCol_HeaderHovered : ImGuiCol_Header); From 83429abf4af6dee15516fe43e9d12fd62d25be52 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 5 Jan 2023 12:01:16 +0100 Subject: [PATCH 6/8] Internals: simplify ButtonBehavior(), also to allow easily adding a mouse_button_down thing. --- imgui_widgets.cpp | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index f0673c6f19ef..83da2506271a 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -544,13 +544,21 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool const ImGuiID test_owner_id = (flags & ImGuiButtonFlags_NoTestKeyOwner) ? ImGuiKeyOwner_Any : id; if (hovered) { + // Poll mouse buttons + // - 'mouse_button_clicked' is generally carried into ActiveIdMouseButton when setting ActiveId. + // - Technically we only need some values in one code path, but since this is gated by hovered test this is fine. + int mouse_button_clicked = -1; + int mouse_button_released = -1; + for (int button = 0; button < 3; button++) + if (flags & (ImGuiButtonFlags_MouseButtonLeft << button)) // Handle ImGuiButtonFlags_MouseButtonRight and ImGuiButtonFlags_MouseButtonMiddle here. + { + if (IsMouseClicked(button, test_owner_id) && mouse_button_clicked == -1) { mouse_button_clicked = button; } + if (IsMouseReleased(button, test_owner_id) && mouse_button_released == -1) { mouse_button_released = button; } + } + + // Process initial action if (!(flags & ImGuiButtonFlags_NoKeyModifiers) || (!g.IO.KeyCtrl && !g.IO.KeyShift && !g.IO.KeyAlt)) { - // Poll buttons - int mouse_button_clicked = -1; - if ((flags & ImGuiButtonFlags_MouseButtonLeft) && IsMouseClicked(0, test_owner_id)) { mouse_button_clicked = 0; } - else if ((flags & ImGuiButtonFlags_MouseButtonRight) && IsMouseClicked(1, test_owner_id)) { mouse_button_clicked = 1; } - else if ((flags & ImGuiButtonFlags_MouseButtonMiddle) && IsMouseClicked(2, test_owner_id)) { mouse_button_clicked = 2; } if (mouse_button_clicked != -1 && g.ActiveId != id) { if (!(flags & ImGuiButtonFlags_NoSetKeyOwner)) @@ -578,10 +586,6 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool } if (flags & ImGuiButtonFlags_PressedOnRelease) { - int mouse_button_released = -1; - if ((flags & ImGuiButtonFlags_MouseButtonLeft) && IsMouseReleased(0, test_owner_id)) { mouse_button_released = 0; } - else if ((flags & ImGuiButtonFlags_MouseButtonRight) && IsMouseReleased(1, test_owner_id)) { mouse_button_released = 1; } - else if ((flags & ImGuiButtonFlags_MouseButtonMiddle) && IsMouseReleased(2, test_owner_id)) { mouse_button_released = 2; } if (mouse_button_released != -1) { const bool has_repeated_at_least_once = (flags & ImGuiButtonFlags_Repeat) && g.IO.MouseDownDurationPrev[mouse_button_released] >= g.IO.KeyRepeatDelay; // Repeat mode trumps on release behavior From e06bbe05e1d39cd5033aec4a3d6bb9441215d60c Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 5 Jan 2023 15:21:48 +0100 Subject: [PATCH 7/8] Revert most/part of "Shortcut: added Shortcut() function and ImGuiInputFlags in public API + Demo." (#456, #2637) This reverts commit 0949acb6e6f4f6343a09ff70d811c2e81e0e5474. # Conflicts: # imgui.h --- docs/CHANGELOG.txt | 7 ---- imgui.h | 46 +------------------------ imgui_demo.cpp | 86 +++------------------------------------------- imgui_internal.h | 35 ++++++++++++++++--- 4 files changed, 36 insertions(+), 138 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 51763f2b372d..79f04d511aa8 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -39,12 +39,6 @@ Breaking changes: Other changes: -- Inputs: added Shortcut() function (w/ routing policies) in public API. (#456, #2637) - Added ImGuiInputFlags_RouteFocused, ImGuiInputFlags_RouteGlobalXXX and other routing policies. - e.g. ImGui::Shortcut(ImGuiMod_Ctrl | ImGuiKey_C); with default policy: - - check that CTRL+C is pressed, - - and that current window is in focus stack, - - and that no other requests for CTRL+C have been made from deeper locations of the window/item stack. - Fixed cases where CTRL+Tab or Modal can occasionally lead to the creation of ImDrawCmd with zero triangles, which would makes the render loop of some backends assert (e.g. Metal with debugging, Allegro). (#4857, #5937) @@ -73,7 +67,6 @@ Other changes: amount of glyphs from being packed correctly. (#5788, #5829) - Fonts: added a 'void* UserData' field in ImFontAtlas, as a convenience for use by applications using multiple font atlases. -- Demo: added "Inputs->Shortcut Routing" section. - Demo: simplified "Inputs" section, moved contents to Metrics->Inputs. - Debug Tools: Metrics: added "Inputs" section, moved from Demo for consistency. - Misc: fixed parameters to IMGUI_DEBUG_LOG() not being dead-stripped when building diff --git a/imgui.h b/imgui.h index fe49f7f0cf53..20f054e099b0 100644 --- a/imgui.h +++ b/imgui.h @@ -23,7 +23,7 @@ // Library Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM > 12345') #define IMGUI_VERSION "1.89.2 WIP" -#define IMGUI_VERSION_NUM 18917 +#define IMGUI_VERSION_NUM 18918 #define IMGUI_HAS_TABLE /* @@ -192,7 +192,6 @@ typedef int ImGuiComboFlags; // -> enum ImGuiComboFlags_ // Flags: f typedef int ImGuiDragDropFlags; // -> enum ImGuiDragDropFlags_ // Flags: for BeginDragDropSource(), AcceptDragDropPayload() typedef int ImGuiFocusedFlags; // -> enum ImGuiFocusedFlags_ // Flags: for IsWindowFocused() typedef int ImGuiHoveredFlags; // -> enum ImGuiHoveredFlags_ // Flags: for IsItemHovered(), IsWindowHovered() etc. -typedef int ImGuiInputFlags; // -> enum ImGuiInputFlags_ // Flags: for Shortcut() (+ upcoming advanced versions of IsKeyPressed()/IsMouseClicked()/SetKeyOwner()/SetItemKeyOwner() currently in imgui_internal.h) typedef int ImGuiInputTextFlags; // -> enum ImGuiInputTextFlags_ // Flags: for InputText(), InputTextMultiline() typedef int ImGuiKeyChord; // -> ImGuiKey | ImGuiMod_XXX // Flags: for storage only for now: an ImGuiKey optionally OR-ed with one or more ImGuiMod_XXX values. typedef int ImGuiPopupFlags; // -> enum ImGuiPopupFlags_ // Flags: for OpenPopup*(), BeginPopupContext*(), IsPopupOpen() @@ -896,21 +895,6 @@ namespace ImGui IMGUI_API const char* GetKeyName(ImGuiKey key); // [DEBUG] returns English name of the key. Those names a provided for debugging purpose and are not meant to be saved persistently not compared. IMGUI_API void SetNextFrameWantCaptureKeyboard(bool want_capture_keyboard); // Override io.WantCaptureKeyboard flag next frame (said flag is left for your application to handle, typically when true it instructs your app to ignore inputs). e.g. force capture keyboard when your widget is being hovered. This is equivalent to setting "io.WantCaptureKeyboard = want_capture_keyboard"; after the next NewFrame() call. - // Inputs Utilities: Shortcut testing (with Routing Resolution) - // - ImGuiKeyChord = a ImGuiKey optionally OR-red with ImGuiMod_Alt/ImGuiMod_Ctrl/ImGuiMod_Shift/ImGuiMod_Super/ImGuiMod_Shortcut. - // ImGuiKey_C (accepted by functions taking ImGuiKey or ImGuiKeyChord) - // ImGuiKey_C | ImGuiMod_Ctrl (accepted by functions taking ImGuiKeyChord) - // ONLY ImGuiMod_XXX values are legal to 'OR' with an ImGuiKey. You CANNOT 'OR' two ImGuiKey values. - // - The general idea of routing is that multiple locations may register interest in a shortcut, - // and only one location will be granted access to the shortcut. - // - The default routing policy (ImGuiInputFlags_RouteFocused) checks for current window being in - // the focus stack, and route the shortcut to the deepest requesting window in the focus stack. - // - Consider Shortcut() to be a widget: the calling location matters + it has side-effects as shortcut routes are - // registered into the system (for it to be able to pick the best one). This is why this is not called 'IsShortcutPressed()'. - // - If this is called for a specific widget, pass its ID as 'owner_id' in order for key ownership and routing priorities - // to be honored (e.g. with default ImGuiInputFlags_RouteFocused, the highest priority is given to active item). - IMGUI_API bool Shortcut(ImGuiKeyChord key_chord, ImGuiID owner_id = 0, ImGuiInputFlags flags = 0); - // Inputs Utilities: Mouse specific // - To refer to a mouse button, you may use named enums in your code e.g. ImGuiMouseButton_Left, ImGuiMouseButton_Right. // - You can also use regular integer: it is forever guaranteed that 0=Left, 1=Right, 2=Middle. @@ -1492,34 +1476,6 @@ enum ImGuiKey : int #endif }; -// Flags for Shortcut() -// (+ for upcoming advanced versions of IsKeyPressed()/IsMouseClicked()/SetKeyOwner()/SetItemKeyOwner() that are currently in imgui_internal.h) -enum ImGuiInputFlags_ -{ - ImGuiInputFlags_None = 0, - ImGuiInputFlags_Repeat = 1 << 0, // Return true on successive repeats. Default for legacy IsKeyPressed(). NOT Default for legacy IsMouseClicked(). MUST BE == 1. - - // Routing policies for Shortcut() + low-level SetShortcutRouting() - // - The general idea is that several callers register interest in a shortcut, and only one owner gets it. - // - When a policy (other than _RouteAlways) is set, Shortcut() will register itself with SetShortcutRouting(), - // allowing the system to decide where to route the input among other route-aware calls. - // - Shortcut() uses ImGuiInputFlags_RouteFocused by default: meaning that a simple Shortcut() poll - // will register a route and only succeed when parent window is in the focus stack and if no-one - // with a higher priority is claiming the shortcut. - // - Using ImGuiInputFlags_RouteAlways is roughly equivalent to doing e.g. IsKeyPressed(key) + testing mods. - // - Priorities: GlobalHigh > Focused (when owner is active item) > Global > Focused (when focused window) > GlobalLow. - - // Policies (can select only 1 policy among all available) - ImGuiInputFlags_RouteFocused = 1 << 8, // (Default) Register focused route: Accept inputs if window is in focus stack. Deep-most focused window takes inputs. ActiveId takes inputs over deep-most focused window. - ImGuiInputFlags_RouteGlobalLow = 1 << 9, // Register route globally (lowest priority: unless a focused window or active item registered the route) -> recommended Global priority. - ImGuiInputFlags_RouteGlobal = 1 << 10, // Register route globally (medium priority: unless an active item registered the route, e.g. CTRL+A registered by InputText). - ImGuiInputFlags_RouteGlobalHigh = 1 << 11, // Register route globally (highest priority: unlikely you need to use that: will interfere with every active items) - ImGuiInputFlags_RouteAlways = 1 << 12, // Do not register route, poll keys directly. - - // Policies Options - ImGuiInputFlags_RouteUnlessBgFocused= 1 << 13, // Global routes will not be applied if underlying background/void is focused (== no Dear ImGui windows are focused). Useful for overlay applications. -}; - #ifndef IMGUI_DISABLE_OBSOLETE_KEYIO // OBSOLETED in 1.88 (from July 2022): ImGuiNavInput and io.NavInputs[]. // Official backends between 1.60 and 1.86: will keep working and feed gamepad inputs as long as IMGUI_DISABLE_OBSOLETE_KEYIO is not set. diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 435c3684fd48..04f3f1923fc5 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -5775,76 +5775,6 @@ static void ShowDemoWindowInputs() ImGui::TreePop(); } - // Demonstrate using Shortcut() and Routing Policies. - // The general flow is: - // - Code interested in a chord (e.g. "Ctrl+A") declares their intent. - // - Multiple locations may be interested in same chord! Routing helps find a winner. - // - Every frame, we resolve all claims and assign one owner if the modifiers are matching. - // - The lower-level function is 'bool SetShortcutRouting()', returns true when caller got the route. - // - Most of the times, SetShortcutRouting() is not called directly. User mostly calls Shortcut() with routing flags. - // - If you call Shortcut() WITHOUT any routing option, it uses ImGuiInputFlags_RouteFocused. - // TL;DR: Most uses will simply be: - // - Shortcut(ImGuiMod_Ctrl | ImGuiKey_A); // Use ImGuiInputFlags_RouteFocused policy. - if (ImGui::TreeNode("Shortcut Routing")) - { - const float line_height = ImGui::GetTextLineHeightWithSpacing(); - const ImGuiKeyChord key_chord = ImGuiMod_Ctrl | ImGuiKey_A; - static ImGuiInputFlags repeat_flags = ImGuiInputFlags_Repeat; - static ImGuiInputFlags routing_flags = ImGuiInputFlags_RouteFocused; - ImGui::CheckboxFlags("ImGuiInputFlags_Repeat", &repeat_flags, ImGuiInputFlags_Repeat); - ImGui::RadioButton("ImGuiInputFlags_RouteFocused (default)", &routing_flags, ImGuiInputFlags_RouteFocused); - ImGui::RadioButton("ImGuiInputFlags_RouteAlways", &routing_flags, ImGuiInputFlags_RouteAlways); - ImGui::RadioButton("ImGuiInputFlags_RouteGlobal", &routing_flags, ImGuiInputFlags_RouteGlobal); - ImGui::RadioButton("ImGuiInputFlags_RouteGlobalHigh", &routing_flags, ImGuiInputFlags_RouteGlobalHigh); - ImGui::RadioButton("ImGuiInputFlags_RouteGlobalLow", &routing_flags, ImGuiInputFlags_RouteGlobalLow); - const ImGuiInputFlags flags = repeat_flags | routing_flags; // Merged flags - - ImGui::Text("IsWindowFocused: %d, Shortcut: %s", ImGui::IsWindowFocused(), ImGui::Shortcut(key_chord, 0, flags) ? "PRESSED" : "..."); - - ImGui::BeginChild("WindowA", ImVec2(-FLT_MIN, line_height * 18), true); - ImGui::Text("Press CTRL+A and see who receives it!"); - ImGui::Separator(); - - // 1: Window polling for CTRL+A - ImGui::Text("(in WindowA)"); - ImGui::Text("IsWindowFocused: %d, Shortcut: %s", ImGui::IsWindowFocused(), ImGui::Shortcut(key_chord, 0, flags) ? "PRESSED" : "..."); - - // 2: InputText also polling for CTRL+A: it always uses _RouteFocused internally (gets priority when active) - char str[16] = "Press CTRL+A"; - ImGui::Spacing(); - ImGui::InputText("InputTextB", str, IM_ARRAYSIZE(str), ImGuiInputTextFlags_ReadOnly); - ImGuiID item_id = ImGui::GetItemID(); - ImGui::SameLine(); HelpMarker("Internal widgets always use _RouteFocused"); - ImGui::Text("IsWindowFocused: %d, Shortcut: %s", ImGui::IsWindowFocused(), ImGui::Shortcut(key_chord, item_id, flags) ? "PRESSED" : "..."); - - // 3: Dummy child is not claiming the route: focusing them shouldn't steal route away from WindowA - ImGui::BeginChild("ChildD", ImVec2(-FLT_MIN, line_height * 4), true); - ImGui::Text("(in ChildD: not using same Shortcut)"); - ImGui::Text("IsWindowFocused: %d", ImGui::IsWindowFocused()); - ImGui::EndChild(); - - // 4: Child window polling for CTRL+A. It is deeper than WindowA and gets priority when focused. - ImGui::BeginChild("ChildE", ImVec2(-FLT_MIN, line_height * 4), true); - ImGui::Text("(in ChildE: using same Shortcut)"); - ImGui::Text("IsWindowFocused: %d, Shortcut: %s", ImGui::IsWindowFocused(), ImGui::Shortcut(key_chord, 0, flags) ? "PRESSED" : "..."); - ImGui::EndChild(); - - // 5: In a popup - if (ImGui::Button("Open Popup")) - ImGui::OpenPopup("PopupF"); - if (ImGui::BeginPopup("PopupF")) - { - ImGui::Text("(in PopupF)"); - ImGui::Text("IsWindowFocused: %d, Shortcut: %s", ImGui::IsWindowFocused(), ImGui::Shortcut(key_chord, 0, flags) ? "PRESSED" : "..."); - ImGui::InputText("InputTextG", str, IM_ARRAYSIZE(str), ImGuiInputTextFlags_ReadOnly); - ImGui::Text("IsWindowFocused: %d, Shortcut: %s", ImGui::IsWindowFocused(), ImGui::Shortcut(key_chord, ImGui::GetItemID(), flags) ? "PRESSED" : "..."); - ImGui::EndPopup(); - } - ImGui::EndChild(); - - ImGui::TreePop(); - } - // Display mouse cursors IMGUI_DEMO_MARKER("Inputs & Focus/Mouse Cursors"); if (ImGui::TreeNode("Mouse Cursors")) @@ -7108,9 +7038,6 @@ static void ShowExampleAppLayout(bool* p_open) ImGui::EndMenuBar(); } - if (ImGui::Shortcut(ImGuiMod_Ctrl | ImGuiKey_W)) - *p_open = false; - // Left static int selected = 0; { @@ -7818,14 +7745,11 @@ struct MyDocument ImGui::PushStyleColor(ImGuiCol_Text, doc->Color); ImGui::TextWrapped("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."); ImGui::PopStyleColor(); - if (ImGui::Button("Modify (Ctrl+M)") || ImGui::Shortcut(ImGuiMod_Shortcut | ImGuiKey_M)) + if (ImGui::Button("Modify", ImVec2(100, 0))) doc->Dirty = true; ImGui::SameLine(); - if (ImGui::Button("Save (Ctrl+S)") || ImGui::Shortcut(ImGuiMod_Shortcut | ImGuiKey_S)) + if (ImGui::Button("Save", ImVec2(100, 0))) doc->DoSave(); - ImGui::SameLine(); - if (ImGui::Button("Close (Ctrl+W)") || ImGui::Shortcut(ImGuiMod_Shortcut | ImGuiKey_W)) - doc->DoQueueClose(); ImGui::ColorEdit3("color", &doc->Color.x); // Useful to test drag and drop and hold-dragged-to-open-tab behavior. ImGui::PopID(); } @@ -7838,9 +7762,9 @@ struct MyDocument char buf[256]; sprintf(buf, "Save %s", doc->Name); - if (ImGui::MenuItem(buf, "Ctrl+S", false, doc->Open)) + if (ImGui::MenuItem(buf, "CTRL+S", false, doc->Open)) doc->DoSave(); - if (ImGui::MenuItem("Close", "Ctrl+W", false, doc->Open)) + if (ImGui::MenuItem("Close", "CTRL+W", false, doc->Open)) doc->DoQueueClose(); ImGui::EndPopup(); } @@ -7918,7 +7842,7 @@ void ShowExampleAppDocuments(bool* p_open) if (ImGui::MenuItem("Close All Documents", NULL, false, open_count > 0)) for (int doc_n = 0; doc_n < app.Documents.Size; doc_n++) app.Documents[doc_n].DoQueueClose(); - if (ImGui::MenuItem("Exit") && p_open) + if (ImGui::MenuItem("Exit", "Ctrl+F4") && p_open) *p_open = false; ImGui::EndMenu(); } diff --git a/imgui_internal.h b/imgui_internal.h index 4e6ede9509e8..1820dc62f836 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -154,6 +154,7 @@ typedef int ImGuiLayoutType; // -> enum ImGuiLayoutType_ // E // Flags typedef int ImGuiActivateFlags; // -> enum ImGuiActivateFlags_ // Flags: for navigation/focus function (will be for ActivateItem() later) typedef int ImGuiDebugLogFlags; // -> enum ImGuiDebugLogFlags_ // Flags: for ShowDebugLogWindow(), g.DebugLogFlags +typedef int ImGuiInputFlags; // -> enum ImGuiInputFlags_ // Flags: for IsKeyPressed(), IsMouseClicked(), SetKeyOwner(), SetItemKeyOwner() etc. typedef int ImGuiItemFlags; // -> enum ImGuiItemFlags_ // Flags: for PushItemFlag(), g.LastItemData.InFlags typedef int ImGuiItemStatusFlags; // -> enum ImGuiItemStatusFlags_ // Flags: for g.LastItemData.StatusFlags typedef int ImGuiOldColumnFlags; // -> enum ImGuiOldColumnFlags_ // Flags: for BeginColumns() @@ -1327,12 +1328,13 @@ struct ImGuiKeyOwnerData ImGuiKeyOwnerData() { OwnerCurr = OwnerNext = ImGuiKeyOwner_None; LockThisFrame = LockUntilRelease = false; } }; -// Extend ImGuiInputFlags_ // Flags for extended versions of IsKeyPressed(), IsMouseClicked(), Shortcut(), SetKeyOwner(), SetItemKeyOwner() // Don't mistake with ImGuiInputTextFlags! (for ImGui::InputText() function) -enum ImGuiInputFlagsPrivate_ +enum ImGuiInputFlags_ { // Flags for IsKeyPressed(), IsMouseClicked(), Shortcut() + ImGuiInputFlags_None = 0, + ImGuiInputFlags_Repeat = 1 << 0, // Return true on successive repeats. Default for legacy IsKeyPressed(). NOT Default for legacy IsMouseClicked(). MUST BE == 1. ImGuiInputFlags_RepeatRateDefault = 1 << 1, // Repeat rate: Regular (default) ImGuiInputFlags_RepeatRateNavMove = 1 << 2, // Repeat rate: Fast ImGuiInputFlags_RepeatRateNavTweak = 1 << 3, // Repeat rate: Faster @@ -1348,9 +1350,26 @@ enum ImGuiInputFlagsPrivate_ ImGuiInputFlags_LockThisFrame = 1 << 6, // Access to key data will require EXPLICIT owner ID (ImGuiKeyOwner_Any/0 will NOT accepted for polling). Cleared at end of frame. This is useful to make input-owner-aware code steal keys from non-input-owner-aware code. ImGuiInputFlags_LockUntilRelease = 1 << 7, // Access to key data will require EXPLICIT owner ID (ImGuiKeyOwner_Any/0 will NOT accepted for polling). Cleared when the key is released or at end of each frame if key is released. This is useful to make input-owner-aware code steal keys from non-input-owner-aware code. + // Routing policies for Shortcut() + low-level SetShortcutRouting() + // - The general idea is that several callers register interest in a shortcut, and only one owner gets it. + // - When a policy (other than _RouteAlways) is set, Shortcut() will register itself with SetShortcutRouting(), + // allowing the system to decide where to route the input among other route-aware calls. + // - Shortcut() uses ImGuiInputFlags_RouteFocused by default: meaning that a simple Shortcut() poll + // will register a route and only succeed when parent window is in the focus stack and if no-one + // with a higher priority is claiming the shortcut. + // - Using ImGuiInputFlags_RouteAlways is roughly equivalent to doing e.g. IsKeyPressed(key) + testing mods. + // - Priorities: GlobalHigh > Focused (when owner is active item) > Global > Focused (when focused window) > GlobalLow. + // - Can select only 1 policy among all available. + ImGuiInputFlags_RouteFocused = 1 << 8, // (Default) Register focused route: Accept inputs if window is in focus stack. Deep-most focused window takes inputs. ActiveId takes inputs over deep-most focused window. + ImGuiInputFlags_RouteGlobalLow = 1 << 9, // Register route globally (lowest priority: unless a focused window or active item registered the route) -> recommended Global priority. + ImGuiInputFlags_RouteGlobal = 1 << 10, // Register route globally (medium priority: unless an active item registered the route, e.g. CTRL+A registered by InputText). + ImGuiInputFlags_RouteGlobalHigh = 1 << 11, // Register route globally (highest priority: unlikely you need to use that: will interfere with every active items) + ImGuiInputFlags_RouteMask_ = ImGuiInputFlags_RouteFocused | ImGuiInputFlags_RouteGlobal | ImGuiInputFlags_RouteGlobalLow | ImGuiInputFlags_RouteGlobalHigh, // _Always not part of this! + ImGuiInputFlags_RouteAlways = 1 << 12, // Do not register route, poll keys directly. + ImGuiInputFlags_RouteUnlessBgFocused= 1 << 13, // Global routes will not be applied if underlying background/void is focused (== no Dear ImGui windows are focused). Useful for overlay applications. + ImGuiInputFlags_RouteExtraMask_ = ImGuiInputFlags_RouteAlways | ImGuiInputFlags_RouteUnlessBgFocused, + // [Internal] Mask of which function support which flags - ImGuiInputFlags_RouteMask_ = ImGuiInputFlags_RouteFocused | ImGuiInputFlags_RouteGlobal | ImGuiInputFlags_RouteGlobalLow | ImGuiInputFlags_RouteGlobalHigh, // _Always not part of this! - ImGuiInputFlags_RouteExtraMask_ = ImGuiInputFlags_RouteAlways | ImGuiInputFlags_RouteUnlessBgFocused, ImGuiInputFlags_SupportedByIsKeyPressed = ImGuiInputFlags_Repeat | ImGuiInputFlags_RepeatRateMask_, ImGuiInputFlags_SupportedByShortcut = ImGuiInputFlags_Repeat | ImGuiInputFlags_RepeatRateMask_ | ImGuiInputFlags_RouteMask_ | ImGuiInputFlags_RouteExtraMask_, ImGuiInputFlags_SupportedBySetKeyOwner = ImGuiInputFlags_LockThisFrame | ImGuiInputFlags_LockUntilRelease, @@ -2915,11 +2934,17 @@ namespace ImGui IMGUI_API bool IsMouseClicked(ImGuiMouseButton button, ImGuiID owner_id, ImGuiInputFlags flags = 0); IMGUI_API bool IsMouseReleased(ImGuiMouseButton button, ImGuiID owner_id); - // [EXPERIMENTAL] Low-Level: Shortcut Routing + // [EXPERIMENTAL] Shortcut Routing + // - ImGuiKeyChord = a ImGuiKey optionally OR-red with ImGuiMod_Alt/ImGuiMod_Ctrl/ImGuiMod_Shift/ImGuiMod_Super. + // ImGuiKey_C (accepted by functions taking ImGuiKey or ImGuiKeyChord) + // ImGuiKey_C | ImGuiMod_Ctrl (accepted by functions taking ImGuiKeyChord) + // ONLY ImGuiMod_XXX values are legal to 'OR' with an ImGuiKey. You CANNOT 'OR' two ImGuiKey values. + // - When using one of the routing flags (e.g. ImGuiInputFlags_RouteFocused): routes requested ahead of time given a chord (key + modifiers) and a routing policy. // - Routes are resolved during NewFrame(): if keyboard modifiers are matching current ones: SetKeyOwner() is called + route is granted for the frame. // - Route is granted to a single owner. When multiple requests are made we have policies to select the winning route. // - Multiple read sites may use the same owner id and will all get the granted route. // - For routing: when owner_id is 0 we use the current Focus Scope ID as a default owner in order to identify our location. + IMGUI_API bool Shortcut(ImGuiKeyChord key_chord, ImGuiID owner_id = 0, ImGuiInputFlags flags = 0); IMGUI_API bool SetShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id = 0, ImGuiInputFlags flags = 0); IMGUI_API bool TestShortcutRouting(ImGuiKeyChord key_chord, ImGuiID owner_id); IMGUI_API ImGuiKeyRoutingData* GetShortcutRoutingData(ImGuiKeyChord key_chord); From d7c8516a4b848c0291e3d75b627c0843f515f591 Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 5 Jan 2023 15:29:17 +0100 Subject: [PATCH 8/8] Version 1.89.2 --- docs/CHANGELOG.txt | 10 +++++----- imgui.cpp | 2 +- imgui.h | 12 ++++++------ imgui_demo.cpp | 2 +- imgui_draw.cpp | 2 +- imgui_internal.h | 2 +- imgui_tables.cpp | 2 +- imgui_widgets.cpp | 2 +- 8 files changed, 17 insertions(+), 17 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 79f04d511aa8..88653b399cf3 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -32,16 +32,13 @@ HOW TO UPDATE? ----------------------------------------------------------------------- - VERSION 1.89.2 WIP (In Progress) + VERSION 1.89.2 (Released 2023-01-05) ----------------------------------------------------------------------- -Breaking changes: +Decorated log and release notes: https://github.com/ocornut/imgui/releases/tag/v1.89.2 Other changes: -- Fixed cases where CTRL+Tab or Modal can occasionally lead to the creation of ImDrawCmd with - zero triangles, which would makes the render loop of some backends assert (e.g. Metal with - debugging, Allegro). (#4857, #5937) - Tables, Nav, Scrolling: fixed scrolling functions and focus tracking with frozen rows and frozen columns. Windows now have a better understanding of outer/inner decoration sizes, which should later lead us toward more flexible uses of menu/status bars. (#5143, #3692) @@ -49,6 +46,9 @@ Other changes: - Tables, Columns: fixed cases where empty columns may lead to empty ImDrawCmd. (#4857, #5937) - Tables: fixed matching width of synchronized tables (multiple tables with same id) when only some instances have a vertical scrollbar and not all. (#5920) +- Fixed cases where CTRL+Tab or Modal can occasionally lead to the creation of ImDrawCmd with + zero triangles, which would makes the render loop of some backends assert (e.g. Metal with + debugging, Allegro). (#4857, #5937) - Inputs, IO: reworked ImGuiMod_Shortcut to redirect to Ctrl/Super at runtime instead of compile-time, being consistent with our support for io.ConfigMacOSXBehaviors and making it easier for bindings generators to process that value. (#5923, #456) diff --git a/imgui.cpp b/imgui.cpp index 501f5c91459b..3faca98f1206 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.89.2 WIP +// dear imgui, v1.89.2 // (main code and documentation) // Help: diff --git a/imgui.h b/imgui.h index 20f054e099b0..152f4f09db46 100644 --- a/imgui.h +++ b/imgui.h @@ -1,4 +1,4 @@ -// dear imgui, v1.89.2 WIP +// dear imgui, v1.89.2 // (headers) // Help: @@ -22,8 +22,8 @@ // Library Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM > 12345') -#define IMGUI_VERSION "1.89.2 WIP" -#define IMGUI_VERSION_NUM 18918 +#define IMGUI_VERSION "1.89.2" +#define IMGUI_VERSION_NUM 18920 #define IMGUI_HAS_TABLE /* @@ -255,8 +255,8 @@ struct ImVec2 float x, y; constexpr ImVec2() : x(0.0f), y(0.0f) { } constexpr ImVec2(float _x, float _y) : x(_x), y(_y) { } - float operator[] (size_t idx) const { IM_ASSERT(idx <= 1); return (&x)[idx]; } // We very rarely use this [] operator, the assert overhead is fine. - float& operator[] (size_t idx) { IM_ASSERT(idx <= 1); return (&x)[idx]; } // We very rarely use this [] operator, the assert overhead is fine. + float operator[] (size_t idx) const { IM_ASSERT(idx == 0 || idx == 1); return (&x)[idx]; } // We very rarely use this [] operator, the assert overhead is fine. + float& operator[] (size_t idx) { IM_ASSERT(idx == 0 || idx == 1); return (&x)[idx]; } // We very rarely use this [] operator, the assert overhead is fine. #ifdef IM_VEC2_CLASS_EXTRA IM_VEC2_CLASS_EXTRA // Define additional constructors and implicit cast operators in imconfig.h to convert back and forth between your math types and ImVec2. #endif @@ -419,7 +419,7 @@ namespace ImGui IMGUI_API void PopTextWrapPos(); // Style read access - // - Use the style editor (ShowStyleEditor() function) to interactively see what the colors are) + // - Use the ShowStyleEditor() function to interactively see/edit the colors. IMGUI_API ImFont* GetFont(); // get current font IMGUI_API float GetFontSize(); // get current font size (= height in pixels) of current font with current scale applied IMGUI_API ImVec2 GetFontTexUvWhitePixel(); // get UV coordinate for a while pixel, useful to draw custom shapes via the ImDrawList API diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 04f3f1923fc5..c1b7dbe5ace2 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.89.2 WIP +// dear imgui, v1.89.2 // (demo code) // Help: diff --git a/imgui_draw.cpp b/imgui_draw.cpp index 7cd9c7c1054e..2d423cd87403 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.89.2 WIP +// dear imgui, v1.89.2 // (drawing and font code) /* diff --git a/imgui_internal.h b/imgui_internal.h index 1820dc62f836..e57eab7757e5 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1,4 +1,4 @@ -// dear imgui, v1.89.2 WIP +// dear imgui, v1.89.2 // (internal structures/api) // You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility! diff --git a/imgui_tables.cpp b/imgui_tables.cpp index 7a65c5b66cba..47fc8a2873c7 100644 --- a/imgui_tables.cpp +++ b/imgui_tables.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.89.2 WIP +// dear imgui, v1.89.2 // (tables and columns code) /* diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 83da2506271a..0a1ea6789de1 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.89.2 WIP +// dear imgui, v1.89.2 // (widgets code) /*