From: Alexandros Frantzis alexandros.frantzis@collabora.com
When we are notified by Wine core that the user wants to interactively resize the window, forward the request to compositor, so it can take over and resize the window according to user input.
In the process of the interactive resize we receive a stream of xdg_toplevel configure events informing us about the updated window sizes. --- dlls/winewayland.drv/wayland_surface.c | 3 ++ dlls/winewayland.drv/waylanddrv.h | 9 ++++- dlls/winewayland.drv/window.c | 47 ++++++++++++++++++++++++-- 3 files changed, 56 insertions(+), 3 deletions(-)
diff --git a/dlls/winewayland.drv/wayland_surface.c b/dlls/winewayland.drv/wayland_surface.c index 9514106d0d1..8551ad98eeb 100644 --- a/dlls/winewayland.drv/wayland_surface.c +++ b/dlls/winewayland.drv/wayland_surface.c @@ -88,6 +88,9 @@ static void xdg_toplevel_handle_configure(void *data, case XDG_TOPLEVEL_STATE_MAXIMIZED: config_state |= WAYLAND_SURFACE_CONFIG_STATE_MAXIMIZED; break; + case XDG_TOPLEVEL_STATE_RESIZING: + config_state |= WAYLAND_SURFACE_CONFIG_STATE_RESIZING; + break; default: break; } diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index bb78883c539..4c6eb170900 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -59,7 +59,8 @@ enum wayland_window_message
enum wayland_surface_config_state { - WAYLAND_SURFACE_CONFIG_STATE_MAXIMIZED = (1 << 0) + WAYLAND_SURFACE_CONFIG_STATE_MAXIMIZED = (1 << 0), + WAYLAND_SURFACE_CONFIG_STATE_RESIZING = (1 << 1) };
struct wayland_cursor @@ -147,6 +148,7 @@ struct wayland_surface pthread_mutex_t mutex; struct wayland_surface_config pending, requested, processing, current; struct wayland_shm_buffer *latest_window_buffer; + BOOL resizing; };
struct wayland_shm_buffer @@ -228,6 +230,11 @@ static inline BOOL intersect_rect(RECT *dst, const RECT *src1, const RECT *src2) return !IsRectEmpty(dst); }
+static inline LRESULT send_message(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) +{ + return NtUserMessageCall(hwnd, msg, wparam, lparam, NULL, NtUserSendMessage, FALSE); +} + RGNDATA *get_region_data(HRGN region) DECLSPEC_HIDDEN;
/********************************************************************** diff --git a/dlls/winewayland.drv/window.c b/dlls/winewayland.drv/window.c index 881ba24d01d..5079d820929 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -335,6 +335,8 @@ static void wayland_configure_window(HWND hwnd) UINT flags; uint32_t state; DWORD style; + BOOL needs_enter_size_move = FALSE; + BOOL needs_exit_size_move = FALSE;
if (!(surface = wayland_surface_lock_hwnd(hwnd))) return;
@@ -359,10 +361,25 @@ static void wayland_configure_window(HWND hwnd) height = surface->processing.height; state = surface->processing.state;
+ if ((state & WAYLAND_SURFACE_CONFIG_STATE_RESIZING) && !surface->resizing) + { + surface->resizing = TRUE; + needs_enter_size_move = TRUE; + } + + if (!(state & WAYLAND_SURFACE_CONFIG_STATE_RESIZING) && surface->resizing) + { + surface->resizing = FALSE; + needs_exit_size_move = TRUE; + } + pthread_mutex_unlock(&surface->mutex);
TRACE("processing=%dx%d,%#x\n", width, height, state);
+ if (needs_enter_size_move) send_message(hwnd, WM_ENTERSIZEMOVE, 0, 0); + if (needs_exit_size_move) send_message(hwnd, WM_EXITSIZEMOVE, 0, 0); + flags = SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOOWNERZORDER | SWP_NOMOVE; if (width == 0 || height == 0) flags |= SWP_NOSIZE;
@@ -415,6 +432,22 @@ LRESULT WAYLAND_DesktopWindowProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) return NtUserMessageCall(hwnd, msg, wp, lp, 0, NtUserDefWindowProc, FALSE); }
+static enum xdg_toplevel_resize_edge hittest_to_resize_edge(WPARAM hittest) +{ + switch (hittest) + { + case WMSZ_LEFT: return XDG_TOPLEVEL_RESIZE_EDGE_LEFT; + case WMSZ_RIGHT: return XDG_TOPLEVEL_RESIZE_EDGE_RIGHT; + case WMSZ_TOP: return XDG_TOPLEVEL_RESIZE_EDGE_TOP; + case WMSZ_TOPLEFT: return XDG_TOPLEVEL_RESIZE_EDGE_TOP_LEFT; + case WMSZ_TOPRIGHT: return XDG_TOPLEVEL_RESIZE_EDGE_TOP_RIGHT; + case WMSZ_BOTTOM: return XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM; + case WMSZ_BOTTOMLEFT: return XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_LEFT; + case WMSZ_BOTTOMRIGHT: return XDG_TOPLEVEL_RESIZE_EDGE_BOTTOM_RIGHT; + default: return XDG_TOPLEVEL_RESIZE_EDGE_NONE; + } +} + /*********************************************************************** * WAYLAND_SysCommand */ @@ -436,14 +469,24 @@ LRESULT WAYLAND_SysCommand(HWND hwnd, WPARAM wparam, LPARAM lparam) button_serial = 0; pthread_mutex_unlock(&process_wayland.pointer.mutex);
- if (command == SC_MOVE) + if (command == SC_MOVE || command == SC_SIZE) { if ((surface = wayland_surface_lock_hwnd(hwnd))) { pthread_mutex_lock(&process_wayland.seat.mutex); wl_seat = process_wayland.seat.wl_seat; if (wl_seat && surface->xdg_toplevel && button_serial) - xdg_toplevel_move(surface->xdg_toplevel, wl_seat, button_serial); + { + if (command == SC_MOVE) + { + xdg_toplevel_move(surface->xdg_toplevel, wl_seat, button_serial); + } + else if (command == SC_SIZE) + { + xdg_toplevel_resize(surface->xdg_toplevel, wl_seat, button_serial, + hittest_to_resize_edge(wparam & 0x0f)); + } + } pthread_mutex_unlock(&process_wayland.seat.mutex); pthread_mutex_unlock(&surface->mutex); ret = 0;