From 1a6c1b2159ae1a8d8aaa0e1ddf764ab3d371fd0a Mon Sep 17 00:00:00 2001 From: Matin Aniss <76515905+MatinAniss@users.noreply.github.com> Date: Mon, 23 Jun 2025 23:13:53 +1000 Subject: [PATCH] windows: Fix window close animation (#33228) Implements a workaround which removes the `WS_EX_LAYERED` style from the window right before closing it which seems to fix the window close animation not playing. Release Notes: - N/A --- crates/gpui/src/platform/windows/events.rs | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/crates/gpui/src/platform/windows/events.rs b/crates/gpui/src/platform/windows/events.rs index a390762ddd..65565c6b3f 100644 --- a/crates/gpui/src/platform/windows/events.rs +++ b/crates/gpui/src/platform/windows/events.rs @@ -48,7 +48,7 @@ pub(crate) fn handle_msg( WM_DISPLAYCHANGE => handle_display_change_msg(handle, state_ptr), WM_NCHITTEST => handle_hit_test_msg(handle, msg, wparam, lparam, state_ptr), WM_PAINT => handle_paint_msg(handle, state_ptr), - WM_CLOSE => handle_close_msg(state_ptr), + WM_CLOSE => handle_close_msg(handle, state_ptr), WM_DESTROY => handle_destroy_msg(handle, state_ptr), WM_MOUSEMOVE => handle_mouse_move_msg(handle, lparam, wparam, state_ptr), WM_MOUSELEAVE | WM_NCMOUSELEAVE => handle_mouse_leave_msg(state_ptr), @@ -248,16 +248,30 @@ fn handle_paint_msg(handle: HWND, state_ptr: Rc) -> Optio Some(0) } -fn handle_close_msg(state_ptr: Rc) -> Option { +fn handle_close_msg(handle: HWND, state_ptr: Rc) -> Option { let mut lock = state_ptr.state.borrow_mut(); - if let Some(mut callback) = lock.callbacks.should_close.take() { + let output = if let Some(mut callback) = lock.callbacks.should_close.take() { drop(lock); let should_close = callback(); state_ptr.state.borrow_mut().callbacks.should_close = Some(callback); if should_close { None } else { Some(0) } } else { None + }; + + // Workaround as window close animation is not played with `WS_EX_LAYERED` enabled. + if output.is_none() { + unsafe { + let current_style = get_window_long(handle, GWL_EXSTYLE); + set_window_long( + handle, + GWL_EXSTYLE, + current_style & !WS_EX_LAYERED.0 as isize, + ); + } } + + output } fn handle_destroy_msg(handle: HWND, state_ptr: Rc) -> Option {