removed poll/sleep code to improve performance.
This commit is contained in:
parent
869617a34a
commit
a541ebc557
|
@ -1,8 +1,8 @@
|
|||
#include "CXWindowsClipboard.h"
|
||||
#include "CXWindowsUtil.h"
|
||||
#include "CLog.h"
|
||||
#include "CStopwatch.h"
|
||||
#include "CThread.h"
|
||||
#include "TMethodJob.h"
|
||||
#include <stdio.h>
|
||||
#include <X11/Xatom.h>
|
||||
|
||||
|
@ -1099,6 +1099,9 @@ bool CXWindowsClipboard::CICCCMGetClipboard::readClipboard(
|
|||
*m_actualTarget = None;
|
||||
*m_data = "";
|
||||
|
||||
// get timeout atom
|
||||
m_timeout = XInternAtom(display, "SYNERGY_TIMEOUT", False);
|
||||
|
||||
// delete target property
|
||||
XDeleteProperty(display, m_requestor, m_property);
|
||||
|
||||
|
@ -1112,26 +1115,21 @@ bool CXWindowsClipboard::CICCCMGetClipboard::readClipboard(
|
|||
XConvertSelection(display, selection, target,
|
||||
m_property, m_requestor, m_time);
|
||||
|
||||
// process selection events. use a timeout so we don't get
|
||||
// screwed by a bad selection owner.
|
||||
CStopwatch timer(true);
|
||||
// process selection events. have a separate thread send us an
|
||||
// event after a timeout so we don't get locked up by badly
|
||||
// behaved selection owners.
|
||||
CThread timer(new TMethodJob<CXWindowsClipboard::CICCCMGetClipboard>(
|
||||
this,
|
||||
&CXWindowsClipboard::CICCCMGetClipboard::timeout,
|
||||
display));
|
||||
XEvent xevent;
|
||||
while (!m_done && !m_failed) {
|
||||
// return false if we've timed-out
|
||||
if (timer.getTime() >= 0.2) {
|
||||
log((CLOG_DEBUG1 "request timed out"));
|
||||
XSelectInput(display, m_requestor, attr.your_event_mask);
|
||||
return false;
|
||||
}
|
||||
|
||||
// process events
|
||||
if (!XCheckIfEvent(display, &xevent,
|
||||
XIfEvent(display, &xevent,
|
||||
&CXWindowsClipboard::CICCCMGetClipboard::eventPredicate,
|
||||
reinterpret_cast<XPointer>(this))) {
|
||||
// wait a bit to avoid spinning
|
||||
CThread::sleep(0.05);
|
||||
}
|
||||
reinterpret_cast<XPointer>(this));
|
||||
}
|
||||
timer.cancel();
|
||||
|
||||
// restore mask
|
||||
XSelectInput(display, m_requestor, attr.your_event_mask);
|
||||
|
@ -1188,6 +1186,16 @@ bool CXWindowsClipboard::CICCCMGetClipboard::doEventPredicate(
|
|||
// otherwise not interested
|
||||
return false;
|
||||
|
||||
case ClientMessage:
|
||||
// done if this is the timeout message
|
||||
if (xevent->xclient.window == m_requestor &&
|
||||
xevent->xclient.message_type == m_timeout) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// otherwise not interested
|
||||
return false;
|
||||
|
||||
default:
|
||||
// not interested
|
||||
return false;
|
||||
|
@ -1200,7 +1208,7 @@ bool CXWindowsClipboard::CICCCMGetClipboard::doEventPredicate(
|
|||
m_property, m_data, &target, NULL, True)) {
|
||||
// unable to read property
|
||||
m_failed = true;
|
||||
return True;
|
||||
return true;
|
||||
}
|
||||
|
||||
// note if incremental. if we're already incremental then the
|
||||
|
@ -1276,6 +1284,24 @@ Bool CXWindowsClipboard::CICCCMGetClipboard::eventPredicate(
|
|||
return self->doEventPredicate(display, xevent) ? True : False;
|
||||
}
|
||||
|
||||
void CXWindowsClipboard::CICCCMGetClipboard::timeout(
|
||||
void* vdisplay)
|
||||
{
|
||||
// wait
|
||||
CThread::sleep(0.2); // FIXME -- is this too short?
|
||||
|
||||
// send wake up
|
||||
Display* display = reinterpret_cast<Display*>(vdisplay);
|
||||
XEvent event;
|
||||
event.xclient.type = ClientMessage;
|
||||
event.xclient.display = display;
|
||||
event.xclient.window = m_requestor;
|
||||
event.xclient.message_type = m_timeout;
|
||||
event.xclient.format = 8;
|
||||
CXWindowsUtil::CErrorLock lock;
|
||||
XSendEvent(display, m_requestor, False, 0, &event);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// CXWindowsClipboard::CReply
|
||||
|
|
|
@ -106,6 +106,7 @@ private:
|
|||
static Bool eventPredicate(Display* display,
|
||||
XEvent* event,
|
||||
XPointer arg);
|
||||
void timeout(void*);
|
||||
|
||||
private:
|
||||
Window m_requestor;
|
||||
|
@ -125,6 +126,9 @@ private:
|
|||
// selection owner cannot convert to the requested type.
|
||||
Atom* m_actualTarget;
|
||||
|
||||
// property used in event to wake up event loop
|
||||
Atom m_timeout;
|
||||
|
||||
public:
|
||||
// true iff the selection owner didn't follow ICCCM conventions
|
||||
bool m_error;
|
||||
|
|
|
@ -150,12 +150,8 @@ Time CXWindowsUtil::getCurrentTime(
|
|||
|
||||
// wait for reply
|
||||
XEvent xevent;
|
||||
while (XCheckIfEvent(display, &xevent,
|
||||
&CXWindowsUtil::propertyNotifyPredicate,
|
||||
(XPointer)&filter) != True) {
|
||||
// wait a bit
|
||||
CThread::sleep(0.05);
|
||||
}
|
||||
XIfEvent(display, &xevent, &CXWindowsUtil::propertyNotifyPredicate,
|
||||
(XPointer)&filter);
|
||||
assert(xevent.type == PropertyNotify);
|
||||
assert(xevent.xproperty.window == window);
|
||||
assert(xevent.xproperty.atom == atom);
|
||||
|
|
Loading…
Reference in New Issue