From d9c54826bbf7170901e68010be3b8efaa6030605 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 22 Nov 2018 17:27:35 +0100 Subject: [PATCH 1/9] Viewport: Stop relying on viewport->CreatedPlatformWindow to create Platform_DestroyWindow and Renderer_DestroyWindow. Explicitly require Platform_GetWindowFocus() to require supporting empty data. --- imgui.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 767a7bbd..298bdcc6 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3459,7 +3459,6 @@ void ImGui::Initialize(ImGuiContext* context) ImGuiViewportP* viewport = IM_NEW(ImGuiViewportP)(); viewport->ID = IMGUI_VIEWPORT_DEFAULT_ID; viewport->Idx = 0; - viewport->CreatedPlatformWindow = true; // Set this flag so DestroyPlatformWindows() gives a chance for backend to receive DestroyWindow calls for the main viewport. g.Viewports.push_back(viewport); g.PlatformIO.MainViewport = g.Viewports[0]; // Make it accessible in public-facing GetPlatformIO() immediately (before the first call to EndFrame) g.PlatformIO.Viewports.push_back(g.Viewports[0]); @@ -7645,11 +7644,12 @@ void ImGui::UpdatePlatformWindows() } // Update our implicit z-order knowledge of platform windows, which is used when the back-end cannot provide io.MouseHoveredViewport. + // When setting Platform_GetWindowFocus, it is expected that the platform back-end can handle calls without crashing if it doesn't have data stored. if (g.PlatformIO.Platform_GetWindowFocus != NULL) { ImGuiViewportP* focused_viewport = NULL; for (int i = 0; i < g.Viewports.Size && focused_viewport == NULL; i++) - if (g.Viewports[i]->PlatformUserData != NULL || g.Viewports[i]->PlatformHandle != NULL || g.Viewports[i]->CreatedPlatformWindow) + if (g.Viewports[i]->PlatformUserData != NULL || g.Viewports[i]->PlatformHandle != NULL) if (g.PlatformIO.Platform_GetWindowFocus(g.Viewports[i])) focused_viewport = g.Viewports[i]; if (focused_viewport && g.PlatformLastFocusedViewport != focused_viewport->ID) @@ -7732,9 +7732,9 @@ void ImGui::RenderPlatformWindowsDefault(void* platform_render_arg, void* render void ImGui::DestroyPlatformWindow(ImGuiViewportP* viewport) { ImGuiContext& g = *GImGui; - if (viewport->CreatedPlatformWindow && g.PlatformIO.Renderer_DestroyWindow) + if (g.PlatformIO.Renderer_DestroyWindow) g.PlatformIO.Renderer_DestroyWindow(viewport); - if (viewport->CreatedPlatformWindow && g.PlatformIO.Platform_DestroyWindow) + if (g.PlatformIO.Platform_DestroyWindow) g.PlatformIO.Platform_DestroyWindow(viewport); IM_ASSERT(viewport->RendererUserData == NULL); IM_ASSERT(viewport->PlatformUserData == NULL); @@ -7745,15 +7745,15 @@ void ImGui::DestroyPlatformWindow(ImGuiViewportP* viewport) void ImGui::DestroyPlatformWindows() { - // We call the destroy window on the main viewport (index 0) to give a chance to the back-end to clear any data - // have stored in e.g. PlatformUserData, RendererUserData. It can be convenient for the platform back-end code to - // store something in the main viewport, in order for e.g. the mouse handling code to work in a more generic manner. + // We call the destroy window on every viewport (including the main viewport, index 0) to give a chance to the back-end + // to clear any data they may have stored in e.g. PlatformUserData, RendererUserData. + // It is convenient for the platform back-end code to store something in the main viewport, in order for e.g. the mouse handling + // code to operator a consistent manner. // It is expected that the back-end can handle calls to Renderer_DestroyWindow/Platform_DestroyWindow without // crashing if it doesn't have data stored. ImGuiContext& g = *GImGui; for (int i = 0; i < g.Viewports.Size; i++) - if (g.Viewports[i]->CreatedPlatformWindow) - DestroyPlatformWindow(g.Viewports[i]); + DestroyPlatformWindow(g.Viewports[i]); } //----------------------------------------------------------------------------- From d27ffefbd40cebf8da316d48409a619668987347 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 22 Nov 2018 18:59:43 +0100 Subject: [PATCH 2/9] Version 1.67 WIP --- docs/CHANGELOG.txt | 9 +++++++++ imgui.cpp | 2 +- imgui.h | 6 +++--- imgui_demo.cpp | 2 +- imgui_draw.cpp | 2 +- imgui_internal.h | 2 +- imgui_widgets.cpp | 2 +- 7 files changed, 17 insertions(+), 8 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 9035730a..c147284d 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -29,6 +29,15 @@ HOW TO UPDATE? - Please report any issue! +----------------------------------------------------------------------- + VERSION 1.67 (In Progress) +----------------------------------------------------------------------- + +Breaking Changes: + +Other Changes: + + ----------------------------------------------------------------------- VERSION 1.66 (Released 2018-11-22) ----------------------------------------------------------------------- diff --git a/imgui.cpp b/imgui.cpp index 1478fd6f..d9aca86d 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.66 +// dear imgui, v1.67 WIP // (main code and documentation) // Call and read ImGui::ShowDemoWindow() in imgui_demo.cpp for demo code. diff --git a/imgui.h b/imgui.h index 45a2178d..c4d47574 100644 --- a/imgui.h +++ b/imgui.h @@ -1,4 +1,4 @@ -// dear imgui, v1.66 +// dear imgui, v1.67 WIP // (headers) // See imgui.cpp file for documentation. @@ -23,8 +23,8 @@ // Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY00 then bounced up to XYY01 when release tagging happens) -#define IMGUI_VERSION "1.66" -#define IMGUI_VERSION_NUM 16601 +#define IMGUI_VERSION "1.67 WIP" +#define IMGUI_VERSION_NUM 16700 #define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert)) // Define attributes of all API symbols declarations (e.g. for DLL under Windows) diff --git a/imgui_demo.cpp b/imgui_demo.cpp index b7f53104..d9c9020f 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.66 +// dear imgui, v1.67 WIP // (demo code) // Message to the person tempted to delete this file when integrating Dear ImGui into their code base: diff --git a/imgui_draw.cpp b/imgui_draw.cpp index f96a4734..7e733f6a 100644 --- a/imgui_draw.cpp +++ b/imgui_draw.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.66 +// dear imgui, v1.67 WIP // (drawing and font code) /* diff --git a/imgui_internal.h b/imgui_internal.h index c6cf50d1..6169e3a9 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1,4 +1,4 @@ -// dear imgui, v1.66 +// dear imgui, v1.67 WIP // (internal structures/api) // You may use this file to debug, understand or extend ImGui features but we don't provide any guarantee of forward compatibility! diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index 7a24cfa6..1f426343 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -1,4 +1,4 @@ -// dear imgui, v1.66 +// dear imgui, v1.67 WIP // (widgets code) /* From 0c4dee083c2ae25d47f6bb975b510274ee3ed813 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 22 Nov 2018 18:56:24 +0100 Subject: [PATCH 3/9] Internals: Added ImPool helper data structure (used by testing system, and already in docking branch) --- imgui_internal.h | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/imgui_internal.h b/imgui_internal.h index 6169e3a9..0800b2aa 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -213,6 +213,30 @@ static inline ImVec2 ImRotate(const ImVec2& v, float cos_a, float sin_a) static inline float ImLinearSweep(float current, float target, float speed) { if (current < target) return ImMin(current + speed, target); if (current > target) return ImMax(current - speed, target); return current; } static inline ImVec2 ImMul(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y); } +// Helper: ImPool<>. Basic keyed storage for contiguous instances, slow/amortized insertion, O(1) indexable, O(Log N) queries by ID over a dense/hot buffer, +// Honor constructor/destructor. Add/remove invalidate all pointers. Indexes have the same lifetime as the associated object. +typedef int ImPoolIdx; +template +struct IMGUI_API ImPool +{ + ImVector Data; // Contiguous data + ImGuiStorage Map; // ID->Index + ImPoolIdx FreeIdx; // Next free idx to use + + ImPool() { FreeIdx = 0; } + ~ImPool() { Clear(); } + T* GetByKey(ImGuiID key) { int idx = Map.GetInt(key, -1); return (idx != -1) ? &Data[idx] : NULL; } + T* GetByIndex(ImPoolIdx n) { return &Data[n]; } + ImPoolIdx GetIndex(const T* p) const { IM_ASSERT(p >= Data.Data && p < Data.Data + Data.Size); return (ImPoolIdx)(p - Data.Data); } + T* GetOrAddByKey(ImGuiID key) { int* p_idx = Map.GetIntRef(key, -1); if (*p_idx != -1) return &Data[*p_idx]; *p_idx = FreeIdx; return Add(); } + void Clear() { for (int n = 0; n < Map.Data.Size; n++) { int idx = Map.Data[n].val_i; if (idx != -1) Data[idx].~T(); } Map.Clear(); Data.clear(); FreeIdx = 0; } + T* Add() { int idx = FreeIdx; if (idx == Data.Size) { Data.resize(Data.Size + 1); FreeIdx++; } else { FreeIdx = *(int*)&Data[idx]; } IM_PLACEMENT_NEW(&Data[idx]) T(); return &Data[idx]; } + void Remove(ImGuiID key, const T* p) { Remove(key, GetIndex(p)); } + void Remove(ImGuiID key, ImPoolIdx idx) { Data[idx].~T(); *(int*)&Data[idx] = FreeIdx; FreeIdx = idx; Map.SetInt(key, -1); } + void Reserve(int capacity) { Data.reserve(capacity); Map.Data.reserve(capacity); } + int GetSize() const { return Data.Size; } +}; + //----------------------------------------------------------------------------- // Types //----------------------------------------------------------------------------- From 1f78e08427f458e4ee5f215a15810b1f61050622 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 22 Nov 2018 20:13:55 +0100 Subject: [PATCH 4/9] Viewport: UpdateTryMergeWindowIntoHostViewport() calls BringWindowToDisplayFront() - possible now that BringWindowToFocusFront() is a different function. --- imgui.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/imgui.cpp b/imgui.cpp index 298bdcc6..acac2268 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -7214,6 +7214,7 @@ static void ImGui::UpdateTryMergeWindowIntoHostViewport(ImGuiWindow* window, ImG if (g.Windows[n]->Viewport == old_viewport) SetWindowViewport(g.Windows[n], viewport); SetWindowViewport(window, viewport); + BringWindowToDisplayFront(window); } // Scale all windows (position, size). Use when e.g. changing DPI. (This is a lossy operation!) From cae4d020dc41ec7bc20c8528852e4540787d3026 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 22 Nov 2018 21:13:07 +0100 Subject: [PATCH 5/9] Viewport: Merging/Extracting to/from main host viewport is now performed based on current state rather than triggers. Windows which don't fit in host window are now consistently in their own viewport. Toward simplifying the UpdateSelectWindowViewport() function. Probably broke something.. (#1542) --- imgui.cpp | 62 +++++++++++++++++------------------------------- imgui_internal.h | 2 -- 2 files changed, 22 insertions(+), 42 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index acac2268..5d29849d 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2369,7 +2369,6 @@ ImGuiWindow::ImGuiWindow(ImGuiContext* context, const char* name) ScrollbarSizes = ImVec2(0.0f, 0.0f); ScrollbarX = ScrollbarY = false; ViewportOwned = false; - ViewportTryMerge = ViewportTrySplit = false; Active = WasActive = false; WriteAccessed = false; Collapsed = false; @@ -4762,10 +4761,6 @@ static void ImGui::UpdateManualResize(ImGuiWindow* window, const ImVec2& size_au if (size_target.x != FLT_MAX && (size_target.x != window->SizeFull.x || size_target.y != window->SizeFull.y)) { window->SizeFull = size_target; - if (window->ViewportOwned) - window->ViewportTryMerge = true; - else - window->ViewportTrySplit = true; MarkIniSettingsDirty(window); } if (pos_target.x != FLT_MAX) @@ -5082,10 +5077,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) { // Late create viewport, based on the assumption that with our calculations, the DPI will be known ahead (same as the DPI of the selection done in UpdateSelectWindowViewport) //ImGuiViewport* old_viewport = window->Viewport; - ImGuiViewportFlags viewport_flags = ImGuiViewportFlags_NoFocusOnAppearing; - if ((window->Flags & ImGuiWindowFlags_NoMouseInputs) && (window->Flags & ImGuiWindowFlags_NoNavInputs)) - viewport_flags |= ImGuiViewportFlags_NoInputs; - window->Viewport = AddUpdateViewport(window, window->ID, window->Pos, window->Size, viewport_flags); + window->Viewport = AddUpdateViewport(window, window->ID, window->Pos, window->Size, ImGuiViewportFlags_NoFocusOnAppearing); // FIXME-DPI //IM_ASSERT(old_viewport->DpiScale == window->Viewport->DpiScale); // FIXME-DPI: Something went wrong @@ -5098,15 +5090,9 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) if (window->ViewportOwned) { if (window->Viewport->PlatformRequestMove) - { window->Pos = window->Viewport->Pos; - window->ViewportTryMerge = true; - } if (window->Viewport->PlatformRequestResize) - { window->Size = window->SizeFull = window->Viewport->Size; - window->ViewportTryMerge = true; - } // We also tell the back-end that clearing the platform window won't be necessary, as our window is filling the viewport and we have disabled BgAlpha window->Viewport->Flags |= ImGuiViewportFlags_NoRendererClear; @@ -5127,7 +5113,6 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags) { // Fallback for "lost" window (e.g. a monitor disconnected): we move the window back over the main viewport SetWindowPos(window, g.Viewports[0]->Pos + style.DisplayWindowPadding, ImGuiCond_Always); - window->ViewportTryMerge = true; } else { @@ -7385,11 +7370,22 @@ static void ImGui::UpdateViewports() IM_ASSERT(g.MouseViewport != NULL); } +// FIXME: We should ideally refactor the system to call this everyframe (we currently don't) ImGuiViewportP* ImGui::AddUpdateViewport(ImGuiWindow* window, ImGuiID id, const ImVec2& pos, const ImVec2& size, ImGuiViewportFlags flags) { ImGuiContext& g = *GImGui; IM_ASSERT(id != 0); + if (window != NULL) + { + if (g.MovingWindow && g.MovingWindow->RootWindow == window) + flags |= ImGuiViewportFlags_NoInputs | ImGuiViewportFlags_NoFocusOnAppearing; + if ((window->Flags & ImGuiWindowFlags_NoMouseInputs) && (window->Flags & ImGuiWindowFlags_NoNavInputs)) + flags |= ImGuiViewportFlags_NoInputs; + if (window->Flags & ImGuiWindowFlags_NoFocusOnAppearing) + flags |= ImGuiViewportFlags_NoFocusOnAppearing; + } + ImGuiViewportP* viewport = (ImGuiViewportP*)FindViewportByID(id); if (viewport) { @@ -7407,9 +7403,6 @@ ImGuiViewportP* ImGui::AddUpdateViewport(ImGuiWindow* window, ImGuiID id, const viewport->PlatformMonitor = FindPlatformMonitorForRect(viewport->GetRect()); g.Viewports.push_back(viewport); - if (window && (window->Flags & ImGuiWindowFlags_NoFocusOnAppearing)) - flags |= ImGuiViewportFlags_NoFocusOnAppearing; - // We normally setup for all viewports in NewFrame() but here need to handle the mid-frame creation of a new viewport. // We need to extend the fullscreen clip rect so the OverlayDrawList clip is correct for that the first frame g.DrawListSharedData.ClipRectFullscreen.z = ImMax(g.DrawListSharedData.ClipRectFullscreen.z, viewport->Pos.x + viewport->Size.x); @@ -7447,12 +7440,9 @@ static void ImGui::UpdateSelectWindowViewport(ImGuiWindow* window) return; } - // Merge into host viewports (after moving, resizing) - if (window->ViewportOwned && window->ViewportTryMerge && g.ActiveId == 0) - { + // Merge into host viewport + if (window->ViewportOwned && g.ActiveId == 0) UpdateTryMergeWindowIntoHostViewport(window, g.Viewports[0]); - window->ViewportTryMerge = false; - } window->ViewportOwned = false; // Appearing popups reset their viewport so they can inherit again @@ -7492,23 +7482,15 @@ static void ImGui::UpdateSelectWindowViewport(ImGuiWindow* window) { window->Viewport = g.MouseViewport; } - else if (g.MovingWindow && g.MovingWindow->RootWindow == window && IsMousePosValid()) - { - // Transition to our own viewport when leaving our host boundaries + set the NoInputs flag (will be cleared in UpdateMouseMovingWindow() when releasing mouse) - // If we are already in our own viewport, if need to set the NoInputs flag. - // If we have no viewport (which happens when detaching a docked node) immediately create one. - // We test for 'window->Viewport->Window == window' instead of 'window->ViewportOwned' because ViewportOwned is not valid during this function. - bool has_viewport = (window->Viewport != NULL); - bool own_viewport = has_viewport && (window->Viewport->Window == window); - bool leave_host_viewport = has_viewport && !own_viewport && !window->Viewport->GetRect().Contains(window->Rect()); - bool move_from_own_viewport = has_viewport && own_viewport && !(window->Viewport->Flags & ImGuiViewportFlags_NoInputs); - if (!has_viewport || leave_host_viewport || move_from_own_viewport) - window->Viewport = AddUpdateViewport(window, window->ID, window->Pos, window->Size, ImGuiViewportFlags_NoFocusOnAppearing | ImGuiViewportFlags_NoInputs); - } else if (GetWindowAlwaysWantOwnViewport(window)) { window->Viewport = AddUpdateViewport(window, window->ID, window->Pos, window->Size, ImGuiViewportFlags_None); } + else if (g.MovingWindow && g.MovingWindow->RootWindow == window && IsMousePosValid()) + { + if (window->Viewport != NULL && window->Viewport->Window == window) + window->Viewport = AddUpdateViewport(window, window->ID, window->Pos, window->Size, ImGuiViewportFlags_None); + } // Mark window as allowed to protrude outside of its viewport and into the current monitor // We need to take account of the possibility that mouse may become invalid. @@ -7522,14 +7504,14 @@ static void ImGui::UpdateSelectWindowViewport(ImGuiWindow* window) else window->ViewportAllowPlatformMonitorExtend = window->Viewport->PlatformMonitor; } - if (window->ViewportTrySplit && window->ViewportAllowPlatformMonitorExtend < 0) - window->ViewportAllowPlatformMonitorExtend = window->Viewport->PlatformMonitor; - window->ViewportTrySplit = false; // Fallback to default viewport if (window->Viewport == NULL) window->Viewport = main_viewport; + if (window->ViewportAllowPlatformMonitorExtend < 0) + window->ViewportAllowPlatformMonitorExtend = window->Viewport->PlatformMonitor; + // Update flags window->ViewportOwned = (window == window->Viewport->Window); diff --git a/imgui_internal.h b/imgui_internal.h index 2bebf9a0..e84669c3 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1074,8 +1074,6 @@ struct IMGUI_API ImGuiWindow ImVec2 ScrollbarSizes; // Size taken by scrollbars on each axis bool ScrollbarX, ScrollbarY; bool ViewportOwned; - bool ViewportTryMerge; // Request attempt to merge into a host viewport and destroy our owned viewport - bool ViewportTrySplit; // Request attempt to split out of a host viewport and create our owned viewport bool Active; // Set to true on Begin(), unless Collapsed bool WasActive; bool WriteAccessed; // Set to true when any widget access the current window From 862781b1950b9b55170ea7fbf3a90c2453afad33 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 23 Nov 2018 15:50:33 +0100 Subject: [PATCH 6/9] Viewport: Avoid unnecessary reapplying platform pos/size every frame. (#2205) + Fix GLFW ImGui_ImplGlfw_CreateWindow() from not applying position immediately. Clear LastNameHash properly (bug already fixed in Docking branch) --- examples/imgui_impl_glfw.cpp | 1 + imgui.cpp | 17 ++++++++++------- imgui_internal.h | 6 ++++-- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/examples/imgui_impl_glfw.cpp b/examples/imgui_impl_glfw.cpp index d357d5de..c062c704 100644 --- a/examples/imgui_impl_glfw.cpp +++ b/examples/imgui_impl_glfw.cpp @@ -409,6 +409,7 @@ static void ImGui_ImplGlfw_CreateWindow(ImGuiViewport* viewport) data->Window = glfwCreateWindow((int)viewport->Size.x, (int)viewport->Size.y, "No Title Yet", NULL, share_window); data->WindowOwned = true; viewport->PlatformHandle = (void*)data->Window; + glfwSetWindowPos(data->Window, (int)viewport->Pos.x, (int)viewport->Pos.y); // Install callbacks for secondary viewports glfwSetMouseButtonCallback(data->Window, ImGui_ImplGlfw_MouseButtonCallback); diff --git a/imgui.cpp b/imgui.cpp index 5d29849d..3f94cd02 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -7280,9 +7280,9 @@ static void ImGui::UpdateViewports() // Apply Position and Size (from Platform Window to ImGui) if requested. // We do it early in the frame instead of waiting for UpdatePlatformWindows() to avoid a frame of lag when moving/resizing using OS facilities. if (viewport->PlatformRequestMove) - viewport->Pos = g.PlatformIO.Platform_GetWindowPos(viewport); + viewport->Pos = viewport->LastPlatformPos = g.PlatformIO.Platform_GetWindowPos(viewport); if (viewport->PlatformRequestResize) - viewport->Size = g.PlatformIO.Platform_GetWindowSize(viewport); + viewport->Size = viewport->LastPlatformSize = g.PlatformIO.Platform_GetWindowSize(viewport); // Translate imgui windows when a Host Viewport has been moved ImVec2 delta = viewport->Pos - viewport->LastPos; @@ -7576,18 +7576,21 @@ void ImGui::UpdatePlatformWindows() g.PlatformIO.Platform_CreateWindow(viewport); if (g.PlatformIO.Renderer_CreateWindow != NULL) g.PlatformIO.Renderer_CreateWindow(viewport); - viewport->RendererLastSize = viewport->Size; + viewport->LastNameHash = 0; + viewport->LastPlatformPos = viewport->LastPlatformSize = ImVec2(FLT_MAX, FLT_MAX); // By clearing those we'll enforce a call to Platform_SetWindowPos/Platform_SetWindowSize before Platform_ShowWindow + viewport->LastRendererSize = viewport->Size; viewport->CreatedPlatformWindow = true; } // Apply Position and Size (from ImGui to Platform/Renderer back-ends) - if (!viewport->PlatformRequestMove) + if ((viewport->LastPlatformPos.x != viewport->Pos.x || viewport->LastPlatformPos.y != viewport->Pos.y) && !viewport->PlatformRequestMove) g.PlatformIO.Platform_SetWindowPos(viewport, viewport->Pos); - if (!viewport->PlatformRequestResize) + if ((viewport->LastPlatformSize.x != viewport->Size.x || viewport->LastPlatformSize.y != viewport->Size.y) && !viewport->PlatformRequestResize) g.PlatformIO.Platform_SetWindowSize(viewport, viewport->Size); - if (g.PlatformIO.Renderer_SetWindowSize && (viewport->RendererLastSize.x != viewport->Size.x || viewport->RendererLastSize.y != viewport->Size.y)) + if ((viewport->LastRendererSize.x != viewport->Size.x || viewport->LastRendererSize.y != viewport->Size.y) && g.PlatformIO.Renderer_SetWindowSize) g.PlatformIO.Renderer_SetWindowSize(viewport, viewport->Size); - viewport->RendererLastSize = viewport->Size; + viewport->LastPlatformPos = viewport->Pos; + viewport->LastPlatformSize = viewport->LastRendererSize = viewport->Size; // Update title bar (if it changed) if (ImGuiWindow* window_for_title = viewport->Window) diff --git a/imgui_internal.h b/imgui_internal.h index e84669c3..83a4c326 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -611,9 +611,11 @@ struct ImGuiViewportP : public ImGuiViewport ImDrawList* OverlayDrawList; // For convenience, a draw list we can render to that's always rendered last (we use it to draw software mouse cursor when io.MouseDrawCursor is set) ImDrawData DrawDataP; ImDrawDataBuilder DrawDataBuilder; - ImVec2 RendererLastSize; + ImVec2 LastPlatformPos; + ImVec2 LastPlatformSize; + ImVec2 LastRendererSize; - ImGuiViewportP() { Idx = -1; LastFrameActive = LastFrameOverlayDrawList = LastFrontMostStampCount = -1; LastNameHash = 0; CreatedPlatformWindow = false; Alpha = LastAlpha = 1.0f; PlatformMonitor = INT_MIN; Window = NULL; OverlayDrawList = NULL; RendererLastSize = ImVec2(-1.0f,-1.0f); } + ImGuiViewportP() { Idx = -1; LastFrameActive = LastFrameOverlayDrawList = LastFrontMostStampCount = -1; LastNameHash = 0; CreatedPlatformWindow = false; Alpha = LastAlpha = 1.0f; PlatformMonitor = INT_MIN; Window = NULL; OverlayDrawList = NULL; LastPlatformPos = LastPlatformSize = LastRendererSize = ImVec2(FLT_MAX, FLT_MAX); } ~ImGuiViewportP() { if (OverlayDrawList) IM_DELETE(OverlayDrawList); } ImRect GetRect() const { return ImRect(Pos.x, Pos.y, Pos.x + Size.x, Pos.y + Size.y); } ImVec2 GetCenter() const{ return ImVec2(Pos.x + Size.x * 0.5f, Pos.y + Size.y * 0.5f); } From d8ab2c1ac9e40ebb09e962a9cffd719c5ca2b244 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 23 Nov 2018 16:18:30 +0100 Subject: [PATCH 7/9] Viewport: Added support for minimized window which caused problem when ImGuiBackendFlags_HasMouseHoveredViewport was not supported. (#1542) + todo --- docs/TODO.txt | 6 +++++- examples/imgui_impl_glfw.cpp | 7 +++++++ examples/imgui_impl_sdl.cpp | 8 ++++++++ examples/imgui_impl_win32.cpp | 8 ++++++++ imgui.cpp | 35 +++++++++++++++++++++-------------- imgui.h | 1 + imgui_internal.h | 3 ++- 7 files changed, 52 insertions(+), 16 deletions(-) diff --git a/docs/TODO.txt b/docs/TODO.txt index 9b2893d3..ffc0dbe0 100644 --- a/docs/TODO.txt +++ b/docs/TODO.txt @@ -281,14 +281,18 @@ It's mostly a bunch of personal notes, probably incomplete. Feel free to query i - examples: move ImGui::NewFrame() out of the backend _NewFrame() ? - viewport: make it possible to have no main/hosting viewport + - viewport: We set ImGuiViewportFlags_NoFocusOnAppearing in a way that is required for GLFW/SDL binding, but could be handled better without + on a custom e.g. Win32 bindings. It prevents newly dragged-out viewports from taking the focus, which makes ALT+F4 more ambiguous. + - viewport: not focusing newly undocked viewport means clicking back on previous one doesn't bring OS window to front. - viewport: with platform decoration enabled, platform may force constraint (e.g. minimum size) - viewport: use getfocus/setfocus api to synchronize imgui<>platform focus better (e.g imgui-side ctrl-tab can focus os window, OS initial setup and alt-tab can focus imgui window etc.) - viewport: store per-viewport/monitor DPI in .ini file so an application reload or main window changing DPI on reload can be properly patched for. - - viewport: vulkan renderer implementation. + - viewport: implicit Debug window can hog a zombie viewport (harmless, noisy?) - viewport: need to clarify how to use GetMousePos() from a user point of view. - platform: glfw: no support for ImGuiBackendFlags_HasMouseHoveredViewport. - platform: sdl: no support for ImGuiBackendFlags_HasMouseHoveredViewport. maybe we could use SDL_GetMouseFocus() / SDL_WINDOW_MOUSE_FOCUS if imgui could fallback on its heuristic when NoInputs is set - platform: sdl: no refresh of monitor/display (SDL doesn't seem to have an event for it). + - platform: sdl: multi-viewport + minimized window seems to break mouse wheel events (at least under Win32). - inputs: we need an explicit flag about whether the imgui window is focused, to be able to distinguish focused key releases vs alt-tabbing all release behaviors. - inputs: rework IO system to be able to pass actual ordered/timestamped events. use an event queue? (~#335, #71) diff --git a/examples/imgui_impl_glfw.cpp b/examples/imgui_impl_glfw.cpp index c062c704..f1cc1cfc 100644 --- a/examples/imgui_impl_glfw.cpp +++ b/examples/imgui_impl_glfw.cpp @@ -548,6 +548,12 @@ static bool ImGui_ImplGlfw_GetWindowFocus(ImGuiViewport* viewport) return glfwGetWindowAttrib(data->Window, GLFW_FOCUSED) != 0; } +static bool ImGui_ImplGlfw_GetWindowMinimized(ImGuiViewport* viewport) +{ + ImGuiViewportDataGlfw* data = (ImGuiViewportDataGlfw*)viewport->PlatformUserData; + return glfwGetWindowAttrib(data->Window, GLFW_ICONIFIED) != 0; +} + #if GLFW_HAS_WINDOW_ALPHA static void ImGui_ImplGlfw_SetWindowAlpha(ImGuiViewport* viewport, float alpha) { @@ -668,6 +674,7 @@ static void ImGui_ImplGlfw_InitPlatformInterface() platform_io.Platform_GetWindowSize = ImGui_ImplGlfw_GetWindowSize; platform_io.Platform_SetWindowFocus = ImGui_ImplGlfw_SetWindowFocus; platform_io.Platform_GetWindowFocus = ImGui_ImplGlfw_GetWindowFocus; + platform_io.Platform_GetWindowMinimized = ImGui_ImplGlfw_GetWindowMinimized; platform_io.Platform_SetWindowTitle = ImGui_ImplGlfw_SetWindowTitle; platform_io.Platform_RenderWindow = ImGui_ImplGlfw_RenderWindow; platform_io.Platform_SwapBuffers = ImGui_ImplGlfw_SwapBuffers; diff --git a/examples/imgui_impl_sdl.cpp b/examples/imgui_impl_sdl.cpp index 2917a421..b0fb5c6b 100644 --- a/examples/imgui_impl_sdl.cpp +++ b/examples/imgui_impl_sdl.cpp @@ -10,6 +10,7 @@ // Missing features: // [ ] Platform: SDL2 handling of IME under Windows appears to be broken and it explicitly disable the regular Windows IME. You can restore Windows IME by compiling SDL with SDL_DISABLE_WINDOWS_IME. // [ ] Platform: Gamepad support (need to use SDL_GameController API to fill the io.NavInputs[] value when ImGuiConfigFlags_NavEnableGamepad is set). +// [ ] Platform: Multi-viewport + Minimized windows seems to break mouse wheel events (at least under Windows). // You can copy and use unmodified imgui_impl_* files in your project. See main.cpp for an example of using this. // If you are new to dear imgui, read examples/README.txt and read the documentation at the top of imgui.cpp. @@ -472,6 +473,12 @@ static bool ImGui_ImplSDL2_GetWindowFocus(ImGuiViewport* viewport) return (SDL_GetWindowFlags(data->Window) & SDL_WINDOW_INPUT_FOCUS) != 0; } +static bool ImGui_ImplSDL2_GetWindowMinimized(ImGuiViewport* viewport) +{ + ImGuiViewportDataSDL2* data = (ImGuiViewportDataSDL2*)viewport->PlatformUserData; + return (SDL_GetWindowFlags(data->Window) & SDL_WINDOW_MINIMIZED) != 0; +} + static void ImGui_ImplSDL2_RenderWindow(ImGuiViewport* viewport, void*) { ImGuiViewportDataSDL2* data = (ImGuiViewportDataSDL2*)viewport->PlatformUserData; @@ -543,6 +550,7 @@ static void ImGui_ImplSDL2_InitPlatformInterface(SDL_Window* window, void* sdl_g platform_io.Platform_GetWindowSize = ImGui_ImplSDL2_GetWindowSize; platform_io.Platform_SetWindowFocus = ImGui_ImplSDL2_SetWindowFocus; platform_io.Platform_GetWindowFocus = ImGui_ImplSDL2_GetWindowFocus; + platform_io.Platform_GetWindowMinimized = ImGui_ImplSDL2_GetWindowMinimized; platform_io.Platform_SetWindowTitle = ImGui_ImplSDL2_SetWindowTitle; platform_io.Platform_RenderWindow = ImGui_ImplSDL2_RenderWindow; platform_io.Platform_SwapBuffers = ImGui_ImplSDL2_SwapBuffers; diff --git a/examples/imgui_impl_win32.cpp b/examples/imgui_impl_win32.cpp index fb753794..b040bd97 100644 --- a/examples/imgui_impl_win32.cpp +++ b/examples/imgui_impl_win32.cpp @@ -536,6 +536,13 @@ static bool ImGui_ImplWin32_GetWindowFocus(ImGuiViewport* viewport) return ::GetActiveWindow() == data->Hwnd; } +static bool ImGui_ImplWin32_GetWindowMinimized(ImGuiViewport* viewport) +{ + ImGuiViewportDataWin32* data = (ImGuiViewportDataWin32*)viewport->PlatformUserData; + IM_ASSERT(data->Hwnd != 0); + return ::IsIconic(data->Hwnd) != 0; +} + static void ImGui_ImplWin32_SetWindowTitle(ImGuiViewport* viewport, const char* title) { // ::SetWindowTextA() doesn't properly handle UTF-8 so we explicitely convert our string. @@ -683,6 +690,7 @@ static void ImGui_ImplWin32_InitPlatformInterface() platform_io.Platform_GetWindowSize = ImGui_ImplWin32_GetWindowSize; platform_io.Platform_SetWindowFocus = ImGui_ImplWin32_SetWindowFocus; platform_io.Platform_GetWindowFocus = ImGui_ImplWin32_GetWindowFocus; + platform_io.Platform_GetWindowMinimized = ImGui_ImplWin32_GetWindowMinimized; platform_io.Platform_SetWindowTitle = ImGui_ImplWin32_SetWindowTitle; platform_io.Platform_SetWindowAlpha = ImGui_ImplWin32_SetWindowAlpha; platform_io.Platform_GetWindowDpiScale = ImGui_ImplWin32_GetWindowDpiScale; diff --git a/imgui.cpp b/imgui.cpp index 3f94cd02..77e7cdd5 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -7185,7 +7185,7 @@ static bool ImGui::GetWindowAlwaysWantOwnViewport(ImGuiWindow* window) static void ImGui::UpdateTryMergeWindowIntoHostViewport(ImGuiWindow* window, ImGuiViewportP* viewport) { ImGuiContext& g = *GImGui; - if (!(viewport->Flags & ImGuiViewportFlags_CanHostOtherWindows) || window->Viewport == viewport) + if (!(viewport->Flags & ImGuiViewportFlags_CanHostOtherWindows) || window->Viewport == viewport || viewport->PlatformIsMinimized) return; if (!viewport->GetRect().Contains(window->Rect())) return; @@ -7228,7 +7228,7 @@ static ImGuiViewportP* FindViewportHoveredFromPlatformWindowStack(const ImVec2 m for (int n = 0; n < g.Viewports.Size; n++) { ImGuiViewportP* viewport = g.Viewports[n]; - if (!(viewport->Flags & ImGuiViewportFlags_NoInputs) && viewport->GetRect().Contains(mouse_platform_pos)) + if (!(viewport->Flags & ImGuiViewportFlags_NoInputs) && !viewport->PlatformIsMinimized && viewport->GetRect().Contains(mouse_platform_pos)) if (best_candidate == NULL || best_candidate->LastFrontMostStampCount < viewport->LastFrontMostStampCount) best_candidate = viewport; } @@ -7277,12 +7277,18 @@ static void ImGui::UpdateViewports() if ((g.IO.ConfigFlags & ImGuiConfigFlags_ViewportsEnable)) { + if (g.PlatformIO.Platform_GetWindowMinimized && (n == 0 || viewport->CreatedPlatformWindow)) + viewport->PlatformIsMinimized = g.PlatformIO.Platform_GetWindowMinimized(viewport); + // Apply Position and Size (from Platform Window to ImGui) if requested. // We do it early in the frame instead of waiting for UpdatePlatformWindows() to avoid a frame of lag when moving/resizing using OS facilities. - if (viewport->PlatformRequestMove) - viewport->Pos = viewport->LastPlatformPos = g.PlatformIO.Platform_GetWindowPos(viewport); - if (viewport->PlatformRequestResize) - viewport->Size = viewport->LastPlatformSize = g.PlatformIO.Platform_GetWindowSize(viewport); + if (!viewport->PlatformIsMinimized) + { + if (viewport->PlatformRequestMove) + viewport->Pos = viewport->LastPlatformPos = g.PlatformIO.Platform_GetWindowPos(viewport); + if (viewport->PlatformRequestResize) + viewport->Size = viewport->LastPlatformSize = g.PlatformIO.Platform_GetWindowSize(viewport); + } // Translate imgui windows when a Host Viewport has been moved ImVec2 delta = viewport->Pos - viewport->LastPos; @@ -9866,7 +9872,8 @@ static void RenderViewportThumbnail(ImDrawList* draw_list, ImGuiViewportP* viewp ImVec2 scale = bb.GetSize() / viewport->Size; ImVec2 off = bb.Min - viewport->Pos * scale; - window->DrawList->AddRectFilled(bb.Min, bb.Max, ImGui::GetColorU32(ImGuiCol_Border, 0.40f)); + float alpha_mul = viewport->PlatformIsMinimized ? 0.30f : 1.00f; + window->DrawList->AddRectFilled(bb.Min, bb.Max, ImGui::GetColorU32(ImGuiCol_Border, alpha_mul * 0.40f)); for (int i = 0; i != g.Windows.Size; i++) { ImGuiWindow* thumb_window = g.Windows[i]; @@ -9884,12 +9891,12 @@ static void RenderViewportThumbnail(ImDrawList* draw_list, ImGuiViewportP* viewp thumb_r_scaled.ClipWithFull(bb); title_r_scaled.ClipWithFull(bb); const bool window_is_focused = (g.NavWindow && thumb_window->RootWindowForTitleBarHighlight == g.NavWindow->RootWindowForTitleBarHighlight); - window->DrawList->AddRectFilled(thumb_r_scaled.Min, thumb_r_scaled.Max, ImGui::GetColorU32(ImGuiCol_WindowBg)); - window->DrawList->AddRectFilled(title_r_scaled.Min, title_r_scaled.Max, ImGui::GetColorU32(window_is_focused ? ImGuiCol_TitleBgActive : ImGuiCol_TitleBg)); - window->DrawList->AddRect(thumb_r_scaled.Min, thumb_r_scaled.Max, ImGui::GetColorU32(ImGuiCol_Border)); - window->DrawList->AddText(g.Font, g.FontSize * 1.0f, title_r_scaled.Min, ImGui::GetColorU32(ImGuiCol_Text), thumb_window->Name, ImGui::FindRenderedTextEnd(thumb_window->Name)); + window->DrawList->AddRectFilled(thumb_r_scaled.Min, thumb_r_scaled.Max, ImGui::GetColorU32(ImGuiCol_WindowBg, alpha_mul)); + window->DrawList->AddRectFilled(title_r_scaled.Min, title_r_scaled.Max, ImGui::GetColorU32(window_is_focused ? ImGuiCol_TitleBgActive : ImGuiCol_TitleBg, alpha_mul)); + window->DrawList->AddRect(thumb_r_scaled.Min, thumb_r_scaled.Max, ImGui::GetColorU32(ImGuiCol_Border, alpha_mul)); + window->DrawList->AddText(g.Font, g.FontSize * 1.0f, title_r_scaled.Min, ImGui::GetColorU32(ImGuiCol_Text, alpha_mul), thumb_window->Name, ImGui::FindRenderedTextEnd(thumb_window->Name)); } - draw_list->AddRect(bb.Min, bb.Max, ImGui::GetColorU32(ImGuiCol_Border)); + draw_list->AddRect(bb.Min, bb.Max, ImGui::GetColorU32(ImGuiCol_Border, alpha_mul)); } void ImGui::ShowViewportThumbnails() @@ -10069,10 +10076,10 @@ void ImGui::ShowMetricsWindow(bool* p_open) ImGuiWindowFlags flags = viewport->Flags; ImGui::BulletText("Pos: (%.0f,%.0f), Size: (%.0f,%.0f), Monitor: %d, DpiScale: %.0f%%", viewport->Pos.x, viewport->Pos.y, viewport->Size.x, viewport->Size.y, viewport->PlatformMonitor, viewport->DpiScale * 100.0f); if (viewport->Idx > 0) { ImGui::SameLine(); if (ImGui::SmallButton("Reset Pos")) { viewport->Pos = ImVec2(200,200); if (viewport->Window) viewport->Window->Pos = ImVec2(200,200); } } - ImGui::BulletText("Flags: 0x%04X =%s%s%s%s%s", viewport->Flags, + ImGui::BulletText("Flags: 0x%04X =%s%s%s%s%s%s", viewport->Flags, (flags & ImGuiViewportFlags_CanHostOtherWindows) ? " CanHostOtherWindows" : "", (flags & ImGuiViewportFlags_NoDecoration) ? " NoDecoration" : "", (flags & ImGuiViewportFlags_NoFocusOnAppearing) ? " NoFocusOnAppearing" : "", (flags & ImGuiViewportFlags_NoInputs) ? " NoInputs" : "", - (flags & ImGuiViewportFlags_NoRendererClear) ? " NoRendererClear" : ""); + (flags & ImGuiViewportFlags_NoRendererClear) ? " NoRendererClear" : "", viewport->PlatformIsMinimized ? ", PlatformIsMinimized" : ""); for (int layer_i = 0; layer_i < IM_ARRAYSIZE(viewport->DrawDataBuilder.Layers); layer_i++) for (int draw_list_i = 0; draw_list_i < viewport->DrawDataBuilder.Layers[layer_i].Size; draw_list_i++) Funcs::NodeDrawList(NULL, viewport, viewport->DrawDataBuilder.Layers[layer_i][draw_list_i], "DrawList"); diff --git a/imgui.h b/imgui.h index b4062708..bee7411b 100644 --- a/imgui.h +++ b/imgui.h @@ -2047,6 +2047,7 @@ struct ImGuiPlatformIO ImVec2 (*Platform_GetWindowSize)(ImGuiViewport* vp); void (*Platform_SetWindowFocus)(ImGuiViewport* vp); // Move window to front and set input focus bool (*Platform_GetWindowFocus)(ImGuiViewport* vp); + bool (*Platform_GetWindowMinimized)(ImGuiViewport* vp); void (*Platform_SetWindowTitle)(ImGuiViewport* vp, const char* title); void (*Platform_SetWindowAlpha)(ImGuiViewport* vp, float alpha); // (Optional) Setup window transparency void (*Platform_RenderWindow)(ImGuiViewport* vp, void* render_arg); // (Optional) Setup for render (platform side) diff --git a/imgui_internal.h b/imgui_internal.h index 83a4c326..4f623c25 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -607,6 +607,7 @@ struct ImGuiViewportP : public ImGuiViewport float Alpha; // Window opacity (when dragging dockable windows/viewports we make them transparent) float LastAlpha; int PlatformMonitor; + bool PlatformIsMinimized; ImGuiWindow* Window; ImDrawList* OverlayDrawList; // For convenience, a draw list we can render to that's always rendered last (we use it to draw software mouse cursor when io.MouseDrawCursor is set) ImDrawData DrawDataP; @@ -615,7 +616,7 @@ struct ImGuiViewportP : public ImGuiViewport ImVec2 LastPlatformSize; ImVec2 LastRendererSize; - ImGuiViewportP() { Idx = -1; LastFrameActive = LastFrameOverlayDrawList = LastFrontMostStampCount = -1; LastNameHash = 0; CreatedPlatformWindow = false; Alpha = LastAlpha = 1.0f; PlatformMonitor = INT_MIN; Window = NULL; OverlayDrawList = NULL; LastPlatformPos = LastPlatformSize = LastRendererSize = ImVec2(FLT_MAX, FLT_MAX); } + ImGuiViewportP() { Idx = -1; LastFrameActive = LastFrameOverlayDrawList = LastFrontMostStampCount = -1; LastNameHash = 0; CreatedPlatformWindow = false; Alpha = LastAlpha = 1.0f; PlatformMonitor = INT_MIN; PlatformIsMinimized = false; Window = NULL; OverlayDrawList = NULL; LastPlatformPos = LastPlatformSize = LastRendererSize = ImVec2(FLT_MAX, FLT_MAX); } ~ImGuiViewportP() { if (OverlayDrawList) IM_DELETE(OverlayDrawList); } ImRect GetRect() const { return ImRect(Pos.x, Pos.y, Pos.x + Size.x, Pos.y + Size.y); } ImVec2 GetCenter() const{ return ImVec2(Pos.x + Size.x * 0.5f, Pos.y + Size.y * 0.5f); } From 35d648341b6bbf030512605952814815c58e1104 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 23 Nov 2018 18:12:37 +0100 Subject: [PATCH 8/9] Examples: SDL: changed the signature of ImGui_ImplSDL2_ProcessEvent() to use a const SDL_Event*. (#2187) --- docs/CHANGELOG.txt | 2 ++ examples/imgui_impl_sdl.cpp | 4 +++- examples/imgui_impl_sdl.h | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index c147284d..a4ae37fd 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -37,6 +37,8 @@ Breaking Changes: Other Changes: +- Examples: SDL: changed the signature of ImGui_ImplSDL2_ProcessEvent() to use a const SDL_Event*. (#2187) + ----------------------------------------------------------------------- VERSION 1.66 (Released 2018-11-22) diff --git a/examples/imgui_impl_sdl.cpp b/examples/imgui_impl_sdl.cpp index 21f8df71..2b6d97e0 100644 --- a/examples/imgui_impl_sdl.cpp +++ b/examples/imgui_impl_sdl.cpp @@ -16,6 +16,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) +// 2018-11-14: Changed the signature of ImGui_ImplSDL2_ProcessEvent() to take a 'const SDL_Event*'. // 2018-08-01: Inputs: Workaround for Emscripten which doesn't seem to handle focus related calls. // 2018-06-29: Inputs: Added support for the ImGuiMouseCursor_Hand cursor. // 2018-06-08: Misc: Extracted imgui_impl_sdl.cpp/.h away from the old combined SDL2+OpenGL/Vulkan examples. @@ -72,7 +73,8 @@ static void ImGui_ImplSDL2_SetClipboardText(void*, const char* text) // - When io.WantCaptureMouse is true, do not dispatch mouse input data to your main application. // - When io.WantCaptureKeyboard is true, do not dispatch keyboard input data to your main application. // Generally you may always pass all inputs to dear imgui, and hide them from your application based on those two flags. -bool ImGui_ImplSDL2_ProcessEvent(SDL_Event* event) +// If you have multiple SDL events and some of them are not meant to be used by dear imgui, you may need to filter events based on their windowID field. +bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event) { ImGuiIO& io = ImGui::GetIO(); switch (event->type) diff --git a/examples/imgui_impl_sdl.h b/examples/imgui_impl_sdl.h index 124d7048..ec8190cc 100644 --- a/examples/imgui_impl_sdl.h +++ b/examples/imgui_impl_sdl.h @@ -23,4 +23,4 @@ IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForOpenGL(SDL_Window* window, void* s IMGUI_IMPL_API bool ImGui_ImplSDL2_InitForVulkan(SDL_Window* window); IMGUI_IMPL_API void ImGui_ImplSDL2_Shutdown(); IMGUI_IMPL_API void ImGui_ImplSDL2_NewFrame(SDL_Window* window); -IMGUI_IMPL_API bool ImGui_ImplSDL2_ProcessEvent(SDL_Event* event); +IMGUI_IMPL_API bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event); From 379733aba12279fedc7790b87a6b27e1f68b258d Mon Sep 17 00:00:00 2001 From: omar Date: Mon, 26 Nov 2018 14:53:04 +0100 Subject: [PATCH 9/9] Viewport: Fix viewport regression with protruding child window creating their own viewport. (fixes cae4d02, 760c1d95) (#1542) --- imgui.cpp | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 77e7cdd5..2afa1d45 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -7498,6 +7498,10 @@ static void ImGui::UpdateSelectWindowViewport(ImGuiWindow* window) window->Viewport = AddUpdateViewport(window, window->ID, window->Pos, window->Size, ImGuiViewportFlags_None); } + // Fallback to default viewport + if (window->Viewport == NULL) + window->Viewport = main_viewport; + // Mark window as allowed to protrude outside of its viewport and into the current monitor // We need to take account of the possibility that mouse may become invalid. if (flags & (ImGuiWindowFlags_Tooltip | ImGuiWindowFlags_Popup)) @@ -7507,15 +7511,8 @@ static void ImGui::UpdateSelectWindowViewport(ImGuiWindow* window) bool mouse_valid = IsMousePosValid(&mouse_ref); if ((window->Appearing || (flags & ImGuiWindowFlags_Tooltip)) && (!use_mouse_ref || mouse_valid)) window->ViewportAllowPlatformMonitorExtend = FindPlatformMonitorForPos((use_mouse_ref && mouse_valid) ? mouse_ref : NavCalcPreferredRefPos()); - else - window->ViewportAllowPlatformMonitorExtend = window->Viewport->PlatformMonitor; } - - // Fallback to default viewport - if (window->Viewport == NULL) - window->Viewport = main_viewport; - - if (window->ViewportAllowPlatformMonitorExtend < 0) + if (window->ViewportAllowPlatformMonitorExtend < 0 && (flags & ImGuiWindowFlags_ChildWindow) == 0) window->ViewportAllowPlatformMonitorExtend = window->Viewport->PlatformMonitor; // Update flags