hoffstadt / DearPyGui

Dear PyGui: A fast and powerful Graphical User Interface Toolkit for Python with minimal dependencies

Home Page:https://dearpygui.readthedocs.io/en/latest/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Viewport client size is reported incorrectly at startup

v-ein opened this issue · comments

Version of Dear PyGui

Version: 1.11
Operating System: Windows 10

My Issue/Question

If dpg.get_viewport_client_width/height is called at application startup or in the first few frames, it reports outer size of the viewport instead of client size.

Here's a more detailed description from Discord, assuming a 1000x500 pixels viewport:


1000x500 are "external" width and height of the viewport window. The client width and height receive these values at the start, in dpg.show_viewport (IMHO, this is what's causing confusion - it would be better if they defaulted to zero at the start, or maybe they could be set as 984x461 at the start, too).

984x461 is the size of the inner area where DPG renders its UI, which is called the client area. It's smaller than the outer size by the size of window borders and its title bar.

On Windows, the client size gets updated every time WM_PAINT is received, that is, when Windows tells the viewport to render. It is different from DPG performing rendering on its own in a loop. So what happens at the start of your app is:

  • You call create_viewport with width/height set to 1000x500.
  • You call show_viewport and at this point the client size, as reported by DPG, are set to be 1000x500. Also, DPG creates a Windows window of that size.
  • Windows probably puts a WM_PAINT message into the window queue right away, though here I'm not sure. It doesn't matter, really.
  • You start the rendering loop.
  • DPG starts rendering frames at a certain FPS rate (e.g. 60 FPS).
  • Several milliseconds later, WM_PAINT is processed by DPG. By this time, DPG has already rendered several frames, but it's only now that the WM_PAINT handler updates the client size within DPG to what it actually is, 984x461.

This sequence only applies to Windows. On Linux/MacOS it's slightly different, though in the end you get correct readings of the client size anyway.


To Reproduce

Run the example below, click the button and look into the console.

Expected behavior

Report the correct client size as soon as possible (which is probably earlier than the first WM_PAINT). If there's time interval where the client area is not available yet (e.g. even before the viewport's window got created), report client size as (0, 0).

Screenshots/Video

None.

Standalone, minimal, complete and verifiable example

import dearpygui.dearpygui as dpg

dpg.create_context()
dpg.setup_dearpygui()
dpg.create_viewport(title="Test", width=600, height=600)

with dpg.window():
    btn = dpg.add_button(label="Get it", callback=lambda: print((dpg.get_viewport_client_width(), dpg.get_viewport_client_height())))

dpg.show_viewport()
print((dpg.get_viewport_client_width(), dpg.get_viewport_client_height()))
dpg.start_dearpygui()
dpg.destroy_context()

This example prints (600, 600) at startup and something like (592, 573) (YMMV) when the button is clicked.