diff options
Diffstat (limited to 'src/plugins/platforms/xcb')
-rw-r--r-- | src/plugins/platforms/xcb/qxcbconnection.cpp | 30 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbconnection.h | 7 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbcursor.cpp | 40 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbcursor.h | 30 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbintegration.cpp | 20 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbintegration.h | 5 | ||||
-rw-r--r-- | src/plugins/platforms/xcb/qxcbsessionmanager.h | 9 |
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 ¶meters, 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 ¶meters, 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 |