DearPyGui
DearPyGui copied to clipboard
Item resize handler handle only increasing of the primary window size
Version of Dear PyGui
Version: 1.7.1 Operating System: Windows 10 build 19044.2006
My Issue/Question
Item resize handler (mvAppItemType::mvResizeHandler
) calls its callback function in realtime while increasing size of the viewport with primary window. When viewport (as well as primary window) size is decreased callback is called only if mouse button released or if size increased again. Both bind_item_handler_registry
and set_viewport_resize_callback
have this bug.
The same bug could be seen in this example if the window is set to primary.
Important note: if the window is not primary, than callback is called in realtime both while increasing and decreasing the window size. Therefore for not primary windows resize item handler works as expected.
To Reproduce
- Create viewport.
- Create window and set it primary.
- Define resize callback function with some obvious actions (e. g. print).
- Create item resize handler.
- Bind handler to window and function.
- Set viewport resize callback to defined function.
- Run the program and try to change window (not dpg, OS window -- viewport) size in horizontal and vertical directions or both.
- Take a look in terminal. Callback do its job only while stretching and only once while size reducing (only when button released or stretching occured).
Expected behavior
I expect exactly the same behaviour in both directions.
Screenshots/Video
Demonstration of this bug can be seen on this video. As can be seen on the video I've used code from example below simply pasted in IPython.
Standalone, minimal, complete and verifiable example
# Here's shortest example which I could make.
import dearpygui.dearpygui as dpg
dpg.create_context()
dpg.create_viewport()
dpg.setup_dearpygui()
#Variable to show number of calls of the callback function below
i = 0
def resized():
global i
i += 1
print(f"Callback called {i} times.")
with dpg.window(tag="#main_window", label="tutorial"):
dpg.add_button(label="Press me")
dpg.set_primary_window("#main_window", True)
with dpg.item_handler_registry(tag="#resize_handler"):
dpg.add_item_resize_handler(callback=resized)
#Next two strings bind function resize to window and viewport resize events.
#Any of two may be commented as it will not affect on the bug
dpg.bind_item_handler_registry("#main_window", "#resize_handler")
dpg.set_viewport_resize_callback(resized)
dpg.show_viewport()
dpg.start_dearpygui()
dpg.destroy_context()
Found that this bug is platform-dependent. Under OpenSUSE example works properly -- callback is called in real-time both while increasing and decreasing viewport size.
Digging in DPG sources leads me to file mvViewport_win32.cpp->mvHandleMsg where in block case WM_SIZE
calling mvOnResize() is commented due to fixing issue #1250. I still couldn't check was this bug before this fix or not, because of lack of Python packages building skills.
There is also another interesting thing which in my opinion linked to this bug. To explain it let me show two facts here.
The first is that mvOnResize()
on Windows is called in two cases:
- In method
mvViewport_win32.cpp->mvHandleMsg
when messageWM_PAINT
received. - In
dearpygui_commands.h->render_dearpygui_frame
ifGContext->viewport->resized
is True.
To show the second fact I have to ask you to launch example below. It prints window height every render frame. But (seems there is a bug, too) if you try to drag the viewport horizontal edge changing its height then printing stops. I don't actually know if it stops rendering or not. Another interesting thing that in OpenSUSE this example don't stop printing while changing viewport size.
import dearpygui.dearpygui as dpg
dpg.create_context()
dpg.create_viewport()
dpg.setup_dearpygui()
with dpg.window(tag="#Window"):
dpg.add_text("Hello, world")
dpg.show_viewport()
dpg.set_primary_window("#Window", True)
while dpg.is_dearpygui_running():
print(dpg.get_item_height("#Window"))
dpg.render_dearpygui_frame()
dpg.destroy_context()
So, taking both of this facts into account I think that root of the bug is somewhere in calling of the render_dearpygui_frame
method under windows. I hope it helps to find the bug.
P. S. If my comments violates contribution policy, I appreciate if you be so kind to tell me where. I haven't enough experience in such cases.
@vanekrus I found a solution to this: create a non-primary window with resize callback that can set viewport size, and set resizable=False
for viewport. Carefully design the app UI such that it looks like we're resizing the viewport instead of the non-primary window, and you should get a smooth resizing experience. Other details might be needed to improve UI depending on your requirements.
It looks like this:

Try code below:
import dearpygui.dearpygui as dpg
dpg.create_context()
# Viewport - note that we need to set resizable=False
dpg.create_viewport(title="Solving Viewport Resize Callback Issue",
resizable=False, width=800, height=600, x_pos=0, y_pos=0)
scale = [0.4, 0.6] # used for setting the size of child windows
delta_width = 17 # UI design: viewport width - non-primary window width
delta_height = 43 # UI design: viewport height - non-primary window height
delta_height_child = 15 # UI design: non-primary window height - child height
# Non-primray window - fixed its relative position with viewport
dpg.add_window(tag="non_primary_window", label="Resize works well",
no_title_bar=True, no_move=True, min_size=[250, 250],
no_scrollbar=True, pos=[0, 3], width=300, height=200)
with dpg.group(horizontal=True, parent="non_primary_window"):
dpg.add_child_window(width=int(scale[0] * 300), tag="child01")
dpg.add_child_window(width=int(scale[1] * 300), tag="child02")
width_n = dpg.get_item_width("non_primary_window")
height_n = dpg.get_item_height("non_primary_window")
# Resize callback for non-primary window - used to normal usage
def resizeNonPrimaryWindowCb():
global width_n, height_n
width_n = dpg.get_item_width("non_primary_window")
height_n = dpg.get_item_height("non_primary_window")
dpg.configure_item("child01",
width=int(scale[0] * width_n),
height=int(height_n - delta_height_child),
)
dpg.configure_item("child02",
width=int(scale[1] * width_n - 20),
height=int(height_n - delta_height_child),
)
dpg.set_viewport_width(width_n + delta_width)
dpg.set_viewport_height(height_n + delta_height)
# Resize handler for non-primary window
with dpg.item_handler_registry(tag="resize_regular_window_handler"):
dpg.add_item_resize_handler(callback=resizeNonPrimaryWindowCb)
dpg.bind_item_handler_registry("non_primary_window", "resize_regular_window_handler")
dpg.setup_dearpygui()
dpg.show_viewport()
dpg.start_dearpygui()
dpg.destroy_context()
Is this being worked on? Id rather have a native solution than trying to hack it with a workaround. It looks really bad.
Being worked on now!
Any news on this bug?