summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/xcb
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/xcb')
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp30
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h7
-rw-r--r--src/plugins/platforms/xcb/qxcbcursor.cpp40
-rw-r--r--src/plugins/platforms/xcb/qxcbcursor.h30
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.cpp20
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.h5
-rw-r--r--src/plugins/platforms/xcb/qxcbsessionmanager.h9
7 files changed, 100 insertions, 41 deletions
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index d6f64d29fd..433758e065 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -290,16 +290,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra
qFatal("QXcbConnection: Could not connect to display %s", m_displayName.constData());
m_reader = new QXcbEventReader(this);
- connect(m_reader, SIGNAL(eventPending()), this, SLOT(processXcbEvents()), Qt::QueuedConnection);
- connect(m_reader, SIGNAL(finished()), this, SLOT(processXcbEvents()));
- if (!m_reader->startThread()) {
- QSocketNotifier *notifier = new QSocketNotifier(xcb_get_file_descriptor(xcb_connection()), QSocketNotifier::Read, this);
- connect(notifier, SIGNAL(activated(int)), this, SLOT(processXcbEvents()));
-
- QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::eventDispatcher;
- connect(dispatcher, SIGNAL(aboutToBlock()), this, SLOT(processXcbEvents()));
- connect(dispatcher, SIGNAL(awake()), this, SLOT(processXcbEvents()));
- }
+ m_reader->start();
xcb_extension_t *extensions[] = {
&xcb_shm_id, &xcb_xfixes_id, &xcb_randr_id, &xcb_shape_id, &xcb_sync_id,
@@ -977,14 +968,27 @@ QXcbEventReader::QXcbEventReader(QXcbConnection *connection)
#endif
}
-bool QXcbEventReader::startThread()
+void QXcbEventReader::start()
{
if (m_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();
- return true;
+ } else {
+ // Must be done after we have an event-dispatcher. By posting a method invocation
+ // we are sure that by the time the method is called we have an event-dispatcher.
+ QMetaObject::invokeMethod(this, "registerForEvents", Qt::QueuedConnection);
}
+}
- return false;
+void QXcbEventReader::registerForEvents()
+{
+ QSocketNotifier *notifier = new QSocketNotifier(xcb_get_file_descriptor(m_connection->xcb_connection()), QSocketNotifier::Read, this);
+ connect(notifier, SIGNAL(activated(int)), m_connection, SLOT(processXcbEvents()));
+
+ QAbstractEventDispatcher *dispatcher = QGuiApplicationPrivate::eventDispatcher;
+ connect(dispatcher, SIGNAL(aboutToBlock()), m_connection, SLOT(processXcbEvents()));
+ connect(dispatcher, SIGNAL(awake()), m_connection, SLOT(processXcbEvents()));
}
void QXcbEventReader::run()
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index 7cabe67a68..0e52b2ec46 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -298,11 +298,14 @@ public:
QXcbEventArray *lock();
void unlock();
- bool startThread();
+ void start();
signals:
void eventPending();
+private slots:
+ void registerForEvents();
+
private:
void addEvent(xcb_generic_event_t *event);
@@ -574,6 +577,8 @@ private:
QByteArray m_startupId;
QXcbSystemTrayTracker *m_systemTrayTracker;
+
+ friend class QXcbEventReader;
};
#define DISPLAY_FROM_XCB(object) ((Display *)(object->connection()->xlib_display()))
diff --git a/src/plugins/platforms/xcb/qxcbcursor.cpp b/src/plugins/platforms/xcb/qxcbcursor.cpp
index 756c3c22dd..11848d503b 100644
--- a/src/plugins/platforms/xcb/qxcbcursor.cpp
+++ b/src/plugins/platforms/xcb/qxcbcursor.cpp
@@ -272,6 +272,26 @@ static const char * const cursorNames[] = {
"link"
};
+#ifndef QT_NO_CURSOR
+
+QXcbCursorCacheKey::QXcbCursorCacheKey(const QCursor &c)
+ : shape(c.shape()), bitmapCacheKey(0), maskCacheKey(0)
+{
+ if (shape == Qt::BitmapCursor) {
+ const qint64 pixmapCacheKey = c.pixmap().cacheKey();
+ if (pixmapCacheKey) {
+ bitmapCacheKey = pixmapCacheKey;
+ } else {
+ Q_ASSERT(c.bitmap());
+ Q_ASSERT(c.mask());
+ bitmapCacheKey = c.bitmap()->cacheKey();
+ maskCacheKey = c.mask()->cacheKey();
+ }
+ }
+}
+
+#endif // !QT_NO_CURSOR
+
QXcbCursor::QXcbCursor(QXcbConnection *conn, QXcbScreen *screen)
: QXcbObject(conn), m_screen(screen), m_gtkCursorThemeInitialized(false)
{
@@ -318,9 +338,7 @@ QXcbCursor::~QXcbCursor()
if (!--cursorCount)
xcb_close_font(conn, cursorFont);
- foreach (xcb_cursor_t cursor, m_bitmapCursorMap)
- xcb_free_cursor(conn, cursor);
- foreach (xcb_cursor_t cursor, m_shapeCursorMap)
+ foreach (xcb_cursor_t cursor, m_cursorHash)
xcb_free_cursor(conn, cursor);
}
@@ -336,17 +354,13 @@ void QXcbCursor::changeCursor(QCursor *cursor, QWindow *widget)
xcb_cursor_t c = XCB_CURSOR_NONE;
if (cursor) {
- if (cursor->shape() == Qt::BitmapCursor) {
- qint64 id = cursor->pixmap().cacheKey();
- if (!m_bitmapCursorMap.contains(id))
- m_bitmapCursorMap.insert(id, createBitmapCursor(cursor));
- c = m_bitmapCursorMap.value(id);
- } else {
- int id = cursor->shape();
- if (!m_shapeCursorMap.contains(id))
- m_shapeCursorMap.insert(id, createFontCursor(cursor->shape()));
- c = m_shapeCursorMap.value(id);
+ const QXcbCursorCacheKey key(*cursor);
+ CursorHash::iterator it = m_cursorHash.find(key);
+ if (it == m_cursorHash.end()) {
+ const Qt::CursorShape shape = cursor->shape();
+ it = m_cursorHash.insert(key, shape == Qt::BitmapCursor ? createBitmapCursor(cursor) : createFontCursor(shape));
}
+ c = it.value();
}
w->setCursor(c);
diff --git a/src/plugins/platforms/xcb/qxcbcursor.h b/src/plugins/platforms/xcb/qxcbcursor.h
index 081300868c..f224aae4e0 100644
--- a/src/plugins/platforms/xcb/qxcbcursor.h
+++ b/src/plugins/platforms/xcb/qxcbcursor.h
@@ -47,6 +47,31 @@
QT_BEGIN_NAMESPACE
+#ifndef QT_NO_CURSOR
+
+struct QXcbCursorCacheKey
+{
+ explicit QXcbCursorCacheKey(const QCursor &c);
+ explicit QXcbCursorCacheKey(Qt::CursorShape s) : shape(s), bitmapCacheKey(0), maskCacheKey(0) {}
+ QXcbCursorCacheKey() : shape(Qt::CustomCursor), bitmapCacheKey(0), maskCacheKey(0) {}
+
+ Qt::CursorShape shape;
+ qint64 bitmapCacheKey;
+ qint64 maskCacheKey;
+};
+
+inline bool operator==(const QXcbCursorCacheKey &k1, const QXcbCursorCacheKey &k2)
+{
+ return k1.shape == k2.shape && k1.bitmapCacheKey == k2.bitmapCacheKey && k1.maskCacheKey == k2.maskCacheKey;
+}
+
+inline uint qHash(const QXcbCursorCacheKey &k, uint seed) Q_DECL_NOTHROW
+{
+ return (uint(k.shape) + uint(k.bitmapCacheKey) + uint(k.maskCacheKey)) ^ seed;
+}
+
+#endif // !QT_NO_CURSOR
+
class QXcbCursor : public QXcbObject, public QPlatformCursor
{
public:
@@ -62,6 +87,8 @@ public:
private:
#ifndef QT_NO_CURSOR
+ typedef QHash<QXcbCursorCacheKey, xcb_cursor_t> CursorHash;
+
xcb_cursor_t createFontCursor(int cshape);
xcb_cursor_t createBitmapCursor(QCursor *cursor);
xcb_cursor_t createNonStandardCursor(int cshape);
@@ -69,8 +96,7 @@ private:
QXcbScreen *m_screen;
#ifndef QT_NO_CURSOR
- QMap<int, xcb_cursor_t> m_shapeCursorMap;
- QMap<qint64, xcb_cursor_t> m_bitmapCursorMap;
+ CursorHash m_cursorHash;
#endif
#ifdef XCB_USE_XLIB
static void cursorThemePropertyChanged(QXcbScreen *screen,
diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp
index cef81ddfec..2249446242 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.cpp
+++ b/src/plugins/platforms/xcb/qxcbintegration.cpp
@@ -124,12 +124,9 @@ static bool runningUnderDebugger()
#endif
QXcbIntegration::QXcbIntegration(const QStringList &parameters, int &argc, char **argv)
- : m_eventDispatcher(createUnixEventDispatcher())
- , m_services(new QGenericUnixServices)
+ : m_services(new QGenericUnixServices)
, m_instanceName(0)
{
- QGuiApplicationPrivate::instance()->setEventDispatcher(m_eventDispatcher);
-
#ifdef XCB_USE_XLIB
XInitThreads();
#endif
@@ -176,9 +173,6 @@ QXcbIntegration::QXcbIntegration(const QStringList &parameters, int &argc, char
m_fontDatabase.reset(new QGenericUnixFontDatabase());
m_inputContext.reset(QPlatformInputContextFactory::create());
-#if !defined(QT_NO_ACCESSIBILITY) && !defined(QT_NO_ACCESSIBILITY_ATSPI_BRIDGE)
- m_accessibility.reset(new QSpiAccessibleBridge());
-#endif
}
QXcbIntegration::~QXcbIntegration()
@@ -293,9 +287,9 @@ bool QXcbIntegration::hasCapability(QPlatformIntegration::Capability cap) const
}
}
-QAbstractEventDispatcher *QXcbIntegration::guiThreadEventDispatcher() const
+QAbstractEventDispatcher *QXcbIntegration::createEventDispatcher() const
{
- return m_eventDispatcher;
+ return createUnixEventDispatcher();
}
void QXcbIntegration::moveToScreen(QWindow *window, int screen)
@@ -336,6 +330,14 @@ QPlatformInputContext *QXcbIntegration::inputContext() const
#ifndef QT_NO_ACCESSIBILITY
QPlatformAccessibility *QXcbIntegration::accessibility() const
{
+#if !defined(QT_NO_ACCESSIBILITY_ATSPI_BRIDGE)
+ if (!m_accessibility) {
+ Q_ASSERT_X(QCoreApplication::eventDispatcher(), "QXcbIntegration",
+ "Initializing accessibility without event-dispatcher!");
+ m_accessibility.reset(new QSpiAccessibleBridge());
+ }
+#endif
+
return m_accessibility.data();
}
#endif
diff --git a/src/plugins/platforms/xcb/qxcbintegration.h b/src/plugins/platforms/xcb/qxcbintegration.h
index 7ca7befc64..008d03fbcb 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.h
+++ b/src/plugins/platforms/xcb/qxcbintegration.h
@@ -67,7 +67,7 @@ public:
QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const;
bool hasCapability(Capability cap) const;
- QAbstractEventDispatcher *guiThreadEventDispatcher() const;
+ QAbstractEventDispatcher *createEventDispatcher() const;
void moveToScreen(QWindow *window, int screen);
@@ -112,10 +112,9 @@ private:
QScopedPointer<QXcbNativeInterface> m_nativeInterface;
QScopedPointer<QPlatformInputContext> m_inputContext;
- QAbstractEventDispatcher *m_eventDispatcher;
#ifndef QT_NO_ACCESSIBILITY
- QScopedPointer<QPlatformAccessibility> m_accessibility;
+ mutable QScopedPointer<QPlatformAccessibility> m_accessibility;
#endif
QScopedPointer<QPlatformServices> m_services;
diff --git a/src/plugins/platforms/xcb/qxcbsessionmanager.h b/src/plugins/platforms/xcb/qxcbsessionmanager.h
index 0dca36d16f..28eb287097 100644
--- a/src/plugins/platforms/xcb/qxcbsessionmanager.h
+++ b/src/plugins/platforms/xcb/qxcbsessionmanager.h
@@ -43,6 +43,15 @@
#ifndef QXCBSESSIONMANAGER_H
#define QXCBSESSIONMANAGER_H
+//
+// W A R N I N G
+// -------------
+//
+// This file is part of the QPA API and is not meant to be used
+// in applications. Usage of this API may make your code
+// source and binary incompatible with future versions of Qt.
+//
+
#include <qpa/qplatformsessionmanager.h>
QT_BEGIN_NAMESPACE