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:
parent
da241e83a4
commit
26d10f1197
@ -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
|
@ -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
|
||||
|
554
0001-xcb-XInput2-fixes-enter-leave-event-fixes.patch
Normal file
554
0001-xcb-XInput2-fixes-enter-leave-event-fixes.patch
Normal 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
|
||||
|
@ -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
|
||||
|
98
0003-xcb-Fix-not-delivering-focusIn-event-on-hide-show.patch
Normal file
98
0003-xcb-Fix-not-delivering-focusIn-event-on-hide-show.patch
Normal 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
|
||||
|
89
0004-xcb-Fix-drag-and-drop-between-xcb-screens.patch
Normal file
89
0004-xcb-Fix-drag-and-drop-between-xcb-screens.patch
Normal 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
|
||||
|
@ -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
|
@ -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
|
||||
|
@ -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
|
||||
|
337
0007-xcb-Deliver-mouse-enter-event-to-window-when-closing.patch
Normal file
337
0007-xcb-Deliver-mouse-enter-event-to-window-when-closing.patch
Normal 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
|
||||
|
@ -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
|
||||
|
153
0009-Expose-the-number-of-X-screen-through-the-QXcbScreen.patch
Normal file
153
0009-Expose-the-number-of-X-screen-through-the-QXcbScreen.patch
Normal 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
|
||||
|
199
0010-xcb-mark-mouse-events-from-tablet-devices-as-synthes.patch
Normal file
199
0010-xcb-mark-mouse-events-from-tablet-devices-as-synthes.patch
Normal 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
|
||||
|
142
0011-xcb-Initialize-all-xcb_client_message_event_t-member.patch
Normal file
142
0011-xcb-Initialize-all-xcb_client_message_event_t-member.patch
Normal 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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
206
0014-xcb-Properly-process-enter-leave-events.patch
Normal file
206
0014-xcb-Properly-process-enter-leave-events.patch
Normal 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
|
||||
|
149
0015-Use-the-state-of-the-key-event-to-process-it.patch
Normal file
149
0015-Use-the-state-of-the-key-event-to-process-it.patch
Normal 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
|
||||
|
@ -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
|
||||
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
||||
|
124
Fix-QtDBus-deadlock-inside-kded-kiod.patch
Normal file
124
Fix-QtDBus-deadlock-inside-kded-kiod.patch
Normal 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
|
@ -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
|
||||
|
@ -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
|
158
QtDBus-finish-all-pending-call-with-error-if-disconnected.patch
Normal file
158
QtDBus-finish-all-pending-call-with-error-if-disconnected.patch
Normal 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
|
@ -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
|
||||
|
||||
|
@ -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}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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());
|
@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:dfa4e8a4d7e4c6b69285e7e8833eeecd819987e1bdbe5baa6b6facd4420de916
|
||||
size 46389212
|
3
qtbase-opensource-src-5.6.0.tar.xz
Normal file
3
qtbase-opensource-src-5.6.0.tar.xz
Normal file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:6efa8a5c559e92b2e526d48034e858023d5fd3c39115ac1bfd3bb65834dbd67a
|
||||
size 46757096
|
@ -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
|
39
tell-the-truth-about-private-api.patch
Normal file
39
tell-the-truth-about-private-api.patch
Normal 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
|
@ -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
|
@ -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
|
Loading…
Reference in New Issue
Block a user