pthom / imgui_bundle

Dear ImGui Bundle: an extensive set of Ready-to-use widgets and libraries, based on ImGui. Start your first app in 5 lines of code, or less. Whether you prefer Python or C++, this pack has your back!
https://pthom.github.io/imgui_bundle/
MIT License
590 stars 62 forks source link

Screen resolution and fontsize incorrect on windows 11 #180

Closed IvanCobotic closed 4 months ago

IvanCobotic commented 5 months ago

I run into some resolution / screen size issue when testing imgui bundle on windows 11.

when I create a fresh venv, then run pip install imgui-bundle demo_imgui_bundle

the window opens in an enlarged state, outside of my screen size. If i bring it back to within the screen the resolution is still enlarged and font size is bigger than normal. The same fenomena occurs for all demos in the package when i run them under windows.

If i run the browser based version or run imgui_bundle under wsl the resolution / font size are correct. We are however targeting a "platform independant" app and windows is important to me.

The screenshot below shows a side by side comparison of the windows 11 native and browser version. Im using python 3.11 Screenshot 2024-02-03 175754

my package versions are

pip freeze 
glfw==2.6.5
imgui-bundle==1.3.0
munch==4.0.0
numpy==1.26.3
pillow==10.2.0
PyGLM==2.7.1
PyOpenGL==3.1.7

other than the low resolution and enlarged font, the imgui_bundle seems to work fine on windows.

I previously worked with pyimgui without encountering scaling/ font size issues under windows, so im thinking this problem is something related to imgui_bundle under win11

IvanCobotic commented 5 months ago

I found this on the hello imgui issue tracker https://github.com/pthom/hello_imgui/issues/83

My System->Display->Scale (under Scale & layout) is set to 150% (Recommended) by default If i change this setting to 100% the imgui_bundle programs work correctly.

It clearly has something to do with the startup of the program, if I set scale to 100%, then start the demo_imgui_bundle, then set scale back to 150% the imgui_bundle program works correctly. I can switch monitors / resize the window etc and the dpi is still correct. But if scale is set to 150% when the imgui_bundle starts up, i get the low dpi version again.

pthom commented 5 months ago

Handling DPI on all platforms is a hard subject. HelloImGui tries to handle this automatically. it seems like it failed in your case. I need to study this.

pthom commented 4 months ago

I will correct this by adding user preferences, but it’s gonna take a few days

IvanCobotic commented 4 months ago

Sounds good! I tried to checkout the cpp version of hello_imgui and build it on my computer for windows. I get the same behaviour with the cpp demos (i ran the hello_imgui_demodocking.exe). The behaviour is basically that the app starts with correct resolution if the Windows My System->Display->Scale is set to 100% for my primary display. If Primary display scale is set to 150% i get the inflated DPI.

I also noticed that the backend that was used in my case was GLFW, for the GLFW backend DPI_awareness handling never gets called (it should be handled by imgui?) i.e. hello_imgui\internal\backend_impls\backend_window_helper\win32_dpi_awareness.cpp is only called if the backend is sdl, i.e src\hello_imgui\internal\backend_impls\backend_window_helper\sdl_window_helper.cpp has

#ifdef _WIN32
            if (backendOptions.dpiAwareSdl)
                Internal::ImGui_ImplWin32_EnableDpiAwareness();
#endif

i tested to add the same statement to glfw_window_helper.cpp, but this did not change anything.

I also noticed that in win32_dpi_awareness.cpp a return was recently removed after the

if (_IsWindows10OrGreater())

This causes both _IsWindows10OrGreater() and _IsWindows8Point1OrGreater() statements to be executed, I believe this is incorrect. According to MS documentation only one DPI_awareness call should be made and subsequent calls are ignored. Nevertheless, I tested commenting out the

        if (_IsWindows8Point1OrGreater())
        {
            std::ofstream debugFile("debug.txt", std::ios::app);  // Open 'debug.txt' in append mode
            if (debugFile.is_open()) {
                debugFile << "_IsWindows8Point1OrGreater" << std::endl;
                debugFile.close();
            }
            static HINSTANCE shcore_dll = ::LoadLibraryA("shcore.dll");  // Reference counted per-process
            if (PFN_SetProcessDpiAwareness SetProcessDpiAwarenessFn =
                    (PFN_SetProcessDpiAwareness)::GetProcAddress(shcore_dll, "SetProcessDpiAwareness"))
            {
                SetProcessDpiAwarenessFn(PROCESS_PER_MONITOR_DPI_AWARE);
                std::ofstream debugFile("debug.txt", std::ios::app);  // Open 'debug.txt' in append mode
                if (debugFile.is_open()) {
                    debugFile << "PROCESS_PER_MONITOR_DPI_AWARE" << std::endl;
                    debugFile.close();
                }
                return;
            }
        }

but this made no difference. I think I tried all possibilities for PROCESS_PER_MONITOR_DPI_AWARE etc settings, but nothing i tested changed the base behaviour, i.e. inflated when scale is higher than 100% and correct if scale is 100%.

pthom commented 4 months ago

glfw tried to make apps dpi aware, sdl does not, hence the difference.

Could you please place a breakpoint inside abstractrunner::DpiWindowSizeFactor

And tell me the value it returns ?

If it returns 1 we may be facing an issue inside glfw, otherwise I can handle it via a pref inside hello imgui.

pthom commented 4 months ago

I made an update to HelloImGui, it is summarized here: https://pthom.github.io/hello_imgui/book/doc_params.html#dpi-aware-params

Could you try adding an ini file and tell me if it helps with C++ HelloImGui.

Porting this to ImGui Bundle is gonna take a few more days

IvanCobotic commented 4 months ago

I pulled the changes to hello_imgui, rebuilt and added a hello_imgui.ini file under the hello_imgui folder, setting the contents to

     [DpiAwareParams]
     dpiWindowSizeFactor=1
     fontRenderingScale=1

Result -> demo app starts in a compressed state on the Laptop. If i drag the app to the monitor the app it displayed in the correct resolution.

Laptop

Screenshot 2024-02-06 091756

Monitor

Screenshot 2024-02-06 090203

The difference between Chrome and the windows app is that Chrome rescales the gui when i pull it from one display to the other. The windows app stays at the same scale and does not respond to scale change depending on the monitor.

So by setting the parameters in hello_imgui.ini i can get the app to look correctly on my monitor.

if I instead use

     [DpiAwareParams]
     dpiWindowSizeFactor=1.5
     fontRenderingScale=0.6666667

And start the app on my Laptop display -> scaling is correct. Actually the font looks crisper than chrome version even. However, the main app window is larger than my screen, so it opens with titlebar outside of the screen. Windows has a feature to draw apps back to screen area, but this causes the lower part of app to be outside of screen. This particular demo app dosnt have the maximize / minimize buttons, the only way to resize it is by dragging the lower right corner, and unfourtunately its not possible to access the lower right corner.

So to sum up, I can confirm that the hello_imgui.ini file has the intended effect It still does not allow a user to drag the app between screens with differet scaling while keeping correct resolution Starting on a screen with scaling 150% and correct DpiAwareParams may cause the app to open out of screen, causing issues for the user that may be hard to adjust.

pthom commented 4 months ago

Thanks for the testing!

It still does not allow a user to drag the app between screens with differet scaling while keeping correct resolution

Yes, this is a known quirk in ImGui, see https://github.com/ocornut/imgui/blob/master/docs/FAQ.md#q-how-should-i-handle-dpi-in-my-application

This particular demo app dosnt have the maximize / minimize buttons, the only way to resize it is by dragging the lower right corner, and unfourtunately its not possible to access the lower right corner.

Yes, it is actually using a borderless window with added resizing widgets. You can switch back to a standard window: comment out those lines: https://github.com/pthom/hello_imgui/blob/044fa385fc23f9553b4f23cb9547c7d2fe88f408/src/hello_imgui_demos/hello_imgui_demodocking/hello_imgui_demodocking.main.cpp#L666-L669

pthom commented 4 months ago

Could you test the cmake_install branch of imgui_bundle. It should add the same settings.

There are pre-compiled wheels in the artifact here

IvanCobotic commented 4 months ago

Cool. commenting out lines 666-669 in hello_imgui_demodocking.main.cpp brings back the title bar and i can rescale the window properly and display it on my laptop screen with Scale = 150%. its not exactly like the chrome version, but close enough. and actually the fonts look better in the windows app with [DpiAwareParams] dpiWindowSizeFactor=1.5 fontRenderingScale=0.6666667

Laptop

Screenshot 2024-02-06 130824

Since automatic rescaling between monitors is a known issue in imgui, i guess my final thought would be regarding window size at open. it would be nice if the window checked the scaled screen size on startup and adjusted its size to fit on the screen.

IvanCobotic commented 4 months ago

About testing the cmake of imgui_bundle, sure. But I have a question first, im not sure if my build setup is correct. When i run

cmake ..

in the build directory of hello_imgui, i get some error output,

cmake ..
-- Selecting Windows SDK version 10.0.22621.0 to target Windows 10.0.22631.
-- HELLOIMGUI_WITH_TEST_ENGINE=OFF
-- Library hello_imgui
-- Added installable dependency stb_hello_imgui, HELLOIMGUI_INSTALLABLE_DEPENDENCIES=stb_hello_imgui
-- HELLOIMGUI_USE_IMGUI_CMAKE_PACKAGE is OFF
-- Added installable dependency imgui, HELLOIMGUI_INSTALLABLE_DEPENDENCIES=stb_hello_imgui;imgui
-- HelloImGui: downloading and building freetype
CMake Deprecation Warning at build/_deps/freetype-src/CMakeLists.txt:113 (cmake_minimum_required):
  Compatibility with CMake < 3.5 will be removed from a future version of
  CMake.

  Update the VERSION argument <min> value or use a ...<max> suffix to tell
  CMake that the project does not need compatibility with older versions.

-- Could NOT find PkgConfig (missing: PKG_CONFIG_EXECUTABLE) 
CMake Warning at build/_deps/freetype-src/builds/cmake/FindHarfBuzz.cmake:99 (message):
  Required version (2.0.0) is higher than found version ()
Call Stack (most recent call first):
  build/_deps/freetype-src/CMakeLists.txt:258 (find_package)

-- Could NOT find ZLIB (missing: ZLIB_LIBRARY ZLIB_INCLUDE_DIR) 
-- Could NOT find PNG (missing: PNG_LIBRARY PNG_PNG_INCLUDE_DIR)
-- Could NOT find ZLIB (missing: ZLIB_LIBRARY ZLIB_INCLUDE_DIR) 
-- Could NOT find BZip2 (missing: BZIP2_LIBRARIES BZIP2_INCLUDE_DIR) 
-- Could NOT find BrotliDec (missing: BROTLIDEC_INCLUDE_DIRS BROTLIDEC_LIBRARIES) 
CMake Deprecation Warning at build/_deps/lunasvg-src/CMakeLists.txt:1 (cmake_minimum_required):
  Compatibility with CMake < 3.5 will be removed from a future version of
  CMake.

  Update the VERSION argument <min> value or use a ...<max> suffix to tell
  CMake that the project does not need compatibility with older versions.

-- Added installable dependency lunasvg, HELLOIMGUI_INSTALLABLE_DEPENDENCIES=stb_hello_imgui;imgui;lunasvg
-- Added installable dependency hello_imgui, HELLOIMGUI_INSTALLABLE_DEPENDENCIES=stb_hello_imgui;imgui;lunasvg;hello_imgui   
-- HelloImGui: downloading and building glfw
-- Using Win32 for window creation
-- Added installable dependency glfw, HELLOIMGUI_INSTALLABLE_DEPENDENCIES=stb_hello_imgui;imgui;lunasvg;hello_imgui;glfw
-- Added installable dependency glad, HELLOIMGUI_INSTALLABLE_DEPENDENCIES=stb_hello_imgui;imgui;lunasvg;hello_imgui;glfw;glad
-- HELLOIMGUI_INSTALLABLE_DEPENDENCIES=stb_hello_imgui;imgui;lunasvg;hello_imgui;glfw;glad
-- 
    ===========================================================================
        Hello ImGui build options:
    ===========================================================================
      Platform Backend(s):               HELLOIMGUI_USE_GLFW3
      Rendering Backend(s):              HELLOIMGUI_HAS_OPENGL3
    ---------------------------------------------------------------------------
      Options:
        HELLOIMGUI_USE_FREETYPE:        ON  (Use target freetype)
        HELLOIMGUI_WITH_TEST_ENGINE:    OFF
        BUILD_DEMOS - TESTS - DOCS:     ON - OFF - OFF
    ---------------------------------------------------------------------------
      ImGui:
        Build ImGui:                    ON
        ImGui source dir:               external/imgui
    ---------------------------------------------------------------------------
      OpenGL - use glad loader          ON
    ---------------------------------------------------------------------------
      Platform Backend(s):
        Glfw:                           Downloaded 3.3.8
    ---------------------------------------------------------------------------
      Windows:
        HELLOIMGUI_WIN32_NO_CONSOLE:    ON
        HELLOIMGUI_WIN32_AUTO_WINMAIN:  ON
    ===========================================================================
-- Configuring done (5.4s)
-- Generating done (2.2s)
-- Build files have been written to: C:/mygits/hello_imgui/build

im unsure about the warnings Could NOT find PkgConfig (missing: PKG_CONFIG_EXECUTABLE) CMake Warning at build/_deps/freetype-src/builds/cmake/FindHarfBuzz.cmake:99 (message): Required version (2.0.0) is higher than found version ()

-- Could NOT find ZLIB (missing: ZLIB_LIBRARY ZLIB_INCLUDE_DIR) -- Could NOT find PNG (missing: PNG_LIBRARY PNG_PNG_INCLUDE_DIR) -- Could NOT find ZLIB (missing: ZLIB_LIBRARY ZLIB_INCLUDE_DIR) -- Could NOT find BZip2 (missing: BZIP2_LIBRARIES BZIP2_INCLUDE_DIR) -- Could NOT find BrotliDec (missing: BROTLIDEC_INCLUDE_DIRS BROTLIDEC_LIBRARIES) CMake Deprecation Warning at build/_deps/lunasvg-src/CMakeLists.txt:1 (cmake_minimum_required): Compatibility with CMake < 3.5 will be removed from a future version of CMake.

im using cmake version 3.27.9, which i think is the latest? Are theese error messages normal / can be ignored? or am i really missing some dependecy? The demo programs seem to build correctly with

cmake --build .

at least the demodocker program..

IvanCobotic commented 4 months ago

at first i actually tried to install all the missing dependencies from the warnings, using vcpkg, but this got messy quick (I use python for a reason ;)). Then I noticed that it was actually possible to build the package despite the error messages..

IvanCobotic commented 4 months ago

ok, i cloned the repo at cmake_install (was faster then downloading the artifact)

build it with cmake .. / cmake --build .

Now when i run bin/Debug/demo_docking.exe it works perfectly!! scaling is correct on my laptop screen with 150% scale and the app opens with correct size that fits on the screen without adjustments. I didnt need to add any ini file or make corrections to window size, it just worked. It also works to open the app on the monitor screen with 100% scale. In both cases the app fits nicely on the screen and has correct scaling, without any extra adjustments on my side.

Im not sure why it suddenly worked, but im happy with the result, nice work!

IvanCobotic commented 4 months ago

glfw tried to make apps dpi aware, sdl does not, hence the difference.

Could you please place a breakpoint inside abstractrunner::DpiWindowSizeFactor

And tell me the value it returns ?

If it returns 1 we may be facing an issue inside glfw, otherwise I can handle it via a pref inside hello imgui.

Sorry, i missed this comment. Debugging in cpp is out of my league. Im using VSCode, i tried to setup debugging for hello_imgui but was not succesful. I can log to a file however,

after removing the hello_imgui.ini file (if that file is still in place this code is not executed) i log the value in line 310 in abstract_runner.cpp

Running on laptop screen with scale 150% gives dpiWindowSizeFactor: 1.5

Running on monitor with scale 100% dpiWindowSizeFactor: 1

Running on Laptop with scale 100% dpiWindowSizeFactor: 1

So dpiWindowSizeFactor is correctly detected on the primary monitor.

pthom commented 4 months ago

You can also pip install -v .