Port from XLib XSync to xcb sync

This commit is contained in:
Martin Gräßlin 2013-07-31 10:11:39 +02:00
parent d164e16b56
commit 94e4a31370
5 changed files with 43 additions and 79 deletions

View file

@ -54,10 +54,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <QScriptProgram>
#endif
#include <QWhatsThis>
// X
#ifdef HAVE_XSYNC
#include <X11/extensions/sync.h>
#endif
// system
#include <unistd.h>
#include <signal.h>
@ -142,11 +138,9 @@ Client::Client()
, m_decoInputExtent()
{
// TODO: Do all as initialization
#ifdef HAVE_XSYNC
syncRequest.counter = syncRequest.alarm = None;
syncRequest.counter = syncRequest.alarm = XCB_NONE;
syncRequest.timeout = syncRequest.failsafeTimeout = NULL;
syncRequest.isPending = false;
#endif
// Set the initial mapping state
mapping_state = Withdrawn;
@ -227,10 +221,8 @@ Client::~Client()
m_killHelperPID = 0;
}
//SWrapper::Client::clientRelease(this);
#ifdef HAVE_XSYNC
if (syncRequest.alarm != None)
XSyncDestroyAlarm(display(), syncRequest.alarm);
#endif
if (syncRequest.alarm != XCB_NONE)
xcb_sync_destroy_alarm(connection(), syncRequest.alarm);
assert(!moveResizeMode);
assert(m_client == XCB_WINDOW_NONE);
assert(m_wrapper == XCB_WINDOW_NONE);
@ -2107,7 +2099,6 @@ void Client::getWindowProtocols()
void Client::getSyncCounter()
{
#ifdef HAVE_XSYNC
if (!Xcb::Extensions::self()->isSyncAvailable())
return;
@ -2121,26 +2112,31 @@ void Client::getSyncCounter()
if (ret == Success && formatRet == 32) {
syncRequest.counter = *(long*)(propRet);
XSyncIntToValue(&syncRequest.value, 0);
XSyncValue zero;
XSyncIntToValue(&zero, 0);
XSyncSetCounter(display(), syncRequest.counter, zero);
if (syncRequest.alarm == None) {
XSyncAlarmAttributes attrs;
attrs.trigger.counter = syncRequest.counter;
attrs.trigger.value_type = XSyncRelative;
attrs.trigger.test_type = XSyncPositiveTransition;
XSyncIntToValue(&attrs.trigger.wait_value, 1);
XSyncIntToValue(&attrs.delta, 1);
syncRequest.alarm = XSyncCreateAlarm(display(),
XSyncCACounter | XSyncCAValueType | XSyncCATestType | XSyncCADelta | XSyncCAValue,
&attrs);
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);
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 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);
}
}
if (ret == Success)
XFree(propRet);
#endif
}
/**
@ -2148,8 +2144,7 @@ void Client::getSyncCounter()
*/
void Client::sendSyncRequest()
{
#ifdef HAVE_XSYNC
if (syncRequest.counter == None || syncRequest.isPending)
if (syncRequest.counter == XCB_NONE || syncRequest.isPending)
return; // do NOT, NEVER send a sync request when there's one on the stack. the clients will just stop respoding. FOREVER! ...
if (!syncRequest.failsafeTimeout) {
@ -2164,11 +2159,11 @@ void Client::sendSyncRequest()
// We increment before the notify so that after the notify
// syncCounterSerial will equal the value we are expecting
// in the acknowledgement
int overflow;
XSyncValue one;
XSyncIntToValue(&one, 1);
#undef XSyncValueAdd // It causes a warning :-/
XSyncValueAdd(&syncRequest.value, syncRequest.value, one, &overflow);
const uint32_t oldLo = syncRequest.value.lo;
syncRequest.value.lo++;;
if (oldLo > syncRequest.value.lo) {
syncRequest.value.hi++;
}
// Send the message to client
XEvent ev;
@ -2178,13 +2173,12 @@ void Client::sendSyncRequest()
ev.xclient.message_type = atoms->wm_protocols;
ev.xclient.data.l[0] = atoms->net_wm_sync_request;
ev.xclient.data.l[1] = xTime();
ev.xclient.data.l[2] = XSyncValueLow32(syncRequest.value);
ev.xclient.data.l[3] = XSyncValueHigh32(syncRequest.value);
ev.xclient.data.l[2] = syncRequest.value.lo;
ev.xclient.data.l[3] = syncRequest.value.hi;
ev.xclient.data.l[4] = 0;
syncRequest.isPending = true;
XSendEvent(display(), window(), False, NoEventMask, &ev);
XSync(display(), false);
#endif
Xcb::sync();
}
void Client::removeSyncSupport()
@ -2193,12 +2187,10 @@ void Client::removeSyncSupport()
setReadyForPainting();
return;
}
#ifdef HAVE_XSYNC
syncRequest.isPending = false;
syncRequest.counter = syncRequest.alarm = None;
syncRequest.counter = syncRequest.alarm = XCB_NONE;
delete syncRequest.timeout; delete syncRequest.failsafeTimeout;
syncRequest.timeout = syncRequest.failsafeTimeout = NULL;
#endif
}
bool Client::wantsTabFocus() const

View file

@ -34,11 +34,9 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
// Qt
#include <QPixmap>
// X
#ifdef HAVE_XSYNC
#include <X11/extensions/sync.h>
#endif
#include <X11/Xutil.h>
#include <fixx11h.h>
#include <xcb/sync.h>
// TODO: Cleanup the order of things in this .h file
@ -316,9 +314,7 @@ public:
bool windowEvent(xcb_generic_event_t *e);
virtual bool eventFilter(QObject* o, QEvent* e);
#ifdef HAVE_XSYNC
void syncEvent(xcb_sync_alarm_notify_event_t* e);
#endif
NET::WindowType windowType(bool direct = false, int supported_types = 0) const;
bool manage(xcb_window_t w, bool isMapped);
@ -955,15 +951,13 @@ private:
QRect geom_before_block;
QRect deco_rect_before_block;
bool shade_geometry_change;
#ifdef HAVE_XSYNC
struct {
XSyncCounter counter;
XSyncValue value;
XSyncAlarm alarm;
xcb_sync_counter_t counter;
xcb_sync_int64_t value;
xcb_sync_alarm_t alarm;
QTimer *timeout, *failsafeTimeout;
bool isPending;
} syncRequest;
#endif
int border_left, border_right, border_top, border_bottom;
int padding_left, padding_right, padding_top, padding_bottom;
QRegion _mask;

View file

@ -882,7 +882,6 @@ bool Toplevel::compositing() const
void Client::damageNotifyEvent()
{
#ifdef HAVE_XSYNC
if (syncRequest.isPending && isResize()) {
emit damaged(this, QRect());
m_isDamaged = true;
@ -890,13 +889,9 @@ void Client::damageNotifyEvent()
}
if (!ready_for_painting) { // avoid "setReadyForPainting()" function calling overhead
if (syncRequest.counter == None) // cannot detect complete redraw, consider done now
if (syncRequest.counter == XCB_NONE) // cannot detect complete redraw, consider done now
setReadyForPainting();
}
#else
if (!ready_for_painting)
setReadyForPainting();
#endif
Toplevel::damageNotifyEvent();
}

View file

@ -443,12 +443,10 @@ bool Workspace::workspaceEvent(xcb_generic_event_t *e)
}
} else if (eventType == Xcb::Extensions::self()->syncAlarmNotifyEvent() && Xcb::Extensions::self()->isSyncAvailable()) {
#ifdef HAVE_XSYNC
for (Client *c : clients)
c->syncEvent(reinterpret_cast< xcb_sync_alarm_notify_event_t* >(e));
for (Client *c : desktops)
c->syncEvent(reinterpret_cast< xcb_sync_alarm_notify_event_t* >(e));
#endif
} else if (eventType == Xcb::Extensions::self()->fixesCursorNotifyEvent() && Xcb::Extensions::self()->isFixesAvailable()) {
Cursor::self()->notifyCursorChanged(reinterpret_cast<xcb_xfixes_cursor_notify_event_t*>(e)->cursor_serial);
}
@ -1530,12 +1528,9 @@ void Client::keyPressEvent(uint key_code)
Cursor::setPos(pos);
}
#ifdef HAVE_XSYNC
void Client::syncEvent(xcb_sync_alarm_notify_event_t* e)
{
#warning port XSync to XCB
#if KWIN_QT5_PORTING
if (e->alarm == syncRequest.alarm && XSyncValueEqual(e->counter_value, syncRequest.value)) {
if (e->alarm == syncRequest.alarm && e->counter_value.hi == syncRequest.value.hi && e->counter_value.lo == syncRequest.value.lo) {
setReadyForPainting();
syncRequest.isPending = false;
if (syncRequest.failsafeTimeout)
@ -1547,9 +1542,7 @@ void Client::syncEvent(xcb_sync_alarm_notify_event_t* e)
} else // setReadyForPainting does as well, but there's a small chance for resize syncs after the resize ended
addRepaintFull();
}
#endif
}
#endif
// ****************************************
// Unmanaged

View file

@ -1902,9 +1902,7 @@ void Client::setGeometry(int x, int y, int w, int h, ForceGeometry_t force)
QSize cs = clientSize();
XMoveResizeWindow(display(), wrapperId(), clientPos().x(), clientPos().y(),
cs.width(), cs.height());
#ifdef HAVE_XSYNC
if (!isResize() || syncRequest.counter == None)
#endif
if (!isResize() || syncRequest.counter == XCB_NONE)
XMoveResizeWindow(display(), window(), 0, 0, cs.width(), cs.height());
// SELI - won't this be too expensive?
// THOMAS - yes, but gtk+ clients will not resize without ...
@ -2654,12 +2652,10 @@ void Client::leaveMoveResize()
m_moveResizeGrabWindow.reset();
workspace()->setClientIsMoving(0);
moveResizeMode = false;
#ifdef HAVE_XSYNC
if (syncRequest.counter == None) // don't forget to sanitize since the timeout will no more fire
if (syncRequest.counter == XCB_NONE) // don't forget to sanitize since the timeout will no more fire
syncRequest.isPending = false;
delete syncRequest.timeout;
syncRequest.timeout = NULL;
#endif
#ifdef KWIN_BUILD_SCREENEDGES
if (ScreenEdges::self()->isDesktopSwitchingMovingClients())
ScreenEdges::self()->reserveDesktopSwitching(false, Qt::Vertical|Qt::Horizontal);
@ -2738,10 +2734,8 @@ void Client::delayedMoveResize()
void Client::handleMoveResize(int x, int y, int x_root, int y_root)
{
#ifdef HAVE_XSYNC
if (syncRequest.isPending && isResize())
return; // we're still waiting for the client or the timeout
#endif
if ((mode == PositionCenter && !isMovableAcrossScreens())
|| (mode != PositionCenter && (isShade() || !isResizable())))
@ -3007,14 +3001,13 @@ void Client::handleMoveResize(int x, int y, int x_root, int y_root)
if (!update)
return;
#ifdef HAVE_XSYNC
if (isResize() && !s_haveResizeEffect) {
if (!syncRequest.timeout) {
syncRequest.timeout = new QTimer(this);
connect(syncRequest.timeout, SIGNAL(timeout()), SLOT(performMoveResize()));
syncRequest.timeout->setSingleShot(true);
}
if (syncRequest.counter != None) {
if (syncRequest.counter != XCB_NONE) {
syncRequest.timeout->start(250);
sendSyncRequest();
} else { // for clients not supporting the XSYNC protocol, we
@ -3023,7 +3016,6 @@ void Client::handleMoveResize(int x, int y, int x_root, int y_root)
} // and no human can control faster resizes anyway
XMoveResizeWindow(display(), window(), 0, 0, moveResizeGeom.width() - (border_left + border_right), moveResizeGeom.height() - (border_top + border_bottom));
} else
#endif
performMoveResize();
#ifdef KWIN_BUILD_SCREENEDGES
@ -3038,13 +3030,11 @@ void Client::performMoveResize()
if (isMove() || (isResize() && !s_haveResizeEffect)) {
setGeometry(moveResizeGeom);
}
#ifdef HAVE_XSYNC
if (syncRequest.counter == None) // client w/o XSYNC support. allow the next resize event
if (syncRequest.counter == XCB_NONE) // client w/o XSYNC support. allow the next resize event
syncRequest.isPending = false; // NEVER do this for clients with a valid counter
// (leads to sync request races in some clients)
if (isResize())
addRepaintFull();
#endif
positionGeometryTip();
emit clientStepUserMovedResized(this, moveResizeGeom);
}