1
0
forked from pool/libqt5-qtbase

Accepting request 391423 from KDE:Qt5

Update to 5.6.0 + xcb fixes

OBS-URL: https://build.opensuse.org/request/show/391423
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/libqt5-qtbase?expand=0&rev=53
This commit is contained in:
Dominique Leuenberger 2016-05-17 15:06:30 +00:00 committed by Git OBS Bridge
parent da241e83a4
commit 26d10f1197
38 changed files with 2805 additions and 1629 deletions

View File

@ -1,165 +0,0 @@
From 5944a751857de997ee674a90c2e35ff3adaa655b Mon Sep 17 00:00:00 2001
From: Alexander Volkov <a.volkov@rusbitech.ru>
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<SetWmWindowRole>(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<QXcbWindow *>(window->handle())->setWmWindowType(windowTypes, window->flags());
}
+void QXcbWindow::setWmWindowRoleStatic(QWindow *window, const QByteArray &role)
+{
+ if (window->handle())
+ static_cast<QXcbWindow *>(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

View File

@ -1,35 +0,0 @@
From 479e84dcbd0d7f1333105c495d7931f1bef3e63b Mon Sep 17 00:00:00 2001
From: "Richard J. Moore" <rich@kde.org>
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 <peter-qt@hartmann.tk>
---
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

View File

@ -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?= <spaz16@wp.pl>
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 <laszlo.agocs@theqtcompany.com>
Reviewed-by: Shawn Rutledge <shawn.rutledge@theqtcompany.com>
(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<int> 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<xXIGenericDeviceEvent *>(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<xXIDeviceEvent *>(event);
eventListener = windowEventListenerFromId(xiDeviceEvent->event);
- if (eventListener) {
- long result = 0;
- if (eventListener->handleGenericEvent(reinterpret_cast<xcb_generic_event_t *>(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<xXIEnterEvent *>(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<xcb_generic_event_t *>(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<int, ScrollingDevice>::iterator it = m_scrollingDevices.begin();
const QHash<int, ScrollingDevice>::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<xXIModifierInfo *>(modInfo);
xXIGroupInfo *group = static_cast<xXIGroupInfo *>(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<xXIDeviceEvent *>(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<xXIEnterEvent *>(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

View File

@ -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?= <spaz16@wp.pl>
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 <shawn.rutledge@theqtcompany.com>
(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

View File

@ -0,0 +1,98 @@
From f371c645e2a06234355693551e16d69961839ac1 Mon Sep 17 00:00:00 2001
From: Alexander Bersenev <bay@hackerdom.ru>
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 <aha_1980@gmx.de>
Reviewed-by: Lisandro Damián Nicanor Pérez Meyer <perezmeyer@gmail.com>
Reviewed-by: Shawn Rutledge <shawn.rutledge@theqtcompany.com>
(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

View File

@ -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?= <spaz16@wp.pl>
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 <Friedemann.Kleint@theqtcompany.com>
Reviewed-by: Shawn Rutledge <shawn.rutledge@theqtcompany.com>
(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<QPlatformScreen*>(screen)->screen(), deviceIndependentPos);
+ if (connection()->mouseGrabber() == Q_NULLPTR)
+ shapedPixmapWindow()->setMouseGrabEnabled(true);
+
current_virtual_desktop = virtualDesktop;
} else {
QBasicDrag::moveShapedPixmapWindow(deviceIndependentPos);
--
2.6.6

View File

@ -1,116 +0,0 @@
From 5e5031527a3b443c93bf9e762c2f47e6786d7a31 Mon Sep 17 00:00:00 2001
From: Alexander Volkov <a.volkov@rusbitech.ru>
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<QWidget*>(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<QXcbWindowFunctions::WmWindowType>(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

View File

@ -0,0 +1,35 @@
From bbfc5818bb9f8d87d64f6b6f94bbfe1cea199ec9 Mon Sep 17 00:00:00 2001
From: Alexander Volkov <a.volkov@rusbitech.ru>
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ł <spaz16@wp.pl>
Reviewed-by: Shawn Rutledge <shawn.rutledge@theqtcompany.com>
(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

View File

@ -0,0 +1,42 @@
From 412a0b8502614ff6fac6b6b45c48091a19d67014 Mon Sep 17 00:00:00 2001
From: Shawn Rutledge <shawn.rutledge@digia.com>
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ł <spaz16@wp.pl>
Reviewed-by: Shawn Rutledge <shawn.rutledge@theqtcompany.com>
(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<xcb_get_window_attributes_reply_t, QScopedPointerPodDeleter> rootAttribs(
--
2.6.6

View File

@ -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?= <spaz16@wp.pl>
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 <shawn.rutledge@theqtcompany.com>
(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 <qpa/qplatformintegration.h>
+#include <qpa/qplatformcursor.h>
#include <algorithm>
@@ -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<QWindow *>(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

View File

@ -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?= <spaz16@wp.pl>
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 <shawn.rutledge@theqtcompany.com>
(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

View File

@ -0,0 +1,153 @@
From fd6049144e0ba5b4696798eadd84da021438d050 Mon Sep 17 00:00:00 2001
From: Alexander Volkov <a.volkov@rusbitech.ru>
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 <shawn.rutledge@theqtcompany.com>
(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 <QtPlatformHeaders/QPlatformHeaderHelper>
+
+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<int, VirtualDesktopNumber, const QScreen *>(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 <QtPlatformHeaders/qxcbwindowfunctions.h>
#include <QtPlatformHeaders/qxcbintegrationfunctions.h>
+#include <QtPlatformHeaders/qxcbscreenfunctions.h>
#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<const QXcbScreen *>(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

View File

@ -0,0 +1,199 @@
From c44d853fd7e71eff0e1a1d4512c2215a1e701008 Mon Sep 17 00:00:00 2001
From: Shawn Rutledge <shawn.rutledge@digia.com>
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 <laszlo.agocs@theqtcompany.com>
(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<xcb_ge_event_t *>(event));
+ eventListener->handleXIMouseEvent(reinterpret_cast<xcb_ge_event_t *>(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 <QtDebug>
+#include <QMetaEnum>
#include <QScreen>
#include <QtGui/QIcon>
#include <QtGui/QRegion>
@@ -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<xXIDeviceEvent *>(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

View File

@ -0,0 +1,142 @@
From 3c8b9236ed7a0b1284922097da875cc8baa1bb78 Mon Sep 17 00:00:00 2001
From: Shawn Rutledge <shawn.rutledge@theqtcompany.com>
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 <orgads@gmail.com>
(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

View File

@ -0,0 +1,71 @@
From cc32b65569c3cd947a7d012d41379490c9bf80c0 Mon Sep 17 00:00:00 2001
From: David Rosca <nowrep@gmail.com>
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 <shawn.rutledge@theqtcompany.com>
Reviewed-by: Uli Schlachter <psychon@znc.in>
(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<xcb_atom_t> 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<const xcb_atom_t *>(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

View File

@ -0,0 +1,43 @@
From a148affea7763395ce503f695ddb6c7b4c1e4b08 Mon Sep 17 00:00:00 2001
From: Alexander Volkov <a.volkov@rusbitech.ru>
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 <daniel.vratil@kdab.com>
Reviewed-by: Laszlo Agocs <laszlo.agocs@theqtcompany.com>
(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

View File

@ -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?= <spaz16@wp.pl>
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 <mitya57@gmail.com>
Reviewed-by: Laszlo Agocs <laszlo.agocs@theqtcompany.com>
Reviewed-by: Shawn Rutledge <shawn.rutledge@theqtcompany.com>
(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

View File

@ -0,0 +1,149 @@
From d7be69c973623e76deff3fa00354927946b21c66 Mon Sep 17 00:00:00 2001
From: Albert Astals Cid <aacid@kde.org>
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

View File

@ -0,0 +1,92 @@
From 7c3b3375b2d54ef1965c32131123a9becfa27f98 Mon Sep 17 00:00:00 2001
From: Urs Fleisch <ufleisch@users.sourceforge.net>
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

View File

@ -1,110 +0,0 @@
From 38c28ad2420542d795a27c5359226260c886b112 Mon Sep 17 00:00:00 2001
From: Thiago Macieira <thiago.macieira@intel.com>
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

View File

@ -1,125 +0,0 @@
From c665b0ce8c663030b856073262bd2ce30347bd7b Mon Sep 17 00:00:00 2001
From: Thiago Macieira <thiago.macieira@intel.com>
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

View File

@ -1,142 +0,0 @@
From bdb8ab0690eb927575de6f3e34d2b49a148e046f Mon Sep 17 00:00:00 2001
From: Thiago Macieira <thiago.macieira@intel.com>
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 <QtCore/qatomic.h>
#include <QtCore/qglobalstatic.h>
#include <QtCore/qnumeric.h>
+#include <QtCore/qversiontagging.h>
#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 <QtCore/qglobal.h>
+
+#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

View File

@ -1,207 +0,0 @@
From e7bf0edfd49de9a4d8285fbe8d878f8fda910e6d Mon Sep 17 00:00:00 2001
From: Andreas Hartmetz <ahartmetz@gmail.com>
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 <oswald.buddenhagen@theqtcompany.com>
Reviewed-by: David Faure <david.faure@kdab.com>
---
.../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<QObject *> 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

View File

@ -1,102 +0,0 @@
From 4c738356ee4f20b6414e43a1cd73817f7eb28dd1 Mon Sep 17 00:00:00 2001
From: Thiago Macieira <thiago.macieira@intel.com>
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 <lars.knoll@theqtcompany.com>
Reviewed-by: Simon Hausmann <simon.hausmann@theqtcompany.com>
(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

View File

@ -0,0 +1,124 @@
From f328f0cd2eb6be2a0a0d148bd769d51eae42bdc6 Mon Sep 17 00:00:00 2001
From: Thiago Macieira <thiago.macieira@intel.com>
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

View File

@ -1,94 +0,0 @@
From 72b4f0d4743826ee14ec06bf0ada26418f4a69be Mon Sep 17 00:00:00 2001
From: David Faure <david.faure@kdab.com>
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 <edward.welbourne@theqtcompany.com>
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
---
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 <sys/types.h>
+#include <sys/stat.h>
+#endif
+
#include <QtCore/QFile>
#include <QtCore/QFileInfo>
#include <QtCore/QStandardPaths>
@@ -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<QString>("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

View File

@ -0,0 +1,87 @@
From b024fbe83863fc57364a52c717d5b43d654bdb5d Mon Sep 17 00:00:00 2001
From: Weng Xuetian <wengxt@gmail.com>
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<int> &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

View File

@ -0,0 +1,158 @@
From acde2e69df5dedc624674107596f276125e22864 Mon Sep 17 00:00:00 2001
From: Weng Xuetian <wengxt@gmail.com>
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

View File

@ -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

View File

@ -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}

View File

@ -1,332 +0,0 @@
From 2d2cb6434f1d6e00f421c98b20467ff3f4388319 Mon Sep 17 00:00:00 2001
From: Thiago Macieira <thiago.macieira@intel.com>
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 <oswald.buddenhagen@theqtcompany.com>
---
.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 <module directory> 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" <<EOF
+#define QT_VERSION_MAJOR $QT_MAJOR_VERSION
+#define QT_VERSION_MINOR $QT_MINOR_VERSION
+#define QT_VERSION_PATCH $QT_PATCH_VERSION
+#define QT_VERSION_STR "$QT_VERSION"
+
+EOF
+
case "$CFG_QCONFIG" in
full)
- echo "/* Everything */" >"$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 <stddef.h>
-#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 <QtCore/qconfig.h>
#include <QtCore/qfeatures.h>
#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

View File

@ -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());

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:dfa4e8a4d7e4c6b69285e7e8833eeecd819987e1bdbe5baa6b6facd4420de916
size 46389212

View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:6efa8a5c559e92b2e526d48034e858023d5fd3c39115ac1bfd3bb65834dbd67a
size 46757096

View File

@ -1,32 +0,0 @@
From acb4f5cfb5efa053dd2d5dcd6490d610bb1f8c0e Mon Sep 17 00:00:00 2001
From: Ulf Hermann <ulf.hermann@theqtcompany.com>
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

View File

@ -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

View File

@ -1,57 +0,0 @@
From c2dd0bb2c7a0468abefb9556dead85456daa851f Mon Sep 17 00:00:00 2001
From: Shawn Rutledge <shawn.rutledge@theqtcompany.com>
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

View File

@ -1,36 +0,0 @@
From d72da0b4b2ee089156d1bd614523838b1635bbf5 Mon Sep 17 00:00:00 2001
From: Shawn Rutledge <shawn.rutledge@theqtcompany.com>
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 <psychon@znc.in>
Reviewed-by: Laszlo Agocs <laszlo.agocs@theqtcompany.com>
---
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