Examples, Platform, Viewport: Fixed inconsistent window ownership issues. Added comments. Made Win32/SDL back-ends track ownership.

This commit is contained in:
omar
2018-04-09 22:01:24 +02:00
parent 56ad2a2d74
commit d4dd448511
9 changed files with 44 additions and 28 deletions

View File

@ -554,6 +554,7 @@ static void ImGui_ImplDX10_CreateWindow(ImGuiViewport* viewport)
static void ImGui_ImplDX10_DestroyWindow(ImGuiViewport* viewport)
{
// The main viewport (owned by the application) will always have RendererUserData == NULL here since we didn't create the data for it.
if (ImGuiViewportDataDx10* data = (ImGuiViewportDataDx10*)viewport->RendererUserData)
{
if (data->SwapChain)

View File

@ -561,6 +561,7 @@ static void ImGui_ImplDX11_CreateWindow(ImGuiViewport* viewport)
static void ImGui_ImplDX11_DestroyWindow(ImGuiViewport* viewport)
{
// The main viewport (owned by the application) will always have RendererUserData == NULL since we didn't create the data for it.
if (ImGuiViewportDataDx11* data = (ImGuiViewportDataDx11*)viewport->RendererUserData)
{
if (data->SwapChain)

View File

@ -690,6 +690,7 @@ static void ImGui_ImplDX12_CreateWindow(ImGuiViewport* viewport)
static void ImGui_ImplDX12_DestroyWindow(ImGuiViewport* viewport)
{
// The main viewport (owned by the application) will always have RendererUserData == NULL since we didn't create the data for it.
if (ImGuiViewportDataDx12* data = (ImGuiViewportDataDx12*)viewport->RendererUserData)
{
IM_ASSERT(0);

View File

@ -371,12 +371,14 @@ static void ImGui_ImplGlfw_DestroyWindow(ImGuiViewport* viewport)
{
if (ImGuiViewportDataGlfw* data = (ImGuiViewportDataGlfw*)viewport->PlatformUserData)
{
if (data->WindowOwned)
{
#if GLFW_HAS_GLFW_HOVERED
HWND hwnd = glfwGetWin32Window(data->Window);
::RemovePropA(hwnd, "IMGUI_VIEWPORT");
#endif
if (data->Window && data->WindowOwned)
HWND hwnd = glfwGetWin32Window(data->Window);
::RemovePropA(hwnd, "IMGUI_VIEWPORT");
#endif
glfwDestroyWindow(data->Window);
}
data->Window = NULL;
IM_DELETE(data);
}
@ -539,12 +541,13 @@ static void ImGui_ImplGlfw_InitPlatformInterface()
platform_io.Platform_CreateVkSurface = ImGui_ImplGlfw_CreateVkSurface;
#endif
// Register main window handle
// Register main window handle (which is owned by the main application, not by us)
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
ImGuiViewportDataGlfw* data = IM_NEW(ImGuiViewportDataGlfw)();
data->Window = g_Window;
data->WindowOwned = false;
main_viewport->PlatformUserData = data;
main_viewport->PlatformHandle = (void*)g_Window;
}
static void ImGui_ImplGlfw_ShutdownPlatformInterface()

View File

@ -285,9 +285,10 @@ struct ImGuiViewportDataSDL2
{
SDL_Window* Window;
Uint32 WindowID;
bool WindowOwned;
SDL_GLContext GLContext;
ImGuiViewportDataSDL2() { Window = NULL; WindowID = 0; GLContext = NULL; }
ImGuiViewportDataSDL2() { Window = NULL; WindowID = 0; WindowOwned = false; GLContext = NULL; }
~ImGuiViewportDataSDL2() { IM_ASSERT(Window == NULL && GLContext == NULL); }
};
@ -316,8 +317,8 @@ static void ImGui_ImplSDL2_CreateWindow(ImGuiViewport* viewport)
sdl_flags |= SDL_WINDOW_HIDDEN;
sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoDecoration) ? SDL_WINDOW_BORDERLESS : 0;
sdl_flags |= (viewport->Flags & ImGuiViewportFlags_NoDecoration) ? 0 : SDL_WINDOW_RESIZABLE;
data->Window = SDL_CreateWindow("No Title Yet",
(int)viewport->PlatformPos.x, (int)viewport->PlatformPos.y, (int)viewport->Size.x, (int)viewport->Size.y, sdl_flags);
data->Window = SDL_CreateWindow("No Title Yet", (int)viewport->PlatformPos.x, (int)viewport->PlatformPos.y, (int)viewport->Size.x, (int)viewport->Size.y, sdl_flags);
data->WindowOwned = true;
if (use_opengl)
data->GLContext = SDL_GL_CreateContext(data->Window);
if (use_opengl && backup_context)
@ -329,11 +330,11 @@ static void ImGui_ImplSDL2_DestroyWindow(ImGuiViewport* viewport)
{
if (ImGuiViewportDataSDL2* data = (ImGuiViewportDataSDL2*)viewport->PlatformUserData)
{
if (data->GLContext)
if (data->GLContext && data->WindowOwned)
SDL_GL_DeleteContext(data->GLContext);
data->GLContext = NULL;
if (data->Window)
if (data->Window && data->WindowOwned)
SDL_DestroyWindow(data->Window);
data->GLContext = NULL;
data->Window = NULL;
IM_DELETE(data);
}
@ -455,11 +456,12 @@ static void ImGui_ImplSDL2_InitPlatformInterface(SDL_Window* window, void* sdl_g
platform_io.Platform_CreateVkSurface = ImGui_ImplSDL2_CreateVkSurface;
#endif
// Register main window handle
// Register main window handle (which is owned by the main application, not by us)
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
ImGuiViewportDataSDL2* data = IM_NEW(ImGuiViewportDataSDL2)();
data->Window = window;
data->WindowID = SDL_GetWindowID(window);
data->WindowOwned = false;
data->GLContext = sdl_gl_context;
main_viewport->PlatformUserData = data;
main_viewport->PlatformHandle = data->Window;

View File

@ -1108,6 +1108,7 @@ static void ImGui_ImplVulkan_CreateWindow(ImGuiViewport* viewport)
static void ImGui_ImplVulkan_DestroyWindow(ImGuiViewport* viewport)
{
// The main viewport (owned by the application) will always have RendererUserData == NULL since we didn't create the data for it.
if (ImGuiViewportDataVulkan* data = (ImGuiViewportDataVulkan*)viewport->RendererUserData)
{
ImGui_ImplVulkanH_DestroyWindowData(g_Instance, g_Device, &data->WindowData, g_Allocator);

View File

@ -364,10 +364,11 @@ float ImGui_ImplWin32_GetDpiScaleForRect(int x1, int y1, int x2, int y2)
struct ImGuiViewportDataWin32
{
HWND Hwnd;
bool HwndOwned;
DWORD DwStyle;
DWORD DwExStyle;
ImGuiViewportDataWin32() { Hwnd = NULL; DwStyle = DwExStyle = 0; }
ImGuiViewportDataWin32() { Hwnd = NULL; HwndOwned = false; DwStyle = DwExStyle = 0; }
~ImGuiViewportDataWin32() { IM_ASSERT(Hwnd == NULL); }
};
@ -393,10 +394,11 @@ static void ImGui_ImplWin32_CreateWindow(ImGuiViewport* viewport)
// Create window
RECT rect = { (LONG)viewport->PlatformPos.x, (LONG)viewport->PlatformPos.y, (LONG)(viewport->PlatformPos.x + viewport->Size.x), (LONG)(viewport->PlatformPos.y + viewport->Size.y) };
::AdjustWindowRectEx(&rect, data->DwStyle, FALSE, data->DwExStyle);
data->Hwnd = ::CreateWindowExA(
data->DwExStyle, "ImGui Platform", "No Title Yet", data->DwStyle, // Style, class name, window name
rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, // Window area
g_hWnd, NULL, ::GetModuleHandle(NULL), NULL); // Parent window, Menu, Instance, Param
data->Hwnd = ::CreateWindowEx(
data->DwExStyle, _T("ImGui Platform"), _T("No Title Yet"), data->DwStyle, // Style, class name, window name
rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, // Window area
g_hWnd, NULL, ::GetModuleHandle(NULL), NULL); // Parent window, Menu, Instance, Param
data->HwndOwned = true;
viewport->PlatformRequestResize = false;
viewport->PlatformHandle = data->Hwnd;
}
@ -411,7 +413,7 @@ static void ImGui_ImplWin32_DestroyWindow(ImGuiViewport* viewport)
::ReleaseCapture();
::SetCapture(g_hWnd);
}
if (data->Hwnd)
if (data->Hwnd && data->HwndOwned)
::DestroyWindow(data->Hwnd);
data->Hwnd = NULL;
IM_DELETE(data);
@ -564,12 +566,13 @@ static void ImGui_ImplWin32_InitPlatformInterface()
platform_io.Platform_SetWindowAlpha = ImGui_ImplWin32_SetWindowAlpha;
platform_io.Platform_GetWindowDpiScale = ImGui_ImplWin32_GetWindowDpiScale;
// Register main window handle
// Register main window handle (which is owned by the main application, not by us)
ImGuiViewport* main_viewport = ImGui::GetMainViewport();
ImGuiViewportDataWin32* data = IM_NEW(ImGuiViewportDataWin32)();
data->Hwnd = g_hWnd;
data->HwndOwned = false;
main_viewport->PlatformUserData = data;
main_viewport->PlatformHandle = (void*)data->Hwnd;
main_viewport->PlatformHandle = (void*)g_hWnd;
}
static void ImGui_ImplWin32_ShutdownPlatformInterface()