summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJon TURNEY <jon.turney@dronecode.org.uk>2013-11-21 15:18:48 +0000
committerJon TURNEY <jon.turney@dronecode.org.uk>2013-12-09 17:02:57 +0000
commit39415d1e767e724936c630f04b91b4e8d2615aa7 (patch)
tree30d10cd00c40c8604336f1c2fdd399ff6017f2b0
parentf1e68c2c6a18c251be02cc0ecbabb265c7610b55 (diff)
Improve reliability of clipboard X->Windows pastes
Sometimes, particularly with large clipboard pastes to Windows, we could end up waiting for the timeout to expire, rather than pasting the data. Various changes to improve reliability: 1. Use XFlush() not XSync() in winProcessXEventsTimeout(). It makes no sense to ensure we have received replies to outstanding requests if we are going to wait for them using select() 2. Add XFlush() to winClipboardProc() Make sure we have sent any requests before we wait using select() 3. Don't use FD_ISSET() to check which fd is ready This looks like a select() bug in that it sometimes returns 0 with an empty fd set before the timeout expires, but a fd appears to be ready. Add select() return value to debug output when we are warning that this has happened. 4. Drain event queues before entering select() Unconditionally drain event queues before entering select(). This is the recommended way of writing select() and X event processing loops. winClipboardFlushXEvents() checks using XPending(), and winClipboardFlushWindowsMessageQueue() checks using PeekMessage() so this is safe against blocking, but means that may not need to enter select() at all sometimes.
-rw-r--r--hw/xwin/winclipboard/thread.c45
-rw-r--r--hw/xwin/winclipboard/wndproc.c34
2 files changed, 31 insertions, 48 deletions
diff --git a/hw/xwin/winclipboard/thread.c b/hw/xwin/winclipboard/thread.c
index 2b9a6f34f..1653747ea 100644
--- a/hw/xwin/winclipboard/thread.c
+++ b/hw/xwin/winclipboard/thread.c
@@ -244,24 +244,26 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
}
}
- /* Pre-flush X events */
- /*
- * NOTE: Apparently you'll freeze if you don't do this,
- * because there may be events in local data structures
- * already.
- */
ClipboardConversionData data;
data.fUseUnicode = fUseUnicode;
- winClipboardFlushXEvents(hwnd, iWindow, pDisplay, &data, &atoms);
-
- /* Pre-flush Windows messages */
- if (!winClipboardFlushWindowsMessageQueue(hwnd)) {
- ErrorF("winClipboardProc - winClipboardFlushWindowsMessageQueue failed\n");
- pthread_exit(NULL);
- }
- /* Loop for X events */
+ /* Loop for events */
while (1) {
+
+ /* Process X events */
+ winClipboardFlushXEvents(hwnd,
+ iWindow, pDisplay, &data, &atoms);
+
+ /* Process Windows messages */
+ if (!winClipboardFlushWindowsMessageQueue(hwnd)) {
+ ErrorF("winClipboardProc - winClipboardFlushWindowsMessageQueue trapped "
+ "WM_QUIT message, exiting main loop.\n");
+ break;
+ }
+
+ /* We need to ensure that all pending requests are sent */
+ XFlush(pDisplay);
+
/* Setup the file descriptor set */
/*
* NOTE: You have to do this before every call to select
@@ -312,14 +314,9 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
winDebug("winClipboardProc - select returned %d\n", iReturn);
- /* Branch on which descriptor became active */
if (FD_ISSET(iConnectionNumber, &fdsRead)) {
winDebug
("winClipboardProc - X connection ready, pumping X event queue\n");
-
- /* Process X events */
- winClipboardFlushXEvents(hwnd,
- iWindow, pDisplay, &data, &atoms);
}
#ifdef HAS_DEVWINDOWS
@@ -331,20 +328,12 @@ winClipboardProc(Bool fUseUnicode, char *szDisplay)
{
winDebug
("winClipboardProc - /dev/windows ready, pumping Windows message queue\n");
-
- /* Process Windows messages */
- if (!winClipboardFlushWindowsMessageQueue(hwnd)) {
- ErrorF("winClipboardProc - "
- "winClipboardFlushWindowsMessageQueue trapped "
- "WM_QUIT message, exiting main loop.\n");
- break;
- }
}
#ifdef HAS_DEVWINDOWS
if (!(FD_ISSET(iConnectionNumber, &fdsRead)) &&
!(FD_ISSET(fdMessageQueue, &fdsRead))) {
- winDebug("winClipboardProc - Spurious wake\n");
+ winDebug("winClipboardProc - Spurious wake, select() returned %d\n", iReturn);
}
#endif
}
diff --git a/hw/xwin/winclipboard/wndproc.c b/hw/xwin/winclipboard/wndproc.c
index 83f11417d..b5566fa5a 100644
--- a/hw/xwin/winclipboard/wndproc.c
+++ b/hw/xwin/winclipboard/wndproc.c
@@ -83,8 +83,18 @@ winProcessXEventsTimeout(HWND hwnd, Window iWindow, Display * pDisplay,
fd_set fdsRead;
long remainingTime;
- /* We need to ensure that all pending events are processed */
- XSync(pDisplay, FALSE);
+ /* Process X events */
+ iReturn = winClipboardFlushXEvents(hwnd, iWindow, pDisplay, data, atoms);
+
+ winDebug("winProcessXEventsTimeout () - winClipboardFlushXEvents returned %d\n", iReturn);
+
+ if ((WIN_XEVENTS_NOTIFY_DATA == iReturn) || (WIN_XEVENTS_NOTIFY_TARGETS == iReturn) || (WIN_XEVENTS_FAILED == iReturn)) {
+ /* Bail out */
+ return iReturn;
+ }
+
+ /* We need to ensure that all pending requests are sent */
+ XFlush(pDisplay);
/* Setup the file descriptor set */
FD_ZERO(&fdsRead);
@@ -113,24 +123,8 @@ winProcessXEventsTimeout(HWND hwnd, Window iWindow, Display * pDisplay,
break;
}
- /* Branch on which descriptor became active */
- if (FD_ISSET(iConnNumber, &fdsRead)) {
- /* Process X events */
- /* Exit when we see that server is shutting down */
- iReturn = winClipboardFlushXEvents(hwnd,
- iWindow, pDisplay, data, atoms);
-
- winDebug
- ("winProcessXEventsTimeout () - winClipboardFlushXEvents returned %d\n",
- iReturn);
-
- if ((WIN_XEVENTS_NOTIFY_DATA == iReturn) || (WIN_XEVENTS_NOTIFY_TARGETS == iReturn) || (WIN_XEVENTS_FAILED == iReturn)) {
- /* Bail out */
- return iReturn;
- }
- }
- else {
- winDebug("winProcessXEventsTimeout - Spurious wake\n");
+ if (!FD_ISSET(iConnNumber, &fdsRead)) {
+ winDebug("winProcessXEventsTimeout - Spurious wake, select() returned %d\n", iReturn);
}
}