From e0ca765a449d93d835588fb93f1c31233014025d Mon Sep 17 00:00:00 2001 From: David Robillard Date: Sun, 8 Mar 2020 17:47:08 +0100 Subject: Windows: Prevent input in one window from stalling another This dispatches events on a per-window basic instead of globally, using the same mark trick as before to bound the number of events dispatched. After the events are dispatched, all the windows are updated if they have an invalid region. This ensures that all windows get drawn every iteration if necessary, since Windows itself does not send WM_PAINT messages if there is lots of input activity. --- pugl/detail/win.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/pugl/detail/win.c b/pugl/detail/win.c index 080460d..6b7414a 100644 --- a/pugl/detail/win.c +++ b/pugl/detail/win.c @@ -735,8 +735,8 @@ puglWaitForEvent(PuglView* PUGL_UNUSED(view)) } #endif -PUGL_API PuglStatus -puglDispatchEvents(PuglWorld* PUGL_UNUSED(world)) +static PuglStatus +puglDispatchViewEvents(PuglView* view) { /* Windows has no facility to process only currently queued messages, which causes the event loop to run forever in cases like mouse movement where @@ -744,11 +744,10 @@ puglDispatchEvents(PuglWorld* PUGL_UNUSED(world)) this, we post a message to ourselves before starting, record its time when it is received, then break the loop on the first message that was created afterwards. */ - PostMessage(NULL, PUGL_LOCAL_MARK_MSG, 0, 0); long markTime = 0; MSG msg; - while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { + while (PeekMessage(&msg, view->impl->hwnd, 0, 0, PM_REMOVE)) { if (msg.message == PUGL_LOCAL_MARK_MSG) { markTime = GetMessageTime(); } else { @@ -763,6 +762,24 @@ puglDispatchEvents(PuglWorld* PUGL_UNUSED(world)) return PUGL_SUCCESS; } +PUGL_API PuglStatus +puglDispatchEvents(PuglWorld* world) +{ + for (size_t i = 0; i < world->numViews; ++i) { + PostMessage(world->views[i]->impl->hwnd, PUGL_LOCAL_MARK_MSG, 0, 0); + } + + for (size_t i = 0; i < world->numViews; ++i) { + puglDispatchViewEvents(world->views[i]); + } + + for (size_t i = 0; i < world->numViews; ++i) { + UpdateWindow(world->views[i]->impl->hwnd); + } + + return PUGL_SUCCESS; +} + #ifndef PUGL_DISABLE_DEPRECATED PuglStatus puglProcessEvents(PuglView* view) -- cgit v1.2.1