diff --git a/src/Windowing/Silk.NET.Windowing.Glfw/GlfwWindow.cs b/src/Windowing/Silk.NET.Windowing.Glfw/GlfwWindow.cs index 15030d3772..d6aca425df 100644 --- a/src/Windowing/Silk.NET.Windowing.Glfw/GlfwWindow.cs +++ b/src/Windowing/Silk.NET.Windowing.Glfw/GlfwWindow.cs @@ -23,6 +23,7 @@ internal unsafe class GlfwWindow : WindowImplementationBase, IVkSurface private GlfwCallbacks.WindowPosCallback? _onMove; private GlfwCallbacks.WindowSizeCallback? _onResize; private GlfwCallbacks.FramebufferSizeCallback? _onFramebufferResize; + private GlfwCallbacks.WindowRefreshCallback? _onRefresh; private GlfwCallbacks.DropCallback? _onFileDrop; private GlfwCallbacks.WindowCloseCallback? _onClosing; private GlfwCallbacks.WindowFocusCallback? _onFocusChanged; @@ -37,6 +38,16 @@ internal unsafe class GlfwWindow : WindowImplementationBase, IVkSurface private string _localTitleCache; // glfw doesn't let us get the window title. private GlfwContext? _glContext; private string _windowClass; + private bool _inDoEvents; + + /// + /// The action passed to . + /// + /// + /// May be called on repaint from within . + /// For example, during modal operations such as resizing on Windows. + /// + protected Action? _onFrame; public GlfwWindow(WindowOptions optionsCache, GlfwWindow? parent, GlfwMonitor? monitor) : base(optionsCache) { @@ -67,6 +78,19 @@ protected override Rectangle CoreBorderSize protected override nint CoreHandle => (nint) _glfwWindow; + public override void Run(Action onFrame) + { + try + { + _onFrame = onFrame; + base.Run(onFrame); + } + finally + { + _onFrame = null; + } + } + protected override void CoreReset() { if (_glfwWindow == null) @@ -598,13 +622,24 @@ public override Vector2D FramebufferSize public override void DoEvents() { - if (IsEventDriven) + if (!_inDoEvents) { - _glfw.WaitEvents(); - } - else - { - _glfw.PollEvents(); + try + { + _inDoEvents = true; + if (IsEventDriven) + { + _glfw.WaitEvents(); + } + else + { + _glfw.PollEvents(); + } + } + finally + { + _inDoEvents = false; + } } } @@ -658,6 +693,8 @@ protected override void RegisterCallbacks() FramebufferResize?.Invoke(new(width, height)); }; + _onRefresh = (window) => _onFrame?.Invoke(); + _onClosing = window => Closing?.Invoke(); _onFocusChanged = (window, isFocused) => FocusChanged?.Invoke(isFocused); @@ -744,6 +781,7 @@ protected override void RegisterCallbacks() _glfw.SetWindowIconifyCallback(_glfwWindow, _onMinimized); _glfw.SetWindowMaximizeCallback(_glfwWindow, _onMaximized); _glfw.SetFramebufferSizeCallback(_glfwWindow, _onFramebufferResize); + _glfw.SetWindowRefreshCallback(_glfwWindow, _onRefresh); _glfw.SetDropCallback(_glfwWindow, _onFileDrop); GLFW.Glfw.ThrowExceptions(); } @@ -761,6 +799,7 @@ protected override void UnregisterCallbacks() _glfw.GcUtility.Unpin(_onMove); _glfw.GcUtility.Unpin(_onResize); _glfw.GcUtility.Unpin(_onFramebufferResize); + _glfw.GcUtility.Unpin(_onRefresh); _glfw.GcUtility.Unpin(_onFileDrop); _glfw.GcUtility.Unpin(_onFocusChanged); @@ -770,6 +809,7 @@ protected override void UnregisterCallbacks() _onMove = null; _onResize = null; _onFramebufferResize = null; + _onRefresh = null; _onFileDrop = null; _onFocusChanged = null; }