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/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 );
}