diff --git a/0001-Fix-QWidget-setWindowRole.patch b/0001-Fix-QWidget-setWindowRole.patch deleted file mode 100644 index f126bdc..0000000 --- a/0001-Fix-QWidget-setWindowRole.patch +++ /dev/null @@ -1,165 +0,0 @@ -From 5944a751857de997ee674a90c2e35ff3adaa655b Mon Sep 17 00:00:00 2001 -From: Alexander Volkov -Date: Mon, 8 Jun 2015 14:35:22 +0300 -Subject: [PATCH] Fix QWidget::setWindowRole() - -Introduce QXcbWindowFunctions::setWmWindowRole() and call it either from -the implementation of QWidget::setWindowRole() or after the creation of -the corresponding QWidgetWindow. - -Change-Id: I143450f4673dd707bb491c1d0f0e8b61d564283d -Task-number: QTBUG-45484 ---- - .../xcbfunctions/qxcbwindowfunctions.h | 10 ++++++++++ - src/plugins/platforms/xcb/qxcbnativeinterface.cpp | 3 +++ - src/plugins/platforms/xcb/qxcbwindow.cpp | 21 +++++++++++++++++++++ - src/plugins/platforms/xcb/qxcbwindow.h | 2 ++ - src/widgets/kernel/qwidget.cpp | 12 +++++++----- - 5 files changed, 43 insertions(+), 5 deletions(-) - -diff --git a/src/platformheaders/xcbfunctions/qxcbwindowfunctions.h b/src/platformheaders/xcbfunctions/qxcbwindowfunctions.h -index ae05cf5..a7fe8d9 100644 ---- a/src/platformheaders/xcbfunctions/qxcbwindowfunctions.h -+++ b/src/platformheaders/xcbfunctions/qxcbwindowfunctions.h -@@ -73,6 +73,16 @@ public: - func(window, type); - } - -+ typedef void (*SetWmWindowRole)(QWindow *window, const QByteArray &role); -+ static const QByteArray setWmWindowRoleIdentifier() { return QByteArrayLiteral("XcbSetWmWindowRole"); } -+ -+ static void setWmWindowRole(QWindow *window, const QByteArray &role) -+ { -+ SetWmWindowRole func = reinterpret_cast(QGuiApplication::platformFunction(setWmWindowRoleIdentifier())); -+ if (func) -+ func(window, role); -+ } -+ - typedef uint (*VisualId)(QWindow *window); - static const QByteArray visualIdIdentifier() { return QByteArrayLiteral("XcbVisualId"); } - -diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp -index 8bf9003..3cfdbde 100644 ---- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp -+++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp -@@ -392,6 +392,9 @@ QFunctionPointer QXcbNativeInterface::platformFunction(const QByteArray &functio - if (function == QXcbWindowFunctions::setWmWindowTypeIdentifier()) { - return QFunctionPointer(QXcbWindow::setWmWindowTypeStatic); - } -+ if (function == QXcbWindowFunctions::setWmWindowRoleIdentifier()) { -+ return QFunctionPointer(QXcbWindow::setWmWindowRoleStatic); -+ } - if (function == QXcbWindowFunctions::visualIdIdentifier()) { - return QFunctionPointer(QXcbWindowFunctions::VisualId(QXcbWindow::visualIdStatic)); - } -diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp -index 6e021ce..edf68d4 100644 ---- a/src/plugins/platforms/xcb/qxcbwindow.cpp -+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp -@@ -322,6 +322,7 @@ static inline XTextProperty* qstringToXTP(Display *dpy, const QString& s) - #endif // XCB_USE_XLIB - - static const char *wm_window_type_property_id = "_q_xcb_wm_window_type"; -+static const char *wm_window_role_property_id = "_q_xcb_wm_window_role"; - - QXcbWindow::QXcbWindow(QWindow *window) - : QPlatformWindow(window) -@@ -660,6 +661,11 @@ void QXcbWindow::create() - setOpacity(opacity); - if (window()->isTopLevel()) - setWindowIcon(window()->icon()); -+ -+ if (window()->dynamicPropertyNames().contains(wm_window_type_property_id)) { -+ QByteArray wmWindowRole = window()->property(wm_window_type_property_id).toByteArray(); -+ setWmWindowRole(wmWindowRole); -+ } - } - - QXcbWindow::~QXcbWindow() -@@ -1674,6 +1680,14 @@ void QXcbWindow::setWmWindowTypeStatic(QWindow *window, QXcbWindowFunctions::WmW - static_cast(window->handle())->setWmWindowType(windowTypes, window->flags()); - } - -+void QXcbWindow::setWmWindowRoleStatic(QWindow *window, const QByteArray &role) -+{ -+ if (window->handle()) -+ static_cast(window->handle())->setWmWindowRole(role); -+ else -+ window->setProperty(wm_window_role_property_id, role); -+} -+ - uint QXcbWindow::visualIdStatic(QWindow *window) - { - if (window && window->handle()) -@@ -1839,6 +1853,13 @@ void QXcbWindow::setWmWindowType(QXcbWindowFunctions::WmWindowTypes types, Qt::W - xcb_flush(xcb_connection()); - } - -+void QXcbWindow::setWmWindowRole(const QByteArray &role) -+{ -+ Q_XCB_CALL(xcb_change_property(xcb_connection(), XCB_PROP_MODE_REPLACE, m_window, -+ atom(QXcbAtom::WM_WINDOW_ROLE), XCB_ATOM_STRING, 8, -+ role.size(), role.constData())); -+} -+ - class ExposeCompressor - { - public: -diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h -index a379a6f..15d5c1b 100644 ---- a/src/plugins/platforms/xcb/qxcbwindow.h -+++ b/src/plugins/platforms/xcb/qxcbwindow.h -@@ -140,10 +140,12 @@ public: - void updateNetWmUserTime(xcb_timestamp_t timestamp); - - static void setWmWindowTypeStatic(QWindow *window, QXcbWindowFunctions::WmWindowTypes windowTypes); -+ static void setWmWindowRoleStatic(QWindow *window, const QByteArray &role); - static uint visualIdStatic(QWindow *window); - - QXcbWindowFunctions::WmWindowTypes wmWindowTypes() const; - void setWmWindowType(QXcbWindowFunctions::WmWindowTypes types, Qt::WindowFlags flags); -+ void setWmWindowRole(const QByteArray &role); - - uint visualId() const; - -diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp -index bd77e7f..4b64490 100644 ---- a/src/widgets/kernel/qwidget.cpp -+++ b/src/widgets/kernel/qwidget.cpp -@@ -100,6 +100,7 @@ - - #include "qwindowcontainer_p.h" - -+#include "QtPlatformHeaders/qxcbwindowfunctions.h" - - // widget/widget data creation count - //#define QWIDGET_EXTRA_DEBUG -@@ -1451,6 +1452,9 @@ void QWidgetPrivate::create_sys(WId window, bool initializeWindow, bool destroyO - - data.window_flags = win->flags(); - -+ if (!topData()->role.isNull()) -+ QXcbWindowFunctions::setWmWindowRole(win, topData()->role.toLatin1()); -+ - QBackingStore *store = q->backingStore(); - - if (!store) { -@@ -6254,13 +6258,11 @@ QString QWidget::windowRole() const - */ - void QWidget::setWindowRole(const QString &role) - { --#if defined(Q_DEAD_CODE_FROM_QT4_X11) - Q_D(QWidget); -+ d->createTLExtra(); - d->topData()->role = role; -- d->setWindowRole(); --#else -- Q_UNUSED(role) --#endif -+ if (windowHandle()) -+ QXcbWindowFunctions::setWmWindowRole(windowHandle(), role.toLatin1()); - } - - /*! --- -2.3.5 diff --git a/0001-Fix-exclusion-of-anonymous-ciphers.patch b/0001-Fix-exclusion-of-anonymous-ciphers.patch deleted file mode 100644 index ad06b0b..0000000 --- a/0001-Fix-exclusion-of-anonymous-ciphers.patch +++ /dev/null @@ -1,35 +0,0 @@ -From 479e84dcbd0d7f1333105c495d7931f1bef3e63b Mon Sep 17 00:00:00 2001 -From: "Richard J. Moore" -Date: Sat, 18 Apr 2015 12:44:30 +0100 -Subject: [PATCH] Fix exclusion of anonymous ciphers. - -Qt attempted to exclude anonymous ciphers since they offer no MITM -protection, but missed export ADH ciphers and AECDH from the exclude -list. - -Change-Id: Icdfa9b31643a0e9927010885c7c1d02c42460d79 -Reviewed-by: Peter Hartmann ---- - src/network/ssl/qsslsocket_openssl.cpp | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp -index 55762c9..00e13e4 100644 ---- a/src/network/ssl/qsslsocket_openssl.cpp -+++ b/src/network/ssl/qsslsocket_openssl.cpp -@@ -662,8 +662,10 @@ void QSslSocketPrivate::resetDefaultCiphers() - if (SSL_CIPHER *cipher = q_sk_SSL_CIPHER_value(supportedCiphers, i)) { - QSslCipher ciph = QSslSocketBackendPrivate::QSslCipher_from_SSL_CIPHER(cipher); - if (!ciph.isNull()) { -- // Unconditionally exclude ADH ciphers since they offer no MITM protection -- if (!ciph.name().toLower().startsWith(QLatin1String("adh"))) -+ // Unconditionally exclude ADH and AECDH ciphers since they offer no MITM protection -+ if (!ciph.name().toLower().startsWith(QLatin1String("adh")) && -+ !ciph.name().toLower().startsWith(QLatin1String("exp-adh")) && -+ !ciph.name().toLower().startsWith(QLatin1String("aecdh"))) - ciphers << ciph; - if (ciph.usedBits() >= 128) - defaultCiphers << ciph; --- -2.6.2 - diff --git a/0001-xcb-XInput2-fixes-enter-leave-event-fixes.patch b/0001-xcb-XInput2-fixes-enter-leave-event-fixes.patch new file mode 100644 index 0000000..b539d85 --- /dev/null +++ b/0001-xcb-XInput2-fixes-enter-leave-event-fixes.patch @@ -0,0 +1,554 @@ +From e4c22c34fb105fc9c30be855048692d95b31c760 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= +Date: Fri, 8 Jan 2016 19:37:52 +0100 +Subject: [PATCH 01/16] xcb: XInput2 fixes, enter/leave event fixes + +Added enter/leave event handling in XInput2 to avoid problems with +those events when the mouse is grabbed. + +This commit amends: 53d289ec4c0f512a3475da4bbf1f940cd6838ace +This commit amends: ed2e15780385f7cf0a0d3aedc9cb2059d470bd58 + +Task-number: QTBUG-50340 +Change-Id: I7a120b46daa4f8fa4c218346273ae90b6abfa156 +Reviewed-by: Laszlo Agocs +Reviewed-by: Shawn Rutledge +(cherry picked from commit e4fb521b3f3b9e59146b7569b72aee08dbaeb268) +--- + src/plugins/platforms/xcb/qxcbconnection.cpp | 16 +- + src/plugins/platforms/xcb/qxcbconnection.h | 12 +- + src/plugins/platforms/xcb/qxcbconnection_xi2.cpp | 54 +++++-- + src/plugins/platforms/xcb/qxcbkeyboard.cpp | 8 +- + src/plugins/platforms/xcb/qxcbkeyboard.h | 2 + + src/plugins/platforms/xcb/qxcbwindow.cpp | 177 ++++++++++++++--------- + src/plugins/platforms/xcb/qxcbwindow.h | 9 ++ + 7 files changed, 183 insertions(+), 95 deletions(-) + +diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp +index 9cedd296e1e9ad870900a09f2d955e3460484205..aeb730670d62b3ce2239fba48b58ccb4752e912d 100644 +--- a/src/plugins/platforms/xcb/qxcbconnection.cpp ++++ b/src/plugins/platforms/xcb/qxcbconnection.cpp +@@ -613,8 +613,8 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra + initializeScreens(); + + initializeXRender(); +- m_xi2Enabled = false; + #if defined(XCB_USE_XINPUT2) ++ m_xi2Enabled = false; + initializeXInput2(); + #endif + initializeXShape(); +@@ -1133,8 +1133,16 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event) + handleClientMessageEvent((xcb_client_message_event_t *)event); + break; + case XCB_ENTER_NOTIFY: ++#ifdef XCB_USE_XINPUT22 ++ if (isAtLeastXI22() && xi2MouseEvents()) ++ break; ++#endif + HANDLE_PLATFORM_WINDOW_EVENT(xcb_enter_notify_event_t, event, handleEnterNotifyEvent); + case XCB_LEAVE_NOTIFY: ++#ifdef XCB_USE_XINPUT22 ++ if (isAtLeastXI22() && xi2MouseEvents()) ++ break; ++#endif + m_keyboard->updateXKBStateFromCore(((xcb_leave_notify_event_t *)event)->state); + HANDLE_PLATFORM_WINDOW_EVENT(xcb_leave_notify_event_t, event, handleLeaveNotifyEvent); + case XCB_FOCUS_IN: +@@ -2216,13 +2224,15 @@ void QXcbConnection::initializeXKB() + #endif + } + ++#if defined(XCB_USE_XINPUT22) + bool QXcbConnection::xi2MouseEvents() const + { + static bool mouseViaXI2 = !qEnvironmentVariableIsSet("QT_XCB_NO_XI2_MOUSE"); +- // Don't use XInput2 when Xinerama extension is enabled, +- // because it causes problems with multi-monitor setup. ++ // FIXME: Don't use XInput2 mouse events when Xinerama extension ++ // is enabled, because it causes problems with multi-monitor setup. + return mouseViaXI2 && !has_xinerama_extension; + } ++#endif + + #if defined(XCB_USE_XINPUT2) + static int xi2ValuatorOffset(unsigned char *maskPtr, int maskLen, int number) +diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h +index a6a7b9e7ca1898fe2add7a51107bfc9e535d9b44..6c2b8583af24e9abd7a087144fb33504ec36fbf8 100644 +--- a/src/plugins/platforms/xcb/qxcbconnection.h ++++ b/src/plugins/platforms/xcb/qxcbconnection.h +@@ -347,8 +347,10 @@ public: + virtual void handleFocusInEvent(const xcb_focus_in_event_t *) {} + virtual void handleFocusOutEvent(const xcb_focus_out_event_t *) {} + virtual void handlePropertyNotifyEvent(const xcb_property_notify_event_t *) {} ++#ifdef XCB_USE_XINPUT22 + virtual void handleXIMouseEvent(xcb_ge_event_t *) {} +- ++ virtual void handleXIEnterLeave(xcb_ge_event_t *) {} ++#endif + virtual QXcbWindow *toWindow() { return 0; } + }; + +@@ -485,8 +487,8 @@ public: + static bool xEmbedSystemTrayAvailable(); + static bool xEmbedSystemTrayVisualHasAlphaChannel(); + +-#ifdef XCB_USE_XINPUT2 +- void handleEnterEvent(const xcb_enter_notify_event_t *); ++#ifdef XCB_USE_XINPUT21 ++ void handleEnterEvent(); + #endif + + #ifdef XCB_USE_XINPUT22 +@@ -500,7 +502,9 @@ public: + + QXcbGlIntegration *glIntegration() const { return m_glIntegration; } + ++#ifdef XCB_USE_XINPUT22 + bool xi2MouseEvents() const; ++#endif + + protected: + bool event(QEvent *e) Q_DECL_OVERRIDE; +@@ -534,9 +538,9 @@ private: + void initializeScreens(); + bool compressEvent(xcb_generic_event_t *event, int currentIndex, QXcbEventArray *eventqueue) const; + ++#ifdef XCB_USE_XINPUT2 + bool m_xi2Enabled; + int m_xi2Minor; +-#ifdef XCB_USE_XINPUT2 + void initializeXInput2(); + void finalizeXInput2(); + void xi2SetupDevices(); +diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +index e055ad1424f9ec51a5f4e814babd85601c920c90..0c78c0e0d2bc9d05e9f6768ead72cad4a51d03a7 100644 +--- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp ++++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +@@ -293,6 +293,11 @@ void QXcbConnection::xi2Select(xcb_window_t window) + bitMask |= XI_ButtonPressMask; + bitMask |= XI_ButtonReleaseMask; + bitMask |= XI_MotionMask; ++ ++ // There is a check for enter/leave events in plain xcb enter/leave event handler ++ bitMask |= XI_EnterMask; ++ bitMask |= XI_LeaveMask; ++ + qCDebug(lcQpaXInput, "XInput 2.2: Selecting press/release/motion events in addition to touch"); + } + XIEventMask mask; +@@ -307,9 +312,12 @@ void QXcbConnection::xi2Select(xcb_window_t window) + if (result != Success) + qCDebug(lcQpaXInput, "XInput 2.2: failed to select pointer/touch events, window %x, result %d", window, result); + } +-#endif // XCB_USE_XINPUT22 + + const bool pointerSelected = isAtLeastXI22() && xi2MouseEvents(); ++#else ++ const bool pointerSelected = false; ++#endif // XCB_USE_XINPUT22 ++ + QSet tabletDevices; + #ifndef QT_NO_TABLETEVENT + if (!m_tabletData.isEmpty()) { +@@ -474,6 +482,7 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event) + xXIGenericDeviceEvent *xiEvent = reinterpret_cast(event); + int sourceDeviceId = xiEvent->deviceid; // may be the master id + xXIDeviceEvent *xiDeviceEvent = 0; ++ xXIEnterEvent *xiEnterEvent = 0; + QXcbWindowEventListener *eventListener = 0; + + switch (xiEvent->evtype) { +@@ -488,14 +497,16 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event) + { + xiDeviceEvent = reinterpret_cast(event); + eventListener = windowEventListenerFromId(xiDeviceEvent->event); +- if (eventListener) { +- long result = 0; +- if (eventListener->handleGenericEvent(reinterpret_cast(event), &result)) +- return; +- } + sourceDeviceId = xiDeviceEvent->sourceid; // use the actual device id instead of the master + break; + } ++ case XI_Enter: ++ case XI_Leave: { ++ xiEnterEvent = reinterpret_cast(event); ++ eventListener = windowEventListenerFromId(xiEnterEvent->event); ++ sourceDeviceId = xiEnterEvent->sourceid; // use the actual device id instead of the master ++ break; ++ } + case XI_HierarchyChanged: + xi2HandleHierachyEvent(xiEvent); + return; +@@ -506,11 +517,19 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event) + break; + } + ++ if (eventListener) { ++ long result = 0; ++ if (eventListener->handleGenericEvent(reinterpret_cast(event), &result)) ++ return; ++ } ++ + #ifndef QT_NO_TABLETEVENT +- for (int i = 0; i < m_tabletData.count(); ++i) { +- if (m_tabletData.at(i).deviceId == sourceDeviceId) { +- if (xi2HandleTabletEvent(xiEvent, &m_tabletData[i], eventListener)) +- return; ++ if (!xiEnterEvent) { ++ for (int i = 0; i < m_tabletData.count(); ++i) { ++ if (m_tabletData.at(i).deviceId == sourceDeviceId) { ++ if (xi2HandleTabletEvent(xiEvent, &m_tabletData[i], eventListener)) ++ return; ++ } + } + } + #endif // QT_NO_TABLETEVENT +@@ -543,6 +562,13 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event) + xi2ProcessTouch(xiDeviceEvent, platformWindow); + break; + } ++ } else if (xiEnterEvent && xi2MouseEvents() && eventListener) { ++ switch (xiEnterEvent->evtype) { ++ case XI_Enter: ++ case XI_Leave: ++ eventListener->handleXIEnterLeave(event); ++ break; ++ } + } + #endif // XCB_USE_XINPUT22 + } +@@ -718,6 +744,8 @@ bool QXcbConnection::xi2SetMouseGrabEnabled(xcb_window_t w, bool grab) + XISetMask(mask, XI_ButtonPress); + XISetMask(mask, XI_ButtonRelease); + XISetMask(mask, XI_Motion); ++ XISetMask(mask, XI_Enter); ++ XISetMask(mask, XI_Leave); + XISetMask(mask, XI_TouchBegin); + XISetMask(mask, XI_TouchUpdate); + XISetMask(mask, XI_TouchEnd); +@@ -827,9 +855,9 @@ void QXcbConnection::updateScrollingDevice(ScrollingDevice &scrollingDevice, int + #endif + } + +-void QXcbConnection::handleEnterEvent(const xcb_enter_notify_event_t *) +-{ + #ifdef XCB_USE_XINPUT21 ++void QXcbConnection::handleEnterEvent() ++{ + QHash::iterator it = m_scrollingDevices.begin(); + const QHash::iterator end = m_scrollingDevices.end(); + while (it != end) { +@@ -845,8 +873,8 @@ void QXcbConnection::handleEnterEvent(const xcb_enter_notify_event_t *) + XIFreeDeviceInfo(xiDeviceInfo); + ++it; + } +-#endif + } ++#endif + + void QXcbConnection::xi2HandleScrollEvent(void *event, ScrollingDevice &scrollingDevice) + { +diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp +index 2e088d3ca51dfff7fcf41f476b4f8db7c8f40543..631dd17908f458533f413409773b6c078b743d98 100644 +--- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp ++++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp +@@ -797,9 +797,9 @@ void QXcbKeyboard::updateXKBStateFromCore(quint16 state) + } + } + ++#ifdef XCB_USE_XINPUT22 + void QXcbKeyboard::updateXKBStateFromXI(void *modInfo, void *groupInfo) + { +-#ifdef XCB_USE_XINPUT22 + if (m_config && !connection()->hasXKB()) { + xXIModifierInfo *mods = static_cast(modInfo); + xXIGroupInfo *group = static_cast(groupInfo); +@@ -815,12 +815,8 @@ void QXcbKeyboard::updateXKBStateFromXI(void *modInfo, void *groupInfo) + //qWarning("TODO: Support KeyboardLayoutChange on QPA (QTBUG-27681)"); + } + } +-#else +- Q_UNUSED(modInfo); +- Q_UNUSED(groupInfo); +- Q_ASSERT(false); // this can't be +-#endif + } ++#endif + + quint32 QXcbKeyboard::xkbModMask(quint16 state) + { +diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.h b/src/plugins/platforms/xcb/qxcbkeyboard.h +index d2e37d624cfe5960bf50d8f18f2a82756824fa4d..457a27affb166e2a3e54c78761361ff3713a4d18 100644 +--- a/src/plugins/platforms/xcb/qxcbkeyboard.h ++++ b/src/plugins/platforms/xcb/qxcbkeyboard.h +@@ -68,7 +68,9 @@ public: + void updateXKBMods(); + quint32 xkbModMask(quint16 state); + void updateXKBStateFromCore(quint16 state); ++#ifdef XCB_USE_XINPUT22 + void updateXKBStateFromXI(void *modInfo, void *groupInfo); ++#endif + #ifndef QT_NO_XKB + // when XKEYBOARD is present on the X server + int coreDeviceId() const { return core_device_id; } +diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp +index f97f570831a099c7d1d87cb12ed3c44baa7237eb..91c5eadf3456e15467ba94dd72a886a365aa6a7d 100644 +--- a/src/plugins/platforms/xcb/qxcbwindow.cpp ++++ b/src/plugins/platforms/xcb/qxcbwindow.cpp +@@ -2157,6 +2157,78 @@ void QXcbWindow::handleButtonReleaseEvent(int event_x, int event_y, int root_x, + handleMouseEvent(timestamp, local, global, modifiers); + } + ++static bool ignoreLeaveEvent(quint8 mode, quint8 detail) ++{ ++ return (mode == XCB_NOTIFY_MODE_GRAB && detail == XCB_NOTIFY_DETAIL_ANCESTOR) // Check for AwesomeWM ++ || detail == XCB_NOTIFY_DETAIL_VIRTUAL ++ || detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL; ++} ++ ++static bool ignoreEnterEvent(quint8 mode, quint8 detail) ++{ ++ return ((mode == XCB_NOTIFY_MODE_UNGRAB && detail == XCB_NOTIFY_DETAIL_ANCESTOR) // Check for AwesomeWM ++ || (mode != XCB_NOTIFY_MODE_NORMAL && mode != XCB_NOTIFY_MODE_UNGRAB) ++ || detail == XCB_NOTIFY_DETAIL_VIRTUAL ++ || detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL); ++} ++ ++class EnterEventChecker ++{ ++public: ++ bool checkEvent(xcb_generic_event_t *event) ++ { ++ if (!event) ++ return false; ++ if ((event->response_type & ~0x80) != XCB_ENTER_NOTIFY) ++ return false; ++ ++ xcb_enter_notify_event_t *enter = (xcb_enter_notify_event_t *)event; ++ if (ignoreEnterEvent(enter->mode, enter->detail)) ++ return false; ++ ++ return true; ++ } ++}; ++ ++void QXcbWindow::handleEnterNotifyEvent(int event_x, int event_y, int root_x, int root_y, ++ quint8 mode, quint8 detail, xcb_timestamp_t timestamp) ++{ ++ connection()->setTime(timestamp); ++#ifdef XCB_USE_XINPUT21 ++ connection()->handleEnterEvent(); ++#endif ++ ++ if (ignoreEnterEvent(mode, detail)) ++ return; ++ ++ const QPoint local(event_x, event_y); ++ QPoint global = QPoint(root_x, root_y); ++ QWindowSystemInterface::handleEnterEvent(window(), local, global); ++} ++ ++void QXcbWindow::handleLeaveNotifyEvent(int root_x, int root_y, ++ quint8 mode, quint8 detail, xcb_timestamp_t timestamp) ++{ ++ connection()->setTime(timestamp); ++ ++ if (ignoreLeaveEvent(mode, detail)) ++ return; ++ ++ EnterEventChecker checker; ++ xcb_enter_notify_event_t *enter = (xcb_enter_notify_event_t *)connection()->checkEvent(checker); ++ QXcbWindow *enterWindow = enter ? connection()->platformWindowFromId(enter->event) : 0; ++ ++ if (enterWindow) { ++ QPoint local(enter->event_x, enter->event_y); ++ QPoint global = QPoint(root_x, root_y); ++ QWindowSystemInterface::handleEnterLeaveEvent(enterWindow->window(), window(), local, global); ++ } else { ++ QWindowSystemInterface::handleLeaveEvent(window()); ++ } ++ ++ free(enter); ++} ++ + void QXcbWindow::handleMotionNotifyEvent(int event_x, int event_y, int root_x, int root_y, + Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp) + { +@@ -2191,12 +2263,10 @@ static inline int fixed1616ToInt(FP1616 val) + { + return int((qreal(val >> 16)) + (val & 0xFFFF) / (qreal)0xFFFF); + } +-#endif + + // With XI 2.2+ press/release/motion comes here instead of the above handlers. + void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event) + { +-#ifdef XCB_USE_XINPUT22 + QXcbConnection *conn = connection(); + xXIDeviceEvent *ev = reinterpret_cast(event); + const Qt::KeyboardModifiers modifiers = conn->keyboard()->translateModifiers(ev->mods.effective_mods); +@@ -2234,12 +2304,41 @@ void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event) + qWarning() << "Unrecognized XI2 mouse event" << ev->evtype; + break; + } +-#else +- Q_UNUSED(event); +- Q_ASSERT(false); // this can't be +-#endif + } + ++// With XI 2.2+ enter/leave comes here and are blocked in plain xcb events ++void QXcbWindow::handleXIEnterLeave(xcb_ge_event_t *event) ++{ ++ xXIEnterEvent *ev = reinterpret_cast(event); ++ ++ // Compare the window with current mouse grabber to prevent deliver events to any other windows. ++ // If leave event occurs and the window is under mouse - allow to deliver the leave event. ++ QXcbWindow *mouseGrabber = connection()->mouseGrabber(); ++ if (mouseGrabber && mouseGrabber != this ++ && (ev->evtype != XI_Leave || QGuiApplicationPrivate::currentMouseWindow != window())) { ++ return; ++ } ++ ++ const int root_x = fixed1616ToInt(ev->root_x); ++ const int root_y = fixed1616ToInt(ev->root_y); ++ ++ switch (ev->evtype) { ++ case XI_Enter: { ++ const int event_x = fixed1616ToInt(ev->event_x); ++ const int event_y = fixed1616ToInt(ev->event_y); ++ qCDebug(lcQpaXInput, "XI2 mouse enter %d,%d, mode %d, detail %d, time %d", event_x, event_y, ev->mode, ev->detail, ev->time); ++ handleEnterNotifyEvent(event_x, event_y, root_x, root_y, ev->mode, ev->detail, ev->time); ++ break; ++ } ++ case XI_Leave: ++ qCDebug(lcQpaXInput, "XI2 mouse leave, mode %d, detail %d, time %d", ev->mode, ev->detail, ev->time); ++ connection()->keyboard()->updateXKBStateFromXI(&ev->mods, &ev->group); ++ handleLeaveNotifyEvent(root_x, root_y, ev->mode, ev->detail, ev->time); ++ break; ++ } ++} ++#endif ++ + QXcbWindow *QXcbWindow::toWindow() { return this; } + + void QXcbWindow::handleMouseEvent(xcb_timestamp_t time, const QPoint &local, const QPoint &global, Qt::KeyboardModifiers modifiers) +@@ -2248,74 +2347,14 @@ void QXcbWindow::handleMouseEvent(xcb_timestamp_t time, const QPoint &local, con + QWindowSystemInterface::handleMouseEvent(window(), time, local, global, connection()->buttons(), modifiers); + } + +-static bool ignoreLeaveEvent(const xcb_leave_notify_event_t *event) +-{ +- return event->detail == XCB_NOTIFY_DETAIL_VIRTUAL +- || event->detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL +- || event->mode == XCB_NOTIFY_MODE_GRAB; +-} +- +-static bool ignoreEnterEvent(const xcb_enter_notify_event_t *event) +-{ +- return (event->mode != XCB_NOTIFY_MODE_NORMAL +- || event->detail == XCB_NOTIFY_DETAIL_VIRTUAL +- || event->detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL); +-} +- +-class EnterEventChecker +-{ +-public: +- bool checkEvent(xcb_generic_event_t *event) +- { +- if (!event) +- return false; +- if ((event->response_type & ~0x80) != XCB_ENTER_NOTIFY) +- return false; +- +- xcb_enter_notify_event_t *enter = (xcb_enter_notify_event_t *)event; +- if (ignoreEnterEvent(enter)) +- return false; +- +- return true; +- } +-}; +- + void QXcbWindow::handleEnterNotifyEvent(const xcb_enter_notify_event_t *event) + { +- connection()->setTime(event->time); +-#ifdef XCB_USE_XINPUT2 +- connection()->handleEnterEvent(event); +-#endif +- +- if (ignoreEnterEvent(event)) +- return; +- +- const QPoint local(event->event_x, event->event_y); +- QPoint global = QPoint(event->root_x, event->root_y); +- QWindowSystemInterface::handleEnterEvent(window(), local, global); ++ handleEnterNotifyEvent(event->event_x, event->event_y, event->root_x, event->root_y, event->mode, event->detail, event->time); + } + + void QXcbWindow::handleLeaveNotifyEvent(const xcb_leave_notify_event_t *event) + { +- connection()->setTime(event->time); +- +- if (ignoreLeaveEvent(event)) +- return; +- +- EnterEventChecker checker; +- xcb_enter_notify_event_t *enter = (xcb_enter_notify_event_t *)connection()->checkEvent(checker); +- QXcbWindow *enterWindow = enter ? connection()->platformWindowFromId(enter->event) : 0; +- +- if (enterWindow) { +- QPoint local(enter->event_x, enter->event_y); +- QPoint global = QPoint(event->root_x, event->root_y); +- +- QWindowSystemInterface::handleEnterLeaveEvent(enterWindow->window(), window(), local, global); +- } else { +- QWindowSystemInterface::handleLeaveEvent(window()); +- } +- +- free(enter); ++ handleLeaveNotifyEvent(event->root_x, event->root_y, event->mode, event->detail, event->time); + } + + void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *event) +@@ -2419,7 +2458,7 @@ bool QXcbWindow::setMouseGrabEnabled(bool grab) + if (!grab && connection()->mouseGrabber() == this) + connection()->setMouseGrabber(Q_NULLPTR); + #ifdef XCB_USE_XINPUT22 +- if (connection()->xi2MouseEvents()) { ++ if (connection()->isAtLeastXI22() && connection()->xi2MouseEvents()) { + bool result = connection()->xi2SetMouseGrabEnabled(m_window, grab); + if (grab && result) + connection()->setMouseGrabber(this); +diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h +index d2c02fe3df4e0d0667711dfa9bfc10fed30d9554..69790f29ae098bbfcc5aa6edec75e3d0fea8ea75 100644 +--- a/src/plugins/platforms/xcb/qxcbwindow.h ++++ b/src/plugins/platforms/xcb/qxcbwindow.h +@@ -132,7 +132,10 @@ public: + void handleFocusInEvent(const xcb_focus_in_event_t *event) Q_DECL_OVERRIDE; + 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 handleXIMouseEvent(xcb_ge_event_t *) Q_DECL_OVERRIDE; ++ void handleXIEnterLeave(xcb_ge_event_t *) Q_DECL_OVERRIDE; ++#endif + + QXcbWindow *toWindow() Q_DECL_OVERRIDE; + +@@ -212,6 +215,12 @@ protected: + void handleMotionNotifyEvent(int event_x, int event_y, int root_x, int root_y, + Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp); + ++ void handleEnterNotifyEvent(int event_x, int event_y, int root_x, int root_y, ++ quint8 mode, quint8 detail, xcb_timestamp_t timestamp); ++ ++ void handleLeaveNotifyEvent(int root_x, int root_y, ++ quint8 mode, quint8 detail, xcb_timestamp_t timestamp); ++ + xcb_window_t m_window; + + uint m_depth; +-- +2.6.6 + diff --git a/0002-xcb-Correct-enter-leave-event-handling-when-mouse-bu.patch b/0002-xcb-Correct-enter-leave-event-handling-when-mouse-bu.patch new file mode 100644 index 0000000..2a5ee03 --- /dev/null +++ b/0002-xcb-Correct-enter-leave-event-handling-when-mouse-bu.patch @@ -0,0 +1,55 @@ +From 592f96911bf453dcdc6ae14814927303db544ac8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= +Date: Sat, 17 Oct 2015 17:22:16 +0200 +Subject: [PATCH 02/16] xcb: Correct enter/leave event handling when mouse + button is pressed + +This patch fixes cursor shape when mouse leaves the window and enters +the window again with pressed mouse button - ignore the mouse enter +and leave event when any of mouse buttons is pressed. + +Task-number: QTBUG-46576 +Change-Id: Id6ce50cd0d66da51a251d4811bc42cd31606de29 +Reviewed-by: Shawn Rutledge +(cherry picked from commit b9f76db30d261421e4da58f29053181af04ceb4d) +--- + src/plugins/platforms/xcb/qxcbwindow.cpp | 13 ++++++++++--- + 1 file changed, 10 insertions(+), 3 deletions(-) + +diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp +index 91c5eadf3456e15467ba94dd72a886a365aa6a7d..354c29152fadd9200e8d10bc245aed89526a5f6e 100644 +--- a/src/plugins/platforms/xcb/qxcbwindow.cpp ++++ b/src/plugins/platforms/xcb/qxcbwindow.cpp +@@ -2198,11 +2198,14 @@ void QXcbWindow::handleEnterNotifyEvent(int event_x, int event_y, int root_x, in + connection()->handleEnterEvent(); + #endif + +- if (ignoreEnterEvent(mode, detail)) ++ const QPoint global = QPoint(root_x, root_y); ++ ++ if (ignoreEnterEvent(mode, detail) ++ || (connection()->buttons() != Qt::NoButton ++ && QGuiApplicationPrivate::lastCursorPosition != global)) + return; + + const QPoint local(event_x, event_y); +- QPoint global = QPoint(root_x, root_y); + QWindowSystemInterface::handleEnterEvent(window(), local, global); + } + +@@ -2211,7 +2214,11 @@ void QXcbWindow::handleLeaveNotifyEvent(int root_x, int root_y, + { + connection()->setTime(timestamp); + +- if (ignoreLeaveEvent(mode, detail)) ++ const QPoint global(root_x, root_y); ++ ++ if (ignoreLeaveEvent(mode, detail) ++ || (connection()->buttons() != Qt::NoButton ++ && QGuiApplicationPrivate::lastCursorPosition != global)) + return; + + EnterEventChecker checker; +-- +2.6.6 + diff --git a/0003-xcb-Fix-not-delivering-focusIn-event-on-hide-show.patch b/0003-xcb-Fix-not-delivering-focusIn-event-on-hide-show.patch new file mode 100644 index 0000000..8fa23c3 --- /dev/null +++ b/0003-xcb-Fix-not-delivering-focusIn-event-on-hide-show.patch @@ -0,0 +1,98 @@ +From f371c645e2a06234355693551e16d69961839ac1 Mon Sep 17 00:00:00 2001 +From: Alexander Bersenev +Date: Fri, 6 Nov 2015 01:39:27 +0500 +Subject: [PATCH 03/16] xcb: Fix not delivering focusIn event on hide/show +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Consider a window which was hidden and shown with hide() and show() +methods and mouse pointer was in window when hide() was called. + +At first, window got focusOutEvent and then Qt library sends X server +a message to unmap the window. + +Then X server will send client two messages: +1) FocusOut(10) detail=Nonlinear(0x03) +2) FocusIn(9) detail=Pointer(0x05) + +QXcbWindow has a logic for not seting active window to 0 if there is +a FocusIn coming (see QXcbWindow::doFocusOut). + +So QGuiApplicationPrivate::focus_window still points to the current +window. + +Then when show() is called, qt compares previous focus with new focus +and, since they are equal, doesn't do anything. Event focusInEvent +isn't delivered to the window. + +Here are two links why X server sends FocusIn just after FocusOut: +http://lists.freedesktop.org/archives/xorg/2008-December/041684.html +https://tronche.com/gui/x/xlib/events/input-focus/normal-and-grabbed.html + +Proposed fix ignores FocusIn events with detail==Pointer. +The text of explaining comment is taken from the Chromium project: +https://chromium.googlesource.com/chromium/src/+/master/ui/views/widget/desktop_aura/x11_desktop_handler.cc +from X11DesktopHandler::ProcessXEvent function. + +[ChangeLog][module][Linux/XCB] Fix not delivering focusIn event on +hide/show with XCB + +Task-number: QTBUG-49071 +Change-Id: I433c8b638834c25f113cc134ee4185778c44f540 +Reviewed-by: André Hartmann +Reviewed-by: Lisandro Damián Nicanor Pérez Meyer +Reviewed-by: Shawn Rutledge +(cherry picked from commit 8eaf3352590690079735eda9fb872ec8c9c58f0a) +--- + src/plugins/platforms/xcb/qxcbwindow.cpp | 21 +++++++++++++++++---- + 1 file changed, 17 insertions(+), 4 deletions(-) + +diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp +index 354c29152fadd9200e8d10bc245aed89526a5f6e..46b7b70f8025a8481ab2db37257a52494a84d234 100644 +--- a/src/plugins/platforms/xcb/qxcbwindow.cpp ++++ b/src/plugins/platforms/xcb/qxcbwindow.cpp +@@ -894,8 +894,13 @@ static bool focusInPeeker(QXcbConnection *connection, xcb_generic_event_t *event + return true; + } + uint response_type = event->response_type & ~0x80; +- if (response_type == XCB_FOCUS_IN) +- return true; ++ if (response_type == XCB_FOCUS_IN) { ++ // Ignore focus events that are being sent only because the pointer is over ++ // our window, even if the input focus is in a different window. ++ xcb_focus_in_event_t *e = (xcb_focus_in_event_t *) event; ++ if (e->detail != XCB_NOTIFY_DETAIL_POINTER) ++ return true; ++ } + + /* We are also interested in XEMBED_FOCUS_IN events */ + if (response_type == XCB_CLIENT_MESSAGE) { +@@ -2415,14 +2420,22 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev + } + } + +-void QXcbWindow::handleFocusInEvent(const xcb_focus_in_event_t *) ++void QXcbWindow::handleFocusInEvent(const xcb_focus_in_event_t *event) + { ++ // Ignore focus events that are being sent only because the pointer is over ++ // our window, even if the input focus is in a different window. ++ if (event->detail == XCB_NOTIFY_DETAIL_POINTER) ++ return; + doFocusIn(); + } + + +-void QXcbWindow::handleFocusOutEvent(const xcb_focus_out_event_t *) ++void QXcbWindow::handleFocusOutEvent(const xcb_focus_out_event_t *event) + { ++ // Ignore focus events that are being sent only because the pointer is over ++ // our window, even if the input focus is in a different window. ++ if (event->detail == XCB_NOTIFY_DETAIL_POINTER) ++ return; + doFocusOut(); + } + +-- +2.6.6 + diff --git a/0004-xcb-Fix-drag-and-drop-between-xcb-screens.patch b/0004-xcb-Fix-drag-and-drop-between-xcb-screens.patch new file mode 100644 index 0000000..2c07dcf --- /dev/null +++ b/0004-xcb-Fix-drag-and-drop-between-xcb-screens.patch @@ -0,0 +1,89 @@ +From a9b7b17655d7b0826c5adc36f66407283564eb72 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= +Date: Mon, 15 Feb 2016 20:50:16 +0100 +Subject: [PATCH 04/16] xcb: Fix drag and drop between xcb screens + +Set the proper screen before creating a shaped pixmap window in +QBasicDrag::startDrag(). Grab mouse again when D&D window is +recreated. + +Task-number: QTBUG-51215 +Change-Id: I5cb47d3b11672b56d17b32072d84a722bdcdcd9a +Reviewed-by: Friedemann Kleint +Reviewed-by: Shawn Rutledge +(cherry picked from commit 78ad8f208d8dbe3575194bb9b97d4e42efdc32d5) +--- + src/gui/kernel/qsimpledrag.cpp | 5 +++-- + src/gui/kernel/qsimpledrag_p.h | 3 +++ + src/plugins/platforms/xcb/qxcbdrag.cpp | 4 ++++ + 3 files changed, 10 insertions(+), 2 deletions(-) + +diff --git a/src/gui/kernel/qsimpledrag.cpp b/src/gui/kernel/qsimpledrag.cpp +index 9f38c9b78ad4f8537e9e4c3a39af9d2c56fb67c7..00589d23039ed4f043d026e89187d645ad2ee214 100644 +--- a/src/gui/kernel/qsimpledrag.cpp ++++ b/src/gui/kernel/qsimpledrag.cpp +@@ -88,7 +88,8 @@ static QWindow* topLevelAt(const QPoint &pos) + QBasicDrag::QBasicDrag() : + m_restoreCursor(false), m_eventLoop(0), + m_executed_drop_action(Qt::IgnoreAction), m_can_drop(false), +- m_drag(0), m_drag_icon_window(0), m_useCompositing(true) ++ m_drag(0), m_drag_icon_window(0), m_useCompositing(true), ++ m_screen(Q_NULLPTR) + { + } + +@@ -211,7 +212,7 @@ void QBasicDrag::startDrag() + pos = QPoint(); + } + #endif +- recreateShapedPixmapWindow(Q_NULLPTR, pos); ++ recreateShapedPixmapWindow(m_screen, pos); + enableEventFilter(); + } + +diff --git a/src/gui/kernel/qsimpledrag_p.h b/src/gui/kernel/qsimpledrag_p.h +index 055136c436ed3b3504c2ee564e49cee1bd4439d4..b208c8ccc97a668205ef08fdce591e4c0d78c939 100644 +--- a/src/gui/kernel/qsimpledrag_p.h ++++ b/src/gui/kernel/qsimpledrag_p.h +@@ -90,6 +90,8 @@ protected: + bool useCompositing() const { return m_useCompositing; } + void setUseCompositing(bool on) { m_useCompositing = on; } + ++ void setScreen(QScreen *screen) { m_screen = screen; } ++ + Qt::DropAction executedDropAction() const { return m_executed_drop_action; } + void setExecutedDropAction(Qt::DropAction da) { m_executed_drop_action = da; } + +@@ -108,6 +110,7 @@ private: + QDrag *m_drag; + QShapedPixmapWindow *m_drag_icon_window; + bool m_useCompositing; ++ QScreen *m_screen; + }; + + class Q_GUI_EXPORT QSimpleDrag : public QBasicDrag +diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp +index 9296a6d1410f72d00efcf8c249bdd8a037b8b4be..aa6445d2da56f09696c98cba76baf6c74e44841c 100644 +--- a/src/plugins/platforms/xcb/qxcbdrag.cpp ++++ b/src/plugins/platforms/xcb/qxcbdrag.cpp +@@ -193,6 +193,7 @@ void QXcbDrag::startDrag() + XCB_ATOM_ATOM, 32, drag_types.size(), (const void *)drag_types.constData()); + + setUseCompositing(current_virtual_desktop->compositingActive()); ++ setScreen(current_virtual_desktop->screens().constFirst()->screen()); + QBasicDrag::startDrag(); + if (connection()->mouseGrabber() == Q_NULLPTR) + shapedPixmapWindow()->setMouseGrabEnabled(true); +@@ -322,6 +323,9 @@ void QXcbDrag::move(const QPoint &globalPos) + if (virtualDesktop != current_virtual_desktop) { + setUseCompositing(virtualDesktop->compositingActive()); + recreateShapedPixmapWindow(static_cast(screen)->screen(), deviceIndependentPos); ++ if (connection()->mouseGrabber() == Q_NULLPTR) ++ shapedPixmapWindow()->setMouseGrabEnabled(true); ++ + current_virtual_desktop = virtualDesktop; + } else { + QBasicDrag::moveShapedPixmapWindow(deviceIndependentPos); +-- +2.6.6 + diff --git a/0005-Restore-documented-behavior-for-the-WA_X11NetWmWindo.patch b/0005-Restore-documented-behavior-for-the-WA_X11NetWmWindo.patch deleted file mode 100644 index 87b8f67..0000000 --- a/0005-Restore-documented-behavior-for-the-WA_X11NetWmWindo.patch +++ /dev/null @@ -1,116 +0,0 @@ -From 5e5031527a3b443c93bf9e762c2f47e6786d7a31 Mon Sep 17 00:00:00 2001 -From: Alexander Volkov -Date: Thu, 7 May 2015 17:36:57 +0300 -Subject: [PATCH] Restore documented behavior for the WA_X11NetWmWindowType* - attributes - -Use QXcbWindowFunctions::setWmWindowType() to add the corresponding -types to the window's _NET_WM_WINDOW_TYPE X11 window property. - -Change-Id: Ia2413ad7a69ab8d49b448de11dd07c77101a564c -Task-number: QTBUG-39887 ---- - src/widgets/kernel/qwidget.cpp | 44 ++++++++++++++++++++++++++++++++++++++---- - src/widgets/kernel/qwidget_p.h | 3 ++- - 2 files changed, 42 insertions(+), 5 deletions(-) - -diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp -index 2c9cc5c..0f05280 100644 ---- a/src/widgets/kernel/qwidget.cpp -+++ b/src/widgets/kernel/qwidget.cpp -@@ -1414,6 +1414,7 @@ void QWidgetPrivate::create_sys(WId wind - win->setProperty("_q_showWithoutActivating", QVariant(true)); - if (q->testAttribute(Qt::WA_MacAlwaysShowToolWindow)) - win->setProperty("_q_macAlwaysShowToolWindow", QVariant::fromValue(QVariant(true))); -+ setNetWmWindowTypes(); - win->setFlags(data.window_flags); - fixPosIncludesFrame(); - if (q->testAttribute(Qt::WA_Moved) -@@ -11149,7 +11150,6 @@ void QWidget::setAttribute(Qt::WidgetAtt - break; - } - --#ifdef Q_DEAD_CODE_FROM_QT4_X11 - case Qt::WA_X11NetWmWindowTypeDesktop: - case Qt::WA_X11NetWmWindowTypeDock: - case Qt::WA_X11NetWmWindowTypeToolBar: -@@ -11163,10 +11163,8 @@ void QWidget::setAttribute(Qt::WidgetAtt - case Qt::WA_X11NetWmWindowTypeNotification: - case Qt::WA_X11NetWmWindowTypeCombo: - case Qt::WA_X11NetWmWindowTypeDND: -- if (testAttribute(Qt::WA_WState_Created)) -- d->setNetWmWindowTypes(); -+ d->setNetWmWindowTypes(); - break; --#endif - - case Qt::WA_StaticContents: - if (QWidgetBackingStore *bs = d->maybeBackingStore()) { -@@ -12823,6 +12821,44 @@ void QWidgetPrivate::setWidgetParentHelp - widget->setParent(static_cast(newParent)); - } - -+void QWidgetPrivate::setNetWmWindowTypes() -+{ -+ Q_Q(QWidget); -+ -+ if (!q->windowHandle()) -+ return; -+ -+ int wmWindowType = 0; -+ if (q->testAttribute(Qt::WA_X11NetWmWindowTypeDesktop)) -+ wmWindowType |= QXcbWindowFunctions::Desktop; -+ if (q->testAttribute(Qt::WA_X11NetWmWindowTypeDock)) -+ wmWindowType |= QXcbWindowFunctions::Dock; -+ if (q->testAttribute(Qt::WA_X11NetWmWindowTypeToolBar)) -+ wmWindowType |= QXcbWindowFunctions::Toolbar; -+ if (q->testAttribute(Qt::WA_X11NetWmWindowTypeMenu)) -+ wmWindowType |= QXcbWindowFunctions::Menu; -+ if (q->testAttribute(Qt::WA_X11NetWmWindowTypeUtility)) -+ wmWindowType |= QXcbWindowFunctions::Utility; -+ if (q->testAttribute(Qt::WA_X11NetWmWindowTypeSplash)) -+ wmWindowType |= QXcbWindowFunctions::Splash; -+ if (q->testAttribute(Qt::WA_X11NetWmWindowTypeDialog)) -+ wmWindowType |= QXcbWindowFunctions::Dialog; -+ if (q->testAttribute(Qt::WA_X11NetWmWindowTypeDropDownMenu)) -+ wmWindowType |= QXcbWindowFunctions::DropDownMenu; -+ if (q->testAttribute(Qt::WA_X11NetWmWindowTypePopupMenu)) -+ wmWindowType |= QXcbWindowFunctions::PopupMenu; -+ if (q->testAttribute(Qt::WA_X11NetWmWindowTypeToolTip)) -+ wmWindowType |= QXcbWindowFunctions::Tooltip; -+ if (q->testAttribute(Qt::WA_X11NetWmWindowTypeNotification)) -+ wmWindowType |= QXcbWindowFunctions::Notification; -+ if (q->testAttribute(Qt::WA_X11NetWmWindowTypeCombo)) -+ wmWindowType |= QXcbWindowFunctions::Combo; -+ if (q->testAttribute(Qt::WA_X11NetWmWindowTypeDND)) -+ wmWindowType |= QXcbWindowFunctions::Dnd; -+ -+ QXcbWindowFunctions::setWmWindowType(q->windowHandle(), static_cast(wmWindowType)); -+} -+ - /*! \fn Qt::HANDLE QWidget::macCGHandle() const - \internal - -diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h -index fe65cb1..dc1c580 100644 ---- a/src/widgets/kernel/qwidget_p.h -+++ b/src/widgets/kernel/qwidget_p.h -@@ -752,7 +752,6 @@ public: - - void setWindowRole(); - void sendStartupMessage(const char *message) const; -- void setNetWmWindowTypes(); - void x11UpdateIsOpaque(); - bool isBackgroundInherited() const; - void updateX11AcceptFocus(); -@@ -849,6 +848,8 @@ public: - static bool qt_widget_rgn(QWidget *, short, RgnHandle, bool); - void registerTouchWindow(bool enable = true); - #endif -+ void setNetWmWindowTypes(); -+ - bool stealKeyboardGrab(bool grab); - bool stealMouseGrab(bool grab); - }; --- -2.3.5 diff --git a/0005-xcb-Properly-initialize-available-geometry-when-XRan.patch b/0005-xcb-Properly-initialize-available-geometry-when-XRan.patch new file mode 100644 index 0000000..c2129b8 --- /dev/null +++ b/0005-xcb-Properly-initialize-available-geometry-when-XRan.patch @@ -0,0 +1,35 @@ +From bbfc5818bb9f8d87d64f6b6f94bbfe1cea199ec9 Mon Sep 17 00:00:00 2001 +From: Alexander Volkov +Date: Thu, 18 Feb 2016 18:12:57 +0300 +Subject: [PATCH 05/16] xcb: Properly initialize available geometry when XRandR + is missing +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Take an intersection of the screen geometry and the work area. + +Change-Id: Ia61d090ac103cb4d13d656ec09037f642b255a79 +Reviewed-by: Błażej Szczygieł +Reviewed-by: Shawn Rutledge +(cherry picked from commit 7cd23a7d5f5b7b10c0e317afcf8bc49020a42e53) +--- + src/plugins/platforms/xcb/qxcbscreen.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp +index f3d381b99e014116317286b791a0876ad6d8ca6d..0ef7166b9076e47fc71d4b2106cbfdc6420166d3 100644 +--- a/src/plugins/platforms/xcb/qxcbscreen.cpp ++++ b/src/plugins/platforms/xcb/qxcbscreen.cpp +@@ -208,7 +208,7 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDe + m_geometry = QRect(QPoint(), m_virtualSize); + + if (m_availableGeometry.isEmpty()) +- m_availableGeometry = m_geometry; ++ m_availableGeometry = m_geometry & m_virtualDesktop->workArea(); + + readXResources(); + +-- +2.6.6 + diff --git a/0006-xcb-properly-initialize-size-in-millimeters-if-XRand.patch b/0006-xcb-properly-initialize-size-in-millimeters-if-XRand.patch new file mode 100644 index 0000000..ba97f14 --- /dev/null +++ b/0006-xcb-properly-initialize-size-in-millimeters-if-XRand.patch @@ -0,0 +1,42 @@ +From 412a0b8502614ff6fac6b6b45c48091a19d67014 Mon Sep 17 00:00:00 2001 +From: Shawn Rutledge +Date: Thu, 18 Feb 2016 14:05:39 +0100 +Subject: [PATCH 06/16] xcb: properly initialize size in millimeters if XRandR + is not supported +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +QXcbScreen did not set the m_sizeMillimeters if the xcb connection does +not support XRandR. This caused physicalSize() to return an invalid QSize. + +This change fixes a regression compared to Qt 5.4 discovered by a +broken unit test for KWin on KDE's CI system, which uses Xvfb and by +that no XRandR support. + +Task-number: QTBUG-49885 +Change-Id: Ie472a194ba410f0748ccfda8aa467727fafa10a3 +Reviewed-by: Błażej Szczygieł +Reviewed-by: Shawn Rutledge +(cherry picked from commit 3f4eba746d23550be19dc4edafe193fa5ce0d3d4) +--- + src/plugins/platforms/xcb/qxcbscreen.cpp | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp +index 0ef7166b9076e47fc71d4b2106cbfdc6420166d3..28b175371264cd445c1bd67a8d33f6de5a8fa219 100644 +--- a/src/plugins/platforms/xcb/qxcbscreen.cpp ++++ b/src/plugins/platforms/xcb/qxcbscreen.cpp +@@ -210,6 +210,9 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, QXcbVirtualDesktop *virtualDe + if (m_availableGeometry.isEmpty()) + m_availableGeometry = m_geometry & m_virtualDesktop->workArea(); + ++ if (m_sizeMillimeters.isEmpty()) ++ m_sizeMillimeters = m_virtualSizeMillimeters; ++ + readXResources(); + + QScopedPointer rootAttribs( +-- +2.6.6 + diff --git a/0007-xcb-Deliver-mouse-enter-event-to-window-when-closing.patch b/0007-xcb-Deliver-mouse-enter-event-to-window-when-closing.patch new file mode 100644 index 0000000..0a171c5 --- /dev/null +++ b/0007-xcb-Deliver-mouse-enter-event-to-window-when-closing.patch @@ -0,0 +1,337 @@ +From 3ecd1178940a6fd9f486f62f711df4dc75197390 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= +Date: Tue, 19 Jan 2016 22:32:52 +0100 +Subject: [PATCH 07/16] xcb: Deliver mouse enter event to window when closing + modal window + +When a modal window is closed and the mouse is not under the modal +window - find a proper window and send a fake enter event. + +Added auto test for checking enter event on window when modal window +is closed. + +Task-number: QTBUG-35109 +Change-Id: I370b52d386503820ac9de21e6d05fd019ca456ec +Reviewed-by: Shawn Rutledge +(cherry picked from commit 7091be1b7999d93fe2126042161dcd1d8fd20026) +--- + src/plugins/platforms/xcb/qxcbwindow.cpp | 48 +++++++ + tests/auto/gui/kernel/qwindow/BLACKLIST | 2 + + tests/auto/gui/kernel/qwindow/tst_qwindow.cpp | 193 ++++++++++++++++++++++++++ + 3 files changed, 243 insertions(+) + +diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp +index 46b7b70f8025a8481ab2db37257a52494a84d234..7eae2d92ab39843d09cb6294f9afd7fc51260ecb 100644 +--- a/src/plugins/platforms/xcb/qxcbwindow.cpp ++++ b/src/plugins/platforms/xcb/qxcbwindow.cpp +@@ -50,6 +50,7 @@ + #include "qxcbsystemtraytracker.h" + + #include ++#include + + #include + +@@ -261,6 +262,26 @@ static inline XTextProperty* qstringToXTP(Display *dpy, const QString& s) + } + #endif // XCB_USE_XLIB + ++// TODO move this into a utility function in QWindow or QGuiApplication ++static QWindow *childWindowAt(QWindow *win, const QPoint &p) ++{ ++ foreach (QObject *obj, win->children()) { ++ if (obj->isWindowType()) { ++ QWindow *childWin = static_cast(obj); ++ if (childWin->isVisible()) { ++ if (QWindow *recurse = childWindowAt(childWin, p)) ++ return recurse; ++ } ++ } ++ } ++ if (!win->isTopLevel() ++ && !(win->flags() & Qt::WindowTransparentForInput) ++ && win->geometry().contains(win->parent()->mapFromGlobal(p))) { ++ return win; ++ } ++ return Q_NULLPTR; ++} ++ + static const char *wm_window_type_property_id = "_q_xcb_wm_window_type"; + + QXcbWindow::QXcbWindow(QWindow *window) +@@ -855,6 +876,33 @@ void QXcbWindow::hide() + connection()->setMouseGrabber(Q_NULLPTR); + + m_mapped = false; ++ ++ // Hiding a modal window doesn't send an enter event to its transient parent when the ++ // mouse is already over the parent window, so the enter event must be emulated. ++ if (window()->isModal()) { ++ // Get the cursor position at modal window screen ++ const QPoint nativePos = xcbScreen()->cursor()->pos(); ++ const QPoint cursorPos = QHighDpi::fromNativePixels(nativePos, xcbScreen()->screenForPosition(nativePos)->screen()); ++ ++ // Find the top level window at cursor position. ++ // Don't use QGuiApplication::topLevelAt(): search only the virtual siblings of this window's screen ++ QWindow *enterWindow = Q_NULLPTR; ++ foreach (QPlatformScreen *screen, xcbScreen()->virtualSiblings()) { ++ if (screen->geometry().contains(cursorPos)) { ++ const QPoint devicePosition = QHighDpi::toNativePixels(cursorPos, screen->screen()); ++ enterWindow = screen->topLevelAt(devicePosition); ++ break; ++ } ++ } ++ ++ if (enterWindow && enterWindow != window()) { ++ // Find the child window at cursor position, otherwise use the top level window ++ if (QWindow *childWindow = childWindowAt(enterWindow, cursorPos)) ++ enterWindow = childWindow; ++ const QPoint localPos = enterWindow->mapFromGlobal(cursorPos); ++ QWindowSystemInterface::handleEnterEvent(enterWindow, localPos, cursorPos); ++ } ++ } + } + + static QWindow *tlWindow(QWindow *window) +diff --git a/tests/auto/gui/kernel/qwindow/BLACKLIST b/tests/auto/gui/kernel/qwindow/BLACKLIST +index ee9709e68ba75bfc29903111087abe31040a059d..a34066dd7cec05f2e089582c87791e81d388a482 100644 +--- a/tests/auto/gui/kernel/qwindow/BLACKLIST ++++ b/tests/auto/gui/kernel/qwindow/BLACKLIST +@@ -4,3 +4,5 @@ ubuntu-14.04 + ubuntu-14.04 + [modalWithChildWindow] + ubuntu-14.04 ++[modalWindowEnterEventOnHide_QTBUG35109] ++ubuntu-14.04 +diff --git a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp +index a89f0da4d27c01a345a475ebf7fcaffb83d797c3..0cce5a072caf6a9ed63bab8c9318edbc8453e717 100644 +--- a/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp ++++ b/tests/auto/gui/kernel/qwindow/tst_qwindow.cpp +@@ -92,6 +92,9 @@ private slots: + void modalWithChildWindow(); + void modalWindowModallity(); + void modalWindowPosition(); ++#ifndef QT_NO_CURSOR ++ void modalWindowEnterEventOnHide_QTBUG35109(); ++#endif + void windowsTransientChildren(); + void requestUpdate(); + void initTestCase(); +@@ -706,10 +709,24 @@ public: + } + } + } ++ bool event(QEvent *e) { ++ switch (e->type()) { ++ case QEvent::Enter: ++ ++enterEventCount; ++ break; ++ case QEvent::Leave: ++ ++leaveEventCount; ++ break; ++ default: ++ break; ++ } ++ return QWindow::event(e); ++ } + void resetCounters() { + mousePressedCount = mouseReleasedCount = mouseMovedCount = mouseDoubleClickedCount = 0; + mouseSequenceSignature = QString(); + touchPressedCount = touchReleasedCount = touchMovedCount = 0; ++ enterEventCount = leaveEventCount = 0; + } + + InputTestWindow() { +@@ -727,6 +744,7 @@ public: + QPointF mousePressScreenPos, mouseMoveScreenPos, mousePressLocalPos; + int touchPressedCount, touchReleasedCount, touchMovedCount; + QEvent::Type touchEventType; ++ int enterEventCount, leaveEventCount; + + bool ignoreMouse, ignoreTouch; + +@@ -1732,6 +1750,181 @@ void tst_QWindow::modalWindowPosition() + QCOMPARE(window.geometry(), origGeo); + } + ++#ifndef QT_NO_CURSOR ++void tst_QWindow::modalWindowEnterEventOnHide_QTBUG35109() ++{ ++ if (QGuiApplication::platformName() == QLatin1String("cocoa")) ++ QSKIP("This test fails on OS X on CI"); ++ ++ const QPoint center = QGuiApplication::primaryScreen()->availableGeometry().center(); ++ ++ const int childOffset = 16; ++ const QPoint rootPos = center - QPoint(m_testWindowSize.width(), ++ m_testWindowSize.height())/2; ++ const QPoint modalPos = rootPos + QPoint(childOffset * 5, ++ childOffset * 5); ++ const QPoint cursorPos = rootPos - QPoint(80, 80); ++ ++ // Test whether tlw can receive the enter event ++ { ++ QCursor::setPos(cursorPos); ++ QCoreApplication::processEvents(); ++ ++ InputTestWindow root; ++ root.setTitle(__FUNCTION__); ++ root.setGeometry(QRect(rootPos, m_testWindowSize)); ++ root.show(); ++ QVERIFY(QTest::qWaitForWindowExposed(&root)); ++ root.requestActivate(); ++ QVERIFY(QTest::qWaitForWindowActive(&root)); ++ ++ // Move the mouse over the root window, but not over the modal window. ++ QCursor::setPos(rootPos + QPoint(childOffset * 5 / 2, ++ childOffset * 5 / 2)); ++ ++ // Wait for the enter event. It must be delivered here, otherwise second ++ // compare can PASS because of this event even after "resetCounters()". ++ QTRY_COMPARE(root.enterEventCount, 1); ++ QTRY_COMPARE(root.leaveEventCount, 0); ++ ++ QWindow modal; ++ modal.setTitle(QLatin1String("Modal - ") + __FUNCTION__); ++ modal.setTransientParent(&root); ++ modal.resize(m_testWindowSize/2); ++ modal.setFramePosition(modalPos); ++ modal.setModality(Qt::ApplicationModal); ++ modal.show(); ++ QVERIFY(QTest::qWaitForWindowExposed(&modal)); ++ modal.requestActivate(); ++ QVERIFY(QTest::qWaitForWindowActive(&modal)); ++ ++ QCoreApplication::processEvents(); ++ QTRY_COMPARE(root.leaveEventCount, 1); ++ ++ root.resetCounters(); ++ modal.close(); ++ ++ // Check for the enter event ++ QTRY_COMPARE(root.enterEventCount, 1); ++ } ++ ++ // Test whether child window can receive the enter event ++ { ++ QCursor::setPos(cursorPos); ++ QCoreApplication::processEvents(); ++ ++ QWindow root; ++ root.setTitle(__FUNCTION__); ++ root.setGeometry(QRect(rootPos, m_testWindowSize)); ++ ++ QWindow childLvl1; ++ childLvl1.setParent(&root); ++ childLvl1.setGeometry(childOffset, ++ childOffset, ++ m_testWindowSize.width() - childOffset, ++ m_testWindowSize.height() - childOffset); ++ ++ InputTestWindow childLvl2; ++ childLvl2.setParent(&childLvl1); ++ childLvl2.setGeometry(childOffset, ++ childOffset, ++ childLvl1.width() - childOffset, ++ childLvl1.height() - childOffset); ++ ++ root.show(); ++ childLvl1.show(); ++ childLvl2.show(); ++ ++ QVERIFY(QTest::qWaitForWindowExposed(&root)); ++ root.requestActivate(); ++ QVERIFY(QTest::qWaitForWindowActive(&root)); ++ QVERIFY(childLvl1.isVisible()); ++ QVERIFY(childLvl2.isVisible()); ++ ++ // Move the mouse over the child window, but not over the modal window. ++ // Be sure that the value is almost left-top of second child window for ++ // checking proper position mapping. ++ QCursor::setPos(rootPos + QPoint(childOffset * 5 / 2, ++ childOffset * 5 / 2)); ++ ++ // Wait for the enter event. It must be delivered here, otherwise second ++ // compare can PASS because of this event even after "resetCounters()". ++ QTRY_COMPARE(childLvl2.enterEventCount, 1); ++ QTRY_COMPARE(childLvl2.leaveEventCount, 0); ++ ++ QWindow modal; ++ modal.setTitle(QLatin1String("Modal - ") + __FUNCTION__); ++ modal.setTransientParent(&root); ++ modal.resize(m_testWindowSize/2); ++ modal.setFramePosition(modalPos); ++ modal.setModality(Qt::ApplicationModal); ++ modal.show(); ++ QVERIFY(QTest::qWaitForWindowExposed(&modal)); ++ modal.requestActivate(); ++ QVERIFY(QTest::qWaitForWindowActive(&modal)); ++ ++ QCoreApplication::processEvents(); ++ QTRY_COMPARE(childLvl2.leaveEventCount, 1); ++ ++ childLvl2.resetCounters(); ++ modal.close(); ++ ++ // Check for the enter event ++ QTRY_COMPARE(childLvl2.enterEventCount, 1); ++ } ++ ++ // Test whether tlw can receive the enter event if mouse is over the invisible child windnow ++ { ++ QCursor::setPos(cursorPos); ++ QCoreApplication::processEvents(); ++ ++ InputTestWindow root; ++ root.setTitle(__FUNCTION__); ++ root.setGeometry(QRect(rootPos, m_testWindowSize)); ++ ++ QWindow child; ++ child.setParent(&root); ++ child.setGeometry(QRect(QPoint(), m_testWindowSize)); ++ ++ root.show(); ++ ++ QVERIFY(QTest::qWaitForWindowExposed(&root)); ++ root.requestActivate(); ++ QVERIFY(QTest::qWaitForWindowActive(&root)); ++ QVERIFY(!child.isVisible()); ++ ++ // Move the mouse over the child window, but not over the modal window. ++ QCursor::setPos(rootPos + QPoint(childOffset * 5 / 2, ++ childOffset * 5 / 2)); ++ ++ // Wait for the enter event. It must be delivered here, otherwise second ++ // compare can PASS because of this event even after "resetCounters()". ++ QTRY_COMPARE(root.enterEventCount, 1); ++ QTRY_COMPARE(root.leaveEventCount, 0); ++ ++ QWindow modal; ++ modal.setTitle(QLatin1String("Modal - ") + __FUNCTION__); ++ modal.setTransientParent(&root); ++ modal.resize(m_testWindowSize/2); ++ modal.setFramePosition(modalPos); ++ modal.setModality(Qt::ApplicationModal); ++ modal.show(); ++ QVERIFY(QTest::qWaitForWindowExposed(&modal)); ++ modal.requestActivate(); ++ QVERIFY(QTest::qWaitForWindowActive(&modal)); ++ ++ QCoreApplication::processEvents(); ++ QTRY_COMPARE(root.leaveEventCount, 1); ++ ++ root.resetCounters(); ++ modal.close(); ++ ++ // Check for the enter event ++ QTRY_COMPARE(root.enterEventCount, 1); ++ } ++} ++#endif ++ + class ColoredWindow : public QRasterWindow { + public: + explicit ColoredWindow(const QColor &color, QWindow *parent = 0) : QRasterWindow(parent), m_color(color) {} +-- +2.6.6 + diff --git a/0008-xcb-resourceType-names-must-have-only-small-letters.patch b/0008-xcb-resourceType-names-must-have-only-small-letters.patch new file mode 100644 index 0000000..892f7aa --- /dev/null +++ b/0008-xcb-resourceType-names-must-have-only-small-letters.patch @@ -0,0 +1,28 @@ +From e467aba779546f73f8308838071fe7da00d2ec7e Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= +Date: Thu, 3 Mar 2016 01:43:41 +0100 +Subject: [PATCH 08/16] xcb: resourceType names must have only small letters + +Change-Id: I563ae26c9e7e6111399fd0b9af7bfb3ff750b34a +Reviewed-by: Shawn Rutledge +(cherry picked from commit caa82c3518b4a5c09b1de990874190d5d765656f) +--- + src/plugins/platforms/xcb/qxcbnativeinterface.cpp | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp +index dfb0a125e25ea72c6a9f5aaf3e3145a2eb3efbeb..f6bd878bde4ef1b659fc22d357a691e5ae6bfc71 100644 +--- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp ++++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp +@@ -76,7 +76,7 @@ static int resourceType(const QByteArray &key) + QByteArrayLiteral("startupid"), QByteArrayLiteral("traywindow"), + QByteArrayLiteral("gettimestamp"), QByteArrayLiteral("x11screen"), + QByteArrayLiteral("rootwindow"), +- QByteArrayLiteral("subpixeltype"), QByteArrayLiteral("antialiasingEnabled"), ++ QByteArrayLiteral("subpixeltype"), QByteArrayLiteral("antialiasingenabled"), + QByteArrayLiteral("nofonthinting"), + QByteArrayLiteral("atspibus") + }; +-- +2.6.6 + diff --git a/0009-Expose-the-number-of-X-screen-through-the-QXcbScreen.patch b/0009-Expose-the-number-of-X-screen-through-the-QXcbScreen.patch new file mode 100644 index 0000000..ad9a300 --- /dev/null +++ b/0009-Expose-the-number-of-X-screen-through-the-QXcbScreen.patch @@ -0,0 +1,153 @@ +From fd6049144e0ba5b4696798eadd84da021438d050 Mon Sep 17 00:00:00 2001 +From: Alexander Volkov +Date: Thu, 10 Sep 2015 14:44:52 +0300 +Subject: [PATCH 09/16] Expose the number of X screen through the + QXcbScreenFunctions + +X screen corresponds to Qt virtual desktop, and RandR output +corresponds to QScreen. There can be more than one X screen, +so we need a way to get the number of X screen for QScreen, +in particular for the right implementation of some methods +in QX11Info. + +Change-Id: Ib5e38703bf11ae08bb283f26a7b7b15f1a5e8671 +Reviewed-by: Shawn Rutledge +(cherry picked from commit 362b977e7c99d47c9c598cef946273089881fd81) +--- + .../xcbfunctions/qxcbscreenfunctions.h | 56 ++++++++++++++++++++++ + src/platformheaders/xcbfunctions/xcbfunctions.pri | 3 +- + src/plugins/platforms/xcb/qxcbnativeinterface.cpp | 5 ++ + src/plugins/platforms/xcb/qxcbscreen.cpp | 8 ++++ + src/plugins/platforms/xcb/qxcbscreen.h | 1 + + 5 files changed, 72 insertions(+), 1 deletion(-) + create mode 100644 src/platformheaders/xcbfunctions/qxcbscreenfunctions.h + +diff --git a/src/platformheaders/xcbfunctions/qxcbscreenfunctions.h b/src/platformheaders/xcbfunctions/qxcbscreenfunctions.h +new file mode 100644 +index 0000000000000000000000000000000000000000..7773c275b9d6d6bacbf776d13cbb5a5ccbcf2bbf +--- /dev/null ++++ b/src/platformheaders/xcbfunctions/qxcbscreenfunctions.h +@@ -0,0 +1,56 @@ ++/**************************************************************************** ++** ++** Copyright (C) 2016 The Qt Company Ltd. ++** Contact: http://www.qt.io/licensing/ ++** ++** This file is part of the plugins of the Qt Toolkit. ++** ++** $QT_BEGIN_LICENSE:LGPL21$ ++** 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 http://www.qt.io/terms-conditions. For further ++** information use the contact form at http://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 2.1 or version 3 as published by the Free ++** Software Foundation and appearing in the file LICENSE.LGPLv21 and ++** LICENSE.LGPLv3 included in the packaging of this file. Please review the ++** following information to ensure the GNU Lesser General Public License ++** requirements will be met: https://www.gnu.org/licenses/lgpl.html and ++** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. ++** ++** As a special exception, The Qt Company gives you certain additional ++** rights. These rights are described in The Qt Company LGPL Exception ++** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. ++** ++** $QT_END_LICENSE$ ++** ++****************************************************************************/ ++ ++#ifndef QXCBSCREENFUNCTIONS_H ++#define QXCBSCREENFUNCTIONS_H ++ ++#include ++ ++QT_BEGIN_NAMESPACE ++ ++class QScreen; ++ ++class QXcbScreenFunctions ++{ ++public: ++ typedef bool (*VirtualDesktopNumber)(const QScreen *screen); ++ static const QByteArray virtualDesktopNumberIdentifier() { return QByteArrayLiteral("XcbVirtualDesktopNumber"); } ++ static int virtualDesktopNumber(const QScreen *screen) ++ { ++ return QPlatformHeaderHelper::callPlatformFunction(virtualDesktopNumberIdentifier(), screen); ++ } ++}; ++ ++QT_END_NAMESPACE ++ ++#endif /*QXCBSCREENFUNCTIONS_H*/ +diff --git a/src/platformheaders/xcbfunctions/xcbfunctions.pri b/src/platformheaders/xcbfunctions/xcbfunctions.pri +index 7f611d80bd5518b1e018a4738c0da79d814d2f47..3f2bcb2b34cb23e55ad57898b44ff442d66980e3 100644 +--- a/src/platformheaders/xcbfunctions/xcbfunctions.pri ++++ b/src/platformheaders/xcbfunctions/xcbfunctions.pri +@@ -1,3 +1,4 @@ + HEADERS += \ + $$PWD/qxcbwindowfunctions.h \ +- $$PWD/qxcbintegrationfunctions.h ++ $$PWD/qxcbintegrationfunctions.h \ ++ $$PWD/qxcbscreenfunctions.h +diff --git a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp +index f6bd878bde4ef1b659fc22d357a691e5ae6bfc71..96239a0f2041d901500fd645d6c699a93ceda5c9 100644 +--- a/src/plugins/platforms/xcb/qxcbnativeinterface.cpp ++++ b/src/plugins/platforms/xcb/qxcbnativeinterface.cpp +@@ -48,6 +48,7 @@ + + #include + #include ++#include + + #ifndef QT_NO_DBUS + #include "QtPlatformSupport/private/qdbusmenuconnection_p.h" +@@ -367,6 +368,10 @@ QFunctionPointer QXcbNativeInterface::platformFunction(const QByteArray &functio + if (function == QXcbWindowFunctions::visualIdIdentifier()) { + return QFunctionPointer(QXcbWindowFunctions::VisualId(QXcbWindow::visualIdStatic)); + } ++ ++ if (function == QXcbScreenFunctions::virtualDesktopNumberIdentifier()) ++ return QFunctionPointer(QXcbScreenFunctions::VirtualDesktopNumber(QXcbScreen::virtualDesktopNumberStatic)); ++ + return Q_NULLPTR; + } + +diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp +index 28b175371264cd445c1bd67a8d33f6de5a8fa219..1a90f824fc454c69f73ac195b1241bc6371d7aed 100644 +--- a/src/plugins/platforms/xcb/qxcbscreen.cpp ++++ b/src/plugins/platforms/xcb/qxcbscreen.cpp +@@ -438,6 +438,14 @@ void QXcbScreen::setOutput(xcb_randr_output_t outputId, + // TODO: Send an event to the QScreen instance that the screen changed its name + } + ++int QXcbScreen::virtualDesktopNumberStatic(const QScreen *screen) ++{ ++ if (screen && screen->handle()) ++ return static_cast(screen->handle())->screenNumber(); ++ ++ return 0; ++} ++ + /*! + \brief handle the XCB screen change event and update properties + +diff --git a/src/plugins/platforms/xcb/qxcbscreen.h b/src/plugins/platforms/xcb/qxcbscreen.h +index f4de2b9dfd5e3042f4192b85c8e7b9b79aa04e74..7376ddf35c3b34ef7f5310299039431a9a97d45b 100644 +--- a/src/plugins/platforms/xcb/qxcbscreen.h ++++ b/src/plugins/platforms/xcb/qxcbscreen.h +@@ -133,6 +133,7 @@ public: + bool isPrimary() const { return m_primary; } + + int screenNumber() const { return m_virtualDesktop->number(); } ++ static int virtualDesktopNumberStatic(const QScreen *screen); + + xcb_screen_t *screen() const { return m_virtualDesktop->screen(); } + xcb_window_t root() const { return screen()->root; } +-- +2.6.6 + diff --git a/0010-xcb-mark-mouse-events-from-tablet-devices-as-synthes.patch b/0010-xcb-mark-mouse-events-from-tablet-devices-as-synthes.patch new file mode 100644 index 0000000..b7496e0 --- /dev/null +++ b/0010-xcb-mark-mouse-events-from-tablet-devices-as-synthes.patch @@ -0,0 +1,199 @@ +From c44d853fd7e71eff0e1a1d4512c2215a1e701008 Mon Sep 17 00:00:00 2001 +From: Shawn Rutledge +Date: Tue, 8 Mar 2016 15:50:20 +0100 +Subject: [PATCH 10/16] xcb: mark mouse events from tablet devices as + synthesized + +Task-number: QTBUG-51617 +Change-Id: Ic1d258c56165947ff821b1bf4d044bcf29b41a3b +Reviewed-by: Laszlo Agocs +(cherry picked from commit d7db6c6c1944894737babf3958d0cff1e6222a22) +--- + src/plugins/platforms/xcb/qxcbconnection.h | 2 +- + src/plugins/platforms/xcb/qxcbconnection_xi2.cpp | 2 +- + src/plugins/platforms/xcb/qxcbwindow.cpp | 39 +++++++++++++++--------- + src/plugins/platforms/xcb/qxcbwindow.h | 11 ++++--- + 4 files changed, 32 insertions(+), 22 deletions(-) + +diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h +index 6c2b8583af24e9abd7a087144fb33504ec36fbf8..4d318457e3b05de8c343580aad217cc1bad9072c 100644 +--- a/src/plugins/platforms/xcb/qxcbconnection.h ++++ b/src/plugins/platforms/xcb/qxcbconnection.h +@@ -348,7 +348,7 @@ public: + virtual void handleFocusOutEvent(const xcb_focus_out_event_t *) {} + virtual void handlePropertyNotifyEvent(const xcb_property_notify_event_t *) {} + #ifdef XCB_USE_XINPUT22 +- virtual void handleXIMouseEvent(xcb_ge_event_t *) {} ++ virtual void handleXIMouseEvent(xcb_ge_event_t *, Qt::MouseEventSource = Qt::MouseEventNotSynthesized) {} + virtual void handleXIEnterLeave(xcb_ge_event_t *) {} + #endif + virtual QXcbWindow *toWindow() { return 0; } +diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +index 0c78c0e0d2bc9d05e9f6768ead72cad4a51d03a7..bf961318a343e56ee4e4a72a854ff757875be534 100644 +--- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp ++++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp +@@ -1096,7 +1096,7 @@ bool QXcbConnection::xi2HandleTabletEvent(void *event, TabletData *tabletData, Q + // Synthesize mouse events since otherwise there are no mouse events from + // the pen on the XI 2.2+ path. + if (xi2MouseEvents() && eventListener) +- eventListener->handleXIMouseEvent(reinterpret_cast(event)); ++ eventListener->handleXIMouseEvent(reinterpret_cast(event), Qt::MouseEventSynthesizedByQt); + #else + Q_UNUSED(eventListener); + #endif +diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp +index 7eae2d92ab39843d09cb6294f9afd7fc51260ecb..5ed35ec8e2bbc0c29b72fb616a746a352a9df969 100644 +--- a/src/plugins/platforms/xcb/qxcbwindow.cpp ++++ b/src/plugins/platforms/xcb/qxcbwindow.cpp +@@ -34,6 +34,7 @@ + #include "qxcbwindow.h" + + #include ++#include + #include + #include + #include +@@ -2157,7 +2158,7 @@ void QXcbWindow::handleUnmapNotifyEvent(const xcb_unmap_notify_event_t *event) + } + + void QXcbWindow::handleButtonPressEvent(int event_x, int event_y, int root_x, int root_y, +- int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp) ++ int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp, Qt::MouseEventSource source) + { + const bool isWheel = detail >= 4 && detail <= 7; + if (!isWheel && window() != QGuiApplication::focusWindow()) { +@@ -2193,11 +2194,11 @@ void QXcbWindow::handleButtonPressEvent(int event_x, int event_y, int root_x, in + return; + } + +- handleMouseEvent(timestamp, local, global, modifiers); ++ handleMouseEvent(timestamp, local, global, modifiers, source); + } + + void QXcbWindow::handleButtonReleaseEvent(int event_x, int event_y, int root_x, int root_y, +- int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp) ++ int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp, Qt::MouseEventSource source) + { + QPoint local(event_x, event_y); + QPoint global(root_x, root_y); +@@ -2207,7 +2208,7 @@ void QXcbWindow::handleButtonReleaseEvent(int event_x, int event_y, int root_x, + return; + } + +- handleMouseEvent(timestamp, local, global, modifiers); ++ handleMouseEvent(timestamp, local, global, modifiers, source); + } + + static bool ignoreLeaveEvent(quint8 mode, quint8 detail) +@@ -2290,11 +2291,11 @@ void QXcbWindow::handleLeaveNotifyEvent(int root_x, int root_y, + } + + void QXcbWindow::handleMotionNotifyEvent(int event_x, int event_y, int root_x, int root_y, +- Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp) ++ Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp, Qt::MouseEventSource source) + { + QPoint local(event_x, event_y); + QPoint global(root_x, root_y); +- handleMouseEvent(timestamp, local, global, modifiers); ++ handleMouseEvent(timestamp, local, global, modifiers, source); + } + + // Handlers for plain xcb events. Used only when XI 2.2 or newer is not available. +@@ -2325,7 +2326,7 @@ static inline int fixed1616ToInt(FP1616 val) + } + + // With XI 2.2+ press/release/motion comes here instead of the above handlers. +-void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event) ++void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event, Qt::MouseEventSource source) + { + QXcbConnection *conn = connection(); + xXIDeviceEvent *ev = reinterpret_cast(event); +@@ -2345,20 +2346,27 @@ void QXcbWindow::handleXIMouseEvent(xcb_ge_event_t *event) + conn->setButton(conn->translateMouseButton(i), XIMaskIsSet(buttonMask, i)); + } + ++ const char *sourceName = nullptr; ++ if (lcQpaXInput().isDebugEnabled()) { ++ const QMetaObject *metaObject = qt_getEnumMetaObject(source); ++ const QMetaEnum me = metaObject->enumerator(metaObject->indexOfEnumerator(qt_getEnumName(source))); ++ sourceName = me.valueToKey(source); ++ } ++ + switch (ev->evtype) { + case XI_ButtonPress: +- qCDebug(lcQpaXInput, "XI2 mouse press, button %d, time %d", button, ev->time); ++ qCDebug(lcQpaXInput, "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); ++ handleButtonPressEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time, source); + break; + case XI_ButtonRelease: +- qCDebug(lcQpaXInput, "XI2 mouse release, button %d, time %d", button, ev->time); ++ qCDebug(lcQpaXInput, "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); ++ handleButtonReleaseEvent(event_x, event_y, root_x, root_y, ev->detail, modifiers, ev->time, source); + break; + case XI_Motion: +- qCDebug(lcQpaXInput, "XI2 mouse motion %d,%d, time %d", event_x, event_y, ev->time); +- handleMotionNotifyEvent(event_x, event_y, root_x, root_y, modifiers, ev->time); ++ qCDebug(lcQpaXInput, "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); + break; + default: + qWarning() << "Unrecognized XI2 mouse event" << ev->evtype; +@@ -2401,10 +2409,11 @@ void QXcbWindow::handleXIEnterLeave(xcb_ge_event_t *event) + + QXcbWindow *QXcbWindow::toWindow() { return this; } + +-void QXcbWindow::handleMouseEvent(xcb_timestamp_t time, const QPoint &local, const QPoint &global, Qt::KeyboardModifiers modifiers) ++void QXcbWindow::handleMouseEvent(xcb_timestamp_t time, const QPoint &local, const QPoint &global, ++ Qt::KeyboardModifiers modifiers, Qt::MouseEventSource source) + { + connection()->setTime(time); +- QWindowSystemInterface::handleMouseEvent(window(), time, local, global, connection()->buttons(), modifiers); ++ QWindowSystemInterface::handleMouseEvent(window(), time, local, global, connection()->buttons(), modifiers, source); + } + + void QXcbWindow::handleEnterNotifyEvent(const xcb_enter_notify_event_t *event) +diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h +index 69790f29ae098bbfcc5aa6edec75e3d0fea8ea75..4673f3dd33fd5cc9aa12bc1c50244b84ee3e398e 100644 +--- a/src/plugins/platforms/xcb/qxcbwindow.h ++++ b/src/plugins/platforms/xcb/qxcbwindow.h +@@ -133,13 +133,14 @@ 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 handleXIMouseEvent(xcb_ge_event_t *) Q_DECL_OVERRIDE; ++ void handleXIMouseEvent(xcb_ge_event_t *, Qt::MouseEventSource source = Qt::MouseEventNotSynthesized) Q_DECL_OVERRIDE; + void handleXIEnterLeave(xcb_ge_event_t *) Q_DECL_OVERRIDE; + #endif + + QXcbWindow *toWindow() Q_DECL_OVERRIDE; + +- void handleMouseEvent(xcb_timestamp_t time, const QPoint &local, const QPoint &global, Qt::KeyboardModifiers modifiers); ++ void handleMouseEvent(xcb_timestamp_t time, const QPoint &local, const QPoint &global, ++ Qt::KeyboardModifiers modifiers, Qt::MouseEventSource source); + + void updateNetWmUserTime(xcb_timestamp_t timestamp); + +@@ -207,13 +208,13 @@ protected: + bool compressExposeEvent(QRegion &exposeRegion); + + void handleButtonPressEvent(int event_x, int event_y, int root_x, int root_y, +- int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp); ++ int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp, Qt::MouseEventSource source = Qt::MouseEventNotSynthesized); + + void handleButtonReleaseEvent(int event_x, int event_y, int root_x, int root_y, +- int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp); ++ int detail, Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp, Qt::MouseEventSource source = Qt::MouseEventNotSynthesized); + + void handleMotionNotifyEvent(int event_x, int event_y, int root_x, int root_y, +- Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp); ++ Qt::KeyboardModifiers modifiers, xcb_timestamp_t timestamp, Qt::MouseEventSource source = Qt::MouseEventNotSynthesized); + + void handleEnterNotifyEvent(int event_x, int event_y, int root_x, int root_y, + quint8 mode, quint8 detail, xcb_timestamp_t timestamp); +-- +2.6.6 + diff --git a/0011-xcb-Initialize-all-xcb_client_message_event_t-member.patch b/0011-xcb-Initialize-all-xcb_client_message_event_t-member.patch new file mode 100644 index 0000000..e65c4af --- /dev/null +++ b/0011-xcb-Initialize-all-xcb_client_message_event_t-member.patch @@ -0,0 +1,142 @@ +From 3c8b9236ed7a0b1284922097da875cc8baa1bb78 Mon Sep 17 00:00:00 2001 +From: Shawn Rutledge +Date: Mon, 14 Mar 2016 10:07:20 +0100 +Subject: [PATCH 11/16] xcb: Initialize all xcb_client_message_event_t members + before use + +Change-Id: I01e4b69b138fd19fc7e67751d93adebc1326b2f9 +Reviewed-by: Orgad Shaneh +(cherry picked from commit 6c53f2528c86fb72f19951a799f0afaa02ad4490) +--- + src/plugins/platforms/xcb/qxcbdrag.cpp | 6 ++++++ + src/plugins/platforms/xcb/qxcbscreen.cpp | 1 + + src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp | 2 +- + src/plugins/platforms/xcb/qxcbwindow.cpp | 5 +++++ + 4 files changed, 13 insertions(+), 1 deletion(-) + +diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp +index aa6445d2da56f09696c98cba76baf6c74e44841c..f5cc87394b941014a1f45e0064d341dc8ad093d0 100644 +--- a/src/plugins/platforms/xcb/qxcbdrag.cpp ++++ b/src/plugins/platforms/xcb/qxcbdrag.cpp +@@ -423,6 +423,7 @@ void QXcbDrag::move(const QPoint &globalPos) + + xcb_client_message_event_t enter; + enter.response_type = XCB_CLIENT_MESSAGE; ++ enter.sequence = 0; + enter.window = target; + enter.format = 32; + enter.type = atom(QXcbAtom::XdndEnter); +@@ -451,6 +452,7 @@ void QXcbDrag::move(const QPoint &globalPos) + + xcb_client_message_event_t move; + move.response_type = XCB_CLIENT_MESSAGE; ++ move.sequence = 0; + move.window = target; + move.format = 32; + move.type = atom(QXcbAtom::XdndPosition); +@@ -479,6 +481,7 @@ void QXcbDrag::drop(const QPoint &globalPos) + + xcb_client_message_event_t drop; + drop.response_type = XCB_CLIENT_MESSAGE; ++ drop.sequence = 0; + drop.window = current_target; + drop.format = 32; + drop.type = atom(QXcbAtom::XdndDrop); +@@ -740,6 +743,7 @@ void QXcbDrag::handle_xdnd_position(QPlatformWindow *w, const xcb_client_message + + xcb_client_message_event_t response; + response.response_type = XCB_CLIENT_MESSAGE; ++ response.sequence = 0; + response.window = xdnd_dragsource; + response.format = 32; + response.type = atom(QXcbAtom::XdndStatus); +@@ -886,6 +890,7 @@ void QXcbDrag::send_leave() + + xcb_client_message_event_t leave; + leave.response_type = XCB_CLIENT_MESSAGE; ++ leave.sequence = 0; + leave.window = current_target; + leave.format = 32; + leave.type = atom(QXcbAtom::XdndLeave); +@@ -956,6 +961,7 @@ void QXcbDrag::handleDrop(QPlatformWindow *, const xcb_client_message_event_t *e + + xcb_client_message_event_t finished; + finished.response_type = XCB_CLIENT_MESSAGE; ++ finished.sequence = 0; + finished.window = xdnd_dragsource; + finished.format = 32; + finished.type = atom(QXcbAtom::XdndFinished); +diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp +index 1a90f824fc454c69f73ac195b1241bc6371d7aed..f74244e13c852d4a4844bb6e470d037e03a45c84 100644 +--- a/src/plugins/platforms/xcb/qxcbscreen.cpp ++++ b/src/plugins/platforms/xcb/qxcbscreen.cpp +@@ -361,6 +361,7 @@ void QXcbScreen::sendStartupMessage(const QByteArray &message) const + ev.response_type = XCB_CLIENT_MESSAGE; + ev.format = 8; + ev.type = connection()->atom(QXcbAtom::_NET_STARTUP_INFO_BEGIN); ++ ev.sequence = 0; + ev.window = rootWindow; + int sent = 0; + int length = message.length() + 1; // include NUL byte +diff --git a/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp b/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp +index 1f217e8de798d5161ec52bf8e88508f7314e6328..49c0440a3c4b48e2abaff5515cc4341257bcbc88 100644 +--- a/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp ++++ b/src/plugins/platforms/xcb/qxcbsystemtraytracker.cpp +@@ -94,9 +94,9 @@ xcb_window_t QXcbSystemTrayTracker::locateTrayWindow(const QXcbConnection *conne + void QXcbSystemTrayTracker::requestSystemTrayWindowDock(xcb_window_t window) const + { + xcb_client_message_event_t trayRequest; +- memset(&trayRequest, 0, sizeof(trayRequest)); + trayRequest.response_type = XCB_CLIENT_MESSAGE; + trayRequest.format = 32; ++ trayRequest.sequence = 0; + trayRequest.window = m_trayWindow; + trayRequest.type = m_trayAtom; + trayRequest.data.data32[0] = XCB_CURRENT_TIME; +diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp +index 5ed35ec8e2bbc0c29b72fb616a746a352a9df969..1dc066c692d5beaf632ead78784683c928d1c1e4 100644 +--- a/src/plugins/platforms/xcb/qxcbwindow.cpp ++++ b/src/plugins/platforms/xcb/qxcbwindow.cpp +@@ -1224,6 +1224,7 @@ void QXcbWindow::changeNetWmState(bool set, xcb_atom_t one, xcb_atom_t two) + + event.response_type = XCB_CLIENT_MESSAGE; + event.format = 32; ++ event.sequence = 0; + event.window = m_window; + event.type = atom(QXcbAtom::_NET_WM_STATE); + event.data.data32[0] = set ? 1 : 0; +@@ -1265,6 +1266,7 @@ void QXcbWindow::setWindowState(Qt::WindowState state) + + event.response_type = XCB_CLIENT_MESSAGE; + event.format = 32; ++ event.sequence = 0; + event.window = m_window; + event.type = atom(QXcbAtom::WM_CHANGE_STATE); + event.data.data32[0] = XCB_WM_STATE_ICONIC; +@@ -1660,6 +1662,7 @@ void QXcbWindow::requestActivateWindow() + + event.response_type = XCB_CLIENT_MESSAGE; + event.format = 32; ++ event.sequence = 0; + event.window = m_window; + event.type = atom(QXcbAtom::_NET_ACTIVE_WINDOW); + event.data.data32[0] = 1; +@@ -2607,6 +2610,7 @@ bool QXcbWindow::startSystemResize(const QPoint &pos, Qt::Corner corner) + xcb_client_message_event_t xev; + xev.response_type = XCB_CLIENT_MESSAGE; + xev.type = moveResize; ++ xev.sequence = 0; + xev.window = xcb_window(); + xev.format = 32; + const QPoint globalPos = window()->mapToGlobal(pos); +@@ -2635,6 +2639,7 @@ void QXcbWindow::sendXEmbedMessage(xcb_window_t window, quint32 message, + + event.response_type = XCB_CLIENT_MESSAGE; + event.format = 32; ++ event.sequence = 0; + event.window = window; + event.type = atom(QXcbAtom::_XEMBED); + event.data.data32[0] = connection()->time(); +-- +2.6.6 + diff --git a/0012-xcb-Merge-_NET_WM_STATE-hints-instead-of-overwriting.patch b/0012-xcb-Merge-_NET_WM_STATE-hints-instead-of-overwriting.patch new file mode 100644 index 0000000..b09f902 --- /dev/null +++ b/0012-xcb-Merge-_NET_WM_STATE-hints-instead-of-overwriting.patch @@ -0,0 +1,71 @@ +From cc32b65569c3cd947a7d012d41379490c9bf80c0 Mon Sep 17 00:00:00 2001 +From: David Rosca +Date: Wed, 16 Mar 2016 08:35:22 +0100 +Subject: [PATCH 12/16] xcb: Merge _NET_WM_STATE hints instead of overwriting + +This makes possible to set custom _NET_WM_STATE hints before +showing the window. + +Change-Id: I86ad3863f7a8b3bb610a31b9af4b02c9d38eb111 +Task-number: QTBUG-26978 +Reviewed-by: Ilya Kotov +Reviewed-by: Shawn Rutledge +Reviewed-by: Uli Schlachter +(cherry picked from commit e4cea305ed2ba3c9f580bf9d16c59a1048af0e8a) +--- + src/plugins/platforms/xcb/qxcbwindow.cpp | 32 ++++++++++++++++++++++++-------- + 1 file changed, 24 insertions(+), 8 deletions(-) + +diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp +index 1dc066c692d5beaf632ead78784683c928d1c1e4..d2475a8b1329dee1034f5ac5e054e5318ca2ea09 100644 +--- a/src/plugins/platforms/xcb/qxcbwindow.cpp ++++ b/src/plugins/platforms/xcb/qxcbwindow.cpp +@@ -1091,21 +1091,37 @@ QXcbWindow::NetWmStates QXcbWindow::netWmStates() + void QXcbWindow::setNetWmStates(NetWmStates states) + { + QVector atoms; +- if (states & NetWmStateAbove) ++ ++ xcb_get_property_cookie_t get_cookie = ++ xcb_get_property_unchecked(xcb_connection(), 0, m_window, atom(QXcbAtom::_NET_WM_STATE), ++ XCB_ATOM_ATOM, 0, 1024); ++ ++ xcb_get_property_reply_t *reply = ++ xcb_get_property_reply(xcb_connection(), get_cookie, NULL); ++ ++ if (reply && reply->format == 32 && reply->type == XCB_ATOM_ATOM && reply->value_len > 0) { ++ const xcb_atom_t *data = static_cast(xcb_get_property_value(reply)); ++ atoms.resize(reply->value_len); ++ memcpy((void *)&atoms.first(), (void *)data, reply->value_len * sizeof(xcb_atom_t)); ++ } ++ ++ free(reply); ++ ++ if (states & NetWmStateAbove && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_ABOVE))) + atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_ABOVE)); +- if (states & NetWmStateBelow) ++ if (states & NetWmStateBelow && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_BELOW))) + atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_BELOW)); +- if (states & NetWmStateFullScreen) ++ if (states & NetWmStateFullScreen && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_FULLSCREEN))) + atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_FULLSCREEN)); +- if (states & NetWmStateMaximizedHorz) ++ if (states & NetWmStateMaximizedHorz && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_HORZ))) + atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_HORZ)); +- if (states & NetWmStateMaximizedVert) ++ if (states & NetWmStateMaximizedVert && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_VERT))) + atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_MAXIMIZED_VERT)); +- if (states & NetWmStateModal) ++ if (states & NetWmStateModal && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_MODAL))) + atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_MODAL)); +- if (states & NetWmStateStaysOnTop) ++ if (states & NetWmStateStaysOnTop && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_STAYS_ON_TOP))) + atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_STAYS_ON_TOP)); +- if (states & NetWmStateDemandsAttention) ++ if (states & NetWmStateDemandsAttention && !atoms.contains(atom(QXcbAtom::_NET_WM_STATE_DEMANDS_ATTENTION))) + atoms.push_back(atom(QXcbAtom::_NET_WM_STATE_DEMANDS_ATTENTION)); + + if (atoms.isEmpty()) { +-- +2.6.6 + diff --git a/0013-xcb-Fix-interpretation-of-the-size-from-RRCrtcChange.patch b/0013-xcb-Fix-interpretation-of-the-size-from-RRCrtcChange.patch new file mode 100644 index 0000000..5c85d00 --- /dev/null +++ b/0013-xcb-Fix-interpretation-of-the-size-from-RRCrtcChange.patch @@ -0,0 +1,43 @@ +From a148affea7763395ce503f695ddb6c7b4c1e4b08 Mon Sep 17 00:00:00 2001 +From: Alexander Volkov +Date: Fri, 8 Apr 2016 18:50:15 +0300 +Subject: [PATCH 13/16] xcb: Fix interpretation of the size from + RRCrtcChangeNotify +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The size in RRCrtcChangeNotify is a size of the mode and it is +not rotated. At the same time when we call RRGetCrtcInfo, it +returns a rotated size, which is then passed to +QXcbScreen::updateGeometry(const QRect &geom, uint8_t rotation). + +So to pass the expected size to QXcbScreen::updateGeometry() +after receiving RRCrtcChangeNotify, we should rotate the size +according the screen rotation. + +Change-Id: If5b5b52403b077d3cd64b9a05d938bb9ac00b1e0 +Reviewed-by: Daniel Vrátil +Reviewed-by: Laszlo Agocs +(cherry picked from commit d8667fde189fa08002295fc66414d67e73b3c67b) +--- + src/plugins/platforms/xcb/qxcbconnection.cpp | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp +index aeb730670d62b3ce2239fba48b58ccb4752e912d..9f170b095926501b91a20f401284c6c6149a07ab 100644 +--- a/src/plugins/platforms/xcb/qxcbconnection.cpp ++++ b/src/plugins/platforms/xcb/qxcbconnection.cpp +@@ -209,6 +209,9 @@ void QXcbConnection::updateScreens(const xcb_randr_notify_event_t *event) + // CRTC with node mode could mean that output has been disabled, and we'll + // get RRNotifyOutputChange notification for that. + if (screen && crtc.mode) { ++ if (crtc.rotation == XCB_RANDR_ROTATION_ROTATE_90 || ++ crtc.rotation == XCB_RANDR_ROTATION_ROTATE_270) ++ std::swap(crtc.width, crtc.height); + screen->updateGeometry(QRect(crtc.x, crtc.y, crtc.width, crtc.height), crtc.rotation); + if (screen->mode() != crtc.mode) + screen->updateRefreshRate(crtc.mode); +-- +2.6.6 + diff --git a/0014-xcb-Properly-process-enter-leave-events.patch b/0014-xcb-Properly-process-enter-leave-events.patch new file mode 100644 index 0000000..351eff4 --- /dev/null +++ b/0014-xcb-Properly-process-enter-leave-events.patch @@ -0,0 +1,206 @@ +From 123a082fd423422412d554a3b5973bcfc78c62a8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= +Date: Thu, 14 Apr 2016 17:00:23 +0200 +Subject: [PATCH 14/16] xcb: Properly process enter/leave events + +Ignore enter/leave events when there is a window under mouse button. +Unset window under mouse button if other window is grabbed. +Smarter ignoring (un)grab ancestor enter/leave event. +Ignore ungrab inferior leave event. + +Amends: b9f76db30d261421e4da58f29053181af04ceb4d + +Task-number: QTBUG-46576 +Task-number: QTBUG-51573 +Task-number: QTBUG-52332 +Task-number: QTBUG-52488 +Change-Id: I8d926309aa60bb8929728691c31ecf93d1e299ad +Reviewed-by: Dmitry Shachnev +Reviewed-by: Laszlo Agocs +Reviewed-by: Shawn Rutledge +(cherry picked from commit c511466d747d99ee76465cfe90ce594fa1f27469) +--- + src/plugins/platforms/xcb/qxcbconnection.cpp | 6 +++ + src/plugins/platforms/xcb/qxcbconnection.h | 3 ++ + src/plugins/platforms/xcb/qxcbwindow.cpp | 70 ++++++++++++++++++++++------ + 3 files changed, 64 insertions(+), 15 deletions(-) + +diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp +index 9f170b095926501b91a20f401284c6c6149a07ab..333a9606f50e9c27bdb7d24c836a3029a635b881 100644 +--- a/src/plugins/platforms/xcb/qxcbconnection.cpp ++++ b/src/plugins/platforms/xcb/qxcbconnection.cpp +@@ -560,6 +560,7 @@ QXcbConnection::QXcbConnection(QXcbNativeInterface *nativeInterface, bool canGra + , m_buttons(0) + , m_focusWindow(0) + , m_mouseGrabber(0) ++ , m_mousePressWindow(0) + , m_clientLeader(0) + , m_systemTrayTracker(0) + , m_glIntegration(Q_NULLPTR) +@@ -1367,6 +1368,11 @@ void QXcbConnection::setFocusWindow(QXcbWindow *w) + void QXcbConnection::setMouseGrabber(QXcbWindow *w) + { + m_mouseGrabber = w; ++ m_mousePressWindow = Q_NULLPTR; ++} ++void QXcbConnection::setMousePressWindow(QXcbWindow *w) ++{ ++ m_mousePressWindow = w; + } + + void QXcbConnection::grabServer() +diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h +index 4d318457e3b05de8c343580aad217cc1bad9072c..0c004a86dd286a2c4aaf77d249eef14a2af8ff03 100644 +--- a/src/plugins/platforms/xcb/qxcbconnection.h ++++ b/src/plugins/platforms/xcb/qxcbconnection.h +@@ -473,6 +473,8 @@ public: + void setFocusWindow(QXcbWindow *); + QXcbWindow *mouseGrabber() const { return m_mouseGrabber; } + void setMouseGrabber(QXcbWindow *); ++ QXcbWindow *mousePressWindow() const { return m_mousePressWindow; } ++ void setMousePressWindow(QXcbWindow *); + + QByteArray startupId() const { return m_startupId; } + void setStartupId(const QByteArray &nextId) { m_startupId = nextId; } +@@ -656,6 +658,7 @@ private: + + QXcbWindow *m_focusWindow; + QXcbWindow *m_mouseGrabber; ++ QXcbWindow *m_mousePressWindow; + + xcb_window_t m_clientLeader; + QByteArray m_startupId; +diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp +index d2475a8b1329dee1034f5ac5e054e5318ca2ea09..e8ad6be82bba983127ecf0fe2c7f0a951d9b5fb3 100644 +--- a/src/plugins/platforms/xcb/qxcbwindow.cpp ++++ b/src/plugins/platforms/xcb/qxcbwindow.cpp +@@ -616,8 +616,12 @@ QXcbWindow::~QXcbWindow() + { + if (window()->type() != Qt::ForeignWindow) + destroy(); +- else if (connection()->mouseGrabber() == this) +- connection()->setMouseGrabber(Q_NULLPTR); ++ else { ++ if (connection()->mouseGrabber() == this) ++ connection()->setMouseGrabber(Q_NULLPTR); ++ if (connection()->mousePressWindow() == this) ++ connection()->setMousePressWindow(Q_NULLPTR); ++ } + } + + void QXcbWindow::destroy() +@@ -875,6 +879,16 @@ void QXcbWindow::hide() + + if (connection()->mouseGrabber() == this) + connection()->setMouseGrabber(Q_NULLPTR); ++ if (QPlatformWindow *w = connection()->mousePressWindow()) { ++ // Unset mousePressWindow when it (or one of its parents) is unmapped ++ while (w) { ++ if (w == this) { ++ connection()->setMousePressWindow(Q_NULLPTR); ++ break; ++ } ++ w = w->parent(); ++ } ++ } + + m_mapped = false; + +@@ -2213,6 +2227,8 @@ void QXcbWindow::handleButtonPressEvent(int event_x, int event_y, int root_x, in + return; + } + ++ connection()->setMousePressWindow(this); ++ + handleMouseEvent(timestamp, local, global, modifiers, source); + } + +@@ -2227,19 +2243,44 @@ void QXcbWindow::handleButtonReleaseEvent(int event_x, int event_y, int root_x, + return; + } + ++ if (connection()->buttons() == Qt::NoButton) ++ connection()->setMousePressWindow(Q_NULLPTR); ++ + handleMouseEvent(timestamp, local, global, modifiers, source); + } + +-static bool ignoreLeaveEvent(quint8 mode, quint8 detail) ++static inline bool doCheckUnGrabAncestor(QXcbConnection *conn) ++{ ++ /* Checking for XCB_NOTIFY_MODE_GRAB and XCB_NOTIFY_DETAIL_ANCESTOR prevents unwanted ++ * enter/leave events on AwesomeWM on mouse button press. It also ignores duplicated ++ * enter/leave events on Alt+Tab switching on some WMs with XInput2 events. ++ * Without XInput2 events the (Un)grabAncestor cannot be checked when mouse button is ++ * not pressed, otherwise (e.g. on Alt+Tab) it can igonre important enter/leave events. ++ */ ++ if (conn) { ++ const bool mouseButtonsPressed = (conn->buttons() != Qt::NoButton); ++#ifdef XCB_USE_XINPUT22 ++ return mouseButtonsPressed || (conn->isAtLeastXI22() && conn->xi2MouseEvents()); ++#else ++ return mouseButtonsPressed; ++#endif ++ } ++ return true; ++} ++ ++static bool ignoreLeaveEvent(quint8 mode, quint8 detail, QXcbConnection *conn = Q_NULLPTR) + { +- return (mode == XCB_NOTIFY_MODE_GRAB && detail == XCB_NOTIFY_DETAIL_ANCESTOR) // Check for AwesomeWM ++ return ((doCheckUnGrabAncestor(conn) ++ && mode == XCB_NOTIFY_MODE_GRAB && detail == XCB_NOTIFY_DETAIL_ANCESTOR) ++ || (mode == XCB_NOTIFY_MODE_UNGRAB && detail == XCB_NOTIFY_DETAIL_INFERIOR) + || detail == XCB_NOTIFY_DETAIL_VIRTUAL +- || detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL; ++ || detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL); + } + +-static bool ignoreEnterEvent(quint8 mode, quint8 detail) ++static bool ignoreEnterEvent(quint8 mode, quint8 detail, QXcbConnection *conn = Q_NULLPTR) + { +- return ((mode == XCB_NOTIFY_MODE_UNGRAB && detail == XCB_NOTIFY_DETAIL_ANCESTOR) // Check for AwesomeWM ++ return ((doCheckUnGrabAncestor(conn) ++ && mode == XCB_NOTIFY_MODE_UNGRAB && detail == XCB_NOTIFY_DETAIL_ANCESTOR) + || (mode != XCB_NOTIFY_MODE_NORMAL && mode != XCB_NOTIFY_MODE_UNGRAB) + || detail == XCB_NOTIFY_DETAIL_VIRTUAL + || detail == XCB_NOTIFY_DETAIL_NONLINEAR_VIRTUAL); +@@ -2273,9 +2314,7 @@ void QXcbWindow::handleEnterNotifyEvent(int event_x, int event_y, int root_x, in + + const QPoint global = QPoint(root_x, root_y); + +- if (ignoreEnterEvent(mode, detail) +- || (connection()->buttons() != Qt::NoButton +- && QGuiApplicationPrivate::lastCursorPosition != global)) ++ if (ignoreEnterEvent(mode, detail, connection()) || connection()->mousePressWindow()) + return; + + const QPoint local(event_x, event_y); +@@ -2287,11 +2326,7 @@ void QXcbWindow::handleLeaveNotifyEvent(int root_x, int root_y, + { + connection()->setTime(timestamp); + +- const QPoint global(root_x, root_y); +- +- if (ignoreLeaveEvent(mode, detail) +- || (connection()->buttons() != Qt::NoButton +- && QGuiApplicationPrivate::lastCursorPosition != global)) ++ if (ignoreLeaveEvent(mode, detail, connection()) || connection()->mousePressWindow()) + return; + + EnterEventChecker checker; +@@ -2314,6 +2349,11 @@ void QXcbWindow::handleMotionNotifyEvent(int event_x, int event_y, int root_x, i + { + QPoint local(event_x, event_y); + QPoint global(root_x, root_y); ++ ++ // "mousePressWindow" can be NULL i.e. if a window will be grabbed or umnapped, so set it again here ++ if (connection()->buttons() != Qt::NoButton && connection()->mousePressWindow() == Q_NULLPTR) ++ connection()->setMousePressWindow(this); ++ + handleMouseEvent(timestamp, local, global, modifiers, source); + } + +-- +2.6.6 + diff --git a/0015-Use-the-state-of-the-key-event-to-process-it.patch b/0015-Use-the-state-of-the-key-event-to-process-it.patch new file mode 100644 index 0000000..2b3ebba --- /dev/null +++ b/0015-Use-the-state-of-the-key-event-to-process-it.patch @@ -0,0 +1,149 @@ +From d7be69c973623e76deff3fa00354927946b21c66 Mon Sep 17 00:00:00 2001 +From: Albert Astals Cid +Date: Thu, 21 Apr 2016 01:39:27 +0200 +Subject: [PATCH 15/16] Use the state of the key event to process it + +Use the state of the key event instead of the global state. +UpdateXKBStateFromState uses xkbModMask, which needs updateXKBMods +to be called beforehand. + +Task-number: QTBUG-48795 +Change-Id: Ic2c545718adb68df41730e5a3bf25adb374ffce3 +--- + src/plugins/platforms/xcb/qxcbkeyboard.cpp | 72 ++++++++++++++++++------------ + src/plugins/platforms/xcb/qxcbkeyboard.h | 2 + + 2 files changed, 46 insertions(+), 28 deletions(-) + +diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp +index 631dd17908f458533f413409773b6c078b743d98..baba7ec812c16025893bf5267fba545e8b4378bf 100644 +--- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp ++++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp +@@ -742,8 +742,7 @@ void QXcbKeyboard::updateKeymap() + // update xkb state object + xkb_state_unref(xkb_state); + xkb_state = new_state; +- if (!connection()->hasXKB()) +- updateXKBMods(); ++ updateXKBMods(); + + checkForLatinLayout(); + } +@@ -768,32 +767,37 @@ void QXcbKeyboard::updateXKBState(xcb_xkb_state_notify_event_t *state) + } + #endif + ++void QXcbKeyboard::updateXKBStateFromState(struct xkb_state *kb_state, quint16 state) ++{ ++ const quint32 modsDepressed = xkb_state_serialize_mods(kb_state, XKB_STATE_MODS_DEPRESSED); ++ const quint32 modsLatched = xkb_state_serialize_mods(kb_state, XKB_STATE_MODS_LATCHED); ++ const quint32 modsLocked = xkb_state_serialize_mods(kb_state, XKB_STATE_MODS_LOCKED); ++ const quint32 xkbMask = xkbModMask(state); ++ ++ const quint32 latched = modsLatched & xkbMask; ++ const quint32 locked = modsLocked & xkbMask; ++ quint32 depressed = modsDepressed & xkbMask; ++ // set modifiers in depressed if they don't appear in any of the final masks ++ depressed |= ~(depressed | latched | locked) & xkbMask; ++ ++ const xkb_state_component newState ++ = xkb_state_update_mask(kb_state, ++ depressed, ++ latched, ++ locked, ++ 0, ++ 0, ++ (state >> 13) & 3); // bits 13 and 14 report the state keyboard group ++ ++ if ((newState & XKB_STATE_LAYOUT_EFFECTIVE) == XKB_STATE_LAYOUT_EFFECTIVE) { ++ //qWarning("TODO: Support KeyboardLayoutChange on QPA (QTBUG-27681)"); ++ } ++} ++ + void QXcbKeyboard::updateXKBStateFromCore(quint16 state) + { + if (m_config && !connection()->hasXKB()) { +- const quint32 modsDepressed = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_DEPRESSED); +- const quint32 modsLatched = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LATCHED); +- const quint32 modsLocked = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LOCKED); +- const quint32 xkbMask = xkbModMask(state); +- +- const quint32 latched = modsLatched & xkbMask; +- const quint32 locked = modsLocked & xkbMask; +- quint32 depressed = modsDepressed & xkbMask; +- // set modifiers in depressed if they don't appear in any of the final masks +- depressed |= ~(depressed | latched | locked) & xkbMask; +- +- const xkb_state_component newState +- = xkb_state_update_mask(xkb_state, +- depressed, +- latched, +- locked, +- 0, +- 0, +- (state >> 13) & 3); // bits 13 and 14 report the state keyboard group +- +- if ((newState & XKB_STATE_LAYOUT_EFFECTIVE) == XKB_STATE_LAYOUT_EFFECTIVE) { +- //qWarning("TODO: Support KeyboardLayoutChange on QPA (QTBUG-27681)"); +- } ++ updateXKBStateFromState(xkb_state, state); + } + } + +@@ -1445,7 +1449,16 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type, + if (type == QEvent::KeyPress) + targetWindow->updateNetWmUserTime(time); + +- xcb_keysym_t sym = xkb_state_key_get_one_sym(xkb_state, code); ++ // Have a temporary keyboard state filled in from state ++ // this way we allow for synthetic events to have different state ++ // from the current state i.e. you can have Alt+Ctrl pressed ++ // and receive a synthetic key event that has neither Alt nor Ctrl pressed ++ struct xkb_state *kb_state = xkb_state_new(xkb_keymap); ++ if (!kb_state) ++ return; ++ updateXKBStateFromState(kb_state, state); ++ ++ xcb_keysym_t sym = xkb_state_key_get_one_sym(kb_state, code); + + QPlatformInputContext *inputContext = QGuiApplicationPrivate::platformIntegration()->inputContext(); + QMetaMethod method; +@@ -1464,11 +1477,13 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type, + Q_ARG(uint, code), + Q_ARG(uint, state), + Q_ARG(bool, type == QEvent::KeyPress)); +- if (retval) ++ if (retval) { ++ xkb_state_unref(kb_state); + return; ++ } + } + +- QString string = lookupString(xkb_state, code); ++ QString string = lookupString(kb_state, code); + + // Ιf control modifier is set we should prefer latin character, this is + // used for standard shortcuts in checks like "key == QKeySequence::Copy", +@@ -1537,6 +1552,7 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type, + QWindowSystemInterface::handleExtendedKeyEvent(window, time, QEvent::KeyPress, qtcode, modifiers, + code, sym, state, string, isAutoRepeat); + } ++ xkb_state_unref(kb_state); + } + + QString QXcbKeyboard::lookupString(struct xkb_state *state, xcb_keycode_t code) const +diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.h b/src/plugins/platforms/xcb/qxcbkeyboard.h +index 457a27affb166e2a3e54c78761361ff3713a4d18..dc27511b56e98bfc0f642e03c0b3aa8b2f4778e9 100644 +--- a/src/plugins/platforms/xcb/qxcbkeyboard.h ++++ b/src/plugins/platforms/xcb/qxcbkeyboard.h +@@ -98,6 +98,8 @@ protected: + void checkForLatinLayout(); + + private: ++ void updateXKBStateFromState(struct xkb_state *kb_state, quint16 state); ++ + bool m_config; + xcb_keycode_t m_autorepeat_code; + +-- +2.6.6 + diff --git a/0016-xcb-Fix-drag-and-drop-to-applications-like-Emacs-and.patch b/0016-xcb-Fix-drag-and-drop-to-applications-like-Emacs-and.patch new file mode 100644 index 0000000..9170271 --- /dev/null +++ b/0016-xcb-Fix-drag-and-drop-to-applications-like-Emacs-and.patch @@ -0,0 +1,92 @@ +From 7c3b3375b2d54ef1965c32131123a9becfa27f98 Mon Sep 17 00:00:00 2001 +From: Urs Fleisch +Date: Fri, 26 Feb 2016 17:46:09 +0100 +Subject: [PATCH 16/16] xcb: Fix drag and drop to applications like Emacs and + Chromium. + +Drops without matching time stamp do not work. I have fixed the issue by +reanimating the findXdndAwareParent() function (adapted to XCB) and +using it to find a matching transaction if all else fails. + +Task-number: QTBUG-45812 +Change-Id: Ibca15bbab02ccf2f25280418e9edf36972ebf9a0 +--- + src/plugins/platforms/xcb/qxcbdrag.cpp | 55 +++++++++++++++++++++++++++------- + 1 file changed, 44 insertions(+), 11 deletions(-) + +diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp +index f5cc87394b941014a1f45e0064d341dc8ad093d0..f1428d0a9632bd692ceaa130be58992f282d3081 100644 +--- a/src/plugins/platforms/xcb/qxcbdrag.cpp ++++ b/src/plugins/platforms/xcb/qxcbdrag.cpp +@@ -1072,6 +1072,40 @@ void QXcbDrag::cancel() + send_leave(); + } + ++// find an ancestor with XdndAware on it ++static xcb_window_t findXdndAwareParent(QXcbConnection *c, xcb_window_t window) ++{ ++ xcb_window_t target = 0; ++ forever { ++ // check if window has XdndAware ++ xcb_get_property_cookie_t gpCookie = Q_XCB_CALL( ++ xcb_get_property(c->xcb_connection(), false, window, ++ c->atom(QXcbAtom::XdndAware), XCB_GET_PROPERTY_TYPE_ANY, 0, 0)); ++ xcb_get_property_reply_t *gpReply = xcb_get_property_reply( ++ c->xcb_connection(), gpCookie, 0); ++ bool aware = gpReply && gpReply->type != XCB_NONE; ++ free(gpReply); ++ if (aware) { ++ target = window; ++ break; ++ } ++ ++ // try window's parent ++ xcb_query_tree_cookie_t qtCookie = Q_XCB_CALL( ++ xcb_query_tree_unchecked(c->xcb_connection(), window)); ++ xcb_query_tree_reply_t *qtReply = xcb_query_tree_reply( ++ c->xcb_connection(), qtCookie, NULL); ++ if (!qtReply) ++ break; ++ xcb_window_t root = qtReply->root; ++ xcb_window_t parent = qtReply->parent; ++ free(qtReply); ++ if (window == root) ++ break; ++ window = parent; ++ } ++ return target; ++} + + void QXcbDrag::handleSelectionRequest(const xcb_selection_request_event_t *event) + { +@@ -1099,17 +1133,16 @@ void QXcbDrag::handleSelectionRequest(const xcb_selection_request_event_t *event + // xcb_convert_selection() that we sent the XdndDrop event to. + at = findTransactionByWindow(event->requestor); + } +-// if (at == -1 && event->time == XCB_CURRENT_TIME) { +-// // previous Qt versions always requested the data on a child of the target window +-// // using CurrentTime... but it could be asking for either drop data or the current drag's data +-// Window target = findXdndAwareParent(event->requestor); +-// if (target) { +-// if (current_target && current_target == target) +-// at = -2; +-// else +-// at = findXdndDropTransactionByWindow(target); +-// } +-// } ++ ++ if (at == -1 && event->time == XCB_CURRENT_TIME) { ++ xcb_window_t target = findXdndAwareParent(connection(), event->requestor); ++ if (target) { ++ if (current_target == target) ++ at = -2; ++ else ++ at = findTransactionByWindow(target); ++ } ++ } + } + + QDrag *transactionDrag = 0; +-- +2.6.6 + diff --git a/Add-a-linker-version-script-to-Qt-libraries.patch b/Add-a-linker-version-script-to-Qt-libraries.patch deleted file mode 100644 index f891da9..0000000 --- a/Add-a-linker-version-script-to-Qt-libraries.patch +++ /dev/null @@ -1,110 +0,0 @@ -From 38c28ad2420542d795a27c5359226260c886b112 Mon Sep 17 00:00:00 2001 -From: Thiago Macieira -Date: Tue, 2 Jun 2015 11:10:22 -0700 -Subject: [PATCH] Add a linker version script to Qt libraries - -This linker script is only enabled for systems with GCC or GCC-like -compilers, though technically it should work on the BSDs too (will -enable after testing). For regular modules, this declares one ELF -version "Qt_5" and places all QtCore symbols inside, then it declares -unused ELF versions "Qt_5.x" for each older minor release. For modules -declared "internal_module", all symbols are placed in version -Qt_5_PRIVATE_API. - -The big advantage of an ELF version is that, when we do Qt 6, both -versions of QtCore could be loaded in memory without conflicts and all -symbols would be resolved to the correct library. No module can talk to -both at the same time, but this avoids mistakes of loading them -indirectly by plugins. - -The extra Qt_5.x versions will be used in the next commit. - -Change-Id: I049a653beeb5454c9539ffff13e3fe6f050fdf31 ---- - mkspecs/common/gcc-base-unix.conf | 1 + - mkspecs/common/qcc-base-qnx.conf | 1 + - mkspecs/features/qt_module.prf | 22 ++++++++++++++++++++++ - mkspecs/linux-icc/qmake.conf | 1 + - mkspecs/unsupported/linux-host-g++/qmake.conf | 1 + - 5 files changed, 26 insertions(+) - -diff --git a/mkspecs/common/gcc-base-unix.conf b/mkspecs/common/gcc-base-unix.conf -index f82c8a843062d6591713160d865b51264cc9cb5b..0178bda75a97398d6ca78b2bb8f04ca3fe8b9455 100644 ---- a/mkspecs/common/gcc-base-unix.conf -+++ b/mkspecs/common/gcc-base-unix.conf -@@ -22,3 +22,4 @@ QMAKE_LFLAGS_USE_GOLD = -fuse-ld=gold - # -Bsymbolic-functions (ld) support - QMAKE_LFLAGS_BSYMBOLIC_FUNC = -Wl,-Bsymbolic-functions - QMAKE_LFLAGS_DYNAMIC_LIST = -Wl,--dynamic-list, -+QMAKE_LFLAGS_VERSION_SCRIPT = -Wl,--version-script, -diff --git a/mkspecs/common/qcc-base-qnx.conf b/mkspecs/common/qcc-base-qnx.conf -index a0a88b9605412e9c316a2ab831f71740245fbf20..cebbe06661196834701938cff84127667f9ddb35 100644 ---- a/mkspecs/common/qcc-base-qnx.conf -+++ b/mkspecs/common/qcc-base-qnx.conf -@@ -19,6 +19,7 @@ QMAKE_LFLAGS_RPATHLINK = -Wl,-rpath-link, - # -Bsymbolic-functions (ld) support - QMAKE_LFLAGS_BSYMBOLIC_FUNC = -Wl,-Bsymbolic-functions - QMAKE_LFLAGS_DYNAMIC_LIST = -Wl,--dynamic-list, -+QMAKE_LFLAGS_VERSION_SCRIPT = -Wl,--version-script, - - # Generic options for all BlackBerry/QNX qcc mkspecs - QMAKE_CFLAGS_THREAD = -D_REENTRANT -diff --git a/mkspecs/features/qt_module.prf b/mkspecs/features/qt_module.prf -index c89b6d2793bcaef69102c51c4433b304bf6fb769..5206691a17949eab630632f05d0f91d0e56d27b6 100644 ---- a/mkspecs/features/qt_module.prf -+++ b/mkspecs/features/qt_module.prf -@@ -185,6 +185,28 @@ equals(QT_ARCH, i386):contains(QT_CPU_FEATURES.$$QT_ARCH, sse2):compiler_support - QMAKE_CXXFLAGS += -mfpmath=sse - } - -+unix:!isEmpty(QMAKE_LFLAGS_VERSION_SCRIPT):!no_linker_version_script:!static { -+ verscript = $$OUT_PWD/$${TARGET}.version -+ QMAKE_LFLAGS += $${QMAKE_LFLAGS_VERSION_SCRIPT}$$verscript -+ -+ internal_module { -+ verscript_content = "Qt_$${QT_MAJOR_VERSION}_PRIVATE_API { *; };" -+ } else { -+ current = Qt_$$QT_MAJOR_VERSION -+ verscript_content = "$$current { *; };" -+ for(i, 0..$$section(VERSION, ., 1, 1)) { -+ previous = $$current -+ current = Qt_$${QT_MAJOR_VERSION}.$$i -+ verscript_content += "$$current {} $$previous;" -+ } -+ } -+ write_file($$verscript, verscript_content)|error("Aborting.") -+ unset(current) -+ unset(previous) -+ unset(verscript) -+ unset(verscript_content) -+} -+ - android: CONFIG += qt_android_deps - - #install directives -diff --git a/mkspecs/linux-icc/qmake.conf b/mkspecs/linux-icc/qmake.conf -index 9190aa9f28cf6b38455a718afd6851d341ca57b5..4b10d42d44dd0cb8d788c6247099b42ba25c33a6 100644 ---- a/mkspecs/linux-icc/qmake.conf -+++ b/mkspecs/linux-icc/qmake.conf -@@ -97,6 +97,7 @@ QMAKE_CXXFLAGS_PRECOMPILE = -c -pch-create ${QMAKE_PCH_OUTPUT} -include ${QMAKE_ - # -Bsymbolic-functions (ld) support - QMAKE_LFLAGS_BSYMBOLIC_FUNC = -Wl,-Bsymbolic-functions - QMAKE_LFLAGS_DYNAMIC_LIST = -Wl,--dynamic-list, -+QMAKE_LFLAGS_VERSION_SCRIPT = -Wl,--version-script, - - # Symbol visibility control - QMAKE_CFLAGS_HIDESYMS += -fvisibility=hidden -diff --git a/mkspecs/unsupported/linux-host-g++/qmake.conf b/mkspecs/unsupported/linux-host-g++/qmake.conf -index 1523126eaaa4761708fe58e449f8b43f6c3b8c14..546ff213498c80649d5a40810f068aca1c598494 100644 ---- a/mkspecs/unsupported/linux-host-g++/qmake.conf -+++ b/mkspecs/unsupported/linux-host-g++/qmake.conf -@@ -71,6 +71,7 @@ QMAKE_PCH_OUTPUT_EXT = .gch - # -Bsymbolic-functions (ld) support - QMAKE_LFLAGS_BSYMBOLIC_FUNC = -Wl,-Bsymbolic-functions - QMAKE_LFLAGS_DYNAMIC_LIST = -Wl,--dynamic-list, -+QMAKE_LFLAGS_VERSION_SCRIPT = -Wl,--version-script, - - # - # qmake configuration for common linux --- -2.6.0 diff --git a/Add-a-qt_version_tag-symbol-to-QtCore-that-uses-ELF-versions.patch b/Add-a-qt_version_tag-symbol-to-QtCore-that-uses-ELF-versions.patch deleted file mode 100644 index 714d9c3..0000000 --- a/Add-a-qt_version_tag-symbol-to-QtCore-that-uses-ELF-versions.patch +++ /dev/null @@ -1,125 +0,0 @@ -From c665b0ce8c663030b856073262bd2ce30347bd7b Mon Sep 17 00:00:00 2001 -From: Thiago Macieira -Date: Tue, 2 Jun 2015 11:15:05 -0700 -Subject: [PATCH] Add a qt_version_tag symbol to QtCore that uses ELF versions - -This symbol will exist with different ELF versions, allowing us to know -which version of Qt a given library or application was linked -against. When this symbol gets used, automatic packaging tools will -extract the dependency. The trick here is that the application uses -qt_version_tag without knowing which version is current, but the linker -resolves it to the current version and records that. - -For example, if this were used with Qt 5.5, RPM's find-requires on an -application using QtCore would print: - - libQt5Core.so.5()(64bit) - libQt5Core.so.5(Qt_5.5)(64bit) - libQt5Core.so.5(Qt_5)(64bit) - -Whereas find-provides on QtCore would print: - - libQt5Core.so.5()(64bit) - libQt5Core.so.5(libQt5Core.so.5)(64bit) - libQt5Core.so.5(Qt_5.0)(64bit) - libQt5Core.so.5(Qt_5.1)(64bit) - libQt5Core.so.5(Qt_5.2)(64bit) - libQt5Core.so.5(Qt_5.3)(64bit) - libQt5Core.so.5(Qt_5.4)(64bit) - libQt5Core.so.5(Qt_5.5)(64bit) - libQt5Core.so.5(Qt_5)(64bit) - -Therefore, automatic dependency resolution would have the information it -needs to conclude that the application requires Qt >= 5.5. - -Change-Id: I049a653beeb5454c9539ffff13e3fec9aeb50197 ---- - src/corelib/global/global.pri | 3 +- - src/corelib/global/qversiontagging.cpp | 62 ++++++++++++++++++++++++++++++++++ - 2 files changed, 64 insertions(+), 1 deletion(-) - create mode 100644 src/corelib/global/qversiontagging.cpp - -diff --git a/src/corelib/global/global.pri b/src/corelib/global/global.pri -index 6a8104bee2c129778efb86368a71392132dd2e22..7ca0734f1face0d4517fdb1257dbb9812f04d0d2 100644 ---- a/src/corelib/global/global.pri -+++ b/src/corelib/global/global.pri -@@ -27,7 +27,8 @@ SOURCES += \ - global/qmalloc.cpp \ - global/qnumeric.cpp \ - global/qlogging.cpp \ -- global/qhooks.cpp -+ global/qhooks.cpp \ -+ global/qversiontagging.cpp - - # qlibraryinfo.cpp includes qconfig.cpp - INCLUDEPATH += $$QT_BUILD_TREE/src/corelib/global -diff --git a/src/corelib/global/qversiontagging.cpp b/src/corelib/global/qversiontagging.cpp -new file mode 100644 -index 0000000000000000000000000000000000000000..e3d9efa16b7677a29963020660bc9c4b4a143356 ---- /dev/null -+++ b/src/corelib/global/qversiontagging.cpp -@@ -0,0 +1,62 @@ -+/**************************************************************************** -+** -+** Copyright (C) 2015 Intel Corporation. -+** Contact: http://www.qt.io/licensing/ -+** -+** This file is part of the QtCore module of the Qt Toolkit. -+** -+** $QT_BEGIN_LICENSE:LGPL21$ -+** 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 http://www.qt.io/terms-conditions. For further -+** information use the contact form at http://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 2.1 or version 3 as published by the Free -+** Software Foundation and appearing in the file LICENSE.LGPLv21 and -+** LICENSE.LGPLv3 included in the packaging of this file. Please review the -+** following information to ensure the GNU Lesser General Public License -+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -+** -+** As a special exception, The Qt Company gives you certain additional -+** rights. These rights are described in The Qt Company LGPL Exception -+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -+** -+** $QT_END_LICENSE$ -+** -+****************************************************************************/ -+ -+#include "qglobal.h" -+ -+#if defined(Q_CC_GNU) && defined(Q_OS_LINUX) && defined(Q_PROCESSOR_X86) && !defined(QT_STATIC) -+# define SYM QT_MANGLE_NAMESPACE(qt_version_tag) -+# define SSYM QT_STRINGIFY(SYM) -+ -+asm( -+// ASM macro that makes one ELF versioned symbol qt_version_tag{sep}Qt_{major}.{minor} -+// that is an alias to qt_version_tag_{major}_{minor}. -+// The {sep} parameter must be @ for all old versions and @@ for the current version. -+".macro make_one_tag major minor sep\n" -+".globl " SSYM "_\\major\\()_\\minor\n" // make the symbol global -+SSYM "_\\major\\()_\\minor:\n" // declare it -+" .symver " SSYM "_\\major\\()_\\minor, " SSYM "\\sep\\()Qt_\\major\\().\\minor\n" -+".endm\n" -+ -+".altmacro\n" -+".bss\n" -+".set qt_version_major, " QT_STRINGIFY(QT_VERSION) " >> 16\n" // set qt_version_major -+".set qt_version_minor, 0\n" // set qt_version_minor to 0 (it will grow to the current) -+".rept (" QT_STRINGIFY(QT_VERSION) " >> 8) & 0xff\n" // repeat minor version times (0 to N-1) -+" make_one_tag %qt_version_major, %qt_version_minor, @\n" -+" .set qt_version_minor, (qt_version_minor + 1)\n" -+".endr\n" -+" make_one_tag %qt_version_major, %qt_version_minor, @@\n" // call the macro for the current version -+" .space 1\n" // variable is 1 byte, value 0 -+); -+ -+#endif --- -2.6.0 diff --git a/Add-an-automatic-use-of-the-ELF-versioned-QtCore-symbol.patch b/Add-an-automatic-use-of-the-ELF-versioned-QtCore-symbol.patch deleted file mode 100644 index 33b73f2..0000000 --- a/Add-an-automatic-use-of-the-ELF-versioned-QtCore-symbol.patch +++ /dev/null @@ -1,142 +0,0 @@ -From bdb8ab0690eb927575de6f3e34d2b49a148e046f Mon Sep 17 00:00:00 2001 -From: Thiago Macieira -Date: Tue, 2 Jun 2015 11:30:57 -0700 -Subject: [PATCH] Add an automatic use of the ELF-versioned QtCore symbol - -See the comment in the header for an explanation of what it does. - -This trick is enabled for every single .o that is compiled, unless -QT_NO_VERSION_TAGGING is defined. The assembly expands to a COMDAT -section, which is mergeable by the linker, so only one copy of the -output is present in the ELF module. - -This is enabled only for Linux and x86 / x86-64 / x32 due to the -requirement of writing assembly and relocations, so it needs to be -tested on each platform, which I have not done. It might work on -Solaris/x86, but again it requires testing. Support for other -architectures requires different assembly output and relocations and can -be added as needed, but they are not as important since this trick is -has most value on desktop systems. - -Change-Id: I049a653beeb5454c9539ffff13e3ff5782a8cb86 ---- - src/corelib/global/global.pri | 3 +- - src/corelib/global/qglobal.h | 1 + - src/corelib/global/qversiontagging.h | 86 ++++++++++++++++++++++++++++++++++++ - 3 files changed, 89 insertions(+), 1 deletion(-) - create mode 100644 src/corelib/global/qversiontagging.h - -diff --git a/src/corelib/global/global.pri b/src/corelib/global/global.pri -index 2165a6c22e86948655c0074d50f8669c8a192d40..e231a8f1fddf8fd705f665089c235bd11a55f0b4 100644 ---- a/src/corelib/global/global.pri -+++ b/src/corelib/global/global.pri -@@ -17,7 +17,8 @@ HEADERS += \ - global/qisenum.h \ - global/qtypetraits.h \ - global/qflags.h \ -- global/qhooks_p.h -+ global/qhooks_p.h \ -+ global/qversiontagging.h - - SOURCES += \ - global/archdetect.cpp \ -diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h -index 15d9b6536a9f1ee85371fea6dc9115438eec32d1..1a5afbe753ad08d088c9174c58fcce54ce327e0e 100644 ---- a/src/corelib/global/qglobal.h -+++ b/src/corelib/global/qglobal.h -@@ -1104,6 +1104,7 @@ QT_END_NAMESPACE - #include - #include - #include -+#include - - #endif /* __cplusplus */ - -diff --git a/src/corelib/global/qversiontagging.h b/src/corelib/global/qversiontagging.h -new file mode 100644 -index 0000000000000000000000000000000000000000..94246dd08b139fe3b9040a95824dcb3116a5b790 ---- /dev/null -+++ b/src/corelib/global/qversiontagging.h -@@ -0,0 +1,80 @@ -+/**************************************************************************** -+** -+** Copyright (C) 2015 Intel Corporation. -+** Contact: http://www.qt.io/licensing/ -+** -+** This file is part of the QtCore module of the Qt Toolkit. -+** -+** $QT_BEGIN_LICENSE:LGPL21$ -+** 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 http://www.qt.io/terms-conditions. For further -+** information use the contact form at http://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 2.1 or version 3 as published by the Free -+** Software Foundation and appearing in the file LICENSE.LGPLv21 and -+** LICENSE.LGPLv3 included in the packaging of this file. Please review the -+** following information to ensure the GNU Lesser General Public License -+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -+** -+** As a special exception, The Qt Company gives you certain additional -+** rights. These rights are described in The Qt Company LGPL Exception -+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -+** -+** $QT_END_LICENSE$ -+** -+****************************************************************************/ -+ -+// qglobal.h includes this header, so keep it outside of our include guards -+#include -+ -+#if !defined(QVERSIONTAGGING_H) && !defined(QT_NO_VERSION_TAGGING) -+#define QVERSIONTAGGING_H -+ -+QT_BEGIN_NAMESPACE -+ -+/* -+ * Ugly hack warning and explanation: -+ * -+ * This file causes all ELF modules, be they libraries or applications, to use the -+ * qt_version_tag symbol that is present in QtCore. Such symbol is versioned, -+ * so the linker will automatically pull the current Qt version and add it to -+ * the ELF header of the library/application. The assembly produces one section -+ * called ".qtversion" containing two pointer-sized values. The first is a -+ * relocation to the qt_version_tag symbol (which is what causes the ELF -+ * version to get used). The second value is the current Qt version at the time -+ * of compilation. -+ * -+ * There will only be one copy of the section in the output library or application. -+ */ -+ -+#if defined(QT_BUILD_CORE_LIB) -+// skip -+#elif defined(Q_CC_GNU) -+# if defined(Q_PROCESSOR_X86) && defined(Q_OS_LINUX) -+asm ( -+".section .qtversion, \"aG\", @progbits, qt_version_tag, comdat\n" -+".align 8\n" -+# ifdef __LP64__ -+".quad " QT_STRINGIFY(QT_MANGLE_NAMESPACE(qt_version_tag)) "@GOTPCREL\n" -+# elif defined(Q_PROCESSOR_X86_64) // x32 -+".long " QT_STRINGIFY(QT_MANGLE_NAMESPACE(qt_version_tag)) "@GOTPCREL\n" -+# else // x86 -+".long " QT_STRINGIFY(QT_MANGLE_NAMESPACE(qt_version_tag)) "@GOT\n" -+#endif -+".long " QT_STRINGIFY(QT_VERSION) "\n" -+".align 8\n" -+".previous" -+); -+# endif -+#endif -+ -+QT_END_NAMESPACE -+ -+#endif // QVERSIONTAGGING_H && !QT_NO_VERSION_TAGGING --- -2.6.0 diff --git a/Add-option-to-disable-session-management-by-closing-windows.patch b/Add-option-to-disable-session-management-by-closing-windows.patch deleted file mode 100644 index caa87dc..0000000 --- a/Add-option-to-disable-session-management-by-closing-windows.patch +++ /dev/null @@ -1,207 +0,0 @@ -From e7bf0edfd49de9a4d8285fbe8d878f8fda910e6d Mon Sep 17 00:00:00 2001 -From: Andreas Hartmetz -Date: Tue, 19 Jan 2016 14:30:18 +0100 -Subject: Add option to disable "session management by closing windows". - -That feature is a poor man's session management for applications -that do not implement any specific session management features. -It badly interferes with proper session management support, so -applications must be able to disable it. - -This enables fixing applications with -QGuiApplication::quitOnLastWindowClosed() true - the default - -dying too early, before they are enumerated for the list of -applications to restart on session restore, thus preventing them -from being restored. See -https://bugs.kde.org/show_bug.cgi?id=354724 - -[ChangeLog][QtGui] Qt asking to close windows on session exit as -a fallback session management mechanism has been made optional. -Disabling it fixes session management for applications that -implement full session management. See -QGuiApplication::isFallbackSessionManagementEnabled(). - -Task-number: QTBUG-49667 -Change-Id: Ib22e58c9c64351dea8b7e2a74db91d26dd7ab7aa -Reviewed-by: Oswald Buddenhagen -Reviewed-by: David Faure ---- - .../widgets/mainwindows/application/mainwindow.cpp | 16 ++++++ - .../widgets/mainwindows/application/mainwindow.h | 2 + - .../code/src_gui_kernel_qguiapplication.cpp | 1 + - src/gui/kernel/qguiapplication.cpp | 60 +++++++++++++++++++++- - src/gui/kernel/qguiapplication.h | 3 ++ - src/gui/kernel/qguiapplication_p.h | 1 + - src/gui/kernel/qsessionmanager.cpp | 19 ++++--- - 7 files changed, 90 insertions(+), 12 deletions(-) - -diff --git a/src/gui/doc/snippets/code/src_gui_kernel_qguiapplication.cpp b/src/gui/doc/snippets/code/src_gui_kernel_qguiapplication.cpp -index 4ddf8c8..63fdb3b 100644 ---- a/src/gui/doc/snippets/code/src_gui_kernel_qguiapplication.cpp -+++ b/src/gui/doc/snippets/code/src_gui_kernel_qguiapplication.cpp -@@ -53,6 +53,7 @@ int main(int argc, char *argv[]) - MyMainWidget::MyMainWidget(QWidget *parent) - :QWidget(parent) - { -+ QGuiApplication::setFallbackSessionManagementEnabled(false); - connect(qApp, SIGNAL(commitDataRequest(QSessionManager)), SLOT(commitData(QSessionManager))); - } - -diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp -index 65d679c..8f1c62f 100644 ---- a/src/gui/kernel/qguiapplication.cpp -+++ b/src/gui/kernel/qguiapplication.cpp -@@ -138,6 +138,8 @@ QPlatformTheme *QGuiApplicationPrivate::platform_theme = 0; - - QList QGuiApplicationPrivate::generic_plugin_list; - -+bool QGuiApplicationPrivate::is_fallback_session_management_enabled = true; -+ - enum ApplicationResourceFlags - { - ApplicationPaletteExplicitlySet = 0x1, -@@ -3082,6 +3084,55 @@ void QGuiApplicationPrivate::setApplicationState(Qt::ApplicationState state, boo - emit qApp->applicationStateChanged(applicationState); - } - -+// ### Qt6: consider removing the feature or making it less intrusive -+/*! -+ \since 5.6 -+ -+ Returns whether QGuiApplication will use fallback session management. -+ -+ The default is \c true. -+ -+ If this is \c true and the session manager allows user interaction, -+ QGuiApplication will try to close toplevel windows after -+ commitDataRequest() has been emitted. If a window cannot be closed, session -+ shutdown will be canceled and the application will keep running. -+ -+ Fallback session management only benefits applications that have an -+ "are you sure you want to close this window?" feature or other logic that -+ prevents closing a toplevel window depending on certain conditions, and -+ that do nothing to explicitly implement session management. In applications -+ that \e do implement session management using the proper session management -+ API, fallback session management interferes and may break session -+ management logic. -+ -+ \warning If all windows \e are closed due to fallback session management -+ and quitOnLastWindowClosed() is \c true, the application will quit before -+ it is explicitly instructed to quit through the platform's session -+ management protocol. That violation of protocol may prevent the platform -+ session manager from saving application state. -+ -+ \sa setFallbackSessionManagementEnabled(), -+ QSessionManager::allowsInteraction(), saveStateRequest(), -+ commitDataRequest(), {Session Management} -+*/ -+bool QGuiApplication::isFallbackSessionManagementEnabled() -+{ -+ return QGuiApplicationPrivate::is_fallback_session_management_enabled; -+} -+ -+/*! -+ \since 5.6 -+ -+ Sets whether QGuiApplication will use fallback session management to -+ \a enabled. -+ -+ \sa isFallbackSessionManagementEnabled() -+*/ -+void QGuiApplication::setFallbackSessionManagementEnabled(bool enabled) -+{ -+ QGuiApplicationPrivate::is_fallback_session_management_enabled = enabled; -+} -+ - /*! - \since 4.2 - \fn void QGuiApplication::commitDataRequest(QSessionManager &manager) -@@ -3106,7 +3157,8 @@ void QGuiApplicationPrivate::setApplicationState(Qt::ApplicationState state, boo - - \note You should use Qt::DirectConnection when connecting to this signal. - -- \sa isSessionRestored(), sessionId(), saveStateRequest(), {Session Management} -+ \sa setFallbackSessionManagementEnabled(), isSessionRestored(), -+ sessionId(), saveStateRequest(), {Session Management} - */ - - /*! -@@ -3236,9 +3288,13 @@ void QGuiApplicationPrivate::commitData() - { - Q_Q(QGuiApplication); - is_saving_session = true; -+ - emit q->commitDataRequest(*session_manager); -- if (session_manager->allowsInteraction() && !tryCloseAllWindows()) -+ if (is_fallback_session_management_enabled && session_manager->allowsInteraction() -+ && !tryCloseAllWindows()) { - session_manager->cancel(); -+ } -+ - is_saving_session = false; - } - -diff --git a/src/gui/kernel/qguiapplication.h b/src/gui/kernel/qguiapplication.h -index d995387..3f233d4 100644 ---- a/src/gui/kernel/qguiapplication.h -+++ b/src/gui/kernel/qguiapplication.h -@@ -152,6 +152,9 @@ public: - QString sessionId() const; - QString sessionKey() const; - bool isSavingSession() const; -+ -+ static bool isFallbackSessionManagementEnabled(); -+ static void setFallbackSessionManagementEnabled(bool); - #endif - - static void sync(); -diff --git a/src/gui/kernel/qguiapplication_p.h b/src/gui/kernel/qguiapplication_p.h -index 7c7da97..4f0f6fd 100644 ---- a/src/gui/kernel/qguiapplication_p.h -+++ b/src/gui/kernel/qguiapplication_p.h -@@ -234,6 +234,7 @@ public: - #endif - - #ifndef QT_NO_SESSIONMANAGER -+ static bool is_fallback_session_management_enabled; - QSessionManager *session_manager; - bool is_session_restored; - bool is_saving_session; -diff --git a/src/gui/kernel/qsessionmanager.cpp b/src/gui/kernel/qsessionmanager.cpp -index f4b56fd..c6d23f1 100644 ---- a/src/gui/kernel/qsessionmanager.cpp -+++ b/src/gui/kernel/qsessionmanager.cpp -@@ -64,22 +64,21 @@ QT_BEGIN_NAMESPACE - settings. - - QSessionManager provides an interface between the application and the -- session manager so that the program can work well with the session manager. -- In Qt, session management requests for action are handled by the two -- signals QGuiApplication::commitDataRequest() and -- QGuiApplication::saveStateRequest(). Both provide a reference to a session -- manager object as argument, to allow the application to communicate with -- the session manager. The session manager can only be accessed through these -- functions. -+ platform's session manager. In Qt, session management requests for action -+ are handled by the two signals QGuiApplication::commitDataRequest() and -+ QGuiApplication::saveStateRequest(). Both provide a reference to a -+ QSessionManager object as argument. The session manager can only be -+ accessed in slots invoked by these signals. -+ -+ \warning If you use QSessionManager, you should disable fallback session -+ management: QGuiApplication::setFallbackSessionManagementEnabled(). - - No user interaction is possible \e unless the application gets explicit - permission from the session manager. You ask for permission by calling - allowsInteraction() or, if it is really urgent, allowsErrorInteraction(). - Qt does not enforce this, but the session manager may. - -- You can try to abort the shutdown process by calling cancel(). The default -- commitData() function does this if some top-level window rejected its -- closeEvent(). -+ You can try to abort the shutdown process by calling cancel(). - - For sophisticated session managers provided on Unix/X11, QSessionManager - offers further possibilities to fine-tune an application's session --- -cgit v0.11.0 diff --git a/Fix-QtCore-compilation-with-clang.patch b/Fix-QtCore-compilation-with-clang.patch deleted file mode 100644 index a9b3652..0000000 --- a/Fix-QtCore-compilation-with-clang.patch +++ /dev/null @@ -1,102 +0,0 @@ -From 4c738356ee4f20b6414e43a1cd73817f7eb28dd1 Mon Sep 17 00:00:00 2001 -From: Thiago Macieira -Date: Thu, 17 Sep 2015 11:35:36 -0700 -Subject: [PATCH 3/5] Fix QtCore compilation with clang - -The .altmacro is not supported with Clang's integrated assembly. - -The worst part is that I had this fixed, but apparently I never pushed -the update to Gerrit and then we staged the old version. This commit -brings back the fixes. - -Incidentally, it also makes things work with freebsd-clang. - -Change-Id: Id2a5d90d07d7ee470fcb9ad9696a9a0f9ced7ea7 -Reviewed-by: Lars Knoll -Reviewed-by: Simon Hausmann -(cherry picked from commit 05d401104ee6b10699b7288ead044d6765b19c4d) ---- - src/corelib/global/global.pri | 28 ++++++++++++++++++++++++++-- - src/corelib/global/qversiontagging.cpp | 15 +++++++++++---- - 2 files changed, 37 insertions(+), 6 deletions(-) - -diff --git a/src/corelib/global/global.pri b/src/corelib/global/global.pri -index 7ca0734f1face0d4517fdb1257dbb9812f04d0d2..2165a6c22e86948655c0074d50f8669c8a192d40 100644 ---- a/src/corelib/global/global.pri -+++ b/src/corelib/global/global.pri -@@ -27,8 +27,7 @@ SOURCES += \ - global/qmalloc.cpp \ - global/qnumeric.cpp \ - global/qlogging.cpp \ -- global/qhooks.cpp \ -- global/qversiontagging.cpp -+ global/qhooks.cpp - - # qlibraryinfo.cpp includes qconfig.cpp - INCLUDEPATH += $$QT_BUILD_TREE/src/corelib/global -@@ -55,3 +54,28 @@ journald { - PKGCONFIG_PRIVATE += libsystemd-journal - DEFINES += QT_USE_JOURNALD - } -+ -+linux|freebsd { -+ VERSIONTAGGING_SOURCES = global/qversiontagging.cpp -+ ltcg|clang { -+ versiontagging_compiler.commands = $$QMAKE_CXX -c $(CXXFLAGS) $(INCPATH) -+ -+ # Disable LTO, as the global inline assembly may not get processed -+ versiontagging_compiler.commands += -fno-lto -+ -+ # Disable the integrated assembler for Clang, since it can't parse with -+ # the alternate macro syntax in use in qversiontagging.cpp -+ clang: versiontagging_compiler.commands += -no-integrated-as -+ -+ versiontagging_compiler.commands += -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_IN} -+ versiontagging_compiler.dependency_type = TYPE_C -+ versiontagging_compiler.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}$${first(QMAKE_EXT_OBJ)} -+ versiontagging_compiler.input = VERSIONTAGGING_SOURCES -+ versiontagging_compiler.variable_out = OBJECTS -+ versiontagging_compiler.name = compiling[versiontagging] ${QMAKE_FILE_IN} -+ silent: versiontagging_compiler.commands = @echo compiling[versiontagging] ${QMAKE_FILE_IN} && $$versiontagging_compiler.commands -+ QMAKE_EXTRA_COMPILERS += versiontagging_compiler -+ } else { -+ SOURCES += $$VERSIONTAGGING_SOURCES -+ } -+} -diff --git a/src/corelib/global/qversiontagging.cpp b/src/corelib/global/qversiontagging.cpp -index e3d9efa16b7677a29963020660bc9c4b4a143356..66d3f8d00f7297d98c08cfa7aa359874e2e0aa8f 100644 ---- a/src/corelib/global/qversiontagging.cpp -+++ b/src/corelib/global/qversiontagging.cpp -@@ -33,18 +33,25 @@ - - #include "qglobal.h" - --#if defined(Q_CC_GNU) && defined(Q_OS_LINUX) && defined(Q_PROCESSOR_X86) && !defined(QT_STATIC) -+#if defined(Q_CC_GNU) && (defined(Q_OS_LINUX) || defined(Q_OS_FREEBSD)) && defined(Q_PROCESSOR_X86) && !defined(QT_STATIC) - # define SYM QT_MANGLE_NAMESPACE(qt_version_tag) - # define SSYM QT_STRINGIFY(SYM) - - asm( -+// ASM macro that makes one ELF versioned symbol -+".macro make_versioned_symbol plainsym versionedsym\n" -+".globl plainsym\n" -+".type plainsym, @object\n" -+".size plainsym, 1\n" -+".symver plainsym, versionedsym\n" -+"plainsym :\n" -+".endm\n" -+ - // ASM macro that makes one ELF versioned symbol qt_version_tag{sep}Qt_{major}.{minor} - // that is an alias to qt_version_tag_{major}_{minor}. - // The {sep} parameter must be @ for all old versions and @@ for the current version. - ".macro make_one_tag major minor sep\n" --".globl " SSYM "_\\major\\()_\\minor\n" // make the symbol global --SSYM "_\\major\\()_\\minor:\n" // declare it --" .symver " SSYM "_\\major\\()_\\minor, " SSYM "\\sep\\()Qt_\\major\\().\\minor\n" -+" make_versioned_symbol " SSYM "_\\major\\()_\\minor, " SSYM "\\sep\\()Qt_\\major\\().\\minor\n" - ".endm\n" - - ".altmacro\n" --- -2.6.0 - diff --git a/Fix-QtDBus-deadlock-inside-kded-kiod.patch b/Fix-QtDBus-deadlock-inside-kded-kiod.patch new file mode 100644 index 0000000..65521bb --- /dev/null +++ b/Fix-QtDBus-deadlock-inside-kded-kiod.patch @@ -0,0 +1,124 @@ +From f328f0cd2eb6be2a0a0d148bd769d51eae42bdc6 Mon Sep 17 00:00:00 2001 +From: Thiago Macieira +Date: Tue, 15 Mar 2016 11:00:20 -0700 +Subject: [PATCH] Fix QtDBus deadlock inside kded/kiod + +Whenever a message spy was installed, we failed to actually process +looped-back messages by queueing them for processing by the spy. That +had as a consequence that the caller got an error reply and the message, +later, we attempted to deliver the message. Since that message still was +isLocal==true, bad things happened inside the manager thread. + +The correct solution is not to queue the message for the filter. If the +message is local, then simply deliver directly, as we're still in the +user's thread. This used to be the behavior in Qt 5.5. + +Task-number: QTBUG-51676 +Change-Id: I1dc112894cde7121e8ce302ae51b438ade1ff612 +--- + src/dbus/qdbusintegrator.cpp | 42 ++++++++++++++++++++++++++++++++---------- + src/dbus/qdbusintegrator_p.h | 1 + + 2 files changed, 33 insertions(+), 10 deletions(-) + +diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp +index cd44861..478a2c4 100644 +--- a/src/dbus/qdbusintegrator.cpp ++++ b/src/dbus/qdbusintegrator.cpp +@@ -481,6 +481,11 @@ QDBusSpyCallEvent::~QDBusSpyCallEvent() + + void QDBusSpyCallEvent::placeMetaCall(QObject *) + { ++ invokeSpyHooks(msg, hooks, hookCount); ++} ++ ++inline void QDBusSpyCallEvent::invokeSpyHooks(const QDBusMessage &msg, const Hook *hooks, int hookCount) ++{ + // call the spy hook list + for (int i = 0; i < hookCount; ++i) + hooks[i](msg); +@@ -509,7 +514,12 @@ bool QDBusConnectionPrivate::handleMessage(const QDBusMessage &amsg) + { + if (!ref.load()) + return false; +- if (!dispatchEnabled && !QDBusMessagePrivate::isLocal(amsg)) { ++ ++ // local message are always delivered, regardless of filtering ++ // or whether the dispatcher is enabled ++ bool isLocal = QDBusMessagePrivate::isLocal(amsg); ++ ++ if (!dispatchEnabled && !isLocal) { + // queue messages only, we'll handle them later + qDBusDebug() << this << "delivery is suspended"; + pendingMessages << amsg; +@@ -523,13 +533,23 @@ bool QDBusConnectionPrivate::handleMessage(const QDBusMessage &amsg) + // let them see the signal too + return false; + case QDBusMessage::MethodCallMessage: +- // run it through the spy filters (if any) before the regular processing ++ // run it through the spy filters (if any) before the regular processing: ++ // a) if it's a local message, we're in the caller's thread, so invoke the filter directly ++ // b) if it's an external message, post to the main thread + if (Q_UNLIKELY(qDBusSpyHookList.exists()) && qApp) { + const QDBusSpyHookList &list = *qDBusSpyHookList; +- qDBusDebug() << this << "invoking message spies"; +- QCoreApplication::postEvent(qApp, new QDBusSpyCallEvent(this, QDBusConnection(this), +- amsg, list.constData(), list.size())); +- return true; ++ if (isLocal) { ++ Q_ASSERT(QThread::currentThread() != thread()); ++ qDBusDebug() << this << "invoking message spies directly"; ++ QDBusSpyCallEvent::invokeSpyHooks(amsg, list.constData(), list.size()); ++ } else { ++ qDBusDebug() << this << "invoking message spies via event"; ++ QCoreApplication::postEvent(qApp, new QDBusSpyCallEvent(this, QDBusConnection(this), ++ amsg, list.constData(), list.size())); ++ ++ // we'll be called back, so return ++ return true; ++ } + } + + handleObjectCall(amsg); +@@ -1451,9 +1471,9 @@ void QDBusConnectionPrivate::handleObjectCall(const QDBusMessage &msg) + // that means the dispatchLock mutex is locked + // must not call out to user code in that case + // +- // however, if the message is internal, handleMessage was called +- // directly and no lock is in place. We can therefore call out to +- // user code, if necessary ++ // however, if the message is internal, handleMessage was called directly ++ // (user's thread) and no lock is in place. We can therefore call out to ++ // user code, if necessary. + ObjectTreeNode result; + int usedLength; + QThread *objThread = 0; +@@ -1492,12 +1512,14 @@ void QDBusConnectionPrivate::handleObjectCall(const QDBusMessage &msg) + usedLength, msg)); + return; + } else if (objThread != QThread::currentThread()) { +- // synchronize with other thread ++ // looped-back message, targeting another thread: ++ // synchronize with it + postEventToThread(HandleObjectCallPostEventAction, result.obj, + new QDBusActivateObjectEvent(QDBusConnection(this), this, result, + usedLength, msg, &sem)); + semWait = true; + } else { ++ // looped-back message, targeting current thread + semWait = false; + } + } // release the lock +diff --git a/src/dbus/qdbusintegrator_p.h b/src/dbus/qdbusintegrator_p.h +index 2bbebdf..c0d9c22 100644 +--- a/src/dbus/qdbusintegrator_p.h ++++ b/src/dbus/qdbusintegrator_p.h +@@ -145,6 +145,7 @@ public: + {} + ~QDBusSpyCallEvent(); + void placeMetaCall(QObject *) Q_DECL_OVERRIDE; ++ static inline void invokeSpyHooks(const QDBusMessage &msg, const Hook *hooks, int hookCount); + + QDBusConnection conn; // keeps the refcount in QDBusConnectionPrivate up + QDBusMessage msg; +-- +2.6.2.2.g1b5ffa3 diff --git a/QMimeDatabase-follow-symlinks-when-checking-for-FIFO.patch b/QMimeDatabase-follow-symlinks-when-checking-for-FIFO.patch deleted file mode 100644 index 4c32eb3..0000000 --- a/QMimeDatabase-follow-symlinks-when-checking-for-FIFO.patch +++ /dev/null @@ -1,94 +0,0 @@ -From 72b4f0d4743826ee14ec06bf0ada26418f4a69be Mon Sep 17 00:00:00 2001 -From: David Faure -Date: Mon, 30 Nov 2015 12:03:18 +0100 -Subject: [PATCH 1/1] QMimeDatabase: follow symlinks when checking for FIFO - etc. - -This was documented, but not what the code did. - -Task-number: QTBUG-48529 -Change-Id: I4849778c61dcae13be27c62b24717693c0c07d78 -Reviewed-by: Edward Welbourne -Reviewed-by: Thiago Macieira ---- - src/corelib/mimetypes/qmimedatabase.cpp | 3 ++- - .../mimetypes/qmimedatabase/tst_qmimedatabase.cpp | 27 ++++++++++++++++++++++ - .../mimetypes/qmimedatabase/tst_qmimedatabase.h | 1 + - 3 files changed, 30 insertions(+), 1 deletion(-) - -diff --git a/src/corelib/mimetypes/qmimedatabase.cpp b/src/corelib/mimetypes/qmimedatabase.cpp -index c1e17b9..fd11dbc 100644 ---- a/src/corelib/mimetypes/qmimedatabase.cpp -+++ b/src/corelib/mimetypes/qmimedatabase.cpp -@@ -354,9 +354,10 @@ QMimeType QMimeDatabase::mimeTypeForFile(const QFileInfo &fileInfo, MatchMode mo - - #ifdef Q_OS_UNIX - // Cannot access statBuf.st_mode from the filesystem engine, so we have to stat again. -+ // In addition we want to follow symlinks. - const QByteArray nativeFilePath = QFile::encodeName(file.fileName()); - QT_STATBUF statBuffer; -- if (QT_LSTAT(nativeFilePath.constData(), &statBuffer) == 0) { -+ if (QT_STAT(nativeFilePath.constData(), &statBuffer) == 0) { - if (S_ISCHR(statBuffer.st_mode)) - return d->mimeTypeForName(QLatin1String("inode/chardevice")); - if (S_ISBLK(statBuffer.st_mode)) -diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp -index 0171c4a..1b4dc02 100644 ---- a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp -+++ b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp -@@ -35,6 +35,11 @@ - - #include "qstandardpaths.h" - -+#ifdef Q_OS_UNIX -+#include -+#include -+#endif -+ - #include - #include - #include -@@ -646,6 +651,28 @@ void tst_QMimeDatabase::knownSuffix() - QCOMPARE(db.suffixForFileName(QString::fromLatin1("foo.tar.bz2")), QString::fromLatin1("tar.bz2")); - } - -+void tst_QMimeDatabase::symlinkToFifo() // QTBUG-48529 -+{ -+#ifdef Q_OS_UNIX -+ QTemporaryDir tempDir; -+ QVERIFY(tempDir.isValid()); -+ const QString dir = tempDir.path(); -+ const QString fifo = dir + "/fifo"; -+ QCOMPARE(mkfifo(QFile::encodeName(fifo), 0006), 0); -+ -+ QMimeDatabase db; -+ QCOMPARE(db.mimeTypeForFile(fifo).name(), QString::fromLatin1("inode/fifo")); -+ -+ // Now make a symlink to the fifo -+ const QString link = dir + "/link"; -+ QVERIFY(QFile::link(fifo, link)); -+ QCOMPARE(db.mimeTypeForFile(link).name(), QString::fromLatin1("inode/fifo")); -+ -+#else -+ QSKIP("This test requires pipes and symlinks"); -+#endif -+} -+ - void tst_QMimeDatabase::findByFileName_data() - { - QTest::addColumn("filePath"); -diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.h b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.h -index 2827bd2..4b703f1 100644 ---- a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.h -+++ b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.h -@@ -70,6 +70,7 @@ private slots: - void suffixes_data(); - void suffixes(); - void knownSuffix(); -+ void symlinkToFifo(); - void fromThreads(); - - // shared-mime-info test suite --- -2.6.2.2.g1b5ffa3 - diff --git a/QtDBus-clean-up-signal-hooks-and-object-tree-in-closeConnection.patch b/QtDBus-clean-up-signal-hooks-and-object-tree-in-closeConnection.patch new file mode 100644 index 0000000..c983041 --- /dev/null +++ b/QtDBus-clean-up-signal-hooks-and-object-tree-in-closeConnection.patch @@ -0,0 +1,87 @@ +From b024fbe83863fc57364a52c717d5b43d654bdb5d Mon Sep 17 00:00:00 2001 +From: Weng Xuetian +Date: Sat, 5 Mar 2016 12:23:21 -0800 +Subject: [PATCH] QtDBus: clean up signal hooks and object tree in + closeConnection + +If a QObject is added or passed as receiver to QDBusConnection::connect() +and it is managed by Q_GLOBAL_STATIC or similar mechanism, it is +possible that when that its destructor is called after the dbus daemon +thread ends. In that case, QObject::destroyed connected via +Qt::BlockingQueuedConnection to QDBusConnectionPrivate will cause dead +lock since the thread is no longer processing events. + +Task-number: QTBUG-51648 +Change-Id: I1a1810a6d6d0234af0269d5f3fc1f54101bf1547 +--- + src/dbus/qdbusconnection_p.h | 1 + + src/dbus/qdbusintegrator.cpp | 28 +++++++++++++++++++++++++++- + 2 files changed, 28 insertions(+), 1 deletion(-) + +diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h +index c77daf7..565eb83 100644 +--- a/src/dbus/qdbusconnection_p.h ++++ b/src/dbus/qdbusconnection_p.h +@@ -254,6 +254,7 @@ private: + const QVector &metaTypes, int slotIdx); + + SignalHookHash::Iterator removeSignalHookNoLock(SignalHookHash::Iterator it); ++ void disconnectObjectTree(ObjectTreeNode &node); + + bool isServiceRegisteredByThread(const QString &serviceName); + +diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp +index cd44861..a3cd47b 100644 +--- a/src/dbus/qdbusintegrator.cpp ++++ b/src/dbus/qdbusintegrator.cpp +@@ -1030,7 +1030,6 @@ QDBusConnectionPrivate::~QDBusConnectionPrivate() + qPrintable(name)); + + closeConnection(); +- rootNode.children.clear(); // free resources + qDeleteAll(cachedMetaObjects); + + if (mode == ClientMode || mode == PeerMode) { +@@ -1052,6 +1051,20 @@ QDBusConnectionPrivate::~QDBusConnectionPrivate() + } + } + ++void QDBusConnectionPrivate::disconnectObjectTree(QDBusConnectionPrivate::ObjectTreeNode &haystack) ++{ ++ QDBusConnectionPrivate::ObjectTreeNode::DataList::Iterator it = haystack.children.begin(); ++ ++ while (it != haystack.children.end()) { ++ disconnectObjectTree(*it); ++ it++; ++ } ++ ++ if (haystack.obj) { ++ haystack.obj->disconnect(this); ++ } ++} ++ + void QDBusConnectionPrivate::closeConnection() + { + QDBusWriteLocker locker(CloseConnectionAction, this); +@@ -1075,6 +1088,19 @@ void QDBusConnectionPrivate::closeConnection() + } + + qDeleteAll(pendingCalls); ++ ++ // clean up all signal hook and object tree, to avoid QObject::destroyed ++ // being activated to dbus daemon thread which already quits. ++ // dbus connection is already closed, so there is nothing we could do be clean ++ // up everything here. ++ SignalHookHash::iterator sit = signalHooks.begin(); ++ while (sit != signalHooks.end()) { ++ sit.value().obj->disconnect(this); ++ sit++; ++ } ++ ++ disconnectObjectTree(rootNode); ++ rootNode.children.clear(); // free resources + } + + void QDBusConnectionPrivate::checkThread() +-- +2.6.2.2.g1b5ffa3 diff --git a/QtDBus-finish-all-pending-call-with-error-if-disconnected.patch b/QtDBus-finish-all-pending-call-with-error-if-disconnected.patch new file mode 100644 index 0000000..1d728de --- /dev/null +++ b/QtDBus-finish-all-pending-call-with-error-if-disconnected.patch @@ -0,0 +1,158 @@ +From acde2e69df5dedc624674107596f276125e22864 Mon Sep 17 00:00:00 2001 +From: Weng Xuetian +Date: Thu, 3 Mar 2016 21:56:53 -0800 +Subject: [PATCH] QtDBus: finish all pending call with error if disconnected + +libdbus will send a local signal if connection gets disconnected. When +this happens, end all pending calls with QDBusError::Disconnected. + +Task-number: QTBUG-51649 +Change-Id: I5c7d2a468bb5da746d0c0e53e458c1e376f186a9 +--- + src/dbus/dbus_minimal_p.h | 2 ++ + src/dbus/qdbusintegrator.cpp | 26 +++++++++++++++++----- + src/dbus/qdbusutil_p.h | 6 +++++ + .../dbus/qdbusconnection/tst_qdbusconnection.cpp | 22 ++++++++++++++++++ + .../dbus/qdbusconnection/tst_qdbusconnection.h | 1 + + 5 files changed, 51 insertions(+), 6 deletions(-) + +diff --git a/src/dbus/dbus_minimal_p.h b/src/dbus/dbus_minimal_p.h +index f0a2954..8f25b24 100644 +--- a/src/dbus/dbus_minimal_p.h ++++ b/src/dbus/dbus_minimal_p.h +@@ -99,9 +99,11 @@ typedef dbus_uint32_t dbus_bool_t; + /* dbus-shared.h */ + #define DBUS_SERVICE_DBUS "org.freedesktop.DBus" + #define DBUS_PATH_DBUS "/org/freedesktop/DBus" ++#define DBUS_PATH_LOCAL "/org/freedesktop/DBus/Local" + #define DBUS_INTERFACE_DBUS "org.freedesktop.DBus" + #define DBUS_INTERFACE_INTROSPECTABLE "org.freedesktop.DBus.Introspectable" + #define DBUS_INTERFACE_PROPERTIES "org.freedesktop.DBus.Properties" ++#define DBUS_INTERFACE_LOCAL "org.freedesktop.DBus.Local" + + #define DBUS_NAME_FLAG_ALLOW_REPLACEMENT 0x1 /**< Allow another service to become the primary owner if requested */ + #define DBUS_NAME_FLAG_REPLACE_EXISTING 0x2 /**< Request to replace the current primary owner */ +diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp +index cd44861..320419f 100644 +--- a/src/dbus/qdbusintegrator.cpp ++++ b/src/dbus/qdbusintegrator.cpp +@@ -519,6 +519,14 @@ bool QDBusConnectionPrivate::handleMessage(const QDBusMessage &amsg) + switch (amsg.type()) { + case QDBusMessage::SignalMessage: + handleSignal(amsg); ++ // Check local disconnected signal from libdbus ++ if (amsg.interface() == QDBusUtil::dbusInterfaceLocal() ++ && amsg.path() == QDBusUtil::dbusPathLocal() ++ && amsg.member() == QDBusUtil::disconnected() ++ && !QDBusMessagePrivate::isLocal(amsg)) { ++ while (!pendingCalls.isEmpty()) ++ processFinishedCall(pendingCalls.first()); ++ } + // if there are any other filters in this DBusConnection, + // let them see the signal too + return false; +@@ -1767,10 +1775,16 @@ void QDBusConnectionPrivate::processFinishedCall(QDBusPendingCallPrivate *call) + + QDBusMessage &msg = call->replyMessage; + if (call->pending) { +- // decode the message +- DBusMessage *reply = q_dbus_pending_call_steal_reply(call->pending); +- msg = QDBusMessagePrivate::fromDBusMessage(reply, connection->capabilities); +- q_dbus_message_unref(reply); ++ // when processFinishedCall is called and pending call is not completed, ++ // it means we received disconnected signal from libdbus ++ if (q_dbus_pending_call_get_completed(call->pending)) { ++ // decode the message ++ DBusMessage *reply = q_dbus_pending_call_steal_reply(call->pending); ++ msg = QDBusMessagePrivate::fromDBusMessage(reply, connection->capabilities); ++ q_dbus_message_unref(reply); ++ } else { ++ msg = QDBusMessage::createError(QDBusError::Disconnected, QDBusUtil::disconnectedErrorMessage()); ++ } + } + qDBusDebug() << connection << "got message reply:" << msg; + +@@ -2070,8 +2084,8 @@ void QDBusConnectionPrivate::sendInternal(QDBusPendingCallPrivate *pcall, void * + pcall->pending = pending; + q_dbus_pending_call_set_notify(pending, qDBusResultReceived, pcall, 0); + +- // DBus won't notify us when a peer disconnects so we need to track these ourselves +- if (mode == QDBusConnectionPrivate::PeerMode) ++ // DBus won't notify us when a peer disconnects or server terminates so we need to track these ourselves ++ if (mode == QDBusConnectionPrivate::PeerMode || mode == QDBusConnectionPrivate::ClientMode) + pendingCalls.append(pcall); + + return; +diff --git a/src/dbus/qdbusutil_p.h b/src/dbus/qdbusutil_p.h +index 8f5ae92..ca70ff9 100644 +--- a/src/dbus/qdbusutil_p.h ++++ b/src/dbus/qdbusutil_p.h +@@ -155,6 +155,8 @@ namespace QDBusUtil + { return QStringLiteral(DBUS_SERVICE_DBUS); } + inline QString dbusPath() + { return QStringLiteral(DBUS_PATH_DBUS); } ++ inline QString dbusPathLocal() ++ { return QStringLiteral(DBUS_PATH_LOCAL); } + inline QString dbusInterface() + { + // it's the same string, but just be sure +@@ -165,8 +167,12 @@ namespace QDBusUtil + { return QStringLiteral(DBUS_INTERFACE_PROPERTIES); } + inline QString dbusInterfaceIntrospectable() + { return QStringLiteral(DBUS_INTERFACE_INTROSPECTABLE); } ++ inline QString dbusInterfaceLocal() ++ { return QStringLiteral(DBUS_INTERFACE_LOCAL); } + inline QString nameOwnerChanged() + { return QStringLiteral("NameOwnerChanged"); } ++ inline QString disconnected() ++ { return QStringLiteral("Disconnected"); } + inline QString disconnectedErrorMessage() + { return QStringLiteral("Not connected to D-Bus server"); } + } +diff --git a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp +index e91f87d..6c7e6b1 100644 +--- a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp ++++ b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.cpp +@@ -1218,6 +1218,28 @@ void tst_QDBusConnection::callVirtualObjectLocal() + QCOMPARE(obj.replyArguments, subPathReply.arguments()); + } + ++void tst_QDBusConnection::pendingCallWhenDisconnected() ++{ ++ QDBusServer *server = new QDBusServer; ++ QDBusConnection con = QDBusConnection::connectToPeer(server->address(), "disconnect"); ++ QTestEventLoop::instance().enterLoop(2); ++ QVERIFY(!QTestEventLoop::instance().timeout()); ++ QVERIFY(con.isConnected()); ++ ++ delete server; ++ ++ // Make sure we call the method before we know it is disconnected. ++ QVERIFY(con.isConnected()); ++ QDBusMessage message = QDBusMessage::createMethodCall("", "/", QString(), "method"); ++ QDBusPendingCall reply = con.asyncCall(message); ++ ++ QTestEventLoop::instance().enterLoop(2); ++ QVERIFY(!con.isConnected()); ++ QVERIFY(reply.isFinished()); ++ QVERIFY(reply.isError()); ++ QVERIFY(reply.error().type() == QDBusError::Disconnected); ++} ++ + QString MyObject::path; + QString MyObjectWithoutInterface::path; + QString MyObjectWithoutInterface::interface; +diff --git a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.h b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.h +index a53ba32..720e484 100644 +--- a/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.h ++++ b/tests/auto/dbus/qdbusconnection/tst_qdbusconnection.h +@@ -121,6 +121,7 @@ private slots: + void registerVirtualObject(); + void callVirtualObject(); + void callVirtualObjectLocal(); ++ void pendingCallWhenDisconnected(); + + public: + QString serviceName() const { return "org.qtproject.Qt.Autotests.QDBusConnection"; } +-- +2.6.2.2.g1b5ffa3 diff --git a/libqt5-qtbase.changes b/libqt5-qtbase.changes index 91eb88b..5fd7e6b 100644 --- a/libqt5-qtbase.changes +++ b/libqt5-qtbase.changes @@ -1,3 +1,53 @@ +------------------------------------------------------------------- +Sat Apr 23 18:04:33 UTC 2016 - hrvoje.senjan@gmail.com + +- Add patches from upstream: + 0001-xcb-XInput2-fixes-enter-leave-event-fixes.patch + 0002-xcb-Correct-enter-leave-event-handling-when-mouse-bu.patch + 0003-xcb-Fix-not-delivering-focusIn-event-on-hide-show.patch + 0004-xcb-Fix-drag-and-drop-between-xcb-screens.patch + 0005-xcb-Properly-initialize-available-geometry-when-XRan.patch + 0006-xcb-properly-initialize-size-in-millimeters-if-XRand.patch + 0007-xcb-Deliver-mouse-enter-event-to-window-when-closing.patch + 0008-xcb-resourceType-names-must-have-only-small-letters.patch + 0009-Expose-the-number-of-X-screen-through-the-QXcbScreen.patch + 0010-xcb-mark-mouse-events-from-tablet-devices-as-synthes.patch + 0011-xcb-Initialize-all-xcb_client_message_event_t-member.patch + 0012-xcb-Merge-_NET_WM_STATE-hints-instead-of-overwriting.patch + 0013-xcb-Fix-interpretation-of-the-size-from-RRCrtcChange.patch + 0014-xcb-Properly-process-enter-leave-events.patch + 0015-Use-the-state-of-the-key-event-to-process-it.patch + 0016-xcb-Fix-drag-and-drop-to-applications-like-Emacs-and.patch + +------------------------------------------------------------------- +Fri Mar 18 19:03:01 UTC 2016 - hrvoje.senjan@gmail.com + +- Update to 5.6.0 + * For more details please see: + http://blog.qt.io/blog/2016/03/16/qt-5-6-released/ + and https://wiki.qt.io/New_Features_in_Qt_5.6 +- Added patches for various QtDBus issues: + Fix-QtDBus-deadlock-inside-kded-kiod.patch, + QtDBus-clean-up-signal-hooks-and-object-tree-in-closeConnection.patch + and QtDBus-finish-all-pending-call-with-error-if-disconnected.patch +- Added tell-the-truth-about-private-api.patch: mark private and QPA API + with symbols for only current patch release +- Drop obsolete and/or upstreamed patches: + xcb-fix-yet-another-crash-when-screens-are-disconnected.patch, + xcb-dont-crash-in-mapToNativemapFromNative-if-the-screen-is-null.patch, + qtwidgets_do_not-hide_show_via_WA_OutsideWSRange_for_native_widgets.patch, + protect-geometry-QTBUG-40584.patch, + move-the-official-Qt-version-from-qglobal-to-qmake-conf.patch, + QMimeDatabase-follow-symlinks-when-checking-for-FIFO.patch, + Fix-QtCore-compilation-with-clang.patch, + Add-option-to-disable-session-management-by-closing-windows.patch, + Add-an-automatic-use-of-the-ELF-versioned-QtCore-symbol.patch, + Add-a-qt_version_tag-symbol-to-QtCore-that-uses-ELF-versions.patch, + Add-a-linker-version-script-to-Qt-libraries.patch, + 0005-Restore-documented-behavior-for-the-WA_X11NetWmWindo.patch, + 0001-Fix-exclusion-of-anonymous-ciphers.patch and + 0001-Fix-QWidget-setWindowRole.patch + ------------------------------------------------------------------- Wed Mar 9 15:59:46 UTC 2016 - mlin@suse.com diff --git a/libqt5-qtbase.spec b/libqt5-qtbase.spec index 71f49f3..d0dea23 100644 --- a/libqt5-qtbase.spec +++ b/libqt5-qtbase.spec @@ -26,15 +26,15 @@ %endif Name: libqt5-qtbase -Version: 5.5.1 +Version: 5.6.0 Release: 0 Summary: C++ Program Library, Core Components License: GPL-3.0 or SUSE-LGPL-2.1-with-digia-exception-1.1 Group: System/Libraries Url: http://qt.digia.com %define base_name libqt5 -%define real_version 5.5.1 -%define so_version 5.5.1 +%define real_version 5.6.0 +%define so_version 5.6.0 %define tar_version qtbase-opensource-src-%{real_version} Source: %{tar_version}.tar.xz # to get mtime of file: @@ -47,28 +47,32 @@ Source99: libqt5-qtbase-rpmlintrc Patch2: use-freetype-default.patch # PATCH-FIX-SUSE libqt5-Fix-Gujarati-font.patch bnc#878292 fix broken Gujarati font rendering Patch3: libqt5-Fix-Gujarati-font.patch -# PATCH-FIX-UPSTREAM protect-geometry-QTBUG-40584.patch -- https://bugreports.qt-project.org/browse/QTBUG-40584 -Patch4: protect-geometry-QTBUG-40584.patch # Patch-FIX-SUSE libqt5-do-not-use-shm-if-display-name-doesnt-look-local.patch -- bnc#888858 Patch5: libqt5-do-not-use-shm-if-display-name-doesnt-look-local.patch -# PATCH-FIX-UPSTREAM 0001-Fix-exclusion-of-anonymous-ciphers.patch -- Exclude more ciphers from being used by default -Patch6: 0001-Fix-exclusion-of-anonymous-ciphers.patch # PATCH-FIX-OPENSUSE disable-rc4-ciphers-bnc865241.diff bnc#865241-- Exclude rc4 ciphers from being used by default -Patch7: disable-rc4-ciphers-bnc865241.diff -# patches 1000-2000 and above from upstream 5.3 branch # -# patches 2000-3000 and above from upstream 5.5 branch # -Patch2010: 0001-Fix-QWidget-setWindowRole.patch -Patch2014: 0005-Restore-documented-behavior-for-the-WA_X11NetWmWindo.patch -Patch3000: Add-a-linker-version-script-to-Qt-libraries.patch -Patch3001: Add-a-qt_version_tag-symbol-to-QtCore-that-uses-ELF-versions.patch -Patch3002: Fix-QtCore-compilation-with-clang.patch -Patch3003: move-the-official-Qt-version-from-qglobal-to-qmake-conf.patch -Patch3004: Add-an-automatic-use-of-the-ELF-versioned-QtCore-symbol.patch -Patch3005: xcb-fix-yet-another-crash-when-screens-are-disconnected.patch -Patch3006: xcb-dont-crash-in-mapToNativemapFromNative-if-the-screen-is-null.patch -Patch3007: qtwidgets_do_not-hide_show_via_WA_OutsideWSRange_for_native_widgets.patch -Patch3008: Add-option-to-disable-session-management-by-closing-windows.patch -Patch3009: QMimeDatabase-follow-symlinks-when-checking-for-FIFO.patch +Patch6: disable-rc4-ciphers-bnc865241.diff +Patch7: tell-the-truth-about-private-api.patch +# patches 1000-2000 and above from upstream 5.6 branch # +Patch1000: 0001-xcb-XInput2-fixes-enter-leave-event-fixes.patch +Patch1001: 0002-xcb-Correct-enter-leave-event-handling-when-mouse-bu.patch +Patch1002: 0003-xcb-Fix-not-delivering-focusIn-event-on-hide-show.patch +Patch1003: 0004-xcb-Fix-drag-and-drop-between-xcb-screens.patch +Patch1004: 0005-xcb-Properly-initialize-available-geometry-when-XRan.patch +Patch1005: 0006-xcb-properly-initialize-size-in-millimeters-if-XRand.patch +Patch1006: 0007-xcb-Deliver-mouse-enter-event-to-window-when-closing.patch +Patch1007: 0008-xcb-resourceType-names-must-have-only-small-letters.patch +Patch1008: 0009-Expose-the-number-of-X-screen-through-the-QXcbScreen.patch +Patch1009: 0010-xcb-mark-mouse-events-from-tablet-devices-as-synthes.patch +Patch1010: 0011-xcb-Initialize-all-xcb_client_message_event_t-member.patch +Patch1011: 0012-xcb-Merge-_NET_WM_STATE-hints-instead-of-overwriting.patch +Patch1012: 0013-xcb-Fix-interpretation-of-the-size-from-RRCrtcChange.patch +Patch1013: 0014-xcb-Properly-process-enter-leave-events.patch +# patches 2000-3000 and above from upstream 5.7 branch # +Patch3000: Fix-QtDBus-deadlock-inside-kded-kiod.patch +Patch3001: QtDBus-clean-up-signal-hooks-and-object-tree-in-closeConnection.patch +Patch3002: QtDBus-finish-all-pending-call-with-error-if-disconnected.patch +Patch3003: 0015-Use-the-state-of-the-key-event-to-process-it.patch +Patch3004: 0016-xcb-Fix-drag-and-drop-to-applications-like-Emacs-and.patch BuildRequires: alsa-devel BuildRequires: cups-devel BuildRequires: gcc-c++ @@ -109,7 +113,7 @@ BuildRequires: xorg-x11-devel BuildRequires: xz BuildRequires: pkgconfig(glib-2.0) BuildRequires: pkgconfig(gtk+-2.0) -%if 0%{?is_opensuse} || 0%{?suse_version} != 1315 +%if 0%{?is_opensuse} BuildRequires: pkgconfig(harfbuzz) %endif BuildRequires: pkgconfig(ice) @@ -149,25 +153,32 @@ handling. %setup -q -n qtbase-opensource-src-%{real_version} %patch2 -p1 %patch3 -p1 -%patch4 -p1 %patch5 -p1 %patch6 -p1 %patch7 -p1 -%patch2010 -p1 -%patch2014 -p1 +%patch1000 -p1 +%patch1001 -p1 +%patch1002 -p1 +%patch1003 -p1 +%patch1004 -p1 +%patch1005 -p1 +%patch1006 -p1 +%patch1007 -p1 +%patch1008 -p1 +%patch1009 -p1 +%patch1010 -p1 +%patch1011 -p1 +%patch1012 -p1 +%patch1013 -p1 %patch3000 -p1 %patch3001 -p1 %patch3002 -p1 %patch3003 -p1 %patch3004 -p1 -%patch3005 -p1 -%patch3006 -p1 -%patch3007 -p1 -%patch3008 -p1 -%patch3009 -p1 # be sure not to use them rm -r src/3rdparty/{libjpeg,freetype,libpng,zlib} +#rm -r mkspecs/features/qt_module.prf.orig #rm -r qtimageformats/src/3rdparty/{libtiff,libmng} %package devel @@ -175,7 +186,6 @@ Summary: Qt Development Kit Group: Development/Libraries/X11 # External deps shall be found via pkgconfig Requires: %{name}-common-devel -Requires: %{name}-doc = %{version} Requires: libQt5Concurrent-devel = %{version} Requires: libQt5Core-devel = %{version} Requires: libQt5DBus-devel = %{version} @@ -569,15 +579,6 @@ Requires: libQt5Sql-devel = %{version} %description -n libQt5Sql-private-headers-devel Qt 5 SQL Library - Non-ABI stable development files. -%package doc -Summary: Qt 5 tool used by Qt Developers to generate documentation -Group: Development/Libraries/C and C++ -Requires: %{name}-common-devel = %{version} - -%description doc -Qt 5 tool used by Qt Developers to generate documentation for software projects. - - %package private-headers-devel Summary: Non-ABI stable experimental API Group: Development/Libraries/C and C++ @@ -749,7 +750,7 @@ echo yes | ./configure $platform \ -system-libjpeg \ -openssl-linked \ -system-libpng \ -%if 0%{?is_opensuse} || 0%{?suse_version} != 1315 +%if 0%{?is_opensuse} -system-harfbuzz \ %endif -fontconfig \ @@ -895,7 +896,9 @@ popd %{_bindir}/uic* %{libqt5_bindir}/uic* %{_bindir}/syncqt.pl* +%{_bindir}/fixqt4headers.pl* %{libqt5_bindir}/syncqt.pl* +%{libqt5_bindir}/fixqt4headers.pl* %{_bindir}/qlalr* %{libqt5_bindir}/qlalr* %{libqt5_archdatadir}/mkspecs/ @@ -923,6 +926,7 @@ popd %{libqt5_libdir}/pkgconfig/Qt5Core.pc %{libqt5_includedir}/QtCore/ %exclude %{libqt5_includedir}/QtCore/%{so_version} +%{libqt5_docdir} %files -n libQt5Concurrent5 %defattr(-,root,root,755) @@ -1065,7 +1069,7 @@ popd %{libqt5_plugindir}/platforms %{libqt5_plugindir}/egldeviceintegrations %{libqt5_plugindir}/xcbglintegrations -%{libqt5_plugindir}/platformthemes +%{libqt5_plugindir}/platformthemes/ %files -n libQt5Gui-devel %defattr(-,root,root,755) @@ -1121,19 +1125,12 @@ popd %doc *.txt LICENSE.* %{libqt5_plugindir}/sqldrivers/libqsqlmysql*.so -%files doc -%defattr(-,root,root,755) -%doc *.txt LICENSE.* -%{_bindir}/qdoc* -%{libqt5_bindir}/qdoc* -%{libqt5_docdir} - %files -n libQt5Bootstrap-devel-static %defattr(-,root,root,755) %doc *.txt LICENSE.* %{libqt5_libdir}/libQt5Bootstrap.a %{libqt5_libdir}/libQt5Bootstrap.prl -%{libqt5_libdir}/pkgconfig/Qt5Bootstrap.pc +#{libqt5_libdir}/pkgconfig/Qt5Bootstrap.pc %files -n libQt5OpenGLExtensions-devel-static %defattr(-,root,root,755) @@ -1153,9 +1150,9 @@ popd %{libqt5_libdir}/libQt5PlatformSupport.prl %{libqt5_libdir}/libQt5EglDeviceIntegration.prl %{libqt5_libdir}/libQt5XcbQpa.prl -%{libqt5_libdir}/pkgconfig/Qt5PlatformSupport.pc -%{libqt5_libdir}/pkgconfig/Qt5EglDeviceIntegration.pc -%{libqt5_libdir}/pkgconfig/Qt5XcbQpa.pc +#{libqt5_libdir}/pkgconfig/Qt5PlatformSupport.pc +#{libqt5_libdir}/pkgconfig/Qt5EglDeviceIntegration.pc +#{libqt5_libdir}/pkgconfig/Qt5XcbQpa.pc %{libqt5_includedir}/QtPlatformSupport/ %exclude %{libqt5_includedir}/QtPlatformSupport/%{so_version} diff --git a/move-the-official-Qt-version-from-qglobal-to-qmake-conf.patch b/move-the-official-Qt-version-from-qglobal-to-qmake-conf.patch deleted file mode 100644 index 21a1737..0000000 --- a/move-the-official-Qt-version-from-qglobal-to-qmake-conf.patch +++ /dev/null @@ -1,332 +0,0 @@ -From 2d2cb6434f1d6e00f421c98b20467ff3f4388319 Mon Sep 17 00:00:00 2001 -From: Thiago Macieira -Date: Thu, 17 Sep 2015 18:17:40 -0700 -Subject: Move the official Qt version from qglobal.h to .qmake.conf - -It's easier to parse than qglobal.h. The objective is actually to have -macros with parts of the version number, so the major or minor numbers -could be used in other preprocessor macros. - -Change-Id: I42e7ef1a481840699a8dffff1404eda1dd5c308d -Reviewed-by: Oswald Buddenhagen ---- - .qmake.conf | 3 +-- - bin/syncqt.pl | 8 +------- - configure | 37 +++++++++++++++++++++---------------- - configure.bat | 20 ++++++++++++++++++-- - qmake/Makefile.unix | 1 + - qmake/Makefile.win32 | 1 + - src/corelib/global/qglobal.h | 4 ++-- - tools/configure/Makefile.mingw | 2 +- - tools/configure/Makefile.win32 | 2 +- - tools/configure/configureapp.cpp | 37 ++++++++++++++++++++++--------------- - 10 files changed, 69 insertions(+), 46 deletions(-) - -diff --git a/.qmake.conf b/.qmake.conf -index 481544b253daa7a41485c5eeddd6d2ef694a4b70..732b5da2621f2fc821404e7aef3ab7ed576dfc0c 100644 ---- a/.qmake.conf -+++ b/.qmake.conf -@@ -5,5 +5,4 @@ CONFIG += warning_clean - QT_SOURCE_TREE = $$PWD - QT_BUILD_TREE = $$shadowed($$PWD) - --# In qtbase, all modules follow qglobal.h --MODULE_VERSION = $$QT_VERSION -+MODULE_VERSION = 5.5.1 -diff --git a/bin/syncqt.pl b/bin/syncqt.pl -index 3b3e127e86e664185a6b94829ac968673bf75651..c75390c561debf6558a4b7ae4b237b44a7c8f16b 100755 ---- a/bin/syncqt.pl -+++ b/bin/syncqt.pl -@@ -786,6 +786,7 @@ while ( @ARGV ) { - - # if we have no $basedir we cannot be sure which sources you want, so die - die "Could not find any sync.profile for your module!\nPass to syncqt to sync your header files.\nsyncqt failed" if (!$basedir); -+die "The -version argument is mandatory" if (!$module_version); - - our @ignore_headers = (); - our @ignore_for_master_contents = (); -@@ -803,13 +804,6 @@ my %allmoduleheadersprivate = map { $_ => 1 } @allmoduleheadersprivate; - - $isunix = checkUnix; #cache checkUnix - --if (!$module_version) { -- my $filco = fileContents($basedir."/src/corelib/global/qglobal.h"); -- if ($filco !~ m,.*^#[ \t]*define[ \t]+QT_VERSION_STR[ \t]+"([^"]+)".*,sm) { -- die "Cannot determine Qt/Module version. Use -version.\n"; -- } -- $module_version = $1; --} - foreach my $lib (@modules_to_sync) { - die "No such module: $lib" unless(defined $modules{$lib}); - -diff --git a/configure b/configure -index cea62fbc0c46ae54938df282fffbbfde5bf794d6..45c74a61dc04b3cb80452eec22fda6189fc29795 100755 ---- a/configure -+++ b/configure -@@ -539,23 +539,16 @@ fi - #----------------------------------------------------------------------------- - # Qt version detection - #----------------------------------------------------------------------------- --QT_VERSION=`grep '^# *define *QT_VERSION_STR' "$relpath"/src/corelib/global/qglobal.h` -+QT_VERSION= - QT_MAJOR_VERSION= - QT_MINOR_VERSION=0 - QT_PATCH_VERSION=0 --if [ -n "$QT_VERSION" ]; then -- QT_VERSION=`echo $QT_VERSION | sed 's,^# *define *QT_VERSION_STR *"*\([^ ]*\)"$,\1,'` -- MAJOR=`echo $QT_VERSION | sed 's,^\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*,\1,'` -- if [ -n "$MAJOR" ]; then -- MINOR=`echo $QT_VERSION | sed 's,^\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*,\2,'` -- PATCH=`echo $QT_VERSION | sed 's,^\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*,\3,'` -- QT_MAJOR_VERSION="$MAJOR" -- [ -z "$MINOR" ] || QT_MINOR_VERSION="$MINOR" -- [ -z "$PATCH" ] || QT_PATCH_VERSION="$PATCH" -- fi --fi -+eval `sed -n -e 's/^MODULE_VERSION = \(\([0-9]*\)\.\([0-9]*\)\.\([0-9]*\).*\)$/QT_VERSION=\1\ -+ QT_MAJOR_VERSION=\2\ -+ QT_MINOR_VERSION=\3\ -+ QT_PATCH_VERSION=\4/p' < "$relpath"/.qmake.conf` - if [ -z "$QT_MAJOR_VERSION" ]; then -- echo "Cannot process version from qglobal.h: $QT_VERSION" -+ echo "Cannot process version from .qmake.conf" - echo "Cannot proceed." - exit 1 - fi -@@ -3896,7 +3889,7 @@ if [ -e "$relpath/.git" ]; then - exit 1 - fi - -- "$relpath/bin/syncqt.pl" -minimal -module QtCore "$relpath" || exit 1 -+ "$relpath/bin/syncqt.pl" -version $QT_VERSION -minimal -module QtCore "$relpath" || exit 1 - fi - - # $1: input variable name (awk regexp) -@@ -4038,6 +4031,9 @@ if true; then ###[ '!' -f "$outpath/bin/qmake" ]; - fi - echo "QMAKESPEC = $adjqmakespec" >> "$mkfile" - echo "QT_VERSION = $QT_VERSION" >> "$mkfile" -+ echo "QT_MAJOR_VERSION = $QT_MAJOR_VERSION" >> "$mkfile" -+ echo "QT_MINOR_VERSION = $QT_MINOR_VERSION" >> "$mkfile" -+ echo "QT_PATCH_VERSION = $QT_PATCH_VERSION" >> "$mkfile" - echo "EXTRA_CFLAGS = $EXTRA_CFLAGS" >> "$mkfile" - echo "EXTRA_CXXFLAGS = $EXTRA_CXXFLAGS" >> "$mkfile" - echo "QTOBJS =" $EXTRA_OBJS >> "$mkfile" -@@ -6514,13 +6510,22 @@ esac - # part of configuration information goes into qconfig.h - #------------------------------------------------------------------------------- - -+# start with Qt's version number -+cat > "$outpath/src/corelib/global/qconfig.h.new" <"$outpath/src/corelib/global/qconfig.h.new" -+ echo "/* Everything */" >>"$outpath/src/corelib/global/qconfig.h.new" - ;; - *) - tmpconfig="$outpath/src/corelib/global/qconfig.h.new" -- echo "#ifndef QT_BOOTSTRAPPED" >"$tmpconfig" -+ echo "#ifndef QT_BOOTSTRAPPED" >>"$tmpconfig" - cat "$CFG_QCONFIG_PATH" >>"$tmpconfig" - echo "#endif" >>"$tmpconfig" - ;; -diff --git a/configure.bat b/configure.bat -index 1220bfedc2de5ad78edbd636f4af7e39dbfde27b..47acf26d6278d43e70d3d6369a4f1cf06b3a57f7 100644 ---- a/configure.bat -+++ b/configure.bat -@@ -34,6 +34,7 @@ - @echo off - set QTSRC=%~dp0 - set QTDIR=%CD% -+ - if not exist %QTSRC%.gitignore goto sconf - echo Please wait while bootstrapping configure ... - -@@ -47,7 +48,18 @@ if not exist mkspecs ( - md mkspecs - if errorlevel 1 goto exit - ) --perl %QTSRC%bin\syncqt.pl -minimal -module QtCore -outdir "%QTDIR%" %QTSRC% -+ -+rem Extract Qt's version from .qmake.conf -+for /f "eol=# tokens=1,2,3,4 delims=.= " %%i in (%QTSRC%.qmake.conf) do ( -+ if %%i == MODULE_VERSION ( -+ set QTVERMAJ=%%j -+ set QTVERMIN=%%k -+ set QTVERPAT=%%l -+ ) -+) -+set QTVERSION=%QTVERMAJ%.%QTVERMIN%.%QTVERPAT% -+ -+perl %QTSRC%bin\syncqt.pl -minimal -version %QTVERSION% -module QtCore -outdir "%QTDIR%" %QTSRC% - if errorlevel 1 goto exit - - if not exist tools\configure ( -@@ -62,7 +74,11 @@ if not "%jom.exe%" == "" set make=jom - - echo #### Generated by configure.bat - DO NOT EDIT! ####> Makefile - echo/>> Makefile --for /f "tokens=3 usebackq" %%V in (`findstr QT_VERSION_STR %QTSRC%src\corelib\global\qglobal.h`) do @echo QTVERSION = %%~V>> Makefile -+echo QTVERSION = %QTVERSION%>> Makefile -+rem These must have trailing spaces to avoid misinterpretation as 5>>, etc. -+echo QT_VERSION_MAJOR = %QTVERMAJ% >> Makefile -+echo QT_VERSION_MINOR = %QTVERMIN% >> Makefile -+echo QT_VERSION_PATCH = %QTVERPAT% >> Makefile - if not "%icl.exe%" == "" ( - echo CXX = icl>>Makefile - echo EXTRA_CXXFLAGS = /Zc:forScope>>Makefile -diff --git a/qmake/Makefile.unix b/qmake/Makefile.unix -index 86f884fe209195d814e8037fd8e9352e3e585ad0..d2d7bf7e6327fa57576c5dfe803c335ef4b965ca 100644 ---- a/qmake/Makefile.unix -+++ b/qmake/Makefile.unix -@@ -101,6 +101,7 @@ CPPFLAGS = -g $(EXTRA_CPPFLAGS) \ - -I$(BUILD_PATH)/src/corelib/global -DHAVE_QCONFIG_CPP \ - -I$(QMAKESPEC) \ - -I$(SOURCE_PATH)/tools/shared \ -+ -DQT_VERSION_STR=\"$(QT_VERSION)\" -DQT_VERSION_MAJOR=$(QT_MAJOR_VERSION) -DQT_VERSION_MINOR=$(QT_MINOR_VERSION) -DQT_VERSION_PATCH=$(QT_PATCH_VERSION) \ - -DQT_BUILD_QMAKE -DQT_BOOTSTRAPPED -DPROEVALUATOR_FULL \ - -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_NO_COMPONENT -DQT_NO_COMPRESS \ - -DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -DQT_NO_DATASTREAM \ -diff --git a/qmake/Makefile.win32 b/qmake/Makefile.win32 -index 9dda6ca1e7b7399e6179732b677824d624e745d0..fdbb9c8499a78a980cf3e0a7900567320aae9676 100644 ---- a/qmake/Makefile.win32 -+++ b/qmake/Makefile.win32 -@@ -36,6 +36,7 @@ CFLAGS_BARE = -c -Fo./ -Fdqmake.pdb \ - -I$(BUILD_PATH)\src\corelib\global -DHAVE_QCONFIG_CPP \ - -I$(SOURCE_PATH)\mkspecs\$(QMAKESPEC) \ - -I$(SOURCE_PATH)\tools\shared \ -+ -DQT_VERSION_STR=\"$(QT_VERSION)\" -DQT_VERSION_MAJOR=$(QT_MAJOR_VERSION) -DQT_VERSION_MINOR=$(QT_MINOR_VERSION) -DQT_VERSION_PATCH=$(QT_PATCH_VERSION) \ - -DQT_BUILD_QMAKE -DQT_BOOTSTRAPPED -DPROEVALUATOR_FULL \ - -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_NO_COMPONENT -DQT_NO_COMPRESS \ - -DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -DQT_NO_DATASTREAM \ -diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h -index 97c5f37cab02c35bfdb75ec8ab58b97dc0a6b1de..15d9b6536a9f1ee85371fea6dc9115438eec32d1 100644 ---- a/src/corelib/global/qglobal.h -+++ b/src/corelib/global/qglobal.h -@@ -41,11 +41,10 @@ - - #include - --#define QT_VERSION_STR "5.5.1" - /* - QT_VERSION is (major << 16) + (minor << 8) + patch. - */ --#define QT_VERSION 0x050501 -+#define QT_VERSION QT_VERSION_CHECK(QT_VERSION_MAJOR, QT_VERSION_MINOR, QT_VERSION_PATCH) - /* - can be used like #if (QT_VERSION >= QT_VERSION_CHECK(4, 4, 0)) - */ -@@ -55,6 +54,7 @@ - #include - #include - #endif -+ - #ifdef _MSC_VER - # define QT_SUPPORTS(FEATURE) (!defined QT_NO_##FEATURE) - #else -diff --git a/tools/configure/Makefile.mingw b/tools/configure/Makefile.mingw -index 9ac99fd678f46445771147d80542e9bba3b37acf..6ec77c8ab511c4375711964fbb41e9a817decf2e 100644 ---- a/tools/configure/Makefile.mingw -+++ b/tools/configure/Makefile.mingw -@@ -4,7 +4,7 @@ CONFSRC = $(TOOLSRC)/configure - - RAW_PCH = configure_pch.h - PCH = $(RAW_PCH).gch/c++ --DEFINES = -DUNICODE -DQT_NO_DATASTREAM -DQT_NO_CODECS -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT -DQT_NO_COMPRESS -DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -D_CRT_SECURE_NO_DEPRECATE -DQT_BOOTSTRAPPED -DQT_BUILD_CONFIGURE -+DEFINES = -DUNICODE -DQT_NO_DATASTREAM -DQT_NO_CODECS -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT -DQT_NO_COMPRESS -DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -D_CRT_SECURE_NO_DEPRECATE -DQT_BOOTSTRAPPED -DQT_BUILD_CONFIGURE -DQT_VERSION_STR=\"$(QTVERSION)\" -DQT_VERSION_MAJOR=$(QT_VERSION_MAJOR) -DQT_VERSION_MINOR=$(QT_VERSION_MINOR) -DQT_VERSION_PATCH=$(QT_VERSION_PATCH) - INCPATH = -I"../../include" -I"../../include/QtCore" -I"../../include/QtCore/$(QTVERSION)" -I"../../include/QtCore/$(QTVERSION)/QtCore" -I"$(TOOLSRC)/shared" -I"$(QTSRC)mkspecs/win32-g++" - CXXFLAGS_BARE = -fno-rtti -fno-exceptions -mthreads -Wall -Wextra $(DEFINES) $(INCPATH) - CXXFLAGS = -include $(RAW_PCH) $(CXXFLAGS_BARE) -diff --git a/tools/configure/Makefile.win32 b/tools/configure/Makefile.win32 -index 8c6d213e4243b444357712cf6c0d8d4dcfa3ff36..456e441c6f548bc3e3c0ac0a8847bf965aeb5902 100644 ---- a/tools/configure/Makefile.win32 -+++ b/tools/configure/Makefile.win32 -@@ -3,7 +3,7 @@ TOOLSRC = $(QTSRC)tools - CONFSRC = $(TOOLSRC)\configure - - PCH = configure_pch.pch --DEFINES = -DUNICODE -DQT_NO_CODECS -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT -DQT_NO_COMPRESS -DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -D_CRT_SECURE_NO_DEPRECATE -DQT_BOOTSTRAPPED -DQT_BUILD_CONFIGURE -+DEFINES = -DUNICODE -DQT_NO_CODECS -DQT_NO_TEXTCODEC -DQT_NO_UNICODETABLES -DQT_LITE_COMPONENT -DQT_NO_COMPRESS -DQT_NO_THREAD -DQT_NO_QOBJECT -DQT_NO_GEOM_VARIANT -D_CRT_SECURE_NO_DEPRECATE -DQT_BOOTSTRAPPED -DQT_BUILD_CONFIGURE -DQT_VERSION_STR=\"$(QTVERSION)\" -DQT_VERSION_MAJOR=$(QT_VERSION_MAJOR) -DQT_VERSION_MINOR=$(QT_VERSION_MINOR) -DQT_VERSION_PATCH=$(QT_VERSION_PATCH) - INCPATH = -I"..\..\include" -I"..\..\include\QtCore" -I"..\..\include\QtCore\$(QTVERSION)" -I"..\..\include\QtCore\$(QTVERSION)\QtCore" -I"$(TOOLSRC)\shared" -I"$(QTSRC)mkspecs\win32-msvc2008" - CXXFLAGS_BARE = -nologo -Zc:wchar_t -W3 -GR -EHsc -w34100 -w34189 $(CFLAGS_CRT) $(EXTRA_CXXFLAGS) $(DEFINES) $(INCPATH) - CXXFLAGS = -FIconfigure_pch.h -Yuconfigure_pch.h -Fp$(PCH) -MP $(CXXFLAGS_BARE) -diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp -index 3bf0546ac1628e8ab51979526bb102d1e8db8de8..36cc8b03cd24ddb5d01d85fc57254059e76a49da 100644 ---- a/tools/configure/configureapp.cpp -+++ b/tools/configure/configureapp.cpp -@@ -197,20 +197,18 @@ Configure::Configure(int& argc, char** argv) - dictionary[ "QT_INSTALL_SETTINGS" ] = "/etc/xdg"; - - QString version; -- QFile qglobal_h(sourcePath + "/src/corelib/global/qglobal.h"); -- if (qglobal_h.open(QFile::ReadOnly)) { -- QTextStream read(&qglobal_h); -- QRegExp version_regexp("^# *define *QT_VERSION_STR *\"([^\"]*)\""); -- QString line; -- while (!read.atEnd()) { -- line = read.readLine(); -- if (version_regexp.exactMatch(line)) { -- version = version_regexp.cap(1).trimmed(); -- if (!version.isEmpty()) -- break; -- } -+ QFile qmake_conf(sourcePath + "/.qmake.conf"); -+ if (qmake_conf.open(QFile::ReadOnly)) { -+ while (!qmake_conf.atEnd()) { -+ static const char beginning[] = "MODULE_VERSION = "; -+ QByteArray line = qmake_conf.readLine(); -+ if (!line.startsWith(beginning)) -+ continue; -+ -+ version = qMove(line).mid(int(strlen(beginning))).trimmed(); -+ break; - } -- qglobal_h.close(); -+ qmake_conf.close(); - } - - if (version.isEmpty()) -@@ -3540,6 +3538,12 @@ void Configure::generateConfigfiles() - { - FileWriter tmpStream(buildPath + "/src/corelib/global/qconfig.h"); - -+ tmpStream << "#define QT_VERSION_MAJOR " << dictionary["VERSION_MAJOR"] << endl -+ << "#define QT_VERSION_MINOR " << dictionary["VERSION_MINOR"] << endl -+ << "#define QT_VERSION_PATCH " << dictionary["VERSION_PATCH"] << endl -+ << "#define QT_VERSION_STR \"" << dictionary["VERSION"] << "\"\n" -+ << endl; -+ - if (dictionary[ "QCONFIG" ] == "full") { - tmpStream << "/* Everything */" << endl; - } else { -@@ -3939,7 +3943,7 @@ void Configure::generateHeaders() - QStringList args; - args << "perl" << "-w"; - args += sourcePath + "/bin/syncqt.pl"; -- args << "-minimal" << "-module" << "QtCore"; -+ args << "-version" << dictionary["VERSION"] << "-minimal" << "-module" << "QtCore"; - args += sourcePath; - int retc = Environment::execute(args, QStringList(), QStringList()); - if (retc) { -@@ -4202,7 +4206,10 @@ void Configure::buildQmake() - << "INC_PATH = " << QDir::toNativeSeparators( - (QFile::exists(sourcePath + "/.git") ? ".." : sourcePath) - + "/include") << endl; -- stream << "QT_VERSION = " << dictionary["VERSION"] << endl; -+ stream << "QT_VERSION = " << dictionary["VERSION"] << endl -+ << "QT_MAJOR_VERSION = " << dictionary["VERSION_MAJOR"] << endl -+ << "QT_MINOR_VERSION = " << dictionary["VERSION_MINOR"] << endl -+ << "QT_PATCH_VERSION = " << dictionary["VERSION_PATCH"] << endl; - if (dictionary[ "QMAKESPEC" ] == QString("win32-g++")) { - stream << "QMAKESPEC = $(SOURCE_PATH)\\mkspecs\\win32-g++" << endl - << "EXTRA_CFLAGS = -DUNICODE -ffunction-sections" << endl --- -2.6.0 - diff --git a/protect-geometry-QTBUG-40584.patch b/protect-geometry-QTBUG-40584.patch deleted file mode 100644 index 845bf1a..0000000 --- a/protect-geometry-QTBUG-40584.patch +++ /dev/null @@ -1,19 +0,0 @@ -diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp -index 35a526e..d417e41 100644 ---- a/src/widgets/kernel/qwidgetwindow.cpp -+++ b/src/widgets/kernel/qwidgetwindow.cpp -@@ -573,6 +573,14 @@ bool QWidgetWindow::updatePos() - void QWidgetWindow::updateMargins() - { - const QMargins margins = frameMargins(); -+ -+ if (geometry().x() != m_widget->data->crect.x() || -+ geometry().y() != m_widget->data->crect.y()) -+ m_widget->setAttribute(Qt::WA_Moved); -+ if (geometry().width() != m_widget->data->crect.width() || -+ geometry().height() != m_widget->data->crect.height()) -+ m_widget->setAttribute(Qt::WA_Resized); -+ - QTLWExtra *te = m_widget->d_func()->topData(); - te->posIncludesFrame= false; - te->frameStrut.setCoords(margins.left(), margins.top(), margins.right(), margins.bottom()); diff --git a/qtbase-opensource-src-5.5.1.tar.xz b/qtbase-opensource-src-5.5.1.tar.xz deleted file mode 100644 index a14ab2e..0000000 --- a/qtbase-opensource-src-5.5.1.tar.xz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:dfa4e8a4d7e4c6b69285e7e8833eeecd819987e1bdbe5baa6b6facd4420de916 -size 46389212 diff --git a/qtbase-opensource-src-5.6.0.tar.xz b/qtbase-opensource-src-5.6.0.tar.xz new file mode 100644 index 0000000..c3ca375 --- /dev/null +++ b/qtbase-opensource-src-5.6.0.tar.xz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6efa8a5c559e92b2e526d48034e858023d5fd3c39115ac1bfd3bb65834dbd67a +size 46757096 diff --git a/qtwidgets_do_not-hide_show_via_WA_OutsideWSRange_for_native_widgets.patch b/qtwidgets_do_not-hide_show_via_WA_OutsideWSRange_for_native_widgets.patch deleted file mode 100644 index f03806d..0000000 --- a/qtwidgets_do_not-hide_show_via_WA_OutsideWSRange_for_native_widgets.patch +++ /dev/null @@ -1,32 +0,0 @@ -From acb4f5cfb5efa053dd2d5dcd6490d610bb1f8c0e Mon Sep 17 00:00:00 2001 -From: Ulf Hermann -Date: Tue, 27 Oct 2015 15:25:42 +0100 -Subject: [PATCH] QtWidgets: Do hide/show via WA_OutsideWSRange for native - widgets - -If a native widget has a width or height of 0 we don't have to -invalidate its backing store as that is done by the window -system. Certain applications rely on ... interesting ... behavior -of certain window systems in this case. - -Task-number: QTBUG-48321 -Change-Id: I78ef29975181ee22429c9bd4b11d96d9e68b7a9c ---- - src/widgets/kernel/qwidget.cpp | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp -index 7734715..4286130 100644 ---- a/src/widgets/kernel/qwidget.cpp -+++ b/src/widgets/kernel/qwidget.cpp -@@ -7169,7 +7169,7 @@ void QWidgetPrivate::setGeometry_sys(int x, int y, int w, int h, bool isMove) - - bool needsShow = false; - -- if (q->isWindow()) { -+ if (q->isWindow() || q->windowHandle()) { - if (!(data.window_state & Qt::WindowFullScreen) && (w == 0 || h == 0)) { - q->setAttribute(Qt::WA_OutsideWSRange, true); - if (q->isVisible() && q->testAttribute(Qt::WA_Mapped)) --- -2.1.4 diff --git a/tell-the-truth-about-private-api.patch b/tell-the-truth-about-private-api.patch new file mode 100644 index 0000000..432ec26 --- /dev/null +++ b/tell-the-truth-about-private-api.patch @@ -0,0 +1,39 @@ +diff --git a/mkspecs/features/qt_module.prf b/mkspecs/features/qt_module.prf +index aefd3ae..53a3f60 100644 +--- a/mkspecs/features/qt_module.prf ++++ b/mkspecs/features/qt_module.prf +@@ -195,16 +195,18 @@ + + !header_module:unix:!isEmpty(QMAKE_LFLAGS_VERSION_SCRIPT):!no_linker_version_script:!static { + verscript = $${TARGET}.version + QMAKE_LFLAGS += $${QMAKE_LFLAGS_VERSION_SCRIPT}$$verscript + ++ private_api_headers = $$SYNCQT.PRIVATE_HEADER_FILES $$SYNCQT.QPA_HEADER_FILES ++ + internal_module { +- verscript_content = "Qt_$${QT_MAJOR_VERSION}_PRIVATE_API { *; };" ++ verscript_content = "Qt_$${QT_MAJOR_VERSION}.$${QT_MINOR_VERSION}.$${QT_PATCH_VERSION}_PRIVATE_API { *; };" + } else { +- verscript_content = "Qt_$${QT_MAJOR_VERSION}_PRIVATE_API {" \ ++ verscript_content = "Qt_$${QT_MAJOR_VERSION}.$${QT_MINOR_VERSION}.$${QT_PATCH_VERSION}_PRIVATE_API {" \ + " qt_private_api_tag*;" +- for(header, SYNCQT.PRIVATE_HEADER_FILES): \ ++ for(header, private_api_headers): \ + verscript_content += " @FILE:$${_PRO_FILE_PWD_}/$$header@" + verscript_content += "};" + + current = Qt_$$QT_MAJOR_VERSION + verscript_content += "$$current { *; };" +@@ -221,11 +223,11 @@ + # Add a post-processing step to replace the @FILE:filename@ + verscript_in = $${verscript}.in + verscriptprocess.name = linker version script ${QMAKE_FILE_BASE} + verscriptprocess.input = verscript_in + verscriptprocess.CONFIG += no_link target_predeps +- for(header, SYNCQT.PRIVATE_HEADER_FILES): \ ++ for(header, private_api_headers)): \ + verscriptprocess.depends += $${_PRO_FILE_PWD_}/$$header + verscriptprocess.output = $$verscript + verscriptprocess.commands = perl $${PWD}/data/unix/findclasslist.pl < ${QMAKE_FILE_IN} > $@ + silent:verscriptprocess.commands = @echo creating linker version script ${QMAKE_FILE_BASE} && $$verscriptprocess.commands + QMAKE_EXTRA_COMPILERS += verscriptprocess diff --git a/xcb-dont-crash-in-mapToNativemapFromNative-if-the-screen-is-null.patch b/xcb-dont-crash-in-mapToNativemapFromNative-if-the-screen-is-null.patch deleted file mode 100644 index 40b28f6..0000000 --- a/xcb-dont-crash-in-mapToNativemapFromNative-if-the-screen-is-null.patch +++ /dev/null @@ -1,57 +0,0 @@ -From c2dd0bb2c7a0468abefb9556dead85456daa851f Mon Sep 17 00:00:00 2001 -From: Shawn Rutledge -Date: Fri, 4 Sep 2015 14:25:15 +0200 -Subject: [PATCH] xcb: don't crash in mapToNative/mapFromNative if the screen - is null - -The results will be wrong, but it only happens in rare cases anyway. - -Task-number: QTBUG-42985 -Task-number: QTBUG-47385 -Change-Id: I6438f219f175af2b118e6b3af16b5b626136defa ---- - src/plugins/platforms/xcb/qxcbwindow.cpp | 8 ++++++++ - 1 file changed, 8 insertions(+) - -diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp -index 4fdebe1..3b589d2 100644 ---- a/src/plugins/platforms/xcb/qxcbwindow.cpp -+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp -@@ -179,6 +179,8 @@ QXcbScreen *QXcbWindow::parentScreen() - - QPoint QXcbWindow::mapToNative(const QPoint &pos, const QXcbScreen *screen) const - { -+ if (!screen) -+ return pos; - if (parent()) - return pos * int(screen->devicePixelRatio()); - else -@@ -186,6 +188,8 @@ QPoint QXcbWindow::mapToNative(const QPoint &pos, const QXcbScreen *screen) cons - } - QPoint QXcbWindow::mapFromNative(const QPoint &pos, const QXcbScreen *screen) const - { -+ if (!screen) -+ return pos; - if (parent()) - return pos / int(screen->devicePixelRatio()); - else -@@ -193,6 +197,8 @@ QPoint QXcbWindow::mapFromNative(const QPoint &pos, const QXcbScreen *screen) co - } - QRect QXcbWindow::mapToNative(const QRect &rect, const QXcbScreen *screen) const - { -+ if (!screen) -+ return rect; - if (parent()) - return mapLocalGeometryToNative(rect, int(screen->devicePixelRatio())); - else -@@ -200,6 +206,8 @@ QRect QXcbWindow::mapToNative(const QRect &rect, const QXcbScreen *screen) const - } - QRect QXcbWindow::mapFromNative(const QRect &rect, const QXcbScreen *screen) const - { -+ if (!screen) -+ return rect; - if (parent()) - return mapLocalGeometryFromNative(rect, int(screen->devicePixelRatio())); - else --- -2.3.5 diff --git a/xcb-fix-yet-another-crash-when-screens-are-disconnected.patch b/xcb-fix-yet-another-crash-when-screens-are-disconnected.patch deleted file mode 100644 index 79fcdb3..0000000 --- a/xcb-fix-yet-another-crash-when-screens-are-disconnected.patch +++ /dev/null @@ -1,36 +0,0 @@ -From d72da0b4b2ee089156d1bd614523838b1635bbf5 Mon Sep 17 00:00:00 2001 -From: Shawn Rutledge -Date: Fri, 4 Sep 2015 13:27:48 +0200 -Subject: [PATCH] xcb: fix yet another crash when screens are disconnected - -Can't assume that m_screens is not an empty list. - -Task-number: QTBUG-42985 -Change-Id: I6f9422638c219123dc898813910d03c7afbd1450 -Reviewed-by: Uli Schlachter -Reviewed-by: Laszlo Agocs ---- - src/plugins/platforms/xcb/qxcbconnection.cpp | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp -index f65437f..c35b019 100644 ---- a/src/plugins/platforms/xcb/qxcbconnection.cpp -+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp -@@ -1300,10 +1300,12 @@ void QXcbConnection::sendConnectionEvent(QXcbAtom::Atom a, uint id) - memset(&event, 0, sizeof(event)); - - const xcb_window_t eventListener = xcb_generate_id(m_connection); -+ xcb_screen_iterator_t it = xcb_setup_roots_iterator(m_setup); -+ xcb_screen_t *screen = it.data; - Q_XCB_CALL(xcb_create_window(m_connection, XCB_COPY_FROM_PARENT, -- eventListener, m_screens.at(0)->root(), -+ eventListener, screen->root, - 0, 0, 1, 1, 0, XCB_WINDOW_CLASS_INPUT_ONLY, -- m_screens.at(0)->screen()->root_visual, 0, 0)); -+ screen->root_visual, 0, 0)); - - event.response_type = XCB_CLIENT_MESSAGE; - event.format = 32; --- -2.3.5