aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--examples/pugl_shader_demo.c19
-rw-r--r--include/pugl/detail/implementation.c3
-rw-r--r--include/pugl/detail/mac.m15
-rw-r--r--include/pugl/detail/win.c16
-rw-r--r--include/pugl/detail/win.h1
-rw-r--r--include/pugl/pugl.h34
-rw-r--r--include/pugl/pugl.hpp14
-rw-r--r--include/pugl/pugl.ipp12
-rw-r--r--test/test_utils.h8
9 files changed, 90 insertions, 32 deletions
diff --git a/examples/pugl_shader_demo.c b/examples/pugl_shader_demo.c
index 1122410..4b8064d 100644
--- a/examples/pugl_shader_demo.c
+++ b/examples/pugl_shader_demo.c
@@ -47,12 +47,14 @@
#include <math.h>
#include <stddef.h>
+#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-static const int defaultWidth = 512;
-static const int defaultHeight = 512;
+static const int defaultWidth = 512;
+static const int defaultHeight = 512;
+static const uintptr_t resizeTimerId = 1u;
typedef struct
{
@@ -166,11 +168,24 @@ onEvent(PuglView* view, const PuglEvent* event)
break;
case PUGL_EXPOSE: onExpose(view); break;
case PUGL_CLOSE: app->quit = 1; break;
+ case PUGL_LOOP_ENTER:
+ puglStartTimer(view,
+ resizeTimerId,
+ 1.0 / (double)puglGetViewHint(view, PUGL_REFRESH_RATE));
+ break;
+ case PUGL_LOOP_LEAVE:
+ puglStopTimer(view, resizeTimerId);
+ break;
case PUGL_KEY_PRESS:
if (event->key.key == 'q' || event->key.key == PUGL_KEY_ESCAPE) {
app->quit = 1;
}
break;
+ case PUGL_TIMER:
+ if (event->timer.id == resizeTimerId) {
+ puglPostRedisplay(view);
+ }
+ break;
default: break;
}
diff --git a/include/pugl/detail/implementation.c b/include/pugl/detail/implementation.c
index e9a3450..f15b856 100644
--- a/include/pugl/detail/implementation.c
+++ b/include/pugl/detail/implementation.c
@@ -398,7 +398,8 @@ void
puglDispatchSimpleEvent(PuglView* view, const PuglEventType type)
{
assert(type == PUGL_CREATE || type == PUGL_DESTROY || type == PUGL_MAP ||
- type == PUGL_UNMAP || type == PUGL_UPDATE || type == PUGL_CLOSE);
+ type == PUGL_UNMAP || type == PUGL_UPDATE || type == PUGL_CLOSE ||
+ type == PUGL_LOOP_ENTER || type == PUGL_LOOP_LEAVE);
const PuglEvent event = {{type, 0}};
puglDispatchEvent(view, &event);
diff --git a/include/pugl/detail/mac.m b/include/pugl/detail/mac.m
index efcaca0..a807761 100644
--- a/include/pugl/detail/mac.m
+++ b/include/pugl/detail/mac.m
@@ -190,7 +190,6 @@ updateViewRect(PuglView* view)
PuglView* puglview;
NSTrackingArea* trackingArea;
NSMutableAttributedString* markedText;
- NSTimer* timer;
NSMutableDictionary* userTimers;
bool reshaped;
}
@@ -717,15 +716,7 @@ handleCrossing(PuglWrapperView* view, NSEvent* event, const PuglEventType type)
- (void)viewWillStartLiveResize
{
- timer = [NSTimer timerWithTimeInterval:(1 / 60.0)
- target:self
- selector:@selector(resizeTick)
- userInfo:nil
- repeats:YES];
- [[NSRunLoop currentRunLoop] addTimer:timer
- forMode:NSRunLoopCommonModes];
-
- [super viewWillStartLiveResize];
+ puglDispatchSimpleEvent(puglview, PUGL_LOOP_ENTER);
}
- (void)viewWillDraw
@@ -749,9 +740,7 @@ handleCrossing(PuglWrapperView* view, NSEvent* event, const PuglEventType type)
- (void)viewDidEndLiveResize
{
- [super viewDidEndLiveResize];
- [timer invalidate];
- timer = NULL;
+ puglDispatchSimpleEvent(puglview, PUGL_LOOP_LEAVE);
}
@end
diff --git a/include/pugl/detail/win.c b/include/pugl/detail/win.c
index 84cca27..237ebde 100644
--- a/include/pugl/detail/win.c
+++ b/include/pugl/detail/win.c
@@ -51,7 +51,6 @@
#define PUGL_LOCAL_CLOSE_MSG (WM_USER + 50)
#define PUGL_LOCAL_MARK_MSG (WM_USER + 51)
#define PUGL_LOCAL_CLIENT_MSG (WM_USER + 52)
-#define PUGL_RESIZE_TIMER_ID 9461
#define PUGL_USER_TIMER_MIN 9470
typedef BOOL (WINAPI *PFN_SetProcessDPIAware)(void);
@@ -590,17 +589,10 @@ handleMessage(PuglView* view, UINT message, WPARAM wParam, LPARAM lParam)
break;
case WM_ENTERSIZEMOVE:
case WM_ENTERMENULOOP:
- view->impl->resizing = true;
- SetTimer(view->impl->hwnd,
- PUGL_RESIZE_TIMER_ID,
- 1000 / (UINT)view->hints[PUGL_REFRESH_RATE],
- NULL);
+ puglDispatchSimpleEvent(view, PUGL_LOOP_ENTER);
break;
case WM_TIMER:
- if (wParam == PUGL_RESIZE_TIMER_ID) {
- RedrawWindow(view->impl->hwnd, NULL, NULL,
- RDW_INVALIDATE|RDW_ALLCHILDREN|RDW_INTERNALPAINT);
- } else if (wParam >= PUGL_USER_TIMER_MIN) {
+ if (wParam >= PUGL_USER_TIMER_MIN) {
PuglEvent ev = {{PUGL_TIMER, 0}};
ev.timer.id = wParam - PUGL_USER_TIMER_MIN;
puglDispatchEvent(view, &ev);
@@ -608,9 +600,7 @@ handleMessage(PuglView* view, UINT message, WPARAM wParam, LPARAM lParam)
break;
case WM_EXITSIZEMOVE:
case WM_EXITMENULOOP:
- KillTimer(view->impl->hwnd, PUGL_RESIZE_TIMER_ID);
- view->impl->resizing = false;
- puglPostRedisplay(view);
+ puglDispatchSimpleEvent(view, PUGL_LOOP_LEAVE);
break;
case WM_GETMINMAXINFO:
mmi = (MINMAXINFO*)lParam;
diff --git a/include/pugl/detail/win.h b/include/pugl/detail/win.h
index 0ead1fa..4c0a3c0 100644
--- a/include/pugl/detail/win.h
+++ b/include/pugl/detail/win.h
@@ -42,7 +42,6 @@ struct PuglInternalsImpl {
HDC hdc;
PuglSurface* surface;
bool flashing;
- bool resizing;
bool mouseTracked;
};
diff --git a/include/pugl/pugl.h b/include/pugl/pugl.h
index 1ec5491..19f9fa4 100644
--- a/include/pugl/pugl.h
+++ b/include/pugl/pugl.h
@@ -200,6 +200,8 @@ typedef enum {
PUGL_SCROLL, ///< Scrolled, a #PuglEventScroll
PUGL_CLIENT, ///< Custom client message, a #PuglEventClient
PUGL_TIMER, ///< Timer triggered, a #PuglEventTimer
+ PUGL_LOOP_ENTER, ///< Recursive loop entered, a #PuglEventLoopEnter
+ PUGL_LOOP_LEAVE, ///< Recursive loop left, a #PuglEventLoopLeave
#ifndef PUGL_DISABLE_DEPRECATED
PUGL_ENTER_NOTIFY PUGL_DEPRECATED_BY("PUGL_POINTER_IN") = PUGL_POINTER_IN,
@@ -515,6 +517,38 @@ typedef struct {
} PuglEventTimer;
/**
+ Recursive loop enter event.
+
+ This event is sent when the window system enters a recursive loop. The main
+ loop will be stalled and no expose events will be received while in the
+ recursive loop. To give the application full control, Pugl does not do any
+ special handling of this situation, but this event can be used to install a
+ timer to perform continuous actions (such as drawing) on platforms that do
+ this.
+
+ - MacOS: A recursive loop is entered while the window is being live resized.
+
+ - Windows: A recursive loop is entered while the window is being live
+ resized or the menu is shown.
+
+ - X11: A recursive loop is never entered and the event loop runs as usual
+ while the view is being resized.
+
+ This event type has no extra fields.
+*/
+typedef PuglEventAny PuglEventLoopEnter;
+
+/**
+ Recursive loop leave event.
+
+ This event is sent after a loop enter event when the recursive loop is
+ finished and normal iteration will continue.
+
+ This event type has no extra fields.
+*/
+typedef PuglEventAny PuglEventLoopLeave;
+
+/**
View event.
This is a union of all event types. The type must be checked to determine
diff --git a/include/pugl/pugl.hpp b/include/pugl/pugl.hpp
index 2097534..7650b1f 100644
--- a/include/pugl/pugl.hpp
+++ b/include/pugl/pugl.hpp
@@ -176,6 +176,12 @@ using ClientEvent = Event<PUGL_CLIENT, PuglEventClient>;
/// @copydoc PuglEventTimer
using TimerEvent = Event<PUGL_TIMER, PuglEventTimer>;
+/// @copydoc PuglEventLoopEnter
+using LoopEnterEvent = Event<PUGL_LOOP_ENTER, PuglEventLoopEnter>;
+
+/// @copydoc PuglEventLoopLeave
+using LoopLeaveEvent = Event<PUGL_LOOP_LEAVE, PuglEventLoopLeave>;
+
/**
@}
@name Status
@@ -610,6 +616,8 @@ public:
virtual Status onScroll(const ScrollEvent&) PUGL_CONST_FUNC;
virtual Status onClient(const ClientEvent&) PUGL_CONST_FUNC;
virtual Status onTimer(const TimerEvent&) PUGL_CONST_FUNC;
+ virtual Status onLoopEnter(const LoopEnterEvent&) PUGL_CONST_FUNC;
+ virtual Status onLoopLeave(const LoopLeaveEvent&) PUGL_CONST_FUNC;
/**
@}
@@ -709,6 +717,12 @@ private:
case PUGL_TIMER:
return static_cast<PuglStatus>(
onTimer(typedEventRef<TimerEvent>(event->timer)));
+ case PUGL_LOOP_ENTER:
+ return static_cast<PuglStatus>(
+ onLoopEnter(typedEventRef<LoopEnterEvent>(event->any)));
+ case PUGL_LOOP_LEAVE:
+ return static_cast<PuglStatus>(
+ onLoopLeave(typedEventRef<LoopLeaveEvent>(event->any)));
}
return PUGL_FAILURE;
diff --git a/include/pugl/pugl.ipp b/include/pugl/pugl.ipp
index 0ed8c4d..aa6e6f1 100644
--- a/include/pugl/pugl.ipp
+++ b/include/pugl/pugl.ipp
@@ -151,4 +151,16 @@ View::onTimer(const TimerEvent&)
return pugl::Status::success;
}
+Status
+View::onLoopEnter(const LoopEnterEvent&)
+{
+ return pugl::Status::success;
+}
+
+Status
+View::onLoopLeave(const LoopLeaveEvent&)
+{
+ return pugl::Status::success;
+}
+
} // namespace pugl
diff --git a/test/test_utils.h b/test/test_utils.h
index d86018c..7a91535 100644
--- a/test/test_utils.h
+++ b/test/test_utils.h
@@ -173,8 +173,10 @@ printEvent(const PuglEvent* event, const char* prefix, const bool verbose)
prefix,
event->client.data1,
event->client.data2);
- case PUGL_TIMER:
- return PRINT("%sTimer %" PRIuPTR "\n", prefix, event->timer.id);
+ case PUGL_LOOP_ENTER:
+ return PRINT("%sLoop enter\n", prefix);
+ case PUGL_LOOP_LEAVE:
+ return PRINT("%sLoop leave\n", prefix);
default:
break;
}
@@ -212,6 +214,8 @@ printEvent(const PuglEvent* event, const char* prefix, const bool verbose)
prefix,
event->motion.x,
event->motion.y);
+ case PUGL_TIMER:
+ return PRINT("%sTimer %" PRIuPTR "\n", prefix, event->timer.id);
default:
return PRINT("%sUnknown event type %d\n", prefix, (int)event->type);
}