summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/xcb/qxcbconnection.cpp
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@theqtcompany.com>2015-08-06 10:45:40 +0200
committerFrederik Gladhorn <frederik.gladhorn@theqtcompany.com>2015-08-06 10:54:01 +0200
commit77da617dc8e378a631ee8c15b1b414f16b87f147 (patch)
tree563f4f8e64e416774ea2b1599b896b589385168c /src/plugins/platforms/xcb/qxcbconnection.cpp
parentc17134e2db4d364855aa78a0d3c47cb9ef964dd9 (diff)
parent01f3530650f9f6f4c08520263a3c62281d81e3fc (diff)
Merge remote-tracking branch 'origin/5.5' into dev
Conflicts: doc/global/qt-cpp-defines.qdocconf src/3rdparty/forkfd/forkfd.c src/corelib/codecs/qtextcodec.cpp src/corelib/kernel/qmetatype.cpp src/corelib/tools/qset.qdoc src/gui/accessible/qaccessible.cpp src/gui/image/qpixmapcache.cpp src/opengl/qgl.cpp src/tools/qdoc/generator.cpp src/widgets/kernel/qwidget.cpp tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp Change-Id: I4fbe1fa756a54c6843aa75f4ef70a1069ba7b085
Diffstat (limited to 'src/plugins/platforms/xcb/qxcbconnection.cpp')
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp64
1 files changed, 45 insertions, 19 deletions
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index 1fe46ff290..15d3575e60 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -55,7 +55,6 @@
#include <algorithm>
-#include <dlfcn.h>
#include <stdio.h>
#include <errno.h>
#include <xcb/shm.h>
@@ -77,6 +76,25 @@
#include <xcb/render.h>
#endif
+#if defined(Q_CC_GNU) && defined(Q_OF_ELF)
+static xcb_generic_event_t *local_xcb_poll_for_queued_event(xcb_connection_t *c)
+ __attribute__((weakref("xcb_poll_for_queued_event")));
+
+static inline void checkXcbPollForQueuedEvent()
+{ }
+#else
+#include <dlfcn.h>
+typedef xcb_generic_event_t * (*XcbPollForQueuedEventFunctionPointer)(xcb_connection_t *c);
+static XcbPollForQueuedEventFunctionPointer local_xcb_poll_for_queued_event;
+
+static inline void checkXcbPollForQueuedEvent()
+{
+#ifdef RTLD_DEFAULT
+ local_xcb_poll_for_queued_event = (XcbPollForQueuedEventFunctionPointer)dlsym(RTLD_DEFAULT, "xcb_poll_for_queued_event");
+#endif
+}
+#endif
+
QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcQpaXInput, "qt.qpa.input")
@@ -252,16 +270,32 @@ void QXcbConnection::updateScreens(const xcb_randr_notify_event_t *event)
otherScreen->addVirtualSibling(screen);
m_screens << screen;
QXcbIntegration::instance()->screenAdded(screen, screen->isPrimary());
+
+ // Windows which had null screens have already had expose events by now.
+ // They need to be told the screen is back, it's OK to render.
+ foreach (QWindow *window, QGuiApplication::topLevelWindows()) {
+ QXcbWindow *xcbWin = static_cast<QXcbWindow*>(window->handle());
+ if (xcbWin)
+ xcbWin->maybeSetScreen(screen);
+ }
}
// else ignore disabled screens
} else if (screen) {
// Screen has been disabled -> remove
if (output.crtc == XCB_NONE && output.mode == XCB_NONE) {
- qCDebug(lcQpaScreen) << "output" << screen->name() << "has been disabled";
- m_screens.removeOne(screen);
- foreach (QXcbScreen *otherScreen, m_screens)
- otherScreen->removeVirtualSibling((QPlatformScreen *) screen);
- QXcbIntegration::instance()->destroyScreen(screen);
+ xcb_randr_get_output_info_cookie_t outputInfoCookie =
+ xcb_randr_get_output_info(xcb_connection(), output.output, output.config_timestamp);
+ QScopedPointer<xcb_randr_get_output_info_reply_t, QScopedPointerPodDeleter> outputInfo(
+ xcb_randr_get_output_info_reply(xcb_connection(), outputInfoCookie, NULL));
+ if (outputInfo->crtc == XCB_NONE) {
+ qCDebug(lcQpaScreen) << "output" << screen->name() << "has been disabled";
+ m_screens.removeOne(screen);
+ foreach (QXcbScreen *otherScreen, m_screens)
+ otherScreen->removeVirtualSibling((QPlatformScreen *) screen);
+ QXcbIntegration::instance()->destroyScreen(screen);
+ } else {
+ qCDebug(lcQpaScreen) << "output" << screen->name() << "has been temporarily disabled for the mode switch";
+ }
} else {
// Just update existing screen
screen->updateGeometry(output.config_timestamp);
@@ -1153,21 +1187,13 @@ void QXcbConnection::addPeekFunc(PeekFunc f)
QXcbEventReader::QXcbEventReader(QXcbConnection *connection)
: m_connection(connection)
- , m_xcb_poll_for_queued_event(0)
{
-#ifdef RTLD_DEFAULT
- m_xcb_poll_for_queued_event = (XcbPollForQueuedEventFunctionPointer)dlsym(RTLD_DEFAULT, "xcb_poll_for_queued_event");
-#endif
-
-#ifdef Q_XCB_DEBUG
- if (m_xcb_poll_for_queued_event)
- qDebug("Using threaded event reader with xcb_poll_for_queued_event");
-#endif
+ checkXcbPollForQueuedEvent();
}
void QXcbEventReader::start()
{
- if (m_xcb_poll_for_queued_event) {
+ if (local_xcb_poll_for_queued_event) {
connect(this, SIGNAL(eventPending()), m_connection, SLOT(processXcbEvents()), Qt::QueuedConnection);
connect(this, SIGNAL(finished()), m_connection, SLOT(processXcbEvents()));
QThread::start();
@@ -1193,7 +1219,7 @@ void QXcbEventReader::registerEventDispatcher(QAbstractEventDispatcher *dispatch
// flush the xcb connection before the EventDispatcher is going to block
// In the non-threaded case processXcbEvents is called before going to block,
// which flushes the connection.
- if (m_xcb_poll_for_queued_event)
+ if (local_xcb_poll_for_queued_event)
connect(dispatcher, SIGNAL(aboutToBlock()), m_connection, SLOT(flush()));
}
@@ -1203,7 +1229,7 @@ void QXcbEventReader::run()
while (m_connection && (event = xcb_wait_for_event(m_connection->xcb_connection()))) {
m_mutex.lock();
addEvent(event);
- while (m_connection && (event = m_xcb_poll_for_queued_event(m_connection->xcb_connection())))
+ while (m_connection && (event = local_xcb_poll_for_queued_event(m_connection->xcb_connection())))
addEvent(event);
m_mutex.unlock();
emit eventPending();
@@ -1227,7 +1253,7 @@ void QXcbEventReader::addEvent(xcb_generic_event_t *event)
QXcbEventArray *QXcbEventReader::lock()
{
m_mutex.lock();
- if (!m_xcb_poll_for_queued_event) {
+ if (!local_xcb_poll_for_queued_event) {
while (xcb_generic_event_t *event = xcb_poll_for_event(m_connection->xcb_connection()))
m_events << event;
}