Browse Source

Backends: SDL: Fix multi-viewport dragging issue with SDL on some systems. (#5012)

Rokas Kupstys 3 years ago
parent
commit
f337378066
2 changed files with 17 additions and 6 deletions
  1. 16 6
      backends/imgui_impl_sdl.cpp
  2. 1 0
      docs/CHANGELOG.txt

+ 16 - 6
backends/imgui_impl_sdl.cpp

@@ -96,6 +96,7 @@ struct ImGui_ImplSDL2_Data
     Uint32          MouseWindowID;
     Uint32          MouseWindowID;
     int             MouseButtonsDown;
     int             MouseButtonsDown;
     SDL_Cursor*     MouseCursors[ImGuiMouseCursor_COUNT];
     SDL_Cursor*     MouseCursors[ImGuiMouseCursor_COUNT];
+    int             PendingMouseLeaveFrame;
     char*           ClipboardTextData;
     char*           ClipboardTextData;
     bool            MouseCanUseGlobalState;
     bool            MouseCanUseGlobalState;
     bool            UseVulkan;
     bool            UseVulkan;
@@ -315,16 +316,19 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event)
         }
         }
         case SDL_WINDOWEVENT:
         case SDL_WINDOWEVENT:
         {
         {
-            // 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.
+            // - 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;
             Uint8 window_event = event->window.event;
             if (window_event == SDL_WINDOWEVENT_ENTER)
             if (window_event == SDL_WINDOWEVENT_ENTER)
-                bd->MouseWindowID = event->window.windowID;
-            if (window_event == SDL_WINDOWEVENT_LEAVE)
             {
             {
-                bd->MouseWindowID = 0;
-                io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
+                bd->MouseWindowID = event->window.windowID;
+                bd->PendingMouseLeaveFrame = 0;
             }
             }
+            if (window_event == SDL_WINDOWEVENT_LEAVE)
+                bd->PendingMouseLeaveFrame = ImGui::GetFrameCount() + 1;
             if (window_event == SDL_WINDOWEVENT_FOCUS_GAINED)
             if (window_event == SDL_WINDOWEVENT_FOCUS_GAINED)
                 io.AddFocusEvent(true);
                 io.AddFocusEvent(true);
             else if (window_event == SDL_WINDOWEVENT_FOCUS_LOST)
             else if (window_event == SDL_WINDOWEVENT_FOCUS_LOST)
@@ -665,6 +669,12 @@ void ImGui_ImplSDL2_NewFrame()
     io.DeltaTime = bd->Time > 0 ? (float)((double)(current_time - bd->Time) / frequency) : (float)(1.0f / 60.0f);
     io.DeltaTime = bd->Time > 0 ? (float)((double)(current_time - bd->Time) / frequency) : (float)(1.0f / 60.0f);
     bd->Time = current_time;
     bd->Time = current_time;
 
 
+    if (bd->PendingMouseLeaveFrame && bd->PendingMouseLeaveFrame == ImGui::GetFrameCount())
+    {
+        bd->MouseWindowID = 0;
+        io.AddMousePosEvent(-FLT_MAX, -FLT_MAX);
+    }
+
     ImGui_ImplSDL2_UpdateMouseData();
     ImGui_ImplSDL2_UpdateMouseData();
     ImGui_ImplSDL2_UpdateMouseCursor();
     ImGui_ImplSDL2_UpdateMouseCursor();
 
 

+ 1 - 0
docs/CHANGELOG.txt

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