Module: wine Branch: master Commit: d52e454c12305857bf750ac9988e7e0752ced79e URL: https://source.winehq.org/git/wine.git/?a=commit;h=d52e454c12305857bf750ac99...
Author: Jacek Caban jacek@codeweavers.com Date: Tue Feb 8 13:12:50 2022 +0100
server: Keep a reference to parent in window objects.
Signed-off-by: Jacek Caban jacek@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
server/window.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-)
diff --git a/server/window.c b/server/window.c index 4373297b152..9fd67656eea 100644 --- a/server/window.c +++ b/server/window.c @@ -170,6 +170,12 @@ static void window_destroy( struct object *obj )
assert( !win->handle );
+ if (win->parent) + { + list_remove( &win->entry ); + release_object( win->parent ); + } + if (win->win_region) free_region( win->win_region ); if (win->update_region) free_region( win->update_region ); if (win->class) release_class( win->class ); @@ -312,7 +318,8 @@ static int set_parent_window( struct window *win, struct window *parent )
if (parent) { - win->parent = parent; + if (win->parent) release_object( win->parent ); + win->parent = (struct window *)grab_object( parent ); link_window( win, WINPTR_TOP );
if (!is_desktop_window( parent )) @@ -537,7 +544,7 @@ static struct window *create_window( struct window *parent, struct window *owner }
if (!(win = alloc_object( &window_ops ))) goto failed; - win->parent = parent; + win->parent = parent ? (struct window *)grab_object( parent ) : NULL; win->owner = owner ? owner->handle : 0; win->thread = current; win->desktop = desktop; @@ -1935,6 +1942,8 @@ static void set_window_region( struct window *win, struct region *region, int re /* destroy a window */ void free_window_handle( struct window *win ) { + struct window *child, *next; + assert( win->handle );
/* hide the window */ @@ -1953,10 +1962,16 @@ void free_window_handle( struct window *win ) }
/* destroy all children */ - while (!list_empty(&win->children)) - free_window_handle( LIST_ENTRY( list_head(&win->children), struct window, entry )); - while (!list_empty(&win->unlinked)) - free_window_handle( LIST_ENTRY( list_head(&win->unlinked), struct window, entry )); + LIST_FOR_EACH_ENTRY_SAFE( child, next, &win->children, struct window, entry ) + { + if (!child->handle) continue; + free_window_handle( child ); + } + LIST_FOR_EACH_ENTRY_SAFE( child, next, &win->children, struct window, entry ) + { + if (!child->handle) continue; + free_window_handle( child ); + }
/* reset global window pointers, if the corresponding window is destroyed */ if (win == shell_window) shell_window = NULL; @@ -1966,7 +1981,6 @@ void free_window_handle( struct window *win ) free_hotkeys( win->desktop, win->handle ); cleanup_clipboard_window( win->desktop, win->handle ); destroy_properties( win ); - list_remove( &win->entry ); if (is_desktop_window(win)) { struct desktop *desktop = win->desktop; @@ -1981,6 +1995,7 @@ void free_window_handle( struct window *win )
detach_window_thread( win );
+ if (win->parent) set_parent_window( win, NULL ); free_user_handle( win->handle ); win->handle = 0; release_object( win );