[PATCH v2 0/2] MR10712: wineandroid: fix desktop sizing and repaint on resolution changes
This series fixes two related issues in wineandroid affecting desktop initialization and repaint behavior when using the virtual desktop mode. First, launching explorer.exe with an empty desktop size ("/desktop=shell,,android") does not behave as intended on wineandroid. When the size is omitted, explorer attempts to determine the desktop resolution via get_default_desktop_size(). If no matching registry entry is found, it falls back to a hardcoded default (typically 800x600). Later, even if the wineandroid backend sets the correct display size through pCreateDesktop, explorer overrides it again during initialize_display_settings(), restoring the default resolution. As a result, the desktop ends up stuck at 800x600 regardless of the actual display size reported by the backend. To address this, the desktop is now launched with a size of "-1x-1". This value is accepted by parse_size(), but does not correspond to a valid resolution. As a result, explorer does not fall back to the default resolution, and also avoids overriding the backend-provided size during initialization. This allows the desktop to retain the correct resolution as configured by wineandroid. Second, window repainting on resolution changes is fixed. Previously, WM_ANDROID_REFRESH used NtUserExposeWindowSurface(), which only exposes existing surface contents without invalidating the window. This prevents WM_PAINT and WM_ERASEBKGND from being generated. When the desktop or other windows are resized (e.g. after applying a new display mode), they may retain stale contents instead of repainting. This is resolved by replacing NtUserExposeWindowSurface() with NtUserRedrawWindow(), ensuring proper invalidation and repaint of window contents. This fixes cases where the desktop background is not redrawn after a resolution change. Together, these changes ensure that the desktop starts with the correct resolution and that windows are properly repainted when display settings change. -- v2: wineandroid: request dynamic desktop size using -1x-1 win32u: Don't set SWP_NOREDRAW for the desktop window in fixup_swp_flags. https://gitlab.winehq.org/wine/wine/-/merge_requests/10712
From: Twaik Yont <9674930+twaik@users.noreply.github.com> NtUserGetAncestor( hwnd, GA_PARENT ) returns 0 for the desktop window (it has no parent), and is_window_visible(0) returns FALSE. So SWP_NOREDRAW gets forced on every SetWindowPos() for the desktop, making set_window_pos() skip the exposed-region/erase computation on resize (e.g. from WM_DISPLAYCHANGE), leaving stale contents on screen. Signed-off-by: Twaik Yont <9674930+twaik@users.noreply.github.com> --- dlls/win32u/window.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 1ecdca6c7d8..f4693bd2367 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -3756,7 +3756,7 @@ static BOOL fixup_swp_flags( WINDOWPOS *winpos, const RECT *old_window_rect, int else if (winpos->cy > 32767) winpos->cy = 32767; parent = NtUserGetAncestor( winpos->hwnd, GA_PARENT ); - if (!is_window_visible( parent )) winpos->flags |= SWP_NOREDRAW; + if (parent && !is_window_visible( parent )) winpos->flags |= SWP_NOREDRAW; if (win->dwStyle & WS_VISIBLE) winpos->flags &= ~SWP_SHOWWINDOW; else -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10712
From: Twaik Yont <9674930+twaik@users.noreply.github.com> Use “-1x-1” instead of an empty size in the /desktop option when launching explorer.exe. An empty size causes get_default_desktop_size() to be used, which falls back to a fixed default (typically 800x600). This prevents the desktop from matching the actual display size provided by the Android backend. Passing “-1x-1” is accepted by parse_size() and results in large unsigned values, which are then clamped by the driver to the current screen size. This effectively requests a dynamically sized desktop matching the Android display. This ensures that the desktop resolution is derived from the backend instead of being forced to the default fixed size. Signed-off-by: Twaik Yont <9674930+twaik@users.noreply.github.com> --- dlls/wineandroid.drv/WineActivity.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/wineandroid.drv/WineActivity.java b/dlls/wineandroid.drv/WineActivity.java index 291e88d5486..5295f0c7825 100644 --- a/dlls/wineandroid.drv/WineActivity.java +++ b/dlls/wineandroid.drv/WineActivity.java @@ -177,7 +177,7 @@ private final void runWine( String loader, String cmdline, File log ) CountDownLatch latch = new CountDownLatch(1); String[] cmd = { loader, "c:\\windows\\system32\\explorer.exe", - "/desktop=shell,,android", + "/desktop=shell,-1x-1,android", cmdline }; runOnUiThread( new Runnable() { public void run() { -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10712
Updated the desktop window redrawing fix — root cause was SWP_NOREDRAW incorrectly getting forced for the desktop window in fixup_swp_flags() (GA_PARENT returns 0 for it, treated as an invisible parent). Tested `explorer /desktop=shell,,x11`, `/desktop=shell,,wayland`, and managed mode (no `/desktop`) on host — seems like there are no regressions or crashes. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10712#note_145019
participants (2)
-
Twaik Yont -
Twaik Yont (@twaik)