Port from XLib XSync to xcb sync
This commit is contained in:
parent
d164e16b56
commit
94e4a31370
5 changed files with 43 additions and 79 deletions
74
client.cpp
74
client.cpp
|
@ -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
|
||||
|
|
14
client.h
14
client.h
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
18
geometry.cpp
18
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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue