From: Zhiyi Zhang zzhang@codeweavers.com
When transitioning a window from IconicState to NormalState and the window is managed, go through WithdrawnState. This is needed because Mutter doesn't unmap windows when making windows iconic/minimized as Mutter needs to support live preview for minimized windows. So on Mutter, a window can be both iconic and mapped. If the window is mapped, then XMapWindow() will have no effect according to the XMapWindow() documentation. Thus we have to transition to WithdrawnState first, then to NormalState.
Fix Mass Effect Legendary Edition (1328670) starts minimized. --- dlls/user32/tests/win.c | 1 - dlls/winex11.drv/window.c | 14 ++++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/dlls/user32/tests/win.c b/dlls/user32/tests/win.c index bfe89539ba4..02a6793f352 100644 --- a/dlls/user32/tests/win.c +++ b/dlls/user32/tests/win.c @@ -7817,7 +7817,6 @@ static void test_ShowWindow(void) BitBlt(mem_dc, 0, 0, 200, 200, screen_dc, 0, 0, SRCCOPY);
color = GetPixel(mem_dc, 150, 150); - todo_wine_if(color != RGB(0xff, 0, 0xff)) /* fails on Mutter */ ok(color == RGB(0xff, 0, 0xff), "Got unexpected color %#lx.\n", color);
DeleteObject(mem_bitmap); diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index b033960fc26..7ae1d8ef66a 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -1448,6 +1448,20 @@ static void window_set_wm_state( struct x11drv_win_data *data, UINT new_state ) return; /* another map/unmap WM_STATE update is pending, wait for it to complete */ if (old_state == new_state) return; /* states are the same, nothing to update */
+ /* When transitioning a window from IconicState to NormalState and the window is managed, go + * through WithdrawnState. This is needed because Mutter doesn't unmap windows when making + * windows iconic/minimized as Mutter needs to support live preview for minimized windows. So on + * Mutter, a window can be both iconic and mapped. If the window is mapped, then XMapWindow() + * will have no effect according to the XMapWindow() documentation. Thus we have to transition + * to WithdrawnState first, then to NormalState */ + if (data->managed && MAKELONG(old_state, new_state) == MAKELONG(IconicState, NormalState)) + { + WARN( "window %p/%lx is iconic, remapping to workaround Mutter issues.\n", data->hwnd, data->whole_window ); + window_set_wm_state( data, WithdrawnState ); + window_set_wm_state( data, NormalState ); + return; + } + switch (MAKELONG(old_state, new_state)) { case MAKELONG(WithdrawnState, IconicState):