Fix seg-fault when using without a window (#1874)

* Fix seg-fault when using without a window #1869

* Update changelog
This commit is contained in:
Artúr Kovács 2021-03-06 11:17:23 +01:00 committed by GitHub
parent 3571dcd68c
commit 4192d04a53
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 16 additions and 11 deletions

View file

@ -1,5 +1,6 @@
# Unreleased # Unreleased
- On macOS, fix segmentation fault after dropping the main window.
- On Android, `InputEvent::KeyEvent` is partially implemented providing the key scancode. - On Android, `InputEvent::KeyEvent` is partially implemented providing the key scancode.
- Added `is_maximized` method to `Window`. - Added `is_maximized` method to `Window`.
- On Windows, fix bug where clicking the decoration bar would make the cursor blink. - On Windows, fix bug where clicking the decoration bar would make the cursor blink.

View file

@ -341,9 +341,7 @@ impl AppState {
unsafe { unsafe {
let app: id = NSApp(); let app: id = NSApp();
let windows: id = msg_send![app, windows]; let windows: id = msg_send![app, windows];
let window: id = msg_send![windows, objectAtIndex:0];
let window_count: usize = msg_send![windows, count]; let window_count: usize = msg_send![windows, count];
assert_ne!(window, nil);
let dialog_open = if window_count > 1 { let dialog_open = if window_count > 1 {
let dialog: id = msg_send![windows, lastObject]; let dialog: id = msg_send![windows, lastObject];
@ -373,16 +371,19 @@ impl AppState {
data2: 0 data2: 0
]; ];
// To stop event loop immediately, we need to post some event here. // To stop event loop immediately, we need to post some event here.
let _: () = msg_send![window, postEvent: dummy_event atStart: YES]; let _: () = msg_send![app, postEvent: dummy_event atStart: YES];
} }
pool.drain(); pool.drain();
let window_has_focus = msg_send![window, isKeyWindow]; if window_count > 0 {
if !dialog_open && window_has_focus && dialog_is_closing { let window: id = msg_send![windows, objectAtIndex:0];
HANDLER.dialog_is_closing.store(false, Ordering::SeqCst); let window_has_focus = msg_send![window, isKeyWindow];
} if !dialog_open && window_has_focus && dialog_is_closing {
if dialog_open { HANDLER.dialog_is_closing.store(false, Ordering::SeqCst);
HANDLER.dialog_is_closing.store(true, Ordering::SeqCst); }
if dialog_open {
HANDLER.dialog_is_closing.store(true, Ordering::SeqCst);
}
} }
}; };
} }

View file

@ -207,7 +207,10 @@ pub unsafe fn set_title_async(ns_window: id, title: String) {
// `close:` is thread-safe, but we want the event to be triggered from the main // `close:` is thread-safe, but we want the event to be triggered from the main
// thread. Though, it's a good idea to look into that more... // thread. Though, it's a good idea to look into that more...
pub unsafe fn close_async(ns_window: id) { //
// ArturKovacs: It's important that this operation keeps the underlying window alive
// through the `IdRef` because otherwise it would dereference free'd memory
pub unsafe fn close_async(ns_window: IdRef) {
let ns_window = MainThreadSafe(ns_window); let ns_window = MainThreadSafe(ns_window);
Queue::main().exec_async(move || { Queue::main().exec_async(move || {
autoreleasepool(move || { autoreleasepool(move || {

View file

@ -1158,7 +1158,7 @@ impl Drop for UnownedWindow {
trace!("Dropping `UnownedWindow` ({:?})", self as *mut _); trace!("Dropping `UnownedWindow` ({:?})", self as *mut _);
// Close the window if it has not yet been closed. // Close the window if it has not yet been closed.
if *self.ns_window != nil { if *self.ns_window != nil {
unsafe { util::close_async(*self.ns_window) }; unsafe { util::close_async(self.ns_window.clone()) };
} }
} }
} }