Browse Source

Windows: Fix unintended window size changes when resizing windows close to main viewport edges.

Rokas Kupstys 5 years ago
parent
commit
6b0cf2e6ae
2 changed files with 14 additions and 6 deletions
  1. 7 6
      docs/CHANGELOG.txt
  2. 7 0
      imgui.cpp

+ 7 - 6
docs/CHANGELOG.txt

@@ -55,17 +55,18 @@ Other Changes:
   Set to 0.0f (default) to always make a close button appear on hover (same as Chrome, VS).
   Set to 0.0f (default) to always make a close button appear on hover (same as Chrome, VS).
   Set to FLT_MAX to only display a close button when selected (merely hovering is not enough).
   Set to FLT_MAX to only display a close button when selected (merely hovering is not enough).
   Set to an intermediary value to toggle behavior based on width (same as Firefox).
   Set to an intermediary value to toggle behavior based on width (same as Firefox).
-- Tab: Added a ImGuiTabItemFlags_NoTooltip flag to disable the tooltip for individual tab item 
+- Tab: Added a ImGuiTabItemFlags_NoTooltip flag to disable the tooltip for individual tab item
   (vs ImGuiTabBarFlags_NoTooltip for entire tab bar). [@Xipiryon]
   (vs ImGuiTabBarFlags_NoTooltip for entire tab bar). [@Xipiryon]
-- Popups: All functions capable of opening popups (OpenPopup*, BeginPopupContext*) now take a new 
-  ImGuiPopupFlags sets of flags instead of a mouse button index. The API is automatically backward 
+- Windows: Fix unintended feedback loops when resizing windows close to main viewport edges. [@rokups]
+- Popups: All functions capable of opening popups (OpenPopup*, BeginPopupContext*) now take a new
+  ImGuiPopupFlags sets of flags instead of a mouse button index. The API is automatically backward
   compatible as ImGuiPopupFlags is guaranteed to hold mouse button index in the lower bits.
   compatible as ImGuiPopupFlags is guaranteed to hold mouse button index in the lower bits.
 - Popups: Added ImGuiPopupFlags_NoOpenOverExistingPopup for OpenPopup*/BeginPopupContext* functions
 - Popups: Added ImGuiPopupFlags_NoOpenOverExistingPopup for OpenPopup*/BeginPopupContext* functions
   to first test for the presence of another popup at the same level.
   to first test for the presence of another popup at the same level.
 - Popups: Added ImGuiPopupFlags_NoOpenOverItems for BeginPopupContextWindow() - similar to testing
 - Popups: Added ImGuiPopupFlags_NoOpenOverItems for BeginPopupContextWindow() - similar to testing
   for !IsAnyItemHovered() prior to doing an OpenPopup.
   for !IsAnyItemHovered() prior to doing an OpenPopup.
-- Popups: Added ImGuiPopupFlags_AnyPopupId and ImGuiPopupFlags_AnyPopupLevel flags for IsPopupOpen(), 
-  allowing to check if any popup is open at the current level, if a given popup is open at any popup 
+- Popups: Added ImGuiPopupFlags_AnyPopupId and ImGuiPopupFlags_AnyPopupLevel flags for IsPopupOpen(),
+  allowing to check if any popup is open at the current level, if a given popup is open at any popup
   level, if any popup is open at all.
   level, if any popup is open at all.
 - Popups: Fix an edge case where programatically closing a popup while clicking on its empty space
 - Popups: Fix an edge case where programatically closing a popup while clicking on its empty space
   would attempt to focus it and close other popups. (#2880)
   would attempt to focus it and close other popups. (#2880)
@@ -73,7 +74,7 @@ Other Changes:
 - Popups: Clarified some of the comments and function prototypes.
 - Popups: Clarified some of the comments and function prototypes.
 - Modals: BeginPopupModal() doesn't set the ImGuiWindowFlags_NoSavedSettings flag anymore, and will
 - Modals: BeginPopupModal() doesn't set the ImGuiWindowFlags_NoSavedSettings flag anymore, and will
   not always be auto-centered. Note that modals are more similar to regular windows than they are to
   not always be auto-centered. Note that modals are more similar to regular windows than they are to
-  popups, so api and behavior may evolve further toward embracing this. (#915, #3091) 
+  popups, so api and behavior may evolve further toward embracing this. (#915, #3091)
   Enforce centering using e.g. SetNextWindowPos(io.DisplaySize * 0.5f, ImGuiCond_Appearing, ImVec2(0.5f,0.5f)).
   Enforce centering using e.g. SetNextWindowPos(io.DisplaySize * 0.5f, ImGuiCond_Appearing, ImVec2(0.5f,0.5f)).
 - Metrics: Added a "Settings" section with some details about persistent ini settings.
 - 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
 - Nav, Menus: Fix vertical wrap-around in menus or popups created with multiple appending calls to

+ 7 - 0
imgui.cpp

@@ -5071,6 +5071,9 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s
             // Resize from any of the four corners
             // Resize from any of the four corners
             // We don't use an incremental MouseDelta but rather compute an absolute target size based on mouse position
             // We don't use an incremental MouseDelta but rather compute an absolute target size based on mouse position
             ImVec2 corner_target = g.IO.MousePos - g.ActiveIdClickOffset + ImLerp(grip.InnerDir * grip_hover_outer_size, grip.InnerDir * -grip_hover_inner_size, grip.CornerPosN); // Corner of the window corresponding to our corner grip
             ImVec2 corner_target = g.IO.MousePos - g.ActiveIdClickOffset + ImLerp(grip.InnerDir * grip_hover_outer_size, grip.InnerDir * -grip_hover_inner_size, grip.CornerPosN); // Corner of the window corresponding to our corner grip
+            ImVec2 clamp_min = ImVec2(grip.CornerPosN.x == 1 ? g.Style.DisplayWindowPadding.x : -FLT_MAX, grip.CornerPosN.y == 1 ? g.Style.DisplayWindowPadding.y : -FLT_MAX);
+            ImVec2 clamp_max = ImVec2(grip.CornerPosN.x == 0 ? g.IO.DisplaySize.x - g.Style.DisplayWindowPadding.x : FLT_MAX, grip.CornerPosN.y == 0 ? g.IO.DisplaySize.y - g.Style.DisplayWindowPadding.y : FLT_MAX);
+            corner_target = ImClamp(corner_target, clamp_min, clamp_max);
             CalcResizePosSizeFromAnyCorner(window, corner_target, grip.CornerPosN, &pos_target, &size_target);
             CalcResizePosSizeFromAnyCorner(window, corner_target, grip.CornerPosN, &pos_target, &size_target);
         }
         }
         if (resize_grip_n == 0 || held || hovered)
         if (resize_grip_n == 0 || held || hovered)
@@ -5096,6 +5099,9 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s
             if (border_n == 1) { border_posn = ImVec2(1, 0); border_target.x = (g.IO.MousePos.x - g.ActiveIdClickOffset.x + WINDOWS_RESIZE_FROM_EDGES_HALF_THICKNESS); } // Right
             if (border_n == 1) { border_posn = ImVec2(1, 0); border_target.x = (g.IO.MousePos.x - g.ActiveIdClickOffset.x + WINDOWS_RESIZE_FROM_EDGES_HALF_THICKNESS); } // Right
             if (border_n == 2) { border_posn = ImVec2(0, 1); border_target.y = (g.IO.MousePos.y - g.ActiveIdClickOffset.y + WINDOWS_RESIZE_FROM_EDGES_HALF_THICKNESS); } // Bottom
             if (border_n == 2) { border_posn = ImVec2(0, 1); border_target.y = (g.IO.MousePos.y - g.ActiveIdClickOffset.y + WINDOWS_RESIZE_FROM_EDGES_HALF_THICKNESS); } // Bottom
             if (border_n == 3) { border_posn = ImVec2(0, 0); border_target.x = (g.IO.MousePos.x - g.ActiveIdClickOffset.x + WINDOWS_RESIZE_FROM_EDGES_HALF_THICKNESS); } // Left
             if (border_n == 3) { border_posn = ImVec2(0, 0); border_target.x = (g.IO.MousePos.x - g.ActiveIdClickOffset.x + WINDOWS_RESIZE_FROM_EDGES_HALF_THICKNESS); } // Left
+            ImVec2 clamp_min = ImVec2(border_n == 1 ? g.Style.DisplayWindowPadding.x : -FLT_MAX, border_n == 2 ? g.Style.DisplayWindowPadding.y : -FLT_MAX);
+            ImVec2 clamp_max = ImVec2(border_n == 3 ? g.IO.DisplaySize.x - g.Style.DisplayWindowPadding.x : FLT_MAX, border_n == 0 ? g.IO.DisplaySize.y - g.Style.DisplayWindowPadding.y : FLT_MAX);
+            border_target = ImClamp(border_target, clamp_min, clamp_max);
             CalcResizePosSizeFromAnyCorner(window, border_target, border_posn, &pos_target, &size_target);
             CalcResizePosSizeFromAnyCorner(window, border_target, border_posn, &pos_target, &size_target);
         }
         }
     }
     }
@@ -5117,6 +5123,7 @@ static bool ImGui::UpdateWindowManualResize(ImGuiWindow* window, const ImVec2& s
         {
         {
             const float NAV_RESIZE_SPEED = 600.0f;
             const float NAV_RESIZE_SPEED = 600.0f;
             nav_resize_delta *= ImFloor(NAV_RESIZE_SPEED * g.IO.DeltaTime * ImMin(g.IO.DisplayFramebufferScale.x, g.IO.DisplayFramebufferScale.y));
             nav_resize_delta *= ImFloor(NAV_RESIZE_SPEED * g.IO.DeltaTime * ImMin(g.IO.DisplayFramebufferScale.x, g.IO.DisplayFramebufferScale.y));
+            nav_resize_delta = ImClamp(nav_resize_delta, g.Style.DisplayWindowPadding - window->Pos - window->Size, ImVec2(FLT_MAX, FLT_MAX));
             g.NavWindowingToggleLayer = false;
             g.NavWindowingToggleLayer = false;
             g.NavDisableMouseHover = true;
             g.NavDisableMouseHover = true;
             resize_grip_col[0] = GetColorU32(ImGuiCol_ResizeGripActive);
             resize_grip_col[0] = GetColorU32(ImGuiCol_ResizeGripActive);