@@ -23,6 +23,7 @@ internal unsafe class GlfwWindow : WindowImplementationBase, IVkSurface
2323 private GlfwCallbacks . WindowPosCallback ? _onMove ;
2424 private GlfwCallbacks . WindowSizeCallback ? _onResize ;
2525 private GlfwCallbacks . FramebufferSizeCallback ? _onFramebufferResize ;
26+ private GlfwCallbacks . WindowRefreshCallback ? _onRefresh ;
2627 private GlfwCallbacks . DropCallback ? _onFileDrop ;
2728 private GlfwCallbacks . WindowCloseCallback ? _onClosing ;
2829 private GlfwCallbacks . WindowFocusCallback ? _onFocusChanged ;
@@ -37,6 +38,16 @@ internal unsafe class GlfwWindow : WindowImplementationBase, IVkSurface
3738 private string _localTitleCache ; // glfw doesn't let us get the window title.
3839 private GlfwContext ? _glContext ;
3940 private string _windowClass ;
41+ private bool _inDoEvents ;
42+
43+ /// <summary>
44+ /// The action passed to <see cref="Run"/>.
45+ /// </summary>
46+ /// <remarks>
47+ /// May be called on repaint from within <see cref="DoEvents"/>.
48+ /// For example, during modal operations such as resizing on Windows.
49+ /// </remarks>
50+ protected Action ? _onFrame ;
4051
4152 public GlfwWindow ( WindowOptions optionsCache , GlfwWindow ? parent , GlfwMonitor ? monitor ) : base ( optionsCache )
4253 {
@@ -67,6 +78,19 @@ protected override Rectangle<int> CoreBorderSize
6778
6879 protected override nint CoreHandle => ( nint ) _glfwWindow ;
6980
81+ public override void Run ( Action onFrame )
82+ {
83+ try
84+ {
85+ _onFrame = onFrame ;
86+ base . Run ( onFrame ) ;
87+ }
88+ finally
89+ {
90+ _onFrame = null ;
91+ }
92+ }
93+
7094 protected override void CoreReset ( )
7195 {
7296 if ( _glfwWindow == null )
@@ -598,13 +622,24 @@ public override Vector2D<int> FramebufferSize
598622
599623 public override void DoEvents ( )
600624 {
601- if ( IsEventDriven )
625+ if ( ! _inDoEvents )
602626 {
603- _glfw . WaitEvents ( ) ;
604- }
605- else
606- {
607- _glfw . PollEvents ( ) ;
627+ try
628+ {
629+ _inDoEvents = true ;
630+ if ( IsEventDriven )
631+ {
632+ _glfw . WaitEvents ( ) ;
633+ }
634+ else
635+ {
636+ _glfw . PollEvents ( ) ;
637+ }
638+ }
639+ finally
640+ {
641+ _inDoEvents = false ;
642+ }
608643 }
609644 }
610645
@@ -658,6 +693,8 @@ protected override void RegisterCallbacks()
658693 FramebufferResize ? . Invoke ( new ( width , height ) ) ;
659694 } ;
660695
696+ _onRefresh = ( window ) => _onFrame ? . Invoke ( ) ;
697+
661698 _onClosing = window => Closing ? . Invoke ( ) ;
662699
663700 _onFocusChanged = ( window , isFocused ) => FocusChanged ? . Invoke ( isFocused ) ;
@@ -744,6 +781,7 @@ protected override void RegisterCallbacks()
744781 _glfw . SetWindowIconifyCallback ( _glfwWindow , _onMinimized ) ;
745782 _glfw . SetWindowMaximizeCallback ( _glfwWindow , _onMaximized ) ;
746783 _glfw . SetFramebufferSizeCallback ( _glfwWindow , _onFramebufferResize ) ;
784+ _glfw . SetWindowRefreshCallback ( _glfwWindow , _onRefresh ) ;
747785 _glfw . SetDropCallback ( _glfwWindow , _onFileDrop ) ;
748786 GLFW . Glfw . ThrowExceptions ( ) ;
749787 }
@@ -761,6 +799,7 @@ protected override void UnregisterCallbacks()
761799 _glfw . GcUtility . Unpin ( _onMove ) ;
762800 _glfw . GcUtility . Unpin ( _onResize ) ;
763801 _glfw . GcUtility . Unpin ( _onFramebufferResize ) ;
802+ _glfw . GcUtility . Unpin ( _onRefresh ) ;
764803 _glfw . GcUtility . Unpin ( _onFileDrop ) ;
765804 _glfw . GcUtility . Unpin ( _onFocusChanged ) ;
766805
@@ -770,6 +809,7 @@ protected override void UnregisterCallbacks()
770809 _onMove = null ;
771810 _onResize = null ;
772811 _onFramebufferResize = null ;
812+ _onRefresh = null ;
773813 _onFileDrop = null ;
774814 _onFocusChanged = null ;
775815 }
0 commit comments