Open Artrender opened 7 months ago
Can you report the contents of the platform_io.Monitors[] array, and find how/why that data is emitted from the GLFW platform callback?
Also please report the return value of glfwGetMonitorContentScale()
.
I used: //platform_io.Monitors[]
ImGuiPlatformIO& platform_io = ImGui::GetPlatformIO();
for (int i = 0; i < platform_io.Monitors.Size; i++)
{
const ImGuiPlatformMonitor& mon = platform_io.Monitors[i];
// Print or log the monitor information
printf("Monitor %d:\n", i);
printf(" MainPos: (%.1f, %.1f)\n", mon.MainPos.x, mon.MainPos.y);
printf(" MainSize: (%.1f, %.1f)\n", mon.MainSize.x, mon.MainSize.y);
printf(" WorkPos: (%.1f, %.1f)\n", mon.WorkPos.x, mon.WorkPos.y);
printf(" WorkSize: (%.1f, %.1f)\n", mon.WorkSize.x, mon.WorkSize.y);
printf(" DpiScale: %.1f\n\n", mon.DpiScale);
}
//Get Monitor Content Scale
int monitorCount;
GLFWmonitor** monitors = glfwGetMonitors(&monitorCount);
for (int i = 0; i < monitorCount; ++i)
{
float xscale, yscale;
glfwGetMonitorContentScale(monitors[i], &xscale, &yscale);
printf("Monitor %d content scale: x = %f, y = %f\n", i, xscale, yscale);
}
Got: Monitor 0: MainPos: (0.0, 0.0) MainSize: (3840.0, 2160.0) WorkPos: (0.0, 0.0) WorkSize: (3840.0, 2088.0) DpiScale: 1.5
Monitor 1: MainPos: (-3840.0, 0.0) MainSize: (3840.0, 2160.0) WorkPos: (-4608.0, 0.0) WorkSize: (4608.0, 2520.0) DpiScale: 1.5
Monitor 0 content scale: x = 1.500000, y = 1.500000 Monitor 1 content scale: x = 1.500000, y = 1.500000 Assertion failed: ImRect(mon.MainPos, mon.MainPos + mon.MainSize).Contains(ImRect(mon.WorkPos, mon.WorkPos + mon.WorkSize)) && "Monitor work bounds not setup properly. If you don't have work area information, just copy MainPos/MainSize into them.", file H:\DigitalEdge\imgui-base-app\imgui\imgui.cpp, line 10048
But it looks that this is not accurate information from glfw, as the scale for Monitor 1 (in Windows it is 2) is 125%, not 150%
This looks incorrect:
MainPos: (-3840.0, 0.0)
MainSize: (3840.0, 2160.0)
WorkPos: (-4608.0, 0.0)
WorkSize: (4608.0, 2520.0)
WorkPos/WorkSize doesn't fit in MainPos/MainSize.
Can you try examples/example_win32_directx11
and examples/example_sdl2_opengl3
?
See what is reported by those? You can visualize the Monitors information in Demo->Tools->Metrics->Viewport.
Just check if the WorkPos/WorkSize looks correct with those.
Depending on the result of this we can see where to investigate further.
But it looks that this is not accurate information from glfw, as the scale for Monitor 1 (in Windows it is 2) is 125%, not 150%
DPI feedback in Windows is a mess (depends on app manifest, process settings, etc.), so I wouldn't worry too much about that but indeed it is odd.
Thank you, Omar, for your prompt responses. It seems that I have identified the potential cause of the issue.
The error occurs when I use the SetProcessDPIAware() function, and it only happens with certain monitors. Using this function might be affecting how the application handles DPI scaling, especially when interacting with monitors that have different DPI settings.
Should I refrain from using SetProcessDPIAware() in the future to avoid such issues? Is there a recommended approach to ensure DPI awareness across various monitors that you would suggest?
It would be good if you compared with Win32 and SDL2 backends as requested.
Should I refrain from using SetProcessDPIAware() in the future to avoid such issues? Is there a recommended approach to ensure DPI awareness across various monitors that you would suggest?
I don't know. This may be a GLFW bug as well, without additional information I cannot tell.
Had the same issue. Resolved it by calling SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2)
instead of SetProcessDPIAware()
.
With SetProcessDPIAware()
in ImGui_Impl_glfw.cpp :
#if GLFW_HAS_PER_MONITOR_DPI
// Warning: the validity of monitor DPI information on Windows depends on the application DPI awareness settings, which generally needs to be set in the manifest or at runtime.
float x_scale, y_scale; // <----- THESE VALUES END UP BEING 0.0f but only for one of my three monitors.
glfwGetMonitorContentScale(glfw_monitors[n], &x_scale, &y_scale);
if (x_scale == 0.0f || y_scale == 0.0f)
{
const char* err_desc = nullptr; //<------- Win32: Failed to query monitor DPI
int error_code = glfwGetError(&err_desc); // <-------------- ERROR CODE 65544
}
monitor.DpiScale = x_scale;
#endif
...
SetProcessDpiAwarenessContext(DPI_AWARENESS_CONTEXT_PER_MONITOR_AWARE_V2)
resolves this.
Version/Branch of Dear ImGui:
Version 1.90.1 WIP, Branch:docking
Back-ends:
imgui_impl_opengl3.cpp + imgui_impl_glfw.cpp
Compiler, OS:
Windows 11 Visual Studio 2022, Windows 10 Visual Studio 2019
Full config/build information:
No response
Details:
My Issue: Assertion failed! Error for some monitors 4k with a scale less than 150% on Windows 11 and on one monitor on Windows 10 with the latest GLFW library updated to v 3.3
At startup of the application it gives:
Microsoft Visual C++ Runtime Library
Assertion failed!
Program: ...m File: ...:...\imgui\imgui.cpp Line: 9880
Expression: ImRect(mon.MainPos, mon.MainPos + mon.MainSize).Contains(ImRect(mon.WorkPos, mon.WorkPos + mon.WorkSize)) && "Monitor work bounds not setup properly. If you don't have work area information, just copy MainPos/MainSize into them."
For information on how your program can cause an assertion failure, see the Visual C++ documentation on asserts
(Press Retry to debug the application - JIT must be enabled)
Abort Retry Ignore
Screenshots/Video:
The error disappears if I downgrade to GLFW lib 3.2, but I loose many features that I need - like transparent GLFW and frameless.