[PATCH 2/2] winex11.drv: Use __WINE_RESTORE_PROPRTY so Window is un-minimized on FocusIn.

Arkadiusz Hiler ahiler at codeweavers.com
Fri Jul 2 08:01:29 CDT 2021


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 at 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 );
-- 
2.32.0




More information about the wine-devel mailing list