hw/xwin: Fix clipboard thread restart
It seems that the clipboard thread restart mechanism has been broken for a while, which can be demonstrated using XDMCP with KDM (e.g. to a Kubutunu 12.04 host) KDM kills all attached clients, including the clipboard integration client, which restarts, but then exits on WM_QUIT. Using PostQuitMessage() in WM_DESTROY is unhelpful, as we may not actually be quitting the thread, if we just destroyed the window because the clipboard thread is about to retry, because he WM_QUIT message sticks around, and is noticed the next time we look at the window message queue and confuses us into thinking we need to quit. Sending a WM_DESTROY is apparently never correct anyhow, see [1] So: 1/ Use DestroyWindow() to destroy the clipboard messaging window when cleaning up for retry or exit in winClipboardProc (the clipboard thread main proc) 2/ Send a special WM_WM_QUIT message in winClipboardWindowDestroy() from the X server thread when the X server is resetting. 3/ When processing that WM_WM_QUIT message in the clipboard thread, cause the clipboard window to PostQuitMessage(), which causes the clipboard thread to exit. [1] http://blogs.msdn.com/b/oldnewthing/archive/2011/09/26/10216420.aspx Signed-off-by: Jon TURNEY <jon.turney@dronecode.org.uk> Reviewed-by: Colin Harrison <colin.harrison@virgin.net>
This commit is contained in:
parent
b4a08e642b
commit
94d433c8cb
|
@ -44,6 +44,7 @@
|
||||||
#define WIN_XEVENTS_NOTIFY_TARGETS 4
|
#define WIN_XEVENTS_NOTIFY_TARGETS 4
|
||||||
|
|
||||||
#define WM_WM_REINIT (WM_USER + 1)
|
#define WM_WM_REINIT (WM_USER + 1)
|
||||||
|
#define WM_WM_QUIT (WM_USER + 2)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* References to external symbols
|
* References to external symbols
|
||||||
|
|
|
@ -351,7 +351,7 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
|
||||||
winClipboardProc_Done:
|
winClipboardProc_Done:
|
||||||
/* Close our Windows window */
|
/* Close our Windows window */
|
||||||
if (g_hwndClipboard) {
|
if (g_hwndClipboard) {
|
||||||
winClipboardWindowDestroy();
|
DestroyWindow(g_hwndClipboard);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Close our X window */
|
/* Close our X window */
|
||||||
|
@ -491,7 +491,7 @@ void
|
||||||
winClipboardWindowDestroy(void)
|
winClipboardWindowDestroy(void)
|
||||||
{
|
{
|
||||||
if (g_hwndClipboard) {
|
if (g_hwndClipboard) {
|
||||||
SendMessage(g_hwndClipboard, WM_DESTROY, 0, 0);
|
SendMessage(g_hwndClipboard, WM_WM_QUIT, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -154,6 +154,12 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
ChangeClipboardChain(hwnd, s_hwndNextViewer);
|
ChangeClipboardChain(hwnd, s_hwndNextViewer);
|
||||||
|
|
||||||
s_hwndNextViewer = NULL;
|
s_hwndNextViewer = NULL;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case WM_WM_QUIT:
|
||||||
|
{
|
||||||
|
winDebug("winClipboardWindowProc - WM_WM_QUIT\n");
|
||||||
|
|
||||||
PostQuitMessage(0);
|
PostQuitMessage(0);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue