No more hanging up when the viewport it resized#2521
No more hanging up when the viewport it resized#2521hoffstadt merged 1 commit intohoffstadt:masterfrom
Conversation
… WM_SIZING as it is not needed and was processed incorrectly (hoffstadt#2401). Reworked the message loop so that it processes all pending messages rather than one message per frame (hoffstadt#544, hoffstadt#1571, hoffstadt#2357). Continue rendering when the viewport is being moved or resized by the user. Sending resize events, too (hoffstadt#1896, hoffstadt#2217). Removed unused width/height fields from mvViewport.
|
Yet another issue this PR is going to fix is when a drag handler misbehaves after On Windows, DPG needs to process Win32 messages and feed some of them to Dear ImGui so that ImGui can get user input (keyboard/mouse events). There are different ways a message can be retrieved and processed. User input comes via the message queue. DPG calls Okay, DPG handles one queued message per frame. So what? Even within the queue, there are different categories of messages. Some of them are low-priority and generated on-the-fly when the queue is empty. Here's a good StackOverflow discussion on the topics - check both answers: When you simply drag the window, DPG fetches To put it simple: you shift the mouse, the drag handler sees a nonzero delta, calls the callback, the callback moves the viewport by that delta, and next frame ImGui updates mouse position so that the delta gets back to zero. Now, you might wonder how the hell could an input widget mess things up here. When you click the input widget, Windows posts a WM_IME_NOTIFY to the message queue. Yes, even though the doc states the message is sent (i.e. not queued), Windows can actually post it, too, with an undocumented As soon as you drag the mouse, |
…es a regression in hoffstadt#2521).
…es a regression in #2521).
|
One of the problems this PR solves is a "visual hang-up" that occurs on Windows when the user is dragging or resizing the window - DPG does not render frames while the mouse is held down. This is not related to hang-up after the mouse is released, and the cause is that Windows starts a modal message loop for the duration of move or resize. The PR solves it by doing extra rendering on |
name: Pull Request
about: Create a pull request to help us improve
title: No more hanging up when the viewport it resized
assignees: ''
Description:
The main issue this PR addresses is #2401. It is caused by
WM_SIZINGbranch in the window procedure, which is handled by the same code asWM_SIZE. That branch uses LPARAM to get the new viewport size and to appropriately resize DirectX buffers. Works fine onWM_SIZE, butWM_SIZINGgets a different type of data in LPARAM (a LPRECT pointer), and therefore feeds wrong sizes to DX and spoils its swap chain. Moreover,WM_SIZINGis not needed and can be safely removed. It's exactly what I did to fix the hangup issue. This resolves #2401.In addition to that, I've modified the message loop so that it processes all pending messages rather than one message per frame. This fixes #1571 and fixes #2357.
Yet another change is to actually render frames on
WM_TIMERwhile the user is resizing or moving the window. This makes DPG behave the same way as on Linux, where resizing does not block rendering. This is actually a bit of a double-edged change becauserender_dearpygui_frame()will still hang up when the user starts resizing, and DPG will start an internal rendering loop to compensate for that. Will work fine for most DPG users (those who simply callstart_dearpygui()) but might give some surprising side effects to those who use a custom rendering loop (e.g. asyncio-based apps). In future we might want to add an option to opt-out of this behavior.Anyway, rendering on
WM_TIMERseems to work quite well, and also helps with callingviewport_resize_callbackproperly. I've also corrected the code callingSetTimer(no need to call it twice). This fixes #1896 and fixes #2217.Note: I've completely removed
WM_PAINTand letDefWindowProchandle it. This is perfectly normal since we're rendering frames all the time anyway (either viarender_dearpygui_frameor onWM_TIMER).Concerning Areas:
None.