diff options
author | Jon TURNEY <jon.turney@dronecode.org.uk> | 2014-04-28 12:48:15 +0100 |
---|---|---|
committer | Jon TURNEY <jon.turney@dronecode.org.uk> | 2014-05-05 12:31:10 +0100 |
commit | c61a08fa8df8811803dc896970c417da78b721e3 (patch) | |
tree | a88c9e7d0f2f87af47eac8ff817d349f1984f166 | |
parent | a7d1c2be40d5b9f5c51e03292a20f6e20503e335 (diff) |
Fix hang on shutdown when we own the clipboard.
If we are the clipboard owner when we are shutdown, we recieve a
WM_RENDERALLFORMATS. Unfortunately, it's far too late to do anything with this,
as the server is waiting for the clipboard thread to exit, so can't process
requests to convert clipboard contents.
Change so we just do nothing on WM_RENDERALLFORMATS. (I'm not convinced that
WM_RENDERALLFORMATS has ever worked usefully, in any case).
(To make this work, I guess we would need to rearrange the way shutdown works
completely: first synchronously stop the clipboard, then stop the X server)
We also then receive a WM_DRAWCLIPBOARD, perhaps telling us that the available
clipboard formats have changed (as ones which haven't been rendered are now
removed), but the clipboard owner is now the system, not us, which we have to
arrange to ignore.
Also: add dependency of XWin on libXWinclipboard, so it gets relinked when it
changes.
-rw-r--r-- | hw/xwin/Makefile.am | 3 | ||||
-rw-r--r-- | hw/xwin/winclipboard/wndproc.c | 70 |
2 files changed, 27 insertions, 46 deletions
diff --git a/hw/xwin/Makefile.am b/hw/xwin/Makefile.am index df920eb6d..1a97ca2f1 100644 --- a/hw/xwin/Makefile.am +++ b/hw/xwin/Makefile.am @@ -152,7 +152,8 @@ AM_CPPFLAGS = -I$(top_srcdir)/miext/rootless XWIN_SYS_LIBS += -ldxguid XWIN_LIBS += $(top_builddir)/pseudoramiX/libPseudoramiX.la -XWin_DEPENDENCIES = $(MULTIWINDOW_LIBS) $(MULTIWINDOWEXTWM_LIBS) $(XWIN_GLX_LIBS) $(XWIN_LIBS) $(XSERVER_LIBS) +XWin_DEPENDENCIES = $(MULTIWINDOW_LIBS) $(MULTIWINDOWEXTWM_LIBS) $(XWIN_GLX_LIBS) $(XWIN_LIBS) $(XSERVER_LIBS) \ + $(CLIPBOARD_LIBS) XWin_LDADD = $(MULTIWINDOW_LIBS) $(MULTIWINDOWEXTWM_LIBS) $(XWIN_GLX_LIBS) $(XWIN_LIBS) $(XSERVER_LIBS) \ $(CLIPBOARD_LIBS) $(XWIN_GLX_SYS_LIBS) $(XSERVER_SYS_LIBS) $(XWIN_SYS_LIBS) $(MULTIWINDOW_SYS_LIBS) XWin_LDFLAGS = -mwindows -Wl,--disable-stdcall-fixup $(LD_EXPORT_SYMBOLS_FLAG) diff --git a/hw/xwin/winclipboard/wndproc.c b/hw/xwin/winclipboard/wndproc.c index 423dcade3..f0867f91d 100644 --- a/hw/xwin/winclipboard/wndproc.c +++ b/hw/xwin/winclipboard/wndproc.c @@ -143,6 +143,7 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) static Display *pDisplay; static Window iWindow; static ClipboardAtoms *atoms; + static Bool fRunning; /* Branch on message type */ switch (message) { @@ -160,7 +161,7 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) case WM_WM_QUIT: { winDebug("winClipboardWindowProc - WM_WM_QUIT\n"); - + fRunning = FALSE; PostQuitMessage(0); } return 0; @@ -176,6 +177,7 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) pDisplay = cwcp->pClipboardDisplay; iWindow = cwcp->iClipboardWindow; atoms = cwcp->atoms; + fRunning = TRUE; first = GetClipboardViewer(); /* Get handle to first viewer in chain. */ if (first == hwnd) @@ -308,6 +310,10 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) return 0; } + /* Bail when shutting down */ + if (!fRunning) + return 0; + /* * Do not take ownership of the X11 selections when something * other than CF_TEXT or CF_UNICODETEXT has been copied @@ -441,24 +447,31 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) winDebug("winClipboardWindowProc - WM_DESTROYCLIPBOARD - Ignored.\n"); return 0; - case WM_RENDERFORMAT: case WM_RENDERALLFORMATS: + winDebug("winClipboardWindowProc - WM_RENDERALLFORMATS - Hello.\n"); + + /* + WM_RENDERALLFORMATS is sent as we are shutting down, to render the + clipboard so it's contents remains available to other applications. + + Unfortunately, this can't work without major changes. The server is + already waiting for us to stop, so we can't ask for the rendering of + clipboard text now. + */ + + return 0; + + case WM_RENDERFORMAT: { int iReturn; Bool fConvertToUnicode; Bool pasted = FALSE; - if (message == WM_RENDERALLFORMATS) - winDebug("winClipboardWindowProc - WM_RENDERALLFORMATS - Hello.\n"); - else - winDebug("winClipboardWindowProc - WM_RENDERFORMAT %d - Hello.\n", - wParam); + winDebug("winClipboardWindowProc - WM_RENDERFORMAT %d - Hello.\n", + wParam); /* Flag whether to convert to Unicode or not */ - if (message == WM_RENDERALLFORMATS) - fConvertToUnicode = FALSE; - else - fConvertToUnicode = (CF_UNICODETEXT == wParam); + fConvertToUnicode = (CF_UNICODETEXT == wParam); Atom selection = winClipboardGetLastOwnedSelectionAtom(atoms); @@ -543,28 +556,6 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) atoms->atomLocalProperty, iWindow, CurrentTime); - /* Special handling for WM_RENDERALLFORMATS */ - if (message == WM_RENDERALLFORMATS) { - /* We must open and empty the clipboard */ - - /* Close clipboard if we have it open already */ - if (GetOpenClipboardWindow() == hwnd) { - CloseClipboard(); - } - - if (!OpenClipboard(hwnd)) { - ErrorF("winClipboardWindowProc - WM_RENDER*FORMATS - " - "OpenClipboard () failed: %08x\n", - GetLastError()); - } - - if (!EmptyClipboard()) { - ErrorF("winClipboardWindowProc - WM_RENDER*FORMATS - " - "EmptyClipboard () failed: %08x\n", - GetLastError()); - } - } - /* Process X events */ iReturn = winProcessXEventsTimeout(hwnd, iWindow, @@ -598,18 +589,7 @@ winClipboardWindowProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) SetClipboardData(CF_TEXT, NULL); } - /* Special handling for WM_RENDERALLFORMATS */ - if (message == WM_RENDERALLFORMATS) { - /* We must close the clipboard */ - - if (!CloseClipboard()) { - ErrorF("winClipboardWindowProc - WM_RENDERALLFORMATS - " - "CloseClipboard () failed: %08x\n", - GetLastError()); - } - } - - winDebug("winClipboardWindowProc - WM_RENDER*FORMAT - Returning.\n"); + winDebug("winClipboardWindowProc - WM_RENDERFORMAT - Returning.\n"); return 0; } } |