speeded up clipboard transfer by avoiding a selection request

when it wasn't necessary.  (in particular, we were getting the
clipboard update time from the owner then emptying the clipboard,
so we didn't need to get the time.  worse, most owners don't
support getting the time and we often timed out.)

also fixed a multithread bug using the X display.  we were using
a CThread to send an event after a timeout while we were waiting
in XIfEvent().  this necessarily involved two threads calling
into Xlib at once, which is not allowed.  now using polling to
do the timeout because Xlib doesn't have a function to get
events with a timeout.
This commit is contained in:
crs 2002-06-20 14:01:44 +00:00
parent 3d27de39bb
commit 2423dc662d
1 changed files with 10 additions and 5 deletions

View File

@ -288,7 +288,6 @@ CXWindowsClipboard::open(Time time) const
// be sure to flush the cache later if it's dirty // be sure to flush the cache later if it's dirty
m_checkCache = true; m_checkCache = true;
checkCache();
return true; return true;
} }
@ -1161,6 +1160,9 @@ CXWindowsClipboard::CICCCMGetClipboard::readClipboard(Display* display,
XConvertSelection(display, selection, target, XConvertSelection(display, selection, target,
m_property, m_requestor, m_time); m_property, m_requestor, m_time);
// synchronize with server before we start following timeout countdown
XSync(display, False);
// Xlib inexplicably omits the ability to wait for an event with // Xlib inexplicably omits the ability to wait for an event with
// a timeout. (it's inexplicable because there's no portable way // a timeout. (it's inexplicable because there's no portable way
// to do it.) we'll poll until we have what we're looking for or // to do it.) we'll poll until we have what we're looking for or
@ -1169,10 +1171,10 @@ CXWindowsClipboard::CICCCMGetClipboard::readClipboard(Display* display,
XEvent xevent; XEvent xevent;
SInt32 lastPending = 0; SInt32 lastPending = 0;
CStopwatch timeout(true); CStopwatch timeout(true);
static const double s_timeout = 0.2; // FIXME -- is this too short? static const double s_timeout = 0.25; // FIXME -- is this too short?
while (!m_done && !m_failed) { while (!m_done && !m_failed) {
// fail if timeout has expired // fail if timeout has expired
if (timeout.getTime() < s_timeout) { if (timeout.getTime() >= s_timeout) {
m_failed = true; m_failed = true;
break; break;
} }
@ -1183,9 +1185,12 @@ CXWindowsClipboard::CICCCMGetClipboard::readClipboard(Display* display,
// process events if there are more otherwise sleep // process events if there are more otherwise sleep
if (pending > lastPending) { if (pending > lastPending) {
lastPending = pending; lastPending = pending;
XCheckIfEvent(display, &xevent, while (!m_done && !m_failed &&
XCheckIfEvent(display, &xevent,
&CXWindowsClipboard::CICCCMGetClipboard::eventPredicate, &CXWindowsClipboard::CICCCMGetClipboard::eventPredicate,
reinterpret_cast<XPointer>(this)); reinterpret_cast<XPointer>(this))) {
lastPending = XPending(display);
}
} }
else { else {
CThread::sleep(0.01); CThread::sleep(0.01);