Skip to content

Commit f337378

Browse files
rokupsocornut
authored andcommitted
Backends: SDL: Fix multi-viewport dragging issue with SDL on some systems. (ocornut#5012)
1 parent 8639a2f commit f337378

File tree

2 files changed

+17
-6
lines changed

2 files changed

+17
-6
lines changed

backends/imgui_impl_sdl.cpp

+16-6
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ struct ImGui_ImplSDL2_Data
9696
Uint32 MouseWindowID;
9797
int MouseButtonsDown;
9898
SDL_Cursor* MouseCursors[ImGuiMouseCursor_COUNT];
99+
int PendingMouseLeaveFrame;
99100
char* ClipboardTextData;
100101
bool MouseCanUseGlobalState;
101102
bool UseVulkan;
@@ -315,16 +316,19 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
315316
}
316317
case SDL_WINDOWEVENT:
317318
{
318-
// 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.
319-
// However we won't get a correct LEAVE event for a captured window.
319+
// - 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.
320+
// - However we won't get a correct LEAVE event for a captured window.
321+
// - In some cases, when detaching a window from main viewport SDL may send SDL_WINDOWEVENT_ENTER one frame too late,
322+
// causing SDL_WINDOWEVENT_LEAVE on previous frame to interrupt drag operation by clear mouse position. This is why
323+
// we delay process the SDL_WINDOWEVENT_LEAVE events by one frame. See issue #5012 for details.
320324
Uint8 window_event = event->window.event;
321325
if (window_event == SDL_WINDOWEVENT_ENTER)
322-
bd->MouseWindowID = event->window.windowID;
323-
if (window_event == SDL_WINDOWEVENT_LEAVE)
324326
{
325-
bd->MouseWindowID = 0;
326-
io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
327+
bd->MouseWindowID = event->window.windowID;
328+
bd->PendingMouseLeaveFrame = 0;
327329
}
330+
if (window_event == SDL_WINDOWEVENT_LEAVE)
331+
bd->PendingMouseLeaveFrame = ImGui::GetFrameCount() + 1;
328332
if (window_event == SDL_WINDOWEVENT_FOCUS_GAINED)
329333
io.AddFocusEvent(true);
330334
else if (window_event == SDL_WINDOWEVENT_FOCUS_LOST)
@@ -665,6 +669,12 @@ void ImGui_ImplSDL2_NewFrame()
665669
io.DeltaTime = bd->Time > 0 ? (float)((double)(current_time - bd->Time) / frequency) : (float)(1.0f / 60.0f);
666670
bd->Time = current_time;
667671

672+
if (bd->PendingMouseLeaveFrame && bd->PendingMouseLeaveFrame == ImGui::GetFrameCount())
673+
{
674+
bd->MouseWindowID = 0;
675+
io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
676+
}
677+
668678
ImGui_ImplSDL2_UpdateMouseData();
669679
ImGui_ImplSDL2_UpdateMouseCursor();
670680

docs/CHANGELOG.txt

+1
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ Docking+Viewports Branch:
134134

135135
- Docking: Fixed floating docked nodes not being clamped into viewport workrect to stay reachable
136136
when g.ConfigWindowsMoveFromTitleBarOnly is set and multi-viewports are disabled. (#5044)
137+
- Backends: SDL: Fixed dragging out main viewport broken on some SDL setups. (#5012) [@rokups]
137138
- Viewports: Fixed translating a host viewport from briefly altering the size of AlwaysAutoResize windows. (#5057)
138139
- Viewports: Fixed main viewport size not matching ImDrawData::DisplaySize for one frame during resize
139140
when multi-viewports are disabled. (#4900)

0 commit comments

Comments
 (0)