From bc410cc706e107881d3ee982287441993cabb8a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= Date: Mon, 1 Feb 2016 11:49:02 +0100 Subject: QtWidgets: Reduce paint events when resizing native widget This patch reduces paint events by removing code which sets native widgets dirty in QWidgetWindow::handleExposeEvent. Native widgets are also marked dirty in QWidgetPrivate::drawWidget, so it is enough for proper painting. This restores Qt4 behavior when one resize means one repaint for native widgets. Without this patch the native widget is marked as dirty on every expose event, so one repaint is from syncBackingStore and second (or more) is from marking the widget dirty explicitly. This patch improves performance of native widgets and it also reduces locks when paint event is v-synced, e.g. on OpenGL swap buffers or on any other technology like VDPAU, VA-API, etc. Added autotest for checking number of paint events for native widgets. Task-number: QTBUG-50796 Change-Id: I4e1649069e2e73d15b038fd1834d0551915252ee Reviewed-by: Friedemann Kleint --- src/widgets/kernel/qwidgetwindow.cpp | 8 +------- .../kernel/qwidget_window/tst_qwidget_window.cpp | 24 ++++++++++++++++++++++ 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/widgets/kernel/qwidgetwindow.cpp b/src/widgets/kernel/qwidgetwindow.cpp index 5290d79d9e..872572a7e2 100644 --- a/src/widgets/kernel/qwidgetwindow.cpp +++ b/src/widgets/kernel/qwidgetwindow.cpp @@ -873,14 +873,8 @@ void QWidgetWindow::handleExposeEvent(QExposeEvent *event) { if (isExposed()) { m_widget->setAttribute(Qt::WA_Mapped); - if (!event->region().isNull()) { - // Exposed native widgets need to be marked dirty to get them repainted correctly. - if (m_widget->internalWinId() && !m_widget->isWindow() && m_widget->isVisible() && m_widget->updatesEnabled()) { - if (QWidgetBackingStore *bs = m_widget->d_func()->maybeBackingStore()) - bs->markDirty(event->region(), m_widget); - } + if (!event->region().isNull()) m_widget->d_func()->syncBackingStore(event->region()); - } } else { m_widget->setAttribute(Qt::WA_Mapped, false); } diff --git a/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp b/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp index 27be063333..3a4b563a6c 100644 --- a/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp +++ b/tests/auto/widgets/kernel/qwidget_window/tst_qwidget_window.cpp @@ -88,6 +88,7 @@ private slots: void tst_showWithoutActivating(); void tst_paintEventOnSecondShow(); + void tst_paintEventOnResize_QTBUG50796(); #ifndef QT_NO_DRAGANDDROP void tst_dnd(); @@ -369,6 +370,29 @@ void tst_QWidget_window::tst_paintEventOnSecondShow() QTRY_VERIFY(w.paintEventCount > 0); } +void tst_QWidget_window::tst_paintEventOnResize_QTBUG50796() +{ + const QRect availableGeo = QGuiApplication::primaryScreen()->availableGeometry(); + + QWidget root; + root.setGeometry(availableGeo.width()/2 - 100, availableGeo.height()/2 - 100, + 200, 200); + + PaintTestWidget *native = new PaintTestWidget(&root); + native->winId(); // We're testing native widgets + native->setGeometry(10, 10, 50, 50); + + root.show(); + QVERIFY(QTest::qWaitForWindowExposed(&root)); + QVERIFY(QTest::qWaitForWindowActive(&root)); + QVERIFY(native->isVisible()); + + native->paintEventCount = 0; + native->resize(native->width() + 10, native->height() + 10); + QTest::qWait(50); // Wait for paint events + QTRY_COMPARE(native->paintEventCount, 1); // Only one paint event must occur +} + #ifndef QT_NO_DRAGANDDROP /* DnD test for QWidgetWindow (handleDrag*Event() functions). -- cgit v1.2.3 From dd8745e1d4beedfb8ef2e42fc10050287d3975f3 Mon Sep 17 00:00:00 2001 From: Ralf Nolden Date: Thu, 19 May 2016 07:27:39 +0200 Subject: Remove linux only-dependency from devicediscovery As libudev and libevdev have their config.tests and do work on other operating systems as well (FreeBSD, evdev), there is no need to make this exclusive for linux only. Thus, use the checks only; the else-section can go with that at the end, too. Change-Id: I2a5175a154b4f3e001bb42d187d8c7640c014049 Reviewed-by: Thiago Macieira --- .../devicediscovery/devicediscovery.pri | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/platformsupport/devicediscovery/devicediscovery.pri b/src/platformsupport/devicediscovery/devicediscovery.pri index 1ac25da901..9829ae88ba 100644 --- a/src/platformsupport/devicediscovery/devicediscovery.pri +++ b/src/platformsupport/devicediscovery/devicediscovery.pri @@ -1,18 +1,14 @@ HEADERS += $$PWD/qdevicediscovery_p.h -linux { - contains(QT_CONFIG, libudev) { - SOURCES += $$PWD/qdevicediscovery_udev.cpp - HEADERS += $$PWD/qdevicediscovery_udev_p.h - INCLUDEPATH += $$QMAKE_INCDIR_LIBUDEV - LIBS_PRIVATE += $$QMAKE_LIBS_LIBUDEV - } else: contains(QT_CONFIG, evdev) { - SOURCES += $$PWD/qdevicediscovery_static.cpp - HEADERS += $$PWD/qdevicediscovery_static_p.h - } else { - SOURCES += $$PWD/qdevicediscovery_dummy.cpp - HEADERS += $$PWD/qdevicediscovery_dummy_p.h - } +contains(QT_CONFIG, libudev) { + SOURCES += $$PWD/qdevicediscovery_udev.cpp + HEADERS += $$PWD/qdevicediscovery_udev_p.h + INCLUDEPATH += $$QMAKE_INCDIR_LIBUDEV + LIBS_PRIVATE += $$QMAKE_LIBS_LIBUDEV +} else: contains(QT_CONFIG, evdev) { + SOURCES += $$PWD/qdevicediscovery_static.cpp + HEADERS += $$PWD/qdevicediscovery_static_p.h } else { SOURCES += $$PWD/qdevicediscovery_dummy.cpp + HEADERS += $$PWD/qdevicediscovery_dummy_p.h } -- cgit v1.2.3 From e9628fbd391972d4ffe5882d283d512df7fa705c Mon Sep 17 00:00:00 2001 From: Oleksandr Tymoshenko Date: Mon, 16 May 2016 23:24:36 -0700 Subject: Fix dynamic librariy support detection for platforms without libdl Some platforms (e.g. FreeBSD) do not have libdl, but dlopen and related functions are part of libc. So first check for dlopen in libc, and only if that fails, look for it in libdl. Task-number: QTBUG-52951 Change-Id: I65a8ed18fce157da32f4e1ffeba30d7513385a8f Reviewed-by: Oswald Buddenhagen Reviewed-by: Thiago Macieira --- config.tests/unix/dlopen/dlopen.cpp | 39 +++++++++++++++++++++++++++++++++++++ config.tests/unix/dlopen/dlopen.pro | 2 ++ config.tests/unix/libdl/libdl.cpp | 39 ------------------------------------- config.tests/unix/libdl/libdl.pro | 5 ++--- configure | 8 ++++++-- 5 files changed, 49 insertions(+), 44 deletions(-) create mode 100644 config.tests/unix/dlopen/dlopen.cpp create mode 100644 config.tests/unix/dlopen/dlopen.pro delete mode 100644 config.tests/unix/libdl/libdl.cpp diff --git a/config.tests/unix/dlopen/dlopen.cpp b/config.tests/unix/dlopen/dlopen.cpp new file mode 100644 index 0000000000..28a82330f2 --- /dev/null +++ b/config.tests/unix/dlopen/dlopen.cpp @@ -0,0 +1,39 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the config.tests 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 + +int main(int, char **) +{ + dlopen(0, 0); +} diff --git a/config.tests/unix/dlopen/dlopen.pro b/config.tests/unix/dlopen/dlopen.pro new file mode 100644 index 0000000000..1d34314332 --- /dev/null +++ b/config.tests/unix/dlopen/dlopen.pro @@ -0,0 +1,2 @@ +SOURCES = $$PWD/dlopen.cpp +CONFIG -= qt dylib diff --git a/config.tests/unix/libdl/libdl.cpp b/config.tests/unix/libdl/libdl.cpp deleted file mode 100644 index 28a82330f2..0000000000 --- a/config.tests/unix/libdl/libdl.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the config.tests 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 - -int main(int, char **) -{ - dlopen(0, 0); -} diff --git a/config.tests/unix/libdl/libdl.pro b/config.tests/unix/libdl/libdl.pro index 8ed5231a8f..4016395d35 100644 --- a/config.tests/unix/libdl/libdl.pro +++ b/config.tests/unix/libdl/libdl.pro @@ -1,3 +1,2 @@ -SOURCES = libdl.cpp -CONFIG -= qt dylib -!qnx: LIBS += -ldl +include(../dlopen/dlopen.pro) +LIBS += -ldl diff --git a/configure b/configure index 7c65fbd8b5..109c0bbbac 100755 --- a/configure +++ b/configure @@ -4743,9 +4743,13 @@ if [ "$CFG_LIBPNG" = "auto" ]; then fi # detect dl -if ! compileTest unix/libdl "libdl"; then - QMakeVar add DEFINES QT_NO_DYNAMIC_LIBRARY +if compileTest unix/dlopen "dlopen"; then QMAKE_CONFIG="$QMAKE_CONFIG no-libdl" +else + if ! compileTest unix/libdl "libdl"; then + QMAKE_CONFIG="$QMAKE_CONFIG no-libdl" + QMakeVar add DEFINES QT_NO_DYNAMIC_LIBRARY + fi fi if [ "$CFG_EGLFS" = "yes" ]; then -- cgit v1.2.3 From 6086c81e4d999d88ce4d412a20d250a219ab3c2c Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 18 May 2016 11:07:04 +0200 Subject: Windows QPA: Improve workaround for non-Areo theme GL rendering. Reportedly, clearing the clip region is sufficient to fix the issue. InvalidateRect() should be avoided when handling WM_PAINT as it may cause events. Task-number: QTBUG-7865 Change-Id: Id9a7c280fcc2c8242bb34c34e73e53c3146e7a6e Reviewed-by: Andy Shaw Reviewed-by: Oliver Wolff Reviewed-by: Friedemann Kleint --- src/plugins/platforms/windows/qwindowswindow.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp index cf13de427e..9c6cb53365 100644 --- a/src/plugins/platforms/windows/qwindowswindow.cpp +++ b/src/plugins/platforms/windows/qwindowswindow.cpp @@ -1568,11 +1568,12 @@ bool QWindowsWindow::handleWmPaint(HWND hwnd, UINT message, return false; PAINTSTRUCT ps; + BeginPaint(hwnd, &ps); + // Observed painting problems with Aero style disabled (QTBUG-7865). + // 5.8: Consider making it dependent on !DwmIsCompositionEnabled(). if (testFlag(OpenGLSurface) && testFlag(OpenGLDoubleBuffered)) - InvalidateRect(hwnd, 0, false); - - BeginPaint(hwnd, &ps); + SelectClipRgn(ps.hdc, NULL); // If the a window is obscured by another window (such as a child window) // we still need to send isExposed=true, for compatibility. -- cgit v1.2.3 From eff3a7ded138e5f73fe716efae9e4bf74c71a8a4 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Tue, 17 May 2016 10:45:43 +0200 Subject: delay application of -D/-I/-L/-l on windows as well clearly, "the windows configure does not have any of this magic to start with" was flat-out wrong. Task-number: QTBUG-53312 Change-Id: I80ac10bc8b1581e61c57fcd97f25626990d120ec Reviewed-by: Konstantin Tokarev Reviewed-by: Simon Hausmann --- tools/configure/configureapp.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/configure/configureapp.cpp b/tools/configure/configureapp.cpp index a03be4df0a..0909ff8aab 100644 --- a/tools/configure/configureapp.cpp +++ b/tools/configure/configureapp.cpp @@ -2987,7 +2987,7 @@ void Configure::generateOutputVars() qtConfig += "accessibility"; if (!qmakeLibs.isEmpty()) - qmakeVars += "LIBS += " + formatPaths(qmakeLibs); + qmakeVars += "EXTRA_LIBS += " + formatPaths(qmakeLibs); if (!dictionary["QT_LFLAGS_SQLITE"].isEmpty()) qmakeVars += "QT_LFLAGS_SQLITE += " + dictionary["QT_LFLAGS_SQLITE"]; @@ -3105,9 +3105,9 @@ void Configure::generateOutputVars() qtConfig += "rpath"; if (!qmakeDefines.isEmpty()) - qmakeVars += QString("DEFINES += ") + qmakeDefines.join(' '); + qmakeVars += QString("EXTRA_DEFINES += ") + qmakeDefines.join(' '); if (!qmakeIncludes.isEmpty()) - qmakeVars += QString("INCLUDEPATH += ") + formatPaths(qmakeIncludes); + qmakeVars += QString("EXTRA_INCLUDEPATH += ") + formatPaths(qmakeIncludes); if (!opensslLibs.isEmpty()) qmakeVars += opensslLibs; if (dictionary[ "OPENSSL" ] == "linked") { -- cgit v1.2.3 From b2e9c680e3e3f446e84748fc5068d527daf10b62 Mon Sep 17 00:00:00 2001 From: Robin Burchell Date: Thu, 19 May 2016 12:37:10 +0200 Subject: qpa: Use LIBS_PRIVATE, not LIBS when linking in font database bits. LIBS_PRIVATE is more correct (these shouldn't be part of the public API), and additionally, using LIBS_PRIVATE also ensures these libraries come last on the link command, which fixes builds using -Wl,--as-needed. Change-Id: I9f2e4e78855a30a53ce9013623597b840a2832bd Reviewed-by: Oswald Buddenhagen --- mkspecs/features/qpa/basicunixfontdatabase.prf | 2 +- mkspecs/features/qpa/genericunixfontdatabase.prf | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mkspecs/features/qpa/basicunixfontdatabase.prf b/mkspecs/features/qpa/basicunixfontdatabase.prf index 261eadb5d0..f2e4016c99 100644 --- a/mkspecs/features/qpa/basicunixfontdatabase.prf +++ b/mkspecs/features/qpa/basicunixfontdatabase.prf @@ -1,3 +1,3 @@ contains(QT_CONFIG, system-freetype) { - LIBS += -lfreetype + LIBS_PRIVATE += -lfreetype } diff --git a/mkspecs/features/qpa/genericunixfontdatabase.prf b/mkspecs/features/qpa/genericunixfontdatabase.prf index fc11bea470..b0d81e5571 100644 --- a/mkspecs/features/qpa/genericunixfontdatabase.prf +++ b/mkspecs/features/qpa/genericunixfontdatabase.prf @@ -1,7 +1,7 @@ CONFIG += qpa/basicunixfontdatabase contains(QT_CONFIG, fontconfig) { DEFINES += Q_FONTCONFIGDATABASE - LIBS += -lfontconfig + LIBS_PRIVATE += -lfontconfig } else:!android { fonts.path = $$[QT_INSTALL_LIBS]/fonts fonts.files = $$QT_SOURCE_TREE/lib/fonts/* -- cgit v1.2.3 From 9c0a7cac83a511141e8dc91825dc5f9da64a1d69 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Tue, 17 May 2016 17:32:41 +0200 Subject: Doc: Fix references to QGuiApplication::clipboard() QClipboard's documentation still referred to QApplication::clipboard(), where the method was located in Qt4. Change-Id: I7fc31bacf5afa783f8ca38723773f24cd0bda347 Reviewed-by: Friedemann Kleint Reviewed-by: Leena Miettinen --- src/gui/doc/snippets/code/src_gui_kernel_qclipboard.cpp | 2 +- src/gui/kernel/qclipboard.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/gui/doc/snippets/code/src_gui_kernel_qclipboard.cpp b/src/gui/doc/snippets/code/src_gui_kernel_qclipboard.cpp index 2596845275..decfee26f6 100644 --- a/src/gui/doc/snippets/code/src_gui_kernel_qclipboard.cpp +++ b/src/gui/doc/snippets/code/src_gui_kernel_qclipboard.cpp @@ -39,7 +39,7 @@ ****************************************************************************/ //! [0] -QClipboard *clipboard = QApplication::clipboard(); +QClipboard *clipboard = QGuiApplication::clipboard(); QString originalText = clipboard->text(); ... clipboard->setText(newText); diff --git a/src/gui/kernel/qclipboard.cpp b/src/gui/kernel/qclipboard.cpp index 922c7fb8d9..817c50d9b2 100644 --- a/src/gui/kernel/qclipboard.cpp +++ b/src/gui/kernel/qclipboard.cpp @@ -61,7 +61,7 @@ QT_BEGIN_NAMESPACE Drop}. There is a single QClipboard object in an application, accessible - as QApplication::clipboard(). + as QGuiApplication::clipboard(). Example: \snippet code/src_gui_kernel_qclipboard.cpp 0 @@ -131,7 +131,7 @@ QT_BEGIN_NAMESPACE \endlist - \sa QApplication + \sa QGuiApplication */ /*! @@ -141,7 +141,7 @@ QT_BEGIN_NAMESPACE Do not call this function. - Call QApplication::clipboard() instead to get a pointer to the + Call QGuiApplication::clipboard() instead to get a pointer to the application's global clipboard object. There is only one clipboard in the window system, and creating @@ -159,7 +159,7 @@ QClipboard::QClipboard(QObject *parent) Destroys the clipboard. - You should never delete the clipboard. QApplication will do this + You should never delete the clipboard. QGuiApplication will do this when the application terminates. */ QClipboard::~QClipboard() -- cgit v1.2.3 From cdf1e67de1c462a59b71ee0b14bab73dc3391b65 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 24 Mar 2016 10:40:32 +0100 Subject: QDesktopWidget: fix tracking QScreens. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The old code failed to reliably detect new QScreens and connect their signals to its own slots. For example, if the QApplication added a new screen at the beginning of the screen list (which happens if the new screen is primary), the signal-connecting loop would actually instead add the now second screen to QDesktopWidget's list *again*, and connect its signals, but not connect any signal to the new, first screen. Furthermore, QDesktopWidget would miss geometry changes because QWidget (and hence QDesktopScreenWidget) automatically shrinks when the screen it is on gets smaller. To fix all of this, QDesktopScreenWidget now keeps its own record of the screen and its geometry, and it always scans over the entire screen list without relying on any ordering guarantees on behalf of QApplication. Change-Id: I2ee8361adf643849f43b7dd9a95966920fd13528 Task-number: QTBUG-52101 Reviewed-by: Błażej Szczygieł Reviewed-by: Marc Mutz --- src/widgets/kernel/qdesktopwidget.cpp | 99 ++++++++++++++++++++++++----------- src/widgets/kernel/qdesktopwidget_p.h | 16 ++++-- 2 files changed, 80 insertions(+), 35 deletions(-) diff --git a/src/widgets/kernel/qdesktopwidget.cpp b/src/widgets/kernel/qdesktopwidget.cpp index d1b37bc03a..e87b13c630 100644 --- a/src/widgets/kernel/qdesktopwidget.cpp +++ b/src/widgets/kernel/qdesktopwidget.cpp @@ -40,6 +40,21 @@ QT_BEGIN_NAMESPACE +QDesktopScreenWidget::QDesktopScreenWidget(QScreen *screen, const QRect &geometry) + : QWidget(Q_NULLPTR, Qt::Desktop), m_screen(screen) +{ + setVisible(false); + if (QWindow *winHandle = windowHandle()) + winHandle->setScreen(screen); + setScreenGeometry(geometry); +} + +void QDesktopScreenWidget::setScreenGeometry(const QRect &geometry) +{ + m_geometry = geometry; + setGeometry(geometry); +} + int QDesktopScreenWidget::screenNumber() const { const QDesktopWidgetPrivate *desktopWidgetP @@ -74,54 +89,76 @@ const QRect QDesktopWidget::availableGeometry(const QWidget *widget) const return rect; } +QDesktopScreenWidget *QDesktopWidgetPrivate::widgetForScreen(QScreen *qScreen) const +{ + foreach (QDesktopScreenWidget *widget, screens) { + if (widget->screen() == qScreen) + return widget; + } + return Q_NULLPTR; +} + void QDesktopWidgetPrivate::_q_updateScreens() { Q_Q(QDesktopWidget); const QList screenList = QGuiApplication::screens(); const int targetLength = screenList.length(); - const int oldLength = screens.length(); - - // Add or remove screen widgets as necessary - while (screens.size() > targetLength) - delete screens.takeLast(); - - for (int currentLength = screens.size(); currentLength < targetLength; ++currentLength) { - QScreen *qScreen = screenList.at(currentLength); - QDesktopScreenWidget *screenWidget = new QDesktopScreenWidget; - screenWidget->setGeometry(qScreen->geometry()); - QObject::connect(qScreen, SIGNAL(geometryChanged(QRect)), - q, SLOT(_q_updateScreens()), Qt::QueuedConnection); - QObject::connect(qScreen, SIGNAL(availableGeometryChanged(QRect)), - q, SLOT(_q_availableGeometryChanged()), Qt::QueuedConnection); - QObject::connect(qScreen, SIGNAL(destroyed()), - q, SLOT(_q_updateScreens()), Qt::QueuedConnection); - screens.append(screenWidget); - } + bool screenCountChanged = false; + // Re-build our screens list. This is the easiest way to later compute which signals to emit. + // Create new screen widgets as necessary. While iterating, keep the old list in place so + // that widgetForScreen works. + // Furthermore, we note which screens have changed, and compute the overall virtual geometry. + QList newScreens; + QList changedScreens; QRegion virtualGeometry; - // update the geometry of each screen widget, determine virtual geometry, - // set the new screen for window handle and emit change signals afterwards. - QList changedScreens; - for (int i = 0; i < screens.length(); i++) { - QDesktopScreenWidget *screenWidget = screens.at(i); + for (int i = 0; i < targetLength; ++i) { QScreen *qScreen = screenList.at(i); - QWindow *winHandle = screenWidget->windowHandle(); - if (winHandle && winHandle->screen() != qScreen) - winHandle->setScreen(qScreen); const QRect screenGeometry = qScreen->geometry(); - if (screenGeometry != screenWidget->geometry()) { - screenWidget->setGeometry(screenGeometry); - changedScreens.push_back(i); + QDesktopScreenWidget *screenWidget = widgetForScreen(qScreen); + if (screenWidget) { + // an old screen. update geometry and remember the index in the *new* list + if (screenGeometry != screenWidget->screenGeometry()) { + screenWidget->setScreenGeometry(screenGeometry); + changedScreens.push_back(i); + } + } else { + // a new screen, create a widget and connect the signals. + screenWidget = new QDesktopScreenWidget(qScreen, screenGeometry); + QObject::connect(qScreen, SIGNAL(geometryChanged(QRect)), + q, SLOT(_q_updateScreens()), Qt::QueuedConnection); + QObject::connect(qScreen, SIGNAL(availableGeometryChanged(QRect)), + q, SLOT(_q_availableGeometryChanged()), Qt::QueuedConnection); + QObject::connect(qScreen, SIGNAL(destroyed()), + q, SLOT(_q_updateScreens()), Qt::QueuedConnection); + screenCountChanged = true; } + // record all the screens and the overall geometry. + newScreens.push_back(screenWidget); virtualGeometry += screenGeometry; } + // Now we apply the accumulated updates. + screens.swap(newScreens); // now [newScreens] is the old screen list + Q_ASSERT(screens.size() == targetLength); q->setGeometry(virtualGeometry.boundingRect()); - if (oldLength != targetLength) - emit q->screenCountChanged(targetLength); + // Delete the QDesktopScreenWidget that are not used any more. + foreach (QDesktopScreenWidget *screen, newScreens) { + if (!screens.contains(screen)) { + delete screen; + screenCountChanged = true; + } + } + // Finally, emit the signals. + if (screenCountChanged) { + // Notice that we trigger screenCountChanged even if a screen was removed and another one added, + // in which case the total number of screens did not change. This is the only way for applications + // to notice that a screen was swapped out against another one. + emit q->screenCountChanged(targetLength); + } foreach (int changedScreen, changedScreens) emit q->resized(changedScreen); } diff --git a/src/widgets/kernel/qdesktopwidget_p.h b/src/widgets/kernel/qdesktopwidget_p.h index 1fcad7fa65..d5ae629c64 100644 --- a/src/widgets/kernel/qdesktopwidget_p.h +++ b/src/widgets/kernel/qdesktopwidget_p.h @@ -55,12 +55,19 @@ QT_BEGIN_NAMESPACE class QDesktopScreenWidget : public QWidget { Q_OBJECT public: - QDesktopScreenWidget() : QWidget(Q_NULLPTR, Qt::Desktop) - { - setVisible(false); - } + explicit QDesktopScreenWidget(QScreen *screen, const QRect &geometry); int screenNumber() const; + void setScreenGeometry(const QRect &geometry); + + QScreen *screen() const { return m_screen.data(); } + QRect screenGeometry() const { return m_geometry; } + +private: + // The widget updates its screen and geometry automatically. We need to save them separately + // to detect changes, and trigger the appropriate signals. + const QPointer m_screen; + QRect m_geometry; }; class QDesktopWidgetPrivate : public QWidgetPrivate { @@ -70,6 +77,7 @@ public: ~QDesktopWidgetPrivate() { qDeleteAll(screens); } void _q_updateScreens(); void _q_availableGeometryChanged(); + QDesktopScreenWidget *widgetForScreen(QScreen *qScreen) const; QList screens; }; -- cgit v1.2.3 From 1acb29c3dd53fe675c71b05a5364e5b77ec0fe2a Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Fri, 29 Apr 2016 15:58:46 -0700 Subject: QMenu auto-test: Add test for two-level tearable menus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This has been fixed in 5.6.1 but we can afford the extra test to guard against regressions. The setup for this test is two menus, one parent of the other. The submenu is tearable. We open the parent menu, open its submenu and then move the mouse cursor straight over the submenu's tear-off area. The submenu should stay open even after a short delay. Change-Id: Ia8ad326d78dde31b6dd91b0ebacf0db1898715d4 Task-number: QTBUG-53068 Reviewed-by: Błażej Szczygieł Reviewed-by: Gabriel de Dietrich --- tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp | 46 ++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp index 20f17f6e9e..4deade0b4d 100644 --- a/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp +++ b/tests/auto/widgets/widgets/qmenu/tst_qmenu.cpp @@ -90,6 +90,7 @@ private slots: void mouseActivation(); #endif void tearOff(); + void submenuTearOffDontClose(); void layoutDirection(); void task208001_stylesheet(); @@ -631,6 +632,51 @@ void tst_QMenu::tearOff() QVERIFY(!torn->isVisible()); } +void tst_QMenu::submenuTearOffDontClose() +{ + QWidget widget; + QMenu *menu = new QMenu(&widget); + QVERIFY(!menu->isTearOffEnabled()); //default value + menu->setTearOffEnabled(true); + QVERIFY(menu->isTearOffEnabled()); + QMenu *submenu = new QMenu(&widget); + submenu->addAction("aaa"); + submenu->addAction("bbb"); + QVERIFY(!submenu->isTearOffEnabled()); //default value + submenu->setTearOffEnabled(true); + QVERIFY(submenu->isTearOffEnabled()); + menu->addMenu(submenu); + + widget.resize(300, 200); + centerOnScreen(&widget); + widget.show(); + widget.activateWindow(); + QVERIFY(QTest::qWaitForWindowActive(&widget)); + // Show parent menu + menu->popup(widget.geometry().topRight() + QPoint(50, 0)); + QVERIFY(QTest::qWaitForWindowActive(menu)); + // Then its submenu + const QRect submenuRect = menu->actionGeometry(menu->actions().at(0)); + const QPoint submenuPos(submenuRect.topLeft() + QPoint(3, 3)); + // Move then click to avoid the submenu moves from causing it to close + QTest::mouseMove(menu, submenuPos, 100); + QTest::mouseClick(menu, Qt::LeftButton, 0, submenuPos, 100); + QTRY_VERIFY(QTest::qWaitForWindowActive(submenu)); + // Make sure we enter the submenu frame directly on the tear-off area + QTest::mouseMove(submenu, QPoint(10, 3), 100); + if (submenu->style()->styleHint(QStyle::SH_Menu_SubMenuDontStartSloppyOnLeave)) { + qWarning("Sloppy menu timer disabled by the style: %s", qPrintable(QApplication::style()->objectName())); + // Submenu must get the enter event + QTRY_VERIFY(submenu->underMouse()); + } else { + const int closeTimeout = submenu->style()->styleHint(QStyle::SH_Menu_SubMenuSloppyCloseTimeout); + QTest::qWait(closeTimeout + 100); + // Menu must not disappear and it must get the enter event + QVERIFY(submenu->isVisible()); + QVERIFY(submenu->underMouse()); + } +} + void tst_QMenu::layoutDirection() { QMainWindow win; -- cgit v1.2.3 From a1dccd0708ae805b014489b5b16cc055d3001c50 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Thu, 19 May 2016 09:37:22 +0200 Subject: WinRT: Do not assert on socket close If no read was established before (no IO pending) the function will fail. In this case there is no need to assert though. Change-Id: Iaa18e4124389783fc2b8363a85c60a308903a713 Task-number: QTBUG-53424 Reviewed-by: Maurice Kalinowski --- src/network/socket/qnativesocketengine_winrt.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp index ecd364b84b..aae0dd835b 100644 --- a/src/network/socket/qnativesocketengine_winrt.cpp +++ b/src/network/socket/qnativesocketengine_winrt.cpp @@ -469,7 +469,10 @@ void QNativeSocketEngine::close() hr = socket3->CancelIOAsync(&action); Q_ASSERT_SUCCEEDED(hr); hr = QWinRTFunctions::await(action); - Q_ASSERT_SUCCEEDED(hr); + // If there is no pending IO (no read established before) the function will fail with + // "function was called at an unexpected time" which is fine. + if (hr != E_ILLEGAL_METHOD_CALL) + Q_ASSERT_SUCCEEDED(hr); } #endif // _MSC_VER >= 1900 -- cgit v1.2.3 From 9e3e98759028dc6b6452c8fd426dd00622ffc7ae Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Mon, 16 May 2016 16:28:24 -0700 Subject: QNSView: Pass on the responder chain if deletion is pending MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I7d098b61f6feb2ac38582c0efb1bbdf25a83e967 Task-number: QTBUG-53398 Reviewed-by: René J.V. Bertin Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qnsview.mm | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 0d58faa5bf..e78cc411a8 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -653,7 +653,9 @@ QT_WARNING_POP - (BOOL)becomeFirstResponder { - if (m_window && (m_window->flags() & Qt::WindowTransparentForInput) ) + if (!m_window || !m_platformWindow) + return NO; + if (m_window->flags() & Qt::WindowTransparentForInput) return NO; if (!m_platformWindow->windowIsPopupType() && !m_isMenuView) QWindowSystemInterface::handleWindowActivated([self topLevelWindow]); @@ -662,11 +664,13 @@ QT_WARNING_POP - (BOOL)acceptsFirstResponder { + if (!m_window || !m_platformWindow) + return NO; if (m_isMenuView) return NO; if (m_platformWindow->shouldRefuseKeyWindowAndFirstResponder()) return NO; - if (m_window && (m_window->flags() & Qt::WindowTransparentForInput) ) + if (m_window->flags() & Qt::WindowTransparentForInput) return NO; if ((m_window->flags() & Qt::ToolTip) == Qt::ToolTip) return NO; @@ -676,7 +680,9 @@ QT_WARNING_POP - (BOOL)acceptsFirstMouse:(NSEvent *)theEvent { Q_UNUSED(theEvent) - if (m_window && (m_window->flags() & Qt::WindowTransparentForInput) ) + if (!m_window || !m_platformWindow) + return NO; + if (m_window->flags() & Qt::WindowTransparentForInput) return NO; return YES; } -- cgit v1.2.3 From d2af1d71c11ee937a6796eca0057d4052b0220af Mon Sep 17 00:00:00 2001 From: Ralf Nolden Date: Fri, 20 May 2016 20:38:06 +0200 Subject: Remove obsolete freebsd-icc mkspecs The freebsd-icc mkspec was intended to be used with the Intel compiler, which nowadays is still only available in version 8.1.038 (https://www.freshports.org/lang/icc/) and for i386 only while the current version is around 17. On FreeBSD the port was actually never supported by Intel anyway. Change-Id: I03b1939be63eef4363bd6b074a6b739365f495ac Reviewed-by: Thiago Macieira --- mkspecs/freebsd-icc/qmake.conf | 95 ------------------------------------- mkspecs/freebsd-icc/qplatformdefs.h | 34 ------------- 2 files changed, 129 deletions(-) delete mode 100644 mkspecs/freebsd-icc/qmake.conf delete mode 100644 mkspecs/freebsd-icc/qplatformdefs.h diff --git a/mkspecs/freebsd-icc/qmake.conf b/mkspecs/freebsd-icc/qmake.conf deleted file mode 100644 index d72ea73278..0000000000 --- a/mkspecs/freebsd-icc/qmake.conf +++ /dev/null @@ -1,95 +0,0 @@ -# -# qmake configuration for freebsd-icc -# -# Written for Intel C++ 7.1 and 8.0 on FreeBSD -# -# Note: Some of the remarks from the Intel compiler are disabled (even -# with 'warn_on' specified): -# -# remark #171: invalid type conversion: "int" to "void *" -# remark #193: zero used for undefined preprocessing identifier -# remark #279: controlling expression is constant -# remark #304: access control not specified ("public" by default) -# remark #310: old-style parameter list (anachronism) -# remark #383: value copied to temporary, reference to temporary used -# remark #424: extra ";" ignored -# remark #444: destructor for base class "Class" is not virtual -# remark #488: template parameter "T" is not used in declaring the parameter -# types of function template "function" -# remark #810: conversion from "type1" to "type2" may loose significant bits -# remark #858: type qualifier on return type is meaningless -# remark #967: conversion from "type1" to "type2"; sizes do not match -# remark #981: operands are evaluated in unspecified order -# remark #1418: external definition with no prior declaration -# remark #1419: external declaration in primary source file -# warning #1476: field uses tail padding of a base class -# warning #1477: GNU C++ compilers may use bit field padding -# warning #1572: floating-point equality and inequality comparisons are unreliable -# - -MAKEFILE_GENERATOR = UNIX -QMAKE_PLATFORM = freebsd bsd - -include(../common/unix.conf) - -QMAKE_COMPILER = gcc intel_icc # icc pretends to be gcc - -QMAKE_CC = icc -QMAKE_LEX = flex -QMAKE_LEXFLAGS = -QMAKE_YACC = yacc -QMAKE_YACCFLAGS = -d -QMAKE_CFLAGS = -wd858,1572 -QMAKE_CFLAGS_DEPS = -M -QMAKE_CFLAGS_WARN_ON = -w2 -wd171,193,279,304,310,383,424,444,488,810,967,981,1418,1419,1476,1477 -QMAKE_CFLAGS_WARN_OFF = -w -QMAKE_CFLAGS_RELEASE = -QMAKE_CFLAGS_DEBUG = -g -QMAKE_CFLAGS_SHLIB = -fpic -QMAKE_CFLAGS_STATIC_LIB = $$QMAKE_CFLAGS_SHLIB -QMAKE_CFLAGS_YACC = -QMAKE_CFLAGS_THREAD = -D_THREAD_SAFE - -QMAKE_CXX = icpc -QMAKE_CXXFLAGS = $$QMAKE_CFLAGS -QMAKE_CXXFLAGS_DEPS = $$QMAKE_CFLAGS_DEPS -QMAKE_CXXFLAGS_WARN_ON = $$QMAKE_CFLAGS_WARN_ON -QMAKE_CXXFLAGS_WARN_OFF = $$QMAKE_CFLAGS_WARN_OFF -QMAKE_CXXFLAGS_RELEASE = $$QMAKE_CFLAGS_RELEASE -QMAKE_CXXFLAGS_DEBUG = $$QMAKE_CFLAGS_DEBUG -QMAKE_CXXFLAGS_SHLIB = $$QMAKE_CFLAGS_SHLIB -QMAKE_CXXFLAGS_STATIC_LIB = $$QMAKE_CFLAGS_STATIC_LIB -QMAKE_CXXFLAGS_YACC = $$QMAKE_CFLAGS_YACC -QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD - -# Addon software goes into /usr/local on the BSDs, by default we will look there -QMAKE_INCDIR = /usr/local/include -QMAKE_LIBDIR = /usr/local/lib -QMAKE_INCDIR_X11 = /usr/X11R6/include -QMAKE_LIBDIR_X11 = /usr/X11R6/lib -QMAKE_INCDIR_OPENGL = /usr/X11R6/include -QMAKE_LIBDIR_OPENGL = /usr/X11R6/lib - -QMAKE_LINK = icpc -QMAKE_LINK_SHLIB = icpc -QMAKE_LFLAGS = -QMAKE_LFLAGS_RELEASE = -QMAKE_LFLAGS_DEBUG = -QMAKE_LFLAGS_SHLIB = -shared -QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB -QMAKE_LFLAGS_SONAME = -Qoption,ld,-soname, -QMAKE_LFLAGS_THREAD = -mt -QMAKE_LFLAGS_RPATH = -Qoption,ld,-rpath, - -QMAKE_LIBS = -QMAKE_LIBS_DYNLOAD = -QMAKE_LIBS_X11 = -lXext -lX11 -lm -QMAKE_LIBS_OPENGL = -lGL -QMAKE_LIBS_THREAD = - -QMAKE_AR = ar cqs -QMAKE_OBJCOPY = objcopy -QMAKE_NM = nm -P -QMAKE_RANLIB = - -load(qt_config) diff --git a/mkspecs/freebsd-icc/qplatformdefs.h b/mkspecs/freebsd-icc/qplatformdefs.h deleted file mode 100644 index 48dc4d64fb..0000000000 --- a/mkspecs/freebsd-icc/qplatformdefs.h +++ /dev/null @@ -1,34 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the qmake spec 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 "../freebsd-g++/qplatformdefs.h" -- cgit v1.2.3 From c18b802e337c1a58a687a0e9f1b23465c9036b0a Mon Sep 17 00:00:00 2001 From: Jesus Fernandez Date: Fri, 20 May 2016 09:55:05 +0200 Subject: Fixed variable type A port was being assigned to qint16 instead of quint16. Change-Id: I9414e2dcca52beab1bc17ef61cfff56db8ab83a0 Reviewed-by: Edward Welbourne Reviewed-by: Timur Pocheptsov --- src/network/access/qhttpnetworkconnectionchannel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp index f591abc28b..dfa5d0e74a 100644 --- a/src/network/access/qhttpnetworkconnectionchannel.cpp +++ b/src/network/access/qhttpnetworkconnectionchannel.cpp @@ -325,7 +325,7 @@ bool QHttpNetworkConnectionChannel::ensureConnection() priv->phase = QAuthenticatorPrivate::Start; QString connectHost = connection->d_func()->hostName; - qint16 connectPort = connection->d_func()->port; + quint16 connectPort = connection->d_func()->port; #ifndef QT_NO_NETWORKPROXY // HTTPS always use transparent proxy. -- cgit v1.2.3 From 11f14a0442883a2446116dc5c91c3e10ef339555 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Mon, 23 May 2016 09:55:13 +0200 Subject: Turn off optimization for checkForAlphaPixels on Windows ARM This function is optimized in a way that it returns bad results with the arm msvc compiler. Task-number: QTBUG-52007 Change-Id: Ica4517dfb7dde5a78d563f9253c4c907090c9459 Reviewed-by: Andreas Holzammer Reviewed-by: Kevin Funk Reviewed-by: Friedemann Kleint --- src/gui/image/qimage.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 29a688099b..59a83a6750 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -170,6 +170,9 @@ QImageData::~QImageData() data = 0; } +#if defined(_M_ARM) +#pragma optimize("", off) +#endif bool QImageData::checkForAlphaPixels() const { @@ -277,6 +280,9 @@ bool QImageData::checkForAlphaPixels() const return has_alpha_pixels; } +#if defined(_M_ARM) +#pragma optimize("", on) +#endif /*! \class QImage -- cgit v1.2.3 From eda29451e958cb4981c254d48a20125988a04a45 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Thu, 12 May 2016 17:16:51 +0200 Subject: Enable -separate-debug-info for mingw toolchains Having the debug info in separate files is very helpful, especially on memory constrained 32bit systems. When the debug info is compiled into the object files, processes can run out of memory when trying to load them. Change-Id: I1808a32e855d6a62e17e1b734c511b31db5f03f1 Reviewed-by: Oswald Buddenhagen --- config.tests/unix/objcopy/objcopy.pro | 5 ++++- mkspecs/features/win32/separate_debug_info.prf | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 mkspecs/features/win32/separate_debug_info.prf diff --git a/config.tests/unix/objcopy/objcopy.pro b/config.tests/unix/objcopy/objcopy.pro index 3c28b89ef3..3c76ae92ef 100644 --- a/config.tests/unix/objcopy/objcopy.pro +++ b/config.tests/unix/objcopy/objcopy.pro @@ -1,4 +1,7 @@ SOURCES = objcopy.cpp CONFIG -= qt +TARGET = objcopytest -QMAKE_POST_LINK += $$QMAKE_OBJCOPY --only-keep-debug objcopy objcopy.debug && $$QMAKE_OBJCOPY --strip-debug objcopy && $$QMAKE_OBJCOPY --add-gnu-debuglink=objcopy.debug objcopy +load(resolve_target) + +QMAKE_POST_LINK += $$QMAKE_OBJCOPY --only-keep-debug $$QMAKE_RESOLVED_TARGET objcopytest.debug && $$QMAKE_OBJCOPY --strip-debug $$QMAKE_RESOLVED_TARGET && $$QMAKE_OBJCOPY --add-gnu-debuglink=objcopytest.debug $$QMAKE_RESOLVED_TARGET diff --git a/mkspecs/features/win32/separate_debug_info.prf b/mkspecs/features/win32/separate_debug_info.prf new file mode 100644 index 0000000000..2838020f01 --- /dev/null +++ b/mkspecs/features/win32/separate_debug_info.prf @@ -0,0 +1,18 @@ +have_target:!static:!isEmpty(QMAKE_OBJCOPY) { + load(resolve_target) + QMAKE_TARGET_DEBUG_INFO = $${QMAKE_RESOLVED_TARGET}.debug + + shell_target = $$shell_quote($$relative_path($$QMAKE_RESOLVED_TARGET, $$OUT_PWD)) + shell_target_debug_info = $$shell_quote($$relative_path($$QMAKE_TARGET_DEBUG_INFO, $$OUT_PWD)) + copy_debug_info = $$QMAKE_OBJCOPY --only-keep-debug $$shell_target $$shell_target_debug_info + link_debug_info = $$QMAKE_OBJCOPY --add-gnu-debuglink=$$shell_target_debug_info $$shell_target + strip_debug_info = $$QMAKE_OBJCOPY --strip-debug $$shell_target + + !isEmpty(QMAKE_POST_LINK):QMAKE_POST_LINK = $$escape_expand(\\n\\t)$$QMAKE_POST_LINK + + QMAKE_POST_LINK = $$copy_debug_info && $$strip_debug_info && $$link_debug_info $$QMAKE_POST_LINK + silent:QMAKE_POST_LINK = @echo creating $@.debug && $$QMAKE_POST_LINK + + target.targets += $$QMAKE_TARGET_DEBUG_INFO + QMAKE_DISTCLEAN += $$QMAKE_TARGET_DEBUG_INFO +} -- cgit v1.2.3 From e28d31dbfaca7f870240fe414ccfedceb16731d7 Mon Sep 17 00:00:00 2001 From: Ralf Nolden Date: Fri, 20 May 2016 21:50:36 +0200 Subject: Move freebsd-g++ mkspecs back for supported FreeBSD 9.3 and up FreeBSD 9.3 is still supported and uses gcc as the default compiler, therefore FreeBSD ports require patching the mkspecs back. To avoid patching, move the mkspecs back to the right place and adapt the path in the qmake.conf/qplatformdefs.h [ChangeLog][FreeBSD] The freebsd-g++ mkspec was moved back and no longer requires the "unsupported/" prefix, matching the FreeBSD ports tree, as FreeBSD 9.3 still defaults to using GCC. Users of GCC that did not previously use the ports patch will need to adapt their build scripts and drop the "unsupported/" prefix. Change-Id: Ideda4a33cccf5381000f6f50b6ae92a5c24ba9d4 Reviewed-by: Thiago Macieira --- configure | 2 +- mkspecs/freebsd-g++/qmake.conf | 34 +++++++++++++++++++++++++ mkspecs/freebsd-g++/qplatformdefs.h | 34 +++++++++++++++++++++++++ mkspecs/unsupported/freebsd-g++/qmake.conf | 34 ------------------------- mkspecs/unsupported/freebsd-g++/qplatformdefs.h | 34 ------------------------- 5 files changed, 69 insertions(+), 69 deletions(-) create mode 100644 mkspecs/freebsd-g++/qmake.conf create mode 100644 mkspecs/freebsd-g++/qplatformdefs.h delete mode 100644 mkspecs/unsupported/freebsd-g++/qmake.conf delete mode 100644 mkspecs/unsupported/freebsd-g++/qplatformdefs.h diff --git a/configure b/configure index 109c0bbbac..9d75668452 100755 --- a/configure +++ b/configure @@ -2872,7 +2872,7 @@ if [ -z "$PLATFORM" ]; then FreeBSD:*) PLATFORM=freebsd-clang PLATFORM_NOTES=" - - Also available for FreeBSD: freebsd-icc + - Also available for FreeBSD: freebsd-g++ " ;; OpenBSD:*) diff --git a/mkspecs/freebsd-g++/qmake.conf b/mkspecs/freebsd-g++/qmake.conf new file mode 100644 index 0000000000..282b6bdfa7 --- /dev/null +++ b/mkspecs/freebsd-g++/qmake.conf @@ -0,0 +1,34 @@ +# +# qmake configuration for freebsd-g++ +# + +MAKEFILE_GENERATOR = UNIX +QMAKE_PLATFORM = freebsd bsd + +include(../common/unix.conf) + +QMAKE_CFLAGS_THREAD = -pthread -D_THREAD_SAFE + +QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD + +# Addon software goes into /usr/local on the BSDs, by default we will look there +QMAKE_INCDIR = /usr/local/include +QMAKE_LIBDIR = /usr/local/lib + +QMAKE_LFLAGS_THREAD = -pthread + +QMAKE_LIBS = +QMAKE_LIBS_DYNLOAD = +QMAKE_LIBS_EXECINFO = -lexecinfo +QMAKE_LIBS_X11 = -lXext -lX11 -lm +QMAKE_LIBS_OPENGL = -lGL +QMAKE_LIBS_THREAD = + +QMAKE_AR = ar cqs +QMAKE_OBJCOPY = objcopy +QMAKE_NM = nm -P +QMAKE_RANLIB = + +include(../common/gcc-base-unix.conf) +include(../common/g++-unix.conf) +load(qt_config) diff --git a/mkspecs/freebsd-g++/qplatformdefs.h b/mkspecs/freebsd-g++/qplatformdefs.h new file mode 100644 index 0000000000..aa51e08990 --- /dev/null +++ b/mkspecs/freebsd-g++/qplatformdefs.h @@ -0,0 +1,34 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the qmake spec 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 "../freebsd-clang/qplatformdefs.h" diff --git a/mkspecs/unsupported/freebsd-g++/qmake.conf b/mkspecs/unsupported/freebsd-g++/qmake.conf deleted file mode 100644 index 527a94870c..0000000000 --- a/mkspecs/unsupported/freebsd-g++/qmake.conf +++ /dev/null @@ -1,34 +0,0 @@ -# -# qmake configuration for freebsd-g++ -# - -MAKEFILE_GENERATOR = UNIX -QMAKE_PLATFORM = freebsd bsd - -include(../../common/unix.conf) - -QMAKE_CFLAGS_THREAD = -pthread -D_THREAD_SAFE - -QMAKE_CXXFLAGS_THREAD = $$QMAKE_CFLAGS_THREAD - -# Addon software goes into /usr/local on the BSDs, by default we will look there -QMAKE_INCDIR = /usr/local/include -QMAKE_LIBDIR = /usr/local/lib - -QMAKE_LFLAGS_THREAD = -pthread - -QMAKE_LIBS = -QMAKE_LIBS_DYNLOAD = -QMAKE_LIBS_EXECINFO = -lexecinfo -QMAKE_LIBS_X11 = -lXext -lX11 -lm -QMAKE_LIBS_OPENGL = -lGL -QMAKE_LIBS_THREAD = - -QMAKE_AR = ar cqs -QMAKE_OBJCOPY = objcopy -QMAKE_NM = nm -P -QMAKE_RANLIB = - -include(../../common/gcc-base-unix.conf) -include(../../common/g++-unix.conf) -load(qt_config) diff --git a/mkspecs/unsupported/freebsd-g++/qplatformdefs.h b/mkspecs/unsupported/freebsd-g++/qplatformdefs.h deleted file mode 100644 index b52be38b4e..0000000000 --- a/mkspecs/unsupported/freebsd-g++/qplatformdefs.h +++ /dev/null @@ -1,34 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the qmake spec 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 "../../freebsd-clang/qplatformdefs.h" -- cgit v1.2.3 From defec688d20d32c1d3bc21067968c0c521da47c1 Mon Sep 17 00:00:00 2001 From: Ralf Nolden Date: Sun, 22 May 2016 01:08:10 +0200 Subject: Use -liconv on OpenBSD as well in config.tests OpenBSD iconv is in -liconv, so it needs to be added here. NetBSD has iconv in libc, so only OpenBSD is affected. Patch obtained from Vadim Zhukov , OpenBSD qt ports maintainer. Change-Id: Icce25d154857f0ce161b5f6b7ddac3c150a02bb8 Reviewed-by: Thiago Macieira --- config.tests/unix/iconv/iconv.pro | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.tests/unix/iconv/iconv.pro b/config.tests/unix/iconv/iconv.pro index ca12e51947..65273ccc94 100644 --- a/config.tests/unix/iconv/iconv.pro +++ b/config.tests/unix/iconv/iconv.pro @@ -1,3 +1,3 @@ SOURCES = iconv.cpp CONFIG -= qt dylib -mac|mingw|qnx|haiku:LIBS += -liconv +mac|mingw|openbsd|qnx|haiku:LIBS += -liconv -- cgit v1.2.3 From e91be71ef04c22e478a3e98256ded87b28d0d767 Mon Sep 17 00:00:00 2001 From: Ralf Nolden Date: Sun, 22 May 2016 01:32:30 +0200 Subject: Add OpenBSD to list of BSD systems defines using kqueue too Besides FreeBSD and NetBSD, OpenBSD uses kqueue too, so add the according Q_OS_OPENBSD define here to make that work. Patch obtained via OpenBSD qt ports maintainer Vadim Zhukov from OpenBSD qt ports patches. Change-Id: Ib9e6f6303b661beb88666bd3c2bf36a77e929f9d Reviewed-by: Thiago Macieira --- src/corelib/io/qfilesystemwatcher.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/corelib/io/qfilesystemwatcher.cpp b/src/corelib/io/qfilesystemwatcher.cpp index 354e4931b9..d8564c4c40 100644 --- a/src/corelib/io/qfilesystemwatcher.cpp +++ b/src/corelib/io/qfilesystemwatcher.cpp @@ -52,7 +52,7 @@ # include "qfilesystemwatcher_win_p.h" #elif defined(USE_INOTIFY) # include "qfilesystemwatcher_inotify_p.h" -#elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) || defined(Q_OS_IOS) +#elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) || defined(Q_OS_OPENBSD) || defined(Q_OS_IOS) # include "qfilesystemwatcher_kqueue_p.h" #elif defined(Q_OS_OSX) # include "qfilesystemwatcher_fsevents_p.h" @@ -68,7 +68,7 @@ QFileSystemWatcherEngine *QFileSystemWatcherPrivate::createNativeEngine(QObject // there is a chance that inotify may fail on Linux pre-2.6.13 (August // 2005), so we can't just new inotify directly. return QInotifyFileSystemWatcherEngine::create(parent); -#elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) || defined(Q_OS_IOS) +#elif defined(Q_OS_FREEBSD) || defined(Q_OS_NETBSD) || defined(Q_OS_OPENBSD) || defined(Q_OS_IOS) return QKqueueFileSystemWatcherEngine::create(parent); #elif defined(Q_OS_OSX) return QFseventsFileSystemWatcherEngine::create(parent); -- cgit v1.2.3 From 14ae00dd50ed4a75c2efa0b34da971b0e252e124 Mon Sep 17 00:00:00 2001 From: Ralf Nolden Date: Sun, 22 May 2016 13:31:27 +0200 Subject: Compile fix: undefine types before defining them On NetBSD, the types uint64_t, uint32_t and uint8_t are already defined in sys/types.h which leads to compile errors. Those types need to be properly undefined before defining them with the Qt code. Change-Id: Icd58f421619f15b899cf5c5de1cfb22a519a4e4b Reviewed-by: Thiago Macieira --- src/corelib/tools/qcryptographichash.cpp | 20 ++++++++++++++++++++ src/corelib/tools/qmessageauthenticationcode.cpp | 20 ++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/src/corelib/tools/qcryptographichash.cpp b/src/corelib/tools/qcryptographichash.cpp index 1c74a602c6..ab549f071e 100644 --- a/src/corelib/tools/qcryptographichash.cpp +++ b/src/corelib/tools/qcryptographichash.cpp @@ -89,9 +89,29 @@ static SHA3Final * const sha3Final = Final; available on all platforms (MSVC 2008, for example), we #define them to the Qt equivalents. */ + +#ifdef uint64_t +#undef uint64_t +#endif + #define uint64_t QT_PREPEND_NAMESPACE(quint64) + +#ifdef uint32_t +#undef uint32_t +#endif + #define uint32_t QT_PREPEND_NAMESPACE(quint32) + +#ifdef uint8_t +#undef uint8_t +#endif + #define uint8_t QT_PREPEND_NAMESPACE(quint8) + +#ifdef int_least16_t +#undef int_least16_t +#endif + #define int_least16_t QT_PREPEND_NAMESPACE(qint16) // Header from rfc6234 with 1 modification: diff --git a/src/corelib/tools/qmessageauthenticationcode.cpp b/src/corelib/tools/qmessageauthenticationcode.cpp index 5e7f1fc431..f25a76d450 100644 --- a/src/corelib/tools/qmessageauthenticationcode.cpp +++ b/src/corelib/tools/qmessageauthenticationcode.cpp @@ -40,9 +40,29 @@ available on all platforms (MSVC 2008, for example), we #define them to the Qt equivalents. */ + +#ifdef uint64_t +#undef uint64_t +#endif + #define uint64_t QT_PREPEND_NAMESPACE(quint64) + +#ifdef uint32_t +#undef uint32_t +#endif + #define uint32_t QT_PREPEND_NAMESPACE(quint32) + +#ifdef uint8_t +#undef uint8_t +#endif + #define uint8_t QT_PREPEND_NAMESPACE(quint8) + +#ifdef int_least16_t +#undef int_least16_t +#endif + #define int_least16_t QT_PREPEND_NAMESPACE(qint16) // Header from rfc6234 with 1 modification: -- cgit v1.2.3 From 9b153f989bcc40fed85d5cbd8a489c6e0eb5c9c7 Mon Sep 17 00:00:00 2001 From: Ralf Nolden Date: Sun, 22 May 2016 13:59:27 +0200 Subject: Compile fix: convert argument to long to match parameter comparison GCC creates a warning "enumeral and non-enumeral type in conditional expression" as the types of the two arguments don't match. Fix the compile warning by converting the first argument to (long) to match the type of the second parameter. Fix confirmed to work on NetBSD and FreeBSD, obtained from Kamil Rytarowski , NetBSD qt ports maintainer. Change-Id: I777dd066a0a8cc8a46e34bd39b256882080a7773 Reviewed-by: Thiago Macieira --- src/corelib/tools/qdatetime.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/tools/qdatetime.cpp b/src/corelib/tools/qdatetime.cpp index 491ed99301..29c8dbb2ea 100644 --- a/src/corelib/tools/qdatetime.cpp +++ b/src/corelib/tools/qdatetime.cpp @@ -2159,7 +2159,7 @@ static int qt_timezone() // number of seconds west of UTC. // - It also takes DST into account, so we need to adjust it to always // get the Standard Time offset. - return -t.tm_gmtoff + (t.tm_isdst ? SECS_PER_HOUR : 0L); + return -t.tm_gmtoff + (t.tm_isdst ? (long)SECS_PER_HOUR : 0L); #else return timezone; #endif // Q_OS_WIN -- cgit v1.2.3 From 725a9c27021bef1ac3828a4eafc013a2f50e6f22 Mon Sep 17 00:00:00 2001 From: Ralf Nolden Date: Sun, 22 May 2016 14:06:08 +0200 Subject: Compile fix: add NetBSD define for ffsll usage On NetBSD, ffsll needs to be defined to compile. The fix adds the according Q_OS_NETBSD define to the list of operating systems needing the define. Fix obtained from NetBSD port maintainer Kamil Rytarowski via IRC. Change-Id: I966a7b3fba43fb56e72f19f6b7f7cacc19c3c6cf Reviewed-by: Thiago Macieira --- src/corelib/tools/qsimd.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/tools/qsimd.cpp b/src/corelib/tools/qsimd.cpp index a1ee5b6348..0e3359ab81 100644 --- a/src/corelib/tools/qsimd.cpp +++ b/src/corelib/tools/qsimd.cpp @@ -636,7 +636,7 @@ int ffsll(quint64 i) #endif } #endif -#elif defined(Q_OS_ANDROID) || defined(Q_OS_QNX) || defined(Q_OS_OSX) || defined(Q_OS_HAIKU) +#elif defined(Q_OS_NETBSD) || defined(Q_OS_ANDROID) || defined(Q_OS_QNX) || defined(Q_OS_OSX) || defined(Q_OS_HAIKU) # define ffsll __builtin_ffsll #endif -- cgit v1.2.3 From f8c3820de789a2c08dab2ddb7bf18728cdbd7028 Mon Sep 17 00:00:00 2001 From: Ralf Nolden Date: Sun, 22 May 2016 15:04:01 +0200 Subject: Compile fix: remove unused variable bool isEmpty MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The local variable isEmpty triggers a compile warning with GCC: variable ‘isEmpty’ set but not used [-Werror=unused-but-set-variable], so remove the variable assignment and declaration. Error is triggered on FreeBSD and NetBSD with gcc. Change-Id: I37bdb3408ad69093708f2d4bdb04392da66e04e5 Reviewed-by: Thiago Macieira --- src/corelib/io/qfilesystemwatcher_kqueue.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/corelib/io/qfilesystemwatcher_kqueue.cpp b/src/corelib/io/qfilesystemwatcher_kqueue.cpp index 80cbcb26cc..9b574cbdfb 100644 --- a/src/corelib/io/qfilesystemwatcher_kqueue.cpp +++ b/src/corelib/io/qfilesystemwatcher_kqueue.cpp @@ -166,7 +166,6 @@ QStringList QKqueueFileSystemWatcherEngine::removePaths(const QStringList &paths QStringList *files, QStringList *directories) { - bool isEmpty; QStringList p = paths; if (pathToID.isEmpty()) return p; @@ -187,7 +186,6 @@ QStringList QKqueueFileSystemWatcherEngine::removePaths(const QStringList &paths else files->removeAll(path); } - isEmpty = pathToID.isEmpty(); return p; } -- cgit v1.2.3 From e3d1058ae9de6eee4d64ea1af66571497208d8c5 Mon Sep 17 00:00:00 2001 From: Ralf Nolden Date: Sun, 22 May 2016 20:15:03 +0200 Subject: Compile fix for NetBSD: only BSD using statvfs, disable f_flags define Compile fix for NetBSD's use of statvfs having f_flags.All other BSDs use statfs instead of statvfs, so the f_flags define needs to be prevented on NetBSD. Fix obtained from Kamil Rytarowski , NetBSD qt ports maintainer. Change-Id: Ifbd7ba0cba7f6cf280f5984c64abd7649f667332 Reviewed-by: Thiago Macieira --- src/corelib/io/qstorageinfo_unix.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/io/qstorageinfo_unix.cpp b/src/corelib/io/qstorageinfo_unix.cpp index 1d1b2907b7..c02d82a711 100644 --- a/src/corelib/io/qstorageinfo_unix.cpp +++ b/src/corelib/io/qstorageinfo_unix.cpp @@ -78,7 +78,7 @@ # if !defined(ST_RDONLY) # define ST_RDONLY MNT_RDONLY # endif -# if !defined(_STATFS_F_FLAGS) +# if !defined(_STATFS_F_FLAGS) && !defined(Q_OS_NETBSD) # define _STATFS_F_FLAGS 1 # endif #elif defined(Q_OS_ANDROID) -- cgit v1.2.3 From 5f02feae05a63dbd447e491b7518b1ed45c8b711 Mon Sep 17 00:00:00 2001 From: Ralf Nolden Date: Sun, 22 May 2016 20:39:24 +0200 Subject: Compile fix: add -lexecinfo on NetBSD and OpenBSD Add -lexecinfo for backtrace(3) on NetBSD and OpenBSD. Without, qlogging.cpp linking will result in undefined references to backtrace and backtrace_symbols. The behavior required is identical to FreeBSD so no additional fixes are required (see src/corelib/global/global.pri:41) Change-Id: I3cfd1d75f1fb5b8505c08a880f91e7b39a5a650d Reviewed-by: Thiago Macieira --- mkspecs/netbsd-g++/qmake.conf | 1 + mkspecs/openbsd-g++/qmake.conf | 1 + 2 files changed, 2 insertions(+) diff --git a/mkspecs/netbsd-g++/qmake.conf b/mkspecs/netbsd-g++/qmake.conf index 04c675da24..b470c9d08a 100644 --- a/mkspecs/netbsd-g++/qmake.conf +++ b/mkspecs/netbsd-g++/qmake.conf @@ -61,6 +61,7 @@ QMAKE_LFLAGS_RPATH = -Wl,-rpath, QMAKE_LIBS = QMAKE_LIBS_DYNLOAD = +QMAKE_LIBS_EXECINFO = -lexecinfo QMAKE_LIBS_X11 = -lXext -lX11 -lm QMAKE_LIBS_OPENGL = -lGL QMAKE_LIBS_THREAD = diff --git a/mkspecs/openbsd-g++/qmake.conf b/mkspecs/openbsd-g++/qmake.conf index 10330bc081..6a66f086ed 100644 --- a/mkspecs/openbsd-g++/qmake.conf +++ b/mkspecs/openbsd-g++/qmake.conf @@ -62,6 +62,7 @@ QMAKE_LFLAGS_NOUNDEF = -Wl,-no_unresolved QMAKE_LIBS = QMAKE_LIBS_DYNLOAD = +QMAKE_LIBS_EXECINFO = -lexecinfo QMAKE_LIBS_X11 = -lXext -lX11 -lm QMAKE_LIBS_OPENGL = -lGL QMAKE_LIBS_THREAD = -- cgit v1.2.3 From 932cce18f72d9af99629f1bad8bd1b6114de0300 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Tue, 8 Mar 2016 12:36:14 +0100 Subject: QSocks5SocketEngine: connect after auth fail as if connecting afresh. If the client has responded to an earlier auth fail sensibly, further use of the socks connection probably means we have fresh credentials. So treat AuthenticatingError like Uninitialized. This makes tst_QNetworkReply::authenticationCacheAfterCancel(*+socksauth) work again. Task-number: QTBUG-51545 Change-Id: I237ca5a3194b093cc6480dd33aa7709b7b584941 Reviewed-by: Timur Pocheptsov --- src/network/socket/qsocks5socketengine.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/network/socket/qsocks5socketengine.cpp b/src/network/socket/qsocks5socketengine.cpp index 6868e8c73a..c0398a8105 100644 --- a/src/network/socket/qsocks5socketengine.cpp +++ b/src/network/socket/qsocks5socketengine.cpp @@ -1112,7 +1112,9 @@ bool QSocks5SocketEngine::connectInternal() } if (d->socketState != QAbstractSocket::ConnectingState) { - if (d->socks5State == QSocks5SocketEnginePrivate::Uninitialized) { + if (d->socks5State == QSocks5SocketEnginePrivate::Uninitialized + // We may have new auth credentials since an earlier failure: + || d->socks5State == QSocks5SocketEnginePrivate::AuthenticatingError) { setState(QAbstractSocket::ConnectingState); //limit buffer in internal socket, data is buffered in the external socket under application control d->data->controlSocket->setReadBufferSize(65536); -- cgit v1.2.3 From 5c6d27b8dfa695ab04766a1711b00421dba9c7d0 Mon Sep 17 00:00:00 2001 From: Ralf Nolden Date: Tue, 17 May 2016 12:38:44 +0200 Subject: Make eglfs-egldevice check work with pkgconfig as well Until now the check didn't use pkgconfig at all, but using pkgconfig alone does not work for some devices (special cases), so we have to use a combination of both here. Change-Id: Ia19a279d80a65352c467661d91a3762448c23ae6 Reviewed-by: Laszlo Agocs --- config.tests/qpa/eglfs-egldevice/eglfs-egldevice.pro | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/config.tests/qpa/eglfs-egldevice/eglfs-egldevice.pro b/config.tests/qpa/eglfs-egldevice/eglfs-egldevice.pro index 521a911219..d0945465a0 100644 --- a/config.tests/qpa/eglfs-egldevice/eglfs-egldevice.pro +++ b/config.tests/qpa/eglfs-egldevice/eglfs-egldevice.pro @@ -6,7 +6,10 @@ for(p, QMAKE_LIBDIR_EGL) { INCLUDEPATH += $$QMAKE_INCDIR_EGL LIBS += $$QMAKE_LIBS_EGL - -LIBS += -ldrm - +CONFIG += link_pkgconfig +!contains(QT_CONFIG, no-pkg-config) { + PKGCONFIG += libdrm +} else { + LIBS += -ldrm +} CONFIG -= qt -- cgit v1.2.3 From bdb1c18e411a1660f038e4f0e219d363d38e987a Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Tue, 22 Mar 2016 15:32:36 +0100 Subject: windows: Fall back to D3D9 when 11 fails It is assumed that this happens automatically but that is not always the case. Do not become stuck with a non-functional D3D11-backed EGL environment. Instead, try again as if QT_ANGLE_PLATFORM=d3d9 was requested. Task-number: QTBUG-52056 Change-Id: I12ac6ca5f1d06f9504d05120d8e1053e97edfab3 Reviewed-by: Friedemann Kleint --- .../platforms/windows/qwindowseglcontext.cpp | 67 ++++++++++++++-------- src/plugins/platforms/windows/qwindowseglcontext.h | 2 + 2 files changed, 45 insertions(+), 24 deletions(-) diff --git a/src/plugins/platforms/windows/qwindowseglcontext.cpp b/src/plugins/platforms/windows/qwindowseglcontext.cpp index 787a072a7a..9ae1ca8acb 100644 --- a/src/plugins/platforms/windows/qwindowseglcontext.cpp +++ b/src/plugins/platforms/windows/qwindowseglcontext.cpp @@ -347,26 +347,9 @@ QWindowsEGLStaticContext::QWindowsEGLStaticContext(EGLDisplay display) { } -QWindowsEGLStaticContext *QWindowsEGLStaticContext::create(QWindowsOpenGLTester::Renderers preferredType) +bool QWindowsEGLStaticContext::initializeAngle(QWindowsOpenGLTester::Renderers preferredType, HDC dc, + EGLDisplay *display, EGLint *major, EGLint *minor) { - const HDC dc = QWindowsContext::instance()->displayContext(); - if (!dc){ - qWarning("%s: No Display", __FUNCTION__); - return 0; - } - - if (!libEGL.init()) { - qWarning("%s: Failed to load and resolve libEGL functions", __FUNCTION__); - return 0; - } - if (!libGLESv2.init()) { - qWarning("%s: Failed to load and resolve libGLESv2 functions", __FUNCTION__); - return 0; - } - - EGLDisplay display = EGL_NO_DISPLAY; - EGLint major = 0; - EGLint minor = 0; #ifdef EGL_ANGLE_platform_angle if (libEGL.eglGetPlatformDisplayEXT && (preferredType & QWindowsOpenGLTester::AngleBackendMask)) { @@ -384,16 +367,52 @@ QWindowsEGLStaticContext *QWindowsEGLStaticContext::create(QWindowsOpenGLTester: else if (preferredType & QWindowsOpenGLTester::AngleRendererD3d11Warp) attributes = anglePlatformAttributes[2]; if (attributes) { - display = libEGL.eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, dc, attributes); - if (!libEGL.eglInitialize(display, &major, &minor)) { - display = EGL_NO_DISPLAY; - major = minor = 0; + *display = libEGL.eglGetPlatformDisplayEXT(EGL_PLATFORM_ANGLE_ANGLE, dc, attributes); + if (!libEGL.eglInitialize(*display, major, minor)) { + libEGL.eglTerminate(*display); + *display = EGL_NO_DISPLAY; + *major = *minor = 0; + return false; } } } #else // EGL_ANGLE_platform_angle - Q_UNUSED(preferredType) + Q_UNUSED(preferredType); + Q_UNUSED(dc); + Q_UNUSED(display); + Q_UNUSED(major); + Q_UNUSED(minor); #endif + return true; +} + +QWindowsEGLStaticContext *QWindowsEGLStaticContext::create(QWindowsOpenGLTester::Renderers preferredType) +{ + const HDC dc = QWindowsContext::instance()->displayContext(); + if (!dc){ + qWarning("%s: No Display", __FUNCTION__); + return 0; + } + + if (!libEGL.init()) { + qWarning("%s: Failed to load and resolve libEGL functions", __FUNCTION__); + return 0; + } + if (!libGLESv2.init()) { + qWarning("%s: Failed to load and resolve libGLESv2 functions", __FUNCTION__); + return 0; + } + + EGLDisplay display = EGL_NO_DISPLAY; + EGLint major = 0; + EGLint minor = 0; + + if (!initializeAngle(preferredType, dc, &display, &major, &minor) + && (preferredType & QWindowsOpenGLTester::AngleRendererD3d11)) { + preferredType &= ~QWindowsOpenGLTester::AngleRendererD3d11; + initializeAngle(preferredType, dc, &display, &major, &minor); + } + if (display == EGL_NO_DISPLAY) display = libEGL.eglGetDisplay(dc); if (!display) { diff --git a/src/plugins/platforms/windows/qwindowseglcontext.h b/src/plugins/platforms/windows/qwindowseglcontext.h index 6945939941..1a6058c921 100644 --- a/src/plugins/platforms/windows/qwindowseglcontext.h +++ b/src/plugins/platforms/windows/qwindowseglcontext.h @@ -271,6 +271,8 @@ public: private: explicit QWindowsEGLStaticContext(EGLDisplay display); + static bool initializeAngle(QWindowsOpenGLTester::Renderers preferredType, HDC dc, + EGLDisplay *display, EGLint *major, EGLint *minor); const EGLDisplay m_display; }; -- cgit v1.2.3 From 1937a4e8b9b729e62426ce3018cc0a96a0c40972 Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Mon, 23 May 2016 12:41:01 +0200 Subject: Add a workaround for render-to-texture widgets in fullscreen windows The performance optimization of falling back to flushing windows the normal (raster) way once no render-to-texture widgets are visible has issues with fullscreen windows, presumably due to the compositor's special handling of such windows. Disable our smartness and stick with composeAndFlush for ever in case the window is fullscreen. Change-Id: Ifb31e0d36bd0a3933fcfe55a9a7d502513d6e3cf Task-number: QTBUG-53515 Reviewed-by: Friedemann Kleint --- src/widgets/kernel/qwidgetbackingstore.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp index 8269bd13f6..049ed248de 100644 --- a/src/widgets/kernel/qwidgetbackingstore.cpp +++ b/src/widgets/kernel/qwidgetbackingstore.cpp @@ -1000,8 +1000,18 @@ static QPlatformTextureList *widgetTexturesFor(QWidget *tlw, QWidget *widget) static bool switchableWidgetComposition = QGuiApplicationPrivate::instance()->platformIntegration() ->hasCapability(QPlatformIntegration::SwitchableWidgetComposition); - if (!switchableWidgetComposition) + if (!switchableWidgetComposition +// The Windows compositor handles fullscreen OpenGL window specially. Besides +// having trouble with popups, it also has issues with flip-flopping between +// OpenGL-based and normal flushing. Therefore, stick with GL for fullscreen +// windows. (QTBUG-53515) +#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) && !defined(Q_OS_WINCE) + || tlw->windowState().testFlag(Qt::WindowFullScreen) +#endif + ) + { return qt_dummy_platformTextureList(); + } } return 0; -- cgit v1.2.3 From 644d0e75240811212ed9fd0c21e3bd05db3ba5db Mon Sep 17 00:00:00 2001 From: Ralf Nolden Date: Fri, 20 May 2016 22:03:39 +0200 Subject: Cleanup NIS support leftover from Qt 3/4 Qt 3/4 had NIS configure options and tests for NIS defines, those were used in QPrintDialog at the time to support NIS-printers. As the implementation went away a long time ago and no NIS featueres are implemented anywhere in Qt, the configure options and config.tests for NIS can be removed. Change-Id: Ie920e6a422540bf938623265b6ee68c793aeff84 Reviewed-by: Thiago Macieira Reviewed-by: Oswald Buddenhagen --- config.tests/unix/nis/nis.cpp | 44 ------------------------------------------- config.tests/unix/nis/nis.pro | 4 ---- configure | 31 ------------------------------ 3 files changed, 79 deletions(-) delete mode 100644 config.tests/unix/nis/nis.cpp delete mode 100644 config.tests/unix/nis/nis.pro diff --git a/config.tests/unix/nis/nis.cpp b/config.tests/unix/nis/nis.cpp deleted file mode 100644 index f2d7f223e3..0000000000 --- a/config.tests/unix/nis/nis.cpp +++ /dev/null @@ -1,44 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the config.tests 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 -#include -#include -#include - -int main(int, char **) -{ - char *d; - yp_get_default_domain(&d); - return 0; -} diff --git a/config.tests/unix/nis/nis.pro b/config.tests/unix/nis/nis.pro deleted file mode 100644 index b7f5693b60..0000000000 --- a/config.tests/unix/nis/nis.pro +++ /dev/null @@ -1,4 +0,0 @@ -SOURCES = nis.cpp -CONFIG -= qt dylib -solaris-*:LIBS += -lnsl -else:LIBS += $$QMAKE_LIBS_NIS diff --git a/configure b/configure index 9d75668452..0e0a36b00f 100755 --- a/configure +++ b/configure @@ -708,7 +708,6 @@ CFG_LIBINPUT=auto CFG_OBSOLETE_WAYLAND=no CFG_EVDEV=auto CFG_TSLIB=auto -CFG_NIS=auto CFG_CUPS=auto CFG_ICONV=auto CFG_DBUS=auto @@ -2033,13 +2032,6 @@ while [ "$#" -gt 0 ]; do UNKNOWN_OPT=yes fi ;; - nis) - if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then - CFG_NIS="$VAL" - else - UNKNOWN_OPT=yes - fi - ;; largefile) if [ "$VAL" = "yes" ] || [ "$VAL" = "no" ]; then CFG_LARGEFILE="$VAL" @@ -2639,9 +2631,6 @@ Additional options: -silent ............ Reduce the build output so that warnings and errors can be seen more easily. - -no-nis ............ Do not compile NIS support. - * -nis ............... Compile NIS support. - -no-cups ........... Do not compile CUPS support. * -cups .............. Compile CUPS support. Requires cups/cups.h and libcups.so.2. @@ -5014,23 +5003,6 @@ for _SQLDR in $CFG_SQL_AVAILABLE; do esac done -# auto-detect NIS support -if [ "$CFG_NIS" != "no" ]; then - if compileTest unix/nis "NIS"; then - CFG_NIS=yes - else - if [ "$CFG_NIS" = "yes" ] && [ "$CFG_CONFIGURE_EXIT_ON_ERROR" = "yes" ]; then - echo "NIS support cannot be enabled due to functionality tests!" - echo " Turn on verbose messaging (-v) to $0 to see the final report." - echo " If you believe this message is in error you may use the continue" - echo " switch (-continue) to $0 to continue." - exit 101 - else - CFG_NIS=no - fi - fi -fi - # auto-detect CUPS support if [ "$CFG_CUPS" != "no" ]; then if compileTest unix/cups "Cups"; then @@ -6444,7 +6416,6 @@ elif [ "$CFG_ZLIB" = "system" ]; then fi [ "$CFG_MTDEV" = "yes" ] && QT_CONFIG="$QT_CONFIG mtdev" -[ "$CFG_NIS" = "yes" ] && QT_CONFIG="$QT_CONFIG nis" [ "$CFG_CUPS" = "yes" ] && QT_CONFIG="$QT_CONFIG cups" [ "$CFG_ICONV" = "yes" ] && QT_CONFIG="$QT_CONFIG iconv" [ "$CFG_ICONV" = "sun" ] && QT_CONFIG="$QT_CONFIG sun-libiconv" @@ -6869,7 +6840,6 @@ QMakeVar set sql-plugins "$SQL_PLUGINS" [ "$CFG_INOTIFY" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_INOTIFY" [ "$CFG_EVENTFD" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_EVENTFD" [ "$CFG_CLOEXEC" = "yes" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_THREADSAFE_CLOEXEC=1" -[ "$CFG_NIS" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_NIS" [ "$CFG_OPENSSL" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_OPENSSL" [ "$CFG_OPENSSL" = "linked" ]&& QCONFIG_FLAGS="$QCONFIG_FLAGS QT_LINKED_OPENSSL" [ "$CFG_OPENSSL" = "no" ] && [ "$CFG_SECURETRANSPORT" = "no" ] && QCONFIG_FLAGS="$QCONFIG_FLAGS QT_NO_SSL" @@ -7341,7 +7311,6 @@ report_support " libproxy.............." "$CFG_LIBPROXY" report_support " OpenSSL .............." "$CFG_OPENSSL" yes "loading libraries at run-time" linked "linked to the libraries" [ "$XPLATFORM_MAC" = "yes" ] && \ report_support " SecureTransport ......" "$CFG_SECURETRANSPORT" -report_support " NIS ...................." "$CFG_NIS" report_support " OpenGL / OpenVG:" report_support " EGL .................." "$CFG_EGL" report_support " OpenGL ..............." "$CFG_OPENGL" yes "Desktop OpenGL" es2 "OpenGL ES 2.0+" -- cgit v1.2.3 From ffd99e1d1803a8b82eab8d8b6c1cd9e58af36ee5 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 23 May 2016 14:27:05 +0200 Subject: Add section "Getting Started" to QPlatformHeader's documentation. Change-Id: Id57c65a5f5281ed0ff8f4e5876cf121781f2ae90 Reviewed-by: Andy Shaw --- src/platformheaders/doc/src/qtplatformheaders.qdoc | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/platformheaders/doc/src/qtplatformheaders.qdoc b/src/platformheaders/doc/src/qtplatformheaders.qdoc index 89c2394bdc..d2caa5b212 100644 --- a/src/platformheaders/doc/src/qtplatformheaders.qdoc +++ b/src/platformheaders/doc/src/qtplatformheaders.qdoc @@ -80,6 +80,19 @@ \sa QXcbWindowFunctions QWindowsWindowFunctions + \section1 Getting Started + + To include the definitions of the module's functions and classes, use the following directives: + \code + #include + #include + \endcode + + As the module is header-only, no further modifications to the .pro files are required to use it. + + \note The module name (\c QtPlatformHeaders) must appear in the \c #include directive. + \note It is not necessary to enclose the code in \c #ifdef directives depending on platform. + \section1 API Reference \list \li \l{Qt Platform Headers C++ Classes}{C++ Classes} -- cgit v1.2.3 From 3cae115d6d6e8a1d4d0385e3cde16f59b25acad0 Mon Sep 17 00:00:00 2001 From: Allan Sandfeld Jensen Date: Wed, 27 Apr 2016 11:53:16 +0200 Subject: Correct compositionMode documentation Most composition modes require an alpha-channel to be meaningful, but not all, and there is no requirements of specific formats. Change-Id: I11e930ccc07e9ff5df06dbda6745e4afb79f5e08 Reviewed-by: Leena Miettinen Reviewed-by: Gunnar Sletta --- src/gui/painting/qpainter.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 1acd84754a..51c0f3e22a 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -2182,11 +2182,10 @@ void QPainter::setBrushOrigin(const QPointF &p) destination pixel in such a way that the alpha component of the source defines the translucency of the pixel. - When the paint device is a QImage, the image format must be set to - \l {QImage::Format}{Format_ARGB32_Premultiplied} or - \l {QImage::Format}{Format_ARGB32} for the composition modes to have - any effect. For performance the premultiplied version is the preferred - format. + Several composition modes require an alpha channel in the source or + target images to have an effect. For optimal performance the + image format \l {QImage::Format}{Format_ARGB32_Premultiplied} is + preferred. When a composition mode is set it applies to all painting operator, pens, brushes, gradients and pixmap/image drawing. -- cgit v1.2.3 From cf6a2e96175b7ec2be757ae247ffd86e28ac563b Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 22 May 2016 11:18:34 -0700 Subject: forkfd: Make sure we handle SIGPIPE too We can't depend on the application/library ignoring the signal for us, so we do it. O_NOSIGPIPE exists on the BSDs and I'll add it to Linux. If it isn't supported, then we need to ignore SIGPIPE globally. Change-Id: I25d85d86649448d5b2b3fffd1450f6afeaea8b18 Reviewed-by: Ralf Nolden Reviewed-by: Rafael Roquetto --- src/3rdparty/forkfd/forkfd.c | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/src/3rdparty/forkfd/forkfd.c b/src/3rdparty/forkfd/forkfd.c index fef710a79e..9284a67674 100644 --- a/src/3rdparty/forkfd/forkfd.c +++ b/src/3rdparty/forkfd/forkfd.c @@ -410,6 +410,26 @@ chain_handler: old_sigaction.sa_handler(signum); } +static void ignore_sigpipe() +{ +#ifdef O_NOSIGPIPE + static ffd_atomic_int done = FFD_ATOMIC_INIT(0); + if (ffd_atomic_load(&done, FFD_ATOMIC_RELAXED)) + return; +#endif + + struct sigaction action; + memset(&action, 0, sizeof action); + sigemptyset(&action.sa_mask); + action.sa_handler = SIG_IGN; + action.sa_flags = 0; + sigaction(SIGPIPE, &action, NULL); + +#ifdef O_NOSIGPIPE + ffd_atomic_store(&done, 1, FFD_ATOMIC_RELAXED); +#endif +} + static void forkfd_initialize() { #if defined(HAVE_BROKEN_WAITID) @@ -446,6 +466,11 @@ static void forkfd_initialize() */ sigaction(SIGCHLD, &action, &old_sigaction); +#ifndef O_NOSIGPIPE + /* disable SIGPIPE too */ + ignore_sigpipe(); +#endif + #ifndef __GNUC__ atexit(cleanup); #endif @@ -486,13 +511,23 @@ static void cleanup() static int create_pipe(int filedes[], int flags) { - int ret; + int ret = -1; #ifdef HAVE_PIPE2 /* use pipe2(2) whenever possible, since it can thread-safely create a * cloexec pair of pipes. Without it, we have a race condition setting * FD_CLOEXEC */ - ret = pipe2(filedes, O_CLOEXEC); + +# ifdef O_NOSIGPIPE + /* try first with O_NOSIGPIPE */ + ret = pipe2(filedes, O_CLOEXEC | O_NOSIGPIPE); + if (ret == -1) { + /* O_NOSIGPIPE not supported, ignore SIGPIPE */ + ignore_sigpipe(); + } +# endif + if (ret == -1) + ret = pipe2(filedes, O_CLOEXEC); if (ret == -1) return ret; -- cgit v1.2.3 From f156c81d7fada47835f4ebce9f70f8b1bdb01201 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 18 May 2016 10:30:45 -0700 Subject: Restore the -fno-lto build of qversiontagging.cpp I'm not sure how one of my machines has this problem and the other doesn't (same distribution and same compiler version). Must be operator error. But this is required to compile QtGui when QtCore was compiled in LTO mode. qversiontagging.cpp used to be built with -fno-lto before commit 629ceec208ad5fe9f5d201fc42fce611e55c567d. This commit restores that functionality, but not the clang "-no-integrated-as" part. Change-Id: Ie9fd7afe060b4e4a8052fffd144fb9c1a1166854 Reviewed-by: Oswald Buddenhagen --- src/corelib/global/global.pri | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/src/corelib/global/global.pri b/src/corelib/global/global.pri index dd846955f6..6a8948822c 100644 --- a/src/corelib/global/global.pri +++ b/src/corelib/global/global.pri @@ -28,8 +28,9 @@ SOURCES += \ global/qmalloc.cpp \ global/qnumeric.cpp \ global/qlogging.cpp \ - global/qhooks.cpp \ - global/qversiontagging.cpp + global/qhooks.cpp + +VERSIONTAGGING_SOURCES = global/qversiontagging.cpp # qlibraryinfo.cpp includes qconfig.cpp INCLUDEPATH += $$QT_BUILD_TREE/src/corelib/global @@ -63,3 +64,21 @@ journald { syslog { DEFINES += QT_USE_SYSLOG } + +gcc:ltcg { + versiontagging_compiler.commands = $$QMAKE_CXX -c $(CXXFLAGS) $(INCPATH) + + # Disable LTO, as the symbols disappear somehow under GCC + versiontagging_compiler.commands += -fno-lto + + 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 +} -- cgit v1.2.3 From 40074bc985f1fa5c859dc48aed84b48d4c17fff3 Mon Sep 17 00:00:00 2001 From: Oswald Buddenhagen Date: Thu, 19 May 2016 13:26:29 +0200 Subject: Bump version Change-Id: I944b2a5e1b377fb2d39f9cbf549e1a9c01894cde Reviewed-by: Joerg Bornemann --- .qmake.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.qmake.conf b/.qmake.conf index 50d27cf9ce..1e64c2e238 100644 --- a/.qmake.conf +++ b/.qmake.conf @@ -4,4 +4,4 @@ CONFIG += warning_clean QT_SOURCE_TREE = $$PWD QT_BUILD_TREE = $$shadowed($$PWD) -MODULE_VERSION = 5.6.1 +MODULE_VERSION = 5.6.2 -- cgit v1.2.3 From d6905b2ada509cbe2322f65b862af3b99b79b792 Mon Sep 17 00:00:00 2001 From: Venugopal Shivashankar Date: Thu, 12 May 2016 11:08:02 +0200 Subject: Add changelog for 5.6.1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Done-with: Oswald Buddenhagen Change-Id: Ia29cc9b578ef0a6094d43759b504640c3843eb28 Reviewed-by: Topi Reiniö --- dist/changes-5.6.1 | 165 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 165 insertions(+) create mode 100644 dist/changes-5.6.1 diff --git a/dist/changes-5.6.1 b/dist/changes-5.6.1 new file mode 100644 index 0000000000..c256f36305 --- /dev/null +++ b/dist/changes-5.6.1 @@ -0,0 +1,165 @@ +Qt 5.6.1 is a bug-fix release. It maintains both forward and backward +compatibility (source and binary) with Qt 5.6.0. + +For more details, refer to the online documentation included in this +distribution. The documentation is also available online: + + https://doc.qt.io/qt-5/ + +The Qt version 5.6 series is binary compatible with the 5.5.x series. +Applications compiled for 5.5 will continue to run with 5.6. + +Some of the changes listed in this file include issue tracking numbers +corresponding to tasks in the Qt Bug Tracker: + + https://bugreports.qt.io/ + +Each of these identifiers can be entered in the bug tracker to obtain more +information about a particular change. + +**************************************************************************** +* Important Behavior Changes * +**************************************************************************** + + - Support for DirectFB is disabled by default, due to lack of + development in upstream. To enable the platform plugin, pass the + -directfb option to configure. + - [QTBUG-44964] The new X event compression feature that was added in 5.6.0 + no longer applies to motion events from drawing tablets. + +configure & build system +------------------------ + + - The configure -D/-I/-L/-l/-R options do not affect the build of Qt's + host tools any more when cross-building. While this usually improves + the chances of a build succeeding, it may also require adjustments. + +qmake +----- + + - [Unix] Paths passed to configure -R are not automatically used by 3rd + party projects any more. Use QMAKE_RPATHDIR if your project explicitly + depends on external libraries. Note that this is not needed for Qt or + its transitive dependencies. + - Expansions of ${QMAKE_FILE_IN_BASE} and ${QMAKE_FILE_OUT_BASE} in extra + compilers are now automatically quoted. + +**************************************************************************** +* Library * +**************************************************************************** + +QtCore +------ + + - QObject: + * [QTBUG-52542] If the compiler supports variadic templates, functors + connected to signals will no longer be copied each time the signal is + emitted. + + - QRect: + * Fixed integer overflow in center(). This fixes the result for some + corner-cases such as a 1x1 rectangle at (INT_MIN, INT_MIN), for which the + previous implementation could return anything (due to invoking undefined + behavior), but commonly returned (0, 0). + + - QStringRef: + * Fixed relational operators against (const char*) to return the correct + result. + +QtGui +----- + + - [QTBUG-50199] QWheelEvent::phase() now returns zero rather than + Qt::ScrollUpdate when the wheel event comes from an actual non-emulated + mouse wheel, and the QT_ENABLE_MOUSE_WHEEL_TRACKING environment variable + is set. + +- Image: + * [QTBUG-50745] Fixed possible crash in QImage::pixel() for mono or indexed + images. + +QtWidgets +--------- + + - Dialogs: + * [QTBUG-51148] Fixed font dialog support for fonts with a non-existent + family name and/or pixel size. + + - QHeaderView: + * [QTBUG-50171] Fixed a repainting issue when items had been reordered. + + - QListWidget: + * [QTBUG-15741] Fixed a bug that caused the default drop action to be + ignored when using icon mode. + + +**************************************************************************** +* Platform-specific Changes * +**************************************************************************** + +Android +------- + + - The navigation bar is now hidden only on Android API level 19 and above. + +OS X +---- + - [QTBUG-50262] QStandardPaths now returns the correct display name for the + download folder. + - [QTBUG-7000] QMacPrintEngine now really sets the printer resolution. + - [QTBUG-48138] QPinchGesture on OS X now behaves like on other platforms: + totalScaleFactor is the magnitude of the pinch and scaleFactor is the delta + for the current event. + +Windows +------- + + - Text: + * [QTBUG-18711] Fixed disabling hints for application fonts. + For example, when automatic scaling by device pixel ratio is in effect. + * [QTBUG-47141] Made it possible to disable antialiasing for text when + drawing into images. + +X11/XCB +------- + + - [QTBUG-49071] Fixed failure to deliver focusIn events on hide/show. + +**************************************************************************** +* Tools * +**************************************************************************** + +configure & build system +------------------------ + + - [QTBUG-11545][Windows] Added missing -pch/-no-pch options to configure.exe. + - [QTBUG-37952][Apple] configure -separate-debug-info is now supported. + - [QTBUG-47313][QTBUG-47639] Fixed builds with "debug" and/or "release" in + the build path's name. + - [QTBUG-51621][Unix] Fixed transitive dependencies on non-Qt libraries. + - [QTBUG-51644][QTBUG-53017] Fixed cross-builds which use a host compiler + which is significantly different from the target compiler. + - [QTBUG-52578][QNX] Unified some defaults between the Unix and Windows + configures. + - [Unix] configure -R now supports paths relative to -libdir. + - [Android@Windows] Added missing -android-ndk-host option to configure.exe. + - [MinGW] Fixed -release -force-debug-info builds actually being neither. + - [WinCE] Fixed (Open)SSL detection. + - Fixed builds with static libc. + +qmake +----- + + - [QTBUG-34182] Fixed UTF-8 BOM breaking dependency calculation. + - [QTBUG-38802][WinRT] Capabilities needed by Qt are now automatically + added to the manifest. + - [QTBUG-50924][WEC7][VS] Fixed deployment of Qt. + - [QTBUG-51775][Unix@Windows] Fixed installation of target.targets when + cross-building. + - [QTBUG-51782] Fixed simultaneous use of the separate_debug_info and + no_plugin_name_prefix CONFIG flags. + - [QTBUG-52008] qmake-generated Visual Studio projects now automatically + invoke windeployqt by default. + - [QTBUG-52998] Restored use of -P option when invoking lex. + - The expansions ${QMAKE_FILE_IN_EXT}, ${QMAKE_FILE_IN_NAME}, and + ${QMAKE_FILE_OUT_PATH} are now understood in extra compilers. -- cgit v1.2.3 From a324194b5965b4232b01e38c32741eadc130e8d1 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Thu, 28 Apr 2016 16:18:15 +0200 Subject: QWidgetLineControl::Command - delete default ctor. While dealing with Coverity's CID 11424 ('missing initializer'), it was recommended (by Marc, thanks) to get rid of Command's default ctor, since it's apparently not needed at all (replacing QVector with std::vector also). Change-Id: Ibe9d2789c67431a9810feb7db4fa1bce0b61921c Reviewed-by: Marc Mutz --- src/widgets/widgets/qwidgetlinecontrol.cpp | 18 +++++++++--------- src/widgets/widgets/qwidgetlinecontrol_p.h | 5 +++-- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/widgets/widgets/qwidgetlinecontrol.cpp b/src/widgets/widgets/qwidgetlinecontrol.cpp index 9097ad01a8..918b6e8c81 100644 --- a/src/widgets/widgets/qwidgetlinecontrol.cpp +++ b/src/widgets/widgets/qwidgetlinecontrol.cpp @@ -697,7 +697,7 @@ bool QWidgetLineControl::finishChange(int validateFromState, bool update, bool e if (m_transactions.count()) return false; internalUndo(validateFromState); - m_history.resize(m_undoState); + m_history.erase(m_history.begin() + m_undoState, m_history.end()); if (m_modifiedState > m_undoState) m_modifiedState = -1; m_validInput = true; @@ -776,14 +776,14 @@ void QWidgetLineControl::internalSetText(const QString &txt, int pos, bool edite */ void QWidgetLineControl::addCommand(const Command &cmd) { - if (m_separator && m_undoState && m_history[m_undoState - 1].type != Separator) { - m_history.resize(m_undoState + 2); - m_history[m_undoState++] = Command(Separator, m_cursor, 0, m_selstart, m_selend); - } else { - m_history.resize(m_undoState + 1); - } + m_history.erase(m_history.begin() + m_undoState, m_history.end()); + + if (m_separator && m_undoState && m_history[m_undoState - 1].type != Separator) + m_history.push_back(Command(Separator, m_cursor, 0, m_selstart, m_selend)); + m_separator = false; - m_history[m_undoState++] = cmd; + m_history.push_back(cmd); + m_undoState = int(m_history.size()); } /*! @@ -1914,7 +1914,7 @@ bool QWidgetLineControl::isRedoAvailable() const // Same as with undo. Disabled for password modes. return !m_readOnly && m_echoMode == QLineEdit::Normal - && m_undoState < m_history.size(); + && m_undoState < int(m_history.size()); } QT_END_NAMESPACE diff --git a/src/widgets/widgets/qwidgetlinecontrol_p.h b/src/widgets/widgets/qwidgetlinecontrol_p.h index 039453f0d5..3d8df9e3ff 100644 --- a/src/widgets/widgets/qwidgetlinecontrol_p.h +++ b/src/widgets/widgets/qwidgetlinecontrol_p.h @@ -61,6 +61,8 @@ #include "qplatformdefs.h" +#include + #ifdef DrawText # undef DrawText #endif @@ -461,7 +463,6 @@ private: // undo/redo handling enum CommandType { Separator, Insert, Remove, Delete, RemoveSelection, DeleteSelection, SetSelection }; struct Command { - inline Command() {} inline Command(CommandType t, int p, QChar c, int ss, int se) : type(t),uc(c),pos(p),selStart(ss),selEnd(se) {} uint type : 4; QChar uc; @@ -469,7 +470,7 @@ private: }; int m_modifiedState; int m_undoState; - QVector m_history; + std::vector m_history; void addCommand(const Command& cmd); inline void separate() { m_separator = true; } -- cgit v1.2.3 From b092f681cf571a1c3068007d1a46633e5ab8b52f Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Thu, 19 May 2016 16:49:45 -0700 Subject: QNSView: Reset the internal buttons state after dragging ends We only track left and right mouse buttons when dragging. But some applications may do this with other mouse buttons. In this case, instead of tracking which button was pressed and which one was released, we just ask Cocoa for the current state. Change-Id: I0df7799b7ae6d7816377f881bc0ede867737d245 Task-number: QTBUG-53374 Reviewed-by: Timur Pocheptsov --- src/plugins/platforms/cocoa/qnsview.mm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 0d58faa5bf..6117e3f2e9 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -2070,7 +2070,11 @@ static QPoint mapWindowCoordinates(QWindow *source, QWindow *target, QPoint poin // keep our state, and QGuiApplication state (buttons member) in-sync, // or future mouse events will be processed incorrectly - m_buttons &= ~(m_sendUpAsRightButton ? Qt::RightButton : Qt::LeftButton); + NSUInteger pmb = [NSEvent pressedMouseButtons]; + for (int buttonNumber = 0; buttonNumber < 32; buttonNumber++) { // see cocoaButton2QtButton() for the 32 value + if (!(pmb & (1 << buttonNumber))) + m_buttons &= ~cocoaButton2QtButton(buttonNumber); + } NSPoint windowPoint = [self convertPoint: point fromView: nil]; QPoint qtWindowPoint(windowPoint.x, windowPoint.y); -- cgit v1.2.3 From 17a4384d120e8bc242f2f0d6c3559609e7547030 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Mon, 23 May 2016 15:35:17 +0200 Subject: iOS: ensure we don't break UIKit IM state when sending key events MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We need to be careful about calling textDidChange on the input delegate, since that will reset the internal IM state in UIKit and stop any ongoing text composition or spell checking. For that reason we set m_inSendEventToFocusObject to true whenever we send an IM event to Qt, to not call the abovementioned method when callbacks from UIKit is the reason for changing the text. But until now we never applied the same protection for key events. This lead to ligatures not working correctly (e.g when using Korean IM), since UIKit composes ligatures by first selecting the characters that can be truncated, then do a deleteBackwards, then insert the ligature. And deleteBackwards leads us to send backspace key events, which ends up in a textDidChange call, which confuses UIKit. This patch will ensure we don't call textDidChange as a result of sending key events. Task-number: QTBUG-52486 Change-Id: Ida268edae517f55a5b5f975340a5d3821f7b8f52 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiostextresponder.mm | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/platforms/ios/qiostextresponder.mm b/src/plugins/platforms/ios/qiostextresponder.mm index 320b1cac61..0cf505930f 100644 --- a/src/plugins/platforms/ios/qiostextresponder.mm +++ b/src/plugins/platforms/ios/qiostextresponder.mm @@ -353,6 +353,7 @@ - (void)sendKeyPressRelease:(Qt::Key)key modifiers:(Qt::KeyboardModifiers)modifiers { + QScopedValueRollback rollback(m_inSendEventToFocusObject, true); QWindowSystemInterface::handleKeyEvent(qApp->focusWindow(), QEvent::KeyPress, key, modifiers); QWindowSystemInterface::handleKeyEvent(qApp->focusWindow(), QEvent::KeyRelease, key, modifiers); QWindowSystemInterface::flushWindowSystemEvents(); -- cgit v1.2.3 From c96ddd9ee553b89bdd0073d273312d40771006bd Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Mon, 23 May 2016 09:41:06 +0200 Subject: QWindowsTheme: Suppress error dialogs when calling SHGetFileInfo(). Set the error mode flag SEM_NOOPENFILEERRORBOX when calling Win32 API SHGetFileInfo() to prevent it from prompting to insert media as does QStorageInfoPrivate::mountedVolumes(). Task-number: QTBUG-32457 Task-number: QTBUG-48823 Change-Id: I01a2f99b5a75b39dd729509ca319f634e3dcd695 Reviewed-by: Maurice Kalinowski --- src/plugins/platforms/windows/qwindowstheme.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp index 4a13f646f2..f673ce5c25 100644 --- a/src/plugins/platforms/windows/qwindowstheme.cpp +++ b/src/plugins/platforms/windows/qwindowstheme.cpp @@ -132,7 +132,16 @@ public: explicit ShGetFileInfoFunction(const wchar_t *fn, DWORD a, SHFILEINFO *i, UINT f, bool *r) : m_fileName(fn), m_attributes(a), m_flags(f), m_info(i), m_result(r) {} - void operator()() const { *m_result = SHGetFileInfo(m_fileName, m_attributes, m_info, sizeof(SHFILEINFO), m_flags); } + void operator()() const + { +#ifndef Q_OS_WINCE + const UINT oldErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX); +#endif + *m_result = SHGetFileInfo(m_fileName, m_attributes, m_info, sizeof(SHFILEINFO), m_flags); +#ifndef Q_OS_WINCE + SetErrorMode(oldErrorMode); +#endif + } private: const wchar_t *m_fileName; -- cgit v1.2.3 From 61521b64a4b9fc1046e0d16cb84c6181ae85493c Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Mon, 23 May 2016 13:32:59 +0200 Subject: Avoid missing paints when resizing GV with QOpenGLWidget viewport There is nothing guaranteeing there will be a paint request after resizeViewportFramebuffer() is called. However we must not be left with a framebuffer with uninitialized content. So trigger an update. Include also a half-hearted autotest. QOpenGLWidget (or QGLWidget) viewports have not been autotested at all. Try to verify that it is functional at least, even if we cannot check the actual output. Change-Id: I34d78fe32e94c39dad919216b5a4f4bb2aea3cc2 Task-number: QTBUG-52419 Reviewed-by: Friedemann Kleint Reviewed-by: Paul Olav Tvete --- src/widgets/kernel/qopenglwidget.cpp | 4 +- .../qgraphicsview/tst_qgraphicsview.cpp | 45 ++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp index e5c5b1dbfd..1d48be5198 100644 --- a/src/widgets/kernel/qopenglwidget.cpp +++ b/src/widgets/kernel/qopenglwidget.cpp @@ -904,8 +904,10 @@ void QOpenGLWidgetPrivate::resizeViewportFramebuffer() if (!initialized) return; - if (!fbo || q->size() * q->devicePixelRatioF() != fbo->size()) + if (!fbo || q->size() * q->devicePixelRatioF() != fbo->size()) { recreateFbo(); + q->update(); + } } /*! diff --git a/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp b/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp index 98473fb5cc..f5083795c7 100644 --- a/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp +++ b/tests/auto/widgets/graphicsview/qgraphicsview/tst_qgraphicsview.cpp @@ -54,6 +54,9 @@ #include #include #include +#ifndef QT_NO_OPENGL +#include +#endif #include #include #include "../../../shared/platforminputcontext.h" @@ -161,6 +164,9 @@ private slots: void sceneRect_growing(); void setSceneRect(); void viewport(); +#ifndef QT_NO_OPENGL + void openGLViewport(); +#endif void dragMode_scrollHand(); void dragMode_rubberBand(); void rubberBandSelectionMode(); @@ -675,6 +681,45 @@ void tst_QGraphicsView::viewport() QTest::qWait(25); } +#ifndef QT_NO_OPENGL +void tst_QGraphicsView::openGLViewport() +{ + QGraphicsScene scene; + scene.setBackgroundBrush(Qt::white); + scene.addText("GraphicsView"); + scene.addEllipse(QRectF(400, 50, 50, 50)); + scene.addEllipse(QRectF(-100, -400, 50, 50)); + scene.addEllipse(QRectF(50, -100, 50, 50)); + scene.addEllipse(QRectF(-100, 50, 50, 50)); + + QGraphicsView view(&scene); + view.setSceneRect(-400, -400, 800, 800); + view.resize(400, 400); + + QOpenGLWidget *glw = new QOpenGLWidget; + QSignalSpy spy1(glw, SIGNAL(resized())); + QSignalSpy spy2(glw, SIGNAL(frameSwapped())); + + view.setViewport(glw); + + view.show(); + QTest::qWaitForWindowExposed(&view); + QTRY_VERIFY(spy1.count() > 0); + QTRY_VERIFY(spy2.count() >= spy1.count()); + spy1.clear(); + spy2.clear(); + + // Now test for resize (QTBUG-52419). This is special when the viewport is + // a QOpenGLWidget since the underlying FBO must also be maintained. + view.resize(300, 300); + QTRY_VERIFY(spy1.count() > 0); + QTRY_VERIFY(spy2.count() >= spy1.count()); + // There is no sane way to check if the framebuffer contents got updated + // (grabFramebuffer is no good for the viewport case as that does not go + // through paintGL). So skip the actual verification. +} +#endif + void tst_QGraphicsView::dragMode_scrollHand() { for (int j = 0; j < 2; ++j) { -- cgit v1.2.3 From e9041c7fc1052167f1ec2df0ea9623059e55d00f Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 28 Apr 2016 22:09:01 -0700 Subject: Fix parsing of tzfile(5) POSIX rule zone names with bracket quotes POSIX.1-2001 allows quoting a zone name so that it can contain other characters besides letters, by enclosing it in angle brackets ('<' and '>'). This hadn't been used until recently (tzdata2016b), when the Asia/Barnaul rule started using a zone name "+07" (the name variable contained the value "<+07>-7"). Thanks to Paul Eggert for reporting and investigating the root cause. Task-number: QTBUG-53071 Change-Id: Id5480807d25e49e78b79ffff1449bc410776cb66 Reviewed-by: Edward Welbourne Reviewed-by: Lars Knoll --- src/corelib/tools/qtimezoneprivate_tz.cpp | 176 ++++++++++++++------- .../auto/corelib/tools/qtimezone/tst_qtimezone.cpp | 10 ++ 2 files changed, 130 insertions(+), 56 deletions(-) diff --git a/src/corelib/tools/qtimezoneprivate_tz.cpp b/src/corelib/tools/qtimezoneprivate_tz.cpp index 85ed345869..cb9581ab63 100644 --- a/src/corelib/tools/qtimezoneprivate_tz.cpp +++ b/src/corelib/tools/qtimezoneprivate_tz.cpp @@ -41,6 +41,8 @@ #include +#include "qlocale_tools_p.h" + #include QT_BEGIN_NAMESPACE @@ -384,25 +386,100 @@ static QTime parsePosixTime(const QByteArray &timeRule) return QTime(2, 0, 0); } -static int parsePosixOffset(const QByteArray &timeRule) +static int parsePosixOffset(const char *begin, const char *end) { // Format "[+|-]hh[:mm[:ss]]" - QList parts = timeRule.split(':'); - int count = parts.count(); - if (count == 3) { - int hour = parts.at(0).toInt(); - int sign = hour >= 0 ? -1 : 1; - return sign * ((qAbs(hour) * 60 * 60) + (parts.at(1).toInt() * 60) + parts.at(2).toInt()); - } else if (count == 2) { - int hour = parts.at(0).toInt(); - int sign = hour >= 0 ? -1 : 1; - return sign * ((qAbs(hour) * 60 * 60) + (parts.at(1).toInt() * 60)); - } else if (count == 1) { - int hour = parts.at(0).toInt(); - int sign = hour >= 0 ? -1 : 1; - return sign * (qAbs(hour) * 60 * 60); - } - return 0; + int hour, min = 0, sec = 0; + + // note that the sign is inverted because POSIX counts in hours West of GMT + bool negate = true; + if (*begin == '+') { + ++begin; + } else if (*begin == '-') { + negate = false; + ++begin; + } + + bool ok = false; + hour = qstrtoll(begin, &begin, 10, &ok); + if (!ok) + return INT_MIN; + if (begin < end && *begin == ':') { + // minutes + ++begin; + min = qstrtoll(begin, &begin, 10, &ok); + if (!ok || min < 0) + return INT_MIN; + + if (begin < end && *begin == ':') { + // seconds + ++begin; + sec = qstrtoll(begin, &begin, 10, &ok); + if (!ok || sec < 0) + return INT_MIN; + } + } + + // we must have consumed everything + if (begin != end) + return INT_MIN; + + int value = (hour * 60 + min) * 60 + sec; + return negate ? -value : value; +} + +static inline bool asciiIsLetter(char ch) +{ + ch |= 0x20; // lowercases if it is a letter, otherwise just corrupts ch + return ch >= 'a' && ch <= 'z'; +} + +// Returns the zone name, the offset (in seconds) and advances \a begin to +// where the parsing ended. Returns a zone of INT_MIN in case an offset +// couldn't be read. +static QPair parsePosixZoneNameAndOffset(const char *&pos, const char *end) +{ + static const char offsetChars[] = "0123456789:"; + QPair result = qMakePair(QString(), INT_MIN); + + const char *nameBegin = pos; + const char *nameEnd; + Q_ASSERT(pos < end); + + if (*pos == '<') { + nameBegin = pos + 1; // skip the '<' + nameEnd = nameBegin; + while (nameEnd < end && *nameEnd != '>') { + // POSIX says only alphanumeric, but we allow anything + ++nameEnd; + } + pos = nameEnd + 1; // skip the '>' + } else { + nameBegin = pos; + nameEnd = nameBegin; + while (nameEnd < end && asciiIsLetter(*nameEnd)) + ++nameEnd; + pos = nameEnd; + } + if (nameEnd - nameBegin < 3) + return result; // name must be at least 3 characters long + + // zone offset, form [+-]hh:mm:ss + const char *zoneBegin = pos; + const char *zoneEnd = pos; + if (zoneEnd < end && (zoneEnd[0] == '+' || zoneEnd[0] == '-')) + ++zoneEnd; + while (zoneEnd < end) { + if (strchr(offsetChars, char(*zoneEnd)) == NULL) + break; + ++zoneEnd; + } + + result.first = QString::fromUtf8(nameBegin, nameEnd - nameBegin); + if (zoneEnd > zoneBegin) + result.second = parsePosixOffset(zoneBegin, zoneEnd); + pos = zoneEnd; + return result; } static QVector calculatePosixTransitions(const QByteArray &posixRule, @@ -419,51 +496,38 @@ static QVector calculatePosixTransitions(const QByteArra // POSIX Format is like "TZ=CST6CDT,M3.2.0/2:00:00,M11.1.0/2:00:00" // i.e. "std offset dst [offset],start[/time],end[/time]" - // See http://www.gnu.org/software/libc/manual/html_node/TZ-Variable.html + // See the section about TZ at http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html QList parts = posixRule.split(','); - QString name = QString::fromUtf8(parts.at(0)); - QString stdName; - QString stdOffsetString; - QString dstName; - QString dstOffsetString; - bool parsedStdName = false; - bool parsedStdOffset = false; - for (int i = 0; i < name.size(); ++i) { - if (name.at(i).isLetter()) { - if (parsedStdName) { - parsedStdOffset = true; - dstName.append(name.at(i)); - } else { - stdName.append(name.at(i)); + QPair stdZone, dstZone; + { + const QByteArray &zoneinfo = parts.at(0); + const char *begin = zoneinfo.constBegin(); + + stdZone = parsePosixZoneNameAndOffset(begin, zoneinfo.constEnd()); + if (stdZone.second == INT_MIN) { + stdZone.second = 0; // reset to UTC if we failed to parse + } else if (begin < zoneinfo.constEnd()) { + dstZone = parsePosixZoneNameAndOffset(begin, zoneinfo.constEnd()); + if (dstZone.second == INT_MIN) { + // if the dst offset isn't provided, it is 1 hour ahead of the standard offset + dstZone.second = stdZone.second + (60 * 60); } - } else { - parsedStdName = true; - if (parsedStdOffset) - dstOffsetString.append(name.at(i)); - else - stdOffsetString.append(name.at(i)); } } - int utcOffset = parsePosixOffset(stdOffsetString.toUtf8()); - // If only the name part then no transitions if (parts.count() == 1) { QTimeZonePrivate::Data data; data.atMSecsSinceEpoch = lastTranMSecs; - data.offsetFromUtc = utcOffset; - data.standardTimeOffset = utcOffset; + data.offsetFromUtc = stdZone.second; + data.standardTimeOffset = stdZone.second; data.daylightTimeOffset = 0; - data.abbreviation = stdName; + data.abbreviation = stdZone.first; result << data; return result; } - // If not populated the total dst offset is 1 hour - int dstOffset = utcOffset + (60 * 60); - if (!dstOffsetString.isEmpty()) - dstOffset = parsePosixOffset(dstOffsetString.toUtf8()); // Get the std to dst transtion details QList dstParts = parts.at(1).split('/'); @@ -486,18 +550,18 @@ static QVector calculatePosixTransitions(const QByteArra for (int year = startYear; year <= endYear; ++year) { QTimeZonePrivate::Data dstData; QDateTime dst(calculatePosixDate(dstDateRule, year), dstTime, Qt::UTC); - dstData.atMSecsSinceEpoch = dst.toMSecsSinceEpoch() - (utcOffset * 1000); - dstData.offsetFromUtc = dstOffset; - dstData.standardTimeOffset = utcOffset; - dstData.daylightTimeOffset = dstOffset - utcOffset; - dstData.abbreviation = dstName; + dstData.atMSecsSinceEpoch = dst.toMSecsSinceEpoch() - (stdZone.second * 1000); + dstData.offsetFromUtc = dstZone.second; + dstData.standardTimeOffset = stdZone.second; + dstData.daylightTimeOffset = dstZone.second - stdZone.second; + dstData.abbreviation = dstZone.first; QTimeZonePrivate::Data stdData; QDateTime std(calculatePosixDate(stdDateRule, year), stdTime, Qt::UTC); - stdData.atMSecsSinceEpoch = std.toMSecsSinceEpoch() - (dstOffset * 1000); - stdData.offsetFromUtc = utcOffset; - stdData.standardTimeOffset = utcOffset; + stdData.atMSecsSinceEpoch = std.toMSecsSinceEpoch() - (dstZone.second * 1000); + stdData.offsetFromUtc = stdZone.second; + stdData.standardTimeOffset = stdZone.second; stdData.daylightTimeOffset = 0; - stdData.abbreviation = stdName; + stdData.abbreviation = stdZone.first; // Part of the high year will overflow if (year == 292278994 && (dstData.atMSecsSinceEpoch < 0 || stdData.atMSecsSinceEpoch < 0)) { if (dstData.atMSecsSinceEpoch > 0) { diff --git a/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp b/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp index ea835108ee..ce72e7ca7f 100644 --- a/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp +++ b/tests/auto/corelib/tools/qtimezone/tst_qtimezone.cpp @@ -847,6 +847,16 @@ void tst_QTimeZone::tzTest() QTzTimeZonePrivate::Data datatz2 = tztz2.data(std); QTzTimeZonePrivate::Data datautc2 = tzutc2.data(std); QCOMPARE(datatz2.offsetFromUtc, datautc2.offsetFromUtc); + + // Test a timezone with a name that isn't all letters + QTzTimeZonePrivate tzBarnaul("Asia/Barnaul"); + if (tzBarnaul.isValid()) { + QCOMPARE(tzBarnaul.data(std).abbreviation, QString("+07")); + + // first full day of the new rule (tzdata2016b) + QDateTime dt(QDate(2016, 3, 28), QTime(0, 0, 0), Qt::UTC); + QCOMPARE(tzBarnaul.data(dt.toMSecsSinceEpoch()).abbreviation, QString("+07")); + } #endif // Q_OS_UNIX } -- cgit v1.2.3 From cd25866f6533923c208f52d58516f3725f69cefb Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 18 May 2016 13:38:55 -0700 Subject: Use the code we already have for parsing the transition time too It's there and it's more efficient anyway. Change-Id: Ie9fd7afe060b4e4a8052fffd144fc40647430268 Reviewed-by: Edward Welbourne Reviewed-by: Brett Stottlemyer Reviewed-by: Lars Knoll --- src/corelib/tools/qtimezoneprivate_tz.cpp | 68 ++++++++++++++++++------------- 1 file changed, 40 insertions(+), 28 deletions(-) diff --git a/src/corelib/tools/qtimezoneprivate_tz.cpp b/src/corelib/tools/qtimezoneprivate_tz.cpp index cb9581ab63..bfa967e67b 100644 --- a/src/corelib/tools/qtimezoneprivate_tz.cpp +++ b/src/corelib/tools/qtimezoneprivate_tz.cpp @@ -372,37 +372,21 @@ static QDate calculatePosixDate(const QByteArray &dateRule, int year) } } -static QTime parsePosixTime(const QByteArray &timeRule) +// returns the time in seconds, INT_MIN if we failed to parse +static int parsePosixTime(const char *begin, const char *end) { - // Format "HH:mm:ss", put check parts count just in case - QList parts = timeRule.split(':'); - int count = parts.count(); - if (count == 3) - return QTime(parts.at(0).toInt(), parts.at(1).toInt(), parts.at(2).toInt()); - else if (count == 2) - return QTime(parts.at(0).toInt(), parts.at(1).toInt(), 0); - else if (count == 1) - return QTime(parts.at(0).toInt(), 0, 0); - return QTime(2, 0, 0); -} - -static int parsePosixOffset(const char *begin, const char *end) -{ - // Format "[+|-]hh[:mm[:ss]]" + // Format "hh[:mm[:ss]]" int hour, min = 0, sec = 0; - // note that the sign is inverted because POSIX counts in hours West of GMT - bool negate = true; - if (*begin == '+') { - ++begin; - } else if (*begin == '-') { - negate = false; - ++begin; - } + // Note that the calls to qstrtoll do *not* check the end pointer, which + // means they proceed until they find a non-digit. We check that we're + // still in range at the end, but we may have read from past end. It's the + // caller's responsibility to ensure that begin is part of a + // null-terminated string. bool ok = false; hour = qstrtoll(begin, &begin, 10, &ok); - if (!ok) + if (!ok || hour < 0) return INT_MIN; if (begin < end && *begin == ':') { // minutes @@ -424,7 +408,35 @@ static int parsePosixOffset(const char *begin, const char *end) if (begin != end) return INT_MIN; - int value = (hour * 60 + min) * 60 + sec; + return (hour * 60 + min) * 60 + sec; +} + +static QTime parsePosixTransitionTime(const QByteArray &timeRule) +{ + // Format "hh[:mm[:ss]]" + int value = parsePosixTime(timeRule.constBegin(), timeRule.constEnd()); + if (value == INT_MIN) { + // if we failed to parse, return 02:00 + return QTime(2, 0, 0); + } + return QTime::fromMSecsSinceStartOfDay(value * 1000); +} + +static int parsePosixOffset(const char *begin, const char *end) +{ + // Format "[+|-]hh[:mm[:ss]]" + // note that the sign is inverted because POSIX counts in hours West of GMT + bool negate = true; + if (*begin == '+') { + ++begin; + } else if (*begin == '-') { + negate = false; + ++begin; + } + + int value = parsePosixTime(begin, end); + if (value == INT_MIN) + return value; return negate ? -value : value; } @@ -534,7 +546,7 @@ static QVector calculatePosixTransitions(const QByteArra QByteArray dstDateRule = dstParts.at(0); QTime dstTime; if (dstParts.count() > 1) - dstTime = parsePosixTime(dstParts.at(1)); + dstTime = parsePosixTransitionTime(dstParts.at(1)); else dstTime = QTime(2, 0, 0); @@ -543,7 +555,7 @@ static QVector calculatePosixTransitions(const QByteArra QByteArray stdDateRule = stdParts.at(0); QTime stdTime; if (stdParts.count() > 1) - stdTime = parsePosixTime(stdParts.at(1)); + stdTime = parsePosixTransitionTime(stdParts.at(1)); else stdTime = QTime(2, 0, 0); -- cgit v1.2.3 From 84ab88ce416fe5bb616ff64d26e5282e86f54cd8 Mon Sep 17 00:00:00 2001 From: Andy Shaw Date: Tue, 24 May 2016 06:50:59 +0200 Subject: QWindowsPrintDevice: Handle return value of DocumentProperties correctly If the return value is less than 0 which signifies an error then trying to malloc that will cause an exception. Change-Id: Ia0153d4cb7aac1dacb509280b45be149a093b7c4 Reviewed-by: Friedemann Kleint --- .../printsupport/windows/qwindowsprintdevice.cpp | 156 +++++++++------------ 1 file changed, 68 insertions(+), 88 deletions(-) diff --git a/src/plugins/printsupport/windows/qwindowsprintdevice.cpp b/src/plugins/printsupport/windows/qwindowsprintdevice.cpp index d378ff3130..98978f4bbe 100644 --- a/src/plugins/printsupport/windows/qwindowsprintdevice.cpp +++ b/src/plugins/printsupport/windows/qwindowsprintdevice.cpp @@ -1,6 +1,7 @@ /**************************************************************************** ** ** Copyright (C) 2014 John Layt +** Copyright (C) 2016 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of the plugins of the Qt Toolkit. @@ -74,6 +75,22 @@ static QPrint::InputSlot paperBinToInputSlot(int windowsId, const QString &name) return slot; } +static LPDEVMODE getDevmode(HANDLE hPrinter, const QString &printerId) +{ + LPWSTR printerIdUtf16 = const_cast(reinterpret_cast(printerId.utf16())); + // Allocate the required DEVMODE buffer + LONG dmSize = DocumentProperties(NULL, hPrinter, printerIdUtf16, NULL, NULL, 0); + if (dmSize < 0) + return Q_NULLPTR; + LPDEVMODE pDevMode = reinterpret_cast(malloc(dmSize)); + // Get the default DevMode + LONG result = DocumentProperties(NULL, hPrinter, printerIdUtf16, pDevMode, NULL, DM_OUT_BUFFER); + if (result != IDOK) { + free(pDevMode); + pDevMode = Q_NULLPTR; + } + return pDevMode; +} QWindowsPrintDevice::QWindowsPrintDevice() : QPlatformPrintDevice(), @@ -191,26 +208,21 @@ QPageSize QWindowsPrintDevice::defaultPageSize() const QPageSize pageSize; - // Allocate the required DEVMODE buffer - DWORD dmSize = DocumentProperties(NULL, m_hPrinter, (LPWSTR)m_id.utf16(), NULL, NULL, 0); - LPDEVMODE pDevMode = (LPDEVMODE)malloc(dmSize); - - // Get the default DevMode - DWORD result = DocumentProperties(NULL, m_hPrinter, (LPWSTR)m_id.utf16(), pDevMode, NULL, DM_OUT_BUFFER); - - // Get the default paper size - if (result == IDOK && pDevMode->dmFields & DM_PAPERSIZE) { - // Find the supported page size that matches, in theory default should be one of them - foreach (const QPageSize &ps, m_pageSizes) { - if (ps.windowsId() == pDevMode->dmPaperSize) { - pageSize = ps; - break; + if (LPDEVMODE pDevMode = getDevmode(m_hPrinter, m_id)) { + // Get the default paper size + if (pDevMode->dmFields & DM_PAPERSIZE) { + // Find the supported page size that matches, in theory default should be one of them + foreach (const QPageSize &ps, m_pageSizes) { + if (ps.windowsId() == pDevMode->dmPaperSize) { + pageSize = ps; + break; + } } } + // Clean-up + free(pDevMode); } - // Clean-up - free(pDevMode); return pageSize; } @@ -226,20 +238,14 @@ QMarginsF QWindowsPrintDevice::printableMargins(const QPageSize &pageSize, QScopedArrayPointer buffer(new BYTE[needed]); if (GetPrinter(m_hPrinter, 2, buffer.data(), needed, &needed)) { PPRINTER_INFO_2 info = reinterpret_cast(buffer.data()); - DEVMODE *devMode = info->pDevMode; + LPDEVMODE devMode = info->pDevMode; bool separateDevMode = false; if (!devMode) { // GetPrinter() didn't include the DEVMODE. Get it a different way. - LONG result = DocumentProperties(NULL, m_hPrinter, (LPWSTR)m_id.utf16(), - NULL, NULL, 0); - devMode = (DEVMODE *)malloc(result); - separateDevMode = true; - result = DocumentProperties(NULL, m_hPrinter, (LPWSTR)m_id.utf16(), - devMode, NULL, DM_OUT_BUFFER); - if (result != IDOK) { - free(devMode); + devMode = getDevmode(m_hPrinter, m_id); + if (!devMode) return margins; - } + separateDevMode = true; } HDC pDC = CreateDC(NULL, (LPWSTR)m_id.utf16(), NULL, devMode); @@ -291,23 +297,17 @@ int QWindowsPrintDevice::defaultResolution() const { int resolution = 72; // TODO Set a sensible default? - // Allocate the required DEVMODE buffer - DWORD dmSize = DocumentProperties(NULL, m_hPrinter, (LPWSTR)m_id.utf16(), NULL, NULL, 0); - LPDEVMODE pDevMode = (LPDEVMODE)malloc(dmSize); - - // Get the default DevMode - DWORD result = DocumentProperties(NULL, m_hPrinter, (LPWSTR)m_id.utf16(), pDevMode, NULL, DM_OUT_BUFFER); - - // Get the default resolution - if (result == IDOK && pDevMode->dmFields & DM_YRESOLUTION) { - if (pDevMode->dmPrintQuality > 0) - resolution = pDevMode->dmPrintQuality; - else - resolution = pDevMode->dmYResolution; + if (LPDEVMODE pDevMode = getDevmode(m_hPrinter, m_id)) { + // Get the default resolution + if (pDevMode->dmFields & DM_YRESOLUTION) { + if (pDevMode->dmPrintQuality > 0) + resolution = pDevMode->dmPrintQuality; + else + resolution = pDevMode->dmYResolution; + } + // Clean-up + free(pDevMode); } - - // Clean-up - free(pDevMode); return resolution; } @@ -340,26 +340,20 @@ QPrint::InputSlot QWindowsPrintDevice::defaultInputSlot() const { QPrint::InputSlot inputSlot = QPlatformPrintDevice::defaultInputSlot();; - // Allocate the required DEVMODE buffer - DWORD dmSize = DocumentProperties(NULL, m_hPrinter, (LPWSTR)m_id.utf16(), NULL, NULL, 0); - LPDEVMODE pDevMode = (LPDEVMODE)malloc(dmSize); - - // Get the default DevMode - DWORD result = DocumentProperties(NULL, m_hPrinter, (LPWSTR)m_id.utf16(), pDevMode, NULL, DM_OUT_BUFFER); - - // Get the default input slot - if (result == IDOK && pDevMode->dmFields & DM_DEFAULTSOURCE) { - QPrint::InputSlot tempSlot = paperBinToInputSlot(pDevMode->dmDefaultSource, QString()); - foreach (const QPrint::InputSlot &slot, supportedInputSlots()) { - if (slot.key == tempSlot.key) { - inputSlot = slot; - break; + if (LPDEVMODE pDevMode = getDevmode(m_hPrinter, m_id)) { + // Get the default input slot + if (pDevMode->dmFields & DM_DEFAULTSOURCE) { + QPrint::InputSlot tempSlot = paperBinToInputSlot(pDevMode->dmDefaultSource, QString()); + foreach (const QPrint::InputSlot &slot, supportedInputSlots()) { + if (slot.key == tempSlot.key) { + inputSlot = slot; + break; + } } } + // Clean-up + free(pDevMode); } - - // Clean-up - free(pDevMode); return inputSlot; } @@ -386,23 +380,17 @@ QPrint::DuplexMode QWindowsPrintDevice::defaultDuplexMode() const { QPrint::DuplexMode duplexMode = QPrint::DuplexNone; - // Allocate the required DEVMODE buffer - DWORD dmSize = DocumentProperties(NULL, m_hPrinter, (LPWSTR)m_id.utf16(), NULL, NULL, 0); - LPDEVMODE pDevMode = (LPDEVMODE)malloc(dmSize); - - // Get the default DevMode - DWORD result = DocumentProperties(NULL, m_hPrinter, (LPWSTR)m_id.utf16(), pDevMode, NULL, DM_OUT_BUFFER); - - // Get the default duplex mode - if (result == IDOK && pDevMode->dmFields & DM_DUPLEX) { - if (pDevMode->dmDuplex == DMDUP_VERTICAL) - duplexMode = QPrint::DuplexLongSide; - else if (pDevMode->dmDuplex == DMDUP_HORIZONTAL) - duplexMode = QPrint::DuplexShortSide; + if (LPDEVMODE pDevMode = getDevmode(m_hPrinter, m_id)) { + // Get the default duplex mode + if (pDevMode->dmFields & DM_DUPLEX) { + if (pDevMode->dmDuplex == DMDUP_VERTICAL) + duplexMode = QPrint::DuplexLongSide; + else if (pDevMode->dmDuplex == DMDUP_HORIZONTAL) + duplexMode = QPrint::DuplexShortSide; + } + // Clean-up + free(pDevMode); } - - // Clean-up - free(pDevMode); return duplexMode; } @@ -424,21 +412,13 @@ QPrint::ColorMode QWindowsPrintDevice::defaultColorMode() const QPrint::ColorMode colorMode = QPrint::GrayScale; - // Allocate the required DEVMODE buffer - DWORD dmSize = DocumentProperties(NULL, m_hPrinter, (LPWSTR)m_id.utf16(), NULL, NULL, 0); - LPDEVMODE pDevMode = (LPDEVMODE)malloc(dmSize); - - // Get the default DevMode - DWORD result = DocumentProperties(NULL, m_hPrinter, (LPWSTR)m_id.utf16(), pDevMode, NULL, DM_OUT_BUFFER); - - // Get the default color mode - if (result == IDOK && pDevMode->dmFields & DM_COLOR) { - if (pDevMode->dmColor == DMCOLOR_COLOR) + if (LPDEVMODE pDevMode = getDevmode(m_hPrinter, m_id)) { + // Get the default color mode + if (pDevMode->dmFields & DM_COLOR && pDevMode->dmColor == DMCOLOR_COLOR) colorMode = QPrint::Color; + // Clean-up + free(pDevMode); } - - // Clean-up - free(pDevMode); return colorMode; } -- cgit v1.2.3 From 07667b439025a8bb47f6089673b11a479b21b72d Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Tue, 24 May 2016 14:37:44 +0200 Subject: tst_QNetworkReply: Un-blacklist recently fixed test. A recent fix now makes authenticationCacheAfterCancel(http+socksauth) work again, so un-blacklist it. Added a helpful comment while I was at it. Change-Id: I2d7eae8d80c12957d22659a82e5072301735c41f Reviewed-by: Timur Pocheptsov --- tests/auto/network/access/qnetworkreply/BLACKLIST | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/auto/network/access/qnetworkreply/BLACKLIST b/tests/auto/network/access/qnetworkreply/BLACKLIST index 0605677e29..1d56c78bbc 100644 --- a/tests/auto/network/access/qnetworkreply/BLACKLIST +++ b/tests/auto/network/access/qnetworkreply/BLACKLIST @@ -1,3 +1,4 @@ +# See qtbase/src/testlib/qtestblacklist.cpp for format osx [ioGetFromBuiltinHttp:http+limited] ubuntu-14.04 @@ -7,7 +8,3 @@ ubuntu-14.04 * [backgroundRequestInterruption:ftp, bg, nobg] * -[authenticationCacheAfterCancel:http+socksauth] -rhel-7.1 -[authenticationCacheAfterCancel:https+socksauth] -rhel-7.1 -- cgit v1.2.3 From 832715a67908683241b8da524f6aa0c1a8a4267e Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Tue, 24 May 2016 16:13:02 +0200 Subject: qtestblacklist: only generate the distro and version once We were looking up distro and version, in order to conditionally add them to keywords if missing, on every keyword line of each BLACKLIST that we parsed. In particular, this meant the static holding the list of keywords couldn't be const. Move the distro-handling to an intemediary function that adds to the raw keywords and supplies one-off initialization for the list of conditions to match. Change-Id: Ia383ec060e24b7f72d2c8fd6ae65816318daafd0 Reviewed-by: Lars Knoll --- src/testlib/qtestblacklist.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/testlib/qtestblacklist.cpp b/src/testlib/qtestblacklist.cpp index 04c6aa2717..da98b88989 100644 --- a/src/testlib/qtestblacklist.cpp +++ b/src/testlib/qtestblacklist.cpp @@ -135,19 +135,26 @@ static QSet keywords() return set; } -static bool checkCondition(const QByteArray &condition) +static QSet activeConditions() { - static QSet matchedConditions = keywords(); - QList conds = condition.split(' '); + QSet result = keywords(); QByteArray distributionName = QSysInfo::productType().toLower().toUtf8(); QByteArray distributionRelease = QSysInfo::productVersion().toLower().toUtf8(); if (!distributionName.isEmpty()) { - if (matchedConditions.find(distributionName) == matchedConditions.end()) - matchedConditions.insert(distributionName); - matchedConditions.insert(distributionName + "-" + distributionRelease); + if (result.find(distributionName) == result.end()) + result.insert(distributionName); + result.insert(distributionName + "-" + distributionRelease); } + return result; +} + +static bool checkCondition(const QByteArray &condition) +{ + static const QSet matchedConditions = activeConditions(); + QList conds = condition.split(' '); + for (int i = 0; i < conds.size(); ++i) { QByteArray c = conds.at(i); bool result = c.startsWith('!'); -- cgit v1.2.3 From 6f59926e670d68b27a387651a466f47ca9e8fd37 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Tue, 24 May 2016 16:16:56 +0200 Subject: qtestblacklist: check against duplicating versioned distro Also check the version is non-empty. Probably makes no difference, but it's obviously more correct. Change-Id: I05eee5623ac432d2ea02f7aad874513beeb2ceeb Reviewed-by: Lars Knoll --- src/testlib/qtestblacklist.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/testlib/qtestblacklist.cpp b/src/testlib/qtestblacklist.cpp index da98b88989..9300cb58af 100644 --- a/src/testlib/qtestblacklist.cpp +++ b/src/testlib/qtestblacklist.cpp @@ -144,7 +144,11 @@ static QSet activeConditions() if (!distributionName.isEmpty()) { if (result.find(distributionName) == result.end()) result.insert(distributionName); - result.insert(distributionName + "-" + distributionRelease); + if (!distributionRelease.isEmpty()) { + QByteArray versioned = distributionName + "-" + distributionRelease; + if (result.find(versioned) == result.end()) + result.insert(versioned); + } } return result; -- cgit v1.2.3 From b057fdbb12341da9e972bcd16c5c4f1b751cac01 Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Tue, 24 May 2016 15:32:43 +0200 Subject: Improve documentation of BLACKLIST file format. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In particular, make sure the word BLACKLIST appears in it so it can actually be *found*. Mention the comment format, mention version suffixes, mention negation; expand and clarify the description. Break it up into paragraphs for ease of reading. Corrected the example to use osx, not its old platform name. Gave it a comment that I wish I'd found in the BLACKLIST file that obliged me to come looking for this in the first place. Illustrated the use of comments to document reasons for ignoring tests. Change-Id: I78d49b4706c0f70b714f7a410f850fb42ebb77c0 Reviewed-by: Lars Knoll Reviewed-by: Timur Pocheptsov Reviewed-by: Jędrzej Nowacki --- src/testlib/qtestblacklist.cpp | 47 ++++++++++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/src/testlib/qtestblacklist.cpp b/src/testlib/qtestblacklist.cpp index 9300cb58af..9dfd5065ad 100644 --- a/src/testlib/qtestblacklist.cpp +++ b/src/testlib/qtestblacklist.cpp @@ -46,21 +46,38 @@ QT_BEGIN_NAMESPACE /* - The file format is simply a grouped listing of keywords - Ungrouped entries at the beginning apply to the whole testcase - Groups define testfunctions or specific test data to ignore. - After the groups come a list of entries (one per line) that define - for which platform/os combination to ignore the test result. - All keys in a single line have to match to blacklist the test. - - mac - [testFunction] - linux - windows 64bit - [testfunction2:testData] - msvc - - The known keys are listed below: + The BLACKLIST file format is a grouped listing of keywords. + + Blank lines and lines starting with # are simply ignored. An initial #-line + referring to this documentation is kind to readers. Comments can also be used + to indicate the reasons for ignoring particular cases. + + A key names a platform, O/S, distribution, tool-chain or architecture; a ! + prefix reverses what it checks. A version, joined to a key (at present, only + for distributions and for msvc) with a hyphen, limits the key to the specific + version. A keyword line matches if every key on it applies to the present + run. Successive lines are alternate conditions for ignoring a test. + + Ungrouped lines at the beginning of a file apply to the whole testcase. + A group starts with a [square-bracketed] identification of a test function, + optionally with (after a colon, the name of) a specific data set, to ignore. + Subsequent lines give conditions for ignoring this test. + + # See qtbase/src/testlib/qtestblacklist.cpp for format + osx + + # QTBUG-12345 + [testFunction] + linux + windows 64bit + + # Needs basic C++11 support + [testfunction2:testData] + msvc-2010 + + Keys are lower-case. Distribution name and version are supported if + QSysInfo's productType() and productVersion() return them. + The other known keys are listed below: */ static QSet keywords() -- cgit v1.2.3 From 5c16b73243f56cc61bf199a8505a86f011405e98 Mon Sep 17 00:00:00 2001 From: Ralf Nolden Date: Tue, 24 May 2016 19:22:29 +0200 Subject: Compile Fix: unused variable in q_refreshRateFromFb() on non-linux To fix a compile warning under non-Linux systems, declare framebufferDevice in q_refreshRateFromFb() as Q_UNUSED like in the other functions. Change-Id: I31a4e788f07d27d3cff7f6ea7fd82813a7acc7d9 Reviewed-by: Laszlo Agocs --- src/platformsupport/eglconvenience/qeglconvenience.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/platformsupport/eglconvenience/qeglconvenience.cpp b/src/platformsupport/eglconvenience/qeglconvenience.cpp index 922455c96f..be700dce01 100644 --- a/src/platformsupport/eglconvenience/qeglconvenience.cpp +++ b/src/platformsupport/eglconvenience/qeglconvenience.cpp @@ -578,6 +578,10 @@ int q_screenDepthFromFb(int framebufferDevice) qreal q_refreshRateFromFb(int framebufferDevice) { +#ifndef Q_OS_LINUX + Q_UNUSED(framebufferDevice) +#endif + static qreal rate = 0; #ifdef Q_OS_LINUX -- cgit v1.2.3 From e0ab94b5251e732d4bea553f2d6e943f5d714720 Mon Sep 17 00:00:00 2001 From: Ralf Nolden Date: Tue, 24 May 2016 22:02:02 +0200 Subject: Compile fix: for OpenBSD: not included by On OpenBSD, isn't included in , so that leads to compile errors on files that include qcore_unix_p.h: qcore_unix_p.h:335:69: error: 'fd_set' has not been declared Just move the whole select include section from qcore_unix.cpp, no functional changes. The patch is adapted from OpenBSD ports maintainer Vadim Zhukov patch for qt ports. Change-Id: I35ba693440b1c1644bcfcdb69823e2b37870ad97 Reviewed-by: Thiago Macieira --- src/corelib/kernel/qcore_unix.cpp | 10 ---------- src/corelib/kernel/qcore_unix_p.h | 10 ++++++++++ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/corelib/kernel/qcore_unix.cpp b/src/corelib/kernel/qcore_unix.cpp index 5695cb3ec5..1bcb4720c2 100644 --- a/src/corelib/kernel/qcore_unix.cpp +++ b/src/corelib/kernel/qcore_unix.cpp @@ -34,16 +34,6 @@ #include "qcore_unix_p.h" #include "qelapsedtimer.h" -#ifdef Q_OS_NACL -#elif !defined (Q_OS_VXWORKS) -# if !defined(Q_OS_HPUX) || defined(__ia64) -# include -# endif -# include -#else -# include -#endif - #include #ifdef Q_OS_MAC diff --git a/src/corelib/kernel/qcore_unix_p.h b/src/corelib/kernel/qcore_unix_p.h index f80dcb5a50..05711354ff 100644 --- a/src/corelib/kernel/qcore_unix_p.h +++ b/src/corelib/kernel/qcore_unix_p.h @@ -58,6 +58,16 @@ #include #include +#ifdef Q_OS_NACL +#elif !defined (Q_OS_VXWORKS) +# if !defined(Q_OS_HPUX) || defined(__ia64) +# include +# endif +# include +#else +# include +#endif + #include #include #include -- cgit v1.2.3 From f75b78a92a689b90124c79e50525bbc78540c576 Mon Sep 17 00:00:00 2001 From: Timur Pocheptsov Date: Wed, 18 May 2016 16:31:52 +0200 Subject: Cocoa integration - fix QCocoaWindow::setContentView MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - QCocoaWindow::setContentView calls -removeFromSuperView and this is not valid for a view that is a content view for a NSWindow: using it will release the view but not clear the window.contentView pointer. Set contentView to nil instead. Fixing this makes visible the second problem: - QNSWindowHelper in its -handleWindowEvent: can access content view and assumes it's QNSView - it is not always guaranteed and can result in invalid message sent to a view, we can use m_qtView instead (it will be nil if it has a type different from QNSView, the call will be noop then). Task-number: QTBUG-53325 Change-Id: I0472eba8165a04b6a3f81b2171b3bb9827ff5681 Reviewed-by: Morten Johan Sørvig --- src/plugins/platforms/cocoa/qcocoawindow.mm | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm index c5519995b6..c0d5904367 100644 --- a/src/plugins/platforms/cocoa/qcocoawindow.mm +++ b/src/plugins/platforms/cocoa/qcocoawindow.mm @@ -148,7 +148,7 @@ static bool isMouseEvent(NSEvent *ev) if (NSMouseInRect(loc, windowFrame, NO) && !NSMouseInRect(loc, contentFrame, NO)) { - QNSView *contentView = (QNSView *)pw->contentView(); + QNSView *contentView = pw->m_qtView; [contentView handleFrameStrutMouseEvent: theEvent]; } } @@ -1173,7 +1173,11 @@ NSView *QCocoaWindow::contentView() const void QCocoaWindow::setContentView(NSView *contentView) { // Remove and release the previous content view - [m_contentView removeFromSuperview]; + if (m_nsWindow) + [m_nsWindow setContentView:nil]; + else + [m_contentView removeFromSuperview]; + [m_contentView release]; // Insert and retain the new content view -- cgit v1.2.3 From 421aa422af2f6b147ad076ad1736b3747abc4317 Mon Sep 17 00:00:00 2001 From: Eirik Aavitsland Date: Wed, 25 May 2016 10:27:51 +0200 Subject: Really fix crash on certain malformed bmp images This is an improvement of e4f71b0c. By using the QImageReader::read() overload taking a QImage pointer, and ignoring the return value, one could still end up with a corrupt QImage object. Avoid the subsequent crashes by closing that hole. Change-Id: I5dca10e4808ac3365e3ddba6689edecb7444948f Reviewed-by: Allan Sandfeld Jensen Reviewed-by: Lars Knoll Reviewed-by: Richard J. Moore --- src/gui/image/qbmphandler.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/gui/image/qbmphandler.cpp b/src/gui/image/qbmphandler.cpp index 27bab10196..bb238d3eb3 100644 --- a/src/gui/image/qbmphandler.cpp +++ b/src/gui/image/qbmphandler.cpp @@ -283,6 +283,12 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, int offset, int format = QImage::Format_Mono; } + if (depth != 32) { + ncols = bi.biClrUsed ? bi.biClrUsed : 1 << nbits; + if (ncols < 1 || ncols > 256) // sanity check - don't run out of mem if color table is broken + return false; + } + if (bi.biHeight < 0) h = -h; // support images with negative height @@ -290,19 +296,15 @@ static bool read_dib_body(QDataStream &s, const BMP_INFOHDR &bi, int offset, int image = QImage(w, h, format); if (image.isNull()) // could not create image return false; - } - - if (depth != 32) { - ncols = bi.biClrUsed ? bi.biClrUsed : 1 << nbits; - if (ncols < 1 || ncols > 256) // sanity check - don't run out of mem if color table is broken - return false; - image.setColorCount(ncols); + if (ncols) + image.setColorCount(ncols); // Ensure valid QImage } image.setDotsPerMeterX(bi.biXPelsPerMeter); image.setDotsPerMeterY(bi.biYPelsPerMeter); if (ncols > 0) { // read color table + image.setColorCount(ncols); uchar rgb[4]; int rgb_len = t == BMP_OLD ? 3 : 4; for (int i=0; i Date: Tue, 15 Mar 2016 10:10:12 -0700 Subject: Replace qUnaligned{Load,Store} with the existing q{To,From}Unaligned Move the Q_ALWAYS_INLINE and forcing of __builtin_memcpy to the existing functions. Change-Id: Icaa7fb2a490246bda156ffff143c137e520eea79 Reviewed-by: Lars Knoll --- src/corelib/global/qendian.h | 30 +++++++++++++++++--------- src/corelib/global/qendian.qdoc | 23 ++++++++++++++++++++ src/corelib/json/qjson_p.h | 2 +- src/corelib/mimetypes/qmimemagicrule.cpp | 3 +-- src/corelib/tools/qbitarray.cpp | 26 ++++------------------ src/corelib/tools/qhash.cpp | 9 ++++---- src/corelib/tools/qsimd.cpp | 22 ------------------- src/corelib/tools/qsimd_p.h | 37 -------------------------------- src/corelib/tools/qstring.cpp | 2 +- 9 files changed, 55 insertions(+), 99 deletions(-) diff --git a/src/corelib/global/qendian.h b/src/corelib/global/qendian.h index 2ddefaec8b..23dda270e3 100644 --- a/src/corelib/global/qendian.h +++ b/src/corelib/global/qendian.h @@ -42,6 +42,11 @@ QT_BEGIN_NAMESPACE +#ifdef __has_builtin +# define QT_HAS_BUILTIN(x) __has_builtin(x) +#else +# define QT_HAS_BUILTIN(x) 0 +#endif /* * ENDIAN FUNCTIONS @@ -64,18 +69,29 @@ template inline void qbswap(const T src, uchar *dest) // Used to implement a type-safe and alignment-safe copy operation // If you want to avoid the memcpy, you must write specializations for these functions -template inline void qToUnaligned(const T src, uchar *dest) +template Q_ALWAYS_INLINE void qToUnaligned(const T src, uchar *dest) { // Using sizeof(T) inside memcpy function produces internal compiler error with // MSVC2008/ARM in tst_endian -> use extra indirection to resolve size of T. const size_t size = sizeof(T); - memcpy(dest, &src, size); +#if QT_HAS_BUILTIN(__builtin_memcpy) + __builtin_memcpy +#else + memcpy +#endif + (dest, &src, size); } -template inline T qFromUnaligned(const uchar *src) + +template Q_ALWAYS_INLINE T qFromUnaligned(const uchar *src) { T dest; const size_t size = sizeof(T); - memcpy(&dest, src, size); +#if QT_HAS_BUILTIN(__builtin_memcpy) + __builtin_memcpy +#else + memcpy +#endif + (&dest, src, size); return dest; } @@ -87,12 +103,6 @@ template inline T qFromUnaligned(const uchar *src) */ template T qbswap(T source); -#ifdef __has_builtin -# define QT_HAS_BUILTIN(x) __has_builtin(x) -#else -# define QT_HAS_BUILTIN(x) 0 -#endif - // GCC 4.3 implemented all the intrinsics, but the 16-bit one only got implemented in 4.8; // Clang 2.6 implemented the 32- and 64-bit but waited until 3.2 to implement the 16-bit one #if (defined(Q_CC_GNU) && Q_CC_GNU >= 403) || QT_HAS_BUILTIN(__builtin_bswap32) diff --git a/src/corelib/global/qendian.qdoc b/src/corelib/global/qendian.qdoc index e110461f8b..b7494c9a21 100644 --- a/src/corelib/global/qendian.qdoc +++ b/src/corelib/global/qendian.qdoc @@ -33,6 +33,29 @@ little and big endian representations of numbers. */ +/*! + \internal + \fn T qFromUnaligned(const uchar *ptr) + \since 5.5 + + Loads a \c{T} from address \a ptr, which may be misaligned. + + Use of this function avoids the undefined behavior that the C++ standard + otherwise attributes to unaligned loads. +*/ + +/*! + \internal + \fn void qToUnaligned(T t, uchar *ptr) + \since 4.5 + + Stores \a t to address \a ptr, which may be misaligned. + + Use of this function avoids the undefined behavior that the C++ standard + otherwise attributes to unaligned stores. +*/ + + /*! \fn T qFromBigEndian(const uchar *src) \since 4.3 diff --git a/src/corelib/json/qjson_p.h b/src/corelib/json/qjson_p.h index 59d0c91785..c52a37ba2b 100644 --- a/src/corelib/json/qjson_p.h +++ b/src/corelib/json/qjson_p.h @@ -402,7 +402,7 @@ public: // pack with itself, we'll discard the high part anyway chunk = _mm_packus_epi16(chunk, chunk); // unaligned 64-bit store - qUnalignedStore(l + i, _mm_cvtsi128_si64(chunk)); + qToUnaligned(_mm_cvtsi128_si64(chunk), l + i); i += 8; } # endif diff --git a/src/corelib/mimetypes/qmimemagicrule.cpp b/src/corelib/mimetypes/qmimemagicrule.cpp index 44834420fe..398a670544 100644 --- a/src/corelib/mimetypes/qmimemagicrule.cpp +++ b/src/corelib/mimetypes/qmimemagicrule.cpp @@ -42,7 +42,6 @@ #include #include #include -#include // for qUnalignedLoad QT_BEGIN_NAMESPACE @@ -177,7 +176,7 @@ static bool matchNumber(const QMimeMagicRulePrivate *d, const QByteArray &data) const char *p = data.constData() + d->startPos; const char *e = data.constData() + qMin(data.size() - int(sizeof(T)), d->endPos + 1); for ( ; p <= e; ++p) { - if ((qUnalignedLoad(p) & mask) == (value & mask)) + if ((qFromUnaligned(reinterpret_cast(p)) & mask) == (value & mask)) return true; } diff --git a/src/corelib/tools/qbitarray.cpp b/src/corelib/tools/qbitarray.cpp index a64edea77e..8e6b1203f8 100644 --- a/src/corelib/tools/qbitarray.cpp +++ b/src/corelib/tools/qbitarray.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include QT_BEGIN_NAMESPACE @@ -162,25 +163,6 @@ QBitArray::QBitArray(int size, bool value) Same as size(). */ -template T qUnalignedLoad(const uchar *ptr) -{ - /* - * Testing with different compilers shows that they all optimize the memcpy - * call away and replace with direct loads whenever possible. On x86 and PPC, - * GCC does direct unaligned loads; on MIPS, it generates a pair of load-left - * and load-right instructions. ICC and Clang do the same on x86. This is both - * 32- and 64-bit. - * - * On ARM cores without unaligned loads, the compiler leaves a call to - * memcpy. - */ - - T u; - memcpy(&u, ptr, sizeof(u)); - return u; -} - - /*! If \a on is true, this function returns the number of 1-bits stored in the bit array; otherwise the number @@ -196,17 +178,17 @@ int QBitArray::count(bool on) const const quint8 *const end = reinterpret_cast(d.end()); while (bits + 7 <= end) { - quint64 v = qUnalignedLoad(bits); + quint64 v = qFromUnaligned(bits); bits += 8; numBits += int(qPopulationCount(v)); } if (bits + 3 <= end) { - quint32 v = qUnalignedLoad(bits); + quint32 v = qFromUnaligned(bits); bits += 4; numBits += int(qPopulationCount(v)); } if (bits + 1 < end) { - quint16 v = qUnalignedLoad(bits); + quint16 v = qFromUnaligned(bits); bits += 2; numBits += int(qPopulationCount(v)); } diff --git a/src/corelib/tools/qhash.cpp b/src/corelib/tools/qhash.cpp index d40570d347..c5669babd9 100644 --- a/src/corelib/tools/qhash.cpp +++ b/src/corelib/tools/qhash.cpp @@ -51,6 +51,7 @@ #include #include #include +#include #include #ifndef QT_BOOTSTRAPPED @@ -105,24 +106,24 @@ static uint crc32(const Char *ptr, size_t len, uint h) p += 8; for ( ; p <= e; p += 8) - h2 = _mm_crc32_u64(h2, qUnalignedLoad(p - 8)); + h2 = _mm_crc32_u64(h2, qFromUnaligned(p - 8)); h = h2; p -= 8; len = e - p; if (len & 4) { - h = _mm_crc32_u32(h, qUnalignedLoad(p)); + h = _mm_crc32_u32(h, qFromUnaligned(p)); p += 4; } # else p += 4; for ( ; p <= e; p += 4) - h = _mm_crc32_u32(h, qUnalignedLoad(p - 4)); + h = _mm_crc32_u32(h, qFromUnaligned(p - 4)); p -= 4; len = e - p; # endif if (len & 2) { - h = _mm_crc32_u16(h, qUnalignedLoad(p)); + h = _mm_crc32_u16(h, qFromUnaligned(p)); p += 2; } if (sizeof(Char) == 1 && len & 1) diff --git a/src/corelib/tools/qsimd.cpp b/src/corelib/tools/qsimd.cpp index 5ca2ce4c6f..f07eb098f2 100644 --- a/src/corelib/tools/qsimd.cpp +++ b/src/corelib/tools/qsimd.cpp @@ -716,26 +716,4 @@ void qDumpCPUFeatures() puts(""); } -/*! - \internal - \fn T qUnalignedLoad(const void *ptr) - \since 5.6.1 - - Loads a \c{T} from address \a ptr, which may be misaligned. - - Use of this function avoid the undefined behavior that the C++ standard - otherwise attributes to unaligned loads. -*/ - -/*! - \internal - \fn void qUnalignedStore(void *ptr, T t) - \since 5.6.1 - - Stores \a t to address \a ptr, which may be misaligned. - - Use of this function avoid the undefined behavior that the C++ standard - otherwise attributes to unaligned stores. -*/ - QT_END_NAMESPACE diff --git a/src/corelib/tools/qsimd_p.h b/src/corelib/tools/qsimd_p.h index ca53908cf5..d689654b29 100644 --- a/src/corelib/tools/qsimd_p.h +++ b/src/corelib/tools/qsimd_p.h @@ -476,43 +476,6 @@ unsigned _bit_scan_forward(unsigned val) #define ALIGNMENT_PROLOGUE_16BYTES(ptr, i, length) \ for (; i < static_cast(qMin(static_cast(length), ((4 - ((reinterpret_cast(ptr) >> 2) & 0x3)) & 0x3))); ++i) -// these defines are copied from qendian.h -// in Qt 5.7, they have been moved to qglobal.h -// drop them when merging this to 5.7 -#ifdef __has_builtin -# define QT_HAS_BUILTIN(x) __has_builtin(x) -#else -# define QT_HAS_BUILTIN(x) 0 -#endif - -template -Q_ALWAYS_INLINE -T qUnalignedLoad(const void *ptr) Q_DECL_NOTHROW -{ - T result; -#if QT_HAS_BUILTIN(__builtin_memcpy) - __builtin_memcpy -#else - memcpy -#endif - /*memcpy*/(&result, ptr, sizeof result); - return result; -} - -template -Q_ALWAYS_INLINE -void qUnalignedStore(void *ptr, T t) Q_DECL_NOTHROW -{ -#if QT_HAS_BUILTIN(__builtin_memcpy) - __builtin_memcpy -#else - memcpy -#endif - /*memcpy*/(ptr, &t, sizeof t); -} - -#undef QT_HAS_BUILTIN - QT_END_NAMESPACE #endif // QSIMD_P_H diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 6bbaf05fef..be1ca8ba95 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -577,7 +577,7 @@ static int ucstrncmp(const QChar *a, const uchar *c, int l) // we'll read uc[offset..offset+7] (16 bytes) and c[offset..offset+7] (8 bytes) if (uc + offset + 7 < e) { // same, but we're using an 8-byte load - __m128i chunk = _mm_cvtsi64_si128(qUnalignedLoad(c + offset)); + __m128i chunk = _mm_cvtsi64_si128(qFromUnaligned(c + offset)); __m128i secondHalf = _mm_unpacklo_epi8(chunk, nullmask); __m128i ucdata = _mm_loadu_si128((const __m128i*)(uc + offset)); -- cgit v1.2.3 From 11353ea6a50682d5877baf4c356de56f7ab89376 Mon Sep 17 00:00:00 2001 From: Ralf Nolden Date: Wed, 25 May 2016 17:57:21 +0200 Subject: Compile fix: C++11 usage: Replace nullptr with Q_NULLPTR Another compile fix when compiling qt with -stdc++ c++98 option. Replace nullptr with Q_NULLPTR. Change-Id: I7765905031fa91250dbbcc9768b9e8b109e7594d Reviewed-by: Thiago Macieira --- .../platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmscursor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmscursor.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmscursor.cpp index 830e270eeb..bcc908905c 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmscursor.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmscursor.cpp @@ -125,7 +125,7 @@ void QEglFSKmsCursor::updateMouseStatus() m_state = visible ? CursorPendingVisible : CursorPendingHidden; #ifndef QT_NO_CURSOR - changeCursor(nullptr, m_screen->topLevelAt(pos())); + changeCursor(Q_NULLPTR, m_screen->topLevelAt(pos())); #endif } -- cgit v1.2.3 From 4605ca20130170757c2cbe6f69eb7fcfbc9f9101 Mon Sep 17 00:00:00 2001 From: Jake Petroules Date: Mon, 23 May 2016 17:17:14 -0700 Subject: Remove QNetworkReplyNSURLConnectionImpl. This class is no longer needed now that SecureTransport is the default SSL backend on iOS. It also uses NSURLConnection, which is deprecated on iOS and tvOS and completely prohibited on watchOS (in favor of NSURLSession). [ChangeLog][Important Behavior Changes] The NSURLConnection backend of QNetworkAccessManager has been removed, since SecureTransport is the default SSL backend on iOS and is enabled by default. This means that building with -no-openssl -no-securetransport will no longer provide SSL capabilities on iOS. Task-number: QTBUG-45031 Change-Id: I86b774fa369c7d76197bfc0504d5ad234bb47e5c Reviewed-by: Richard J. Moore --- src/network/access/access.pri | 8 - src/network/access/qnetworkaccessmanager.cpp | 10 - .../access/qnetworkreplynsurlconnectionimpl.mm | 451 --------------------- .../access/qnetworkreplynsurlconnectionimpl_p.h | 81 ---- 4 files changed, 550 deletions(-) delete mode 100644 src/network/access/qnetworkreplynsurlconnectionimpl.mm delete mode 100644 src/network/access/qnetworkreplynsurlconnectionimpl_p.h diff --git a/src/network/access/access.pri b/src/network/access/access.pri index e829d52cbe..38e9c25269 100644 --- a/src/network/access/access.pri +++ b/src/network/access/access.pri @@ -72,12 +72,4 @@ SOURCES += \ mac: LIBS_PRIVATE += -framework Security -ios { - HEADERS += \ - access/qnetworkreplynsurlconnectionimpl_p.h - - OBJECTIVE_SOURCES += \ - access/qnetworkreplynsurlconnectionimpl.mm -} - include($$PWD/../../3rdparty/zlib_dependency.pri) diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp index d023228fd2..b649aba4a8 100644 --- a/src/network/access/qnetworkaccessmanager.cpp +++ b/src/network/access/qnetworkaccessmanager.cpp @@ -50,10 +50,6 @@ #include "qnetworkreplydataimpl_p.h" #include "qnetworkreplyfileimpl_p.h" -#if defined(Q_OS_IOS) && defined(QT_NO_SSL) -#include "qnetworkreplynsurlconnectionimpl_p.h" -#endif - #include "QtCore/qbuffer.h" #include "QtCore/qurl.h" #include "QtCore/qvector.h" @@ -1201,12 +1197,6 @@ QNetworkReply *QNetworkAccessManager::createRequest(QNetworkAccessManager::Opera } } -// Use NSURLConnection for https on iOS when OpenSSL is disabled. -#if defined(Q_OS_IOS) && defined(QT_NO_SSL) - if (scheme == QLatin1String("https")) - return new QNetworkReplyNSURLConnectionImpl(this, request, op, outgoingData); -#endif - #ifndef QT_NO_HTTP // Since Qt 5 we use the new QNetworkReplyHttpImpl if (scheme == QLatin1String("http") || scheme == QLatin1String("preconnect-http") diff --git a/src/network/access/qnetworkreplynsurlconnectionimpl.mm b/src/network/access/qnetworkreplynsurlconnectionimpl.mm deleted file mode 100644 index f4f494560c..0000000000 --- a/src/network/access/qnetworkreplynsurlconnectionimpl.mm +++ /dev/null @@ -1,451 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtNetwork 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 "qnetworkreplynsurlconnectionimpl_p.h" - -#include "QtCore/qdatetime.h" -#include -#include -#include - -QT_BEGIN_NAMESPACE - -// Network reply implementation using NSUrlConnection. -// -// Class/object structure: -// -// QNetworkReplyNSURLConnectionImpl -// |- QNetworkReplyNSURLConnectionImplPrivate -// |- (bytes read) -// |- (QIODevice and CFStream for async POST data transfer) -// |- NSURLConnection -// |- QtNSURLConnectionDelegate -// |- NSURLResponse/NSHTTPURLResponse -// |- (response data) -// -// The main entry point is the QNetworkReplyNSURLConnectionImpl constructor, which -// receives a network request from QNetworkAccessManager. The constructor -// creates a NSURLRequest and initiates a NSURLConnection with a QtNSURLConnectionDelegate. -// The delegate callbacks are then called asynchronously as the request completes. -// - -@class QtNSURLConnectionDelegate; -class QNetworkReplyNSURLConnectionImplPrivate: public QNetworkReplyPrivate -{ -public: - QNetworkReplyNSURLConnectionImplPrivate(); - virtual ~QNetworkReplyNSURLConnectionImplPrivate(); - - Q_DECLARE_PUBLIC(QNetworkReplyNSURLConnectionImpl) - NSURLConnection * urlConnection; - QtNSURLConnectionDelegate *urlConnectionDelegate; - qint64 bytesRead; - - // Sequental outgiong data streaming - QIODevice *outgoingData; - CFReadStreamRef readStream; - CFWriteStreamRef writeStream; - CFIndex transferBufferSize; - - // Forwarding functions to the public class. - void setFinished(); - void setHeader(QNetworkRequest::KnownHeaders header, const QVariant &value); - void setRawHeader(const QByteArray &headerName, const QByteArray &value); - void setError(QNetworkReply::NetworkError errorCode, const QString &errorString); - void setAttribute(QNetworkRequest::Attribute code, const QVariant &value); -}; - -@interface QtNSURLConnectionDelegate : NSObject -{ - NSURLResponse *response; - NSMutableData *responseData; - QNetworkReplyNSURLConnectionImplPrivate * replyprivate; -} - -- (id)initWithQNetworkReplyNSURLConnectionImplPrivate:(QNetworkReplyNSURLConnectionImplPrivate *)a_replyPrivate ; -#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_7, __IPHONE_3_0) -- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge; -#endif -- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError*)error; -- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse*)response; -- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData*)data; -- (void)connection:(NSURLConnection *)connection didSendBodyData:(NSInteger)bytesWritten - totalBytesWritten:(NSInteger)totalBytesWritten totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite; -- (NSCachedURLResponse*)connection:(NSURLConnection*)connection willCacheResponse:(NSCachedURLResponse*)cachedResponse; -- (NSURLRequest*)connection:(NSURLConnection*)connection willSendRequest:(NSURLRequest*)request redirectResponse:(NSURLResponse*)redirectResponse; -- (void)connectionDidFinishLoading:(NSURLConnection*)connection; -- (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection*)connection; - -@end - -QNetworkReplyNSURLConnectionImplPrivate::QNetworkReplyNSURLConnectionImplPrivate() - : QNetworkReplyPrivate() - , urlConnection(0) - , urlConnectionDelegate(0) - , bytesRead(0) - , readStream(0) - , writeStream(0) - , transferBufferSize(4096) -{ -} - -QNetworkReplyNSURLConnectionImplPrivate::~QNetworkReplyNSURLConnectionImplPrivate() -{ - [urlConnection cancel]; - [urlConnection release]; - [urlConnectionDelegate release]; - if (readStream) - CFRelease(readStream); - if (writeStream) - CFRelease(writeStream); -} - -void QNetworkReplyNSURLConnectionImplPrivate::setFinished() -{ - q_func()->setFinished(true); - QMetaObject::invokeMethod(q_func(), "finished", Qt::QueuedConnection); -} - -void QNetworkReplyNSURLConnectionImplPrivate::setHeader(QNetworkRequest::KnownHeaders header, const QVariant &value) -{ - q_func()->setHeader(header, value); -} - -void QNetworkReplyNSURLConnectionImplPrivate::setRawHeader(const QByteArray &headerName, const QByteArray &value) -{ - q_func()->setRawHeader(headerName, value); -} - -void QNetworkReplyNSURLConnectionImplPrivate::setError(QNetworkReply::NetworkError errorCode, const QString &errorString) -{ - q_func()->setError(errorCode, errorString); -} - -void QNetworkReplyNSURLConnectionImplPrivate::setAttribute(QNetworkRequest::Attribute code, const QVariant &value) -{ - q_func()->setAttribute(code, value); -} - -void QNetworkReplyNSURLConnectionImpl::readyReadOutgoingData() -{ - Q_D(QNetworkReplyNSURLConnectionImpl); - int bytesRead = 0; - do { - char data[d->transferBufferSize]; - bytesRead = d->outgoingData->read(data, d->transferBufferSize); - if (bytesRead <= 0) - break; - CFIndex bytesWritten = CFWriteStreamWrite(d->writeStream, reinterpret_cast(data), bytesRead); - if (bytesWritten != bytesRead) { - CFErrorRef err = CFWriteStreamCopyError(d->writeStream); - qWarning() << "QNetworkReplyNSURLConnectionImpl: CFWriteStreamWrite error" - << (err ? QString::number(CFErrorGetCode(err)) : QStringLiteral("")); - } - } while (bytesRead > 0); - - if (d->outgoingData->atEnd()) - CFWriteStreamClose(d->writeStream); -} - -@interface QtNSURLConnectionDelegate () - -@property (nonatomic, retain) NSURLResponse* response; -@property (nonatomic, retain) NSMutableData* responseData; - -@end - -@implementation QtNSURLConnectionDelegate - -@synthesize response; -@synthesize responseData; - -- (id)initWithQNetworkReplyNSURLConnectionImplPrivate:(QNetworkReplyNSURLConnectionImplPrivate *)a_replyPrivate -{ - if (self = [super init]) - replyprivate = a_replyPrivate; - return self; -} - -- (void)dealloc -{ - [response release]; - [responseData release]; - [super dealloc]; -} - -#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_7, __IPHONE_3_0) -- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge -{ - Q_UNUSED(connection) - Q_UNUSED(challenge) - - if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) { - SecTrustRef serverTrust = challenge.protectionSpace.serverTrust; - SecTrustResultType resultType; - SecTrustEvaluate(serverTrust, &resultType); - if (resultType == kSecTrustResultUnspecified) { - // All good - [challenge.sender performDefaultHandlingForAuthenticationChallenge:challenge]; - } else if (resultType == kSecTrustResultRecoverableTrustFailure) { - // Certificate verification error, ask user - // ### TODO actually ask user - // (test site: https://testssl-expire.disig.sk/index.en.html) - qWarning() << "QNetworkReplyNSURLConnection: Certificate verification error handlig is" - << "not implemented. Connection will time out."; - } else { - // other error, which the default handler will handle - [challenge.sender performDefaultHandlingForAuthenticationChallenge:challenge]; - } - } - - [challenge.sender performDefaultHandlingForAuthenticationChallenge:challenge]; -} -#endif - -- (void)connection:(NSURLConnection*)connection didFailWithError:(NSError*)error -{ - Q_UNUSED(connection) - - QNetworkReply::NetworkError qtError = QNetworkReply::UnknownNetworkError; - if ([[error domain] isEqualToString:NSURLErrorDomain]) { - switch ([error code]) { - case NSURLErrorTimedOut: qtError = QNetworkReply::TimeoutError; break; - case NSURLErrorUnsupportedURL: qtError = QNetworkReply::ProtocolUnknownError; break; - case NSURLErrorCannotFindHost: qtError = QNetworkReply::HostNotFoundError; break; - case NSURLErrorCannotConnectToHost: qtError = QNetworkReply::ConnectionRefusedError; break; - case NSURLErrorNetworkConnectionLost: qtError = QNetworkReply::NetworkSessionFailedError; break; - case NSURLErrorDNSLookupFailed: qtError = QNetworkReply::HostNotFoundError; break; - case NSURLErrorNotConnectedToInternet: qtError = QNetworkReply::NetworkSessionFailedError; break; - case NSURLErrorUserAuthenticationRequired: qtError = QNetworkReply::AuthenticationRequiredError; break; - default: break; - } - } - - replyprivate->setError(qtError, QString::fromNSString([error localizedDescription])); - replyprivate->setFinished(); -} - -- (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSURLResponse*)aResponse -{ - Q_UNUSED(connection) - self.response = aResponse; - self.responseData = [NSMutableData data]; - - // copy headers - if ([aResponse isKindOfClass:[NSHTTPURLResponse class]]) { - NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)aResponse; - NSDictionary *headers = [httpResponse allHeaderFields]; - for (NSString *key in headers) { - NSString *value = [headers objectForKey:key]; - replyprivate->setRawHeader(QString::fromNSString(key).toUtf8(), QString::fromNSString(value).toUtf8()); - } - - int code = [httpResponse statusCode]; - replyprivate->setAttribute(QNetworkRequest::HttpStatusCodeAttribute, code); - } else { - if ([aResponse expectedContentLength] != NSURLResponseUnknownLength) - replyprivate->setHeader(QNetworkRequest::ContentLengthHeader, [aResponse expectedContentLength]); - } - - QMetaObject::invokeMethod(replyprivate->q_func(), "metaDataChanged", Qt::QueuedConnection); -} - -- (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)data -{ - Q_UNUSED(connection) - [responseData appendData:data]; - - if ([response expectedContentLength] != NSURLResponseUnknownLength) { - QMetaObject::invokeMethod(replyprivate->q_func(), "downloadProgress", Qt::QueuedConnection, - Q_ARG(qint64, qint64([responseData length] + replyprivate->bytesRead)), - Q_ARG(qint64, qint64([response expectedContentLength]))); - } - - QMetaObject::invokeMethod(replyprivate->q_func(), "readyRead", Qt::QueuedConnection); -} - -- (void)connection:(NSURLConnection*)connection didSendBodyData:(NSInteger)bytesWritten totalBytesWritten:(NSInteger)totalBytesWritten - totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite -{ - Q_UNUSED(connection) - Q_UNUSED(bytesWritten) - QMetaObject::invokeMethod(replyprivate->q_func(), "uploadProgress", Qt::QueuedConnection, - Q_ARG(qint64, qint64(totalBytesWritten)), - Q_ARG(qint64, qint64(totalBytesExpectedToWrite))); -} - -- (NSCachedURLResponse*)connection:(NSURLConnection*)connection willCacheResponse:(NSCachedURLResponse*)cachedResponse -{ - Q_UNUSED(connection) - return cachedResponse; -} - -- (NSURLRequest*)connection:(NSURLConnection*)connection willSendRequest:(NSURLRequest*)request redirectResponse:(NSURLResponse*)redirectResponse -{ - Q_UNUSED(connection) - Q_UNUSED(redirectResponse) - return request; -} - -- (void)connectionDidFinishLoading:(NSURLConnection*)connection -{ - Q_UNUSED(connection) - replyprivate->setFinished(); -} - -- (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection*)connection -{ - Q_UNUSED(connection) - return YES; -} - -@end - -QNetworkReplyNSURLConnectionImpl::~QNetworkReplyNSURLConnectionImpl() -{ -} - -QNetworkReplyNSURLConnectionImpl::QNetworkReplyNSURLConnectionImpl(QObject *parent, - const QNetworkRequest &request, const QNetworkAccessManager::Operation operation, QIODevice* outgoingData) - : QNetworkReply(*new QNetworkReplyNSURLConnectionImplPrivate(), parent) -{ - setRequest(request); - setUrl(request.url()); - setOperation(operation); - QNetworkReply::open(QIODevice::ReadOnly); - - QNetworkReplyNSURLConnectionImplPrivate *d = (QNetworkReplyNSURLConnectionImplPrivate*) d_func(); - - QUrl url = request.url(); - if (url.host() == QLatin1String("localhost")) - url.setHost(QString()); - - if (url.path().isEmpty()) - url.setPath(QLatin1String("/")); - setUrl(url); - - // Create a NSMutableURLRequest from QNetworkRequest - NSMutableURLRequest *nsRequest = [NSMutableURLRequest requestWithURL:request.url().toNSURL() - cachePolicy:NSURLRequestUseProtocolCachePolicy - timeoutInterval:60.0]; - // copy headers - foreach (const QByteArray &header, request.rawHeaderList()) { - QByteArray headerValue = request.rawHeader(header); - [nsRequest addValue:QString::fromUtf8(headerValue).toNSString() - forHTTPHeaderField:QString::fromUtf8(header).toNSString()]; - } - - if (operation == QNetworkAccessManager::GetOperation) - [nsRequest setHTTPMethod:@"GET"]; - else if (operation == QNetworkAccessManager::PostOperation) - [nsRequest setHTTPMethod:@"POST"]; - else if (operation == QNetworkAccessManager::PutOperation) - [nsRequest setHTTPMethod:@"PUT"]; - else if (operation == QNetworkAccessManager::DeleteOperation) - [nsRequest setHTTPMethod:@"DELETE"]; - else - qWarning() << "QNetworkReplyNSURLConnection: Unsupported netork operation" << operation; - - if (outgoingData) { - d->outgoingData = outgoingData; - if (outgoingData->isSequential()) { - // set up streaming from outgoingData iodevice to request - CFStreamCreateBoundPair(kCFAllocatorDefault, &d->readStream, &d->writeStream, d->transferBufferSize); - CFWriteStreamOpen(d->writeStream); - [nsRequest setHTTPBodyStream:reinterpret_cast(d->readStream)]; - connect(outgoingData, SIGNAL(readyRead()), this, SLOT(readyReadOutgoingData())); - readyReadOutgoingData(); - } else { - // move all data at once - QByteArray data = outgoingData->readAll(); - [nsRequest setHTTPBody:[NSData dataWithBytes:data.constData() length:data.length()]]; - } - } - - // Create connection - d->urlConnectionDelegate = [[QtNSURLConnectionDelegate alloc] initWithQNetworkReplyNSURLConnectionImplPrivate:d]; - d->urlConnection = [[NSURLConnection alloc] initWithRequest:nsRequest delegate:d->urlConnectionDelegate]; - if (!d->urlConnection) { - // ### what type of error is an initWithRequest fail? - setError(QNetworkReply::ProtocolUnknownError, QStringLiteral("QNetworkReplyNSURLConnection internal error")); - } -} - -void QNetworkReplyNSURLConnectionImpl::close() -{ - // No-op? Network ops should continue (especially POSTs) - QNetworkReply::close(); -} - -void QNetworkReplyNSURLConnectionImpl::abort() -{ - Q_D(QNetworkReplyNSURLConnectionImpl); - [d->urlConnection cancel]; - QNetworkReply::close(); -} - -qint64 QNetworkReplyNSURLConnectionImpl::bytesAvailable() const -{ - Q_D(const QNetworkReplyNSURLConnectionImpl); - qint64 available = QNetworkReply::bytesAvailable() + - [[d->urlConnectionDelegate responseData] length]; - return available; -} - -bool QNetworkReplyNSURLConnectionImpl::isSequential() const -{ - return true; -} - -qint64 QNetworkReplyNSURLConnectionImpl::size() const -{ - Q_D(const QNetworkReplyNSURLConnectionImpl); - return [[d->urlConnectionDelegate responseData] length] + d->bytesRead; -} - -/*! - \internal -*/ -qint64 QNetworkReplyNSURLConnectionImpl::readData(char *data, qint64 maxlen) -{ - Q_D(QNetworkReplyNSURLConnectionImpl); - qint64 dataSize = [[d->urlConnectionDelegate responseData] length]; - qint64 canRead = qMin(maxlen, dataSize); - const char *sourceBase = static_cast([[d->urlConnectionDelegate responseData] bytes]); - memcpy(data, sourceBase, canRead); - [[d->urlConnectionDelegate responseData] replaceBytesInRange:NSMakeRange(0, canRead) withBytes:NULL length:0]; - d->bytesRead += canRead; - return canRead; -} - -QT_END_NAMESPACE diff --git a/src/network/access/qnetworkreplynsurlconnectionimpl_p.h b/src/network/access/qnetworkreplynsurlconnectionimpl_p.h deleted file mode 100644 index 8eacaf6712..0000000000 --- a/src/network/access/qnetworkreplynsurlconnectionimpl_p.h +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the QtNetwork 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$ -** -****************************************************************************/ - -#ifndef QNETWORKREPLYNSURLCONNECTIONIMPL_H -#define QNETWORKREPLYNSURLCONNECTIONIMPL_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists for the convenience -// of the Network Access API. This header file may change from -// version to version without notice, or even be removed. -// -// We mean it. -// - -#include "qnetworkreply.h" -#include "qnetworkreply_p.h" -#include "qnetworkaccessmanager.h" -#include -#include - -QT_BEGIN_NAMESPACE - - -class QNetworkReplyNSURLConnectionImplPrivate; -class QNetworkReplyNSURLConnectionImpl: public QNetworkReply -{ - Q_OBJECT -public: - QNetworkReplyNSURLConnectionImpl(QObject *parent, const QNetworkRequest &req, const QNetworkAccessManager::Operation op, QIODevice* outgoingData); - virtual ~QNetworkReplyNSURLConnectionImpl(); - virtual void abort(); - - // reimplemented from QNetworkReply - virtual void close(); - virtual qint64 bytesAvailable() const; - virtual bool isSequential () const; - qint64 size() const; - - virtual qint64 readData(char *data, qint64 maxlen); -public Q_SLOTS: - void readyReadOutgoingData(); - - Q_DECLARE_PRIVATE(QNetworkReplyNSURLConnectionImpl) -}; - -QT_END_NAMESPACE - -#endif // QNetworkReplyNSURLConnectionImpl_H -- cgit v1.2.3 From 2ceacd537279e735025a2c74a7a1b73ea8c4fc06 Mon Sep 17 00:00:00 2001 From: Jake Petroules Date: Mon, 23 May 2016 17:42:49 -0700 Subject: Fix httpwindow example. DownloadLocation is not writable on some platforms (iOS) in Qt 5.6, and qt-project.org HTTPS does not work anymore. Change-Id: I78bfbee1472cd39cd05ec7f846d1195d4fbb1b2c Reviewed-by: Timur Pocheptsov --- examples/network/http/httpwindow.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/examples/network/http/httpwindow.cpp b/examples/network/http/httpwindow.cpp index 301431fd5e..41563dc235 100644 --- a/examples/network/http/httpwindow.cpp +++ b/examples/network/http/httpwindow.cpp @@ -46,9 +46,9 @@ #include "ui_authenticationdialog.h" #ifndef QT_NO_SSL -static const char defaultUrl[] = "https://qt-project.org/"; +static const char defaultUrl[] = "https://www.qt.io/"; #else -static const char defaultUrl[] = "http://qt-project.org/"; +static const char defaultUrl[] = "http://www.qt.io/"; #endif static const char defaultFileName[] = "index.html"; @@ -96,7 +96,7 @@ HttpWindow::HttpWindow(QWidget *parent) connect(urlLineEdit, &QLineEdit::textChanged, this, &HttpWindow::enableDownloadButton); formLayout->addRow(tr("&URL:"), urlLineEdit); - QString downloadDirectory = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation); + QString downloadDirectory = QStandardPaths::writableLocation(QStandardPaths::TempLocation); if (downloadDirectory.isEmpty() || !QFileInfo(downloadDirectory).isDir()) downloadDirectory = QDir::currentPath(); downloadDirectoryLineEdit->setText(QDir::toNativeSeparators(downloadDirectory)); -- cgit v1.2.3 From 0e70d35f151c52a8821be987e4cd1aef3d40b010 Mon Sep 17 00:00:00 2001 From: Richard Moe Gustavsen Date: Thu, 26 May 2016 15:06:11 +0200 Subject: iOS: Return correct QLocale from QIOSInputContext MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Ensure we return a correct QLocale on iOS by overriding QPlatformInputContext::locale(). A broader implementation involving subclassing QSystemLocale will be done in dev. Task-number: QTBUG-48772 Change-Id: I5250bdad320cbe66d63456926f6eab6fc2865424 Reviewed-by: Tor Arne Vestbø --- src/plugins/platforms/ios/qiosinputcontext.h | 5 ++++ src/plugins/platforms/ios/qiosinputcontext.mm | 40 +++++++++++++++++++++++++++ 2 files changed, 45 insertions(+) diff --git a/src/plugins/platforms/ios/qiosinputcontext.h b/src/plugins/platforms/ios/qiosinputcontext.h index 40ddbfce28..923c87b07b 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.h +++ b/src/plugins/platforms/ios/qiosinputcontext.h @@ -36,6 +36,7 @@ #include +#include #include #include #include @@ -46,6 +47,7 @@ const char kImePlatformDataReturnKeyType[] = "returnKeyType"; QT_BEGIN_NAMESPACE +@class QIOSLocaleListener; @class QIOSKeyboardListener; @class QIOSTextInputResponder; @protocol KeyboardState; @@ -92,6 +94,8 @@ public: void reset() Q_DECL_OVERRIDE; void commit() Q_DECL_OVERRIDE; + QLocale locale() const Q_DECL_OVERRIDE; + void clearCurrentFocusObject(); void setFocusObject(QObject *object) Q_DECL_OVERRIDE; @@ -112,6 +116,7 @@ public: private: UIView* scrollableRootView(); + QIOSLocaleListener *m_localeListener; QIOSKeyboardListener *m_keyboardHideGesture; QIOSTextInputResponder *m_textResponder; KeyboardState m_keyboardState; diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm index d03c589b2a..c9463087c7 100644 --- a/src/plugins/platforms/ios/qiosinputcontext.mm +++ b/src/plugins/platforms/ios/qiosinputcontext.mm @@ -56,6 +56,39 @@ static QUIView *focusView() // ------------------------------------------------------------------------- +@interface QIOSLocaleListener : NSObject +@end + +@implementation QIOSLocaleListener + +- (id)init +{ + if (self = [super init]) { + NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; + [notificationCenter addObserver:self + selector:@selector(localeDidChange:) + name:NSCurrentLocaleDidChangeNotification object:nil]; + } + + return self; +} + +- (void)dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver:self]; + [super dealloc]; +} + +- (void)localeDidChange:(NSNotification *)notification +{ + Q_UNUSED(notification); + QIOSInputContext::instance()->emitLocaleChanged(); +} + +@end + +// ------------------------------------------------------------------------- + @interface QIOSKeyboardListener : UIGestureRecognizer { @private QIOSInputContext *m_context; @@ -285,6 +318,7 @@ QIOSInputContext *QIOSInputContext::instance() QIOSInputContext::QIOSInputContext() : QPlatformInputContext() + , m_localeListener([QIOSLocaleListener new]) , m_keyboardHideGesture([[QIOSKeyboardListener alloc] initWithQIOSInputContext:this]) , m_textResponder(0) { @@ -298,6 +332,7 @@ QIOSInputContext::QIOSInputContext() QIOSInputContext::~QIOSInputContext() { + [m_localeListener release]; [m_keyboardHideGesture.view removeGestureRecognizer:m_keyboardHideGesture]; [m_keyboardHideGesture release]; @@ -657,3 +692,8 @@ void QIOSInputContext::commit() [m_textResponder unmarkText]; [m_textResponder notifyInputDelegate:Qt::ImSurroundingText]; } + +QLocale QIOSInputContext::locale() const +{ + return QLocale(QString::fromNSString([[NSLocale currentLocale] objectForKey:NSLocaleIdentifier])); +} -- cgit v1.2.3 From c85f988fc785690ade283305181de8e7256d4040 Mon Sep 17 00:00:00 2001 From: Ralf Nolden Date: Wed, 25 May 2016 11:51:52 +0200 Subject: Disable thread_local on clang for FreeBSD FreeBSD's clang currently is not able to handle thread_local calls due to linker errors on __cxa_thread_atexit. The patch disables the define Q_COMPILER_THREAD_LOCAL for clang __FreeBSD__ only, no functional change. Otherwise, linking the tst_compiler autotest will fail. For details, see https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=192320 Change-Id: I2395c06499d4821213e2154769ccbeed3dcf1ffe Reviewed-by: Thiago Macieira --- src/corelib/global/qcompilerdetection.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h index 8574059616..ad881ef4c9 100644 --- a/src/corelib/global/qcompilerdetection.h +++ b/src/corelib/global/qcompilerdetection.h @@ -699,7 +699,9 @@ # define Q_COMPILER_TEMPLATE_ALIAS # endif # if __has_feature(cxx_thread_local) -# define Q_COMPILER_THREAD_LOCAL +# if !defined(__FreeBSD__) /* FreeBSD clang fails on __cxa_thread_atexit */ +# define Q_COMPILER_THREAD_LOCAL +# endif # endif # if __has_feature(cxx_user_literals) # define Q_COMPILER_UDL -- cgit v1.2.3 From 614e86f564450fd31de39d3288866332298802c0 Mon Sep 17 00:00:00 2001 From: Ralf Nolden Date: Thu, 26 May 2016 08:36:57 +0200 Subject: Platform detection: Use freebsd-g++ on systems < 10, otherwise -clang FreeBSD uses gcc as the default compiler until FreeBSD 10 where it was switched to clang for the whole system. Choose freebsd-clang for any system release > 10, otherwise choose freebsd-g++ by default. Change-Id: I2bf38aa027453c25ed2a29d587c2962ded5fcd4a Reviewed-by: Oswald Buddenhagen --- configure | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/configure b/configure index 0e0a36b00f..d175ed32b5 100755 --- a/configure +++ b/configure @@ -2859,10 +2859,17 @@ if [ -z "$PLATFORM" ]; then PLATFORM=ultrix-g++ ;; FreeBSD:*) - PLATFORM=freebsd-clang - PLATFORM_NOTES=" - - Also available for FreeBSD: freebsd-g++ - " + if [ "$(uname -r | cut -d. -f1)" -ge 10 ]; then + PLATFORM=freebsd-clang + PLATFORM_NOTES=" + - Also available for FreeBSD: freebsd-g++ + " + else + PLATFORM=freebsd-g++ + PLATFORM_NOTES=" + - Also available for FreeBSD: freebsd-clang + " + fi ;; OpenBSD:*) PLATFORM=openbsd-g++ -- cgit v1.2.3 From 965b5b7ae07f8abec580729001abd61e8db729e5 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 26 May 2016 16:31:02 +0200 Subject: OpenGL legacy example: Fix compilation in namespaced builds. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I6b2f3e8c240e105c73008fa61f9ed50cc9d982ac Reviewed-by: Alexandru Croitor Reviewed-by: Laszlo Agocs Reviewed-by: Topi Reiniö --- examples/opengl/legacy/shared/qtlogo.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/opengl/legacy/shared/qtlogo.h b/examples/opengl/legacy/shared/qtlogo.h index 9bd15a1431..c5d8db9f9f 100644 --- a/examples/opengl/legacy/shared/qtlogo.h +++ b/examples/opengl/legacy/shared/qtlogo.h @@ -44,7 +44,8 @@ #include #include -class QOpenGLFunctions_1_1; +QT_FORWARD_DECLARE_CLASS(QOpenGLFunctions_1_1) + class Patch; struct Geometry; -- cgit v1.2.3 From b59cf8a1b4384bebc3d14fd7ce69db74b5f60e1d Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Wed, 25 May 2016 12:55:24 +0300 Subject: Android: Removed super old NDK checks Change-Id: I8c16dca1272f0413ac486fd1d54b6c678a8c9dd8 Reviewed-by: Oswald Buddenhagen Reviewed-by: Eskil Abrahamsen Blomfeldt --- mkspecs/android-g++/qmake.conf | 8 -------- 1 file changed, 8 deletions(-) diff --git a/mkspecs/android-g++/qmake.conf b/mkspecs/android-g++/qmake.conf index fc14eeae5a..28f5638463 100644 --- a/mkspecs/android-g++/qmake.conf +++ b/mkspecs/android-g++/qmake.conf @@ -188,14 +188,6 @@ QMAKE_LFLAGS = --sysroot=$$ANDROID_PLATFORM_ROOT_PATH QMAKE_RPATHLINK = $$QMAKE_ANDROID_PLATFORM_LIBDIR QMAKE_LFLAGS_APP = -Wl,--no-undefined -Wl,-z,noexecstack -shared QMAKE_LFLAGS_SHLIB = -Wl,--no-undefined -Wl,-z,noexecstack -shared - -contains(NDK_ROOT, ".*r6")|contains(NDK_ROOT, ".*r5.*") { - !equals(ANDROID_PLATFORM, android-4):!equals(ANDROID_PLATFORM, android-5):!equals(ANDROID_PLATFORM, android-8) { - warning("Your NDK version is outdated. A workaround is enabled. Consider updating your NDK (workarounds are required until r6(a))") - QMAKE_LFLAGS_SHLIB += $$QMAKE_ANDROID_PLATFORM_LIBDIR/crtbegin_so.o $$QMAKE_ANDROID_PLATFORM_LIBDIR/crtend_so.o - } -} - QMAKE_LFLAGS_PLUGIN = $$QMAKE_LFLAGS_SHLIB QMAKE_LFLAGS_NOUNDEF = -Wl,--no-undefined QMAKE_LFLAGS_RPATH = -Wl,-rpath= -- cgit v1.2.3 From 9e9888f69aa0b78d10b16f85235918f9d41db152 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Wed, 25 May 2016 12:22:21 +0300 Subject: Initialize the value before using it. LIBGCC_PATH was used before we initialized it, somehow it magically worked ... Change-Id: I0a9a748ffbfc641f60736b0cf85d23f499b64e66 Reviewed-by: Oswald Buddenhagen --- mkspecs/android-g++/qmake.conf | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/mkspecs/android-g++/qmake.conf b/mkspecs/android-g++/qmake.conf index 28f5638463..ef78c42de9 100644 --- a/mkspecs/android-g++/qmake.conf +++ b/mkspecs/android-g++/qmake.conf @@ -168,13 +168,6 @@ QMAKE_STRIP = QMAKE_RANLIB = $$NDK_TOOLCHAIN_PATH/bin/$$NDK_TOOLS_PREFIX-ranlib -QMAKE_INCDIR = $$ANDROID_SOURCES_CXX_STL_INCDIR $$QMAKE_ANDROID_PLATFORM_INCDIR -QMAKE_LIBDIR = $$ANDROID_SOURCES_CXX_STL_LIBDIR $$QMAKE_ANDROID_PLATFORM_LIBDIR $$LIBGCC_PATH -QMAKE_INCDIR_X11 = -QMAKE_LIBDIR_X11 = -QMAKE_INCDIR_OPENGL = $$QMAKE_ANDROID_PLATFORM_INCDIR -QMAKE_LIBDIR_OPENGL = $$QMAKE_ANDROID_PLATFORM_LIBDIR - equals(ANDROID_TARGET_ARCH, armeabi)|equals(ANDROID_TARGET_ARCH, armeabi-v7a): \ LIBGCC_PATH_FULL = $$system("$$QMAKE_CC -mthumb-interwork -print-libgcc-file-name") else: \ @@ -182,6 +175,13 @@ else: \ LIBGCC_PATH = $$dirname(LIBGCC_PATH_FULL) +QMAKE_INCDIR = $$ANDROID_SOURCES_CXX_STL_INCDIR $$QMAKE_ANDROID_PLATFORM_INCDIR +QMAKE_LIBDIR = $$ANDROID_SOURCES_CXX_STL_LIBDIR $$QMAKE_ANDROID_PLATFORM_LIBDIR $$LIBGCC_PATH +QMAKE_INCDIR_X11 = +QMAKE_LIBDIR_X11 = +QMAKE_INCDIR_OPENGL = $$QMAKE_ANDROID_PLATFORM_INCDIR +QMAKE_LIBDIR_OPENGL = $$QMAKE_ANDROID_PLATFORM_LIBDIR + QMAKE_LINK = $$QMAKE_CXX QMAKE_LINK_SHLIB = $$QMAKE_CXX QMAKE_LFLAGS = --sysroot=$$ANDROID_PLATFORM_ROOT_PATH -- cgit v1.2.3 From 0f559a2d998d7ff5b7dec83a1c7e8a9996cbaa26 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Mon, 25 Apr 2016 10:59:31 -0700 Subject: Force the use of the C++11 alignof keyword instead of an extension If the compiler supports C++11 alignof, let's use it. No point in perpetuating the use of __alignof__ or __alignof. There's a fallback implementation in qglobal.h that works even without compiler extensions. We can't drop it just yet (alignas is not a required C++11 feature), but at this point I doubt that fallback is used anywhere anymore. The tst_compiler test was wrong to use alignof(variable). That's not permitted by the standard nor would it work with our fallback implementation. MSVC 2015 enforces this, but ICC, GCC and Clang don't. Change-Id: Ifea6e497f11a461db432ffff1448abfa86672c63 Reviewed-by: Olivier Goffart (Woboq GmbH) --- src/corelib/global/qcompilerdetection.h | 3 ++- tests/auto/other/compiler/tst_compiler.cpp | 7 ++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h index ad881ef4c9..01b3a298af 100644 --- a/src/corelib/global/qcompilerdetection.h +++ b/src/corelib/global/qcompilerdetection.h @@ -1053,7 +1053,8 @@ # define Q_DECL_NOTHROW Q_DECL_NOEXCEPT #endif -#if defined(Q_COMPILER_ALIGNOF) && !defined(Q_ALIGNOF) +#if defined(Q_COMPILER_ALIGNOF) +# undef Q_ALIGNOF # define Q_ALIGNOF(x) alignof(x) #endif diff --git a/tests/auto/other/compiler/tst_compiler.cpp b/tests/auto/other/compiler/tst_compiler.cpp index 540c155fd8..8cd25bf164 100644 --- a/tests/auto/other/compiler/tst_compiler.cpp +++ b/tests/auto/other/compiler/tst_compiler.cpp @@ -636,9 +636,10 @@ void tst_Compiler::cxx11_alignas() #ifndef Q_COMPILER_ALIGNAS QSKIP("Compiler does not support C++11 feature"); #else - alignas(double) char c; - Q_UNUSED(c); - QCOMPARE(Q_ALIGNOF(c), Q_ALIGNOF(double)); + struct S { + alignas(double) char c; + }; + QCOMPARE(Q_ALIGNOF(S), Q_ALIGNOF(double)); #endif } -- cgit v1.2.3 From 261f9101dd8b03019251cf9aa58382de0fbde2e7 Mon Sep 17 00:00:00 2001 From: Orgad Shaneh Date: Sun, 15 May 2016 14:53:38 +0300 Subject: QLockFile: Use a more robust stale file detection When a process that locked a lockfile crashes on Windows, sometimes a new instance of the process fails to lock. Unfortunately, I can't find a way to reproduce the problem consistently, but it happens from time to time with Qt Creator and Qbs. There are several ways to detect a dead process on Windows. Some of them can be found in stackoverflow[1]. The current implementation of stale lock detection is based on the second answer (using WaitForSingleObject), but apparently it doesn't work in 100% of the cases. The most voted answer[2] (using GetProcessExitCode) proves to work also on this case. [1] http://stackoverflow.com/q/1591342/764870 [2] http://stackoverflow.com/a/1591379/764870 Task-number: QTBUG-53392 Change-Id: Ied7bf00985d0f12e833b887a0143f7bdeee3e772 Reviewed-by: Kai Koehne Reviewed-by: Thiago Macieira --- src/corelib/io/qlockfile_win.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/corelib/io/qlockfile_win.cpp b/src/corelib/io/qlockfile_win.cpp index 5bd1ba04c9..e72e486cce 100644 --- a/src/corelib/io/qlockfile_win.cpp +++ b/src/corelib/io/qlockfile_win.cpp @@ -137,9 +137,11 @@ bool QLockFilePrivate::isApparentlyStale() const if (!procHandle) return true; // We got a handle but check if process is still alive - DWORD dwR = ::WaitForSingleObject(procHandle, 0); + DWORD exitCode = 0; + if (!::GetExitCodeProcess(procHandle, &exitCode)) + exitCode = 0; ::CloseHandle(procHandle); - if (dwR == WAIT_TIMEOUT) + if (exitCode != STILL_ACTIVE) return true; const QString processName = processNameByPid(pid); if (!processName.isEmpty() && processName != appname) -- cgit v1.2.3 From 16864c42d6bc0ee6b3e3fa03123ef5884557ceea Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 18 May 2016 14:40:20 -0700 Subject: Fix linking of the minimal platform plugin on OS X platformsupport/fontdatabases/fontdatabases.pri disables all font databases except CoreText on OS X, so this is required for linking. Otherwise, we get undefined reference linker errors: Undefined symbols for architecture x86_64: "vtable for QBasicFontDatabase", referenced from: QMinimalIntegration::fontDatabase() const in qminimalintegration.o Change-Id: I31298e973803b4d6eedbf61607056114d1556584 Reviewed-by: Jake Petroules --- src/plugins/platforms/minimal/minimal.pro | 1 + 1 file changed, 1 insertion(+) diff --git a/src/plugins/platforms/minimal/minimal.pro b/src/plugins/platforms/minimal/minimal.pro index 0d31d6605b..bd6f2d8e6f 100644 --- a/src/plugins/platforms/minimal/minimal.pro +++ b/src/plugins/platforms/minimal/minimal.pro @@ -11,6 +11,7 @@ HEADERS = qminimalintegration.h \ OTHER_FILES += minimal.json CONFIG += qpa/genericunixfontdatabase +darwin: DEFINES += QT_NO_FONTCONFIG PLUGIN_TYPE = platforms PLUGIN_CLASS_NAME = QMinimalIntegrationPlugin -- cgit v1.2.3 From 6d31d3e7effabcc998792283249d46f5c0d73b3d Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Wed, 18 May 2016 20:28:33 -0700 Subject: Fix build with ICC on OS X: __Z18qt_getQtMetaObjectv was undefiend It's inline, but the compiler did not inline it properly from Objective C++ sources. Undefined symbols for architecture x86_64: "__Z18qt_getQtMetaObjectv", referenced from: __ZN2Qt20qt_getEnumMetaObjectENS_15ScrollBarPolicyE in qlocale_mac.o ... Change-Id: Ie9fd7afe060b4e4a8052fffd144fda60c50a9779 Reviewed-by: Olivier Goffart (Woboq GmbH) Reviewed-by: Thiago Macieira --- src/corelib/kernel/qobject.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/corelib/kernel/qobject.h b/src/corelib/kernel/qobject.h index 771d2f5ea0..b39eefa795 100644 --- a/src/corelib/kernel/qobject.h +++ b/src/corelib/kernel/qobject.h @@ -444,8 +444,7 @@ protected: QScopedPointer d_ptr; static const QMetaObject staticQtMetaObject; - friend inline const QMetaObject *qt_getQtMetaObject() Q_DECL_NOEXCEPT - { return &staticQtMetaObject; } + friend inline const QMetaObject *qt_getQtMetaObject() Q_DECL_NOEXCEPT; friend struct QMetaObject; friend struct QMetaObjectPrivate; @@ -476,6 +475,9 @@ inline QMetaObject::Connection QObject::connect(const QObject *asender, const ch const char *amember, Qt::ConnectionType atype) const { return connect(asender, asignal, this, amember, atype); } +inline const QMetaObject *qt_getQtMetaObject() Q_DECL_NOEXCEPT +{ return &QObject::staticQtMetaObject; } + #ifndef QT_NO_USERDATA class Q_CORE_EXPORT QObjectUserData { public: -- cgit v1.2.3 From 32c301e2296c5b3ba31528e6d92b521d43a216e9 Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Sun, 29 May 2016 17:45:05 -0300 Subject: Fix crash when connecting a non-PMF with Qt::UniqueConnection... ...if a PMF connection had already happened. Since UniqueConnection isn't implemented for non-PMFs (functors and lambdas aren't comparable, even if static member functions or non-member functions are), we pass a null pointer for comparison argument. The disconnect() code already protected against a null pointer there, but not the connect code path with Qt::UniqueConnection Change-Id: I87e17314d8b24ae983b1fffd145324beced0494d Reviewed-by: Olivier Goffart (Woboq GmbH) Reviewed-by: Dario Freddi --- src/corelib/kernel/qobject.cpp | 2 +- tests/auto/corelib/kernel/qobject/tst_qobject.cpp | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp index d97f8d0ef1..a21dbffad5 100644 --- a/src/corelib/kernel/qobject.cpp +++ b/src/corelib/kernel/qobject.cpp @@ -4683,7 +4683,7 @@ QMetaObject::Connection QObjectPrivate::connectImpl(const QObject *sender, int s QOrderedMutexLocker locker(signalSlotLock(sender), signalSlotLock(receiver)); - if (type & Qt::UniqueConnection) { + if (type & Qt::UniqueConnection && slot) { QObjectConnectionListVector *connectionLists = QObjectPrivate::get(s)->connectionLists; if (connectionLists && connectionLists->count() > signal_index) { const QObjectPrivate::Connection *c2 = diff --git a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp index 5b89ef3792..46889225eb 100644 --- a/tests/auto/corelib/kernel/qobject/tst_qobject.cpp +++ b/tests/auto/corelib/kernel/qobject/tst_qobject.cpp @@ -139,6 +139,7 @@ private slots: void connectFunctorOverloads(); void connectFunctorQueued(); void connectFunctorWithContext(); + void connectFunctorWithContextUnique(); void connectFunctorDeadlock(); void connectStaticSlotWithObject(); void disconnectDoesNotLeakFunctor(); @@ -5800,6 +5801,22 @@ void tst_QObject::connectFunctorWithContext() context->deleteLater(); } +void tst_QObject::connectFunctorWithContextUnique() +{ + // Qt::UniqueConnections currently don't work for functors, but we need to + // be sure that they don't crash. If that is implemented, change this test. + + SenderObject sender; + ReceiverObject receiver; + QObject::connect(&sender, &SenderObject::signal1, &receiver, &ReceiverObject::slot1); + receiver.count_slot1 = 0; + + QObject::connect(&sender, &SenderObject::signal1, &receiver, SlotFunctor(), Qt::UniqueConnection); + + sender.emitSignal1(); + QCOMPARE(receiver.count_slot1, 1); +} + class MyFunctor { public: -- cgit v1.2.3 From fae8ee8b428ae7a406199e504b2d0eedd5059dbd Mon Sep 17 00:00:00 2001 From: Thiago Macieira Date: Thu, 19 May 2016 18:46:39 -0700 Subject: Update the high scaling settings after an XCB screen is added Without this, the newly-added screen will still have the scaleFactorProperty unset, which means QScreen::devicePixelRatio will return 1.0. That differs from what happens if the screen had been detected when the application started. This is part of the fix for the bug report, but insufficient. Task-number: QTBUG-53500 Change-Id: Id3aab65533904562a6cbfffd14502365d86bd36d Reviewed-by: Shawn Rutledge --- src/plugins/platforms/xcb/qxcbconnection.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp index 669ef3a98e..b5c5028995 100644 --- a/src/plugins/platforms/xcb/qxcbconnection.cpp +++ b/src/plugins/platforms/xcb/qxcbconnection.cpp @@ -32,6 +32,7 @@ ****************************************************************************/ #include +#include #include #include "qxcbconnection.h" @@ -257,6 +258,7 @@ void QXcbConnection::updateScreens(const xcb_randr_notify_event_t *event) } else { screen = createScreen(virtualDesktop, output, outputInfo.data()); qCDebug(lcQpaScreen) << "output" << screen->name() << "is connected and enabled"; + QHighDpiScaling::updateHighDpiScaling(); } } } else if (screen) { -- cgit v1.2.3 From b403b8c094a1bf59b70368e28cbd454b6872498f Mon Sep 17 00:00:00 2001 From: Ralf Nolden Date: Thu, 26 May 2016 23:09:36 +0200 Subject: Add Interix OS system detection defines NetBSD (pkgsrc) ports are building qt on Interix as well, where the necessary defines are missing for in qsystemdetection.h. Patch for adding them provided by NetBSD ports maintainer Kamil Rytarowski Change-Id: I769c47f623317efda3130a7061307e84d3350fac Reviewed-by: Oswald Buddenhagen Reviewed-by: Thiago Macieira --- src/corelib/global/qsystemdetection.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/corelib/global/qsystemdetection.h b/src/corelib/global/qsystemdetection.h index f1abc88b99..b6a7835ef2 100644 --- a/src/corelib/global/qsystemdetection.h +++ b/src/corelib/global/qsystemdetection.h @@ -60,6 +60,7 @@ NETBSD - NetBSD OPENBSD - OpenBSD BSDI - BSD/OS + INTERIX - Interix IRIX - SGI Irix OSF - HP Tru64 UNIX SCO - SCO OpenServer 5 @@ -147,6 +148,9 @@ #elif defined(__bsdi__) # define Q_OS_BSDI # define Q_OS_BSD4 +#elif defined(__INTERIX) +# define Q_OS_INTERIX +# define Q_OS_BSD4 #elif defined(__sgi) # define Q_OS_IRIX #elif defined(__osf__) -- cgit v1.2.3 From 1d9d16515853932205d4ca82a385dfb9c2221394 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?B=C5=82a=C5=BCej=20Szczygie=C5=82?= Date: Tue, 24 May 2016 16:30:02 +0200 Subject: QAbstractItemView: Reset the drop indicator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Always reset the drop indicator position and rect when drag action will be finished. This can prevent drawing the indicator in bad place when the next drag will be performed. Task-number: QTBUG-53541 Change-Id: I420207a0ede6f19f48472a8f0f723afe948de1c6 Reviewed-by: Friedemann Kleint Reviewed-by: Thorbjørn Lund Martsum --- src/widgets/itemviews/qabstractitemview.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp index 9dbe5c6c54..057718cdba 100644 --- a/src/widgets/itemviews/qabstractitemview.cpp +++ b/src/widgets/itemviews/qabstractitemview.cpp @@ -3620,6 +3620,9 @@ void QAbstractItemView::startDrag(Qt::DropActions supportedActions) defaultDropAction = Qt::CopyAction; if (drag->exec(supportedActions, defaultDropAction) == Qt::MoveAction) d->clearOrRemove(); + // Reset the drop indicator + d->dropIndicatorRect = QRect(); + d->dropIndicatorPosition = OnItem; } } #endif // QT_NO_DRAGANDDROP -- cgit v1.2.3 From 886086f5d39a317443018689f817e8eb8ecb0be8 Mon Sep 17 00:00:00 2001 From: Aleksei Timofeyev Date: Fri, 22 Apr 2016 12:57:17 +0500 Subject: QWindowsPipeWriter: Discard queued signals in stop() The _q_queueBytesWritten signal may be already queued from the event loop at the time when stop() is called. We do not want to emit signals once stopped, so reset all respective state variables. Change-Id: I343e1702955e0bbc1d11930d19e75dab6e129b4c Reviewed-by: Alex Trotsenko Reviewed-by: Joerg Bornemann --- src/corelib/io/qwindowspipewriter.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/corelib/io/qwindowspipewriter.cpp b/src/corelib/io/qwindowspipewriter.cpp index 839dc8a19c..3731aba97b 100644 --- a/src/corelib/io/qwindowspipewriter.cpp +++ b/src/corelib/io/qwindowspipewriter.cpp @@ -202,6 +202,8 @@ bool QWindowsPipeWriter::write(const QByteArray &ba) void QWindowsPipeWriter::stop() { stopped = true; + bytesWrittenPending = false; + pendingBytesWrittenValue = 0; if (writeSequenceStarted) { if (!qt_cancelIo(handle, &overlapped)) { const DWORD dwError = GetLastError(); -- cgit v1.2.3 From 00061b968d23d34cdbd43e0930463be06a2775b3 Mon Sep 17 00:00:00 2001 From: Alexandru Croitor Date: Mon, 25 Apr 2016 15:43:57 +0200 Subject: Fix opaque texture-based widgets not being always shown. Whenever a regular QWidget contains a child render-to-texture widget (like a QOpenGLWidget) that is opaque (attribute Qt::WA_OpaquePaintEvent is set) and completely covers the parent geometry, the child widget would not be shown. This happens because QWidgetBackingStore::doSync contains a check to see if an opaque child completely covers its parent, in which case it does not draw the parent, and only draws the child. This is an issue if the widget is actually a texture-based one, because for it to be seen on screen, the parent widget has to be redrawn with a proper blending mask, so that the rtt widget gets properly composed into the place where the mask is. The fix consists in keeping the parent widget being marked dirty, in case it has an opaque texture-based child that completely covers it. This will force a redraw of the parent widget with a proper blending mask. Change-Id: If1feec04b86bff2c49158b8d72f175cec252dea1 Task-number: QTBUG-52123 Reviewed-by: Allan Sandfeld Jensen --- src/widgets/kernel/qwidgetbackingstore.cpp | 10 ++ .../widgets/qopenglwidget/tst_qopenglwidget.cpp | 133 +++++++++++++++++++++ 2 files changed, 143 insertions(+) diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp index 049ed248de..5d13fb926b 100644 --- a/src/widgets/kernel/qwidgetbackingstore.cpp +++ b/src/widgets/kernel/qwidgetbackingstore.cpp @@ -1211,10 +1211,20 @@ void QWidgetBackingStore::doSync() // We know for sure that the widget isn't overlapped if 'isMoved' is true. if (!wd->isMoved) wd->subtractOpaqueSiblings(wd->dirty, &hasDirtySiblingsAbove); + + // Make a copy of the widget's dirty region, to restore it in case there is an opaque + // render-to-texture child that completely covers the widget, because otherwise the + // render-to-texture child won't be visible, due to its parent widget not being redrawn + // with a proper blending mask. + const QRegion dirtyBeforeSubtractedOpaqueChildren = wd->dirty; + // Scrolled and moved widgets must draw all children. if (!wd->isScrolled && !wd->isMoved) wd->subtractOpaqueChildren(wd->dirty, w->rect()); + if (wd->dirty.isEmpty() && wd->textureChildSeen) + wd->dirty = dirtyBeforeSubtractedOpaqueChildren; + if (wd->dirty.isEmpty()) { resetWidget(w); continue; diff --git a/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp b/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp index a4a0045265..f5c127a063 100644 --- a/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp +++ b/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp @@ -34,11 +34,14 @@ #include #include #include +#include +#include #include #include #include #include #include +#include #include #include @@ -59,6 +62,7 @@ private slots: void fboRedirect(); void showHide(); void nativeWindow(); + void stackWidgetOpaqueChildIsVisible(); }; void tst_QOpenGLWidget::create() @@ -425,6 +429,135 @@ void tst_QOpenGLWidget::nativeWindow() QVERIFY(image.pixel(30, 40) == qRgb(0, 255, 0)); } +static inline QString msgRgbMismatch(unsigned actual, unsigned expected) +{ + return QString::asprintf("Color mismatch, %#010x != %#010x", actual, expected); +} + +static QPixmap grabWidgetWithoutRepaint(const QWidget *widget, QRect clipArea) +{ + const QWidget *targetWidget = widget; +#ifdef Q_OS_WIN + // OpenGL content is not properly grabbed on Windows when passing a top level widget window, + // because GDI functions can't grab OpenGL layer content. + // Instead the whole screen should be captured, with an adjusted clip area, which contains + // the final composited content. + QDesktopWidget *desktopWidget = QApplication::desktop(); + const QWidget *mainScreenWidget = desktopWidget->screen(); + targetWidget = mainScreenWidget; + clipArea = QRect(widget->mapToGlobal(clipArea.topLeft()), + widget->mapToGlobal(clipArea.bottomRight())); +#endif + + const QWindow *window = targetWidget->window()->windowHandle(); + Q_ASSERT(window); + WId windowId = window->winId(); + + QScreen *screen = window->screen(); + Q_ASSERT(screen); + + const QSize size = clipArea.size(); + const QPixmap result = screen->grabWindow(windowId, + clipArea.x(), + clipArea.y(), + size.width(), + size.height()); + return result; +} + +#define VERIFY_COLOR(child, region, color) verifyColor(child, region, color, __LINE__) + +bool verifyColor(const QWidget *widget, const QRect &clipArea, const QColor &color, int callerLine) +{ + for (int t = 0; t < 6; t++) { + const QPixmap pixmap = grabWidgetWithoutRepaint(widget, clipArea); + if (!QTest::qCompare(pixmap.size(), + clipArea.size(), + "pixmap.size()", + "rect.size()", + __FILE__, + callerLine)) + return false; + + + const QImage image = pixmap.toImage(); + QPixmap expectedPixmap(pixmap); /* ensure equal formats */ + expectedPixmap.detach(); + expectedPixmap.fill(color); + + uint alphaCorrection = image.format() == QImage::Format_RGB32 ? 0xff000000 : 0; + uint firstPixel = image.pixel(0,0) | alphaCorrection; + + // Retry a couple of times. Some window managers have transparency animation, or are + // just slow to render. + if (t < 5) { + if (firstPixel == QColor(color).rgb() + && image == expectedPixmap.toImage()) + return true; + else + QTest::qWait(200); + } else { + if (!QTest::qVerify(firstPixel == QColor(color).rgb(), + "firstPixel == QColor(color).rgb()", + qPrintable(msgRgbMismatch(firstPixel, QColor(color).rgb())), + __FILE__, callerLine)) { + return false; + } + if (!QTest::qVerify(image == expectedPixmap.toImage(), + "image == expectedPixmap.toImage()", + "grabbed pixmap differs from expected pixmap", + __FILE__, callerLine)) { + return false; + } + } + } + + return false; +} + +void tst_QOpenGLWidget::stackWidgetOpaqueChildIsVisible() +{ +#ifdef Q_OS_OSX + QSKIP("QScreen::grabWindow() doesn't work properly on OSX HighDPI screen: QTBUG-46803"); + return; +#endif + + QStackedWidget stack; + + QWidget* emptyWidget = new QWidget(&stack); + stack.addWidget(emptyWidget); + + // Create an opaque red QOpenGLWidget. + const int dimensionSize = 400; + ClearWidget* clearWidget = new ClearWidget(&stack, dimensionSize, dimensionSize); + clearWidget->setAttribute(Qt::WA_OpaquePaintEvent); + stack.addWidget(clearWidget); + + // Show initial QWidget. + stack.setCurrentIndex(0); + stack.resize(dimensionSize, dimensionSize); + stack.show(); + QTest::qWaitForWindowExposed(&stack); + QTest::qWaitForWindowActive(&stack); + + // Switch to the QOpenGLWidget. + stack.setCurrentIndex(1); + QTRY_COMPARE(clearWidget->m_paintCalled, true); + + // Resize the tested region to be half size in the middle, because some OSes make the widget + // have rounded corners (e.g. OSX), and the grabbed window pixmap will not coincide perfectly + // with what was actually painted. + QRect clipArea = stack.rect(); + clipArea.setSize(clipArea.size() / 2); + const int translationOffsetToMiddle = dimensionSize / 4; + clipArea.translate(translationOffsetToMiddle, translationOffsetToMiddle); + + // Verify that the QOpenGLWidget was actually painted AND displayed. + const QColor red(255, 0, 0, 255); + VERIFY_COLOR(&stack, clipArea, red); + #undef VERIFY_COLOR +} + QTEST_MAIN(tst_QOpenGLWidget) #include "tst_qopenglwidget.moc" -- cgit v1.2.3 From 2f0ffba638bdb868a810bc0349c240b6b6e172cd Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Mon, 30 May 2016 14:15:49 +0200 Subject: Fix emission of QProcess:errorOccurred Consistently use setErrorAndEmit to emit errorOccurred and the deprecated error signal. Change-Id: I8bc7634a72d4d13f74bbf76547de08271dfcbb59 Reviewed-by: Kai Koehne --- src/corelib/io/qprocess.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp index 502628489d..6e1a771258 100644 --- a/src/corelib/io/qprocess.cpp +++ b/src/corelib/io/qprocess.cpp @@ -2090,10 +2090,7 @@ void QProcess::start(const QString &program, const QStringList &arguments, OpenM return; } if (program.isEmpty()) { - Q_D(QProcess); - d->processError = QProcess::FailedToStart; - setErrorString(tr("No program defined")); - emit error(d->processError); + d->setErrorAndEmit(QProcess::FailedToStart, tr("No program defined")); return; } @@ -2120,10 +2117,7 @@ void QProcess::start(OpenMode mode) return; } if (d->program.isEmpty()) { - Q_D(QProcess); - d->processError = QProcess::FailedToStart; - setErrorString(tr("No program defined")); - emit error(d->processError); + d->setErrorAndEmit(QProcess::FailedToStart, tr("No program defined")); return; } -- cgit v1.2.3 From eb50193136c7c73be864e3232d01e98ddc24e539 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 26 Apr 2016 14:33:17 +0200 Subject: QDialog::adjustPosition(): Manually set target screen before moving. QDialog::adjustPosition() can move the dialog across screens. A call to QWindow::resize() later in the show sequence might then see the wrong scaling factor if the screen changed notification is still stuck in an event queue. Prevent that by setting the target screen early on. Task-number: QTBUG-52735 Change-Id: I17bb3490b660f8f17c36524457cb87adbb7851e9 Reviewed-by: Andy Shaw --- src/widgets/dialogs/qdialog.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/widgets/dialogs/qdialog.cpp b/src/widgets/dialogs/qdialog.cpp index 5124960ab4..45d2279ed5 100644 --- a/src/widgets/dialogs/qdialog.cpp +++ b/src/widgets/dialogs/qdialog.cpp @@ -860,6 +860,12 @@ void QDialog::adjustPosition(QWidget* w) if (p.y() < desk.y()) p.setY(desk.y()); + // QTBUG-52735: Manually set the correct target screen since scaling in a + // subsequent call to QWindow::resize() may otherwise use the wrong factor + // if the screen changed notification is still in an event queue. + if (QWindow *window = windowHandle()) + window->setScreen(QGuiApplication::screens().at(scrn)); + move(p); } -- cgit v1.2.3 From 28db26f6917174d787bd4c6eadbecebc952d59dc Mon Sep 17 00:00:00 2001 From: Edward Welbourne Date: Mon, 30 May 2016 15:25:06 +0200 Subject: qtestcase: Fix buffer over-run, '\0' appended beyond buffer end MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Noticed by Coverity (CID 161673). If the file being read contains enough to fill the buffer, read() shall do that and return the nbytes it was passed; as this was the size of the buffer, subsequently writing a '\0' at this index in buffer is out of bounds. Fortunately, /proc/self/status is typically < 1k so fits well inside the 2k buffer. All the same, we can safely pass sizeof(buffer) - 1 as nbytes and *be sure* of not getting a buffer over-run. Change-Id: Ib620a330fbc94f0579c953737f7c4417ca449968 Reviewed-by: Jędrzej Nowacki --- src/testlib/qtestcase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index 62649441db..eae490e278 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -2514,7 +2514,7 @@ static bool debuggerPresent() if (fd == -1) return false; char buffer[2048]; - ssize_t size = read(fd, buffer, sizeof(buffer)); + ssize_t size = read(fd, buffer, sizeof(buffer) - 1); if (size == -1) { close(fd); return false; -- cgit v1.2.3 From a9bef62ec216a4c0c4f95ca45e1e98ef96ca42f3 Mon Sep 17 00:00:00 2001 From: Ralf Nolden Date: Tue, 31 May 2016 13:15:56 +0200 Subject: Compile fix for OpenBSD using Q_OS_OPENBSD defines OpenBSD does not have EPROTO and LLINDEX.. LLINDEX is only a macro pointing at sdl_index so use the FreeBSD macro from as a a workaround. Change-Id: Ic3ccecc1b671bb28d14da83ba915ec3fcad2657d Reviewed-by: Richard J. Moore --- src/network/socket/qnativesocketengine_unix.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/network/socket/qnativesocketengine_unix.cpp b/src/network/socket/qnativesocketengine_unix.cpp index 6a740f4c30..e92123e10c 100644 --- a/src/network/socket/qnativesocketengine_unix.cpp +++ b/src/network/socket/qnativesocketengine_unix.cpp @@ -573,7 +573,9 @@ int QNativeSocketEnginePrivate::nativeAccept() setError(QAbstractSocket::SocketResourceError, NotSocketErrorString); break; case EPROTONOSUPPORT: +#if !defined(Q_OS_OPENBSD) case EPROTO: +#endif case EAFNOSUPPORT: case EINVAL: setError(QAbstractSocket::UnsupportedSocketOperationError, ProtocolUnsupportedErrorString); @@ -904,7 +906,9 @@ qint64 QNativeSocketEnginePrivate::nativeReceiveDatagram(char *data, qint64 maxS if (cmsgptr->cmsg_level == IPPROTO_IP && cmsgptr->cmsg_type == IP_RECVIF && cmsgptr->cmsg_len >= CMSG_LEN(sizeof(sockaddr_dl))) { sockaddr_dl *sdl = reinterpret_cast(CMSG_DATA(cmsgptr)); - +# if defined(Q_OS_OPENBSD) +# define LLINDEX(s) ((s)->sdl_index) +# endif header->ifindex = LLINDEX(sdl); } # endif -- cgit v1.2.3 From ed08e3be340ff0592ea6e11435d9546db4a9366f Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Tue, 31 May 2016 13:21:58 +0200 Subject: tst_QPlainTextEdit/tst_QTextEdit: Do not output unprintable characters. The test selectWordsFromStringsContainingSeparators() duplicated in boths tests caused tab and Nbsp characters to be output to the log, which upsets editors. Use an array of ushort instead of a wasteful QStringList and output the hex codes for the unprintable characters. Change-Id: I08724268f376b4c0da492b4109570e44f7d4a3fb Reviewed-by: Eskil Abrahamsen Blomfeldt --- .../widgets/qplaintextedit/tst_qplaintextedit.cpp | 19 +++++++++++++------ .../auto/widgets/widgets/qtextedit/tst_qtextedit.cpp | 19 +++++++++++++------ 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp b/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp index d466489acb..8c86056ad3 100644 --- a/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp +++ b/tests/auto/widgets/widgets/qplaintextedit/tst_qplaintextedit.cpp @@ -1184,12 +1184,19 @@ void tst_QPlainTextEdit::selectWordsFromStringsContainingSeparators_data() QTest::addColumn("testString"); QTest::addColumn("selectedWord"); - QStringList wordSeparators; - wordSeparators << "." << "," << "?" << "!" << ":" << ";" << "-" << "<" << ">" << "[" - << "]" << "(" << ")" << "{" << "}" << "=" << "\t"<< QString(QChar::Nbsp); - - foreach (QString s, wordSeparators) - QTest::newRow(QString("separator: " + s).toLocal8Bit()) << QString("foo") + s + QString("bar") << QString("foo"); + const ushort wordSeparators[] = + {'.', ',', '?', '!', ':', ';', '-', '<', '>', '[', ']', '(', ')', '{', '}', + '=', '\t', ushort(QChar::Nbsp)}; + + for (size_t i = 0, count = sizeof(wordSeparators) / sizeof(wordSeparators[0]); i < count; ++i) { + const ushort u = wordSeparators[i]; + QByteArray rowName = QByteArrayLiteral("separator: "); + if (u >= 32 && u < 128) + rowName += char(u); + else + rowName += QByteArrayLiteral("0x") + QByteArray::number(u, 16); + QTest::newRow(rowName.constData()) << QString("foo") + QChar(u) + QString("bar") << QString("foo"); + } } void tst_QPlainTextEdit::selectWordsFromStringsContainingSeparators() diff --git a/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp b/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp index b81e4df123..690a25a87d 100644 --- a/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp +++ b/tests/auto/widgets/widgets/qtextedit/tst_qtextedit.cpp @@ -1530,12 +1530,19 @@ void tst_QTextEdit::selectWordsFromStringsContainingSeparators_data() QTest::addColumn("testString"); QTest::addColumn("selectedWord"); - QStringList wordSeparators; - wordSeparators << "." << "," << "?" << "!" << ":" << ";" << "-" << "<" << ">" << "[" - << "]" << "(" << ")" << "{" << "}" << "=" << "\t"<< QString(QChar::Nbsp); - - foreach (QString s, wordSeparators) - QTest::newRow(QString("separator: " + s).toLocal8Bit()) << QString("foo") + s + QString("bar") << QString("foo"); + const ushort wordSeparators[] = + {'.', ',', '?', '!', ':', ';', '-', '<', '>', '[', ']', '(', ')', '{', '}', + '=', '\t', ushort(QChar::Nbsp)}; + + for (size_t i = 0, count = sizeof(wordSeparators) / sizeof(wordSeparators[0]); i < count; ++i) { + const ushort u = wordSeparators[i]; + QByteArray rowName = QByteArrayLiteral("separator: "); + if (u >= 32 && u < 128) + rowName += char(u); + else + rowName += QByteArrayLiteral("0x") + QByteArray::number(u, 16); + QTest::newRow(rowName.constData()) << QString("foo") + QChar(u) + QString("bar") << QString("foo"); + } } void tst_QTextEdit::selectWordsFromStringsContainingSeparators() -- cgit v1.2.3 From 0ff45fbf1b9a6ab6da2541bb70533e49dc892954 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Wed, 30 Mar 2016 09:42:34 +0200 Subject: winrt: Enable drop support Allow Qt applications to receive drops. Dragging is not supported yet and will be handled in a separate commit. Task-number: QTBUG-50827 Change-Id: I684e3d5685ce73f74805691f6ac7bbc45e2d19ec Reviewed-by: Oliver Wolff --- src/plugins/platforms/winrt/qwinrtdrag.cpp | 672 ++++++++++++++++++++++ src/plugins/platforms/winrt/qwinrtdrag.h | 113 ++++ src/plugins/platforms/winrt/qwinrtintegration.cpp | 10 + src/plugins/platforms/winrt/qwinrtintegration.h | 4 + src/plugins/platforms/winrt/qwinrtscreen.cpp | 12 + src/plugins/platforms/winrt/winrt.pro | 7 + 6 files changed, 818 insertions(+) create mode 100644 src/plugins/platforms/winrt/qwinrtdrag.cpp create mode 100644 src/plugins/platforms/winrt/qwinrtdrag.h diff --git a/src/plugins/platforms/winrt/qwinrtdrag.cpp b/src/plugins/platforms/winrt/qwinrtdrag.cpp new file mode 100644 index 0000000000..a52ed91749 --- /dev/null +++ b/src/plugins/platforms/winrt/qwinrtdrag.cpp @@ -0,0 +1,672 @@ +/**************************************************************************** +** +** 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:LGPL3$ +** 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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ +#include "qwinrtdrag.h" + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +using namespace ABI::Windows::ApplicationModel::DataTransfer; +using namespace ABI::Windows::ApplicationModel::DataTransfer::DragDrop; +using namespace ABI::Windows::Foundation; +using namespace ABI::Windows::Foundation::Collections; +using namespace ABI::Windows::Storage; +using namespace ABI::Windows::Storage::Streams; +using namespace ABI::Windows::UI::Xaml; +using namespace Microsoft::WRL; +using namespace Microsoft::WRL::Wrappers; + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(lcQpaMime, "qt.qpa.mime") + +class DragThreadTransferData : public QObject +{ + Q_OBJECT +public slots: + void handleDrag(); +public: + explicit DragThreadTransferData(QObject *parent = Q_NULLPTR); + QWindow *window; + QWinRTInternalMimeData *mime; + QPoint point; + Qt::DropActions actions; + bool dropAction; + ComPtr nativeArgs; + ComPtr deferral; +}; + +inline QString hStringToQString(const HString &hString) +{ + quint32 l; + const wchar_t *raw = hString.GetRawBuffer(&l); + return (QString::fromWCharArray(raw, l)); +} + +namespace NativeFormatStrings { + static ComPtr dataStatics; + static HSTRING text; // text/plain + static HSTRING html; // text/html + static HSTRING storage; // text/uri-list +} + +static inline DataPackageOperation translateFromQDragDropActions(const Qt::DropAction action) +{ + switch (action) { + case Qt::CopyAction: + return DataPackageOperation_Copy; + case Qt::MoveAction: + return DataPackageOperation_Move; + case Qt::LinkAction: + return DataPackageOperation_Link; + case Qt::IgnoreAction: + default: + return DataPackageOperation_None; + } +} + +static inline Qt::DropActions translateToQDragDropActions(const DataPackageOperation op) +{ + Qt::DropActions actions = Qt::IgnoreAction; + // None needs to be interpreted as the sender being able to handle + // anything and let the receiver decide + if (op == DataPackageOperation_None) + actions = Qt::LinkAction | Qt::CopyAction | Qt::MoveAction; + if (op & DataPackageOperation_Link) + actions |= Qt::LinkAction; + if (op & DataPackageOperation_Copy) + actions |= Qt::CopyAction; + if (op & DataPackageOperation_Move) + actions |= Qt::MoveAction; + return actions; +} + +QWinRTInternalMimeData::QWinRTInternalMimeData() + : QInternalMimeData() +{ + qCDebug(lcQpaMime) << __FUNCTION__; + if (!NativeFormatStrings::dataStatics) { + HRESULT hr; + hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_ApplicationModel_DataTransfer_StandardDataFormats).Get(), + IID_PPV_ARGS(&NativeFormatStrings::dataStatics)); + Q_ASSERT_SUCCEEDED(hr); + hr = NativeFormatStrings::dataStatics->get_Text(&NativeFormatStrings::text); + Q_ASSERT_SUCCEEDED(hr); + hr = NativeFormatStrings::dataStatics->get_Html(&NativeFormatStrings::html); + Q_ASSERT_SUCCEEDED(hr); + hr = NativeFormatStrings::dataStatics->get_StorageItems(&NativeFormatStrings::storage); + Q_ASSERT_SUCCEEDED(hr); + } +} + +QWinRTInternalMimeData::~QWinRTInternalMimeData() +{ +} + +bool QWinRTInternalMimeData::hasFormat_sys(const QString &mimetype) const +{ + qCDebug(lcQpaMime) << __FUNCTION__ << mimetype; + + if (!dataView) + return false; + + return formats_sys().contains(mimetype); +} + +QStringList QWinRTInternalMimeData::formats_sys() const +{ + qCDebug(lcQpaMime) << __FUNCTION__; + + if (!dataView) + return QStringList(); + + if (!formats.isEmpty()) + return formats; + + boolean contains; + HRESULT hr; + hr = dataView->Contains(NativeFormatStrings::text, &contains); + if (SUCCEEDED(hr) && contains) + formats.append(QLatin1String("text/plain")); + + hr = dataView->Contains(NativeFormatStrings::html, &contains); + if (SUCCEEDED(hr) && contains) + formats.append(QLatin1String("text/html")); + + hr = dataView->Contains(NativeFormatStrings::storage, &contains); + if (SUCCEEDED(hr) && contains) + formats.append(QLatin1String("text/uri-list")); + + // We need to add any additional format as well, for legacy windows + // reasons, but also in case someone adds custom formats. + ComPtr> availableFormats; + hr = dataView->get_AvailableFormats(&availableFormats); + RETURN_IF_FAILED("Could not query available formats.", return formats); + + quint32 size; + hr = availableFormats->get_Size(&size); + RETURN_IF_FAILED("Could not query format vector size.", return formats); + for (quint32 i = 0; i < size; ++i) { + HString str; + hr = availableFormats->GetAt(i, str.GetAddressOf()); + if (FAILED(hr)) + continue; + formats.append(hStringToQString(str)); + } + qDebug() << __FUNCTION__ << "Available formats:" << formats; + return formats; +} + +QVariant QWinRTInternalMimeData::retrieveData_sys(const QString &mimetype, QVariant::Type preferredType) const +{ + qCDebug(lcQpaMime) << __FUNCTION__ << mimetype << preferredType; + + if (!dataView || !formats.contains(mimetype)) + return QVariant(); + + QVariant result; + HRESULT hr; + if (mimetype == QLatin1String("text/plain")) { + hr = QEventDispatcherWinRT::runOnXamlThread([this, &result]() { + HRESULT hr; + ComPtr> op; + HString res; + hr = dataView->GetTextAsync(&op); + Q_ASSERT_SUCCEEDED(hr); + hr = QWinRTFunctions::await(op, res.GetAddressOf()); + Q_ASSERT_SUCCEEDED(hr); + result.setValue(hStringToQString(res)); + return S_OK; + }); + } else if (mimetype == QLatin1String("text/uri-list")) { + hr = QEventDispatcherWinRT::runOnXamlThread([this, &result]() { + HRESULT hr; + ComPtr*>> op; + hr = dataView->GetStorageItemsAsync(&op); + Q_ASSERT_SUCCEEDED(hr); + ComPtr> nativeItems; + hr = QWinRTFunctions::await(op, nativeItems.GetAddressOf()); + Q_ASSERT_SUCCEEDED(hr); + QList items; + quint32 count; + hr = nativeItems->get_Size(&count); + for (quint32 i = 0; i < count; ++i) { + ComPtr item; + hr = nativeItems->GetAt(i, &item); + Q_ASSERT_SUCCEEDED(hr); + HString path; + hr = item->get_Path(path.GetAddressOf()); + Q_ASSERT_SUCCEEDED(hr); + items.append(QUrl::fromLocalFile(hStringToQString(path))); + } + result.setValue(items); + return S_OK; + }); + } else if (mimetype == QLatin1String("text/html")) { + hr = QEventDispatcherWinRT::runOnXamlThread([this, &result]() { + HRESULT hr; + ComPtr> op; + HString res; + hr = dataView->GetHtmlFormatAsync(&op); + Q_ASSERT_SUCCEEDED(hr); + hr = QWinRTFunctions::await(op, res.GetAddressOf()); + Q_ASSERT_SUCCEEDED(hr); + result.setValue(hStringToQString(res)); + return S_OK; + }); + } else if (mimetype.startsWith(QLatin1String("image/"))) { + Q_UNIMPLEMENTED(); + } else { + // Asking for custom data + hr = QEventDispatcherWinRT::runOnXamlThread([this, &result, mimetype]() { + HRESULT hr; + ComPtr> op; + ComPtr res; + HString type; + type.Set(reinterpret_cast(mimetype.utf16()), mimetype.size()); + hr = dataView->GetDataAsync(type.Get(), &op); + RETURN_OK_IF_FAILED("Could not query custom drag data."); + hr = QWinRTFunctions::await(op, res.GetAddressOf()); + if (FAILED(hr) || !res) { + qCDebug(lcQpaMime) << "Custom drop data operation returned no results or failed."; + return S_OK; + } + + // Test for properties + ComPtr propertyValue; + hr = res.As(&propertyValue); + if (SUCCEEDED(hr)) { + // We need to check which type of custom data we are receiving + PropertyType type; + propertyValue->get_Type(&type); + switch (type) { + case PropertyType_UInt8: { + quint8 v; + hr = propertyValue->GetUInt8(&v); + Q_ASSERT_SUCCEEDED(hr); + result.setValue(v); + return S_OK; + } + case PropertyType_Int16: { + qint16 v; + hr = propertyValue->GetInt16(&v); + Q_ASSERT_SUCCEEDED(hr); + result.setValue(v); + return S_OK; + } + case PropertyType_UInt16: { + quint16 v; + hr = propertyValue->GetUInt16(&v); + Q_ASSERT_SUCCEEDED(hr); + result.setValue(v); + return S_OK; + } + case PropertyType_Int32: { + qint32 v; + hr = propertyValue->GetInt32(&v); + Q_ASSERT_SUCCEEDED(hr); + result.setValue(v); + return S_OK; + } + case PropertyType_UInt32: { + quint32 v; + hr = propertyValue->GetUInt32(&v); + Q_ASSERT_SUCCEEDED(hr); + result.setValue(v); + return S_OK; + } + case PropertyType_Int64: { + qint64 v; + hr = propertyValue->GetInt64(&v); + Q_ASSERT_SUCCEEDED(hr); + result.setValue(v); + return S_OK; + } + case PropertyType_UInt64: { + quint64 v; + hr = propertyValue->GetUInt64(&v); + Q_ASSERT_SUCCEEDED(hr); + result.setValue(v); + return S_OK; + } + case PropertyType_Single: { + float v; + hr = propertyValue->GetSingle(&v); + Q_ASSERT_SUCCEEDED(hr); + result.setValue(v); + return S_OK; + } + case PropertyType_Double: { + double v; + hr = propertyValue->GetDouble(&v); + Q_ASSERT_SUCCEEDED(hr); + result.setValue(v); + return S_OK; + } + case PropertyType_Char16: { + wchar_t v; + hr = propertyValue->GetChar16(&v); + Q_ASSERT_SUCCEEDED(hr); + result.setValue(QString::fromWCharArray(&v, 1)); + return S_OK; + } + case PropertyType_Boolean: { + boolean v; + hr = propertyValue->GetBoolean(&v); + Q_ASSERT_SUCCEEDED(hr); + result.setValue(v); + return S_OK; + } + case PropertyType_String: { + HString stringProperty; + hr = propertyValue->GetString(stringProperty.GetAddressOf()); + Q_ASSERT_SUCCEEDED(hr); + result.setValue(hStringToQString(stringProperty)); + return S_OK; + } + default: + qCDebug(lcQpaMime) << "Unknown property type dropped:" << type; + } + return S_OK; + } + + // Custom data can be read via input streams + ComPtr randomAccessStream; + hr = res.As(&randomAccessStream); + if (SUCCEEDED(hr)) { + UINT64 size; + hr = randomAccessStream->get_Size(&size); + Q_ASSERT_SUCCEEDED(hr); + ComPtr stream; + hr = randomAccessStream.As(&stream); + Q_ASSERT_SUCCEEDED(hr); + + ComPtr bufferFactory; + hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_Streams_Buffer).Get(), + IID_PPV_ARGS(&bufferFactory)); + Q_ASSERT_SUCCEEDED(hr); + + UINT32 length = qBound(quint64(0), quint64(size), quint64(UINT_MAX)); + ComPtr buffer; + hr = bufferFactory->Create(length, &buffer); + Q_ASSERT_SUCCEEDED(hr); + + ComPtr> readOp; + hr = stream->ReadAsync(buffer.Get(), length, InputStreamOptions_None, &readOp); + + ComPtr effectiveBuffer; + hr = QWinRTFunctions::await(readOp, effectiveBuffer.GetAddressOf()); + + hr = effectiveBuffer->get_Length(&length); + + ComPtr byteArrayAccess; + hr = effectiveBuffer.As(&byteArrayAccess); + + byte *bytes; + hr = byteArrayAccess->Buffer(&bytes); + QByteArray array((char *)bytes, length); + result.setValue(array); + return S_OK; + } + + HSTRING runtimeClass; + hr = res->GetRuntimeClassName(&runtimeClass); + Q_ASSERT_SUCCEEDED(hr); + HString converted; + converted.Set(runtimeClass); + qCDebug(lcQpaMime) << "Unknown drop data type received (" << hStringToQString(converted) + << "). Ignoring..."; + return S_OK; + }); + } + return result; +} + +void QWinRTInternalMimeData::setDataView(const Microsoft::WRL::ComPtr &d) +{ + dataView = d; + formats.clear(); +} + +static HRESULT qt_drag_enter(IInspectable *sender, ABI::Windows::UI::Xaml::IDragEventArgs *e) +{ + QWinRTDrag::instance()->handleNativeDragEvent(sender, e); + return S_OK; +} + +static HRESULT qt_drag_over(IInspectable *sender, ABI::Windows::UI::Xaml::IDragEventArgs *e) +{ + QWinRTDrag::instance()->handleNativeDragEvent(sender, e); + return S_OK; +} + +static HRESULT qt_drag_leave(IInspectable *sender, ABI::Windows::UI::Xaml::IDragEventArgs *e) +{ + // Qt internally checks for new drags and auto sends leave events + // Also there is no QPA function for handling leave + Q_UNUSED(sender); + Q_UNUSED(e); + return S_OK; +} + +static HRESULT qt_drop(IInspectable *sender, ABI::Windows::UI::Xaml::IDragEventArgs *e) +{ + QWinRTDrag::instance()->handleNativeDragEvent(sender, e, true); + return S_OK; +} + +#define Q_DECLARE_DRAGHANDLER(name,func) \ +class QtDragEventHandler##name : public IDragEventHandler \ +{ \ +public: \ + virtual HRESULT STDMETHODCALLTYPE Invoke(IInspectable *sender, \ + ABI::Windows::UI::Xaml::IDragEventArgs *e) \ + { \ + return qt_##func(sender, e);\ + } \ + \ + STDMETHODIMP \ + QueryInterface(REFIID riid, void FAR* FAR* ppvObj) \ + { \ + if (riid == IID_IUnknown || riid == IID_IDragEventHandler) { \ + *ppvObj = this; \ + AddRef(); \ + return NOERROR; \ + } \ + *ppvObj = NULL; \ + return ResultFromScode(E_NOINTERFACE); \ + } \ + \ + STDMETHODIMP_(ULONG) \ + AddRef(void) \ + { \ + return ++m_refs; \ + } \ + \ + STDMETHODIMP_(ULONG) \ + Release(void) \ + { \ + if (--m_refs == 0) { \ + delete this; \ + return 0; \ + } \ + return m_refs; \ + } \ +private: \ +ULONG m_refs{0}; \ +}; + +Q_DECLARE_DRAGHANDLER(Enter, drag_enter) +Q_DECLARE_DRAGHANDLER(Over, drag_over) +Q_DECLARE_DRAGHANDLER(Leave, drag_leave) +Q_DECLARE_DRAGHANDLER(Drop, drop) + +#define Q_INST_DRAGHANDLER(name) QtDragEventHandler##name() + +Q_GLOBAL_STATIC(QWinRTDrag, gDrag); + +QWinRTDrag::QWinRTDrag() + : QPlatformDrag() + , m_dragTarget(0) +{ + qCDebug(lcQpaMime) << __FUNCTION__; + m_enter = new Q_INST_DRAGHANDLER(Enter); + m_over = new Q_INST_DRAGHANDLER(Over); + m_leave = new Q_INST_DRAGHANDLER(Leave); + m_drop = new Q_INST_DRAGHANDLER(Drop); + m_mimeData = new QWinRTInternalMimeData; +} + +QWinRTDrag::~QWinRTDrag() +{ + qCDebug(lcQpaMime) << __FUNCTION__; + delete m_enter; + delete m_over; + delete m_leave; + delete m_drop; + delete m_mimeData; +} + +QWinRTDrag *QWinRTDrag::instance() +{ + return gDrag; +} + +Qt::DropAction QWinRTDrag::drag(QDrag *drag) +{ + qCDebug(lcQpaMime) << __FUNCTION__ << drag; + // ### TODO: Add dragging from Window + return Qt::IgnoreAction; +} + +void QWinRTDrag::setDropTarget(QWindow *target) +{ + qCDebug(lcQpaMime) << __FUNCTION__ << target; + m_dragTarget = target; +} + +QMimeData *QWinRTDrag::platformDropData() +{ + qCDebug(lcQpaMime) << __FUNCTION__; + return m_mimeData; +} + +void QWinRTDrag::setUiElement(ComPtr &element) +{ + qCDebug(lcQpaMime) << __FUNCTION__; + m_ui = element; + // We set the element to always accept drops and then evaluate during + // runtime + HRESULT hr = element->put_AllowDrop(TRUE); + EventRegistrationToken tok; + hr = element->add_DragEnter(m_enter, &tok); + RETURN_VOID_IF_FAILED("Failed to add DragEnter handler."); + hr = element->add_DragOver(m_over, &tok); + RETURN_VOID_IF_FAILED("Failed to add DragOver handler."); + hr = element->add_DragLeave(m_leave, &tok); + RETURN_VOID_IF_FAILED("Failed to add DragLeave handler."); + hr = element->add_Drop(m_drop, &tok); + RETURN_VOID_IF_FAILED("Failed to add Drop handler."); +} + +void QWinRTDrag::handleNativeDragEvent(IInspectable *sender, ABI::Windows::UI::Xaml::IDragEventArgs *e, bool drop) +{ + Q_UNUSED(sender); + + if (!m_dragTarget) + return; + + HRESULT hr; + Point relativePoint; + hr = e->GetPosition(m_ui.Get(), &relativePoint); + RETURN_VOID_IF_FAILED("Could not query drag position."); + const QPoint p(relativePoint.X, relativePoint.Y); + qDebug() << "Point received:" << relativePoint.X << "/" << relativePoint.Y; + + ComPtr e2; + hr = e->QueryInterface(IID_PPV_ARGS(&e2)); + RETURN_VOID_IF_FAILED("Could not convert drag event args"); + + DragDropModifiers modifiers; + hr = e2->get_Modifiers(&modifiers); + + ComPtr e3; + hr = e->QueryInterface(IID_PPV_ARGS(&e3)); + Q_ASSERT_SUCCEEDED(hr); + + DataPackageOperation dataOp; + hr = e3->get_AllowedOperations(&dataOp); + if (FAILED(hr)) + qCDebug(lcQpaMime) << __FUNCTION__ << "Could not query drag operations"; + + const Qt::DropActions actions = translateToQDragDropActions(dataOp); + + ComPtr dataView; + hr = e2->get_DataView(&dataView); + Q_ASSERT_SUCCEEDED(hr); + + m_mimeData->setDataView(dataView); + + // We use deferral as we need to jump to the Qt thread to handle + // the drag event + ComPtr deferral; + hr = e2->GetDeferral(&deferral); + Q_ASSERT_SUCCEEDED(hr); + + DragThreadTransferData *transferData = new DragThreadTransferData; + transferData->moveToThread(qGuiApp->thread()); + transferData->window = m_dragTarget; + transferData->point = p; + transferData->mime = m_mimeData; + transferData->actions = actions; + transferData->dropAction = drop; + transferData->nativeArgs = e; + transferData->deferral = deferral; + QMetaObject::invokeMethod(transferData, "handleDrag", Qt::QueuedConnection); +} + +DragThreadTransferData::DragThreadTransferData(QObject *parent) + : QObject(parent) + , dropAction(false) +{ +} + +void DragThreadTransferData::handleDrag() +{ + bool accepted = false; + Qt::DropAction acceptedAction; + if (dropAction) { + QPlatformDropQtResponse response = QWindowSystemInterface::handleDrop(window, mime, point, actions); + accepted = response.isAccepted(); + acceptedAction = response.acceptedAction(); + } else { + QPlatformDragQtResponse response = QWindowSystemInterface::handleDrag(window, mime, point, actions); + accepted = response.isAccepted(); + acceptedAction = response.acceptedAction(); + } + + HRESULT hr; + hr = QEventDispatcherWinRT::runOnXamlThread([accepted, acceptedAction, this]() { + HRESULT hr; + hr = nativeArgs->put_Handled(accepted); + if (acceptedAction != Qt::IgnoreAction) { + ComPtr e2; + hr = nativeArgs.As(&e2); + if (SUCCEEDED(hr)) + hr = e2->put_AcceptedOperation(translateFromQDragDropActions(acceptedAction)); + } + deferral->Complete(); + return S_OK; + }); + Q_ASSERT_SUCCEEDED(hr); + deleteLater(); +} + +QT_END_NAMESPACE + +#include "qwinrtdrag.moc" diff --git a/src/plugins/platforms/winrt/qwinrtdrag.h b/src/plugins/platforms/winrt/qwinrtdrag.h new file mode 100644 index 0000000000..97079d831b --- /dev/null +++ b/src/plugins/platforms/winrt/qwinrtdrag.h @@ -0,0 +1,113 @@ +/**************************************************************************** +** +** 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:LGPL3$ +** 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 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include + +#include +#include +#include // QInternalMime + +#include + +namespace ABI { + namespace Windows { + namespace ApplicationModel { + namespace DataTransfer { + struct IDataPackageView; + } + } + namespace UI { + namespace Xaml { + struct IUIElement; + struct IDragEventArgs; + struct IDragOperationDeferral; + //struct IDataPackageView; + } + } + } +} + +QT_BEGIN_NAMESPACE + +Q_DECLARE_LOGGING_CATEGORY(lcQpaMime) + +class QtDragEventHandlerEnter; +class QtDragEventHandlerOver; +class QtDragEventHandlerLeave; +class QtDragEventHandlerDrop; +class QWinRTInternalMimeData; + +class QWinRTInternalMimeData : public QInternalMimeData { +public: + QWinRTInternalMimeData(); + virtual ~QWinRTInternalMimeData(); + + bool hasFormat_sys(const QString &mimetype) const Q_DECL_OVERRIDE; + QStringList formats_sys() const Q_DECL_OVERRIDE; + QVariant retrieveData_sys(const QString &mimetype, QVariant::Type preferredType) const Q_DECL_OVERRIDE; + + void setDataView(const Microsoft::WRL::ComPtr &d); +private: + Microsoft::WRL::ComPtr dataView; + mutable QStringList formats; +}; + +class QWinRTDrag : public QPlatformDrag { +public: + QWinRTDrag(); + virtual ~QWinRTDrag(); + static QWinRTDrag *instance(); + + QMimeData *platformDropData(void) Q_DECL_OVERRIDE; + Qt::DropAction drag(QDrag *) Q_DECL_OVERRIDE; + + void setDropTarget(QWindow *target); + + // Native integration and registration + void setUiElement(Microsoft::WRL::ComPtr &element); + + void handleNativeDragEvent(IInspectable *sender, ABI::Windows::UI::Xaml::IDragEventArgs *e, bool drop = false); +private: + Microsoft::WRL::ComPtr m_ui; + QWindow *m_dragTarget; + QtDragEventHandlerEnter *m_enter; + QtDragEventHandlerOver *m_over; + QtDragEventHandlerLeave *m_leave; + QtDragEventHandlerDrop *m_drop; + QWinRTInternalMimeData *m_mimeData; +}; + +QT_END_NAMESPACE diff --git a/src/plugins/platforms/winrt/qwinrtintegration.cpp b/src/plugins/platforms/winrt/qwinrtintegration.cpp index 30c0e81e21..01e8a42b8e 100644 --- a/src/plugins/platforms/winrt/qwinrtintegration.cpp +++ b/src/plugins/platforms/winrt/qwinrtintegration.cpp @@ -45,6 +45,7 @@ #include "qwinrtfontdatabase.h" #include "qwinrttheme.h" #include "qwinrtclipboard.h" +#include "qwinrtdrag.h" #include #include @@ -309,6 +310,15 @@ QPlatformClipboard *QWinRTIntegration::clipboard() const return d->clipboard; } +QPlatformDrag *QWinRTIntegration::drag() const +{ +#if _MSC_VER >= 1900 + return QWinRTDrag::instance(); +#else + return QPlatformIntegration::drag(); +#endif +} + Qt::KeyboardModifiers QWinRTIntegration::queryKeyboardModifiers() const { Q_D(const QWinRTIntegration); diff --git a/src/plugins/platforms/winrt/qwinrtintegration.h b/src/plugins/platforms/winrt/qwinrtintegration.h index 1ed286ab2e..ffdfa55e49 100644 --- a/src/plugins/platforms/winrt/qwinrtintegration.h +++ b/src/plugins/platforms/winrt/qwinrtintegration.h @@ -94,6 +94,10 @@ public: QPlatformInputContext *inputContext() const Q_DECL_OVERRIDE; QPlatformServices *services() const Q_DECL_OVERRIDE; QPlatformClipboard *clipboard() const Q_DECL_OVERRIDE; +#ifndef QT_NO_DRAGANDDROP + QPlatformDrag *drag() const Q_DECL_OVERRIDE; +#endif + Qt::KeyboardModifiers queryKeyboardModifiers() const Q_DECL_OVERRIDE; QStringList themeNames() const Q_DECL_OVERRIDE; diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp index 0255527e91..3d9baf555d 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.cpp +++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp @@ -39,6 +39,7 @@ #include "qwinrtbackingstore.h" #include "qwinrtinputcontext.h" #include "qwinrtcursor.h" +#include "qwinrtdrag.h" #include "qwinrtwindow.h" #include @@ -553,6 +554,9 @@ QWinRTScreen::QWinRTScreen() ComPtr uiElement; hr = canvas.As(&uiElement); Q_ASSERT_SUCCEEDED(hr); +#if _MSC_VER >= 1900 + QWinRTDrag::instance()->setUiElement(uiElement); +#endif hr = window->put_Content(uiElement.Get()); Q_ASSERT_SUCCEEDED(hr); hr = canvas.As(&d->canvas); @@ -761,6 +765,10 @@ void QWinRTScreen::addWindow(QWindow *window) QWindowSystemInterface::handleWindowActivated(window, Qt::OtherFocusReason); handleExpose(); QWindowSystemInterface::flushWindowSystemEvents(); + +#if _MSC_VER >= 1900 + QWinRTDrag::instance()->setDropTarget(window); +#endif } void QWinRTScreen::removeWindow(QWindow *window) @@ -775,6 +783,10 @@ void QWinRTScreen::removeWindow(QWindow *window) QWindowSystemInterface::handleWindowActivated(window, Qt::OtherFocusReason); handleExpose(); QWindowSystemInterface::flushWindowSystemEvents(); +#if _MSC_VER >= 1900 + if (wasTopWindow) + QWinRTDrag::instance()->setDropTarget(topWindow()); +#endif } void QWinRTScreen::raise(QWindow *window) diff --git a/src/plugins/platforms/winrt/winrt.pro b/src/plugins/platforms/winrt/winrt.pro index 261295ef0b..5c62b5718b 100644 --- a/src/plugins/platforms/winrt/winrt.pro +++ b/src/plugins/platforms/winrt/winrt.pro @@ -14,6 +14,7 @@ SOURCES = \ qwinrtbackingstore.cpp \ qwinrtclipboard.cpp \ qwinrtcursor.cpp \ + qwinrtdrag.cpp \ qwinrteglcontext.cpp \ qwinrteventdispatcher.cpp \ qwinrtfiledialoghelper.cpp \ @@ -32,6 +33,7 @@ HEADERS = \ qwinrtbackingstore.h \ qwinrtclipboard.h \ qwinrtcursor.h \ + qwinrtdrag.h \ qwinrteglcontext.h \ qwinrteventdispatcher.h \ qwinrtfiledialoghelper.h \ @@ -47,6 +49,11 @@ HEADERS = \ OTHER_FILES += winrt.json +*-msvc2013 { + SOURCES -= qwinrtdrag.cpp + HEADERS -= qwinrtdrag.h +} + PLUGIN_TYPE = platforms PLUGIN_CLASS_NAME = QWinRTIntegrationPlugin !equals(TARGET, $$QT_DEFAULT_QPA_PLUGIN): PLUGIN_EXTENDS = - -- cgit v1.2.3 From 94f319a2bb191b24498a7575d3b9e186eb772d4d Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Thu, 26 May 2016 10:19:28 +0200 Subject: winrt: enable drag support Allow applications to initiate drag operations. Task-number: QTBUG-50827 Change-Id: I3c29b54756af1af24544f49803305f0c95d8b7f9 Reviewed-by: Oliver Wolff --- src/plugins/platforms/winrt/qwinrtdrag.cpp | 188 ++++++++++++++++++++++++++- src/plugins/platforms/winrt/qwinrtscreen.cpp | 4 + 2 files changed, 188 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/winrt/qwinrtdrag.cpp b/src/plugins/platforms/winrt/qwinrtdrag.cpp index a52ed91749..8ccb211e4f 100644 --- a/src/plugins/platforms/winrt/qwinrtdrag.cpp +++ b/src/plugins/platforms/winrt/qwinrtdrag.cpp @@ -88,6 +88,13 @@ inline QString hStringToQString(const HString &hString) return (QString::fromWCharArray(raw, l)); } +inline HString qStringToHString(const QString &qString) +{ + HString h; + h.Set(reinterpret_cast(qString.utf16()), qString.size()); + return h; +} + namespace NativeFormatStrings { static ComPtr dataStatics; static HSTRING text; // text/plain @@ -198,7 +205,6 @@ QStringList QWinRTInternalMimeData::formats_sys() const continue; formats.append(hStringToQString(str)); } - qDebug() << __FUNCTION__ << "Available formats:" << formats; return formats; } @@ -510,6 +516,8 @@ Q_DECLARE_DRAGHANDLER(Drop, drop) Q_GLOBAL_STATIC(QWinRTDrag, gDrag); +extern ComPtr qt_winrt_lastPointerPoint; // qwinrtscreen.cpp + QWinRTDrag::QWinRTDrag() : QPlatformDrag() , m_dragTarget(0) @@ -537,11 +545,184 @@ QWinRTDrag *QWinRTDrag::instance() return gDrag; } +inline HRESULT resetUiElementDrag(ComPtr &elem3, EventRegistrationToken startingToken) +{ + return QEventDispatcherWinRT::runOnXamlThread([elem3, startingToken]() { + HRESULT hr; + hr = elem3->put_CanDrag(false); + Q_ASSERT_SUCCEEDED(hr); + hr = elem3->remove_DragStarting(startingToken); + Q_ASSERT_SUCCEEDED(hr); + return S_OK; + }); +} + Qt::DropAction QWinRTDrag::drag(QDrag *drag) { qCDebug(lcQpaMime) << __FUNCTION__ << drag; - // ### TODO: Add dragging from Window - return Qt::IgnoreAction; + + if (!qt_winrt_lastPointerPoint) { + Q_ASSERT_X(qt_winrt_lastPointerPoint, Q_FUNC_INFO, "No pointerpoint known"); + return Qt::IgnoreAction; + } + + ComPtr elem3; + HRESULT hr = m_ui.As(&elem3); + Q_ASSERT_SUCCEEDED(hr); + + ComPtr> op; + EventRegistrationToken startingToken; + + hr = QEventDispatcherWinRT::runOnXamlThread([drag, &op, &hr, elem3, &startingToken, this]() { + + hr = elem3->put_CanDrag(true); + Q_ASSERT_SUCCEEDED(hr); + + auto startingCallback = Callback> ([drag](IInspectable *, IDragStartingEventArgs *args) { + qCDebug(lcQpaMime) << "Drag starting" << args; + + ComPtr dataPackage; + HRESULT hr; + hr = args->get_Data(dataPackage.GetAddressOf()); + Q_ASSERT_SUCCEEDED(hr); + Qt::DropAction action = drag->defaultAction(); + hr = dataPackage->put_RequestedOperation(translateFromQDragDropActions(action)); + Q_ASSERT_SUCCEEDED(hr); + + ComPtr args2; + hr = args->QueryInterface(IID_PPV_ARGS(&args2)); + Q_ASSERT_SUCCEEDED(hr); + + Qt::DropActions actions = drag->supportedActions(); + DataPackageOperation allowedOperations = DataPackageOperation_None; + if (actions & Qt::CopyAction) + allowedOperations |= DataPackageOperation_Copy; + if (actions & Qt::MoveAction) + allowedOperations |= DataPackageOperation_Move; + if (actions & Qt::LinkAction) + allowedOperations |= DataPackageOperation_Link; + hr = args2->put_AllowedOperations(allowedOperations); + Q_ASSERT_SUCCEEDED(hr); + + QMimeData *mimeData = drag->mimeData(); + if (mimeData->hasText()) { + hr = dataPackage->SetText(qStringToHString(mimeData->text()).Get()); + Q_ASSERT_SUCCEEDED(hr); + } + if (mimeData->hasHtml()) { + hr = dataPackage->SetHtmlFormat(qStringToHString(mimeData->html()).Get()); + Q_ASSERT_SUCCEEDED(hr); + } + // ### TODO: Missing: weblink, image + + const QStringList formats = mimeData->formats(); + for (auto item : formats) { + QByteArray data = mimeData->data(item); + + ComPtr bufferFactory; + hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_Streams_Buffer).Get(), + IID_PPV_ARGS(&bufferFactory)); + Q_ASSERT_SUCCEEDED(hr); + + ComPtr buffer; + const UINT32 length = data.size(); + hr = bufferFactory->Create(length, &buffer); + Q_ASSERT_SUCCEEDED(hr); + hr = buffer->put_Length(length); + Q_ASSERT_SUCCEEDED(hr); + + ComPtr byteArrayAccess; + hr = buffer.As(&byteArrayAccess); + Q_ASSERT_SUCCEEDED(hr); + + byte *bytes; + hr = byteArrayAccess->Buffer(&bytes); + Q_ASSERT_SUCCEEDED(hr); + memcpy(bytes, data.constData(), length); + + // We cannot push the buffer to the data package as the result on + // recipient side is different from native events. It still sends a + // buffer, but that potentially cannot be parsed. Hence we need to create + // a IRandomAccessStream which gets forwarded as is to the drop side. + ComPtr ras; + hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Storage_Streams_InMemoryRandomAccessStream).Get(), &ras); + Q_ASSERT_SUCCEEDED(hr); + + hr = ras->put_Size(length); + ComPtr outputStream; + hr = ras->GetOutputStreamAt(0, &outputStream); + Q_ASSERT_SUCCEEDED(hr); + + ComPtr> writeOp; + hr = outputStream->WriteAsync(buffer.Get(), &writeOp); + Q_ASSERT_SUCCEEDED(hr); + + UINT32 result; + hr = QWinRTFunctions::await(writeOp, &result); + Q_ASSERT_SUCCEEDED(hr); + + unsigned char flushResult; + ComPtr> flushOp; + hr = outputStream.Get()->FlushAsync(&flushOp); + Q_ASSERT_SUCCEEDED(hr); + + hr = QWinRTFunctions::await(flushOp, &flushResult); + Q_ASSERT_SUCCEEDED(hr); + + hr = dataPackage->SetData(qStringToHString(item).Get(), ras.Get()); + Q_ASSERT_SUCCEEDED(hr); + + } + return S_OK; + }); + + hr = elem3->add_DragStarting(startingCallback.Get(), &startingToken); + Q_ASSERT_SUCCEEDED(hr); + + ComPtr pointStatics; + + hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_Input_PointerPoint).Get(), + IID_PPV_ARGS(&pointStatics)); + Q_ASSERT_SUCCEEDED(hr); + + hr = elem3->StartDragAsync(qt_winrt_lastPointerPoint.Get(), &op); + Q_ASSERT_SUCCEEDED(hr); + + return hr; + }); + if (!op || FAILED(hr)) { + qCDebug(lcQpaMime) << "Drag failed:" << hr; + hr = resetUiElementDrag(elem3, startingToken); + Q_ASSERT_SUCCEEDED(hr); + return Qt::IgnoreAction; + } + + DataPackageOperation nativeOperationType; + // Do not yield, as that can cause deadlocks when dropping inside the same app + hr = QWinRTFunctions::await(op, &nativeOperationType, QWinRTFunctions::ProcessThreadEvents); + Q_ASSERT_SUCCEEDED(hr); + + hr = resetUiElementDrag(elem3, startingToken); + Q_ASSERT_SUCCEEDED(hr); + + Qt::DropAction resultAction; + switch (nativeOperationType) { + case DataPackageOperation_Link: + resultAction = Qt::LinkAction; + break; + case DataPackageOperation_Copy: + resultAction = Qt::CopyAction; + break; + case DataPackageOperation_Move: + resultAction = Qt::MoveAction; + break; + case DataPackageOperation_None: + default: + resultAction = Qt::IgnoreAction; + break; + } + + return resultAction; } void QWinRTDrag::setDropTarget(QWindow *target) @@ -586,7 +767,6 @@ void QWinRTDrag::handleNativeDragEvent(IInspectable *sender, ABI::Windows::UI::X hr = e->GetPosition(m_ui.Get(), &relativePoint); RETURN_VOID_IF_FAILED("Could not query drag position."); const QPoint p(relativePoint.X, relativePoint.Y); - qDebug() << "Point received:" << relativePoint.X << "/" << relativePoint.Y; ComPtr e2; hr = e->QueryInterface(IID_PPV_ARGS(&e2)); diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp index 3d9baf555d..43847e1ecc 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.cpp +++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp @@ -982,6 +982,9 @@ HRESULT QWinRTScreen::onPointerExited(ICoreWindow *, IPointerEventArgs *args) return S_OK; } +// Required for qwinrtdrag.cpp +ComPtr qt_winrt_lastPointerPoint; + HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args) { Q_D(QWinRTScreen); @@ -989,6 +992,7 @@ HRESULT QWinRTScreen::onPointerUpdated(ICoreWindow *, IPointerEventArgs *args) if (FAILED(args->get_CurrentPoint(&pointerPoint))) return E_INVALIDARG; + qt_winrt_lastPointerPoint = pointerPoint; // Common traits - point, modifiers, properties Point point; pointerPoint->get_Position(&point); -- cgit v1.2.3 From e8ff3c8cbc8a66c344e2c974ae92f2cea7a2e5fe Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Fri, 27 May 2016 13:13:40 +0200 Subject: winrt: fix drag pixmap support Previously dragging only displayed the type of operation provided by the system. Now, in case a pixmap is specified, an image is shown. Also incorporated some cleanups. Task-number: QTBUG-50827 Change-Id: I471e2081eabfed014b08d189538d1d62cdb7248e Reviewed-by: Oliver Wolff --- src/plugins/platforms/winrt/qwinrtdrag.cpp | 156 ++++++++++++++++++----------- 1 file changed, 96 insertions(+), 60 deletions(-) diff --git a/src/plugins/platforms/winrt/qwinrtdrag.cpp b/src/plugins/platforms/winrt/qwinrtdrag.cpp index 8ccb211e4f..14bea7ab30 100644 --- a/src/plugins/platforms/winrt/qwinrtdrag.cpp +++ b/src/plugins/platforms/winrt/qwinrtdrag.cpp @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -55,6 +56,7 @@ using namespace ABI::Windows::ApplicationModel::DataTransfer; using namespace ABI::Windows::ApplicationModel::DataTransfer::DragDrop; using namespace ABI::Windows::Foundation; using namespace ABI::Windows::Foundation::Collections; +using namespace ABI::Windows::Graphics::Imaging; using namespace ABI::Windows::Storage; using namespace ABI::Windows::Storage::Streams; using namespace ABI::Windows::UI::Xaml; @@ -65,6 +67,34 @@ QT_BEGIN_NAMESPACE Q_LOGGING_CATEGORY(lcQpaMime, "qt.qpa.mime") +ComPtr createIBufferFromData(const char *data, qint32 size) +{ + static ComPtr bufferFactory; + HRESULT hr; + if (!bufferFactory) { + hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_Streams_Buffer).Get(), + IID_PPV_ARGS(&bufferFactory)); + Q_ASSERT_SUCCEEDED(hr); + } + + ComPtr buffer; + const UINT32 length = size; + hr = bufferFactory->Create(length, &buffer); + Q_ASSERT_SUCCEEDED(hr); + hr = buffer->put_Length(length); + Q_ASSERT_SUCCEEDED(hr); + + ComPtr byteArrayAccess; + hr = buffer.As(&byteArrayAccess); + Q_ASSERT_SUCCEEDED(hr); + + byte *bytes; + hr = byteArrayAccess->Buffer(&bytes); + Q_ASSERT_SUCCEEDED(hr); + memcpy(bytes, data, length); + return buffer; +} + class DragThreadTransferData : public QObject { Q_OBJECT @@ -175,36 +205,42 @@ QStringList QWinRTInternalMimeData::formats_sys() const if (!formats.isEmpty()) return formats; - boolean contains; HRESULT hr; - hr = dataView->Contains(NativeFormatStrings::text, &contains); - if (SUCCEEDED(hr) && contains) - formats.append(QLatin1String("text/plain")); - - hr = dataView->Contains(NativeFormatStrings::html, &contains); - if (SUCCEEDED(hr) && contains) - formats.append(QLatin1String("text/html")); - - hr = dataView->Contains(NativeFormatStrings::storage, &contains); - if (SUCCEEDED(hr) && contains) - formats.append(QLatin1String("text/uri-list")); - - // We need to add any additional format as well, for legacy windows - // reasons, but also in case someone adds custom formats. - ComPtr> availableFormats; - hr = dataView->get_AvailableFormats(&availableFormats); - RETURN_IF_FAILED("Could not query available formats.", return formats); - - quint32 size; - hr = availableFormats->get_Size(&size); - RETURN_IF_FAILED("Could not query format vector size.", return formats); - for (quint32 i = 0; i < size; ++i) { - HString str; - hr = availableFormats->GetAt(i, str.GetAddressOf()); - if (FAILED(hr)) - continue; - formats.append(hStringToQString(str)); - } + hr = QEventDispatcherWinRT::runOnXamlThread([this]() { + boolean contains; + HRESULT hr; + hr = dataView->Contains(NativeFormatStrings::text, &contains); + if (SUCCEEDED(hr) && contains) + formats.append(QLatin1String("text/plain")); + + hr = dataView->Contains(NativeFormatStrings::html, &contains); + if (SUCCEEDED(hr) && contains) + formats.append(QLatin1String("text/html")); + + hr = dataView->Contains(NativeFormatStrings::storage, &contains); + if (SUCCEEDED(hr) && contains) + formats.append(QLatin1String("text/uri-list")); + + // We need to add any additional format as well, for legacy windows + // reasons, but also in case someone adds custom formats. + ComPtr> availableFormats; + hr = dataView->get_AvailableFormats(&availableFormats); + RETURN_OK_IF_FAILED("Could not query available formats."); + + quint32 size; + hr = availableFormats->get_Size(&size); + RETURN_OK_IF_FAILED("Could not query format vector size."); + for (quint32 i = 0; i < size; ++i) { + HString str; + hr = availableFormats->GetAt(i, str.GetAddressOf()); + if (FAILED(hr)) + continue; + formats.append(hStringToQString(str)); + } + return S_OK; + }); + Q_ASSERT_SUCCEEDED(hr); + return formats; } @@ -265,8 +301,6 @@ QVariant QWinRTInternalMimeData::retrieveData_sys(const QString &mimetype, QVari result.setValue(hStringToQString(res)); return S_OK; }); - } else if (mimetype.startsWith(QLatin1String("image/"))) { - Q_UNIMPLEMENTED(); } else { // Asking for custom data hr = QEventDispatcherWinRT::runOnXamlThread([this, &result, mimetype]() { @@ -615,30 +649,39 @@ Qt::DropAction QWinRTDrag::drag(QDrag *drag) } // ### TODO: Missing: weblink, image - const QStringList formats = mimeData->formats(); - for (auto item : formats) { - QByteArray data = mimeData->data(item); + if (!drag->pixmap().isNull()) { + const QImage image2 = drag->pixmap().toImage(); + const QImage image = image2.convertToFormat(QImage::Format_ARGB32); + if (!image.isNull()) { + // Create IBuffer containing image + ComPtr imageBuffer = createIBufferFromData(reinterpret_cast(image.bits()), image.byteCount()); - ComPtr bufferFactory; - hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_Streams_Buffer).Get(), - IID_PPV_ARGS(&bufferFactory)); - Q_ASSERT_SUCCEEDED(hr); + ComPtr bitmapFactory; + hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Graphics_Imaging_SoftwareBitmap).Get(), + IID_PPV_ARGS(&bitmapFactory)); + Q_ASSERT_SUCCEEDED(hr); - ComPtr buffer; - const UINT32 length = data.size(); - hr = bufferFactory->Create(length, &buffer); - Q_ASSERT_SUCCEEDED(hr); - hr = buffer->put_Length(length); - Q_ASSERT_SUCCEEDED(hr); + ComPtr bitmap; + hr = bitmapFactory->Create(BitmapPixelFormat_Rgba8, image.width(), image.height(), &bitmap); + Q_ASSERT_SUCCEEDED(hr); - ComPtr byteArrayAccess; - hr = buffer.As(&byteArrayAccess); - Q_ASSERT_SUCCEEDED(hr); + hr = bitmap->CopyFromBuffer(imageBuffer.Get()); + Q_ASSERT_SUCCEEDED(hr); - byte *bytes; - hr = byteArrayAccess->Buffer(&bytes); - Q_ASSERT_SUCCEEDED(hr); - memcpy(bytes, data.constData(), length); + ComPtr dragUi; + hr = args->get_DragUI(dragUi.GetAddressOf()); + Q_ASSERT_SUCCEEDED(hr); + + hr = dragUi->SetContentFromSoftwareBitmap(bitmap.Get()); + Q_ASSERT_SUCCEEDED(hr); + } + } + + const QStringList formats = mimeData->formats(); + for (auto item : formats) { + QByteArray data = mimeData->data(item); + + ComPtr buffer = createIBufferFromData(data.constData(), data.size()); // We cannot push the buffer to the data package as the result on // recipient side is different from native events. It still sends a @@ -648,7 +691,7 @@ Qt::DropAction QWinRTDrag::drag(QDrag *drag) hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Storage_Streams_InMemoryRandomAccessStream).Get(), &ras); Q_ASSERT_SUCCEEDED(hr); - hr = ras->put_Size(length); + hr = ras->put_Size(data.size()); ComPtr outputStream; hr = ras->GetOutputStreamAt(0, &outputStream); Q_ASSERT_SUCCEEDED(hr); @@ -663,7 +706,7 @@ Qt::DropAction QWinRTDrag::drag(QDrag *drag) unsigned char flushResult; ComPtr> flushOp; - hr = outputStream.Get()->FlushAsync(&flushOp); + hr = outputStream->FlushAsync(&flushOp); Q_ASSERT_SUCCEEDED(hr); hr = QWinRTFunctions::await(flushOp, &flushResult); @@ -671,7 +714,6 @@ Qt::DropAction QWinRTDrag::drag(QDrag *drag) hr = dataPackage->SetData(qStringToHString(item).Get(), ras.Get()); Q_ASSERT_SUCCEEDED(hr); - } return S_OK; }); @@ -679,12 +721,6 @@ Qt::DropAction QWinRTDrag::drag(QDrag *drag) hr = elem3->add_DragStarting(startingCallback.Get(), &startingToken); Q_ASSERT_SUCCEEDED(hr); - ComPtr pointStatics; - - hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_UI_Input_PointerPoint).Get(), - IID_PPV_ARGS(&pointStatics)); - Q_ASSERT_SUCCEEDED(hr); - hr = elem3->StartDragAsync(qt_winrt_lastPointerPoint.Get(), &op); Q_ASSERT_SUCCEEDED(hr); -- cgit v1.2.3 From bb30da895eca5a80265317db1fc7a0d151005e30 Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Tue, 31 May 2016 13:46:51 +0200 Subject: winrt: fix compilation without drag and drop support Change-Id: Ifd0d2238e8dacffe34753d95e12cccfd13519c55 Reviewed-by: Oliver Wolff --- src/plugins/platforms/winrt/qwinrtintegration.cpp | 4 ++++ src/plugins/platforms/winrt/qwinrtscreen.cpp | 8 +++++--- src/plugins/platforms/winrt/winrt.pro | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/plugins/platforms/winrt/qwinrtintegration.cpp b/src/plugins/platforms/winrt/qwinrtintegration.cpp index 01e8a42b8e..8c419dcdbc 100644 --- a/src/plugins/platforms/winrt/qwinrtintegration.cpp +++ b/src/plugins/platforms/winrt/qwinrtintegration.cpp @@ -45,7 +45,9 @@ #include "qwinrtfontdatabase.h" #include "qwinrttheme.h" #include "qwinrtclipboard.h" +#ifndef QT_NO_DRAGANDDROP #include "qwinrtdrag.h" +#endif #include #include @@ -310,6 +312,7 @@ QPlatformClipboard *QWinRTIntegration::clipboard() const return d->clipboard; } +#ifndef QT_NO_DRAGANDDROP QPlatformDrag *QWinRTIntegration::drag() const { #if _MSC_VER >= 1900 @@ -318,6 +321,7 @@ QPlatformDrag *QWinRTIntegration::drag() const return QPlatformIntegration::drag(); #endif } +#endif // QT_NO_DRAGANDDROP Qt::KeyboardModifiers QWinRTIntegration::queryKeyboardModifiers() const { diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp index 43847e1ecc..c1118cd0b8 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.cpp +++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp @@ -39,7 +39,9 @@ #include "qwinrtbackingstore.h" #include "qwinrtinputcontext.h" #include "qwinrtcursor.h" +#ifndef QT_NO_DRAGANDDROP #include "qwinrtdrag.h" +#endif #include "qwinrtwindow.h" #include @@ -554,7 +556,7 @@ QWinRTScreen::QWinRTScreen() ComPtr uiElement; hr = canvas.As(&uiElement); Q_ASSERT_SUCCEEDED(hr); -#if _MSC_VER >= 1900 +#if _MSC_VER >= 1900 && !defined(QT_NO_DRAGANDDROP) QWinRTDrag::instance()->setUiElement(uiElement); #endif hr = window->put_Content(uiElement.Get()); @@ -766,7 +768,7 @@ void QWinRTScreen::addWindow(QWindow *window) handleExpose(); QWindowSystemInterface::flushWindowSystemEvents(); -#if _MSC_VER >= 1900 +#if _MSC_VER >= 1900 && !defined(QT_NO_DRAGANDDROP) QWinRTDrag::instance()->setDropTarget(window); #endif } @@ -783,7 +785,7 @@ void QWinRTScreen::removeWindow(QWindow *window) QWindowSystemInterface::handleWindowActivated(window, Qt::OtherFocusReason); handleExpose(); QWindowSystemInterface::flushWindowSystemEvents(); -#if _MSC_VER >= 1900 +#if _MSC_VER >= 1900 && !defined(QT_NO_DRAGANDDROP) if (wasTopWindow) QWinRTDrag::instance()->setDropTarget(topWindow()); #endif diff --git a/src/plugins/platforms/winrt/winrt.pro b/src/plugins/platforms/winrt/winrt.pro index 5c62b5718b..dd1e051c33 100644 --- a/src/plugins/platforms/winrt/winrt.pro +++ b/src/plugins/platforms/winrt/winrt.pro @@ -49,7 +49,7 @@ HEADERS = \ OTHER_FILES += winrt.json -*-msvc2013 { +*-msvc2013|contains(DEFINES, QT_NO_DRAGANDDROP) { SOURCES -= qwinrtdrag.cpp HEADERS -= qwinrtdrag.h } -- cgit v1.2.3 From a160bd4fccaebafb5453a642f43bdefafc1e2565 Mon Sep 17 00:00:00 2001 From: Jake Petroules Date: Thu, 5 May 2016 02:17:56 -0700 Subject: Fix bugs causing Thin font weights to be ignored or mishandled. Task-number: QTBUG-53196 Change-Id: If12b3cab3d8de5e0e452fca844b0a484c29e9e86 Reviewed-by: Allan Sandfeld Jensen --- src/gui/text/qfontdatabase.cpp | 3 +-- src/gui/text/qfontengine.cpp | 3 +-- src/gui/text/qtextformat.cpp | 7 ++++--- src/gui/text/qtextformat.h | 4 ++-- src/plugins/platforms/windows/qwindowsfontengine.cpp | 6 ++---- tests/auto/gui/text/qfontcache/tst_qfontcache.cpp | 2 -- 6 files changed, 10 insertions(+), 15 deletions(-) diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp index 928d1e4eb5..c4b849878c 100644 --- a/src/gui/text/qfontdatabase.cpp +++ b/src/gui/text/qfontdatabase.cpp @@ -2730,8 +2730,7 @@ void QFontDatabase::load(const QFontPrivate *d, int script) } if (req.pointSize < 0) req.pointSize = req.pixelSize*72.0/d->dpi; - if (req.weight == 0) - req.weight = QFont::Normal; + req.weight = QFont::Normal; if (req.stretch == 0) req.stretch = 100; diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 39348a52b0..5e8aac82b8 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -1840,8 +1840,7 @@ QFontEngine *QFontEngineMulti::loadEngine(int at) request.family = fallbackFamilyAt(at - 1); if (QFontEngine *engine = QFontDatabase::findFont(request, m_script)) { - if (request.weight > QFont::Normal) - engine->fontDef.weight = request.weight; + engine->fontDef.weight = request.weight; if (request.style > QFont::StyleNormal) engine->fontDef.style = request.style; return engine; diff --git a/src/gui/text/qtextformat.cpp b/src/gui/text/qtextformat.cpp index 7dcd060ba1..4b31b49df2 100644 --- a/src/gui/text/qtextformat.cpp +++ b/src/gui/text/qtextformat.cpp @@ -357,9 +357,10 @@ void QTextFormatPrivate::recalcFont() const f.setPixelSize(props.at(i).value.toInt()); break; case QTextFormat::FontWeight: { - int weight = props.at(i).value.toInt(); - if (weight == 0) weight = QFont::Normal; - f.setWeight(weight); + const QVariant weightValue = props.at(i).value; + int weight = weightValue.toInt(); + if (weight >= 0 && weightValue.isValid()) + f.setWeight(weight); break; } case QTextFormat::FontItalic: f.setItalic(props.at(i).value.toBool()); diff --git a/src/gui/text/qtextformat.h b/src/gui/text/qtextformat.h index 6c1b75aa35..dbc50f70f9 100644 --- a/src/gui/text/qtextformat.h +++ b/src/gui/text/qtextformat.h @@ -424,9 +424,9 @@ public: { return doubleProperty(FontPointSize); } inline void setFontWeight(int weight) - { if (weight == QFont::Normal) weight = 0; setProperty(FontWeight, weight); } + { setProperty(FontWeight, weight); } inline int fontWeight() const - { int weight = intProperty(FontWeight); if (weight == 0) weight = QFont::Normal; return weight; } + { return hasProperty(FontWeight) ? intProperty(FontWeight) : QFont::Normal; } inline void setFontItalic(bool italic) { setProperty(FontItalic, italic); } inline bool fontItalic() const diff --git a/src/plugins/platforms/windows/qwindowsfontengine.cpp b/src/plugins/platforms/windows/qwindowsfontengine.cpp index 660c138097..3ac7e6c9ec 100644 --- a/src/plugins/platforms/windows/qwindowsfontengine.cpp +++ b/src/plugins/platforms/windows/qwindowsfontengine.cpp @@ -1342,8 +1342,7 @@ QFontEngine *QWindowsMultiFontEngine::loadEngine(int at) QWindowsFontEngineDirectWrite *fedw = new QWindowsFontEngineDirectWrite(directWriteFontFace, fontEngine->fontDef.pixelSize, data); - if (fontEngine->fontDef.weight > QFont::Normal) - fedw->fontDef.weight = fontEngine->fontDef.weight; + fedw->fontDef.weight = fontEngine->fontDef.weight; if (fontEngine->fontDef.style > QFont::StyleNormal) fedw->fontDef.style = fontEngine->fontDef.style; fedw->fontDef.family = fam; @@ -1360,8 +1359,7 @@ QFontEngine *QWindowsMultiFontEngine::loadEngine(int at) // reason QFontEngine *fe = new QWindowsFontEngine(fam, lf, data); - if (fontEngine->fontDef.weight > QFont::Normal) - fe->fontDef.weight = fontEngine->fontDef.weight; + fe->fontDef.weight = fontEngine->fontDef.weight; if (fontEngine->fontDef.style > QFont::StyleNormal) fe->fontDef.style = fontEngine->fontDef.style; fe->fontDef.family = fam; diff --git a/tests/auto/gui/text/qfontcache/tst_qfontcache.cpp b/tests/auto/gui/text/qfontcache/tst_qfontcache.cpp index 4d5ddfd523..a0bb1ebef9 100644 --- a/tests/auto/gui/text/qfontcache/tst_qfontcache.cpp +++ b/tests/auto/gui/text/qfontcache/tst_qfontcache.cpp @@ -106,8 +106,6 @@ void tst_QFontCache::engineData() } if (req.pointSize < 0) req.pointSize = req.pixelSize*72.0/d->dpi; - if (req.weight == 0) - req.weight = QFont::Normal; if (req.stretch == 0) req.stretch = 100; -- cgit v1.2.3 From 7cbafa8de7bc516f089503d12cab397e7965b8a5 Mon Sep 17 00:00:00 2001 From: Jake Petroules Date: Fri, 27 May 2016 23:47:49 -0700 Subject: Call a function in the MySQL configure test to make sure it links. This fixes a problem where the configure test may produce a false positive on iOS if a copy of libmysql for OS X is located, due to the fact that linking to a dynamic library of a different architecture than expected is not (yet) an error. Change-Id: Id41765f49e31d9c9c3becc3436ff5a69b160b8e0 Reviewed-by: Oswald Buddenhagen --- config.tests/unix/mysql/mysql.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/config.tests/unix/mysql/mysql.cpp b/config.tests/unix/mysql/mysql.cpp index 9cc2db03d9..3d51c612da 100644 --- a/config.tests/unix/mysql/mysql.cpp +++ b/config.tests/unix/mysql/mysql.cpp @@ -35,5 +35,6 @@ int main(int, char **) { + mysql_get_client_version(); return 0; } -- cgit v1.2.3 From 0b401d74e6ee40d87755a781b199c5ea6ad3e566 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Tue, 1 Sep 2015 15:52:39 +0200 Subject: Platformsupport: Don't include dbus on darwin. This created a false dependency from the cocoa platform plugin to QtDBus, which caused macdeployqt to deploy it. This change is for libplatformsupport only, and has no effect on QtDBus usage in general. Change-Id: I35f342574a6497ff88a785e93eef1acdea8b1452 Task-number: QTBUG-48015 Reviewed-by: Jake Petroules --- src/platformsupport/platformsupport.pro | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/platformsupport/platformsupport.pro b/src/platformsupport/platformsupport.pro index 1ea6d0eb69..c5894c4f98 100644 --- a/src/platformsupport/platformsupport.pro +++ b/src/platformsupport/platformsupport.pro @@ -21,7 +21,11 @@ include(accessibility/accessibility.pri) include(linuxaccessibility/linuxaccessibility.pri) include(clipboard/clipboard.pri) include(platformcompositor/platformcompositor.pri) -contains(QT_CONFIG, dbus) { + +# dbus convenience, but not for darwin: the platform +# plugins for these platforms do not use dbus and we +# don't want to create a false dependency. +!darwin: contains(QT_CONFIG, dbus) { include(dbusmenu/dbusmenu.pri) include(dbustray/dbustray.pri) } -- cgit v1.2.3 From 58408ffa1b9c0b42a1719d3c8a4d4c62dec4fce6 Mon Sep 17 00:00:00 2001 From: Andy Nichols Date: Tue, 31 May 2016 14:46:17 +0200 Subject: Add install target to mac widget examples Change-Id: I524ba3fcc82a6ef015241d90f212059ae7772443 Reviewed-by: Jake Petroules Reviewed-by: Timur Pocheptsov Reviewed-by: Oswald Buddenhagen --- .../widgets/mac/qmaccocoaviewcontainer/qmaccocoaviewcontainer.pro | 3 +++ examples/widgets/mac/qmacnativewidget/qmacnativewidget.pro | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/examples/widgets/mac/qmaccocoaviewcontainer/qmaccocoaviewcontainer.pro b/examples/widgets/mac/qmaccocoaviewcontainer/qmaccocoaviewcontainer.pro index c8c2195cb8..183e307877 100644 --- a/examples/widgets/mac/qmaccocoaviewcontainer/qmaccocoaviewcontainer.pro +++ b/examples/widgets/mac/qmaccocoaviewcontainer/qmaccocoaviewcontainer.pro @@ -5,3 +5,6 @@ LIBS += -framework Cocoa QT += widgets +# install +target.path = $$[QT_INSTALL_EXAMPLES]/widgets/mac/qmaccocoaviewcontainer +INSTALLS += target diff --git a/examples/widgets/mac/qmacnativewidget/qmacnativewidget.pro b/examples/widgets/mac/qmacnativewidget/qmacnativewidget.pro index cafff9f035..b39792e6dd 100644 --- a/examples/widgets/mac/qmacnativewidget/qmacnativewidget.pro +++ b/examples/widgets/mac/qmacnativewidget/qmacnativewidget.pro @@ -5,3 +5,7 @@ LIBS += -framework Cocoa QT += widgets #QT += widgets-private gui-private core-private + +# install +target.path = $$[QT_INSTALL_EXAMPLES]/widgets/mac/qmacnativewidget +INSTALLS += target -- cgit v1.2.3 From 8fb29ed259393a83e8fb5545c419543a85fc7bc9 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Tue, 31 May 2016 10:56:25 +0200 Subject: Don't alter input string in QTextLayout with ShowLineAndParagraphSeparators When ShowLineAndParagraphSeparators was set, we would replace the separator character in the user's string in some cases, since we never detached from the input string and just const_cast the pointer to the shared buffer. [ChangeLog][QtGui][Text] Fixed bug where a QTextLayout with ShowLineAndParagraphSeparators would modify the layout's input string. Task-number: QTBUG-42033 Change-Id: I92f9100b750f16e52b38b718245c13e5c4a0ebb9 Reviewed-by: Lars Knoll Reviewed-by: Konstantin Ritt --- src/gui/text/qtextengine.cpp | 8 +++++- .../auto/gui/text/qtextlayout/tst_qtextlayout.cpp | 33 ++++++++++++++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index d0c2779a65..17a91f5a6a 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1635,8 +1635,14 @@ void QTextEngine::itemize() const if (analysis->bidiLevel % 2) --analysis->bidiLevel; analysis->flags = QScriptAnalysis::LineOrParagraphSeparator; - if (option.flags() & QTextOption::ShowLineAndParagraphSeparators) + if (option.flags() & QTextOption::ShowLineAndParagraphSeparators) { + const int offset = uc - string; + layoutData->string.detach(); + string = reinterpret_cast(layoutData->string.unicode()); + uc = string + offset; + e = uc + length; *const_cast(uc) = 0x21B5; // visual line separator + } break; case QChar::Tabulation: analysis->flags = QScriptAnalysis::Tab; diff --git a/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp b/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp index de0c2d6dbe..e778232461 100644 --- a/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp +++ b/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp @@ -142,6 +142,7 @@ private slots: void xToCursorForLigatures(); void cursorInNonStopChars(); void nbsp(); + void noModificationOfInputString(); private: QFont testFont; @@ -2176,5 +2177,37 @@ void tst_QTextLayout::layoutWithCustomTabStops() QVERIFY(longWidth > shortWidth); } +void tst_QTextLayout::noModificationOfInputString() +{ + QString s = QString(QChar(QChar::LineSeparator)); + { + QTextLayout layout; + layout.setText(s); + + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + QCOMPARE(s.size(), 1); + QCOMPARE(s.at(0), QChar(QChar::LineSeparator)); + } + + { + QTextLayout layout; + layout.setText(s); + + QTextOption option; + option.setFlags(QTextOption::ShowLineAndParagraphSeparators); + layout.setTextOption(option); + + layout.beginLayout(); + layout.createLine(); + layout.endLayout(); + + QCOMPARE(s.size(), 1); + QCOMPARE(s.at(0), QChar(QChar::LineSeparator)); + } +} + QTEST_MAIN(tst_QTextLayout) #include "tst_qtextlayout.moc" -- cgit v1.2.3 From 3432742caa5171ceddee0e75adefda9310c3b1eb Mon Sep 17 00:00:00 2001 From: Ralf Nolden Date: Mon, 23 May 2016 22:00:05 +0200 Subject: Merge BSD implementations of QLockFilePrivate::processNameByPid() Until now, several solutions for the implementations of processNameByPid() on BSD systems existed: - one for FreeBSD using libutil through kinfo_getproc() using sysctl() implicitly - one for GNU/kFreeBSD using sysctl() explicitly added in commit a8f4fa217daa1b6f7b13cc48c1e5ee8d2d76b008 OpenBSD and NetBSD also had different approaches in their ports patches using kvm() and sysctl(). The code unifies this for all BSDs using sysctl(). Change-Id: Iced9ef01e5966d8688f464f51024a7ed562e26a3 Reviewed-by: Thiago Macieira Reviewed-by: Dmitry Shachnev --- src/corelib/io/io.pri | 1 - src/corelib/io/qlockfile_unix.cpp | 43 ++++++++++++++++++++------------------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/src/corelib/io/io.pri b/src/corelib/io/io.pri index 8d9908cd90..553c996458 100644 --- a/src/corelib/io/io.pri +++ b/src/corelib/io/io.pri @@ -147,7 +147,6 @@ win32 { SOURCES += io/qsettings_mac.cpp OBJECTIVE_SOURCES += io/qurl_mac.mm } - freebsd: LIBS_PRIVATE += -lutil # qlockfile_unix.cpp requires this mac { osx { OBJECTIVE_SOURCES += io/qfilesystemwatcher_fsevents.mm diff --git a/src/corelib/io/qlockfile_unix.cpp b/src/corelib/io/qlockfile_unix.cpp index f23a232fb8..eed3158fbe 100644 --- a/src/corelib/io/qlockfile_unix.cpp +++ b/src/corelib/io/qlockfile_unix.cpp @@ -59,14 +59,12 @@ # include # include #elif defined(Q_OS_BSD4) && !defined(Q_OS_IOS) +# if !defined(Q_OS_NETBSD) # include -# if defined(__GLIBC__) && defined(__FreeBSD_kernel__) +# endif # include # include # include -# else -# include -# endif #endif QT_BEGIN_NAMESPACE @@ -269,30 +267,33 @@ QString QLockFilePrivate::processNameByPid(qint64 pid) buf[len] = 0; return QFileInfo(QFile::decodeName(buf)).fileName(); #elif defined(Q_OS_BSD4) && !defined(Q_OS_IOS) -# if defined(__GLIBC__) && defined(__FreeBSD_kernel__) - int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, pid }; - size_t len = 0; - if (sysctl(mib, 4, NULL, &len, NULL, 0) < 0) - return QString(); - kinfo_proc *proc = static_cast(malloc(len)); +# if defined(Q_OS_NETBSD) + struct kinfo_proc2 kp; + int mib[6] = { CTL_KERN, KERN_PROC2, KERN_PROC_PID, (int)pid, sizeof(struct kinfo_proc2), 1 }; +# elif defined(Q_OS_OPENBSD) + struct kinfo_proc kp; + int mib[6] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, (int)pid, sizeof(struct kinfo_proc), 1 }; # else - kinfo_proc *proc = kinfo_getproc(pid); + struct kinfo_proc kp; + int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, (int)pid }; # endif - if (!proc) + size_t len = sizeof(kp); + u_int mib_len = sizeof(mib)/sizeof(u_int); + + if (sysctl(mib, mib_len, &kp, &len, NULL, 0) < 0) return QString(); -# if defined(__GLIBC__) && defined(__FreeBSD_kernel__) - if (sysctl(mib, 4, proc, &len, NULL, 0) < 0) { - free(proc); + +# if defined(Q_OS_OPENBSD) || defined(Q_OS_NETBSD) + if (kp.p_pid != pid) return QString(); - } - if (proc->ki_pid != pid) { - free(proc); + QString name = QFile::decodeName(kp.p_comm); +# else + if (kp.ki_pid != pid) return QString(); - } + QString name = QFile::decodeName(kp.ki_comm); # endif - QString name = QFile::decodeName(proc->ki_comm); - free(proc); return name; + #else Q_UNUSED(pid); return QString(); -- cgit v1.2.3 From d96057328aae28a27a46492a310d9a05e250631c Mon Sep 17 00:00:00 2001 From: Ralf Nolden Date: Tue, 31 May 2016 06:13:50 +0200 Subject: Compile fix: add OpenBSD define for ffsll usage On OpenBSD, ffsll needs to be defined to compile. This is the same change as in commit 725a9c27021bef1ac3828a4eafc013a2f50e6f22 for NetBSD. Change-Id: I3060caa10950a9419084a12de8c88a2f98b34d07 Reviewed-by: Thiago Macieira --- src/corelib/tools/qsimd.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/corelib/tools/qsimd.cpp b/src/corelib/tools/qsimd.cpp index 0e3359ab81..ac28832c31 100644 --- a/src/corelib/tools/qsimd.cpp +++ b/src/corelib/tools/qsimd.cpp @@ -636,7 +636,7 @@ int ffsll(quint64 i) #endif } #endif -#elif defined(Q_OS_NETBSD) || defined(Q_OS_ANDROID) || defined(Q_OS_QNX) || defined(Q_OS_OSX) || defined(Q_OS_HAIKU) +#elif defined(Q_OS_NETBSD) || defined(Q_OS_OPENBSD) || defined(Q_OS_ANDROID) || defined(Q_OS_QNX) || defined(Q_OS_OSX) || defined(Q_OS_HAIKU) # define ffsll __builtin_ffsll #endif -- cgit v1.2.3 From 9dd58c6239a28a558e110309beb86d6ea3f2dec2 Mon Sep 17 00:00:00 2001 From: Ralf Nolden Date: Tue, 31 May 2016 12:14:24 +0200 Subject: Compile fix: OpenBSD does not have Fix compiling under OpenBSD by using Q_OS_OPENBSD define for missing include file and adding required typedef. Obtained from OpenBSD ports patches for qt-5.5.1 at http://cvsweb.openbsd.org/cgi-bin/cvsweb/ports/x11/qt5/patches/ Change-Id: Ide223bffb6b116e8341d0eb39329af4d7a0be6a0 Reviewed-by: Thiago Macieira --- src/network/kernel/qdnslookup_unix.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/network/kernel/qdnslookup_unix.cpp b/src/network/kernel/qdnslookup_unix.cpp index cb3bdfe8ff..584f0b0f0e 100644 --- a/src/network/kernel/qdnslookup_unix.cpp +++ b/src/network/kernel/qdnslookup_unix.cpp @@ -40,7 +40,9 @@ #include #include #include -#include +#if !defined(Q_OS_OPENBSD) +# include +#endif #include #if defined(__GNU_LIBRARY__) && !defined(__UCLIBC__) @@ -51,6 +53,9 @@ QT_BEGIN_NAMESPACE #ifndef QT_NO_LIBRARY +#if defined(Q_OS_OPENBSD) +typedef struct __res_state* res_state; +#endif typedef int (*dn_expand_proto)(const unsigned char *, const unsigned char *, const unsigned char *, char *, int); static dn_expand_proto local_dn_expand = 0; typedef void (*res_nclose_proto)(res_state); -- cgit v1.2.3 From 0720569b151efd59cb253025d66ec9982b5d797a Mon Sep 17 00:00:00 2001 From: Ralf Nolden Date: Tue, 31 May 2016 14:00:10 +0200 Subject: OpenBSD: add /etc/ssl as cert dir Add the /etc/ssl default path to the list of certificate directories for OpenBSD. Change-Id: I13dff6a219e2c848501ec9bf191160a48f919515 Reviewed-by: Richard J. Moore --- src/network/ssl/qsslsocket.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/network/ssl/qsslsocket.cpp b/src/network/ssl/qsslsocket.cpp index 805adc734f..25a471dda8 100644 --- a/src/network/ssl/qsslsocket.cpp +++ b/src/network/ssl/qsslsocket.cpp @@ -2590,7 +2590,8 @@ QList QSslSocketPrivate::unixRootCertDirectories() << "/var/ssl/certs/" // AIX << "/usr/local/ssl/certs/" // Solaris << "/etc/openssl/certs/" // BlackBerry - << "/opt/openssl/certs/"; // HP-UX + << "/opt/openssl/certs/" // HP-UX + << "/etc/ssl/"; // OpenBSD } /*! -- cgit v1.2.3 From a1de7c40f4a22f996fcf922e69315c1f2cea6e96 Mon Sep 17 00:00:00 2001 From: Alexandru Croitor Date: Wed, 1 Jun 2016 13:14:01 +0200 Subject: Blacklist tst_QOpenGLWidget::stackWidgetOpaqueChildIsVisible test. It fails randomly on Windows, possibly due to timing issues. Change-Id: I0ef74f203455eb4ea8aeee4c8fc9bf1fbf6fb8ff Reviewed-by: Eskil Abrahamsen Blomfeldt --- tests/auto/widgets/widgets/qopenglwidget/BLACKLIST | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/widgets/widgets/qopenglwidget/BLACKLIST b/tests/auto/widgets/widgets/qopenglwidget/BLACKLIST index 725b8e93b4..cdff75ba65 100644 --- a/tests/auto/widgets/widgets/qopenglwidget/BLACKLIST +++ b/tests/auto/widgets/widgets/qopenglwidget/BLACKLIST @@ -1,2 +1,4 @@ [clearAndGrab] opensuse-13.1 +[stackWidgetOpaqueChildIsVisible] +windows -- cgit v1.2.3 From bbb440bab261fecc7c9baf779dadf36659d3cf6f Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Fri, 20 May 2016 06:28:26 +0200 Subject: QJsonValue: fix use-after-free in assignment operator The assignment operator of a String QJsonValue that holds the only remaining reference to the QString::Data block was freeing the block before obtaining its own reference, leading to a use-after-free in the case where *this was passed as 'other' (self-assignment). Fixed by reformulating the assignment operator in terms of the copy ctor, using the copy-swap idiom, with the twist that QJsonValue doesn't, yet, have a swap member function, so we use three per-member qSwap()s. Change-Id: I3c5ccc4d9f32c7593af3fc6a0edbf12b7feb1391 Reviewed-by: Lars Knoll --- src/corelib/json/qjsonvalue.cpp | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/src/corelib/json/qjsonvalue.cpp b/src/corelib/json/qjsonvalue.cpp index 76e5ae562f..c9f3ec35fe 100644 --- a/src/corelib/json/qjsonvalue.cpp +++ b/src/corelib/json/qjsonvalue.cpp @@ -269,25 +269,11 @@ QJsonValue::QJsonValue(const QJsonValue &other) */ QJsonValue &QJsonValue::operator =(const QJsonValue &other) { - if (t == String && stringData && !stringData->ref.deref()) - free(stringData); - - t = other.t; - dbl = other.dbl; - - if (d != other.d) { - - if (d && !d->ref.deref()) - delete d; - d = other.d; - if (d) - d->ref.ref(); - - } - - if (t == String && stringData) - stringData->ref.ref(); - + QJsonValue copy(other); + // swap(copy); + qSwap(dbl, copy.dbl); + qSwap(d, copy.d); + qSwap(t, copy.t); return *this; } -- cgit v1.2.3 From 492cfe7002a41d5eb542f467bc8ce4a281dc11c6 Mon Sep 17 00:00:00 2001 From: BogDan Vatra Date: Wed, 1 Jun 2016 11:48:08 +0300 Subject: Android: remove unused plugins These plugins can't be used on Android, but they are built, installed and also bundled into every .apk file. Change-Id: I3326c913282af5bd43e1c732de9ae2f255711414 Reviewed-by: Christian Stromme --- configure | 3 +++ src/plugins/platforms/platforms.pro | 4 ++-- src/plugins/plugins.pro | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/configure b/configure index d175ed32b5..be89b22291 100755 --- a/configure +++ b/configure @@ -3216,6 +3216,9 @@ if [ "$XPLATFORM_ANDROID" = "yes" ]; then if [ "$CFG_DBUS" = "auto" ]; then CFG_DBUS="no" fi + if [ "$CFG_EGLFS" = "auto" ]; then + CFG_EGLFS="no" + fi if [ -z "$CFG_DEFAULT_ANDROID_NDK_HOST" ]; then case $PLATFORM in linux-*) diff --git a/src/plugins/platforms/platforms.pro b/src/plugins/platforms/platforms.pro index 43bb04e318..9b4b6c518a 100644 --- a/src/plugins/platforms/platforms.pro +++ b/src/plugins/platforms/platforms.pro @@ -2,9 +2,9 @@ TEMPLATE = subdirs android:!android-no-sdk: SUBDIRS += android -SUBDIRS += minimal +!android: SUBDIRS += minimal -!win32|contains(QT_CONFIG, freetype):SUBDIRS += offscreen +!android:if(!win32|contains(QT_CONFIG, freetype)): SUBDIRS += offscreen contains(QT_CONFIG, xcb) { SUBDIRS += xcb diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro index 03b7dc266b..5e180904c7 100644 --- a/src/plugins/plugins.pro +++ b/src/plugins/plugins.pro @@ -6,7 +6,7 @@ qtHaveModule(network):!contains(QT_DISABLED_FEATURES, bearermanagement): SUBDIRS qtHaveModule(gui) { SUBDIRS *= platforms platforminputcontexts platformthemes !contains(QT_DISABLED_FEATURES, imageformatplugin): SUBDIRS *= imageformats - !contains(QT_DISABLED_FEATURES, library): SUBDIRS *= generic + !android:!contains(QT_DISABLED_FEATURES, library): SUBDIRS *= generic } qtHaveModule(widgets): SUBDIRS *= styles -- cgit v1.2.3 From 06f7f3fd36f0faec3f7fda559af3bea66d4df47e Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Fri, 27 May 2016 17:28:26 +0200 Subject: Doc: Describe QMAKE_EXTENSION_STATICLIB in qmake Manual Task-number: QTBUG-44176 Change-Id: I6f7ad50793b05585ba661cbe187d7619a36cafe5 Reviewed-by: Tim Jenssen Reviewed-by: Oswald Buddenhagen --- qmake/doc/src/qmake-manual.qdoc | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/qmake/doc/src/qmake-manual.qdoc b/qmake/doc/src/qmake-manual.qdoc index e59b0ddcbe..9cd4ab98aa 100644 --- a/qmake/doc/src/qmake-manual.qdoc +++ b/qmake/doc/src/qmake-manual.qdoc @@ -1616,6 +1616,13 @@ \note Platform-specific variables that change the extension override the contents of this variable. + \target QMAKE_EXTENSION_STATICLIB + \section1 QMAKE_EXTENSION_STATICLIB + + Contains the extension for shared static libraries. The value of + this variable is typically handled by qmake or + \l{#QMAKESPEC}{qmake.conf} and rarely needs to be modified. + \section1 QMAKE_EXT_MOC Contains the extension used on included moc files. -- cgit v1.2.3 From 0a8d3f914c54b057b59942a25d1b76b82e1fa64d Mon Sep 17 00:00:00 2001 From: Laszlo Agocs Date: Thu, 2 Jun 2016 13:00:57 +0200 Subject: evdev: Stop reading on ENODEV Touch does this correctly for some time already. Keyboard and mouse do not, leading to flooding the console with the Could not read from ... warning for ever when using the 'static' device discovery (no libudev) and unplugging a mouse or keyboard. Change-Id: I6bef44fbed4bc21cc2736b28d1166bf2b7d90edc Reviewed-by: Andy Nichols --- .../input/evdevkeyboard/qevdevkeyboardhandler.cpp | 15 +++++++++++---- .../input/evdevkeyboard/qevdevkeyboardhandler_p.h | 3 +++ .../input/evdevmouse/qevdevmousehandler.cpp | 13 ++++++++++--- 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp index 06751de0ef..089cc13032 100644 --- a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp +++ b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler.cpp @@ -53,7 +53,7 @@ Q_LOGGING_CATEGORY(qLcEvdevKeyMap, "qt.qpa.input.keymap") #include "qevdevkeyboard_defaultmap_p.h" QEvdevKeyboardHandler::QEvdevKeyboardHandler(const QString &device, int fd, bool disableZap, bool enableCompose, const QString &keymapFile) - : m_device(device), m_fd(fd), + : m_device(device), m_fd(fd), m_notify(Q_NULLPTR), m_modifiers(0), m_composing(0), m_dead_unicode(0xffff), m_no_zap(disableZap), m_do_compose(enableCompose), m_keymap(0), m_keymap_size(0), m_keycompose(0), m_keycompose_size(0) @@ -68,9 +68,8 @@ QEvdevKeyboardHandler::QEvdevKeyboardHandler(const QString &device, int fd, bool unloadKeymap(); // socket notifier for events on the keyboard device - QSocketNotifier *notifier; - notifier = new QSocketNotifier(m_fd, QSocketNotifier::Read, this); - connect(notifier, SIGNAL(activated(int)), this, SLOT(readKeycode())); + m_notify = new QSocketNotifier(m_fd, QSocketNotifier::Read, this); + connect(m_notify, SIGNAL(activated(int)), this, SLOT(readKeycode())); } QEvdevKeyboardHandler::~QEvdevKeyboardHandler() @@ -155,6 +154,14 @@ void QEvdevKeyboardHandler::readKeycode() } else if (result < 0) { if (errno != EINTR && errno != EAGAIN) { qErrnoWarning(errno, "evdevkeyboard: Could not read from input device"); + // If the device got disconnected, stop reading, otherwise we get flooded + // by the above error over and over again. + if (errno == ENODEV) { + delete m_notify; + m_notify = Q_NULLPTR; + qt_safe_close(m_fd); + m_fd = -1; + } return; } } else { diff --git a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler_p.h b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler_p.h index 90142c6837..84c251c3c2 100644 --- a/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler_p.h +++ b/src/platformsupport/input/evdevkeyboard/qevdevkeyboardhandler_p.h @@ -51,6 +51,8 @@ QT_BEGIN_NAMESPACE +class QSocketNotifier; + namespace QEvdevKeyboardMap { const quint32 FileMagic = 0x514d4150; // 'QMAP' @@ -180,6 +182,7 @@ private: QString m_device; int m_fd; + QSocketNotifier *m_notify; // keymap handling quint8 m_modifiers; diff --git a/src/platformsupport/input/evdevmouse/qevdevmousehandler.cpp b/src/platformsupport/input/evdevmouse/qevdevmousehandler.cpp index 76d8aab8f2..23bf0b3c30 100644 --- a/src/platformsupport/input/evdevmouse/qevdevmousehandler.cpp +++ b/src/platformsupport/input/evdevmouse/qevdevmousehandler.cpp @@ -105,9 +105,8 @@ QEvdevMouseHandler::QEvdevMouseHandler(const QString &device, int fd, bool abs, m_abs = getHardwareMaximum(); // socket notifier for events on the mouse device - QSocketNotifier *notifier; - notifier = new QSocketNotifier(m_fd, QSocketNotifier::Read, this); - connect(notifier, SIGNAL(activated(int)), this, SLOT(readMouseData())); + m_notify = new QSocketNotifier(m_fd, QSocketNotifier::Read, this); + connect(m_notify, SIGNAL(activated(int)), this, SLOT(readMouseData())); } QEvdevMouseHandler::~QEvdevMouseHandler() @@ -196,6 +195,14 @@ void QEvdevMouseHandler::readMouseData() } else if (result < 0) { if (errno != EINTR && errno != EAGAIN) { qErrnoWarning(errno, "evdevmouse: Could not read from input device"); + // If the device got disconnected, stop reading, otherwise we get flooded + // by the above error over and over again. + if (errno == ENODEV) { + delete m_notify; + m_notify = Q_NULLPTR; + qt_safe_close(m_fd); + m_fd = -1; + } return; } } else { -- cgit v1.2.3 From c2d4c3588c8b0f65923c1b3dd98826a99c589495 Mon Sep 17 00:00:00 2001 From: Leena Miettinen Date: Thu, 2 Jun 2016 16:03:02 +0200 Subject: Doc: Fix examples install path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The example directory name for Qt Test module is qtestlib. Without this change, Qt Creator cannot find the tutorial files and tags them "broken" in the Welcome mode. Change-Id: Ib2de0cd2263aa1651abb697f9f03ecd8eb871ca2 Reviewed-by: Topi Reiniö --- src/testlib/doc/qttestlib.qdocconf | 2 +- src/testlib/doc/src/qttestlib-manual.qdoc | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/testlib/doc/qttestlib.qdocconf b/src/testlib/doc/qttestlib.qdocconf index 0fafc733b1..899f94ec53 100644 --- a/src/testlib/doc/qttestlib.qdocconf +++ b/src/testlib/doc/qttestlib.qdocconf @@ -4,7 +4,7 @@ project = QtTestLib description = Qt Test Reference Documentation version = $QT_VERSION -examplesinstallpath = testlib +examplesinstallpath = qtestlib qhp.projects = QtTestLib diff --git a/src/testlib/doc/src/qttestlib-manual.qdoc b/src/testlib/doc/src/qttestlib-manual.qdoc index 82651d5cba..781eec0560 100644 --- a/src/testlib/doc/src/qttestlib-manual.qdoc +++ b/src/testlib/doc/src/qttestlib-manual.qdoc @@ -484,6 +484,7 @@ \nextpage {Chapter 2: Data Driven Testing}{Chapter 2} \title Chapter 1: Writing a Unit Test + \brief How to write a unit test. In this first chapter we will see how to write a simple unit test for a class, and how to execute it. @@ -559,6 +560,7 @@ \nextpage {Chapter 3: Simulating Gui Events}{Chapter 3} \title Chapter 2: Data Driven Testing + \brief How to create data driven tests. In this chapter we will demonstrate how to execute a test multiple times with different test data. @@ -664,6 +666,7 @@ \nextpage {Chapter 4: Replaying GUI Events}{Chapter 4} \title Chapter 3: Simulating GUI Events + \brief Howe to simulate GUI events. Qt Test features some mechanisms to test graphical user interfaces. Instead of simulating native window system events, @@ -724,6 +727,7 @@ \nextpage {Chapter 5: Writing a Benchmark}{Chapter 5} \title Chapter 4: Replaying GUI Events + \brief How to replay GUI events. In this chapter, we will show how to simulate a GUI event, and how to store a series of GUI events as well as replay them on @@ -803,6 +807,7 @@ \contentspage {Qt Test Tutorial}{Contents} \title Chapter 5: Writing a Benchmark + \brief How to write a benchmark. In this final chapter we will demonstrate how to write benchmarks using Qt Test. -- cgit v1.2.3 From 9c01fdb2badd0cbc5369cc31b6626718e5b4c23c Mon Sep 17 00:00:00 2001 From: Maurice Kalinowski Date: Thu, 2 Jun 2016 11:12:29 +0200 Subject: winrt: Fix compilation for 10586 SDK The current implementation of drag and drop requires Redstone 2 Update (SDK version 14322) to be fully functional. The API is limited for previous versions. However, this mostly affects passing allowed operations between sender and receiver, the rest is mostly functional still. Once RedStone 2 is out (estimated July 2016) we can bump the minimum SDK version to 14322. Task-number: QTBUG-50827 Change-Id: I5bab9d36a228d68c1809c241a64168d48c353335 Reviewed-by: Simon Hausmann Reviewed-by: Friedemann Kleint Reviewed-by: Liang Qi Reviewed-by: Oliver Wolff --- src/plugins/platforms/winrt/qwinrtdrag.cpp | 7 ++++++- src/plugins/platforms/winrt/winrt.pro | 4 ++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/plugins/platforms/winrt/qwinrtdrag.cpp b/src/plugins/platforms/winrt/qwinrtdrag.cpp index 14bea7ab30..2ef50aa4e2 100644 --- a/src/plugins/platforms/winrt/qwinrtdrag.cpp +++ b/src/plugins/platforms/winrt/qwinrtdrag.cpp @@ -623,6 +623,7 @@ Qt::DropAction QWinRTDrag::drag(QDrag *drag) hr = dataPackage->put_RequestedOperation(translateFromQDragDropActions(action)); Q_ASSERT_SUCCEEDED(hr); +#ifndef QT_WINRT_LIMITED_DRAGANDDROP ComPtr args2; hr = args->QueryInterface(IID_PPV_ARGS(&args2)); Q_ASSERT_SUCCEEDED(hr); @@ -637,7 +638,7 @@ Qt::DropAction QWinRTDrag::drag(QDrag *drag) allowedOperations |= DataPackageOperation_Link; hr = args2->put_AllowedOperations(allowedOperations); Q_ASSERT_SUCCEEDED(hr); - +#endif // QT_WINRT_LIMITED_DRAGANDDROP QMimeData *mimeData = drag->mimeData(); if (mimeData->hasText()) { hr = dataPackage->SetText(qStringToHString(mimeData->text()).Get()); @@ -811,6 +812,7 @@ void QWinRTDrag::handleNativeDragEvent(IInspectable *sender, ABI::Windows::UI::X DragDropModifiers modifiers; hr = e2->get_Modifiers(&modifiers); +#ifndef QT_WINRT_LIMITED_DRAGANDDROP ComPtr e3; hr = e->QueryInterface(IID_PPV_ARGS(&e3)); Q_ASSERT_SUCCEEDED(hr); @@ -821,6 +823,9 @@ void QWinRTDrag::handleNativeDragEvent(IInspectable *sender, ABI::Windows::UI::X qCDebug(lcQpaMime) << __FUNCTION__ << "Could not query drag operations"; const Qt::DropActions actions = translateToQDragDropActions(dataOp); +#else // !QT_WINRT_LIMITED_DRAGANDDROP + const Qt::DropActions actions = Qt::LinkAction | Qt::CopyAction | Qt::MoveAction;; +#endif // !QT_WINRT_LIMITED_DRAGANDDROP ComPtr dataView; hr = e2->get_DataView(&dataView); diff --git a/src/plugins/platforms/winrt/winrt.pro b/src/plugins/platforms/winrt/winrt.pro index dd1e051c33..f5591934f5 100644 --- a/src/plugins/platforms/winrt/winrt.pro +++ b/src/plugins/platforms/winrt/winrt.pro @@ -49,6 +49,10 @@ HEADERS = \ OTHER_FILES += winrt.json +WINRT_SDK_VERSION_STRING = $$(UCRTVersion) +WINRT_SDK_VERSION = $$member($$list($$split(WINRT_SDK_VERSION_STRING, .)), 2) +lessThan(WINRT_SDK_VERSION, 14322): DEFINES += QT_WINRT_LIMITED_DRAGANDDROP + *-msvc2013|contains(DEFINES, QT_NO_DRAGANDDROP) { SOURCES -= qwinrtdrag.cpp HEADERS -= qwinrtdrag.h -- cgit v1.2.3 From 4fc797147821b4ef3372d4db9253d3cb1ed0704e Mon Sep 17 00:00:00 2001 From: Ralf Nolden Date: Thu, 2 Jun 2016 13:46:52 +0200 Subject: NetBSD/OpenBSD: Compile fix and proper detection of pipe2 Add the necessary defines for HAVE_PIPE2 for NetBSD and OpenBSD depending on OS version when pipe2(2) was added. This also fixes the compile error on NetBSD if -Werror=unused-function for ignore_sigpipe() as the HAVE_PIPE2 tree is prior to O_NOSIGPIPE in create_pipe(). Change-Id: Ic8f875e34ef826a7bf046c77588afecaa097deca Reviewed-by: Thiago Macieira --- src/3rdparty/forkfd/forkfd.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/3rdparty/forkfd/forkfd.c b/src/3rdparty/forkfd/forkfd.c index 9284a67674..7d2115abb6 100644 --- a/src/3rdparty/forkfd/forkfd.c +++ b/src/3rdparty/forkfd/forkfd.c @@ -30,6 +30,9 @@ #include "forkfd.h" #include +#if defined(__OpenBSD__) || defined(__NetBSD__) +# include +#endif #include #include #include @@ -65,7 +68,9 @@ # undef HAVE_WAITID #endif -#if defined(__FreeBSD__) && defined(__FreeBSD_version) && __FreeBSD_version >= 1000032 +#if (defined(__FreeBSD__) && defined(__FreeBSD_version) && __FreeBSD_version >= 1000032) || \ + (defined(__OpenBSD__) && OpenBSD >= 201505) || \ + (defined(__NetBSD__) && __NetBSD_Version__ >= 600000000) # define HAVE_PIPE2 1 #endif #if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__FreeBSD_kernel__) || \ -- cgit v1.2.3 From 8c7d6b94d5e1e28c0352c5ae6ac52d4d1ea9b681 Mon Sep 17 00:00:00 2001 From: "Richard J. Moore" Date: Tue, 31 May 2016 17:10:07 +0100 Subject: Detect if the 'openssl' is really libressl at configure time. Qt does not support libressl which reports itself as openssl but uses a high version number. This means that we expect it to have features that it doesn't and will fail to build. Instead detect this situation at configure time and disable the ssl support. Change-Id: I73cca4d1544df2aaca0723c38ba63758c287ec41 Reviewed-by: Ralf Nolden Reviewed-by: Timur Pocheptsov Reviewed-by: Oswald Buddenhagen --- config.tests/unix/openssl/openssl.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/config.tests/unix/openssl/openssl.cpp b/config.tests/unix/openssl/openssl.cpp index 6282bfa328..d0b6cca562 100644 --- a/config.tests/unix/openssl/openssl.cpp +++ b/config.tests/unix/openssl/openssl.cpp @@ -37,6 +37,12 @@ # error "OpenSSL >= 0.9.7 is required" #endif +#include + +#if OPENSSL_VERSION_NUMBER-0 >= 0x10002000L && !defined(OPENSSL_NO_EC) && !defined(SSL_CTRL_SET_CURVES) +# error "OpenSSL was reported as >= 1.0.2 but is missing required features, possibly it's libressl which is unsupported" +#endif + int main() { } -- cgit v1.2.3 From 372e3c8592f80358942ddc1cadb2b76bb401ab56 Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Thu, 2 Jun 2016 14:29:57 +0200 Subject: WinRT: Early return in case of network error Change-Id: I7c410732f41b86f39b41fd1dccd07815e5ca4e45 Reviewed-by: Maurice Kalinowski --- src/network/socket/qnativesocketengine_winrt.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp index 7077fefa65..03c9327958 100644 --- a/src/network/socket/qnativesocketengine_winrt.cpp +++ b/src/network/socket/qnativesocketengine_winrt.cpp @@ -1224,21 +1224,21 @@ void QNativeSocketEnginePrivate::handleConnectionEstablished(IAsyncAction *actio case 0x8007274c: // A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. setError(QAbstractSocket::NetworkError, ConnectionTimeOutErrorString); socketState = QAbstractSocket::UnconnectedState; - break; + return; case 0x80072751: // A socket operation was attempted to an unreachable host. setError(QAbstractSocket::HostNotFoundError, HostUnreachableErrorString); socketState = QAbstractSocket::UnconnectedState; - break; + return; case 0x8007274d: // No connection could be made because the target machine actively refused it. setError(QAbstractSocket::ConnectionRefusedError, ConnectionRefusedErrorString); socketState = QAbstractSocket::UnconnectedState; - break; + return; default: if (FAILED(hr)) { setError(QAbstractSocket::UnknownSocketError, UnknownSocketErrorString); socketState = QAbstractSocket::UnconnectedState; + return; } - break; } // The callback might be triggered several times if we do not cancel/reset it here -- cgit v1.2.3 From 265d91da0dfa1712823ea38c28af1326a0368f6f Mon Sep 17 00:00:00 2001 From: Oliver Wolff Date: Thu, 2 Jun 2016 14:34:28 +0200 Subject: WinRT: Rename connectToHost/handleConnectionEstablished The two functions are merged and also renamed. handleConnectionEstablished indicates that the operation succeeded, but that is not necessarily the case. Change-Id: I66a4181a5693353fc9507785a6e6bbb8d5300a4b Reviewed-by: Maurice Kalinowski --- src/network/socket/qnativesocketengine_winrt.cpp | 25 ++++++++++-------------- src/network/socket/qnativesocketengine_winrt_p.h | 3 +-- 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp index 03c9327958..3a4ef4b400 100644 --- a/src/network/socket/qnativesocketengine_winrt.cpp +++ b/src/network/socket/qnativesocketengine_winrt.cpp @@ -331,7 +331,7 @@ bool QNativeSocketEngine::connectToHostByName(const QString &name, quint16 port) d->socketState = QAbstractSocket::ConnectingState; hr = QEventDispatcherWinRT::runOnXamlThread([d]() { return d->connectOp->put_Completed(Callback( - d, &QNativeSocketEnginePrivate::handleConnectToHost).Get()); + d, &QNativeSocketEnginePrivate::handleConnectOpFinished).Get()); }); Q_ASSERT_SUCCEEDED(hr); @@ -755,7 +755,7 @@ bool QNativeSocketEngine::waitForWrite(int msecs, bool *timedOut) if (d->socketState == QAbstractSocket::ConnectingState) { HRESULT hr = QWinRTFunctions::await(d->connectOp, QWinRTFunctions::ProcessMainThreadEvents); if (SUCCEEDED(hr)) { - d->handleConnectionEstablished(d->connectOp.Get()); + d->handleConnectOpFinished(d->connectOp.Get(), Completed); return true; } } @@ -1207,37 +1207,31 @@ HRESULT QNativeSocketEnginePrivate::handleClientConnection(IStreamSocketListener return S_OK; } -HRESULT QNativeSocketEnginePrivate::handleConnectToHost(IAsyncAction *action, AsyncStatus) -{ - handleConnectionEstablished(action); - return S_OK; -} - -void QNativeSocketEnginePrivate::handleConnectionEstablished(IAsyncAction *action) +HRESULT QNativeSocketEnginePrivate::handleConnectOpFinished(IAsyncAction *action, AsyncStatus) { Q_Q(QNativeSocketEngine); if (wasDeleted || !connectOp) // Protect against a late callback - return; + return S_OK; HRESULT hr = action->GetResults(); switch (hr) { case 0x8007274c: // A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. setError(QAbstractSocket::NetworkError, ConnectionTimeOutErrorString); socketState = QAbstractSocket::UnconnectedState; - return; + return S_OK; case 0x80072751: // A socket operation was attempted to an unreachable host. setError(QAbstractSocket::HostNotFoundError, HostUnreachableErrorString); socketState = QAbstractSocket::UnconnectedState; - return; + return S_OK; case 0x8007274d: // No connection could be made because the target machine actively refused it. setError(QAbstractSocket::ConnectionRefusedError, ConnectionRefusedErrorString); socketState = QAbstractSocket::UnconnectedState; - return; + return S_OK; default: if (FAILED(hr)) { setError(QAbstractSocket::UnknownSocketError, UnknownSocketErrorString); socketState = QAbstractSocket::UnconnectedState; - return; + return S_OK; } } @@ -1260,13 +1254,14 @@ void QNativeSocketEnginePrivate::handleConnectionEstablished(IAsyncAction *actio emit q->connectionReady(); if (socketType != QAbstractSocket::TcpSocket) - return; + return S_OK; // Delay the reader so that the SSL socket can upgrade if (sslSocket) QObject::connect(qobject_cast(sslSocket), &QSslSocket::encrypted, q, &QNativeSocketEngine::establishRead); else q->establishRead(); + return S_OK; } HRESULT QNativeSocketEnginePrivate::handleReadyRead(IAsyncBufferOperation *asyncInfo, AsyncStatus status) diff --git a/src/network/socket/qnativesocketengine_winrt_p.h b/src/network/socket/qnativesocketengine_winrt_p.h index 2c1c42ecbc..c1fbcf70fa 100644 --- a/src/network/socket/qnativesocketengine_winrt_p.h +++ b/src/network/socket/qnativesocketengine_winrt_p.h @@ -214,8 +214,7 @@ private: ABI::Windows::Networking::Sockets::IDatagramSocketMessageReceivedEventArgs *args); HRESULT handleClientConnection(ABI::Windows::Networking::Sockets::IStreamSocketListener *tcpListener, ABI::Windows::Networking::Sockets::IStreamSocketListenerConnectionReceivedEventArgs *args); - HRESULT handleConnectToHost(ABI::Windows::Foundation::IAsyncAction *, ABI::Windows::Foundation::AsyncStatus); - void handleConnectionEstablished(ABI::Windows::Foundation::IAsyncAction *action); + HRESULT handleConnectOpFinished(ABI::Windows::Foundation::IAsyncAction *, ABI::Windows::Foundation::AsyncStatus); HRESULT handleReadyRead(ABI::Windows::Foundation::IAsyncOperationWithProgress *asyncInfo, ABI::Windows::Foundation::AsyncStatus); }; -- cgit v1.2.3 From 22667483e1da3da2de5def9a1ee8aa6b22ee50d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morten=20Johan=20S=C3=B8rvig?= Date: Fri, 3 Jun 2016 12:37:20 +0200 Subject: Blacklist modalDialogClosingOneOfTwoModal on OS X Passes locally (on 10.10), but seems to have become unstable on the CI system. Task-number: QTBUG-53790 Change-Id: I0432fca4121b97bcdd6cec529fc4e148dfb8c1ab Reviewed-by: Timur Pocheptsov --- tests/auto/gui/kernel/qwindow/BLACKLIST | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/auto/gui/kernel/qwindow/BLACKLIST b/tests/auto/gui/kernel/qwindow/BLACKLIST index a34066dd7c..427d63b845 100644 --- a/tests/auto/gui/kernel/qwindow/BLACKLIST +++ b/tests/auto/gui/kernel/qwindow/BLACKLIST @@ -6,3 +6,5 @@ ubuntu-14.04 ubuntu-14.04 [modalWindowEnterEventOnHide_QTBUG35109] ubuntu-14.04 +[modalDialogClosingOneOfTwoModal] +osx -- cgit v1.2.3 From cf19b06f221430db7eba00e792237abe14df4a3d Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Fri, 18 Mar 2016 16:50:28 -0700 Subject: Cocoa QPA: Mute mouse dragging warnings While probably valid, these warnings are beyond the user's control, and more likely a sign of Qt's own expectations or misbehavior. So, we should not annoy the users with them. This change introduces the same logging category as 3ee01f74031d9e1d0 in 5.7 as is a partial backport to simplify a subsequent 5.6 to 5.7 merge. Change-Id: Ica2e3b1c5bc372923fd823b5d7d537d319835685 Task-number: QTBUG-42846 Reviewed-by: Timur Pocheptsov --- src/plugins/platforms/cocoa/qcocoahelpers.h | 2 ++ src/plugins/platforms/cocoa/qcocoahelpers.mm | 2 ++ src/plugins/platforms/cocoa/qnsview.mm | 6 +++--- src/plugins/platforms/cocoa/qt_mac_p.h | 1 + 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.h b/src/plugins/platforms/cocoa/qcocoahelpers.h index 89f8bc2f6a..c2abe4e245 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.h +++ b/src/plugins/platforms/cocoa/qcocoahelpers.h @@ -50,6 +50,8 @@ QT_BEGIN_NAMESPACE +Q_DECLARE_LOGGING_CATEGORY(lcQpaCocoaWindow) + class QPixmap; class QString; diff --git a/src/plugins/platforms/cocoa/qcocoahelpers.mm b/src/plugins/platforms/cocoa/qcocoahelpers.mm index 29a204d579..58d2961111 100644 --- a/src/plugins/platforms/cocoa/qcocoahelpers.mm +++ b/src/plugins/platforms/cocoa/qcocoahelpers.mm @@ -48,6 +48,8 @@ QT_BEGIN_NAMESPACE +Q_LOGGING_CATEGORY(lcQpaCocoaWindow, "qt.qpa.cocoa.window"); + // // Conversion Functions // diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index 4009c13ad5..4e482fb146 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -880,7 +880,7 @@ QT_WARNING_POP if (m_window && (m_window->flags() & Qt::WindowTransparentForInput) ) return [super mouseDragged:theEvent]; if (!(m_buttons & (m_sendUpAsRightButton ? Qt::RightButton : Qt::LeftButton))) - qWarning("QNSView mouseDragged: Internal mouse button tracking invalid (missing Qt::LeftButton)"); + qCDebug(lcQpaCocoaWindow, "QNSView mouseDragged: Internal mouse button tracking invalid (missing Qt::LeftButton)"); [self handleMouseEvent:theEvent]; } @@ -1019,7 +1019,7 @@ QT_WARNING_POP if (m_window && (m_window->flags() & Qt::WindowTransparentForInput) ) return [super rightMouseDragged:theEvent]; if (!(m_buttons & Qt::RightButton)) - qWarning("QNSView rightMouseDragged: Internal mouse button tracking invalid (missing Qt::RightButton)"); + qCDebug(lcQpaCocoaWindow, "QNSView rightMouseDragged: Internal mouse button tracking invalid (missing Qt::RightButton)"); [self handleMouseEvent:theEvent]; } @@ -1045,7 +1045,7 @@ QT_WARNING_POP if (m_window && (m_window->flags() & Qt::WindowTransparentForInput) ) return [super otherMouseDragged:theEvent]; if (!(m_buttons & ~(Qt::LeftButton | Qt::RightButton))) - qWarning("QNSView otherMouseDragged: Internal mouse button tracking invalid (missing Qt::MiddleButton or Qt::ExtraButton*)"); + qCDebug(lcQpaCocoaWindow, "QNSView otherMouseDragged: Internal mouse button tracking invalid (missing Qt::MiddleButton or Qt::ExtraButton*)"); [self handleMouseEvent:theEvent]; } diff --git a/src/plugins/platforms/cocoa/qt_mac_p.h b/src/plugins/platforms/cocoa/qt_mac_p.h index 576e0f9729..299678eee8 100644 --- a/src/plugins/platforms/cocoa/qt_mac_p.h +++ b/src/plugins/platforms/cocoa/qt_mac_p.h @@ -58,6 +58,7 @@ #include "QtCore/qvariant.h" #include "QtCore/qmimedata.h" #include "QtCore/qpointer.h" +#include "QtCore/qloggingcategory.h" #include "private/qcore_mac_p.h" -- cgit v1.2.3 From 23bed9f8203bb6d475622c02ea9a96efdea78108 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Wed, 1 Jun 2016 11:07:22 +0200 Subject: Remove tst_QWidget::immediateRepaintAfterShow(). It tested whether a paint event was received when calling QWidget::repaint() right after QWidget::show() without waiting for the window to be exposed. This caused a QEvent::UpdateRequest to be sent, which ended up in QWidgetBackingStore::sync() which returns after checking QWidgetBackingStore::discardSyncRequest(), since Qt::WA_Mapped is not set on the non-exposed widget. The test passed on Windows since it contains one call to QCoreApplication::processEvents() which causes the the initial WM_PAINT message to be processed in QWindowsWindow::handleWmPaint() which calls QWindowSystemInterface::flushWindowSystemEvents() and causes Qt::WA_Mapped to be set. This seems counter to the intention of the test. Remove the test since it won't pass anymore in Qt 5 unless Qt::WA_Mapped is set. Task-number: QTBUG-26424 Task-number: QTBUG-38327 Task-number: QTBUG-39842 Change-Id: Iede026d52825dcf1f2e9014a316d26d260309214 Reviewed-by: Joerg Bornemann --- tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp index 10d32472be..b7c152603c 100644 --- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp +++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp @@ -378,7 +378,6 @@ private slots: void setMaskInResizeEvent(); void moveInResizeEvent(); - void immediateRepaintAfterShow(); void immediateRepaintAfterInvalidateBuffer(); void effectiveWinId(); @@ -8145,25 +8144,6 @@ void tst_QWidget::moveInResizeEvent() QTRY_COMPARE(testWidget.geometry(), expectedGeometry); } -void tst_QWidget::immediateRepaintAfterShow() -{ - if (m_platform == QStringLiteral("xcb")) - QSKIP("QTBUG-26424"); - if (m_platform != QStringLiteral("xcb") && m_platform != QStringLiteral("windows")) - QSKIP("We don't support immediate repaint right after show on other platforms."); - - UpdateWidget widget; - centerOnScreen(&widget); - widget.show(); - qApp->processEvents(); - // On X11 in particular, we are now waiting for a MapNotify event before - // syncing the backing store. However, if someone request a repaint() - // we must repaint immediately regardless of the current state. - widget.numPaintEvents = 0; - widget.repaint(); - QCOMPARE(widget.numPaintEvents, 1); -} - void tst_QWidget::immediateRepaintAfterInvalidateBuffer() { if (m_platform != QStringLiteral("xcb") && m_platform != QStringLiteral("windows")) -- cgit v1.2.3 From 95f1f6f719858bcb2429acee855c82a5e8164b4e Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Thu, 2 Jun 2016 11:31:23 +0200 Subject: tst_QTemporaryFile: Run in temporary directory. The test leaks a file (named qt_...xxx) in QDir::tempPath(). Moreover, when tests fail, it can happen that more files are leaked and subsequent runs do not recover since the check for non-existence of those files fails. Change-Id: Iaea6d09ee7c271903a1b9c63e263c19f9e90bba9 Reviewed-by: David Faure --- tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp b/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp index 6e461cae17..7b06355990 100644 --- a/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp +++ b/tests/auto/corelib/io/qtemporaryfile/tst_qtemporaryfile.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include @@ -86,13 +87,15 @@ private slots: void QTBUG_4796(); void guaranteeUnique(); private: + QTemporaryDir m_temporaryDir; QString m_previousCurrent; }; void tst_QTemporaryFile::initTestCase() { + QVERIFY2(m_temporaryDir.isValid(), qPrintable(m_temporaryDir.errorString())); m_previousCurrent = QDir::currentPath(); - QDir::setCurrent(QDir::tempPath()); + QVERIFY(QDir::setCurrent(m_temporaryDir.path())); // For QTBUG_4796 QVERIFY(QDir("test-XXXXXX").exists() || QDir().mkdir("test-XXXXXX")); @@ -119,9 +122,6 @@ void tst_QTemporaryFile::initTestCase() void tst_QTemporaryFile::cleanupTestCase() { - // From QTBUG_4796 - QVERIFY(QDir().rmdir("test-XXXXXX")); - QDir::setCurrent(m_previousCurrent); } -- cgit v1.2.3 From fd70978693bd92761e9989bc1c76bf83c1e8c987 Mon Sep 17 00:00:00 2001 From: Friedemann Kleint Date: Fri, 3 Jun 2016 11:27:39 +0200 Subject: Diaglib: Extend class information for QWidget dumps. Output the class hierarchy until a base class within QtWidgets is found. Change-Id: I0ecee22e2ead1dea8b39cce8ca2f0739290aac22 Reviewed-by: Alexandru Croitor --- tests/manual/diaglib/qwidgetdump.cpp | 46 ++++++++++++++++++++++++++++++++++-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/tests/manual/diaglib/qwidgetdump.cpp b/tests/manual/diaglib/qwidgetdump.cpp index e5fdfaeb71..0795bec37f 100644 --- a/tests/manual/diaglib/qwidgetdump.cpp +++ b/tests/manual/diaglib/qwidgetdump.cpp @@ -45,11 +45,50 @@ namespace QtDiag { +static const char *qtWidgetClasses[] = { + "QAbstractItemView", "QAbstractScrollArea", "QAbstractSlider", "QAbstractSpinBox", + "QCalendarWidget", "QCheckBox", "QColorDialog", "QColumnView", "QComboBox", + "QCommandLinkButton", "QDateEdit", "QDateTimeEdit", "QDesktopWidget", "QDial", + "QDialog", "QDialogButtonBox", "QDockWidget", "QDoubleSpinBox", "QErrorMessage", + "QFileDialog", "QFontComboBox", "QFontDialog", "QFrame", "QGraphicsView", + "QGroupBox", "QHeaderView", "QInputDialog", "QLCDNumber", "QLabel", "QLineEdit", + "QListView", "QListWidget", "QMainWindow", "QMdiArea", "QMdiSubWindow", "QMenu", + "QMenuBar", "QMessageBox", "QOpenGLWidget", "QPlainTextEdit", "QProgressBar", + "QProgressDialog", "QPushButton", "QRadioButton", "QRubberBand", "QScrollArea", + "QScrollBar", "QSlider", "QSpinBox", "QSplashScreen", "QSplitter", + "QStackedWidget", "QStatusBar", "QTabBar", "QTabWidget", "QTableView", + "QTableWidget", "QTextBrowser", "QTextEdit", "QTimeEdit", "QToolBar", + "QToolBox", "QToolButton", "QTreeView", "QTreeWidget", "QWidget", + "QWizard", "QWizardPage" +}; + +static bool isQtWidget(const char *className) +{ + for (size_t i = 0, count = sizeof(qtWidgetClasses) / sizeof(qtWidgetClasses[0]); i < count; ++i) { + if (!qstrcmp(className, qtWidgetClasses[i])) + return true; + } + return false; +} + +static void formatWidgetClass(QTextStream &str, const QWidget *w) +{ + const QMetaObject *mo = w->metaObject(); + str << mo->className(); + while (!isQtWidget(mo->className())) { + mo = mo->superClass(); + str << ':' << mo->className(); + } + const QString on = w->objectName(); + if (!on.isEmpty()) + str << "/\"" << on << '"'; +} + static void dumpWidgetRecursion(QTextStream &str, const QWidget *w, FormatWindowOptions options, int depth = 0) { indentStream(str, 2 * depth); - formatObject(str, w); + formatWidgetClass(str, w); str << ' ' << (w->isVisible() ? "[visible] " : "[hidden] "); if (const WId nativeWinId = w->internalWinId()) str << "[native: " << hex << showbase << nativeWinId << dec << noshowbase << "] "; @@ -114,7 +153,10 @@ void dumpAllWidgets(FormatWindowOptions options, const QWidget *root) foreach (QWidget *tw, topLevels) dumpWidgetRecursion(str, tw, options); #if QT_VERSION >= 0x050400 - qDebug().noquote() << d; + { + foreach (const QString &line, d.split(QLatin1Char('\n'))) + qDebug().noquote() << line; + } #else qDebug("%s", qPrintable(d)); #endif -- cgit v1.2.3