Alexandre Julliard : user32: Only show a window the first time WS_VISIBLE is toggled, to work around Steam's WM_SETREDRAW usage.

Alexandre Julliard julliard at winehq.org
Tue Sep 4 12:38:36 CDT 2012


Module: wine
Branch: master
Commit: 2dc234d923b70fa0a0e1815d909035d059aa8772
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=2dc234d923b70fa0a0e1815d909035d059aa8772

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Tue Sep  4 12:38:33 2012 +0200

user32: Only show a window the first time WS_VISIBLE is toggled, to work around Steam's WM_SETREDRAW usage.

---

 dlls/user32/win.c    |   58 +++++++++++++++++++++++++++++++-------------------
 dlls/user32/win.h    |    1 +
 dlls/user32/winpos.c |    3 ++
 3 files changed, 40 insertions(+), 22 deletions(-)

diff --git a/dlls/user32/win.c b/dlls/user32/win.c
index 66fc8cc..82d62b1 100644
--- a/dlls/user32/win.c
+++ b/dlls/user32/win.c
@@ -606,7 +606,7 @@ HWND WIN_SetOwner( HWND hwnd, HWND owner )
  */
 ULONG WIN_SetStyle( HWND hwnd, ULONG set_bits, ULONG clear_bits )
 {
-    BOOL ok;
+    BOOL ok, needs_show = FALSE;
     STYLESTRUCT style;
     WND *win = WIN_GetPtr( hwnd );
 
@@ -638,20 +638,29 @@ ULONG WIN_SetStyle( HWND hwnd, ULONG set_bits, ULONG clear_bits )
         }
     }
     SERVER_END_REQ;
-    WIN_ReleasePtr( win );
-    if (ok)
+
+    if (ok && ((style.styleOld ^ style.styleNew) & WS_VISIBLE))
     {
-        if ((style.styleOld ^ style.styleNew) & WS_VISIBLE)
-        {
-            RECT window_rect, client_rect;
-            UINT flags = style.styleNew & WS_VISIBLE ? SWP_SHOWWINDOW : 0; /* we don't hide it */
+        /* Some apps try to make their window visible through WM_SETREDRAW.
+         * Only do that if the window was never explicitly hidden,
+         * because Steam messes with WM_SETREDRAW after hiding its windows. */
+        needs_show = !(win->flags & WIN_HIDDEN) && (style.styleNew & WS_VISIBLE);
+        invalidate_dce( win, NULL );
+    }
+    WIN_ReleasePtr( win );
 
-            WIN_GetRectangles( hwnd, COORDS_PARENT, &window_rect, &client_rect );
-            set_window_pos( hwnd, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE |
-                            SWP_NOZORDER | SWP_NOACTIVATE | flags, &window_rect, &client_rect, NULL );
-        }
-        USER_Driver->pSetWindowStyle( hwnd, GWL_STYLE, &style );
+    if (!ok) return 0;
+
+    if (needs_show)
+    {
+        RECT window_rect, client_rect;
+        WIN_GetRectangles( hwnd, COORDS_PARENT, &window_rect, &client_rect );
+        set_window_pos( hwnd, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE |
+                        SWP_NOZORDER | SWP_NOACTIVATE | SWP_SHOWWINDOW,
+                        &window_rect, &client_rect, NULL );
     }
+
+    USER_Driver->pSetWindowStyle( hwnd, GWL_STYLE, &style );
     return style.styleOld;
 }
 
@@ -2135,7 +2144,7 @@ static LONG_PTR WIN_GetWindowLong( HWND hwnd, INT offset, UINT size, BOOL unicod
 LONG_PTR WIN_SetWindowLong( HWND hwnd, INT offset, UINT size, LONG_PTR newval, BOOL unicode )
 {
     STYLESTRUCT style;
-    BOOL ok;
+    BOOL ok, needs_show = FALSE;
     LONG_PTR retval = 0;
     WND *wndPtr;
 
@@ -2334,23 +2343,28 @@ LONG_PTR WIN_SetWindowLong( HWND hwnd, INT offset, UINT size, LONG_PTR newval, B
         }
     }
     SERVER_END_REQ;
+
+    if (offset == GWL_STYLE && ((style.styleOld ^ style.styleNew) & WS_VISIBLE))
+    {
+        needs_show = !(wndPtr->flags & WIN_HIDDEN) && (style.styleNew & WS_VISIBLE);
+        invalidate_dce( wndPtr, NULL );
+    }
     WIN_ReleasePtr( wndPtr );
 
     if (!ok) return 0;
 
+    if (needs_show)
+    {
+        RECT window_rect, client_rect;
+        WIN_GetRectangles( hwnd, COORDS_PARENT, &window_rect, &client_rect );
+        set_window_pos( hwnd, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE |
+                        SWP_NOZORDER | SWP_NOACTIVATE | SWP_SHOWWINDOW,
+                        &window_rect, &client_rect, NULL );
+    }
     if (offset == GWL_STYLE || offset == GWL_EXSTYLE)
     {
         style.styleOld = retval;
         style.styleNew = newval;
-        if (offset == GWL_STYLE && ((style.styleOld ^ style.styleNew) & WS_VISIBLE))
-        {
-            RECT window_rect, client_rect;
-            UINT flags = style.styleNew & WS_VISIBLE ? SWP_SHOWWINDOW : 0; /* we don't hide it */
-
-            WIN_GetRectangles( hwnd, COORDS_PARENT, &window_rect, &client_rect );
-            set_window_pos( hwnd, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOCLIENTSIZE | SWP_NOCLIENTMOVE |
-                            SWP_NOZORDER | SWP_NOACTIVATE | flags, &window_rect, &client_rect, NULL );
-        }
         USER_Driver->pSetWindowStyle( hwnd, offset, &style );
         SendMessageW( hwnd, WM_STYLECHANGED, offset, (LPARAM)&style );
     }
diff --git a/dlls/user32/win.h b/dlls/user32/win.h
index 13ee58e..7c899ac 100644
--- a/dlls/user32/win.h
+++ b/dlls/user32/win.h
@@ -73,6 +73,7 @@ typedef struct tagWND
 #define WIN_ISUNICODE             0x0010 /* Window is Unicode */
 #define WIN_NEEDS_SHOW_OWNEDPOPUP 0x0020 /* WM_SHOWWINDOW:SC_SHOW must be sent in the next ShowOwnedPopup call */
 #define WIN_CHILDREN_MOVED        0x0040 /* children may have moved, ignore stored positions */
+#define WIN_HIDDEN                0x0080 /* hidden by an explicit SWP_HIDEWINDOW (as opposed to WM_SETREDRAW) */
 
   /* Window functions */
 extern HWND get_hwnd_message_parent(void) DECLSPEC_HIDDEN;
diff --git a/dlls/user32/winpos.c b/dlls/user32/winpos.c
index 23b0b7f..507a5ce 100644
--- a/dlls/user32/winpos.c
+++ b/dlls/user32/winpos.c
@@ -1872,6 +1872,9 @@ static BOOL fixup_flags( WINDOWPOS *winpos )
     parent = GetAncestor( winpos->hwnd, GA_PARENT );
     if (!IsWindowVisible( parent )) winpos->flags |= SWP_NOREDRAW;
 
+    if (winpos->flags & SWP_HIDEWINDOW) wndPtr->flags |= WIN_HIDDEN;
+    else if (winpos->flags & SWP_SHOWWINDOW) wndPtr->flags &= ~WIN_HIDDEN;
+
     if (wndPtr->dwStyle & WS_VISIBLE) winpos->flags &= ~SWP_SHOWWINDOW;
     else
     {




More information about the wine-cvs mailing list