Keep timestamp of last syncRequest and update with xTime on each sync

The sync protocol with e.g. Qt 4 windows is broken if our app time is
older than the one of the last sync alarm event. Thus we keep a timestamp
in the syncRequest struct of the last sent sync request. If the timestamp
is newer than our xTime when sending the next request, we update the
xTime to ensure that we have a new timestamp again.

BUG: 333512
REVIEW: 117734
This commit is contained in:
Martin Gräßlin 2014-04-24 11:00:48 +02:00
parent f44575ddbf
commit 7d302b9039
2 changed files with 7 additions and 0 deletions

View file

@ -236,6 +236,7 @@ Client::Client()
// TODO: Do all as initialization // TODO: Do all as initialization
syncRequest.counter = syncRequest.alarm = XCB_NONE; syncRequest.counter = syncRequest.alarm = XCB_NONE;
syncRequest.timeout = syncRequest.failsafeTimeout = NULL; syncRequest.timeout = syncRequest.failsafeTimeout = NULL;
syncRequest.lastTimestamp = xTime();
syncRequest.isPending = false; syncRequest.isPending = false;
// Set the initial mapping state // Set the initial mapping state
@ -2220,6 +2221,7 @@ void Client::sendSyncRequest()
syncRequest.counter = syncRequest.alarm = XCB_NONE; syncRequest.counter = syncRequest.alarm = XCB_NONE;
delete syncRequest.timeout; delete syncRequest.failsafeTimeout; delete syncRequest.timeout; delete syncRequest.failsafeTimeout;
syncRequest.timeout = syncRequest.failsafeTimeout = nullptr; syncRequest.timeout = syncRequest.failsafeTimeout = nullptr;
syncRequest.lastTimestamp = XCB_CURRENT_TIME;
} }
); );
syncRequest.failsafeTimeout->setSingleShot(true); syncRequest.failsafeTimeout->setSingleShot(true);
@ -2236,6 +2238,9 @@ void Client::sendSyncRequest()
if (oldLo > syncRequest.value.lo) { if (oldLo > syncRequest.value.lo) {
syncRequest.value.hi++; syncRequest.value.hi++;
} }
if (syncRequest.lastTimestamp >= xTime()) {
updateXTime();
}
// Send the message to client // Send the message to client
XEvent ev; XEvent ev;
@ -2249,6 +2254,7 @@ void Client::sendSyncRequest()
ev.xclient.data.l[3] = syncRequest.value.hi; ev.xclient.data.l[3] = syncRequest.value.hi;
ev.xclient.data.l[4] = 0; ev.xclient.data.l[4] = 0;
syncRequest.isPending = true; syncRequest.isPending = true;
syncRequest.lastTimestamp = xTime();
XSendEvent(display(), window(), False, NoEventMask, &ev); XSendEvent(display(), window(), False, NoEventMask, &ev);
Xcb::sync(); Xcb::sync();
} }

View file

@ -978,6 +978,7 @@ private:
xcb_sync_counter_t counter; xcb_sync_counter_t counter;
xcb_sync_int64_t value; xcb_sync_int64_t value;
xcb_sync_alarm_t alarm; xcb_sync_alarm_t alarm;
xcb_timestamp_t lastTimestamp;
QTimer *timeout, *failsafeTimeout; QTimer *timeout, *failsafeTimeout;
bool isPending; bool isPending;
} syncRequest; } syncRequest;