diff options
-rw-r--r-- | examples/pugl_shader_demo.c | 19 | ||||
-rw-r--r-- | include/pugl/detail/implementation.c | 3 | ||||
-rw-r--r-- | include/pugl/detail/mac.m | 15 | ||||
-rw-r--r-- | include/pugl/detail/win.c | 16 | ||||
-rw-r--r-- | include/pugl/detail/win.h | 1 | ||||
-rw-r--r-- | include/pugl/pugl.h | 34 | ||||
-rw-r--r-- | include/pugl/pugl.hpp | 14 | ||||
-rw-r--r-- | include/pugl/pugl.ipp | 12 | ||||
-rw-r--r-- | test/test_utils.h | 8 |
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); } |