diff --git a/backends/imgui_impl_glfw.cpp b/backends/imgui_impl_glfw.cpp index 756958e03..f71462e0a 100644 --- a/backends/imgui_impl_glfw.cpp +++ b/backends/imgui_impl_glfw.cpp @@ -30,6 +30,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) // 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. +// 2025-02-21: [Docking] Update monitors and work areas information every frame, as the later may change regardless of monitor changes. (#8415) // 2024-11-05: [Docking] Added Linux workaround for spurious mouse up events emitted while dragging and creating new viewport. (#3158, #7733, #7922) // 2024-08-22: moved some OS/backend related function pointers from ImGuiIO to ImGuiPlatformIO: // - io.GetClipboardTextFn -> platform_io.Platform_GetClipboardTextFn @@ -180,7 +181,6 @@ struct ImGui_ImplGlfw_Data GLFWwindow* KeyOwnerWindows[GLFW_KEY_LAST]; bool InstalledCallbacks; bool CallbacksChainForAllWindows; - bool WantUpdateMonitors; #ifdef EMSCRIPTEN_USE_EMBEDDED_GLFW3 const char* CanvasSelector; #endif @@ -519,8 +519,7 @@ void ImGui_ImplGlfw_CharCallback(GLFWwindow* window, unsigned int c) void ImGui_ImplGlfw_MonitorCallback(GLFWmonitor*, int) { - ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); - bd->WantUpdateMonitors = true; + // This function is technically part of the API even if we stopped using the callback, so leaving it around. } #ifdef EMSCRIPTEN_USE_EMBEDDED_GLFW3 @@ -627,7 +626,6 @@ static bool ImGui_ImplGlfw_Init(GLFWwindow* window, bool install_callbacks, Glfw bd->Window = window; bd->Time = 0.0; - bd->WantUpdateMonitors = true; ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); platform_io.Platform_SetClipboardTextFn = [](ImGuiContext*, const char* text) { glfwSetClipboardString(nullptr, text); }; @@ -910,9 +908,7 @@ static void ImGui_ImplGlfw_UpdateGamepads() static void ImGui_ImplGlfw_UpdateMonitors() { - ImGui_ImplGlfw_Data* bd = ImGui_ImplGlfw_GetBackendData(); ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); - bd->WantUpdateMonitors = false; int monitors_count = 0; GLFWmonitor** glfw_monitors = glfwGetMonitors(&monitors_count); @@ -966,8 +962,7 @@ void ImGui_ImplGlfw_NewFrame() io.DisplaySize = ImVec2((float)w, (float)h); if (w > 0 && h > 0) io.DisplayFramebufferScale = ImVec2((float)display_w / (float)w, (float)display_h / (float)h); - if (bd->WantUpdateMonitors) - ImGui_ImplGlfw_UpdateMonitors(); + ImGui_ImplGlfw_UpdateMonitors(); // Setup time step // (Accept glfwGetTime() not returning a monotonically increasing value. Seems to happens on disconnecting peripherals and probably on VMs and Emscripten, see #6491, #6189, #6114, #3644) diff --git a/backends/imgui_impl_sdl2.cpp b/backends/imgui_impl_sdl2.cpp index 9d82efe07..190668cfd 100644 --- a/backends/imgui_impl_sdl2.cpp +++ b/backends/imgui_impl_sdl2.cpp @@ -26,6 +26,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) // 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. +// 2025-02-21: [Docking] Update monitors and work areas information every frame, as the later may change regardless of monitor changes. (#8415) // 2025-02-10: Using SDL_OpenURL() in platform_io.Platform_OpenInShellFn handler. // 2025-01-20: Made ImGui_ImplSDL2_SetGamepadMode(ImGui_ImplSDL2_GamepadMode_Manual) accept an empty array. // 2024-10-24: Emscripten: from SDL 2.30.9, SDL_EVENT_MOUSE_WHEEL event doesn't require dividing by 100.0f. @@ -144,7 +145,6 @@ struct ImGui_ImplSDL2_Data Uint64 Time; char* ClipboardTextData; bool UseVulkan; - bool WantUpdateMonitors; // Mouse handling Uint32 MouseWindowID; @@ -436,15 +436,6 @@ bool ImGui_ImplSDL2_ProcessEvent(const SDL_Event* event) io.SetKeyEventNativeData(key, event->key.keysym.sym, event->key.keysym.scancode, event->key.keysym.scancode); // To support legacy indexing (<1.87 user code). Legacy backend uses SDLK_*** as indices to IsKeyXXX() functions. return true; } -#if SDL_HAS_DISPLAY_EVENT - case SDL_DISPLAYEVENT: - { - // 2.0.26 has SDL_DISPLAYEVENT_CONNECTED/SDL_DISPLAYEVENT_DISCONNECTED/SDL_DISPLAYEVENT_ORIENTATION, - // so change of DPI/Scaling are not reflected in this event. (SDL3 has it) - bd->WantUpdateMonitors = true; - return true; - } -#endif case SDL_WINDOWEVENT: { ImGuiViewport* viewport = ImGui_ImplSDL2_GetViewportForWindowID(event->window.windowID); @@ -862,10 +853,8 @@ static void ImGui_ImplSDL2_UpdateGamepads() // FIXME: Note that doesn't update with DPI/Scaling change only as SDL2 doesn't have an event for it (SDL3 has). static void ImGui_ImplSDL2_UpdateMonitors() { - ImGui_ImplSDL2_Data* bd = ImGui_ImplSDL2_GetBackendData(); ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); platform_io.Monitors.resize(0); - bd->WantUpdateMonitors = false; int display_count = SDL_GetNumVideoDisplays(); for (int n = 0; n < display_count; n++) { @@ -921,8 +910,7 @@ void ImGui_ImplSDL2_NewFrame() io.DisplayFramebufferScale = ImVec2((float)display_w / w, (float)display_h / h); // Update monitors - if (bd->WantUpdateMonitors) - ImGui_ImplSDL2_UpdateMonitors(); + ImGui_ImplSDL2_UpdateMonitors(); // Setup time step (we don't use SDL_GetTicks() because it is using millisecond resolution) // (Accept SDL_GetPerformanceCounter() not returning a monotonically increasing value. Happens in VMs and Emscripten, see #6189, #6114, #3644) diff --git a/backends/imgui_impl_sdl3.cpp b/backends/imgui_impl_sdl3.cpp index 7deeee192..55f618d1d 100644 --- a/backends/imgui_impl_sdl3.cpp +++ b/backends/imgui_impl_sdl3.cpp @@ -24,6 +24,7 @@ // CHANGELOG // (minor and older changes stripped away, please see git history for details) // 2025-XX-XX: Platform: Added support for multiple windows via the ImGuiPlatformIO interface. +// 2025-02-21: [Docking] Update monitors and work areas information every frame, as the later may change regardless of monitor changes. (#8415) // 2025-02-10: Using SDL_OpenURL() in platform_io.Platform_OpenInShellFn handler. // 2025-01-20: Made ImGui_ImplSDL3_SetGamepadMode(ImGui_ImplSDL3_GamepadMode_Manual) accept an empty array. // 2024-10-24: Emscripten: SDL_EVENT_MOUSE_WHEEL event doesn't require dividing by 100.0f on Emscripten. @@ -99,7 +100,6 @@ struct ImGui_ImplSDL3_Data Uint64 Time; char* ClipboardTextData; bool UseVulkan; - bool WantUpdateMonitors; // IME handling SDL_Window* ImeWindow; @@ -400,15 +400,6 @@ bool ImGui_ImplSDL3_ProcessEvent(const SDL_Event* event) io.SetKeyEventNativeData(key, event->key.key, event->key.scancode, event->key.scancode); // To support legacy indexing (<1.87 user code). Legacy backend uses SDLK_*** as indices to IsKeyXXX() functions. return true; } - case SDL_EVENT_DISPLAY_ORIENTATION: - case SDL_EVENT_DISPLAY_ADDED: - case SDL_EVENT_DISPLAY_REMOVED: - case SDL_EVENT_DISPLAY_MOVED: - case SDL_EVENT_DISPLAY_CONTENT_SCALE_CHANGED: - { - bd->WantUpdateMonitors = true; - return true; - } case SDL_EVENT_WINDOW_MOUSE_ENTER: { if (ImGui_ImplSDL3_GetViewportForWindowID(event->window.windowID) == nullptr) @@ -824,10 +815,8 @@ static void ImGui_ImplSDL3_UpdateGamepads() static void ImGui_ImplSDL3_UpdateMonitors() { - ImGui_ImplSDL3_Data* bd = ImGui_ImplSDL3_GetBackendData(); ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO(); platform_io.Monitors.resize(0); - bd->WantUpdateMonitors = false; int display_count; SDL_DisplayID* displays = SDL_GetDisplays(&display_count); @@ -872,8 +861,7 @@ void ImGui_ImplSDL3_NewFrame() io.DisplayFramebufferScale = ImVec2((float)display_w / w, (float)display_h / h); // Update monitors - if (bd->WantUpdateMonitors) - ImGui_ImplSDL3_UpdateMonitors(); + ImGui_ImplSDL3_UpdateMonitors(); // Setup time step (we don't use SDL_GetTicks() because it is using millisecond resolution) // (Accept SDL_GetPerformanceCounter() not returning a monotonically increasing value. Happens in VMs and Emscripten, see #6189, #6114, #3644) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 71a36a6bb..f19515687 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -99,6 +99,8 @@ Docking+Viewports Branch: - Viewports: fixed an assert when a window load settings with a position outside monitor bounds, when there are multiple monitors. (#8393, #8385) [@gaborodriguez] +- Backends: GLFW, SDL2/SDL3: Update monitors and work areas information every frame, + as the later may change regardless of monitor/display changes. (#8415) - Backends: Win32: WM_SETTINGCHANGE's SPI_SETWORKAREA message also triggers a refresh of monitor list, as they contain work area information. (#8415) [@PathogenDavid, @lailoken]