From 32f9dfc1261e4b8dd4a026588ee966c200b7f3f0 Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 26 Jun 2024 14:32:48 +0200 Subject: [PATCH] Viewports: Backported 'void* ImGuiViewport::PlatformHandle' from docking branch for use by backends. --- backends/imgui_impl_glfw.cpp | 15 ++++++++------- backends/imgui_impl_osx.mm | 4 +++- backends/imgui_impl_sdl2.cpp | 17 +++++++++-------- backends/imgui_impl_sdl3.cpp | 2 +- backends/imgui_impl_win32.cpp | 3 ++- docs/CHANGELOG.txt | 2 ++ imgui.h | 3 ++- 7 files changed, 27 insertions(+), 19 deletions(-) diff --git a/backends/imgui_impl_glfw.cpp b/backends/imgui_impl_glfw.cpp index 883917875fa3..3c95f178660b 100644 --- a/backends/imgui_impl_glfw.cpp +++ b/backends/imgui_impl_glfw.cpp @@ -145,7 +145,7 @@ struct ImGui_ImplGlfw_Data GLFWcharfun PrevUserCallbackChar; GLFWmonitorfun PrevUserCallbackMonitor; #ifdef _WIN32 - WNDPROC GlfwWndProc; + WNDPROC PrevWndProc; #endif ImGui_ImplGlfw_Data() { memset((void*)this, 0, sizeof(*this)); } @@ -497,7 +497,7 @@ static LRESULT CALLBACK ImGui_ImplGlfw_WndProc(HWND hWnd, UINT msg, WPARAM wPara ImGui::GetIO().AddMouseSourceEvent(GetMouseSourceFromMessageExtraInfo()); break; } - return ::CallWindowProcW(bd->GlfwWndProc, hWnd, msg, wParam, lParam); + return ::CallWindowProcW(bd->PrevWndProc, hWnd, msg, wParam, lParam); } #endif @@ -612,6 +612,7 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw // Set platform dependent data in viewport ImGuiViewport* main_viewport = ImGui::GetMainViewport(); + main_viewport->PlatformHandle = (void*)bd->Window; #ifdef _WIN32 main_viewport->PlatformHandleRaw = glfwGetWin32Window(bd->Window); #elif defined(__APPLE__) @@ -622,8 +623,8 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw // Windows: register a WndProc hook so we can intercept some messages. #ifdef _WIN32 - bd->GlfwWndProc = (WNDPROC)::GetWindowLongPtrW((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC); - IM_ASSERT(bd->GlfwWndProc != nullptr); + bd->PrevWndProc = (WNDPROC)::GetWindowLongPtrW((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC); + IM_ASSERT(bd->PrevWndProc != nullptr); ::SetWindowLongPtrW((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC, (LONG_PTR)ImGui_ImplGlfw_WndProc); #endif @@ -661,11 +662,11 @@ void ImGui_ImplGlfw_Shutdown() for (ImGuiMouseCursor cursor_n = 0; cursor_n < ImGuiMouseCursor_COUNT; cursor_n++) glfwDestroyCursor(bd->MouseCursors[cursor_n]); - // Windows: register a WndProc hook so we can intercept some messages. + // Windows: restore our WndProc hook #ifdef _WIN32 ImGuiViewport* main_viewport = ImGui::GetMainViewport(); - ::SetWindowLongPtrW((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC, (LONG_PTR)bd->GlfwWndProc); - bd->GlfwWndProc = nullptr; + ::SetWindowLongPtrW((HWND)main_viewport->PlatformHandleRaw, GWLP_WNDPROC, (LONG_PTR)bd->PrevWndProc); + bd->PrevWndProc = nullptr; #endif io.BackendPlatformName = nullptr; diff --git a/backends/imgui_impl_osx.mm b/backends/imgui_impl_osx.mm index 322798022914..14cdd85cd00a 100644 --- a/backends/imgui_impl_osx.mm +++ b/backends/imgui_impl_osx.mm @@ -133,7 +133,7 @@ - (void)setImePosX:(float)posX imePosY:(float)posY - (void)updateImePosWithView:(NSView *)view { - NSWindow *window = view.window; + NSWindow* window = view.window; if (!window) return; NSRect contentRect = [window contentRectForFrameRect:window.frame]; @@ -402,6 +402,8 @@ bool ImGui_ImplOSX_Init(NSView* view) //io.BackendFlags |= ImGuiBackendFlags_HasSetMousePos; // We can honor io.WantSetMousePos requests (optional, rarely used) bd->Observer = [ImGuiObserver new]; + ImGuiViewport* main_viewport = ImGui::GetMainViewport(); + main_viewport->PlatformHandle = main_viewport->PlatformHandleRaw = (__bridge_retained void*)bd->Window; // Load cursors. Some of them are undocumented. bd->MouseCursorHidden = false; diff --git a/backends/imgui_impl_sdl2.cpp b/backends/imgui_impl_sdl2.cpp index 892fe9050fa1..a18c013fd4fb 100644 --- a/backends/imgui_impl_sdl2.cpp +++ b/backends/imgui_impl_sdl2.cpp @@ -397,7 +397,7 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event) return false; } -static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer) +static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer, void* sdl_gl_context) { ImGuiIO& io = ImGui::GetIO(); IMGUI_CHECKVERSION(); @@ -448,6 +448,7 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer) // Set platform dependent data in viewport // Our mouse update function expect PlatformHandle to be filled for the main viewport ImGuiViewport* main_viewport = ImGui::GetMainViewport(); + main_viewport->PlatformHandle = (void*)window; main_viewport->PlatformHandleRaw = nullptr; SDL_SysWMinfo info; SDL_VERSION(&info.version); @@ -481,13 +482,13 @@ static bool ImGui_ImplSDL2_Init(SDL_Window* window, SDL_Renderer* renderer) SDL_SetHint(SDL_HINT_MOUSE_AUTO_CAPTURE, "0"); #endif + (void)sdl_gl_context; // Unused in 'master' branch. return true; } bool ImGui_ImplSDL2_InitForOpenGL(SDL_Window* window, void* sdl_gl_context) { - IM_UNUSED(sdl_gl_context); // Viewport branch will need this. - return ImGui_ImplSDL2_Init(window, nullptr); + return ImGui_ImplSDL2_Init(window, nullptr, sdl_gl_context); } bool ImGui_ImplSDL2_InitForVulkan(SDL_Window* window) @@ -495,7 +496,7 @@ bool ImGui_ImplSDL2_InitForVulkan(SDL_Window* window) #if !SDL_HAS_VULKAN IM_ASSERT(0 && "Unsupported"); #endif - return ImGui_ImplSDL2_Init(window, nullptr); + return ImGui_ImplSDL2_Init(window, nullptr, nullptr); } bool ImGui_ImplSDL2_InitForD3D(SDL_Window* window) @@ -503,22 +504,22 @@ bool ImGui_ImplSDL2_InitForD3D(SDL_Window* window) #if !defined(_WIN32) IM_ASSERT(0 && "Unsupported"); #endif - return ImGui_ImplSDL2_Init(window, nullptr); + return ImGui_ImplSDL2_Init(window, nullptr, nullptr); } bool ImGui_ImplSDL2_InitForMetal(SDL_Window* window) { - return ImGui_ImplSDL2_Init(window, nullptr); + return ImGui_ImplSDL2_Init(window, nullptr, nullptr); } bool ImGui_ImplSDL2_InitForSDLRenderer(SDL_Window* window, SDL_Renderer* renderer) { - return ImGui_ImplSDL2_Init(window, renderer); + return ImGui_ImplSDL2_Init(window, renderer, nullptr); } bool ImGui_ImplSDL2_InitForOther(SDL_Window* window) { - return ImGui_ImplSDL2_Init(window, nullptr); + return ImGui_ImplSDL2_Init(window, nullptr, nullptr); } static void ImGui_ImplSDL2_CloseGamepads(); diff --git a/backends/imgui_impl_sdl3.cpp b/backends/imgui_impl_sdl3.cpp index 8b210b223e3a..189c6f412834 100644 --- a/backends/imgui_impl_sdl3.cpp +++ b/backends/imgui_impl_sdl3.cpp @@ -365,7 +365,7 @@ bool ImGui_ImplSDL3_ProcessEvent(const SDL_Event* event) static void ImGui_ImplSDL3_SetupPlatformHandles(ImGuiViewport* viewport, SDL_Window* window) { - IM_UNUSED(window); + viewport->PlatformHandle = window; viewport->PlatformHandleRaw = nullptr; #if defined(__WIN32__) && !defined(__WINRT__) viewport->PlatformHandleRaw = (HWND)SDL_GetProperty(SDL_GetWindowProperties(window), "SDL.window.win32.hwnd", nullptr); diff --git a/backends/imgui_impl_win32.cpp b/backends/imgui_impl_win32.cpp index 3e59b62e36b4..b0f694057908 100644 --- a/backends/imgui_impl_win32.cpp +++ b/backends/imgui_impl_win32.cpp @@ -169,7 +169,8 @@ static bool ImGui_ImplWin32_InitEx(void* hwnd, bool platform_has_own_dc) ImGui_ImplWin32_UpdateKeyboardCodePage(); // Set platform dependent data in viewport - ImGui::GetMainViewport()->PlatformHandleRaw = (void*)hwnd; + ImGuiViewport* main_viewport = ImGui::GetMainViewport(); + main_viewport->PlatformHandle = main_viewport->PlatformHandleRaw = (void*)bd->hWnd; IM_UNUSED(platform_has_own_dc); // Used in 'docking' branch // Dynamically load XInput library diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 3c3c6ad3c5ab..ed4c1d71866f 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -81,6 +81,8 @@ Other changes: frame instead of last drag source frame, which makes a difference if not resubmitting payload every frame. (#143) - Debug Tools: Metrics/Debugger: Browsing a Storage perform hover lookup on identifier. +- Viewports: Backported 'void* ImGuiViewport::PlatformHandle' from docking branch for + use by backends. - Backends: SDL3: Update for API removal of keysym field in SDL_KeyboardEvent. (#7728) - Backends: Vulkan: Remove Volk/ from volk.h #include directives. (#7722, #6582, #4854) [@martin-ejdestig] diff --git a/imgui.h b/imgui.h index e3c4db777f0a..95506954be78 100644 --- a/imgui.h +++ b/imgui.h @@ -2202,7 +2202,7 @@ struct ImGuiIO // - Backends may have other side-effects on focus loss, so this will reduce side-effects but not necessary remove all of them. bool ConfigDebugIgnoreFocusLoss; // = false // Ignore io.AddFocusEvent(false), consequently not calling io.ClearInputKeys()/io.ClearInputMouse() in input processing. - // Options to audit .ini data + // Option to audit .ini data bool ConfigDebugIniSettings; // = false // Save .ini data with extra comments (particularly helpful for Docking, but makes saving slower) //------------------------------------------------------------------ @@ -3240,6 +3240,7 @@ struct ImGuiViewport ImVec2 WorkSize; // Work Area: Size of the viewport minus task bars, menu bars, status bars (<= Size) // Platform/Backend Dependent Data + void* PlatformHandle; // void* to hold higher-level, platform window handle (e.g. HWND, GLFWWindow*, SDL_Window*) void* PlatformHandleRaw; // void* to hold lower-level, platform-native window handle (under Win32 this is expected to be a HWND, unused for other platforms) ImGuiViewport() { memset(this, 0, sizeof(*this)); }