summaryrefslogtreecommitdiff
path: root/glfw/src/window.rs
diff options
context:
space:
mode:
Diffstat (limited to 'glfw/src/window.rs')
-rw-r--r--glfw/src/window.rs34
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,