From 47aad8f1cc24f47b6c3b6b4888c56710887d6eb7 Mon Sep 17 00:00:00 2001 From: Kai Uwe Broulik Date: Thu, 28 Apr 2016 15:59:28 +0200 Subject: Android: show status bar for any window state except fullscreen This fixes the status bar not re-appearing when a window is reset to Qt::WindowNoState Task-number: QTBUG-37830 Change-Id: Iaef99221993ddf17b9da5b48796143abbcd98c01 Reviewed-by: Risto Avila Reviewed-by: BogDan Vatra --- src/plugins/platforms/android/qandroidplatformwindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/plugins/platforms/android/qandroidplatformwindow.cpp b/src/plugins/platforms/android/qandroidplatformwindow.cpp index b39695b0ef..7e46e5f09e 100644 --- a/src/plugins/platforms/android/qandroidplatformwindow.cpp +++ b/src/plugins/platforms/android/qandroidplatformwindow.cpp @@ -149,7 +149,7 @@ void QAndroidPlatformWindow::updateStatusBarVisibility() if (!isNonRegularWindow) { if (m_windowState & Qt::WindowFullScreen) QtAndroid::hideStatusBar(); - else if (m_windowState & Qt::WindowMaximized) + else QtAndroid::showStatusBar(); } } -- cgit v1.2.3 From c8a6b4278b04ff3ffb4484a3cf17cf4638dbadb4 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Mon, 22 Aug 2016 12:07:16 +0200 Subject: winrt: Exclude user events when adding/removing windows Handling user events while creating a window can cause problems and crashes as the event tries to access non initialized parts of the window itself being created. Hence exclude user input events at that time and have them handled when the event loop checks for them regularly. Change-Id: I2a78efd619250be8f6f2e737ed78e39481a4cf76 Reviewed-by: Oliver Wolff Reviewed-by: Friedemann Kleint --- src/plugins/platforms/winrt/qwinrtscreen.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp index dd2ebee3d5..3be17b0180 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.cpp +++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp @@ -767,7 +767,7 @@ void QWinRTScreen::addWindow(QWindow *window) updateWindowTitle(window->title()); QWindowSystemInterface::handleWindowActivated(window, Qt::OtherFocusReason); handleExpose(); - QWindowSystemInterface::flushWindowSystemEvents(); + QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents); #if _MSC_VER >= 1900 && !defined(QT_NO_DRAGANDDROP) QWinRTDrag::instance()->setDropTarget(window); @@ -785,7 +785,7 @@ void QWinRTScreen::removeWindow(QWindow *window) if (wasTopWindow) QWindowSystemInterface::handleWindowActivated(Q_NULLPTR, Qt::OtherFocusReason); handleExpose(); - QWindowSystemInterface::flushWindowSystemEvents(); + QWindowSystemInterface::flushWindowSystemEvents(QEventLoop::ExcludeUserInputEvents); #if _MSC_VER >= 1900 && !defined(QT_NO_DRAGANDDROP) if (wasTopWindow) QWinRTDrag::instance()->setDropTarget(topWindow()); -- cgit v1.2.3 From a0d3455ee396b1df5d10a0dc1ee84950fc3635a6 Mon Sep 17 00:00:00 2001 From: David Schulz Date: Fri, 12 Aug 2016 07:08:33 +0200 Subject: Taking trailing whitespace into account when shaping lines The calculated end position of script lines, consisting of nothing but trailing spaces, is lower than the start position. This results in not shaping those script lines. Task-number: QTBUG-55255 Change-Id: Ib70c1a800d2f70b7f61e3d05c10618e275f45f12 Reviewed-by: Konstantin Ritt Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qtextengine.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index 17a91f5a6a..3b50376504 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -922,7 +922,7 @@ void QTextEngine::shapeLine(const QScriptLine &line) if (item == -1) return; - const int end = findItem(line.from + line.length - 1, item); + const int end = findItem(line.from + line.length + line.trailingSpaces - 1, item); for ( ; item <= end; ++item) { QScriptItem &si = layoutData->items[item]; if (si.analysis.flags == QScriptAnalysis::Tab) { -- cgit v1.2.3 From bd9f3c50df9ad782b49eb47edf6264f8c4e8ac74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9rgio=20Martins?= Date: Tue, 23 Aug 2016 20:42:42 +0100 Subject: QToolButton: fix read of uninitialized variable Calling style() can trigger a call into user code which can read the tool button's members before they are initialized ==3566== Conditional jump or move depends on uninitialised value(s) ==3566== at 0x421C39: MyProxyStyle::pixelMetric(QStyle::PixelMetric, QStyleOption const*, QWidget const*) const (MyProxyStyle.cpp:635) ==3566== by 0x504B8B1: QRenderRule::QRenderRule(QVector const&, QObject const*) (qstylesheetstyle.cpp:1004) ==3566== by 0x504D084: QStyleSheetStyle::renderRule(QObject const*, int, unsigned long long) const (qstylesheetstyle.cpp:1747) ==3566== by 0x504D4A5: QStyleSheetStyle::renderRule(QObject const*, QStyleOption const*, int) const (qstylesheetstyle.cpp:2023) ==3566== by 0x504FF02: QStyleSheetStyle::styleHint(QStyle::StyleHint, QStyleOption const*, QWidget const*, QStyleHintReturn*) const (qstylesheetstyle.cpp:5146) ==3566== by 0x517B2D0: QToolButtonPrivate::init() (qtoolbutton.cpp:193) Change-Id: I56bca15d3ec7cd7b255a83dca786532a2f9b9b48 Reviewed-by: David Faure --- src/widgets/widgets/qtoolbutton.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/widgets/widgets/qtoolbutton.cpp b/src/widgets/widgets/qtoolbutton.cpp index f8b2dff720..998dad1372 100644 --- a/src/widgets/widgets/qtoolbutton.cpp +++ b/src/widgets/widgets/qtoolbutton.cpp @@ -190,7 +190,6 @@ QToolButton::QToolButton(QWidget * parent) void QToolButtonPrivate::init() { Q_Q(QToolButton); - delay = q->style()->styleHint(QStyle::SH_ToolButton_PopupDelay, 0, q); defaultAction = 0; #ifndef QT_NO_TOOLBAR if (qobject_cast(parent)) @@ -216,7 +215,7 @@ void QToolButtonPrivate::init() #endif setLayoutItemMargins(QStyle::SE_ToolButtonLayoutItem); - + delay = q->style()->styleHint(QStyle::SH_ToolButton_PopupDelay, 0, q); } /*! -- cgit v1.2.3 From 43a710df639c695f4c87e4857b8e8b045ab3df76 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Mon, 5 Sep 2016 09:14:05 +0200 Subject: MySQL: Fix MySQL plugin build with MySQL 5.0 Task-number: QTBUG-55544 Change-Id: Iff4e3109f475f9c3c8764fc6741b8d0547769ba2 Reviewed-by: Jesus Fernandez Reviewed-by: Mark Brand --- src/sql/drivers/mysql/qsql_mysql.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/sql/drivers/mysql/qsql_mysql.cpp b/src/sql/drivers/mysql/qsql_mysql.cpp index 55bf499e42..99472542bf 100644 --- a/src/sql/drivers/mysql/qsql_mysql.cpp +++ b/src/sql/drivers/mysql/qsql_mysql.cpp @@ -1318,7 +1318,7 @@ bool QMYSQLDriver::open(const QString& db, : sslCipher.toLocal8Bit().constData()); } -#if MYSQL_VERSION_ID >= 50000 +#if MYSQL_VERSION_ID >= 50100 if (connectTimeout != 0) mysql_options(d->mysql, MYSQL_OPT_CONNECT_TIMEOUT, &connectTimeout); if (readTimeout != 0) @@ -1347,7 +1347,7 @@ bool QMYSQLDriver::open(const QString& db, setOpenError(true); return false; } -#if MYSQL_VERSION_ID >= 50000 +#if MYSQL_VERSION_ID >= 50100 if (reconnect) mysql_options(d->mysql, MYSQL_OPT_RECONNECT, &reconnect); #endif -- cgit v1.2.3 From cf88d74466cd6506875676ef2557c179d72fe422 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Tue, 6 Sep 2016 11:53:41 +0200 Subject: winrt: Fix file dialog handling for Windows Phone Windows Phone needs to use activation targets to properly handle the return value of a file dialog. 0f9ca217d0f479756e50459473cad7371f29047c introduced launching an app via different modes, but broke above use- case for Windows Phone. Hence, we first check if a dispatcher exists and use this one to forward the activation. Task-number: QTBUG-54342 Change-Id: If9dd2df9a45e9aa104775530c695325fe6f684f2 Reviewed-by: Oliver Wolff --- src/winmain/qtmain_winrt.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'src') diff --git a/src/winmain/qtmain_winrt.cpp b/src/winmain/qtmain_winrt.cpp index 83a7dc800c..e49817ada4 100644 --- a/src/winmain/qtmain_winrt.cpp +++ b/src/winmain/qtmain_winrt.cpp @@ -198,6 +198,14 @@ public: private: HRESULT activatedLaunch(IInspectable *activateArgs) { + // Check if an application instance is already running + // This is mostly needed for Windows Phone and file pickers + QAbstractEventDispatcher *dispatcher = QCoreApplication::eventDispatcher(); + if (dispatcher) { + QCoreApplication::postEvent(dispatcher, new QActivationEvent(activateArgs)); + return S_OK; + } + QCoreApplication *app = QCoreApplication::instance(); // Check whether the app already runs -- cgit v1.2.3 From a32217cb551612277d43b3f7c08da85abe3874ac Mon Sep 17 00:00:00 2001 From: Alberto Mardegan Date: Tue, 9 Aug 2016 17:01:37 +0300 Subject: QDBusServer: delay processing of D-Bus messages We must ensure that QDBusServer's newConnection() signal has been processed by the application, before starting processing messages on it. Task-number: QTBUG-55087 Change-Id: I595329b2f98788dbf9f40558b8c230c0c0817ef8 Reviewed-by: Timo Jyrinki Reviewed-by: Thiago Macieira --- src/dbus/qdbusconnection.cpp | 20 -------------------- src/dbus/qdbusconnection_p.h | 19 +++++++++++++++++++ src/dbus/qdbusintegrator.cpp | 12 ++++++++++++ src/dbus/qdbusserver.cpp | 2 ++ 4 files changed, 33 insertions(+), 20 deletions(-) (limited to 'src') diff --git a/src/dbus/qdbusconnection.cpp b/src/dbus/qdbusconnection.cpp index 7cdacc1284..c88cf89897 100644 --- a/src/dbus/qdbusconnection.cpp +++ b/src/dbus/qdbusconnection.cpp @@ -68,24 +68,6 @@ static void preventDllUnload(); Q_GLOBAL_STATIC(QDBusConnectionManager, _q_manager) -// can be replaced with a lambda in Qt 5.7 -class QDBusConnectionDispatchEnabler : public QObject -{ - Q_OBJECT - QDBusConnectionPrivate *con; -public: - QDBusConnectionDispatchEnabler(QDBusConnectionPrivate *con) : con(con) {} - -public slots: - void execute() - { - con->setDispatchEnabled(true); - if (!con->ref.deref()) - con->deleteLater(); - deleteLater(); - } -}; - struct QDBusConnectionManager::ConnectionRequestData { enum RequestType { @@ -1281,8 +1263,6 @@ QByteArray QDBusConnection::localMachineId() QT_END_NAMESPACE -#include "qdbusconnection.moc" - #ifdef Q_OS_WIN # include diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h index fff9f29b03..d16cd05058 100644 --- a/src/dbus/qdbusconnection_p.h +++ b/src/dbus/qdbusconnection_p.h @@ -375,6 +375,25 @@ extern QDBusMessage qDBusPropertySet(const QDBusConnectionPrivate::ObjectTreeNod const QDBusMessage &msg); extern QDBusMessage qDBusPropertyGetAll(const QDBusConnectionPrivate::ObjectTreeNode &node, const QDBusMessage &msg); + +// can be replaced with a lambda in Qt 5.7 +class QDBusConnectionDispatchEnabler : public QObject +{ + Q_OBJECT + QDBusConnectionPrivate *con; +public: + QDBusConnectionDispatchEnabler(QDBusConnectionPrivate *con) : con(con) {} + +public slots: + void execute() + { + con->setDispatchEnabled(true); + if (!con->ref.deref()) + con->deleteLater(); + deleteLater(); + } +}; + #endif // QT_BOOTSTRAPPED QT_END_NAMESPACE diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index 147966b9b0..878a58294c 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -309,9 +309,21 @@ static void qDBusNewConnection(DBusServer *server, DBusConnection *connection, v // setPeer does the error handling for us QDBusErrorInternal error; newConnection->setPeer(connection, error); + newConnection->setDispatchEnabled(false); // this is a queued connection and will resume in the QDBusServer's thread emit serverConnection->newServerConnection(newConnection); + + // we've disabled dispatching of events, so now we post an event to the + // QDBusServer's thread in order to enable it after the + // QDBusServer::newConnection() signal has been received by the + // application's code + newConnection->ref.ref(); + QReadLocker serverLock(&serverConnection->lock); + QDBusConnectionDispatchEnabler *o = new QDBusConnectionDispatchEnabler(newConnection); + QTimer::singleShot(0, o, SLOT(execute())); + if (serverConnection->serverObject) + o->moveToThread(serverConnection->serverObject->thread()); } void QDBusConnectionPrivate::_q_newConnection(QDBusConnectionPrivate *newConnection) diff --git a/src/dbus/qdbusserver.cpp b/src/dbus/qdbusserver.cpp index babb270da0..39d08b4e63 100644 --- a/src/dbus/qdbusserver.cpp +++ b/src/dbus/qdbusserver.cpp @@ -97,6 +97,7 @@ QDBusServer::QDBusServer(QObject *parent) */ QDBusServer::~QDBusServer() { + QWriteLocker locker(&d->lock); if (QDBusConnectionManager::instance()) { QMutexLocker locker(&QDBusConnectionManager::instance()->mutex); Q_FOREACH (const QString &name, d->serverConnectionNames) { @@ -104,6 +105,7 @@ QDBusServer::~QDBusServer() } d->serverConnectionNames.clear(); } + d->serverObject = nullptr; d->ref.store(0); d->deleteLater(); } -- cgit v1.2.3 From 1eb74c9f101eef530b3a5d633cc2fcd1fb547e9d Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Wed, 20 Jul 2016 11:16:32 +0200 Subject: QIOSTextInputOverlay: compile with Xcode 8 beta / iOS 10 The iOS 10 SDK have introduced a protocol CAAnimationDelegate, which is required for CAAnimation delegates. So we let our delegate implement it. Since the SDK is not out yet, we need to support both version 9 and 10 for now. Change-Id: I2624d8150c39439540a6554cba4921e3b9a2f0cf Reviewed-by: Jake Petroules --- src/plugins/platforms/ios/qiostextinputoverlay.mm | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiostextinputoverlay.mm b/src/plugins/platforms/ios/qiostextinputoverlay.mm index 733367f3be..d930965bde 100644 --- a/src/plugins/platforms/ios/qiostextinputoverlay.mm +++ b/src/plugins/platforms/ios/qiostextinputoverlay.mm @@ -299,7 +299,11 @@ static void executeBlockWithoutAnimation(Block block) // ------------------------------------------------------------------------- +#if QT_IOS_PLATFORM_SDK_EQUAL_OR_ABOVE(__IPHONE_10_0) +@interface QIOSHandleLayer : CALayer { +#else @interface QIOSHandleLayer : CALayer { +#endif CALayer *_handleCursorLayer; CALayer *_handleKnobLayer; Qt::Edge _selectionEdge; -- cgit v1.2.3 From 66fcd0cf6674fa96ede7776ca3afa786499a07ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorbj=C3=B8rn=20Lindeijer?= Date: Tue, 6 Sep 2016 11:38:18 +0200 Subject: Fixed glitch when dragging a movable QTabBar tab When you would start to drag a tab, and then drag it in the other direction along the point where you started the drag, the tab would fail to follow the mouse for a distance twice the "startDragDistance", before jumping to the mouse again. Fixed this by only taking into account the "startDragDistance" when checking whether a drag is started, and to rely on the "dragInProgress" variable otherwise. Change-Id: I5dd4ebd8340fef7e870f087be68c5097b49728cb Reviewed-by: Marc Mutz --- src/widgets/widgets/qtabbar.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'src') diff --git a/src/widgets/widgets/qtabbar.cpp b/src/widgets/widgets/qtabbar.cpp index ed820888b4..2a163c18b5 100644 --- a/src/widgets/widgets/qtabbar.cpp +++ b/src/widgets/widgets/qtabbar.cpp @@ -1869,9 +1869,8 @@ void QTabBar::mouseMoveEvent(QMouseEvent *event) } } - int offset = (event->pos() - d->dragStartPosition).manhattanLength(); if (event->buttons() == Qt::LeftButton - && offset > QApplication::startDragDistance() + && d->dragInProgress && d->validIndex(d->pressedIndex)) { bool vertical = verticalTabs(d->shape); int dragDistance; -- cgit v1.2.3 From 3b8df0ea44b048b8fcc4317ffdfd074e2547a95e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= Date: Thu, 24 Mar 2016 23:50:24 +0100 Subject: QtWidgets: Send show/hide event to children on restore/minimize Child widgets should get the show/hide event when the TLW changes its state, because child widgets are also visible or invisible. This restores the Qt4 behavior (fixes the Qt4->Qt5 regression). Restoring/minimizing the TLW now sends the spontaneous show/hide event. Show events are now handled also in the expose event handler in the QWidgetWindow class, because the show event must occur before the expose event to avoid possible flicker e.g. the OpenGL content. This can happen e.g. on XCB platform. If the "WindowStateChange" event occur before the expose event (e.g. Windows platform) then the code in expose event handler will be ignored to prevent event duplications. Added autotest. Task-number: QTBUG-50589 Change-Id: Ie9a9329b1f29bff876de28d5948d0d5fb6bc1f05 Reviewed-by: Friedemann Kleint --- src/widgets/kernel/qwidget.cpp | 18 +++++++++++++++--- src/widgets/kernel/qwidget_p.h | 2 ++ src/widgets/kernel/qwidgetwindow.cpp | 34 ++++++++++++++++++++++++++++++++-- 3 files changed, 49 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp index b1d80d7b8f..b99fca6620 100644 --- a/src/widgets/kernel/qwidget.cpp +++ b/src/widgets/kernel/qwidget.cpp @@ -276,6 +276,8 @@ QWidgetPrivate::QWidgetPrivate(int version) , renderToTextureReallyDirty(1) , renderToTextureComposeActive(0) #endif + , childrenHiddenByWState(0) + , childrenShownByExpose(0) #if defined(Q_OS_WIN) , noPaintOnScreen(0) #endif @@ -9005,13 +9007,23 @@ bool QWidget::event(QEvent *event) case QEvent::WindowStateChange: { const bool wasMinimized = static_cast(event)->oldState() & Qt::WindowMinimized; if (wasMinimized != isMinimized()) { + QWidget *widget = const_cast(this); if (wasMinimized) { - QShowEvent showEvent; - QCoreApplication::sendEvent(const_cast(this), &showEvent); + // Always send the spontaneous events here, otherwise it can break the application! + if (!d->childrenShownByExpose) { + // Show widgets only when they are not yet shown by the expose event + d->showChildren(true); + QShowEvent showEvent; + QCoreApplication::sendSpontaneousEvent(widget, &showEvent); + } + d->childrenHiddenByWState = false; // Set it always to "false" when window is restored } else { QHideEvent hideEvent; - QCoreApplication::sendEvent(const_cast(this), &hideEvent); + QCoreApplication::sendSpontaneousEvent(widget, &hideEvent); + d->hideChildren(true); + d->childrenHiddenByWState = true; } + d->childrenShownByExpose = false; // Set it always to "false" when window state changes } changeEvent(event); } diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h index b130c5421a..5f07a8802a 100644 --- a/src/widgets/kernel/qwidget_p.h +++ b/src/widgets/kernel/qwidget_p.h @@ -746,6 +746,8 @@ public: uint renderToTextureReallyDirty : 1; uint renderToTextureComposeActive : 1; #endif + uint childrenHiddenByWState : 1; + uint childrenShownByExpose : 1; // *************************** Platform specific ************************************ #if defined(Q_OS_WIN) diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index 872572a7e2..aa7bcc2ef8 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -871,10 +871,40 @@ void QWidgetWindow::handleDropEvent(QDropEvent *event) void QWidgetWindow::handleExposeEvent(QExposeEvent *event) { - if (isExposed()) { + QWidgetPrivate *wPriv = m_widget->d_func(); + const bool exposed = isExposed(); + + if (wPriv->childrenHiddenByWState) { + // If widgets has been previously hidden by window state change event + // and they aren't yet shown... + if (exposed) { + // If the window becomes exposed... + if (!wPriv->childrenShownByExpose) { + // ... and they haven't been shown by this function yet - show it. + wPriv->showChildren(true); + QShowEvent showEvent; + QCoreApplication::sendSpontaneousEvent(m_widget, &showEvent); + wPriv->childrenShownByExpose = true; + } + } else { + // If the window becomes not exposed... + if (wPriv->childrenShownByExpose) { + // ... and child widgets was previously shown by the expose event - hide widgets again. + // This is a workaround, because sometimes when window is minimized programatically, + // the QPA can notify that the window is exposed after changing window state to minimized + // and then, the QPA can send next expose event with null exposed region (not exposed). + wPriv->hideChildren(true); + QHideEvent hideEvent; + QCoreApplication::sendSpontaneousEvent(m_widget, &hideEvent); + wPriv->childrenShownByExpose = false; + } + } + } + + if (exposed) { m_widget->setAttribute(Qt::WA_Mapped); if (!event->region().isNull()) - m_widget->d_func()->syncBackingStore(event->region()); + wPriv->syncBackingStore(event->region()); } else { m_widget->setAttribute(Qt::WA_Mapped, false); } -- cgit v1.2.3 From 3370ab9119df09ca14f7d4641c555e60c1b3f478 Mon Sep 17 00:00:00 2001 From: Milian Wolff Date: Mon, 22 Aug 2016 14:32:05 +0200 Subject: Never return char variants when reading prepared MySQL statements This has undesired effects when converting a QSqlRecord to JSON. A char(0) e.g. has special semantics that are undesired when reading a Tinyint column. I don't think that returning bool for the special case of a Tinyint(1) is required. This also did not happen before, and is also not happening when not using a prepared statement. Instead, a plain int/uint QVariant is returned. This patch extends tst_QSqlQuery::integralTypesMysql to also cover reading and writing booleans from/to a MySQL table column of type Tinyint(1). Additionally, the reading is now also done with a prepared statement and we also check the raw variant value. The broken behavior fixed by this patch was introduced by me in commit 194403a3483b7317cc9511bc8b2ab307775643c5. Change-Id: I028a3abd83fdd2b42d98d478950d205e5b6bbeb5 Task-number: QTBUG-53397 Reviewed-by: Andy Shaw --- src/sql/drivers/mysql/qsql_mysql.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/sql/drivers/mysql/qsql_mysql.cpp b/src/sql/drivers/mysql/qsql_mysql.cpp index 99472542bf..c26c03ad07 100644 --- a/src/sql/drivers/mysql/qsql_mysql.cpp +++ b/src/sql/drivers/mysql/qsql_mysql.cpp @@ -596,8 +596,15 @@ QVariant QMYSQLResult::data(int field) if (f.nullIndicator) return QVariant(f.type); - if (qIsInteger(f.type)) - return QVariant(f.type, f.outField); + if (qIsInteger(f.type)) { + QVariant variant(f.type, f.outField); + // we never want to return char variants here, see QTBUG-53397 + if (static_cast(f.type) == QMetaType::UChar) + return variant.toUInt(); + else if (static_cast(f.type) == QMetaType::Char) + return variant.toInt(); + return variant; + } if (f.type != QVariant::ByteArray) val = toUnicode(d->driver->d_func()->tc, f.outField, f.bufLength); -- cgit v1.2.3 From 7529c39ba350c3fe9a2b4a96d3300481e3ea419f Mon Sep 17 00:00:00 2001 From: Dyami Caliri Date: Wed, 7 Sep 2016 11:05:51 -0700 Subject: QStyleOption: return Q_NULLPTR from qstyleoption_cast instead of 0 qstyleoption_cast should use Q_NULLPTR to represent a null pointer. Task-number: QTBUG-45291 Change-Id: I85078ceb435b310daf63db2ed771be2f36cf3e4f Reviewed-by: Marc Mutz --- src/widgets/styles/qstyleoption.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/widgets/styles/qstyleoption.h b/src/widgets/styles/qstyleoption.h index 9fd693d033..74dd35cc4a 100644 --- a/src/widgets/styles/qstyleoption.h +++ b/src/widgets/styles/qstyleoption.h @@ -664,7 +664,7 @@ T qstyleoption_cast(const QStyleOption *opt) || (int(Opt::Type) == QStyleOption::SO_Complex && opt->type > QStyleOption::SO_Complex))) return static_cast(opt); - return 0; + return Q_NULLPTR; } template @@ -676,7 +676,7 @@ T qstyleoption_cast(QStyleOption *opt) || (int(Opt::Type) == QStyleOption::SO_Complex && opt->type > QStyleOption::SO_Complex))) return static_cast(opt); - return 0; + return Q_NULLPTR; } // -------------------------- QStyleHintReturn ------------------------------- @@ -725,7 +725,7 @@ T qstyleoption_cast(const QStyleHintReturn *hint) if (hint && hint->version <= Opt::Version && (hint->type == Opt::Type || int(Opt::Type) == QStyleHintReturn::SH_Default)) return static_cast(hint); - return 0; + return Q_NULLPTR; } template @@ -735,7 +735,7 @@ T qstyleoption_cast(QStyleHintReturn *hint) if (hint && hint->version <= Opt::Version && (hint->type == Opt::Type || int(Opt::Type) == QStyleHintReturn::SH_Default)) return static_cast(hint); - return 0; + return Q_NULLPTR; } #if !defined(QT_NO_DEBUG_STREAM) -- cgit v1.2.3 From a54d44298f6d2ecc1ec4d8c5c42c89c8a06fc5dd Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Wed, 14 Sep 2016 16:14:16 +0200 Subject: QLatin1String: Fix UB (nullptr passed) in relational operators Found by UBSan: qstring.h:1160:44: runtime error: null pointer passed as argument 1, which is declared to never be null qstring.h:1160:44: runtime error: null pointer passed as argument 2, which is declared to never be null Fix by avoiding the memcmp() calls if there's a chance that they might be called with nullptr. While at it, also implement !=, >, <=, >= in terms of ==, <, and add a test, because this particular UB was not fingered by any of the QtCore test cases, but by a Qt3D one. Change-Id: I413792dcc8431ef14f0c79f26e89a3e9fab69465 Reviewed-by: Thiago Macieira Reviewed-by: Edward Welbourne --- src/corelib/tools/qstring.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h index 886973fe10..58ad2caa2b 100644 --- a/src/corelib/tools/qstring.h +++ b/src/corelib/tools/qstring.h @@ -1127,21 +1127,21 @@ inline bool operator!=(QString::Null, const QString &s) { return !s.isNull(); } inline bool operator!=(const QString &s, QString::Null) { return !s.isNull(); } inline bool operator==(QLatin1String s1, QLatin1String s2) Q_DECL_NOTHROW -{ return (s1.size() == s2.size() && !memcmp(s1.latin1(), s2.latin1(), s1.size())); } +{ return s1.size() == s2.size() && (!s1.size() || !memcmp(s1.latin1(), s2.latin1(), s1.size())); } inline bool operator!=(QLatin1String s1, QLatin1String s2) Q_DECL_NOTHROW -{ return (s1.size() != s2.size() || memcmp(s1.latin1(), s2.latin1(), s1.size())); } +{ return !operator==(s1, s2); } inline bool operator<(QLatin1String s1, QLatin1String s2) Q_DECL_NOTHROW -{ int r = memcmp(s1.latin1(), s2.latin1(), qMin(s1.size(), s2.size())); - return (r < 0) || (r == 0 && s1.size() < s2.size()); } -inline bool operator<=(QLatin1String s1, QLatin1String s2) Q_DECL_NOTHROW -{ int r = memcmp(s1.latin1(), s2.latin1(), qMin(s1.size(), s2.size())); - return (r < 0) || (r == 0 && s1.size() <= s2.size()); } +{ + const int len = qMin(s1.size(), s2.size()); + const int r = len ? memcmp(s1.latin1(), s2.latin1(), len) : 0; + return r < 0 || (r == 0 && s1.size() < s2.size()); +} inline bool operator>(QLatin1String s1, QLatin1String s2) Q_DECL_NOTHROW -{ int r = memcmp(s1.latin1(), s2.latin1(), qMin(s1.size(), s2.size())); - return (r > 0) || (r == 0 && s1.size() > s2.size()); } +{ return operator<(s2, s1); } +inline bool operator<=(QLatin1String s1, QLatin1String s2) Q_DECL_NOTHROW +{ return !operator>(s1, s2); } inline bool operator>=(QLatin1String s1, QLatin1String s2) Q_DECL_NOTHROW -{ int r = memcmp(s1.latin1(), s2.latin1(), qMin(s1.size(), s2.size())); - return (r > 0) || (r == 0 && s1.size() >= s2.size()); } +{ return !operator<(s1, s2); } inline bool QLatin1String::operator==(const QString &s) const Q_DECL_NOTHROW { return s == *this; } -- cgit v1.2.3 From 258e4d05edcb36406c32be56a8207fe992d284dc Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 15 Sep 2016 00:36:54 +0200 Subject: QDBusError: don't bother dealing with unusable 'unused' field The move constructor as well as member-swap were dealing with the 'unused' field as if it would be usable. But as the comment in the default ctor suggests, the field can never be used in Qt 5, due to the inline dtor. So, don't bother with the field. Doing so only triggers checkers such as Coverity. Also mark the field for removal in Qt 6. Coverity-Id: 154503 Coverity-Id: 154510 Change-Id: If42c5ed66d1133e651de7477f3313b3989b64bc9 Reviewed-by: Thiago Macieira --- src/dbus/qdbuserror.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/dbus/qdbuserror.h b/src/dbus/qdbuserror.h index ce5275dee9..12a19a8eda 100644 --- a/src/dbus/qdbuserror.h +++ b/src/dbus/qdbuserror.h @@ -94,8 +94,8 @@ public: QDBusError(const QDBusError &other); #ifdef Q_COMPILER_RVALUE_REFS QDBusError(QDBusError &&other) Q_DECL_NOTHROW - : code(other.code), msg(std::move(other.msg)), nm(std::move(other.nm)), unused(other.unused) - { other.unused = Q_NULLPTR; } + : code(other.code), msg(std::move(other.msg)), nm(std::move(other.nm)) + {} QDBusError &operator=(QDBusError &&other) Q_DECL_NOTHROW { swap(other); return *this; } #endif QDBusError &operator=(const QDBusError &other); @@ -108,7 +108,6 @@ public: qSwap(code, other.code); qSwap(msg, other.msg); qSwap(nm, other.nm); - qSwap(unused, other.unused); } ErrorType type() const; @@ -122,6 +121,8 @@ private: ErrorType code; QString msg; QString nm; + // ### This class has an implicit (therefore inline) destructor + // so the following field cannot be used: void *unused; }; Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QDBusError) -- cgit v1.2.3 From 2cf3dee10be1d2163eff0893f51f9ece643c2540 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= Date: Mon, 12 Sep 2016 15:22:20 +0200 Subject: xcb: Don't send "Qt::WindowNoState" event when hiding minimized window This prevents getting "QWidget::showEvent()" when hiding minimized widget on some WMs like Marco or Xfwm4. If QWindow is minimized and it gets the new "XCB_WM_STATE_WITHDRAWN" event from XCB, then don't change the QWindow state. Task-number: QTBUG-55942 Change-Id: I90cfc2bf55e507864ad8f26c8f569ea562c27314 Reviewed-by: Uli Schlachter Reviewed-by: Shawn Rutledge --- src/plugins/platforms/xcb/qxcbwindow.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp index da5020168f..d46228cf8a 100644 --- a/src/plugins/platforms/xcb/qxcbwindow.cpp +++ b/src/plugins/platforms/xcb/qxcbwindow.cpp @@ -2543,8 +2543,13 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev if (reply && reply->format == 32 && reply->type == atom(QXcbAtom::WM_STATE)) { const quint32 *data = (const quint32 *)xcb_get_property_value(reply); - if (reply->length != 0 && XCB_WM_STATE_ICONIC == data[0]) - newState = Qt::WindowMinimized; + if (reply->length != 0) { + if (data[0] == XCB_WM_STATE_ICONIC + || (data[0] == XCB_WM_STATE_WITHDRAWN + && m_lastWindowStateEvent == Qt::WindowMinimized)) { + newState = Qt::WindowMinimized; + } + } } free(reply); } else { // _NET_WM_STATE can't change minimized state -- cgit v1.2.3 From 25c9a6c9b46e6ae58dcccdc3ba158d14945cbf33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= Date: Wed, 4 May 2016 00:23:16 +0200 Subject: QtWidgets: Fix enter/leave events on popup menus If the sloppy menu popups - send the leave event to the last active menu (except Cocoa), because only currect active menu gets enter/leave events (currently Cocoa is an exception). Check that the menu really has a mouse before hiding the sloppy menu - don't rely on enter events. This patch removes some unnecessary synthetic mouse enter/leave events from QMenu which causes event duplications with different mouse cursor position. Refactor sloppy menu timer handling - start or restart timers on mouse move events. Enter/leave events are not reliable. Fixes: - better enter/leave events handling for native widget actions, - reduce duplicated enter/leave events for menu actions, - better handle torn off sloppy menus. Partially reverts: 0ed68f3f58c63bd1496cb268bd83881da180051f Amends: 57ecd5aeeb1f609206933be66b92fcdf703703d7 Task-number: QTBUG-53068 Change-Id: I7ad56ac1619db124915d373fab82d0512d44c90e Reviewed-by: Shawn Rutledge --- src/widgets/kernel/qwidgetwindow.cpp | 34 +++++++------- src/widgets/widgets/qmenu.cpp | 86 ++++++++++++++++++++---------------- src/widgets/widgets/qmenu_p.h | 23 ++-------- 3 files changed, 70 insertions(+), 73 deletions(-) (limited to 'src') diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index aa7bcc2ef8..95f63025fb 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -381,7 +381,14 @@ void QWidgetWindow::handleEnterLeaveEvent(QEvent *event) const QEnterEvent *ee = static_cast(event); QWidget *child = m_widget->childAt(ee->pos()); QWidget *receiver = child ? child : m_widget.data(); - QApplicationPrivate::dispatchEnterLeave(receiver, 0, ee->screenPos()); + QWidget *leave = Q_NULLPTR; + if (QApplicationPrivate::inPopupMode() && receiver == m_widget + && qt_last_mouse_receiver != m_widget) { + // This allows to deliver the leave event to the native widget + // action on first-level menu. + leave = qt_last_mouse_receiver; + } + QApplicationPrivate::dispatchEnterLeave(receiver, leave, ee->screenPos()); qt_last_mouse_receiver = receiver; } } @@ -471,34 +478,31 @@ void QWidgetWindow::handleMouseEvent(QMouseEvent *event) receiver = popupChild; if (receiver != activePopupWidget) widgetPos = receiver->mapFromGlobal(event->globalPos()); - QWidget *alien = receiver; #if !defined(Q_OS_OSX) && !defined(Q_OS_IOS) // Cocoa tracks popups const bool reallyUnderMouse = activePopupWidget->rect().contains(mapped); const bool underMouse = activePopupWidget->underMouse(); - if (activePopupWidget != m_widget || (!underMouse && qt_button_down)) { - // If active popup menu is not the first-level popup menu then we must emulate enter/leave events, - // because first-level popup menu grabs the mouse and enter/leave events are delivered only to it - // by QPA. Make an exception for first-level popup menu when the mouse button is pressed on widget. - if (underMouse != reallyUnderMouse) { - if (reallyUnderMouse) { + if (underMouse != reallyUnderMouse) { + if (reallyUnderMouse) { + const QPoint receiverMapped = receiver->mapFromGlobal(event->screenPos().toPoint()); + // Prevent negative mouse position on enter event - this event + // should be properly handled in "handleEnterLeaveEvent()". + if (receiverMapped.x() >= 0 && receiverMapped.y() >= 0) { QApplicationPrivate::dispatchEnterLeave(receiver, Q_NULLPTR, event->screenPos()); qt_last_mouse_receiver = receiver; - } else { - QApplicationPrivate::dispatchEnterLeave(Q_NULLPTR, qt_last_mouse_receiver, event->screenPos()); - qt_last_mouse_receiver = receiver; - receiver = activePopupWidget; } + } else { + QApplicationPrivate::dispatchEnterLeave(Q_NULLPTR, qt_last_mouse_receiver, event->screenPos()); + qt_last_mouse_receiver = receiver; + receiver = activePopupWidget; } - } else if (!reallyUnderMouse) { - alien = Q_NULLPTR; } #endif QMouseEvent e(event->type(), widgetPos, event->windowPos(), event->screenPos(), event->button(), event->buttons(), event->modifiers(), event->source()); e.setTimestamp(event->timestamp()); - QApplicationPrivate::sendMouseEvent(receiver, &e, alien, receiver->window(), &qt_button_down, qt_last_mouse_receiver); + QApplicationPrivate::sendMouseEvent(receiver, &e, receiver, receiver->window(), &qt_button_down, qt_last_mouse_receiver); qt_last_mouse_receiver = receiver; } else { // close disabled popups when a mouse button is pressed or released diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp index c194547f2d..2fd5340f3b 100644 --- a/src/widgets/widgets/qmenu.cpp +++ b/src/widgets/widgets/qmenu.cpp @@ -70,22 +70,6 @@ QT_BEGIN_NAMESPACE QMenu *QMenuPrivate::mouseDown = 0; -QPointer QMenuPrivate::previousMouseMenu(Q_NULLPTR); -static void handleEnterLeaveEvents(QPointer *previous_ptr, QMenu *next) -{ - QWidget *previous = previous_ptr->data(); - if (previous != next) { - if (previous) { - QEvent leaveEvent(QEvent::Leave); - QApplication::sendEvent(previous, &leaveEvent); - } - if (next) { - QEvent enterEvent(QEvent::Enter); - QApplication::sendEvent(next, &enterEvent); - } - } - *previous_ptr = next; -} /* QMenu code */ // internal class used for the torn off popup @@ -504,8 +488,6 @@ void QMenuPrivate::hideMenu(QMenu *menu) menu->d_func()->causedPopup.action = 0; menu->close(); menu->d_func()->causedPopup.widget = 0; - if (previousMouseMenu.data() == menu) - handleEnterLeaveEvents(&previousMouseMenu, Q_NULLPTR); } void QMenuPrivate::popupAction(QAction *action, int delay, bool activateFirst) @@ -671,10 +653,26 @@ void QMenuSloppyState::enter() m_parent->childEnter(); } +void QMenuSloppyState::childEnter() +{ + stopTimer(); + if (m_parent) + m_parent->childEnter(); +} + +void QMenuSloppyState::leave() +{ + if (!m_dont_start_time_on_leave) { + if (m_parent) + m_parent->childLeave(); + startTimerIfNotRunning(); + } +} + void QMenuSloppyState::childLeave() { if (m_enabled && !QMenuPrivate::get(m_menu)->hasReceievedEnter) { - startTimer(); + startTimerIfNotRunning(); if (m_parent) m_parent->childLeave(); } @@ -720,8 +718,17 @@ public: void QMenuSloppyState::timeout() { QMenuPrivate *menu_priv = QMenuPrivate::get(m_menu); + + bool reallyHasMouse = menu_priv->hasReceievedEnter; + if (!reallyHasMouse) { + // Check whether the menu really has a mouse, because only active popup + // menu gets the enter/leave events. Currently Cocoa is an exception. + const QPoint lastCursorPos = QGuiApplicationPrivate::lastCursorPosition.toPoint(); + reallyHasMouse = m_menu->frameGeometry().contains(lastCursorPos); + } + if (menu_priv->currentAction == m_reset_action - && menu_priv->hasReceievedEnter + && reallyHasMouse && (menu_priv->currentAction && menu_priv->currentAction->menu() == menu_priv->activeMenu)) { return; @@ -729,13 +736,13 @@ void QMenuSloppyState::timeout() ResetOnDestroy resetState(this, &m_init_guard); - if (hasParentActiveDelayTimer() || !m_menu || !m_menu->isVisible()) + if (hasParentActiveDelayTimer() || !m_menu->isVisible()) return; if (m_sub_menu) menu_priv->hideMenu(m_sub_menu); - if (menu_priv->hasReceievedEnter) + if (reallyHasMouse) menu_priv->setCurrentAction(m_reset_action,0); else menu_priv->setCurrentAction(Q_NULLPTR, 0); @@ -1089,10 +1096,8 @@ bool QMenuPrivate::mouseEventTaken(QMouseEvent *e) tearoffHighlighted = 0; } - if (q->frameGeometry().contains(e->globalPos())) { //otherwise if the event is in our rect we want it.. - handleEnterLeaveEvents(&previousMouseMenu, q); - return false; - } + if (q->frameGeometry().contains(e->globalPos())) + return false; //otherwise if the event is in our rect we want it.. for(QWidget *caused = causedPopup.widget; caused;) { bool passOnEvent = false; @@ -1108,17 +1113,16 @@ bool QMenuPrivate::mouseEventTaken(QMouseEvent *e) next_widget = m->d_func()->causedPopup.widget; } if (passOnEvent) { - handleEnterLeaveEvents(&previousMouseMenu,qobject_cast(caused)); - if(e->type() != QEvent::MouseButtonRelease || mouseDown == caused) { - QMouseEvent new_e(e->type(), cpos, caused->mapTo(caused->topLevelWidget(), cpos), e->screenPos(), - e->button(), e->buttons(), e->modifiers(), e->source()); - QApplication::sendEvent(caused, &new_e); - return true; + if (e->type() != QEvent::MouseButtonRelease || mouseDown == caused) { + QMouseEvent new_e(e->type(), cpos, caused->mapTo(caused->topLevelWidget(), cpos), e->screenPos(), + e->button(), e->buttons(), e->modifiers(), e->source()); + QApplication::sendEvent(caused, &new_e); + return true; } } caused = next_widget; if (!caused) - handleEnterLeaveEvents(&previousMouseMenu, Q_NULLPTR); + sloppyState.leave(); // Start timers } return false; } @@ -3169,7 +3173,6 @@ void QMenu::enterEvent(QEvent *) Q_D(QMenu); d->hasReceievedEnter = true; d->sloppyState.enter(); - d->sloppyState.startTimer(); d->motions = -1; // force us to ignore the generate mouse move in mouseMoveEvent() } @@ -3180,7 +3183,6 @@ void QMenu::leaveEvent(QEvent *) { Q_D(QMenu); d->hasReceievedEnter = false; - d->sloppyState.leave(); if (!d->activeMenu && d->currentAction) setActiveAction(0); } @@ -3352,10 +3354,18 @@ void QMenu::internalDelayedPopup() const QRect actionRect(d->actionRect(d->currentAction)); const QPoint rightPos(mapToGlobal(QPoint(actionRect.right() + subMenuOffset + 1, actionRect.top()))); - QPoint pos(rightPos); - - d->activeMenu->popup(pos); + d->activeMenu->popup(rightPos); d->sloppyState.setSubMenuPopup(actionRect, d->currentAction, d->activeMenu); + +#if !defined(Q_OS_DARWIN) + // Send the leave event to the current menu - only active popup menu gets + // mouse enter/leave events. Currently Cocoa is an exception, so disable + // it there to avoid event duplication. + if (underMouse()) { + QEvent leaveEvent(QEvent::Leave); + QCoreApplication::sendEvent(this, &leaveEvent); + } +#endif } /*! diff --git a/src/widgets/widgets/qmenu_p.h b/src/widgets/widgets/qmenu_p.h index e717d923ae..c78abf8aed 100644 --- a/src/widgets/widgets/qmenu_p.h +++ b/src/widgets/widgets/qmenu_p.h @@ -122,8 +122,6 @@ public: void reset(); bool enabled() const { return m_enabled; } - void setResetAction(QAction *action) { m_reset_action = action; } - enum MouseEventResult { EventIsProcessed, EventShouldBePropagated, @@ -148,22 +146,9 @@ public: } void enter(); + void childEnter(); - void childEnter() - { - stopTimer(); - if (m_parent) - m_parent->childEnter(); - } - - void leave() - { - if (m_dont_start_time_on_leave) - return; - if (m_parent) - m_parent->childLeave(); - startTimer(); - } + void leave(); void childLeave(); static float slope(const QPointF &p1, const QPointF &p2) @@ -189,8 +174,7 @@ public: if (!m_enabled) return EventShouldBePropagated; - if (!m_time.isActive()) - startTimer(); + startTimerIfNotRunning(); if (!m_sub_menu) { reset(); @@ -493,7 +477,6 @@ public: QAction* wceCommands(uint command); #endif QPointer noReplayFor; - static QPointer previousMouseMenu; }; #endif // QT_NO_MENU -- cgit v1.2.3 From f4eefce86364112ab215975e0a79755143c20491 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Mon, 22 Feb 2016 09:16:26 +0100 Subject: Fix typos in highdpi docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I15fd6859ff777388a229e3cb10de45886fe543fb Reviewed-by: Nico Vertriest Reviewed-by: Morten Johan Sørvig --- src/gui/kernel/qhighdpiscaling.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/gui/kernel/qhighdpiscaling.cpp b/src/gui/kernel/qhighdpiscaling.cpp index 2d00b9dce9..6846196719 100644 --- a/src/gui/kernel/qhighdpiscaling.cpp +++ b/src/gui/kernel/qhighdpiscaling.cpp @@ -163,11 +163,11 @@ static inline qreal initialGlobalScaleFactor() The QT_SCALE_FACTOR environment variable can be used to set a global scale factor for all windows in the processs. This is useful for testing and debugging (you can simulate any - devicePixelRatio without needing access to sepcial hardware), + devicePixelRatio without needing access to special hardware), and perhaps also for targeting a specific application to a specific display type (embedded use cases). - 2) A per-screen scale factors + 2) Per-screen scale factors Some platform plugins support providing a per-screen scale factor based on display density information. These platforms include X11, Windows, and Android. @@ -180,13 +180,13 @@ static inline qreal initialGlobalScaleFactor() Enabling either will make QHighDpiScaling call QPlatformScreen::pixelDensity() and use the value provided as the scale factor for the screen in question. Disabling is done on a 'veto' basis where either the - environment or the application source can disable. The intended use + environment or the application can disable the scaling. The intended use cases are 'My system is not providing correct display density information' and 'My application needs to work in display pixels', respectively. The QT_SCREEN_SCALE_FACTORS environment variable can be used to set the screen - scale factors manually.Set this to a semicolon-separated + scale factors manually. Set this to a semicolon-separated list of scale factors (matching the order of QGuiApplications::screens()), or to a list of name=value pairs (where name matches QScreen::name()). -- cgit v1.2.3 From 835d7cf54328bdd93d58bb64ed96a9c322580aea Mon Sep 17 00:00:00 2001 From: Dmitry Shachnev Date: Wed, 7 Sep 2016 17:37:50 +0300 Subject: QMenuBar: Get rid of QMenuBarPrivate::nativeMenuBar Instead of trying to keep that variable in sync with platformMenuBar state, just check whether platformMenuBar exists instead. Now QMenuBar::isNativeMenuBar() is more reliable, and will not return true if the QPA plugin provides no platform menu bar. Also, remove useless restrictions for code using isNativeMenuBar(). That method is available on all platforms for a long time, not only on macOS or WinCE. This makes sure local menus do not appear if global menus are available, and setVisible(true) is called. Change-Id: I7a5944c64376b4714a38ad981089df8a151c3403 Task-number: QTBUG-54793 Reviewed-by: J-P Nurmi Reviewed-by: Shawn Rutledge --- src/widgets/widgets/qmenubar.cpp | 28 ++++------------------------ src/widgets/widgets/qmenubar_p.h | 4 +--- 2 files changed, 5 insertions(+), 27 deletions(-) (limited to 'src') diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp index d7a8ecdae1..70e8d983db 100644 --- a/src/widgets/widgets/qmenubar.cpp +++ b/src/widgets/widgets/qmenubar.cpp @@ -1010,13 +1010,11 @@ void QMenuBar::paintEvent(QPaintEvent *e) */ void QMenuBar::setVisible(bool visible) { -#if defined(Q_OS_MAC) || defined(Q_OS_WINCE) if (isNativeMenuBar()) { if (!visible) QWidget::setVisible(false); return; } -#endif QWidget::setVisible(visible); } @@ -1559,11 +1557,7 @@ QRect QMenuBar::actionGeometry(QAction *act) const QSize QMenuBar::minimumSizeHint() const { Q_D(const QMenuBar); -#if defined(Q_OS_MAC) || defined(Q_OS_WINCE) const bool as_gui_menubar = !isNativeMenuBar(); -#else - const bool as_gui_menubar = true; -#endif ensurePolished(); QSize ret(0, 0); @@ -1615,12 +1609,7 @@ QSize QMenuBar::minimumSizeHint() const QSize QMenuBar::sizeHint() const { Q_D(const QMenuBar); -#if defined(Q_OS_MAC) || defined(Q_OS_WINCE) const bool as_gui_menubar = !isNativeMenuBar(); -#else - const bool as_gui_menubar = true; -#endif - ensurePolished(); QSize ret(0, 0); @@ -1673,11 +1662,7 @@ QSize QMenuBar::sizeHint() const int QMenuBar::heightForWidth(int) const { Q_D(const QMenuBar); -#if defined(Q_OS_MAC) || defined(Q_OS_WINCE) const bool as_gui_menubar = !isNativeMenuBar(); -#else - const bool as_gui_menubar = true; -#endif const_cast(d)->updateGeometries(); int height = 0; @@ -1822,10 +1807,8 @@ QWidget *QMenuBar::cornerWidget(Qt::Corner corner) const void QMenuBar::setNativeMenuBar(bool nativeMenuBar) { Q_D(QMenuBar); - if (d->nativeMenuBar == -1 || (nativeMenuBar != bool(d->nativeMenuBar))) { - d->nativeMenuBar = nativeMenuBar; - - if (!d->nativeMenuBar) { + if (nativeMenuBar != bool(d->platformMenuBar)) { + if (!nativeMenuBar) { delete d->platformMenuBar; d->platformMenuBar = 0; } else { @@ -1834,7 +1817,7 @@ void QMenuBar::setNativeMenuBar(bool nativeMenuBar) } updateGeometry(); - if (!d->nativeMenuBar && parentWidget()) + if (!nativeMenuBar && parentWidget()) setVisible(true); } } @@ -1842,10 +1825,7 @@ void QMenuBar::setNativeMenuBar(bool nativeMenuBar) bool QMenuBar::isNativeMenuBar() const { Q_D(const QMenuBar); - if (d->nativeMenuBar == -1) { - return !QApplication::instance()->testAttribute(Qt::AA_DontUseNativeMenuBar); - } - return d->nativeMenuBar; + return bool(d->platformMenuBar); } /*! diff --git a/src/widgets/widgets/qmenubar_p.h b/src/widgets/widgets/qmenubar_p.h index 7ef696f50e..1b1915843f 100644 --- a/src/widgets/widgets/qmenubar_p.h +++ b/src/widgets/widgets/qmenubar_p.h @@ -59,7 +59,7 @@ class QMenuBarPrivate : public QWidgetPrivate public: QMenuBarPrivate() : itemsDirty(0), currentAction(0), mouseDown(0), closePopupMode(0), defaultPopDown(1), popupState(0), keyboardState(0), altPressed(0), - nativeMenuBar(-1), doChildEffects(false), platformMenuBar(0) + doChildEffects(false), platformMenuBar(0) #ifdef Q_OS_WINCE , wce_menubar(0), wceClassicMenu(false) @@ -102,8 +102,6 @@ public: uint keyboardState : 1, altPressed : 1; QPointer keyboardFocusWidget; - - int nativeMenuBar : 3; // Only has values -1, 0, and 1 //firing of events void activateAction(QAction *, QAction::ActionEvent); -- cgit v1.2.3 From 63656dbed7bd2b3e35fd8f74a7fb65773baecdd5 Mon Sep 17 00:00:00 2001 From: Dmitry Shachnev Date: Fri, 9 Sep 2016 11:39:10 +0300 Subject: dbustray: Delete m_notifier in QDBusTrayIcon::cleanup() This fixes a bug where notificationClosed() and actionInvoked() slots were called more than once, from previous alive notifier instances. Change-Id: I4cb4dfc27ee129bc5282fbd8e0961959d0765112 Reviewed-by: Shawn Rutledge --- src/platformsupport/dbustray/qdbustrayicon.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/platformsupport/dbustray/qdbustrayicon.cpp b/src/platformsupport/dbustray/qdbustrayicon.cpp index 4d6e70720d..859047424d 100644 --- a/src/platformsupport/dbustray/qdbustrayicon.cpp +++ b/src/platformsupport/dbustray/qdbustrayicon.cpp @@ -118,6 +118,8 @@ void QDBusTrayIcon::cleanup() dBusConnection()->unregisterTrayIcon(this); delete m_dbusConnection; m_dbusConnection = Q_NULLPTR; + delete m_notifier; + m_notifier = Q_NULLPTR; m_registered = false; } -- cgit v1.2.3 From 5ca9631d3a0717afb066471ed5eb3b3ed9a9c08a Mon Sep 17 00:00:00 2001 From: Dmitry Shachnev Date: Wed, 7 Sep 2016 17:19:19 +0300 Subject: =?UTF-8?q?dbusmenu:=20Don=E2=80=99t=20leave=20dangling=20pointers?= =?UTF-8?q?=20when=20menus=20are=20destroyed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Delete references from menu to its containing item, and vice versa. Fixes https://launchpad.net/bugs/1620937 Task-number: QTBUG-55966 Change-Id: I58f0f0a90184bee4b0466c28d91c670a34fa65a5 Reviewed-by: Shawn Rutledge --- src/platformsupport/dbusmenu/qdbusplatformmenu.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src') diff --git a/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp b/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp index 5c259d5b67..a5ee52e73c 100644 --- a/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp +++ b/src/platformsupport/dbusmenu/qdbusplatformmenu.cpp @@ -60,6 +60,8 @@ QDBusPlatformMenuItem::QDBusPlatformMenuItem(quintptr tag) QDBusPlatformMenuItem::~QDBusPlatformMenuItem() { menuItemsByID.remove(m_dbusID); + if (m_subMenu) + static_cast(m_subMenu)->setContainingMenuItem(Q_NULLPTR); } void QDBusPlatformMenuItem::setTag(quintptr tag) @@ -162,6 +164,8 @@ QDBusPlatformMenu::QDBusPlatformMenu(quintptr tag) QDBusPlatformMenu::~QDBusPlatformMenu() { + if (m_containingMenuItem) + m_containingMenuItem->setMenu(Q_NULLPTR); } void QDBusPlatformMenu::insertMenuItem(QPlatformMenuItem *menuItem, QPlatformMenuItem *before) -- cgit v1.2.3 From 0dedb603857532b213936c36a1c9e61ba6d3f503 Mon Sep 17 00:00:00 2001 From: Victor Kropp Date: Thu, 4 Aug 2016 16:42:46 +0200 Subject: Save temp icon in higher resolution on HiDPI screens In case temporary system tray icon is saved to /tmp, scale it according to current devicePixelRatio() instead of using hardcoded 22x22. Change-Id: I2adf2151da3241f4600f8645e323346daabcec4b Reviewed-by: Shawn Rutledge --- src/platformsupport/dbustray/qdbustrayicon.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/platformsupport/dbustray/qdbustrayicon.cpp b/src/platformsupport/dbustray/qdbustrayicon.cpp index da368bf9b7..33e320ad6d 100644 --- a/src/platformsupport/dbustray/qdbustrayicon.cpp +++ b/src/platformsupport/dbustray/qdbustrayicon.cpp @@ -161,9 +161,10 @@ QTemporaryFile *QDBusTrayIcon::tempIcon(const QIcon &icon) } if (!necessary) return Q_NULLPTR; + qreal dpr = qGuiApp->devicePixelRatio(); QTemporaryFile *ret = new QTemporaryFile(TempFileTemplate, this); ret->open(); - icon.pixmap(QSize(22, 22)).save(ret); + icon.pixmap(QSize(22 * dpr, 22 * dpr)).save(ret); ret->close(); return ret; } -- cgit v1.2.3 From c3084f101d5ebb0719b2575663d2d3fdb9266005 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Tue, 13 Sep 2016 14:37:19 +0200 Subject: iOS: accept window modal message dialogs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Although we cannot really show anything but application modal dialogs on iOS, falling back to using non-native dialogs for window modal seems unnecessary strict; In practice you will never have a work flow on iOS where you have several windows visible, and at the same time, need to show a dialog that blocks only one of them. This patch will lift the restriction, and handle window modal as application modal on iOS. Task-number: QTBUG-55909 Change-Id: I581c1a47724ee2bfc2e041672c82c25ed34b2b2d Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosmessagedialog.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/plugins/platforms/ios/qiosmessagedialog.mm b/src/plugins/platforms/ios/qiosmessagedialog.mm index ac04bf88e1..50d5442f17 100644 --- a/src/plugins/platforms/ios/qiosmessagedialog.mm +++ b/src/plugins/platforms/ios/qiosmessagedialog.mm @@ -108,7 +108,7 @@ bool QIOSMessageDialog::show(Qt::WindowFlags windowFlags, Qt::WindowModality win Q_UNUSED(windowFlags); if (m_alertController // Ensure that the dialog is not showing already || !options() // Some message dialogs don't have options (QErrorMessage) - || windowModality != Qt::ApplicationModal // We can only do app modal dialogs + || windowModality == Qt::NonModal // We can only do modal dialogs || QSysInfo::MacintoshVersion < QSysInfo::MV_IOS_8_0) // API limitation return false; -- cgit v1.2.3 From 9ff7e7df0ff70f6ff576a9170e6f6c7a5bfce6f2 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Fri, 9 Sep 2016 13:53:23 +0200 Subject: winrt: Fix touch on Hololens The pressure indicator is not handled for touch on the Hololens causing touch heuristic to fail and not identify the press event. Change-Id: I2aba95fde8aa9abfa3838cad6b3466ff8bc41811 Reviewed-by: Oliver Wolff --- src/plugins/platforms/winrt/qwinrtscreen.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src') diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp index ad32c046df..849acc2d3f 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.cpp +++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp @@ -1094,6 +1094,12 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args) properties->get_IsLeftButtonPressed(&isPressed); // IsInContact not reliable on phone #endif + // Devices like the Hololens set a static pressure of 0.5 independent + // of the pressed state. In those cases we need to synthesize the + // pressure value. To our knowledge this does not apply to pens + if (pointerDeviceType == PointerDeviceType_Touch && pressure == 0.5f) + pressure = isPressed ? 1. : 0.; + const QRectF areaRect(area.X * d->scaleFactor, area.Y * d->scaleFactor, area.Width * d->scaleFactor, area.Height * d->scaleFactor); -- cgit v1.2.3 From 43d935aa2d0fd5749fea717d4aa576cf52a05c5a Mon Sep 17 00:00:00 2001 From: Shawn Rutledge Date: Wed, 14 Sep 2016 13:36:06 +0200 Subject: QMenuBar: improve documentation of the D-Bus unified menu bar Since 5.7.0 this is not just a macOS feature. It's also not necessarily limited to Ubuntu Unity, since the specification is open, and there's work in progress to implement it on KDE. Also fixed a couple of typos. Task-number: QTBUG-54793 Change-Id: Idbc68ddafff4dea30649e634ca29f10703f60d3b Reviewed-by: Jake Petroules --- src/widgets/widgets/qmenubar.cpp | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp index b6597df47c..0e7b25f65d 100644 --- a/src/widgets/widgets/qmenubar.cpp +++ b/src/widgets/widgets/qmenubar.cpp @@ -616,9 +616,10 @@ void QMenuBar::initStyleOption(QStyleOptionMenuItem *option, const QAction *acti for items in the menu bar are only shown when the \uicontrol{Alt} key is pressed. - \section1 QMenuBar on \macos + \section1 QMenuBar as a Global Menu Bar - QMenuBar on \macos is a wrapper for using the system-wide menu bar. + On \macos and on certain Linux desktop environments such as + Ubuntu Unity, QMenuBar is a wrapper for using the system-wide menu bar. If you have multiple menu bars in one dialog the outermost menu bar (normally inside a widget with widget flag Qt::Window) will be used for the system-wide menu bar. @@ -661,11 +662,16 @@ void QMenuBar::initStyleOption(QStyleOptionMenuItem *option, const QAction *acti as its parent. That menu bar would only be displayed for the parent QMainWindow. - \b{Note:} The text used for the application name in the menu + \b{Note:} The text used for the application name in the \macos menu bar is obtained from the value set in the \c{Info.plist} file in the application's bundle. See \l{Qt for macOS - Deployment} for more information. + \b{Note:} On Linux, if the com.canonical.AppMenu.Registrar + service is available on the D-Bus session bus, then Qt will + communicate with it to install the application's menus into the + global menu bar, as described. + \section1 Examples The \l{mainwindows/menus}{Menus} example shows how to use QMenuBar @@ -1809,14 +1815,16 @@ QWidget *QMenuBar::cornerWidget(Qt::Corner corner) const \brief Whether or not a menubar will be used as a native menubar on platforms that support it \since 4.6 - This property specifies whether or not the menubar should be used as a native menubar on \macos. + This property specifies whether or not the menubar should be used as a native menubar on + platforms that support it. The currently supported platforms are \macos, and + Linux desktops which use the com.canonical.dbusmenu D-Bus interface (such as Ubuntu Unity). If this property is \c true, the menubar is used in the native menubar and is not in the window of - its parent, if \c false the menubar remains in the window. On other platforms the value of this - attribute has no effect. + its parent; if \c false the menubar remains in the window. On other platforms, + setting this attribute has no effect, and reading this attribute will always return \c false. The default is to follow whether the Qt::AA_DontUseNativeMenuBar attribute - is set for the application. Explicitly settings this property overrides - the presence (or abscence) of the attribute. + is set for the application. Explicitly setting this property overrides + the presence (or absence) of the attribute. */ void QMenuBar::setNativeMenuBar(bool nativeMenuBar) -- cgit v1.2.3 From c59c759fcccd17b06255e7062cc1ceb532912a8a Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 15 Sep 2016 09:07:53 -0700 Subject: Suppress ICC warning #111 about unreachable code in toWCharArray qstring.h(961): warning #111: statement is unreachable Change-Id: I33dc971f005a4848bb8ffffd14748ae03dadefc9 Reviewed-by: Marc Mutz --- src/corelib/tools/qstring.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src') diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h index 58ad2caa2b..4863b1d2c5 100644 --- a/src/corelib/tools/qstring.h +++ b/src/corelib/tools/qstring.h @@ -947,6 +947,7 @@ inline QString QString::section(QChar asep, int astart, int aend, SectionFlags a QT_WARNING_PUSH QT_WARNING_DISABLE_MSVC(4127) // "conditional expression is constant" +QT_WARNING_DISABLE_INTEL(111) // "statement is unreachable" inline int QString::toWCharArray(wchar_t *array) const { -- cgit v1.2.3 From 469d68b344380c1a9ccef95bb784b39a436a7634 Mon Sep 17 00:00:00 2001 From: Sune Vuorela Date: Sun, 4 Sep 2016 14:59:37 +0200 Subject: Fix handling of bad compose table MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The ASAN talk at QtCon was pointing out a out of bound read in a vector. Let's try to do something about it. If the lazy initialization of compose table fails, the first character handling still tries to actually access it. Later characters are properly handled in the caller. Reported-by: Hanno Böck Change-Id: Ieac3e95361abd0fcd06c555bcd00ca1c4d8f1931 Reviewed-by: Thiago Macieira --- .../compose/qcomposeplatforminputcontext.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp index d1bea9af23..fb40480203 100644 --- a/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp +++ b/src/plugins/platforminputcontexts/compose/qcomposeplatforminputcontext.cpp @@ -162,11 +162,19 @@ bool QComposeInputContext::checkComposeTable() TableGenerator reader; m_tableState = reader.tableState(); - if ((m_tableState & TableGenerator::NoErrors) == TableGenerator::NoErrors) - m_composeTable = reader.composeTable(); - m_compositionTableInitialized = true; + if ((m_tableState & TableGenerator::NoErrors) == TableGenerator::NoErrors) { + m_composeTable = reader.composeTable(); + } else { +#ifdef DEBUG_COMPOSING + qDebug( "### FAILED_PARSING ###" ); +#endif + // if we have errors, don' try to look things up anyways. + reset(); + return false; + } } + Q_ASSERT(!m_composeTable.isEmpty()); QVector::const_iterator it = std::lower_bound(m_composeTable.constBegin(), m_composeTable.constEnd(), m_composeBuffer, Compare()); -- cgit v1.2.3 From 8ceab12814a7437a01d917c83ec28fd6e81c459e Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 8 Sep 2016 13:56:16 -0700 Subject: Fake exporting of the QDBusUtil namespace It's a namespace containing only private things, but some of those get used in some QtDBus tools. By adding a macro that expands to nothing, findclasslist.pl will notice the namespace and add it to the ELF version script. Task-number: QTBUG-55897 Change-Id: I371f5b01e24a4d56b304fffd1472748cde56f0c3 Reviewed-by: Oswald Buddenhagen --- src/dbus/qdbusutil_p.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/dbus/qdbusutil_p.h b/src/dbus/qdbusutil_p.h index e11fe573b5..4331fdb1d1 100644 --- a/src/dbus/qdbusutil_p.h +++ b/src/dbus/qdbusutil_p.h @@ -64,7 +64,8 @@ QT_BEGIN_NAMESPACE -namespace QDBusUtil +#define Q_DBUS_NO_EXPORT // force findclasslist.pl looking into this namespace +namespace Q_DBUS_NO_EXPORT QDBusUtil { Q_DBUS_EXPORT bool isValidInterfaceName(const QString &ifaceName); -- cgit v1.2.3 From ebf0b121084822ce754c14ed7255bde0f90bf42f Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Tue, 6 Sep 2016 11:41:00 -0700 Subject: Make QDBusConnectionPrivate::relaySignal be called in the right thread This function sends D-Bus messages directly (in huntAndEmit), so it should only be called from the QDBusConnectionManager thread. Somehow, I missed this in the Qt 5.6 refactoring of QtDBus. Being called in the wrong thread means that there's a visible behavior change compared to Qt 5.5: if the user code sent a method call or method return/error and then emitted a signal, we'd have two threads racing to send the D-Bus messages. This was observed in Telepathy-Qt code: certain signals arrived before a method return, even though they were clearly emitted by a queued QMetaObject::invokeMethod. In addition to that, we have has an internal problem (though not observed): the libdbus-1 timer and socket callbacks would be called in the wrong thread and we no longer have protection against that. Unit testing not possible since this is a race condition. Change-Id: I9e96ecd4f6aa4ff0ae08fffd1471d002142613d6 Reviewed-by: Gustavo Pichorim Boiko Reviewed-by: Alex Blasche --- src/dbus/qdbusintegrator.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index 878a58294c..c2cf7f41e4 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -1257,6 +1257,7 @@ void QDBusConnectionPrivate::relaySignal(QObject *obj, const QMetaObject *mo, in break; } + checkThread(); QDBusReadLocker locker(RelaySignalAction, this); QDBusMessage message = QDBusMessage::createSignal(QLatin1String("/"), interface, QLatin1String(memberName)); @@ -2368,12 +2369,9 @@ void QDBusConnectionPrivate::registerObject(const ObjectTreeNode *node) connector->connectAllSignals(node->obj); } - // disconnect and reconnect to avoid duplicates - connector->disconnect(SIGNAL(relaySignal(QObject*,const QMetaObject*,int,QVariantList)), - this, SLOT(relaySignal(QObject*,const QMetaObject*,int,QVariantList))); connect(connector, SIGNAL(relaySignal(QObject*,const QMetaObject*,int,QVariantList)), this, SLOT(relaySignal(QObject*,const QMetaObject*,int,QVariantList)), - Qt::DirectConnection); + Qt::ConnectionType(Qt::QueuedConnection | Qt::UniqueConnection)); } } -- cgit v1.2.3 From 2ccf6c60d993714ed8efbb860dd03bc07db197ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lo=C3=AFc=20Molinari?= Date: Thu, 1 Sep 2016 19:13:32 +0200 Subject: Fix the GCC version supporting -Wsuggest-override Q_CC_GNU is (__GNUC__ * 100 + __GNUC_MINOR__), so 510 is 5.10 not 5.1.0. The first GCC 5 release has support for -Wsuggest-override, so it should really be 501. Change-Id: I7b264af087cd4562ce8720c99b70116d7654ea5f Reviewed-by: Thiago Macieira --- src/corelib/kernel/qobjectdefs.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/corelib/kernel/qobjectdefs.h b/src/corelib/kernel/qobjectdefs.h index 0a4492dcda..3c6ecf7c9e 100644 --- a/src/corelib/kernel/qobjectdefs.h +++ b/src/corelib/kernel/qobjectdefs.h @@ -173,7 +173,7 @@ inline void qYouForgotTheQ_OBJECT_Macro(T1, T2) {} #if defined(Q_CC_CLANG) && Q_CC_CLANG >= 306 # define Q_OBJECT_NO_OVERRIDE_WARNING QT_WARNING_DISABLE_CLANG("-Winconsistent-missing-override") -#elif defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && Q_CC_GNU >= 510 +#elif defined(Q_CC_GNU) && !defined(Q_CC_INTEL) && Q_CC_GNU >= 501 # define Q_OBJECT_NO_OVERRIDE_WARNING QT_WARNING_DISABLE_GCC("-Wsuggest-override") #else # define Q_OBJECT_NO_OVERRIDE_WARNING -- cgit v1.2.3 From f1e87dc9bcc1f9d12183736dfa29a46df5930088 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Thu, 15 Sep 2016 15:25:01 +0200 Subject: QTableGenerator: Fix uninit'ed values It's probably benign, but it causes Corverity to complain, so always init all fields of QComposeCacheFileHeader. Format the code so it can easily be ported to uniform init later on. Coverity-Id: 93043 Change-Id: Ifa1ccc3fa58dc813306917f216772fd24d4930c9 Reviewed-by: Thiago Macieira --- .../compose/generator/qtablegenerator.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp index 44f1d7e6ba..338c7ca3be 100644 --- a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp +++ b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp @@ -106,15 +106,15 @@ static QByteArray localHostName() */ static QComposeCacheFileHeader readFileMetadata(const QString &path) { - QComposeCacheFileHeader info; - info.reserved = 0; - info.fileSize = 0; + quint64 fileSize = 0; + qint64 lastModified = 0; const QByteArray pathBytes = QFile::encodeName(path); QT_STATBUF st; - if (QT_STAT(pathBytes.data(), &st) != 0) - return info; - info.lastModified = st.st_mtime; - info.fileSize = st.st_size; + if (QT_STAT(pathBytes.data(), &st) == 0) { + lastModified = st.st_mtime; + fileSize = st.st_size; + } + QComposeCacheFileHeader info = { 0, 0, fileSize, lastModified }; return info; } -- cgit v1.2.3 From 2c48695f04b0f4b3b11ec037b13132b146cad082 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Thu, 15 Sep 2016 23:21:15 +0200 Subject: XCB Drop from external app: fix keyboard modifier state Fix inspired by Qt 4 sources. When we get drop events that are not coming from the same application, it's unlikely that the keyboard modifiers are in a sensible state (the usual XCB events are not sent during drag and drop), so set the keyboard modifier state explicitly. Task-number: QTBUG-49645 Change-Id: I9360f2b7ffeaa5243a4dfe7ccf96df134c5d2156 Reviewed-by: Shawn Rutledge Reviewed-by: Laszlo Agocs --- src/plugins/platforms/xcb/qxcbdrag.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src') diff --git a/src/plugins/platforms/xcb/qxcbdrag.cpp b/src/plugins/platforms/xcb/qxcbdrag.cpp index f93e420bcf..acfb580b94 100644 --- a/src/plugins/platforms/xcb/qxcbdrag.cpp +++ b/src/plugins/platforms/xcb/qxcbdrag.cpp @@ -960,6 +960,9 @@ void QXcbDrag::handleDrop(QPlatformWindow *, const xcb_client_message_event_t *e } else { dropData = platformDropData(); supported_drop_actions = accepted_drop_action; + + // Drop coming from another app? Update keyboard modifiers. + QGuiApplicationPrivate::modifier_buttons = QGuiApplication::queryKeyboardModifiers(); } if (!dropData) -- cgit v1.2.3 From a95d81e786ea839e59d6d6594c7d648b78a3c226 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Thu, 8 Sep 2016 18:57:46 +0200 Subject: Q(Date|Time)+::(to|from)String(): mention relevant QLocale methods The const QString &format variants of these methods lack adequate control over the locale used; the Qt::DateFormat variants give only limited control over the format string. So reference the QLocale methods that provide the general case, in the docs of each. Also made the \sa cross-referencing among these methods a little more coherent. Task-number: QTBUG-55632 Change-Id: Icd0c8548045e74879e941ba089c3bdea78f14e34 Reviewed-by: Thiago Macieira --- src/corelib/tools/qdatetime.cpp | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index e6d0b97836..6b09b4107c 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -842,7 +842,7 @@ static QString toStringIsoDate(qint64 jd) range 0 to 9999. This restriction may apply to locale-aware formats as well, depending on the locale settings. - \sa shortDayName(), shortMonthName() + \sa fromString(), shortDayName(), shortMonthName(), QLocale::toString() */ QString QDate::toString(Qt::DateFormat format) const { @@ -918,7 +918,7 @@ QString QDate::toString(Qt::DateFormat format) const If the datetime is invalid, an empty string will be returned. - \sa QDateTime::toString(), QTime::toString(), QLocale::toString() + \sa fromString(), QDateTime::toString(), QTime::toString(), QLocale::toString() */ QString QDate::toString(const QString& format) const @@ -1185,6 +1185,8 @@ qint64 QDate::daysTo(const QDate &d) const Note for Qt::TextDate: It is recommended that you use the English short month names (e.g. "Jan"). Although localized month names can also be used, they depend on the user's locale settings. + + \sa toString(), QLocale::toDate() */ QDate QDate::fromString(const QString& string, Qt::DateFormat format) { @@ -1303,8 +1305,8 @@ QDate QDate::fromString(const QString& string, Qt::DateFormat format) \snippet code/src_corelib_tools_qdatetime.cpp 3 - \sa QDateTime::fromString(), QTime::fromString(), QDate::toString(), - QDateTime::toString(), QTime::toString() + \sa toString(), QDateTime::fromString(), QTime::fromString(), + QLocale::toDate() */ QDate QDate::fromString(const QString &string, const QString &format) @@ -1571,7 +1573,7 @@ int QTime::msec() const If the time is invalid, an empty string will be returned. - \sa QDate::toString(), QDateTime::toString() + \sa fromString(), QDate::toString(), QDateTime::toString(), QLocale::toString() */ QString QTime::toString(Qt::DateFormat format) const @@ -1644,7 +1646,7 @@ QString QTime::toString(Qt::DateFormat format) const If the time is invalid, an empty string will be returned. If \a format is empty, the default format "hh:mm:ss" is used. - \sa QDate::toString(), QDateTime::toString(), QLocale::toString() + \sa fromString(), QDate::toString(), QDateTime::toString(), QLocale::toString() */ QString QTime::toString(const QString& format) const { @@ -1929,6 +1931,8 @@ static QTime fromIsoTimeString(const QStringRef &string, Qt::DateFormat format, this may result in two conversion attempts (if the conversion fails for the default locale). This should be considered an implementation detail. + + \sa toString(), QLocale::toTime() */ QTime QTime::fromString(const QString& string, Qt::DateFormat format) { @@ -2002,8 +2006,8 @@ QTime QTime::fromString(const QString& string, Qt::DateFormat format) \snippet code/src_corelib_tools_qdatetime.cpp 8 - \sa QDateTime::fromString(), QDate::fromString(), QDate::toString(), - QDateTime::toString(), QTime::toString() + \sa toString(), QDateTime::fromString(), QDate::fromString(), + QLocale::toTime() */ QTime QTime::fromString(const QString &string, const QString &format) @@ -3520,7 +3524,8 @@ void QDateTime::setTime_t(uint secsSince1Jan1970UTC) range 0 to 9999. This restriction may apply to locale-aware formats as well, depending on the locale settings. - \sa QDate::toString(), QTime::toString(), Qt::DateFormat + \sa fromString(), QDate::toString(), QTime::toString(), + QLocale::toString() */ QString QDateTime::toString(Qt::DateFormat format) const @@ -3660,7 +3665,7 @@ QString QDateTime::toString(Qt::DateFormat format) const If the datetime is invalid, an empty string will be returned. - \sa QDate::toString(), QTime::toString(), QLocale::toString() + \sa fromString(), QDate::toString(), QTime::toString(), QLocale::toString() */ QString QDateTime::toString(const QString& format) const { @@ -4356,6 +4361,8 @@ int QDateTime::utcOffset() const Note for Qt::TextDate: It is recommended that you use the English short month names (e.g. "Jan"). Although localized month names can also be used, they depend on the user's locale settings. + + \sa toString(), QLocale::toDateTime() */ QDateTime QDateTime::fromString(const QString& string, Qt::DateFormat format) { @@ -4657,8 +4664,8 @@ QDateTime QDateTime::fromString(const QString& string, Qt::DateFormat format) \snippet code/src_corelib_tools_qdatetime.cpp 14 - \sa QDate::fromString(), QTime::fromString(), QDate::toString(), - QDateTime::toString(), QTime::toString() + \sa toString(), QDate::fromString(), QTime::fromString(), + QLocale::toDateTime() */ QDateTime QDateTime::fromString(const QString &string, const QString &format) -- cgit v1.2.3 From 71e195f6ef2f4ba1822353fd46124b166187c70f Mon Sep 17 00:00:00 2001 From: James McDonnell Date: Thu, 25 Aug 2016 10:55:35 -0400 Subject: Reverse the flush-screen-context test It was backwards so the screen context was being flushed on every screen interaction when the parameter was _not_ specified. During mouse/touch movement, the number of flushes can be so great that it negatively impacts performance. Change-Id: I4dfe9c33c8ce31237db1d78db1cb8e04c00c4dd3 Reviewed-by: Dan Cape Reviewed-by: Rafael Roquetto --- src/plugins/platforms/qnx/qqnxintegration.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/plugins/platforms/qnx/qqnxintegration.cpp b/src/plugins/platforms/qnx/qqnxintegration.cpp index 6548c82310..621a96a3cf 100644 --- a/src/plugins/platforms/qnx/qqnxintegration.cpp +++ b/src/plugins/platforms/qnx/qqnxintegration.cpp @@ -116,7 +116,7 @@ static inline QQnxIntegration::Options parseOptions(const QStringList ¶mList options |= QQnxIntegration::FullScreenApplication; } - if (!paramList.contains(QLatin1String("flush-screen-context"))) { + if (paramList.contains(QLatin1String("flush-screen-context"))) { options |= QQnxIntegration::AlwaysFlushScreenContext; } -- cgit v1.2.3 From 8a2401bd45bb5991cf4c6a69539cb58f72e19994 Mon Sep 17 00:00:00 2001 From: James McDonnell Date: Tue, 26 Jul 2016 16:33:47 -0400 Subject: Switch to 7.0 screen property names The names of some screen properties have changed in 7.0. For 6.6, map the 7.0 names to 6.6 names. Change-Id: Iaf9d297fdd6a0329a84150f2b9a27665d89cc1ec Reviewed-by: Dan Cape Reviewed-by: Rafael Roquetto --- src/plugins/platforms/qnx/qqnxscreen.h | 11 +++++++++++ src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp | 12 ++++++------ src/plugins/platforms/qnx/qqnxwindow.cpp | 2 +- 3 files changed, 18 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/qnx/qqnxscreen.h b/src/plugins/platforms/qnx/qqnxscreen.h index 00176ac32c..8a6e2bbcac 100644 --- a/src/plugins/platforms/qnx/qqnxscreen.h +++ b/src/plugins/platforms/qnx/qqnxscreen.h @@ -43,6 +43,17 @@ #include +// For pre-7.0 SDPs, map some screen property names to the old +// names. +#include +#if _NTO_VERSION < 700 +const int SCREEN_PROPERTY_FLAGS = SCREEN_PROPERTY_KEY_FLAGS; +const int SCREEN_PROPERTY_FOCUS = SCREEN_PROPERTY_KEYBOARD_FOCUS; +const int SCREEN_PROPERTY_MODIFIERS = SCREEN_PROPERTY_KEY_MODIFIERS; +const int SCREEN_PROPERTY_SCAN = SCREEN_PROPERTY_KEY_SCAN; +const int SCREEN_PROPERTY_SYM = SCREEN_PROPERTY_KEY_SYM; +#endif + QT_BEGIN_NAMESPACE class QQnxWindow; diff --git a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp index 6c9532c428..09585b1aac 100644 --- a/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp +++ b/src/plugins/platforms/qnx/qqnxscreeneventhandler.cpp @@ -233,20 +233,20 @@ void QQnxScreenEventHandler::handleKeyboardEvent(screen_event_t event) { // get flags of key event int flags; - Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_FLAGS, &flags), + Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_FLAGS, &flags), "Failed to query event flags"); // get key code int sym; - Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_SYM, &sym), + Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_SYM, &sym), "Failed to query event sym"); int modifiers; - Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_MODIFIERS, &modifiers), + Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_MODIFIERS, &modifiers), "Failed to query event modifieres"); int scan; - Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_KEY_SCAN, &scan), + Q_SCREEN_CHECKERROR(screen_get_event_property_iv(event, SCREEN_PROPERTY_SCAN, &scan), "Failed to query event scan"); int cap; @@ -593,7 +593,7 @@ void QQnxScreenEventHandler::handlePropertyEvent(screen_event_t event) qFatal("QQnx: failed to query window property, errno=%d", errno); switch (property) { - case SCREEN_PROPERTY_KEYBOARD_FOCUS: + case SCREEN_PROPERTY_FOCUS: handleKeyboardFocusPropertyEvent(window); break; default: @@ -606,7 +606,7 @@ void QQnxScreenEventHandler::handleKeyboardFocusPropertyEvent(screen_window_t wi { errno = 0; int focus = 0; - if (window && screen_get_window_property_iv(window, SCREEN_PROPERTY_KEYBOARD_FOCUS, &focus) != 0) + if (window && screen_get_window_property_iv(window, SCREEN_PROPERTY_FOCUS, &focus) != 0) qFatal("QQnx: failed to query keyboard focus property, errno=%d", errno); QWindow *focusWindow = QQnxIntegration::window(window); diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp index da2929d4c0..bb95342726 100644 --- a/src/plugins/platforms/qnx/qqnxwindow.cpp +++ b/src/plugins/platforms/qnx/qqnxwindow.cpp @@ -581,7 +581,7 @@ void QQnxWindow::setFocus(screen_window_t newFocusWindow) screen_get_window_property_pv(nativeHandle(), SCREEN_PROPERTY_GROUP, reinterpret_cast(&screenGroup)); if (screenGroup) { - screen_set_group_property_pv(screenGroup, SCREEN_PROPERTY_KEYBOARD_FOCUS, + screen_set_group_property_pv(screenGroup, SCREEN_PROPERTY_FOCUS, reinterpret_cast(&newFocusWindow)); } } -- cgit v1.2.3 From 597d625c2cd87fec870a23ea3c57eb0a106c993e Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 15 Sep 2016 09:11:19 -0700 Subject: Disable forcing of -fomit-frame-pointer with ICC qlogging.cpp(1226): error #3175: unrecognized gcc optimization level __attribute__((optimize("omit-frame-pointer"))) ^ Change-Id: I33dc971f005a4848bb8ffffd14748b100dcefa95 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/global/qlogging.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp index 49a8aa0df1..5842b26ecb 100644 --- a/src/corelib/global/qlogging.cpp +++ b/src/corelib/global/qlogging.cpp @@ -1197,7 +1197,8 @@ void QMessagePattern::setPattern(const QString &pattern) #if defined(QLOGGING_HAVE_BACKTRACE) && !defined(QT_BOOTSTRAPPED) // make sure the function has "Message" in the name so the function is removed -#if (defined(Q_CC_GNU) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS)) || QT_HAS_ATTRIBUTE(optimize) +#if ((defined(Q_CC_GNU) && defined(QT_COMPILER_SUPPORTS_SIMD_ALWAYS)) || QT_HAS_ATTRIBUTE(optimize)) \ + && !defined(Q_CC_INTEL) // force skipping the frame pointer, to save the backtrace() function some work __attribute__((optimize("omit-frame-pointer"))) #endif -- cgit v1.2.3 From 734da261a8283701a25c1690c5270ba70c8d0a37 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Thu, 8 Sep 2016 12:45:20 +0300 Subject: Android: Don't hang when resuming the application If the main thread is blocked updateApplicationState will hang. It happens when we're using functions like runOnAndroidThreadSync or requestPermissionsSync. Change-Id: Ic1135c5630b48cf1076ef5cbc133933fce439bfb Reviewed-by: Alex Blasche --- src/plugins/platforms/android/androidjnimain.cpp | 5 ----- 1 file changed, 5 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp index 677a2e2626..c79198d7fe 100644 --- a/src/plugins/platforms/android/androidjnimain.cpp +++ b/src/plugins/platforms/android/androidjnimain.cpp @@ -672,11 +672,6 @@ static void updateApplicationState(JNIEnv */*env*/, jobject /*thiz*/, jint state QAndroidEventDispatcherStopper::instance()->goingToStop(true); QCoreApplication::processEvents(); QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationState(state)); - { - AndroidDeadlockProtector protector; - if (protector.acquire()) - QWindowSystemInterface::flushWindowSystemEvents(); - } if (state == Qt::ApplicationSuspended) QAndroidEventDispatcherStopper::instance()->stopAll(); } else { -- cgit v1.2.3 From 8d64d1e0c3f7ebcee859e8b5f40aa27a8df86351 Mon Sep 17 00:00:00 2001 From: Albert Astals Cid Date: Tue, 31 May 2016 01:13:03 +0200 Subject: xcb: Do not eat events with different keyboard state Change-Id: Iac8dc7b369eb7c2fbe0cf27baa34a40278088219 Reviewed-by: Frederik Gladhorn Reviewed-by: Gatis Paeglis --- src/plugins/platforms/xcb/qxcbkeyboard.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp index 811ef4251a..bb7d5c714a 100644 --- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp +++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp @@ -1393,10 +1393,11 @@ void QXcbKeyboard::resolveMaskConflicts() class KeyChecker { public: - KeyChecker(xcb_window_t window, xcb_keycode_t code, xcb_timestamp_t time) + KeyChecker(xcb_window_t window, xcb_keycode_t code, xcb_timestamp_t time, quint16 state) : m_window(window) , m_code(code) , m_time(time) + , m_state(state) , m_error(false) , m_release(true) { @@ -1413,7 +1414,7 @@ public: xcb_key_press_event_t *event = (xcb_key_press_event_t *)ev; - if (event->event != m_window || event->detail != m_code) { + if (event->event != m_window || event->detail != m_code || event->state != m_state) { m_error = true; return false; } @@ -1441,6 +1442,7 @@ private: xcb_window_t m_window; xcb_keycode_t m_code; xcb_timestamp_t m_time; + quint16 m_state; bool m_error; bool m_release; @@ -1505,7 +1507,7 @@ void QXcbKeyboard::handleKeyEvent(xcb_window_t sourceWindow, QEvent::Type type, } } else { // look ahead for auto-repeat - KeyChecker checker(source->xcb_window(), code, time); + KeyChecker checker(source->xcb_window(), code, time, state); xcb_generic_event_t *event = connection()->checkEvent(checker); if (event) { isAutoRepeat = true; -- cgit v1.2.3