Replace the link_window request by a set_parent request since that is all link_window is used for at this point. Get rid of the WIN_LinkWindow/UnlinkWindow functions.
diff --git a/dlls/user/user32.spec b/dlls/user/user32.spec index 895238a..c9a6efb 100644 --- a/dlls/user/user32.spec +++ b/dlls/user/user32.spec
@@ -732,6 +732,4 @@ @ cdecl WINPOS_GetMinMaxInfo(long ptr ptr ptr ptr) @ cdecl WINPOS_ShowIconTitle(long long) @ cdecl WIN_GetPtr(long) -@ cdecl WIN_LinkWindow(long long long) @ cdecl WIN_SetStyle(long long long) -@ cdecl WIN_UnlinkWindow(long)
diff --git a/dlls/x11drv/window.c b/dlls/x11drv/window.c index f987d87..b4a7fe4 100644 --- a/dlls/x11drv/window.c +++ b/dlls/x11drv/window.c
@@ -39,8 +39,9 @@ #include "winuser.h" #include "wine/unicode.h" -#include "wine/debug.h" #include "x11drv.h" +#include "wine/debug.h" +#include "wine/server.h" #include "win.h" #include "winpos.h" #include "mwm.h" @@ -1003,11 +1004,7 @@ else ret = (SendMessageA( hwnd, WM_CREATE, 0, (LPARAM)cs ) != -1); - if (!ret) - { - WIN_UnlinkWindow( hwnd ); - return FALSE; - } + if (!ret) return FALSE; NotifyWinEvent(EVENT_OBJECT_CREATE, hwnd, OBJID_WINDOW, 0); @@ -1127,22 +1124,37 @@ HWND X11DRV_SetParent( HWND hwnd, HWND parent ) { Display *display = thread_display(); - HWND old_parent; + WND *wndPtr; + BOOL ret; + HWND old_parent = 0; /* Windows hides the window first, then shows it again * including the WM_SHOWWINDOW messages and all */ BOOL was_visible = ShowWindow( hwnd, SW_HIDE ); - if (!IsWindow( parent )) return 0; + wndPtr = WIN_GetPtr( hwnd ); + if (!wndPtr || wndPtr == WND_OTHER_PROCESS || wndPtr == WND_DESKTOP) return 0; - old_parent = GetAncestor( hwnd, GA_PARENT ); + SERVER_START_REQ( set_parent ) + { + req->handle = hwnd; + req->parent = parent; + if ((ret = !wine_server_call( req ))) + { + old_parent = reply->old_parent; + wndPtr->parent = parent = reply->full_parent; + } + + } + SERVER_END_REQ; + WIN_ReleasePtr( wndPtr ); + if (!ret) return 0; + if (parent != old_parent) { - struct x11drv_win_data *data; + struct x11drv_win_data *data = X11DRV_get_win_data( hwnd ); - if (!(data = X11DRV_get_win_data( hwnd ))) return 0; - - WIN_LinkWindow( hwnd, parent, HWND_TOP ); + if (!data) return 0; if (parent != GetDesktopWindow()) /* a child window */ {
diff --git a/include/win.h b/include/win.h index b55b9f9..7895479 100644 --- a/include/win.h +++ b/include/win.h
@@ -77,8 +77,6 @@ extern HWND WIN_Handle32( HWND16 hwnd16 ); extern HWND WIN_IsCurrentProcess( HWND hwnd ); extern HWND WIN_IsCurrentThread( HWND hwnd ); -extern void WIN_LinkWindow( HWND hwnd, HWND parent, HWND hwndInsertAfter ); -extern void WIN_UnlinkWindow( HWND hwnd ); extern HWND WIN_SetOwner( HWND hwnd, HWND owner ); extern ULONG WIN_SetStyle( HWND hwnd, ULONG set_bits, ULONG clear_bits ); extern BOOL WIN_GetRectangles( HWND hwnd, RECT *rectWindow, RECT *rectClient );
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index fa632e0..747c05b 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h
@@ -2435,21 +2435,6 @@ -struct link_window_request -{ - struct request_header __header; - user_handle_t handle; - user_handle_t parent; - user_handle_t previous; -}; -struct link_window_reply -{ - struct reply_header __header; - user_handle_t full_parent; -}; - - - struct destroy_window_request { struct request_header __header; @@ -2527,6 +2512,21 @@ +struct set_parent_request +{ + struct request_header __header; + user_handle_t handle; + user_handle_t parent; +}; +struct set_parent_reply +{ + struct reply_header __header; + user_handle_t old_parent; + user_handle_t full_parent; +}; + + + struct get_window_parents_request { struct request_header __header; @@ -3380,11 +3380,11 @@ REQ_disconnect_named_pipe, REQ_get_named_pipe_info, REQ_create_window, - REQ_link_window, REQ_destroy_window, REQ_set_window_owner, REQ_get_window_info, REQ_set_window_info, + REQ_set_parent, REQ_get_window_parents, REQ_get_window_children, REQ_get_window_children_from_point, @@ -3572,11 +3572,11 @@ struct disconnect_named_pipe_request disconnect_named_pipe_request; struct get_named_pipe_info_request get_named_pipe_info_request; struct create_window_request create_window_request; - struct link_window_request link_window_request; struct destroy_window_request destroy_window_request; struct set_window_owner_request set_window_owner_request; struct get_window_info_request get_window_info_request; struct set_window_info_request set_window_info_request; + struct set_parent_request set_parent_request; struct get_window_parents_request get_window_parents_request; struct get_window_children_request get_window_children_request; struct get_window_children_from_point_request get_window_children_from_point_request; @@ -3762,11 +3762,11 @@ struct disconnect_named_pipe_reply disconnect_named_pipe_reply; struct get_named_pipe_info_reply get_named_pipe_info_reply; struct create_window_reply create_window_reply; - struct link_window_reply link_window_reply; struct destroy_window_reply destroy_window_reply; struct set_window_owner_reply set_window_owner_reply; struct get_window_info_reply get_window_info_reply; struct set_window_info_reply set_window_info_reply; + struct set_parent_reply set_parent_reply; struct get_window_parents_reply get_window_parents_reply; struct get_window_children_reply get_window_children_reply; struct get_window_children_from_point_reply get_window_children_from_point_reply; @@ -3812,6 +3812,6 @@ struct duplicate_token_reply duplicate_token_reply; }; -#define SERVER_PROTOCOL_VERSION 163 +#define SERVER_PROTOCOL_VERSION 164 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/protocol.def b/server/protocol.def index b6553e2..da7dfe8 100644 --- a/server/protocol.def +++ b/server/protocol.def
@@ -1718,16 +1718,6 @@ @END -/* Link a window into the tree */ -@REQ(link_window) - user_handle_t handle; /* handle to the window */ - user_handle_t parent; /* handle to the parent */ - user_handle_t previous; /* previous child in Z-order */ -@REPLY - user_handle_t full_parent; /* full handle of new parent */ -@END - - /* Destroy a window */ @REQ(destroy_window) user_handle_t handle; /* handle to the window */ @@ -1784,6 +1774,16 @@ #define SET_WIN_EXTRA 0x20 +/* Set the parent of a window */ +@REQ(set_parent) + user_handle_t handle; /* handle to the window */ + user_handle_t parent; /* handle to the parent */ +@REPLY + user_handle_t old_parent; /* old parent window */ + user_handle_t full_parent; /* full handle of new parent */ +@END + + /* Get a list of the window parents, up to the root of the tree */ @REQ(get_window_parents) user_handle_t handle; /* handle to the window */
diff --git a/server/request.h b/server/request.h index 7ce7aa1..5c8ffe2 100644 --- a/server/request.h +++ b/server/request.h
@@ -240,11 +240,11 @@ DECL_HANDLER(disconnect_named_pipe); DECL_HANDLER(get_named_pipe_info); DECL_HANDLER(create_window); -DECL_HANDLER(link_window); DECL_HANDLER(destroy_window); DECL_HANDLER(set_window_owner); DECL_HANDLER(get_window_info); DECL_HANDLER(set_window_info); +DECL_HANDLER(set_parent); DECL_HANDLER(get_window_parents); DECL_HANDLER(get_window_children); DECL_HANDLER(get_window_children_from_point); @@ -431,11 +431,11 @@ (req_handler)req_disconnect_named_pipe, (req_handler)req_get_named_pipe_info, (req_handler)req_create_window, - (req_handler)req_link_window, (req_handler)req_destroy_window, (req_handler)req_set_window_owner, (req_handler)req_get_window_info, (req_handler)req_set_window_info, + (req_handler)req_set_parent, (req_handler)req_get_window_parents, (req_handler)req_get_window_children, (req_handler)req_get_window_children_from_point,
diff --git a/server/trace.c b/server/trace.c index 738a1b8..317d22d 100644 --- a/server/trace.c +++ b/server/trace.c
@@ -2069,18 +2069,6 @@ fprintf( stderr, " class_ptr=%p", req->class_ptr ); } -static void dump_link_window_request( const struct link_window_request *req ) -{ - fprintf( stderr, " handle=%p,", req->handle ); - fprintf( stderr, " parent=%p,", req->parent ); - fprintf( stderr, " previous=%p", req->previous ); -} - -static void dump_link_window_reply( const struct link_window_reply *req ) -{ - fprintf( stderr, " full_parent=%p", req->full_parent ); -} - static void dump_destroy_window_request( const struct destroy_window_request *req ) { fprintf( stderr, " handle=%p", req->handle ); @@ -2136,6 +2124,18 @@ fprintf( stderr, " old_extra_value=%08x", req->old_extra_value ); } +static void dump_set_parent_request( const struct set_parent_request *req ) +{ + fprintf( stderr, " handle=%p,", req->handle ); + fprintf( stderr, " parent=%p", req->parent ); +} + +static void dump_set_parent_reply( const struct set_parent_reply *req ) +{ + fprintf( stderr, " old_parent=%p,", req->old_parent ); + fprintf( stderr, " full_parent=%p", req->full_parent ); +} + static void dump_get_window_parents_request( const struct get_window_parents_request *req ) { fprintf( stderr, " handle=%p", req->handle ); @@ -2834,11 +2834,11 @@ (dump_func)dump_disconnect_named_pipe_request, (dump_func)dump_get_named_pipe_info_request, (dump_func)dump_create_window_request, - (dump_func)dump_link_window_request, (dump_func)dump_destroy_window_request, (dump_func)dump_set_window_owner_request, (dump_func)dump_get_window_info_request, (dump_func)dump_set_window_info_request, + (dump_func)dump_set_parent_request, (dump_func)dump_get_window_parents_request, (dump_func)dump_get_window_children_request, (dump_func)dump_get_window_children_from_point_request, @@ -3022,11 +3022,11 @@ (dump_func)dump_disconnect_named_pipe_reply, (dump_func)dump_get_named_pipe_info_reply, (dump_func)dump_create_window_reply, - (dump_func)dump_link_window_reply, (dump_func)0, (dump_func)dump_set_window_owner_reply, (dump_func)dump_get_window_info_reply, (dump_func)dump_set_window_info_reply, + (dump_func)dump_set_parent_reply, (dump_func)dump_get_window_parents_reply, (dump_func)dump_get_window_children_reply, (dump_func)dump_get_window_children_from_point_reply, @@ -3210,11 +3210,11 @@ "disconnect_named_pipe", "get_named_pipe_info", "create_window", - "link_window", "destroy_window", "set_window_owner", "get_window_info", "set_window_info", + "set_parent", "get_window_parents", "get_window_children", "get_window_children_from_point",
diff --git a/server/window.c b/server/window.c index ae46dc9..ff8c339 100644 --- a/server/window.c +++ b/server/window.c
@@ -111,21 +111,37 @@ return ret; } -/* link a window into the tree (or unlink it if the new parent is NULL) */ -static void link_window( struct window *win, struct window *parent, struct window *previous ) +/* change the parent of a window (or unlink the window if the new parent is NULL) */ +static int set_parent_window( struct window *win, struct window *parent ) { + struct window *ptr; + + /* make sure parent is not a child of window */ + for (ptr = parent; ptr; ptr = ptr->parent) + { + if (ptr == win) + { + set_error( STATUS_INVALID_PARAMETER ); + return 0; + } + } + list_remove( &win->entry ); /* unlink it from the previous location */ if (parent) { win->parent = parent; - if (previous) list_add_after( &previous->entry, &win->entry ); - else list_add_head( &parent->children, &win->entry ); + list_add_head( &parent->children, &win->entry ); + + /* if parent belongs to a different thread, attach the two threads */ + if (parent->thread && parent->thread != win->thread) + attach_thread_input( win->thread, parent->thread ); } else /* move it to parent unlinked list */ { list_add_head( &win->parent->unlinked, &win->entry ); } + return 1; } /* get next window in Z-order list */ @@ -1094,7 +1110,12 @@ win->window_rect = *window_rect; win->visible_rect = *visible_rect; win->client_rect = *client_rect; - if (!(swp_flags & SWP_NOZORDER)) link_window( win, win->parent, previous ); + if (!(swp_flags & SWP_NOZORDER) && win->parent) + { + list_remove( &win->entry ); /* unlink it from the previous location */ + if (previous) list_add_after( &previous->entry, &win->entry ); + else list_add_head( &win->parent->children, &win->entry ); + } if (swp_flags & SWP_SHOWWINDOW) win->style |= WS_VISIBLE; else if (swp_flags & SWP_HIDEWINDOW) win->style &= ~WS_VISIBLE; @@ -1198,10 +1219,10 @@ } -/* link a window into the tree */ -DECL_HANDLER(link_window) +/* set the parent of a window */ +DECL_HANDLER(set_parent) { - struct window *win, *parent = NULL, *previous = NULL; + struct window *win, *parent = NULL; if (!(win = get_window( req->handle ))) return; if (req->parent && !(parent = get_window( req->parent ))) return; @@ -1211,26 +1232,9 @@ set_error( STATUS_INVALID_PARAMETER ); return; } + reply->old_parent = win->parent->handle; reply->full_parent = parent ? parent->handle : 0; - if (parent && req->previous) - { - if (req->previous == (user_handle_t)1) /* special case: HWND_BOTTOM */ - { - previous = get_last_child( parent ); - if (previous == win) return; /* nothing to do */ - } - else - { - if (!(previous = get_window( req->previous ))) return; - /* previous must be a child of parent, and not win itself */ - if (previous->parent != parent || previous == win) - { - set_error( STATUS_INVALID_PARAMETER ); - return; - } - } - } - link_window( win, parent, previous ); + set_parent_window( win, parent ); }
diff --git a/windows/win.c b/windows/win.c index 0405749..f3a2dca 100644 --- a/windows/win.c +++ b/windows/win.c
@@ -395,52 +395,6 @@ /*********************************************************************** - * WIN_UnlinkWindow - * - * Remove a window from the siblings linked list. - */ -void WIN_UnlinkWindow( HWND hwnd ) -{ - WIN_LinkWindow( hwnd, 0, 0 ); -} - - -/*********************************************************************** - * WIN_LinkWindow - * - * Insert a window into the siblings linked list. - * The window is inserted after the specified window, which can also - * be specified as HWND_TOP or HWND_BOTTOM. - * If parent is 0, window is unlinked from the tree. - */ -void WIN_LinkWindow( HWND hwnd, HWND parent, HWND hwndInsertAfter ) -{ - WND *wndPtr = WIN_GetPtr( hwnd ); - - if (!wndPtr || wndPtr == WND_DESKTOP) return; - if (wndPtr == WND_OTHER_PROCESS) - { - if (IsWindow(hwnd)) ERR(" cannot link other process window %p\n", hwnd ); - return; - } - - SERVER_START_REQ( link_window ) - { - req->handle = hwnd; - req->parent = parent; - req->previous = hwndInsertAfter; - if (!wine_server_call( req )) - { - if (reply->full_parent) wndPtr->parent = reply->full_parent; - } - - } - SERVER_END_REQ; - WIN_ReleasePtr( wndPtr ); -} - - -/*********************************************************************** * WIN_SetOwner * * Change the owner of a window. @@ -584,12 +538,6 @@ TRACE("%p\n", hwnd ); - if (!(hwnd = WIN_IsCurrentThread( hwnd ))) - { - ERR( "window doesn't belong to current thread\n" ); - return 0; - } - /* free child windows */ if ((list = WIN_ListChildren( hwnd ))) { @@ -603,7 +551,13 @@ } /* Unlink now so we won't bother with the children later on */ - WIN_UnlinkWindow( hwnd ); + SERVER_START_REQ( set_parent ) + { + req->handle = hwnd; + req->parent = 0; + wine_server_call( req ); + } + SERVER_END_REQ; /* * Send the WM_NCDESTROY to the window being destroyed. @@ -2556,9 +2510,7 @@ */ HWND WINAPI SetParent( HWND hwnd, HWND parent ) { - WND *wndPtr; - HWND retvalue, full_handle; - BOOL was_visible; + HWND full_handle; if (is_broadcast(hwnd) || is_broadcast(parent)) { @@ -2585,43 +2537,10 @@ if (!(full_handle = WIN_IsCurrentThread( hwnd ))) return (HWND)SendMessageW( hwnd, WM_WINE_SETPARENT, (WPARAM)parent, 0 ); - hwnd = full_handle; - if (USER_Driver.pSetParent) - return USER_Driver.pSetParent( hwnd, parent ); + return USER_Driver.pSetParent( full_handle, parent ); - /* Windows hides the window first, then shows it again - * including the WM_SHOWWINDOW messages and all */ - was_visible = ShowWindow( hwnd, SW_HIDE ); - - if (!IsWindow( parent )) return 0; - if (!(wndPtr = WIN_GetPtr(hwnd)) || wndPtr == WND_OTHER_PROCESS || wndPtr == WND_DESKTOP) return 0; - - retvalue = wndPtr->parent; /* old parent */ - if (parent != retvalue) - { - WIN_LinkWindow( hwnd, parent, HWND_TOP ); - - if (parent != GetDesktopWindow()) /* a child window */ - { - if (!(wndPtr->dwStyle & WS_CHILD)) - { - HMENU menu = (HMENU)SetWindowLongPtrW( hwnd, GWLP_ID, 0 ); - if (menu) DestroyMenu( menu ); - } - } - } - WIN_ReleasePtr( wndPtr ); - - /* SetParent additionally needs to make hwnd the topmost window - in the x-order and send the expected WM_WINDOWPOSCHANGING and - WM_WINDOWPOSCHANGED notification messages. - */ - SetWindowPos( hwnd, HWND_TOPMOST, 0, 0, 0, 0, - SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE | (was_visible ? SWP_SHOWWINDOW : 0) ); - /* FIXME: a WM_MOVE is also generated (in the DefWindowProc handler - * for WM_WINDOWPOSCHANGED) in Windows, should probably remove SWP_NOMOVE */ - return retvalue; + return 0; }