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