Skip to content
Open
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
5 changes: 5 additions & 0 deletions .changes/wm-endsession-exit.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
tao: patch
---

Exits the process on receiving `WM_ENDSESSION` message, this fixes the `cannot move state from Destroyed` crash after receiving the message from Restart Manager
8 changes: 7 additions & 1 deletion src/platform_impl/windows/event_loop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2414,8 +2414,14 @@ unsafe extern "system" fn thread_event_target_callback<T: 'static>(
// and we don't need to handle that case since we didn't do anything prior in response to `WM_QUERYENDSESSION`
if wparam.0 == TRUE.0 as usize {
subclass_input.event_loop_runner.loop_destroyed();
// `WM_ENDSESSION` can be sent by Windows during shutdown or by Restart Manager
//
// - From Windows shutdown: Windows will shut us down after we return `0` here
// - From Restart Manager: Restart Manager only sends the message but will wait for us to shutdown ourselves
//
// So, we call `exit` here directly to align this behavior
std::process::exit(0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does also happen in the run_return case? I would really like to not have this then as we want to do some graceful cleanup before exiting.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does also happen in the run_return case?

This happens in all cases when you spin the event loop, and yes, including run_return. One thing to note here is no matter what we do here, during shutdown, Windows will terminate us anyways

This does trigger Exit event for you to do some clean ups though

Copy link
Contributor

@thomaseizinger thomaseizinger Feb 20, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does trigger Exit event for you to do some clean ups though

I don't quite understand that. If you call process exit here, no more code can execute after this, right?

I don't know the details of WM_ENDSESSION but why can't we just gracefully exit the event-loop here? What would be the point of a signal from Windows if we can't run a few more instructions to shut down?

Exiting the process should IMO be reserved for the binary that embeds Tauri and not happen in Tauri itself.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't quite understand that. If you call process exit here, no more code can execute after this, right?

Yes, the event handler is called in the line above

subclass_input.event_loop_runner.loop_destroyed();


I don't know the details of WM_ENDSESSION but why can't we just gracefully exit the event-loop here? What would be the point of a signal from Windows if we can't run a few more instructions to shut down?

Exiting the process should IMO be reserved for the binary that embeds Tauri and not happen in Tauri itself.

In the Windows shutdown case, you're supposed to block the event loop (not returning from the window procedure) to do the clean up, and once you return, Windows terminates the app if you don't do it yourselves

For the restart manager case, see my comment above #1157 (comment)

}
// Note: after we return 0 here, Windows will shut us down
LRESULT(0)
}

Expand Down
Loading