aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2020-03-08 17:47:08 +0100
committerDavid Robillard <d@drobilla.net>2020-03-08 17:47:08 +0100
commite0ca765a449d93d835588fb93f1c31233014025d (patch)
treeb1bdf326830a7050e78a430a22230f474882b79a
parentab21ada7abb8f276a14dbb63e32ce2774456bb1b (diff)
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.
-rw-r--r--pugl/detail/win.c25
1 files 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)