[kwin] Work around broken xcb_sync_create_alarm

The xcb sync protocol is incorrectly defined (see [1]) which results in
xcb_sync_create_alarm not creating a valid alarm. To work around this
issue we only create the alarm without setting the int64 values. For
those we use the XLib XSyncChangeAlarm call after we verified that the
alarm got created. This unfortunately reintroduces linking against
libxext. But at least resizing works again.

[1] http://lists.freedesktop.org/archives/xcb/2013-June/008375.html
This commit is contained in:
Martin Gräßlin 2013-11-11 11:30:59 +01:00
parent 478486d46b
commit c32ec9b32b
2 changed files with 16 additions and 10 deletions

View file

@ -263,6 +263,7 @@ set(kwin_KDE_LIBS
set(kwin_XLIB_LIBS
${X11_X11_LIB}
${X11_Xext_LIB}
${X11_Xcursor_LIB}
${X11_ICE_LIB}
${X11_SM_LIB}

View file

@ -55,6 +55,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <QScriptProgram>
#endif
#include <QWhatsThis>
// XLib
#include <X11/extensions/sync.h>
// system
#include <unistd.h>
#include <signal.h>
@ -2113,27 +2115,30 @@ void Client::getSyncCounter()
0, 1, false, XA_CARDINAL, &retType, &formatRet, &nItemRet, &byteRet, &propRet);
if (ret == Success && formatRet == 32) {
syncRequest.counter = *(long*)(propRet);
syncRequest.counter = *(xcb_sync_counter_t*)(propRet);
syncRequest.value.hi = 0;
syncRequest.value.lo = 0;
xcb_sync_int64_t zero;
zero.hi = 0;
zero.lo = 0;
auto *c = connection();
xcb_sync_set_counter(c, syncRequest.counter, zero);
xcb_sync_set_counter(c, syncRequest.counter, syncRequest.value);
if (syncRequest.alarm == XCB_NONE) {
const uint32_t mask = XCB_SYNC_CA_COUNTER | XCB_SYNC_CA_VALUE_TYPE | XCB_SYNC_CA_VALUE | XCB_SYNC_CA_TEST_TYPE | XCB_SYNC_CA_DELTA ;
const uint32_t mask = XCB_SYNC_CA_COUNTER | XCB_SYNC_CA_VALUE_TYPE | XCB_SYNC_CA_TEST_TYPE | XCB_SYNC_CA_EVENTS;
const uint32_t values[] = {
syncRequest.counter,
XCB_SYNC_VALUETYPE_RELATIVE,
0,
1,
XCB_SYNC_TESTTYPE_POSITIVE_TRANSITION,
0,
1
};
syncRequest.alarm = xcb_generate_id(c);
xcb_sync_create_alarm(c, syncRequest.alarm, mask, values);
auto cookie = xcb_sync_create_alarm_checked(c, syncRequest.alarm, mask, values);
ScopedCPointer<xcb_generic_error_t> error(xcb_request_check(c, cookie));
if (!error.isNull()) {
syncRequest.alarm = XCB_NONE;
} else {
XSyncAlarmAttributes attrs;
XSyncIntToValue(&attrs.trigger.wait_value, 1);
XSyncIntToValue(&attrs.delta, 1);
XSyncChangeAlarm(display(), syncRequest.alarm, XSyncCADelta | XSyncCAValue, &attrs);
}
}
}