Some applications depend on the fact that WM_WINDOWPOSCHANGING is sent after WM_SHOWWINDOW when SetParent is called, even if the window ends up not visible because its parent is not visible, and occurs when the window itself does not have the WS_CHILD style set.
This also fixes a TODO message sequence, so that Wine matches Windows.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=40262 Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/user32/tests/msg.c | 3 ++- dlls/user32/winpos.c | 11 +++++++---- 2 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c index bf20c5c..fb341cc 100644 --- a/dlls/user32/tests/msg.c +++ b/dlls/user32/tests/msg.c @@ -16397,6 +16397,7 @@ static const struct message WmSetParentSeq_2[] = { { HCBT_ACTIVATE, hook|optional }, { EVENT_SYSTEM_FOREGROUND, winevent_hook|wparam|lparam, 0, 0 }, { WM_WINDOWPOSCHANGING, sent|wparam|optional, SWP_NOSIZE|SWP_NOMOVE }, + { WM_QUERYNEWPALETTE, sent|optional }, { WM_NCACTIVATE, sent|wparam|optional, 1 }, { WM_ACTIVATE, sent|wparam|optional, 1 }, { HCBT_SETFOCUS, hook|optional }, @@ -16467,7 +16468,7 @@ static void test_SetParent(void)
SetParent(popup, child); flush_events(); - ok_sequence(WmSetParentSeq_2, "SetParent() visible WS_POPUP", TRUE); + ok_sequence(WmSetParentSeq_2, "SetParent() visible WS_POPUP", FALSE);
ok(GetWindowLongA(popup, GWL_STYLE) & WS_VISIBLE, "WS_VISIBLE should be set\n"); ok(!IsWindowVisible(popup), "IsWindowVisible() should return FALSE\n"); diff --git a/dlls/user32/winpos.c b/dlls/user32/winpos.c index e3c3f5c..7b5c657 100644 --- a/dlls/user32/winpos.c +++ b/dlls/user32/winpos.c @@ -1122,8 +1122,8 @@ static BOOL show_window( HWND hwnd, INT cmd )
swp = USER_Driver->pShowWindow( hwnd, cmd, &newPos, swp );
- parent = GetAncestor( hwnd, GA_PARENT ); - if (parent && !IsWindowVisible( parent ) && !(swp & SWP_STATECHANGED)) + if ((style & WS_CHILD) && (parent = GetAncestor( hwnd, GA_PARENT )) && + !IsWindowVisible( parent ) && !(swp & SWP_STATECHANGED)) { /* if parent is not visible simply toggle WS_VISIBLE and return */ if (showFlag) WIN_SetStyle( hwnd, WS_VISIBLE, 0 ); @@ -1958,8 +1958,11 @@ static BOOL fixup_flags( WINDOWPOS *winpos, const RECT *old_window_rect, int par if (winpos->cy < 0) winpos->cy = 0; else if (winpos->cy > 32767) winpos->cy = 32767;
- parent = GetAncestor( winpos->hwnd, GA_PARENT ); - if (!IsWindowVisible( parent )) winpos->flags |= SWP_NOREDRAW; + if (wndPtr->dwStyle & WS_CHILD) + { + parent = GetAncestor( winpos->hwnd, GA_PARENT ); + if (!IsWindowVisible( parent )) winpos->flags |= SWP_NOREDRAW; + }
if (wndPtr->dwStyle & WS_VISIBLE) winpos->flags &= ~SWP_SHOWWINDOW; else
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=78790
Your paranoid android.
=== w10pro64 (64 bit report) ===
user32: msg.c:13904: Test failed: CreateDialogParam_1: 15: the msg 0x001c was expected, but got msg 0x0047 instead msg.c:13904: Test failed: CreateDialogParam_1: 16: the msg 0x0086 was expected, but got msg 0x001c instead msg.c:13904: Test failed: CreateDialogParam_1: 17: the msg 0x0006 was expected, but got msg 0x0086 instead msg.c:13904: Test failed: CreateDialogParam_1: 18: the msg 0x0007 was expected, but got msg 0x0006 instead msg.c:13904: Test failed: CreateDialogParam_1: 20: the msg sequence is not complete: expected 0000 - actual 0007
=== debiant (32 bit report) ===
user32: monitor: Timeout
=== debiant (32 bit Chinese:China report) ===
user32: monitor: Timeout
=== debiant (32 bit WoW report) ===
user32: monitor: Timeout
=== debiant (64 bit WoW report) ===
user32: monitor: Timeout
Hi,
Is there something wrong with this patch, or something I should add to it? I've resent it a few times now and always slept through the cracks. It fixes the bug, and fixes the existing message sequence to match Windows. (the WM_QUERYNEWPALETTE is optional and only because Wine sends it, Windows only does that in 256-color mode, which is completely unrelated to this patch)
FWIW, the patch just adds checks for WS_CHILD, because apparently that's what Windows does, and that's what fixes the bug, too.