From 417ac68f82912ae4291e8e9b05abf38877a64b83 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 18 May 2020 11:55:36 +0200 Subject: [PATCH 01/13] Internals: AddPolyline: Add spaces for consistency, renaming. --- imgui_draw.cpp | 56 +++++++++++++++++++++++++------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/imgui_draw.cpp b/imgui_draw.cpp index f566cbc5..2dfccf07 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -627,13 +627,12 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 if (points_count < 2) return; - const ImVec2 uv = _Data->TexUvWhitePixel; - + const ImVec2 opaque_uv = _Data->TexUvWhitePixel; int count = points_count; if (!closed) count = points_count-1; - const bool thick_line = thickness > 1.0f; + const bool thick_line = (thickness > 1.0f); if (Flags & ImDrawListFlags_AntiAliasedLines) { // Anti-aliased stroke @@ -704,9 +703,9 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 // Add vertices for (int i = 0; i < points_count; i++) { - _VtxWritePtr[0].pos = points[i]; _VtxWritePtr[0].uv = uv; _VtxWritePtr[0].col = col; - _VtxWritePtr[1].pos = temp_points[i*2+0]; _VtxWritePtr[1].uv = uv; _VtxWritePtr[1].col = col_trans; - _VtxWritePtr[2].pos = temp_points[i*2+1]; _VtxWritePtr[2].uv = uv; _VtxWritePtr[2].col = col_trans; + _VtxWritePtr[0].pos = points[i]; _VtxWritePtr[0].uv = opaque_uv; _VtxWritePtr[0].col = col; + _VtxWritePtr[1].pos = temp_points[i*2+0]; _VtxWritePtr[1].uv = opaque_uv; _VtxWritePtr[1].col = col_trans; + _VtxWritePtr[2].pos = temp_points[i*2+1]; _VtxWritePtr[2].uv = opaque_uv; _VtxWritePtr[2].col = col_trans; _VtxWritePtr += 3; } } @@ -715,22 +714,23 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 const float half_inner_thickness = (thickness - AA_SIZE) * 0.5f; if (!closed) { + const int points_last = points_count - 1; temp_points[0] = points[0] + temp_normals[0] * (half_inner_thickness + AA_SIZE); temp_points[1] = points[0] + temp_normals[0] * (half_inner_thickness); temp_points[2] = points[0] - temp_normals[0] * (half_inner_thickness); temp_points[3] = points[0] - temp_normals[0] * (half_inner_thickness + AA_SIZE); - temp_points[(points_count-1)*4+0] = points[points_count-1] + temp_normals[points_count-1] * (half_inner_thickness + AA_SIZE); - temp_points[(points_count-1)*4+1] = points[points_count-1] + temp_normals[points_count-1] * (half_inner_thickness); - temp_points[(points_count-1)*4+2] = points[points_count-1] - temp_normals[points_count-1] * (half_inner_thickness); - temp_points[(points_count-1)*4+3] = points[points_count-1] - temp_normals[points_count-1] * (half_inner_thickness + AA_SIZE); + temp_points[points_last * 4 + 0] = points[points_last] + temp_normals[points_last] * (half_inner_thickness + AA_SIZE); + temp_points[points_last * 4 + 1] = points[points_last] + temp_normals[points_last] * (half_inner_thickness); + temp_points[points_last * 4 + 2] = points[points_last] - temp_normals[points_last] * (half_inner_thickness); + temp_points[points_last * 4 + 3] = points[points_last] - temp_normals[points_last] * (half_inner_thickness + AA_SIZE); } // FIXME-OPT: Merge the different loops, possibly remove the temporary buffer. unsigned int idx1 = _VtxCurrentIdx; for (int i1 = 0; i1 < count; i1++) { - const int i2 = (i1+1) == points_count ? 0 : i1+1; - unsigned int idx2 = (i1+1) == points_count ? _VtxCurrentIdx : idx1+4; + const int i2 = (i1 + 1) == points_count ? 0 : (i1 + 1); // i2 is the second point of the line segment + const unsigned int idx2 = (i1 + 1) == points_count ? _VtxCurrentIdx : (idx1 + 4); // Vertex index for end of segment // Average normals float dm_x = (temp_normals[i1].x + temp_normals[i2].x) * 0.5f; @@ -753,12 +753,12 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 out_vtx[3].y = points[i2].y - dm_out_y; // Add indexes - _IdxWritePtr[0] = (ImDrawIdx)(idx2+1); _IdxWritePtr[1] = (ImDrawIdx)(idx1+1); _IdxWritePtr[2] = (ImDrawIdx)(idx1+2); - _IdxWritePtr[3] = (ImDrawIdx)(idx1+2); _IdxWritePtr[4] = (ImDrawIdx)(idx2+2); _IdxWritePtr[5] = (ImDrawIdx)(idx2+1); - _IdxWritePtr[6] = (ImDrawIdx)(idx2+1); _IdxWritePtr[7] = (ImDrawIdx)(idx1+1); _IdxWritePtr[8] = (ImDrawIdx)(idx1+0); - _IdxWritePtr[9] = (ImDrawIdx)(idx1+0); _IdxWritePtr[10] = (ImDrawIdx)(idx2+0); _IdxWritePtr[11] = (ImDrawIdx)(idx2+1); - _IdxWritePtr[12] = (ImDrawIdx)(idx2+2); _IdxWritePtr[13] = (ImDrawIdx)(idx1+2); _IdxWritePtr[14] = (ImDrawIdx)(idx1+3); - _IdxWritePtr[15] = (ImDrawIdx)(idx1+3); _IdxWritePtr[16] = (ImDrawIdx)(idx2+3); _IdxWritePtr[17] = (ImDrawIdx)(idx2+2); + _IdxWritePtr[0] = (ImDrawIdx)(idx2 + 1); _IdxWritePtr[1] = (ImDrawIdx)(idx1 + 1); _IdxWritePtr[2] = (ImDrawIdx)(idx1 + 2); + _IdxWritePtr[3] = (ImDrawIdx)(idx1 + 2); _IdxWritePtr[4] = (ImDrawIdx)(idx2 + 2); _IdxWritePtr[5] = (ImDrawIdx)(idx2 + 1); + _IdxWritePtr[6] = (ImDrawIdx)(idx2 + 1); _IdxWritePtr[7] = (ImDrawIdx)(idx1 + 1); _IdxWritePtr[8] = (ImDrawIdx)(idx1 + 0); + _IdxWritePtr[9] = (ImDrawIdx)(idx1 + 0); _IdxWritePtr[10] = (ImDrawIdx)(idx2 + 0); _IdxWritePtr[11] = (ImDrawIdx)(idx2 + 1); + _IdxWritePtr[12] = (ImDrawIdx)(idx2 + 2); _IdxWritePtr[13] = (ImDrawIdx)(idx1 + 2); _IdxWritePtr[14] = (ImDrawIdx)(idx1 + 3); + _IdxWritePtr[15] = (ImDrawIdx)(idx1 + 3); _IdxWritePtr[16] = (ImDrawIdx)(idx2 + 3); _IdxWritePtr[17] = (ImDrawIdx)(idx2 + 2); _IdxWritePtr += 18; idx1 = idx2; @@ -767,10 +767,10 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 // Add vertices for (int i = 0; i < points_count; i++) { - _VtxWritePtr[0].pos = temp_points[i*4+0]; _VtxWritePtr[0].uv = uv; _VtxWritePtr[0].col = col_trans; - _VtxWritePtr[1].pos = temp_points[i*4+1]; _VtxWritePtr[1].uv = uv; _VtxWritePtr[1].col = col; - _VtxWritePtr[2].pos = temp_points[i*4+2]; _VtxWritePtr[2].uv = uv; _VtxWritePtr[2].col = col; - _VtxWritePtr[3].pos = temp_points[i*4+3]; _VtxWritePtr[3].uv = uv; _VtxWritePtr[3].col = col_trans; + _VtxWritePtr[0].pos = temp_points[i * 4 + 0]; _VtxWritePtr[0].uv = opaque_uv; _VtxWritePtr[0].col = col_trans; + _VtxWritePtr[1].pos = temp_points[i * 4 + 1]; _VtxWritePtr[1].uv = opaque_uv; _VtxWritePtr[1].col = col; + _VtxWritePtr[2].pos = temp_points[i * 4 + 2]; _VtxWritePtr[2].uv = opaque_uv; _VtxWritePtr[2].col = col; + _VtxWritePtr[3].pos = temp_points[i * 4 + 3]; _VtxWritePtr[3].uv = opaque_uv; _VtxWritePtr[3].col = col_trans; _VtxWritePtr += 4; } } @@ -795,14 +795,14 @@ void ImDrawList::AddPolyline(const ImVec2* points, const int points_count, ImU32 dx *= (thickness * 0.5f); dy *= (thickness * 0.5f); - _VtxWritePtr[0].pos.x = p1.x + dy; _VtxWritePtr[0].pos.y = p1.y - dx; _VtxWritePtr[0].uv = uv; _VtxWritePtr[0].col = col; - _VtxWritePtr[1].pos.x = p2.x + dy; _VtxWritePtr[1].pos.y = p2.y - dx; _VtxWritePtr[1].uv = uv; _VtxWritePtr[1].col = col; - _VtxWritePtr[2].pos.x = p2.x - dy; _VtxWritePtr[2].pos.y = p2.y + dx; _VtxWritePtr[2].uv = uv; _VtxWritePtr[2].col = col; - _VtxWritePtr[3].pos.x = p1.x - dy; _VtxWritePtr[3].pos.y = p1.y + dx; _VtxWritePtr[3].uv = uv; _VtxWritePtr[3].col = col; + _VtxWritePtr[0].pos.x = p1.x + dy; _VtxWritePtr[0].pos.y = p1.y - dx; _VtxWritePtr[0].uv = opaque_uv; _VtxWritePtr[0].col = col; + _VtxWritePtr[1].pos.x = p2.x + dy; _VtxWritePtr[1].pos.y = p2.y - dx; _VtxWritePtr[1].uv = opaque_uv; _VtxWritePtr[1].col = col; + _VtxWritePtr[2].pos.x = p2.x - dy; _VtxWritePtr[2].pos.y = p2.y + dx; _VtxWritePtr[2].uv = opaque_uv; _VtxWritePtr[2].col = col; + _VtxWritePtr[3].pos.x = p1.x - dy; _VtxWritePtr[3].pos.y = p1.y + dx; _VtxWritePtr[3].uv = opaque_uv; _VtxWritePtr[3].col = col; _VtxWritePtr += 4; - _IdxWritePtr[0] = (ImDrawIdx)(_VtxCurrentIdx); _IdxWritePtr[1] = (ImDrawIdx)(_VtxCurrentIdx+1); _IdxWritePtr[2] = (ImDrawIdx)(_VtxCurrentIdx+2); - _IdxWritePtr[3] = (ImDrawIdx)(_VtxCurrentIdx); _IdxWritePtr[4] = (ImDrawIdx)(_VtxCurrentIdx+2); _IdxWritePtr[5] = (ImDrawIdx)(_VtxCurrentIdx+3); + _IdxWritePtr[0] = (ImDrawIdx)(_VtxCurrentIdx); _IdxWritePtr[1] = (ImDrawIdx)(_VtxCurrentIdx + 1); _IdxWritePtr[2] = (ImDrawIdx)(_VtxCurrentIdx + 2); + _IdxWritePtr[3] = (ImDrawIdx)(_VtxCurrentIdx); _IdxWritePtr[4] = (ImDrawIdx)(_VtxCurrentIdx + 2); _IdxWritePtr[5] = (ImDrawIdx)(_VtxCurrentIdx + 3); _IdxWritePtr += 6; _VtxCurrentIdx += 4; } From 75bbbda645c650a52783e8bd5c49da4b6905d81e Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 20 May 2020 11:44:00 +0200 Subject: [PATCH 02/13] Examples: Update comments to get SDL2 package with msys2's pacman (#3251) --- examples/example_sdl_opengl2/Makefile | 2 +- examples/example_sdl_opengl3/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/example_sdl_opengl2/Makefile b/examples/example_sdl_opengl2/Makefile index ce29a249..9c57337e 100644 --- a/examples/example_sdl_opengl2/Makefile +++ b/examples/example_sdl_opengl2/Makefile @@ -8,7 +8,7 @@ # Mac OS X: # brew install sdl2 # MSYS2: -# pacman -S mingw-w64-i686-SDL +# pacman -S mingw-w64-i686-SDL2 # #CXX = g++ diff --git a/examples/example_sdl_opengl3/Makefile b/examples/example_sdl_opengl3/Makefile index ada77197..e8b2f566 100644 --- a/examples/example_sdl_opengl3/Makefile +++ b/examples/example_sdl_opengl3/Makefile @@ -8,7 +8,7 @@ # Mac OS X: # brew install sdl2 # MSYS2: -# pacman -S mingw-w64-i686-SDL +# pacman -S mingw-w64-i686-SDL2 # #CXX = g++ From f44962c01a0e5f5fdf9652cb28e775838fe0dbbc Mon Sep 17 00:00:00 2001 From: Espyo Date: Wed, 20 May 2020 16:48:21 +0100 Subject: [PATCH 03/13] Backends: Allegro: Don't call AddInputCharacter if the pressed key has no character. (#3252) --- examples/imgui_impl_allegro5.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/imgui_impl_allegro5.cpp b/examples/imgui_impl_allegro5.cpp index 76f74a3f..2c7df9a9 100644 --- a/examples/imgui_impl_allegro5.cpp +++ b/examples/imgui_impl_allegro5.cpp @@ -357,7 +357,8 @@ bool ImGui_ImplAllegro5_ProcessEvent(ALLEGRO_EVENT *ev) return true; case ALLEGRO_EVENT_KEY_CHAR: if (ev->keyboard.display == g_Display) - io.AddInputCharacter((unsigned int)ev->keyboard.unichar); + if (ev->keyboard.unichar != 0) + io.AddInputCharacter((unsigned int)ev->keyboard.unichar); return true; case ALLEGRO_EVENT_KEY_DOWN: case ALLEGRO_EVENT_KEY_UP: From c8cde28cf3fb5d1e86faa80edf9b2c48ccc2f8dc Mon Sep 17 00:00:00 2001 From: omar Date: Wed, 20 May 2020 17:56:08 +0200 Subject: [PATCH 04/13] IO: AddInputCharacters function ignore 0 input. (#3252) Amend ef13d954 + c8ea0a01 (#2541, #2538, #2815) --- imgui.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 726b05f5..6a984849 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1142,17 +1142,21 @@ ImGuiIO::ImGuiIO() // - on Windows you can get those using ToAscii+keyboard state, or via the WM_CHAR message void ImGuiIO::AddInputCharacter(unsigned int c) { - InputQueueCharacters.push_back(c > 0 && c <= IM_UNICODE_CODEPOINT_MAX ? (ImWchar)c : IM_UNICODE_CODEPOINT_INVALID); + if (c != 0) + InputQueueCharacters.push_back(c <= IM_UNICODE_CODEPOINT_MAX ? (ImWchar)c : IM_UNICODE_CODEPOINT_INVALID); } // UTF16 strings use surrogate pairs to encode codepoints >= 0x10000, so // we should save the high surrogate. void ImGuiIO::AddInputCharacterUTF16(ImWchar16 c) { + if (c == 0 && InputQueueSurrogate == 0) + return; + if ((c & 0xFC00) == 0xD800) // High surrogate, must save { if (InputQueueSurrogate != 0) - InputQueueCharacters.push_back(0xFFFD); + InputQueueCharacters.push_back(IM_UNICODE_CODEPOINT_INVALID); InputQueueSurrogate = c; return; } @@ -1177,7 +1181,7 @@ void ImGuiIO::AddInputCharactersUTF8(const char* utf8_chars) { unsigned int c = 0; utf8_chars += ImTextCharFromUtf8(&c, utf8_chars, NULL); - if (c > 0) + if (c != 0) InputQueueCharacters.push_back((ImWchar)c); } } From d29157ce584e731114ff09d448120e094307304f Mon Sep 17 00:00:00 2001 From: omar Date: Sun, 24 May 2020 12:32:31 +0200 Subject: [PATCH 05/13] Moved static array with non-trivial constructors outside of function seems to remove requirement of linking with libstdc++ on some compilers. --- imgui.cpp | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 6a984849..97b15411 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5064,6 +5064,21 @@ static const ImGuiResizeGripDef resize_grip_def[4] = { ImVec2(1,0), ImVec2(-1,+1), 9,12 }, // Upper-right (Unused) }; +struct ImGuiResizeBorderDef +{ + ImVec2 InnerDir; + ImVec2 CornerPosN1, CornerPosN2; + float OuterAngle; +}; + +static const ImGuiResizeBorderDef resize_border_def[4] = +{ + { ImVec2(0,+1), ImVec2(0,0), ImVec2(1,0), IM_PI*1.50f }, // Top + { ImVec2(-1,0), ImVec2(1,0), ImVec2(1,1), IM_PI*0.00f }, // Right + { ImVec2(0,-1), ImVec2(1,1), ImVec2(0,1), IM_PI*0.50f }, // Bottom + { ImVec2(+1,0), ImVec2(0,1), ImVec2(0,0), IM_PI*1.00f } // Left +}; + static ImRect GetResizeBorderRect(ImGuiWindow* window, int border_n, float perp_padding, float thickness) { ImRect rect = window->Rect(); @@ -5229,19 +5244,6 @@ static void ImGui::RenderWindowOuterBorders(ImGuiWindow* window) int border_held = window->ResizeBorderHeld; if (border_held != -1) { - struct ImGuiResizeBorderDef - { - ImVec2 InnerDir; - ImVec2 CornerPosN1, CornerPosN2; - float OuterAngle; - }; - static const ImGuiResizeBorderDef resize_border_def[4] = - { - { ImVec2(0,+1), ImVec2(0,0), ImVec2(1,0), IM_PI*1.50f }, // Top - { ImVec2(-1,0), ImVec2(1,0), ImVec2(1,1), IM_PI*0.00f }, // Right - { ImVec2(0,-1), ImVec2(1,1), ImVec2(0,1), IM_PI*0.50f }, // Bottom - { ImVec2(+1,0), ImVec2(0,1), ImVec2(0,0), IM_PI*1.00f } // Left - }; const ImGuiResizeBorderDef& def = resize_border_def[border_held]; ImRect border_r = GetResizeBorderRect(window, border_held, rounding, 0.0f); window->DrawList->PathArcTo(ImLerp(border_r.Min, border_r.Max, def.CornerPosN1) + ImVec2(0.5f, 0.5f) + def.InnerDir * rounding, rounding, def.OuterAngle - IM_PI*0.25f, def.OuterAngle); From 39d17ca07f14d3e37b8e6a85ee65bc078abf023e Mon Sep 17 00:00:00 2001 From: Nicolas Burrus Date: Mon, 25 May 2020 07:34:12 +0200 Subject: [PATCH 06/13] Examples: Apple: catch events from the right and other mouse buttons when using Cocoa. (#3260) --- docs/CHANGELOG.txt | 6 +++-- .../Shared/ViewController.mm | 24 +++++++++++++++++++ examples/example_apple_opengl2/main.mm | 24 ++++++++++++------- 3 files changed, 44 insertions(+), 10 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 6730d29f..78719031 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -54,6 +54,8 @@ Other Changes: - Metrics: Added a "Settings" section with some details about persistent ini settings. - Nav, Menus: Fix vertical wrap-around in menus or popups created with multiple appending calls to BeginMenu()/EndMenu() or BeginPopup/EndPopup(). (#3223, #1207) [@rokups] +- Drag and Drop: Fixed unintended fallback "..." tooltip display during drag operation when + drag source uses _SourceNoPreviewTooltip flags. (#3160) [@rokups] - Backends: Win32: Support for #define NOGDI, won't try to call GetDeviceCaps(). (#3137, #2327) - Backends: Win32: Fix _WIN32_WINNT < 0x0600 (MinGW defaults to 0x502 == Windows 2003). (#3183) - Backends: OpenGL: Fixed handling of GL 4.5+ glClipControl(GL_UPPER_LEFT) by inverting the @@ -62,8 +64,8 @@ Other Changes: - Backends: Vulkan: Fixed error in if initial frame has no vertices. (#3177) - Backends: Vulkan: Fixed edge case where render callbacks wouldn't be called if the ImDrawData structure didn't have any vertices. (#2697) [@kudaba] -- Drag and Drop: Fixed unintended fallback "..." tooltip display during drag operation when - drag source uses _SourceNoPreviewTooltip flags. (#3160) [@rokups] +- Examples: Apple: Fixed example_apple_metal and example_apple_opengl2 using imgui_impl_osx.mm + not forwarding right and center mouse clicks. (#3260) [@nburrus] ----------------------------------------------------------------------- diff --git a/examples/example_apple_metal/Shared/ViewController.mm b/examples/example_apple_metal/Shared/ViewController.mm index 73040add..3c79cc1c 100644 --- a/examples/example_apple_metal/Shared/ViewController.mm +++ b/examples/example_apple_metal/Shared/ViewController.mm @@ -72,14 +72,38 @@ ImGui_ImplOSX_HandleEvent(event, self.view); } +- (void)rightMouseDown:(NSEvent *)event { + ImGui_ImplOSX_HandleEvent(event, self.view); +} + +- (void)otherMouseDown:(NSEvent *)event { + ImGui_ImplOSX_HandleEvent(event, self.view); +} + - (void)mouseUp:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); } +- (void)rightMouseUp:(NSEvent *)event { + ImGui_ImplOSX_HandleEvent(event, self.view); +} + +- (void)otherMouseUp:(NSEvent *)event { + ImGui_ImplOSX_HandleEvent(event, self.view); +} + - (void)mouseDragged:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); } +- (void)rightMouseDragged:(NSEvent *)event { + ImGui_ImplOSX_HandleEvent(event, self.view); +} + +- (void)otherMouseDragged:(NSEvent *)event { + ImGui_ImplOSX_HandleEvent(event, self.view); +} + - (void)scrollWheel:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self.view); } diff --git a/examples/example_apple_opengl2/main.mm b/examples/example_apple_opengl2/main.mm index e8f2768b..7cbf3409 100644 --- a/examples/example_apple_opengl2/main.mm +++ b/examples/example_apple_opengl2/main.mm @@ -139,14 +139,22 @@ } // Forward Mouse/Keyboard events to dear imgui OSX back-end. It returns true when imgui is expecting to use the event. --(void)keyUp:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } --(void)keyDown:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } --(void)flagsChanged:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } --(void)mouseDown:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } --(void)mouseUp:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } --(void)mouseMoved:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } --(void)mouseDragged:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } --(void)scrollWheel:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } +-(void)keyUp:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } +-(void)keyDown:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } +-(void)flagsChanged:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } +-(void)mouseDown:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } +-(void)rightMouseDown:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } +-(void)otherMouseDown:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } +-(void)mouseUp:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } +-(void)rightMouseUp:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } +-(void)otherMouseUp:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } +-(void)mouseMoved:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } +-(void)rightMouseMoved:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } +-(void)otherMouseMoved:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } +-(void)mouseDragged:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } +-(void)rightMouseDragged:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } +-(void)otherMouseDragged:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } +-(void)scrollWheel:(NSEvent *)event { ImGui_ImplOSX_HandleEvent(event, self); } @end From 43f79aa21069485f27bf5dee3f9977464fd746e3 Mon Sep 17 00:00:00 2001 From: Nicolas Burrus Date: Mon, 25 May 2020 08:27:17 +0200 Subject: [PATCH 07/13] Backends: OSX: import the glfw workaround to avoid missing mouse clicks. (#3261) --- examples/imgui_impl_osx.mm | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/examples/imgui_impl_osx.mm b/examples/imgui_impl_osx.mm index 54b23d07..221fa562 100644 --- a/examples/imgui_impl_osx.mm +++ b/examples/imgui_impl_osx.mm @@ -14,6 +14,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2020-05-25: Inputs: Added a fix for missing trackpad clicks when done with "soft tap". // 2019-12-05: Inputs: Added support for ImGuiMouseCursor_NotAllowed mouse cursor. // 2019-10-11: Inputs: Fix using Backspace key. // 2019-07-21: Re-added clipboard handlers as they are not enabled by default in core imgui.cpp (reverted 2019-05-18 change). @@ -27,6 +28,8 @@ static CFAbsoluteTime g_Time = 0.0; static NSCursor* g_MouseCursors[ImGuiMouseCursor_COUNT] = {}; static bool g_MouseCursorHidden = false; +static bool g_MouseJustPressed[5] = { false, false, false, false, false }; +static bool g_MouseDown[5] = { false, false, false, false, false }; // Undocumented methods for creating cursors. @interface NSCursor() @@ -121,9 +124,17 @@ void ImGui_ImplOSX_Shutdown() { } -static void ImGui_ImplOSX_UpdateMouseCursor() +static void ImGui_ImplOSX_UpdateMouseCursorAndButtons() { ImGuiIO& io = ImGui::GetIO(); + + for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown) && i < IM_ARRAYSIZE(g_MouseJustPressed); i++) + { + // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. + io.MouseDown[i] = g_MouseJustPressed[i] || g_MouseDown[i]; + g_MouseJustPressed[i] = false; + } + if (io.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange) return; @@ -167,7 +178,7 @@ void ImGui_ImplOSX_NewFrame(NSView* view) io.DeltaTime = current_time - g_Time; g_Time = current_time; - ImGui_ImplOSX_UpdateMouseCursor(); + ImGui_ImplOSX_UpdateMouseCursorAndButtons(); } static int mapCharacterToKey(int c) @@ -197,16 +208,19 @@ bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view) if (event.type == NSEventTypeLeftMouseDown || event.type == NSEventTypeRightMouseDown || event.type == NSEventTypeOtherMouseDown) { int button = (int)[event buttonNumber]; - if (button >= 0 && button < IM_ARRAYSIZE(io.MouseDown)) - io.MouseDown[button] = true; + if (button >= 0 && button < IM_ARRAYSIZE(g_MouseJustPressed)) + { + g_MouseJustPressed[button] = true; + g_MouseDown[button] = true; + } return io.WantCaptureMouse; } if (event.type == NSEventTypeLeftMouseUp || event.type == NSEventTypeRightMouseUp || event.type == NSEventTypeOtherMouseUp) { int button = (int)[event buttonNumber]; - if (button >= 0 && button < IM_ARRAYSIZE(io.MouseDown)) - io.MouseDown[button] = false; + if (button >= 0 && button < IM_ARRAYSIZE(g_MouseDown)) + g_MouseDown[button] = false; return io.WantCaptureMouse; } From 9c209d5a9070f8d2dfc3a311a15064daf2f81518 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 25 May 2020 11:42:20 +0200 Subject: [PATCH 08/13] Minor amend 9028088 (#3261) --- docs/CHANGELOG.txt | 1 + examples/imgui_impl_glfw.cpp | 2 +- examples/imgui_impl_osx.mm | 15 ++++++--------- imgui.h | 2 +- 4 files changed, 9 insertions(+), 11 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 78719031..3528c1e1 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -64,6 +64,7 @@ Other Changes: - Backends: Vulkan: Fixed error in if initial frame has no vertices. (#3177) - Backends: Vulkan: Fixed edge case where render callbacks wouldn't be called if the ImDrawData structure didn't have any vertices. (#2697) [@kudaba] +- Backends: OSX: Added workaround to avoid fast mouse clicks. (#3261, #1992, #2525) [@nburrus] - Examples: Apple: Fixed example_apple_metal and example_apple_opengl2 using imgui_impl_osx.mm not forwarding right and center mouse clicks. (#3260) [@nburrus] diff --git a/examples/imgui_impl_glfw.cpp b/examples/imgui_impl_glfw.cpp index c496232c..ef63c81f 100644 --- a/examples/imgui_impl_glfw.cpp +++ b/examples/imgui_impl_glfw.cpp @@ -68,7 +68,7 @@ enum GlfwClientApi static GLFWwindow* g_Window = NULL; // Main window static GlfwClientApi g_ClientApi = GlfwClientApi_Unknown; static double g_Time = 0.0; -static bool g_MouseJustPressed[5] = { false, false, false, false, false }; +static bool g_MouseJustPressed[ImGuiMouseButton_COUNT] = {}; static GLFWcursor* g_MouseCursors[ImGuiMouseCursor_COUNT] = {}; static bool g_InstalledCallbacks = false; diff --git a/examples/imgui_impl_osx.mm b/examples/imgui_impl_osx.mm index 221fa562..90501624 100644 --- a/examples/imgui_impl_osx.mm +++ b/examples/imgui_impl_osx.mm @@ -28,8 +28,8 @@ static CFAbsoluteTime g_Time = 0.0; static NSCursor* g_MouseCursors[ImGuiMouseCursor_COUNT] = {}; static bool g_MouseCursorHidden = false; -static bool g_MouseJustPressed[5] = { false, false, false, false, false }; -static bool g_MouseDown[5] = { false, false, false, false, false }; +static bool g_MouseJustPressed[ImGuiMouseButton_COUNT] = {}; +static bool g_MouseDown[ImGuiMouseButton_COUNT] = {}; // Undocumented methods for creating cursors. @interface NSCursor() @@ -126,9 +126,9 @@ void ImGui_ImplOSX_Shutdown() static void ImGui_ImplOSX_UpdateMouseCursorAndButtons() { + // Update buttons ImGuiIO& io = ImGui::GetIO(); - - for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown) && i < IM_ARRAYSIZE(g_MouseJustPressed); i++) + for (int i = 0; i < IM_ARRAYSIZE(io.MouseDown); i++) { // If a mouse press event came, always pass it as "mouse held this frame", so we don't miss click-release events that are shorter than 1 frame. io.MouseDown[i] = g_MouseJustPressed[i] || g_MouseDown[i]; @@ -208,11 +208,8 @@ bool ImGui_ImplOSX_HandleEvent(NSEvent* event, NSView* view) if (event.type == NSEventTypeLeftMouseDown || event.type == NSEventTypeRightMouseDown || event.type == NSEventTypeOtherMouseDown) { int button = (int)[event buttonNumber]; - if (button >= 0 && button < IM_ARRAYSIZE(g_MouseJustPressed)) - { - g_MouseJustPressed[button] = true; - g_MouseDown[button] = true; - } + if (button >= 0 && button < IM_ARRAYSIZE(g_MouseDown)) + g_MouseDown[button] = g_MouseJustPressed[button] = true; return io.WantCaptureMouse; } diff --git a/imgui.h b/imgui.h index 788f74c9..1a8d7a40 100644 --- a/imgui.h +++ b/imgui.h @@ -1488,7 +1488,7 @@ struct ImGuiIO //------------------------------------------------------------------ ImVec2 MousePos; // Mouse position, in pixels. Set to ImVec2(-FLT_MAX,-FLT_MAX) if mouse is unavailable (on another screen, etc.) - bool MouseDown[5]; // Mouse buttons: 0=left, 1=right, 2=middle + extras. ImGui itself mostly only uses left button (BeginPopupContext** are using right button). Others buttons allows us to track if the mouse is being used by your application + available to user as a convenience via IsMouse** API. + bool MouseDown[5]; // Mouse buttons: 0=left, 1=right, 2=middle + extras (ImGuiMouseButton_COUNT == 5). Dear ImGui mostly uses left and right buttons. Others buttons allows us to track if the mouse is being used by your application + available to user as a convenience via IsMouse** API. float MouseWheel; // Mouse wheel Vertical: 1 unit scrolls about 5 lines text. float MouseWheelH; // Mouse wheel Horizontal. Most users don't have a mouse with an horizontal wheel, may not be filled by all back-ends. bool KeyCtrl; // Keyboard modifier pressed: Control From a056603d8b8e2fd7f151844999cc077ac628097b Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 25 May 2020 12:05:11 +0200 Subject: [PATCH 09/13] Backends: Vulkan: Rename internal helper ImGui_ImplVulkanH_CreateWindow to ImGui_ImplVulkanH_CreateOrResizeWindow --- examples/example_glfw_vulkan/main.cpp | 11 ++++++----- examples/example_sdl_vulkan/main.cpp | 11 ++++++----- examples/imgui_impl_vulkan.cpp | 3 ++- examples/imgui_impl_vulkan.h | 2 +- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/examples/example_glfw_vulkan/main.cpp b/examples/example_glfw_vulkan/main.cpp index 910d4738..15ec2068 100644 --- a/examples/example_glfw_vulkan/main.cpp +++ b/examples/example_glfw_vulkan/main.cpp @@ -48,8 +48,9 @@ static int g_SwapChainResizeHeight = 0; static void check_vk_result(VkResult err) { - if (err == 0) return; - printf("VkResult %d\n", err); + if (err == 0) + return; + fprintf(stderr, "[vulkan] Error: VkResult = %d\n", err); if (err < 0) abort(); } @@ -58,7 +59,7 @@ static void check_vk_result(VkResult err) static VKAPI_ATTR VkBool32 VKAPI_CALL debug_report(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage, void* pUserData) { (void)flags; (void)object; (void)location; (void)messageCode; (void)pUserData; (void)pLayerPrefix; // Unused arguments - fprintf(stderr, "[vulkan] ObjectType: %i\nMessage: %s\n\n", objectType, pMessage); + fprintf(stderr, "[vulkan] Debug report from ObjectType: %i\nMessage: %s\n\n", objectType, pMessage); return VK_FALSE; } #endif // IMGUI_VULKAN_DEBUG_REPORT @@ -225,7 +226,7 @@ static void SetupVulkanWindow(ImGui_ImplVulkanH_Window* wd, VkSurfaceKHR surface // Create SwapChain, RenderPass, Framebuffer, etc. IM_ASSERT(g_MinImageCount >= 2); - ImGui_ImplVulkanH_CreateWindow(g_Instance, g_PhysicalDevice, g_Device, wd, g_QueueFamily, g_Allocator, width, height, g_MinImageCount); + ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, wd, g_QueueFamily, g_Allocator, width, height, g_MinImageCount); } static void CleanupVulkan() @@ -459,7 +460,7 @@ int main(int, char**) { g_SwapChainRebuild = false; ImGui_ImplVulkan_SetMinImageCount(g_MinImageCount); - ImGui_ImplVulkanH_CreateWindow(g_Instance, g_PhysicalDevice, g_Device, &g_MainWindowData, g_QueueFamily, g_Allocator, g_SwapChainResizeWidth, g_SwapChainResizeHeight, g_MinImageCount); + ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, &g_MainWindowData, g_QueueFamily, g_Allocator, g_SwapChainResizeWidth, g_SwapChainResizeHeight, g_MinImageCount); g_MainWindowData.FrameIndex = 0; } diff --git a/examples/example_sdl_vulkan/main.cpp b/examples/example_sdl_vulkan/main.cpp index c4e529e1..53975516 100644 --- a/examples/example_sdl_vulkan/main.cpp +++ b/examples/example_sdl_vulkan/main.cpp @@ -40,8 +40,9 @@ static int g_SwapChainResizeHeight = 0; static void check_vk_result(VkResult err) { - if (err == 0) return; - printf("VkResult %d\n", err); + if (err == 0) + return; + fprintf(stderr, "[vulkan] Error: VkResult = %d\n", err); if (err < 0) abort(); } @@ -50,7 +51,7 @@ static void check_vk_result(VkResult err) static VKAPI_ATTR VkBool32 VKAPI_CALL debug_report(VkDebugReportFlagsEXT flags, VkDebugReportObjectTypeEXT objectType, uint64_t object, size_t location, int32_t messageCode, const char* pLayerPrefix, const char* pMessage, void* pUserData) { (void)flags; (void)object; (void)location; (void)messageCode; (void)pUserData; (void)pLayerPrefix; // Unused arguments - fprintf(stderr, "[vulkan] ObjectType: %i\nMessage: %s\n\n", objectType, pMessage); + fprintf(stderr, "[vulkan] Debug report from ObjectType: %i\nMessage: %s\n\n", objectType, pMessage); return VK_FALSE; } #endif // IMGUI_VULKAN_DEBUG_REPORT @@ -217,7 +218,7 @@ static void SetupVulkanWindow(ImGui_ImplVulkanH_Window* wd, VkSurfaceKHR surface // Create SwapChain, RenderPass, Framebuffer, etc. IM_ASSERT(g_MinImageCount >= 2); - ImGui_ImplVulkanH_CreateWindow(g_Instance, g_PhysicalDevice, g_Device, wd, g_QueueFamily, g_Allocator, width, height, g_MinImageCount); + ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, wd, g_QueueFamily, g_Allocator, width, height, g_MinImageCount); } static void CleanupVulkan() @@ -456,7 +457,7 @@ int main(int, char**) { g_SwapChainRebuild = false; ImGui_ImplVulkan_SetMinImageCount(g_MinImageCount); - ImGui_ImplVulkanH_CreateWindow(g_Instance, g_PhysicalDevice, g_Device, &g_MainWindowData, g_QueueFamily, g_Allocator, g_SwapChainResizeWidth, g_SwapChainResizeHeight, g_MinImageCount); + ImGui_ImplVulkanH_CreateOrResizeWindow(g_Instance, g_PhysicalDevice, g_Device, &g_MainWindowData, g_QueueFamily, g_Allocator, g_SwapChainResizeWidth, g_SwapChainResizeHeight, g_MinImageCount); g_MainWindowData.FrameIndex = 0; } diff --git a/examples/imgui_impl_vulkan.cpp b/examples/imgui_impl_vulkan.cpp index 652476c7..93c3b404 100644 --- a/examples/imgui_impl_vulkan.cpp +++ b/examples/imgui_impl_vulkan.cpp @@ -1155,7 +1155,8 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, V } } -void ImGui_ImplVulkanH_CreateWindow(VkInstance instance, VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, uint32_t queue_family, const VkAllocationCallbacks* allocator, int width, int height, uint32_t min_image_count) +// Create or resize window +void ImGui_ImplVulkanH_CreateOrResizeWindow(VkInstance instance, VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wd, uint32_t queue_family, const VkAllocationCallbacks* allocator, int width, int height, uint32_t min_image_count) { (void)instance; ImGui_ImplVulkanH_CreateWindowSwapChain(physical_device, device, wd, allocator, width, height, min_image_count); diff --git a/examples/imgui_impl_vulkan.h b/examples/imgui_impl_vulkan.h index c85b5f28..0eb772e7 100644 --- a/examples/imgui_impl_vulkan.h +++ b/examples/imgui_impl_vulkan.h @@ -72,7 +72,7 @@ struct ImGui_ImplVulkanH_Frame; struct ImGui_ImplVulkanH_Window; // Helpers -IMGUI_IMPL_API void ImGui_ImplVulkanH_CreateWindow(VkInstance instance, VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wnd, uint32_t queue_family, const VkAllocationCallbacks* allocator, int w, int h, uint32_t min_image_count); +IMGUI_IMPL_API void ImGui_ImplVulkanH_CreateOrResizeWindow(VkInstance instance, VkPhysicalDevice physical_device, VkDevice device, ImGui_ImplVulkanH_Window* wnd, uint32_t queue_family, const VkAllocationCallbacks* allocator, int w, int h, uint32_t min_image_count); IMGUI_IMPL_API void ImGui_ImplVulkanH_DestroyWindow(VkInstance instance, VkDevice device, ImGui_ImplVulkanH_Window* wnd, const VkAllocationCallbacks* allocator); IMGUI_IMPL_API VkSurfaceFormatKHR ImGui_ImplVulkanH_SelectSurfaceFormat(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkFormat* request_formats, int request_formats_count, VkColorSpaceKHR request_color_space); IMGUI_IMPL_API VkPresentModeKHR ImGui_ImplVulkanH_SelectPresentMode(VkPhysicalDevice physical_device, VkSurfaceKHR surface, const VkPresentModeKHR* request_modes, int request_modes_count); From bb2529dd48f01d550afb00c3eff61a255e110282 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 25 May 2020 12:23:49 +0200 Subject: [PATCH 10/13] Backends: SDL: Report a zero display-size when window is minimized, consistent with other backends. --- docs/CHANGELOG.txt | 2 ++ examples/imgui_impl_sdl.cpp | 3 +++ 2 files changed, 5 insertions(+) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 3528c1e1..2ad7a085 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -58,6 +58,8 @@ Other Changes: drag source uses _SourceNoPreviewTooltip flags. (#3160) [@rokups] - Backends: Win32: Support for #define NOGDI, won't try to call GetDeviceCaps(). (#3137, #2327) - Backends: Win32: Fix _WIN32_WINNT < 0x0600 (MinGW defaults to 0x502 == Windows 2003). (#3183) +- Backends: SDL: Report a zero display-size when window is minimized, consistent with other backends, + making more render/clipping code use an early out path. - Backends: OpenGL: Fixed handling of GL 4.5+ glClipControl(GL_UPPER_LEFT) by inverting the projection matrix top and bottom values. (#3143, #3146) [@u3shit] - Backends: OpenGL: On OSX, if unspecified by app, made default GLSL version 150. (#3199) [@albertvaka] diff --git a/examples/imgui_impl_sdl.cpp b/examples/imgui_impl_sdl.cpp index 9fd2cc48..695ac810 100644 --- a/examples/imgui_impl_sdl.cpp +++ b/examples/imgui_impl_sdl.cpp @@ -17,6 +17,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2020-05-25: Misc: Report a zero display-size when window is minimized, to be consistent with other backends. // 2020-02-20: Inputs: Fixed mapping for ImGuiKey_KeyPadEnter (using SDL_SCANCODE_KP_ENTER instead of SDL_SCANCODE_RETURN2). // 2019-12-17: Inputs: On Wayland, use SDL_GetMouseState (because there is no global mouse state). // 2019-12-05: Inputs: Added support for ImGuiMouseCursor_NotAllowed mouse cursor. @@ -348,6 +349,8 @@ void ImGui_ImplSDL2_NewFrame(SDL_Window* window) int w, h; int display_w, display_h; SDL_GetWindowSize(window, &w, &h); + if (SDL_GetWindowFlags(window) & SDL_WINDOW_MINIMIZED) + w = h = 0; SDL_GL_GetDrawableSize(window, &display_w, &display_h); io.DisplaySize = ImVec2((float)w, (float)h); if (w > 0 && h > 0) From 6b688561aa8f2b83a591c93c7d75d07a7beb24dd Mon Sep 17 00:00:00 2001 From: Rokas Kupstys Date: Mon, 25 May 2020 13:25:22 +0300 Subject: [PATCH 11/13] CI: Test building without C++ runtime on GCC/Clang. --- .github/workflows/build.yml | 15 +++++++++++++++ docs/CHANGELOG.txt | 5 ++++- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 03641749..8edef47b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -288,6 +288,14 @@ jobs: echo '#include "examples/example_null/main.cpp"' >> example_single_file.cpp g++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp + - name: Build example_null (without c++ runtime, Clang) + run: | + echo '#define IMGUI_IMPLEMENTATION' > example_single_file.cpp + echo '#define IMGUI_DISABLE_DEMO_WINDOWS' >> example_single_file.cpp + echo '#include "misc/single_file/imgui_single_file.h"' >> example_single_file.cpp + echo '#include "examples/example_null/main.cpp"' >> example_single_file.cpp + clang++ -I. -Wall -Wformat -nodefaultlibs -fno-rtti -fno-exceptions -fno-threadsafe-statics -lc -lm -o example_single_file example_single_file.cpp + - name: Build example_glfw_opengl2 run: make -C examples/example_glfw_opengl2 @@ -324,6 +332,13 @@ jobs: echo '#include "examples/example_null/main.cpp"' >> example_single_file.cpp clang++ -I. -Wall -Wformat -o example_single_file example_single_file.cpp + - name: Build example_null (without c++ runtime) + run: | + echo '#define IMGUI_IMPLEMENTATION' > example_single_file.cpp + echo '#include "misc/single_file/imgui_single_file.h"' >> example_single_file.cpp + echo '#include "examples/example_null/main.cpp"' >> example_single_file.cpp + clang++ -I. -Wall -Wformat -nodefaultlibs -fno-rtti -fno-exceptions -fno-threadsafe-statics -lc -lm -o example_single_file example_single_file.cpp + - name: Build example_glfw_opengl2 run: make -C examples/example_glfw_opengl2 diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 2ad7a085..da94c890 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -56,6 +56,9 @@ Other Changes: BeginMenu()/EndMenu() or BeginPopup/EndPopup(). (#3223, #1207) [@rokups] - Drag and Drop: Fixed unintended fallback "..." tooltip display during drag operation when drag source uses _SourceNoPreviewTooltip flags. (#3160) [@rokups] +- CI: Added CI test to verify we're never accidentally dragging libstdc++ (on some compiler setups, + static constructors for non-pod data seems to drag in libstdc++ due to thread-safety concerns). + Fixed a static contructor which led to this dependency on some compiler setups (unclear which). - Backends: Win32: Support for #define NOGDI, won't try to call GetDeviceCaps(). (#3137, #2327) - Backends: Win32: Fix _WIN32_WINNT < 0x0600 (MinGW defaults to 0x502 == Windows 2003). (#3183) - Backends: SDL: Report a zero display-size when window is minimized, consistent with other backends, @@ -67,7 +70,7 @@ Other Changes: - Backends: Vulkan: Fixed edge case where render callbacks wouldn't be called if the ImDrawData structure didn't have any vertices. (#2697) [@kudaba] - Backends: OSX: Added workaround to avoid fast mouse clicks. (#3261, #1992, #2525) [@nburrus] -- Examples: Apple: Fixed example_apple_metal and example_apple_opengl2 using imgui_impl_osx.mm +- Examples: Apple: Fixed example_apple_metal and example_apple_opengl2 using imgui_impl_osx.mm not forwarding right and center mouse clicks. (#3260) [@nburrus] From a06eb833590478276a3c186a7b66a9cf5082ebf4 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 25 May 2020 15:31:33 +0200 Subject: [PATCH 12/13] Examples: GLFW+Vulkan, SDL+Vulkan: Fix for handling of minimized windows. (#3259) --- docs/CHANGELOG.txt | 1 + examples/example_glfw_vulkan/main.cpp | 20 ++++++++++++-------- examples/example_sdl_vulkan/main.cpp | 23 +++++++++++++++-------- examples/imgui_impl_vulkan.cpp | 1 + 4 files changed, 29 insertions(+), 16 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index da94c890..dff65283 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -70,6 +70,7 @@ Other Changes: - Backends: Vulkan: Fixed edge case where render callbacks wouldn't be called if the ImDrawData structure didn't have any vertices. (#2697) [@kudaba] - Backends: OSX: Added workaround to avoid fast mouse clicks. (#3261, #1992, #2525) [@nburrus] +- Examples: GLFW+Vulkan, SDL+Vulkan: Fix for handling of minimized windows. (#3259) - Examples: Apple: Fixed example_apple_metal and example_apple_opengl2 using imgui_impl_osx.mm not forwarding right and center mouse clicks. (#3260) [@nburrus] diff --git a/examples/example_glfw_vulkan/main.cpp b/examples/example_glfw_vulkan/main.cpp index 15ec2068..3ce1984a 100644 --- a/examples/example_glfw_vulkan/main.cpp +++ b/examples/example_glfw_vulkan/main.cpp @@ -248,7 +248,7 @@ static void CleanupVulkanWindow() ImGui_ImplVulkanH_DestroyWindow(g_Instance, g_Device, &g_MainWindowData, g_Allocator); } -static void FrameRender(ImGui_ImplVulkanH_Window* wd) +static void FrameRender(ImGui_ImplVulkanH_Window* wd, ImDrawData* draw_data) { VkResult err; @@ -286,8 +286,8 @@ static void FrameRender(ImGui_ImplVulkanH_Window* wd) vkCmdBeginRenderPass(fd->CommandBuffer, &info, VK_SUBPASS_CONTENTS_INLINE); } - // Record Imgui Draw Data and draw funcs into command buffer - ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), fd->CommandBuffer); + // Record dear imgui primitives into command buffer + ImGui_ImplVulkan_RenderDrawData(draw_data, fd->CommandBuffer); // Submit command buffer vkCmdEndRenderPass(fd->CommandBuffer); @@ -456,7 +456,8 @@ int main(int, char**) // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. glfwPollEvents(); - if (g_SwapChainRebuild) + // Resize swap chain? + if (g_SwapChainRebuild && g_SwapChainResizeWidth > 0 && g_SwapChainResizeHeight > 0) { g_SwapChainRebuild = false; ImGui_ImplVulkan_SetMinImageCount(g_MinImageCount); @@ -508,10 +509,13 @@ int main(int, char**) // Rendering ImGui::Render(); - memcpy(&wd->ClearValue.color.float32[0], &clear_color, 4 * sizeof(float)); - FrameRender(wd); - - FramePresent(wd); + ImDrawData* draw_data = ImGui::GetDrawData(); + const bool is_minimized = (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f); + if (!is_minimized) + { + FrameRender(wd, draw_data); + FramePresent(wd); + } } // Cleanup diff --git a/examples/example_sdl_vulkan/main.cpp b/examples/example_sdl_vulkan/main.cpp index 53975516..9eaea945 100644 --- a/examples/example_sdl_vulkan/main.cpp +++ b/examples/example_sdl_vulkan/main.cpp @@ -240,7 +240,7 @@ static void CleanupVulkanWindow() ImGui_ImplVulkanH_DestroyWindow(g_Instance, g_Device, &g_MainWindowData, g_Allocator); } -static void FrameRender(ImGui_ImplVulkanH_Window* wd) +static void FrameRender(ImGui_ImplVulkanH_Window* wd, ImDrawData* draw_data) { VkResult err; @@ -278,8 +278,8 @@ static void FrameRender(ImGui_ImplVulkanH_Window* wd) vkCmdBeginRenderPass(fd->CommandBuffer, &info, VK_SUBPASS_CONTENTS_INLINE); } - // Record Imgui Draw Data and draw funcs into command buffer - ImGui_ImplVulkan_RenderDrawData(ImGui::GetDrawData(), fd->CommandBuffer); + // Record dear imgui primitives into command buffer + ImGui_ImplVulkan_RenderDrawData(draw_data, fd->CommandBuffer); // Submit command buffer vkCmdEndRenderPass(fd->CommandBuffer); @@ -447,13 +447,17 @@ int main(int, char**) done = true; if (event.type == SDL_WINDOWEVENT && event.window.event == SDL_WINDOWEVENT_RESIZED && event.window.windowID == SDL_GetWindowID(window)) { + // Note: your own application may rely on SDL_WINDOWEVENT_MINIMIZED/SDL_WINDOWEVENT_RESTORED to skip updating all-together. + // Here ImGui_ImplSDL2_NewFrame() will set io.DisplaySize to zero which will disable rendering but let application run. + // Please note that you can't Present into a minimized window. g_SwapChainResizeWidth = (int)event.window.data1; g_SwapChainResizeHeight = (int)event.window.data2; g_SwapChainRebuild = true; } } - if (g_SwapChainRebuild) + // Resize swap chain? + if (g_SwapChainRebuild && g_SwapChainResizeWidth > 0 && g_SwapChainResizeHeight > 0) { g_SwapChainRebuild = false; ImGui_ImplVulkan_SetMinImageCount(g_MinImageCount); @@ -505,10 +509,13 @@ int main(int, char**) // Rendering ImGui::Render(); - memcpy(&wd->ClearValue.color.float32[0], &clear_color, 4 * sizeof(float)); - FrameRender(wd); - - FramePresent(wd); + ImDrawData* draw_data = ImGui::GetDrawData(); + const bool is_minimized = (draw_data->DisplaySize.x <= 0.0f || draw_data->DisplaySize.y <= 0.0f); + if (!is_minimized) + { + FrameRender(wd, draw_data); + FramePresent(wd); + } } // Cleanup diff --git a/examples/imgui_impl_vulkan.cpp b/examples/imgui_impl_vulkan.cpp index 93c3b404..c65b2db0 100644 --- a/examples/imgui_impl_vulkan.cpp +++ b/examples/imgui_impl_vulkan.cpp @@ -999,6 +999,7 @@ void ImGui_ImplVulkanH_CreateWindowSwapChain(VkPhysicalDevice physical_device, V { VkResult err; VkSwapchainKHR old_swapchain = wd->Swapchain; + wd->Swapchain = NULL; err = vkDeviceWaitIdle(device); check_vk_result(err); From 5ddf60d8ce57ad119833003f9afd777c0b1a3a74 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 25 May 2020 18:28:25 +0200 Subject: [PATCH 13/13] Commit to facilitate branches merges --- imgui.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 97b15411..68b50827 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -10158,8 +10158,8 @@ void ImGui::ShowMetricsWindow(bool* p_open) // Debugging enums enum { WRT_OuterRect, WRT_OuterRectClipped, WRT_InnerRect, WRT_InnerClipRect, WRT_WorkRect, WRT_Content, WRT_ContentRegionRect, WRT_Count }; // Windows Rect Type const char* wrt_rects_names[WRT_Count] = { "OuterRect", "OuterRectClipped", "InnerRect", "InnerClipRect", "WorkRect", "Content", "ContentRegionRect" }; - enum { TRT_OuterRect, TRT_WorkRect, TRT_HostClipRect, TRT_InnerClipRect, TRT_BackgroundClipRect, TRT_ColumnsRect, TRT_ColumnsClipRect, TRT_ColumnsContentHeadersUsed, TRT_ColumnsContentHeadersDesired, TRT_ColumnsContentRowsFrozen, TRT_ColumnsContentRowsUnfrozen, TRT_Count }; // Tables Rect Type - const char* trt_rects_names[TRT_Count] = { "OuterRect", "WorkRect", "HostClipRect", "InnerClipRect", "BackgroundClipRect", "ColumnsRect", "ColumnsClipRect", "ColumnsContentHeadersUsed", "ColumnsContentHeadersDesired", "ColumnsContentRowsFrozen", "ColumnsContentRowsUnfrozen" }; + enum { TRT_OuterRect, TRT_WorkRect, TRT_HostClipRect, TRT_InnerClipRect, TRT_BackgroundClipRect, TRT_ColumnsRect, TRT_ColumnsClipRect, TRT_ColumnsContentHeadersUsed, TRT_ColumnsContentHeadersIdeal, TRT_ColumnsContentRowsFrozen, TRT_ColumnsContentRowsUnfrozen, TRT_Count }; // Tables Rect Type + const char* trt_rects_names[TRT_Count] = { "OuterRect", "WorkRect", "HostClipRect", "InnerClipRect", "BackgroundClipRect", "ColumnsRect", "ColumnsClipRect", "ColumnsContentHeadersUsed", "ColumnsContentHeadersIdeal", "ColumnsContentRowsFrozen", "ColumnsContentRowsUnfrozen" }; // State static bool show_windows_rects = false; @@ -10433,7 +10433,6 @@ void ImGui::ShowMetricsWindow(bool* p_open) } }; - // Tools if (ImGui::TreeNode("Tools")) { @@ -10504,7 +10503,7 @@ void ImGui::ShowMetricsWindow(bool* p_open) Funcs::NodeTable(g.Tables.GetByIndex(n)); ImGui::TreePop(); } -#endif // #define IMGUI_HAS_TABLE +#endif // #ifdef IMGUI_HAS_TABLE // Details for Docking #ifdef IMGUI_HAS_DOCK @@ -10512,7 +10511,7 @@ void ImGui::ShowMetricsWindow(bool* p_open) { ImGui::TreePop(); } -#endif // #define IMGUI_HAS_DOCK +#endif // #ifdef IMGUI_HAS_DOCK // Settings if (ImGui::TreeNode("Settings")) @@ -10548,10 +10547,10 @@ void ImGui::ShowMetricsWindow(bool* p_open) Funcs::NodeTableSettings(settings); ImGui::TreePop(); } -#endif +#endif // #ifdef IMGUI_HAS_TABLE #ifdef IMGUI_HAS_DOCK -#endif +#endif // #ifdef IMGUI_HAS_DOCK if (ImGui::TreeNode("SettingsIniData", "Settings unpacked data (.ini): %d bytes", g.SettingsIniData.size())) { @@ -10617,14 +10616,14 @@ void ImGui::ShowMetricsWindow(bool* p_open) ImGuiTable* table = g.Tables.GetByIndex(table_n); } } -#endif // #define IMGUI_HAS_TABLE +#endif // #ifdef IMGUI_HAS_TABLE #ifdef IMGUI_HAS_DOCK // Overlay: Display Docking info if (show_docking_nodes && g.IO.KeyCtrl) { } -#endif // #define IMGUI_HAS_DOCK +#endif // #ifdef IMGUI_HAS_DOCK ImGui::End(); }