Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions crates/crashes/src/crashes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,7 @@ pub struct CrashServer {
active_gpu: Mutex<Option<system_specs::GpuSpecs>>,
user_info: Mutex<Option<UserInfo>>,
abort_message_location: Mutex<Option<AbortMessageLocation>>,
shutdown: Arc<AtomicBool>,
has_connection: Arc<AtomicBool>,
logs_dir: PathBuf,
}
Expand Down Expand Up @@ -255,13 +256,19 @@ pub fn set_user_info(crash_client: &Arc<Client>, info: UserInfo) {
send_crash_server_message(crash_client, CrashServerMessage::UserInfo(info));
}

/// Requests an orderly exit from the crash-handler sidecar.
pub fn shutdown_crash_handler(crash_client: &Arc<Client>) {
send_crash_server_message(crash_client, CrashServerMessage::Shutdown);
}

#[derive(Serialize, Deserialize, Debug)]
enum CrashServerMessage {
Init(InitCrashHandler),
Panic(CrashPanic),
GPUInfo(GpuSpecs),
UserInfo(UserInfo),
AbortMessageLocation(AbortMessageLocation),
Shutdown,
}

/// glibc records the diagnostic it prints just before aborting (malloc integrity
Expand Down Expand Up @@ -464,6 +471,9 @@ impl minidumper::ServerHandler for CrashServer {
CrashServerMessage::AbortMessageLocation(location) => {
self.abort_message_location.lock().replace(location);
}
CrashServerMessage::Shutdown => {
self.shutdown.store(true, Ordering::SeqCst);
}
}
}

Expand Down Expand Up @@ -668,6 +678,7 @@ pub fn crash_server(socket: &Path, logs_dir: PathBuf) {
panic_info: Mutex::default(),
user_info: Mutex::default(),
abort_message_location: Mutex::default(),
shutdown: shutdown.clone(),
has_connection,
active_gpu: Mutex::default(),
logs_dir,
Expand Down
15 changes: 13 additions & 2 deletions crates/gpui/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -918,8 +918,19 @@ impl App {
platform.on_quit(Box::new({
let cx = Rc::downgrade(&app);
move || {
if let Some(cx) = cx.upgrade() {
cx.borrow_mut().shutdown();
let Some(cx) = cx.upgrade() else {
return true;
};
match cx.try_borrow_mut() {
Ok(mut cx) => {
cx.shutdown();
true
}
Err(_) => {
// Quit was requested while the AppCell was borrowed, so we can't shut down synchronously.
// The platform decides how to proceed.
false
}
}
}
}));
Expand Down
2 changes: 1 addition & 1 deletion crates/gpui/src/platform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@ pub trait Platform: 'static {
fn reveal_path(&self, path: &Path);
fn open_with_system(&self, path: &Path);

fn on_quit(&self, callback: Box<dyn FnMut()>);
fn on_quit(&self, callback: Box<dyn FnMut() -> bool>);
fn on_reopen(&self, callback: Box<dyn FnMut()>);
fn on_system_wake(&self, callback: Box<dyn FnMut()>);

Expand Down
2 changes: 1 addition & 1 deletion crates/gpui/src/platform/test/platform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,7 @@ impl Platform for TestPlatform {
unimplemented!()
}

fn on_quit(&self, _callback: Box<dyn FnMut()>) {}
fn on_quit(&self, _callback: Box<dyn FnMut() -> bool>) {}

fn on_reopen(&self, _callback: Box<dyn FnMut()>) {
unimplemented!()
Expand Down
2 changes: 1 addition & 1 deletion crates/gpui/src/platform/visual_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ impl Platform for VisualTestPlatform {
self.platform.open_with_system(path)
}

fn on_quit(&self, _callback: Box<dyn FnMut()>) {}
fn on_quit(&self, _callback: Box<dyn FnMut() -> bool>) {}

fn on_reopen(&self, _callback: Box<dyn FnMut()>) {}

Expand Down
4 changes: 2 additions & 2 deletions crates/gpui_linux/src/linux/platform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ pub(crate) trait LinuxClient {
#[derive(Default)]
pub(crate) struct PlatformHandlers {
pub(crate) open_urls: Option<Box<dyn FnMut(Vec<String>)>>,
pub(crate) quit: Option<Box<dyn FnMut()>>,
pub(crate) quit: Option<Box<dyn FnMut() -> bool>>,
pub(crate) reopen: Option<Box<dyn FnMut()>>,
pub(crate) app_menu_action: Option<Box<dyn FnMut(&dyn Action)>>,
pub(crate) will_open_app_menu: Option<Box<dyn FnMut()>>,
Expand Down Expand Up @@ -547,7 +547,7 @@ impl<P: LinuxClient + 'static> Platform for LinuxPlatform<P> {
.detach();
}

fn on_quit(&self, callback: Box<dyn FnMut()>) {
fn on_quit(&self, callback: Box<dyn FnMut() -> bool>) {
self.inner.with_common(|common| {
common.callbacks.quit = Some(callback);
});
Expand Down
4 changes: 2 additions & 2 deletions crates/gpui_macos/src/platform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ pub(crate) struct MacPlatformState {
on_thermal_state_change: Option<Box<dyn FnMut()>>,
on_system_wake: Option<Box<dyn FnMut()>>,
system_wake_observer_registered: bool,
quit: Option<Box<dyn FnMut()>>,
quit: Option<Box<dyn FnMut() -> bool>>,
menu_command: Option<Box<dyn FnMut(&dyn Action)>>,
validate_menu_command: Option<Box<dyn FnMut(&dyn Action) -> bool>>,
will_open_menu: Option<Box<dyn FnMut()>>,
Expand Down Expand Up @@ -940,7 +940,7 @@ impl Platform for MacPlatform {
.detach();
}

fn on_quit(&self, callback: Box<dyn FnMut()>) {
fn on_quit(&self, callback: Box<dyn FnMut() -> bool>) {
self.0.lock().quit = Some(callback);
}

Expand Down
4 changes: 2 additions & 2 deletions crates/gpui_web/src/platform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ impl std::error::Error for WebWindowError {}
#[derive(Default)]
struct WebPlatformCallbacks {
open_urls: Option<Box<dyn FnMut(Vec<String>)>>,
quit: Option<Box<dyn FnMut()>>,
quit: Option<Box<dyn FnMut() -> bool>>,
reopen: Option<Box<dyn FnMut()>>,
app_menu_action: Option<Box<dyn FnMut(&dyn Action)>>,
will_open_app_menu: Option<Box<dyn FnMut()>>,
Expand Down Expand Up @@ -458,7 +458,7 @@ impl Platform for WebPlatform {

fn open_with_system(&self, _path: &Path) {}

fn on_quit(&self, callback: Box<dyn FnMut()>) {
fn on_quit(&self, callback: Box<dyn FnMut() -> bool>) {
self.callbacks.borrow_mut().quit = Some(callback);
}

Expand Down
17 changes: 17 additions & 0 deletions crates/gpui_windows/src/events.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ pub(crate) const WM_GPUI_FORCE_UPDATE_WINDOW: u32 = WM_USER + 5;
pub(crate) const WM_GPUI_KEYBOARD_LAYOUT_CHANGED: u32 = WM_USER + 6;
pub(crate) const WM_GPUI_GPU_DEVICE_LOST: u32 = WM_USER + 7;
pub(crate) const WM_GPUI_KEYDOWN: u32 = WM_USER + 8;
pub(crate) const WM_GPUI_END_SESSION: u32 = WM_USER + 9;

const SIZE_MOVE_LOOP_TIMER_ID: usize = 1;

Expand Down Expand Up @@ -108,6 +109,8 @@ impl WindowsWindowInner {
WM_PAINT => self.handle_paint_msg(handle),
WM_CLOSE => self.handle_close_msg(),
WM_DESTROY => self.handle_destroy_msg(handle),
WM_QUERYENDSESSION => Some(1),
WM_ENDSESSION => self.handle_end_session_msg(wparam),
WM_MOUSEMOVE => self.handle_mouse_move_msg(handle, lparam, wparam),
WM_MOUSELEAVE | WM_NCMOUSELEAVE => self.handle_mouse_leave_msg(),
WM_NCMOUSEMOVE => self.handle_nc_mouse_move_msg(handle, lparam),
Expand Down Expand Up @@ -170,6 +173,20 @@ impl WindowsWindowInner {
}
}

fn handle_end_session_msg(&self, wparam: WPARAM) -> Option<isize> {
if wparam.0 != 0 {
unsafe {
SendMessageW(
self.platform_window_handle,
WM_GPUI_END_SESSION,
Some(WPARAM(self.validation_number)),
None,
);
}
}
Some(0)
}

fn handle_move_msg(&self, handle: HWND, lparam: LPARAM) -> Option<isize> {
let origin = logical_point(
lparam.signed_loword() as f32,
Expand Down
34 changes: 29 additions & 5 deletions crates/gpui_windows/src/platform.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ pub(crate) struct WindowsPlatformState {
#[derive(Default)]
struct PlatformCallbacks {
open_urls: Cell<Option<Box<dyn FnMut(Vec<String>)>>>,
quit: Cell<Option<Box<dyn FnMut()>>>,
quit: Cell<Option<Box<dyn FnMut() -> bool>>>,
reopen: Cell<Option<Box<dyn FnMut()>>>,
app_menu_action: Cell<Option<Box<dyn FnMut(&dyn Action)>>>,
will_open_app_menu: Cell<Option<Box<dyn FnMut()>>>,
Expand Down Expand Up @@ -460,8 +460,12 @@ impl Platform for WindowsPlatform {
}
}

self.inner
.with_callback(|callbacks| &callbacks.quit, |callback| callback());
self.inner.with_callback(
|callbacks| &callbacks.quit,
|callback| {
callback();
},
);
}

fn quit(&self) {
Expand Down Expand Up @@ -667,7 +671,7 @@ impl Platform for WindowsPlatform {
.detach();
}

fn on_quit(&self, callback: Box<dyn FnMut()>) {
fn on_quit(&self, callback: Box<dyn FnMut() -> bool>) {
self.inner.state.callbacks.quit.set(Some(callback));
}

Expand Down Expand Up @@ -997,7 +1001,8 @@ impl WindowsPlatformInner {
| WM_GPUI_TASK_DISPATCHED_ON_MAIN_THREAD
| WM_GPUI_DOCK_MENU_ACTION
| WM_GPUI_KEYBOARD_LAYOUT_CHANGED
| WM_GPUI_GPU_DEVICE_LOST => self.handle_gpui_events(msg, wparam, lparam),
| WM_GPUI_GPU_DEVICE_LOST
| WM_GPUI_END_SESSION => self.handle_gpui_events(msg, wparam, lparam),
WM_POWERBROADCAST => self.handle_power_broadcast(wparam),
_ => None,
};
Expand All @@ -1022,10 +1027,29 @@ impl WindowsPlatformInner {
WM_GPUI_DOCK_MENU_ACTION => self.handle_dock_action_event(lparam.0 as _),
WM_GPUI_KEYBOARD_LAYOUT_CHANGED => self.handle_keyboard_layout_change(),
WM_GPUI_GPU_DEVICE_LOST => self.handle_device_lost(lparam),
WM_GPUI_END_SESSION => self.handle_end_session(),
_ => unreachable!(),
}
}

fn handle_end_session(&self) -> Option<isize> {
let mut shutdown_completed = false;
self.with_callback(
|callbacks| &callbacks.quit,
|callback| shutdown_completed = callback(),
);
log::logger().flush();
if shutdown_completed {
std::process::exit(0);
}

// Shutdown couldn't run synchronously, since the AppCell is already borrowed.
// Windows may terminate the application as soon as we return from this handler, but if we post a WM_QUIT message now,
// we may get to gracefully shut down the app before we're terminated by the OS.
unsafe { PostQuitMessage(0) };
Some(0)
}

fn close_one_window(&self, target_window: HWND) -> bool {
let Some(all_windows) = self.raw_window_handles.upgrade() else {
log::error!("Failed to upgrade raw window handles");
Expand Down
Loading