Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57665
---
The issue is that The Medium launcher uses a dialog window procedure, and implements its background by doing a StretchBlt call on WM_PAINT in the dialog procedure call, which happens before the window message loop.
It then itself calls InvalidateRect(hwnd, NULL, 0), which queues a WM_PAINT as well but with only the RDW_INVALIDATE flag.
Next, when the window message loop is executed, the WM_PAINT message is being processed as it should, but as we've invalidate the window with RDW_ERASE ourselves from the expose event, the WM_NCPAINT handler erases the entire window, clearing the pixels that the launcher has just painted.
This regressed since the window surface clipping region logic changed, as the expose event handling was previously not calling `NtUserRedrawWindow` on windows with a surface and without a clipping region. The clipping region was also previously not always set, or set later, and we're setting it more consistently since 51b16963f6e0e8df43118deac63f640aee4698b7, even when it matches the window rect, for compatibility with some old wineandroid logic (where I believe it was used to clip window surfaces to their proper sizes).
-- v3: winex11: Avoid setting RDW_ERASE on expose events. explorer: Paint the desktop even without RDW_ERASE.
From: Rémi Bernon rbernon@codeweavers.com
--- programs/explorer/desktop.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/programs/explorer/desktop.c b/programs/explorer/desktop.c index e0b57a4b37f..ce70c5dd79d 100644 --- a/programs/explorer/desktop.c +++ b/programs/explorer/desktop.c @@ -842,7 +842,7 @@ static LRESULT WINAPI desktop_wnd_proc( HWND hwnd, UINT message, WPARAM wp, LPAR BeginPaint( hwnd, &ps ); if (!using_root) { - if (ps.fErase) PaintDesktop( ps.hdc ); + PaintDesktop( ps.hdc ); draw_launchers( ps.hdc, ps.rcPaint ); } EndPaint( hwnd, &ps );
From: Rémi Bernon rbernon@codeweavers.com
The Medium launcher uses a dialog window procedure, and implements its background by doing a StretchBlt call on WM_PAINT in the dialog procedure call, which happens before the window message loop
It then itself calls InvalidateRect(hwnd, NULL, 0), which queues a WM_PAINT as well but with only the RDW_INVALIDATE flag.
Next, when the window message loop is executed, the WM_PAINT message is being processed as it should, but as we've invalidated the window with RDW_ERASE from the expose event, the WM_NCPAINT handler erases the entire window, clearing the pixels that the launcher has just painted.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=57665 --- dlls/winex11.drv/event.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c index 428dcb7b8b7..f35981abcab 100644 --- a/dlls/winex11.drv/event.c +++ b/dlls/winex11.drv/event.c @@ -968,7 +968,7 @@ static BOOL X11DRV_Expose( HWND hwnd, XEvent *xev ) RECT rect, abs_rect; POINT pos; struct x11drv_win_data *data; - UINT flags = RDW_INVALIDATE | RDW_ERASE | RDW_FRAME | RDW_ALLCHILDREN; + UINT flags = RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN;
TRACE( "win %p (%lx) %d,%d %dx%d\n", hwnd, event->window, event->x, event->y, event->width, event->height );
v3: Remove RDW_ERASE entirely, paint the virtual desktop even without it.