From: Jinoh Kang jinoh.kang.kr@gmail.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53153 Signed-off-by: Jinoh Kang jinoh.kang.kr@gmail.com --- dlls/user32/tests/msg.c | 4 ++-- server/class.c | 5 +++++ server/user.h | 8 ++++++++ server/window.c | 23 +++++++++++++++++++++-- 4 files changed, 36 insertions(+), 4 deletions(-)
diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c index c62b25446a2..317dd9e48dc 100644 --- a/dlls/user32/tests/msg.c +++ b/dlls/user32/tests/msg.c @@ -9295,7 +9295,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 ) ? is_zorder_redraw : - ((extest->style & WS_CLIPCHILDREN) == 0 || is_composited) ) + ((extest->style & WS_CLIPCHILDREN) == 0 && !is_composited) ) ok( !!rgn_equal, "Parent update region shall match expected region\n" );
if (!rgn_equal && winetest_debug > 0) @@ -9354,7 +9354,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 ) ? is_zorder_redraw : - ((extest->style & WS_CLIPCHILDREN) == 0 || is_composited) ) + ((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/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..9e91d427a3a 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 );
@@ -191,6 +192,13 @@ extern void close_process_desktop( struct process *process ); extern void set_thread_default_desktop( struct thread *thread, struct desktop *desktop, obj_handle_t handle ); extern void release_thread_desktop( struct thread *thread, int close );
+/* checks if two rectangles are identical */ +static inline int is_rect_equal( const rectangle_t *rect1, const rectangle_t *rect2 ) +{ + return (rect1->left == rect2->left && rect1->right == rect2->right && + rect1->top == rect2->top && rect1->bottom == rect2->bottom); +} + static inline int is_rect_empty( const rectangle_t *rect ) { return (rect->left >= rect->right || rect->top >= rect->bottom); diff --git a/server/window.c b/server/window.c index 7675cd1103d..6fc9f9f9e40 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 ) { @@ -1712,12 +1722,20 @@ static struct region *expose_window( struct window *win, const rectangle_t *old_ struct region *old_vis_rgn ) { 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 )) + { + return NULL; + }
if (!(new_vis_rgn = get_visible_region( win, DCX_WINDOW ))) return NULL;
if ((exposed_rgn = create_empty_region())) { - if (subtract_region( exposed_rgn, new_vis_rgn, old_vis_rgn ) && !is_region_empty( exposed_rgn )) + if ((is_composited ? union_region( exposed_rgn, new_vis_rgn, old_vis_rgn ) + : subtract_region( exposed_rgn, new_vis_rgn, old_vis_rgn )) && + !is_region_empty( exposed_rgn )) { /* make it relative to the new client area */ offset_region( exposed_rgn, win->window_rect.left - win->client_rect.left, @@ -1736,7 +1754,8 @@ static struct region *expose_window( struct window *win, const rectangle_t *old_ 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) ? + if (is_composited ? union_region( new_vis_rgn, old_vis_rgn, new_vis_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 )) {