summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/plugins/platforms/xcb/qglxintegration.cpp9
-rw-r--r--src/plugins/platforms/xcb/qxcbbackingstore.cpp16
-rw-r--r--src/plugins/platforms/xcb/qxcbbackingstore.h1
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp5
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h3
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.cpp1
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp25
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.h15
8 files changed, 59 insertions, 16 deletions
diff --git a/src/plugins/platforms/xcb/qglxintegration.cpp b/src/plugins/platforms/xcb/qglxintegration.cpp
index f78d3bcc4e..9a56455940 100644
--- a/src/plugins/platforms/xcb/qglxintegration.cpp
+++ b/src/plugins/platforms/xcb/qglxintegration.cpp
@@ -390,6 +390,15 @@ void QGLXContext::swapBuffers(QPlatformSurface *surface)
else
glxDrawable = static_cast<QXcbWindow *>(surface)->xcb_window();
glXSwapBuffers(DISPLAY_FROM_XCB(m_screen), glxDrawable);
+
+ if (surface->surface()->surfaceClass() == QSurface::Window) {
+ QXcbWindow *platformWindow = static_cast<QXcbWindow *>(surface);
+ // OpenGL context might be bound to a non-gui thread
+ // use QueuedConnection to sync the window from the platformWindow's thread
+ // as QXcbWindow is no QObject, a wrapper slot in QXcbConnection is used.
+ if (platformWindow->needsSync())
+ QMetaObject::invokeMethod(m_screen->connection(), "syncWindow", Qt::QueuedConnection, Q_ARG(QXcbWindow*, platformWindow));
+ }
}
void (*QGLXContext::getProcAddress(const QByteArray &procName)) ()
diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.cpp b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
index 57d6bc580b..ada5b0eedf 100644
--- a/src/plugins/platforms/xcb/qxcbbackingstore.cpp
+++ b/src/plugins/platforms/xcb/qxcbbackingstore.cpp
@@ -261,7 +261,6 @@ void QXcbShmImage::preparePaint(const QRegion &region)
QXcbBackingStore::QXcbBackingStore(QWindow *window)
: QPlatformBackingStore(window)
, m_image(0)
- , m_syncingResize(false)
{
QXcbScreen *screen = static_cast<QXcbScreen *>(window->screen()->handle());
setConnection(screen->connection());
@@ -330,13 +329,10 @@ void QXcbBackingStore::flush(QWindow *window, const QRegion &region, const QPoin
Q_XCB_NOOP(connection());
- if (m_syncingResize) {
- connection()->sync();
- m_syncingResize = false;
+ if (platformWindow->needsSync())
platformWindow->updateSyncRequestCounter();
- } else {
+ else
xcb_flush(xcb_connection());
- }
}
#ifndef QT_NO_OPENGL
@@ -347,10 +343,8 @@ void QXcbBackingStore::composeAndFlush(QWindow *window, const QRegion &region, c
Q_XCB_NOOP(connection());
- if (m_syncingResize) {
- QXcbWindow *platformWindow = static_cast<QXcbWindow *>(window->handle());
- connection()->sync();
- m_syncingResize = false;
+ QXcbWindow *platformWindow = static_cast<QXcbWindow *>(window->handle());
+ if (platformWindow->needsSync()) {
platformWindow->updateSyncRequestCounter();
} else {
xcb_flush(xcb_connection());
@@ -376,8 +370,6 @@ void QXcbBackingStore::resize(const QSize &size, const QRegion &)
delete m_image;
m_image = new QXcbShmImage(screen, size, win->depth(), win->imageFormat());
Q_XCB_NOOP(connection());
-
- m_syncingResize = true;
}
extern void qt_scrollRectInImage(QImage &img, const QRect &rect, const QPoint &offset);
diff --git a/src/plugins/platforms/xcb/qxcbbackingstore.h b/src/plugins/platforms/xcb/qxcbbackingstore.h
index 19a5ac62d0..af3c004c2d 100644
--- a/src/plugins/platforms/xcb/qxcbbackingstore.h
+++ b/src/plugins/platforms/xcb/qxcbbackingstore.h
@@ -72,7 +72,6 @@ public:
private:
QXcbShmImage *m_image;
- bool m_syncingResize;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index f5f6c712c5..1b72bb0da1 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -1833,6 +1833,11 @@ QXcbSystemTrayTracker *QXcbConnection::systemTrayTracker()
return m_systemTrayTracker;
}
+void QXcbConnection::syncWindow(QXcbWindow *window)
+{
+ window->updateSyncRequestCounter();
+}
+
QXcbConnectionGrabber::QXcbConnectionGrabber(QXcbConnection *connection)
:m_connection(connection)
{
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index 6e511356c4..f96541318c 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -464,6 +464,9 @@ public:
void handleEnterEvent(const xcb_enter_notify_event_t *);
#endif
+public slots:
+ void syncWindow(QXcbWindow *window);
+
private slots:
void processXcbEvents();
diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp
index 0bab341914..ddb164bf07 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.cpp
+++ b/src/plugins/platforms/xcb/qxcbintegration.cpp
@@ -127,6 +127,7 @@ QXcbIntegration::QXcbIntegration(const QStringList &parameters, int &argc, char
: m_services(new QGenericUnixServices)
, m_instanceName(0)
{
+ qRegisterMetaType<QXcbWindow*>();
#ifdef XCB_USE_XLIB
XInitThreads();
#endif
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 3645b6469a..a46fe437d8 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -200,6 +200,7 @@ QXcbWindow::QXcbWindow(QWindow *window)
, m_eglSurface(0)
#endif
, m_lastWindowStateEvent(-1)
+ , m_syncState(NoSyncNeeded)
{
m_screen = static_cast<QXcbScreen *>(window->screen()->handle());
@@ -367,7 +368,12 @@ void QXcbWindow::create()
properties[propertyCount++] = atom(QXcbAtom::WM_TAKE_FOCUS);
properties[propertyCount++] = atom(QXcbAtom::_NET_WM_PING);
- m_usingSyncProtocol = m_screen->syncRequestSupported() && window()->surfaceType() != QSurface::OpenGLSurface;
+ m_usingSyncProtocol = m_screen->syncRequestSupported();
+#if !defined(XCB_USE_GLX)
+ // synced resize only implemented on GLX
+ if (window()->supportsOpenGL())
+ m_usingSyncProtocol = false;
+#endif
if (m_usingSyncProtocol)
properties[propertyCount++] = atom(QXcbAtom::_NET_WM_SYNC_REQUEST);
@@ -1596,6 +1602,8 @@ void QXcbWindow::handleClientMessageEvent(const xcb_client_message_event_t *even
connection()->setTime(event->data.data32[1]);
m_syncValue.lo = event->data.data32[2];
m_syncValue.hi = event->data.data32[3];
+ if (m_usingSyncProtocol)
+ m_syncState = SyncReceived;
#ifndef QT_NO_WHATSTHIS
} else if (event->data.data32[0] == atom(QXcbAtom::_NET_WM_CONTEXT_HELP)) {
QWindowSystemInterface::handleEnterWhatsThisEvent();
@@ -1669,6 +1677,9 @@ void QXcbWindow::handleConfigureNotifyEvent(const xcb_configure_notify_event_t *
QWindowSystemInterface::handleExposeEvent(window(), QRect(QPoint(), geometry().size()));
}
+ if (m_usingSyncProtocol && m_syncState == SyncReceived)
+ m_syncState = SyncAndConfigureReceived;
+
m_dirtyFrameMargins = true;
}
@@ -1945,12 +1956,17 @@ void QXcbWindow::handleFocusOutEvent(const xcb_focus_out_event_t *)
void QXcbWindow::updateSyncRequestCounter()
{
+ if (m_syncState != SyncAndConfigureReceived) {
+ // window manager does not expect a sync event yet.
+ return;
+ }
if (m_usingSyncProtocol && (m_syncValue.lo != 0 || m_syncValue.hi != 0)) {
Q_XCB_CALL(xcb_sync_set_counter(xcb_connection(), m_syncCounter, m_syncValue));
- connection()->sync();
+ xcb_flush(xcb_connection());
m_syncValue.lo = 0;
m_syncValue.hi = 0;
+ m_syncState = NoSyncNeeded;
}
}
@@ -2173,4 +2189,9 @@ void QXcbWindow::setAlertState(bool enabled)
}
}
+bool QXcbWindow::needsSync() const
+{
+ return m_syncState == SyncAndConfigureReceived;
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h
index 12d17023fb..b924ee27e5 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.h
+++ b/src/plugins/platforms/xcb/qxcbwindow.h
@@ -144,13 +144,17 @@ public:
void handleMouseEvent(xcb_timestamp_t time, const QPoint &local, const QPoint &global, Qt::KeyboardModifiers modifiers);
- void updateSyncRequestCounter();
void updateNetWmUserTime(xcb_timestamp_t timestamp);
#if defined(XCB_USE_EGL)
QXcbEGLSurface *eglSurface() const;
#endif
+ bool needsSync() const;
+
+public Q_SLOTS:
+ void updateSyncRequestCounter();
+
private:
void changeNetWmState(bool set, xcb_atom_t one, xcb_atom_t two = 0);
NetWmStates netWmStates();
@@ -217,8 +221,17 @@ private:
xcb_visualid_t m_visualId;
int m_lastWindowStateEvent;
+
+ enum SyncState {
+ NoSyncNeeded,
+ SyncReceived,
+ SyncAndConfigureReceived
+ };
+ SyncState m_syncState;
};
QT_END_NAMESPACE
+Q_DECLARE_METATYPE(QXcbWindow*)
+
#endif