summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/xcb
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2016-10-13 09:49:38 +0200
committerLiang Qi <liang.qi@qt.io>2016-10-13 09:49:38 +0200
commitdfc177e3a99dd593db4b1e9445d6243ce75ebf07 (patch)
tree4e33c7be90a44642e672fff22ea163b500ff3aef /src/plugins/platforms/xcb
parent72efb2e6f4af2fd909daaf9104f09fd1425acfb0 (diff)
parent1d6eb70dcec105af28d6a5e9b59d56c895c70389 (diff)
Merge remote-tracking branch 'origin/5.8' into dev
Conflicts: qmake/library/qmakeevaluator.cpp (cherry picked from commit 1af6dc2c8fb4d91400fddc5050166f972ae57c9a in qttools) src/corelib/kernel/qcore_mac_objc.mm src/gui/painting/qcolor.h src/plugins/platforms/cocoa/qcocoawindow.mm Change-Id: I5b3ec468a5a9a73911b528d3d24ff8e19f339f31
Diffstat (limited to 'src/plugins/platforms/xcb')
-rw-r--r--src/plugins/platforms/xcb/README10
-rw-r--r--src/plugins/platforms/xcb/gl_integrations/xcb_glx/xcb_glx.pro1
-rw-r--r--src/plugins/platforms/xcb/qxcbclipboard.cpp12
-rw-r--r--src/plugins/platforms/xcb/qxcbclipboard.h2
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection_xi2.cpp21
-rw-r--r--src/plugins/platforms/xcb/qxcbcursor.cpp24
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.cpp5
-rw-r--r--src/plugins/platforms/xcb/qxcbnativeinterface.cpp4
-rw-r--r--src/plugins/platforms/xcb/qxcbnativeinterface.h1
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp48
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.h4
-rw-r--r--src/plugins/platforms/xcb/xcb-static/xcb-static.pro3
-rw-r--r--src/plugins/platforms/xcb/xcb_qpa_lib.pro3
13 files changed, 78 insertions, 60 deletions
diff --git a/src/plugins/platforms/xcb/README b/src/plugins/platforms/xcb/README
index 15cf4cf241..5efc9b7f99 100644
--- a/src/plugins/platforms/xcb/README
+++ b/src/plugins/platforms/xcb/README
@@ -21,3 +21,13 @@ REDUCING RUNTIME DEPENDENCIES
The '-qt-xcb' configure option can be used to get rid of most xcb- dependencies. Only libxcb will
still be linked dynamically, since it will be most likely be pulled in via other dependencies anyway.
This should allow for binaries that are portable across most modern Linux distributions.
+
+PACKAGE VERSION REQUIREMENTS
+
+When using touch input via XInput 2.2 or higher, there is a potential issue on systems that ship with
+a libXi older than 1.7.4. This is because XIAllowTouchEvents can deadlock with libXi 1.7.3 and earlier.
+When touch events are never received, this is not an issue, so plain mouse/keyboard systems are not affected.
+See http://lists.x.org/archives/xorg-devel/2014-July/043059.html for details on the libXi patch.
+Qt versions before 5.8 attempted to recognize this scenario based on the pkg-config package version and skip
+the call. This has been removed starting from 5.8 since relying on pkg-config package versions is unsafe given
+that Qt must also support systems with limited or incomplete pkg-config setups.
diff --git a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/xcb_glx.pro b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/xcb_glx.pro
index d82a1f2d17..e52677d091 100644
--- a/src/plugins/platforms/xcb/gl_integrations/xcb_glx/xcb_glx.pro
+++ b/src/plugins/platforms/xcb/gl_integrations/xcb_glx/xcb_glx.pro
@@ -10,7 +10,6 @@ qtConfig(xcb-glx) {
DEFINES += XCB_HAS_XCB_GLX
QMAKE_USE += xcb_glx
}
-QMAKE_USE += xcb
LIBS += $$QMAKE_LIBS_DYNLOAD
diff --git a/src/plugins/platforms/xcb/qxcbclipboard.cpp b/src/plugins/platforms/xcb/qxcbclipboard.cpp
index b95ad4b5c9..f9c32cd0a4 100644
--- a/src/plugins/platforms/xcb/qxcbclipboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbclipboard.cpp
@@ -275,8 +275,6 @@ QXcbClipboard::QXcbClipboard(QXcbConnection *c)
{
Q_ASSERT(QClipboard::Clipboard == 0);
Q_ASSERT(QClipboard::Selection == 1);
- m_xClipboard[QClipboard::Clipboard] = 0;
- m_xClipboard[QClipboard::Selection] = 0;
m_clientClipboard[QClipboard::Clipboard] = 0;
m_clientClipboard[QClipboard::Selection] = 0;
m_timestamp[QClipboard::Clipboard] = XCB_CURRENT_TIME;
@@ -329,6 +327,10 @@ QXcbClipboard::~QXcbClipboard()
}
free(reply);
}
+
+ if (m_clientClipboard[QClipboard::Clipboard] != m_clientClipboard[QClipboard::Selection])
+ delete m_clientClipboard[QClipboard::Clipboard];
+ delete m_clientClipboard[QClipboard::Selection];
}
void QXcbClipboard::incrTransactionPeeker(xcb_generic_event_t *ge, bool &accepted)
@@ -378,9 +380,9 @@ QMimeData * QXcbClipboard::mimeData(QClipboard::Mode mode)
return m_clientClipboard[mode];
} else {
if (!m_xClipboard[mode])
- m_xClipboard[mode] = new QXcbClipboardMime(mode, this);
+ m_xClipboard[mode].reset(new QXcbClipboardMime(mode, this));
- return m_xClipboard[mode];
+ return m_xClipboard[mode].data();
}
}
@@ -730,7 +732,7 @@ void QXcbClipboard::handleXFixesSelectionRequest(xcb_xfixes_selection_notify_eve
// here we care only about the xfixes events that come from non Qt processes
if (event->owner != XCB_NONE && event->owner != owner()) {
if (!m_xClipboard[mode]) {
- m_xClipboard[mode] = new QXcbClipboardMime(mode, this);
+ m_xClipboard[mode].reset(new QXcbClipboardMime(mode, this));
} else {
m_xClipboard[mode]->reset();
}
diff --git a/src/plugins/platforms/xcb/qxcbclipboard.h b/src/plugins/platforms/xcb/qxcbclipboard.h
index 58c7f32c4c..ffd565c56f 100644
--- a/src/plugins/platforms/xcb/qxcbclipboard.h
+++ b/src/plugins/platforms/xcb/qxcbclipboard.h
@@ -98,7 +98,7 @@ private:
QClipboard::Mode modeForAtom(xcb_atom_t atom) const;
// Selection and Clipboard
- QXcbClipboardMime *m_xClipboard[2];
+ QScopedPointer<QXcbClipboardMime> m_xClipboard[2];
QMimeData *m_clientClipboard[2];
xcb_timestamp_t m_timestamp[2];
diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
index 1147fc82b2..93f8db92bf 100644
--- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
@@ -697,26 +697,7 @@ void QXcbConnection::xi2ProcessTouch(void *xiDevEvent, QXcbWindow *platformWindo
if (m_xiGrab) {
// XIAllowTouchEvents deadlocks with libXi < 1.7.4 (this has nothing to do with the XI2 versions like 2.2)
// http://lists.x.org/archives/xorg-devel/2014-July/043059.html
-#ifndef XCB_USE_XINPUT2
- static bool allowTouchWarningShown = false;
- if (!allowTouchWarningShown) {
- allowTouchWarningShown = true;
- qWarning("Skipping XIAllowTouchEvents() because it was not possible to detect libXi version at build time."
- " Minimum libXi version required is 1.7.4."
- " Expect issues with touch behavior.");
- }
-#elif QT_LIBRARY_VERSION(xinput2) < QT_VERSION_CHECK(1, 7, 4)
- static bool allowTouchWarningShown = false;
- if (!allowTouchWarningShown) {
- allowTouchWarningShown = true;
- qWarning("Skipping XIAllowTouchEvents() due to not having libXi >= 1.7.4."
- " libXi version at build time was %d.%d.%d."
- " Expect issues with touch behavior.",
- QT_LIBRARY_VERSION_MAJOR(xinput2),
- QT_LIBRARY_VERSION_MINOR(xinput2),
- QT_LIBRARY_VERSION_PATCH(xinput2));
- }
-#else
+#ifdef XCB_USE_XINPUT2
XIAllowTouchEvents(static_cast<Display *>(m_xlib_display), xiDeviceEvent->deviceid,
xiDeviceEvent->detail, xiDeviceEvent->event, XIAcceptTouch);
#endif
diff --git a/src/plugins/platforms/xcb/qxcbcursor.cpp b/src/plugins/platforms/xcb/qxcbcursor.cpp
index 11e0c998b1..4de4be43d1 100644
--- a/src/plugins/platforms/xcb/qxcbcursor.cpp
+++ b/src/plugins/platforms/xcb/qxcbcursor.cpp
@@ -359,17 +359,27 @@ void QXcbCursor::changeCursor(QCursor *cursor, QWindow *widget)
return;
xcb_cursor_t c = XCB_CURSOR_NONE;
+ bool isBitmapCursor = false;
+
if (cursor) {
- 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));
+ const Qt::CursorShape shape = cursor->shape();
+ isBitmapCursor = shape == Qt::BitmapCursor;
+
+ if (!isBitmapCursor) {
+ const QXcbCursorCacheKey key(*cursor);
+ CursorHash::iterator it = m_cursorHash.find(key);
+ if (it == m_cursorHash.end()) {
+ it = m_cursorHash.insert(key, createFontCursor(shape));
+ }
+ c = it.value();
+ } else {
+ // Do not cache bitmap cursors, as otherwise they have unclear
+ // lifetime (we effectively leak xcb_cursor_t).
+ c = createBitmapCursor(cursor);
}
- c = it.value();
}
- w->setCursor(c);
+ w->setCursor(c, isBitmapCursor);
}
static int cursorIdForShape(int cshape)
diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp
index 802f7b85ce..b0c5ac79f9 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.cpp
+++ b/src/plugins/platforms/xcb/qxcbintegration.cpp
@@ -61,13 +61,8 @@
#include <stdio.h>
-//this has to be included before egl, since egl pulls in X headers
#include <QtGui/private/qguiapplication_p.h>
-#ifdef XCB_USE_EGL
-# include <QtPlatformSupport/private/qt_egl_p.h>
-#endif
-
#ifdef XCB_USE_XLIB
#include <X11/Xlib.h>
#endif
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
index 189ec53050..b1575cbee4 100644
--- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp
@@ -57,10 +57,6 @@
#include <QtPlatformHeaders/qxcbintegrationfunctions.h>
#include <QtPlatformHeaders/qxcbscreenfunctions.h>
-#ifndef QT_NO_DBUS
-#include "QtPlatformSupport/private/qdbusmenuconnection_p.h"
-#endif
-
#ifdef XCB_USE_XLIB
# include <X11/Xlib.h>
#else
diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.h b/src/plugins/platforms/xcb/qxcbnativeinterface.h
index 8728b6e937..acecbf4116 100644
--- a/src/plugins/platforms/xcb/qxcbnativeinterface.h
+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.h
@@ -53,7 +53,6 @@ class QWidget;
class QXcbScreen;
class QXcbConnection;
class QXcbNativeInterfaceHandler;
-class QDBusMenuConnection;
class Q_XCB_EXPORT QXcbNativeInterface : public QPlatformNativeInterface
{
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index c81858c408..ee7bfd6c53 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -258,7 +258,7 @@ static inline XTextProperty* qstringToXTP(Display *dpy, const QString& s)
free_prop = true;
}
-#ifndef QT_NO_TEXTCODEC
+#if QT_CONFIG(textcodec)
static const QTextCodec* mapper = QTextCodec::codecForLocale();
int errCode = 0;
if (mapper) {
@@ -274,6 +274,7 @@ static inline XTextProperty* qstringToXTP(Display *dpy, const QString& s)
mapper = QTextCodec::codecForName("latin1");
if (!mapper || !mapper->canEncode(s))
return Q_NULLPTR;
+#endif
static QByteArray qcs;
qcs = s.toLatin1();
tp.value = (uchar*)qcs.data();
@@ -281,6 +282,7 @@ static inline XTextProperty* qstringToXTP(Display *dpy, const QString& s)
tp.format = 8;
tp.nitems = qcs.length();
free_prop = false;
+#if QT_CONFIG(textcodec)
}
#endif
return &tp;
@@ -326,6 +328,7 @@ QXcbWindow::QXcbWindow(QWindow *window)
, m_lastWindowStateEvent(-1)
, m_syncState(NoSyncNeeded)
, m_pendingSyncRequest(0)
+ , m_currentBitmapCursor(XCB_CURSOR_NONE)
{
setConnection(xcbScreen()->connection());
}
@@ -600,6 +603,9 @@ void QXcbWindow::create()
QXcbWindow::~QXcbWindow()
{
+ if (m_currentBitmapCursor != XCB_CURSOR_NONE) {
+ xcb_free_cursor(xcb_connection(), m_currentBitmapCursor);
+ }
if (window()->type() != Qt::ForeignWindow)
destroy();
else {
@@ -2416,6 +2422,17 @@ static inline int fixed1616ToInt(FP1616 val)
return int((qreal(val >> 16)) + (val & 0xFFFF) / (qreal)0xFFFF);
}
+void QXcbWindow::handleXIMouseButtonState(const xcb_ge_event_t *event)
+{
+ QXcbConnection *conn = connection();
+ const xXIDeviceEvent *ev = reinterpret_cast<const xXIDeviceEvent *>(event);
+ if (ev->buttons_len > 0) {
+ unsigned char *buttonMask = (unsigned char *) &ev[1];
+ for (int i = 1; i <= 15; ++i)
+ conn->setButton(conn->translateMouseButton(i), XIMaskIsSet(buttonMask, i));
+ }
+}
+
// With XI 2.2+ press/release/motion comes here instead of the above handlers.
void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event, Qt::MouseEventSource source)
{
@@ -2431,12 +2448,6 @@ void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event, Qt::MouseEventSource
const Qt::MouseButton button = conn->xiToQtMouseButton(ev->detail);
- if (ev->buttons_len > 0) {
- unsigned char *buttonMask = (unsigned char *) &ev[1];
- for (int i = 1; i <= 15; ++i)
- conn->setButton(conn->translateMouseButton(i), XIMaskIsSet(buttonMask, i));
- }
-
const char *sourceName = 0;
if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled())) {
const QMetaObject *metaObject = qt_getEnumMetaObject(source);
@@ -2446,18 +2457,23 @@ void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event, Qt::MouseEventSource
switch (ev->evtype) {
case XI_ButtonPress:
+ handleXIMouseButtonState(event);
if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
qCDebug(lcQpaXInputEvents, "XI2 mouse press, button %d, time %d, source %s", button, ev->time, sourceName);
conn->setButton(button, true);
handleButtonPressEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time, source);
break;
case XI_ButtonRelease:
+ handleXIMouseButtonState(event);
if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
qCDebug(lcQpaXInputEvents, "XI2 mouse release, button %d, time %d, source %s", button, ev->time, sourceName);
conn->setButton(button, false);
handleButtonReleaseEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time, source);
break;
case XI_Motion:
+ // Here we do NOT call handleXIMouseButtonState because we don't expect button state change to be bundled with motion.
+ // When a touchscreen is pressed, an XI_Motion event occurs in which XIMaskIsSet says the left button is pressed,
+ // but we don't want QGuiApplicationPrivate::processMouseEvent() to react by generating a mouse press event.
if (Q_UNLIKELY(lcQpaXInputEvents().isDebugEnabled()))
qCDebug(lcQpaXInputEvents, "XI2 mouse motion %d,%d, time %d, source %s", event_x, event_y, ev->time, sourceName);
handleMotionNotifyEvent(event_x, event_y, root_x, root_y, modifiers, ev->time, source);
@@ -2669,10 +2685,22 @@ bool QXcbWindow::setMouseGrabEnabled(bool grab)
return result;
}
-void QXcbWindow::setCursor(xcb_cursor_t cursor)
+void QXcbWindow::setCursor(xcb_cursor_t cursor, bool isBitmapCursor)
{
- xcb_change_window_attributes(xcb_connection(), m_window, XCB_CW_CURSOR, &cursor);
- xcb_flush(xcb_connection());
+ xcb_connection_t *conn = xcb_connection();
+
+ xcb_change_window_attributes(conn, m_window, XCB_CW_CURSOR, &cursor);
+ xcb_flush(conn);
+
+ if (m_currentBitmapCursor != XCB_CURSOR_NONE) {
+ xcb_free_cursor(conn, m_currentBitmapCursor);
+ }
+
+ if (isBitmapCursor) {
+ m_currentBitmapCursor = cursor;
+ } else {
+ m_currentBitmapCursor = XCB_CURSOR_NONE;
+ }
}
void QXcbWindow::windowEvent(QEvent *event)
diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h
index f62938ba8a..92f3f7a67c 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.h
+++ b/src/plugins/platforms/xcb/qxcbwindow.h
@@ -103,7 +103,7 @@ public:
bool setKeyboardGrabEnabled(bool grab) Q_DECL_OVERRIDE;
bool setMouseGrabEnabled(bool grab) Q_DECL_OVERRIDE;
- void setCursor(xcb_cursor_t cursor);
+ void setCursor(xcb_cursor_t cursor, bool isBitmapCursor);
QSurfaceFormat format() const Q_DECL_OVERRIDE;
@@ -139,6 +139,7 @@ public:
void handleFocusOutEvent(const xcb_focus_out_event_t *event) Q_DECL_OVERRIDE;
void handlePropertyNotifyEvent(const xcb_property_notify_event_t *event) Q_DECL_OVERRIDE;
#ifdef XCB_USE_XINPUT22
+ void handleXIMouseButtonState(const xcb_ge_event_t *);
void handleXIMouseEvent(xcb_ge_event_t *, Qt::MouseEventSource source = Qt::MouseEventNotSynthesized) Q_DECL_OVERRIDE;
void handleXIEnterLeave(xcb_ge_event_t *) Q_DECL_OVERRIDE;
#endif
@@ -271,6 +272,7 @@ protected:
SyncState m_syncState;
QXcbSyncWindowRequest *m_pendingSyncRequest;
+ xcb_cursor_t m_currentBitmapCursor;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/xcb-static/xcb-static.pro b/src/plugins/platforms/xcb/xcb-static/xcb-static.pro
index 20481e4834..a1dec2b0b5 100644
--- a/src/plugins/platforms/xcb/xcb-static/xcb-static.pro
+++ b/src/plugins/platforms/xcb/xcb-static/xcb-static.pro
@@ -11,8 +11,7 @@ XCB_DIR = ../../../../3rdparty/xcb
INCLUDEPATH += $$XCB_DIR/include $$XCB_DIR/include/xcb $$XCB_DIR/sysinclude
-QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_XCB
-QMAKE_CFLAGS += $$QMAKE_CFLAGS_XCB
+QMAKE_USE += xcb/nolink
# ignore compiler warnings in 3rdparty code
QMAKE_CFLAGS_STATIC_LIB+=-w
diff --git a/src/plugins/platforms/xcb/xcb_qpa_lib.pro b/src/plugins/platforms/xcb/xcb_qpa_lib.pro
index ec0fa68871..246bb1f118 100644
--- a/src/plugins/platforms/xcb/xcb_qpa_lib.pro
+++ b/src/plugins/platforms/xcb/xcb_qpa_lib.pro
@@ -66,9 +66,6 @@ include(gl_integrations/gl_integrations.pri)
CONFIG += qpa/genericunixfontdatabase
-qtConfig(dbus-linked): \
- QT += dbus
-
!qtConfig(system-xcb) {
DEFINES += XCB_USE_RENDER
XCB_DIR = ../../../3rdparty/xcb