Skip to content

Commit 4192d04

Browse files
authored
Fix seg-fault when using without a window (#1874)
* Fix seg-fault when using without a window #1869 * Update changelog
1 parent 3571dcd commit 4192d04

File tree

4 files changed

+16
-11
lines changed

4 files changed

+16
-11
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Unreleased
22

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

src/platform_impl/macos/app_state.rs

+10-9
Original file line numberDiff line numberDiff line change
@@ -341,9 +341,7 @@ impl AppState {
341341
unsafe {
342342
let app: id = NSApp();
343343
let windows: id = msg_send![app, windows];
344-
let window: id = msg_send![windows, objectAtIndex:0];
345344
let window_count: usize = msg_send![windows, count];
346-
assert_ne!(window, nil);
347345

348346
let dialog_open = if window_count > 1 {
349347
let dialog: id = msg_send![windows, lastObject];
@@ -373,16 +371,19 @@ impl AppState {
373371
data2: 0
374372
];
375373
// To stop event loop immediately, we need to post some event here.
376-
let _: () = msg_send![window, postEvent: dummy_event atStart: YES];
374+
let _: () = msg_send![app, postEvent: dummy_event atStart: YES];
377375
}
378376
pool.drain();
379377

380-
let window_has_focus = msg_send![window, isKeyWindow];
381-
if !dialog_open && window_has_focus && dialog_is_closing {
382-
HANDLER.dialog_is_closing.store(false, Ordering::SeqCst);
383-
}
384-
if dialog_open {
385-
HANDLER.dialog_is_closing.store(true, Ordering::SeqCst);
378+
if window_count > 0 {
379+
let window: id = msg_send![windows, objectAtIndex:0];
380+
let window_has_focus = msg_send![window, isKeyWindow];
381+
if !dialog_open && window_has_focus && dialog_is_closing {
382+
HANDLER.dialog_is_closing.store(false, Ordering::SeqCst);
383+
}
384+
if dialog_open {
385+
HANDLER.dialog_is_closing.store(true, Ordering::SeqCst);
386+
}
386387
}
387388
};
388389
}

src/platform_impl/macos/util/async.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,10 @@ pub unsafe fn set_title_async(ns_window: id, title: String) {
207207

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

src/platform_impl/macos/window.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1158,7 +1158,7 @@ impl Drop for UnownedWindow {
11581158
trace!("Dropping `UnownedWindow` ({:?})", self as *mut _);
11591159
// Close the window if it has not yet been closed.
11601160
if *self.ns_window != nil {
1161-
unsafe { util::close_async(*self.ns_window) };
1161+
unsafe { util::close_async(self.ns_window.clone()) };
11621162
}
11631163
}
11641164
}

0 commit comments

Comments
 (0)