This clips surface rects which are larger than the virtual screen, keeping full window surfaces for one which are smaller. This makes sure that off-screen windows have valid pixels on overviews like macOS Exposé, or similarly, GNOME shell activities view.
Supersedes both https://gitlab.winehq.org/wine/wine/-/merge_requests/5865 and https://gitlab.winehq.org/wine/wine/-/merge_requests/5878.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winex11.drv/bitblt.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/dlls/winex11.drv/bitblt.c b/dlls/winex11.drv/bitblt.c index c4ae4dd522e..715d263028f 100644 --- a/dlls/winex11.drv/bitblt.c +++ b/dlls/winex11.drv/bitblt.c @@ -2186,10 +2186,18 @@ HRGN expose_surface( struct window_surface *window_surface, const RECT *rect )
BOOL get_surface_rect( const RECT *visible_rect, RECT *surface_rect ) { - *surface_rect = NtUserGetVirtualScreenRect(); + RECT virtual_rect = NtUserGetVirtualScreenRect();
- if (!intersect_rect( surface_rect, surface_rect, visible_rect )) return FALSE; + *surface_rect = *visible_rect; + + /* crop surfaces which are larger than the virtual screen rect, some applications create huge windows */ + if ((surface_rect->right - surface_rect->left > virtual_rect.right - virtual_rect.left || + surface_rect->bottom - surface_rect->top > virtual_rect.bottom - virtual_rect.top) && + !intersect_rect( surface_rect, surface_rect, &virtual_rect )) + return FALSE; OffsetRect( surface_rect, -visible_rect->left, -visible_rect->top ); + + /* round the surface coordinates to avoid re-creating them too often on resize */ surface_rect->left &= ~31; surface_rect->top &= ~31; surface_rect->right = max( surface_rect->left + 32, (surface_rect->right + 31) & ~31 );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/wineandroid.drv/window.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c index 764b202d6e5..59f10adb60a 100644 --- a/dlls/wineandroid.drv/window.c +++ b/dlls/wineandroid.drv/window.c @@ -1121,10 +1121,20 @@ static struct android_win_data *create_win_data( HWND hwnd, const RECT *window_r }
-static inline BOOL get_surface_rect( const RECT *visible_rect, RECT *surface_rect ) +static BOOL get_surface_rect( const RECT *visible_rect, RECT *surface_rect ) { - if (!intersect_rect( surface_rect, visible_rect, &virtual_screen_rect )) return FALSE; + RECT virtual_rect = NtUserGetVirtualScreenRect(); + + *surface_rect = *visible_rect; + + /* crop surfaces which are larger than the virtual screen rect, some applications create huge windows */ + if ((surface_rect->right - surface_rect->left > virtual_rect.right - virtual_rect.left || + surface_rect->bottom - surface_rect->top > virtual_rect.bottom - virtual_rect.top) && + !intersect_rect( surface_rect, surface_rect, &virtual_rect )) + return FALSE; OffsetRect( surface_rect, -visible_rect->left, -visible_rect->top ); + + /* round the surface coordinates to avoid re-creating them too often on resize */ surface_rect->left &= ~31; surface_rect->top &= ~31; surface_rect->right = max( surface_rect->left + 32, (surface_rect->right + 31) & ~31 );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winemac.drv/cocoa_window.m | 9 +++++++++ dlls/winemac.drv/macdrv.h | 1 + dlls/winemac.drv/surface.c | 29 +++++++++++++++++++---------- dlls/winemac.drv/window.c | 2 ++ 4 files changed, 31 insertions(+), 10 deletions(-)
diff --git a/dlls/winemac.drv/cocoa_window.m b/dlls/winemac.drv/cocoa_window.m index caf06ff338f..a56dbbc4614 100644 --- a/dlls/winemac.drv/cocoa_window.m +++ b/dlls/winemac.drv/cocoa_window.m @@ -365,6 +365,7 @@ - (id) initWithFrame:(NSRect)frame device:(id<MTLDevice>)device;
@interface WineContentView : WineBaseView <NSTextInputClient, NSViewLayerContentScaleDelegate> { + CGRect surfaceRect; CGImageRef colorImage;
NSMutableArray* glContexts; @@ -489,6 +490,7 @@ - (instancetype) initWithFrame:(NSRect)frame self = [super initWithFrame:frame]; if (self) { + [self setLayerContentsPlacement:NSViewLayerContentsPlacementTopLeft]; [self setWantsLayer:YES]; [self setLayerRetinaProperties:retina_on]; [self setAutoresizesSubviews:NO]; @@ -552,6 +554,7 @@ - (void) updateLayer
if (image) { + layer.position = surfaceRect.origin; layer.contents = (id)image; CFRelease(image); [window windowDidDrawContent]; @@ -567,6 +570,11 @@ - (void) updateLayer } }
+ - (void) setSurfaceRect:(CGRect)rect + { + surfaceRect = rect; + } + - (void) setColorImage:(CGImageRef)image { CGImageRelease(colorImage); @@ -3516,6 +3524,7 @@ void macdrv_window_set_color_image(macdrv_window w, CGImageRef image, CGRect rec WineContentView *view = [window contentView];
[view setColorImage:image]; + [view setSurfaceRect:cgrect_mac_from_win(rect)]; [view setNeedsDisplayInRect:NSRectFromCGRect(cgrect_mac_from_win(dirty))];
CGImageRelease(image); diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h index 811947f723c..6863232b65a 100644 --- a/dlls/winemac.drv/macdrv.h +++ b/dlls/winemac.drv/macdrv.h @@ -208,6 +208,7 @@ extern BOOL macdrv_SystemParametersInfo(UINT action, UINT int_param, void *ptr_p extern RGNDATA *get_region_data(HRGN hrgn, HDC hdc_lptodp); extern void activate_on_following_focus(void); extern void set_surface_use_alpha(struct window_surface *window_surface, BOOL use_alpha); +extern BOOL get_surface_rect(const RECT *visible_rect, RECT *surface_rect);
extern void macdrv_handle_event(const macdrv_event *event);
diff --git a/dlls/winemac.drv/surface.c b/dlls/winemac.drv/surface.c index 8b68d5d0ab5..7b4f744edba 100644 --- a/dlls/winemac.drv/surface.c +++ b/dlls/winemac.drv/surface.c @@ -225,16 +225,25 @@ void set_surface_use_alpha(struct window_surface *window_surface, BOOL use_alpha }
-static inline RECT get_surface_rect(const RECT *visible_rect) +BOOL get_surface_rect(const RECT *visible_rect, RECT *surface_rect) { - RECT rect = *visible_rect; - - OffsetRect(&rect, -visible_rect->left, -visible_rect->top); - rect.left &= ~127; - rect.top &= ~127; - rect.right = max(rect.left + 128, (rect.right + 127) & ~127); - rect.bottom = max(rect.top + 128, (rect.bottom + 127) & ~127); - return rect; + RECT virtual_rect = NtUserGetVirtualScreenRect(); + + *surface_rect = *visible_rect; + + /* crop surfaces which are larger than the virtual screen rect, some applications create huge windows */ + if ((surface_rect->right - surface_rect->left > virtual_rect.right - virtual_rect.left || + surface_rect->bottom - surface_rect->top > virtual_rect.bottom - virtual_rect.top) && + !intersect_rect( surface_rect, surface_rect, &virtual_rect )) + return FALSE; + OffsetRect(surface_rect, -visible_rect->left, -visible_rect->top); + + /* round the surface coordinates to avoid re-creating them too often on resize */ + surface_rect->left &= ~127; + surface_rect->top &= ~127; + surface_rect->right = max(surface_rect->left + 128, (surface_rect->right + 127) & ~127); + surface_rect->bottom = max(surface_rect->top + 128, (surface_rect->bottom + 127) & ~127); + return TRUE; }
@@ -250,11 +259,11 @@ BOOL macdrv_CreateWindowSurface(HWND hwnd, UINT swp_flags, const RECT *visible_r TRACE("hwnd %p, swp_flags %08x, visible %s, surface %p\n", hwnd, swp_flags, wine_dbgstr_rect(visible_rect), surface);
if (!(data = get_win_data(hwnd))) return TRUE; /* use default surface */ + if (!get_surface_rect( visible_rect, &surface_rect )) goto done; /* use default surface */
if (*surface) window_surface_release(*surface); *surface = NULL;
- surface_rect = get_surface_rect(visible_rect); if (data->surface) { if (EqualRect(&data->surface->rect, &surface_rect)) diff --git a/dlls/winemac.drv/window.c b/dlls/winemac.drv/window.c index 36f3e3053d6..0f38d96523e 100644 --- a/dlls/winemac.drv/window.c +++ b/dlls/winemac.drv/window.c @@ -1951,6 +1951,7 @@ BOOL macdrv_WindowPosChanging(HWND hwnd, UINT swp_flags, const RECT *window_rect { struct macdrv_win_data *data = get_win_data(hwnd); DWORD style = NtUserGetWindowLongW(hwnd, GWL_STYLE); + RECT surface_rect; BOOL ret = FALSE;
TRACE("%p swp %04x window %s client %s visible %s\n", hwnd, @@ -1966,6 +1967,7 @@ BOOL macdrv_WindowPosChanging(HWND hwnd, UINT swp_flags, const RECT *window_rect if (!data->cocoa_window) goto done; /* use default surface */ if (swp_flags & SWP_HIDEWINDOW) goto done; /* use default surface */ if (data->ulw_layered) goto done; /* use default surface */ + if (!get_surface_rect( visible_rect, &surface_rect )) goto done; /* use default surface */
ret = TRUE;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winewayland.drv/waylanddrv.h | 3 +- dlls/winewayland.drv/window.c | 14 ++++--- dlls/winewayland.drv/window_surface.c | 55 +++++++++++++++++++-------- 3 files changed, 49 insertions(+), 23 deletions(-)
diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index d0a8977f887..28e754b6562 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -236,6 +236,7 @@ void wayland_output_use_xdg_extension(struct wayland_output *output); * Wayland surface */
+BOOL get_surface_rect(const RECT *visible_rect, RECT *surface_rect); struct wayland_surface *wayland_surface_create(HWND hwnd); void wayland_surface_destroy(struct wayland_surface *surface); void wayland_surface_make_toplevel(struct wayland_surface *surface); @@ -272,7 +273,7 @@ void wayland_shm_buffer_unref(struct wayland_shm_buffer *shm_buffer); * Wayland window surface */
-void wayland_window_surface_update_wayland_surface(struct window_surface *surface, +void wayland_window_surface_update_wayland_surface(struct window_surface *surface, const RECT *visible_rect, struct wayland_surface *wayland_surface); void wayland_window_flush(HWND hwnd);
diff --git a/dlls/winewayland.drv/window.c b/dlls/winewayland.drv/window.c index 060a25d50c6..9d2432262b8 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -124,7 +124,7 @@ static void wayland_win_data_destroy(struct wayland_win_data *data)
if (data->window_surface) { - wayland_window_surface_update_wayland_surface(data->window_surface, NULL); + wayland_window_surface_update_wayland_surface(data->window_surface, NULL, NULL); window_surface_release(data->window_surface); } if (data->wayland_surface) wayland_surface_destroy(data->wayland_surface); @@ -200,20 +200,20 @@ static void reapply_cursor_clipping(void) NtUserSetThreadDpiAwarenessContext(context); }
-static void wayland_win_data_update_wayland_surface(struct wayland_win_data *data) +static void wayland_win_data_update_wayland_surface(struct wayland_win_data *data, const RECT *visible_rect) { struct wayland_surface *surface = data->wayland_surface; HWND parent = NtUserGetAncestor(data->hwnd, GA_PARENT); BOOL visible, xdg_visible; WCHAR text[1024];
- TRACE("hwnd=%p\n", data->hwnd); + TRACE("hwnd=%p, rect=%s\n", data->hwnd, wine_dbgstr_rect(visible_rect));
/* We don't want wayland surfaces for child windows. */ if (parent != NtUserGetDesktopWindow() && parent != 0) { if (data->window_surface) - wayland_window_surface_update_wayland_surface(data->window_surface, NULL); + wayland_window_surface_update_wayland_surface(data->window_surface, NULL, NULL); if (surface) wayland_surface_destroy(surface); surface = NULL; goto out; @@ -251,7 +251,7 @@ static void wayland_win_data_update_wayland_surface(struct wayland_win_data *dat pthread_mutex_unlock(&surface->mutex);
if (data->window_surface) - wayland_window_surface_update_wayland_surface(data->window_surface, surface); + wayland_window_surface_update_wayland_surface(data->window_surface, visible_rect, surface);
/* Size/position changes affect the effective pointer constraint, so update * it as needed. */ @@ -432,6 +432,7 @@ BOOL WAYLAND_WindowPosChanging(HWND hwnd, UINT swp_flags, const RECT *window_rec struct wayland_win_data *data = wayland_win_data_get(hwnd); HWND parent; BOOL visible, ret = FALSE; + RECT surface_rect;
TRACE("hwnd %p window %s client %s visible %s flags %08x\n", hwnd, wine_dbgstr_rect(window_rect), wine_dbgstr_rect(client_rect), @@ -445,6 +446,7 @@ BOOL WAYLAND_WindowPosChanging(HWND hwnd, UINT swp_flags, const RECT *window_rec !(swp_flags & SWP_HIDEWINDOW);
if ((parent && parent != NtUserGetDesktopWindow()) || !visible) goto done; /* use default surface */ + if (!get_surface_rect( visible_rect, &surface_rect )) goto done; /* use default surface */
ret = TRUE;
@@ -484,7 +486,7 @@ void WAYLAND_WindowPosChanged(HWND hwnd, HWND insert_after, UINT swp_flags, if (data->window_surface) window_surface_release(data->window_surface); data->window_surface = surface;
- wayland_win_data_update_wayland_surface(data); + wayland_win_data_update_wayland_surface(data, visible_rect); if (data->wayland_surface) wayland_win_data_update_wayland_state(data);
wayland_win_data_release(data); diff --git a/dlls/winewayland.drv/window_surface.c b/dlls/winewayland.drv/window_surface.c index 9377b05b4ce..c557bd30fe4 100644 --- a/dlls/winewayland.drv/window_surface.c +++ b/dlls/winewayland.drv/window_surface.c @@ -283,8 +283,8 @@ static void copy_pixel_region(char *src_pixels, RECT *src_rect, if (!intersect_rect(&rc, rgn_rect, src_rect)) continue; if (!intersect_rect(&rc, &rc, dst_rect)) continue;
- src = src_pixels + rc.top * src_stride + rc.left * bpp; - dst = dst_pixels + rc.top * dst_stride + rc.left * bpp; + src = src_pixels + (rc.top - src_rect->top) * src_stride + (rc.left - src_rect->left) * bpp; + dst = dst_pixels + (rc.top - dst_rect->top) * dst_stride + (rc.left - dst_rect->left) * bpp; width_bytes = (rc.right - rc.left) * bpp; height = rc.bottom - rc.top;
@@ -346,7 +346,8 @@ static BOOL wayland_window_surface_flush(struct window_surface *window_surface, goto done; }
- surface_damage_region = NtGdiCreateRectRgn(dirty->left, dirty->top, dirty->right, dirty->bottom); + surface_damage_region = NtGdiCreateRectRgn(rect->left + dirty->left, rect->top + dirty->top, + rect->left + dirty->right, rect->top + dirty->bottom); if (!surface_damage_region) { ERR("failed to create surface damage region\n"); @@ -486,7 +487,7 @@ failed: /*********************************************************************** * wayland_window_surface_update_wayland_surface */ -void wayland_window_surface_update_wayland_surface(struct window_surface *window_surface, +void wayland_window_surface_update_wayland_surface(struct window_surface *window_surface, const RECT *visible_rect, struct wayland_surface *wayland_surface) { struct wayland_window_surface *wws; @@ -497,27 +498,51 @@ void wayland_window_surface_update_wayland_surface(struct window_surface *window wws = wayland_window_surface_cast(window_surface); window_surface_lock(window_surface);
- TRACE("surface=%p hwnd=%p wayland_surface=%p\n", wws, window_surface->hwnd, wayland_surface); + TRACE("surface=%p hwnd=%p visible_rect=%s wayland_surface=%p\n", wws, window_surface->hwnd, + wine_dbgstr_rect(visible_rect), wayland_surface);
wws->wayland_surface = wayland_surface;
- /* We only need a buffer queue if we have a surface to commit to. */ - if (wws->wayland_surface && !wws->wayland_buffer_queue) - { - wws->wayland_buffer_queue = - wayland_buffer_queue_create(wws->info.bmiHeader.biWidth, - abs(wws->info.bmiHeader.biHeight)); - } - else if (!wws->wayland_surface && wws->wayland_buffer_queue) + if (wws->wayland_buffer_queue) { wayland_buffer_queue_destroy(wws->wayland_buffer_queue); wws->wayland_buffer_queue = NULL; }
+ /* We only need a buffer queue if we have a surface to commit to. */ + if (wws->wayland_surface) + { + wws->wayland_buffer_queue = + wayland_buffer_queue_create(visible_rect->right - visible_rect->left, + visible_rect->bottom - visible_rect->top); + } + window_surface_unlock(window_surface); }
+BOOL get_surface_rect(const RECT *visible_rect, RECT *surface_rect) +{ + RECT virtual_rect = NtUserGetVirtualScreenRect(); + + *surface_rect = *visible_rect; + + /* crop surfaces which are larger than the virtual screen rect, some applications create huge windows */ + if ((surface_rect->right - surface_rect->left > virtual_rect.right - virtual_rect.left || + surface_rect->bottom - surface_rect->top > virtual_rect.bottom - virtual_rect.top) && + !intersect_rect( surface_rect, surface_rect, &virtual_rect )) + return FALSE; + OffsetRect(surface_rect, -visible_rect->left, -visible_rect->top); + + /* round the surface coordinates to avoid re-creating them too often on resize */ + surface_rect->left &= ~127; + surface_rect->top &= ~127; + surface_rect->right = max(surface_rect->left + 128, (surface_rect->right + 127) & ~127); + surface_rect->bottom = max(surface_rect->top + 128, (surface_rect->bottom + 127) & ~127); + return TRUE; +} + + /*********************************************************************** * WAYLAND_CreateWindowSurface */ @@ -529,14 +554,12 @@ BOOL WAYLAND_CreateWindowSurface(HWND hwnd, UINT swp_flags, const RECT *visible_ TRACE("hwnd %p, swp_flags %08x, visible %s, surface %p\n", hwnd, swp_flags, wine_dbgstr_rect(visible_rect), surface);
if (!(data = wayland_win_data_get(hwnd))) return TRUE; /* use default surface */ + if (!get_surface_rect( visible_rect, &surface_rect )) goto done; /* use default surface */
/* Release the dummy surface wine provides for toplevels. */ if (*surface) window_surface_release(*surface); *surface = NULL;
- surface_rect = *visible_rect; - OffsetRect(&surface_rect, -surface_rect.left, -surface_rect.top); - /* Check if we can reuse our current window surface. */ if (data->window_surface && EqualRect(&data->window_surface->rect, &surface_rect))
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/dce.c | 17 +++++--------- dlls/win32u/driver.c | 2 +- dlls/win32u/win32u_private.h | 2 +- dlls/win32u/window.c | 30 ++++++++++++++++++++--- dlls/wineandroid.drv/android.h | 2 +- dlls/wineandroid.drv/window.c | 34 ++++----------------------- dlls/winemac.drv/macdrv.h | 3 +-- dlls/winemac.drv/surface.c | 32 ++++--------------------- dlls/winemac.drv/window.c | 2 -- dlls/winewayland.drv/waylanddrv.h | 3 +-- dlls/winewayland.drv/window.c | 2 -- dlls/winewayland.drv/window_surface.c | 32 ++++--------------------- dlls/winex11.drv/bitblt.c | 32 ++++--------------------- dlls/winex11.drv/window.c | 2 -- dlls/winex11.drv/x11drv.h | 3 +-- 15 files changed, 55 insertions(+), 143 deletions(-)
diff --git a/dlls/win32u/dce.c b/dlls/win32u/dce.c index cfa3510c60b..145bf2c5237 100644 --- a/dlls/win32u/dce.c +++ b/dlls/win32u/dce.c @@ -154,32 +154,27 @@ static const struct window_surface_funcs offscreen_window_surface_funcs = offscreen_window_surface_destroy };
-void create_offscreen_window_surface( HWND hwnd, const RECT *visible_rect, struct window_surface **surface ) +void create_offscreen_window_surface( HWND hwnd, const RECT *surface_rect, struct window_surface **surface ) { char buffer[FIELD_OFFSET( BITMAPINFO, bmiColors[256] )]; BITMAPINFO *info = (BITMAPINFO *)buffer; struct offscreen_window_surface *impl; - RECT surface_rect = *visible_rect;
- TRACE( "hwnd %p, visible_rect %s, surface %p.\n", hwnd, wine_dbgstr_rect( visible_rect ), surface ); - - OffsetRect( &surface_rect, -surface_rect.left, -surface_rect.top ); - surface_rect.right = (surface_rect.right + 0x1f) & ~0x1f; - surface_rect.bottom = (surface_rect.bottom + 0x1f) & ~0x1f; + TRACE( "hwnd %p, surface_rect %s, surface %p.\n", hwnd, wine_dbgstr_rect( surface_rect ), surface );
/* check that old surface is an offscreen_window_surface, or release it */ if ((impl = impl_from_window_surface( *surface ))) { /* if the rect didn't change, keep the same surface */ - if (EqualRect( &surface_rect, &impl->header.rect )) return; + if (EqualRect( surface_rect, &impl->header.rect )) return; window_surface_release( &impl->header ); } else if (*surface) window_surface_release( *surface );
memset( info, 0, sizeof(*info) ); info->bmiHeader.biSize = sizeof(info->bmiHeader); - info->bmiHeader.biWidth = surface_rect.right; - info->bmiHeader.biHeight = -surface_rect.bottom; /* top-down */ + info->bmiHeader.biWidth = surface_rect->right; + info->bmiHeader.biHeight = -surface_rect->bottom; /* top-down */ info->bmiHeader.biPlanes = 1; info->bmiHeader.biBitCount = 32; info->bmiHeader.biSizeImage = get_dib_image_size( info ); @@ -188,7 +183,7 @@ void create_offscreen_window_surface( HWND hwnd, const RECT *visible_rect, struc /* create a new window surface */ *surface = NULL; if (!(impl = calloc(1, sizeof(*impl)))) return; - window_surface_init( &impl->header, &offscreen_window_surface_funcs, hwnd, &surface_rect, info, 0 ); + window_surface_init( &impl->header, &offscreen_window_surface_funcs, hwnd, surface_rect, info, 0 ); impl->info = *info;
TRACE( "created window surface %p\n", &impl->header ); diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c index 723270f1453..25ed2af1a17 100644 --- a/dlls/win32u/driver.c +++ b/dlls/win32u/driver.c @@ -889,7 +889,7 @@ static BOOL nulldrv_WindowPosChanging( HWND hwnd, UINT swp_flags, const RECT *wi return TRUE; }
-static BOOL nulldrv_CreateWindowSurface( HWND hwnd, UINT swp_flags, const RECT *visible_rect, struct window_surface **surface ) +static BOOL nulldrv_CreateWindowSurface( HWND hwnd, UINT swp_flags, const RECT *surface_rect, struct window_surface **surface ) { return FALSE; } diff --git a/dlls/win32u/win32u_private.h b/dlls/win32u/win32u_private.h index e2e35d6c40d..6abccafd8e2 100644 --- a/dlls/win32u/win32u_private.h +++ b/dlls/win32u/win32u_private.h @@ -45,7 +45,7 @@ extern ULONG_PTR set_icon_param( HICON handle, ULONG_PTR param );
/* dce.c */ extern struct window_surface dummy_surface; -extern void create_offscreen_window_surface( HWND hwnd, const RECT *visible_rect, +extern void create_offscreen_window_surface( HWND hwnd, const RECT *surface_rect, struct window_surface **surface ); extern void erase_now( HWND hwnd, UINT rdw_flags ); extern void flush_window_surfaces( BOOL idle ); diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index caa3b3aa323..2c78eaf1d98 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -1780,6 +1780,29 @@ done: release_win_ptr( win ); }
+ +static BOOL get_surface_rect( const RECT *visible_rect, RECT *surface_rect ) +{ + RECT virtual_rect = NtUserGetVirtualScreenRect(); + + *surface_rect = *visible_rect; + + /* crop surfaces which are larger than the virtual screen rect, some applications create huge windows */ + if ((surface_rect->right - surface_rect->left > virtual_rect.right - virtual_rect.left || + surface_rect->bottom - surface_rect->top > virtual_rect.bottom - virtual_rect.top) && + !intersect_rect( surface_rect, surface_rect, &virtual_rect )) + return FALSE; + OffsetRect( surface_rect, -visible_rect->left, -visible_rect->top ); + + /* round the surface coordinates to avoid re-creating them too often on resize */ + surface_rect->left &= ~127; + surface_rect->top &= ~127; + surface_rect->right = max( surface_rect->left + 128, (surface_rect->right + 127) & ~127 ); + surface_rect->bottom = max( surface_rect->top + 128, (surface_rect->bottom + 127) & ~127 ); + return TRUE; +} + + /*********************************************************************** * apply_window_pos * @@ -1791,11 +1814,12 @@ static BOOL apply_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, WND *win; HWND surface_win = 0, parent = NtUserGetAncestor( hwnd, GA_PARENT ); BOOL ret, needs_surface, needs_update = FALSE; - RECT visible_rect = *window_rect, old_visible_rect, old_window_rect, old_client_rect, extra_rects[3]; + RECT surface_rect, visible_rect = *window_rect, old_visible_rect, old_window_rect, old_client_rect, extra_rects[3]; struct window_surface *old_surface, *new_surface = NULL;
needs_surface = user_driver->pWindowPosChanging( hwnd, swp_flags, window_rect, client_rect, &visible_rect );
+ if (!get_surface_rect( &visible_rect, &surface_rect )) needs_surface = FALSE; if (!parent || parent == get_desktop_window()) { new_surface = &dummy_surface; /* provide a default surface for top-level windows */ @@ -1803,7 +1827,7 @@ static BOOL apply_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, }
if (!needs_surface || IsRectEmpty( &visible_rect )) needs_surface = FALSE; /* use default surface */ - else needs_surface = !user_driver->pCreateWindowSurface( hwnd, swp_flags, &visible_rect, &new_surface ); + else needs_surface = !user_driver->pCreateWindowSurface( hwnd, swp_flags, &surface_rect, &new_surface );
get_window_rects( hwnd, COORDS_SCREEN, &old_window_rect, NULL, get_thread_dpi() ); if (IsRectEmpty( &valid_rects[0] )) valid_rects = NULL; @@ -1820,7 +1844,7 @@ static BOOL apply_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, { window_surface_release( new_surface ); if ((new_surface = win->surface)) window_surface_add_ref( new_surface ); - create_offscreen_window_surface( hwnd, &visible_rect, &new_surface ); + create_offscreen_window_surface( hwnd, &surface_rect, &new_surface ); }
old_visible_rect = win->visible_rect; diff --git a/dlls/wineandroid.drv/android.h b/dlls/wineandroid.drv/android.h index 72be3c4f5a8..d63f0ee37ec 100644 --- a/dlls/wineandroid.drv/android.h +++ b/dlls/wineandroid.drv/android.h @@ -102,7 +102,7 @@ extern BOOL ANDROID_CreateLayeredWindow( HWND hwnd, const RECT *window_rect, COL struct window_surface **surface ); extern LRESULT ANDROID_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ); extern BOOL ANDROID_WindowPosChanging( HWND hwnd, UINT swp_flags, const RECT *window_rect, const RECT *client_rect, RECT *visible_rect ); -extern BOOL ANDROID_CreateWindowSurface( HWND hwnd, UINT swp_flags, const RECT *visible_rect, struct window_surface **surface ); +extern BOOL ANDROID_CreateWindowSurface( HWND hwnd, UINT swp_flags, const RECT *surface_rect, struct window_surface **surface ); extern void ANDROID_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags, const RECT *window_rect, const RECT *client_rect, const RECT *visible_rect, const RECT *valid_rects, diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c index 59f10adb60a..706f050534a 100644 --- a/dlls/wineandroid.drv/window.c +++ b/dlls/wineandroid.drv/window.c @@ -1121,35 +1121,12 @@ static struct android_win_data *create_win_data( HWND hwnd, const RECT *window_r }
-static BOOL get_surface_rect( const RECT *visible_rect, RECT *surface_rect ) -{ - RECT virtual_rect = NtUserGetVirtualScreenRect(); - - *surface_rect = *visible_rect; - - /* crop surfaces which are larger than the virtual screen rect, some applications create huge windows */ - if ((surface_rect->right - surface_rect->left > virtual_rect.right - virtual_rect.left || - surface_rect->bottom - surface_rect->top > virtual_rect.bottom - virtual_rect.top) && - !intersect_rect( surface_rect, surface_rect, &virtual_rect )) - return FALSE; - OffsetRect( surface_rect, -visible_rect->left, -visible_rect->top ); - - /* round the surface coordinates to avoid re-creating them too often on resize */ - surface_rect->left &= ~31; - surface_rect->top &= ~31; - surface_rect->right = max( surface_rect->left + 32, (surface_rect->right + 31) & ~31 ); - surface_rect->bottom = max( surface_rect->top + 32, (surface_rect->bottom + 31) & ~31 ); - return TRUE; -} - - /*********************************************************************** * ANDROID_WindowPosChanging */ BOOL ANDROID_WindowPosChanging( HWND hwnd, UINT swp_flags, const RECT *window_rect, const RECT *client_rect, RECT *visible_rect ) { struct android_win_data *data = get_win_data( hwnd ); - RECT surface_rect; BOOL ret = FALSE;
TRACE( "win %p window %s client %s style %08x flags %08x\n", @@ -1161,7 +1138,6 @@ BOOL ANDROID_WindowPosChanging( HWND hwnd, UINT swp_flags, const RECT *window_re if (data->parent) goto done; /* use default surface */ if (swp_flags & SWP_HIDEWINDOW) goto done; /* use default surface */ if (is_argb_surface( data->surface )) goto done; /* use default surface */ - if (!get_surface_rect( visible_rect, &surface_rect )) goto done; /* use default surface */
ret = TRUE;
@@ -1174,23 +1150,21 @@ done: /*********************************************************************** * ANDROID_CreateWindowSurface */ -BOOL ANDROID_CreateWindowSurface( HWND hwnd, UINT swp_flags, const RECT *visible_rect, struct window_surface **surface ) +BOOL ANDROID_CreateWindowSurface( HWND hwnd, UINT swp_flags, const RECT *surface_rect, struct window_surface **surface ) { struct android_win_data *data; - RECT surface_rect; DWORD flags; COLORREF key; BYTE alpha; BOOL layered = NtUserGetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_LAYERED;
- TRACE( "hwnd %p, swp_flags %08x, visible %s, surface %p\n", hwnd, swp_flags, wine_dbgstr_rect( visible_rect ), surface ); + TRACE( "hwnd %p, swp_flags %08x, surface_rect %s, surface %p\n", hwnd, swp_flags, wine_dbgstr_rect( surface_rect ), surface );
if (!(data = get_win_data( hwnd ))) return TRUE; /* use default surface */ - if (!get_surface_rect( visible_rect, &surface_rect )) goto done; /* use default surface */
if (data->surface) { - if (!memcmp( &data->surface->rect, &surface_rect, sizeof(surface_rect) )) + if (EqualRect( &data->surface->rect, surface_rect )) { /* existing surface is good enough */ window_surface_add_ref( data->surface ); @@ -1207,7 +1181,7 @@ BOOL ANDROID_CreateWindowSurface( HWND hwnd, UINT swp_flags, const RECT *visible if (!(flags & LWA_COLORKEY)) key = CLR_INVALID;
if (*surface) window_surface_release( *surface ); - *surface = create_surface( data->hwnd, &surface_rect, alpha, key, FALSE ); + *surface = create_surface( data->hwnd, surface_rect, alpha, key, FALSE );
done: release_win_data( data ); diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h index 6863232b65a..4a92847dba2 100644 --- a/dlls/winemac.drv/macdrv.h +++ b/dlls/winemac.drv/macdrv.h @@ -151,7 +151,7 @@ extern void macdrv_UpdateLayeredWindow(HWND hwnd, const RECT *window_rect, COLOR BYTE alpha, UINT flags); extern LRESULT macdrv_WindowMessage(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp); extern BOOL macdrv_WindowPosChanging(HWND hwnd, UINT swp_flags, const RECT *window_rect, const RECT *client_rect, RECT *visible_rect); -extern BOOL macdrv_CreateWindowSurface(HWND hwnd, UINT swp_flags, const RECT *visible_rect, struct window_surface **surface); +extern BOOL macdrv_CreateWindowSurface(HWND hwnd, UINT swp_flags, const RECT *surface_rect, struct window_surface **surface); extern void macdrv_WindowPosChanged(HWND hwnd, HWND insert_after, UINT swp_flags, const RECT *window_rect, const RECT *client_rect, const RECT *visible_rect, const RECT *valid_rects, @@ -208,7 +208,6 @@ extern BOOL macdrv_SystemParametersInfo(UINT action, UINT int_param, void *ptr_p extern RGNDATA *get_region_data(HRGN hrgn, HDC hdc_lptodp); extern void activate_on_following_focus(void); extern void set_surface_use_alpha(struct window_surface *window_surface, BOOL use_alpha); -extern BOOL get_surface_rect(const RECT *visible_rect, RECT *surface_rect);
extern void macdrv_handle_event(const macdrv_event *event);
diff --git a/dlls/winemac.drv/surface.c b/dlls/winemac.drv/surface.c index 7b4f744edba..d7c76998995 100644 --- a/dlls/winemac.drv/surface.c +++ b/dlls/winemac.drv/surface.c @@ -225,48 +225,24 @@ void set_surface_use_alpha(struct window_surface *window_surface, BOOL use_alpha }
-BOOL get_surface_rect(const RECT *visible_rect, RECT *surface_rect) -{ - RECT virtual_rect = NtUserGetVirtualScreenRect(); - - *surface_rect = *visible_rect; - - /* crop surfaces which are larger than the virtual screen rect, some applications create huge windows */ - if ((surface_rect->right - surface_rect->left > virtual_rect.right - virtual_rect.left || - surface_rect->bottom - surface_rect->top > virtual_rect.bottom - virtual_rect.top) && - !intersect_rect( surface_rect, surface_rect, &virtual_rect )) - return FALSE; - OffsetRect(surface_rect, -visible_rect->left, -visible_rect->top); - - /* round the surface coordinates to avoid re-creating them too often on resize */ - surface_rect->left &= ~127; - surface_rect->top &= ~127; - surface_rect->right = max(surface_rect->left + 128, (surface_rect->right + 127) & ~127); - surface_rect->bottom = max(surface_rect->top + 128, (surface_rect->bottom + 127) & ~127); - return TRUE; -} - - /*********************************************************************** * CreateWindowSurface (MACDRV.@) */ -BOOL macdrv_CreateWindowSurface(HWND hwnd, UINT swp_flags, const RECT *visible_rect, struct window_surface **surface) +BOOL macdrv_CreateWindowSurface(HWND hwnd, UINT swp_flags, const RECT *surface_rect, struct window_surface **surface) { struct macdrv_win_data *data; DWORD style = NtUserGetWindowLongW(hwnd, GWL_STYLE); - RECT surface_rect;
- TRACE("hwnd %p, swp_flags %08x, visible %s, surface %p\n", hwnd, swp_flags, wine_dbgstr_rect(visible_rect), surface); + TRACE("hwnd %p, swp_flags %08x, surface_rect %s, surface %p\n", hwnd, swp_flags, wine_dbgstr_rect(surface_rect), surface);
if (!(data = get_win_data(hwnd))) return TRUE; /* use default surface */ - if (!get_surface_rect( visible_rect, &surface_rect )) goto done; /* use default surface */
if (*surface) window_surface_release(*surface); *surface = NULL;
if (data->surface) { - if (EqualRect(&data->surface->rect, &surface_rect)) + if (EqualRect(&data->surface->rect, surface_rect)) { /* existing surface is good enough */ window_surface_add_ref(data->surface); @@ -276,7 +252,7 @@ BOOL macdrv_CreateWindowSurface(HWND hwnd, UINT swp_flags, const RECT *visible_r } else if (!(swp_flags & SWP_SHOWWINDOW) && !(style & WS_VISIBLE)) goto done;
- *surface = create_surface(data->hwnd, data->cocoa_window, &surface_rect, data->surface, FALSE); + *surface = create_surface(data->hwnd, data->cocoa_window, surface_rect, data->surface, FALSE);
done: release_win_data(data); diff --git a/dlls/winemac.drv/window.c b/dlls/winemac.drv/window.c index 0f38d96523e..36f3e3053d6 100644 --- a/dlls/winemac.drv/window.c +++ b/dlls/winemac.drv/window.c @@ -1951,7 +1951,6 @@ BOOL macdrv_WindowPosChanging(HWND hwnd, UINT swp_flags, const RECT *window_rect { struct macdrv_win_data *data = get_win_data(hwnd); DWORD style = NtUserGetWindowLongW(hwnd, GWL_STYLE); - RECT surface_rect; BOOL ret = FALSE;
TRACE("%p swp %04x window %s client %s visible %s\n", hwnd, @@ -1967,7 +1966,6 @@ BOOL macdrv_WindowPosChanging(HWND hwnd, UINT swp_flags, const RECT *window_rect if (!data->cocoa_window) goto done; /* use default surface */ if (swp_flags & SWP_HIDEWINDOW) goto done; /* use default surface */ if (data->ulw_layered) goto done; /* use default surface */ - if (!get_surface_rect( visible_rect, &surface_rect )) goto done; /* use default surface */
ret = TRUE;
diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index 28e754b6562..9cce608ce85 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -236,7 +236,6 @@ void wayland_output_use_xdg_extension(struct wayland_output *output); * Wayland surface */
-BOOL get_surface_rect(const RECT *visible_rect, RECT *surface_rect); struct wayland_surface *wayland_surface_create(HWND hwnd); void wayland_surface_destroy(struct wayland_surface *surface); void wayland_surface_make_toplevel(struct wayland_surface *surface); @@ -362,7 +361,7 @@ void WAYLAND_WindowPosChanged(HWND hwnd, HWND insert_after, UINT swp_flags, const RECT *visible_rect, const RECT *valid_rects, struct window_surface *surface); BOOL WAYLAND_WindowPosChanging(HWND hwnd, UINT swp_flags, const RECT *window_rect, const RECT *client_rect, RECT *visible_rect); -BOOL WAYLAND_CreateWindowSurface(HWND hwnd, UINT swp_flags, const RECT *visible_rect, struct window_surface **surface); +BOOL WAYLAND_CreateWindowSurface(HWND hwnd, UINT swp_flags, const RECT *surface_rect, struct window_surface **surface); UINT WAYLAND_VulkanInit(UINT version, void *vulkan_handle, const struct vulkan_driver_funcs **driver_funcs); struct opengl_funcs *WAYLAND_wine_get_wgl_driver(UINT version);
diff --git a/dlls/winewayland.drv/window.c b/dlls/winewayland.drv/window.c index 9d2432262b8..9a77d8cf47e 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -432,7 +432,6 @@ BOOL WAYLAND_WindowPosChanging(HWND hwnd, UINT swp_flags, const RECT *window_rec struct wayland_win_data *data = wayland_win_data_get(hwnd); HWND parent; BOOL visible, ret = FALSE; - RECT surface_rect;
TRACE("hwnd %p window %s client %s visible %s flags %08x\n", hwnd, wine_dbgstr_rect(window_rect), wine_dbgstr_rect(client_rect), @@ -446,7 +445,6 @@ BOOL WAYLAND_WindowPosChanging(HWND hwnd, UINT swp_flags, const RECT *window_rec !(swp_flags & SWP_HIDEWINDOW);
if ((parent && parent != NtUserGetDesktopWindow()) || !visible) goto done; /* use default surface */ - if (!get_surface_rect( visible_rect, &surface_rect )) goto done; /* use default surface */
ret = TRUE;
diff --git a/dlls/winewayland.drv/window_surface.c b/dlls/winewayland.drv/window_surface.c index c557bd30fe4..fa4a69d5490 100644 --- a/dlls/winewayland.drv/window_surface.c +++ b/dlls/winewayland.drv/window_surface.c @@ -521,40 +521,16 @@ void wayland_window_surface_update_wayland_surface(struct window_surface *window }
-BOOL get_surface_rect(const RECT *visible_rect, RECT *surface_rect) -{ - RECT virtual_rect = NtUserGetVirtualScreenRect(); - - *surface_rect = *visible_rect; - - /* crop surfaces which are larger than the virtual screen rect, some applications create huge windows */ - if ((surface_rect->right - surface_rect->left > virtual_rect.right - virtual_rect.left || - surface_rect->bottom - surface_rect->top > virtual_rect.bottom - virtual_rect.top) && - !intersect_rect( surface_rect, surface_rect, &virtual_rect )) - return FALSE; - OffsetRect(surface_rect, -visible_rect->left, -visible_rect->top); - - /* round the surface coordinates to avoid re-creating them too often on resize */ - surface_rect->left &= ~127; - surface_rect->top &= ~127; - surface_rect->right = max(surface_rect->left + 128, (surface_rect->right + 127) & ~127); - surface_rect->bottom = max(surface_rect->top + 128, (surface_rect->bottom + 127) & ~127); - return TRUE; -} - - /*********************************************************************** * WAYLAND_CreateWindowSurface */ -BOOL WAYLAND_CreateWindowSurface(HWND hwnd, UINT swp_flags, const RECT *visible_rect, struct window_surface **surface) +BOOL WAYLAND_CreateWindowSurface(HWND hwnd, UINT swp_flags, const RECT *surface_rect, struct window_surface **surface) { struct wayland_win_data *data; - RECT surface_rect;
- TRACE("hwnd %p, swp_flags %08x, visible %s, surface %p\n", hwnd, swp_flags, wine_dbgstr_rect(visible_rect), surface); + TRACE("hwnd %p, swp_flags %08x, surface_rect %s, surface %p\n", hwnd, swp_flags, wine_dbgstr_rect(surface_rect), surface);
if (!(data = wayland_win_data_get(hwnd))) return TRUE; /* use default surface */ - if (!get_surface_rect( visible_rect, &surface_rect )) goto done; /* use default surface */
/* Release the dummy surface wine provides for toplevels. */ if (*surface) window_surface_release(*surface); @@ -562,7 +538,7 @@ BOOL WAYLAND_CreateWindowSurface(HWND hwnd, UINT swp_flags, const RECT *visible_
/* Check if we can reuse our current window surface. */ if (data->window_surface && - EqualRect(&data->window_surface->rect, &surface_rect)) + EqualRect(&data->window_surface->rect, surface_rect)) { window_surface_add_ref(data->window_surface); *surface = data->window_surface; @@ -570,7 +546,7 @@ BOOL WAYLAND_CreateWindowSurface(HWND hwnd, UINT swp_flags, const RECT *visible_ goto done; }
- *surface = wayland_window_surface_create(data->hwnd, &surface_rect); + *surface = wayland_window_surface_create(data->hwnd, surface_rect);
done: wayland_win_data_release(data); diff --git a/dlls/winex11.drv/bitblt.c b/dlls/winex11.drv/bitblt.c index 715d263028f..11d37f6bb15 100644 --- a/dlls/winex11.drv/bitblt.c +++ b/dlls/winex11.drv/bitblt.c @@ -2184,40 +2184,17 @@ HRGN expose_surface( struct window_surface *window_surface, const RECT *rect ) }
-BOOL get_surface_rect( const RECT *visible_rect, RECT *surface_rect ) -{ - RECT virtual_rect = NtUserGetVirtualScreenRect(); - - *surface_rect = *visible_rect; - - /* crop surfaces which are larger than the virtual screen rect, some applications create huge windows */ - if ((surface_rect->right - surface_rect->left > virtual_rect.right - virtual_rect.left || - surface_rect->bottom - surface_rect->top > virtual_rect.bottom - virtual_rect.top) && - !intersect_rect( surface_rect, surface_rect, &virtual_rect )) - return FALSE; - OffsetRect( surface_rect, -visible_rect->left, -visible_rect->top ); - - /* round the surface coordinates to avoid re-creating them too often on resize */ - surface_rect->left &= ~31; - surface_rect->top &= ~31; - surface_rect->right = max( surface_rect->left + 32, (surface_rect->right + 31) & ~31 ); - surface_rect->bottom = max( surface_rect->top + 32, (surface_rect->bottom + 31) & ~31 ); - return TRUE; -} - - /*********************************************************************** * CreateWindowSurface (X11DRV.@) */ -BOOL X11DRV_CreateWindowSurface( HWND hwnd, UINT swp_flags, const RECT *visible_rect, struct window_surface **surface ) +BOOL X11DRV_CreateWindowSurface( HWND hwnd, UINT swp_flags, const RECT *surface_rect, struct window_surface **surface ) { struct x11drv_win_data *data; - RECT surface_rect; DWORD flags; COLORREF key; BOOL layered = NtUserGetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_LAYERED;
- TRACE( "hwnd %p, swp_flags %08x, visible %s, surface %p\n", hwnd, swp_flags, wine_dbgstr_rect( visible_rect ), surface ); + TRACE( "hwnd %p, swp_flags %08x, surface_rect %s, surface %p\n", hwnd, swp_flags, wine_dbgstr_rect( surface_rect ), surface );
if (!(data = get_win_data( hwnd ))) return TRUE; /* use default surface */
@@ -2229,10 +2206,9 @@ BOOL X11DRV_CreateWindowSurface( HWND hwnd, UINT swp_flags, const RECT *visible_ if (data->client_window) goto done; /* draw directly to the window */ if (!client_side_graphics && !layered) goto done; /* draw directly to the window */
- if (!get_surface_rect( visible_rect, &surface_rect )) goto done; if (data->surface) { - if (EqualRect( &data->surface->rect, &surface_rect )) + if (EqualRect( &data->surface->rect, surface_rect )) { /* existing surface is good enough */ window_surface_add_ref( data->surface ); @@ -2245,7 +2221,7 @@ BOOL X11DRV_CreateWindowSurface( HWND hwnd, UINT swp_flags, const RECT *visible_ if (!layered || !NtUserGetLayeredWindowAttributes( hwnd, &key, NULL, &flags ) || !(flags & LWA_COLORKEY)) key = CLR_INVALID;
- *surface = create_surface( data->hwnd, data->whole_window, &data->vis, &surface_rect, key, FALSE ); + *surface = create_surface( data->hwnd, data->whole_window, &data->vis, surface_rect, key, FALSE );
done: release_win_data( data ); diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index bdf5d2a3b7b..9564f05f8e9 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -2582,7 +2582,6 @@ done: BOOL X11DRV_WindowPosChanging( HWND hwnd, UINT swp_flags, const RECT *window_rect, const RECT *client_rect, RECT *visible_rect ) { struct x11drv_win_data *data = get_win_data( hwnd ); - RECT surface_rect; BOOL ret = FALSE;
if (!data && !(data = X11DRV_create_win_data( hwnd, window_rect, client_rect ))) return FALSE; /* use default surface */ @@ -2602,7 +2601,6 @@ BOOL X11DRV_WindowPosChanging( HWND hwnd, UINT swp_flags, const RECT *window_rec if (!data->whole_window && !data->embedded) goto done; /* use default surface */ if (swp_flags & SWP_HIDEWINDOW) goto done; /* use default surface */ if (data->use_alpha) goto done; /* use default surface */ - if (!get_surface_rect( visible_rect, &surface_rect )) goto done; /* use default surface */
ret = TRUE;
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 3ac86d32669..8b78f9648b2 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -246,7 +246,7 @@ extern void X11DRV_UpdateLayeredWindow( HWND hwnd, const RECT *window_rect, COLO BYTE alpha, UINT flags ); extern LRESULT X11DRV_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ); extern BOOL X11DRV_WindowPosChanging( HWND hwnd, UINT swp_flags, const RECT *window_rect, const RECT *client_rect, RECT *visible_rect ); -extern BOOL X11DRV_CreateWindowSurface( HWND hwnd, UINT swp_flags, const RECT *visible_rect, struct window_surface **surface ); +extern BOOL X11DRV_CreateWindowSurface( HWND hwnd, UINT swp_flags, const RECT *surface_rect, struct window_surface **surface ); extern void X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags, const RECT *rectWindow, const RECT *rectClient, const RECT *visible_rect, const RECT *valid_rects, @@ -685,7 +685,6 @@ typedef int (*x11drv_error_callback)( Display *display, XErrorEvent *event, void
extern void X11DRV_expect_error( Display *display, x11drv_error_callback callback, void *arg ); extern int X11DRV_check_error(void); -extern BOOL get_surface_rect( const RECT *visible_rect, RECT *surface_rect ); extern void X11DRV_X_to_window_rect( struct x11drv_win_data *data, RECT *rect, int x, int y, int cx, int cy ); extern POINT virtual_screen_to_root( INT x, INT y ); extern POINT root_to_virtual_screen( INT x, INT y );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/window.c | 38 +++++++++++++++++++++++++++++++------- 1 file changed, 31 insertions(+), 7 deletions(-)
diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 2c78eaf1d98..05496418665 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -1802,6 +1802,34 @@ static BOOL get_surface_rect( const RECT *visible_rect, RECT *surface_rect ) return TRUE; }
+static BOOL get_default_window_surface( HWND hwnd, const RECT *surface_rect, struct window_surface **surface ) +{ + struct window_surface *previous; + WND *win; + + TRACE( "hwnd %p, surface_rect %s, surface %p\n", hwnd, wine_dbgstr_rect( surface_rect ), surface ); + + if (!(win = get_win_ptr( hwnd )) || win == WND_DESKTOP || win == WND_OTHER_PROCESS) return FALSE; + + if ((previous = win->surface) && EqualRect( &previous->rect, surface_rect )) + { + window_surface_add_ref( (*surface = previous) ); + TRACE( "trying to reuse previous surface %p\n", previous ); + } + else if (!win->parent || win->parent == get_desktop_window()) + { + *surface = &dummy_surface; /* provide a default surface for top-level windows */ + window_surface_add_ref( *surface ); + } + else + { + *surface = NULL; /* use parent surface for child windows */ + TRACE( "using parent window surface\n" ); + } + + release_win_ptr( win ); + return TRUE; +}
/*********************************************************************** * apply_window_pos @@ -1812,19 +1840,15 @@ static BOOL apply_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, const RECT *window_rect, const RECT *client_rect, const RECT *valid_rects ) { WND *win; - HWND surface_win = 0, parent = NtUserGetAncestor( hwnd, GA_PARENT ); + HWND surface_win = 0; BOOL ret, needs_surface, needs_update = FALSE; RECT surface_rect, visible_rect = *window_rect, old_visible_rect, old_window_rect, old_client_rect, extra_rects[3]; - struct window_surface *old_surface, *new_surface = NULL; + struct window_surface *old_surface, *new_surface;
needs_surface = user_driver->pWindowPosChanging( hwnd, swp_flags, window_rect, client_rect, &visible_rect );
if (!get_surface_rect( &visible_rect, &surface_rect )) needs_surface = FALSE; - if (!parent || parent == get_desktop_window()) - { - new_surface = &dummy_surface; /* provide a default surface for top-level windows */ - window_surface_add_ref( new_surface ); - } + if (!get_default_window_surface( hwnd, &surface_rect, &new_surface )) return FALSE;
if (!needs_surface || IsRectEmpty( &visible_rect )) needs_surface = FALSE; /* use default surface */ else needs_surface = !user_driver->pCreateWindowSurface( hwnd, swp_flags, &surface_rect, &new_surface );
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/win32u/driver.c | 2 +- dlls/win32u/window.c | 7 +++++-- dlls/wineandroid.drv/android.h | 2 +- dlls/wineandroid.drv/window.c | 7 ++----- dlls/winemac.drv/macdrv.h | 2 +- dlls/winemac.drv/surface.c | 6 ++---- dlls/winemac.drv/window.c | 1 - dlls/winewayland.drv/waylanddrv.h | 2 +- dlls/winewayland.drv/window.c | 8 ++------ dlls/winewayland.drv/window_surface.c | 4 ++-- dlls/winex11.drv/bitblt.c | 5 ++--- dlls/winex11.drv/window.c | 1 - dlls/winex11.drv/x11drv.h | 2 +- include/wine/gdi_driver.h | 4 ++-- 14 files changed, 22 insertions(+), 31 deletions(-)
diff --git a/dlls/win32u/driver.c b/dlls/win32u/driver.c index 25ed2af1a17..7918945b625 100644 --- a/dlls/win32u/driver.c +++ b/dlls/win32u/driver.c @@ -889,7 +889,7 @@ static BOOL nulldrv_WindowPosChanging( HWND hwnd, UINT swp_flags, const RECT *wi return TRUE; }
-static BOOL nulldrv_CreateWindowSurface( HWND hwnd, UINT swp_flags, const RECT *surface_rect, struct window_surface **surface ) +static BOOL nulldrv_CreateWindowSurface( HWND hwnd, const RECT *surface_rect, struct window_surface **surface ) { return FALSE; } diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c index 05496418665..841ab220074 100644 --- a/dlls/win32u/window.c +++ b/dlls/win32u/window.c @@ -1845,13 +1845,16 @@ static BOOL apply_window_pos( HWND hwnd, HWND insert_after, UINT swp_flags, RECT surface_rect, visible_rect = *window_rect, old_visible_rect, old_window_rect, old_client_rect, extra_rects[3]; struct window_surface *old_surface, *new_surface;
- needs_surface = user_driver->pWindowPosChanging( hwnd, swp_flags, window_rect, client_rect, &visible_rect ); + if (!user_driver->pWindowPosChanging( hwnd, swp_flags, window_rect, client_rect, &visible_rect )) needs_surface = FALSE; + else if (swp_flags & SWP_HIDEWINDOW) needs_surface = FALSE; + else if (swp_flags & SWP_SHOWWINDOW) needs_surface = TRUE; + else needs_surface = !!(NtUserGetWindowLongW( hwnd, GWL_STYLE ) & WS_VISIBLE);
if (!get_surface_rect( &visible_rect, &surface_rect )) needs_surface = FALSE; if (!get_default_window_surface( hwnd, &surface_rect, &new_surface )) return FALSE;
if (!needs_surface || IsRectEmpty( &visible_rect )) needs_surface = FALSE; /* use default surface */ - else needs_surface = !user_driver->pCreateWindowSurface( hwnd, swp_flags, &surface_rect, &new_surface ); + else needs_surface = !user_driver->pCreateWindowSurface( hwnd, &surface_rect, &new_surface );
get_window_rects( hwnd, COORDS_SCREEN, &old_window_rect, NULL, get_thread_dpi() ); if (IsRectEmpty( &valid_rects[0] )) valid_rects = NULL; diff --git a/dlls/wineandroid.drv/android.h b/dlls/wineandroid.drv/android.h index d63f0ee37ec..c92240c40bc 100644 --- a/dlls/wineandroid.drv/android.h +++ b/dlls/wineandroid.drv/android.h @@ -102,7 +102,7 @@ extern BOOL ANDROID_CreateLayeredWindow( HWND hwnd, const RECT *window_rect, COL struct window_surface **surface ); extern LRESULT ANDROID_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ); extern BOOL ANDROID_WindowPosChanging( HWND hwnd, UINT swp_flags, const RECT *window_rect, const RECT *client_rect, RECT *visible_rect ); -extern BOOL ANDROID_CreateWindowSurface( HWND hwnd, UINT swp_flags, const RECT *surface_rect, struct window_surface **surface ); +extern BOOL ANDROID_CreateWindowSurface( HWND hwnd, const RECT *surface_rect, struct window_surface **surface ); extern void ANDROID_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags, const RECT *window_rect, const RECT *client_rect, const RECT *visible_rect, const RECT *valid_rects, diff --git a/dlls/wineandroid.drv/window.c b/dlls/wineandroid.drv/window.c index 706f050534a..6d2e51ee070 100644 --- a/dlls/wineandroid.drv/window.c +++ b/dlls/wineandroid.drv/window.c @@ -1136,7 +1136,6 @@ BOOL ANDROID_WindowPosChanging( HWND hwnd, UINT swp_flags, const RECT *window_re if (!data && !(data = create_win_data( hwnd, window_rect, client_rect ))) return FALSE; /* use default surface */
if (data->parent) goto done; /* use default surface */ - if (swp_flags & SWP_HIDEWINDOW) goto done; /* use default surface */ if (is_argb_surface( data->surface )) goto done; /* use default surface */
ret = TRUE; @@ -1150,7 +1149,7 @@ done: /*********************************************************************** * ANDROID_CreateWindowSurface */ -BOOL ANDROID_CreateWindowSurface( HWND hwnd, UINT swp_flags, const RECT *surface_rect, struct window_surface **surface ) +BOOL ANDROID_CreateWindowSurface( HWND hwnd, const RECT *surface_rect, struct window_surface **surface ) { struct android_win_data *data; DWORD flags; @@ -1158,7 +1157,7 @@ BOOL ANDROID_CreateWindowSurface( HWND hwnd, UINT swp_flags, const RECT *surface BYTE alpha; BOOL layered = NtUserGetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_LAYERED;
- TRACE( "hwnd %p, swp_flags %08x, surface_rect %s, surface %p\n", hwnd, swp_flags, wine_dbgstr_rect( surface_rect ), surface ); + TRACE( "hwnd %p, surface_rect %s, surface %p\n", hwnd, wine_dbgstr_rect( surface_rect ), surface );
if (!(data = get_win_data( hwnd ))) return TRUE; /* use default surface */
@@ -1173,8 +1172,6 @@ BOOL ANDROID_CreateWindowSurface( HWND hwnd, UINT swp_flags, const RECT *surface goto done; } } - if (!(swp_flags & SWP_SHOWWINDOW) && !(NtUserGetWindowLongW( hwnd, GWL_STYLE ) & WS_VISIBLE)) - goto done;
if (!layered || !NtUserGetLayeredWindowAttributes( hwnd, &key, &alpha, &flags )) flags = 0; if (!(flags & LWA_ALPHA)) alpha = 255; diff --git a/dlls/winemac.drv/macdrv.h b/dlls/winemac.drv/macdrv.h index 4a92847dba2..8824f3385fa 100644 --- a/dlls/winemac.drv/macdrv.h +++ b/dlls/winemac.drv/macdrv.h @@ -151,7 +151,7 @@ extern void macdrv_UpdateLayeredWindow(HWND hwnd, const RECT *window_rect, COLOR BYTE alpha, UINT flags); extern LRESULT macdrv_WindowMessage(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp); extern BOOL macdrv_WindowPosChanging(HWND hwnd, UINT swp_flags, const RECT *window_rect, const RECT *client_rect, RECT *visible_rect); -extern BOOL macdrv_CreateWindowSurface(HWND hwnd, UINT swp_flags, const RECT *surface_rect, struct window_surface **surface); +extern BOOL macdrv_CreateWindowSurface(HWND hwnd, const RECT *surface_rect, struct window_surface **surface); extern void macdrv_WindowPosChanged(HWND hwnd, HWND insert_after, UINT swp_flags, const RECT *window_rect, const RECT *client_rect, const RECT *visible_rect, const RECT *valid_rects, diff --git a/dlls/winemac.drv/surface.c b/dlls/winemac.drv/surface.c index d7c76998995..80926760fdf 100644 --- a/dlls/winemac.drv/surface.c +++ b/dlls/winemac.drv/surface.c @@ -228,12 +228,11 @@ void set_surface_use_alpha(struct window_surface *window_surface, BOOL use_alpha /*********************************************************************** * CreateWindowSurface (MACDRV.@) */ -BOOL macdrv_CreateWindowSurface(HWND hwnd, UINT swp_flags, const RECT *surface_rect, struct window_surface **surface) +BOOL macdrv_CreateWindowSurface(HWND hwnd, const RECT *surface_rect, struct window_surface **surface) { struct macdrv_win_data *data; - DWORD style = NtUserGetWindowLongW(hwnd, GWL_STYLE);
- TRACE("hwnd %p, swp_flags %08x, surface_rect %s, surface %p\n", hwnd, swp_flags, wine_dbgstr_rect(surface_rect), surface); + TRACE("hwnd %p, surface_rect %s, surface %p\n", hwnd, wine_dbgstr_rect(surface_rect), surface);
if (!(data = get_win_data(hwnd))) return TRUE; /* use default surface */
@@ -250,7 +249,6 @@ BOOL macdrv_CreateWindowSurface(HWND hwnd, UINT swp_flags, const RECT *surface_r goto done; } } - else if (!(swp_flags & SWP_SHOWWINDOW) && !(style & WS_VISIBLE)) goto done;
*surface = create_surface(data->hwnd, data->cocoa_window, surface_rect, data->surface, FALSE);
diff --git a/dlls/winemac.drv/window.c b/dlls/winemac.drv/window.c index 36f3e3053d6..e772adf29b3 100644 --- a/dlls/winemac.drv/window.c +++ b/dlls/winemac.drv/window.c @@ -1964,7 +1964,6 @@ BOOL macdrv_WindowPosChanging(HWND hwnd, UINT swp_flags, const RECT *window_rect wine_dbgstr_rect(visible_rect));
if (!data->cocoa_window) goto done; /* use default surface */ - if (swp_flags & SWP_HIDEWINDOW) goto done; /* use default surface */ if (data->ulw_layered) goto done; /* use default surface */
ret = TRUE; diff --git a/dlls/winewayland.drv/waylanddrv.h b/dlls/winewayland.drv/waylanddrv.h index 9cce608ce85..d4ef01a8a1e 100644 --- a/dlls/winewayland.drv/waylanddrv.h +++ b/dlls/winewayland.drv/waylanddrv.h @@ -361,7 +361,7 @@ void WAYLAND_WindowPosChanged(HWND hwnd, HWND insert_after, UINT swp_flags, const RECT *visible_rect, const RECT *valid_rects, struct window_surface *surface); BOOL WAYLAND_WindowPosChanging(HWND hwnd, UINT swp_flags, const RECT *window_rect, const RECT *client_rect, RECT *visible_rect); -BOOL WAYLAND_CreateWindowSurface(HWND hwnd, UINT swp_flags, const RECT *surface_rect, struct window_surface **surface); +BOOL WAYLAND_CreateWindowSurface(HWND hwnd, const RECT *surface_rect, struct window_surface **surface); UINT WAYLAND_VulkanInit(UINT version, void *vulkan_handle, const struct vulkan_driver_funcs **driver_funcs); struct opengl_funcs *WAYLAND_wine_get_wgl_driver(UINT version);
diff --git a/dlls/winewayland.drv/window.c b/dlls/winewayland.drv/window.c index 9a77d8cf47e..c1fb5c6e0b5 100644 --- a/dlls/winewayland.drv/window.c +++ b/dlls/winewayland.drv/window.c @@ -431,7 +431,7 @@ BOOL WAYLAND_WindowPosChanging(HWND hwnd, UINT swp_flags, const RECT *window_rec { struct wayland_win_data *data = wayland_win_data_get(hwnd); HWND parent; - BOOL visible, ret = FALSE; + BOOL ret = FALSE;
TRACE("hwnd %p window %s client %s visible %s flags %08x\n", hwnd, wine_dbgstr_rect(window_rect), wine_dbgstr_rect(client_rect), @@ -440,11 +440,7 @@ BOOL WAYLAND_WindowPosChanging(HWND hwnd, UINT swp_flags, const RECT *window_rec if (!data && !(data = wayland_win_data_create(hwnd, window_rect, client_rect))) return FALSE; /* use default surface */
parent = NtUserGetAncestor(hwnd, GA_PARENT); - visible = ((NtUserGetWindowLongW(hwnd, GWL_STYLE) & WS_VISIBLE) || - (swp_flags & SWP_SHOWWINDOW)) && - !(swp_flags & SWP_HIDEWINDOW); - - if ((parent && parent != NtUserGetDesktopWindow()) || !visible) goto done; /* use default surface */ + if ((parent && parent != NtUserGetDesktopWindow())) goto done; /* use default surface */
ret = TRUE;
diff --git a/dlls/winewayland.drv/window_surface.c b/dlls/winewayland.drv/window_surface.c index fa4a69d5490..d1ac582e7ec 100644 --- a/dlls/winewayland.drv/window_surface.c +++ b/dlls/winewayland.drv/window_surface.c @@ -524,11 +524,11 @@ void wayland_window_surface_update_wayland_surface(struct window_surface *window /*********************************************************************** * WAYLAND_CreateWindowSurface */ -BOOL WAYLAND_CreateWindowSurface(HWND hwnd, UINT swp_flags, const RECT *surface_rect, struct window_surface **surface) +BOOL WAYLAND_CreateWindowSurface(HWND hwnd, const RECT *surface_rect, struct window_surface **surface) { struct wayland_win_data *data;
- TRACE("hwnd %p, swp_flags %08x, surface_rect %s, surface %p\n", hwnd, swp_flags, wine_dbgstr_rect(surface_rect), surface); + TRACE("hwnd %p, surface_rect %s, surface %p\n", hwnd, wine_dbgstr_rect(surface_rect), surface);
if (!(data = wayland_win_data_get(hwnd))) return TRUE; /* use default surface */
diff --git a/dlls/winex11.drv/bitblt.c b/dlls/winex11.drv/bitblt.c index 11d37f6bb15..0bc0f02ffd5 100644 --- a/dlls/winex11.drv/bitblt.c +++ b/dlls/winex11.drv/bitblt.c @@ -2187,14 +2187,14 @@ HRGN expose_surface( struct window_surface *window_surface, const RECT *rect ) /*********************************************************************** * CreateWindowSurface (X11DRV.@) */ -BOOL X11DRV_CreateWindowSurface( HWND hwnd, UINT swp_flags, const RECT *surface_rect, struct window_surface **surface ) +BOOL X11DRV_CreateWindowSurface( HWND hwnd, const RECT *surface_rect, struct window_surface **surface ) { struct x11drv_win_data *data; DWORD flags; COLORREF key; BOOL layered = NtUserGetWindowLongW( hwnd, GWL_EXSTYLE ) & WS_EX_LAYERED;
- TRACE( "hwnd %p, swp_flags %08x, surface_rect %s, surface %p\n", hwnd, swp_flags, wine_dbgstr_rect( surface_rect ), surface ); + TRACE( "hwnd %p, surface_rect %s, surface %p\n", hwnd, wine_dbgstr_rect( surface_rect ), surface );
if (!(data = get_win_data( hwnd ))) return TRUE; /* use default surface */
@@ -2216,7 +2216,6 @@ BOOL X11DRV_CreateWindowSurface( HWND hwnd, UINT swp_flags, const RECT *surface_ goto done; } } - else if (!(swp_flags & SWP_SHOWWINDOW) && !(NtUserGetWindowLongW( hwnd, GWL_STYLE ) & WS_VISIBLE)) goto done;
if (!layered || !NtUserGetLayeredWindowAttributes( hwnd, &key, NULL, &flags ) || !(flags & LWA_COLORKEY)) key = CLR_INVALID; diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c index 9564f05f8e9..2a84bc49620 100644 --- a/dlls/winex11.drv/window.c +++ b/dlls/winex11.drv/window.c @@ -2599,7 +2599,6 @@ BOOL X11DRV_WindowPosChanging( HWND hwnd, UINT swp_flags, const RECT *window_rec X11DRV_window_to_X_rect( data, visible_rect, window_rect, client_rect );
if (!data->whole_window && !data->embedded) goto done; /* use default surface */ - if (swp_flags & SWP_HIDEWINDOW) goto done; /* use default surface */ if (data->use_alpha) goto done; /* use default surface */
ret = TRUE; diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h index 8b78f9648b2..4a9bdafd449 100644 --- a/dlls/winex11.drv/x11drv.h +++ b/dlls/winex11.drv/x11drv.h @@ -246,7 +246,7 @@ extern void X11DRV_UpdateLayeredWindow( HWND hwnd, const RECT *window_rect, COLO BYTE alpha, UINT flags ); extern LRESULT X11DRV_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp ); extern BOOL X11DRV_WindowPosChanging( HWND hwnd, UINT swp_flags, const RECT *window_rect, const RECT *client_rect, RECT *visible_rect ); -extern BOOL X11DRV_CreateWindowSurface( HWND hwnd, UINT swp_flags, const RECT *surface_rect, struct window_surface **surface ); +extern BOOL X11DRV_CreateWindowSurface( HWND hwnd, const RECT *surface_rect, struct window_surface **surface ); extern void X11DRV_WindowPosChanged( HWND hwnd, HWND insert_after, UINT swp_flags, const RECT *rectWindow, const RECT *rectClient, const RECT *visible_rect, const RECT *valid_rects, diff --git a/include/wine/gdi_driver.h b/include/wine/gdi_driver.h index 5ee77e25f28..d835e45af3f 100644 --- a/include/wine/gdi_driver.h +++ b/include/wine/gdi_driver.h @@ -179,7 +179,7 @@ struct gdi_dc_funcs };
/* increment this when you change the DC function table */ -#define WINE_GDI_DRIVER_VERSION 85 +#define WINE_GDI_DRIVER_VERSION 86
#define GDI_PRIORITY_NULL_DRV 0 /* null driver */ #define GDI_PRIORITY_FONT_DRV 100 /* any font driver */ @@ -338,7 +338,7 @@ struct user_driver_funcs void (*pUpdateLayeredWindow)(HWND,const RECT *,COLORREF,BYTE,UINT); LRESULT (*pWindowMessage)(HWND,UINT,WPARAM,LPARAM); BOOL (*pWindowPosChanging)(HWND,UINT,const RECT *,const RECT *,RECT *); - BOOL (*pCreateWindowSurface)(HWND,UINT,const RECT *,struct window_surface**); + BOOL (*pCreateWindowSurface)(HWND,const RECT *,struct window_surface**); void (*pWindowPosChanged)(HWND,HWND,UINT,const RECT *,const RECT *,const RECT *, const RECT *,struct window_surface*); /* system parameters */
This merge request was approved by Huw Davies.