Let QXcbConnection::getTimestamp properly exit when X server quits
QXcbConnection::getTimestamp uses dummy events to get timestamp from X server. However, in some cases, X server shuts down while client tries to get timestamp. In this case, QXcbConnection::getTimestamp keeps getting null event and thus falls into indefinite loop. This fix checks if xcb connection is still valid and use a special xcb_timestamp_t value, CurrentTime (0L), as returned value. CurrentTime should not be generated by X server and if getTimestamp returns this value, it means an "exception" case is triggered. This fix is introduced because in kwin_x11 (KDE project), X server can exit on logout. kwin_x11 should handle disconnection from X server. But the indefinite loop prevents kwin_x11 to process disconnection event and therefore kwin_x11 cannot quit properly. Fixes: QTBUG-88435 Pick-to: 5.12 5.15 6.0 Change-Id: Iaf7ef3f8a35fa8389d22a608e3c49041bf90e1b9 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Liang Qi <liang.qi@qt.io> Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>bb10
parent
92a57e0b01
commit
dbd1c8b047
|
|
@ -767,7 +767,10 @@ xcb_timestamp_t QXcbConnection::getTimestamp()
|
|||
|
||||
xcb_generic_event_t *event = nullptr;
|
||||
|
||||
while (!event) {
|
||||
// When disconnection is caused by X server, event will never be able to hold
|
||||
// a valid pointer. isConnected(), which calls xcb_connection_has_error(),
|
||||
// can handle this type of disconnection and properly quits the loop.
|
||||
while (isConnected() && !event) {
|
||||
connection()->sync();
|
||||
event = eventQueue()->peek([window, dummyAtom](xcb_generic_event_t *event, int type) {
|
||||
if (type != XCB_PROPERTY_NOTIFY)
|
||||
|
|
@ -777,6 +780,14 @@ xcb_timestamp_t QXcbConnection::getTimestamp()
|
|||
});
|
||||
}
|
||||
|
||||
if (!event) {
|
||||
// https://www.x.org/releases/X11R7.7/doc/xproto/x11protocol.html#glossary
|
||||
// > One timestamp value (named CurrentTime) is never generated by the
|
||||
// > server. This value is reserved for use in requests to represent the
|
||||
// > current server time.
|
||||
return XCB_CURRENT_TIME;
|
||||
}
|
||||
|
||||
xcb_property_notify_event_t *pn = reinterpret_cast<xcb_property_notify_event_t *>(event);
|
||||
xcb_timestamp_t timestamp = pn->time;
|
||||
free(event);
|
||||
|
|
|
|||
Loading…
Reference in New Issue