diff options
67 files changed, 583 insertions, 197 deletions
diff --git a/config.tests/qpa/egl-x11/egl-x11.pro b/config.tests/qpa/egl-x11/egl-x11.pro index c4e94ca40c..aceb03dd78 100644 --- a/config.tests/qpa/egl-x11/egl-x11.pro +++ b/config.tests/qpa/egl-x11/egl-x11.pro @@ -1,7 +1,7 @@ SOURCES = egl-x11.cpp for(p, QMAKE_LIBDIR_EGL) { - exists($$p):LIBS += -L$$p + LIBS += -L$$p } !isEmpty(QMAKE_INCDIR_EGL): INCLUDEPATH += $$QMAKE_INCDIR_EGL diff --git a/config.tests/qpa/egl/egl.pro b/config.tests/qpa/egl/egl.pro index f04d053543..b5396dab15 100644 --- a/config.tests/qpa/egl/egl.pro +++ b/config.tests/qpa/egl/egl.pro @@ -1,7 +1,7 @@ SOURCES = egl.cpp for(p, QMAKE_LIBDIR_EGL) { - exists($$p):LIBS += -L$$p + LIBS += -L$$p } !isEmpty(QMAKE_INCDIR_EGL): INCLUDEPATH += $$QMAKE_INCDIR_EGL diff --git a/config.tests/qpa/eglfs-brcm/eglfs-brcm.pro b/config.tests/qpa/eglfs-brcm/eglfs-brcm.pro index ce16a3a391..d8b1c3ec7e 100644 --- a/config.tests/qpa/eglfs-brcm/eglfs-brcm.pro +++ b/config.tests/qpa/eglfs-brcm/eglfs-brcm.pro @@ -5,7 +5,7 @@ CONFIG -= qt INCLUDEPATH += $$QMAKE_INCDIR_EGL for(p, QMAKE_LIBDIR_EGL) { - exists($$p):LIBS += -L$$p + LIBS += -L$$p } LIBS += -lEGL -lGLESv2 -lbcm_host diff --git a/config.tests/qpa/eglfs-egldevice/eglfs-egldevice.pro b/config.tests/qpa/eglfs-egldevice/eglfs-egldevice.pro index 87214abc7a..521a911219 100644 --- a/config.tests/qpa/eglfs-egldevice/eglfs-egldevice.pro +++ b/config.tests/qpa/eglfs-egldevice/eglfs-egldevice.pro @@ -1,7 +1,7 @@ SOURCES = eglfs-egldevice.cpp for(p, QMAKE_LIBDIR_EGL) { - exists($$p):LIBS += -L$$p + LIBS += -L$$p } INCLUDEPATH += $$QMAKE_INCDIR_EGL diff --git a/config.tests/unix/compile.test b/config.tests/unix/compile.test index c8929a37f1..ab1bd00884 100755 --- a/config.tests/unix/compile.test +++ b/config.tests/unix/compile.test @@ -15,6 +15,7 @@ QTCONF=$9 shift 9 LFLAGS="$SYSROOT_FLAG" INCLUDEPATH="" +CFLAGS="$SYSROOT_FLAG" CXXFLAGS="$SYSROOT_FLAG" MAC_ARCH_CXXFLAGS="" MAC_ARCH_LFLAGS="" @@ -31,12 +32,14 @@ while [ "$#" -gt 0 ]; do shift ;; -arch) + MAC_ARCH_CFLAGS="$MAC_ARCH_CFLAGS -arch $2" MAC_ARCH_CXXFLAGS="$MAC_ARCH_CXXFLAGS -arch $2" MAC_ARCH_LFLAGS="$MAC_ARCH_LFLAGS -arch $2" shift ;; -F*|-m*|-x*) LFLAGS="$LFLAGS \"$PARAM\"" + CFLAGS="$CFLAGS \"$PARAM\"" CXXFLAGS="$CXXFLAGS \"$PARAM\"" ;; -L*|-l*|-pthread) @@ -47,10 +50,12 @@ while [ "$#" -gt 0 ]; do INCLUDEPATH="$INCLUDEPATH \"$INC\"" ;; -f*|-D*) + CFLAGS="$CFLAGS \"$PARAM\"" CXXFLAGS="$CXXFLAGS \"$PARAM\"" ;; -Qoption) # Two-argument form for the Sun Compiler + CFLAGS="$CFLAGS $PARAM \"$2\"" CXXFLAGS="$CXXFLAGS $PARAM \"$2\"" shift ;; @@ -72,7 +77,7 @@ test -r Makefile && $MAKE distclean >/dev/null 2>&1 # Make sure output from possible previous tests is gone rm -f "$EXE" "${EXE}.exe" -set -- "$QMAKE" -qtconf "$QTCONF" -nocache -spec "$QMKSPEC" "CONFIG+=$QMAKE_CONFIG" "CONFIG+=android_app" "CONFIG-=debug_and_release app_bundle lib_bundle" "LIBS+=$LFLAGS" "LIBS+=$MAC_ARCH_LFLAGS" "INCLUDEPATH*=$INCLUDEPATH" "QMAKE_CXXFLAGS*=$CXXFLAGS" "QMAKE_CXXFLAGS+=$MAC_ARCH_CXXFLAGS" $QMAKE_ARGS "$SRCDIR/$TEST/$EXE.pro" -o "$OUTDIR/$TEST/Makefile" +set -- "$QMAKE" -qtconf "$QTCONF" -nocache -spec "$QMKSPEC" "CONFIG+=$QMAKE_CONFIG" "CONFIG+=android_app" "CONFIG-=debug_and_release app_bundle lib_bundle" "LIBS+=$LFLAGS" "LIBS+=$MAC_ARCH_LFLAGS" "INCLUDEPATH*=$INCLUDEPATH" "QMAKE_CFLAGS*=$CFLAGS" "QMAKE_CFLAGS+=$MAC_ARCH_CFLAGS" "QMAKE_CXXFLAGS*=$CXXFLAGS" "QMAKE_CXXFLAGS+=$MAC_ARCH_CXXFLAGS" $QMAKE_ARGS "$SRCDIR/$TEST/$EXE.pro" -o "$OUTDIR/$TEST/Makefile" if [ "$VERBOSE" = "yes" ]; then OUTDIR=$OUTDIR "$@" && $MAKE && SUCCESS=yes else diff --git a/config.tests/unix/opengles2/opengles2.pro b/config.tests/unix/opengles2/opengles2.pro index c4d76895a8..da30b453c6 100644 --- a/config.tests/unix/opengles2/opengles2.pro +++ b/config.tests/unix/opengles2/opengles2.pro @@ -2,7 +2,7 @@ SOURCES = opengles2.cpp INCLUDEPATH += $$QMAKE_INCDIR_OPENGL_ES2 for(p, QMAKE_LIBDIR_OPENGL_ES2) { - exists($$p):LIBS += -L$$p + LIBS += -L$$p } CONFIG -= qt diff --git a/config.tests/unix/opengles3/opengles3.pro b/config.tests/unix/opengles3/opengles3.pro index 6942b57327..720985f14d 100644 --- a/config.tests/unix/opengles3/opengles3.pro +++ b/config.tests/unix/opengles3/opengles3.pro @@ -6,7 +6,7 @@ SOURCES = opengles3.cpp INCLUDEPATH += $$QMAKE_INCDIR_OPENGL_ES2 for(p, QMAKE_LIBDIR_OPENGL_ES2) { - exists($$p):LIBS += -L$$p + LIBS += -L$$p } CONFIG -= qt diff --git a/config.tests/unix/opengles31/opengles31.pro b/config.tests/unix/opengles31/opengles31.pro index 1df9cedfcd..225180e1c6 100644 --- a/config.tests/unix/opengles31/opengles31.pro +++ b/config.tests/unix/opengles31/opengles31.pro @@ -6,7 +6,7 @@ SOURCES = opengles31.cpp INCLUDEPATH += $$QMAKE_INCDIR_OPENGL_ES2 for(p, QMAKE_LIBDIR_OPENGL_ES2) { - exists($$p):LIBS += -L$$p + LIBS += -L$$p } CONFIG -= qt diff --git a/examples/widgets/mainwindows/application/mainwindow.cpp b/examples/widgets/mainwindows/application/mainwindow.cpp index 4115b8245b..dc93fe4eb2 100644 --- a/examples/widgets/mainwindows/application/mainwindow.cpp +++ b/examples/widgets/mainwindows/application/mainwindow.cpp @@ -69,9 +69,11 @@ MainWindow::MainWindow() connect(textEdit->document(), &QTextDocument::contentsChanged, this, &MainWindow::documentWasModified); +#ifndef QT_NO_SESSIONMANAGER QGuiApplication::setFallbackSessionManagementEnabled(false); connect(qApp, &QGuiApplication::commitDataRequest, this, &MainWindow::commitData); +#endif setCurrentFile(QString()); setUnifiedTitleAndToolBarOnMac(true); @@ -397,7 +399,7 @@ QString MainWindow::strippedName(const QString &fullFileName) return QFileInfo(fullFileName).fileName(); } //! [49] - +#ifndef QT_NO_SESSIONMANAGER void MainWindow::commitData(QSessionManager &manager) { if (manager.allowsInteraction()) { @@ -409,3 +411,4 @@ void MainWindow::commitData(QSessionManager &manager) save(); } } +#endif diff --git a/examples/widgets/mainwindows/application/mainwindow.h b/examples/widgets/mainwindows/application/mainwindow.h index ee805f0caa..9e3e1e907a 100644 --- a/examples/widgets/mainwindows/application/mainwindow.h +++ b/examples/widgets/mainwindows/application/mainwindow.h @@ -80,7 +80,9 @@ private slots: bool saveAs(); void about(); void documentWasModified(); +#ifndef QT_NO_SESSIONMANAGER void commitData(QSessionManager &); +#endif private: void createActions(); diff --git a/mkspecs/common/winrt_winphone/qmake.conf b/mkspecs/common/winrt_winphone/qmake.conf index a9450b0c32..b5e0c7cc71 100644 --- a/mkspecs/common/winrt_winphone/qmake.conf +++ b/mkspecs/common/winrt_winphone/qmake.conf @@ -9,7 +9,7 @@ include(../angle.conf) MAKEFILE_GENERATOR = MSBUILD QMAKE_COMPILER = msvc QMAKE_PLATFORM = winrt win32 -CONFIG += incremental flat precompile_header autogen_precompile_source debug_and_release debug_and_release_target package_manifest rtti +CONFIG = package_manifest $$CONFIG incremental flat precompile_header autogen_precompile_source debug_and_release debug_and_release_target rtti DEFINES += UNICODE WIN32 QT_LARGEFILE_SUPPORT Q_BYTE_ORDER=Q_LITTLE_ENDIAN \ QT_NO_PRINTER QT_NO_PRINTDIALOG # TODO: Remove when printing is re-enabled @@ -95,6 +95,9 @@ VCSOLUTION_EXTENSION = .sln VCPROJ_KEYWORD = Qt4VSv1.0 WINRT_ASSETS_PATH = $$PWD/assets +WINRT_MANIFEST.capabilities = defaults +WINRT_MANIFEST.capabilities_device = defaults + include(../msvc-base.conf) unset(MSC_VER) diff --git a/mkspecs/devices/linux-rpi3-g++/qmake.conf b/mkspecs/devices/linux-rpi3-g++/qmake.conf new file mode 100644 index 0000000000..600d3e7dc1 --- /dev/null +++ b/mkspecs/devices/linux-rpi3-g++/qmake.conf @@ -0,0 +1,41 @@ +# qmake configuration for the Raspberry Pi 3 + +include(../common/linux_device_pre.conf) + +# I consider it a bug that this is required, but our EGL config.test _requires_ it +QMAKE_LFLAGS += -Wl,-rpath-link,$$[QT_SYSROOT]/opt/vc/lib + +VC_LIBRARY_PATH = /opt/vc/lib +VC_INCLUDE_PATH = =/opt/vc/include + +# terrible, they do not appear to resolve "=" in rpath! +VC_LINK_LINE = -L=$${VC_LIBRARY_PATH} -Wl,-rpath-link,$$[QT_SYSROOT]$${VC_LIBRARY_PATH} + +QMAKE_LIBDIR_OPENGL_ES2 = =$${VC_LIBRARY_PATH} +QMAKE_LIBDIR_EGL = $$QMAKE_LIBDIR_OPENGL_ES2 +QMAKE_LIBDIR_OPENVG = $$QMAKE_LIBDIR_OPENGL_ES2 + +QMAKE_INCDIR_EGL = \ + $${VC_INCLUDE_PATH} \ + $${VC_INCLUDE_PATH}/interface/vcos/pthreads \ + $${VC_INCLUDE_PATH}/interface/vmcs_host/linux + +QMAKE_INCDIR_OPENGL_ES2 = $${QMAKE_INCDIR_EGL} + +QMAKE_LIBS_OPENGL_ES2 = $${VC_LINK_LINE} -lGLESv2 + +# The official opt vc EGL references GLESv2 symbols: need to link it +QMAKE_LIBS_EGL = $${VC_LINK_LINE} -lEGL -lGLESv2 + +# We deliberately override the existing Qt CFLAGS as they might be problematic +QMAKE_CFLAGS = -march=armv8-a+crc -mtune=cortex-a53 -mfpu=crypto-neon-fp-armv8 -pipe -Os -mthumb +QMAKE_CXXFLAGS = $$QMAKE_CFLAGS -std=c++1z + +DISTRO_OPTS += hard-float +DISTRO_OPTS += deb-multi-arch + +EGLFS_DEVICE_INTEGRATION= eglfs_brcm + +include(../common/linux_arm_device_post.conf) + +load(qt_config) diff --git a/mkspecs/devices/linux-rpi3-g++/qplatformdefs.h b/mkspecs/devices/linux-rpi3-g++/qplatformdefs.h new file mode 100644 index 0000000000..5ae49b35dd --- /dev/null +++ b/mkspecs/devices/linux-rpi3-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 "../../linux-g++/qplatformdefs.h" diff --git a/mkspecs/features/egl.prf b/mkspecs/features/egl.prf index c3bdd9fdf4..9fa0c9e219 100644 --- a/mkspecs/features/egl.prf +++ b/mkspecs/features/egl.prf @@ -4,5 +4,5 @@ QMAKE_CFLAGS += $$QMAKE_CFLAGS_EGL QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_EGL LIBS += $$QMAKE_LFLAGS_EGL for(p, QMAKE_LIBDIR_EGL) { - exists($$p): LIBS_PRIVATE += -L$$p + LIBS_PRIVATE += -L$$p } diff --git a/mkspecs/features/qml_plugin.prf b/mkspecs/features/qml_plugin.prf index daedeca3a0..20b8eb4d53 100644 --- a/mkspecs/features/qml_plugin.prf +++ b/mkspecs/features/qml_plugin.prf @@ -27,7 +27,7 @@ CONFIG += relative_qt_rpath # Qt's QML plugins should be relocatable } isEmpty(TARGETPATH): TARGETPATH = $$eval(QT.$${CXX_MODULE}.name) -!no_cxx_module:win32:CONFIG(shared, static|shared) { +win32:CONFIG(shared, static|shared) { # Embed a VERSIONINFO resource into the plugin's DLL. isEmpty(VERSION): VERSION = $$MODULE_VERSION CONFIG += skip_target_version_ext diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf index e54841a678..03ec36ae3f 100644 --- a/mkspecs/features/qt.prf +++ b/mkspecs/features/qt.prf @@ -141,6 +141,15 @@ for(ever) { } } } + # Add capabilities as defined by modules used in the project + winrt { + MODULE_WINRT_CAPABILITIES = $$eval(QT.$${QTLIB}.winrt_capabilities) + !isEmpty(MODULE_WINRT_CAPABILITIES): \ + WINRT_MANIFEST.capabilities_default += $$MODULE_WINRT_CAPABILITIES + MODULE_WINRT_CAPABILITIES_DEVICE = $$eval(QT.$${QTLIB}.winrt_capabilities_device) + !isEmpty(MODULE_WINRT_CAPABILITIES_DEVICE): \ + WINRT_MANIFEST.capabilities_device_default += $$MODULE_WINRT_CAPABILITIES_DEVICE + } } !isEmpty(BAD_QT):error("Unknown module(s) in QT$$var_sfx: $$replace(BAD_QT, _private$, -private)") diff --git a/mkspecs/features/qt_module_pris.prf b/mkspecs/features/qt_module_pris.prf index 9c45350543..4dd9e25f9f 100644 --- a/mkspecs/features/qt_module_pris.prf +++ b/mkspecs/features/qt_module_pris.prf @@ -104,6 +104,9 @@ MODULE_FWD_PRI = $$mod_work_pfx/qt_lib_$${MODULE_ID}.pri "QT.$${MODULE_ID}.DEFINES = $$val_escape(MODULE_DEFINES)" \ "" \ "QT_MODULES += $$MODULE" + winrt: MODULE_PRI_CONT += \ + "QT.$${MODULE_ID}.winrt_capabilities =$$join(MODULE_WINRT_CAPABILITIES, " ", " ")" \ + "QT.$${MODULE_ID}.winrt_capabilities_device =$$join(MODULE_WINRT_CAPABILITIES_DEVICE, " ", " ")" write_file($$MODULE_PRI, MODULE_PRI_CONT)|error("Aborting.") !internal_module:!no_private_module { module_build_type += internal_module @@ -186,6 +189,7 @@ MODULE_FWD_PRI = $$mod_work_pfx/qt_lib_$${MODULE_ID}.pri for(var, $$list(VERSION MAJOR_VERSION MINOR_VERSION PATCH_VERSION \ name module depends run_depends plugin_types module_config CONFIG DEFINES \ priority includes bins libs frameworks libexecs plugins imports qml \ + winrt_capabilities winrt_capabilities_device \ )):defined(QT.$${mod}.$$var, var):cache(QT.$${mod}.$$var, transient) } cache(QT_MODULES, transient) diff --git a/mkspecs/features/resolve_target.prf b/mkspecs/features/resolve_target.prf index d6460c1d9d..5c3a46e117 100644 --- a/mkspecs/features/resolve_target.prf +++ b/mkspecs/features/resolve_target.prf @@ -33,7 +33,18 @@ win32 { mac { equals(TEMPLATE, lib) { lib_bundle { - QMAKE_RESOLVED_TARGET = $${QMAKE_RESOLVED_TARGET}$${TARGET}.framework/$${TARGET} + !isEmpty(QMAKE_FRAMEWORK_BUNDLE_NAME): \ + framework_target = $$QMAKE_FRAMEWORK_BUNDLE_NAME + else: \ + framework_target = $$TARGET + QMAKE_RESOLVED_BUNDLE = $${QMAKE_RESOLVED_TARGET}$${framework_target}.framework + !shallow_bundle { + TEMP_VERSION = $$section(VERSION, ., 0, 0) + isEmpty(TEMP_VERSION):TEMP_VERSION = A + QMAKE_RESOLVED_TARGET = $${QMAKE_RESOLVED_BUNDLE}/Versions/$${TEMP_VERSION}/$${TARGET} + } else { + QMAKE_RESOLVED_TARGET = $${QMAKE_RESOLVED_BUNDLE}/$${TARGET} + } } else { QMAKE_RESOLVED_TARGET = $${QMAKE_RESOLVED_TARGET}$${LIBPREFIX}$${TARGET} !plugin { @@ -46,7 +57,15 @@ win32 { } } else { app_bundle { - QMAKE_RESOLVED_TARGET = $${QMAKE_RESOLVED_TARGET}$${TARGET}.app/Contents/MacOS/$${TARGET} + !isEmpty(QMAKE_APPLICATION_BUNDLE_NAME): \ + app_target = $$QMAKE_APPLICATION_BUNDLE_NAME + else: \ + app_target = $$TARGET + QMAKE_RESOLVED_BUNDLE = $${QMAKE_RESOLVED_TARGET}$${app_target}.app + !shallow_bundle: \ + QMAKE_RESOLVED_TARGET = $${QMAKE_RESOLVED_BUNDLE}/Contents/MacOS/$${TARGET} + else: \ + QMAKE_RESOLVED_TARGET = $${QMAKE_RESOLVED_BUNDLE}/$${TARGET} } else { QMAKE_RESOLVED_TARGET = $${QMAKE_RESOLVED_TARGET}$${TARGET} } diff --git a/mkspecs/features/unix/dylib.prf b/mkspecs/features/unix/dylib.prf deleted file mode 100644 index 8b13789179..0000000000 --- a/mkspecs/features/unix/dylib.prf +++ /dev/null @@ -1 +0,0 @@ - diff --git a/mkspecs/features/winrt/package_manifest.prf b/mkspecs/features/winrt/package_manifest.prf index 3520fcdf93..291ebec6e9 100644 --- a/mkspecs/features/winrt/package_manifest.prf +++ b/mkspecs/features/winrt/package_manifest.prf @@ -112,10 +112,19 @@ # capability anymore and is assumed to be standard. *-msvc2015: WINRT_MANIFEST.capabilities += internetClient + contains(WINRT_MANIFEST.capabilities, defaults) { + WINRT_MANIFEST.capabilities -= defaults + WINRT_MANIFEST.capabilities += $$WINRT_MANIFEST.capabilities_default + } + + contains(WINRT_MANIFEST.capabilities_device, defaults) { + WINRT_MANIFEST.capabilities_device -= defaults + WINRT_MANIFEST.capabilities_device += $$WINRT_MANIFEST.capabilities_device_default + } + # Capabilities are given as a string list and may change with the configuration (network, sensors, etc.) WINRT_MANIFEST.capabilities = $$unique(WINRT_MANIFEST.capabilities) WINRT_MANIFEST.capabilities_device = $$unique(WINRT_MANIFEST.capabilities_device) - !isEmpty(WINRT_MANIFEST.capabilities)|!isEmpty(WINRT_MANIFEST.capabilities_device) { MANIFEST_CAPABILITIES += "<Capabilities>" for(CAPABILITY, WINRT_MANIFEST.capabilities): \ diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java index ac471bf126..0cfce2c6af 100644 --- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java +++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java @@ -153,16 +153,15 @@ public class QtActivityDelegate m_activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN); m_activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN); try { - int flags = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION; - flags |= View.SYSTEM_UI_FLAG_LAYOUT_STABLE; - flags |= View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION; - flags |= View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; - flags |= View.SYSTEM_UI_FLAG_FULLSCREEN; - - if (Build.VERSION.SDK_INT >= 19) + if (Build.VERSION.SDK_INT >= 19) { + int flags = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION; + flags |= View.SYSTEM_UI_FLAG_LAYOUT_STABLE; + flags |= View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION; + flags |= View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; + flags |= View.SYSTEM_UI_FLAG_FULLSCREEN; flags |= View.class.getDeclaredField("SYSTEM_UI_FLAG_IMMERSIVE_STICKY").getInt(null); - - m_activity.getWindow().getDecorView().setSystemUiVisibility(flags | View.INVISIBLE); + m_activity.getWindow().getDecorView().setSystemUiVisibility(flags | View.INVISIBLE); + } } catch (Exception e) { e.printStackTrace(); } diff --git a/src/corelib/global/qglobal.cpp b/src/corelib/global/qglobal.cpp index bf6db53040..5e2d7b7c1a 100644 --- a/src/corelib/global/qglobal.cpp +++ b/src/corelib/global/qglobal.cpp @@ -1174,13 +1174,13 @@ bool qSharedBuild() Q_DECL_NOTHROW QSysInfo::MacintoshVersion variable gives the version of the system on which the application is run. - \value MV_9 Mac OS 9 (unsupported) - \value MV_10_0 Mac OS X 10.0 (unsupported) - \value MV_10_1 Mac OS X 10.1 (unsupported) - \value MV_10_2 Mac OS X 10.2 (unsupported) - \value MV_10_3 Mac OS X 10.3 (unsupported) - \value MV_10_4 Mac OS X 10.4 (unsupported) - \value MV_10_5 Mac OS X 10.5 (unsupported) + \value MV_9 Mac OS 9 + \value MV_10_0 Mac OS X 10.0 + \value MV_10_1 Mac OS X 10.1 + \value MV_10_2 Mac OS X 10.2 + \value MV_10_3 Mac OS X 10.3 + \value MV_10_4 Mac OS X 10.4 + \value MV_10_5 Mac OS X 10.5 \value MV_10_6 Mac OS X 10.6 \value MV_10_7 Mac OS X 10.7 \value MV_10_8 OS X 10.8 diff --git a/src/corelib/io/qipaddress.cpp b/src/corelib/io/qipaddress.cpp index 13636ebb8b..02b12f635a 100644 --- a/src/corelib/io/qipaddress.cpp +++ b/src/corelib/io/qipaddress.cpp @@ -117,6 +117,9 @@ static bool parseIp4Internal(IPv4Address &address, const char *ptr, bool acceptL return false; else if (dotCount == 3 || *endptr == '\0') return true; + if (*endptr != '.') + return false; + ++dotCount; ptr = endptr + 1; } diff --git a/src/corelib/io/qlockfile_p.h b/src/corelib/io/qlockfile_p.h index b41b9b4604..d7f2a1d52d 100644 --- a/src/corelib/io/qlockfile_p.h +++ b/src/corelib/io/qlockfile_p.h @@ -81,7 +81,8 @@ public: // Returns \c true if the lock belongs to dead PID, or is old. // The attempt to delete it will tell us if it was really stale or not, though. bool isApparentlyStale() const; - static QString processNameByPid(qint64 pid); + // used in dbusmenu + Q_CORE_EXPORT static QString processNameByPid(qint64 pid); #ifdef Q_OS_UNIX static int checkFcntlWorksAfterFlock(const QString &fn); diff --git a/src/corelib/io/qlockfile_unix.cpp b/src/corelib/io/qlockfile_unix.cpp index 3455305858..7255414bdc 100644 --- a/src/corelib/io/qlockfile_unix.cpp +++ b/src/corelib/io/qlockfile_unix.cpp @@ -148,6 +148,8 @@ static QBasicMutex fcntlLock; static bool fcntlWorksAfterFlock(const QString &fn) { QMutexLocker lock(&fcntlLock); + if (fcntlOK.isDestroyed()) + return QLockFilePrivate::checkFcntlWorksAfterFlock(fn); bool *worksPtr = fcntlOK->object(fn); if (!worksPtr) { worksPtr = new bool(QLockFilePrivate::checkFcntlWorksAfterFlock(fn)); diff --git a/src/corelib/io/qresource.cpp b/src/corelib/io/qresource.cpp index ad24b43568..1ead114235 100644 --- a/src/corelib/io/qresource.cpp +++ b/src/corelib/io/qresource.cpp @@ -1259,8 +1259,10 @@ bool QResourceFileEngine::open(QIODevice::OpenMode flags) } if(flags & QIODevice::WriteOnly) return false; - if(!d->resource.isValid()) - return false; + if (!d->resource.isValid()) { + d->errorString = qt_error_string(ENOENT); + return false; + } return true; } diff --git a/src/corelib/tools/qdatetimeparser.cpp b/src/corelib/tools/qdatetimeparser.cpp index 867aea4184..c1abdf11a7 100644 --- a/src/corelib/tools/qdatetimeparser.cpp +++ b/src/corelib/tools/qdatetimeparser.cpp @@ -167,7 +167,7 @@ bool QDateTimeParser::setDigit(QDateTime &v, int index, int newVal) const break; } - if (!(node.type & (DaySection|DayOfWeekSectionShort|DayOfWeekSectionLong))) { + if (!(node.type & DaySectionMask)) { if (day < cachedDay) day = cachedDay; const int max = QDate(year, month, 1).daysInMonth(); @@ -633,6 +633,10 @@ int QDateTimeParser::sectionMaxSize(Section s, int count) const case Internal: case TimeSectionMask: case DateSectionMask: + case HourSectionMask: + case YearSectionMask: + case DayOfWeekSectionMask: + case DaySectionMask: qWarning("QDateTimeParser::sectionMaxSize: Invalid section %s", SectionNode::name(s).toLatin1().constData()); @@ -987,33 +991,27 @@ QDateTimeParser::StateNode QDateTimeParser::parse(QString &input, int &cursorPos if (state != Invalid) { if (parserType != QVariant::Time) { - if (year % 100 != year2digits) { - switch (isSet & (YearSection2Digits|YearSection)) { - case YearSection2Digits: + if (year % 100 != year2digits && (isSet & YearSection2Digits)) { + if (!(isSet & YearSection)) { year = (year / 100) * 100; year += year2digits; - break; - case ((uint)YearSection2Digits|(uint)YearSection): { + } else { conflicts = true; const SectionNode &sn = sectionNode(currentSectionIndex); if (sn.type == YearSection2Digits) { year = (year / 100) * 100; year += year2digits; } - break; } - default: - break; } } const QDate date(year, month, day); const int diff = dayofweek - date.dayOfWeek(); - if (diff != 0 && state == Acceptable - && isSet & (DayOfWeekSectionShort | DayOfWeekSectionLong)) { + if (diff != 0 && state == Acceptable && isSet & DayOfWeekSectionMask) { if (isSet & DaySection) conflicts = true; const SectionNode &sn = sectionNode(currentSectionIndex); - if (sn.type & (DayOfWeekSectionShort|DayOfWeekSectionLong) || currentSectionIndex == -1) { + if (sn.type & DayOfWeekSectionMask || currentSectionIndex == -1) { // dayofweek should be preferred day += diff; if (day <= 0) { @@ -1025,8 +1023,9 @@ QDateTimeParser::StateNode QDateTimeParser::parse(QString &input, int &cursorPos << diff << QDate(year, month, day).dayOfWeek(); } } + bool needfixday = false; - if (sectionType(currentSectionIndex) & (DaySection|DayOfWeekSectionShort|DayOfWeekSectionLong)) { + if (sectionType(currentSectionIndex) & DaySectionMask) { cachedDay = day; } else if (cachedDay > day) { day = cachedDay; @@ -1054,7 +1053,7 @@ QDateTimeParser::StateNode QDateTimeParser::parse(QString &input, int &cursorPos const SectionNode sn = sectionNode(i); if (sn.type & DaySection) { input.replace(sectionPos(sn), sectionSize(i), loc.toString(day)); - } else if (sn.type & (DayOfWeekSectionShort | DayOfWeekSectionLong)) { + } else if (sn.type & DayOfWeekSectionMask) { const int dayOfWeek = QDate(year, month, day).dayOfWeek(); const QLocale::FormatType dayFormat = (sn.type == DayOfWeekSectionShort @@ -1313,7 +1312,7 @@ int QDateTimeParser::findDay(const QString &str1, int startDay, int sectionIndex int bestCount = 0; if (!str1.isEmpty()) { const SectionNode &sn = sectionNode(sectionIndex); - if (!(sn.type & (DaySection|DayOfWeekSectionShort|DayOfWeekSectionLong))) { + if (!(sn.type & DaySectionMask)) { qWarning("QDateTimeParser::findDay Internal error"); return -1; } diff --git a/src/corelib/tools/qdatetimeparser_p.h b/src/corelib/tools/qdatetimeparser_p.h index ad403f695b..9689d88616 100644 --- a/src/corelib/tools/qdatetimeparser_p.h +++ b/src/corelib/tools/qdatetimeparser_p.h @@ -120,14 +120,20 @@ public: MinuteSection = 0x00008, Hour12Section = 0x00010, Hour24Section = 0x00020, - TimeSectionMask = (AmPmSection|MSecSection|SecondSection|MinuteSection|Hour12Section|Hour24Section), + HourSectionMask = (Hour12Section | Hour24Section), + TimeSectionMask = (MSecSection | SecondSection | MinuteSection | + HourSectionMask | AmPmSection), + DaySection = 0x00100, MonthSection = 0x00200, YearSection = 0x00400, YearSection2Digits = 0x00800, + YearSectionMask = YearSection | YearSection2Digits, DayOfWeekSectionShort = 0x01000, DayOfWeekSectionLong = 0x02000, - DateSectionMask = (DaySection|MonthSection|YearSection|YearSection2Digits|DayOfWeekSectionShort|DayOfWeekSectionLong), + DayOfWeekSectionMask = DayOfWeekSectionShort | DayOfWeekSectionLong, + DaySectionMask = DaySection | DayOfWeekSectionMask, + DateSectionMask = DaySectionMask | MonthSection | YearSectionMask, Internal = 0x10000, FirstSection = 0x20000 | Internal, @@ -138,7 +144,7 @@ public: FirstSectionIndex = -2, LastSectionIndex = -3, CalendarPopupIndex = -4 - }; // duplicated from qdatetimeedit.h + }; // extending qdatetimeedit.h's equivalent Q_DECLARE_FLAGS(Sections, Section) struct Q_CORE_EXPORT SectionNode { @@ -224,6 +230,7 @@ public: FieldInfo fieldInfo(int index) const; + void setDefaultLocale(const QLocale &loc) { defaultLocale = loc; } virtual QDateTime getMinimum() const; virtual QDateTime getMaximum() const; virtual int cursorPosition() const { return -1; } diff --git a/src/corelib/tools/qelapsedtimer_generic.cpp b/src/corelib/tools/qelapsedtimer_generic.cpp index e053d4ced4..8c724247be 100644 --- a/src/corelib/tools/qelapsedtimer_generic.cpp +++ b/src/corelib/tools/qelapsedtimer_generic.cpp @@ -85,7 +85,8 @@ void QElapsedTimer::start() Q_DECL_NOTHROW and then starting the timer again with start(), but it does so in one single operation, avoiding the need to obtain the clock value twice. - Restarting the timer makes it valid again. + Calling this function on a QElapsedTimer that is invalid + results in undefined behavior. The following example illustrates how to use this function to calibrate a parameter to a slow operation (for example, an iteration count) so that @@ -93,7 +94,7 @@ void QElapsedTimer::start() Q_DECL_NOTHROW \snippet qelapsedtimer/main.cpp 3 - \sa start(), invalidate(), elapsed() + \sa start(), invalidate(), elapsed(), isValid() */ qint64 QElapsedTimer::restart() Q_DECL_NOTHROW { @@ -106,8 +107,10 @@ qint64 QElapsedTimer::restart() Q_DECL_NOTHROW /*! \since 4.8 Returns the number of nanoseconds since this QElapsedTimer was last - started. Calling this function in a QElapsedTimer that was invalidated - will result in undefined results. + started. + + Calling this function on a QElapsedTimer that is invalid + results in undefined behavior. On platforms that do not provide nanosecond resolution, the value returned will be the best estimate available. @@ -121,10 +124,12 @@ qint64 QElapsedTimer::nsecsElapsed() const Q_DECL_NOTHROW /*! Returns the number of milliseconds since this QElapsedTimer was last - started. Calling this function in a QElapsedTimer that was invalidated - will result in undefined results. + started. - \sa start(), restart(), hasExpired(), invalidate() + Calling this function on a QElapsedTimer that is invalid + results in undefined behavior. + + \sa start(), restart(), hasExpired(), isValid(), invalidate() */ qint64 QElapsedTimer::elapsed() const Q_DECL_NOTHROW { @@ -172,7 +177,8 @@ qint64 QElapsedTimer::msecsTo(const QElapsedTimer &other) const Q_DECL_NOTHROW \a other was started before this object, the returned value will be negative. If it was started later, the returned value will be positive. - The return value is undefined if this object or \a other were invalidated. + Calling this function on or with a QElapsedTimer that is invalid + results in undefined behavior. \sa msecsTo(), elapsed() */ diff --git a/src/corelib/tools/qlocale.cpp b/src/corelib/tools/qlocale.cpp index 27d2e4c165..eccedca4c8 100644 --- a/src/corelib/tools/qlocale.cpp +++ b/src/corelib/tools/qlocale.cpp @@ -1832,7 +1832,7 @@ QTime QLocale::toTime(const QString &string, const QString &format) const QTime time; #ifndef QT_BOOTSTRAPPED QDateTimeParser dt(QVariant::Time, QDateTimeParser::FromString); - dt.defaultLocale = *this; + dt.setDefaultLocale(*this); if (dt.parseFormat(format)) dt.fromString(string, 0, &time); #else @@ -1863,7 +1863,7 @@ QDate QLocale::toDate(const QString &string, const QString &format) const QDate date; #ifndef QT_BOOTSTRAPPED QDateTimeParser dt(QVariant::Date, QDateTimeParser::FromString); - dt.defaultLocale = *this; + dt.setDefaultLocale(*this); if (dt.parseFormat(format)) dt.fromString(string, &date, 0); #else @@ -1896,7 +1896,7 @@ QDateTime QLocale::toDateTime(const QString &string, const QString &format) cons QDate date; QDateTimeParser dt(QVariant::DateTime, QDateTimeParser::FromString); - dt.defaultLocale = *this; + dt.setDefaultLocale(*this); if (dt.parseFormat(format) && dt.fromString(string, &date, &time)) return QDateTime(date, time); #else diff --git a/src/corelib/tools/qsimd_p.h b/src/corelib/tools/qsimd_p.h index a4fe8e67f8..8ddaed8032 100644 --- a/src/corelib/tools/qsimd_p.h +++ b/src/corelib/tools/qsimd_p.h @@ -483,7 +483,13 @@ static Q_ALWAYS_INLINE unsigned _bit_scan_forward(unsigned val) } #elif defined(Q_PROCESSOR_X86) // Bit scan functions for x86 -# if defined(Q_CC_MSVC) && !defined(Q_OS_WINCE) +# if defined(Q_CC_MSVC) +# if defined _WIN32_WCE && _WIN32_WCE < 0x800 +extern "C" unsigned char _BitScanForward(unsigned long* Index, unsigned long Mask); +extern "C" unsigned char _BitScanReverse(unsigned long* Index, unsigned long Mask); +# pragma intrinsic(_BitScanForward) +# pragma intrinsic(_BitScanReverse) +# endif // MSVC calls it _BitScanReverse and returns the carry flag, which we don't need static __forceinline unsigned long _bit_scan_reverse(uint val) { diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp index 5cbad2554c..9bfc46f32e 100644 --- a/src/corelib/tools/qstring.cpp +++ b/src/corelib/tools/qstring.cpp @@ -5844,7 +5844,9 @@ QString QString::toUpper_helper(QString &str) } /*! - \obsolete Use asprintf(), arg() or QTextStream instead. + \obsolete + + Use asprintf(), arg() or QTextStream instead. */ QString &QString::sprintf(const char *cformat, ...) { @@ -5900,7 +5902,9 @@ QString QString::asprintf(const char *cformat, ...) } /*! - \obsolete Use vasprintf(), arg() or QTextStream instead. + \obsolete + + Use vasprintf(), arg() or QTextStream instead. */ QString &QString::vsprintf(const char *cformat, va_list ap) { @@ -10574,7 +10578,7 @@ float QStringRef::toFloat(bool *ok) const \obsolete \fn QString Qt::escape(const QString &plain) - \sa QString::toHtmlEscaped() + Use QString::toHtmlEscaped() instead. */ /*! diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h index 83a2e6fc32..b2fa8faae8 100644 --- a/src/dbus/qdbusconnection_p.h +++ b/src/dbus/qdbusconnection_p.h @@ -259,6 +259,7 @@ private: const QVector<int> &metaTypes, int slotIdx); SignalHookHash::Iterator removeSignalHookNoLock(SignalHookHash::Iterator it); + void disconnectObjectTree(ObjectTreeNode &node); bool isServiceRegisteredByThread(const QString &serviceName); diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp index 105714ee64..6d4a27cdb5 100644 --- a/src/dbus/qdbusintegrator.cpp +++ b/src/dbus/qdbusintegrator.cpp @@ -1055,7 +1055,6 @@ QDBusConnectionPrivate::~QDBusConnectionPrivate() qPrintable(name)); closeConnection(); - rootNode.children.clear(); // free resources qDeleteAll(cachedMetaObjects); if (mode == ClientMode || mode == PeerMode) { @@ -1077,6 +1076,19 @@ QDBusConnectionPrivate::~QDBusConnectionPrivate() } } +void QDBusConnectionPrivate::disconnectObjectTree(QDBusConnectionPrivate::ObjectTreeNode &haystack) +{ + QDBusConnectionPrivate::ObjectTreeNode::DataList::Iterator it = haystack.children.begin(); + + while (it != haystack.children.end()) { + disconnectObjectTree(*it); + it++; + } + + if (haystack.obj) + haystack.obj->disconnect(this); +} + void QDBusConnectionPrivate::closeConnection() { QDBusWriteLocker locker(CloseConnectionAction, this); @@ -1100,6 +1112,18 @@ void QDBusConnectionPrivate::closeConnection() } qDeleteAll(pendingCalls); + + // Disconnect all signals from signal hooks and from the object tree to + // avoid QObject::destroyed being sent to dbus daemon thread which has + // already quit. + SignalHookHash::iterator sit = signalHooks.begin(); + while (sit != signalHooks.end()) { + sit.value().obj->disconnect(this); + sit++; + } + + disconnectObjectTree(rootNode); + rootNode.children.clear(); // free resources } void QDBusConnectionPrivate::checkThread() diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 128966a35a..3b1ee8ec03 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -2147,7 +2147,6 @@ static QGlyphRun glyphRunWithInfo(QFontEngine *fontEngine, QGlyphRunPrivate *d = QGlyphRunPrivate::get(glyphRun); int rangeStart = textPosition; - logClusters += textPosition; while (*logClusters != glyphsStart && rangeStart < textPosition + textLength) { ++logClusters; ++rangeStart; @@ -2356,9 +2355,9 @@ QList<QGlyphRun> QTextLine::glyphRuns(int from, int length) const width, glyphsStart + start, glyphsStart + end, - logClusters, - iterator.itemStart, - iterator.itemLength)); + logClusters + relativeFrom, + relativeFrom + si.position, + relativeTo - relativeFrom + 1)); for (int i = 0; i < subLayout.numGlyphs; ++i) { QFixed justification = QFixed::fromFixed(subLayout.justifications[i].space_18d6); pos.rx() += (subLayout.advances[i] + justification).toReal(); @@ -2386,9 +2385,9 @@ QList<QGlyphRun> QTextLine::glyphRuns(int from, int length) const width, glyphsStart + start, glyphsStart + end, - logClusters, - iterator.itemStart, - iterator.itemLength); + logClusters + relativeFrom, + relativeFrom + si.position, + relativeTo - relativeFrom + 1); if (!glyphRun.isEmpty()) glyphRuns.append(glyphRun); } else { @@ -2402,9 +2401,9 @@ QList<QGlyphRun> QTextLine::glyphRuns(int from, int length) const width, glyphsStart, glyphsEnd, - logClusters, - iterator.itemStart, - iterator.itemLength); + logClusters + relativeFrom, + relativeFrom + si.position, + relativeTo - relativeFrom + 1); if (!glyphRun.isEmpty()) glyphRuns.append(glyphRun); } diff --git a/src/network/access/qnetworkreply.cpp b/src/network/access/qnetworkreply.cpp index 876e095a0c..3f17b68e79 100644 --- a/src/network/access/qnetworkreply.cpp +++ b/src/network/access/qnetworkreply.cpp @@ -141,10 +141,12 @@ QNetworkReplyPrivate::QNetworkReplyPrivate() \value TooManyRedirectsError while following redirects, the maximum limit was reached. The limit is by default set to 50 or as set by QNetworkRequest::setMaxRedirectsAllowed(). + (This value was introduced in 5.6.) \value InsecureRedirectError while following redirects, the network access API detected a redirect from a encrypted protocol (https) to an unencrypted one (http). + (This value was introduced in 5.6.) \value ProxyConnectionRefusedError the connection to the proxy server was refused (the proxy server is not accepting requests) diff --git a/src/network/access/qnetworkrequest.cpp b/src/network/access/qnetworkrequest.cpp index f674cd5c2e..2ee85fd049 100644 --- a/src/network/access/qnetworkrequest.cpp +++ b/src/network/access/qnetworkrequest.cpp @@ -146,11 +146,12 @@ QT_BEGIN_NAMESPACE Replies only, type: QMetaType::QUrl (no default) If present, it indicates that the server is redirecting the request to a different URL. The Network Access API does not by - default follow redirections: it's up to the application to + default follow redirections: the application can determine if the requested redirection should be allowed, - according to its security policies. However, if - QNetworkRequest::FollowRedirectsAttribute is set, then this attribute - will not be present in the reply. + according to its security policies, or it can set + QNetworkRequest::FollowRedirectsAttribute to true (in which case + the redirection will be followed and this attribute will not + be present in the reply). The returned URL might be relative. Use QUrl::resolved() to create an absolute URL out of it. @@ -271,6 +272,7 @@ QT_BEGIN_NAMESPACE Indicates whether the Network Access API should automatically follow a HTTP redirect response or not. Currently redirects that are insecure, that is redirecting from "https" to "http" protocol, are not allowed. + (This value was introduced in 5.6.) \value User Special type. Additional information can be passed in diff --git a/src/network/bearer/qnetworkconfigmanager_p.cpp b/src/network/bearer/qnetworkconfigmanager_p.cpp index 232875f43c..f2a79319a1 100644 --- a/src/network/bearer/qnetworkconfigmanager_p.cpp +++ b/src/network/bearer/qnetworkconfigmanager_p.cpp @@ -420,6 +420,8 @@ void QNetworkConfigurationManagerPrivate::updateConfigurations() if (generic) { if (!envOK || skipGeneric <= 0) sessionEngines.append(generic); + else + delete generic; } } diff --git a/src/network/kernel/qnetworkinterface_winrt.cpp b/src/network/kernel/qnetworkinterface_winrt.cpp index 1cbc4d686f..24ac3df52f 100644 --- a/src/network/kernel/qnetworkinterface_winrt.cpp +++ b/src/network/kernel/qnetworkinterface_winrt.cpp @@ -92,6 +92,7 @@ static QNetworkInterfacePrivate *interfaceFromProfile(IConnectionProfile *profil Q_ASSERT_SUCCEEDED(hr); if (connectivityLevel != NetworkConnectivityLevel_None) iface->flags = QNetworkInterface::IsUp | QNetworkInterface::IsRunning; + iface->flags |= QNetworkInterface::CanBroadcast; ComPtr<INetworkAdapter> adapter; hr = profile->get_NetworkAdapter(&adapter); diff --git a/src/network/kernel/qnetworkproxy_win.cpp b/src/network/kernel/qnetworkproxy_win.cpp index 832a3badb9..fe9f088062 100644 --- a/src/network/kernel/qnetworkproxy_win.cpp +++ b/src/network/kernel/qnetworkproxy_win.cpp @@ -47,6 +47,7 @@ #include <qurl.h> #include <private/qsystemlibrary_p.h> #include <qnetworkinterface.h> +#include <qdebug.h> #include <string.h> #include <qt_windows.h> @@ -596,8 +597,16 @@ QList<QNetworkProxy> QNetworkProxyFactory::systemProxyForQuery(const QNetworkPro url.setScheme(QLatin1String("https")); } + QString urlQueryString = url.toString(); + if (urlQueryString.size() > 2083) { + // calls to WinHttpGetProxyForUrl with urls longer than 2083 characters + // fail with error code ERROR_INVALID_PARAMETER(87), so we truncate it + qWarning("Proxy query URL too long for windows API, try with truncated URL"); + urlQueryString = url.toString().left(2083); + } + bool getProxySucceeded = ptrWinHttpGetProxyForUrl(sp->hHttpSession, - (LPCWSTR)url.toString().utf16(), + (LPCWSTR)urlQueryString.utf16(), &sp->autoProxyOptions, &proxyInfo); DWORD getProxyError = GetLastError(); @@ -614,7 +623,7 @@ QList<QNetworkProxy> QNetworkProxyFactory::systemProxyForQuery(const QNetworkPro sp->autoProxyOptions.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL; sp->autoProxyOptions.lpszAutoConfigUrl = (LPCWSTR)sp->autoConfigUrl.utf16(); getProxySucceeded = ptrWinHttpGetProxyForUrl(sp->hHttpSession, - (LPCWSTR)url.toString().utf16(), + (LPCWSTR)urlQueryString.utf16(), &sp->autoProxyOptions, &proxyInfo); getProxyError = GetLastError(); @@ -627,7 +636,7 @@ QList<QNetworkProxy> QNetworkProxyFactory::systemProxyForQuery(const QNetworkPro // But now we've to enable it (http://msdn.microsoft.com/en-us/library/aa383153%28v=VS.85%29.aspx) sp->autoProxyOptions.fAutoLogonIfChallenged = TRUE; getProxySucceeded = ptrWinHttpGetProxyForUrl(sp->hHttpSession, - (LPCWSTR)url.toString().utf16(), + (LPCWSTR)urlQueryString.utf16(), &sp->autoProxyOptions, &proxyInfo); getProxyError = GetLastError(); diff --git a/src/network/network.pro b/src/network/network.pro index cdea190222..fed14616af 100644 --- a/src/network/network.pro +++ b/src/network/network.pro @@ -32,6 +32,10 @@ MODULE_PLUGIN_TYPES = \ ANDROID_PERMISSIONS += \ android.permission.ACCESS_NETWORK_STATE +MODULE_WINRT_CAPABILITIES = \ + internetClient \ + internetClientServer + MODULE_PLUGIN_TYPES = \ bearer load(qt_module) diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp index 0f632abbb3..45ed1465f2 100644 --- a/src/network/socket/qnativesocketengine_winrt.cpp +++ b/src/network/socket/qnativesocketengine_winrt.cpp @@ -304,8 +304,10 @@ bool QNativeSocketEngine::connectToHostByName(const QString &name, quint16 port) Q_ASSERT_SUCCEEDED(hr); d->socketState = QAbstractSocket::ConnectingState; - hr = d->connectOp->put_Completed(Callback<IAsyncActionCompletedHandler>( + hr = QEventDispatcherWinRT::runOnXamlThread([d]() { + return d->connectOp->put_Completed(Callback<IAsyncActionCompletedHandler>( d, &QNativeSocketEnginePrivate::handleConnectToHost).Get()); + }); Q_ASSERT_SUCCEEDED(hr); return d->socketState == QAbstractSocket::ConnectedState; @@ -315,50 +317,53 @@ bool QNativeSocketEngine::bind(const QHostAddress &address, quint16 port) { Q_D(QNativeSocketEngine); HRESULT hr; - ComPtr<IHostName> hostAddress; + hr = QEventDispatcherWinRT::runOnXamlThread([address, d, port, this]() { + HRESULT hr; + ComPtr<IHostName> hostAddress; - if (address != QHostAddress::Any && address != QHostAddress::AnyIPv4 && address != QHostAddress::AnyIPv6) { - ComPtr<IHostNameFactory> hostNameFactory; - hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_HostName).Get(), - &hostNameFactory); - Q_ASSERT_SUCCEEDED(hr); - const QString addressString = address.toString(); - HStringReference addressRef(reinterpret_cast<LPCWSTR>(addressString.utf16())); - hr = hostNameFactory->CreateHostName(addressRef.Get(), &hostAddress); - RETURN_FALSE_IF_FAILED("QNativeSocketEngine::bind: Could not create hostname."); - } + if (address != QHostAddress::Any && address != QHostAddress::AnyIPv4 && address != QHostAddress::AnyIPv6) { + ComPtr<IHostNameFactory> hostNameFactory; + hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_HostName).Get(), + &hostNameFactory); + RETURN_HR_IF_FAILED("QNativeSocketEngine::bind: Could not obtain hostname factory"); + const QString addressString = address.toString(); + HStringReference addressRef(reinterpret_cast<LPCWSTR>(addressString.utf16())); + hr = hostNameFactory->CreateHostName(addressRef.Get(), &hostAddress); + RETURN_HR_IF_FAILED("QNativeSocketEngine::bind: Could not create hostname."); + } - QString portQString = port ? QString::number(port) : QString(); - HStringReference portString(reinterpret_cast<LPCWSTR>(portQString.utf16())); + QString portQString = port ? QString::number(port) : QString(); + HStringReference portString(reinterpret_cast<LPCWSTR>(portQString.utf16())); - ComPtr<IAsyncAction> op; - if (d->socketType == QAbstractSocket::TcpSocket) { - if (!d->tcpListener) { - hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_StreamSocketListener).Get(), - &d->tcpListener); - Q_ASSERT_SUCCEEDED(hr); - } + ComPtr<IAsyncAction> op; + if (d->socketType == QAbstractSocket::TcpSocket) { + if (!d->tcpListener) { + hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_StreamSocketListener).Get(), + &d->tcpListener); + RETURN_HR_IF_FAILED("QNativeSocketEngine::bind: Could not create tcp listener"); + } - hr = QEventDispatcherWinRT::runOnXamlThread([d]() { - return d->tcpListener->add_ConnectionReceived( + hr = d->tcpListener->add_ConnectionReceived( Callback<ClientConnectedHandler>(d, &QNativeSocketEnginePrivate::handleClientConnection).Get(), &d->connectionToken); - }); - Q_ASSERT_SUCCEEDED(hr); - hr = d->tcpListener->BindEndpointAsync(hostAddress.Get(), portString.Get(), &op); - } else if (d->socketType == QAbstractSocket::UdpSocket) { - hr = d->udpSocket()->BindEndpointAsync(hostAddress.Get(), portString.Get(), &op); - } - if (hr == E_ACCESSDENIED) { - qErrnoWarning(hr, "Unable to bind socket (%s:%hu/%s). Please check your manifest capabilities.", - qPrintable(address.toString()), port, socketDescription(this).constData()); - return false; - } - Q_ASSERT_SUCCEEDED(hr); + RETURN_HR_IF_FAILED("QNativeSocketEngine::bind: Could not register client connection callback"); + hr = d->tcpListener->BindEndpointAsync(hostAddress.Get(), portString.Get(), &op); + } else if (d->socketType == QAbstractSocket::UdpSocket) { + hr = d->udpSocket()->BindEndpointAsync(hostAddress.Get(), portString.Get(), &op); + } + if (hr == E_ACCESSDENIED) { + qErrnoWarning(hr, "Unable to bind socket (%s:%hu/%s). Please check your manifest capabilities.", + qPrintable(address.toString()), port, socketDescription(this).constData()); + return hr; + } + RETURN_HR_IF_FAILED("QNativeSocketEngine::bind: Unable to bind socket"); - hr = op->put_Completed(Callback<IAsyncActionCompletedHandler>(d, &QNativeSocketEnginePrivate::handleBindCompleted).Get()); - Q_ASSERT_SUCCEEDED(hr); - hr = QWinRTFunctions::await(op); + hr = op->put_Completed(Callback<IAsyncActionCompletedHandler>(d, &QNativeSocketEnginePrivate::handleBindCompleted).Get()); + RETURN_HR_IF_FAILED("QNativeSocketEngine::bind: Could not register bind callback"); + hr = QWinRTFunctions::await(op); + RETURN_HR_IF_FAILED("QNativeSocketEngine::bind: Could not wait for bind to finish"); + return S_OK; + }); Q_ASSERT_SUCCEEDED(hr); d->socketState = QAbstractSocket::BoundState; @@ -410,7 +415,9 @@ int QNativeSocketEngine::accept() socketDescription(this).constData()); return -1; } - hr = op->put_Completed(Callback<SocketReadCompletedHandler>(d, &QNativeSocketEnginePrivate::handleReadyRead).Get()); + hr = QEventDispatcherWinRT::runOnXamlThread([d, op]() { + return op->put_Completed(Callback<SocketReadCompletedHandler>(d, &QNativeSocketEnginePrivate::handleReadyRead).Get()); + }); if (FAILED(hr)) { qErrnoWarning(hr, "accept(): Failed to set socket read callback (%s).", socketDescription(this).constData()); @@ -781,18 +788,22 @@ void QNativeSocketEngine::establishRead() Q_D(QNativeSocketEngine); HRESULT hr; - ComPtr<IInputStream> stream; - hr = d->tcpSocket()->get_InputStream(&stream); - RETURN_VOID_IF_FAILED("Failed to get socket input stream"); + hr = QEventDispatcherWinRT::runOnXamlThread([d]() { + ComPtr<IInputStream> stream; + HRESULT hr = d->tcpSocket()->get_InputStream(&stream); + RETURN_HR_IF_FAILED("QNativeSocketEngine::establishRead: Failed to get socket input stream"); - ComPtr<IBuffer> buffer; - hr = g->bufferFactory->Create(READ_BUFFER_SIZE, &buffer); - Q_ASSERT_SUCCEEDED(hr); + ComPtr<IBuffer> buffer; + hr = g->bufferFactory->Create(READ_BUFFER_SIZE, &buffer); + RETURN_HR_IF_FAILED("QNativeSocketEngine::establishRead: Failed to create buffer"); - ComPtr<IAsyncBufferOperation> op; - hr = stream->ReadAsync(buffer.Get(), READ_BUFFER_SIZE, InputStreamOptions_Partial, &op); - RETURN_VOID_IF_FAILED("Failed to initiate socket read"); - hr = op->put_Completed(Callback<SocketReadCompletedHandler>(d, &QNativeSocketEnginePrivate::handleReadyRead).Get()); + ComPtr<IAsyncBufferOperation> op; + hr = stream->ReadAsync(buffer.Get(), READ_BUFFER_SIZE, InputStreamOptions_Partial, &op); + RETURN_HR_IF_FAILED("QNativeSocketEngine::establishRead: Failed to initiate socket read"); + hr = op->put_Completed(Callback<SocketReadCompletedHandler>(d, &QNativeSocketEnginePrivate::handleReadyRead).Get()); + RETURN_HR_IF_FAILED("QNativeSocketEngine::establishRead: Failed to register read callback"); + return S_OK; + }); Q_ASSERT_SUCCEEDED(hr); } @@ -814,7 +825,10 @@ bool QNativeSocketEnginePrivate::createNewSocket(QAbstractSocket::SocketType soc hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_DatagramSocket).Get(), &socket); Q_ASSERT_SUCCEEDED(hr); socketDescriptor = qintptr(socket.Detach()); - hr = udpSocket()->add_MessageReceived(Callback<DatagramReceivedHandler>(this, &QNativeSocketEnginePrivate::handleNewDatagram).Get(), &connectionToken); + hr = QEventDispatcherWinRT::runOnXamlThread([this]() { + HRESULT hr = udpSocket()->add_MessageReceived(Callback<DatagramReceivedHandler>(this, &QNativeSocketEnginePrivate::handleNewDatagram).Get(), &connectionToken); + return hr; + }); Q_ASSERT_SUCCEEDED(hr); break; } @@ -1242,7 +1256,7 @@ HRESULT QNativeSocketEnginePrivate::handleReadyRead(IAsyncBufferOperation *async // that the connection was closed. The socket cannot be closed here, as the subsequent read // might fail then. if (status == Error || status == Canceled) { - setError(QAbstractSocket::NetworkError, RemoteHostClosedErrorString); + setError(QAbstractSocket::RemoteHostClosedError, RemoteHostClosedErrorString); socketState = QAbstractSocket::UnconnectedState; if (notifyOnRead) emit q->readReady(); @@ -1261,7 +1275,7 @@ HRESULT QNativeSocketEnginePrivate::handleReadyRead(IAsyncBufferOperation *async // the closing of the socket won't be communicated to the caller. So only the error is set. The // actual socket close happens inside of read. if (!bufferLength) { - setError(QAbstractSocket::NetworkError, RemoteHostClosedErrorString); + setError(QAbstractSocket::RemoteHostClosedError, RemoteHostClosedErrorString); socketState = QAbstractSocket::UnconnectedState; if (notifyOnRead) emit q->readReady(); @@ -1307,7 +1321,9 @@ HRESULT QNativeSocketEnginePrivate::handleReadyRead(IAsyncBufferOperation *async socketDescription(q).constData()); return S_OK; } - hr = op->put_Completed(Callback<SocketReadCompletedHandler>(this, &QNativeSocketEnginePrivate::handleReadyRead).Get()); + hr = QEventDispatcherWinRT::runOnXamlThread([op, this]() { + return op->put_Completed(Callback<SocketReadCompletedHandler>(this, &QNativeSocketEnginePrivate::handleReadyRead).Get()); + }); if (FAILED(hr)) { qErrnoWarning(hr, "handleReadyRead(): Failed to set socket read callback (%s).", socketDescription(q).constData()); diff --git a/src/platformsupport/dbustray/qdbustrayicon.cpp b/src/platformsupport/dbustray/qdbustrayicon.cpp index 5351bc9f59..c8de50ebe1 100644 --- a/src/platformsupport/dbustray/qdbustrayicon.cpp +++ b/src/platformsupport/dbustray/qdbustrayicon.cpp @@ -53,13 +53,19 @@ #include <qloggingcategory.h> #include <qplatformintegration.h> #include <qplatformservices.h> +#include <qdbusconnectioninterface.h> +#include <private/qlockfile_p.h> #include <private/qguiapplication_p.h> +// Defined in Windows headers which get included by qlockfile_p.h +#undef interface + QT_BEGIN_NAMESPACE Q_LOGGING_CATEGORY(qLcTray, "qt.qpa.tray") static const QString KDEItemFormat = QStringLiteral("org.kde.StatusNotifierItem-%1-%2"); +static const QString KDEWatcherService = QStringLiteral("org.kde.StatusNotifierWatcher"); static const QString TempFileTemplate = QDir::tempPath() + QStringLiteral("/qt-trayicon-XXXXXX.png"); static const QString XdgNotificationService = QStringLiteral("org.freedesktop.Notifications"); static const QString XdgNotificationPath = QStringLiteral("/org/freedesktop/Notifications"); @@ -142,9 +148,17 @@ void QDBusTrayIcon::setStatus(const QString &status) QTemporaryFile *QDBusTrayIcon::tempIcon(const QIcon &icon) { - // Hack for Unity, which doesn't handle icons sent across D-Bus: + // Hack for indicator-application, which doesn't handle icons sent across D-Bus: // save the icon to a temp file and set the icon name to that filename. - static bool necessary = (QGuiApplicationPrivate::platformIntegration()->services()->desktopEnvironment().split(':').contains("UNITY")); + static bool necessity_checked = false; + static bool necessary = false; + if (!necessity_checked) { + QDBusConnection session = QDBusConnection::sessionBus(); + uint pid = session.interface()->servicePid(KDEWatcherService).value(); + QString processName = QLockFilePrivate::processNameByPid(pid); + necessary = processName.endsWith(QStringLiteral("indicator-application-service")); + necessity_checked = true; + } if (!necessary) return Q_NULLPTR; QTemporaryFile *ret = new QTemporaryFile(TempFileTemplate, this); diff --git a/src/plugins/platforms/android/qandroidplatformtheme.cpp b/src/plugins/platforms/android/qandroidplatformtheme.cpp index f8d0b9c8ba..3949113240 100644 --- a/src/plugins/platforms/android/qandroidplatformtheme.cpp +++ b/src/plugins/platforms/android/qandroidplatformtheme.cpp @@ -368,6 +368,9 @@ QAndroidPlatformTheme::QAndroidPlatformTheme(QAndroidPlatformNativeInterface *an // default in case the style has not set a font m_systemFont = QFont(QLatin1String("Roboto"), 14.0 * 100 / 72); // keep default size the same after changing from 100 dpi to 72 dpi + + // by default use native menu bar + QCoreApplication::setAttribute(Qt::AA_DontUseNativeMenuBar, false); } QPlatformMenuBar *QAndroidPlatformTheme::createPlatformMenuBar() const diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm index cbb4888718..a2e3b9a949 100644 --- a/src/plugins/platforms/cocoa/qnsview.mm +++ b/src/plugins/platforms/cocoa/qnsview.mm @@ -170,6 +170,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil; } m_isMenuView = false; + self.focusRingType = NSFocusRingTypeNone; } return self; } diff --git a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp index 80885df536..c4673edb11 100644 --- a/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp +++ b/src/plugins/platforms/eglfs/deviceintegration/eglfs_kms/qeglfskmsdevice.cpp @@ -429,7 +429,7 @@ void QEglFSKmsDevice::createScreens() Q_FOREACH (QPlatformScreen *screen, siblings) static_cast<QEglFSKmsScreen *>(screen)->setVirtualSiblings(siblings); - if (primaryScreen) + if (primaryScreen && m_integration->hwCursor()) m_globalCursor = new QEglFSKmsCursor(primaryScreen); } } diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp index 9b7f9cd5b0..562372d0b8 100644 --- a/src/plugins/platforms/winrt/qwinrtscreen.cpp +++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp @@ -419,6 +419,23 @@ static inline Qt::Key qKeyFromVirtual(VirtualKey key) } } +// Some keys like modifiers, caps lock etc. should not be automatically repeated if the key is held down +static inline bool shouldAutoRepeat(Qt::Key key) +{ + switch (key) { + case Qt::Key_Shift: + case Qt::Key_Control: + case Qt::Key_Alt: + case Qt::Key_Meta: + case Qt::Key_CapsLock: + case Qt::Key_NumLock: + case Qt::Key_ScrollLock: + return false; + default: + return true; + } +} + static inline Qt::Key qKeyFromCode(quint32 code, int mods) { if (code >= 'a' && code <= 'z') @@ -873,12 +890,33 @@ HRESULT QWinRTScreen::onKeyDown(ABI::Windows::UI::Core::ICoreWindow *, ABI::Wind Q_ASSERT_SUCCEEDED(hr); Qt::Key key = qKeyFromVirtual(virtualKey); - // Defer character key presses to onCharacterReceived - if (key == Qt::Key_unknown || (key >= Qt::Key_Space && key <= Qt::Key_ydiaeresis)) { + + const bool wasPressed = d->activeKeys.contains(key); + if (wasPressed) { + if (!shouldAutoRepeat(key)) + return S_OK; + + // If the key was pressed before trigger a key release before the next key press + QWindowSystemInterface::handleExtendedKeyEvent( + topWindow(), + QEvent::KeyRelease, + key, + keyboardModifiers(), + !status.ScanCode ? -1 : status.ScanCode, + virtualKey, + 0, + QString(), + status.WasKeyDown, + !status.RepeatCount ? 1 : status.RepeatCount, + false); + } else { d->activeKeys.insert(key, KeyInfo(virtualKey)); - return S_OK; } + // Defer character key presses to onCharacterReceived + if (key == Qt::Key_unknown || (key >= Qt::Key_Space && key <= Qt::Key_ydiaeresis)) + return S_OK; + QWindowSystemInterface::handleExtendedKeyEvent( topWindow(), QEvent::KeyPress, @@ -888,7 +926,7 @@ HRESULT QWinRTScreen::onKeyDown(ABI::Windows::UI::Core::ICoreWindow *, ABI::Wind virtualKey, 0, QString(), - status.RepeatCount > 1, + status.WasKeyDown, !status.RepeatCount ? 1 : status.RepeatCount, false); return S_OK; @@ -915,7 +953,7 @@ HRESULT QWinRTScreen::onKeyUp(ABI::Windows::UI::Core::ICoreWindow *, ABI::Window virtualKey, 0, info.text, - status.RepeatCount > 1, + false, // The final key release does not have autoRepeat set on Windows !status.RepeatCount ? 1 : status.RepeatCount, false); return S_OK; @@ -948,7 +986,7 @@ HRESULT QWinRTScreen::onCharacterReceived(ICoreWindow *, ICharacterReceivedEvent virtualKey, 0, text, - status.RepeatCount > 1, + status.WasKeyDown, !status.RepeatCount ? 1 : status.RepeatCount, false); d->activeKeys.insert(key, KeyInfo(text, virtualKey)); diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp index d5b4ae218f..f4f758df6c 100644 --- a/src/testlib/qtestcase.cpp +++ b/src/testlib/qtestcase.cpp @@ -123,6 +123,7 @@ static void stackTrace() char cmd[512]; qsnprintf(cmd, 512, "gdb --pid %d 2>/dev/null <<EOF\n" "set prompt\n" + "set height 0\n" "thread apply all where full\n" "detach\n" "quit\n" diff --git a/src/testlib/qtestcase.qdoc b/src/testlib/qtestcase.qdoc index f3de8964ac..85f71fc27f 100644 --- a/src/testlib/qtestcase.qdoc +++ b/src/testlib/qtestcase.qdoc @@ -528,6 +528,7 @@ \value Press The key is pressed. \value Release The key is released. \value Click The key is clicked (pressed and released). + \value Shortcut A shortcut is activated. This value has been added in Qt 5.6. */ /*! \enum QTest::MouseAction diff --git a/src/tools/rcc/main.cpp b/src/tools/rcc/main.cpp index e71ea57389..423b566896 100644 --- a/src/tools/rcc/main.cpp +++ b/src/tools/rcc/main.cpp @@ -250,6 +250,11 @@ int runRcc(int argc, char *argv[]) // Make sure fwrite to stdout doesn't do LF->CRLF if (library.format() == RCCResourceLibrary::Binary) _setmode(_fileno(stdout), _O_BINARY); + // Make sure QIODevice does not do LF->CRLF, + // otherwise we'll end up in CRCRLF instead of + // CRLF. + if (list) + mode &= ~QIODevice::Text; #endif // Q_OS_WIN // using this overload close() only flushes. out.open(stdout, mode); diff --git a/src/widgets/itemviews/qtreeview.cpp b/src/widgets/itemviews/qtreeview.cpp index 8031d538a6..cecaa4d8fb 100644 --- a/src/widgets/itemviews/qtreeview.cpp +++ b/src/widgets/itemviews/qtreeview.cpp @@ -2556,7 +2556,7 @@ void QTreeView::rowsInserted(const QModelIndex &parent, int start, int end) if (((parentItem != -1) && d->viewItems.at(parentItem).expanded) || (parent == d->root)) { d->doDelayedItemsLayout(); - } else if (parentItem != -1 && (d->model->rowCount(parent) == end - start + 1)) { + } else if (parentItem != -1 && parentRowCount == delta) { // the parent just went from 0 children to more. update to re-paint the decoration d->viewItems[parentItem].hasChildren = true; viewport()->update(); diff --git a/src/widgets/util/qundostack.cpp b/src/widgets/util/qundostack.cpp index 7f6a56e0ec..1a3ff58793 100644 --- a/src/widgets/util/qundostack.cpp +++ b/src/widgets/util/qundostack.cpp @@ -930,7 +930,7 @@ QAction *QUndoStack::createRedoAction(QObject *parent, const QString &prefix) co Calls to beginMacro() and endMacro() may be nested, but every call to beginMacro() must have a matching call to endMacro(). - While a macro is composed, the stack is disabled. This means that: + While a macro is being composed, the stack is disabled. This means that: \list \li indexChanged() and cleanChanged() are not emitted, \li canUndo() and canRedo() return false, diff --git a/src/widgets/widgets/qdatetimeedit.cpp b/src/widgets/widgets/qdatetimeedit.cpp index f72dc088da..cfba2cc87f 100644 --- a/src/widgets/widgets/qdatetimeedit.cpp +++ b/src/widgets/widgets/qdatetimeedit.cpp @@ -1674,12 +1674,7 @@ QDateTimeEditPrivate::QDateTimeEditPrivate() cachedDay = -1; currentSectionIndex = FirstSectionIndex; - first.type = FirstSection; - last.type = LastSection; - none.type = NoSection; first.pos = 0; - last.pos = -1; - none.pos = -1; sections = 0; calendarPopup = false; minimum = QDATETIMEEDIT_COMPAT_DATETIME_MIN; @@ -2053,7 +2048,7 @@ QDateTime QDateTimeEditPrivate::stepBy(int sectionIndex, int steps, bool test) c // doesn't mean that we hit the floor in the other if (steps > 0) { setDigit(v, sectionIndex, min); - if (!(sn.type & (DaySection|DayOfWeekSectionShort|DayOfWeekSectionLong)) && sections & DateSectionMask) { + if (!(sn.type & DaySectionMask) && sections & DateSectionMask) { const int daysInMonth = v.date().daysInMonth(); if (v.date().day() < oldDay && v.date().day() < daysInMonth) { const int adds = qMin(oldDay, daysInMonth); @@ -2068,7 +2063,7 @@ QDateTime QDateTimeEditPrivate::stepBy(int sectionIndex, int steps, bool test) c } } else { setDigit(v, sectionIndex, max); - if (!(sn.type & (DaySection|DayOfWeekSectionShort|DayOfWeekSectionLong)) && sections & DateSectionMask) { + if (!(sn.type & DaySectionMask) && sections & DateSectionMask) { const int daysInMonth = v.date().daysInMonth(); if (v.date().day() < oldDay && v.date().day() < daysInMonth) { const int adds = qMin(oldDay, daysInMonth); @@ -2086,7 +2081,7 @@ QDateTime QDateTimeEditPrivate::stepBy(int sectionIndex, int steps, bool test) c setDigit(v, sectionIndex, (steps > 0 ? localmax : localmin)); } } - if (!test && oldDay != v.date().day() && !(sn.type & (DaySection|DayOfWeekSectionShort|DayOfWeekSectionLong))) { + if (!test && oldDay != v.date().day() && !(sn.type & DaySectionMask)) { // this should not happen when called from stepEnabled cachedDay = qMax<int>(oldDay, cachedDay); } @@ -2278,15 +2273,15 @@ QDateTimeEdit::Sections QDateTimeEditPrivate::convertSections(QDateTimeParser::S ret |= QDateTimeEdit::SecondSection; if (s & QDateTimeParser::MinuteSection) ret |= QDateTimeEdit::MinuteSection; - if (s & (QDateTimeParser::Hour24Section|QDateTimeParser::Hour12Section)) + if (s & (QDateTimeParser::HourSectionMask)) ret |= QDateTimeEdit::HourSection; if (s & QDateTimeParser::AmPmSection) ret |= QDateTimeEdit::AmPmSection; - if (s & (QDateTimeParser::DaySection|QDateTimeParser::DayOfWeekSectionShort|QDateTimeParser::DayOfWeekSectionLong)) + if (s & (QDateTimeParser::DaySectionMask)) ret |= QDateTimeEdit::DaySection; if (s & QDateTimeParser::MonthSection) ret |= QDateTimeEdit::MonthSection; - if (s & (QDateTimeParser::YearSection|QDateTimeParser::YearSection2Digits)) + if (s & (QDateTimeParser::YearSectionMask)) ret |= QDateTimeEdit::YearSection; return ret; diff --git a/src/widgets/widgets/qdatetimeedit.h b/src/widgets/widgets/qdatetimeedit.h index 420ce82f1c..f050061dea 100644 --- a/src/widgets/widgets/qdatetimeedit.h +++ b/src/widgets/widgets/qdatetimeedit.h @@ -75,7 +75,7 @@ class Q_WIDGETS_EXPORT QDateTimeEdit : public QAbstractSpinBox Q_PROPERTY(int sectionCount READ sectionCount) Q_PROPERTY(Qt::TimeSpec timeSpec READ timeSpec WRITE setTimeSpec) public: - enum Section { + enum Section { // a sub-type of QDateTimeParser's like-named enum. NoSection = 0x0000, AmPmSection = 0x0001, MSecSection = 0x0002, diff --git a/src/widgets/widgets/qdatetimeedit_p.h b/src/widgets/widgets/qdatetimeedit_p.h index e8e0749623..6abb3cd9a3 100644 --- a/src/widgets/widgets/qdatetimeedit_p.h +++ b/src/widgets/widgets/qdatetimeedit_p.h @@ -81,14 +81,25 @@ public: void emitSignals(EmitPolicy ep, const QVariant &old); QString textFromValue(const QVariant &f) const; QVariant valueFromText(const QString &f) const; - virtual void _q_editorCursorPositionChanged(int oldpos, int newpos); - virtual void interpret(EmitPolicy ep); - virtual void clearCache() const; QDateTime validateAndInterpret(QString &input, int &, QValidator::State &state, bool fixup = false) const; void clearSection(int index); - virtual QString displayText() const { return edit->text(); } // this is from QDateTimeParser + + // Override QAbstractSpinBoxPrivate: + void _q_editorCursorPositionChanged(int oldpos, int newpos) Q_DECL_OVERRIDE; + void interpret(EmitPolicy ep) Q_DECL_OVERRIDE; + void clearCache() const Q_DECL_OVERRIDE; + QStyle::SubControl newHoverControl(const QPoint &pos) Q_DECL_OVERRIDE; + void updateEditFieldGeometry() Q_DECL_OVERRIDE; + QVariant getZeroVariant() const Q_DECL_OVERRIDE; + void setRange(const QVariant &min, const QVariant &max) Q_DECL_OVERRIDE; + + // Override QDateTimePraser: + QString displayText() const Q_DECL_OVERRIDE { return edit->text(); } + QDateTime getMinimum() const Q_DECL_OVERRIDE { return minimum.toDateTime(); } + QDateTime getMaximum() const Q_DECL_OVERRIDE { return maximum.toDateTime(); } + QLocale locale() const Q_DECL_OVERRIDE { return q_func()->locale(); } int absoluteIndex(QDateTimeEdit::Section s, int index) const; int absoluteIndex(const SectionNode &s) const; @@ -102,18 +113,10 @@ public: void updateCache(const QVariant &val, const QString &str) const; void updateTimeSpec(); - virtual QDateTime getMinimum() const { return minimum.toDateTime(); } - virtual QDateTime getMaximum() const { return maximum.toDateTime(); } - virtual QLocale locale() const { return q_func()->locale(); } QString valueToText(const QVariant &var) const { return textFromValue(var); } QString getAmPmText(AmPm ap, Case cs) const; int cursorPosition() const { return edit ? edit->cursorPosition() : -1; } - virtual QStyle::SubControl newHoverControl(const QPoint &pos); - virtual void updateEditFieldGeometry(); - virtual QVariant getZeroVariant() const; - virtual void setRange(const QVariant &min, const QVariant &max); - void _q_resetButton(); void updateArrow(QStyle::StateFlag state); bool calendarPopupEnabled() const; diff --git a/tests/auto/corelib/io/qfile/tst_qfile.cpp b/tests/auto/corelib/io/qfile/tst_qfile.cpp index 0d912d7b3c..411c73fb90 100644 --- a/tests/auto/corelib/io/qfile/tst_qfile.cpp +++ b/tests/auto/corelib/io/qfile/tst_qfile.cpp @@ -539,6 +539,10 @@ void tst_QFile::open_data() << false << QFile::OpenError; QTest::newRow("noreadfile") << QString::fromLatin1(noReadFile) << int(QIODevice::ReadOnly) << false << QFile::OpenError; + QTest::newRow("resource_file") << QString::fromLatin1(":/does/not/exist") + << int(QIODevice::ReadOnly) + << false + << QFile::OpenError; #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) //opening devices requires administrative privileges (and elevation). HANDLE hTest = CreateFile(_T("\\\\.\\PhysicalDrive0"), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); diff --git a/tests/auto/corelib/io/qipaddress/tst_qipaddress.cpp b/tests/auto/corelib/io/qipaddress/tst_qipaddress.cpp index 5ecd1723c0..ba5e9eaaa1 100644 --- a/tests/auto/corelib/io/qipaddress/tst_qipaddress.cpp +++ b/tests/auto/corelib/io/qipaddress/tst_qipaddress.cpp @@ -181,6 +181,7 @@ void tst_QIpAddress::invalidParseIp4_data() QTest::newRow("..") << ".."; QTest::newRow("...") << "..."; QTest::newRow("....") << "...."; + QTest::newRow(".1.2.3") << ".1.2.3"; QTest::newRow("1.") << "1."; QTest::newRow("1.2.") << "1.2."; QTest::newRow("1.2.3.") << "1.2.3."; @@ -209,9 +210,15 @@ void tst_QIpAddress::invalidParseIp4_data() QTest::newRow("-1.1") << "-1.1"; QTest::newRow("1.-1") << "1.-1"; QTest::newRow("1.1.1.-1") << "1.1.1.-1"; + QTest::newRow("300-05") << "300-05"; + QTest::newRow("127.-1") << "127.-1"; + QTest::newRow("-127-10") << "-127-10"; + QTest::newRow("198.-16") << "198-16"; + QTest::newRow("-127.-0.") << "-127.-0."; // letters QTest::newRow("abc") << "abc"; + QTest::newRow("localhost") << "localhost"; QTest::newRow("1.2.3a.4") << "1.2.3a.4"; QTest::newRow("a.2.3.4") << "a.2.3.4"; QTest::newRow("1.2.3.4a") << "1.2.3.4a"; @@ -244,6 +251,7 @@ void tst_QIpAddress::ip4ToString_data() QTest::newRow("0.0.0.0") << 0u << "0.0.0.0"; QTest::newRow("1.2.3.4") << 0x01020304u << "1.2.3.4"; + QTest::newRow("127.0.0.1") << 0x7f000001u << "127.0.0.1"; QTest::newRow("111.222.33.44") << 0x6fde212cu << "111.222.33.44"; QTest::newRow("255.255.255.255") << 0xffffffffu << "255.255.255.255"; } diff --git a/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp b/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp index 00b82cb377..2e5cfb1053 100644 --- a/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp +++ b/tests/auto/corelib/io/qlockfile/tst_qlockfile.cpp @@ -541,5 +541,15 @@ bool tst_QLockFile::overwritePidInLockFile(const QString &filePath, qint64 pid) return f.write(buf) == buf.size(); } +struct LockFileUsageInGlobalDtor +{ + ~LockFileUsageInGlobalDtor() { + QLockFile lockFile(QDir::currentPath() + "/lastlock"); + QVERIFY(lockFile.lock()); + QVERIFY(lockFile.isLocked()); + } +}; +LockFileUsageInGlobalDtor s_instance; + QTEST_MAIN(tst_QLockFile) #include "tst_qlockfile.moc" diff --git a/tests/auto/corelib/tools/qstringbuilder/qstringbuilder1/stringbuilder.cpp b/tests/auto/corelib/tools/qstringbuilder/qstringbuilder1/stringbuilder.cpp index 4ccc903e32..7a361c0693 100644 --- a/tests/auto/corelib/tools/qstringbuilder/qstringbuilder1/stringbuilder.cpp +++ b/tests/auto/corelib/tools/qstringbuilder/qstringbuilder1/stringbuilder.cpp @@ -88,6 +88,11 @@ void runScenario() r = special + string; QCOMPARE(r, QString(special P string)); + // self-assignment: + r = stringref.toString(); + r = achar + r; + QCOMPARE(r, QString(achar P stringref)); + #ifdef Q_COMPILER_UNICODE_STRINGS r = QStringLiteral(UNICODE_LITERAL); r = r Q QStringLiteral(UNICODE_LITERAL); diff --git a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp index bd9f3a5b72..21a84dfbb2 100644 --- a/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp +++ b/tests/auto/network/access/qnetworkreply/tst_qnetworkreply.cpp @@ -6829,19 +6829,19 @@ void tst_QNetworkReply::authenticationCacheAfterCancel() QTestEventLoop::instance().enterLoop(10); QVERIFY(!QTestEventLoop::instance().timeout()); - if (reply->error() == QNetworkReply::HostNotFoundError) - QSKIP("skip because of quirk in the old test server"); - QCOMPARE(reply->error(), QNetworkReply::ProxyAuthenticationRequiredError); + // Work round known quirk in the old test server (danted -v < v1.1.19): + if (reply->error() != QNetworkReply::HostNotFoundError) + QCOMPARE(reply->error(), QNetworkReply::ProxyAuthenticationRequiredError); QCOMPARE(authSpy.count(), 0); QVERIFY(proxyAuthSpy.count() > 0); proxyAuthSpy.clear(); - //QTBUG-23136 workaround + // QTBUG-23136 workaround (needed even with danted v1.1.19): if (proxy.port() == 1081) { #ifdef QT_BUILD_INTERNAL QNetworkAccessManagerPrivate::clearCache(&manager); #else - return; //XFAIL result above + return; #endif } diff --git a/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp b/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp index a418e59ba4..4fb97fe1f2 100644 --- a/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp +++ b/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp @@ -136,8 +136,16 @@ void tst_QHostAddress::setAddress_QString_data() QTest::newRow("ip4_06") << QString("123.0.0") << true << QString("123.0.0.0") << 4; // for the format of IPv6 addresses see also RFC 5952 - QTest::newRow("ip6_00") << QString("FEDC:BA98:7654:3210:FEDC:BA98:7654:3210") << true << QString("fedc:ba98:7654:3210:fedc:ba98:7654:3210") << 6; - QTest::newRow("ip6_01") << QString("1080:0000:0000:0000:0008:0800:200C:417A") << true << QString("1080::8:800:200c:417a") << 6; + // rule 4.1: Leading zeros MUST be suppressed + // rule 4.2.1: Shorten as Much as Possible + // rule 4.2.2: The symbol "::" MUST NOT be used to shorten just one 16-bit 0 field. + // rule 4.2.3: the longest run of consecutive 16-bit 0 fields MUST be shortened + // When the length of the consecutive 16-bit 0 fields, the first sequence + // of zero bits MUST be shortened + // rule 4.3: The characters "a", "b", "c", "d", "e", and "f" in an IPv6 address + // MUST be represented in lowercase + QTest::newRow("ip6_00") << QString("FEDC:BA98:7654:3210:FEDC:BA98:7654:3210") << true << QString("fedc:ba98:7654:3210:fedc:ba98:7654:3210") << 6; // 4.3 + QTest::newRow("ip6_01") << QString("1080:0000:0000:0000:0008:0800:200C:417A") << true << QString("1080::8:800:200c:417a") << 6; // 4.1, 4.2.1 QTest::newRow("ip6_02") << QString("1080:0:0:0:8:800:200C:417A") << true << QString("1080::8:800:200c:417a") << 6; QTest::newRow("ip6_03") << QString("1080::8:800:200C:417A") << true << QString("1080::8:800:200c:417a") << 6; QTest::newRow("ip6_04") << QString("FF01::43") << true << QString("ff01::43") << 6; @@ -150,10 +158,11 @@ void tst_QHostAddress::setAddress_QString_data() QTest::newRow("ip6_11") << QString("::FFFF:129.144.52.38") << true << QString("::ffff:129.144.52.38") << 6; QTest::newRow("ip6_12") << QString("1::FFFF:129.144.52.38") << true << QString("1::ffff:8190:3426") << 6; QTest::newRow("ip6_13") << QString("A:B::D:E") << true << QString("a:b::d:e") << 6; - QTest::newRow("ip6_14") << QString("1080:0:1:0:8:800:200C:417A") << true << QString("1080:0:1:0:8:800:200c:417a") << 6; + QTest::newRow("ip6_14") << QString("1080:0:1:0:8:800:200C:417A") << true << QString("1080:0:1:0:8:800:200c:417a") << 6; // 4.2.2 QTest::newRow("ip6_15") << QString("1080:0:1:0:8:800:200C:0") << true << QString("1080:0:1:0:8:800:200c:0") << 6; QTest::newRow("ip6_16") << QString("1080:0:1:0:8:800:0:0") << true << QString("1080:0:1:0:8:800::") << 6; - QTest::newRow("ip6_17") << QString("1080:0:0:0:8:800:0:0") << true << QString("1080::8:800:0:0") << 6; + QTest::newRow("ip6_17a") << QString("1080:0:0:8:800:0:0:0") << true << QString("1080:0:0:8:800::") << 6; // 4.2.3a + QTest::newRow("ip6_17b") << QString("1080:0:0:0:8:0:0:0") << true << QString("1080::8:0:0:0") << 6; // 4.2.3b QTest::newRow("ip6_18") << QString("0:1:1:1:8:800:0:0") << true << QString("0:1:1:1:8:800::") << 6; QTest::newRow("ip6_19") << QString("0:1:1:1:8:800:0:1") << true << QString("0:1:1:1:8:800:0:1") << 6; diff --git a/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp b/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp index b5032c8c35..d0baa62e29 100644 --- a/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp +++ b/tests/auto/network/socket/qlocalsocket/tst_qlocalsocket.cpp @@ -839,7 +839,8 @@ void tst_QLocalSocket::processConnection() const QString exeSuffix; #endif - QString socketProcess = QStringLiteral("socketprocess/socketprocess") + exeSuffix; + const QString socketProcess + = QFINDTESTDATA(QStringLiteral("socketprocess/socketprocess") + exeSuffix); QVERIFY(QFile::exists(socketProcess)); QFETCH(int, processes); diff --git a/tests/auto/widgets/widgets/qfontcombobox/BLACKLIST b/tests/auto/widgets/widgets/qfontcombobox/BLACKLIST deleted file mode 100644 index 8bd4caad31..0000000000 --- a/tests/auto/widgets/widgets/qfontcombobox/BLACKLIST +++ /dev/null @@ -1,6 +0,0 @@ -[currentFont] -osx -[fontFilters] -osx -[writingSystem] -osx diff --git a/tests/auto/widgets/widgets/qfontcombobox/tst_qfontcombobox.cpp b/tests/auto/widgets/widgets/qfontcombobox/tst_qfontcombobox.cpp index cda24a19d3..9e6b16d4ce 100644 --- a/tests/auto/widgets/widgets/qfontcombobox/tst_qfontcombobox.cpp +++ b/tests/auto/widgets/widgets/qfontcombobox/tst_qfontcombobox.cpp @@ -80,18 +80,21 @@ void tst_QFontComboBox::qfontcombobox() void tst_QFontComboBox::currentFont_data() { QTest::addColumn<QFont>("currentFont"); + QFontDatabase db; // Normalize the names QFont defaultFont; QFontInfo fi(defaultFont); defaultFont = QFont(fi.family()); // make sure we have a real font name and not something like 'Sans Serif'. - QTest::newRow("default") << defaultFont; + if (!db.isPrivateFamily(defaultFont.family())) + QTest::newRow("default") << defaultFont; defaultFont.setPointSize(defaultFont.pointSize() + 10); - QTest::newRow("default2") << defaultFont; - QFontDatabase db; + if (!db.isPrivateFamily(defaultFont.family())) + QTest::newRow("default2") << defaultFont; QStringList list = db.families(); for (int i = 0; i < list.count(); ++i) { QFont f = QFont(QFontInfo(QFont(list.at(i))).family()); - QTest::newRow(qPrintable(list.at(i))) << f; + if (!db.isPrivateFamily(f.family())) + QTest::newRow(qPrintable(list.at(i))) << f; } } @@ -168,6 +171,8 @@ void tst_QFontComboBox::fontFilters() fontFilters &= ~spacingMask; for (int i = 0; i < list.count(); ++i) { + if (db.isPrivateFamily(list[i])) + continue; if (fontFilters & QFontComboBox::ScalableFonts) { if (!db.isSmoothlyScalable(list[i])) continue; @@ -232,7 +237,12 @@ void tst_QFontComboBox::writingSystem() QFontDatabase db; QStringList list = db.families(writingSystem); - QCOMPARE(box.model()->rowCount(), list.count()); + int c = list.count(); + for (int i = 0; i < list.count(); ++i) { + if (db.isPrivateFamily(list[i])) + c--; + } + QCOMPARE(box.model()->rowCount(), c); if (list.count() == 0) QCOMPARE(box.currentFont(), QFont()); diff --git a/tests/manual/network_remote_stresstest/tst_network_remote_stresstest.cpp b/tests/manual/network_remote_stresstest/tst_network_remote_stresstest.cpp index 0035d47c88..05ede9da99 100644 --- a/tests/manual/network_remote_stresstest/tst_network_remote_stresstest.cpp +++ b/tests/manual/network_remote_stresstest/tst_network_remote_stresstest.cpp @@ -139,7 +139,7 @@ void tst_NetworkRemoteStressTest::init() { // clear the internal cache #ifndef QT_BUILD_INTERNAL - if (strncmp(QTest::currentTestFunction(), "nam") == 0) + if (strncmp(QTest::currentTestFunction(), "nam", 3) == 0) QSKIP("QNetworkAccessManager tests disabled"); #endif } diff --git a/tests/manual/network_stresstest/tst_network_stresstest.cpp b/tests/manual/network_stresstest/tst_network_stresstest.cpp index 9e04d52c4a..e3c76ea11b 100644 --- a/tests/manual/network_stresstest/tst_network_stresstest.cpp +++ b/tests/manual/network_stresstest/tst_network_stresstest.cpp @@ -130,7 +130,7 @@ void tst_NetworkStressTest::init() { // clear the internal cache #ifndef QT_BUILD_INTERNAL - if (strncmp(QTest::currentTestFunction(), "nam") == 0) + if (strncmp(QTest::currentTestFunction(), "nam", 3) == 0) QSKIP("QNetworkAccessManager tests disabled"); #endif } diff --git a/tests/manual/qscreen/main.cpp b/tests/manual/qscreen/main.cpp index f9f93fd525..445af82e09 100644 --- a/tests/manual/qscreen/main.cpp +++ b/tests/manual/qscreen/main.cpp @@ -40,6 +40,61 @@ #include <QStatusBar> #include <QLineEdit> #include <QDesktopWidget> +#include <QPushButton> +#include <QLabel> +#include <QMouseEvent> + + +class MouseMonitor : public QLabel { + Q_OBJECT +public: + MouseMonitor() : m_grabbed(false) { + setMinimumSize(540, 240); + setAlignment(Qt::AlignCenter); + setMouseTracking(true); + setWindowTitle(QLatin1String("Mouse Monitor")); + updateText(); + } + + void updateText() { + QString txt = m_grabbed ? + QLatin1String("Left-click to test QGuiApplication::topLevelAt(click pos)\nRight-click to ungrab\n") : + QLatin1String("Left-click to grab mouse\n"); + if (!m_cursorPos.isNull()) { + txt += QString(QLatin1String("Current mouse position: %1, %2 on screen %3\n")) + .arg(m_cursorPos.x()).arg(m_cursorPos.y()).arg(QApplication::desktop()->screenNumber(m_cursorPos)); + if (QGuiApplication::mouseButtons() & Qt::LeftButton) { + QWindow *win = QGuiApplication::topLevelAt(m_cursorPos); + txt += QString(QLatin1String("Top-level window found? %1\n")) + .arg(win ? (win->title().isEmpty() ? "no title" : win->title()) : "none"); + } + } + setText(txt); + } + +protected: + void mouseMoveEvent(QMouseEvent *ev) Q_DECL_OVERRIDE { + m_cursorPos = ev->screenPos().toPoint(); + updateText(); + } + + void mousePressEvent(QMouseEvent *ev) Q_DECL_OVERRIDE { + m_cursorPos = ev->screenPos().toPoint(); + qDebug() << "top level @" << m_cursorPos << ":" << QGuiApplication::topLevelAt(m_cursorPos); + updateText(); + if (!m_grabbed) { + grabMouse(Qt::CrossCursor); + m_grabbed = true; + } else if (ev->button() == Qt::RightButton) { + setVisible(false); + deleteLater(); + } + } + +private: + QPoint m_cursorPos; + bool m_grabbed; +}; class ScreenPropertyWatcher : public PropertyWatcher { @@ -96,6 +151,7 @@ public: protected: bool event(QEvent *event) Q_DECL_OVERRIDE; + void startMouseMonitor(); private: const QString m_annotation; @@ -119,6 +175,11 @@ ScreenWatcherMainWindow::ScreenWatcherMainWindow(QScreen *screen) a = fileMenu->addAction(QLatin1String("Quit")); a->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q)); connect(a, SIGNAL(triggered()), qApp, SLOT(quit())); + + QMenu *toolsMenu = menuBar()->addMenu(QLatin1String("&Tools")); + a = toolsMenu->addAction(QLatin1String("Mouse Monitor")); + a->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_M)); + connect(a, &QAction::triggered, this, &ScreenWatcherMainWindow::startMouseMonitor); } static inline QString msgScreenChange(const QWidget *w, const QScreen *oldScreen, const QScreen *newScreen) @@ -154,6 +215,12 @@ bool ScreenWatcherMainWindow::event(QEvent *event) return QMainWindow::event(event); } +void ScreenWatcherMainWindow::startMouseMonitor() +{ + MouseMonitor *mm = new MouseMonitor(); + mm->show(); +} + void screenAdded(QScreen* screen) { screen->setOrientationUpdateMask((Qt::ScreenOrientations)0x0F); |