Commit 2c1b1a7
authored
Fix window cleanup logic on macOS (#164)
Instead of trying to detect when to clean up the window based on the `NSView`'s retain count, require window cleanup to be initiated explicitly via `Window::close`, `WindowHandle::close`, or `[NSWindowDelegate windowShouldClose:]` (in non-parented mode; called when the user clicks the "X" button). This fixes the leaks and use-after-frees that can be caused by the inherent unreliability of the retain count logic.
As discussed in #153, this change essentially means that the `NSView` created by Baseview will not be suitable as the top-level view for an Audio Unit, since the Baseview API now requires that child windows be cleaned up by an explicit call to `WindowHandle::close`, and the only reliable signal for cleaning up an Audio Unit view is a call to `[NSView dealloc]`. However, this does not mean that Baseview cannot be used in the context of an Audio Unit; it just means that plugin frameworks must implement a compatibility layer with a wrapper `NSView` (which is the approach taken by JUCE).
In order to implement this change:
- `WindowState` is stored in an `Rc` rather than a `Box`.
- `WindowHandle` holds an `Rc<WindowState>` so that `WindowHandle::close` can directly invoke window cleanup logic.
- Since the window can be closed during an event handler, `WindowState::from_view` now returns a clone of the `Rc<WindowState>` held by the `NSView` to ensure that it lives until the end of an event handler.
- In the non-parented case, the `NSView` is set as the window delegate, which allows it to receive the `windowShouldClose:` call when the user clicks the "X" button, upon which it will dispatch the `WillClose` event and initiate window cleanup logic.
- `Window::open_parented` and `open_blocking` no longer `release` the `NSView` immediately after attaching it. Instead, the `NSView` is released as part of the cleanup logic in `WindowInner::close`.
- `Window::resize` now checks if the window is open to avoid using the `NSView` after releasing it.
- The overridden `release` method, the `retain_count_after_build` field, the `ParentHandle` struct, and the `close_requested` flag have all been removed.1 parent fdb43ea commit 2c1b1a7
2 files changed
Lines changed: 114 additions & 190 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
134 | 134 | | |
135 | 135 | | |
136 | 136 | | |
137 | | - | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
138 | 141 | | |
139 | 142 | | |
140 | 143 | | |
| |||
205 | 208 | | |
206 | 209 | | |
207 | 210 | | |
208 | | - | |
209 | | - | |
210 | | - | |
211 | | - | |
212 | | - | |
213 | | - | |
214 | | - | |
215 | | - | |
216 | | - | |
217 | | - | |
218 | | - | |
219 | | - | |
220 | | - | |
221 | | - | |
222 | | - | |
| 211 | + | |
| 212 | + | |
223 | 213 | | |
224 | | - | |
| 214 | + | |
225 | 215 | | |
226 | | - | |
227 | | - | |
| 216 | + | |
228 | 217 | | |
229 | | - | |
230 | | - | |
231 | | - | |
232 | | - | |
233 | | - | |
234 | | - | |
235 | | - | |
236 | | - | |
237 | | - | |
238 | | - | |
| 218 | + | |
239 | 219 | | |
240 | 220 | | |
241 | 221 | | |
| |||
446 | 426 | | |
447 | 427 | | |
448 | 428 | | |
449 | | - | |
| 429 | + | |
450 | 430 | | |
451 | 431 | | |
452 | 432 | | |
| |||
460 | 440 | | |
461 | 441 | | |
462 | 442 | | |
463 | | - | |
| 443 | + | |
464 | 444 | | |
465 | 445 | | |
466 | 446 | | |
| |||
491 | 471 | | |
492 | 472 | | |
493 | 473 | | |
494 | | - | |
| 474 | + | |
495 | 475 | | |
0 commit comments