Fix #661: quitting no longer crashes on Macs with a Touch Bar
On every quit (Cmd+Q, VectorCraft > Quit, the close button) on a MacBook Pro with a Touch Bar, AppKit threw from -[_NSTouchBarFinderObservation invalidate] and macOS reported a crash. AccessKit's macOS adapter subclasses the window's content view and gives it back its own class when the window is torn down; AppKit's Touch Bar support observes the view under the subclass, so removing that observation throws (the same cause Zed fixed in zed-industries/zed#65186). On macOS with accessibility, the app now ends the process at the end of on_exit, once the preferences are saved, before eframe tears the window down. Nothing after the window is needed on a normal quit. While the window is still starting up it doesn't, so a graphics failure still starts the app again on another adapter (#651). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
01ad745e86
commit
f17bac2c64
File diff suppressed because one or more lines are too long
|
|
@ -37,7 +37,7 @@ const HELP: &str =
|
|||
/// Frames the UI ran before the failure, below which it was still starting up. The failure in
|
||||
/// #502 came on the first or second frame; later, the adapter has proved itself, and a lost
|
||||
/// window is something else (such as the compositor restarting).
|
||||
const STARTUP_FRAMES: u64 = 10;
|
||||
pub const STARTUP_FRAMES: u64 = 10;
|
||||
|
||||
/// The preference used when Preferences say Automatic. Windows and macOS show frames from any GPU
|
||||
/// (the integrated one avoids the flicker of #306). Elsewhere, the system's own order: Mesa's
|
||||
|
|
|
|||
|
|
@ -43,10 +43,13 @@ struct App {
|
|||
graphics_loss: GraphicsLoss,
|
||||
/// The graphics device was lost and the unsaved changes are kept for Data Recovery.
|
||||
graphics_lost: bool,
|
||||
/// Frames the UI has run (see [`end_before_teardown`]).
|
||||
frames: u64,
|
||||
}
|
||||
|
||||
impl eframe::App for App {
|
||||
fn logic(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
|
||||
self.frames = ctx.cumulative_frame_nr();
|
||||
if let Some(why) = self.graphics_loss.take() {
|
||||
// eframe can't give a window a new device: the user saves and starts again.
|
||||
self.graphics_lost = self.app.graphics_lost(&why);
|
||||
|
|
@ -87,6 +90,7 @@ impl eframe::App for App {
|
|||
#[cfg(not(feature = "windows7"))]
|
||||
fn on_exit(&mut self) {
|
||||
save_prefs(&self.app);
|
||||
end_before_teardown(self.frames);
|
||||
}
|
||||
#[cfg(feature = "windows7")]
|
||||
fn on_exit(&mut self, _gl: Option<&eframe::glow::Context>) {
|
||||
|
|
@ -94,6 +98,22 @@ impl eframe::App for App {
|
|||
}
|
||||
}
|
||||
|
||||
/// On macOS with accessibility, end the process once the app has saved what it keeps on quitting,
|
||||
/// before eframe tears the window down (#661). AccessKit then gives the window's content view back
|
||||
/// its own class, which AppKit's Touch Bar support was observing it under, and AppKit aborts the
|
||||
/// app as it quits on Macs with a Touch Bar. Nothing after the window is needed on a normal quit.
|
||||
/// Not while the window is still starting up (`frames` below [`gpu::STARTUP_FRAMES`]): a graphics
|
||||
/// failure then starts the app again on another adapter (#651).
|
||||
#[allow(unused_variables)]
|
||||
fn end_before_teardown(frames: u64) {
|
||||
#[cfg(all(target_os = "macos", feature = "accessibility", feature = "wgpu"))]
|
||||
if frames >= gpu::STARTUP_FRAMES {
|
||||
log::info!("quitting");
|
||||
log::logger().flush();
|
||||
std::process::exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
/// Open files handed to the app (command line, macOS Finder and Dock) as documents. A file that
|
||||
/// can't be opened is reported in the status bar and on stderr; the others still open.
|
||||
fn open_files(app: &mut VectorcraftApp, files: Vec<String>) {
|
||||
|
|
@ -495,7 +515,7 @@ fn main() -> std::process::ExitCode {
|
|||
#[cfg(not(target_os = "macos"))]
|
||||
let _ = in_window_menus;
|
||||
open_files(&mut app, files);
|
||||
Ok(Box::new(App { app, graphics_loss, graphics_lost: false }))
|
||||
Ok(Box::new(App { app, graphics_loss, graphics_lost: false, frames: 0 }))
|
||||
}),
|
||||
)
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue