checkpoint. turned off nagle and send buffering. also
added test to skip clipboard conversion if a previous conversion from that owner failed.
This commit is contained in:
parent
59c5e4bf13
commit
f2e83e607d
|
@ -13,7 +13,7 @@ RMR = /bin/rm -rf
|
|||
#
|
||||
# compiler options
|
||||
#
|
||||
GCXXDEFS = -D_XOPEN_SOURCE=600
|
||||
GCXXDEFS = -D_XOPEN_SOURCE=600 -D_SVID_SOURCE
|
||||
GCXXINCS = -I$(DEPTH)/include -I/usr/X11R6/include
|
||||
GCXXOPTS = -Wall -W -fexceptions
|
||||
CXXOPTIMIZER = -g
|
||||
|
|
|
@ -9,6 +9,9 @@
|
|||
# define INCL_WINSOCK_API_TYPEDEFS 0
|
||||
# include <winsock2.h>
|
||||
typedef int ssize_t;
|
||||
# if !defined(SOL_TCP)
|
||||
# define SOL_TCP IPPROTO_TCP
|
||||
# endif
|
||||
#else
|
||||
# define FAR
|
||||
# define PASCAL
|
||||
|
@ -21,6 +24,9 @@ typedef int ssize_t;
|
|||
# include <netdb.h>
|
||||
# include <netinet/in.h>
|
||||
# include <errno.h>
|
||||
# if !defined(TCP_NODELAY) || !defined(SOL_TCP)
|
||||
# include <netinet/tcp.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
// FIXME -- must handle htonl and ilk when defined as macros
|
||||
|
@ -31,6 +37,7 @@ public:
|
|||
typedef SOCKET Socket;
|
||||
typedef struct sockaddr Address;
|
||||
typedef int AddressLength;
|
||||
typedef BOOL TCPNoDelayType;
|
||||
struct PollEntry {
|
||||
Socket fd;
|
||||
short events;
|
||||
|
@ -47,6 +54,7 @@ public:
|
|||
typedef struct sockaddr Address;
|
||||
typedef socklen_t AddressLength;
|
||||
typedef struct pollfd PollEntry;
|
||||
typedef int TCPNoDelayType;
|
||||
enum {
|
||||
kPOLLIN = POLLIN,
|
||||
kPOLLOUT = POLLOUT,
|
||||
|
|
|
@ -128,6 +128,16 @@ void CTCPSocket::init()
|
|||
m_output = new CBufferedOutputStream(m_mutex,
|
||||
new TMethodJob<CTCPSocket>(
|
||||
this, &CTCPSocket::closeOutput));
|
||||
|
||||
// turn off Nagle algorithm. we send lots of very short messages
|
||||
// that should be sent without (much) delay. for example, the
|
||||
// mouse motion messages are much less useful if they're delayed.
|
||||
CNetwork::TCPNoDelayType flag = 1;
|
||||
CNetwork::setsockopt(m_fd, SOL_TCP, TCP_NODELAY, &flag, sizeof(flag));
|
||||
|
||||
// don't buffer sends, we merge messages ourself
|
||||
int data = 0;
|
||||
CNetwork::setsockopt(m_fd, SOL_SOCKET, SO_SNDBUF, &data, sizeof(data));
|
||||
}
|
||||
|
||||
void CTCPSocket::ioThread(void*)
|
||||
|
|
|
@ -261,6 +261,23 @@ void CXWindowsScreen::getDisplayClipboard(
|
|||
CLock lock(&m_mutex);
|
||||
Atom selection = m_atomClipboard[id];
|
||||
|
||||
// if we're trying to request the clipboard from the same
|
||||
// unresponsive owner then immediately give up. this is lame
|
||||
// because we can't be sure the owner won't become responsive;
|
||||
// we can only ask the X server for the current owner, not the
|
||||
// owner at time timestamp, allowing a race condition; and we
|
||||
// don't detect if the owner window is destroyed in order to
|
||||
// reset the unresponsive flag.
|
||||
Window owner = XGetSelectionOwner(m_display, selection);
|
||||
if (m_clipboards[id].m_unresponsive) {
|
||||
if (owner != None && owner == m_clipboards[id].m_owner) {
|
||||
clipboard->close();
|
||||
return;
|
||||
}
|
||||
}
|
||||
CClipboardInfo& clipboardInfo =
|
||||
const_cast<CClipboardInfo&>(m_clipboards[id]);
|
||||
|
||||
// ask the selection for all the formats it has. some owners return
|
||||
// the TARGETS atom and some the ATOM atom when TARGETS is requested.
|
||||
Atom format;
|
||||
|
@ -268,6 +285,10 @@ void CXWindowsScreen::getDisplayClipboard(
|
|||
if (getDisplayClipboard(selection, m_atomTargets,
|
||||
requestor, timestamp, &format, &targets) &&
|
||||
(format == m_atomTargets || format == XA_ATOM)) {
|
||||
// save owner info
|
||||
clipboardInfo.m_owner = owner;
|
||||
clipboardInfo.m_unresponsive = false;
|
||||
|
||||
// get each target (that we can interpret). some owners return
|
||||
// some targets multiple times in the list so don't try to get
|
||||
// those multiple times.
|
||||
|
@ -330,6 +351,11 @@ void CXWindowsScreen::getDisplayClipboard(
|
|||
else {
|
||||
// non-ICCCM conforming selection owner. try TEXT format.
|
||||
// FIXME
|
||||
|
||||
// save owner info
|
||||
clipboardInfo.m_owner = owner;
|
||||
clipboardInfo.m_unresponsive = true;
|
||||
|
||||
log((CLOG_DEBUG1 "selection doesn't support TARGETS, format is %d", format));
|
||||
}
|
||||
|
||||
|
@ -1014,7 +1040,9 @@ Time CXWindowsScreen::getCurrentTimeNoLock(
|
|||
CXWindowsScreen::CClipboardInfo::CClipboardInfo() :
|
||||
m_clipboard(),
|
||||
m_lostClipboard(CurrentTime),
|
||||
m_requests()
|
||||
m_requests(),
|
||||
m_owner(None),
|
||||
m_unresponsive(false)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
|
|
@ -161,6 +161,12 @@ private:
|
|||
|
||||
// the request queues
|
||||
CRequestMap m_requests;
|
||||
|
||||
// owner of clipboard when we last asked for it
|
||||
Window m_owner;
|
||||
|
||||
// true iff the previous request to m_owner got no reply
|
||||
bool m_unresponsive;
|
||||
};
|
||||
|
||||
Display* m_display;
|
||||
|
|
Loading…
Reference in New Issue