From 94e4a313704b5a4464984dfbf77927f3bb90c8ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Gr=C3=A4=C3=9Flin?= Date: Wed, 31 Jul 2013 10:11:39 +0200 Subject: [PATCH] Port from XLib XSync to xcb sync --- client.cpp | 74 +++++++++++++++++++++++---------------------------- client.h | 14 +++------- composite.cpp | 7 +---- events.cpp | 9 +------ geometry.cpp | 18 +++---------- 5 files changed, 43 insertions(+), 79 deletions(-) diff --git a/client.cpp b/client.cpp index 89a08ebf6b..fa8fb8a9fb 100644 --- a/client.cpp +++ b/client.cpp @@ -54,10 +54,6 @@ along with this program. If not, see . #include #endif #include -// X -#ifdef HAVE_XSYNC -#include -#endif // system #include #include @@ -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 diff --git a/client.h b/client.h index 068419ff2c..4d76eec9eb 100644 --- a/client.h +++ b/client.h @@ -34,11 +34,9 @@ along with this program. If not, see . // Qt #include // X -#ifdef HAVE_XSYNC -#include -#endif #include #include +#include // 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; diff --git a/composite.cpp b/composite.cpp index a2a59c1611..211e036b48 100644 --- a/composite.cpp +++ b/composite.cpp @@ -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(); } diff --git a/events.cpp b/events.cpp index 7fa1d10fa9..8abf14259b 100644 --- a/events.cpp +++ b/events.cpp @@ -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(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 diff --git a/geometry.cpp b/geometry.cpp index d5977492cc..4b7ca8ae53 100644 --- a/geometry.cpp +++ b/geometry.cpp @@ -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); }