From c5f67218bff70ea6b885f7a52687acf9c414ba67 Mon Sep 17 00:00:00 2001 From: Rokas Kupstys Date: Fri, 25 Feb 2022 17:18:40 +0100 Subject: [PATCH] Backends: SDL: Fix multi-viewport dragging issue with SDL on some systems. (v2 for master, using bd->MouseButtonsDown == 0) (#5012, #5082) # Conflicts: # backends/imgui_impl_sdl.cpp # docs/CHANGELOG.txt --- backends/imgui_impl_sdl.cpp | 24 ++++++++++++++++++++---- docs/CHANGELOG.txt | 1 + 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/backends/imgui_impl_sdl.cpp b/backends/imgui_impl_sdl.cpp index b314dbb90..bed000be9 100644 --- a/backends/imgui_impl_sdl.cpp +++ b/backends/imgui_impl_sdl.cpp @@ -18,9 +18,10 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2022-03-22: Inputs: Fix mouse position issues when dragging outside of boundaries. SDL_CaptureMouse() erroneously still gives out LEAVE events when hovering OS decorations. // 2022-03-22: Inputs: Added support for extra mouse buttons (SDL_BUTTON_X1/SDL_BUTTON_X2). // 2022-02-04: Added SDL_Renderer* parameter to ImGui_ImplSDL2_InitForSDLRenderer(), so we can use SDL_GetRendererOutputSize() instead of SDL_GL_GetDrawableSize() when bound to a SDL_Renderer. -// 2022-01-26: Inputs: replaced short-lived io.AddKeyModsEvent() (added two weeks ago)with io.AddKeyEvent() using ImGuiKey_ModXXX flags. Sorry for the confusion. +// 2022-01-26: Inputs: replaced short-lived io.AddKeyModsEvent() (added two weeks ago) with io.AddKeyEvent() using ImGuiKey_ModXXX flags. Sorry for the confusion. // 2021-01-20: Inputs: calling new io.AddKeyAnalogEvent() for gamepad support, instead of writing directly to io.NavInputs[]. // 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+). // 2022-01-17: Inputs: always update key mods next and before key event (not in NewFrame) to fix input queue with very low framerates. @@ -85,6 +86,7 @@ struct ImGui_ImplSDL2_Data Uint64 Time; int MouseButtonsDown; SDL_Cursor* MouseCursors[ImGuiMouseCursor_COUNT]; + int PendingMouseLeaveFrame; char* ClipboardTextData; bool MouseCanUseGlobalState; @@ -292,9 +294,17 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event) } case SDL_WINDOWEVENT: { - if (event->window.event == SDL_WINDOWEVENT_LEAVE) - io.AddMousePosEvent(-FLT_MAX, -FLT_MAX); - if (event->window.event == SDL_WINDOWEVENT_FOCUS_GAINED) + // - When capturing mouse, SDL will send a bunch of conflicting LEAVE/ENTER event on every mouse move, but the final ENTER tends to be right. + // - However we won't get a correct LEAVE event for a captured window. + // - In some cases, when detaching a window from main viewport SDL may send SDL_WINDOWEVENT_ENTER one frame too late, + // causing SDL_WINDOWEVENT_LEAVE on previous frame to interrupt drag operation by clear mouse position. This is why + // we delay process the SDL_WINDOWEVENT_LEAVE events by one frame. See issue #5012 for details. + Uint8 window_event = event->window.event; + if (window_event == SDL_WINDOWEVENT_ENTER) + bd->PendingMouseLeaveFrame = 0; + if (window_event == SDL_WINDOWEVENT_LEAVE) + bd->PendingMouseLeaveFrame = ImGui::GetFrameCount() + 1; + if (window_event == SDL_WINDOWEVENT_FOCUS_GAINED) io.AddFocusEvent(true); else if (event->window.event == SDL_WINDOWEVENT_FOCUS_LOST) io.AddFocusEvent(false); @@ -540,6 +550,12 @@ void ImGui_ImplSDL2_NewFrame() io.DeltaTime = bd->Time > 0 ? (float)((double)(current_time - bd->Time) / frequency) : (float)(1.0f / 60.0f); bd->Time = current_time; + if (bd->PendingMouseLeaveFrame && bd->PendingMouseLeaveFrame >= ImGui::GetFrameCount() && bd->MouseButtonsDown == 0) + { + io.AddMousePosEvent(-FLT_MAX, -FLT_MAX); + bd->PendingMouseLeaveFrame = 0; + } + ImGui_ImplSDL2_UpdateMouseData(); ImGui_ImplSDL2_UpdateMouseCursor(); diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 54d22d7fc..29b6bac7c 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -69,6 +69,7 @@ Other Changes: - Misc: Updated stb_rect_pack.h from 1.00 to 1.01 (minor). (#5075) - Misc: binary_to_compressed_c tool: Added -nostatic option. (#5021) [@podsvirov] - ImVector: Fixed erase() with empty range. (#5009) [@thedmd] +- Backends: SDL: Fixed dragging out viewport broken on some SDL setups. (#5012) [@rokups] - Backends: SDL: Added support for extra mouse buttons (SDL_BUTTON_X1/SDL_BUTTON_X2). (#5125) [@sgiurgiu] - Examples: Emscripten: Fix building for latest Emscripten specs. (#3632)