Note that per-window opacity (i.e., the alpha parameter in SetLayeredWindowAttributes) is not implemented yet.
From: Alexandros Frantzis alexandros.frantzis@collabora.com
--- dlls/winewayland.drv/waylanddrv.h | 3 +++ dlls/winewayland.drv/waylanddrv_main.c | 2 ++ dlls/winewayland.drv/window.c | 35 +++++++++++++++++++++++++- dlls/winewayland.drv/window_surface.c | 17 +++++++++---- 4 files changed, 51 insertions(+), 6 deletions(-)
diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index 515ce006b8e..5592ffe9989 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -373,6 +373,7 @@ struct wayland_win_data struct window_rects rects; BOOL is_fullscreen; BOOL managed; + BOOL layered_attribs_set; };
struct wayland_win_data *wayland_win_data_get(HWND hwnd); @@ -446,7 +447,9 @@ void WAYLAND_DestroyWindow(HWND hwnd); BOOL WAYLAND_SetIMECompositionRect(HWND hwnd, RECT rect); void WAYLAND_SetCursor(HWND hwnd, HCURSOR hcursor); BOOL WAYLAND_SetCursorPos(INT x, INT y); +void WAYLAND_SetLayeredWindowAttributes(HWND hwnd, COLORREF key, BYTE alpha, DWORD flags); void WAYLAND_SetWindowIcon(HWND hwnd, UINT type, HICON icon); +void WAYLAND_SetWindowStyle(HWND hwnd, INT offset, STYLESTRUCT *style); void WAYLAND_SetWindowText(HWND hwnd, LPCWSTR text); LRESULT WAYLAND_SysCommand(HWND hwnd, WPARAM wparam, LPARAM lparam, const POINT *pos); UINT WAYLAND_UpdateDisplayDevices(const struct gdi_device_manager *device_manager, void *param); diff --git a/dlls/winewayland.drv/waylanddrv_main.c b/dlls/winewayland.drv/waylanddrv_main.c index 1c6a0d95d58..4e012f0e3a3 100644 --- a/dlls/winewayland.drv/waylanddrv_main.c +++ b/dlls/winewayland.drv/waylanddrv_main.c @@ -44,7 +44,9 @@ static const struct user_driver_funcs waylanddrv_funcs = .pReleaseKbdTables = WAYLAND_ReleaseKbdTables, .pSetCursor = WAYLAND_SetCursor, .pSetCursorPos = WAYLAND_SetCursorPos, + .pSetLayeredWindowAttributes = WAYLAND_SetLayeredWindowAttributes, .pSetWindowIcon = WAYLAND_SetWindowIcon, + .pSetWindowStyle = WAYLAND_SetWindowStyle, .pSetWindowText = WAYLAND_SetWindowText, .pSysCommand = WAYLAND_SysCommand, .pUpdateDisplayDevices = WAYLAND_UpdateDisplayDevices, diff --git a/dlls/winewayland.drv/window.c b/dlls/winewayland.drv/window.c index cf1e4d2d99b..c84c35153c1 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -196,7 +196,10 @@ static BOOL wayland_win_data_create_wayland_surface(struct wayland_win_data *dat
TRACE("hwnd=%p\n", data->hwnd);
- visible = (NtUserGetWindowLongW(data->hwnd, GWL_STYLE) & WS_VISIBLE) == WS_VISIBLE; + visible = ((NtUserGetWindowLongW(data->hwnd, GWL_STYLE) & WS_VISIBLE) == WS_VISIBLE) && + (!(NtUserGetWindowLongW(data->hwnd, GWL_EXSTYLE) & WS_EX_LAYERED) || + data->layered_attribs_set); + if (!visible) role = WAYLAND_SURFACE_ROLE_NONE; else if (toplevel_surface) role = WAYLAND_SURFACE_ROLE_SUBSURFACE; else role = WAYLAND_SURFACE_ROLE_TOPLEVEL; @@ -667,6 +670,18 @@ LRESULT WAYLAND_DesktopWindowProc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp) return NtUserMessageCall(hwnd, msg, wp, lp, 0, NtUserDefWindowProc, FALSE); }
+/***************************************************************** + * WAYLAND_SetLayeredWindowAttributes + */ +void WAYLAND_SetLayeredWindowAttributes(HWND hwnd, COLORREF key, BYTE alpha, DWORD flags) +{ + struct wayland_win_data *data; + + if (!(data = wayland_win_data_get(hwnd))) return; + data->layered_attribs_set = TRUE; + wayland_win_data_release(data); +} + static enum xdg_toplevel_resize_edge hittest_to_resize_edge(WPARAM hittest) { switch (hittest) @@ -705,6 +720,24 @@ void WAYLAND_SetWindowIcon(HWND hwnd, UINT type, HICON icon) } }
+/*********************************************************************** + * WAYLAND_SetWindowStyle + */ +void WAYLAND_SetWindowStyle(HWND hwnd, INT offset, STYLESTRUCT *style) +{ + struct wayland_win_data *data; + DWORD changed = style->styleNew ^ style->styleOld; + + if (hwnd == NtUserGetDesktopWindow()) return; + if (!(data = wayland_win_data_get(hwnd))) return; + + /* Changing WS_EX_LAYERED resets attributes */ + if (offset == GWL_EXSTYLE && (changed & WS_EX_LAYERED)) + data->layered_attribs_set = FALSE; + + wayland_win_data_release(data); +} + /***************************************************************** * WAYLAND_SetWindowText */ diff --git a/dlls/winewayland.drv/window_surface.c b/dlls/winewayland.drv/window_surface.c index f3bda116e6d..9742794acdc 100644 --- a/dlls/winewayland.drv/window_surface.c +++ b/dlls/winewayland.drv/window_surface.c @@ -45,6 +45,7 @@ struct wayland_window_surface { struct window_surface header; struct wayland_buffer_queue *wayland_buffer_queue; + BOOL layered; };
static struct wayland_window_surface *wayland_window_surface_cast( @@ -387,7 +388,7 @@ static BOOL wayland_window_surface_flush(struct window_surface *window_surface, goto done; }
- buffer_format = shape_bits ? WL_SHM_FORMAT_ARGB8888 : WL_SHM_FORMAT_XRGB8888; + buffer_format = (shape_bits || wws->layered) ? WL_SHM_FORMAT_ARGB8888 : WL_SHM_FORMAT_XRGB8888; if (wws->wayland_buffer_queue->format != buffer_format) { int width = wws->wayland_buffer_queue->width; @@ -439,7 +440,7 @@ static BOOL wayland_window_surface_flush(struct window_surface *window_surface, }
wayland_shm_buffer_copy_data(shm_buffer, color_bits, &surface_rect, copy_from_window_region, - !!shape_bits); + shape_bits && !wws->layered); if (shape_bits) wayland_shm_buffer_copy_shape(shm_buffer, rect, shape_info, shape_bits);
NtGdiSetRectRgn(shm_buffer->damage_region, 0, 0, 0, 0); @@ -474,7 +475,8 @@ static const struct window_surface_funcs wayland_window_surface_funcs = /*********************************************************************** * wayland_window_surface_create */ -static struct window_surface *wayland_window_surface_create(HWND hwnd, const RECT *rect) +static struct window_surface *wayland_window_surface_create(HWND hwnd, const RECT *rect, + BOOL layered) { char buffer[FIELD_OFFSET(BITMAPINFO, bmiColors[256])]; BITMAPINFO *info = (BITMAPINFO *)buffer; @@ -497,7 +499,11 @@ static struct window_surface *wayland_window_surface_create(HWND hwnd, const REC if ((window_surface = window_surface_create(sizeof(*wws), &wayland_window_surface_funcs, hwnd, rect, info, 0))) { struct wayland_window_surface *wws = wayland_window_surface_cast(window_surface); - wws->wayland_buffer_queue = wayland_buffer_queue_create(width, height, WL_SHM_FORMAT_XRGB8888); + wws->wayland_buffer_queue = + wayland_buffer_queue_create(width, height, + layered ? WL_SHM_FORMAT_ARGB8888 : + WL_SHM_FORMAT_XRGB8888); + wws->layered = layered; }
return window_surface; @@ -517,7 +523,8 @@ BOOL WAYLAND_CreateWindowSurface(HWND hwnd, BOOL layered, const RECT *surface_re if (!(data = wayland_win_data_get(hwnd))) return TRUE; /* use default surface */ if (previous) window_surface_release(previous);
- *surface = wayland_window_surface_create(data->hwnd, surface_rect); + if (layered) data->layered_attribs_set = TRUE; + *surface = wayland_window_surface_create(data->hwnd, surface_rect, data->layered_attribs_set);
wayland_win_data_release(data); return TRUE;
This merge request was approved by Rémi Bernon.