From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/window.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 00023632d13..f15e3d5c6b1 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -2546,6 +2546,7 @@ BOOL WINAPI NtUserUpdateLayeredWindow( HWND hwnd, HDC hdc_dst, const POINT *pts_ const BLENDFUNCTION *blend, DWORD flags, const RECT *dirty ) { DWORD swp_flags = SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW; + BYTE source_alpha = blend ? blend->SourceConstantAlpha : 0xff; struct window_rects new_rects; struct window_surface *surface; RECT surface_rect; @@ -2602,7 +2603,7 @@ BOOL WINAPI NtUserUpdateLayeredWindow( HWND hwnd, HDC hdc_dst, const POINT *pts_
if (!hdc_src || surface == &dummy_surface) { - user_driver->pUpdateLayeredWindow( hwnd, blend->SourceConstantAlpha, flags ); + user_driver->pUpdateLayeredWindow( hwnd, source_alpha, flags ); ret = TRUE; } else @@ -2636,7 +2637,7 @@ BOOL WINAPI NtUserUpdateLayeredWindow( HWND hwnd, HDC hdc_dst, const POINT *pts_ if (!(flags & ULW_COLORKEY)) key = CLR_INVALID; window_surface_set_layered( surface, key, -1, 0xff000000 );
- user_driver->pUpdateLayeredWindow( hwnd, blend->SourceConstantAlpha, flags ); + user_driver->pUpdateLayeredWindow( hwnd, source_alpha, flags ); window_surface_flush( surface ); }
From: Rémi Bernon rbernon@codeweavers.com
This is a workaround fixing some regression introduced with b9318e3805f9d000474411cb889719003805fa32, when UpdateLayeredWindow is being called from a non-owner thread which also doesn't have its winex11 thread data initialized.
It would be better to avoid updating windows from any non-owner thread, and most of user32 functions make sure of it by sending messages to the window owner thread when appropriate, but that doesn't work with ULW as the owner thread might not be processing messages, and yet ULW windows are still supposed to be updated and moved around.
The proper fix for that would be to have a dedicated thread managing window surfaces, which might introduced in the future for compositing purposes, but that's a much bigger change and we the workaround should be acceptable in the meantime.
Based on work by Jacob Czekalla. --- dlls/winex11.drv/window.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index fce1bc7e16e..8a525051109 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -1330,7 +1330,7 @@ static void window_set_net_wm_state( struct x11drv_win_data *data, UINT new_stat { UINT i, count, old_state = data->pending_state.net_wm_state;
- new_state &= x11drv_thread_data()->net_wm_state_mask; + new_state &= x11drv_init_thread_data()->net_wm_state_mask; data->desired_state.net_wm_state = new_state; if (!data->whole_window || !data->managed || data->embedded) return; /* no window or not managed, nothing to update */ if (data->wm_state_serial) return; /* another WM_STATE update is pending, wait for it to complete */