From: Alexandros Frantzis alexandros.frantzis@collabora.com
Since a display reconfiguration may affect the compositor side scaling which we apply to a surface, instruct all surfaces to refresh themselves by committing an updated state based on the latest window state. --- dlls/winewayland.drv/display.c | 9 ++++++ dlls/winewayland.drv/waylanddrv.h | 3 ++ dlls/winewayland.drv/window.c | 52 +++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+)
diff --git a/dlls/winewayland.drv/display.c b/dlls/winewayland.drv/display.c index 1f4148ced57..d8168f06774 100644 --- a/dlls/winewayland.drv/display.c +++ b/dlls/winewayland.drv/display.c @@ -326,6 +326,11 @@ BOOL WAYLAND_UpdateDisplayDevices(const struct gdi_device_manager *device_manage return TRUE; }
+static void refresh_hwnd(HWND hwnd) +{ + NtUserPostMessage(hwnd, WM_WAYLAND_REFRESH, 0, 0); +} + /*********************************************************************** * NotifyVirtualDevices (WAYLAND.@) */ @@ -344,4 +349,8 @@ void WAYLAND_NotifyVirtualDevices(const struct gdi_virtual *virtual) process_wayland.virtual = malloc(virtual_size); if (process_wayland.virtual) memcpy(process_wayland.virtual, virtual, virtual_size); pthread_mutex_unlock(&process_wayland.output_mutex); + + /* Refresh all windows to ensure they have been committed with proper + * scaling applied. */ + enum_process_windows(refresh_hwnd); } diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index 32928575629..bc845d7c230 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -62,6 +62,7 @@ enum wayland_window_message WM_WAYLAND_INIT_DISPLAY_DEVICES = WM_WINE_FIRST_DRIVER_MSG, WM_WAYLAND_CONFIGURE, WM_WAYLAND_SET_FOREGROUND, + WM_WAYLAND_REFRESH, };
enum wayland_surface_config_state @@ -322,6 +323,8 @@ static inline BOOL asciiz_to_unicodez(WCHAR *dst, const char *src, size_t n) return !!n; }
+void enum_process_windows(void (*cb)(HWND hwnd)); + /********************************************************************** * USER driver functions */ diff --git a/dlls/winewayland.drv/window.c b/dlls/winewayland.drv/window.c index 2b044563a8d..f4443584ddb 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -651,6 +651,24 @@ static void wayland_configure_window(HWND hwnd) NtUserSetWindowPos(hwnd, 0, 0, 0, window_width, window_height, flags); }
+static void wayland_refresh_window(HWND hwnd) +{ + struct wayland_win_data *data; + + if (!(data = wayland_win_data_get(hwnd))) return; + + if (data->wayland_surface) + { + pthread_mutex_lock(&data->wayland_surface->mutex); + wayland_win_data_get_config(data, &data->wayland_surface->window); + if (wayland_surface_reconfigure(data->wayland_surface)) + wl_surface_commit(data->wayland_surface->wl_surface); + pthread_mutex_unlock(&data->wayland_surface->mutex); + } + + wayland_win_data_release(data); +} + /********************************************************************** * WAYLAND_WindowMessage */ @@ -668,6 +686,9 @@ LRESULT WAYLAND_WindowMessage(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) case WM_WAYLAND_SET_FOREGROUND: NtUserSetForegroundWindow(hwnd); return 0; + case WM_WAYLAND_REFRESH: + wayland_refresh_window(hwnd); + return 0; default: FIXME("got window msg %x hwnd %p wp %lx lp %lx\n", msg, hwnd, (long)wp, lp); return 0; @@ -787,3 +808,34 @@ struct wayland_surface *wayland_surface_lock_hwnd(HWND hwnd)
return surface; } + +/********************************************************************** + * enum_process_windows + */ +void enum_process_windows(void (*cb)(HWND hwnd)) +{ + struct wayland_win_data *data; + HWND *hwnds = NULL; + UINT num_hwnds = 0, i = 0; + + pthread_mutex_lock(&win_data_mutex); + + RB_FOR_EACH_ENTRY(data, &win_data_rb, struct wayland_win_data, entry) + ++num_hwnds; + + if (num_hwnds && (hwnds = malloc(num_hwnds * sizeof(*hwnds)))) + { + RB_FOR_EACH_ENTRY(data, &win_data_rb, struct wayland_win_data, entry) + hwnds[i++] = data->hwnd; + } + else + { + num_hwnds = 0; + } + + pthread_mutex_unlock(&win_data_mutex); + + for (i = 0; i < num_hwnds; i++) cb(hwnds[i]); + + free(hwnds); +}