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/gl_integrations/xcb_glx/qxcbglxwindow.cpp9
-rw-r--r--src/plugins/platforms/xcb/nativepainting/qtessellator.cpp1
-rw-r--r--src/plugins/platforms/xcb/qt_xlib_wrapper.c44
-rw-r--r--src/plugins/platforms/xcb/qt_xlib_wrapper.h54
-rw-r--r--src/plugins/platforms/xcb/qxcbatom.cpp2
-rw-r--r--src/plugins/platforms/xcb/qxcbatom.h2
-rw-r--r--src/plugins/platforms/xcb/qxcbclipboard.cpp28
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp81
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection_basic.cpp10
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection_xi2.cpp8
-rw-r--r--src/plugins/platforms/xcb/qxcbcursor.cpp11
-rw-r--r--src/plugins/platforms/xcb/qxcbdrag.cpp35
-rw-r--r--src/plugins/platforms/xcb/qxcbeventdispatcher.cpp2
-rw-r--r--src/plugins/platforms/xcb/qxcbeventqueue.cpp2
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.cpp4
-rw-r--r--src/plugins/platforms/xcb/qxcbmime.cpp2
-rw-r--r--src/plugins/platforms/xcb/qxcbnativeinterface.cpp2
-rw-r--r--src/plugins/platforms/xcb/qxcbnativeinterface.h2
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.cpp25
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.h2
-rw-r--r--src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp2
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp36
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.h9
-rw-r--r--src/plugins/platforms/xcb/xcb_qpa_lib.pro2
24 files changed, 313 insertions, 62 deletions
diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxwindow.cpp b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxwindow.cpp
index 5e406017ca..e8c9c27ba8 100644
--- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxwindow.cpp
+++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/qxcbglxwindow.cpp
@@ -58,7 +58,7 @@ const xcb_visualtype_t *QXcbGlxWindow::createVisual()
{
QXcbScreen *scr = xcbScreen();
if (!scr)
- return nullptr;
+ return QXcbWindow::createVisual();
qCDebug(lcQpaGl) << "Requested format before FBConfig/Visual selection:" << m_format;
@@ -71,10 +71,13 @@ const xcb_visualtype_t *QXcbGlxWindow::createVisual()
flags |= QGLX_SUPPORTS_SRGB;
}
+ const auto formatBackup = m_format;
XVisualInfo *visualInfo = qglx_findVisualInfo(dpy, scr->screenNumber(), &m_format, GLX_WINDOW_BIT, flags);
if (!visualInfo) {
- qWarning() << "No XVisualInfo for format" << m_format;
- return nullptr;
+ qCDebug(lcQpaGl) << "No XVisualInfo for format" << m_format;
+ // restore initial format before requesting it again
+ m_format = formatBackup;
+ return QXcbWindow::createVisual();
}
const xcb_visualtype_t *xcb_visualtype = scr->visualForId(visualInfo->visualid);
XFree(visualInfo);
diff --git a/src/plugins/platforms/xcb/nativepainting/qtessellator.cpp b/src/plugins/platforms/xcb/nativepainting/qtessellator.cpp
index 1afa00cfc9..118af6ce73 100644
--- a/src/plugins/platforms/xcb/nativepainting/qtessellator.cpp
+++ b/src/plugins/platforms/xcb/nativepainting/qtessellator.cpp
@@ -41,6 +41,7 @@
#include <QRect>
#include <QList>
+#include <QMap>
#include <QDebug>
#include <qmath.h>
diff --git a/src/plugins/platforms/xcb/qt_xlib_wrapper.c b/src/plugins/platforms/xcb/qt_xlib_wrapper.c
new file mode 100644
index 0000000000..d45f468e8c
--- /dev/null
+++ b/src/plugins/platforms/xcb/qt_xlib_wrapper.c
@@ -0,0 +1,44 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+******************************************************************************/
+
+#include "qt_xlib_wrapper.h"
+
+#include <X11/Xlib.h>
+
+void qt_XFlush(Display *dpy) { XFlush(dpy); }
diff --git a/src/plugins/platforms/xcb/qt_xlib_wrapper.h b/src/plugins/platforms/xcb/qt_xlib_wrapper.h
new file mode 100644
index 0000000000..a656c2e50a
--- /dev/null
+++ b/src/plugins/platforms/xcb/qt_xlib_wrapper.h
@@ -0,0 +1,54 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the plugins of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 3 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL3 included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 3 requirements
+** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 2.0 or (at your option) the GNU General
+** Public license version 3 or any later version approved by the KDE Free
+** Qt Foundation. The licenses are as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-2.0.html and
+** https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+******************************************************************************/
+
+#ifndef QT_XLIB_WRAPPER_H
+#define QT_XLIB_WRAPPER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ typedef struct _XDisplay Display;
+ void qt_XFlush(Display *dpy);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // QT_XLIB_WRAPPER_H
diff --git a/src/plugins/platforms/xcb/qxcbatom.cpp b/src/plugins/platforms/xcb/qxcbatom.cpp
index 780816605a..a769ddadbd 100644
--- a/src/plugins/platforms/xcb/qxcbatom.cpp
+++ b/src/plugins/platforms/xcb/qxcbatom.cpp
@@ -90,6 +90,8 @@ static const char *xcb_atomnames = {
"_QT_CLOSE_CONNECTION\0"
+ "_QT_GET_TIMESTAMP\0"
+
"_MOTIF_WM_HINTS\0"
"DTWM_IS_RUNNING\0"
diff --git a/src/plugins/platforms/xcb/qxcbatom.h b/src/plugins/platforms/xcb/qxcbatom.h
index 9cf93ec314..1ce6cca573 100644
--- a/src/plugins/platforms/xcb/qxcbatom.h
+++ b/src/plugins/platforms/xcb/qxcbatom.h
@@ -91,6 +91,8 @@ public:
// Qt/XCB specific
_QT_CLOSE_CONNECTION,
+ _QT_GET_TIMESTAMP,
+
_MOTIF_WM_HINTS,
DTWM_IS_RUNNING,
diff --git a/src/plugins/platforms/xcb/qxcbclipboard.cpp b/src/plugins/platforms/xcb/qxcbclipboard.cpp
index 0a4d675606..2f37ee64b5 100644
--- a/src/plugins/platforms/xcb/qxcbclipboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbclipboard.cpp
@@ -71,7 +71,7 @@ public:
break;
default:
- qWarning("QXcbClipboardMime: Internal error: Unsupported clipboard mode");
+ qCWarning(lcQpaClipboard, "QXcbClipboardMime: Internal error: Unsupported clipboard mode");
break;
}
}
@@ -265,7 +265,7 @@ QXcbClipboard::~QXcbClipboard()
if (auto event = waitForClipboardEvent(m_owner, XCB_SELECTION_NOTIFY, true)) {
free(event);
} else {
- qWarning("QXcbClipboard: Unable to receive an event from the "
+ qCWarning(lcQpaClipboard, "QXcbClipboard: Unable to receive an event from the "
"clipboard manager in a reasonable time");
}
}
@@ -371,7 +371,7 @@ void QXcbClipboard::setMimeData(QMimeData *data, QClipboard::Mode mode)
xcb_set_selection_owner(xcb_connection(), newOwner, modeAtom, connection()->time());
if (getSelectionOwner(modeAtom) != newOwner) {
- qWarning("QXcbClipboard::setMimeData: Cannot set X11 selection owner");
+ qCWarning(lcQpaClipboard, "QXcbClipboard::setMimeData: Cannot set X11 selection owner");
}
emitChanged(mode);
@@ -538,7 +538,7 @@ void QXcbClipboard::handleSelectionClearRequest(xcb_selection_clear_event_t *eve
void QXcbClipboard::handleSelectionRequest(xcb_selection_request_event_t *req)
{
if (requestor() && req->requestor == requestor()) {
- qWarning("QXcbClipboard: Selection request should be caught before");
+ qCWarning(lcQpaClipboard, "QXcbClipboard: Selection request should be caught before");
return;
}
@@ -553,7 +553,8 @@ void QXcbClipboard::handleSelectionRequest(xcb_selection_request_event_t *req)
QMimeData *d;
QClipboard::Mode mode = modeForAtom(req->selection);
if (mode > QClipboard::Selection) {
- qWarning() << "QXcbClipboard: Unknown selection" << connection()->atomName(req->selection);
+ qCWarning(lcQpaClipboard, "QXcbClipboard: Unknown selection %s",
+ connection()->atomName(req->selection).constData());
xcb_send_event(xcb_connection(), false, req->requestor, XCB_EVENT_MASK_NO_EVENT, (const char *)&event);
return;
}
@@ -561,14 +562,14 @@ void QXcbClipboard::handleSelectionRequest(xcb_selection_request_event_t *req)
d = m_clientClipboard[mode];
if (!d) {
- qWarning("QXcbClipboard: Cannot transfer data, no data available");
+ qCWarning(lcQpaClipboard, "QXcbClipboard: Cannot transfer data, no data available");
xcb_send_event(xcb_connection(), false, req->requestor, XCB_EVENT_MASK_NO_EVENT, (const char *)&event);
return;
}
if (m_timestamp[mode] == XCB_CURRENT_TIME // we don't own the selection anymore
|| (req->time != XCB_CURRENT_TIME && req->time < m_timestamp[mode])) {
- qWarning("QXcbClipboard: SelectionRequest too old");
+ qCDebug(lcQpaClipboard, "QXcbClipboard: SelectionRequest too old");
xcb_send_event(xcb_connection(), false, req->requestor, XCB_EVENT_MASK_NO_EVENT, (const char *)&event);
return;
}
@@ -623,7 +624,7 @@ void QXcbClipboard::handleSelectionRequest(xcb_selection_request_event_t *req)
property, XCB_ATOM_INTEGER, 32, 1, &m_timestamp[mode]);
ret = property;
} else {
- qWarning("QXcbClipboard: Invalid data timestamp");
+ qCWarning(lcQpaClipboard, "QXcbClipboard: Invalid data timestamp");
}
} else if (target == targetsAtom) {
ret = sendTargetsSelection(d, req->requestor, property);
@@ -728,7 +729,7 @@ bool QXcbClipboard::clipboardReadProperty(xcb_window_t win, xcb_atom_t property,
// recover -- this shouldn't normally happen, but it doesn't
// hurt to be defensive
if ((int)(buffer_offset + length) > buffer->size()) {
- qWarning("QXcbClipboard: buffer overflow");
+ qCWarning(lcQpaClipboard, "QXcbClipboard: buffer overflow");
length = buffer->size() - buffer_offset;
// escape loop
@@ -835,6 +836,8 @@ QByteArray QXcbClipboard::clipboardReadIncrementalProperty(xcb_window_t win, xcb
alloc_error = buf.size() != nbytes+1;
}
+ QElapsedTimer timer;
+ timer.start();
for (;;) {
connection()->flush();
xcb_generic_event_t *ge = waitForClipboardEvent(win, XCB_PROPERTY_NOTIFY);
@@ -870,9 +873,11 @@ QByteArray QXcbClipboard::clipboardReadIncrementalProperty(xcb_window_t win, xcb
tmp_buf.resize(0);
offset += length;
}
- } else {
- break;
}
+
+ const auto elapsed = timer.elapsed();
+ if (elapsed > clipboard_timeout)
+ break;
}
// timed out ... create a new requestor window, otherwise the requestor
@@ -921,4 +926,5 @@ QByteArray QXcbClipboard::getSelection(xcb_atom_t selection, xcb_atom_t target,
QT_END_NAMESPACE
+#include "moc_qxcbclipboard.cpp"
#include "qxcbclipboard.moc"
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index 9abdae6a7c..013ca7369f 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -71,6 +71,10 @@
#undef explicit
#include <xcb/xinput.h>
+#if QT_CONFIG(xcb_xlib)
+#include "qt_xlib_wrapper.h"
+#endif
+
QT_BEGIN_NAMESPACE
Q_LOGGING_CATEGORY(lcQpaXInput, "qt.qpa.input")
@@ -221,6 +225,12 @@ void QXcbConnection::printXcbEvent(const QLoggingCategory &log, const char *mess
}
#define CASE_PRINT_AND_RETURN(name) case name : PRINT_AND_RETURN(#name);
+#define XI_PRINT_AND_RETURN(name) { \
+ qCDebug(log, "%s | XInput Event(%s) | sequence: %d", message, name, sequence); \
+ return; \
+}
+#define XI_CASE_PRINT_AND_RETURN(name) case name : XI_PRINT_AND_RETURN(#name);
+
switch (response_type) {
CASE_PRINT_AND_RETURN( XCB_KEY_PRESS );
CASE_PRINT_AND_RETURN( XCB_KEY_RELEASE );
@@ -255,7 +265,44 @@ void QXcbConnection::printXcbEvent(const QLoggingCategory &log, const char *mess
CASE_PRINT_AND_RETURN( XCB_COLORMAP_NOTIFY );
CASE_PRINT_AND_RETURN( XCB_CLIENT_MESSAGE );
CASE_PRINT_AND_RETURN( XCB_MAPPING_NOTIFY );
- CASE_PRINT_AND_RETURN( XCB_GE_GENERIC );
+ case XCB_GE_GENERIC: {
+ if (hasXInput2() && isXIEvent(event)) {
+ auto *xiDeviceEvent = reinterpret_cast<const xcb_input_button_press_event_t*>(event); // qt_xcb_input_device_event_t
+ switch (xiDeviceEvent->event_type) {
+ XI_CASE_PRINT_AND_RETURN( XCB_INPUT_KEY_PRESS );
+ XI_CASE_PRINT_AND_RETURN( XCB_INPUT_KEY_RELEASE );
+ XI_CASE_PRINT_AND_RETURN( XCB_INPUT_BUTTON_PRESS );
+ XI_CASE_PRINT_AND_RETURN( XCB_INPUT_BUTTON_RELEASE );
+ XI_CASE_PRINT_AND_RETURN( XCB_INPUT_MOTION );
+ XI_CASE_PRINT_AND_RETURN( XCB_INPUT_ENTER );
+ XI_CASE_PRINT_AND_RETURN( XCB_INPUT_LEAVE );
+ XI_CASE_PRINT_AND_RETURN( XCB_INPUT_FOCUS_IN );
+ XI_CASE_PRINT_AND_RETURN( XCB_INPUT_FOCUS_OUT );
+ XI_CASE_PRINT_AND_RETURN( XCB_INPUT_HIERARCHY );
+ XI_CASE_PRINT_AND_RETURN( XCB_INPUT_PROPERTY );
+ XI_CASE_PRINT_AND_RETURN( XCB_INPUT_RAW_KEY_PRESS );
+ XI_CASE_PRINT_AND_RETURN( XCB_INPUT_RAW_KEY_RELEASE );
+ XI_CASE_PRINT_AND_RETURN( XCB_INPUT_RAW_BUTTON_PRESS );
+ XI_CASE_PRINT_AND_RETURN( XCB_INPUT_RAW_BUTTON_RELEASE );
+ XI_CASE_PRINT_AND_RETURN( XCB_INPUT_RAW_MOTION );
+ XI_CASE_PRINT_AND_RETURN( XCB_INPUT_TOUCH_BEGIN );
+ XI_CASE_PRINT_AND_RETURN( XCB_INPUT_TOUCH_UPDATE );
+ XI_CASE_PRINT_AND_RETURN( XCB_INPUT_TOUCH_END );
+ XI_CASE_PRINT_AND_RETURN( XCB_INPUT_TOUCH_OWNERSHIP );
+ XI_CASE_PRINT_AND_RETURN( XCB_INPUT_RAW_TOUCH_BEGIN );
+ XI_CASE_PRINT_AND_RETURN( XCB_INPUT_RAW_TOUCH_UPDATE );
+ XI_CASE_PRINT_AND_RETURN( XCB_INPUT_RAW_TOUCH_END );
+ XI_CASE_PRINT_AND_RETURN( XCB_INPUT_BARRIER_HIT );
+ XI_CASE_PRINT_AND_RETURN( XCB_INPUT_BARRIER_LEAVE );
+ default:
+ qCDebug(log, "%s | XInput Event(other type) | sequence: %d", message, sequence);
+ return;
+ }
+ } else {
+ qCDebug(log, "%s | %s(%d) | sequence: %d", message, "XCB_GE_GENERIC", response_type, sequence);
+ return;
+ }
+ }
}
// XFixes
if (isXFixesType(response_type, XCB_XFIXES_SELECTION_NOTIFY))
@@ -445,12 +492,12 @@ void QXcbConnection::printXcbError(const char *message, xcb_generic_error_t *err
uint clamped_error_code = qMin<uint>(error->error_code, (sizeof(xcb_errors) / sizeof(xcb_errors[0])) - 1);
uint clamped_major_code = qMin<uint>(error->major_code, (sizeof(xcb_protocol_request_codes) / sizeof(xcb_protocol_request_codes[0])) - 1);
- qCWarning(lcQpaXcb, "%s: %d (%s), sequence: %d, resource id: %d, major code: %d (%s), minor code: %d",
- message,
- int(error->error_code), xcb_errors[clamped_error_code],
- int(error->sequence), int(error->resource_id),
- int(error->major_code), xcb_protocol_request_codes[clamped_major_code],
- int(error->minor_code));
+ qCDebug(lcQpaXcb, "%s: %d (%s), sequence: %d, resource id: %d, major code: %d (%s), minor code: %d",
+ message,
+ int(error->error_code), xcb_errors[clamped_error_code],
+ int(error->sequence), int(error->resource_id),
+ int(error->major_code), xcb_protocol_request_codes[clamped_major_code],
+ int(error->minor_code));
}
static Qt::MouseButtons translateMouseButtons(int s)
@@ -755,8 +802,8 @@ xcb_timestamp_t QXcbConnection::getTimestamp()
{
// send a dummy event to myself to get the timestamp from X server.
xcb_window_t window = rootWindow();
- xcb_atom_t dummyAtom = atom(QXcbAtom::CLIP_TEMPORARY);
- xcb_change_property(xcb_connection(), XCB_PROP_MODE_APPEND, window, dummyAtom,
+ xcb_atom_t dummyAtom = atom(QXcbAtom::_QT_GET_TIMESTAMP);
+ xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, window, dummyAtom,
XCB_ATOM_INTEGER, 32, 0, nullptr);
connection()->flush();
@@ -788,14 +835,18 @@ xcb_timestamp_t QXcbConnection::getTimestamp()
xcb_timestamp_t timestamp = pn->time;
free(event);
- xcb_delete_property(xcb_connection(), window, dummyAtom);
-
return timestamp;
}
xcb_window_t QXcbConnection::getSelectionOwner(xcb_atom_t atom) const
{
- return Q_XCB_REPLY(xcb_get_selection_owner, xcb_connection(), atom)->owner;
+ auto reply = Q_XCB_REPLY(xcb_get_selection_owner, xcb_connection(), atom);
+ if (!reply) {
+ qCDebug(lcQpaXcb) << "failed to query selection owner";
+ return XCB_NONE;
+ }
+
+ return reply->owner;
}
xcb_window_t QXcbConnection::getQtSelectionOwner()
@@ -1019,6 +1070,10 @@ void QXcbConnection::processXcbEvents(QEventLoop::ProcessEventsFlags flags)
m_eventQueue->flushBufferedEvents();
}
+#if QT_CONFIG(xcb_xlib)
+ qt_XFlush(static_cast<Display *>(xlib_display()));
+#endif
+
xcb_flush(xcb_connection());
}
@@ -1150,3 +1205,5 @@ void QXcbConnectionGrabber::release()
}
QT_END_NAMESPACE
+
+#include "moc_qxcbconnection.cpp"
diff --git a/src/plugins/platforms/xcb/qxcbconnection_basic.cpp b/src/plugins/platforms/xcb/qxcbconnection_basic.cpp
index 18dee89adb..115a196769 100644
--- a/src/plugins/platforms/xcb/qxcbconnection_basic.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection_basic.cpp
@@ -179,7 +179,13 @@ xcb_atom_t QXcbBasicConnection::internAtom(const char *name)
if (!name || *name == 0)
return XCB_NONE;
- return Q_XCB_REPLY(xcb_intern_atom, m_xcbConnection, false, strlen(name), name)->atom;
+ auto reply = Q_XCB_REPLY(xcb_intern_atom, m_xcbConnection, false, strlen(name), name);
+ if (!reply) {
+ qCDebug(lcQpaXcb) << "failed to query intern atom: " << name;
+ return XCB_NONE;
+ }
+
+ return reply->atom;
}
QByteArray QXcbBasicConnection::atomName(xcb_atom_t atom)
@@ -424,3 +430,5 @@ void QXcbBasicConnection::initializeXKB()
}
QT_END_NAMESPACE
+
+#include "moc_qxcbconnection_basic.cpp"
diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
index 27a2526df1..1ced02f31d 100644
--- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
@@ -591,8 +591,12 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
event->event_type, xiDeviceEvent->sequence, xiDeviceEvent->detail,
fixed1616ToReal(xiDeviceEvent->event_x), fixed1616ToReal(xiDeviceEvent->event_y),
fixed1616ToReal(xiDeviceEvent->root_x), fixed1616ToReal(xiDeviceEvent->root_y),xiDeviceEvent->event);
- if (QXcbWindow *platformWindow = platformWindowFromId(xiDeviceEvent->event))
+ if (QXcbWindow *platformWindow = platformWindowFromId(xiDeviceEvent->event)) {
xi2ProcessTouch(xiDeviceEvent, platformWindow);
+ } else { // When the window cannot be matched, delete it from touchPoints
+ if (TouchDeviceData *dev = touchDeviceForId(xiDeviceEvent->sourceid))
+ dev->touchPoints.remove((xiDeviceEvent->detail % INT_MAX));
+ }
break;
}
} else if (xiEnterEvent && !xi2MouseEventsDisabled() && eventListener) {
@@ -645,7 +649,7 @@ void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindo
continue;
if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
qCDebug(lcQpaXInputEvents, " valuator %20s value %lf from range %lf -> %lf",
- atomName(vci.label).constData(), value, vci.min, vci.max);
+ atomName(atom(vci.label)).constData(), value, vci.min, vci.max);
if (value > vci.max)
value = vci.max;
if (value < vci.min)
diff --git a/src/plugins/platforms/xcb/qxcbcursor.cpp b/src/plugins/platforms/xcb/qxcbcursor.cpp
index 42c7a52bd4..4210bf428e 100644
--- a/src/plugins/platforms/xcb/qxcbcursor.cpp
+++ b/src/plugins/platforms/xcb/qxcbcursor.cpp
@@ -534,6 +534,8 @@ bool updateCursorTheme(void *dpy, const QByteArray &theme) {
Q_UNUSED(screen);
Q_UNUSED(name);
QXcbCursor *self = static_cast<QXcbCursor *>(handle);
+ self->m_cursorHash.clear();
+
updateCursorTheme(self->connection()->xlib_display(),property.toByteArray());
}
@@ -559,14 +561,16 @@ xcb_cursor_t QXcbCursor::createFontCursor(int cshape)
int cursorId = cursorIdForShape(cshape);
xcb_cursor_t cursor = XCB_NONE;
- // Try Xcursor first
#if QT_CONFIG(xcb_xlib) && QT_CONFIG(library)
+ if (m_screen->xSettings()->initialized())
+ m_screen->xSettings()->registerCallbackForProperty("Gtk/CursorThemeName",cursorThemePropertyChanged,this);
+
+ // Try Xcursor first
if (cshape >= 0 && cshape <= Qt::LastCursor) {
void *dpy = connection()->xlib_display();
cursor = loadCursor(dpy, cshape);
if (!cursor && !m_gtkCursorThemeInitialized && m_screen->xSettings()->initialized()) {
QByteArray gtkCursorTheme = m_screen->xSettings()->setting("Gtk/CursorThemeName").toByteArray();
- m_screen->xSettings()->registerCallbackForProperty("Gtk/CursorThemeName",cursorThemePropertyChanged,this);
if (updateCursorTheme(dpy,gtkCursorTheme)) {
cursor = loadCursor(dpy, cshape);
}
@@ -668,7 +672,8 @@ void QXcbCursor::setPos(const QPoint &pos)
{
QXcbVirtualDesktop *virtualDesktop = nullptr;
queryPointer(connection(), &virtualDesktop, nullptr);
- xcb_warp_pointer(xcb_connection(), XCB_NONE, virtualDesktop->root(), 0, 0, 0, 0, pos.x(), pos.y());
+ if (virtualDesktop)
+ xcb_warp_pointer(xcb_connection(), XCB_NONE, virtualDesktop->root(), 0, 0, 0, 0, pos.x(), pos.y());
xcb_flush(xcb_connection());
}
diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp
index e0aaabbbdf..299835ba1e 100644
--- a/src/plugins/platforms/xcb/qxcbdrag.cpp
+++ b/src/plugins/platforms/xcb/qxcbdrag.cpp
@@ -785,7 +785,7 @@ void QXcbDrag::handle_xdnd_position(QPlatformWindow *w, const xcb_client_message
QPoint p((e->data.data32[2] & 0xffff0000) >> 16, e->data.data32[2] & 0x0000ffff);
Q_ASSERT(w);
QRect geometry = w->geometry();
- p -= geometry.topLeft();
+ p -= w->isEmbedded() ? w->mapToGlobal(geometry.topLeft()) : geometry.topLeft();
if (!w || !w->window() || (w->window()->type() == Qt::Desktop))
return;
@@ -1041,21 +1041,30 @@ void QXcbDrag::handleDrop(QPlatformWindow *, const xcb_client_message_event_t *e
Qt::DropActions supported_drop_actions;
QMimeData *dropData = nullptr;
+ // this could be a same-application drop, just proxied due to
+ // some XEMBEDding, so try to find the real QMimeData used
+ // based on the timestamp for this drop.
+ int at = findTransactionByTime(target_time);
+ if (at != -1) {
+ qCDebug(lcQpaXDnd) << "found one transaction via findTransactionByTime()";
+ dropData = transactions.at(at).drag->mimeData();
+ // Can't use the source QMimeData if we need the image conversion code from xdndObtainData
+ if (dropData && dropData->hasImage())
+ dropData = 0;
+ }
+ // if we can't find it, then use the data in the drag manager
if (currentDrag()) {
- dropData = currentDrag()->mimeData();
+ if (!dropData)
+ dropData = currentDrag()->mimeData();
supported_drop_actions = Qt::DropActions(l[4]);
} else {
- dropData = m_dropData;
+ if (!dropData)
+ dropData = m_dropData;
supported_drop_actions = accepted_drop_action | toDropActions(drop_actions);
}
if (!dropData)
return;
- // ###
- // int at = findXdndDropTransactionByTime(target_time);
- // if (at != -1)
- // dropData = QDragManager::dragPrivate(X11->dndDropTransactions.at(at).object)->data;
- // if we can't find it, then use the data in the drag manager
auto buttons = currentDrag() ? b : connection()->queryMouseButtons();
auto modifiers = currentDrag() ? mods : connection()->queryKeyboardModifiers();
@@ -1064,7 +1073,12 @@ void QXcbDrag::handleDrop(QPlatformWindow *, const xcb_client_message_event_t *e
currentWindow.data(), dropData, currentPosition, supported_drop_actions,
buttons, modifiers);
- setExecutedDropAction(response.acceptedAction());
+ Qt::DropAction acceptedAaction = response.acceptedAction();
+ if (!response.isAccepted()) {
+ // Ignore a failed drag
+ acceptedAaction = Qt::IgnoreAction;
+ }
+ setExecutedDropAction(acceptedAaction);
xcb_client_message_event_t finished = {};
finished.response_type = XCB_CLIENT_MESSAGE;
@@ -1074,7 +1088,7 @@ void QXcbDrag::handleDrop(QPlatformWindow *, const xcb_client_message_event_t *e
finished.type = atom(QXcbAtom::XdndFinished);
finished.data.data32[0] = currentWindow ? xcb_window(currentWindow.data()) : XCB_NONE;
finished.data.data32[1] = response.isAccepted(); // flags
- finished.data.data32[2] = toXdndAction(response.acceptedAction());
+ finished.data.data32[2] = toXdndAction(acceptedAaction);
qCDebug(lcQpaXDnd) << "sending XdndFinished to source:" << xdnd_dragsource;
@@ -1280,6 +1294,7 @@ void QXcbDrag::handleSelectionRequest(const xcb_selection_request_event_t *event
bool QXcbDrag::dndEnable(QXcbWindow *w, bool on)
{
+ qCDebug(lcQpaXDnd) << "dndEnable" << w << on;
// Windows announce that they support the XDND protocol by creating a window property XdndAware.
if (on) {
QXcbWindow *window = nullptr;
diff --git a/src/plugins/platforms/xcb/qxcbeventdispatcher.cpp b/src/plugins/platforms/xcb/qxcbeventdispatcher.cpp
index 3cb2a5b5ef..eb0280cfb7 100644
--- a/src/plugins/platforms/xcb/qxcbeventdispatcher.cpp
+++ b/src/plugins/platforms/xcb/qxcbeventdispatcher.cpp
@@ -160,3 +160,5 @@ QAbstractEventDispatcher *QXcbEventDispatcher::createEventDispatcher(QXcbConnect
}
QT_END_NAMESPACE
+
+#include "moc_qxcbeventdispatcher.cpp"
diff --git a/src/plugins/platforms/xcb/qxcbeventqueue.cpp b/src/plugins/platforms/xcb/qxcbeventqueue.cpp
index 9f3c381216..14f53106e9 100644
--- a/src/plugins/platforms/xcb/qxcbeventqueue.cpp
+++ b/src/plugins/platforms/xcb/qxcbeventqueue.cpp
@@ -400,3 +400,5 @@ bool QXcbEventQueue::isCloseConnectionEvent(const xcb_generic_event_t *event)
}
QT_END_NAMESPACE
+
+#include "moc_qxcbeventqueue.cpp"
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
index e8286381a2..f43b2b66e1 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
@@ -441,7 +441,7 @@ static xkb_layout_index_t lockedGroup(quint16 state)
void QXcbKeyboard::updateXKBStateFromCore(quint16 state)
{
- if (m_config && !connection()->hasXKB()) {
+ if (m_config) {
struct xkb_state *xkbState = m_xkbState.get();
xkb_mod_mask_t modsDepressed = xkb_state_serialize_mods(xkbState, XKB_STATE_MODS_DEPRESSED);
xkb_mod_mask_t modsLatched = xkb_state_serialize_mods(xkbState, XKB_STATE_MODS_LATCHED);
@@ -463,7 +463,7 @@ void QXcbKeyboard::updateXKBStateFromCore(quint16 state)
void QXcbKeyboard::updateXKBStateFromXI(void *modInfo, void *groupInfo)
{
- if (m_config && !connection()->hasXKB()) {
+ if (m_config) {
auto *mods = static_cast<xcb_input_modifier_info_t *>(modInfo);
auto *group = static_cast<xcb_input_group_info_t *>(groupInfo);
const xkb_state_component changedComponents
diff --git a/src/plugins/platforms/xcb/qxcbmime.cpp b/src/plugins/platforms/xcb/qxcbmime.cpp
index 0b3219f792..bbce69614b 100644
--- a/src/plugins/platforms/xcb/qxcbmime.cpp
+++ b/src/plugins/platforms/xcb/qxcbmime.cpp
@@ -319,3 +319,5 @@ xcb_atom_t QXcbMime::mimeAtomForFormat(QXcbConnection *connection, const QString
}
QT_END_NAMESPACE
+
+#include "moc_qxcbmime.cpp"
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
index 30fa6864ac..c96bcb1dab 100644
--- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
@@ -675,3 +675,5 @@ QString QXcbNativeInterface::dumpNativeWindows(WId root) const
}
QT_END_NAMESPACE
+
+#include "moc_qxcbnativeinterface.cpp"
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.h b/src/plugins/platforms/xcb/qxcbnativeinterface.h
index 4656f46be5..f80f23f0cb 100644
--- a/src/plugins/platforms/xcb/qxcbnativeinterface.h
+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.h
@@ -133,8 +133,6 @@ signals:
private:
const QByteArray m_nativeEventType = QByteArrayLiteral("xcb_generic_event_t");
- xcb_atom_t m_sysTraySelectionAtom = XCB_ATOM_NONE;
-
static QXcbScreen *qPlatformScreenForWindow(QWindow *window);
QList<QXcbNativeInterfaceHandler *> m_handlers;
diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp
index 707896b457..9edba7257e 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.cpp
+++ b/src/plugins/platforms/xcb/qxcbscreen.cpp
@@ -114,17 +114,13 @@ QXcbVirtualDesktop::QXcbVirtualDesktop(QXcbConnection *connection, xcb_screen_t
}
auto dpiChangedCallback = [](QXcbVirtualDesktop *desktop, const QByteArray &, const QVariant &property, void *) {
- bool ok;
- int dpiTimes1k = property.toInt(&ok);
- if (!ok)
+ if (!desktop->setDpiFromXSettings(property))
return;
- int dpi = dpiTimes1k / 1024;
- if (desktop->m_forcedDpi == dpi)
- return;
- desktop->m_forcedDpi = dpi;
+ const auto dpi = desktop->forcedDpi();
for (QXcbScreen *screen : desktop->connection()->screens())
QWindowSystemInterface::handleScreenLogicalDotsPerInchChange(screen->QPlatformScreen::screen(), dpi, dpi);
};
+ setDpiFromXSettings(xSettings()->setting("Xft/DPI"));
xSettings()->registerCallbackForProperty("Xft/DPI", dpiChangedCallback, nullptr);
}
@@ -275,7 +271,7 @@ void QXcbVirtualDesktop::handleScreenChange(xcb_randr_screen_change_notify_event
_NET_WORKAREA means with multiple attached monitors. This gets worse when monitors have
different dimensions and/or screens are not virtually aligned. In Qt we want the available
geometry per monitor (QScreen), not desktop (represented by _NET_WORKAREA). WM specification
- does not have an atom for this. Thus, QScreen is limted by the lack of support from the
+ does not have an atom for this. Thus, QScreen is limited by the lack of support from the
underlying system.
One option could be that Qt does WM's job of calculating this by subtracting geometries of
@@ -425,6 +421,19 @@ void QXcbVirtualDesktop::readXResources()
}
}
+bool QXcbVirtualDesktop::setDpiFromXSettings(const QVariant &property)
+{
+ bool ok;
+ int dpiTimes1k = property.toInt(&ok);
+ if (!ok)
+ return false;
+ int dpi = dpiTimes1k / 1024;
+ if (m_forcedDpi == dpi)
+ return false;
+ m_forcedDpi = dpi;
+ return true;
+}
+
QSurfaceFormat QXcbVirtualDesktop::surfaceFormatFor(const QSurfaceFormat &format) const
{
const xcb_visualid_t xcb_visualid = connection()->hasDefaultVisualId() ? connection()->defaultVisualId()
diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h
index bf48dd5d5b..c3a59dc9d1 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.h
+++ b/src/plugins/platforms/xcb/qxcbscreen.h
@@ -118,6 +118,8 @@ private:
QByteArray &stringValue);
void readXResources();
+ bool setDpiFromXSettings(const QVariant &property);
+
xcb_screen_t *m_screen;
const int m_number;
QList<QPlatformScreen *> m_screens;
diff --git a/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp b/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp
index ff5ad98cd2..7f1fc7f5eb 100644
--- a/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp
+++ b/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp
@@ -176,3 +176,5 @@ xcb_visualid_t QXcbSystemTrayTracker::netSystemTrayVisual()
}
QT_END_NAMESPACE
+
+#include "moc_qxcbsystemtraytracker.cpp"
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 050182537d..45bac8ee85 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -93,6 +93,8 @@ enum {
QT_BEGIN_NAMESPACE
+Q_LOGGING_CATEGORY(lcQpaWindow, "qt.qpa.window");
+
Q_DECLARE_TYPEINFO(xcb_rectangle_t, Q_PRIMITIVE_TYPE);
#undef FocusIn
@@ -258,7 +260,7 @@ enum : quint32 {
| XCB_EVENT_MASK_POINTER_MOTION,
transparentForInputEventMask = baseEventMask
- | XCB_EVENT_MASK_VISIBILITY_CHANGE | XCB_EVENT_MASK_RESIZE_REDIRECT
+ | XCB_EVENT_MASK_VISIBILITY_CHANGE
| XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT
| XCB_EVENT_MASK_COLOR_MAP_CHANGE | XCB_EVENT_MASK_OWNER_GRAB_BUTTON
};
@@ -297,11 +299,6 @@ void QXcbWindow::create()
return;
}
- QPlatformWindow::setGeometry(rect);
-
- if (platformScreen != currentScreen)
- QWindowSystemInterface::handleWindowScreenChanged(window(), platformScreen->QPlatformScreen::screen());
-
const QSize minimumSize = windowMinimumSize();
if (rect.width() > 0 || rect.height() > 0) {
rect.setWidth(qBound(1, rect.width(), XCOORD_MAX));
@@ -313,6 +310,11 @@ void QXcbWindow::create()
rect.setHeight(QHighDpi::toNativePixels(int(defaultWindowHeight), platformScreen->QPlatformScreen::screen()));
}
+ QPlatformWindow::setGeometry(rect);
+
+ if (platformScreen != currentScreen)
+ QWindowSystemInterface::handleWindowScreenChanged(window(), platformScreen->QPlatformScreen::screen());
+
xcb_window_t xcb_parent_id = platformScreen->root();
if (parent()) {
xcb_parent_id = static_cast<QXcbWindow *>(parent())->xcb_window();
@@ -555,6 +557,7 @@ void QXcbWindow::destroy()
}
m_mapped = false;
+ m_recreationReasons = RecreationNotNeeded;
if (m_pendingSyncRequest)
m_pendingSyncRequest->invalidate();
@@ -689,6 +692,11 @@ void QXcbWindow::setVisible(bool visible)
void QXcbWindow::show()
{
if (window()->isTopLevel()) {
+ if (m_recreationReasons != RecreationNotNeeded) {
+ qCDebug(lcQpaWindow) << "QXcbWindow: need to recreate window" << window() << m_recreationReasons;
+ create();
+ m_recreationReasons = RecreationNotNeeded;
+ }
// update WM_NORMAL_HINTS
propagateSizeHints();
@@ -698,7 +706,7 @@ void QXcbWindow::show()
if (isTransient(window())) {
const QWindow *tp = window()->transientParent();
if (tp && tp->handle())
- transientXcbParent = static_cast<const QXcbWindow *>(tp->handle())->winId();
+ transientXcbParent = tp->handle()->winId();
// Default to client leader if there is no transient parent, else modal dialogs can
// be hidden by their parents.
if (!transientXcbParent)
@@ -904,6 +912,12 @@ void QXcbWindow::setWindowFlags(Qt::WindowFlags flags)
if (type == Qt::Popup)
flags |= Qt::X11BypassWindowManagerHint;
+ Qt::WindowFlags oldflags = window()->flags();
+ if ((oldflags & Qt::WindowStaysOnTopHint) != (flags & Qt::WindowStaysOnTopHint))
+ m_recreationReasons |= WindowStaysOnTopHintChanged;
+ if ((oldflags & Qt::WindowStaysOnBottomHint) != (flags & Qt::WindowStaysOnBottomHint))
+ m_recreationReasons |= WindowStaysOnBottomHintChanged;
+
const quint32 mask = XCB_CW_OVERRIDE_REDIRECT | XCB_CW_EVENT_MASK;
const quint32 values[] = {
// XCB_CW_OVERRIDE_REDIRECT
@@ -1330,6 +1344,12 @@ void QXcbWindow::setWindowIcon(const QIcon &icon)
}
if (!icon_data.isEmpty()) {
+ // Ignore icon exceeding maximum xcb request length
+ if (size_t(icon_data.size()) > xcb_get_maximum_request_length(xcb_connection())) {
+ qWarning("Ignoring window icon: Size %d exceeds maximum xcb request length %u.",
+ icon_data.size(), xcb_get_maximum_request_length(xcb_connection()));
+ return;
+ }
xcb_change_property(xcb_connection(),
XCB_PROP_MODE_REPLACE,
m_window,
@@ -1619,7 +1639,7 @@ void QXcbWindow::setWmWindowType(QXcbWindowFunctions::WmWindowTypes types, Qt::W
break;
}
- if ((flags & Qt::FramelessWindowHint) && !(type & QXcbWindowFunctions::KdeOverride)) {
+ if ((flags & Qt::FramelessWindowHint) && !(types & QXcbWindowFunctions::KdeOverride)) {
// override netwm type - quick and easy for KDE noborder
atoms.append(atom(QXcbAtom::_KDE_NET_WM_WINDOW_TYPE_OVERRIDE));
}
diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h
index 6f5c1f5ed9..8de486c6d2 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.h
+++ b/src/plugins/platforms/xcb/qxcbwindow.h
@@ -74,6 +74,13 @@ public:
Q_DECLARE_FLAGS(NetWmStates, NetWmState)
+ enum RecreationReason {
+ RecreationNotNeeded = 0,
+ WindowStaysOnTopHintChanged = 0x1,
+ WindowStaysOnBottomHintChanged = 0x2
+ };
+ Q_DECLARE_FLAGS(RecreationReasons, RecreationReason)
+
QXcbWindow(QWindow *window);
~QXcbWindow();
@@ -281,6 +288,8 @@ protected:
int m_swapInterval = -1;
qreal m_sizeHintsScaleFactor = 1.0;
+
+ RecreationReasons m_recreationReasons = RecreationNotNeeded;
};
class QXcbForeignWindow : public QXcbWindow
diff --git a/src/plugins/platforms/xcb/xcb_qpa_lib.pro b/src/plugins/platforms/xcb/xcb_qpa_lib.pro
index a5d05faa9c..587bbcef68 100644
--- a/src/plugins/platforms/xcb/xcb_qpa_lib.pro
+++ b/src/plugins/platforms/xcb/xcb_qpa_lib.pro
@@ -70,6 +70,8 @@ DEFINES += QT_BUILD_XCB_PLUGIN
qtConfig(xcb-xlib) {
QMAKE_USE += xcb_xlib
+ SOURCES += qt_xlib_wrapper.c
+ HEADERS += qt_xlib_wrapper.h
}
qtConfig(xcb-sm) {