|
18 | 18 |
|
19 | 19 | // CHANGELOG
|
20 | 20 | // (minor and older changes stripped away, please see git history for details)
|
| 21 | +// 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. |
21 | 22 | // 2022-03-22: Inputs: Added support for extra mouse buttons (SDL_BUTTON_X1/SDL_BUTTON_X2).
|
22 | 23 | // 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.
|
23 |
| -// 2022-01-26: Inputs: replaced short-lived io.AddKeyModsEvent() (added two weeks ago)with io.AddKeyEvent() using ImGuiKey_ModXXX flags. Sorry for the confusion. |
| 24 | +// 2022-01-26: Inputs: replaced short-lived io.AddKeyModsEvent() (added two weeks ago) with io.AddKeyEvent() using ImGuiKey_ModXXX flags. Sorry for the confusion. |
24 | 25 | // 2021-01-20: Inputs: calling new io.AddKeyAnalogEvent() for gamepad support, instead of writing directly to io.NavInputs[].
|
25 | 26 | // 2022-01-17: Inputs: calling new io.AddMousePosEvent(), io.AddMouseButtonEvent(), io.AddMouseWheelEvent() API (1.87+).
|
26 | 27 | // 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
|
85 | 86 | Uint64 Time;
|
86 | 87 | int MouseButtonsDown;
|
87 | 88 | SDL_Cursor* MouseCursors[ImGuiMouseCursor_COUNT];
|
| 89 | + int PendingMouseLeaveFrame; |
88 | 90 | char* ClipboardTextData;
|
89 | 91 | bool MouseCanUseGlobalState;
|
90 | 92 |
|
@@ -292,9 +294,17 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
|
292 | 294 | }
|
293 | 295 | case SDL_WINDOWEVENT:
|
294 | 296 | {
|
295 |
| - if (event->window.event == SDL_WINDOWEVENT_LEAVE) |
296 |
| - io.AddMousePosEvent(-FLT_MAX, -FLT_MAX); |
297 |
| - if (event->window.event == SDL_WINDOWEVENT_FOCUS_GAINED) |
| 297 | + // - 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. |
| 298 | + // - However we won't get a correct LEAVE event for a captured window. |
| 299 | + // - In some cases, when detaching a window from main viewport SDL may send SDL_WINDOWEVENT_ENTER one frame too late, |
| 300 | + // causing SDL_WINDOWEVENT_LEAVE on previous frame to interrupt drag operation by clear mouse position. This is why |
| 301 | + // we delay process the SDL_WINDOWEVENT_LEAVE events by one frame. See issue #5012 for details. |
| 302 | + Uint8 window_event = event->window.event; |
| 303 | + if (window_event == SDL_WINDOWEVENT_ENTER) |
| 304 | + bd->PendingMouseLeaveFrame = 0; |
| 305 | + if (window_event == SDL_WINDOWEVENT_LEAVE) |
| 306 | + bd->PendingMouseLeaveFrame = ImGui::GetFrameCount() + 1; |
| 307 | + if (window_event == SDL_WINDOWEVENT_FOCUS_GAINED) |
298 | 308 | io.AddFocusEvent(true);
|
299 | 309 | else if (event->window.event == SDL_WINDOWEVENT_FOCUS_LOST)
|
300 | 310 | io.AddFocusEvent(false);
|
@@ -540,6 +550,12 @@ void ImGui_ImplSDL2_NewFrame()
|
540 | 550 | io.DeltaTime = bd->Time > 0 ? (float)((double)(current_time - bd->Time) / frequency) : (float)(1.0f / 60.0f);
|
541 | 551 | bd->Time = current_time;
|
542 | 552 |
|
| 553 | + if (bd->PendingMouseLeaveFrame && bd->PendingMouseLeaveFrame >= ImGui::GetFrameCount() && bd->MouseButtonsDown == 0) |
| 554 | + { |
| 555 | + io.AddMousePosEvent(-FLT_MAX, -FLT_MAX); |
| 556 | + bd->PendingMouseLeaveFrame = 0; |
| 557 | + } |
| 558 | + |
543 | 559 | ImGui_ImplSDL2_UpdateMouseData();
|
544 | 560 | ImGui_ImplSDL2_UpdateMouseCursor();
|
545 | 561 |
|
|
0 commit comments