mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-01 18:58:29 +00:00
server: Keep a list of threads connected to each desktop.
This commit is contained in:
parent
496eed7aaf
commit
f7303cf7b6
|
@ -51,6 +51,7 @@ struct thread
|
||||||
struct object obj; /* object header */
|
struct object obj; /* object header */
|
||||||
struct list entry; /* entry in system-wide thread list */
|
struct list entry; /* entry in system-wide thread list */
|
||||||
struct list proc_entry; /* entry in per-process thread list */
|
struct list proc_entry; /* entry in per-process thread list */
|
||||||
|
struct list desktop_entry; /* entry in per-desktop thread list */
|
||||||
struct process *process;
|
struct process *process;
|
||||||
thread_id_t id; /* thread id */
|
thread_id_t id; /* thread id */
|
||||||
struct list mutex_list; /* list of currently owned mutexes */
|
struct list mutex_list; /* list of currently owned mutexes */
|
||||||
|
|
|
@ -70,6 +70,7 @@ struct desktop
|
||||||
struct winstation *winstation; /* winstation this desktop belongs to */
|
struct winstation *winstation; /* winstation this desktop belongs to */
|
||||||
timeout_t input_time; /* last time this desktop had the input */
|
timeout_t input_time; /* last time this desktop had the input */
|
||||||
struct list entry; /* entry in winstation list of desktops */
|
struct list entry; /* entry in winstation list of desktops */
|
||||||
|
struct list threads; /* list of threads connected to this desktop */
|
||||||
struct window *top_window; /* desktop window for this desktop */
|
struct window *top_window; /* desktop window for this desktop */
|
||||||
struct window *msg_window; /* HWND_MESSAGE top window */
|
struct window *msg_window; /* HWND_MESSAGE top window */
|
||||||
struct hook_table *global_hooks; /* table of global hooks on this desktop */
|
struct hook_table *global_hooks; /* table of global hooks on this desktop */
|
||||||
|
|
|
@ -273,6 +273,7 @@ static struct desktop *create_desktop( const struct unicode_str *name, unsigned
|
||||||
desktop->close_timeout = NULL;
|
desktop->close_timeout = NULL;
|
||||||
desktop->foreground_input = NULL;
|
desktop->foreground_input = NULL;
|
||||||
desktop->users = 0;
|
desktop->users = 0;
|
||||||
|
list_init( &desktop->threads );
|
||||||
memset( &desktop->cursor, 0, sizeof(desktop->cursor) );
|
memset( &desktop->cursor, 0, sizeof(desktop->cursor) );
|
||||||
memset( desktop->keystate, 0, sizeof(desktop->keystate) );
|
memset( desktop->keystate, 0, sizeof(desktop->keystate) );
|
||||||
list_add_tail( &winstation->desktops, &desktop->entry );
|
list_add_tail( &winstation->desktops, &desktop->entry );
|
||||||
|
@ -362,26 +363,37 @@ static void close_desktop_timeout( void *private )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add a user of the desktop and cancel the close timeout */
|
/* add a user of the desktop and cancel the close timeout */
|
||||||
static void add_desktop_user( struct desktop *desktop )
|
static void add_desktop_thread( struct desktop *desktop, struct thread *thread )
|
||||||
{
|
{
|
||||||
desktop->users++;
|
list_add_tail( &desktop->threads, &thread->desktop_entry );
|
||||||
if (desktop->close_timeout)
|
|
||||||
|
if (!thread->process->is_system)
|
||||||
{
|
{
|
||||||
remove_timeout_user( desktop->close_timeout );
|
desktop->users++;
|
||||||
desktop->close_timeout = NULL;
|
if (desktop->close_timeout)
|
||||||
|
{
|
||||||
|
remove_timeout_user( desktop->close_timeout );
|
||||||
|
desktop->close_timeout = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* remove a user of the desktop and start the close timeout if necessary */
|
/* remove a user of the desktop and start the close timeout if necessary */
|
||||||
static void remove_desktop_user( struct desktop *desktop )
|
static void remove_desktop_thread( struct desktop *desktop, struct thread *thread )
|
||||||
{
|
{
|
||||||
struct process *process;
|
struct process *process;
|
||||||
assert( desktop->users > 0 );
|
|
||||||
desktop->users--;
|
|
||||||
|
|
||||||
/* if we have one remaining user, it has to be the manager of the desktop window */
|
list_remove( &thread->desktop_entry );
|
||||||
if ((process = get_top_window_owner( desktop )) && desktop->users == process->running_threads && !desktop->close_timeout)
|
|
||||||
desktop->close_timeout = add_timeout_user( -TICKS_PER_SEC, close_desktop_timeout, desktop );
|
if (!thread->process->is_system)
|
||||||
|
{
|
||||||
|
assert( desktop->users > 0 );
|
||||||
|
desktop->users--;
|
||||||
|
|
||||||
|
/* if we have one remaining user, it has to be the manager of the desktop window */
|
||||||
|
if ((process = get_top_window_owner( desktop )) && desktop->users == process->running_threads && !desktop->close_timeout)
|
||||||
|
desktop->close_timeout = add_timeout_user( -TICKS_PER_SEC, close_desktop_timeout, desktop );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set the thread default desktop handle */
|
/* set the thread default desktop handle */
|
||||||
|
@ -390,7 +402,7 @@ void set_thread_default_desktop( struct thread *thread, struct desktop *desktop,
|
||||||
if (thread->desktop) return; /* nothing to do */
|
if (thread->desktop) return; /* nothing to do */
|
||||||
|
|
||||||
thread->desktop = handle;
|
thread->desktop = handle;
|
||||||
if (!thread->process->is_system) add_desktop_user( desktop );
|
add_desktop_thread( desktop, thread );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set the process default desktop handle */
|
/* set the process default desktop handle */
|
||||||
|
@ -500,14 +512,11 @@ void release_thread_desktop( struct thread *thread, int close )
|
||||||
|
|
||||||
if (!(handle = thread->desktop)) return;
|
if (!(handle = thread->desktop)) return;
|
||||||
|
|
||||||
if (!thread->process->is_system)
|
if (!(desktop = get_desktop_obj( thread->process, handle, 0 ))) clear_error(); /* ignore errors */
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if (!(desktop = get_desktop_obj( thread->process, handle, 0 ))) clear_error(); /* ignore errors */
|
remove_desktop_thread( desktop, thread );
|
||||||
else
|
release_object( desktop );
|
||||||
{
|
|
||||||
remove_desktop_user( desktop );
|
|
||||||
release_object( desktop );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (close)
|
if (close)
|
||||||
|
@ -730,10 +739,10 @@ DECL_HANDLER(set_thread_desktop)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
current->desktop = req->handle; /* FIXME: should we close the old one? */
|
current->desktop = req->handle; /* FIXME: should we close the old one? */
|
||||||
if (!current->process->is_system && old_desktop != new_desktop)
|
if (old_desktop != new_desktop)
|
||||||
{
|
{
|
||||||
add_desktop_user( new_desktop );
|
if (old_desktop) remove_desktop_thread( old_desktop, current );
|
||||||
if (old_desktop) remove_desktop_user( old_desktop );
|
add_desktop_thread( new_desktop, current );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue