From a1edbeb448d1104b8e9dd3181a04d45ff846a397 Mon Sep 17 00:00:00 2001 From: Tony <68118705+Legend-Master@users.noreply.github.com> Date: Sat, 23 Aug 2025 14:21:55 +0800 Subject: [PATCH] fix(windows): emit LoopDestroyed on WM_ENDSESSION (#1126) --- .changes/wm-endsession.md | 5 +++++ src/platform_impl/windows/event_loop.rs | 20 +++++++++++++++++--- src/platform_impl/windows/util.rs | 1 + 3 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 .changes/wm-endsession.md diff --git a/.changes/wm-endsession.md b/.changes/wm-endsession.md new file mode 100644 index 00000000..fc8a3966 --- /dev/null +++ b/.changes/wm-endsession.md @@ -0,0 +1,5 @@ +--- +tao: patch +--- + +Emit `Event::LoopDestroyed` on receiving `WM_ENDSESSION` message on Windows diff --git a/src/platform_impl/windows/event_loop.rs b/src/platform_impl/windows/event_loop.rs index d1a0a818..17fad672 100644 --- a/src/platform_impl/windows/event_loop.rs +++ b/src/platform_impl/windows/event_loop.rs @@ -22,7 +22,9 @@ use std::{ use windows::{ core::{s, BOOL, PCWSTR}, Win32::{ - Foundation::{HANDLE, HINSTANCE, HWND, LPARAM, LRESULT, POINT, RECT, WAIT_TIMEOUT, WPARAM}, + Foundation::{ + HANDLE, HINSTANCE, HWND, LPARAM, LRESULT, POINT, RECT, TRUE, WAIT_TIMEOUT, WPARAM, + }, Graphics::Gdi::*, System::{ LibraryLoader::GetModuleHandleW, @@ -642,7 +644,7 @@ lazy_static! { RegisterWindowMessageA(s!("TaskbarCreated")) }; static ref THREAD_EVENT_TARGET_WINDOW_CLASS: Vec = unsafe { - let class_name= util::encode_wide("Tao Thread Event Target"); + let class_name = util::encode_wide("Tao Thread Event Target"); let class = WNDCLASSEXW { cbSize: mem::size_of::() as u32, @@ -650,7 +652,7 @@ lazy_static! { lpfnWndProc: Some(util::call_default_window_proc), cbClsExtra: 0, cbWndExtra: 0, - hInstance:HINSTANCE(GetModuleHandleW(PCWSTR::null()).unwrap_or_default().0), + hInstance: HINSTANCE(GetModuleHandleW(PCWSTR::null()).unwrap_or_default().0), hIcon: HICON::default(), hCursor: HCURSOR::default(), // must be null in order for cursor state to work properly hbrBackground: HBRUSH::default(), @@ -2380,6 +2382,18 @@ unsafe extern "system" fn thread_event_target_callback( DefSubclassProc(window, msg, wparam, lparam) } + // We don't process `WM_QUERYENDSESSION` yet until we introduce the same mechanism as Tauri's `ExitRequested` event + // win32wm::WM_QUERYENDSESSION => {} + win32wm::WM_ENDSESSION => { + // `wParam` is `FALSE` is for if the shutdown gets canceled, + // 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(); + } + // Note: after we return 0 here, Windows will shut us down + LRESULT(0) + } + _ if msg == *USER_EVENT_MSG_ID => { if let Ok(event) = subclass_input.user_event_receiver.recv() { subclass_input.send_event(Event::UserEvent(event)); diff --git a/src/platform_impl/windows/util.rs b/src/platform_impl/windows/util.rs index b9d2f926..5605603d 100644 --- a/src/platform_impl/windows/util.rs +++ b/src/platform_impl/windows/util.rs @@ -291,6 +291,7 @@ pub type GetDpiForMonitor = unsafe extern "system" fn( type GetSystemMetricsForDpi = unsafe extern "system" fn(nindex: SYSTEM_METRICS_INDEX, dpi: u32) -> i32; pub type EnableNonClientDpiScaling = unsafe extern "system" fn(hwnd: HWND) -> BOOL; +#[allow(non_snake_case)] pub type AdjustWindowRectExForDpi = unsafe extern "system" fn( rect: *mut RECT, dwStyle: WINDOW_STYLE,