diff options
Diffstat (limited to 'glfw/src/window.rs')
-rw-r--r-- | glfw/src/window.rs | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/glfw/src/window.rs b/glfw/src/window.rs index 079b2fb..40eb300 100644 --- a/glfw/src/window.rs +++ b/glfw/src/window.rs @@ -117,6 +117,20 @@ impl Window }) } + /// Sets the callback which is called when the user attempts to close the window. + pub fn set_close_callback(&self, callback: impl Fn() + 'static) + { + CLOSE_CALLBACK.with_borrow_mut(|cb| { + *cb = Some(Box::new(callback)); + }); + + // SAFETY: The initialize function (called when the window is created) makes sure + // the current thread is the main thread + unsafe { + crate::ffi::glfwSetWindowCloseCallback(self.handle, Some(close_callback)); + } + } + pub fn set_framebuffer_size_callback(&self, callback: impl Fn(Size) + 'static) { FRAMEBUFFER_SIZE_CB.with_borrow_mut(|framebuffer_size_cb| { @@ -661,18 +675,38 @@ pub struct CursorPosition pub y: f64, } +type CloseCallback = Box<dyn Fn()>; type FramebufferSizeCb = Box<dyn Fn(Size)>; type KeyCallback = Box<dyn Fn(Key, i32, KeyState, KeyModifiers)>; type CursorPositionCallback = Box<dyn Fn(CursorPosition)>; type MouseButtonCallback = Box<dyn Fn(MouseButton, MouseButtonState, KeyModifiers)>; thread_local! { +static CLOSE_CALLBACK: RefCell<Option<CloseCallback>> = RefCell::new(None); static FRAMEBUFFER_SIZE_CB: RefCell<Option<FramebufferSizeCb>> = RefCell::new(None); static KEY_CALLBACK: RefCell<Option<KeyCallback>> = RefCell::new(None); static CURSOR_POS_CALLBACK: RefCell<Option<CursorPositionCallback>> = RefCell::new(None); static MOUSE_BUTTON_CALLBACK: RefCell<Option<MouseButtonCallback>> = RefCell::new(None); } +extern "C" fn close_callback(_window: *mut crate::ffi::GLFWwindow) +{ + // Unwinds are catched because unwinding from Rust code into foreign code is UB. + let res = catch_unwind(|| { + CLOSE_CALLBACK + .try_with(|close_cb| { + if let Some(cb) = close_cb.borrow().as_deref() { + cb(); + } + }) + .ok(); + }); + + if res.is_err() { + println!("ERROR: Panic in window close callback"); + } +} + extern "C" fn framebuffer_size_callback( _window: *mut crate::ffi::GLFWwindow, c_width: c_int, |