Module: wine Branch: master Commit: 2dc234d923b70fa0a0e1815d909035d059aa8772 URL: http://source.winehq.org/git/wine.git/?a=commit;h=2dc234d923b70fa0a0e1815d90...
Author: Alexandre Julliard julliard@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 {