summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/xcb/qxcbconnection.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/platforms/xcb/qxcbconnection.cpp')
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp131
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)