diff options
Diffstat (limited to 'src/plugins/platforms/xcb/qxcbconnection.cpp')
-rw-r--r-- | src/plugins/platforms/xcb/qxcbconnection.cpp | 131 |
1 files changed, 55 insertions, 76 deletions
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index aca2c347ea..c14f3f3703 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -55,6 +55,7 @@ #include "qxcbsystemtraytracker.h" #include "qxcbglintegrationfactory.h" #include "qxcbglintegration.h" +#include "qxcbcursor.h" #include "qxcbbackingstore.h" #include <QSocketNotifier> @@ -81,8 +82,8 @@ #undef register #endif -#if QT_CONFIG(xinput2) -#include <X11/extensions/XI2proto.h> +#if QT_CONFIG(xcb_xinput) +#include <xcb/xinput.h> #endif #if QT_CONFIG(xcb_render) @@ -118,6 +119,7 @@ Q_LOGGING_CATEGORY(lcQpaEvents, "qt.qpa.events") Q_LOGGING_CATEGORY(lcQpaXcb, "qt.qpa.xcb") // for general (uncategorized) XCB logging Q_LOGGING_CATEGORY(lcQpaPeeker, "qt.qpa.peeker") Q_LOGGING_CATEGORY(lcQpaKeyboard, "qt.qpa.xkeyboard") +Q_LOGGING_CATEGORY(lcQpaXDnd, "qt.qpa.xdnd") // this event type was added in libxcb 1.10, // but we support also older version @@ -125,7 +127,7 @@ Q_LOGGING_CATEGORY(lcQpaKeyboard, "qt.qpa.xkeyboard") #define XCB_GE_GENERIC 35 #endif -#if QT_CONFIG(xinput2) +#if QT_CONFIG(xcb_xinput) // Starting from the xcb version 1.9.3 struct xcb_ge_event_t has changed: // - "pad0" became "extension" // - "pad1" and "pad" became "pad0" @@ -143,7 +145,7 @@ static inline bool isXIEvent(xcb_generic_event_t *event, int opCode) qt_xcb_ge_event_t *e = reinterpret_cast<qt_xcb_ge_event_t *>(event); return e->extension == opCode; } -#endif // QT_CONFIG(xinput2) +#endif // QT_CONFIG(xcb_xinput) #if QT_CONFIG(xcb_xlib) static const char * const xcbConnectionErrors[] = { @@ -578,6 +580,9 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra #if QT_CONFIG(xcb_render) &xcb_render_id, #endif +#if QT_CONFIG(xcb_xinput) + &xcb_input_id, +#endif 0 }; @@ -590,6 +595,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra initializeAllAtoms(); + initializeXSync(); if (!qEnvironmentVariableIsSet("QT_XCB_NO_MITSHM")) initializeShm(); if (!qEnvironmentVariableIsSet("QT_XCB_NO_XRANDR")) @@ -600,7 +606,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra initializeScreens(); initializeXRender(); -#if QT_CONFIG(xinput2) +#if QT_CONFIG(xcb_xinput) if (!qEnvironmentVariableIsSet("QT_XCB_NO_XI2")) initializeXInput2(); #endif @@ -1113,13 +1119,13 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event) handleClientMessageEvent((xcb_client_message_event_t *)event); break; case XCB_ENTER_NOTIFY: -#if QT_CONFIG(xinput2) +#if QT_CONFIG(xcb_xinput) if (hasXInput2() && !xi2MouseEventsDisabled()) break; #endif HANDLE_PLATFORM_WINDOW_EVENT(xcb_enter_notify_event_t, event, handleEnterNotifyEvent); case XCB_LEAVE_NOTIFY: -#if QT_CONFIG(xinput2) +#if QT_CONFIG(xcb_xinput) if (hasXInput2() && !xi2MouseEventsDisabled()) break; #endif @@ -1182,7 +1188,7 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event) } break; } -#if QT_CONFIG(xinput2) +#if QT_CONFIG(xcb_xinput) case XCB_GE_GENERIC: // Here the windowEventListener is invoked from xi2HandleEvent() if (hasXInput2() && isXIEvent(event, m_xiOpCode)) @@ -1552,6 +1558,9 @@ xcb_window_t QXcbConnection::getQtSelectionOwner() xcbScreen->root_visual, // visual 0, // value mask 0); // value list + + QXcbWindow::setWindowTitle(connection(), m_qtSelectionOwner, + QStringLiteral("Qt Selection Window")); } return m_qtSelectionOwner; } @@ -1576,17 +1585,11 @@ xcb_window_t QXcbConnection::clientLeader() XCB_WINDOW_CLASS_INPUT_OUTPUT, screen->screen()->root_visual, 0, 0); -#ifndef QT_NO_DEBUG - QByteArray ba("Qt client leader window"); - xcb_change_property(xcb_connection(), - XCB_PROP_MODE_REPLACE, - m_clientLeader, - atom(QXcbAtom::_NET_WM_NAME), - atom(QXcbAtom::UTF8_STRING), - 8, - ba.length(), - ba.constData()); -#endif + + + QXcbWindow::setWindowTitle(connection(), m_clientLeader, + QStringLiteral("Qt Client Leader Window")); + xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_clientLeader, @@ -1614,39 +1617,14 @@ xcb_window_t QXcbConnection::clientLeader() return m_clientLeader; } -#if QT_CONFIG(xcb_xlib) -void *QXcbConnection::xlib_display() const -{ - return m_xlib_display; -} - -void *QXcbConnection::createVisualInfoForDefaultVisualId() const -{ - if (m_defaultVisualId == UINT_MAX) - return 0; - XVisualInfo info; - memset(&info, 0, sizeof info); - info.visualid = m_defaultVisualId; - - int count = 0; - Display *dpy = static_cast<Display *>(connection()->xlib_display()); - XVisualInfo *retVisual = XGetVisualInfo(dpy, VisualIDMask, &info, &count); - Q_ASSERT(count < 2); - return retVisual; -} - -#endif - -#if QT_CONFIG(xinput2) -// it is safe to cast XI_* events here as long as we are only touching the first 32 bytes, -// after that position event needs memmove, see xi2PrepareXIGenericDeviceEvent +#if QT_CONFIG(xcb_xinput) static inline bool isXIType(xcb_generic_event_t *event, int opCode, uint16_t type) { if (!isXIEvent(event, opCode)) return false; - xXIGenericDeviceEvent *xiEvent = reinterpret_cast<xXIGenericDeviceEvent *>(event); - return xiEvent->evtype == type; + auto *e = reinterpret_cast<qt_xcb_ge_event_t *>(event); + return e->event_type == type; } #endif static inline bool isValid(xcb_generic_event_t *event) @@ -1682,49 +1660,45 @@ bool QXcbConnection::compressEvent(xcb_generic_event_t *event, int currentIndex, } return false; } -#if QT_CONFIG(xinput2) +#if QT_CONFIG(xcb_xinput) // compress XI_* events if (responseType == XCB_GE_GENERIC) { if (!hasXInput2()) return false; // compress XI_Motion - if (isXIType(event, m_xiOpCode, XI_Motion)) { + if (isXIType(event, m_xiOpCode, XCB_INPUT_MOTION)) { #if QT_CONFIG(tabletevent) - xXIDeviceEvent *xdev = reinterpret_cast<xXIDeviceEvent *>(event); - // Xlib's XI2 events need memmove, see xi2PrepareXIGenericDeviceEvent() - auto sourceId = *reinterpret_cast<uint16_t *>(reinterpret_cast<char *>(&xdev->sourceid) + 4); + auto *xdev = reinterpret_cast<xcb_input_motion_event_t *>(event); if (!QCoreApplication::testAttribute(Qt::AA_CompressTabletEvents) && - const_cast<QXcbConnection *>(this)->tabletDataForDevice(sourceId)) + const_cast<QXcbConnection *>(this)->tabletDataForDevice(xdev->sourceid)) return false; #endif // QT_CONFIG(tabletevent) for (int j = nextIndex; j < eventqueue->size(); ++j) { xcb_generic_event_t *next = eventqueue->at(j); if (!isValid(next)) continue; - if (isXIType(next, m_xiOpCode, XI_Motion)) + if (isXIType(next, m_xiOpCode, XCB_INPUT_MOTION)) return true; } return false; } -#ifdef XCB_USE_XINPUT22 // compress XI_TouchUpdate for the same touch point id - if (isXIType(event, m_xiOpCode, XI_TouchUpdate)) { - xXIDeviceEvent *xiDeviceEvent = reinterpret_cast<xXIDeviceEvent *>(event); - uint32_t id = xiDeviceEvent->detail % INT_MAX; + if (isXIType(event, m_xiOpCode, XCB_INPUT_TOUCH_UPDATE)) { + auto *touchUpdateEvent = reinterpret_cast<xcb_input_touch_update_event_t *>(event); + uint32_t id = touchUpdateEvent->detail % INT_MAX; for (int j = nextIndex; j < eventqueue->size(); ++j) { xcb_generic_event_t *next = eventqueue->at(j); if (!isValid(next)) continue; - if (isXIType(next, m_xiOpCode, XI_TouchUpdate)) { - xXIDeviceEvent *xiDeviceNextEvent = reinterpret_cast<xXIDeviceEvent *>(next); - if (id == xiDeviceNextEvent->detail % INT_MAX) + if (isXIType(next, m_xiOpCode, XCB_INPUT_TOUCH_UPDATE)) { + auto *touchUpdateNextEvent = reinterpret_cast<xcb_input_touch_update_event_t *>(next); + if (id == touchUpdateNextEvent->detail % INT_MAX) return true; } } return false; } -#endif return false; } #endif @@ -1850,6 +1824,7 @@ static const char * xcb_atomnames = { "WM_CLIENT_LEADER\0" "WM_WINDOW_ROLE\0" "SM_CLIENT_ID\0" + "WM_CLIENT_MACHINE\0" // Clipboard "CLIPBOARD\0" @@ -2041,10 +2016,7 @@ void QXcbConnection::initializeAllAtoms() { ++ptr; } - Q_ASSERT(i == QXcbAtom::NPredefinedAtoms); - - const QByteArray settings_atom_name = "_QT_SETTINGS_TIMESTAMP_" + m_displayName; - names[i++] = settings_atom_name; + Q_ASSERT(i == QXcbAtom::NAtoms); xcb_intern_atom_cookie_t cookies[QXcbAtom::NAtoms]; @@ -2297,6 +2269,15 @@ void QXcbConnection::initializeXKB() #endif } +void QXcbConnection::initializeXSync() +{ + const xcb_query_extension_reply_t *reply = xcb_get_extension_data(xcb_connection(), &xcb_sync_id); + if (!reply || !reply->present) + return; + + has_sync_extension = true; +} + QXcbSystemTrayTracker *QXcbConnection::systemTrayTracker() const { if (!m_systemTrayTracker) { @@ -2309,20 +2290,18 @@ QXcbSystemTrayTracker *QXcbConnection::systemTrayTracker() const return m_systemTrayTracker; } -bool QXcbConnection::xEmbedSystemTrayAvailable() +Qt::MouseButtons QXcbConnection::queryMouseButtons() const { - if (!QGuiApplicationPrivate::platformIntegration()) - return false; - QXcbConnection *connection = static_cast<QXcbIntegration *>(QGuiApplicationPrivate::platformIntegration())->defaultConnection(); - return connection->systemTrayTracker(); + int stateMask = 0; + QXcbCursor::queryPointer(connection(), 0, 0, &stateMask); + return translateMouseButtons(stateMask); } -bool QXcbConnection::xEmbedSystemTrayVisualHasAlphaChannel() +Qt::KeyboardModifiers QXcbConnection::queryKeyboardModifiers() const { - if (!QGuiApplicationPrivate::platformIntegration()) - return false; - QXcbConnection *connection = static_cast<QXcbIntegration *>(QGuiApplicationPrivate::platformIntegration())->defaultConnection(); - return connection->systemTrayTracker() && connection->systemTrayTracker()->visualHasAlphaChannel(); + int stateMask = 0; + QXcbCursor::queryPointer(connection(), 0, 0, &stateMask); + return keyboard()->translateModifiers(stateMask); } bool QXcbConnection::event(QEvent *e) |