[PATCH v2 2/2] server: Correctly expose composited parent window on SetWindowPos().

Jinoh Kang wine at gitlab.winehq.org
Mon Jun 13 11:46:33 CDT 2022


From: Jinoh Kang <jinoh.kang.kr at gmail.com>

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53153
Signed-off-by: Jinoh Kang <jinoh.kang.kr at gmail.com>
---
 dlls/user32/tests/msg.c |  2 +-
 server/class.c          |  5 +++++
 server/user.h           |  1 +
 server/window.c         | 37 +++++++++++++++++++++++++++++--------
 4 files changed, 36 insertions(+), 9 deletions(-)

diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c
index 67f58032cb3..a431e3b04d6 100644
--- a/dlls/user32/tests/msg.c
+++ b/dlls/user32/tests/msg.c
@@ -9257,7 +9257,7 @@ static void subtest_swp_paint_regions_( int line, int wrap_toplevel, LPCSTR pare
                 rgn_equal = EqualRgn( hrgn_expect, hrgn_actual );
             }
             todo_wine_if( !EqualRect( &rect_old, &rect_new ) &&
-                          ((extest->style & WS_CLIPCHILDREN) == 0 || region_op == RGN_OR) )
+                          (extest->style & WS_CLIPCHILDREN) == 0 && region_op != RGN_OR )
             ok( !!rgn_equal, "Update region shall match expected region\n" );
 
             flush_events();
diff --git a/server/class.c b/server/class.c
index e1e180bd97c..3231f366b26 100644
--- a/server/class.c
+++ b/server/class.c
@@ -141,6 +141,11 @@ int is_hwnd_message_class( struct window_class *class )
     return (!class->local && class->atom == find_global_atom( NULL, &name ));
 }
 
+int get_class_style( struct window_class *class )
+{
+    return class->style;
+}
+
 atom_t get_class_atom( struct window_class *class )
 {
     return class->base_atom;
diff --git a/server/user.h b/server/user.h
index 55a0d35feff..0356fe0c5cd 100644
--- a/server/user.h
+++ b/server/user.h
@@ -175,6 +175,7 @@ extern struct window_class *grab_class( struct process *process, atom_t atom,
 extern void release_class( struct window_class *class );
 extern int is_desktop_class( struct window_class *class );
 extern int is_hwnd_message_class( struct window_class *class );
+extern int get_class_style( struct window_class *class );
 extern atom_t get_class_atom( struct window_class *class );
 extern client_ptr_t get_class_client_ptr( struct window_class *class );
 
diff --git a/server/window.c b/server/window.c
index 7675cd1103d..d007e38f49c 100644
--- a/server/window.c
+++ b/server/window.c
@@ -789,6 +789,16 @@ int is_window_transparent( user_handle_t window )
     return (win->ex_style & (WS_EX_LAYERED|WS_EX_TRANSPARENT)) == (WS_EX_LAYERED|WS_EX_TRANSPARENT);
 }
 
+static int is_window_using_parent_dc( struct window *win )
+{
+    return (win->style & (WS_POPUP|WS_CHILD)) == WS_CHILD && (get_class_style( win->class ) & CS_PARENTDC) != 0;
+}
+
+static int is_window_composited( struct window *win )
+{
+    return (win->ex_style & WS_EX_COMPOSITED) != 0 && !is_window_using_parent_dc(win);
+}
+
 /* check if point is inside the window, and map to window dpi */
 static int is_point_in_window( struct window *win, int *x, int *y, unsigned int dpi )
 {
@@ -1705,7 +1715,6 @@ static unsigned int get_window_update_flags( struct window *win, struct window *
     return 0;
 }
 
-
 /* expose the areas revealed by a vis region change on the window parent */
 /* returns the region exposed on the window itself (in client coordinates) */
 static struct region *expose_window( struct window *win, const rectangle_t *old_window_rect,
@@ -1732,21 +1741,33 @@ static struct region *expose_window( struct window *win, const rectangle_t *old_
 
     if (win->parent && !is_desktop_window( win->parent ))
     {
+        struct region *parent_expose_rgn;
+
         /* make it relative to the old window pos for subtracting */
         offset_region( new_vis_rgn, win->window_rect.left - old_window_rect->left,
                        win->window_rect.top - old_window_rect->top  );
 
-        if ((win->parent->style & WS_CLIPCHILDREN) ?
-            subtract_region( new_vis_rgn, old_vis_rgn, new_vis_rgn ) :
-            xor_region( new_vis_rgn, old_vis_rgn, new_vis_rgn ))
+        if (is_window_composited( win->parent ))
         {
-            if (!is_region_empty( new_vis_rgn ))
+            parent_expose_rgn = xor_region( new_vis_rgn, old_vis_rgn, new_vis_rgn );
+            if (parent_expose_rgn && !is_region_empty( parent_expose_rgn ))
             {
-                /* make it relative to parent */
-                offset_region( new_vis_rgn, old_window_rect->left, old_window_rect->top );
-                redraw_window( win->parent, new_vis_rgn, 0, RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN );
+                parent_expose_rgn = union_region( parent_expose_rgn, old_vis_rgn, parent_expose_rgn );
             }
         }
+        else
+        {
+            parent_expose_rgn = (win->parent->style & WS_CLIPCHILDREN) ?
+                                subtract_region( new_vis_rgn, old_vis_rgn, new_vis_rgn ) :
+                                xor_region( new_vis_rgn, old_vis_rgn, new_vis_rgn );
+        }
+
+        if (parent_expose_rgn && !is_region_empty( parent_expose_rgn ))
+        {
+            /* make it relative to parent */
+            offset_region( parent_expose_rgn, old_window_rect->left, old_window_rect->top );
+            redraw_window( win->parent, parent_expose_rgn, 0, RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN );
+        }
     }
     free_region( new_vis_rgn );
     return exposed_rgn;
-- 
GitLab

https://gitlab.winehq.org/wine/wine/-/merge_requests/231



More information about the wine-devel mailing list