mirror of
https://github.com/zed-industries/zed.git
synced 2025-01-12 21:32:40 +00:00
Fix crash when closing windows
This commit is contained in:
parent
f7d8b6b4c0
commit
3f844bc953
4 changed files with 42 additions and 1 deletions
|
@ -758,6 +758,10 @@ impl MutableAppContext {
|
||||||
(window_id, root_handle)
|
(window_id, root_handle)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn remove_window(&mut self, window_id: usize) {
|
||||||
|
self.presenters_and_platform_windows.remove(&window_id);
|
||||||
|
}
|
||||||
|
|
||||||
fn open_platform_window(&mut self, window_id: usize) {
|
fn open_platform_window(&mut self, window_id: usize) {
|
||||||
let mut window = self.platform.open_window(
|
let mut window = self.platform.open_window(
|
||||||
window_id,
|
window_id,
|
||||||
|
@ -814,6 +818,13 @@ impl MutableAppContext {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
let mut app = self.upgrade();
|
||||||
|
window.on_close(Box::new(move || {
|
||||||
|
app.update(|ctx| ctx.remove_window(window_id));
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
self.presenters_and_platform_windows
|
self.presenters_and_platform_windows
|
||||||
.insert(window_id, (presenter.clone(), window));
|
.insert(window_id, (presenter.clone(), window));
|
||||||
|
|
||||||
|
|
|
@ -61,6 +61,7 @@ unsafe fn build_classes() {
|
||||||
sel!(sendEvent:),
|
sel!(sendEvent:),
|
||||||
send_event as extern "C" fn(&Object, Sel, id),
|
send_event as extern "C" fn(&Object, Sel, id),
|
||||||
);
|
);
|
||||||
|
decl.add_method(sel!(close), close_window as extern "C" fn(&Object, Sel));
|
||||||
decl.register()
|
decl.register()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -125,6 +126,7 @@ struct WindowState {
|
||||||
native_window: id,
|
native_window: id,
|
||||||
event_callback: Option<Box<dyn FnMut(Event)>>,
|
event_callback: Option<Box<dyn FnMut(Event)>>,
|
||||||
resize_callback: Option<Box<dyn FnMut(&mut dyn platform::WindowContext)>>,
|
resize_callback: Option<Box<dyn FnMut(&mut dyn platform::WindowContext)>>,
|
||||||
|
close_callback: Option<Box<dyn FnOnce()>>,
|
||||||
synthetic_drag_counter: usize,
|
synthetic_drag_counter: usize,
|
||||||
executor: Rc<executor::Foreground>,
|
executor: Rc<executor::Foreground>,
|
||||||
scene_to_render: Option<Scene>,
|
scene_to_render: Option<Scene>,
|
||||||
|
@ -184,6 +186,7 @@ impl Window {
|
||||||
native_window,
|
native_window,
|
||||||
event_callback: None,
|
event_callback: None,
|
||||||
resize_callback: None,
|
resize_callback: None,
|
||||||
|
close_callback: None,
|
||||||
synthetic_drag_counter: 0,
|
synthetic_drag_counter: 0,
|
||||||
executor,
|
executor,
|
||||||
scene_to_render: Default::default(),
|
scene_to_render: Default::default(),
|
||||||
|
@ -262,6 +265,10 @@ impl platform::Window for Window {
|
||||||
fn on_resize(&mut self, callback: Box<dyn FnMut(&mut dyn platform::WindowContext)>) {
|
fn on_resize(&mut self, callback: Box<dyn FnMut(&mut dyn platform::WindowContext)>) {
|
||||||
self.0.as_ref().borrow_mut().resize_callback = Some(callback);
|
self.0.as_ref().borrow_mut().resize_callback = Some(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn on_close(&mut self, callback: Box<dyn FnOnce()>) {
|
||||||
|
self.0.as_ref().borrow_mut().close_callback = Some(callback);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl platform::WindowContext for Window {
|
impl platform::WindowContext for Window {
|
||||||
|
@ -310,7 +317,7 @@ unsafe fn get_window_state(object: &Object) -> Rc<RefCell<WindowState>> {
|
||||||
|
|
||||||
unsafe fn drop_window_state(object: &Object) {
|
unsafe fn drop_window_state(object: &Object) {
|
||||||
let raw: *mut c_void = *object.get_ivar(WINDOW_STATE_IVAR);
|
let raw: *mut c_void = *object.get_ivar(WINDOW_STATE_IVAR);
|
||||||
Rc::from_raw(raw as *mut WindowState);
|
Rc::from_raw(raw as *mut RefCell<WindowState>);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" fn yes(_: &Object, _: Sel) -> BOOL {
|
extern "C" fn yes(_: &Object, _: Sel) -> BOOL {
|
||||||
|
@ -371,6 +378,22 @@ extern "C" fn send_event(this: &Object, _: Sel, native_event: id) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" fn close_window(this: &Object, _: Sel) {
|
||||||
|
unsafe {
|
||||||
|
let window_state = get_window_state(this);
|
||||||
|
let close_callback = window_state
|
||||||
|
.as_ref()
|
||||||
|
.try_borrow_mut()
|
||||||
|
.ok()
|
||||||
|
.and_then(|mut window_state| window_state.close_callback.take());
|
||||||
|
if let Some(callback) = close_callback {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
|
||||||
|
let () = msg_send![super(this, class!(NSWindow)), close];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" fn make_backing_layer(this: &Object, _: Sel) -> id {
|
extern "C" fn make_backing_layer(this: &Object, _: Sel) -> id {
|
||||||
let window_state = unsafe { get_window_state(this) };
|
let window_state = unsafe { get_window_state(this) };
|
||||||
let window_state = window_state.as_ref().borrow();
|
let window_state = window_state.as_ref().borrow();
|
||||||
|
|
|
@ -59,6 +59,7 @@ pub trait Dispatcher: Send + Sync {
|
||||||
pub trait Window: WindowContext {
|
pub trait Window: WindowContext {
|
||||||
fn on_event(&mut self, callback: Box<dyn FnMut(Event)>);
|
fn on_event(&mut self, callback: Box<dyn FnMut(Event)>);
|
||||||
fn on_resize(&mut self, callback: Box<dyn FnMut(&mut dyn WindowContext)>);
|
fn on_resize(&mut self, callback: Box<dyn FnMut(&mut dyn WindowContext)>);
|
||||||
|
fn on_close(&mut self, callback: Box<dyn FnOnce()>);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait WindowContext {
|
pub trait WindowContext {
|
||||||
|
|
|
@ -16,6 +16,7 @@ pub struct Window {
|
||||||
current_scene: Option<crate::Scene>,
|
current_scene: Option<crate::Scene>,
|
||||||
event_handlers: Vec<Box<dyn FnMut(super::Event)>>,
|
event_handlers: Vec<Box<dyn FnMut(super::Event)>>,
|
||||||
resize_handlers: Vec<Box<dyn FnMut(&mut dyn super::WindowContext)>>,
|
resize_handlers: Vec<Box<dyn FnMut(&mut dyn super::WindowContext)>>,
|
||||||
|
close_handlers: Vec<Box<dyn FnOnce()>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Platform {
|
impl Platform {
|
||||||
|
@ -92,6 +93,7 @@ impl Window {
|
||||||
size,
|
size,
|
||||||
event_handlers: Vec::new(),
|
event_handlers: Vec::new(),
|
||||||
resize_handlers: Vec::new(),
|
resize_handlers: Vec::new(),
|
||||||
|
close_handlers: Vec::new(),
|
||||||
scale_factor: 1.0,
|
scale_factor: 1.0,
|
||||||
current_scene: None,
|
current_scene: None,
|
||||||
}
|
}
|
||||||
|
@ -130,6 +132,10 @@ impl super::Window for Window {
|
||||||
fn on_resize(&mut self, callback: Box<dyn FnMut(&mut dyn super::WindowContext)>) {
|
fn on_resize(&mut self, callback: Box<dyn FnMut(&mut dyn super::WindowContext)>) {
|
||||||
self.resize_handlers.push(callback);
|
self.resize_handlers.push(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn on_close(&mut self, callback: Box<dyn FnOnce()>) {
|
||||||
|
self.close_handlers.push(callback);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn platform() -> impl super::Platform {
|
pub fn platform() -> impl super::Platform {
|
||||||
|
|
Loading…
Reference in a new issue