Reimplemented Get/SetActiveWindow, Get/SetFocus and
Get/SetForegroundWindow by storing the information in the
server. Implemented correct inter-process window activation.
diff --git a/server/queue.c b/server/queue.c
index 5a08668..5d51e62 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -621,6 +621,25 @@
if (window == input->caret) input->caret = 0;
}
+/* check if the specified window can be set in the input data of a given queue */
+static int check_queue_input_window( struct msg_queue *queue, user_handle_t window )
+{
+ struct thread *thread;
+ int ret = 0;
+
+ if (!window) return 1; /* we can always clear the data */
+
+ if ((thread = get_window_thread( window )))
+ {
+ ret = (queue->input == thread->queue->input);
+ if (!ret) set_error( STATUS_ACCESS_DENIED );
+ release_object( thread );
+ }
+ else set_error( STATUS_INVALID_HANDLE );
+
+ return ret;
+}
+
/* attach two thread input data structures */
int attach_thread_input( struct thread *thread_from, struct thread *thread_to )
{
@@ -1292,3 +1311,61 @@
reply->foreground = foreground_input ? foreground_input->active : 0;
if (thread) release_object( thread );
}
+
+
+/* set the system foreground window */
+DECL_HANDLER(set_foreground_window)
+{
+ struct msg_queue *queue = get_current_queue();
+
+ reply->previous = foreground_input ? foreground_input->active : 0;
+ reply->send_msg_old = (reply->previous && foreground_input != queue->input);
+ reply->send_msg_new = FALSE;
+
+ if (req->handle)
+ {
+ struct thread *thread;
+
+ if (is_top_level_window( req->handle ) &&
+ ((thread = get_window_thread( req->handle ))))
+ {
+ foreground_input = thread->queue->input;
+ reply->send_msg_new = (foreground_input != queue->input);
+ release_object( thread );
+ }
+ else set_error( STATUS_INVALID_HANDLE );
+ }
+ else foreground_input = NULL;
+}
+
+
+/* set the current thread focus window */
+DECL_HANDLER(set_focus_window)
+{
+ struct msg_queue *queue = get_current_queue();
+
+ reply->previous = 0;
+ if (queue && check_queue_input_window( queue, req->handle ))
+ {
+ reply->previous = queue->input->focus;
+ queue->input->focus = get_user_full_handle( req->handle );
+ }
+}
+
+
+/* set the current thread active window */
+DECL_HANDLER(set_active_window)
+{
+ struct msg_queue *queue = get_current_queue();
+
+ reply->previous = 0;
+ if (queue && check_queue_input_window( queue, req->handle ))
+ {
+ if (!req->handle || make_window_active( req->handle ))
+ {
+ reply->previous = queue->input->active;
+ queue->input->active = get_user_full_handle( req->handle );
+ }
+ else set_error( STATUS_INVALID_HANDLE );
+ }
+}