From: Rémi Bernon <rbernon(a)codeweavers.com>
And attach them back when they are.
---
dlls/win32u/ntuser_private.h | 1 +
dlls/win32u/vulkan.c | 49 +++++++++++++++++++++++++++++++++---
dlls/win32u/window.c | 4 ++-
3 files changed, 49 insertions(+), 5 deletions(-)
diff --git a/dlls/win32u/ntuser_private.h b/dlls/win32u/ntuser_private.h
index 04396abca72..7662436a588 100644
--- a/dlls/win32u/ntuser_private.h
+++ b/dlls/win32u/ntuser_private.h
@@ -258,6 +258,7 @@ extern LRESULT system_tray_call( HWND hwnd, UINT msg, WPARAM wparam,
LPARAM lpar
/* vulkan.c */
extern void vulkan_detach_surfaces( struct list *surfaces );
extern void vulkan_set_parent( HWND hwnd, HWND new_parent, HWND old_parent );
+extern void vulkan_set_region( HWND toplevel, HRGN region );
/* window.c */
HANDLE alloc_user_handle( struct user_object *ptr, unsigned int type );
diff --git a/dlls/win32u/vulkan.c b/dlls/win32u/vulkan.c
index e57aa440c81..ca681b49d99 100644
--- a/dlls/win32u/vulkan.c
+++ b/dlls/win32u/vulkan.c
@@ -59,6 +59,7 @@ struct surface
struct list entry;
VkSurfaceKHR host_surface;
void *driver_private;
+ BOOL is_detached;
HWND hwnd;
};
@@ -93,6 +94,8 @@ static VkResult win32u_vkCreateWin32SurfaceKHR( VkInstance instance,
const VkWin
if (!(win = get_win_ptr( toplevel )) || win == WND_DESKTOP || win ==
WND_OTHER_PROCESS)
{
driver_funcs->p_vulkan_surface_detach( surface->hwnd,
surface->driver_private );
+ surface->is_detached = TRUE;
+
pthread_mutex_lock( &vulkan_mutex );
list_add_tail( &offscreen_surfaces, &surface->entry );
pthread_mutex_unlock( &vulkan_mutex );
@@ -279,7 +282,11 @@ void vulkan_detach_surfaces( struct list *surfaces )
struct surface *surface;
LIST_FOR_EACH_ENTRY( surface, surfaces, struct surface, entry )
+ {
+ if (surface->is_detached) continue;
driver_funcs->p_vulkan_surface_detach( surface->hwnd,
surface->driver_private );
+ surface->is_detached = TRUE;
+ }
pthread_mutex_lock( &vulkan_mutex );
list_move_tail( &offscreen_surfaces, surfaces );
@@ -288,7 +295,6 @@ void vulkan_detach_surfaces( struct list *surfaces )
static void append_window_surfaces( HWND toplevel, struct list *surfaces )
{
- struct surface *surface;
WND *win;
if (!(win = get_win_ptr( toplevel )) || win == WND_DESKTOP || win ==
WND_OTHER_PROCESS)
@@ -301,9 +307,6 @@ static void append_window_surfaces( HWND toplevel, struct list
*surfaces )
{
list_move_tail( &win->vulkan_surfaces, surfaces );
release_win_ptr( win );
-
- LIST_FOR_EACH_ENTRY( surface, surfaces, struct surface, entry )
- driver_funcs->p_vulkan_surface_attach( surface->hwnd,
surface->driver_private );
}
}
@@ -351,12 +354,50 @@ void vulkan_set_parent( HWND hwnd, HWND new_parent, HWND old_parent
)
enum_window_surfaces( old_toplevel, hwnd, &surfaces );
+ /* surfaces will be re-attached as needed from surface region updates */
LIST_FOR_EACH_ENTRY( surface, &surfaces, struct surface, entry )
+ {
+ if (surface->is_detached) continue;
driver_funcs->p_vulkan_surface_detach( surface->hwnd,
surface->driver_private );
+ surface->is_detached = TRUE;
+ }
append_window_surfaces( new_toplevel, &surfaces );
}
+void vulkan_set_region( HWND toplevel, HRGN region )
+{
+ struct list surfaces = LIST_INIT(surfaces);
+ struct surface *surface;
+
+ enum_window_surfaces( toplevel, toplevel, &surfaces );
+
+ LIST_FOR_EACH_ENTRY( surface, &surfaces, struct surface, entry )
+ {
+ RECT client_rect;
+ BOOL is_clipped;
+
+ NtUserGetClientRect( surface->hwnd, &client_rect );
+ NtUserMapWindowPoints( surface->hwnd, toplevel, (POINT *)&client_rect, 2
);
+ is_clipped = NtGdiRectInRegion( region, &client_rect );
+
+ if (is_clipped && !surface->is_detached)
+ {
+ TRACE( "surface %p is now clipped\n", surface->hwnd );
+ driver_funcs->p_vulkan_surface_detach( surface->hwnd,
surface->driver_private );
+ surface->is_detached = TRUE;
+ }
+ else if (!is_clipped && surface->is_detached)
+ {
+ TRACE( "surface %p is now unclipped\n", surface->hwnd );
+ driver_funcs->p_vulkan_surface_attach( surface->hwnd,
surface->driver_private );
+ surface->is_detached = FALSE;
+ }
+ }
+
+ append_window_surfaces( toplevel, &surfaces );
+}
+
/***********************************************************************
* __wine_get_vulkan_driver (win32u.so)
*/
diff --git a/dlls/win32u/window.c b/dlls/win32u/window.c
index f630f107b00..4cef4b71757 100644
--- a/dlls/win32u/window.c
+++ b/dlls/win32u/window.c
@@ -1762,10 +1762,12 @@ static void update_surface_region( HWND hwnd )
if (status) goto done;
win->surface->funcs->set_region( win->surface, region );
- if (region) NtGdiDeleteObjectApp( region );
done:
release_win_ptr( win );
+
+ vulkan_set_region( hwnd, region );
+ if (region) NtGdiDeleteObjectApp( region );
}
/***********************************************************************
--
GitLab
https://gitlab.winehq.org/wine/wine/-/merge_requests/5573