diff options
author | J-P Nurmi <jpnurmi@digia.com> | 2014-06-05 22:26:44 +0200 |
---|---|---|
committer | J-P Nurmi <jpnurmi@digia.com> | 2014-06-05 22:26:44 +0200 |
commit | 0fcce50af009f97efa2a5c5f2c74415c92830962 (patch) | |
tree | f8abf0e4f445fed9480b426b2f856b50911f1210 /src/plugins/platforms/xcb | |
parent | 74d46a669badc5bf32187686102ca4e644a3c0af (diff) | |
parent | c54f7720d09e7d00f3309736bbeaaa6a81967ec1 (diff) |
Merge remote-tracking branch 'origin/stable' into dev
Conflicts:
mkspecs/features/qt.prf
src/plugins/platforms/xcb/qxcbwindow.h
src/tools/qdoc/qdocindexfiles.cpp
src/widgets/kernel/qwidget_qpa.cpp
Change-Id: I214f57b03bc2ff86cf3b7dfe2966168af93a5a67
Diffstat (limited to 'src/plugins/platforms/xcb')
-rw-r--r-- | src/plugins/platforms/xcb/qglxintegration.cpp | 9 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbbackingstore.cpp | 16 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbbackingstore.h | 1 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbconnection.cpp | 5 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbconnection.h | 3 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbintegration.cpp | 1 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbwindow.cpp | 25 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbwindow.h | 15 |
8 files changed, 59 insertions, 16 deletions
diff --git a/src/plugins/platforms/xcb/qglxintegration.cpp b/src/plugins/platforms/xcb/qglxintegration.cpp index c18764a4bb..df929c4b61 100644 --- a/src/plugins/platforms/xcb/qglxintegration.cpp +++ b/src/plugins/platforms/xcb/qglxintegration.cpp @@ -516,6 +516,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 ®ion) 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 ®ion, 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 ®ion, 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 1af9f1fdd1..12143a7e4b 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.h +++ b/src/plugins/platforms/xcb/qxcbconnection.h @@ -465,6 +465,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 0315d0762f..36a4b5c5db 100644 --- a/src/plugins/platforms/xcb/qxcbintegration.cpp +++ b/src/plugins/platforms/xcb/qxcbintegration.cpp @@ -128,6 +128,7 @@ QXcbIntegration::QXcbIntegration(const QStringList ¶meters, 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 e4ffda21ea..4b9a99486f 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -202,6 +202,7 @@ QXcbWindow::QXcbWindow(QWindow *window) , m_eglSurface(0) #endif , m_lastWindowStateEvent(-1) + , m_syncState(NoSyncNeeded) { m_screen = static_cast<QXcbScreen *>(window->screen()->handle()); @@ -369,7 +370,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); @@ -1728,6 +1734,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(); @@ -1801,6 +1809,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; } @@ -2077,12 +2088,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; } } @@ -2305,4 +2321,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 268a2aeaa5..72b5c7bcc9 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.h +++ b/src/plugins/platforms/xcb/qxcbwindow.h @@ -146,7 +146,6 @@ 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) @@ -158,6 +157,11 @@ public: QXcbWindowFunctions::WmWindowTypes wmWindowTypes() const; void setWmWindowType(QXcbWindowFunctions::WmWindowTypes types); + bool needsSync() const; + +public Q_SLOTS: + void updateSyncRequestCounter(); + private: void changeNetWmState(bool set, xcb_atom_t one, xcb_atom_t two = 0); NetWmStates netWmStates(); @@ -224,8 +228,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 |