Viewport: when moving window we use the moving window viewport unless drag and dropping. This is to fix e.g. IsItemHovered() + Tooltip pattern that may be active while moving a window. (#1542)

This commit is contained in:
omar 2018-07-17 15:56:02 +02:00
parent 16c6734bcb
commit defbf1c4b3

View File

@ -3808,9 +3808,6 @@ static void ImGui::UpdateViewports()
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
IM_ASSERT(g.PlatformIO.Viewports.Size <= g.Viewports.Size); IM_ASSERT(g.PlatformIO.Viewports.Size <= g.Viewports.Size);
// Update mouse reference viewport
g.MouseRefViewport = g.IO.MousePosViewport ? FindViewportByID(g.IO.MousePosViewport) : g.Viewports[0];
// Update main viewport with current platform position and size // Update main viewport with current platform position and size
ImGuiViewportP* main_viewport = g.Viewports[0]; ImGuiViewportP* main_viewport = g.Viewports[0];
IM_ASSERT(main_viewport->ID == IMGUI_VIEWPORT_DEFAULT_ID); IM_ASSERT(main_viewport->ID == IMGUI_VIEWPORT_DEFAULT_ID);
@ -3820,6 +3817,7 @@ static void ImGui::UpdateViewports()
AddUpdateViewport(NULL, IMGUI_VIEWPORT_DEFAULT_ID, main_viewport_platform_pos, g.IO.DisplaySize, ImGuiViewportFlags_CanHostOtherWindows); AddUpdateViewport(NULL, IMGUI_VIEWPORT_DEFAULT_ID, main_viewport_platform_pos, g.IO.DisplaySize, ImGuiViewportFlags_CanHostOtherWindows);
g.CurrentViewport = NULL; g.CurrentViewport = NULL;
g.MouseRefViewport = NULL;
for (int n = 0; n < g.Viewports.Size; n++) for (int n = 0; n < g.Viewports.Size; n++)
{ {
// Erase unused viewports // Erase unused viewports
@ -3835,7 +3833,6 @@ static void ImGui::UpdateViewports()
g.Viewports.erase(g.Viewports.Data + n); g.Viewports.erase(g.Viewports.Data + n);
// Destroy // Destroy
if (viewport == g.MouseRefViewport) g.MouseRefViewport = main_viewport;
if (viewport == g.MouseLastHoveredViewport) g.MouseLastHoveredViewport = NULL; if (viewport == g.MouseLastHoveredViewport) g.MouseLastHoveredViewport = NULL;
IM_ASSERT(viewport->RendererUserData == NULL && viewport->PlatformUserData == NULL && viewport->PlatformHandle == NULL); IM_ASSERT(viewport->RendererUserData == NULL && viewport->PlatformUserData == NULL && viewport->PlatformHandle == NULL);
IM_ASSERT(g.PlatformIO.Viewports.contains(viewport) == false); IM_ASSERT(g.PlatformIO.Viewports.contains(viewport) == false);
@ -3894,13 +3891,14 @@ static void ImGui::UpdateViewports()
} }
// Mouse handling: decide on the actual mouse viewport for this frame between the active/focused viewport and the hovered viewport. // Mouse handling: decide on the actual mouse viewport for this frame between the active/focused viewport and the hovered viewport.
// Note that 'viewport_hovered' should skip over any viewport that has the ImGuiViewportFlags_NoInputs flags set.
ImGuiViewportP* viewport_hovered = NULL; ImGuiViewportP* viewport_hovered = NULL;
if (g.IO.BackendFlags & ImGuiBackendFlags_HasMouseHoveredViewport) if (g.IO.BackendFlags & ImGuiBackendFlags_HasMouseHoveredViewport)
{ {
viewport_hovered = g.IO.MouseHoveredViewport ? FindViewportByID(g.IO.MouseHoveredViewport) : NULL; viewport_hovered = g.IO.MouseHoveredViewport ? FindViewportByID(g.IO.MouseHoveredViewport) : NULL;
if (viewport_hovered && (viewport_hovered->Flags & ImGuiViewportFlags_NoInputs)) if (viewport_hovered && (viewport_hovered->Flags & ImGuiViewportFlags_NoInputs))
{ {
// Back-end failed at honoring its contract if it returned a viewport with the _NoInputs flag // Back-end failed at honoring its contract if it returned a viewport with the _NoInputs flag.
IM_ASSERT(0); IM_ASSERT(0);
viewport_hovered = FindViewportHoveredFromPlatformWindowStack(g.IO.MousePos); viewport_hovered = FindViewportHoveredFromPlatformWindowStack(g.IO.MousePos);
} }
@ -3915,17 +3913,23 @@ static void ImGui::UpdateViewports()
if (viewport_hovered != NULL) if (viewport_hovered != NULL)
g.MouseLastHoveredViewport = viewport_hovered; g.MouseLastHoveredViewport = viewport_hovered;
// Update mouse reference viewport
g.MouseRefViewport = g.IO.MousePosViewport ? FindViewportByID(g.IO.MousePosViewport) : g.Viewports[0];
// When moving a window we aim at its viewport
if (g.MovingWindow)
g.MouseRefViewport = g.MovingWindow->Viewport;
// When dragging something, always refer to the last hovered viewport. // When dragging something, always refer to the last hovered viewport.
// (So when we are between viewports, our dragged preview will tend to show in the last viewport even if we don't have tooltips in viewports) // - when releasing a moving window we will revert to aiming behind (at viewport_hovered)
// Also consider the case of holding on a menu item to browse child menus: even thought a mouse button is held, there's no active id because menu items only react on mouse release. // - when we are between viewports, our dragged preview will tend to show in the last viewport _even_ if we don't have tooltips in their viewports (when lacking monitor info)
const bool is_mouse_dragging_with_an_expected_destination = g.DragDropActive || (g.MovingWindow != NULL); // - consider the case of holding on a menu item to browse child menus: even thou a mouse button is held, there's no active id because menu items only react on mouse release.
if (is_mouse_dragging_with_an_expected_destination || g.ActiveId == 0 || !ImGui::IsAnyMouseDown()) const bool is_mouse_dragging_with_an_expected_destination = g.DragDropActive;// || (g.MovingWindow != NULL);
{
if (is_mouse_dragging_with_an_expected_destination && viewport_hovered == NULL) if (is_mouse_dragging_with_an_expected_destination && viewport_hovered == NULL)
viewport_hovered = g.MouseLastHoveredViewport; viewport_hovered = g.MouseLastHoveredViewport;
if (is_mouse_dragging_with_an_expected_destination || g.ActiveId == 0 || !ImGui::IsAnyMouseDown())
if (viewport_hovered != NULL && viewport_hovered != g.MouseRefViewport && !(viewport_hovered->Flags & ImGuiViewportFlags_NoInputs)) if (viewport_hovered != NULL && viewport_hovered != g.MouseRefViewport && !(viewport_hovered->Flags & ImGuiViewportFlags_NoInputs))
g.MouseRefViewport = viewport_hovered; g.MouseRefViewport = viewport_hovered;
}
IM_ASSERT(g.MouseRefViewport != NULL); IM_ASSERT(g.MouseRefViewport != NULL);
} }