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