On X11 / XWayland the PropertyNotify for WM_STATE change from IconicState to NormalState arrives before the WM_TAKE_FOCUS ClientMessage and the FocusIn events.
Converting that state change too early to a WM_SYSCOMMAND SC_RESTORE results in it (and the ACTIVATE events because of the previous HAX) arriving without the window being set to foregrounds first.
This breaks the expectations of Project CARS 3. The game tries to re-acquire DirectInput devices with cooperative level set to DISCL_FOREGROUND, which fails.
Signed-off-by: Arkadiusz Hiler ahiler@codeweavers.com --- dlls/winex11.drv/event.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index 1772a27c48b..5f5597a48be 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -87,6 +87,8 @@ extern BOOL ximInComposeMode; #define XEMBED_UNREGISTER_ACCELERATOR 13 #define XEMBED_ACTIVATE_ACCELERATOR 14
+static const WCHAR restore_window_propW[] = {'_','_','W','I','N','E','_','R','E','S','T','O','R','E','_','W','I','N','D','O','W',0}; + Bool (*pXGetEventData)( Display *display, XEvent /*XGenericEventCookie*/ *event ) = NULL; void (*pXFreeEventData)( Display *display, XEvent /*XGenericEventCookie*/ *event ) = NULL;
@@ -556,7 +558,7 @@ static inline BOOL can_activate_window( HWND hwnd )
if (!(style & WS_VISIBLE)) return FALSE; if ((style & (WS_POPUP|WS_CHILD)) == WS_CHILD) return FALSE; - if (style & WS_MINIMIZE) return FALSE; + if ((style & WS_MINIMIZE) && !GetPropW( hwnd, restore_window_propW )) return FALSE; if (GetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_NOACTIVATE) return FALSE; if (hwnd == GetDesktopWindow()) return FALSE; if (GetWindowRect( hwnd, &rect ) && IsRectEmpty( &rect )) return FALSE; @@ -1318,9 +1320,10 @@ static void handle_wm_state_notify( HWND hwnd, XPropertyEvent *event, BOOL updat { TRACE( "restoring win %p/%lx\n", data->hwnd, data->whole_window ); release_win_data( data ); - if ((style & (WS_MINIMIZE | WS_VISIBLE)) == (WS_MINIMIZE | WS_VISIBLE)) - SetActiveWindow( hwnd ); - SendMessageW( hwnd, WM_SYSCOMMAND, SC_RESTORE, 0 ); + if ((style & (WS_MINIMIZE | WS_VISIBLE)) == (WS_MINIMIZE | WS_VISIBLE) && GetForegroundWindow() != hwnd) + SetPropW( hwnd, restore_window_propW, (HANDLE) TRUE ); + else + SendMessageW( hwnd, WM_SYSCOMMAND, SC_RESTORE, 0 ); return; } TRACE( "not restoring win %p/%lx style %08x\n", data->hwnd, data->whole_window, style );