[PATCH v3 3/4] server: Redraw composited window child on its z-order change on SetWindowPos().

Jinoh Kang wine at gitlab.winehq.org
Thu Jun 16 20:36:48 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 |  8 ++++----
 server/window.c         | 18 ++++++++++++------
 2 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c
index 317dd9e48dc..991f1c22076 100644
--- a/dlls/user32/tests/msg.c
+++ b/dlls/user32/tests/msg.c
@@ -9294,8 +9294,8 @@ static void subtest_swp_paint_regions_( int line, int wrap_toplevel, LPCSTR pare
                 CombineRgn( hrgn_expect, hrgn_old_vis, hrgn_new_vis, RGN_DIFF );
                 rgn_equal = EqualRgn( hrgn_expect, hrgn_actual );
             }
-            todo_wine_if( EqualRect( &rect_old, &rect_new ) ? is_zorder_redraw :
-                          ((extest->style & WS_CLIPCHILDREN) == 0 && !is_composited) )
+            todo_wine_if( !EqualRect( &rect_old, &rect_new ) &&
+                          (extest->style & WS_CLIPCHILDREN) == 0 && !is_composited )
             ok( !!rgn_equal, "Parent update region shall match expected region\n" );
 
             if (!rgn_equal && winetest_debug > 0)
@@ -9353,8 +9353,8 @@ static void subtest_swp_paint_regions_( int line, int wrap_toplevel, LPCSTR pare
                 CombineRgn( hrgn_expect_child, hrgn_new_vis_child, hrgn_old_vis_child, RGN_DIFF );
                 rgn_equal = EqualRgn( hrgn_expect, hrgn_actual );
             }
-            todo_wine_if( EqualRect( &rect_old, &rect_new ) ? is_zorder_redraw :
-                          ((extest->style & WS_CLIPCHILDREN) == 0 && !is_composited) )
+            todo_wine_if( !EqualRect( &rect_old, &rect_new ) &&
+                          (extest->style & WS_CLIPCHILDREN) == 0 && !is_composited )
             ok( !!rgn_equal, "Child update region shall match expected region\n" );
 
             if (!rgn_equal && winetest_debug > 0)
diff --git a/server/window.c b/server/window.c
index 6fc9f9f9e40..7e418b7b3fa 100644
--- a/server/window.c
+++ b/server/window.c
@@ -1719,12 +1719,12 @@ static unsigned int get_window_update_flags( struct window *win, struct window *
 /* 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,
-                                     struct region *old_vis_rgn )
+                                     struct region *old_vis_rgn, int zorder_changed )
 {
     struct region *new_vis_rgn, *exposed_rgn;
     int is_composited = win->parent && is_window_composited( win->parent );
 
-    if (is_rect_equal( &win->window_rect, old_window_rect ))
+    if (is_rect_equal( &win->window_rect, old_window_rect ) && !(is_composited && zorder_changed))
     {
         return NULL;
     }
@@ -1785,6 +1785,7 @@ static void set_window_pos( struct window *win, struct window *previous,
     rectangle_t rect;
     int client_changed, frame_changed;
     int visible = (win->style & WS_VISIBLE) || (swp_flags & SWP_SHOWWINDOW);
+    int zorder_changed = 0;
 
     if (win->parent && !is_visible( win->parent )) visible = 0;
 
@@ -1796,7 +1797,12 @@ static void set_window_pos( struct window *win, struct window *previous,
     win->visible_rect = *visible_rect;
     win->surface_rect = *surface_rect;
     win->client_rect  = *client_rect;
-    if (!(swp_flags & SWP_NOZORDER) && win->parent) link_window( win, previous );
+    if (!(swp_flags & SWP_NOZORDER) && win->parent)
+    {
+        struct list *old_prev = win->is_linked ? win->entry.prev : NULL;
+        link_window( win, previous );
+        if (old_prev != win->entry.prev) zorder_changed = 1;
+    }
     if (swp_flags & SWP_SHOWWINDOW) win->style |= WS_VISIBLE;
     else if (swp_flags & SWP_HIDEWINDOW) win->style &= ~WS_VISIBLE;
 
@@ -1825,7 +1831,7 @@ static void set_window_pos( struct window *win, struct window *previous,
     /* expose anything revealed by the change */
 
     if (!(swp_flags & SWP_NOREDRAW))
-        exposed_rgn = expose_window( win, &old_window_rect, old_vis_rgn );
+        exposed_rgn = expose_window( win, &old_window_rect, old_vis_rgn, zorder_changed );
 
     if (!(win->style & WS_VISIBLE))
     {
@@ -1956,7 +1962,7 @@ static void set_window_region( struct window *win, struct region *region, int re
     win->win_region = region;
 
     /* expose anything revealed by the change */
-    if (old_vis_rgn && ((exposed_rgn = expose_window( win, &win->window_rect, old_vis_rgn ))))
+    if (old_vis_rgn && ((exposed_rgn = expose_window( win, &win->window_rect, old_vis_rgn, 0 ))))
     {
         redraw_window( win, exposed_rgn, 1, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME | RDW_ALLCHILDREN );
         free_region( exposed_rgn );
@@ -1981,7 +1987,7 @@ void free_window_handle( struct window *win )
         win->style &= ~WS_VISIBLE;
         if (vis_rgn)
         {
-            struct region *exposed_rgn = expose_window( win, &win->window_rect, vis_rgn );
+            struct region *exposed_rgn = expose_window( win, &win->window_rect, vis_rgn, 0 );
             if (exposed_rgn) free_region( exposed_rgn );
             free_region( vis_rgn );
         }
-- 
GitLab


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



More information about the wine-devel mailing list