summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dist/changes-5.3.1101
-rw-r--r--examples/widgets/doc/src/basiclayouts.qdoc22
-rw-r--r--examples/widgets/doc/src/borderlayout.qdoc11
-rw-r--r--examples/widgets/doc/src/dynamiclayouts.qdoc12
-rw-r--r--examples/widgets/doc/src/flowlayout.qdoc17
-rw-r--r--examples/widgets/doc/src/imageviewer.qdoc21
-rw-r--r--examples/widgets/widgets/imageviewer/imageviewer.cpp68
-rw-r--r--examples/widgets/widgets/imageviewer/imageviewer.h3
-rw-r--r--examples/widgets/widgets/imageviewer/main.cpp12
-rw-r--r--mkspecs/features/create_cmake.prf13
-rw-r--r--mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in13
-rw-r--r--mkspecs/features/qt.prf2
-rw-r--r--mkspecs/features/qt_installs.prf2
-rw-r--r--mkspecs/features/wayland-scanner.prf2
-rw-r--r--mkspecs/qnx-armle-v7-qcc/qplatformdefs.h66
-rw-r--r--qmake/library/qmakeevaluator.cpp20
-rw-r--r--qmake/library/qmakeevaluator.h2
-rw-r--r--qmake/main.cpp4
-rw-r--r--qmake/project.cpp2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-coretext.cc3
-rw-r--r--src/android/accessibility/jar/src/org/qtproject/qt5/android/accessibility/QtAccessibilityDelegate.java13
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtSurface.java18
-rw-r--r--src/corelib/arch/qatomic_bootstrap.h8
-rw-r--r--src/corelib/doc/snippets/code/doc_src_plugins-howto.cpp2
-rw-r--r--src/corelib/global/qglobal.h6
-rw-r--r--src/corelib/global/qlibraryinfo.cpp4
-rw-r--r--src/corelib/global/qlogging.cpp3
-rw-r--r--src/corelib/io/qfileinfo.cpp7
-rw-r--r--src/corelib/io/qfilesystemwatcher_fsevents.mm28
-rw-r--r--src/corelib/io/qloggingcategory.cpp40
-rw-r--r--src/corelib/io/qloggingcategory.h35
-rw-r--r--src/corelib/io/qprocess.cpp164
-rw-r--r--src/corelib/io/qprocess_p.h28
-rw-r--r--src/corelib/io/qprocess_unix.cpp59
-rw-r--r--src/corelib/io/qprocess_win.cpp160
-rw-r--r--src/corelib/io/qprocess_wince.cpp16
-rw-r--r--src/corelib/io/qstandardpaths_winrt.cpp19
-rw-r--r--src/corelib/io/qwindowspipereader.cpp4
-rw-r--r--src/corelib/kernel/qeventdispatcher_win.cpp58
-rw-r--r--src/corelib/kernel/qjnihelpers.cpp4
-rw-r--r--src/corelib/kernel/qobject.cpp2
-rw-r--r--src/corelib/kernel/qobjectdefs_impl.h2
-rw-r--r--src/corelib/kernel/qtcore_eval.cpp6
-rw-r--r--src/corelib/plugin/qlibrary.cpp35
-rw-r--r--src/corelib/plugin/qlibrary_p.h6
-rw-r--r--src/corelib/plugin/qpluginloader.cpp7
-rw-r--r--src/corelib/thread/qatomic.cpp1
-rw-r--r--src/corelib/thread/qmutex.cpp2
-rw-r--r--src/corelib/thread/qmutex.h16
-rw-r--r--src/corelib/tools/qcollator_icu.cpp11
-rw-r--r--src/corelib/tools/qcollator_macx.cpp9
-rw-r--r--src/corelib/tools/qringbuffer_p.h2
-rw-r--r--src/corelib/tools/qscopedvaluerollback.cpp2
-rw-r--r--src/corelib/tools/qsimd_p.h4
-rw-r--r--src/corelib/tools/qstring.cpp4
-rw-r--r--src/dbus/qdbusconnection_p.h2
-rw-r--r--src/dbus/qdbusintegrator.cpp20
-rw-r--r--src/gui/accessible/qaccessible.cpp4
-rw-r--r--src/gui/animation/qguivariantanimation.cpp2
-rw-r--r--src/gui/image/qgifhandler.cpp2
-rw-r--r--src/gui/image/qicon.cpp119
-rw-r--r--src/gui/image/qicon_p.h10
-rw-r--r--src/gui/image/qimage.cpp274
-rw-r--r--src/gui/image/qpixmap.cpp1
-rw-r--r--src/gui/image/qpixmap_raster.cpp6
-rw-r--r--src/gui/kernel/qguiapplication.cpp10
-rw-r--r--src/gui/kernel/qplatformclipboard.cpp3
-rw-r--r--src/gui/opengl/qopenglframebufferobject.cpp11
-rw-r--r--src/gui/opengl/qopenglframebufferobject_p.h1
-rw-r--r--src/gui/opengl/qopenglfunctions.cpp78
-rw-r--r--src/gui/painting/qdrawhelper.cpp67
-rw-r--r--src/gui/painting/qpaintengine.cpp2
-rw-r--r--src/gui/painting/qpaintengineex.cpp4
-rw-r--r--src/gui/text/qfontengine.cpp27
-rw-r--r--src/gui/text/qfontmetrics.cpp6
-rw-r--r--src/network/access/qhttpnetworkconnection.cpp4
-rw-r--r--src/network/access/qhttpnetworkconnection_p.h4
-rw-r--r--src/network/access/qnetworkaccessbackend.cpp2
-rw-r--r--src/network/access/qnetworkaccessmanager.cpp44
-rw-r--r--src/network/access/qnetworkaccessmanager_p.h3
-rw-r--r--src/network/access/qnetworkreplyhttpimpl.cpp12
-rw-r--r--src/network/access/qnetworkreplyhttpimpl_p.h3
-rw-r--r--src/network/access/qnetworkreplynsurlconnectionimpl.mm13
-rw-r--r--src/network/kernel/qdnslookup_unix.cpp6
-rw-r--r--src/network/kernel/qhostaddress.h4
-rw-r--r--src/network/kernel/qnetworkinterface_win_p.h1
-rw-r--r--src/network/socket/qlocalsocket_win.cpp12
-rw-r--r--src/network/socket/qnativesocketengine_winrt.cpp9
-rw-r--r--src/network/ssl/qsslsocket_openssl_android.cpp4
-rw-r--r--src/platformsupport/eglconvenience/qxlibeglintegration.cpp39
-rw-r--r--src/plugins/imageformats/ico/qicohandler.cpp7
-rw-r--r--src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp21
-rw-r--r--src/plugins/platforminputcontexts/compose/generator/qtablegenerator.h3
-rw-r--r--src/plugins/platforms/android/androidjniaccessibility.cpp17
-rw-r--r--src/plugins/platforms/android/androidjniaccessibility.h5
-rw-r--r--src/plugins/platforms/android/androidjniclipboard.cpp4
-rw-r--r--src/plugins/platforms/android/androidjniclipboard.h4
-rw-r--r--src/plugins/platforms/android/androidjniinput.cpp4
-rw-r--r--src/plugins/platforms/android/androidjniinput.h5
-rw-r--r--src/plugins/platforms/android/androidjnimain.cpp32
-rw-r--r--src/plugins/platforms/android/androidjnimain.h5
-rw-r--r--src/plugins/platforms/android/androidjnimenu.cpp4
-rw-r--r--src/plugins/platforms/android/androidjnimenu.h5
-rw-r--r--src/plugins/platforms/android/androidsurfaceclient.h4
-rw-r--r--src/plugins/platforms/android/qandroidassetsfileenginehandler.cpp4
-rw-r--r--src/plugins/platforms/android/qandroidassetsfileenginehandler.h4
-rw-r--r--src/plugins/platforms/android/qandroidplatformdialoghelpers.cpp4
-rw-r--r--src/plugins/platforms/android/qandroidplatformdialoghelpers.h4
-rw-r--r--src/plugins/platforms/android/qandroidplatformfontdatabase.cpp4
-rw-r--r--src/plugins/platforms/android/qandroidplatformfontdatabase.h4
-rw-r--r--src/plugins/platforms/android/qandroidplatformintegration.cpp17
-rw-r--r--src/plugins/platforms/android/qandroidplatformintegration.h5
-rw-r--r--src/plugins/platforms/android/qandroidplatformmenu.cpp4
-rw-r--r--src/plugins/platforms/android/qandroidplatformmenu.h4
-rw-r--r--src/plugins/platforms/android/qandroidplatformmenubar.cpp3
-rw-r--r--src/plugins/platforms/android/qandroidplatformmenubar.h4
-rw-r--r--src/plugins/platforms/android/qandroidplatformmenuitem.cpp4
-rw-r--r--src/plugins/platforms/android/qandroidplatformmenuitem.h4
-rw-r--r--src/plugins/platforms/android/qandroidplatformopenglcontext.cpp1
-rw-r--r--src/plugins/platforms/android/qandroidplatformscreen.cpp29
-rw-r--r--src/plugins/platforms/android/qandroidplatformscreen.h9
-rw-r--r--src/plugins/platforms/android/qandroidplatformservices.cpp4
-rw-r--r--src/plugins/platforms/android/qandroidplatformservices.h4
-rw-r--r--src/plugins/platforms/android/qandroidplatformtheme.cpp4
-rw-r--r--src/plugins/platforms/android/qandroidplatformtheme.h4
-rw-r--r--src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm9
-rw-r--r--src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm3
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm41
-rw-r--r--src/plugins/platforms/cocoa/qnsview.h10
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm70
-rw-r--r--src/plugins/platforms/directfb/main.cpp3
-rw-r--r--src/plugins/platforms/directfb/qdirectfbintegration.cpp2
-rw-r--r--src/plugins/platforms/directfb/qdirectfbintegration.h2
-rw-r--r--src/plugins/platforms/eglfs/qeglfswindow.h2
-rw-r--r--src/plugins/platforms/ios/qiosinputcontext.mm10
-rw-r--r--src/plugins/platforms/ios/quiview.h1
-rw-r--r--src/plugins/platforms/ios/quiview_textinput.mm89
-rw-r--r--src/plugins/platforms/windows/accessible/iaccessible2.cpp1
-rw-r--r--src/plugins/platforms/windows/accessible/iaccessible2.h2
-rw-r--r--src/plugins/platforms/windows/qplatformfunctions_wince.h9
-rw-r--r--src/plugins/platforms/windows/qwindowskeymapper.cpp1
-rw-r--r--src/plugins/platforms/windows/qwindowsmousehandler.cpp9
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp9
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp9
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h8
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection_xi2.cpp258
-rw-r--r--src/plugins/platforms/xcb/qxcbintegration.cpp5
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.cpp9
-rw-r--r--src/plugins/platforms/xcb/qxcbscreen.cpp6
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp34
-rw-r--r--src/plugins/platforms/xcb/xcb-plugin.pro1
-rw-r--r--src/plugins/printsupport/windows/qwindowsprintdevice.cpp3
-rw-r--r--src/printsupport/kernel/qprintengine_win.cpp28
-rw-r--r--src/printsupport/kernel/qprintengine_win_p.h1
-rw-r--r--src/printsupport/kernel/qprinter.cpp6
-rw-r--r--src/sql/doc/src/qtsql.qdoc8
-rw-r--r--src/sql/kernel/qsqldatabase.cpp6
-rw-r--r--src/sql/kernel/qsqldatabase.h7
-rw-r--r--src/tools/moc/moc.cpp2
-rw-r--r--src/tools/qdoc/htmlgenerator.cpp55
-rw-r--r--src/widgets/dialogs/qcolordialog.cpp39
-rw-r--r--src/widgets/dialogs/qcolordialog_p.h11
-rw-r--r--src/widgets/doc/snippets/qstyleplugin/main.cpp2
-rw-r--r--src/widgets/doc/src/qtwidgets-index.qdoc1
-rw-r--r--src/widgets/doc/src/widgets-and-layouts/layout.qdoc10
-rw-r--r--src/widgets/graphicsview/qgraphicsitem.cpp2
-rw-r--r--src/widgets/kernel/qwidget.cpp8
-rw-r--r--src/widgets/styles/qfusionstyle.cpp2
-rw-r--r--src/widgets/styles/qmacstyle_mac.mm22
-rw-r--r--src/widgets/styles/qstylehelper.cpp10
-rw-r--r--src/widgets/styles/qstylehelper_p.h1
-rw-r--r--src/widgets/styles/qstylesheetstyle.cpp1
-rw-r--r--src/widgets/util/qsystemtrayicon_x11.cpp6
-rw-r--r--src/widgets/widgets/qcombobox.cpp45
-rw-r--r--src/widgets/widgets/qcombobox_p.h1
-rw-r--r--src/widgets/widgets/qfontcombobox.cpp2
-rw-r--r--src/widgets/widgets/qmainwindow.cpp9
-rw-r--r--src/widgets/widgets/qstackedwidget.cpp2
-rw-r--r--src/widgets/widgets/qtoolbar.cpp4
-rw-r--r--src/widgets/widgets/qwidgettextcontrol.cpp7
-rw-r--r--tests/auto/corelib/io/qdebug/qdebug.pro2
-rw-r--r--tests/auto/corelib/io/qdebug/tst_qdebug.cpp40
-rw-r--r--tests/auto/corelib/io/qprocess/test/test.pro1
-rw-r--r--tests/auto/corelib/io/qprocess/tst_qprocess.cpp2
-rw-r--r--tests/auto/corelib/plugin/qpluginloader/qpluginloader.pro2
-rw-r--r--tests/auto/corelib/tools/qcollator/tst_qcollator.cpp93
-rw-r--r--tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp7
-rw-r--r--tests/auto/gui/image/qicon/tst_qicon.cpp59
-rw-r--r--tests/auto/gui/image/qimage/tst_qimage.cpp125
-rw-r--r--tests/auto/gui/image/qpixmap/tst_qpixmap.cpp15
-rw-r--r--tests/auto/network/access/qnetworkdiskcache/tst_qnetworkdiskcache.cpp38
-rw-r--r--tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp4
-rw-r--r--tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp6
-rw-r--r--tests/auto/other/macgui/tst_macgui.cpp1
-rw-r--r--tests/auto/other/other.pro3
-rw-r--r--tests/auto/other/qprocess_and_guieventloop/qprocess_and_guieventloop.pro4
-rw-r--r--tests/auto/other/qprocess_and_guieventloop/test.pro5
-rw-r--r--tests/auto/other/qprocess_and_guieventloop/tst_qprocess_and_guieventloop.cpp89
-rw-r--r--tests/auto/other/qprocess_and_guieventloop/write-read-write/main.cpp58
-rw-r--r--tests/auto/other/qprocess_and_guieventloop/write-read-write/write-read-write.pro4
-rw-r--r--tests/auto/tools/moc/tst_moc.cpp6
-rw-r--r--tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp6
-rw-r--r--tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp37
-rw-r--r--tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp43
204 files changed, 2492 insertions, 1296 deletions
diff --git a/dist/changes-5.3.1 b/dist/changes-5.3.1
new file mode 100644
index 0000000000..1e6f592a65
--- /dev/null
+++ b/dist/changes-5.3.1
@@ -0,0 +1,101 @@
+Qt 5.3.1 is a bug-fix release. It maintains both forward and backward
+compatibility (source and binary) with Qt 5.3.0.
+
+For more details, refer to the online documentation included in this
+distribution. The documentation is also available online:
+
+ http://qt-project.org/doc/qt-5.3
+
+The Qt version 5.3 series is binary compatible with the 5.2.x series.
+Applications compiled for 5.2 will continue to run with 5.3.
+
+Some of the changes listed in this file include issue tracking numbers
+corresponding to tasks in the Qt Bug Tracker:
+
+ http://bugreports.qt-project.org/
+
+Each of these identifiers can be entered in the bug tracker to obtain more
+information about a particular change.
+
+****************************************************************************
+* Library *
+****************************************************************************
+
+QtCore
+------
+
+ - QAbstractProxyModel:
+ * Fixed QAbstractProxyModel::sibling to work in the same manner as the
+ Qt4 code used to behave. Previously, Qt5's implementation would treat
+ the row and column as positions in the source model instead of a
+ position in the proxy itself.
+
+QtGui
+-----
+
+ - Text:
+ * [QTBUG-36083] Respect QFont::fixedPitch() for fallbacks when font
+ family cannot be matched.
+ * [QTBUG-37190] Fixed crash when trying to load a font from invalid
+ data.
+
+QtSql
+-----
+
+ - QDB2 and QODBC
+ * [QTBUG-39137] Fix error handling problem caused by unintialized variable
+ passed to SQLNumResultCols.
+
+ - QPSQL
+ * [QTBUG-12477] Fix PSQL column metadata.
+
+ - QSqlQuery
+ * Fix misbehavior of seek in special query positions BeforeFirstRow and
+ AfterLastRow. (commit 3e6e70bddd84536deaae69421d05785ae6ce28cd)
+ * [QTBUG-33169] Fix for bindvalue(int) memory allocation problem.
+
+QtWidgets
+---------
+
+ - QMenu:
+ * [QTBUG-38498] Accessibility: Menus are now read by screen readers
+ with more reliability.
+
+****************************************************************************
+* Platform Specific Changes *
+****************************************************************************
+
+Android
+-------
+
+ - [QTBUG-38960] Fixed regression where there would be flickering on
+ startup and shutdown of the application.
+ - [QTBUG-35975] Fixed repaint issues in drag and drop.
+
+ - Text:
+ * [QTBUG-37844] Fall back to Droid Sans Mono for QFont::Courier style
+ hint.
+
+****************************************************************************
+* Tools *
+****************************************************************************
+
+configure & build system
+------------------------
+
+ - [QTBUG-38445] Fixed build against static ICU on Unix
+ - [QTBUG-38544] Fixed LLVM build with SIMD features
+ - [QTBUG-39253] PDB files are now installed also for static libraries
+ - Added support for -separate-debug-info on Windows
+ - Added [-no]-pulseaudio and [-no]-alsa options on Unix
+ - Several fixes to installed .pc and .prl files
+ - Fixed MinGW build under MSYS
+ - Fixed installation of unneeded static libraries in dynamic builds
+
+qmake
+-----
+
+ - [QTBUG-37054] Fixed use of relative paths in QMAKE_BUNDLE_DATA with Xcode
+ - [QTBUG-38260] Custom Info.plist supplied via QMAKE_INFO_PLIST is now used
+ as-is, without placeholder replacement
+ - QMAKE_TARGET_BUNDLE_PREFIX does not need a trailing dot any more
diff --git a/examples/widgets/doc/src/basiclayouts.qdoc b/examples/widgets/doc/src/basiclayouts.qdoc
index d219b7bff3..0066317165 100644
--- a/examples/widgets/doc/src/basiclayouts.qdoc
+++ b/examples/widgets/doc/src/basiclayouts.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the documentation of the Qt Toolkit.
@@ -28,31 +28,35 @@
/*!
\example layouts/basiclayouts
\title Basic Layouts Example
+ \brief Shows how to use the standard layout managers.
- \brief The Basic Layouts example shows how to use the standard layout
- managers that are available in Qt: QBoxLayout, QGridLayout and
- QFormLayout.
+ \e{Basic Layouts} shows how to use the standard layout managers that are
+ available in Qt: QBoxLayout, QGridLayout, and QFormLayout.
\image basiclayouts-example.png Screenshot of the Basic Layouts example
The QBoxLayout class lines up widgets horizontally or vertically.
QHBoxLayout and QVBoxLayout are convenience subclasses of QBoxLayout.
QGridLayout lays out widgets in cells by dividing the available space
- into rows and columns. QFormLayout, on the other hand, lays out its
+ into rows and columns. QFormLayout, on the other hand, sets its
children in a two-column form with labels in the left column and
input fields in the right column.
+ For more information, visit the \l{Layout Management} page.
+
+ \include examples-run.qdocinc
+
\section1 Dialog Class Definition
\snippet layouts/basiclayouts/dialog.h 0
The \c Dialog class inherits QDialog. It is a custom widget that
displays its child widgets using the geometry managers:
- QHBoxLayout, QVBoxLayout, QGridLayout and QFormLayout.
+ QHBoxLayout, QVBoxLayout, QGridLayout, and QFormLayout.
- We declare four private functions to simplify the class
- constructor: The \c createMenu(), \c createHorizontalGroupBox(),
- \c createGridGroupBox() and \c createFormGroupBox() functions create
+ There are four private functions to simplify the class
+ constructor: the \c createMenu(), \c createHorizontalGroupBox(),
+ \c createGridGroupBox(), and \c createFormGroupBox() functions create
several widgets that the example uses to demonstrate how the layout
affects their appearances.
diff --git a/examples/widgets/doc/src/borderlayout.qdoc b/examples/widgets/doc/src/borderlayout.qdoc
index 8a2958ee80..03a2bf1672 100644
--- a/examples/widgets/doc/src/borderlayout.qdoc
+++ b/examples/widgets/doc/src/borderlayout.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the documentation of the Qt Toolkit.
@@ -28,9 +28,14 @@
/*!
\example layouts/borderlayout
\title Border Layout Example
+ \brief Shows how to arrange child widgets along a border.
- \brief The Border Layout example shows how to create a custom layout that arranges
- child widgets according to a simple set of rules.
+ \e{Border Layout} implements a layout that arranges child widgets to
+ surround the main area.
\image borderlayout-example.png
+
+ For more information, visit the \l{Layout Management} page.
+
+ \include examples-run.qdocinc
*/
diff --git a/examples/widgets/doc/src/dynamiclayouts.qdoc b/examples/widgets/doc/src/dynamiclayouts.qdoc
index 5590ec61f1..497a0d23fd 100644
--- a/examples/widgets/doc/src/dynamiclayouts.qdoc
+++ b/examples/widgets/doc/src/dynamiclayouts.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the documentation of the Qt Toolkit.
@@ -28,7 +28,13 @@
/*!
\example layouts/dynamiclayouts
\title Dynamic Layouts Example
+ \brief Shows how to re-orient widgets in running applications.
- \brief The Dynamic Layouts example shows how to move widgets around in
- existing layouts.
+ \e{Dynamic Layouts} implements dynamically placed widgets within running
+ applications. The widget placement depends on whether \c Horizontal or \c
+ Vertical is chosen.
+
+ For more information, visit the \l{Layout Management} page.
+
+ \include examples-run.qdocinc
*/
diff --git a/examples/widgets/doc/src/flowlayout.qdoc b/examples/widgets/doc/src/flowlayout.qdoc
index b482edf946..84de22416c 100644
--- a/examples/widgets/doc/src/flowlayout.qdoc
+++ b/examples/widgets/doc/src/flowlayout.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the documentation of the Qt Toolkit.
@@ -28,18 +28,19 @@
/*!
\example layouts/flowlayout
\title Flow Layout Example
+ \brief Shows how to arrange widgets for different window sizes.
- \brief The Flow Layout example demonstrates a custom layout that arranges child
- widgets from left to right and top to bottom in a top-level widget.
+ \e{Flow Layout} implements a layout that handles different window sizes. The
+ widget placement changes depending on the width of the application window.
\image flowlayout-example.png Screenshot of the Flow Layout example
- The items are first laid out horizontally and then vertically when each line
- in the layout runs out of space.
-
The Flowlayout class mainly uses QLayout and QWidgetItem, while the
- Window uses QWidget and QLabel. We will only document the definition
- and implementation of \c FlowLayout below.
+ Window uses QWidget and QLabel.
+
+ For more information, visit the \l{Layout Management} page.
+
+ \include examples-run.qdocinc
\section1 FlowLayout Class Definition
diff --git a/examples/widgets/doc/src/imageviewer.qdoc b/examples/widgets/doc/src/imageviewer.qdoc
index 96013e844a..6361e3f35b 100644
--- a/examples/widgets/doc/src/imageviewer.qdoc
+++ b/examples/widgets/doc/src/imageviewer.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the documentation of the Qt Toolkit.
@@ -112,15 +112,19 @@
{ImageViewer}'s appearance.
\snippet widgets/imageviewer/imageviewer.cpp 1
- \snippet widgets/imageviewer/imageviewer.cpp 2
- In the \c open() slot, we show a file dialog to the user. The
- easiest way to create a QFileDialog is to use the static
- convenience functions. QFileDialog::getOpenFileName() returns an
- existing file selected by the user. If the user presses \uicontrol
- Cancel, QFileDialog returns an empty string.
+ In the \c open() slot, we show a file dialog to the user. We compile
+ a list of mime types for use as a filter by querying QImageReader
+ for the available mime type names.
+
+ We show the file dialog until a valid file name is entered or
+ the user cancels.
+
+ The function \c loadFile() is used to load the image.
+
+ \snippet widgets/imageviewer/imageviewer.cpp 2
- Unless the file name is a empty string, we check if the file's
+ In the \c loadFile() function, we check if the file's
format is an image format by constructing a QImage which tries to
load the image from the file. If the constructor returns a null
image, we use a QMessageBox to alert the user.
@@ -135,7 +139,6 @@
information message with an \uicontrol OK button (the default) is
sufficient, since the message is part of a normal operation.
- \snippet widgets/imageviewer/imageviewer.cpp 3
\snippet widgets/imageviewer/imageviewer.cpp 4
If the format is supported, we display the image in \c imageLabel
diff --git a/examples/widgets/widgets/imageviewer/imageviewer.cpp b/examples/widgets/widgets/imageviewer/imageviewer.cpp
index 77ec92d57a..eae94a2499 100644
--- a/examples/widgets/widgets/imageviewer/imageviewer.cpp
+++ b/examples/widgets/widgets/imageviewer/imageviewer.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
@@ -61,39 +61,61 @@ ImageViewer::ImageViewer()
createActions();
createMenus();
- setWindowTitle(tr("Image Viewer"));
- resize(500, 400);
+ resize(QGuiApplication::primaryScreen()->availableSize() * 3 / 5);
}
+
//! [0]
+//! [2]
-//! [1]
-void ImageViewer::open()
-//! [1] //! [2]
+bool ImageViewer::loadFile(const QString &fileName)
{
- QString fileName = QFileDialog::getOpenFileName(this,
- tr("Open File"), QDir::currentPath());
- if (!fileName.isEmpty()) {
- QImage image(fileName);
- if (image.isNull()) {
- QMessageBox::information(this, tr("Image Viewer"),
- tr("Cannot load %1.").arg(fileName));
- return;
- }
+ QImage image(fileName);
+ if (image.isNull()) {
+ QMessageBox::information(this, QGuiApplication::applicationDisplayName(),
+ tr("Cannot load %1.").arg(QDir::toNativeSeparators(fileName)));
+ setWindowFilePath(QString());
+ imageLabel->setPixmap(QPixmap());
+ imageLabel->adjustSize();
+ return false;
+ }
//! [2] //! [3]
- imageLabel->setPixmap(QPixmap::fromImage(image));
+ imageLabel->setPixmap(QPixmap::fromImage(image));
//! [3] //! [4]
- scaleFactor = 1.0;
+ scaleFactor = 1.0;
+
+ printAct->setEnabled(true);
+ fitToWindowAct->setEnabled(true);
+ updateActions();
- printAct->setEnabled(true);
- fitToWindowAct->setEnabled(true);
- updateActions();
+ if (!fitToWindowAct->isChecked())
+ imageLabel->adjustSize();
- if (!fitToWindowAct->isChecked())
- imageLabel->adjustSize();
- }
+ setWindowFilePath(fileName);
+ return true;
}
+
//! [4]
+//! [2]
+
+//! [1]
+void ImageViewer::open()
+{
+ QStringList mimeTypeFilters;
+ foreach (const QByteArray &mimeTypeName, QImageReader::supportedMimeTypes())
+ mimeTypeFilters.append(mimeTypeName);
+ mimeTypeFilters.sort();
+ const QStringList picturesLocations = QStandardPaths::standardLocations(QStandardPaths::PicturesLocation);
+ QFileDialog dialog(this, tr("Open File"),
+ picturesLocations.isEmpty() ? QDir::currentPath() : picturesLocations.first());
+ dialog.setAcceptMode(QFileDialog::AcceptOpen);
+ dialog.setMimeTypeFilters(mimeTypeFilters);
+ dialog.selectMimeTypeFilter("image/jpeg");
+
+ while (dialog.exec() == QDialog::Accepted && !loadFile(dialog.selectedFiles().first())) {}
+}
+//! [1]
+
//! [5]
void ImageViewer::print()
//! [5] //! [6]
diff --git a/examples/widgets/widgets/imageviewer/imageviewer.h b/examples/widgets/widgets/imageviewer/imageviewer.h
index 7a0f0eb845..a4fd82a696 100644
--- a/examples/widgets/widgets/imageviewer/imageviewer.h
+++ b/examples/widgets/widgets/imageviewer/imageviewer.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
@@ -61,6 +61,7 @@ class ImageViewer : public QMainWindow
public:
ImageViewer();
+ bool loadFile(const QString &);
private slots:
void open();
diff --git a/examples/widgets/widgets/imageviewer/main.cpp b/examples/widgets/widgets/imageviewer/main.cpp
index f1697f9e3f..ee66b29591 100644
--- a/examples/widgets/widgets/imageviewer/main.cpp
+++ b/examples/widgets/widgets/imageviewer/main.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
@@ -39,13 +39,23 @@
****************************************************************************/
#include <QApplication>
+#include <QCommandLineParser>
#include "imageviewer.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
+ QGuiApplication::setApplicationDisplayName(ImageViewer::tr("Image Viewer"));
+ QCommandLineParser commandLineParser;
+ commandLineParser.addHelpOption();
+ commandLineParser.addPositionalArgument(ImageViewer::tr("[file]"), ImageViewer::tr("Image file to open."));
+ commandLineParser.process(QCoreApplication::arguments());
ImageViewer imageViewer;
+ if (!commandLineParser.positionalArguments().isEmpty()
+ && !imageViewer.loadFile(commandLineParser.positionalArguments().front())) {
+ return -1;
+ }
imageViewer.show();
return app.exec();
}
diff --git a/mkspecs/features/create_cmake.prf b/mkspecs/features/create_cmake.prf
index aee3e79765..2533b7b8d6 100644
--- a/mkspecs/features/create_cmake.prf
+++ b/mkspecs/features/create_cmake.prf
@@ -166,8 +166,6 @@ contains(CONFIG, plugin) {
return()
}
-contains($$list(network sql widgets gui), $$MODULE): CMAKE_LOAD_PLUGINS = true
-
unix:contains(QT_CONFIG, reduce_relocations):CMAKE_ADD_FPIE_FLAGS = "true"
CMAKE_MKSPEC = $$[QMAKE_XSPEC]
@@ -293,3 +291,14 @@ exists($$cmake_macros_file.input) {
}
cmake_qt5_module_files.path = $$[QT_INSTALL_LIBS]/cmake/Qt5$${CMAKE_MODULE_NAME}
+
+# We are generating cmake files. Most developers of Qt are not aware of cmake,
+# so we require automatic tests to be available. The only module which should
+# set CMAKE_MODULE_TESTS to '-' is enginio because that is known to be broken.
+# Other modules should either create proper tests in tests/auto/cmake or, as
+# a temporary measure, disable the generation of cmake files
+# with 'CONFIG -= create_cmake'
+!equals(CMAKE_MODULE_TESTS, -) {
+ isEmpty(CMAKE_MODULE_TESTS): CMAKE_MODULE_TESTS = $$MODULE_BASE_INDIR/tests/auto/cmake
+ !exists($$CMAKE_MODULE_TESTS): error("Missing CMake tests.")
+}
diff --git a/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in b/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in
index dce981e059..d1dfeed535 100644
--- a/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in
+++ b/mkspecs/features/data/cmake/Qt5BasicConfig.cmake.in
@@ -283,7 +283,7 @@ if (NOT TARGET Qt5::$${CMAKE_MODULE_NAME})
!!ENDIF // CMAKE_DEBUG_TYPE
-!!IF !isEmpty(CMAKE_LOAD_PLUGINS)
+ file(GLOB pluginTargets \"${CMAKE_CURRENT_LIST_DIR}/Qt5$${CMAKE_MODULE_NAME}_*Plugin.cmake\")
macro(_populate_$${CMAKE_MODULE_NAME}_plugin_properties Plugin Configuration PLUGIN_LOCATION)
set_property(TARGET Qt5::${Plugin} APPEND PROPERTY IMPORTED_CONFIGURATIONS ${Configuration})
@@ -299,11 +299,12 @@ if (NOT TARGET Qt5::$${CMAKE_MODULE_NAME})
)
endmacro()
- file(GLOB pluginTargets \"${CMAKE_CURRENT_LIST_DIR}/Qt5$${CMAKE_MODULE_NAME}_*Plugin.cmake\")
- foreach(pluginTarget ${pluginTargets})
- include(${pluginTarget})
- endforeach()
-!!ENDIF
+ if (pluginTargets)
+ foreach(pluginTarget ${pluginTargets})
+ include(${pluginTarget})
+ endforeach()
+ endif()
+
!!IF !isEmpty(CMAKE_MODULE_EXTRAS)
include(\"${CMAKE_CURRENT_LIST_DIR}/Qt5$${CMAKE_MODULE_NAME}ConfigExtras.cmake\")
diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf
index 90640af64a..71dfcf2912 100644
--- a/mkspecs/features/qt.prf
+++ b/mkspecs/features/qt.prf
@@ -128,7 +128,7 @@ contains(qt_module_deps, qml): \
QML_IMPORT_CPP = $$OUT_PWD/$$lower($$basename(TARGET))_qml_plugin_import.cpp
write_file($$QML_IMPORT_CPP, IMPORT_FILE_CONT)|error("Aborting.")
SOURCES += $$QML_IMPORT_CPP
- QMAKE_CLEAN += $$QML_IMPORT_CPP
+ QMAKE_DISTCLEAN += $$QML_IMPORT_CPP
# copy qml files. this part is platform spesific.
mac {
diff --git a/mkspecs/features/qt_installs.prf b/mkspecs/features/qt_installs.prf
index 7d2280e75a..3a5dbb6274 100644
--- a/mkspecs/features/qt_installs.prf
+++ b/mkspecs/features/qt_installs.prf
@@ -22,7 +22,7 @@
target.path = $$[QT_HOST_LIBS]
else: \
target.path = $$[QT_INSTALL_LIBS]
- target.CONFIG = no_dll
+ !static: target.CONFIG = no_dll
INSTALLS += target
}
diff --git a/mkspecs/features/wayland-scanner.prf b/mkspecs/features/wayland-scanner.prf
index 3a9d8cafbd..5a97d98373 100644
--- a/mkspecs/features/wayland-scanner.prf
+++ b/mkspecs/features/wayland-scanner.prf
@@ -32,6 +32,7 @@ qt_install_headers {
!isEmpty(header_files_client) {
wayland_generated_client_headers.files = $$header_files_client
wayland_generated_client_headers.path = $$private_headers.path
+ wayland_generated_client_headers.CONFIG = no_check_exist
INSTALLS += wayland_generated_client_headers
WAYLAND_CLIENT_HEADER_DEST = $$header_dest/
WAYLAND_CLIENT_INCLUDE_DIR = $$MODULE_INCNAME/private
@@ -41,6 +42,7 @@ qt_install_headers {
!isEmpty(header_files_server) {
wayland_generated_server_headers.files = $$header_files_server
wayland_generated_server_headers.path = $$private_headers.path
+ wayland_generated_server_headers.CONFIG = no_check_exist
INSTALLS += wayland_generated_server_headers
WAYLAND_SERVER_HEADER_DEST = $$header_dest/
WAYLAND_SERVER_INCLUDE_DIR = $$MODULE_INCNAME/private
diff --git a/mkspecs/qnx-armle-v7-qcc/qplatformdefs.h b/mkspecs/qnx-armle-v7-qcc/qplatformdefs.h
index 27e4a3aa41..e8590f2e3e 100644
--- a/mkspecs/qnx-armle-v7-qcc/qplatformdefs.h
+++ b/mkspecs/qnx-armle-v7-qcc/qplatformdefs.h
@@ -3,7 +3,7 @@
** Copyright (C) 2012 - 2014 BlackBerry Limited. All rights reserved.
** Contact: http://www.qt-project.org/legal
**
-** This file is part of the QtCore module of the Qt Toolkit.
+** This file is part of the qmake spec of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
@@ -42,68 +42,6 @@
#ifndef QPLATFORMDEFS_H
#define QPLATFORMDEFS_H
-// Get Qt defines/settings
-
-#include "qglobal.h"
-
-// Set any POSIX/XOPEN defines at the top of this file to turn on specific APIs
-
-#include <unistd.h>
-
-#define __STDC_CONSTANT_MACROS
-
-// We are hot - unistd.h should have turned on the specific APIs we requested
-
-
-#include <pthread.h>
-#include <dirent.h>
-#include <fcntl.h>
-#include <grp.h>
-#include <pwd.h>
-#include <signal.h>
-
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <sys/ipc.h>
-#include <sys/time.h>
-// QNX doesn't have the System V <sys/shm.h> header. This is not a standard
-// POSIX header, it's only documented in the Single UNIX Specification.
-// The preferred POSIX compliant way to share memory is to use the functions
-// in <sys/mman.h> that comply with the POSIX Real Time Interface (1003.1b).
-#include <sys/mman.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/wait.h>
-#include <netinet/in.h>
-#ifndef QT_NO_IPV6IFNAME
-#include <net/if.h>
-#endif
-
-// for htonl
-#include <arpa/inet.h>
-
-#define QT_USE_XOPEN_LFS_EXTENSIONS
-#if defined(__EXT_QNX__READDIR_R) && !defined(__EXT_QNX__READDIR64_R)
-#define QT_NO_READDIR64
-#endif
-#include "../common/posix/qplatformdefs.h"
-#if defined(__EXT_QNX__READDIR64_R)
-#define QT_EXT_QNX_READDIR_R ::_readdir64_r
-#elif defined(__EXT_QNX__READDIR_R)
-#define QT_EXT_QNX_READDIR_R ::_readdir_r
-#endif
-
-#define QT_SNPRINTF ::snprintf
-#define QT_VSNPRINTF ::vsnprintf
-
-// QNX6 doesn't have getpagesize()
-inline int getpagesize()
-{
- return ::sysconf(_SC_PAGESIZE);
-}
-
-#include <stdlib.h>
-
-#define QT_QWS_TEMP_DIR QString::fromLatin1(qgetenv("TMP"))
+#include "../common/qnx/qplatformdefs.h"
#endif // QPLATFORMDEFS_H
diff --git a/qmake/library/qmakeevaluator.cpp b/qmake/library/qmakeevaluator.cpp
index 2ea5ffd45e..8e1296e1e8 100644
--- a/qmake/library/qmakeevaluator.cpp
+++ b/qmake/library/qmakeevaluator.cpp
@@ -208,17 +208,17 @@ QMakeEvaluator::~QMakeEvaluator()
{
}
-void QMakeEvaluator::initFrom(const QMakeEvaluator &other)
+void QMakeEvaluator::initFrom(const QMakeEvaluator *other)
{
- Q_ASSERT_X(&other, "QMakeEvaluator::visitProFile", "Project not prepared");
- m_functionDefs = other.m_functionDefs;
- m_valuemapStack = other.m_valuemapStack;
+ Q_ASSERT_X(other, "QMakeEvaluator::visitProFile", "Project not prepared");
+ m_functionDefs = other->m_functionDefs;
+ m_valuemapStack = other->m_valuemapStack;
m_valuemapInited = true;
- m_qmakespec = other.m_qmakespec;
- m_qmakespecName = other.m_qmakespecName;
- m_mkspecPaths = other.m_mkspecPaths;
- m_featureRoots = other.m_featureRoots;
- m_dirSep = other.m_dirSep;
+ m_qmakespec = other->m_qmakespec;
+ m_qmakespecName = other->m_qmakespecName;
+ m_mkspecPaths = other->m_mkspecPaths;
+ m_featureRoots = other->m_featureRoots;
+ m_dirSep = other->m_dirSep;
}
//////// Evaluator tools /////////
@@ -1355,7 +1355,7 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::visitProFile(
return ReturnFalse;
#endif
- initFrom(*baseEnv->evaluator);
+ initFrom(baseEnv->evaluator);
} else {
if (!m_valuemapInited)
loadDefaults();
diff --git a/qmake/library/qmakeevaluator.h b/qmake/library/qmakeevaluator.h
index de13033481..f322a48011 100644
--- a/qmake/library/qmakeevaluator.h
+++ b/qmake/library/qmakeevaluator.h
@@ -167,7 +167,7 @@ public:
bool prepareProject(const QString &inDir);
bool loadSpecInternal();
bool loadSpec();
- void initFrom(const QMakeEvaluator &other);
+ void initFrom(const QMakeEvaluator *other);
void setupProject();
void evaluateCommand(const QString &cmds, const QString &where);
void applyExtraConfigs();
diff --git a/qmake/main.cpp b/qmake/main.cpp
index f5116ba752..82573a61fc 100644
--- a/qmake/main.cpp
+++ b/qmake/main.cpp
@@ -252,8 +252,10 @@ int runQMake(int argc, char **argv)
#endif
if(!dir.isNull() && dir != ".")
Option::output_dir = dir;
- if(QDir::isRelativePath(Option::output_dir))
+ if (QDir::isRelativePath(Option::output_dir)) {
+ Option::output.setFileName(fi.fileName());
Option::output_dir.prepend(oldpwd + QLatin1Char('/'));
+ }
Option::output_dir = QDir::cleanPath(Option::output_dir);
}
diff --git a/qmake/project.cpp b/qmake/project.cpp
index 9f75d1da27..f3d22dfb2c 100644
--- a/qmake/project.cpp
+++ b/qmake/project.cpp
@@ -60,7 +60,7 @@ QMakeProject::QMakeProject()
QMakeProject::QMakeProject(QMakeProject *p)
: QMakeEvaluator(Option::globals, Option::parser, Option::vfs, &Option::evalHandler)
{
- initFrom(*p);
+ initFrom(p);
}
bool QMakeProject::boolRet(VisitReturn vr)
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc b/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc
index 4fef861acc..2507cd1d9f 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-coretext.cc
@@ -738,7 +738,8 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
if (num_glyphs == 0)
continue;
- buffer->ensure (buffer->len + num_glyphs + (endWithPDF ? 1 : 0));
+ const long ensureCount = DIV_CEIL(sizeof(CGGlyph) + sizeof(CGPoint) + sizeof(CFIndex), sizeof(*scratch));
+ buffer->ensure (buffer->len + ensureCount * (num_glyphs + (endWithPDF ? 1 : 0)));
scratch = buffer->get_scratch_buffer (&scratch_size);
diff --git a/src/android/accessibility/jar/src/org/qtproject/qt5/android/accessibility/QtAccessibilityDelegate.java b/src/android/accessibility/jar/src/org/qtproject/qt5/android/accessibility/QtAccessibilityDelegate.java
index c2e2ea5b49..a4626b9bb1 100644
--- a/src/android/accessibility/jar/src/org/qtproject/qt5/android/accessibility/QtAccessibilityDelegate.java
+++ b/src/android/accessibility/jar/src/org/qtproject/qt5/android/accessibility/QtAccessibilityDelegate.java
@@ -53,6 +53,7 @@ import android.text.TextUtils;
import android.view.accessibility.*;
import android.view.MotionEvent;
+import android.view.View.OnHoverListener;
import android.content.Context;
@@ -85,9 +86,19 @@ public class QtAccessibilityDelegate extends View.AccessibilityDelegate
// the offset of the view on screen into account (eg status bar on top)
private final int[] m_globalOffset = new int[2];
+ private class HoverEventListener implements View.OnHoverListener
+ {
+ @Override
+ public boolean onHover(View v, MotionEvent event)
+ {
+ return dispatchHoverEvent(event);
+ }
+ }
+
public QtAccessibilityDelegate(View host)
{
m_view = host;
+ m_view.setOnHoverListener(new HoverEventListener());
m_manager = (AccessibilityManager) host.getContext()
.getSystemService(Context.ACCESSIBILITY_SERVICE);
@@ -103,7 +114,7 @@ public class QtAccessibilityDelegate extends View.AccessibilityDelegate
// For "explore by touch" we need all movement events here first
// (user moves finger over screen to discover items on screen).
- public boolean dispatchHoverEvent(MotionEvent event)
+ private boolean dispatchHoverEvent(MotionEvent event)
{
if (!m_manager.isTouchExplorationEnabled()) {
return false;
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtSurface.java b/src/android/jar/src/org/qtproject/qt5/android/QtSurface.java
index 45a80a3dbb..ca3f20f11b 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtSurface.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtSurface.java
@@ -110,24 +110,6 @@ public class QtSurface extends SurfaceView implements SurfaceHolder.Callback
}
}
- public boolean dispatchHoverEvent(MotionEvent event) {
- // Always attempt to dispatch hover events to accessibility first.
- if (m_accessibilityDelegate != null) {
- try {
- Method dispHoverA11y = m_accessibilityDelegate.getClass().getMethod("dispatchHoverEvent", MotionEvent.class);
- boolean ret = (Boolean) dispHoverA11y.invoke(m_accessibilityDelegate, event);
- if (ret)
- return true;
- SurfaceView view = (SurfaceView) this;
- Method dispHoverView = view.getClass().getMethod("dispatchHoverEvent", MotionEvent.class);
- return (Boolean) dispHoverView.invoke(view, event);
- } catch (Exception e) {
- Log.w("Qt A11y", "EXCEPTION in dispatchHoverEvent for Accessibility: " + e);
- }
- }
- return false;
- }
-
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{
diff --git a/src/corelib/arch/qatomic_bootstrap.h b/src/corelib/arch/qatomic_bootstrap.h
index 7f17387c9c..1ab901d826 100644
--- a/src/corelib/arch/qatomic_bootstrap.h
+++ b/src/corelib/arch/qatomic_bootstrap.h
@@ -67,8 +67,10 @@ template <typename T> struct QAtomicOps: QGenericAtomicOps<QAtomicOps<T> >
return --_q_value != 0;
}
- static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue) Q_DECL_NOTHROW
+ static bool testAndSetRelaxed(T &_q_value, T expectedValue, T newValue, T *currentValue = 0) Q_DECL_NOTHROW
{
+ if (currentValue)
+ *currentValue = _q_value;
if (_q_value == expectedValue) {
_q_value = newValue;
return true;
@@ -83,8 +85,8 @@ template <typename T> struct QAtomicOps: QGenericAtomicOps<QAtomicOps<T> >
return tmp;
}
- static
- T fetchAndAddRelaxed(T &_q_value, typename QAtomicAdditiveType<T>::AdditiveT valueToAdd) Q_DECL_NOTHROW
+ template <typename AdditiveType> static
+ T fetchAndAddRelaxed(T &_q_value, AdditiveType valueToAdd) Q_DECL_NOTHROW
{
T returnValue = _q_value;
_q_value += valueToAdd;
diff --git a/src/corelib/doc/snippets/code/doc_src_plugins-howto.cpp b/src/corelib/doc/snippets/code/doc_src_plugins-howto.cpp
index aae4f4bd00..b86f0bbf68 100644
--- a/src/corelib/doc/snippets/code/doc_src_plugins-howto.cpp
+++ b/src/corelib/doc/snippets/code/doc_src_plugins-howto.cpp
@@ -42,7 +42,7 @@
class MyStylePlugin : public QStylePlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QStyleFactoryInterface" FILE mystyleplugin.json)
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QStyleFactoryInterface" FILE "mystyleplugin.json")
public:
QStyle *create(const QString &key);
};
diff --git a/src/corelib/global/qglobal.h b/src/corelib/global/qglobal.h
index 80c9992e25..2bc52c6150 100644
--- a/src/corelib/global/qglobal.h
+++ b/src/corelib/global/qglobal.h
@@ -59,7 +59,11 @@
#include <QtCore/qconfig.h>
#include <QtCore/qfeatures.h>
#endif
-#define QT_SUPPORTS(FEATURE) (!defined(QT_NO_##FEATURE))
+#if defined(Q_CC_MSVC) && _MSC_VER <= 1500 /* VS2008 */
+# define QT_SUPPORTS(FEATURE) (!defined QT_NO_##FEATURE)
+#else
+# define QT_SUPPORTS(FEATURE) (!defined(QT_NO_##FEATURE))
+#endif
#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
# define QT_NO_UNSHARABLE_CONTAINERS
#endif
diff --git a/src/corelib/global/qlibraryinfo.cpp b/src/corelib/global/qlibraryinfo.cpp
index 860c954bf8..f2ebeb6a03 100644
--- a/src/corelib/global/qlibraryinfo.cpp
+++ b/src/corelib/global/qlibraryinfo.cpp
@@ -566,7 +566,7 @@ QLibraryInfo::rawLocation(LibraryLocation loc, PathGroup group)
QStringList QLibraryInfo::platformPluginArguments(const QString &platformName)
{
-#ifndef QT_BOOTSTRAPPED
+#if !defined(QT_BOOTSTRAPPED) && !defined(QT_NO_SETTINGS)
if (const QSettings *settings = QLibraryInfoPrivate::findConfiguration()) {
QString key = QLatin1String(platformsSection);
key += QLatin1Char('/');
@@ -574,7 +574,7 @@ QStringList QLibraryInfo::platformPluginArguments(const QString &platformName)
key += QLatin1String("Arguments");
return settings->value(key).toStringList();
}
-#endif // !QT_BOOTSTRAPPED
+#endif // !QT_BOOTSTRAPPED && !QT_NO_SETTINGS
return QStringList();
}
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp
index 24a73fffb9..f908dd512e 100644
--- a/src/corelib/global/qlogging.cpp
+++ b/src/corelib/global/qlogging.cpp
@@ -1395,8 +1395,7 @@ void qErrnoWarning(int code, const char *msg, ...)
\since 5.0
Installs a Qt message \a handler which has been defined
- previously. Returns a pointer to the previous message handler
- (which may be 0).
+ previously. Returns a pointer to the previous message handler.
The message handler is a function that prints out debug messages,
warnings, critical and fatal error messages. The Qt library (debug
diff --git a/src/corelib/io/qfileinfo.cpp b/src/corelib/io/qfileinfo.cpp
index 60f7e47e62..210bb3898c 100644
--- a/src/corelib/io/qfileinfo.cpp
+++ b/src/corelib/io/qfileinfo.cpp
@@ -530,7 +530,8 @@ void QFileInfo::setFile(const QDir &dir, const QString &file)
is true. In contrast to canonicalFilePath(), symbolic links or
redundant "." or ".." elements are not necessarily removed.
- If the QFileInfo is empty it returns QDir::currentPath().
+ \warning If filePath() is empty the behavior of this function
+ is undefined.
\sa filePath(), canonicalFilePath(), isRelative()
*/
@@ -572,8 +573,8 @@ QString QFileInfo::canonicalFilePath() const
In contrast to canonicalPath() symbolic links or redundant "." or
".." elements are not necessarily removed.
- \warning If the QFileInfo object was created with an empty QString,
- the behavior of this function is undefined.
+ \warning If filePath() is empty the behavior of this function
+ is undefined.
\sa absoluteFilePath(), path(), canonicalPath(), fileName(), isRelative()
*/
diff --git a/src/corelib/io/qfilesystemwatcher_fsevents.mm b/src/corelib/io/qfilesystemwatcher_fsevents.mm
index 981d663694..085396da6d 100644
--- a/src/corelib/io/qfilesystemwatcher_fsevents.mm
+++ b/src/corelib/io/qfilesystemwatcher_fsevents.mm
@@ -64,6 +64,25 @@
QT_BEGIN_NAMESPACE
+namespace {
+class RaiiAutoreleasePool
+{
+ Q_DISABLE_COPY(RaiiAutoreleasePool)
+
+public:
+ RaiiAutoreleasePool()
+ : pool([[NSAutoreleasePool alloc] init])
+ {}
+
+ ~RaiiAutoreleasePool()
+ { [pool release]; }
+
+private:
+ NSAutoreleasePool *pool;
+};
+#define Q_AUTORELEASE_POOL(pool) RaiiAutoreleasePool pool; Q_UNUSED(pool);
+}
+
static void callBackFunction(ConstFSEventStreamRef streamRef,
void *clientCallBackInfo,
size_t numEvents,
@@ -71,6 +90,8 @@ static void callBackFunction(ConstFSEventStreamRef streamRef,
const FSEventStreamEventFlags eventFlags[],
const FSEventStreamEventId eventIds[])
{
+ Q_AUTORELEASE_POOL(pool)
+
char **paths = static_cast<char **>(eventPaths);
QFseventsFileSystemWatcherEngine *engine = static_cast<QFseventsFileSystemWatcherEngine *>(clientCallBackInfo);
engine->processEvent(streamRef, numEvents, paths, eventFlags, eventIds);
@@ -283,6 +304,7 @@ void QFseventsFileSystemWatcherEngine::doEmitDirectoryChanged(const QString path
void QFseventsFileSystemWatcherEngine::restartStream()
{
+ Q_AUTORELEASE_POOL(pool)
QMutexLocker locker(&lock);
stopStream();
startStream();
@@ -313,6 +335,8 @@ QFseventsFileSystemWatcherEngine::QFseventsFileSystemWatcherEngine(QObject *pare
QFseventsFileSystemWatcherEngine::~QFseventsFileSystemWatcherEngine()
{
+ Q_AUTORELEASE_POOL(pool)
+
if (stream)
FSEventStreamStop(stream);
@@ -327,6 +351,8 @@ QStringList QFseventsFileSystemWatcherEngine::addPaths(const QStringList &paths,
QStringList *files,
QStringList *directories)
{
+ Q_AUTORELEASE_POOL(pool)
+
if (stream) {
DEBUG("Flushing, last id is %llu", FSEventStreamGetLatestEventId(stream));
FSEventStreamFlushSync(stream);
@@ -413,6 +439,8 @@ QStringList QFseventsFileSystemWatcherEngine::removePaths(const QStringList &pat
QStringList *files,
QStringList *directories)
{
+ Q_AUTORELEASE_POOL(pool)
+
QMutexLocker locker(&lock);
bool needsRestart = false;
diff --git a/src/corelib/io/qloggingcategory.cpp b/src/corelib/io/qloggingcategory.cpp
index 518052e537..07245ddea2 100644
--- a/src/corelib/io/qloggingcategory.cpp
+++ b/src/corelib/io/qloggingcategory.cpp
@@ -50,6 +50,18 @@ const char qtDefaultCategoryName[] = "default";
Q_GLOBAL_STATIC_WITH_ARGS(QLoggingCategory, qtDefaultCategory,
(qtDefaultCategoryName))
+#ifndef Q_ATOMIC_INT8_IS_SUPPORTED
+static void setBoolLane(QBasicAtomicInt *atomic, bool enable, int shift)
+{
+ const int bit = 1 << shift;
+
+ if (enable)
+ atomic->fetchAndOrRelaxed(bit);
+ else
+ atomic->fetchAndAndRelaxed(~bit);
+}
+#endif
+
/*!
\class QLoggingCategory
\inmodule QtCore
@@ -129,13 +141,13 @@ Q_GLOBAL_STATIC_WITH_ARGS(QLoggingCategory, qtDefaultCategory,
Order of evaluation:
\list
- \li Rules from QtProject/qlogging.ini
+ \li Rules from QtProject/qtlogging.ini
\li Rules set by \l setFilterRules()
\li Rules from file in \c QT_LOGGING_CONF
\li Rules from environment variable QT_LOGGING_RULES
\endlist
- The \c QtProject/qlogging.ini file is looked up in all directories returned
+ The \c QtProject/qtlogging.ini file is looked up in all directories returned
by QStandardPaths::GenericConfigLocation, e.g.
\list
@@ -171,13 +183,11 @@ Q_GLOBAL_STATIC_WITH_ARGS(QLoggingCategory, qtDefaultCategory,
*/
QLoggingCategory::QLoggingCategory(const char *category)
: d(0),
- name(0),
- enabledDebug(true),
- enabledWarning(true),
- enabledCritical(true)
+ name(0)
{
Q_UNUSED(d);
Q_UNUSED(placeholder);
+ enabled.store(0x01010101); // enabledDebug = enabledWarning = enabledCritical = true;
const bool isDefaultCategory
= (category == 0) || (strcmp(category, qtDefaultCategoryName) == 0);
@@ -249,9 +259,9 @@ QLoggingCategory::~QLoggingCategory()
bool QLoggingCategory::isEnabled(QtMsgType msgtype) const
{
switch (msgtype) {
- case QtDebugMsg: return enabledDebug;
- case QtWarningMsg: return enabledWarning;
- case QtCriticalMsg: return enabledCritical;
+ case QtDebugMsg: return isDebugEnabled();
+ case QtWarningMsg: return isWarningEnabled();
+ case QtCriticalMsg: return isCriticalEnabled();
case QtFatalMsg: return true;
}
return false;
@@ -270,9 +280,15 @@ bool QLoggingCategory::isEnabled(QtMsgType msgtype) const
void QLoggingCategory::setEnabled(QtMsgType type, bool enable)
{
switch (type) {
- case QtDebugMsg: enabledDebug = enable; break;
- case QtWarningMsg: enabledWarning = enable; break;
- case QtCriticalMsg: enabledCritical = enable; break;
+#ifdef Q_ATOMIC_INT8_IS_SUPPORTED
+ case QtDebugMsg: bools.enabledDebug.store(enable); break;
+ case QtWarningMsg: bools.enabledWarning.store(enable); break;
+ case QtCriticalMsg: bools.enabledCritical.store(enable); break;
+#else
+ case QtDebugMsg: setBoolLane(&enabled, enable, DebugShift); break;
+ case QtWarningMsg: setBoolLane(&enabled, enable, WarningShift); break;
+ case QtCriticalMsg: setBoolLane(&enabled, enable, CriticalShift); break;
+#endif
case QtFatalMsg: break;
}
}
diff --git a/src/corelib/io/qloggingcategory.h b/src/corelib/io/qloggingcategory.h
index 4aec8e63bf..573af2105c 100644
--- a/src/corelib/io/qloggingcategory.h
+++ b/src/corelib/io/qloggingcategory.h
@@ -57,10 +57,15 @@ public:
bool isEnabled(QtMsgType type) const;
void setEnabled(QtMsgType type, bool enable);
- bool isDebugEnabled() const { return enabledDebug; }
- bool isWarningEnabled() const { return enabledWarning; }
- bool isCriticalEnabled() const { return enabledCritical; }
-
+#ifdef Q_ATOMIC_INT8_IS_SUPPORTED
+ bool isDebugEnabled() const { return bools.enabledDebug.load(); }
+ bool isWarningEnabled() const { return bools.enabledWarning.load(); }
+ bool isCriticalEnabled() const { return bools.enabledCritical.load(); }
+#else
+ bool isDebugEnabled() const { return enabled.load() >> DebugShift & 1; }
+ bool isWarningEnabled() const { return enabled.load() >> WarningShift & 1; }
+ bool isCriticalEnabled() const { return enabled.load() >> CriticalShift & 1; }
+#endif
const char *categoryName() const { return name; }
// allows usage of both factory method and variable in qCX macros
@@ -78,10 +83,24 @@ private:
void *d; // reserved for future use
const char *name;
- bool enabledDebug;
- bool enabledWarning;
- bool enabledCritical;
- bool placeholder[5]; // reserve for future use
+#ifdef Q_BIG_ENDIAN
+ enum { DebugShift = 0, WarningShift = 8, CriticalShift = 16 };
+#else
+ enum { DebugShift = 24, WarningShift = 16, CriticalShift = 8 };
+#endif
+
+ struct AtomicBools {
+#ifdef Q_ATOMIC_INT8_IS_SUPPORTED
+ QBasicAtomicInteger<bool> enabledDebug;
+ QBasicAtomicInteger<bool> enabledWarning;
+ QBasicAtomicInteger<bool> enabledCritical;
+#endif
+ };
+ union {
+ AtomicBools bools;
+ QBasicAtomicInt enabled;
+ };
+ bool placeholder[4]; // reserve for future use
};
#define Q_DECLARE_LOGGING_CATEGORY(name) \
diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp
index 9f9cba81ab..b03e96d0f6 100644
--- a/src/corelib/io/qprocess.cpp
+++ b/src/corelib/io/qprocess.cpp
@@ -1,6 +1,7 @@
/****************************************************************************
**
** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Intel Corporation
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -819,9 +820,6 @@ QProcessPrivate::QProcessPrivate()
emittedBytesWritten = false;
#ifdef Q_OS_WIN
notifier = 0;
- stdoutReader = 0;
- stderrReader = 0;
- pipeWriter = 0;
processFinishedNotifier = 0;
#endif // Q_OS_WIN
#ifdef Q_OS_UNIX
@@ -889,9 +887,9 @@ void QProcessPrivate::cleanup()
notifier = 0;
}
#endif
- destroyChannel(&stdoutChannel);
- destroyChannel(&stderrChannel);
- destroyChannel(&stdinChannel);
+ closeChannel(&stdoutChannel);
+ closeChannel(&stderrChannel);
+ closeChannel(&stdinChannel);
destroyPipe(childStartedPipe);
destroyPipe(deathPipe);
#ifdef Q_OS_UNIX
@@ -901,49 +899,63 @@ void QProcessPrivate::cleanup()
/*!
\internal
+ Returns true if we emitted readyRead().
*/
-bool QProcessPrivate::_q_canReadStandardOutput()
+bool QProcessPrivate::tryReadFromChannel(Channel *channel)
{
Q_Q(QProcess);
- qint64 available = bytesAvailableFromStdout();
- if (available == 0) {
- if (stdoutChannel.notifier)
- stdoutChannel.notifier->setEnabled(false);
- destroyChannel(&stdoutChannel);
-#if defined QPROCESS_DEBUG
- qDebug("QProcessPrivate::canReadStandardOutput(), 0 bytes available");
-#endif
+ if (channel->pipe[0] == INVALID_Q_PIPE)
return false;
- }
- char *ptr = outputReadBuffer.reserve(available);
- qint64 readBytes = readFromStdout(ptr, available);
+ qint64 available = bytesAvailableInChannel(channel);
+ if (available == 0)
+ available = 1; // always try to read at least one byte
+
+ char *ptr = channel->buffer.reserve(available);
+ qint64 readBytes = readFromChannel(channel, ptr, available);
+ if (readBytes <= 0)
+ channel->buffer.chop(available);
+ if (readBytes == -2) {
+ // EWOULDBLOCK
+ return false;
+ }
if (readBytes == -1) {
processError = QProcess::ReadError;
q->setErrorString(QProcess::tr("Error reading from process"));
emit q->error(processError);
#if defined QPROCESS_DEBUG
- qDebug("QProcessPrivate::canReadStandardOutput(), failed to read from the process");
+ qDebug("QProcessPrivate::tryReadFromChannel(%d), failed to read from the process", channel - &stdinChannel);
+#endif
+ return false;
+ }
+ if (readBytes == 0) {
+ // EOF
+ if (channel->notifier)
+ channel->notifier->setEnabled(false);
+ closeChannel(channel);
+#if defined QPROCESS_DEBUG
+ qDebug("QProcessPrivate::tryReadFromChannel(%d), 0 bytes available", channel - &stdinChannel);
#endif
return false;
}
#if defined QPROCESS_DEBUG
- qDebug("QProcessPrivate::canReadStandardOutput(), read %d bytes from the process' output",
+ qDebug("QProcessPrivate::tryReadFromChannel(%d), read %d bytes from the process' output", channel - &stdinChannel
int(readBytes));
#endif
- if (stdoutChannel.closed) {
- outputReadBuffer.chop(readBytes);
+ if (channel->closed) {
+ channel->buffer.chop(readBytes);
return false;
}
- outputReadBuffer.chop(available - readBytes);
+ channel->buffer.chop(available - readBytes);
bool didRead = false;
+ bool isStdout = channel == &stdoutChannel;
if (readBytes == 0) {
- if (stdoutChannel.notifier)
- stdoutChannel.notifier->setEnabled(false);
- } else if (processChannel == QProcess::StandardOutput) {
+ if (channel->notifier)
+ channel->notifier->setEnabled(false);
+ } else if ((processChannel == QProcess::StandardOutput) == isStdout) {
didRead = true;
if (!emittedReadyRead) {
emittedReadyRead = true;
@@ -951,53 +963,27 @@ bool QProcessPrivate::_q_canReadStandardOutput()
emittedReadyRead = false;
}
}
- emit q->readyReadStandardOutput(QProcess::QPrivateSignal());
+ if (isStdout)
+ emit q->readyReadStandardOutput(QProcess::QPrivateSignal());
+ else
+ emit q->readyReadStandardError(QProcess::QPrivateSignal());
return didRead;
}
/*!
\internal
*/
-bool QProcessPrivate::_q_canReadStandardError()
+bool QProcessPrivate::_q_canReadStandardOutput()
{
- Q_Q(QProcess);
- qint64 available = bytesAvailableFromStderr();
- if (available == 0) {
- if (stderrChannel.notifier)
- stderrChannel.notifier->setEnabled(false);
- destroyChannel(&stderrChannel);
- return false;
- }
-
- char *ptr = errorReadBuffer.reserve(available);
- qint64 readBytes = readFromStderr(ptr, available);
- if (readBytes == -1) {
- processError = QProcess::ReadError;
- q->setErrorString(QProcess::tr("Error reading from process"));
- emit q->error(processError);
- return false;
- }
- if (stderrChannel.closed) {
- errorReadBuffer.chop(readBytes);
- return false;
- }
-
- errorReadBuffer.chop(available - readBytes);
+ return tryReadFromChannel(&stdoutChannel);
+}
- bool didRead = false;
- if (readBytes == 0) {
- if (stderrChannel.notifier)
- stderrChannel.notifier->setEnabled(false);
- } else if (processChannel == QProcess::StandardError) {
- didRead = true;
- if (!emittedReadyRead) {
- emittedReadyRead = true;
- emit q->readyRead();
- emittedReadyRead = false;
- }
- }
- emit q->readyReadStandardError(QProcess::QPrivateSignal());
- return didRead;
+/*!
+ \internal
+*/
+bool QProcessPrivate::_q_canReadStandardError()
+{
+ return tryReadFromChannel(&stderrChannel);
}
/*!
@@ -1009,17 +995,17 @@ bool QProcessPrivate::_q_canWrite()
if (stdinChannel.notifier)
stdinChannel.notifier->setEnabled(false);
- if (writeBuffer.isEmpty()) {
+ if (stdinChannel.buffer.isEmpty()) {
#if defined QPROCESS_DEBUG
qDebug("QProcessPrivate::canWrite(), not writing anything (empty write buffer).");
#endif
return false;
}
- qint64 written = writeToStdin(writeBuffer.readPointer(),
- writeBuffer.nextDataBlockSize());
+ qint64 written = writeToStdin(stdinChannel.buffer.readPointer(),
+ stdinChannel.buffer.nextDataBlockSize());
if (written < 0) {
- destroyChannel(&stdinChannel);
+ closeChannel(&stdinChannel);
processError = QProcess::WriteError;
q->setErrorString(QProcess::tr("Error writing to process"));
emit q->error(processError);
@@ -1031,16 +1017,16 @@ bool QProcessPrivate::_q_canWrite()
#endif
if (written != 0) {
- writeBuffer.free(written);
+ stdinChannel.buffer.free(written);
if (!emittedBytesWritten) {
emittedBytesWritten = true;
emit q->bytesWritten(written);
emittedBytesWritten = false;
}
}
- if (stdinChannel.notifier && !writeBuffer.isEmpty())
+ if (stdinChannel.notifier && !stdinChannel.buffer.isEmpty())
stdinChannel.notifier->setEnabled(true);
- if (writeBuffer.isEmpty() && stdinChannel.closed)
+ if (stdinChannel.buffer.isEmpty() && stdinChannel.closed)
closeWriteChannel();
return true;
}
@@ -1163,7 +1149,7 @@ void QProcessPrivate::closeWriteChannel()
// instead.
flushPipeWriter();
#endif
- destroyChannel(&stdinChannel);
+ closeChannel(&stdinChannel);
}
/*!
@@ -1308,10 +1294,10 @@ void QProcess::setReadChannel(ProcessChannel channel)
QByteArray buf = d->buffer.readAll();
if (d->processChannel == QProcess::StandardOutput) {
for (int i = buf.size() - 1; i >= 0; --i)
- d->outputReadBuffer.ungetChar(buf.at(i));
+ d->stdoutChannel.buffer.ungetChar(buf.at(i));
} else {
for (int i = buf.size() - 1; i >= 0; --i)
- d->errorReadBuffer.ungetChar(buf.at(i));
+ d->stderrChannel.buffer.ungetChar(buf.at(i));
}
}
d->processChannel = channel;
@@ -1359,7 +1345,7 @@ void QProcess::closeWriteChannel()
{
Q_D(QProcess);
d->stdinChannel.closed = true; // closing
- if (d->writeBuffer.isEmpty())
+ if (d->stdinChannel.buffer.isEmpty())
d->closeWriteChannel();
}
@@ -1589,8 +1575,8 @@ bool QProcess::canReadLine() const
{
Q_D(const QProcess);
const QRingBuffer *readBuffer = (d->processChannel == QProcess::StandardError)
- ? &d->errorReadBuffer
- : &d->outputReadBuffer;
+ ? &d->stderrChannel.buffer
+ : &d->stdoutChannel.buffer;
return readBuffer->canReadLine() || QIODevice::canReadLine();
}
@@ -1618,8 +1604,8 @@ bool QProcess::atEnd() const
{
Q_D(const QProcess);
const QRingBuffer *readBuffer = (d->processChannel == QProcess::StandardError)
- ? &d->errorReadBuffer
- : &d->outputReadBuffer;
+ ? &d->stderrChannel.buffer
+ : &d->stdoutChannel.buffer;
return QIODevice::atEnd() && (!isOpen() || readBuffer->isEmpty());
}
@@ -1636,8 +1622,8 @@ qint64 QProcess::bytesAvailable() const
{
Q_D(const QProcess);
const QRingBuffer *readBuffer = (d->processChannel == QProcess::StandardError)
- ? &d->errorReadBuffer
- : &d->outputReadBuffer;
+ ? &d->stderrChannel.buffer
+ : &d->stdoutChannel.buffer;
#if defined QPROCESS_DEBUG
qDebug("QProcess::bytesAvailable() == %i (%s)", readBuffer->size(),
(d->processChannel == QProcess::StandardError) ? "stderr" : "stdout");
@@ -1650,7 +1636,7 @@ qint64 QProcess::bytesAvailable() const
qint64 QProcess::bytesToWrite() const
{
Q_D(const QProcess);
- qint64 size = d->writeBuffer.size();
+ qint64 size = d->stdinChannel.buffer.size();
#ifdef Q_OS_WIN
size += d->pipeWriterBytesToWrite();
#endif
@@ -1897,8 +1883,8 @@ qint64 QProcess::readData(char *data, qint64 maxlen)
if (!maxlen)
return 0;
QRingBuffer *readBuffer = (d->processChannel == QProcess::StandardError)
- ? &d->errorReadBuffer
- : &d->outputReadBuffer;
+ ? &d->stderrChannel.buffer
+ : &d->stdoutChannel.buffer;
if (maxlen == 1 && !readBuffer->isEmpty()) {
int c = readBuffer->getChar();
@@ -1961,7 +1947,7 @@ qint64 QProcess::writeData(const char *data, qint64 len)
}
if (len == 1) {
- d->writeBuffer.putChar(*data);
+ d->stdinChannel.buffer.putChar(*data);
if (d->stdinChannel.notifier)
d->stdinChannel.notifier->setEnabled(true);
#if defined QPROCESS_DEBUG
@@ -1971,7 +1957,7 @@ qint64 QProcess::writeData(const char *data, qint64 len)
return 1;
}
- char *dest = d->writeBuffer.reserve(len);
+ char *dest = d->stdinChannel.buffer.reserve(len);
memcpy(dest, data, len);
if (d->stdinChannel.notifier)
d->stdinChannel.notifier->setEnabled(true);
@@ -2112,8 +2098,8 @@ void QProcessPrivate::start(QIODevice::OpenMode mode)
qDebug() << "QProcess::start(" << program << ',' << arguments << ',' << mode << ')';
#endif
- outputReadBuffer.clear();
- errorReadBuffer.clear();
+ stdoutChannel.buffer.clear();
+ stderrChannel.buffer.clear();
if (stdinChannel.type != QProcessPrivate::Channel::Normal)
mode &= ~QIODevice::WriteOnly; // not open for writing
diff --git a/src/corelib/io/qprocess_p.h b/src/corelib/io/qprocess_p.h
index 5d65b2a068..6cd9047c04 100644
--- a/src/corelib/io/qprocess_p.h
+++ b/src/corelib/io/qprocess_p.h
@@ -253,6 +253,9 @@ public:
{
pipe[0] = INVALID_Q_PIPE;
pipe[1] = INVALID_Q_PIPE;
+#ifdef Q_OS_WIN
+ reader = 0;
+#endif
}
void clear();
@@ -282,6 +285,13 @@ public:
QString file;
QProcessPrivate *process;
QSocketNotifier *notifier;
+#ifdef Q_OS_WIN
+ union {
+ QWindowsPipeReader *reader;
+ QWindowsPipeWriter *writer;
+ };
+#endif
+ QRingBuffer buffer;
Q_PIPE pipe[2];
unsigned type : 2;
@@ -316,8 +326,10 @@ public:
Channel stdinChannel;
Channel stdoutChannel;
Channel stderrChannel;
- bool createChannel(Channel &channel);
+ bool openChannel(Channel &channel);
+ void closeChannel(Channel *channel);
void closeWriteChannel();
+ bool tryReadFromChannel(Channel *channel); // obviously, only stdout and stderr
QString program;
QStringList arguments;
@@ -326,14 +338,9 @@ public:
#endif
QProcessEnvironment environment;
- QRingBuffer outputReadBuffer;
- QRingBuffer errorReadBuffer;
- QRingBuffer writeBuffer;
-
Q_PIPE childStartedPipe[2];
Q_PIPE deathPipe[2];
void destroyPipe(Q_PIPE pipe[2]);
- void destroyChannel(Channel *channel);
QSocketNotifier *startupSocketNotifier;
QSocketNotifier *deathNotifier;
@@ -341,9 +348,6 @@ public:
#ifdef Q_OS_WIN
// the wonderful windows notifier
QTimer *notifier;
- QWindowsPipeReader *stdoutReader;
- QWindowsPipeReader *stderrReader;
- QWindowsPipeWriter *pipeWriter;
QWinEventNotifier *processFinishedNotifier;
#endif
@@ -383,10 +387,8 @@ public:
bool waitForFinished(int msecs = 30000);
bool waitForWrite(int msecs = 30000);
- qint64 bytesAvailableFromStdout() const;
- qint64 bytesAvailableFromStderr() const;
- qint64 readFromStdout(char *data, qint64 maxlen);
- qint64 readFromStderr(char *data, qint64 maxlen);
+ qint64 bytesAvailableInChannel(const Channel *channel) const;
+ qint64 readFromChannel(const Channel *channel, char *data, qint64 maxlen);
qint64 writeToStdin(const char *data, qint64 maxlen);
void cleanup();
diff --git a/src/corelib/io/qprocess_unix.cpp b/src/corelib/io/qprocess_unix.cpp
index 8674371baa..2269740a2f 100644
--- a/src/corelib/io/qprocess_unix.cpp
+++ b/src/corelib/io/qprocess_unix.cpp
@@ -377,7 +377,7 @@ void QProcessPrivate::destroyPipe(int *pipe)
}
}
-void QProcessPrivate::destroyChannel(Channel *channel)
+void QProcessPrivate::closeChannel(Channel *channel)
{
destroyPipe(channel->pipe);
}
@@ -387,7 +387,7 @@ void QProcessPrivate::destroyChannel(Channel *channel)
This function must be called in order: stdin, stdout, stderr
*/
-bool QProcessPrivate::createChannel(Channel &channel)
+bool QProcessPrivate::openChannel(Channel &channel)
{
Q_Q(QProcess);
@@ -573,9 +573,9 @@ void QProcessPrivate::startProcess()
processManager()->start();
// Initialize pipes
- if (!createChannel(stdinChannel) ||
- !createChannel(stdoutChannel) ||
- !createChannel(stderrChannel) ||
+ if (!openChannel(stdinChannel) ||
+ !openChannel(stdoutChannel) ||
+ !openChannel(stderrChannel) ||
qt_create_pipe(childStartedPipe) != 0 ||
qt_create_pipe(deathPipe) != 0) {
processError = QProcess::FailedToStart;
@@ -963,47 +963,32 @@ bool QProcessPrivate::processStarted()
return i <= 0;
}
-qint64 QProcessPrivate::bytesAvailableFromStdout() const
+qint64 QProcessPrivate::bytesAvailableInChannel(const Channel *channel) const
{
+ Q_ASSERT(channel->pipe[0] != INVALID_Q_PIPE);
int nbytes = 0;
qint64 available = 0;
- if (::ioctl(stdoutChannel.pipe[0], FIONREAD, (char *) &nbytes) >= 0)
+ if (::ioctl(channel->pipe[0], FIONREAD, (char *) &nbytes) >= 0)
available = (qint64) nbytes;
#if defined (QPROCESS_DEBUG)
- qDebug("QProcessPrivate::bytesAvailableFromStdout() == %lld", available);
+ qDebug("QProcessPrivate::bytesAvailableInChannel(%d) == %lld", channel - &stdinChannel, available);
#endif
return available;
}
-qint64 QProcessPrivate::bytesAvailableFromStderr() const
+qint64 QProcessPrivate::readFromChannel(const Channel *channel, char *data, qint64 maxlen)
{
- int nbytes = 0;
- qint64 available = 0;
- if (::ioctl(stderrChannel.pipe[0], FIONREAD, (char *) &nbytes) >= 0)
- available = (qint64) nbytes;
-#if defined (QPROCESS_DEBUG)
- qDebug("QProcessPrivate::bytesAvailableFromStderr() == %lld", available);
-#endif
- return available;
-}
-
-qint64 QProcessPrivate::readFromStdout(char *data, qint64 maxlen)
-{
- qint64 bytesRead = qt_safe_read(stdoutChannel.pipe[0], data, maxlen);
-#if defined QPROCESS_DEBUG
- qDebug("QProcessPrivate::readFromStdout(%p \"%s\", %lld) == %lld",
- data, qt_prettyDebug(data, bytesRead, 16).constData(), maxlen, bytesRead);
-#endif
- return bytesRead;
-}
-
-qint64 QProcessPrivate::readFromStderr(char *data, qint64 maxlen)
-{
- qint64 bytesRead = qt_safe_read(stderrChannel.pipe[0], data, maxlen);
+ Q_ASSERT(channel->pipe[0] != INVALID_Q_PIPE);
+ qint64 bytesRead = qt_safe_read(channel->pipe[0], data, maxlen);
#if defined QPROCESS_DEBUG
- qDebug("QProcessPrivate::readFromStderr(%p \"%s\", %lld) == %lld",
+ int save_errno = errno;
+ qDebug("QProcessPrivate::readFromChannel(%d, %p \"%s\", %lld) == %lld",
+ channel - &stdinChannel,
data, qt_prettyDebug(data, bytesRead, 16).constData(), maxlen, bytesRead);
+ errno = save_errno;
#endif
+ if (bytesRead == -1 && errno == EWOULDBLOCK)
+ return -2;
return bytesRead;
}
@@ -1126,7 +1111,7 @@ bool QProcessPrivate::waitForReadyRead(int msecs)
if (stderrChannel.pipe[0] != -1)
add_fd(nfds, stderrChannel.pipe[0], &fdread);
- if (!writeBuffer.isEmpty() && stdinChannel.pipe[1] != -1)
+ if (!stdinChannel.buffer.isEmpty() && stdinChannel.pipe[1] != -1)
add_fd(nfds, stdinChannel.pipe[1], &fdwrite);
int timeout = qt_timeout_value(msecs, stopWatch.elapsed());
@@ -1188,7 +1173,7 @@ bool QProcessPrivate::waitForBytesWritten(int msecs)
QList<QSocketNotifier *> notifiers = defaultNotifiers();
#endif
- while (!writeBuffer.isEmpty()) {
+ while (!stdinChannel.buffer.isEmpty()) {
fd_set fdread;
fd_set fdwrite;
@@ -1207,7 +1192,7 @@ bool QProcessPrivate::waitForBytesWritten(int msecs)
add_fd(nfds, stderrChannel.pipe[0], &fdread);
- if (!writeBuffer.isEmpty() && stdinChannel.pipe[1] != -1)
+ if (!stdinChannel.buffer.isEmpty() && stdinChannel.pipe[1] != -1)
add_fd(nfds, stdinChannel.pipe[1], &fdwrite);
int timeout = qt_timeout_value(msecs, stopWatch.elapsed());
@@ -1282,7 +1267,7 @@ bool QProcessPrivate::waitForFinished(int msecs)
if (processState == QProcess::Running)
add_fd(nfds, deathPipe[0], &fdread);
- if (!writeBuffer.isEmpty() && stdinChannel.pipe[1] != -1)
+ if (!stdinChannel.buffer.isEmpty() && stdinChannel.pipe[1] != -1)
add_fd(nfds, stdinChannel.pipe[1], &fdwrite);
int timeout = qt_timeout_value(msecs, stopWatch.elapsed());
diff --git a/src/corelib/io/qprocess_win.cpp b/src/corelib/io/qprocess_win.cpp
index d7050034bd..7b3f1f8f58 100644
--- a/src/corelib/io/qprocess_win.cpp
+++ b/src/corelib/io/qprocess_win.cpp
@@ -158,7 +158,7 @@ static void duplicateStdWriteChannel(Q_PIPE *pipe, DWORD nStdHandle)
This function must be called in order: stdin, stdout, stderr
*/
-bool QProcessPrivate::createChannel(Channel &channel)
+bool QProcessPrivate::openChannel(Channel &channel)
{
Q_Q(QProcess);
@@ -180,34 +180,31 @@ bool QProcessPrivate::createChannel(Channel &channel)
&channel.pipe[0], 0, TRUE, DUPLICATE_SAME_ACCESS);
}
} else {
- QWindowsPipeReader *pipeReader = 0;
if (&channel == &stdoutChannel) {
if (processChannelMode != QProcess::ForwardedChannels
&& processChannelMode != QProcess::ForwardedOutputChannel) {
- if (!stdoutReader) {
- stdoutReader = new QWindowsPipeReader(q);
- q->connect(stdoutReader, SIGNAL(readyRead()), SLOT(_q_canReadStandardOutput()));
+ if (!stdoutChannel.reader) {
+ stdoutChannel.reader = new QWindowsPipeReader(q);
+ q->connect(stdoutChannel.reader, SIGNAL(readyRead()), SLOT(_q_canReadStandardOutput()));
}
- pipeReader = stdoutReader;
} else {
duplicateStdWriteChannel(channel.pipe, STD_OUTPUT_HANDLE);
}
} else /* if (&channel == &stderrChannel) */ {
if (processChannelMode != QProcess::ForwardedChannels
&& processChannelMode != QProcess::ForwardedErrorChannel) {
- if (!stderrReader) {
- stderrReader = new QWindowsPipeReader(q);
- q->connect(stderrReader, SIGNAL(readyRead()), SLOT(_q_canReadStandardError()));
+ if (!stderrChannel.reader) {
+ stderrChannel.reader = new QWindowsPipeReader(q);
+ q->connect(stderrChannel.reader, SIGNAL(readyRead()), SLOT(_q_canReadStandardError()));
}
- pipeReader = stderrReader;
} else {
duplicateStdWriteChannel(channel.pipe, STD_ERROR_HANDLE);
}
}
- if (pipeReader) {
+ if (channel.reader) {
qt_create_pipe(channel.pipe, false);
- pipeReader->setHandle(channel.pipe[0]);
- pipeReader->startAsyncRead();
+ channel.reader->setHandle(channel.pipe[0]);
+ channel.reader->startAsyncRead();
}
}
@@ -332,25 +329,15 @@ void QProcessPrivate::destroyPipe(Q_PIPE pipe[2])
}
}
-void QProcessPrivate::destroyChannel(Channel *channel)
+void QProcessPrivate::closeChannel(Channel *channel)
{
if (channel == &stdinChannel) {
- if (pipeWriter) {
- delete pipeWriter;
- pipeWriter = 0;
- }
- } else if (channel == &stdoutChannel) {
- if (stdoutReader) {
- stdoutReader->stop();
- stdoutReader->deleteLater();
- stdoutReader = 0;
- }
- } else if (channel == &stderrChannel) {
- if (stderrReader) {
- stderrReader->stop();
- stderrReader->deleteLater();
- stderrReader = 0;
- }
+ delete stdinChannel.writer;
+ stdinChannel.writer = 0;
+ } else if (channel->reader) {
+ channel->reader->stop();
+ channel->reader->deleteLater();
+ channel->reader = 0;
}
destroyPipe(channel->pipe);
}
@@ -486,9 +473,9 @@ void QProcessPrivate::startProcess()
q->setProcessState(QProcess::Starting);
- if (!createChannel(stdinChannel) ||
- !createChannel(stdoutChannel) ||
- !createChannel(stderrChannel))
+ if (!openChannel(stdinChannel) ||
+ !openChannel(stdoutChannel) ||
+ !openChannel(stderrChannel))
return;
QString args = qt_create_commandline(program, arguments);
@@ -577,47 +564,25 @@ bool QProcessPrivate::processStarted()
return processState == QProcess::Running;
}
-qint64 QProcessPrivate::bytesAvailableFromStdout() const
+qint64 QProcessPrivate::bytesAvailableInChannel(const Channel *channel) const
{
- if (stdoutChannel.pipe[0] == INVALID_Q_PIPE)
- return 0;
+ Q_ASSERT(channel->pipe[0] != INVALID_Q_PIPE);
+ Q_ASSERT(channel->reader);
- if (!stdoutReader)
- return 0;
-
- DWORD bytesAvail = stdoutReader->bytesAvailable();
+ DWORD bytesAvail = channel->reader->bytesAvailable();
#if defined QPROCESS_DEBUG
- qDebug("QProcessPrivate::bytesAvailableFromStdout() == %d", bytesAvail);
+ qDebug("QProcessPrivate::bytesAvailableInChannel(%d) == %d", channel - &stdinChannel, bytesAvail);
#endif
return bytesAvail;
}
-qint64 QProcessPrivate::bytesAvailableFromStderr() const
+qint64 QProcessPrivate::readFromChannel(const Channel *channel, char *data, qint64 maxlen)
{
- if (stderrChannel.pipe[0] == INVALID_Q_PIPE)
- return 0;
-
- if (!stderrReader)
- return 0;
-
- DWORD bytesAvail = stderrReader->bytesAvailable();
-#if defined QPROCESS_DEBUG
- qDebug("QProcessPrivate::bytesAvailableFromStderr() == %d", bytesAvail);
-#endif
- return bytesAvail;
+ Q_ASSERT(channel->pipe[0] != INVALID_Q_PIPE);
+ Q_ASSERT(channel->reader);
+ return channel->reader->read(data, maxlen);
}
-qint64 QProcessPrivate::readFromStdout(char *data, qint64 maxlen)
-{
- return stdoutReader ? stdoutReader->read(data, maxlen) : 0;
-}
-
-qint64 QProcessPrivate::readFromStderr(char *data, qint64 maxlen)
-{
- return stderrReader ? stderrReader->read(data, maxlen) : 0;
-}
-
-
static BOOL QT_WIN_CALLBACK qt_terminateApp(HWND hwnd, LPARAM procId)
{
DWORD currentProcId = 0;
@@ -659,20 +624,20 @@ bool QProcessPrivate::waitForStarted(int)
bool QProcessPrivate::drainOutputPipes()
{
- if (!stdoutReader && !stderrReader)
+ if (!stdoutChannel.reader && !stderrChannel.reader)
return false;
bool someReadyReadEmitted = false;
forever {
bool readyReadEmitted = false;
bool readOperationActive = false;
- if (stdoutReader) {
- readyReadEmitted |= stdoutReader->waitForReadyRead(0);
- readOperationActive = stdoutReader && stdoutReader->isReadOperationActive();
+ if (stdoutChannel.reader) {
+ readyReadEmitted |= stdoutChannel.reader->waitForReadyRead(0);
+ readOperationActive = stdoutChannel.reader && stdoutChannel.reader->isReadOperationActive();
}
- if (stderrReader) {
- readyReadEmitted |= stderrReader->waitForReadyRead(0);
- readOperationActive |= stderrReader && stderrReader->isReadOperationActive();
+ if (stderrChannel.reader) {
+ readyReadEmitted |= stderrChannel.reader->waitForReadyRead(0);
+ readOperationActive |= stderrChannel.reader && stderrChannel.reader->isReadOperationActive();
}
someReadyReadEmitted |= readyReadEmitted;
if (!readOperationActive || !readyReadEmitted)
@@ -690,13 +655,13 @@ bool QProcessPrivate::waitForReadyRead(int msecs)
QIncrementalSleepTimer timer(msecs);
forever {
- if (!writeBuffer.isEmpty() && !_q_canWrite())
+ if (!stdinChannel.buffer.isEmpty() && !_q_canWrite())
return false;
- if (pipeWriter && pipeWriter->waitForWrite(0))
+ if (stdinChannel.writer && stdinChannel.writer->waitForWrite(0))
timer.resetIncrements();
- if ((stdoutReader && stdoutReader->waitForReadyRead(0))
- || (stderrReader && stderrReader->waitForReadyRead(0)))
+ if ((stdoutChannel.reader && stdoutChannel.reader->waitForReadyRead(0))
+ || (stderrChannel.reader && stderrChannel.reader->waitForReadyRead(0)))
return true;
if (!pid)
@@ -726,12 +691,12 @@ bool QProcessPrivate::waitForBytesWritten(int msecs)
forever {
// Check if we have any data pending: the pipe writer has
// bytes waiting to written, or it has written data since the
- // last time we called pipeWriter->waitForWrite().
- bool pendingDataInPipe = pipeWriter && (pipeWriter->bytesToWrite() || pipeWriter->hadWritten());
+ // last time we called stdinChannel.writer->waitForWrite().
+ bool pendingDataInPipe = stdinChannel.writer && (stdinChannel.writer->bytesToWrite() || stdinChannel.writer->hadWritten());
// If we don't have pending data, and our write buffer is
// empty, we fail.
- if (!pendingDataInPipe && writeBuffer.isEmpty())
+ if (!pendingDataInPipe && stdinChannel.buffer.isEmpty())
return false;
// If we don't have pending data and we do have data in our
@@ -746,21 +711,21 @@ bool QProcessPrivate::waitForBytesWritten(int msecs)
// written. This will succeed if either the pipe writer has
// already written the data, or if it manages to write data
// within the given timeout. If the write buffer was non-empty
- // and the pipeWriter is now dead, that means _q_canWrite()
+ // and the stdinChannel.writer is now dead, that means _q_canWrite()
// destroyed the writer after it successfully wrote the last
// batch.
- if (!pipeWriter || pipeWriter->waitForWrite(0))
+ if (!stdinChannel.writer || stdinChannel.writer->waitForWrite(0))
return true;
// If we wouldn't write anything, check if we can read stdout.
- if (bytesAvailableFromStdout() != 0) {
- _q_canReadStandardOutput();
+ if (bytesAvailableInChannel(&stdoutChannel) != 0) {
+ tryReadFromChannel(&stdoutChannel);
timer.resetIncrements();
}
// Check if we can read stderr.
- if (bytesAvailableFromStderr() != 0) {
- _q_canReadStandardError();
+ if (bytesAvailableInChannel(&stderrChannel) != 0) {
+ tryReadFromChannel(&stderrChannel);
timer.resetIncrements();
}
@@ -795,13 +760,13 @@ bool QProcessPrivate::waitForFinished(int msecs)
QIncrementalSleepTimer timer(msecs);
forever {
- if (!writeBuffer.isEmpty() && !_q_canWrite())
+ if (!stdinChannel.buffer.isEmpty() && !_q_canWrite())
return false;
- if (pipeWriter && pipeWriter->waitForWrite(0))
+ if (stdinChannel.writer && stdinChannel.writer->waitForWrite(0))
timer.resetIncrements();
- if (stdoutReader && stdoutReader->waitForReadyRead(0))
+ if (stdoutChannel.reader && stdoutChannel.reader->waitForReadyRead(0))
timer.resetIncrements();
- if (stderrReader && stderrReader->waitForReadyRead(0))
+ if (stderrChannel.reader && stderrChannel.reader->waitForReadyRead(0))
timer.resetIncrements();
if (!pid) {
@@ -837,33 +802,32 @@ void QProcessPrivate::findExitCode()
void QProcessPrivate::flushPipeWriter()
{
- if (pipeWriter && pipeWriter->bytesToWrite() > 0) {
- pipeWriter->waitForWrite(ULONG_MAX);
- }
+ if (stdinChannel.writer && stdinChannel.writer->bytesToWrite() > 0)
+ stdinChannel.writer->waitForWrite(ULONG_MAX);
}
qint64 QProcessPrivate::pipeWriterBytesToWrite() const
{
- return pipeWriter ? pipeWriter->bytesToWrite() : qint64(0);
+ return stdinChannel.writer ? stdinChannel.writer->bytesToWrite() : qint64(0);
}
qint64 QProcessPrivate::writeToStdin(const char *data, qint64 maxlen)
{
Q_Q(QProcess);
- if (!pipeWriter) {
- pipeWriter = new QWindowsPipeWriter(stdinChannel.pipe[1], q);
- pipeWriter->start();
+ if (!stdinChannel.writer) {
+ stdinChannel.writer = new QWindowsPipeWriter(stdinChannel.pipe[1], q);
+ stdinChannel.writer->start();
}
- return pipeWriter->write(data, maxlen);
+ return stdinChannel.writer->write(data, maxlen);
}
bool QProcessPrivate::waitForWrite(int msecs)
{
Q_Q(QProcess);
- if (!pipeWriter || pipeWriter->waitForWrite(msecs))
+ if (!stdinChannel.writer || stdinChannel.writer->waitForWrite(msecs))
return true;
processError = QProcess::Timedout;
@@ -875,7 +839,7 @@ void QProcessPrivate::_q_notified()
{
notifier->stop();
- if (!writeBuffer.isEmpty() && (!pipeWriter || pipeWriter->waitForWrite(0)))
+ if (!stdinChannel.buffer.isEmpty() && (!stdinChannel.writer || stdinChannel.writer->waitForWrite(0)))
_q_canWrite();
if (processState != QProcess::NotRunning)
diff --git a/src/corelib/io/qprocess_wince.cpp b/src/corelib/io/qprocess_wince.cpp
index ad9a328133..e0bee48598 100644
--- a/src/corelib/io/qprocess_wince.cpp
+++ b/src/corelib/io/qprocess_wince.cpp
@@ -62,7 +62,7 @@ void QProcessPrivate::destroyPipe(Q_PIPE pipe[2])
Q_UNUSED(pipe);
}
-void QProcessPrivate::destroyChannel(Channel *channel)
+void QProcessPrivate::closeChannel(Channel *channel)
{
Q_UNUSED(channel);
}
@@ -174,22 +174,12 @@ bool QProcessPrivate::processStarted()
return processState == QProcess::Running;
}
-qint64 QProcessPrivate::bytesAvailableFromStdout() const
+qint64 QProcessPrivate::bytesAvailableInChannel(const Channel *) const
{
return 0;
}
-qint64 QProcessPrivate::bytesAvailableFromStderr() const
-{
- return 0;
-}
-
-qint64 QProcessPrivate::readFromStdout(char *data, qint64 maxlen)
-{
- return -1;
-}
-
-qint64 QProcessPrivate::readFromStderr(char *data, qint64 maxlen)
+qint64 QProcessPrivate::readFromChannel(const Channel *, char *data, qint64 maxlen)
{
return -1;
}
diff --git a/src/corelib/io/qstandardpaths_winrt.cpp b/src/corelib/io/qstandardpaths_winrt.cpp
index aa3b710f52..81b9d10baf 100644
--- a/src/corelib/io/qstandardpaths_winrt.cpp
+++ b/src/corelib/io/qstandardpaths_winrt.cpp
@@ -104,14 +104,23 @@ QString QStandardPaths::writableLocation(StandardLocation type)
case GenericCacheLocation:
return writableLocation(GenericDataLocation) + QLatin1String("/cache");
- case RuntimeLocation:
- case HomeLocation:
- result = QDir::homePath();
- break;
-
case TempLocation:
result = QDir::tempPath();
break;
+
+ case ApplicationsLocation:
+ case DesktopLocation:
+ case FontsLocation:
+ case HomeLocation:
+ case RuntimeLocation:
+ // these are read-only
+ break;
+
+ case DocumentsLocation:
+ case MusicLocation:
+ case MoviesLocation:
+ case PicturesLocation:
+ case DownloadLocation:
default:
Q_UNIMPLEMENTED();
}
diff --git a/src/corelib/io/qwindowspipereader.cpp b/src/corelib/io/qwindowspipereader.cpp
index 7dd2125e70..d8a3ec9b42 100644
--- a/src/corelib/io/qwindowspipereader.cpp
+++ b/src/corelib/io/qwindowspipereader.cpp
@@ -132,7 +132,7 @@ qint64 QWindowsPipeReader::bytesAvailable() const
qint64 QWindowsPipeReader::read(char *data, qint64 maxlen)
{
if (pipeBroken && actualReadBufferSize == 0)
- return -1; // signal EOF
+ return 0; // signal EOF
qint64 readSoFar;
// If startAsyncRead() has read data, copy it to its destination.
@@ -159,6 +159,8 @@ qint64 QWindowsPipeReader::read(char *data, qint64 maxlen)
emitReadyReadTimer->stop();
if (!readSequenceStarted)
startAsyncRead();
+ if (readSoFar == 0)
+ return -2; // signal EWOULDBLOCK
}
return readSoFar;
diff --git a/src/corelib/kernel/qeventdispatcher_win.cpp b/src/corelib/kernel/qeventdispatcher_win.cpp
index 64ad2ff0d3..f38ac7bf26 100644
--- a/src/corelib/kernel/qeventdispatcher_win.cpp
+++ b/src/corelib/kernel/qeventdispatcher_win.cpp
@@ -325,8 +325,6 @@ QEventDispatcherWin32Private::~QEventDispatcherWin32Private()
{
if (internalHwnd)
DestroyWindow(internalHwnd);
- QString className = QLatin1String("QEventDispatcherWin32_Internal_Widget") + QString::number(quintptr(qt_internal_proc));
- UnregisterClass((wchar_t*)className.utf16(), qWinAppInst());
}
void QEventDispatcherWin32Private::activateEventNotifier(QWinEventNotifier * wen)
@@ -486,10 +484,26 @@ LRESULT QT_WIN_CALLBACK qt_GetMessageHook(int code, WPARAM wp, LPARAM lp)
#endif
}
-static HWND qt_create_internal_window(const QEventDispatcherWin32 *eventDispatcher)
+// Provide class name and atom for the message window used by
+// QEventDispatcherWin32Private via Q_GLOBAL_STATIC shared between threads.
+struct QWindowsMessageWindowClassContext
+{
+ QWindowsMessageWindowClassContext();
+ ~QWindowsMessageWindowClassContext();
+
+ ATOM atom;
+ wchar_t *className;
+};
+
+QWindowsMessageWindowClassContext::QWindowsMessageWindowClassContext()
+ : atom(0), className(0)
{
// make sure that multiple Qt's can coexist in the same process
- QString className = QLatin1String("QEventDispatcherWin32_Internal_Widget") + QString::number(quintptr(qt_internal_proc));
+ const QString qClassName = QStringLiteral("QEventDispatcherWin32_Internal_Widget")
+ + QString::number(quintptr(qt_internal_proc));
+ className = new wchar_t[qClassName.size() + 1];
+ qClassName.toWCharArray(className);
+ className[qClassName.size()] = 0;
WNDCLASS wc;
wc.style = 0;
@@ -501,16 +515,37 @@ static HWND qt_create_internal_window(const QEventDispatcherWin32 *eventDispatch
wc.hCursor = 0;
wc.hbrBackground = 0;
wc.lpszMenuName = NULL;
- wc.lpszClassName = reinterpret_cast<const wchar_t *> (className.utf16());
+ wc.lpszClassName = className;
+ atom = RegisterClass(&wc);
+ if (!atom) {
+ qErrnoWarning("%s: RegisterClass() failed", Q_FUNC_INFO, qPrintable(qClassName));
+ delete [] className;
+ className = 0;
+ }
+}
+
+QWindowsMessageWindowClassContext::~QWindowsMessageWindowClassContext()
+{
+ if (className) {
+ UnregisterClass(className, qWinAppInst());
+ delete [] className;
+ }
+}
+
+Q_GLOBAL_STATIC(QWindowsMessageWindowClassContext, qWindowsMessageWindowClassContext)
- RegisterClass(&wc);
+static HWND qt_create_internal_window(const QEventDispatcherWin32 *eventDispatcher)
+{
+ QWindowsMessageWindowClassContext *ctx = qWindowsMessageWindowClassContext();
+ if (!ctx->atom)
+ return 0;
#ifdef Q_OS_WINCE
HWND parent = 0;
#else
HWND parent = HWND_MESSAGE;
#endif
- HWND wnd = CreateWindow(wc.lpszClassName, // classname
- wc.lpszClassName, // window name
+ HWND wnd = CreateWindow(ctx->className, // classname
+ ctx->className, // window name
0, // style
0, 0, 0, 0, // geometry
parent, // parent
@@ -519,7 +554,8 @@ static HWND qt_create_internal_window(const QEventDispatcherWin32 *eventDispatch
0); // windows creation data.
if (!wnd) {
- qWarning("QEventDispatcher: Failed to create QEventDispatcherWin32 internal window: %d\n", (int)GetLastError());
+ qErrnoWarning("%s: CreateWindow() for QEventDispatcherWin32 internal window failed", Q_FUNC_INFO);
+ return 0;
}
#ifdef GWLP_USERDATA
@@ -620,7 +656,9 @@ void QEventDispatcherWin32::createInternalHwnd()
// setup GetMessage hook needed to drive our posted events
d->getMessageHook = SetWindowsHookEx(WH_GETMESSAGE, (HOOKPROC) qt_GetMessageHook, NULL, GetCurrentThreadId());
if (!d->getMessageHook) {
- qFatal("Qt: INTERNALL ERROR: failed to install GetMessage hook");
+ int errorCode = GetLastError();
+ qFatal("Qt: INTERNAL ERROR: failed to install GetMessage hook: %d, %s",
+ errorCode, qPrintable(qt_error_string(errorCode)));
}
#endif
diff --git a/src/corelib/kernel/qjnihelpers.cpp b/src/corelib/kernel/qjnihelpers.cpp
index 311ebaa092..cbd3d776a7 100644
--- a/src/corelib/kernel/qjnihelpers.cpp
+++ b/src/corelib/kernel/qjnihelpers.cpp
@@ -113,10 +113,8 @@ jint QtAndroidPrivate::initJNI(JavaVM *vm, JNIEnv *env)
{
jclass jQtNative = env->FindClass("org/qtproject/qt5/android/QtNative");
- if (env->ExceptionCheck()) {
- env->ExceptionClear();
+ if (exceptionCheck(env))
return JNI_ERR;
- }
jmethodID activityMethodID = env->GetStaticMethodID(jQtNative,
"activity",
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index a8e9f4a7e9..6670311353 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -3238,7 +3238,7 @@ QObjectPrivate::Connection *QMetaObjectPrivate::connect(const QObject *sender,
int method_index_absolute = method_index + method_offset;
while (c2) {
- if (c2->receiver == receiver && c2->method() == method_index_absolute)
+ if (!c2->isSlotObject && c2->receiver == receiver && c2->method() == method_index_absolute)
return 0;
c2 = c2->nextConnectionList;
}
diff --git a/src/corelib/kernel/qobjectdefs_impl.h b/src/corelib/kernel/qobjectdefs_impl.h
index de6f65ab7d..de95fcc313 100644
--- a/src/corelib/kernel/qobjectdefs_impl.h
+++ b/src/corelib/kernel/qobjectdefs_impl.h
@@ -622,7 +622,7 @@ namespace QtPrivate {
static char test(...);
enum {
Ok = sizeof(test(dummy<Functor>())) == sizeof(int),
- Value = Ok ? sizeof...(ArgList) : int(ComputeFunctorArgumentCountHelper<Functor, List<ArgList...>, Ok>::Value)
+ Value = Ok ? int(sizeof...(ArgList)) : int(ComputeFunctorArgumentCountHelper<Functor, List<ArgList...>, Ok>::Value)
};
};
diff --git a/src/corelib/kernel/qtcore_eval.cpp b/src/corelib/kernel/qtcore_eval.cpp
index 40c1157fb4..a5c4c36638 100644
--- a/src/corelib/kernel/qtcore_eval.cpp
+++ b/src/corelib/kernel/qtcore_eval.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtCore module of the Qt Toolkit.
@@ -55,7 +55,7 @@ QT_BEGIN_NAMESPACE
static const char boilerplate_supported_but_time_limited[] =
"\nQt %1 Evaluation License\n"
- "Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).\n"
+ "Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).\n"
"This trial version may only be used for evaluation purposes\n"
"and will shut down after 120 minutes.\n"
"Registered to:\n"
@@ -65,7 +65,7 @@ static const char boilerplate_supported_but_time_limited[] =
static const char boilerplate_supported[] =
"\nQt %1 Evaluation License\n"
- "Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).\n"
+ "Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).\n"
"This trial version may only be used for evaluation purposes\n"
"Registered to:\n"
" Licensee: %2\n\n"
diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp
index 9736950c89..50281b632a 100644
--- a/src/corelib/plugin/qlibrary.cpp
+++ b/src/corelib/plugin/qlibrary.cpp
@@ -359,7 +359,7 @@ class QLibraryStore
{
public:
inline ~QLibraryStore();
- static inline QLibraryPrivate *findOrCreate(const QString &fileName, const QString &version);
+ static inline QLibraryPrivate *findOrCreate(const QString &fileName, const QString &version, QLibrary::LoadHints loadHints);
static inline void releaseLibrary(QLibraryPrivate *lib);
static inline void cleanup();
@@ -438,17 +438,21 @@ QLibraryStore *QLibraryStore::instance()
return qt_library_data;
}
-inline QLibraryPrivate *QLibraryStore::findOrCreate(const QString &fileName, const QString &version)
+inline QLibraryPrivate *QLibraryStore::findOrCreate(const QString &fileName, const QString &version,
+ QLibrary::LoadHints loadHints)
{
QMutexLocker locker(&qt_library_mutex);
QLibraryStore *data = instance();
// check if this library is already loaded
QLibraryPrivate *lib = 0;
- if (Q_LIKELY(data))
+ if (Q_LIKELY(data)) {
lib = data->libraryMap.value(fileName);
+ if (lib)
+ lib->mergeLoadHints(loadHints);
+ }
if (!lib)
- lib = new QLibraryPrivate(fileName, version);
+ lib = new QLibraryPrivate(fileName, version, loadHints);
// track this library
if (Q_LIKELY(data))
@@ -479,21 +483,34 @@ inline void QLibraryStore::releaseLibrary(QLibraryPrivate *lib)
delete lib;
}
-QLibraryPrivate::QLibraryPrivate(const QString &canonicalFileName, const QString &version)
+QLibraryPrivate::QLibraryPrivate(const QString &canonicalFileName, const QString &version, QLibrary::LoadHints loadHints)
: pHnd(0), fileName(canonicalFileName), fullVersion(version), instance(0),
- loadHints(0),
+ loadHints(loadHints),
libraryRefCount(0), libraryUnloadCount(0), pluginState(MightBeAPlugin)
-{ }
+{
+ if (canonicalFileName.isEmpty())
+ errorString = QLibrary::tr("The shared library was not found.");
+}
-QLibraryPrivate *QLibraryPrivate::findOrCreate(const QString &fileName, const QString &version)
+QLibraryPrivate *QLibraryPrivate::findOrCreate(const QString &fileName, const QString &version,
+ QLibrary::LoadHints loadHints)
{
- return QLibraryStore::findOrCreate(fileName, version);
+ return QLibraryStore::findOrCreate(fileName, version, loadHints);
}
QLibraryPrivate::~QLibraryPrivate()
{
}
+void QLibraryPrivate::mergeLoadHints(QLibrary::LoadHints lh)
+{
+ // if the library is already loaded, we can't change the load hints
+ if (pHnd)
+ return;
+
+ loadHints = lh;
+}
+
QFunctionPointer QLibraryPrivate::resolve(const char *symbol)
{
if (!pHnd)
diff --git a/src/corelib/plugin/qlibrary_p.h b/src/corelib/plugin/qlibrary_p.h
index 20b0c7e20f..e58d18e87b 100644
--- a/src/corelib/plugin/qlibrary_p.h
+++ b/src/corelib/plugin/qlibrary_p.h
@@ -94,7 +94,8 @@ public:
void release();
QFunctionPointer resolve(const char *);
- static QLibraryPrivate *findOrCreate(const QString &fileName, const QString &version = QString());
+ static QLibraryPrivate *findOrCreate(const QString &fileName, const QString &version = QString(),
+ QLibrary::LoadHints loadHints = 0);
static QStringList suffixes_sys(const QString &fullVersion);
static QStringList prefixes_sys();
@@ -117,8 +118,9 @@ public:
}
private:
- explicit QLibraryPrivate(const QString &canonicalFileName, const QString &version);
+ explicit QLibraryPrivate(const QString &canonicalFileName, const QString &version, QLibrary::LoadHints loadHints);
~QLibraryPrivate();
+ void mergeLoadHints(QLibrary::LoadHints loadHints);
bool load_sys();
bool unload_sys();
diff --git a/src/corelib/plugin/qpluginloader.cpp b/src/corelib/plugin/qpluginloader.cpp
index e4a1d725ec..2c139669e6 100644
--- a/src/corelib/plugin/qpluginloader.cpp
+++ b/src/corelib/plugin/qpluginloader.cpp
@@ -352,11 +352,8 @@ void QPluginLoader::setFileName(const QString &fileName)
else
fn = locatePlugin(fileName);
- d = QLibraryPrivate::findOrCreate(fn);
- d->loadHints = lh;
- if (fn.isEmpty())
- d->errorString = QLibrary::tr("The shared library was not found.");
- else
+ d = QLibraryPrivate::findOrCreate(fn, QString(), lh);
+ if (!fn.isEmpty())
d->updatePluginState();
#else
diff --git a/src/corelib/thread/qatomic.cpp b/src/corelib/thread/qatomic.cpp
index 33e85c1505..b2043a45a1 100644
--- a/src/corelib/thread/qatomic.cpp
+++ b/src/corelib/thread/qatomic.cpp
@@ -58,6 +58,7 @@
\inmodule QtCore
\brief The QAtomicInteger class provides platform-independent atomic operations on integers.
\ingroup thread
+ \since 5.3
For atomic operations on pointers, see the QAtomicPointer class.
diff --git a/src/corelib/thread/qmutex.cpp b/src/corelib/thread/qmutex.cpp
index fe5beb1c01..5e3f3a1cab 100644
--- a/src/corelib/thread/qmutex.cpp
+++ b/src/corelib/thread/qmutex.cpp
@@ -380,7 +380,7 @@ bool QBasicMutex::isRecursive()
*/
/*!
- \fn QMutex *QMutexLocker::mutex()
+ \fn QMutex *QMutexLocker::mutex() const
Returns the mutex on which the QMutexLocker is operating.
diff --git a/src/corelib/thread/qmutex.h b/src/corelib/thread/qmutex.h
index 0ecc96a9b1..011555f904 100644
--- a/src/corelib/thread/qmutex.h
+++ b/src/corelib/thread/qmutex.h
@@ -77,7 +77,7 @@ public:
return fastTryLock();
}
- bool isRecursive();
+ bool isRecursive(); //### Qt6: mark const
private:
inline bool fastTryLock() Q_DECL_NOTHROW {
@@ -186,10 +186,10 @@ public:
inline explicit QMutex(RecursionMode mode = NonRecursive) { Q_UNUSED(mode); }
- static inline void lock() {}
- static inline bool tryLock(int timeout = 0) { Q_UNUSED(timeout); return true; }
- static inline void unlock() {}
- static inline bool isRecursive() { return true; }
+ inline void lock() {}
+ inline bool tryLock(int timeout = 0) { Q_UNUSED(timeout); return true; }
+ inline void unlock() {}
+ inline bool isRecursive() { return true; }
private:
Q_DISABLE_COPY(QMutex)
@@ -201,9 +201,9 @@ public:
inline explicit QMutexLocker(QMutex *) {}
inline ~QMutexLocker() {}
- static inline void unlock() {}
- static void relock() {}
- static inline QMutex *mutex() { return 0; }
+ inline void unlock() {}
+ void relock() {}
+ inline QMutex *mutex() const { return 0; }
private:
Q_DISABLE_COPY(QMutexLocker)
diff --git a/src/corelib/tools/qcollator_icu.cpp b/src/corelib/tools/qcollator_icu.cpp
index 407a493d25..23e88b5015 100644
--- a/src/corelib/tools/qcollator_icu.cpp
+++ b/src/corelib/tools/qcollator_icu.cpp
@@ -75,10 +75,17 @@ void QCollator::setCaseSensitivity(Qt::CaseSensitivity cs)
{
detach();
- UColAttributeValue val = (cs == Qt::CaseSensitive) ? UCOL_UPPER_FIRST : UCOL_OFF;
+ // The strength attribute in ICU is rather badly documented. Basically UCOL_PRIMARY
+ // ignores differences between base characters and accented characters as well as case.
+ // So A and A-umlaut would compare equal.
+ // UCOL_SECONDARY ignores case differences. UCOL_TERTIARY is the default in most languages
+ // and does case sensitive comparison.
+ // UCOL_QUATERNARY is used as default in a few languages such as Japanese to take care of some
+ // additional differences in those languages.
+ UColAttributeValue val = (cs == Qt::CaseSensitive) ? UCOL_DEFAULT_STRENGTH : UCOL_SECONDARY;
UErrorCode status = U_ZERO_ERROR;
- ucol_setAttribute(d->collator, UCOL_CASE_FIRST, val, &status);
+ ucol_setAttribute(d->collator, UCOL_STRENGTH, val, &status);
if (U_FAILURE(status))
qWarning("ucol_setAttribute: Case First failed: %d", status);
}
diff --git a/src/corelib/tools/qcollator_macx.cpp b/src/corelib/tools/qcollator_macx.cpp
index 8985cd4eba..877510489a 100644
--- a/src/corelib/tools/qcollator_macx.cpp
+++ b/src/corelib/tools/qcollator_macx.cpp
@@ -128,12 +128,15 @@ bool QCollator::ignorePunctuation() const
int QCollator::compare(const QChar *s1, int len1, const QChar *s2, int len2) const
{
SInt32 result;
- return UCCompareText(d->collator.collator,
+ Boolean equivalent;
+ UCCompareText(d->collator.collator,
reinterpret_cast<const UniChar *>(s1), len1,
reinterpret_cast<const UniChar *>(s2), len2,
- NULL,
+ &equivalent,
&result);
- return result;
+ if (equivalent)
+ return 0;
+ return result < 0 ? -1 : 1;
}
int QCollator::compare(const QString &str1, const QString &str2) const
{
diff --git a/src/corelib/tools/qringbuffer_p.h b/src/corelib/tools/qringbuffer_p.h
index b17c6d2f40..5d25b0add1 100644
--- a/src/corelib/tools/qringbuffer_p.h
+++ b/src/corelib/tools/qringbuffer_p.h
@@ -90,7 +90,7 @@ public:
// special case: it is in the first buffer
int nextDataBlockSizeValue = nextDataBlockSize();
- if (pos - head < nextDataBlockSizeValue) {
+ if (pos < nextDataBlockSizeValue) {
length = nextDataBlockSizeValue - pos;
return buffers.at(0).constData() + head + pos;
}
diff --git a/src/corelib/tools/qscopedvaluerollback.cpp b/src/corelib/tools/qscopedvaluerollback.cpp
index f37a232985..bd3e03c464 100644
--- a/src/corelib/tools/qscopedvaluerollback.cpp
+++ b/src/corelib/tools/qscopedvaluerollback.cpp
@@ -50,7 +50,7 @@ QT_BEGIN_NAMESPACE
\since 4.8
\ingroup misc
- The QScopedAssignment class can be used to revert state when an
+ The QScopedValueRollback class can be used to revert state when an
exception is thrown without needing to write try-catch blocks.
It can also be used to manage variables that are temporarily set,
diff --git a/src/corelib/tools/qsimd_p.h b/src/corelib/tools/qsimd_p.h
index 8ce7b63f46..19a1943367 100644
--- a/src/corelib/tools/qsimd_p.h
+++ b/src/corelib/tools/qsimd_p.h
@@ -220,8 +220,10 @@
|| (defined(Q_CC_CLANG) && (__clang_major__ * 100 + __clang_minor__ >= 208)) \
|| defined(Q_CC_INTEL))
# define QT_COMPILER_SUPPORTS_X86INTRIN
-# ifndef Q_CC_INTEL
+# ifdef Q_CC_INTEL
// The Intel compiler has no <x86intrin.h> -- all intrinsics are in <immintrin.h>;
+# include <immintrin.h>
+# else
// GCC 4.4 and Clang 2.8 added a few more intrinsics there
# include <x86intrin.h>
# endif
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index a7f932698b..7aaddb9b52 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -9894,9 +9894,7 @@ QString QString::toHtmlEscaped() const
the read-only segment of the compiled object file.
For compilers not supporting the creation of compile time strings, QStringLiteral will fall back to
- QLatin1String.
-
- The result of the QStringLiteral expression can be cast into a QString.
+ QString::fromUtf8().
If you have code looking like:
\code
diff --git a/src/dbus/qdbusconnection_p.h b/src/dbus/qdbusconnection_p.h
index f2590f9c54..fd4ced078d 100644
--- a/src/dbus/qdbusconnection_p.h
+++ b/src/dbus/qdbusconnection_p.h
@@ -256,7 +256,7 @@ private:
void deliverCall(QObject *object, int flags, const QDBusMessage &msg,
const QVector<int> &metaTypes, int slotIdx);
- bool isServiceRegisteredByThread(const QString &serviceName) const;
+ bool isServiceRegisteredByThread(const QString &serviceName);
QString getNameOwnerNoCache(const QString &service);
diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp
index d4079e8076..9533d6b733 100644
--- a/src/dbus/qdbusintegrator.cpp
+++ b/src/dbus/qdbusintegrator.cpp
@@ -73,8 +73,8 @@
QT_BEGIN_NAMESPACE
-static bool isDebugging;
-#define qDBusDebug if (!::isDebugging); else qDebug
+static QBasicAtomicInt isDebugging = Q_BASIC_ATOMIC_INITIALIZER(-1);
+#define qDBusDebug if (::isDebugging == 0); else qDebug
Q_GLOBAL_STATIC_WITH_ARGS(const QString, orgFreedesktopDBusString, (QLatin1String(DBUS_SERVICE_DBUS)))
@@ -1022,13 +1022,12 @@ QDBusConnectionPrivate::QDBusConnectionPrivate(QObject *p)
anonymousAuthenticationAllowed(false)
{
static const bool threads = q_dbus_threads_init_default();
- static const int debugging = qgetenv("QDBUS_DEBUG").toInt();
- ::isDebugging = debugging;
+ if (::isDebugging == -1)
+ ::isDebugging = qgetenv("QDBUS_DEBUG").toInt();
Q_UNUSED(threads)
- Q_UNUSED(debugging)
#ifdef QDBUS_THREAD_DEBUG
- if (debugging > 1)
+ if (::isDebugging > 1)
qdbusThreadDebug = qdbusDefaultThreadDebug;
#endif
@@ -2488,12 +2487,15 @@ void QDBusConnectionPrivate::unregisterServiceNoLock(const QString &serviceName)
serviceNames.removeAll(serviceName);
}
-bool QDBusConnectionPrivate::isServiceRegisteredByThread(const QString &serviceName) const
+bool QDBusConnectionPrivate::isServiceRegisteredByThread(const QString &serviceName)
{
if (!serviceName.isEmpty() && serviceName == baseService)
return true;
- QStringList copy = serviceNames;
- return copy.contains(serviceName);
+ if (serviceName == dbusServiceString())
+ return false;
+
+ QDBusReadLocker locker(UnregisterServiceAction, this);
+ return serviceNames.contains(serviceName);
}
void QDBusConnectionPrivate::postEventToThread(int action, QObject *object, QEvent *ev)
diff --git a/src/gui/accessible/qaccessible.cpp b/src/gui/accessible/qaccessible.cpp
index c715c5c7e0..3d1807ec05 100644
--- a/src/gui/accessible/qaccessible.cpp
+++ b/src/gui/accessible/qaccessible.cpp
@@ -1713,10 +1713,6 @@ Q_GUI_EXPORT QDebug operator<<(QDebug d, const QAccessibleInterface *iface)
/*! \internal */
QDebug operator<<(QDebug d, const QAccessibleEvent &ev)
{
- if (!&ev) {
- d << "QAccessibleEvent(null)";
- return d;
- }
d.nospace() << "QAccessibleEvent(";
if (ev.object()) {
d.nospace() << "object=" << hex << ev.object() << dec;
diff --git a/src/gui/animation/qguivariantanimation.cpp b/src/gui/animation/qguivariantanimation.cpp
index 34abbca282..2cd31696ba 100644
--- a/src/gui/animation/qguivariantanimation.cpp
+++ b/src/gui/animation/qguivariantanimation.cpp
@@ -64,7 +64,7 @@ template<> Q_INLINE_TEMPLATE QQuaternion _q_interpolate(const QQuaternion &f,con
return QQuaternion::slerp(f, t, progress);
}
-static void qRegisterGuiGetInterpolator()
+void qRegisterGuiGetInterpolator()
{
qRegisterAnimationInterpolator<QColor>(_q_interpolateVariant<QColor>);
qRegisterAnimationInterpolator<QVector2D>(_q_interpolateVariant<QVector2D>);
diff --git a/src/gui/image/qgifhandler.cpp b/src/gui/image/qgifhandler.cpp
index 19b838240f..91588edd50 100644
--- a/src/gui/image/qgifhandler.cpp
+++ b/src/gui/image/qgifhandler.cpp
@@ -674,7 +674,7 @@ void QGIFFormat::scan(QIODevice *device, QVector<QSize> *imageSizes, int *loopCo
return;
qint64 oldPos = device->pos();
- if (!device->seek(0))
+ if (device->isSequential() || !device->seek(0))
return;
int colorCount = 0;
diff --git a/src/gui/image/qicon.cpp b/src/gui/image/qicon.cpp
index 0a4b50bbea..8172ecbb48 100644
--- a/src/gui/image/qicon.cpp
+++ b/src/gui/image/qicon.cpp
@@ -363,44 +363,93 @@ void QPixmapIconEngine::addPixmap(const QPixmap &pixmap, QIcon::Mode mode, QIcon
}
}
-void QPixmapIconEngine::addFile(const QString &fileName, const QSize &_size, QIcon::Mode mode, QIcon::State state)
+// Read out original image depth as set by ICOReader
+static inline int origIcoDepth(const QImage &image)
{
- if (!fileName.isEmpty()) {
- QString abs = fileName;
- if (fileName.at(0) != QLatin1Char(':'))
- abs = QFileInfo(fileName).absoluteFilePath();
- QImageReader reader(abs);
-
- do {
- QSize size = _size;
- QPixmap pixmap;
-
- for (int i = 0; i < pixmaps.count(); ++i) {
- if (pixmaps.at(i).mode == mode && pixmaps.at(i).state == state) {
- QPixmapIconEngineEntry *pe = &pixmaps[i];
- if (size == QSize()) {
- pixmap.convertFromImage(reader.read());
- size = pixmap.size();
- }
- if (pe->size == QSize() && pe->pixmap.isNull()) {
- pe->pixmap = QPixmap(pe->fileName);
- // Reset the devicePixelRatio. The pixmap may be loaded from a @2x file,
- // but be used as a 1x pixmap by QIcon.
- pe->pixmap.setDevicePixelRatio(1.0);
- pe->size = pe->pixmap.size();
- }
- if (pe->size == size) {
- pe->pixmap = pixmap;
- pe->fileName = abs;
- return;
- }
- }
+ const QString s = image.text(QStringLiteral("_q_icoOrigDepth"));
+ return s.isEmpty() ? 32 : s.toInt();
+}
+
+static inline int findBySize(const QList<QImage> &images, const QSize &size)
+{
+ for (int i = 0; i < images.size(); ++i) {
+ if (images.at(i).size() == size)
+ return i;
+ }
+ return -1;
+}
+
+// Convenience class providing a bool read() function.
+namespace {
+class ImageReader
+{
+public:
+ ImageReader(const QString &fileName) : m_reader(fileName), m_atEnd(false) {}
+
+ QByteArray format() const { return m_reader.format(); }
+
+ bool read(QImage *image)
+ {
+ if (m_atEnd)
+ return false;
+ *image = m_reader.read();
+ if (!image->size().isValid()) {
+ m_atEnd = true;
+ return false;
+ }
+ m_atEnd = !m_reader.jumpToNextImage();
+ return true;
+ }
+
+private:
+ QImageReader m_reader;
+ bool m_atEnd;
+};
+} // namespace
+
+void QPixmapIconEngine::addFile(const QString &fileName, const QSize &size, QIcon::Mode mode, QIcon::State state)
+{
+ if (fileName.isEmpty())
+ return;
+ const QString abs = fileName.startsWith(QLatin1Char(':')) ? fileName : QFileInfo(fileName).absoluteFilePath();
+ const bool ignoreSize = !size.isValid();
+ ImageReader imageReader(abs);
+ const QByteArray format = imageReader.format();
+ if (format.isEmpty()) // Device failed to open or unsupported format.
+ return;
+ QImage image;
+ if (format != "ico") {
+ if (ignoreSize) { // No size specified: Add all images.
+ while (imageReader.read(&image))
+ pixmaps += QPixmapIconEngineEntry(abs, image, mode, state);
+ } else {
+ // Try to match size. If that fails, add a placeholder with the filename and empty pixmap for the size.
+ while (imageReader.read(&image) && image.size() != size) {}
+ pixmaps += image.size() == size ?
+ QPixmapIconEngineEntry(abs, image, mode, state) : QPixmapIconEngineEntry(abs, size, mode, state);
+ }
+ return;
+ }
+ // Special case for reading Windows ".ico" files. Historically (QTBUG-39287),
+ // these files may contain low-resolution images. As this information is lost,
+ // ICOReader sets the original format as an image text key value. Read all matching
+ // images into a list trying to find the highest quality per size.
+ QList<QImage> icoImages;
+ while (imageReader.read(&image)) {
+ if (ignoreSize || image.size() == size) {
+ const int position = findBySize(icoImages, image.size());
+ if (position >= 0) { // Higher quality available? -> replace.
+ if (origIcoDepth(image) > origIcoDepth(icoImages.at(position)))
+ icoImages[position] = image;
+ } else {
+ icoImages.append(image);
}
- QPixmapIconEngineEntry e(abs, size, mode, state);
- e.pixmap = pixmap;
- pixmaps += e;
- } while (reader.jumpToNextImage());
+ }
}
+ foreach (const QImage &i, icoImages)
+ pixmaps += QPixmapIconEngineEntry(abs, i, mode, state);
+ if (icoImages.isEmpty() && !ignoreSize) // Add placeholder with the filename and empty pixmap for the size.
+ pixmaps += QPixmapIconEngineEntry(abs, size, mode, state);
}
QString QPixmapIconEngine::key() const
diff --git a/src/gui/image/qicon_p.h b/src/gui/image/qicon_p.h
index 7351ad489a..eb94457f48 100644
--- a/src/gui/image/qicon_p.h
+++ b/src/gui/image/qicon_p.h
@@ -89,6 +89,7 @@ struct QPixmapIconEngineEntry
:pixmap(pm), size(pm.size()), mode(m), state(s){}
QPixmapIconEngineEntry(const QString &file, const QSize &sz = QSize(), QIcon::Mode m = QIcon::Normal, QIcon::State s = QIcon::Off)
:fileName(file), size(sz), mode(m), state(s){}
+ QPixmapIconEngineEntry(const QString &file, const QImage &image, QIcon::Mode m = QIcon::Normal, QIcon::State s = QIcon::Off);
QPixmap pixmap;
QString fileName;
QSize size;
@@ -97,7 +98,14 @@ struct QPixmapIconEngineEntry
bool isNull() const {return (fileName.isEmpty() && pixmap.isNull()); }
};
-
+inline QPixmapIconEngineEntry::QPixmapIconEngineEntry(const QString &file, const QImage &image, QIcon::Mode m, QIcon::State s)
+ : fileName(file), size(image.size()), mode(m), state(s)
+{
+ pixmap.convertFromImage(image);
+ // Reset the devicePixelRatio. The pixmap may be loaded from a @2x file,
+ // but be used as a 1x pixmap by QIcon.
+ pixmap.setDevicePixelRatio(1.0);
+}
class QPixmapIconEngine : public QIconEngine {
public:
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index dda8894722..b0b6b27b71 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -1662,11 +1662,14 @@ void QImage::fill(uint pixel)
return;
}
- if (d->format == Format_RGB32 || d->format == Format_RGBX8888)
+ if (d->format == Format_RGB32)
pixel |= 0xff000000;
-
- if (d->format == Format_RGBX8888 || d->format == Format_RGBA8888 || d->format == Format_RGBA8888_Premultiplied)
- pixel = ARGB2RGBA(pixel);
+ if (d->format == Format_RGBX8888)
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
+ pixel |= 0xff000000;
+#else
+ pixel |= 0x000000ff;
+#endif
qt_rectfill<uint>(reinterpret_cast<uint*>(d->data), pixel,
0, 0, d->width, d->height, d->bytes_per_line);
@@ -1716,22 +1719,27 @@ void QImage::fill(const QColor &color)
if (!d)
return;
- if (d->depth == 32) {
- uint pixel = color.rgba();
- if (d->format == QImage::Format_ARGB32_Premultiplied || d->format == QImage::Format_RGBA8888_Premultiplied)
- pixel = qPremultiply(pixel);
- fill((uint) pixel);
-
- } else if (d->format == QImage::Format_RGB16) {
+ switch (d->format) {
+ case QImage::Format_RGB32:
+ case QImage::Format_ARGB32:
+ fill(color.rgba());
+ break;
+ case QImage::Format_ARGB32_Premultiplied:
+ fill(qPremultiply(color.rgba()));
+ break;
+ case QImage::Format_RGBX8888:
+ fill(ARGB2RGBA(color.rgba() | 0xff000000));
+ break;
+ case QImage::Format_RGBA8888:
+ fill(ARGB2RGBA(color.rgba()));
+ break;
+ case QImage::Format_RGBA8888_Premultiplied:
+ fill(ARGB2RGBA(qPremultiply(color.rgba())));
+ break;
+ case QImage::Format_RGB16:
fill((uint) qConvertRgb32To16(color.rgba()));
-
- } else if (d->depth == 1) {
- if (color == Qt::color1)
- fill((uint) 1);
- else
- fill((uint) 0);
-
- } else if (d->depth == 8) {
+ break;
+ case QImage::Format_Indexed8: {
uint pixel = 0;
for (int i=0; i<d->colortable.size(); ++i) {
if (color.rgba() == d->colortable.at(i)) {
@@ -1740,20 +1748,24 @@ void QImage::fill(const QColor &color)
}
}
fill(pixel);
-
- } else {
+ break;
+ }
+ case QImage::Format_Mono:
+ case QImage::Format_MonoLSB:
+ if (color == Qt::color1)
+ fill((uint) 1);
+ else
+ fill((uint) 0);
+ break;
+ default: {
QPainter p(this);
p.setCompositionMode(QPainter::CompositionMode_Source);
p.fillRect(rect(), color);
- }
-
+ }}
}
-
-
-
/*!
Inverts all pixel values in the image.
@@ -2685,13 +2697,6 @@ QImage QImage::createMaskFromColor(QRgb color, Qt::MaskMode mode) const
return maskImage;
}
-
-/*
- This code is contributed by Philipp Lang,
- GeneriCom Software Germany (www.generi.com)
- under the terms of the QPL, Version 1.0
-*/
-
/*!
\fn QImage QImage::mirrored(bool horizontal = false, bool vertical = true) const
Returns a mirror of the image, mirrored in the horizontal and/or
@@ -2703,61 +2708,108 @@ QImage QImage::createMaskFromColor(QRgb color, Qt::MaskMode mode) const
\sa {QImage#Image Transformations}{Image Transformations}
*/
-template<typename T>
-inline void mirrored_helper_loop(int w, int h, int dxi, int dxs, int dyi, int dy, const uchar* sdata, uchar* ddata, int sbpl, int dbpl)
+template<class T> inline void do_mirror_data(QImageData *dst, QImageData *src,
+ int dstX0, int dstY0,
+ int dstXIncr, int dstYIncr,
+ int w, int h)
{
- for (int sy = 0; sy < h; sy++, dy += dyi) {
- const T* ssl = (T*)(sdata + sy*sbpl);
- T* dsl = (T*)(ddata + dy*dbpl);
- int dx = dxs;
- for (int sx = 0; sx < w; sx++, dx += dxi)
- dsl[dx] = ssl[sx];
+ if (dst == src) {
+ // When mirroring in-place, stop in the middle for one of the directions, since we
+ // are swapping the bytes instead of merely copying.
+ const int srcXEnd = dstX0 ? w / 2 : w;
+ const int srcYEnd = !dstX0 && dstY0 ? h / 2 : h;
+ for (int srcY = 0, dstY = dstY0; srcY < srcYEnd; ++srcY, dstY += dstYIncr) {
+ T *srcPtr = (T *) (src->data + srcY * src->bytes_per_line);
+ T *dstPtr = (T *) (dst->data + dstY * dst->bytes_per_line);
+ for (int srcX = 0, dstX = dstX0; srcX < srcXEnd; ++srcX, dstX += dstXIncr)
+ std::swap(srcPtr[srcX], dstPtr[dstX]);
+ }
+ } else {
+ for (int srcY = 0, dstY = dstY0; srcY < h; ++srcY, dstY += dstYIncr) {
+ T *srcPtr = (T *) (src->data + srcY * src->bytes_per_line);
+ T *dstPtr = (T *) (dst->data + dstY * dst->bytes_per_line);
+ for (int srcX = 0, dstX = dstX0; srcX < w; ++srcX, dstX += dstXIncr)
+ dstPtr[dstX] = srcPtr[srcX];
+ }
}
}
-template<typename T>
-inline void mirrored_helper_loop_inplace(int w, int h, int dxi, int dxs, int dyi, int dy, uchar* sdata, int sbpl)
+inline void do_mirror(QImageData *dst, QImageData *src, bool horizontal, bool vertical)
{
- for (int sy = 0; sy < h; sy++, dy += dyi) {
- T* ssl = (T*)(sdata + sy*sbpl);
- T* dsl = (T*)(sdata + dy*sbpl);
- int dx = dxs;
- for (int sx = 0; sx < w; sx++, dx += dxi)
- std::swap(dsl[dx], ssl[sx]);
+ Q_ASSERT(src->width == dst->width && src->height == dst->height && src->depth == dst->depth);
+ int w = src->width;
+ int h = src->height;
+ int depth = src->depth;
+
+ if (src->depth == 1) {
+ w = (w + 7) / 8; // byte aligned width
+ depth = 8;
}
-}
-inline void mirror_horizonal_bitmap(int w, int h, int dxs, uchar* data, int bpl, bool monolsb)
-{
- int shift = w % 8;
- const uchar* bitflip = qt_get_bitflip_array();
- for (int y = h-1; y >= 0; y--) {
- quint8* a0 = (quint8*)(data + y*bpl);
- // Swap bytes
- quint8* a = a0+dxs;
- while (a >= a0) {
- *a = bitflip[*a];
- a--;
- }
- // Shift bits if unaligned
- if (shift != 0) {
- a = a0+dxs;
- quint8 c = 0;
- if (monolsb) {
- while (a >= a0) {
- quint8 nc = *a << shift;
- *a = (*a >> (8-shift)) | c;
- --a;
- c = nc;
- }
- } else {
- while (a >= a0) {
- quint8 nc = *a >> shift;
- *a = (*a << (8-shift)) | c;
- --a;
- c = nc;
+ int dstX0 = 0, dstXIncr = 1;
+ int dstY0 = 0, dstYIncr = 1;
+ if (horizontal) {
+ // 0 -> w-1, 1 -> w-2, 2 -> w-3, ...
+ dstX0 = w - 1;
+ dstXIncr = -1;
+ }
+ if (vertical) {
+ // 0 -> h-1, 1 -> h-2, 2 -> h-3, ...
+ dstY0 = h - 1;
+ dstYIncr = -1;
+ }
+
+ switch (depth) {
+ case 32:
+ do_mirror_data<quint32>(dst, src, dstX0, dstY0, dstXIncr, dstYIncr, w, h);
+ break;
+ case 24:
+ do_mirror_data<quint24>(dst, src, dstX0, dstY0, dstXIncr, dstYIncr, w, h);
+ break;
+ case 16:
+ do_mirror_data<quint16>(dst, src, dstX0, dstY0, dstXIncr, dstYIncr, w, h);
+ break;
+ case 8:
+ do_mirror_data<quint8>(dst, src, dstX0, dstY0, dstXIncr, dstYIncr, w, h);
+ break;
+ default:
+ Q_ASSERT(false);
+ break;
+ }
+
+ // The bytes are now all in the correct place. In addition, the bits in the individual
+ // bytes have to be flipped too when horizontally mirroring a 1 bit-per-pixel image.
+ if (horizontal && dst->depth == 1) {
+ Q_ASSERT(dst->format == QImage::Format_Mono || dst->format == QImage::Format_MonoLSB);
+ const int shift = 8 - (dst->width % 8);
+ const uchar *bitflip = qt_get_bitflip_array();
+ for (int y = 0; y < h; ++y) {
+ uchar *begin = dst->data + y * dst->bytes_per_line;
+ uchar *end = begin + dst->bytes_per_line;
+ for (uchar *p = begin; p < end; ++p) {
+ *p = bitflip[*p];
+ // When the data is non-byte aligned, an extra bit shift (of the number of
+ // unused bits at the end) is needed for the entire scanline.
+ if (shift != 8 && p != begin) {
+ if (dst->format == QImage::Format_Mono) {
+ for (int i = 0; i < shift; ++i) {
+ p[-1] <<= 1;
+ p[-1] |= (*p & (128 >> i)) >> (7 - i);
+ }
+ } else {
+ for (int i = 0; i < shift; ++i) {
+ p[-1] >>= 1;
+ p[-1] |= (*p & (1 << i)) << (7 - i);
+ }
+ }
}
}
+ if (shift != 8) {
+ if (dst->format == QImage::Format_Mono)
+ end[-1] <<= shift;
+ else
+ end[-1] >>= shift;
+ }
}
}
}
@@ -2773,8 +2825,6 @@ QImage QImage::mirrored_helper(bool horizontal, bool vertical) const
if ((d->width <= 1 && d->height <= 1) || (!horizontal && !vertical))
return *this;
- int w = d->width;
- int h = d->height;
// Create result image, copy colormap
QImage result(d->width, d->height, d->format);
QIMAGE_SANITYCHECK_MEMORY(result);
@@ -2787,29 +2837,8 @@ QImage QImage::mirrored_helper(bool horizontal, bool vertical) const
result.d->has_alpha_clut = d->has_alpha_clut;
result.d->devicePixelRatio = d->devicePixelRatio;
- if (d->depth == 1)
- w = (w+7)/8;
- int dxi = horizontal ? -1 : 1;
- int dxs = horizontal ? w-1 : 0;
- int dyi = vertical ? -1 : 1;
- int dys = vertical ? h-1 : 0;
-
- // 1 bit, 8 bit
- if (d->depth == 1 || d->depth == 8)
- mirrored_helper_loop<quint8>(w, h, dxi, dxs, dyi, dys, d->data, result.d->data, d->bytes_per_line, result.d->bytes_per_line);
- // 16 bit
- else if (d->depth == 16)
- mirrored_helper_loop<quint16>(w, h, dxi, dxs, dyi, dys, d->data, result.d->data, d->bytes_per_line, result.d->bytes_per_line);
- // 24 bit
- else if (d->depth == 24)
- mirrored_helper_loop<quint24>(w, h, dxi, dxs, dyi, dys, d->data, result.d->data, d->bytes_per_line, result.d->bytes_per_line);
- // 32 bit
- else if (d->depth == 32)
- mirrored_helper_loop<quint32>(w, h, dxi, dxs, dyi, dys, d->data, result.d->data, d->bytes_per_line, result.d->bytes_per_line);
-
- // special handling of 1 bit images for horizontal mirroring
- if (horizontal && d->depth == 1)
- mirror_horizonal_bitmap(d->width, d->height, dxs, result.d->data, result.d->bytes_per_line, d->format == Format_MonoLSB);
+ do_mirror(result.d, d, horizontal, vertical);
+
return result;
}
@@ -2818,45 +2847,12 @@ QImage QImage::mirrored_helper(bool horizontal, bool vertical) const
*/
void QImage::mirrored_inplace(bool horizontal, bool vertical)
{
- if (!d)
- return;
-
- if ((d->width <= 1 && d->height <= 1) || (!horizontal && !vertical))
+ if (!d || (d->width <= 1 && d->height <= 1) || (!horizontal && !vertical))
return;
detach();
- int w = d->width;
- int h = d->height;
-
- if (d->depth == 1)
- w = (w+7)/8;
- int dxi = horizontal ? -1 : 1;
- int dxs = horizontal ? w-1 : 0;
- int dyi = vertical ? -1 : 1;
- int dys = vertical ? h-1 : 0;
-
- if (vertical)
- h = h/2;
- else if (horizontal)
- w = w/2;
-
- // 1 bit, 8 bit
- if (d->depth == 1 || d->depth == 8)
- mirrored_helper_loop_inplace<quint8>(w, h, dxi, dxs, dyi, dys, d->data, d->bytes_per_line);
- // 16 bit
- else if (d->depth == 16)
- mirrored_helper_loop_inplace<quint16>(w, h, dxi, dxs, dyi, dys, d->data, d->bytes_per_line);
- // 24 bit
- else if (d->depth == 24)
- mirrored_helper_loop_inplace<quint24>(w, h, dxi, dxs, dyi, dys, d->data, d->bytes_per_line);
- // 32 bit
- else if (d->depth == 32)
- mirrored_helper_loop_inplace<quint32>(w, h, dxi, dxs, dyi, dys, d->data, d->bytes_per_line);
-
- // special handling of 1 bit images for horizontal mirroring
- if (horizontal && d->depth == 1)
- mirror_horizonal_bitmap(d->width, d->height, dxs, d->data, d->bytes_per_line, d->format == Format_MonoLSB);
+ do_mirror(d, d, horizontal, vertical);
}
/*!
diff --git a/src/gui/image/qpixmap.cpp b/src/gui/image/qpixmap.cpp
index 86c4dfbdca..c6d8d19bb1 100644
--- a/src/gui/image/qpixmap.cpp
+++ b/src/gui/image/qpixmap.cpp
@@ -1098,6 +1098,7 @@ bool QPixmap::isDetached() const
*/
bool QPixmap::convertFromImage(const QImage &image, Qt::ImageConversionFlags flags)
{
+ detach();
if (image.isNull() || !data)
*this = QPixmap::fromImage(image, flags);
else
diff --git a/src/gui/image/qpixmap_raster.cpp b/src/gui/image/qpixmap_raster.cpp
index 1465fea8b9..d879a5cb61 100644
--- a/src/gui/image/qpixmap_raster.cpp
+++ b/src/gui/image/qpixmap_raster.cpp
@@ -363,10 +363,12 @@ void QRasterPlatformPixmap::createPixmapForImage(QImage &sourceImage, Qt::ImageC
}
is_null = (w <= 0 || h <= 0);
- image.d->devicePixelRatio = sourceImage.devicePixelRatio();
+ if (image.d)
+ image.d->devicePixelRatio = sourceImage.devicePixelRatio();
//ensure the pixmap and the image resulting from toImage() have the same cacheKey();
setSerialNumber(image.cacheKey() >> 32);
- setDetachNumber(image.d->detach_no);
+ if (image.d)
+ setDetachNumber(image.d->detach_no);
}
QImage* QRasterPlatformPixmap::buffer()
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index 85fc9f3893..6ac84c6cab 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -171,6 +171,7 @@ bool QGuiApplicationPrivate::noGrab = false;
static qreal fontSmoothingGamma = 1.7;
extern void qRegisterGuiVariant();
+extern void qRegisterGuiGetInterpolator();
extern void qInitDrawhelperAsm();
extern void qInitImageConversions();
@@ -489,6 +490,12 @@ static QWindowGeometrySpecification windowGeometrySpecification;
\li \c{-platformtheme} \e platformTheme, specifies the platform theme.
Overridden by the \c QT_QPA_PLATFORMTHEME environment variable.
+
+ \li \c{-plugin} \e plugin, specifies additional plugins to load. The argument
+ may appear multiple times.
+
+ Overridden by the \c QT_QPA_GENERIC_PLUGINS environment variable.
+
\li \c{-qmljsdebugger=}, activates the QML/JS debugger with a specified port.
The value must be of format \c{port:1234}\e{[,block]}, where
\e block is optional
@@ -1284,6 +1291,9 @@ void QGuiApplicationPrivate::init()
// trigger registering of QVariant's GUI types
qRegisterGuiVariant();
+ // trigger registering of animation interpolators
+ qRegisterGuiGetInterpolator();
+
QWindowSystemInterfacePrivate::eventTime.start();
is_app_running = true;
diff --git a/src/gui/kernel/qplatformclipboard.cpp b/src/gui/kernel/qplatformclipboard.cpp
index 5c25054260..d93268c9f2 100644
--- a/src/gui/kernel/qplatformclipboard.cpp
+++ b/src/gui/kernel/qplatformclipboard.cpp
@@ -123,7 +123,8 @@ bool QPlatformClipboard::ownsMode(QClipboard::Mode mode) const
void QPlatformClipboard::emitChanged(QClipboard::Mode mode)
{
- QGuiApplication::clipboard()->emitChanged(mode);
+ if (!QGuiApplicationPrivate::is_app_closing) // QTBUG-39317, prevent emission when closing down.
+ QGuiApplication::clipboard()->emitChanged(mode);
}
QT_END_NAMESPACE
diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp
index 2651c23665..97b006b4fc 100644
--- a/src/gui/opengl/qopenglframebufferobject.cpp
+++ b/src/gui/opengl/qopenglframebufferobject.cpp
@@ -443,9 +443,10 @@ void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSi
samples = qBound(0, int(samples), int(maxSamples));
}
+ samples = qMax(0, samples);
+ requestedSamples = samples;
size = sz;
target = texture_target;
- // texture dimensions
QT_RESET_GLERROR(); // reset error state
GLuint fbo = 0;
@@ -477,6 +478,9 @@ void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSi
valid = checkFramebufferStatus(ctx);
if (valid) {
+ // Query the actual number of samples. This can be greater than the requested
+ // value since the typically supported values are 0, 4, 8, ..., and the
+ // requests are mapped to the next supported value.
funcs.glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &samples);
color_buffer_guard = new QOpenGLSharedResourceGuard(ctx, color_buffer, freeRenderbufferFunc);
}
@@ -546,7 +550,10 @@ void QOpenGLFramebufferObjectPrivate::initTexture(GLenum target, GLenum internal
void QOpenGLFramebufferObjectPrivate::initAttachments(QOpenGLContext *ctx, QOpenGLFramebufferObject::Attachment attachment)
{
- int samples = format.samples();
+ // Use the same sample count for all attachments. format.samples() already contains
+ // the actual number of samples for the color attachment and is not suitable. Use
+ // requestedSamples instead.
+ const int samples = requestedSamples;
// free existing attachments
if (depth_buffer_guard) {
diff --git a/src/gui/opengl/qopenglframebufferobject_p.h b/src/gui/opengl/qopenglframebufferobject_p.h
index 7a653bc16d..75348d1481 100644
--- a/src/gui/opengl/qopenglframebufferobject_p.h
+++ b/src/gui/opengl/qopenglframebufferobject_p.h
@@ -131,6 +131,7 @@ public:
GLenum target;
QSize size;
QOpenGLFramebufferObjectFormat format;
+ int requestedSamples;
uint valid : 1;
QOpenGLFramebufferObject::Attachment fbo_attachment;
QOpenGLExtensions funcs;
diff --git a/src/gui/opengl/qopenglfunctions.cpp b/src/gui/opengl/qopenglfunctions.cpp
index 57590cfece..db88fbb68c 100644
--- a/src/gui/opengl/qopenglfunctions.cpp
+++ b/src/gui/opengl/qopenglfunctions.cpp
@@ -283,46 +283,48 @@ static int qt_gl_resolve_features()
QSurfaceFormat format = QOpenGLContext::currentContext()->format();
QOpenGLExtensionMatcher extensions;
- // Recognize features by extension name.
- if (extensions.match("GL_ARB_multitexture"))
- features |= QOpenGLFunctions::Multitexture;
- if (extensions.match("GL_ARB_shader_objects"))
- features |= QOpenGLFunctions::Shaders;
- if (extensions.match("GL_EXT_framebuffer_object") ||
- extensions.match("GL_ARB_framebuffer_object"))
- features |= QOpenGLFunctions::Framebuffers;
- if (extensions.match("GL_EXT_blend_color"))
- features |= QOpenGLFunctions::BlendColor;
- if (extensions.match("GL_EXT_blend_equation_separate"))
- features |= QOpenGLFunctions::BlendEquationSeparate;
- if (extensions.match("GL_EXT_blend_func_separate"))
- features |= QOpenGLFunctions::BlendFuncSeparate;
- if (extensions.match("GL_EXT_blend_subtract"))
- features |= QOpenGLFunctions::BlendSubtract;
- if (extensions.match("GL_ARB_texture_compression"))
- features |= QOpenGLFunctions::CompressedTextures;
- if (extensions.match("GL_ARB_multisample"))
- features |= QOpenGLFunctions::Multisample;
- if (extensions.match("GL_ARB_texture_non_power_of_two"))
- features |= QOpenGLFunctions::NPOTTextures |
- QOpenGLFunctions::NPOTTextureRepeat;
-
- // assume version 2.0 or higher
- features |= QOpenGLFunctions::BlendColor |
- QOpenGLFunctions::BlendEquation |
- QOpenGLFunctions::Multitexture |
- QOpenGLFunctions::CompressedTextures |
- QOpenGLFunctions::Multisample |
- QOpenGLFunctions::BlendFuncSeparate |
- QOpenGLFunctions::Buffers |
- QOpenGLFunctions::Shaders |
- QOpenGLFunctions::StencilSeparate |
- QOpenGLFunctions::BlendEquationSeparate |
- QOpenGLFunctions::NPOTTextures |
- QOpenGLFunctions::NPOTTextureRepeat;
-
if (format.majorVersion() >= 3)
features |= QOpenGLFunctions::Framebuffers;
+ else if (extensions.match("GL_EXT_framebuffer_object") ||
+ extensions.match("GL_ARB_framebuffer_object"))
+ features |= QOpenGLFunctions::Framebuffers;
+
+ if (format.majorVersion() >= 2) {
+ features |= QOpenGLFunctions::BlendColor |
+ QOpenGLFunctions::BlendEquation |
+ QOpenGLFunctions::BlendSubtract |
+ QOpenGLFunctions::Multitexture |
+ QOpenGLFunctions::CompressedTextures |
+ QOpenGLFunctions::Multisample |
+ QOpenGLFunctions::BlendFuncSeparate |
+ QOpenGLFunctions::Buffers |
+ QOpenGLFunctions::Shaders |
+ QOpenGLFunctions::StencilSeparate |
+ QOpenGLFunctions::BlendEquationSeparate |
+ QOpenGLFunctions::NPOTTextures |
+ QOpenGLFunctions::NPOTTextureRepeat;
+ } else {
+ // Recognize features by extension name.
+ if (extensions.match("GL_ARB_multitexture"))
+ features |= QOpenGLFunctions::Multitexture;
+ if (extensions.match("GL_ARB_shader_objects"))
+ features |= QOpenGLFunctions::Shaders;
+ if (extensions.match("GL_EXT_blend_color"))
+ features |= QOpenGLFunctions::BlendColor;
+ if (extensions.match("GL_EXT_blend_equation_separate"))
+ features |= QOpenGLFunctions::BlendEquationSeparate;
+ if (extensions.match("GL_EXT_blend_subtract"))
+ features |= QOpenGLFunctions::BlendSubtract;
+ if (extensions.match("GL_EXT_blend_func_separate"))
+ features |= QOpenGLFunctions::BlendFuncSeparate;
+ if (extensions.match("GL_ARB_texture_compression"))
+ features |= QOpenGLFunctions::CompressedTextures;
+ if (extensions.match("GL_ARB_multisample"))
+ features |= QOpenGLFunctions::Multisample;
+ if (extensions.match("GL_ARB_texture_non_power_of_two"))
+ features |= QOpenGLFunctions::NPOTTextures |
+ QOpenGLFunctions::NPOTTextureRepeat;
+ }
const QPair<int, int> version = format.version();
if (version < qMakePair(3, 0)
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index 2b40bf37e1..44b38dcf1c 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -1798,71 +1798,6 @@ static const uint * QT_FASTCALL fetchTransformedBilinearARGB32PM(uint *buffer, c
}
fx = v_fx.i[0];
fy = v_fy.i[0];
-#elif defined(__ARM_NEON__)
- BILINEAR_ROTATE_BOUNDS_PROLOG
-
- const int16x8_t colorMask = vdupq_n_s16(0x00ff);
- const int16x8_t invColorMask = vmvnq_s16(colorMask);
- const int16x8_t v_256 = vdupq_n_s16(256);
- int32x4_t v_fdx = vdupq_n_s32(fdx*4);
- int32x4_t v_fdy = vdupq_n_s32(fdy*4);
-
- const uchar *textureData = data->texture.imageData;
- const int bytesPerLine = data->texture.bytesPerLine;
-
- union Vect_buffer { int32x4_t vect; quint32 i[4]; };
- Vect_buffer v_fx, v_fy;
-
- for (int i = 0; i < 4; i++) {
- v_fx.i[i] = fx;
- v_fy.i[i] = fy;
- fx += fdx;
- fy += fdy;
- }
-
- const int32x4_t v_ffff_mask = vdupq_n_s32(0x0000ffff);
-
- while (b < boundedEnd) {
- if (fdx > 0 && (v_fx.i[3] >> 16) >= image_x2)
- break;
- if (fdx < 0 && (v_fx.i[3] >> 16) < image_x1)
- break;
- if (fdy > 0 && (v_fy.i[3] >> 16) >= image_y2)
- break;
- if (fdy < 0 && (v_fy.i[3] >> 16) < image_y1)
- break;
-
- Vect_buffer tl, tr, bl, br;
-
- Vect_buffer v_fx_shifted, v_fy_shifted;
- v_fx_shifted.vect = vshrq_n_s32(v_fx.vect, 16);
- v_fy_shifted.vect = vshrq_n_s32(v_fy.vect, 16);
-
- for (int i = 0; i < 4; i++) {
- const int x1 = v_fx_shifted.i[i];
- const int y1 = v_fy_shifted.i[i];
- const uchar *sl = textureData + bytesPerLine * y1;
- const uint *s1 = (const uint *)sl;
- const uint *s2 = (const uint *)(sl + bytesPerLine);
- tl.i[i] = s1[x1];
- tr.i[i] = s1[x1+1];
- bl.i[i] = s2[x1];
- br.i[i] = s2[x1+1];
- }
-
- int32x4_t v_distx = vshrq_n_s32(vandq_s32(v_fx.vect, v_ffff_mask), 12);
- int32x4_t v_disty = vshrq_n_s32(vandq_s32(v_fy.vect, v_ffff_mask), 12);
- v_distx = vorrq_s32(v_distx, vshlq_n_s32(v_distx, 16));
- v_disty = vorrq_s32(v_disty, vshlq_n_s32(v_disty, 16));
- int16x8_t v_disty_ = vshlq_n_s16(v_disty, 4);
-
- interpolate_4_pixels_16_neon(vreinterpretq_s16_s32(tl.vect), vreinterpretq_s16_s32(tr.vect), vreinterpretq_s16_s32(bl.vect), vreinterpretq_s16_s32(br.vect), vreinterpretq_s16_s32(v_distx), v_disty, v_disty_, colorMask, invColorMask, v_256, b);
- b+=4;
- v_fx.vect = vaddq_s32(v_fx.vect, v_fdx);
- v_fy.vect = vaddq_s32(v_fy.vect, v_fdy);
- }
- fx = v_fx.i[0];
- fy = v_fy.i[0];
#endif
}
@@ -6318,6 +6253,7 @@ static void qt_alphamapblit_argb32(QRasterBuffer *rasterBuffer,
}
}
+#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
static void qt_alphamapblit_rgba8888(QRasterBuffer *rasterBuffer,
int x, int y, quint32 color,
const uchar *map,
@@ -6326,6 +6262,7 @@ static void qt_alphamapblit_rgba8888(QRasterBuffer *rasterBuffer,
{
qt_alphamapblit_argb32(rasterBuffer, x, y, ARGB2RGBA(color), map, mapWidth, mapHeight, mapStride, clip);
}
+#endif
static void qt_alphargbblit_argb32(QRasterBuffer *rasterBuffer,
int x, int y, quint32 color,
diff --git a/src/gui/painting/qpaintengine.cpp b/src/gui/painting/qpaintengine.cpp
index acab08e794..ba20186d00 100644
--- a/src/gui/painting/qpaintengine.cpp
+++ b/src/gui/painting/qpaintengine.cpp
@@ -761,7 +761,7 @@ void QPaintEngine::drawTextItem(const QPointF &p, const QTextItem &textItem)
bool((painter()->renderHints() & QPainter::TextAntialiasing)
&& !(painter()->font().styleStrategy() & QFont::NoAntialias)));
painter()->translate(p.x(), p.y());
- painter()->fillPath(path, state->pen().brush());
+ painter()->fillPath(path, painter()->pen().brush());
painter()->restore();
}
}
diff --git a/src/gui/painting/qpaintengineex.cpp b/src/gui/painting/qpaintengineex.cpp
index e75a59cc91..8487cf2394 100644
--- a/src/gui/painting/qpaintengineex.cpp
+++ b/src/gui/painting/qpaintengineex.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtGui module of the Qt Toolkit.
@@ -830,6 +830,8 @@ void QPaintEngineEx::drawEllipse(const QRectF &r)
int point_count = 0;
x.points[0] = qt_curves_for_arc(r, 0, -360, x.points + 1, &point_count);
+ if (point_count == 0)
+ return;
QVectorPath vp((qreal *) pts, point_count + 1, qpaintengineex_ellipse_types, QVectorPath::EllipseHint);
draw(vp);
}
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp
index a165330913..3ce4ae67ae 100644
--- a/src/gui/text/qfontengine.cpp
+++ b/src/gui/text/qfontengine.cpp
@@ -181,9 +181,13 @@ static const HB_FontClass hb_fontClass = {
static HB_Error hb_getSFntTable(void *font, HB_Tag tableTag, HB_Byte *buffer, HB_UInt *length)
{
- QFontEngine *fe = (QFontEngine *)font;
- Q_ASSERT(fe->faceData.get_font_table);
- if (!fe->faceData.get_font_table(fe->faceData.user_data, tableTag, buffer, length))
+ QFontEngine::FaceData *data = (QFontEngine::FaceData *)font;
+ Q_ASSERT(data);
+
+ qt_get_font_table_func_t get_font_table = data->get_font_table;
+ Q_ASSERT(get_font_table);
+
+ if (!get_font_table(data->user_data, tableTag, buffer, length))
return HB_Err_Invalid_Argument;
return HB_Err_Ok;
}
@@ -291,8 +295,11 @@ void *QFontEngine::harfbuzzFont() const
#endif
if (!font_) {
HB_Face hbFace = (HB_Face)harfbuzzFace();
- if (hbFace->font_for_init != 0)
+ if (hbFace->font_for_init) {
+ void *data = hbFace->font_for_init;
q_check_ptr(qHBLoadFace(hbFace));
+ free(data);
+ }
HB_FontRec *hbFont = (HB_FontRec *) malloc(sizeof(HB_FontRec));
Q_CHECK_PTR(hbFont);
@@ -323,7 +330,12 @@ void *QFontEngine::harfbuzzFace() const
return hb_qt_face_get_for_engine(const_cast<QFontEngine *>(this));
#endif
if (!face_) {
- HB_Face hbFace = qHBNewFace(const_cast<QFontEngine *>(this), hb_getSFntTable);
+ QFontEngine::FaceData *data = (QFontEngine::FaceData *)malloc(sizeof(QFontEngine::FaceData));
+ Q_CHECK_PTR(data);
+ data->user_data = faceData.user_data;
+ data->get_font_table = faceData.get_font_table;
+
+ HB_Face hbFace = qHBNewFace(data, hb_getSFntTable);
Q_CHECK_PTR(hbFace);
hbFace->isSymbolFont = symbol;
@@ -376,8 +388,11 @@ bool QFontEngine::supportsScript(QChar::Script script) const
}
#endif
HB_Face hbFace = (HB_Face)harfbuzzFace();
- if (hbFace->font_for_init != 0)
+ if (hbFace->font_for_init) {
+ void *data = hbFace->font_for_init;
q_check_ptr(qHBLoadFace(hbFace));
+ free(data);
+ }
return hbFace->supported_scripts[script_to_hbscript(script)];
}
diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp
index 7868fd23d1..f6ab123739 100644
--- a/src/gui/text/qfontmetrics.cpp
+++ b/src/gui/text/qfontmetrics.cpp
@@ -295,8 +295,7 @@ int QFontMetrics::descent() const
/*!
Returns the height of the font.
- This is always equal to ascent()+descent()+1 (the 1 is for the
- base line).
+ This is always equal to ascent()+descent().
\sa leading(), lineSpacing()
*/
@@ -1159,8 +1158,7 @@ qreal QFontMetricsF::descent() const
/*!
Returns the height of the font.
- This is always equal to ascent()+descent()+1 (the 1 is for the
- base line).
+ This is always equal to ascent()+descent().
\sa leading(), lineSpacing()
*/
diff --git a/src/network/access/qhttpnetworkconnection.cpp b/src/network/access/qhttpnetworkconnection.cpp
index accad6e4c0..7ff6bffed3 100644
--- a/src/network/access/qhttpnetworkconnection.cpp
+++ b/src/network/access/qhttpnetworkconnection.cpp
@@ -1219,8 +1219,8 @@ QHttpNetworkConnection::QHttpNetworkConnection(quint16 connectionCount, const QS
d->init();
}
#else
-QHttpNetworkConnection::QHttpNetworkConnection(const QString &hostName, quint16 port, bool encrypt, QObject *parent,
- QHttpNetworkConnection::ConnectionType connectionType)
+QHttpNetworkConnection::QHttpNetworkConnection(const QString &hostName, quint16 port, bool encrypt,
+ QHttpNetworkConnection::ConnectionType connectionType, QObject *parent)
: QObject(*(new QHttpNetworkConnectionPrivate(hostName, port, encrypt , connectionType)), parent)
{
Q_D(QHttpNetworkConnection);
diff --git a/src/network/access/qhttpnetworkconnection_p.h b/src/network/access/qhttpnetworkconnection_p.h
index 9d4257e217..42114ae9d6 100644
--- a/src/network/access/qhttpnetworkconnection_p.h
+++ b/src/network/access/qhttpnetworkconnection_p.h
@@ -110,8 +110,8 @@ public:
ConnectionType connectionType = ConnectionTypeHTTP);
#else
explicit QHttpNetworkConnection(const QString &hostName, quint16 port = 80, bool encrypt = false,
- QObject *parent = 0,
- ConnectionType connectionType = ConnectionTypeHTTP);
+ ConnectionType connectionType = ConnectionTypeHTTP,
+ QObject *parent = 0);
QHttpNetworkConnection(quint16 channelCount, const QString &hostName, quint16 port = 80,
bool encrypt = false, QObject *parent = 0,
ConnectionType connectionType = ConnectionTypeHTTP);
diff --git a/src/network/access/qnetworkaccessbackend.cpp b/src/network/access/qnetworkaccessbackend.cpp
index f387559cb3..acaba33dee 100644
--- a/src/network/access/qnetworkaccessbackend.cpp
+++ b/src/network/access/qnetworkaccessbackend.cpp
@@ -338,7 +338,7 @@ void QNetworkAccessBackend::error(QNetworkReply::NetworkError code, const QStrin
void QNetworkAccessBackend::proxyAuthenticationRequired(const QNetworkProxy &proxy,
QAuthenticator *authenticator)
{
- manager->proxyAuthenticationRequired(proxy, synchronous, authenticator, &reply->lastProxyAuthentication);
+ manager->proxyAuthenticationRequired(QUrl(), proxy, synchronous, authenticator, &reply->lastProxyAuthentication);
}
#endif
diff --git a/src/network/access/qnetworkaccessmanager.cpp b/src/network/access/qnetworkaccessmanager.cpp
index 473acc5f22..cc61f27cfb 100644
--- a/src/network/access/qnetworkaccessmanager.cpp
+++ b/src/network/access/qnetworkaccessmanager.cpp
@@ -99,13 +99,13 @@ bool getProxyAuth(const QString& proxyHostname, const QString &scheme, QString&
bool retValue = false;
SecProtocolType protocolType = kSecProtocolTypeAny;
if (scheme.compare(QLatin1String("ftp"),Qt::CaseInsensitive)==0) {
- protocolType = kSecProtocolTypeFTP;
+ protocolType = kSecProtocolTypeFTPProxy;
} else if (scheme.compare(QLatin1String("http"),Qt::CaseInsensitive)==0
|| scheme.compare(QLatin1String("preconnect-http"),Qt::CaseInsensitive)==0) {
- protocolType = kSecProtocolTypeHTTP;
+ protocolType = kSecProtocolTypeHTTPProxy;
} else if (scheme.compare(QLatin1String("https"),Qt::CaseInsensitive)==0
|| scheme.compare(QLatin1String("preconnect-https"),Qt::CaseInsensitive)==0) {
- protocolType = kSecProtocolTypeHTTPS;
+ protocolType = kSecProtocolTypeHTTPSProxy;
}
QByteArray proxyHostnameUtf8(proxyHostname.toUtf8());
err = SecKeychainFindInternetPassword(NULL,
@@ -1392,21 +1392,6 @@ void QNetworkAccessManagerPrivate::authenticationRequired(QAuthenticator *authen
}
}
-#ifndef QT_NO_NETWORKPROXY
-#if defined(Q_OS_MACX)
- //now we try to get the username and password from keychain
- //if not successful signal will be emitted
- QString username;
- QString password;
- if (getProxyAuth(proxy.hostName(),reply->request().url().scheme(),username,password)) {
- authenticator->setUser(username);
- authenticator->setPassword(password);
- authenticationManager->cacheProxyCredentials(proxy, authenticator);
- return;
- }
-#endif
-#endif //QT_NO_NETWORKPROXY
-
// if we emit a signal here in synchronous mode, the user might spin
// an event loop, which might recurse and lead to problems
if (synchronous)
@@ -1419,7 +1404,8 @@ void QNetworkAccessManagerPrivate::authenticationRequired(QAuthenticator *authen
}
#ifndef QT_NO_NETWORKPROXY
-void QNetworkAccessManagerPrivate::proxyAuthenticationRequired(const QNetworkProxy &proxy,
+void QNetworkAccessManagerPrivate::proxyAuthenticationRequired(const QUrl &url,
+ const QNetworkProxy &proxy,
bool synchronous,
QAuthenticator *authenticator,
QNetworkProxy *lastProxyAuthentication)
@@ -1435,6 +1421,26 @@ void QNetworkAccessManagerPrivate::proxyAuthenticationRequired(const QNetworkPro
}
}
+#if defined(Q_OS_OSX)
+ //now we try to get the username and password from keychain
+ //if not successful signal will be emitted
+ QString username;
+ QString password;
+ if (getProxyAuth(proxy.hostName(), url.scheme(), username, password)) {
+ // only cache the system credentials if they are correct (or if they have changed)
+ // to not run into an endless loop in case they are wrong
+ QNetworkAuthenticationCredential cred = authenticationManager->fetchCachedProxyCredentials(proxy);
+ if (!priv->hasFailed || cred.user != username || cred.password != password) {
+ authenticator->setUser(username);
+ authenticator->setPassword(password);
+ authenticationManager->cacheProxyCredentials(proxy, authenticator);
+ return;
+ }
+ }
+#else
+ Q_UNUSED(url);
+#endif
+
// if we emit a signal here in synchronous mode, the user might spin
// an event loop, which might recurse and lead to problems
if (synchronous)
diff --git a/src/network/access/qnetworkaccessmanager_p.h b/src/network/access/qnetworkaccessmanager_p.h
index 92762d3ed4..bd5a6faeef 100644
--- a/src/network/access/qnetworkaccessmanager_p.h
+++ b/src/network/access/qnetworkaccessmanager_p.h
@@ -113,7 +113,8 @@ public:
const QAuthenticator *auth = 0);
#ifndef QT_NO_NETWORKPROXY
- void proxyAuthenticationRequired(const QNetworkProxy &proxy,
+ void proxyAuthenticationRequired(const QUrl &url,
+ const QNetworkProxy &proxy,
bool synchronous,
QAuthenticator *authenticator,
QNetworkProxy *lastProxyAuthentication);
diff --git a/src/network/access/qnetworkreplyhttpimpl.cpp b/src/network/access/qnetworkreplyhttpimpl.cpp
index 3f546cf581..3ac8b8f56f 100644
--- a/src/network/access/qnetworkreplyhttpimpl.cpp
+++ b/src/network/access/qnetworkreplyhttpimpl.cpp
@@ -979,6 +979,9 @@ void QNetworkReplyHttpImplPrivate::initCacheSaveDevice()
cacheSaveDevice = managerPrivate->networkCache->prepare(metaData);
+ if (cacheSaveDevice)
+ q->connect(cacheSaveDevice, SIGNAL(aboutToClose()), SLOT(_q_cacheSaveDeviceAboutToClose()));
+
if (!cacheSaveDevice || (cacheSaveDevice && !cacheSaveDevice->isOpen())) {
if (cacheSaveDevice && !cacheSaveDevice->isOpen())
qCritical("QNetworkReplyImpl: network cache returned a device that is not open -- "
@@ -1224,7 +1227,7 @@ void QNetworkReplyHttpImplPrivate::httpAuthenticationRequired(const QHttpNetwork
void QNetworkReplyHttpImplPrivate::proxyAuthenticationRequired(const QNetworkProxy &proxy,
QAuthenticator *authenticator)
{
- managerPrivate->proxyAuthenticationRequired(proxy, synchronous, authenticator, &lastProxyAuthentication);
+ managerPrivate->proxyAuthenticationRequired(request.url(), proxy, synchronous, authenticator, &lastProxyAuthentication);
}
#endif
@@ -1712,6 +1715,13 @@ void QNetworkReplyHttpImplPrivate::_q_bufferOutgoingDataFinished()
QMetaObject::invokeMethod(q, "_q_startOperation", Qt::QueuedConnection);
}
+void QNetworkReplyHttpImplPrivate::_q_cacheSaveDeviceAboutToClose()
+{
+ // do not keep a dangling pointer to the device around (device
+ // is closing because e.g. QAbstractNetworkCache::remove() was called).
+ cacheSaveDevice = 0;
+}
+
void QNetworkReplyHttpImplPrivate::_q_bufferOutgoingData()
{
Q_Q(QNetworkReplyHttpImpl);
diff --git a/src/network/access/qnetworkreplyhttpimpl_p.h b/src/network/access/qnetworkreplyhttpimpl_p.h
index aa2d6f0ec9..d21659ce82 100644
--- a/src/network/access/qnetworkreplyhttpimpl_p.h
+++ b/src/network/access/qnetworkreplyhttpimpl_p.h
@@ -130,6 +130,7 @@ public:
Q_PRIVATE_SLOT(d_func(), void wantUploadDataSlot(qint64))
Q_PRIVATE_SLOT(d_func(), void sentUploadDataSlot(qint64))
Q_PRIVATE_SLOT(d_func(), void emitReplyUploadProgress(qint64, qint64))
+ Q_PRIVATE_SLOT(d_func(), void _q_cacheSaveDeviceAboutToClose())
#ifndef QT_NO_SSL
@@ -179,6 +180,8 @@ public:
void _q_bufferOutgoingData();
void _q_bufferOutgoingDataFinished();
+ void _q_cacheSaveDeviceAboutToClose();
+
#ifndef QT_NO_BEARERMANAGEMENT
void _q_networkSessionConnected();
void _q_networkSessionFailed();
diff --git a/src/network/access/qnetworkreplynsurlconnectionimpl.mm b/src/network/access/qnetworkreplynsurlconnectionimpl.mm
index d49324918e..f93f18357a 100644
--- a/src/network/access/qnetworkreplynsurlconnectionimpl.mm
+++ b/src/network/access/qnetworkreplynsurlconnectionimpl.mm
@@ -90,6 +90,7 @@ public:
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
@@ -140,6 +141,7 @@ QNetworkReplyNSURLConnectionImplPrivate::~QNetworkReplyNSURLConnectionImplPrivat
void QNetworkReplyNSURLConnectionImplPrivate::setFinished()
{
q_func()->setFinished(true);
+ QMetaObject::invokeMethod(q_func(), "finished", Qt::QueuedConnection);
}
void QNetworkReplyNSURLConnectionImplPrivate::setHeader(QNetworkRequest::KnownHeaders header, const QVariant &value)
@@ -157,6 +159,11 @@ void QNetworkReplyNSURLConnectionImplPrivate::setError(QNetworkReply::NetworkErr
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);
@@ -269,6 +276,9 @@ void QNetworkReplyNSURLConnectionImpl::readyReadOutgoingData()
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]);
@@ -317,8 +327,7 @@ void QNetworkReplyNSURLConnectionImpl::readyReadOutgoingData()
- (void)connectionDidFinishLoading:(NSURLConnection*)connection
{
Q_UNUSED(connection)
- replyprivate->setFinished();
- QMetaObject::invokeMethod(replyprivate->q_func(), "finished", Qt::QueuedConnection);
+ replyprivate->setFinished();
}
- (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection*)connection
diff --git a/src/network/kernel/qdnslookup_unix.cpp b/src/network/kernel/qdnslookup_unix.cpp
index 26834dff57..8c5a0ebdba 100644
--- a/src/network/kernel/qdnslookup_unix.cpp
+++ b/src/network/kernel/qdnslookup_unix.cpp
@@ -160,9 +160,11 @@ void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestN
Q_CHECK_PTR(ns);
state._u._ext.nsaddrs[0] = ns;
}
+#ifndef __UCLIBC__
// Set nsmap[] to indicate that nsaddrs[0] is an IPv6 address
// See: https://sourceware.org/ml/libc-hacker/2002-05/msg00035.html
state._u._ext.nsmap[0] = MAXNS + 1;
+#endif
state._u._ext.nscount6 = 1;
ns->sin6_family = AF_INET6;
ns->sin6_port = htons(53);
@@ -370,11 +372,11 @@ void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestN
}
#else
-
-void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestName, QDnsLookupReply *reply)
+void QDnsLookupRunnable::query(const int requestType, const QByteArray &requestName, const QHostAddress &nameserver, QDnsLookupReply *reply)
{
Q_UNUSED(requestType)
Q_UNUSED(requestName)
+ Q_UNUSED(nameserver)
reply->error = QDnsLookup::ResolverError;
reply->errorString = tr("Resolver library can't be loaded: No runtime library loading support");
return;
diff --git a/src/network/kernel/qhostaddress.h b/src/network/kernel/qhostaddress.h
index 49032850be..d27a326fb9 100644
--- a/src/network/kernel/qhostaddress.h
+++ b/src/network/kernel/qhostaddress.h
@@ -85,7 +85,7 @@ public:
explicit QHostAddress(quint32 ip4Addr);
explicit QHostAddress(quint8 *ip6Addr);
explicit QHostAddress(const Q_IPV6ADDR &ip6Addr);
- explicit QHostAddress(const sockaddr *sockaddr);
+ explicit QHostAddress(const sockaddr *address);
explicit QHostAddress(const QString &address);
QHostAddress(const QHostAddress &copy);
QHostAddress(SpecialAddress address);
@@ -97,7 +97,7 @@ public:
void setAddress(quint32 ip4Addr);
void setAddress(quint8 *ip6Addr);
void setAddress(const Q_IPV6ADDR &ip6Addr);
- void setAddress(const sockaddr *sockaddr);
+ void setAddress(const sockaddr *address);
bool setAddress(const QString &address);
QAbstractSocket::NetworkLayerProtocol protocol() const;
diff --git a/src/network/kernel/qnetworkinterface_win_p.h b/src/network/kernel/qnetworkinterface_win_p.h
index d6a3366316..23664647cf 100644
--- a/src/network/kernel/qnetworkinterface_win_p.h
+++ b/src/network/kernel/qnetworkinterface_win_p.h
@@ -53,6 +53,7 @@
// We mean it.
//
+#include <QtCore/qglobal.h>
#include <winsock2.h>
#include <qt_windows.h>
#include <time.h>
diff --git a/src/network/socket/qlocalsocket_win.cpp b/src/network/socket/qlocalsocket_win.cpp
index 96c6c0f6ea..6fef819eee 100644
--- a/src/network/socket/qlocalsocket_win.cpp
+++ b/src/network/socket/qlocalsocket_win.cpp
@@ -202,7 +202,17 @@ qint64 QLocalSocket::readData(char *data, qint64 maxSize)
if (!maxSize)
return 0;
- return d->pipeReader->read(data, maxSize);
+ qint64 ret = d->pipeReader->read(data, maxSize);
+
+ // QWindowsPipeReader::read() returns error codes that don't match what we need
+ switch (ret) {
+ case 0: // EOF -> transform to error
+ return -1;
+ case -2: // EWOULDBLOCK -> no error, just no bytes
+ return 0;
+ default:
+ return ret;
+ }
}
qint64 QLocalSocket::writeData(const char *data, qint64 maxSize)
diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp
index 852a0cd066..ab6c2a6590 100644
--- a/src/network/socket/qnativesocketengine_winrt.cpp
+++ b/src/network/socket/qnativesocketengine_winrt.cpp
@@ -246,8 +246,11 @@ bool QNativeSocketEngine::initialize(qintptr socketDescriptor, QAbstractSocket::
d->tcp = handler->pendingTcpSockets.take(socketDescriptor);
d->socketType = QAbstractSocket::TcpSocket;
- if (!d->tcp || !d->fetchConnectionParameters())
+ if (!d->tcp || !d->fetchConnectionParameters()) {
+ d->setError(QAbstractSocket::UnsupportedSocketOperationError,
+ d->InvalidSocketErrorString);
return false;
+ }
d->socketState = socketState;
return true;
@@ -475,9 +478,9 @@ void QNativeSocketEngine::close()
Q_D(QNativeSocketEngine);
if (d->socketDescriptor != -1) {
ComPtr<IClosable> socket;
- if (d->socketType == QAbstractSocket::TcpSocket)
+ if (d->socketType == QAbstractSocket::TcpSocket && d->tcp)
d->tcp.As(&socket);
- else if (d->socketType == QAbstractSocket::UdpSocket)
+ else if (d->socketType == QAbstractSocket::UdpSocket && d->udp)
d->udp.As(&socket);
if (socket) {
diff --git a/src/network/ssl/qsslsocket_openssl_android.cpp b/src/network/ssl/qsslsocket_openssl_android.cpp
index fa612a75a6..c7cf03d86d 100644
--- a/src/network/ssl/qsslsocket_openssl_android.cpp
+++ b/src/network/ssl/qsslsocket_openssl_android.cpp
@@ -153,6 +153,8 @@ Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void * /*reserved*/)
return JNI_VERSION_1_4;
}
+QT_BEGIN_NAMESPACE
+
QList<QByteArray> QSslSocketPrivate::fetchSslCertificateData()
{
QList<QByteArray> certificateData;
@@ -177,3 +179,5 @@ QList<QByteArray> QSslSocketPrivate::fetchSslCertificateData()
return certificateData;
}
+
+QT_END_NAMESPACE
diff --git a/src/platformsupport/eglconvenience/qxlibeglintegration.cpp b/src/platformsupport/eglconvenience/qxlibeglintegration.cpp
index 80453816fc..9c2d50823a 100644
--- a/src/platformsupport/eglconvenience/qxlibeglintegration.cpp
+++ b/src/platformsupport/eglconvenience/qxlibeglintegration.cpp
@@ -84,32 +84,22 @@ VisualID QXlibEglIntegration::getCompatibleVisualId(Display *display, EGLDisplay
int visualRedSize = qPopulationCount(chosenVisualInfo->red_mask);
int visualGreenSize = qPopulationCount(chosenVisualInfo->green_mask);
int visualBlueSize = qPopulationCount(chosenVisualInfo->blue_mask);
- int visualAlphaSize = -1; // Need XRender to tell us the alpha channel size
-
- bool visualMatchesConfig = false;
- if ( visualRedSize == configRedSize &&
- visualGreenSize == configGreenSize &&
- visualBlueSize == configBlueSize )
- {
- // We need XRender to check the alpha channel size of the visual. If we don't have
- // the alpha size, we don't check it against the EGL config's alpha size.
- if (visualAlphaSize >= 0)
- visualMatchesConfig = visualAlphaSize == configAlphaSize;
- else
- visualMatchesConfig = true;
- }
+ int visualAlphaSize = chosenVisualInfo->depth == 32 ? 8 : 0;
+
+ const bool visualMatchesConfig = visualRedSize == configRedSize
+ && visualGreenSize == configGreenSize
+ && visualBlueSize == configBlueSize
+ && visualAlphaSize == configAlphaSize;
+ // In some cases EGL tends to suggest a 24-bit visual for 8888
+ // configs. In such a case we have to fall back to XGetVisualInfo.
if (!visualMatchesConfig) {
- if (visualAlphaSize >= 0) {
- qWarning("Warning: EGL suggested using X Visual ID %d (ARGB%d%d%d%d) for EGL config %d (ARGB%d%d%d%d), but this is incompatable",
- (int)visualId, visualAlphaSize, visualRedSize, visualGreenSize, visualBlueSize,
- configId, configAlphaSize, configRedSize, configGreenSize, configBlueSize);
- } else {
- qWarning("Warning: EGL suggested using X Visual ID %d (RGB%d%d%d) for EGL config %d (RGB%d%d%d), but this is incompatable",
- (int)visualId, visualRedSize, visualGreenSize, visualBlueSize,
- configId, configRedSize, configGreenSize, configBlueSize);
- }
visualId = 0;
+#ifdef QT_DEBUG_X11_VISUAL_SELECTION
+ qWarning("Warning: EGL suggested using X Visual ID %d (%d %d %d depth %d) for EGL config %d (%d %d %d %d), but this is incompatible",
+ (int)visualId, visualRedSize, visualGreenSize, visualBlueSize, chosenVisualInfo->depth,
+ configId, configRedSize, configGreenSize, configBlueSize, configAlphaSize);
+#endif
}
} else {
qWarning("Warning: EGL suggested using X Visual ID %d for EGL config %d, but that isn't a valid ID",
@@ -133,8 +123,7 @@ VisualID QXlibEglIntegration::getCompatibleVisualId(Display *display, EGLDisplay
return visualId;
}
- // Finally, try to
- // use XGetVisualInfo and only use the bit depths to match on:
+ // Finally, try to use XGetVisualInfo and only use the bit depths to match on:
if (!visualId) {
XVisualInfo visualInfoTemplate;
memset(&visualInfoTemplate, 0, sizeof(XVisualInfo));
diff --git a/src/plugins/imageformats/ico/qicohandler.cpp b/src/plugins/imageformats/ico/qicohandler.cpp
index b65bcdfacb..f013692809 100644
--- a/src/plugins/imageformats/ico/qicohandler.cpp
+++ b/src/plugins/imageformats/ico/qicohandler.cpp
@@ -517,6 +517,8 @@ void ICOReader::read16_24_32BMP(QImage & image)
}
}
+static const char icoOrigDepthKey[] = "_q_icoOrigDepth";
+
QImage ICOReader::iconAt(int index)
{
QImage img;
@@ -535,7 +537,9 @@ QImage ICOReader::iconAt(int index)
if (isPngImage) {
iod->seek(iconEntry.dwImageOffset);
- return QImage::fromData(iod->read(iconEntry.dwBytesInRes), "png");
+ QImage image = QImage::fromData(iod->read(iconEntry.dwBytesInRes), "png");
+ image.setText(QLatin1String(icoOrigDepthKey), QString::number(iconEntry.wBitCount));
+ return image;
}
BMP_INFOHDR header;
@@ -598,6 +602,7 @@ QImage ICOReader::iconAt(int index)
}
}
}
+ img.setText(QLatin1String(icoOrigDepthKey), QString::number(iconEntry.wBitCount));
}
}
}
diff --git a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
index ea0b5261c4..395bb5b090 100644
--- a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
+++ b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.cpp
@@ -111,21 +111,17 @@ void TableGenerator::findComposeFile()
}
// check for the system provided compose files
if (!found && cleanState()) {
- QByteArray loc = locale().toUpper().toUtf8();
- QString table = readLocaleMappings(loc);
- if (table.isEmpty())
- table = readLocaleMappings(readLocaleAliases(loc));
-
+ QString table = composeTableForLocale();
if (cleanState()) {
if (table.isEmpty())
// no table mappings for the system's locale in the compose.dir
m_state = UnsupportedLocale;
else
- found = processFile(systemComposeDir() + QLatin1String("/") + table);
+ found = processFile(systemComposeDir() + QLatin1Char('/') + table);
#ifdef DEBUG_GENERATOR
if (found)
qDebug() << "Using Compose file from: " <<
- systemComposeDir() + QLatin1String("/") + table;
+ systemComposeDir() + QLatin1Char('/') + table;
#endif
}
}
@@ -137,6 +133,15 @@ void TableGenerator::findComposeFile()
m_state = MissingComposeFile;
}
+QString TableGenerator::composeTableForLocale()
+{
+ QByteArray loc = locale().toUpper().toUtf8();
+ QString table = readLocaleMappings(loc);
+ if (table.isEmpty())
+ table = readLocaleMappings(readLocaleAliases(loc));
+ return table;
+}
+
bool TableGenerator::findSystemComposeDir()
{
bool found = false;
@@ -311,7 +316,7 @@ void TableGenerator::parseIncludeInstruction(QString line)
// expand substitutions if present
line.replace(QLatin1String("%H"), QString(qgetenv("HOME")));
- line.replace(QLatin1String("%L"), locale());
+ line.replace(QLatin1String("%L"), systemComposeDir() + QLatin1Char('/') + composeTableForLocale());
line.replace(QLatin1String("%S"), systemComposeDir());
processFile(line);
diff --git a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.h b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.h
index 248c09f3ea..6ce89cfe77 100644
--- a/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.h
+++ b/src/plugins/platforminputcontexts/compose/generator/qtablegenerator.h
@@ -118,13 +118,14 @@ protected:
void findComposeFile();
bool findSystemComposeDir();
QString systemComposeDir();
+ QString composeTableForLocale();
ushort keysymToUtf8(quint32 sym);
QString readLocaleMappings(const QByteArray &locale);
QByteArray readLocaleAliases(const QByteArray &locale);
void initPossibleLocations();
- bool cleanState() const { return ((m_state & NoErrors) == NoErrors); }
+ bool cleanState() const { return m_state == NoErrors; }
QString locale() const;
private:
diff --git a/src/plugins/platforms/android/androidjniaccessibility.cpp b/src/plugins/platforms/android/androidjniaccessibility.cpp
index 7fc7595881..a7fec8748b 100644
--- a/src/plugins/platforms/android/androidjniaccessibility.cpp
+++ b/src/plugins/platforms/android/androidjniaccessibility.cpp
@@ -49,6 +49,7 @@
#include "qrect.h"
#include "QtGui/qaccessible.h"
#include <QtCore/qmath.h>
+#include <QtCore/private/qjnihelpers_p.h>
#include "qdebug.h"
@@ -56,6 +57,8 @@ static const char m_qtTag[] = "Qt A11Y";
static const char m_classErrorMsg[] = "Can't find class \"%s\"";
static const char m_methodErrorMsg[] = "Can't find method \"%s%s\"";
+QT_BEGIN_NAMESPACE
+
namespace QtAndroidAccessibility
{
static jmethodID m_addActionMethodID = 0;
@@ -227,7 +230,7 @@ if (!clazz) { \
if (desc.isEmpty())
desc = iface->text(QAccessible::Description);
if (QAccessibleTextInterface *textIface = iface->textInterface()) {
- if (textIface->selectionCount() > 0) {
+ if (m_setTextSelectionMethodID && textIface->selectionCount() > 0) {
int startSelection;
int endSelection;
textIface->selection(0, &startSelection, &endSelection);
@@ -286,12 +289,15 @@ if (!clazz) { \
bool registerNatives(JNIEnv *env)
{
+ if (QtAndroidPrivate::androidSdkVersion() < 16)
+ return true; // We need API level 16 or higher
+
jclass clazz;
FIND_AND_CHECK_CLASS("org/qtproject/qt5/android/accessibility/QtNativeAccessibility");
jclass appClass = static_cast<jclass>(env->NewGlobalRef(clazz));
if (env->RegisterNatives(appClass, methods, sizeof(methods) / sizeof(methods[0])) < 0) {
- __android_log_print(ANDROID_LOG_FATAL,"Qt", "RegisterNatives failed");
+ __android_log_print(ANDROID_LOG_FATAL,"Qt A11y", "RegisterNatives failed");
return false;
}
@@ -305,9 +311,14 @@ if (!clazz) { \
GET_AND_CHECK_STATIC_METHOD(m_setFocusableMethodID, nodeInfoClass, "setFocusable", "(Z)V");
GET_AND_CHECK_STATIC_METHOD(m_setFocusedMethodID, nodeInfoClass, "setFocused", "(Z)V");
GET_AND_CHECK_STATIC_METHOD(m_setScrollableMethodID, nodeInfoClass, "setScrollable", "(Z)V");
- GET_AND_CHECK_STATIC_METHOD(m_setTextSelectionMethodID, nodeInfoClass, "setTextSelection", "(II)V");
GET_AND_CHECK_STATIC_METHOD(m_setVisibleToUserMethodID, nodeInfoClass, "setVisibleToUser", "(Z)V");
+ if (QtAndroidPrivate::androidSdkVersion() >= 18) {
+ GET_AND_CHECK_STATIC_METHOD(m_setTextSelectionMethodID, nodeInfoClass, "setTextSelection", "(II)V");
+ }
+
return true;
}
}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/androidjniaccessibility.h b/src/plugins/platforms/android/androidjniaccessibility.h
index e708138c33..3ca89242fe 100644
--- a/src/plugins/platforms/android/androidjniaccessibility.h
+++ b/src/plugins/platforms/android/androidjniaccessibility.h
@@ -42,10 +42,15 @@
#ifndef ANDROIDJNIACCESSIBILITY_H
#define ANDROIDJNIACCESSIBILITY_H
#include <jni.h>
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_NAMESPACE
namespace QtAndroidAccessibility
{
bool registerNatives(JNIEnv *env);
}
+QT_END_NAMESPACE
+
#endif // ANDROIDJNIINPUT_H
diff --git a/src/plugins/platforms/android/androidjniclipboard.cpp b/src/plugins/platforms/android/androidjniclipboard.cpp
index 05270ac374..87bb08910d 100644
--- a/src/plugins/platforms/android/androidjniclipboard.cpp
+++ b/src/plugins/platforms/android/androidjniclipboard.cpp
@@ -42,6 +42,8 @@
#include "androidjniclipboard.h"
#include "androidjnimain.h"
+QT_BEGIN_NAMESPACE
+
using namespace QtAndroid;
namespace QtAndroidClipboard
{
@@ -118,3 +120,5 @@ namespace QtAndroidClipboard
return true;
}
}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/androidjniclipboard.h b/src/plugins/platforms/android/androidjniclipboard.h
index 15cd93202e..764ef908df 100644
--- a/src/plugins/platforms/android/androidjniclipboard.h
+++ b/src/plugins/platforms/android/androidjniclipboard.h
@@ -45,6 +45,8 @@
#include <jni.h>
#include <QString>
+QT_BEGIN_NAMESPACE
+
class QAndroidPlatformClipboard;
namespace QtAndroidClipboard
{
@@ -58,4 +60,6 @@ namespace QtAndroidClipboard
bool registerNatives(JNIEnv *env);
}
+QT_END_NAMESPACE
+
#endif // ANDROIDJNICLIPBOARD_H
diff --git a/src/plugins/platforms/android/androidjniinput.cpp b/src/plugins/platforms/android/androidjniinput.cpp
index 760da7a767..defc59abf0 100644
--- a/src/plugins/platforms/android/androidjniinput.cpp
+++ b/src/plugins/platforms/android/androidjniinput.cpp
@@ -49,6 +49,8 @@
#include <QDebug>
+QT_BEGIN_NAMESPACE
+
using namespace QtAndroid;
namespace QtAndroidInput
@@ -758,3 +760,5 @@ namespace QtAndroidInput
return true;
}
}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/androidjniinput.h b/src/plugins/platforms/android/androidjniinput.h
index a78c7519db..5a7357633c 100644
--- a/src/plugins/platforms/android/androidjniinput.h
+++ b/src/plugins/platforms/android/androidjniinput.h
@@ -42,6 +42,9 @@
#ifndef ANDROIDJNIINPUT_H
#define ANDROIDJNIINPUT_H
#include <jni.h>
+#include <QtCore/qglobal.h>
+
+QT_BEGIN_NAMESPACE
namespace QtAndroidInput
{
@@ -56,4 +59,6 @@ namespace QtAndroidInput
bool registerNatives(JNIEnv *env);
}
+QT_END_NAMESPACE
+
#endif // ANDROIDJNIINPUT_H
diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp
index d484a2faff..09c56f398c 100644
--- a/src/plugins/platforms/android/androidjnimain.cpp
+++ b/src/plugins/platforms/android/androidjnimain.cpp
@@ -76,6 +76,8 @@
Q_IMPORT_PLUGIN(QAndroidPlatformIntegrationPlugin)
+QT_BEGIN_NAMESPACE
+
static JavaVM *m_javaVM = NULL;
static jclass m_applicationClass = NULL;
static jobject m_classLoaderObject = NULL;
@@ -423,6 +425,7 @@ namespace QtAndroid
m_destroySurfaceMethodID,
surfaceId);
}
+
} // namespace QtAndroid
@@ -548,7 +551,7 @@ static void setSurface(JNIEnv *env, jobject /*thiz*/, jint id, jobject jSurface,
}
static void setDisplayMetrics(JNIEnv */*env*/, jclass /*clazz*/,
- jint /*widthPixels*/, jint /*heightPixels*/,
+ jint widthPixels, jint heightPixels,
jint desktopWidthPixels, jint desktopHeightPixels,
jdouble xdpi, jdouble ydpi, jdouble scaledDensity)
{
@@ -557,13 +560,17 @@ static void setDisplayMetrics(JNIEnv */*env*/, jclass /*clazz*/,
m_scaledDensity = scaledDensity;
if (!m_androidPlatformIntegration) {
- QAndroidPlatformIntegration::setDefaultDisplayMetrics(desktopWidthPixels,desktopHeightPixels,
- qRound(double(desktopWidthPixels) / xdpi * 25.4),
- qRound(double(desktopHeightPixels) / ydpi * 25.4));
+ QAndroidPlatformIntegration::setDefaultDisplayMetrics(desktopWidthPixels,
+ desktopHeightPixels,
+ qRound(double(desktopWidthPixels) / xdpi * 25.4),
+ qRound(double(desktopHeightPixels) / ydpi * 25.4),
+ widthPixels,
+ heightPixels);
} else {
m_androidPlatformIntegration->setDisplayMetrics(qRound(double(desktopWidthPixels) / xdpi * 25.4),
qRound(double(desktopHeightPixels) / ydpi * 25.4));
m_androidPlatformIntegration->setDesktopSize(desktopWidthPixels, desktopHeightPixels);
+ m_androidPlatformIntegration->setScreenSize(widthPixels, heightPixels);
}
}
@@ -743,17 +750,11 @@ static int registerNatives(JNIEnv *env)
return JNI_TRUE;
}
-jint androidApiLevel(JNIEnv *env)
-{
- jclass clazz;
- FIND_AND_CHECK_CLASS("android/os/Build$VERSION");
- jfieldID fieldId;
- GET_AND_CHECK_STATIC_FIELD(fieldId, clazz, "SDK_INT", "I");
- return env->GetStaticIntField(clazz, fieldId);
-}
+QT_END_NAMESPACE
Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void */*reserved*/)
{
+ QT_USE_NAMESPACE
typedef union {
JNIEnv *nativeEnvironment;
void *venv;
@@ -774,17 +775,12 @@ Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void */*reserved*/)
|| !QtAndroidInput::registerNatives(env)
|| !QtAndroidClipboard::registerNatives(env)
|| !QtAndroidMenu::registerNatives(env)
+ || !QtAndroidAccessibility::registerNatives(env)
|| !QtAndroidDialogHelpers::registerNatives(env)) {
__android_log_print(ANDROID_LOG_FATAL, "Qt", "registerNatives failed");
return -1;
}
- jint apiLevel = androidApiLevel(env);
- if (apiLevel >= 16 && !QtAndroidAccessibility::registerNatives(env)) {
- __android_log_print(ANDROID_LOG_FATAL, "Qt A11y", "registerNatives failed");
- return -1;
- }
-
m_javaVM = vm;
return JNI_VERSION_1_4;
}
diff --git a/src/plugins/platforms/android/androidjnimain.h b/src/plugins/platforms/android/androidjnimain.h
index c00b23fff3..29896529ca 100644
--- a/src/plugins/platforms/android/androidjnimain.h
+++ b/src/plugins/platforms/android/androidjnimain.h
@@ -50,6 +50,8 @@
#include <QImage>
+QT_BEGIN_NAMESPACE
+
class QRect;
class QPoint;
class QThread;
@@ -119,4 +121,7 @@ namespace QtAndroid
QString deviceName();
}
+
+QT_END_NAMESPACE
+
#endif // ANDROID_APP_H
diff --git a/src/plugins/platforms/android/androidjnimenu.cpp b/src/plugins/platforms/android/androidjnimenu.cpp
index dc2afe2b03..6a979b9255 100644
--- a/src/plugins/platforms/android/androidjnimenu.cpp
+++ b/src/plugins/platforms/android/androidjnimenu.cpp
@@ -50,6 +50,8 @@
#include <QQueue>
#include <QWindow>
+QT_BEGIN_NAMESPACE
+
using namespace QtAndroid;
namespace QtAndroidMenu
@@ -428,3 +430,5 @@ namespace QtAndroidMenu
return true;
}
}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/androidjnimenu.h b/src/plugins/platforms/android/androidjnimenu.h
index 7c5422f67b..2ae406901a 100644
--- a/src/plugins/platforms/android/androidjnimenu.h
+++ b/src/plugins/platforms/android/androidjnimenu.h
@@ -43,6 +43,9 @@
#define ANDROIDJNIMENU_H
#include <jni.h>
+#include <qglobal.h>
+
+QT_BEGIN_NAMESPACE
class QAndroidPlatformMenuBar;
class QAndroidPlatformMenu;
@@ -66,4 +69,6 @@ namespace QtAndroidMenu
bool registerNatives(JNIEnv *env);
}
+QT_END_NAMESPACE
+
#endif // ANDROIDJNIMENU_H
diff --git a/src/plugins/platforms/android/androidsurfaceclient.h b/src/plugins/platforms/android/androidsurfaceclient.h
index 254e47123b..94f16a8547 100644
--- a/src/plugins/platforms/android/androidsurfaceclient.h
+++ b/src/plugins/platforms/android/androidsurfaceclient.h
@@ -44,6 +44,8 @@
#include <QMutex>
#include <jni.h>
+QT_BEGIN_NAMESPACE
+
class AndroidSurfaceClient
{
public:
@@ -55,4 +57,6 @@ protected:
QMutex m_surfaceMutex;
};
+QT_END_NAMESPACE
+
#endif // ANDROIDSURFACECLIENT_H
diff --git a/src/plugins/platforms/android/qandroidassetsfileenginehandler.cpp b/src/plugins/platforms/android/qandroidassetsfileenginehandler.cpp
index 224a8ca9f7..70ea3d756f 100644
--- a/src/plugins/platforms/android/qandroidassetsfileenginehandler.cpp
+++ b/src/plugins/platforms/android/qandroidassetsfileenginehandler.cpp
@@ -45,6 +45,8 @@
#include <QCoreApplication>
#include <QVector>
+QT_BEGIN_NAMESPACE
+
typedef QVector<QString> FilesList;
struct AndroidAssetDir
@@ -394,3 +396,5 @@ QAbstractFileEngine * AndroidAssetsFileEngineHandler::create(const QString &file
}
return 0;
}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidassetsfileenginehandler.h b/src/plugins/platforms/android/qandroidassetsfileenginehandler.h
index ac16ad7b79..a48a288ebc 100644
--- a/src/plugins/platforms/android/qandroidassetsfileenginehandler.h
+++ b/src/plugins/platforms/android/qandroidassetsfileenginehandler.h
@@ -49,6 +49,8 @@
#include <android/asset_manager.h>
+QT_BEGIN_NAMESPACE
+
struct AndroidAssetDir;
class AndroidAssetsFileEngineHandler: public QAbstractFileEngineHandler
{
@@ -67,4 +69,6 @@ private:
mutable bool m_hasTriedPrepopulatingCache;
};
+QT_END_NAMESPACE
+
#endif // QANDROIDASSETSFILEENGINEHANDLER_H
diff --git a/src/plugins/platforms/android/qandroidplatformdialoghelpers.cpp b/src/plugins/platforms/android/qandroidplatformdialoghelpers.cpp
index 897feb5802..6e4b6d8255 100644
--- a/src/plugins/platforms/android/qandroidplatformdialoghelpers.cpp
+++ b/src/plugins/platforms/android/qandroidplatformdialoghelpers.cpp
@@ -47,6 +47,8 @@
#include <private/qguiapplication_p.h>
#include <qpa/qplatformtheme.h>
+QT_BEGIN_NAMESPACE
+
namespace QtAndroidDialogHelpers {
static jclass g_messageDialogHelperClass = 0;
@@ -172,3 +174,5 @@ bool registerNatives(JNIEnv *env)
return true;
}
}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidplatformdialoghelpers.h b/src/plugins/platforms/android/qandroidplatformdialoghelpers.h
index 88ec91d936..7cbe21a9f4 100644
--- a/src/plugins/platforms/android/qandroidplatformdialoghelpers.h
+++ b/src/plugins/platforms/android/qandroidplatformdialoghelpers.h
@@ -46,6 +46,8 @@
#include <QEventLoop>
#include <private/qjni_p.h>
+QT_BEGIN_NAMESPACE
+
namespace QtAndroidDialogHelpers {
class QAndroidPlatformMessageDialogHelper: public QPlatformMessageDialogHelper
@@ -74,4 +76,6 @@ bool registerNatives(JNIEnv *env);
}
+QT_END_NAMESPACE
+
#endif // QANDROIDPLATFORMDIALOGHELPERS_H
diff --git a/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp b/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp
index 935caed467..fd14f812a0 100644
--- a/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp
+++ b/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp
@@ -43,6 +43,8 @@
#include "qandroidplatformfontdatabase.h"
+QT_BEGIN_NAMESPACE
+
QString QAndroidPlatformFontDatabase::fontDir() const
{
return QLatin1String("/system/fonts");
@@ -87,3 +89,5 @@ QStringList QAndroidPlatformFontDatabase::fallbacksForFamily(const QString &fami
return QString(qgetenv("QT_ANDROID_FONTS")).split(";") + m_fallbacks[script];
}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidplatformfontdatabase.h b/src/plugins/platforms/android/qandroidplatformfontdatabase.h
index cdd3cf1674..0e961f8ae8 100644
--- a/src/plugins/platforms/android/qandroidplatformfontdatabase.h
+++ b/src/plugins/platforms/android/qandroidplatformfontdatabase.h
@@ -44,6 +44,8 @@
#include <QtPlatformSupport/private/qbasicfontdatabase_p.h>
+QT_BEGIN_NAMESPACE
+
class QAndroidPlatformFontDatabase: public QBasicFontDatabase
{
public:
@@ -58,4 +60,6 @@ private:
QHash<QChar::Script, QStringList> m_fallbacks;
};
+QT_END_NAMESPACE
+
#endif // QANDROIDPLATFORMFONTDATABASE_H
diff --git a/src/plugins/platforms/android/qandroidplatformintegration.cpp b/src/plugins/platforms/android/qandroidplatformintegration.cpp
index 213b1bb7e6..d6d7d3b173 100644
--- a/src/plugins/platforms/android/qandroidplatformintegration.cpp
+++ b/src/plugins/platforms/android/qandroidplatformintegration.cpp
@@ -74,6 +74,8 @@ QT_BEGIN_NAMESPACE
int QAndroidPlatformIntegration::m_defaultGeometryWidth = 320;
int QAndroidPlatformIntegration::m_defaultGeometryHeight = 455;
+int QAndroidPlatformIntegration::m_defaultScreenWidth = 320;
+int QAndroidPlatformIntegration::m_defaultScreenHeight = 455;
int QAndroidPlatformIntegration::m_defaultPhysicalSizeWidth = 50;
int QAndroidPlatformIntegration::m_defaultPhysicalSizeHeight = 71;
@@ -121,7 +123,8 @@ QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList &para
m_primaryScreen = new QAndroidPlatformScreen();
screenAdded(m_primaryScreen);
m_primaryScreen->setPhysicalSize(QSize(m_defaultPhysicalSizeWidth, m_defaultPhysicalSizeHeight));
- m_primaryScreen->setGeometry(QRect(0, 0, m_defaultGeometryWidth, m_defaultGeometryHeight));
+ m_primaryScreen->setAvailableGeometry(QRect(0, 0, m_defaultGeometryWidth, m_defaultGeometryHeight));
+ m_primaryScreen->setSize(QSize(m_defaultScreenWidth, m_defaultScreenHeight));
m_mainThread = QThread::currentThread();
QtAndroid::setAndroidPlatformIntegration(this);
@@ -312,12 +315,14 @@ QPlatformTheme *QAndroidPlatformIntegration::createPlatformTheme(const QString &
return 0;
}
-void QAndroidPlatformIntegration::setDefaultDisplayMetrics(int gw, int gh, int sw, int sh)
+void QAndroidPlatformIntegration::setDefaultDisplayMetrics(int gw, int gh, int sw, int sh, int screenWidth, int screenHeight)
{
m_defaultGeometryWidth = gw;
m_defaultGeometryHeight = gh;
m_defaultPhysicalSizeWidth = sw;
m_defaultPhysicalSizeHeight = sh;
+ m_defaultScreenWidth = screenWidth;
+ m_defaultScreenHeight = screenHeight;
}
void QAndroidPlatformIntegration::setDefaultDesktopSize(int gw, int gh)
@@ -345,7 +350,7 @@ QPlatformAccessibility *QAndroidPlatformIntegration::accessibility() const
void QAndroidPlatformIntegration::setDesktopSize(int width, int height)
{
if (m_primaryScreen)
- QMetaObject::invokeMethod(m_primaryScreen, "setGeometry", Qt::AutoConnection, Q_ARG(QRect, QRect(0,0,width, height)));
+ QMetaObject::invokeMethod(m_primaryScreen, "setAvailableGeometry", Qt::AutoConnection, Q_ARG(QRect, QRect(0,0,width, height)));
}
void QAndroidPlatformIntegration::setDisplayMetrics(int width, int height)
@@ -354,4 +359,10 @@ void QAndroidPlatformIntegration::setDisplayMetrics(int width, int height)
QMetaObject::invokeMethod(m_primaryScreen, "setPhysicalSize", Qt::AutoConnection, Q_ARG(QSize, QSize(width, height)));
}
+void QAndroidPlatformIntegration::setScreenSize(int width, int height)
+{
+ if (m_primaryScreen)
+ QMetaObject::invokeMethod(m_primaryScreen, "setSize", Qt::AutoConnection, Q_ARG(QSize, QSize(width, height)));
+}
+
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidplatformintegration.h b/src/plugins/platforms/android/qandroidplatformintegration.h
index f8fa1a91dd..ce31516ace 100644
--- a/src/plugins/platforms/android/qandroidplatformintegration.h
+++ b/src/plugins/platforms/android/qandroidplatformintegration.h
@@ -86,6 +86,7 @@ public:
virtual void setDesktopSize(int width, int height);
virtual void setDisplayMetrics(int width, int height);
+ void setScreenSize(int width, int height);
bool isVirtualDesktop() { return true; }
QPlatformFontDatabase *fontDatabase() const;
@@ -108,7 +109,7 @@ public:
QStringList themeNames() const;
QPlatformTheme *createPlatformTheme(const QString &name) const;
- static void setDefaultDisplayMetrics(int gw, int gh, int sw, int sh);
+ static void setDefaultDisplayMetrics(int gw, int gh, int sw, int sh, int width, int height);
static void setDefaultDesktopSize(int gw, int gh);
static void setScreenOrientation(Qt::ScreenOrientation currentOrientation,
Qt::ScreenOrientation nativeOrientation);
@@ -135,6 +136,8 @@ private:
static int m_defaultGeometryHeight;
static int m_defaultPhysicalSizeWidth;
static int m_defaultPhysicalSizeHeight;
+ static int m_defaultScreenWidth;
+ static int m_defaultScreenHeight;
static Qt::ScreenOrientation m_orientation;
static Qt::ScreenOrientation m_nativeOrientation;
diff --git a/src/plugins/platforms/android/qandroidplatformmenu.cpp b/src/plugins/platforms/android/qandroidplatformmenu.cpp
index 1ecabb25e2..b602f85cd9 100644
--- a/src/plugins/platforms/android/qandroidplatformmenu.cpp
+++ b/src/plugins/platforms/android/qandroidplatformmenu.cpp
@@ -43,6 +43,8 @@
#include "qandroidplatformmenuitem.h"
#include "androidjnimenu.h"
+QT_BEGIN_NAMESPACE
+
QAndroidPlatformMenu::QAndroidPlatformMenu()
{
m_tag = reinterpret_cast<quintptr>(this); // QMenu will overwrite this later, but we need a unique ID for QtQuick
@@ -175,3 +177,5 @@ QMutex *QAndroidPlatformMenu::menuItemsMutex()
{
return &m_menuItemsMutex;
}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidplatformmenu.h b/src/plugins/platforms/android/qandroidplatformmenu.h
index 305b64168a..7858ca36ae 100644
--- a/src/plugins/platforms/android/qandroidplatformmenu.h
+++ b/src/plugins/platforms/android/qandroidplatformmenu.h
@@ -46,6 +46,8 @@
#include <qvector.h>
#include <qmutex.h>
+QT_BEGIN_NAMESPACE
+
class QAndroidPlatformMenuItem;
class QAndroidPlatformMenu: public QPlatformMenu
{
@@ -89,4 +91,6 @@ private:
QMutex m_menuItemsMutex;
};
+QT_END_NAMESPACE
+
#endif // QANDROIDPLATFORMMENU_H
diff --git a/src/plugins/platforms/android/qandroidplatformmenubar.cpp b/src/plugins/platforms/android/qandroidplatformmenubar.cpp
index 134062fb32..2d457296c5 100644
--- a/src/plugins/platforms/android/qandroidplatformmenubar.cpp
+++ b/src/plugins/platforms/android/qandroidplatformmenubar.cpp
@@ -43,6 +43,7 @@
#include "qandroidplatformmenu.h"
#include "androidjnimenu.h"
+QT_BEGIN_NAMESPACE
QAndroidPlatformMenuBar::QAndroidPlatformMenuBar()
{
@@ -109,3 +110,5 @@ QMutex *QAndroidPlatformMenuBar::menusListMutex()
{
return &m_menusListMutex;
}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidplatformmenubar.h b/src/plugins/platforms/android/qandroidplatformmenubar.h
index 56915335c2..52882b6922 100644
--- a/src/plugins/platforms/android/qandroidplatformmenubar.h
+++ b/src/plugins/platforms/android/qandroidplatformmenubar.h
@@ -46,6 +46,8 @@
#include <qvector.h>
#include <qmutex.h>
+QT_BEGIN_NAMESPACE
+
class QAndroidPlatformMenu;
class QAndroidPlatformMenuBar: public QPlatformMenuBar
{
@@ -71,4 +73,6 @@ private:
QMutex m_menusListMutex;
};
+QT_END_NAMESPACE
+
#endif // QANDROIDPLATFORMMENUBAR_H
diff --git a/src/plugins/platforms/android/qandroidplatformmenuitem.cpp b/src/plugins/platforms/android/qandroidplatformmenuitem.cpp
index bd37834d2a..4e19ec2939 100644
--- a/src/plugins/platforms/android/qandroidplatformmenuitem.cpp
+++ b/src/plugins/platforms/android/qandroidplatformmenuitem.cpp
@@ -42,6 +42,8 @@
#include "qandroidplatformmenuitem.h"
#include "qandroidplatformmenu.h"
+QT_BEGIN_NAMESPACE
+
QAndroidPlatformMenuItem::QAndroidPlatformMenuItem()
{
m_tag = reinterpret_cast<quintptr>(this); // QMenu will overwrite this later, but we need a unique ID for QtQuick
@@ -178,3 +180,5 @@ bool QAndroidPlatformMenuItem::isEnabled() const
{
return m_isEnabled;
}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidplatformmenuitem.h b/src/plugins/platforms/android/qandroidplatformmenuitem.h
index 5861e8e195..40c3ab2761 100644
--- a/src/plugins/platforms/android/qandroidplatformmenuitem.h
+++ b/src/plugins/platforms/android/qandroidplatformmenuitem.h
@@ -43,6 +43,8 @@
#define QANDROIDPLATFORMMENUITEM_H
#include <qpa/qplatformmenu.h>
+QT_BEGIN_NAMESPACE
+
class QAndroidPlatformMenu;
class QAndroidPlatformMenuItem: public QPlatformMenuItem
@@ -96,4 +98,6 @@ private:
bool m_isEnabled;
};
+QT_END_NAMESPACE
+
#endif // QANDROIDPLATFORMMENUITEM_H
diff --git a/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp b/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp
index 53047585cf..3a3ea71562 100644
--- a/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp
+++ b/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp
@@ -74,6 +74,7 @@ bool QAndroidPlatformOpenGLContext::needsFBOReadBackWorkaroud()
needsWorkaround =
qstrcmp(rendererString, "Mali-400 MP") == 0
|| qstrcmp(rendererString, "Adreno (TM) 200") == 0
+ || qstrcmp(rendererString, "Adreno (TM) 205") == 0
|| qstrcmp(rendererString, "GC1000 core") == 0;
set = true;
}
diff --git a/src/plugins/platforms/android/qandroidplatformscreen.cpp b/src/plugins/platforms/android/qandroidplatformscreen.cpp
index e67a039ff4..af184cde02 100644
--- a/src/plugins/platforms/android/qandroidplatformscreen.cpp
+++ b/src/plugins/platforms/android/qandroidplatformscreen.cpp
@@ -86,7 +86,8 @@ private:
QAndroidPlatformScreen::QAndroidPlatformScreen():QObject(),QPlatformScreen()
{
- m_geometry = QRect(0, 0, QAndroidPlatformIntegration::m_defaultGeometryWidth, QAndroidPlatformIntegration::m_defaultGeometryHeight);
+ m_availableGeometry = QRect(0, 0, QAndroidPlatformIntegration::m_defaultGeometryWidth, QAndroidPlatformIntegration::m_defaultGeometryHeight);
+ m_size = QSize(QAndroidPlatformIntegration::m_defaultScreenWidth, QAndroidPlatformIntegration::m_defaultScreenHeight);
// Raster only apps should set QT_ANDROID_RASTER_IMAGE_DEPTH to 16
// is way much faster than 32
if (qgetenv("QT_ANDROID_RASTER_IMAGE_DEPTH").toInt() == 16) {
@@ -204,7 +205,7 @@ void QAndroidPlatformScreen::scheduleUpdate()
void QAndroidPlatformScreen::setDirty(const QRect &rect)
{
- QRect intersection = rect.intersected(m_geometry);
+ QRect intersection = rect.intersected(m_availableGeometry);
m_dirtyRect |= intersection;
scheduleUpdate();
}
@@ -214,15 +215,21 @@ void QAndroidPlatformScreen::setPhysicalSize(const QSize &size)
m_physicalSize = size;
}
-void QAndroidPlatformScreen::setGeometry(const QRect &rect)
+void QAndroidPlatformScreen::setSize(const QSize &size)
+{
+ m_size = size;
+ QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), geometry());
+}
+
+void QAndroidPlatformScreen::setAvailableGeometry(const QRect &rect)
{
QMutexLocker lock(&m_surfaceMutex);
- if (m_geometry == rect)
+ if (m_availableGeometry == rect)
return;
- QRect oldGeometry = m_geometry;
+ QRect oldGeometry = m_availableGeometry;
- m_geometry = rect;
+ m_availableGeometry = rect;
QWindowSystemInterface::handleScreenGeometryChange(QPlatformScreen::screen(), geometry());
QWindowSystemInterface::handleScreenAvailableGeometryChange(QPlatformScreen::screen(), availableGeometry());
resizeMaximizedWindows();
@@ -231,9 +238,11 @@ void QAndroidPlatformScreen::setGeometry(const QRect &rect)
QList<QWindow *> windows = QGuiApplication::allWindows();
for (int i = 0; i < windows.size(); ++i) {
QWindow *w = windows.at(i);
- QRect geometry = w->handle()->geometry();
- if (geometry.width() > 0 && geometry.height() > 0)
- QWindowSystemInterface::handleExposeEvent(w, QRegion(geometry));
+ if (w->handle()) {
+ QRect geometry = w->handle()->geometry();
+ if (geometry.width() > 0 && geometry.height() > 0)
+ QWindowSystemInterface::handleExposeEvent(w, QRegion(geometry));
+ }
}
}
@@ -271,7 +280,7 @@ void QAndroidPlatformScreen::doRedraw()
QMutexLocker lock(&m_surfaceMutex);
if (m_id == -1 && m_rasterSurfaces) {
- m_id = QtAndroid::createSurface(this, m_geometry, true, m_depth);
+ m_id = QtAndroid::createSurface(this, m_availableGeometry, true, m_depth);
m_surfaceWaitCondition.wait(&m_surfaceMutex);
}
diff --git a/src/plugins/platforms/android/qandroidplatformscreen.h b/src/plugins/platforms/android/qandroidplatformscreen.h
index 96a91fbf06..cd9cf2ca71 100644
--- a/src/plugins/platforms/android/qandroidplatformscreen.h
+++ b/src/plugins/platforms/android/qandroidplatformscreen.h
@@ -66,7 +66,8 @@ public:
QAndroidPlatformScreen();
~QAndroidPlatformScreen();
- QRect geometry() const { return m_geometry; }
+ QRect geometry() const { return QRect(QPoint(), m_size); }
+ QRect availableGeometry() const { return m_availableGeometry; }
int depth() const { return m_depth; }
QImage::Format format() const { return m_format; }
QSizeF physicalSize() const { return m_physicalSize; }
@@ -87,7 +88,8 @@ public:
public slots:
void setDirty(const QRect &rect);
void setPhysicalSize(const QSize &size);
- void setGeometry(const QRect &rect);
+ void setAvailableGeometry(const QRect &rect);
+ void setSize(const QSize &size);
protected:
typedef QList<QAndroidPlatformWindow *> WindowStackType;
@@ -95,7 +97,7 @@ protected:
QRect m_dirtyRect;
QTimer m_redrawTimer;
- QRect m_geometry;
+ QRect m_availableGeometry;
int m_depth;
QImage::Format m_format;
QSizeF m_physicalSize;
@@ -114,6 +116,7 @@ private:
QAtomicInt m_rasterSurfaces = 0;
ANativeWindow* m_nativeSurface = nullptr;
QWaitCondition m_surfaceWaitCondition;
+ QSize m_size;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidplatformservices.cpp b/src/plugins/platforms/android/qandroidplatformservices.cpp
index 0df882f1f0..02fe29e576 100644
--- a/src/plugins/platforms/android/qandroidplatformservices.cpp
+++ b/src/plugins/platforms/android/qandroidplatformservices.cpp
@@ -44,6 +44,8 @@
#include <QDir>
#include <QDebug>
+QT_BEGIN_NAMESPACE
+
QAndroidPlatformServices::QAndroidPlatformServices()
{
QtAndroid::AttachedJNIEnv env;
@@ -77,3 +79,5 @@ QByteArray QAndroidPlatformServices::desktopEnvironment() const
{
return QByteArray("Android");
}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidplatformservices.h b/src/plugins/platforms/android/qandroidplatformservices.h
index 8368b19043..08d7773ca4 100644
--- a/src/plugins/platforms/android/qandroidplatformservices.h
+++ b/src/plugins/platforms/android/qandroidplatformservices.h
@@ -46,6 +46,8 @@
#include "androidjnimain.h"
#include <jni.h>
+QT_BEGIN_NAMESPACE
+
class QAndroidPlatformServices: public QPlatformServices
{
public:
@@ -58,4 +60,6 @@ private:
};
+QT_END_NAMESPACE
+
#endif // ANDROIDPLATFORMDESKTOPSERVICE_H
diff --git a/src/plugins/platforms/android/qandroidplatformtheme.cpp b/src/plugins/platforms/android/qandroidplatformtheme.cpp
index 94e58eaeb6..1c9be189c8 100644
--- a/src/plugins/platforms/android/qandroidplatformtheme.cpp
+++ b/src/plugins/platforms/android/qandroidplatformtheme.cpp
@@ -50,6 +50,8 @@
#include <private/qguiapplication_p.h>
#include <qandroidplatformintegration.h>
+QT_BEGIN_NAMESPACE
+
QAndroidPlatformTheme::QAndroidPlatformTheme(QAndroidPlatformNativeInterface *androidPlatformNativeInterface)
{
m_androidPlatformNativeInterface = androidPlatformNativeInterface;
@@ -240,3 +242,5 @@ QPlatformDialogHelper *QAndroidPlatformTheme::createPlatformDialogHelper(QPlatfo
return 0;
}
}
+
+QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidplatformtheme.h b/src/plugins/platforms/android/qandroidplatformtheme.h
index fecd7ca8e9..c37c9986c6 100644
--- a/src/plugins/platforms/android/qandroidplatformtheme.h
+++ b/src/plugins/platforms/android/qandroidplatformtheme.h
@@ -45,6 +45,8 @@
#include <qpa/qplatformtheme.h>
#include <QtGui/qpalette.h>
+QT_BEGIN_NAMESPACE
+
class QAndroidPlatformNativeInterface;
class QAndroidPlatformTheme: public QPlatformTheme
{
@@ -66,4 +68,6 @@ private:
QPalette m_defaultPalette;
};
+QT_END_NAMESPACE
+
#endif // QANDROIDPLATFORMTHEME_H
diff --git a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
index a2f9f8c984..2f5355b180 100644
--- a/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
+++ b/src/plugins/platforms/cocoa/qcocoaapplicationdelegate.mm
@@ -223,7 +223,14 @@ static void cleanupCocoaApplicationDelegate()
// events while the event loop is still running.
const QWindowList topLevels = QGuiApplication::topLevelWindows();
for (int i = 0; i < topLevels.size(); ++i) {
- QWindowSystemInterface::handleCloseEvent(topLevels.at(i));
+ QWindow *topLevelWindow = topLevels.at(i);
+ // Widgets have alreay received a CloseEvent from the QApplication
+ // QCloseEvent handler. (see canQuit above). Prevent running the
+ // CloseEvent logic twice, call close() directly.
+ if (topLevelWindow->inherits("QWidgetWindow"))
+ topLevelWindow->close();
+ else
+ QWindowSystemInterface::handleCloseEvent(topLevelWindow);
}
QWindowSystemInterface::flushWindowSystemEvents();
diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
index e7f8992c6d..4328487f63 100644
--- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
+++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
@@ -870,6 +870,9 @@ void QCocoaEventDispatcherPrivate::processPostedEvents()
return;
}
+ if (cleanupModalSessionsNeeded && currentExecIsNSAppRun)
+ cleanupModalSessions();
+
if (processEventsCalled > 0 && interrupt) {
if (currentExecIsNSAppRun) {
// The event dispatcher has been interrupted. But since
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index d04dc958e1..4be49ed68f 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -158,23 +158,42 @@ qreal QCocoaScreen::devicePixelRatio() const
QWindow *QCocoaScreen::topLevelAt(const QPoint &point) const
{
- // Get a z-ordered list of windows. Iterate through it until
- // we find a (Qt) window which contains the point.
- for (NSWindow *nsWindow in [NSApp orderedWindows]) {
- if (![nsWindow isKindOfClass:[QNSWindow class]])
+ NSPoint screenPoint = qt_mac_flipPoint(point);
+
+ // Search (hit test) for the top-level window. [NSWidow windowNumberAtPoint:
+ // belowWindowWithWindowNumber] may return windows that are not interesting
+ // to Qt. The search iterates until a suitable window or no window is found.
+ NSInteger topWindowNumber = 0;
+ QWindow *window = 0;
+ do {
+ // Get the top-most window, below any previously rejected window.
+ topWindowNumber = [NSWindow windowNumberAtPoint:screenPoint
+ belowWindowWithWindowNumber:topWindowNumber];
+
+ // Continue the search if the window does not belong to this process.
+ NSWindow *nsWindow = [NSApp windowWithWindowNumber:topWindowNumber];
+ if (nsWindow == 0)
continue;
- QNSWindow *qnsWindow = static_cast<QNSWindow *>(nsWindow);
- QCocoaWindow *cocoaWindow = qnsWindow.helper.platformWindow;
+
+ // Continue the search if the window does not belong to Qt.
+ if (![nsWindow conformsToProtocol:@protocol(QNSWindowProtocol)])
+ continue;
+
+ id<QNSWindowProtocol> proto = static_cast<id<QNSWindowProtocol> >(nsWindow);
+ QCocoaWindow *cocoaWindow = proto.helper.platformWindow;
if (!cocoaWindow)
continue;
- QWindow *window = cocoaWindow->window();
+ window = cocoaWindow->window();
+
+ // Continue the search if the window is not a top-level window.
if (!window->isTopLevel())
continue;
- if (window->geometry().contains(point))
- return window;
- }
- return QPlatformScreen::topLevelAt(point);
+ // Stop searching. The current window is the correct window.
+ break;
+ } while (topWindowNumber > 0);
+
+ return window;
}
extern CGContextRef qt_mac_cg_context(const QPaintDevice *pdev);
diff --git a/src/plugins/platforms/cocoa/qnsview.h b/src/plugins/platforms/cocoa/qnsview.h
index a0db46bf4b..53eee4a95d 100644
--- a/src/plugins/platforms/cocoa/qnsview.h
+++ b/src/plugins/platforms/cocoa/qnsview.h
@@ -54,6 +54,8 @@ class QCocoaBackingStore;
class QCocoaGLContext;
QT_END_NAMESPACE
+Q_FORWARD_DECLARE_OBJC_CLASS(QNSViewMouseMoveHelper);
+
@interface QNSView : NSView <NSTextInputClient> {
QCocoaBackingStore* m_backingStore;
QPoint m_backingStoreOffset;
@@ -74,6 +76,7 @@ QT_END_NAMESPACE
bool m_shouldSetGLContextinDrawRect;
#endif
NSString *m_inputSource;
+ QNSViewMouseMoveHelper *m_mouseMoveHelper;
}
- (id)init;
@@ -106,9 +109,10 @@ QT_END_NAMESPACE
- (void)mouseDown:(NSEvent *)theEvent;
- (void)mouseDragged:(NSEvent *)theEvent;
- (void)mouseUp:(NSEvent *)theEvent;
-- (void)mouseMoved:(NSEvent *)theEvent;
-- (void)mouseEntered:(NSEvent *)theEvent;
-- (void)mouseExited:(NSEvent *)theEvent;
+- (void)mouseMovedImpl:(NSEvent *)theEvent;
+- (void)mouseEnteredImpl:(NSEvent *)theEvent;
+- (void)mouseExitedImpl:(NSEvent *)theEvent;
+- (void)cursorUpdateImpl:(NSEvent *)theEvent;
- (void)rightMouseDown:(NSEvent *)theEvent;
- (void)rightMouseDragged:(NSEvent *)theEvent;
- (void)rightMouseUp:(NSEvent *)theEvent;
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index b023edf271..4a562f8a4e 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -77,6 +77,53 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
- (CGFloat)deviceDeltaZ;
@end
+@interface QNSViewMouseMoveHelper : NSObject
+{
+ QNSView *view;
+}
+
+- (id)initWithView:(QNSView *)theView;
+
+- (void)mouseMoved:(NSEvent *)theEvent;
+- (void)mouseEntered:(NSEvent *)theEvent;
+- (void)mouseExited:(NSEvent *)theEvent;
+- (void)cursorUpdate:(NSEvent *)theEvent;
+
+@end
+
+@implementation QNSViewMouseMoveHelper
+
+- (id)initWithView:(QNSView *)theView
+{
+ self = [super init];
+ if (self) {
+ view = theView;
+ }
+ return self;
+}
+
+- (void)mouseMoved:(NSEvent *)theEvent
+{
+ [view mouseMovedImpl:theEvent];
+}
+
+- (void)mouseEntered:(NSEvent *)theEvent
+{
+ [view mouseEnteredImpl:theEvent];
+}
+
+- (void)mouseExited:(NSEvent *)theEvent
+{
+ [view mouseExitedImpl:theEvent];
+}
+
+- (void)cursorUpdate:(NSEvent *)theEvent
+{
+ [view cursorUpdateImpl:theEvent];
+}
+
+@end
+
@implementation QNSView
+ (void)initialize
@@ -104,6 +151,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
currentCustomDragTypes = 0;
m_sendUpAsRightButton = false;
m_inputSource = 0;
+ m_mouseMoveHelper = [[QNSViewMouseMoveHelper alloc] initWithView:self];
if (!touchDevice) {
touchDevice = new QTouchDevice;
@@ -123,6 +171,7 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
m_subscribesForGlobalFrameNotifications = false;
[m_inputSource release];
[[NSNotificationCenter defaultCenter] removeObserver:self];
+ [m_mouseMoveHelper release];
delete currentCustomDragTypes;
@@ -761,13 +810,13 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
| NSTrackingInVisibleRect | NSTrackingMouseMoved | NSTrackingCursorUpdate;
NSTrackingArea *ta = [[[NSTrackingArea alloc] initWithRect:[self frame]
options:trackingOptions
- owner:self
+ owner:m_mouseMoveHelper
userInfo:nil]
autorelease];
[self addTrackingArea:ta];
}
--(void)cursorUpdate:(NSEvent *)theEvent
+-(void)cursorUpdateImpl:(NSEvent *)theEvent
{
Q_UNUSED(theEvent)
// Set the cursor manually if there is no NSWindow.
@@ -784,10 +833,10 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
[self addCursorRect:[self visibleRect] cursor:m_platformWindow->m_windowCursor];
}
-- (void)mouseMoved:(NSEvent *)theEvent
+- (void)mouseMovedImpl:(NSEvent *)theEvent
{
if (m_window->flags() & Qt::WindowTransparentForInput)
- return [super mouseMoved:theEvent];
+ return;
QPointF windowPoint;
QPointF screenPoint;
@@ -814,12 +863,13 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
[self handleMouseEvent: theEvent];
}
-- (void)mouseEntered:(NSEvent *)theEvent
+- (void)mouseEnteredImpl:(NSEvent *)theEvent
{
+ Q_UNUSED(theEvent)
m_platformWindow->m_windowUnderMouse = true;
if (m_window->flags() & Qt::WindowTransparentForInput)
- return [super mouseEntered:theEvent];
+ return;
// Top-level windows generate enter events for sub-windows.
if (!m_platformWindow->m_nsWindow)
@@ -832,13 +882,13 @@ static NSString *_q_NSWindowDidChangeOcclusionStateNotification = nil;
QWindowSystemInterface::handleEnterEvent(m_platformWindow->m_enterLeaveTargetWindow, windowPoint, screenPoint);
}
-- (void)mouseExited:(NSEvent *)theEvent
+- (void)mouseExitedImpl:(NSEvent *)theEvent
{
+ Q_UNUSED(theEvent);
m_platformWindow->m_windowUnderMouse = false;
if (m_window->flags() & Qt::WindowTransparentForInput)
- return [super mouseExited:theEvent];
- Q_UNUSED(theEvent);
+ return;
// Top-level windows generate leave events for sub-windows.
if (!m_platformWindow->m_nsWindow)
@@ -1324,7 +1374,7 @@ static QTabletEvent::TabletDevice wacomTabletDevice(NSEvent *theEvent)
QChar ch = QChar::ReplacementCharacter;
int keyCode = Qt::Key_unknown;
if ([characters length] != 0) {
- if ((modifiers & Qt::MetaModifier) && ([charactersIgnoringModifiers length] != 0))
+ if (((modifiers & Qt::MetaModifier) || (modifiers & Qt::AltModifier)) && ([charactersIgnoringModifiers length] != 0))
ch = QChar([charactersIgnoringModifiers characterAtIndex:0]);
else
ch = QChar([characters characterAtIndex:0]);
diff --git a/src/plugins/platforms/directfb/main.cpp b/src/plugins/platforms/directfb/main.cpp
index 423e33efd5..b0354c236d 100644
--- a/src/plugins/platforms/directfb/main.cpp
+++ b/src/plugins/platforms/directfb/main.cpp
@@ -75,7 +75,8 @@ QPlatformIntegration * QDirectFbIntegrationPlugin::create(const QString& system,
if (!integration)
return 0;
- integration->initialize();
+ integration->connectToDirectFb();
+
return integration;
}
diff --git a/src/plugins/platforms/directfb/qdirectfbintegration.cpp b/src/plugins/platforms/directfb/qdirectfbintegration.cpp
index 7ca7da8bcd..3d1b79ef38 100644
--- a/src/plugins/platforms/directfb/qdirectfbintegration.cpp
+++ b/src/plugins/platforms/directfb/qdirectfbintegration.cpp
@@ -64,7 +64,7 @@ QDirectFbIntegration::QDirectFbIntegration()
{
}
-void QDirectFbIntegration::initialize()
+void QDirectFbIntegration::connectToDirectFb()
{
initializeDirectFB();
initializeScreen();
diff --git a/src/plugins/platforms/directfb/qdirectfbintegration.h b/src/plugins/platforms/directfb/qdirectfbintegration.h
index 5822202eea..b49600bed9 100644
--- a/src/plugins/platforms/directfb/qdirectfbintegration.h
+++ b/src/plugins/platforms/directfb/qdirectfbintegration.h
@@ -60,7 +60,7 @@ public:
QDirectFbIntegration();
~QDirectFbIntegration();
- void initialize();
+ void connectToDirectFb();
QPlatformPixmap *createPlatformPixmap(QPlatformPixmap::PixelType type) const;
QPlatformWindow *createPlatformWindow(QWindow *window) const;
diff --git a/src/plugins/platforms/eglfs/qeglfswindow.h b/src/plugins/platforms/eglfs/qeglfswindow.h
index f3fd06037e..4403e3c28e 100644
--- a/src/plugins/platforms/eglfs/qeglfswindow.h
+++ b/src/plugins/platforms/eglfs/qeglfswindow.h
@@ -66,6 +66,8 @@ public:
void lower() Q_DECL_OVERRIDE;
void propagateSizeHints() Q_DECL_OVERRIDE { }
+ void setOpacity(qreal) Q_DECL_OVERRIDE { }
+ void setMask(const QRegion &) Q_DECL_OVERRIDE { }
bool setKeyboardGrabEnabled(bool) Q_DECL_OVERRIDE { return false; }
bool setMouseGrabEnabled(bool) Q_DECL_OVERRIDE { return false; }
diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm
index 8be3846e06..d109d53168 100644
--- a/src/plugins/platforms/ios/qiosinputcontext.mm
+++ b/src/plugins/platforms/ios/qiosinputcontext.mm
@@ -54,7 +54,6 @@
QIOSInputContext *m_context;
BOOL m_keyboardVisible;
BOOL m_keyboardVisibleAndDocked;
- BOOL m_ignoreKeyboardChanges;
BOOL m_touchPressWhileKeyboardVisible;
BOOL m_keyboardHiddenByGesture;
QRectF m_keyboardRect;
@@ -74,7 +73,6 @@
m_context = context;
m_keyboardVisible = NO;
m_keyboardVisibleAndDocked = NO;
- m_ignoreKeyboardChanges = NO;
m_touchPressWhileKeyboardVisible = NO;
m_keyboardHiddenByGesture = NO;
m_duration = 0;
@@ -160,7 +158,7 @@
- (void) keyboardWillShow:(NSNotification *)notification
{
- if (m_ignoreKeyboardChanges)
+ if ([QUIView inUpdateKeyboardLayout])
return;
// Note that UIKeyboardWillShowNotification is only sendt when the keyboard is docked.
m_keyboardVisibleAndDocked = YES;
@@ -175,7 +173,7 @@
- (void) keyboardWillHide:(NSNotification *)notification
{
- if (m_ignoreKeyboardChanges)
+ if ([QUIView inUpdateKeyboardLayout])
return;
// Note that UIKeyboardWillHideNotification is also sendt when the keyboard is undocked.
m_keyboardVisibleAndDocked = NO;
@@ -407,11 +405,7 @@ void QIOSInputContext::update(Qt::InputMethodQueries query)
void QIOSInputContext::reset()
{
- // Since the call to reset will cause a 'keyboardWillHide'
- // notification to be sendt, we block keyboard nofifications to avoid artifacts:
- m_keyboardListener->m_ignoreKeyboardChanges = true;
[m_focusView reset];
- m_keyboardListener->m_ignoreKeyboardChanges = false;
}
void QIOSInputContext::commit()
diff --git a/src/plugins/platforms/ios/quiview.h b/src/plugins/platforms/ios/quiview.h
index 91c4fc9dde..7c65037004 100644
--- a/src/plugins/platforms/ios/quiview.h
+++ b/src/plugins/platforms/ios/quiview.h
@@ -77,4 +77,5 @@
- (void)updateInputMethodWithQuery:(Qt::InputMethodQueries)query;
- (void)reset;
- (void)commit;
++ (bool)inUpdateKeyboardLayout;
@end
diff --git a/src/plugins/platforms/ios/quiview_textinput.mm b/src/plugins/platforms/ios/quiview_textinput.mm
index 03006b3f99..e65ac1cc46 100644
--- a/src/plugins/platforms/ios/quiview_textinput.mm
+++ b/src/plugins/platforms/ios/quiview_textinput.mm
@@ -45,9 +45,12 @@ class StaticVariables
{
public:
QInputMethodQueryEvent inputMethodQueryEvent;
+ bool inUpdateKeyboardLayout;
QTextCharFormat markedTextFormat;
- StaticVariables() : inputMethodQueryEvent(Qt::ImQueryInput)
+ StaticVariables()
+ : inputMethodQueryEvent(Qt::ImQueryInput)
+ , inUpdateKeyboardLayout(false)
{
// There seems to be no way to query how the preedit text
// should be drawn. So we need to hard-code the color.
@@ -152,6 +155,47 @@ Q_GLOBAL_STATIC(StaticVariables, staticVariables);
return [super resignFirstResponder];
}
++ (bool)inUpdateKeyboardLayout
+{
+ return staticVariables()->inUpdateKeyboardLayout;
+}
+
+- (void)updateKeyboardLayout
+{
+ if (![self isFirstResponder])
+ return;
+
+ // There seems to be no API to inform that the keyboard layout needs to update.
+ // As a work-around, we quickly resign first responder just to reassign it again.
+ QScopedValueRollback<bool> rollback(staticVariables()->inUpdateKeyboardLayout);
+ staticVariables()->inUpdateKeyboardLayout = true;
+ [super resignFirstResponder];
+ [self updateTextInputTraits];
+ [super becomeFirstResponder];
+}
+
+- (void)updateUITextInputDelegate:(NSNumber *)intQuery
+{
+ // As documented, we should not report textWillChange/textDidChange unless the text
+ // was changed externally. That will cause spell checking etc to fail. But we don't
+ // really know if the text/selection was changed by UITextInput or Qt/app when getting
+ // update calls from Qt. We therefore use a less ideal approach where we always assume
+ // that UITextView caused the change if we're currently processing an event sendt from it.
+ if (m_inSendEventToFocusObject)
+ return;
+
+ Qt::InputMethodQueries query = Qt::InputMethodQueries([intQuery intValue]);
+ if (query & (Qt::ImCursorPosition | Qt::ImAnchorPosition)) {
+ [self.inputDelegate selectionWillChange:id<UITextInput>(self)];
+ [self.inputDelegate selectionDidChange:id<UITextInput>(self)];
+ }
+
+ if (query & Qt::ImSurroundingText) {
+ [self.inputDelegate textWillChange:id<UITextInput>(self)];
+ [self.inputDelegate textDidChange:id<UITextInput>(self)];
+ }
+}
+
- (void)updateInputMethodWithQuery:(Qt::InputMethodQueries)query
{
Q_UNUSED(query);
@@ -160,26 +204,13 @@ Q_GLOBAL_STATIC(StaticVariables, staticVariables);
if (!focusObject)
return;
- if (!m_inSendEventToFocusObject) {
- if (query & (Qt::ImCursorPosition | Qt::ImAnchorPosition))
- [self.inputDelegate selectionWillChange:id<UITextInput>(self)];
- if (query & Qt::ImSurroundingText)
- [self.inputDelegate textWillChange:id<UITextInput>(self)];
- }
-
// Note that we ignore \a query, and instead update using Qt::ImQueryInput. This enables us to just
// store the event without copying out the result from the event each time. Besides, we seem to be
// called with Qt::ImQueryInput when only changing selection, and always if typing text. So there would
// not be any performance gain by only updating \a query.
staticVariables()->inputMethodQueryEvent = QInputMethodQueryEvent(Qt::ImQueryInput);
QCoreApplication::sendEvent(focusObject, &staticVariables()->inputMethodQueryEvent);
-
- if (!m_inSendEventToFocusObject) {
- if (query & (Qt::ImCursorPosition | Qt::ImAnchorPosition))
- [self.inputDelegate selectionDidChange:id<UITextInput>(self)];
- if (query & Qt::ImSurroundingText)
- [self.inputDelegate textDidChange:id<UITextInput>(self)];
- }
+ [self updateUITextInputDelegate:[NSNumber numberWithInt:int(query)]];
}
- (void)sendEventToFocusObject:(QEvent &)e
@@ -189,35 +220,31 @@ Q_GLOBAL_STATIC(StaticVariables, staticVariables);
return;
// While sending the event, we will receive back updateInputMethodWithQuery calls.
- // To not confuse iOS, we cannot not call textWillChange/textDidChange at that
- // point since it will cause spell checking etc to fail. So we use a guard.
+ // Note that it would be more correct to post the event instead, but UITextInput expects
+ // callbacks to take effect immediately (it will query us for information after a callback).
+ QScopedValueRollback<BOOL> rollback(m_inSendEventToFocusObject);
m_inSendEventToFocusObject = YES;
QCoreApplication::sendEvent(focusObject, &e);
- m_inSendEventToFocusObject = NO;
}
- (void)reset
{
- [self.inputDelegate textWillChange:id<UITextInput>(self)];
[self setMarkedText:@"" selectedRange:NSMakeRange(0, 0)];
[self updateInputMethodWithQuery:Qt::ImQueryInput];
-
- if ([self isFirstResponder]) {
- // There seem to be no way to inform that the keyboard needs to update (since
- // text input traits might have changed). As a work-around, we quickly resign
- // first responder status just to reassign it again:
- [super resignFirstResponder];
- [self updateTextInputTraits];
- [super becomeFirstResponder];
- }
- [self.inputDelegate textDidChange:id<UITextInput>(self)];
+ // Guard agains recursive callbacks by posting calls to UITextInput
+ [self performSelectorOnMainThread:@selector(updateKeyboardLayout) withObject:nil waitUntilDone:NO];
+ [self performSelectorOnMainThread:@selector(updateUITextInputDelegate:)
+ withObject:[NSNumber numberWithInt:int(Qt::ImQueryInput)]
+ waitUntilDone:NO];
}
- (void)commit
{
- [self.inputDelegate textWillChange:id<UITextInput>(self)];
[self unmarkText];
- [self.inputDelegate textDidChange:id<UITextInput>(self)];
+ // Guard agains recursive callbacks by posting calls to UITextInput
+ [self performSelectorOnMainThread:@selector(updateUITextInputDelegate:)
+ withObject:[NSNumber numberWithInt:int(Qt::ImSurroundingText)]
+ waitUntilDone:NO];
}
- (QVariant)imValue:(Qt::InputMethodQuery)query
diff --git a/src/plugins/platforms/windows/accessible/iaccessible2.cpp b/src/plugins/platforms/windows/accessible/iaccessible2.cpp
index 53b48ee37f..9a17f807a9 100644
--- a/src/plugins/platforms/windows/accessible/iaccessible2.cpp
+++ b/src/plugins/platforms/windows/accessible/iaccessible2.cpp
@@ -522,6 +522,7 @@ HRESULT STDMETHODCALLTYPE QWindowsIA2Accessible::get_locale(IA2Locale *locale)
QLocale l;
res.country = QStringToBSTR(QLocale::countryToString(l.country()));
res.language = QStringToBSTR(QLocale::languageToString(l.language()));
+ res.variant = QStringToBSTR(QString());
*locale = res;
return S_OK;
}
diff --git a/src/plugins/platforms/windows/accessible/iaccessible2.h b/src/plugins/platforms/windows/accessible/iaccessible2.h
index 9c922dce36..9c42fdc631 100644
--- a/src/plugins/platforms/windows/accessible/iaccessible2.h
+++ b/src/plugins/platforms/windows/accessible/iaccessible2.h
@@ -329,7 +329,7 @@ public:
private:
static BSTR relationToBSTR(QAccessible::Relation relation)
{
- wchar_t *constRelationString = 0;
+ const wchar_t *constRelationString = 0;
switch (relation) {
case QAccessible::Label:
constRelationString = IA2_RELATION_LABEL_FOR;
diff --git a/src/plugins/platforms/windows/qplatformfunctions_wince.h b/src/plugins/platforms/windows/qplatformfunctions_wince.h
index 65ce466086..921e64d64c 100644
--- a/src/plugins/platforms/windows/qplatformfunctions_wince.h
+++ b/src/plugins/platforms/windows/qplatformfunctions_wince.h
@@ -271,14 +271,19 @@ typedef struct tagTTPOLYCURVE
#define WM_DRAWCLIPBOARD 0x0308
#endif
+#include <QFileInfo>
+
inline bool IsIconic( HWND /*hWnd*/ )
{
return false;
}
-inline int AddFontResourceExW( LPCWSTR /*name*/, DWORD /*fl*/, PVOID /*res*/)
+inline int AddFontResourceExW( LPCWSTR name, DWORD /*fl*/, PVOID /*res*/)
{
- return 0;
+ QString fName = QString::fromWCharArray(name);
+ QFileInfo fileinfo(fName);
+ fName = fileinfo.absoluteFilePath();
+ return AddFontResource((LPCWSTR)fName.utf16());
}
inline bool RemoveFontResourceExW( LPCWSTR /*name*/, DWORD /*fl*/, PVOID /*pdv*/)
diff --git a/src/plugins/platforms/windows/qwindowskeymapper.cpp b/src/plugins/platforms/windows/qwindowskeymapper.cpp
index 0b257cc48f..6bcfe01a18 100644
--- a/src/plugins/platforms/windows/qwindowskeymapper.cpp
+++ b/src/plugins/platforms/windows/qwindowskeymapper.cpp
@@ -893,6 +893,7 @@ bool QWindowsKeyMapper::translateKeyEventInternal(QWindow *window, const MSG &ms
case Qt::Key_Plus:
case Qt::Key_Minus:
case Qt::Key_Period:
+ case Qt::Key_Comma:
case Qt::Key_0:
case Qt::Key_1:
case Qt::Key_2:
diff --git a/src/plugins/platforms/windows/qwindowsmousehandler.cpp b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
index cc0597b72d..4633378342 100644
--- a/src/plugins/platforms/windows/qwindowsmousehandler.cpp
+++ b/src/plugins/platforms/windows/qwindowsmousehandler.cpp
@@ -178,10 +178,11 @@ bool QWindowsMouseHandler::translateMouseEvent(QWindow *window, HWND hwnd,
// since we do not want to ignore mouse events coming from a tablet.
const quint64 extraInfo = GetMessageExtraInfo();
if ((extraInfo & signatureMask) == miWpSignature) {
- source = Qt::MouseEventSynthesizedBySystem;
- const bool fromTouch = extraInfo & 0x80; // (else: Tablet PC)
- if (fromTouch && !passSynthesizedMouseEvents)
- return false;
+ if (extraInfo & 0x80) { // Bit 7 indicates touch event, else tablet pen.
+ source = Qt::MouseEventSynthesizedBySystem;
+ if (!passSynthesizedMouseEvents)
+ return false;
+ }
}
#endif // !Q_OS_WINCE
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index 1b91ba8e1b..18b4cc85cc 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -1969,7 +1969,10 @@ void QWindowsWindow::getSizeHints(MINMAXINFO *mmi) const
&& (m_data.flags & Qt::FramelessWindowHint)) {
// This block fixes QTBUG-8361: Frameless windows shouldn't cover the
// taskbar when maximized
- if (const QScreen *screen = window()->screen()) {
+ const QScreen *screen = window()->screen();
+
+ // Documentation of MINMAXINFO states that it will only work for the primary screen
+ if (screen && screen == QGuiApplication::primaryScreen()) {
mmi->ptMaxSize.y = screen->availableGeometry().height();
// Width, because you can have the taskbar on the sides too.
@@ -1978,8 +1981,8 @@ void QWindowsWindow::getSizeHints(MINMAXINFO *mmi) const
// If you have the taskbar on top, or on the left you don't want it at (0,0):
mmi->ptMaxPosition.x = screen->availableGeometry().x();
mmi->ptMaxPosition.y = screen->availableGeometry().y();
- } else {
- qWarning() << "Invalid screen";
+ } else if (!screen){
+ qWarning() << "effectiveScreen() returned a null screen";
}
}
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index 1b72bb0da1..7f23c84cb9 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -1028,6 +1028,15 @@ void QXcbEventReader::registerForEvents()
connect(dispatcher, SIGNAL(awake()), m_connection, SLOT(processXcbEvents()));
}
+void QXcbEventReader::registerEventDispatcher(QAbstractEventDispatcher *dispatcher)
+{
+ // flush the xcb connection before the EventDispatcher is going to block
+ // In the non-threaded case processXcbEvents is called before going to block,
+ // which flushes the connection.
+ if (m_xcb_poll_for_queued_event)
+ connect(dispatcher, SIGNAL(aboutToBlock()), m_connection, SLOT(flush()));
+}
+
void QXcbEventReader::run()
{
xcb_generic_event_t *event;
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index 12143a7e4b..15fdf50a1e 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -311,6 +311,8 @@ public:
void start();
+ void registerEventDispatcher(QAbstractEventDispatcher *dispatcher);
+
signals:
void eventPending();
@@ -410,7 +412,6 @@ public:
void sync();
- void flush() { xcb_flush(m_connection); }
void handleXcbError(xcb_generic_error_t *error);
void handleXcbEvent(xcb_generic_event_t *event);
@@ -465,8 +466,11 @@ public:
void handleEnterEvent(const xcb_enter_notify_event_t *);
#endif
+ QXcbEventReader *eventReader() const { return m_reader; }
+
public slots:
void syncWindow(QXcbWindow *window);
+ void flush() { xcb_flush(m_connection); }
private slots:
void processXcbEvents();
@@ -497,8 +501,10 @@ private:
#ifdef XCB_USE_XINPUT2
void initializeXInput2();
void finalizeXInput2();
+ void xi2SetupDevices();
XInput2DeviceData *deviceForId(int id);
void xi2HandleEvent(xcb_ge_event_t *event);
+ void xi2HandleHierachyEvent(void *event);
int m_xiOpCode, m_xiEventBase, m_xiErrorBase;
#ifndef QT_NO_TABLETEVENT
struct TabletData {
diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
index eb7b220c43..a574dcae6c 100644
--- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
@@ -73,10 +73,6 @@ void QXcbConnection::initializeXInput2()
{
debug_xinput = qEnvironmentVariableIsSet("QT_XCB_DEBUG_XINPUT");
debug_xinput_devices = qEnvironmentVariableIsSet("QT_XCB_DEBUG_XINPUT_DEVICES");
-#ifndef QT_NO_TABLETEVENT
- m_tabletData.clear();
-#endif
- m_scrollingDevices.clear();
Display *xDisplay = static_cast<Display *>(m_xlib_display);
if (XQueryExtension(xDisplay, "XInputExtension", &m_xiOpCode, &m_xiEventBase, &m_xiErrorBase)) {
int xiMajor = 2;
@@ -97,126 +93,146 @@ void QXcbConnection::initializeXInput2()
#else
qDebug("XInput version %d.%d is available and Qt supports 2.0", xiMajor, m_xi2Minor);
#endif
- int deviceCount = 0;
- XIDeviceInfo *devices = XIQueryDevice(xDisplay, XIAllDevices, &deviceCount);
- for (int i = 0; i < deviceCount; ++i) {
- // Only non-master pointing devices are relevant here.
- if (devices[i].use != XISlavePointer)
- continue;
- if (Q_UNLIKELY(debug_xinput_devices))
- qDebug() << "input device "<< devices[i].name;
+ }
+
+ xi2SetupDevices();
+ }
+}
+
+void QXcbConnection::xi2SetupDevices()
+{
+#ifndef QT_NO_TABLETEVENT
+ m_tabletData.clear();
+#endif
+ m_scrollingDevices.clear();
+
+ if (!m_xi2Enabled)
+ return;
+
+ Display *xDisplay = static_cast<Display *>(m_xlib_display);
+ int deviceCount = 0;
+ XIDeviceInfo *devices = XIQueryDevice(xDisplay, XIAllDevices, &deviceCount);
+ for (int i = 0; i < deviceCount; ++i) {
+ // Only non-master pointing devices are relevant here.
+ if (devices[i].use != XISlavePointer)
+ continue;
+ if (Q_UNLIKELY(debug_xinput_devices))
+ qDebug() << "input device "<< devices[i].name;
#ifndef QT_NO_TABLETEVENT
- TabletData tabletData;
+ TabletData tabletData;
#endif
- ScrollingDevice scrollingDevice;
- for (int c = 0; c < devices[i].num_classes; ++c) {
- switch (devices[i].classes[c]->type) {
- case XIValuatorClass: {
- XIValuatorClassInfo *vci = reinterpret_cast<XIValuatorClassInfo *>(devices[i].classes[c]);
- const int valuatorAtom = qatom(vci->label);
- if (Q_UNLIKELY(debug_xinput_devices))
- qDebug() << " has valuator" << atomName(vci->label) << "recognized?" << (valuatorAtom < QXcbAtom::NAtoms);
+ ScrollingDevice scrollingDevice;
+ for (int c = 0; c < devices[i].num_classes; ++c) {
+ switch (devices[i].classes[c]->type) {
+ case XIValuatorClass: {
+ XIValuatorClassInfo *vci = reinterpret_cast<XIValuatorClassInfo *>(devices[i].classes[c]);
+ const int valuatorAtom = qatom(vci->label);
+ if (Q_UNLIKELY(debug_xinput_devices))
+ qDebug() << " has valuator" << atomName(vci->label) << "recognized?" << (valuatorAtom < QXcbAtom::NAtoms);
#ifndef QT_NO_TABLETEVENT
- if (valuatorAtom < QXcbAtom::NAtoms) {
- TabletData::ValuatorClassInfo info;
- info.minVal = vci->min;
- info.maxVal = vci->max;
- info.number = vci->number;
- tabletData.valuatorInfo[valuatorAtom] = info;
- }
+ if (valuatorAtom < QXcbAtom::NAtoms) {
+ TabletData::ValuatorClassInfo info;
+ info.minVal = vci->min;
+ info.maxVal = vci->max;
+ info.number = vci->number;
+ tabletData.valuatorInfo[valuatorAtom] = info;
+ }
#endif // QT_NO_TABLETEVENT
- if (valuatorAtom == QXcbAtom::RelHorizScroll || valuatorAtom == QXcbAtom::RelHorizWheel)
- scrollingDevice.lastScrollPosition.setX(vci->value);
- else if (valuatorAtom == QXcbAtom::RelVertScroll || valuatorAtom == QXcbAtom::RelVertWheel)
- scrollingDevice.lastScrollPosition.setY(vci->value);
- break;
- }
+ if (valuatorAtom == QXcbAtom::RelHorizScroll || valuatorAtom == QXcbAtom::RelHorizWheel)
+ scrollingDevice.lastScrollPosition.setX(vci->value);
+ else if (valuatorAtom == QXcbAtom::RelVertScroll || valuatorAtom == QXcbAtom::RelVertWheel)
+ scrollingDevice.lastScrollPosition.setY(vci->value);
+ break;
+ }
#ifdef XCB_USE_XINPUT21
- case XIScrollClass: {
- XIScrollClassInfo *sci = reinterpret_cast<XIScrollClassInfo *>(devices[i].classes[c]);
- if (sci->scroll_type == XIScrollTypeVertical) {
- scrollingDevice.orientations |= Qt::Vertical;
- scrollingDevice.verticalIndex = sci->number;
- scrollingDevice.verticalIncrement = sci->increment;
- }
- else if (sci->scroll_type == XIScrollTypeHorizontal) {
- scrollingDevice.orientations |= Qt::Horizontal;
- scrollingDevice.horizontalIndex = sci->number;
- scrollingDevice.horizontalIncrement = sci->increment;
- }
- break;
- }
- case XIButtonClass: {
- XIButtonClassInfo *bci = reinterpret_cast<XIButtonClassInfo *>(devices[i].classes[c]);
- if (bci->num_buttons >= 5) {
- Atom label4 = bci->labels[3];
- Atom label5 = bci->labels[4];
- if ((!label4 || qatom(label4) == QXcbAtom::ButtonWheelUp) && (!label5 || qatom(label5) == QXcbAtom::ButtonWheelDown))
- scrollingDevice.legacyOrientations |= Qt::Vertical;
- }
- if (bci->num_buttons >= 7) {
- Atom label6 = bci->labels[5];
- Atom label7 = bci->labels[6];
- if ((!label6 || qatom(label6) == QXcbAtom::ButtonHorizWheelLeft) && (!label7 || qatom(label7) == QXcbAtom::ButtonHorizWheelRight))
- scrollingDevice.legacyOrientations |= Qt::Horizontal;
- }
- break;
- }
-#endif
- default:
- break;
- }
+ case XIScrollClass: {
+ XIScrollClassInfo *sci = reinterpret_cast<XIScrollClassInfo *>(devices[i].classes[c]);
+ if (sci->scroll_type == XIScrollTypeVertical) {
+ scrollingDevice.orientations |= Qt::Vertical;
+ scrollingDevice.verticalIndex = sci->number;
+ scrollingDevice.verticalIncrement = sci->increment;
}
- bool isTablet = false;
-#ifndef QT_NO_TABLETEVENT
- // If we have found the valuators which we expect a tablet to have, assume it's a tablet.
- if (tabletData.valuatorInfo.contains(QXcbAtom::AbsX) &&
- tabletData.valuatorInfo.contains(QXcbAtom::AbsY) &&
- tabletData.valuatorInfo.contains(QXcbAtom::AbsPressure)) {
- tabletData.deviceId = devices[i].deviceid;
- tabletData.pointerType = QTabletEvent::Pen;
- if (QByteArray(devices[i].name).toLower().contains("eraser"))
- tabletData.pointerType = QTabletEvent::Eraser;
- m_tabletData.append(tabletData);
- isTablet = true;
- if (Q_UNLIKELY(debug_xinput_devices))
- qDebug() << " it's a tablet with pointer type" << tabletData.pointerType;
+ else if (sci->scroll_type == XIScrollTypeHorizontal) {
+ scrollingDevice.orientations |= Qt::Horizontal;
+ scrollingDevice.horizontalIndex = sci->number;
+ scrollingDevice.horizontalIncrement = sci->increment;
+ }
+ break;
+ }
+ case XIButtonClass: {
+ XIButtonClassInfo *bci = reinterpret_cast<XIButtonClassInfo *>(devices[i].classes[c]);
+ if (bci->num_buttons >= 5) {
+ Atom label4 = bci->labels[3];
+ Atom label5 = bci->labels[4];
+ if ((!label4 || qatom(label4) == QXcbAtom::ButtonWheelUp) && (!label5 || qatom(label5) == QXcbAtom::ButtonWheelDown))
+ scrollingDevice.legacyOrientations |= Qt::Vertical;
}
+ if (bci->num_buttons >= 7) {
+ Atom label6 = bci->labels[5];
+ Atom label7 = bci->labels[6];
+ if ((!label6 || qatom(label6) == QXcbAtom::ButtonHorizWheelLeft) && (!label7 || qatom(label7) == QXcbAtom::ButtonHorizWheelRight))
+ scrollingDevice.legacyOrientations |= Qt::Horizontal;
+ }
+ break;
+ }
+#endif
+ default:
+ break;
+ }
+ }
+ bool isTablet = false;
+#ifndef QT_NO_TABLETEVENT
+ // If we have found the valuators which we expect a tablet to have, assume it's a tablet.
+ if (tabletData.valuatorInfo.contains(QXcbAtom::AbsX) &&
+ tabletData.valuatorInfo.contains(QXcbAtom::AbsY) &&
+ tabletData.valuatorInfo.contains(QXcbAtom::AbsPressure)) {
+ tabletData.deviceId = devices[i].deviceid;
+ tabletData.pointerType = QTabletEvent::Pen;
+ if (QByteArray(devices[i].name).toLower().contains("eraser"))
+ tabletData.pointerType = QTabletEvent::Eraser;
+ m_tabletData.append(tabletData);
+ isTablet = true;
+ if (Q_UNLIKELY(debug_xinput_devices))
+ qDebug() << " it's a tablet with pointer type" << tabletData.pointerType;
+ }
#endif // QT_NO_TABLETEVENT
#ifdef XCB_USE_XINPUT21
- if (scrollingDevice.orientations || scrollingDevice.legacyOrientations) {
- scrollingDevice.deviceId = devices[i].deviceid;
- // Only use legacy wheel button events when we don't have real scroll valuators.
- scrollingDevice.legacyOrientations &= ~scrollingDevice.orientations;
- m_scrollingDevices.insert(scrollingDevice.deviceId, scrollingDevice);
- if (Q_UNLIKELY(debug_xinput_devices))
- qDebug() << " it's a scrolling device";
- }
+ if (scrollingDevice.orientations || scrollingDevice.legacyOrientations) {
+ scrollingDevice.deviceId = devices[i].deviceid;
+ // Only use legacy wheel button events when we don't have real scroll valuators.
+ scrollingDevice.legacyOrientations &= ~scrollingDevice.orientations;
+ m_scrollingDevices.insert(scrollingDevice.deviceId, scrollingDevice);
+ if (Q_UNLIKELY(debug_xinput_devices))
+ qDebug() << " it's a scrolling device";
+ }
#endif
- if (!isTablet) {
- XInput2DeviceData *dev = deviceForId(devices[i].deviceid);
- if (Q_UNLIKELY(debug_xinput_devices)) {
- if (dev && dev->qtTouchDevice->type() == QTouchDevice::TouchScreen)
- qDebug(" it's a touchscreen with type %d capabilities 0x%X max touch points %d",
- dev->qtTouchDevice->type(), (unsigned int)dev->qtTouchDevice->capabilities(),
- dev->qtTouchDevice->maximumTouchPoints());
- else if (dev && dev->qtTouchDevice->type() == QTouchDevice::TouchPad)
- qDebug(" it's a touchpad with type %d capabilities 0x%X max touch points %d size %f x %f",
- dev->qtTouchDevice->type(), (unsigned int)dev->qtTouchDevice->capabilities(),
- dev->qtTouchDevice->maximumTouchPoints(),
- dev->size.width(), dev->size.height());
- }
- }
+ if (!isTablet) {
+ XInput2DeviceData *dev = deviceForId(devices[i].deviceid);
+ if (Q_UNLIKELY(debug_xinput_devices)) {
+ if (dev && dev->qtTouchDevice->type() == QTouchDevice::TouchScreen)
+ qDebug(" it's a touchscreen with type %d capabilities 0x%X max touch points %d",
+ dev->qtTouchDevice->type(), (unsigned int)dev->qtTouchDevice->capabilities(),
+ dev->qtTouchDevice->maximumTouchPoints());
+ else if (dev && dev->qtTouchDevice->type() == QTouchDevice::TouchPad)
+ qDebug(" it's a touchpad with type %d capabilities 0x%X max touch points %d size %f x %f",
+ dev->qtTouchDevice->type(), (unsigned int)dev->qtTouchDevice->capabilities(),
+ dev->qtTouchDevice->maximumTouchPoints(),
+ dev->size.width(), dev->size.height());
}
- XIFreeDeviceInfo(devices);
}
}
+ XIFreeDeviceInfo(devices);
}
void QXcbConnection::finalizeXInput2()
{
+ foreach (XInput2DeviceData *dev, m_touchDevices) {
+ if (dev->xiDeviceInfo)
+ XIFreeDeviceInfo(dev->xiDeviceInfo);
+ delete dev;
+ }
}
void QXcbConnection::xi2Select(xcb_window_t window)
@@ -303,6 +319,16 @@ void QXcbConnection::xi2Select(xcb_window_t window)
#else
Q_UNUSED(xiBitMask);
#endif
+
+ {
+ // Listen for hotplug events
+ XIEventMask xiEventMask;
+ bitMask = XI_HierarchyChangedMask;
+ xiEventMask.deviceid = XIAllDevices;
+ xiEventMask.mask_len = sizeof(bitMask);
+ xiEventMask.mask = xiBitMask;
+ XISelectEvents(xDisplay, window, &xiEventMask, 1);
+ }
}
XInput2DeviceData *QXcbConnection::deviceForId(int id)
@@ -326,10 +352,10 @@ XInput2DeviceData *QXcbConnection::deviceForId(int id)
if (Q_UNLIKELY(debug_xinput_devices))
qDebug(" has touch class with mode %d", tci->mode);
switch (tci->mode) {
- case XIModeRelative:
+ case XIDependentTouch:
type = QTouchDevice::TouchPad;
break;
- case XIModeAbsolute:
+ case XIDirectTouch:
type = QTouchDevice::TouchScreen;
break;
}
@@ -372,6 +398,7 @@ XInput2DeviceData *QXcbConnection::deviceForId(int id)
m_touchDevices[id] = dev;
} else {
m_touchDevices.remove(id);
+ XIFreeDeviceInfo(dev->xiDeviceInfo);
delete dev;
dev = 0;
}
@@ -402,6 +429,10 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
if (xi2PrepareXIGenericDeviceEvent(event, m_xiOpCode)) {
xXIGenericDeviceEvent *xiEvent = reinterpret_cast<xXIGenericDeviceEvent *>(event);
+ if (xiEvent->evtype == XI_HierarchyChanged) {
+ xi2HandleHierachyEvent(xiEvent);
+ return;
+ }
#ifndef QT_NO_TABLETEVENT
for (int i = 0; i < m_tabletData.count(); ++i) {
if (m_tabletData.at(i).deviceId == xiEvent->deviceid) {
@@ -561,6 +592,19 @@ void QXcbConnection::xi2HandleEvent(xcb_ge_event_t *event)
}
}
+void QXcbConnection::xi2HandleHierachyEvent(void *event)
+{
+ xXIHierarchyEvent *xiEvent = reinterpret_cast<xXIHierarchyEvent *>(event);
+ // We only care about hotplugged devices
+ if (!(xiEvent->flags & (XISlaveRemoved | XISlaveAdded)))
+ return;
+ xi2SetupDevices();
+ // Reselect events for all event-listening windows.
+ Q_FOREACH (xcb_window_t window, m_mapper.keys()) {
+ xi2Select(window);
+ }
+}
+
void QXcbConnection::handleEnterEvent(const xcb_enter_notify_event_t *)
{
#ifdef XCB_USE_XINPUT21
diff --git a/src/plugins/platforms/xcb/qxcbintegration.cpp b/src/plugins/platforms/xcb/qxcbintegration.cpp
index 36a4b5c5db..f537a38962 100644
--- a/src/plugins/platforms/xcb/qxcbintegration.cpp
+++ b/src/plugins/platforms/xcb/qxcbintegration.cpp
@@ -316,7 +316,10 @@ bool QXcbIntegration::hasCapability(QPlatformIntegration::Capability cap) const
QAbstractEventDispatcher *QXcbIntegration::createEventDispatcher() const
{
- return createUnixEventDispatcher();
+ QAbstractEventDispatcher *dispatcher = createUnixEventDispatcher();
+ for (int i = 0; i < m_connections.size(); i++)
+ m_connections[i]->eventReader()->registerEventDispatcher(dispatcher);
+ return dispatcher;
}
void QXcbIntegration::initialize()
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
index 69601f44d4..4c84b19f82 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
@@ -929,6 +929,15 @@ int QXcbKeyboard::keysymToQtKey(xcb_keysym_t key) const
i += 2;
}
+ if (rmod_masks.meta) {
+ // translate Super/Hyper keys to Meta if we're using them as the MetaModifier
+ if (rmod_masks.meta == rmod_masks.super && (code == Qt::Key_Super_L || code == Qt::Key_Super_R)) {
+ code = Qt::Key_Meta;
+ } else if (rmod_masks.meta == rmod_masks.hyper && (code == Qt::Key_Hyper_L || code == Qt::Key_Hyper_R)) {
+ code = Qt::Key_Meta;
+ }
+ }
+
return code;
}
diff --git a/src/plugins/platforms/xcb/qxcbscreen.cpp b/src/plugins/platforms/xcb/qxcbscreen.cpp
index 9f19841437..01e78465b6 100644
--- a/src/plugins/platforms/xcb/qxcbscreen.cpp
+++ b/src/plugins/platforms/xcb/qxcbscreen.cpp
@@ -106,6 +106,11 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *scr,
qDebug(" root ID........: %x", screen()->root);
#endif
+ QScopedPointer<xcb_get_window_attributes_reply_t, QScopedPointerPodDeleter> rootAttribs(
+ xcb_get_window_attributes_reply(xcb_connection(),
+ xcb_get_window_attributes_unchecked(xcb_connection(), screen()->root), NULL));
+ const quint32 existingEventMask = rootAttribs.isNull() ? 0 : rootAttribs->your_event_mask;
+
const quint32 mask = XCB_CW_EVENT_MASK;
const quint32 values[] = {
// XCB_CW_EVENT_MASK
@@ -113,6 +118,7 @@ QXcbScreen::QXcbScreen(QXcbConnection *connection, xcb_screen_t *scr,
| XCB_EVENT_MASK_LEAVE_WINDOW
| XCB_EVENT_MASK_PROPERTY_CHANGE
| XCB_EVENT_MASK_STRUCTURE_NOTIFY // for the "MANAGER" atom (system tray notification).
+ | existingEventMask // don't overwrite the event mask on the root window
};
xcb_change_window_attributes(xcb_connection(), screen()->root, mask, values);
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index 4b9a99486f..dd3084e402 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -339,12 +339,38 @@ void QXcbWindow::create()
#endif //defined(XCB_USE_GLX) || defined(XCB_USE_EGL)
{
m_window = xcb_generate_id(xcb_connection());
+ m_visualId = m_screen->screen()->root_visual;
m_depth = m_screen->screen()->root_depth;
+
+ uint32_t mask = 0;
+ uint32_t values[3];
+
+ if (m_format.alphaBufferSize() == 8) {
+ xcb_depth_iterator_t depthIter = xcb_screen_allowed_depths_iterator(m_screen->screen());
+ while (depthIter.rem) {
+ if (depthIter.data->depth == 32) {
+ xcb_visualtype_iterator_t visualIter = xcb_depth_visuals_iterator(depthIter.data);
+ if (visualIter.rem) {
+ m_visualId = visualIter.data->visual_id;
+ m_depth = 32;
+ uint32_t colormap = xcb_generate_id(xcb_connection());
+ xcb_create_colormap(xcb_connection(), XCB_COLORMAP_ALLOC_NONE, colormap,
+ xcb_parent_id, m_visualId);
+ mask |= XCB_CW_BACK_PIXEL | XCB_CW_BORDER_PIXEL | XCB_CW_COLORMAP;
+ values[0] = m_screen->screen()->white_pixel;
+ values[1] = m_screen->screen()->black_pixel;
+ values[2] = colormap;
+ break;
+ }
+ }
+ xcb_depth_next(&depthIter);
+ }
+ }
+
m_imageFormat = imageFormatForDepth(m_depth);
- m_visualId = m_screen->screen()->root_visual;
Q_XCB_CALL(xcb_create_window(xcb_connection(),
- XCB_COPY_FROM_PARENT, // depth -- same as root
+ m_depth,
m_window, // window id
xcb_parent_id, // parent window id
rect.x(),
@@ -354,8 +380,8 @@ void QXcbWindow::create()
0, // border width
XCB_WINDOW_CLASS_INPUT_OUTPUT, // window class
m_visualId, // visual
- 0, // value mask
- 0)); // value list
+ mask,
+ values));
}
connection()->addWindowEventListener(m_window, this);
diff --git a/src/plugins/platforms/xcb/xcb-plugin.pro b/src/plugins/platforms/xcb/xcb-plugin.pro
index a52aaa4a2e..4d76e4d449 100644
--- a/src/plugins/platforms/xcb/xcb-plugin.pro
+++ b/src/plugins/platforms/xcb/xcb-plugin.pro
@@ -109,7 +109,6 @@ QMAKE_CXXFLAGS += $$QMAKE_CFLAGS_XCB
CONFIG += qpa/genericunixfontdatabase
contains(QT_CONFIG, dbus) {
-DEFINES += XCB_USE_IBUS
QT += dbus
LIBS += -ldbus-1
}
diff --git a/src/plugins/printsupport/windows/qwindowsprintdevice.cpp b/src/plugins/printsupport/windows/qwindowsprintdevice.cpp
index 2c75ab7016..915d8380c7 100644
--- a/src/plugins/printsupport/windows/qwindowsprintdevice.cpp
+++ b/src/plugins/printsupport/windows/qwindowsprintdevice.cpp
@@ -252,6 +252,9 @@ QMarginsF QWindowsPrintDevice::printableMargins(const QPageSize &pageSize,
if (GetPrinter(m_hPrinter, 2, buffer.data(), needed, &needed)) {
PPRINTER_INFO_2 info = reinterpret_cast<PPRINTER_INFO_2>(buffer.data());
DEVMODE *devMode = info->pDevMode;
+ if (!devMode)
+ return margins;
+
HDC pDC = CreateDC(NULL, (LPWSTR)m_id.utf16(), NULL, devMode);
if (pageSize.id() == QPageSize::Custom || pageSize.windowsId() <= 0 || pageSize.windowsId() > DMPAPER_LAST) {
devMode->dmPaperSize = 0;
diff --git a/src/printsupport/kernel/qprintengine_win.cpp b/src/printsupport/kernel/qprintengine_win.cpp
index 1adfcfa630..bf39b9309d 100644
--- a/src/printsupport/kernel/qprintengine_win.cpp
+++ b/src/printsupport/kernel/qprintengine_win.cpp
@@ -850,14 +850,13 @@ void QWin32PrintEngine::drawPolygon(const QPointF *points, int pointCount, Polyg
QWin32PrintEnginePrivate::~QWin32PrintEnginePrivate()
{
- if (hdc)
- release();
+ release();
}
void QWin32PrintEnginePrivate::initialize()
{
- if (hdc)
- release();
+ release();
+
Q_ASSERT(!hPrinter);
Q_ASSERT(!hdc);
Q_ASSERT(!devMode);
@@ -884,18 +883,19 @@ void QWin32PrintEnginePrivate::initialize()
if (!ok) {
qErrnoWarning("QWin32PrintEngine::initialize: GetPrinter failed");
- GlobalUnlock(pInfo);
- GlobalFree(hMem);
- ClosePrinter(hPrinter);
- pInfo = 0;
- hMem = 0;
- hPrinter = 0;
+ release();
return;
}
devMode = pInfo->pDevMode;
hdc = CreateDC(NULL, reinterpret_cast<const wchar_t *>(m_printDevice.id().utf16()), 0, devMode);
+ if (!hdc) {
+ qErrnoWarning("QWin32PrintEngine::initialize: CreateDC failed");
+ release();
+ return;
+ }
+
Q_ASSERT(hPrinter);
Q_ASSERT(pInfo);
@@ -947,19 +947,17 @@ void QWin32PrintEnginePrivate::initHDC()
void QWin32PrintEnginePrivate::release()
{
- if (hdc == 0)
- return;
-
if (globalDevMode) { // Devmode comes from print dialog
GlobalUnlock(globalDevMode);
- } else { // Devmode comes from initialize...
+ } else if (hMem) { // Devmode comes from initialize...
// devMode is a part of the same memory block as pInfo so one free is enough...
GlobalUnlock(hMem);
GlobalFree(hMem);
}
if (hPrinter)
ClosePrinter(hPrinter);
- DeleteDC(hdc);
+ if (hdc)
+ DeleteDC(hdc);
hdc = 0;
hPrinter = 0;
diff --git a/src/printsupport/kernel/qprintengine_win_p.h b/src/printsupport/kernel/qprintengine_win_p.h
index 9b944d5921..f698992425 100644
--- a/src/printsupport/kernel/qprintengine_win_p.h
+++ b/src/printsupport/kernel/qprintengine_win_p.h
@@ -125,6 +125,7 @@ public:
globalDevMode(0),
devMode(0),
pInfo(0),
+ hMem(0),
hdc(0),
mode(QPrinter::ScreenResolution),
state(QPrinter::Idle),
diff --git a/src/printsupport/kernel/qprinter.cpp b/src/printsupport/kernel/qprinter.cpp
index bdc9a98f2e..c758d9f4ea 100644
--- a/src/printsupport/kernel/qprinter.cpp
+++ b/src/printsupport/kernel/qprinter.cpp
@@ -120,9 +120,9 @@ QPrinterInfo QPrinterPrivate::findValidPrinter(const QPrinterInfo &printer)
if (printerToUse.isNull()) {
printerToUse = QPrinterInfo::defaultPrinter();
if (printerToUse.isNull()) {
- QList<QPrinterInfo> availablePrinters = QPrinterInfo::availablePrinters();
- if (!availablePrinters.isEmpty())
- printerToUse = availablePrinters.at(0);
+ QStringList availablePrinterNames = QPrinterInfo::availablePrinterNames();
+ if (!availablePrinterNames.isEmpty())
+ printerToUse = QPrinterInfo::printerInfo(availablePrinterNames.at(0));
}
}
return printerToUse;
diff --git a/src/sql/doc/src/qtsql.qdoc b/src/sql/doc/src/qtsql.qdoc
index 2f806b4b45..f7dc840c7b 100644
--- a/src/sql/doc/src/qtsql.qdoc
+++ b/src/sql/doc/src/qtsql.qdoc
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the documentation of the Qt Toolkit.
@@ -51,10 +51,12 @@
QT += sql
\endcode
- \section1 Reference
- These are links to the API reference materials.
+ \section1 Related Information
+
+ These are links to the API reference materials and related pages.
\list
\li \l{Qt SQL C++ Classes}{C++ Classes}
+ \li \l{SQL Examples}
\endlist
*/
diff --git a/src/sql/kernel/qsqldatabase.cpp b/src/sql/kernel/qsqldatabase.cpp
index f8ecabee8f..84e01fce49 100644
--- a/src/sql/kernel/qsqldatabase.cpp
+++ b/src/sql/kernel/qsqldatabase.cpp
@@ -107,7 +107,11 @@ Q_GLOBAL_STATIC_WITH_ARGS(QFactoryLoader, loader,
QLatin1String("/sqldrivers")))
#endif
-QT_STATIC_CONST_IMPL char *QSqlDatabase::defaultConnection = "qt_sql_default_connection";
+#if !defined(Q_CC_MSVC) || _MSC_VER >= 1900
+// ### Qt6: remove the #ifdef
+const
+#endif
+char *QSqlDatabase::defaultConnection = const_cast<char *>("qt_sql_default_connection");
typedef QHash<QString, QSqlDriverCreatorBase*> DriverDict;
diff --git a/src/sql/kernel/qsqldatabase.h b/src/sql/kernel/qsqldatabase.h
index 7249e223a5..ffc10cdd30 100644
--- a/src/sql/kernel/qsqldatabase.h
+++ b/src/sql/kernel/qsqldatabase.h
@@ -113,7 +113,12 @@ public:
QSqlDriver* driver() const;
- QT_STATIC_CONST char *defaultConnection;
+ static
+#if !defined(Q_CC_MSVC) || _MSC_VER >= 1900
+ // ### Qt6: remove the #ifdef
+ const
+#endif
+ char *defaultConnection;
static QSqlDatabase addDatabase(const QString& type,
const QString& connectionName = QLatin1String(defaultConnection));
diff --git a/src/tools/moc/moc.cpp b/src/tools/moc/moc.cpp
index ea4838c8f2..f5700899fa 100644
--- a/src/tools/moc/moc.cpp
+++ b/src/tools/moc/moc.cpp
@@ -788,7 +788,7 @@ void Moc::parse()
if (!def.hasQObject && !def.hasQGadget)
- error("Class declarations lacks Q_OBJECT macro.");
+ error("Class declaration lacks Q_OBJECT macro.");
// Add meta tags to the plugin meta data:
if (!def.pluginData.iid.isEmpty())
diff --git a/src/tools/qdoc/htmlgenerator.cpp b/src/tools/qdoc/htmlgenerator.cpp
index f5e2e6309e..59cf538ec8 100644
--- a/src/tools/qdoc/htmlgenerator.cpp
+++ b/src/tools/qdoc/htmlgenerator.cpp
@@ -4501,36 +4501,43 @@ void HtmlGenerator::generateManifestFile(QString manifest, QString element)
}
QString ename = en->name().mid(en->name().lastIndexOf('/')+1);
- QSet<QString> usedNames;
+ QMap<int, const Node*> filesToOpen;
foreach (const Node* child, en->childNodes()) {
if (child->subType() == Node::File) {
- QString file = child->name();
- QString fileName = file.mid(file.lastIndexOf('/')+1);
- QString baseName = fileName;
- if ((fileName.count(QChar('.')) > 0) &&
- (fileName.endsWith(".cpp") ||
- fileName.endsWith(".h") ||
- fileName.endsWith(".qml")))
- baseName.truncate(baseName.lastIndexOf(QChar('.')));
- if (baseName.compare(ename, Qt::CaseInsensitive) == 0) {
- if (!usedNames.contains(fileName)) {
- writer.writeStartElement("fileToOpen");
- writer.writeCharacters(examplesPath + file);
- writer.writeEndElement(); // fileToOpen
- usedNames.insert(fileName);
- }
+ QFileInfo fileInfo(child->name());
+ QString fileName = fileInfo.fileName().toLower();
+ // open .qml, .cpp and .h files with a
+ // basename matching the example (project) name
+ // QMap key indicates the priority -
+ // the lowest value will be the top-most file
+ if ((fileInfo.baseName().compare(ename, Qt::CaseInsensitive) == 0)) {
+ if (fileName.endsWith(".qml"))
+ filesToOpen.insert(0, child);
+ else if (fileName.endsWith(".cpp"))
+ filesToOpen.insert(1, child);
+ else if (fileName.endsWith(".h"))
+ filesToOpen.insert(2, child);
}
- else if (fileName.toLower().endsWith("main.cpp") ||
- fileName.toLower().endsWith("main.qml")) {
- if (!usedNames.contains(fileName)) {
- writer.writeStartElement("fileToOpen");
- writer.writeCharacters(examplesPath + file);
- writer.writeEndElement(); // fileToOpen
- usedNames.insert(fileName);
- }
+ // main.qml takes precedence over main.cpp
+ else if (fileName.endsWith("main.qml")) {
+ filesToOpen.insert(3, child);
}
+ else if (fileName.endsWith("main.cpp")) {
+ filesToOpen.insert(4, child);
+ }
}
}
+
+ QMap<int, const Node*>::const_iterator it = filesToOpen.constEnd();
+ while (it != filesToOpen.constBegin()) {
+ writer.writeStartElement("fileToOpen");
+ if (--it == filesToOpen.constBegin()) {
+ writer.writeAttribute(QStringLiteral("mainFile"), QStringLiteral("true"));
+ }
+ writer.writeCharacters(examplesPath + it.value()->name());
+ writer.writeEndElement();
+ }
+
writer.writeEndElement(); // example
++i;
}
diff --git a/src/widgets/dialogs/qcolordialog.cpp b/src/widgets/dialogs/qcolordialog.cpp
index 744666155a..714dcfa1f4 100644
--- a/src/widgets/dialogs/qcolordialog.cpp
+++ b/src/widgets/dialogs/qcolordialog.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtWidgets module of the Qt Toolkit.
@@ -1450,7 +1450,7 @@ void QColorDialogPrivate::_q_newHsv(int h, int s, int v)
}
//sets all widgets to display rgb
-void QColorDialogPrivate::setCurrentColor(QRgb rgb)
+void QColorDialogPrivate::setCurrentRgbColor(QRgb rgb)
{
if (!nativeDialogInUse) {
cs->setRgb(rgb);
@@ -1533,14 +1533,14 @@ void QColorDialogPrivate::_q_nextCustom(int r, int c)
void QColorDialogPrivate::_q_newCustom(int r, int c)
{
const int i = r + 2 * c;
- setCurrentColor(QColorDialogOptions::customColor(i));
+ setCurrentRgbColor(QColorDialogOptions::customColor(i));
if (standard)
standard->setSelected(-1,-1);
}
void QColorDialogPrivate::_q_newStandard(int r, int c)
{
- setCurrentColor(QColorDialogOptions::standardColor(r + c * 6));
+ setCurrentRgbColor(QColorDialogOptions::standardColor(r + c * 6));
if (custom)
custom->setSelected(-1,-1);
}
@@ -1881,6 +1881,21 @@ QColorDialog::QColorDialog(const QColor &initial, QWidget *parent)
d->init(initial);
}
+void QColorDialogPrivate::setCurrentColor(const QColor &color, SetColorMode setColorMode)
+{
+ if (nativeDialogInUse) {
+ platformColorDialogHelper()->setCurrentColor(color);
+ return;
+ }
+
+ if (setColorMode & ShowColor) {
+ setCurrentRgbColor(color.rgb());
+ setCurrentAlpha(color.alpha());
+ }
+ if (setColorMode & SelectColor)
+ selectColor(color);
+}
+
/*!
\property QColorDialog::currentColor
\brief the currently selected color in the dialog
@@ -1889,13 +1904,7 @@ QColorDialog::QColorDialog(const QColor &initial, QWidget *parent)
void QColorDialog::setCurrentColor(const QColor &color)
{
Q_D(QColorDialog);
- if (d->nativeDialogInUse)
- d->platformColorDialogHelper()->setCurrentColor(color);
- else {
- d->setCurrentColor(color.rgb());
- d->selectColor(color);
- d->setCurrentAlpha(color.alpha());
- }
+ d->setCurrentColor(color);
}
QColor QColorDialog::currentColor() const
@@ -2170,10 +2179,11 @@ void QColorDialog::changeEvent(QEvent *e)
bool QColorDialogPrivate::handleColorPickingMouseMove(QMouseEvent *e)
{
- Q_Q(QColorDialog);
const QPoint globalPos = e->globalPos();
const QColor color = grabScreenColor(globalPos);
- q->setCurrentColor(color);
+ // QTBUG-39792, do not change standard, custom color selectors while moving as
+ // otherwise it is not possible to pre-select a custom cell for assignment.
+ setCurrentColor(color, ShowColor);
lblScreenColorInfo->setText(QColorDialog::tr("Cursor at %1, %2, color: %3\nPress ESC to cancel")
.arg(globalPos.x()).arg(globalPos.y()).arg(color.name()));
return true;
@@ -2181,8 +2191,7 @@ bool QColorDialogPrivate::handleColorPickingMouseMove(QMouseEvent *e)
bool QColorDialogPrivate::handleColorPickingMouseButtonRelease(QMouseEvent *e)
{
- Q_Q(QColorDialog);
- q->setCurrentColor(grabScreenColor(e->globalPos()));
+ setCurrentColor(grabScreenColor(e->globalPos()), SetColorAll);
releaseColorPicking();
return true;
}
diff --git a/src/widgets/dialogs/qcolordialog_p.h b/src/widgets/dialogs/qcolordialog_p.h
index 72c3b0e3cd..feabce4bbf 100644
--- a/src/widgets/dialogs/qcolordialog_p.h
+++ b/src/widgets/dialogs/qcolordialog_p.h
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtWidgets module of the Qt Toolkit.
@@ -77,6 +77,12 @@ class QColorDialogPrivate : public QDialogPrivate
Q_DECLARE_PUBLIC(QColorDialog)
public:
+ enum SetColorMode {
+ ShowColor = 0x1,
+ SelectColor = 0x2,
+ SetColorAll = ShowColor | SelectColor
+ };
+
QColorDialogPrivate() : options(new QColorDialogOptions) {}
QPlatformColorDialogHelper *platformColorDialogHelper() const
@@ -86,7 +92,8 @@ public:
void initWidgets();
QRgb currentColor() const;
QColor currentQColor() const;
- void setCurrentColor(QRgb rgb);
+ void setCurrentColor(const QColor &color, SetColorMode setColorMode = SetColorAll);
+ void setCurrentRgbColor(QRgb rgb);
void setCurrentQColor(const QColor &color);
bool selectColor(const QColor &color);
QColor grabScreenColor(const QPoint &p);
diff --git a/src/widgets/doc/snippets/qstyleplugin/main.cpp b/src/widgets/doc/snippets/qstyleplugin/main.cpp
index 4cf20ab960..e1a0d1b626 100644
--- a/src/widgets/doc/snippets/qstyleplugin/main.cpp
+++ b/src/widgets/doc/snippets/qstyleplugin/main.cpp
@@ -45,7 +45,7 @@
class MyStylePlugin : public QStylePlugin
{
Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QStyleFactoryInterface" FILE mystyleplugin.json)
+ Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QStyleFactoryInterface" FILE "mystyleplugin.json")
public:
MyStylePlugin(QObject *parent = 0);
diff --git a/src/widgets/doc/src/qtwidgets-index.qdoc b/src/widgets/doc/src/qtwidgets-index.qdoc
index 859a0ef933..bc74f43b35 100644
--- a/src/widgets/doc/src/qtwidgets-index.qdoc
+++ b/src/widgets/doc/src/qtwidgets-index.qdoc
@@ -139,6 +139,7 @@ interfaces
\section2 Examples
\list
\li \l{Qt Widgets Examples}
+ \li \l{Layout Examples}
\endlist
\section1 API Reference
diff --git a/src/widgets/doc/src/widgets-and-layouts/layout.qdoc b/src/widgets/doc/src/widgets-and-layouts/layout.qdoc
index 99d512b507..f581df4cb3 100644
--- a/src/widgets/doc/src/widgets-and-layouts/layout.qdoc
+++ b/src/widgets/doc/src/widgets-and-layouts/layout.qdoc
@@ -386,5 +386,13 @@
then set it. (This does not only apply to layouts, you should do
the same if you implement your own resizeEvent(), for example.)
\endlist
-*/
+ \section1 Layout Examples
+
+ Many Qt Widgets \l{Qt Widgets Examples}{examples} already use layouts,
+ however, several examples exist to showcase various layouts.
+
+ \list
+ \li \l{Layout Examples}
+ \endlist
+*/
diff --git a/src/widgets/graphicsview/qgraphicsitem.cpp b/src/widgets/graphicsview/qgraphicsitem.cpp
index 605e96802b..551f229611 100644
--- a/src/widgets/graphicsview/qgraphicsitem.cpp
+++ b/src/widgets/graphicsview/qgraphicsitem.cpp
@@ -9943,7 +9943,7 @@ void QGraphicsTextItem::setDefaultTextColor(const QColor &col)
}
/*!
- Returns the default text color that is used to for unformatted text.
+ Returns the default text color that is used for unformatted text.
*/
QColor QGraphicsTextItem::defaultTextColor() const
{
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index a1f3fbe8db..52d39759dc 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -3182,7 +3182,13 @@ void QWidget::showNormal()
This is the case if neither the widget itself nor every parent up
to but excluding \a ancestor has been explicitly disabled.
- isEnabledTo(0) is equivalent to isEnabled().
+ isEnabledTo(0) returns false if this widget or any if its ancestors
+ was explicitly disabled.
+
+ The word ancestor here means a parent widget within the same window.
+
+ Therefore isEnabledTo(0) stops at this widget's window, unlike
+ isEnabled() which also takes parent windows into considerations.
\sa setEnabled(), enabled
*/
diff --git a/src/widgets/styles/qfusionstyle.cpp b/src/widgets/styles/qfusionstyle.cpp
index 2172c9082f..82c53def7d 100644
--- a/src/widgets/styles/qfusionstyle.cpp
+++ b/src/widgets/styles/qfusionstyle.cpp
@@ -2493,7 +2493,7 @@ void QFusionStyle::drawComplexControl(ComplexControl control, const QStyleOption
QColor arrowColor = option->palette.foreground().color();
arrowColor.setAlpha(220);
- const QColor bgColor = option->palette.color(QPalette::Base);
+ const QColor bgColor = QStyleHelper::backgroundColor(option->palette, widget);
const bool isDarkBg = bgColor.red() < 128 && bgColor.green() < 128 && bgColor.blue() < 128;
if (transient) {
diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm
index da6422ffec..f03a7796d9 100644
--- a/src/widgets/styles/qmacstyle_mac.mm
+++ b/src/widgets/styles/qmacstyle_mac.mm
@@ -3186,17 +3186,15 @@ void QMacStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, QPai
fdi.version = qt_mac_hitheme_version;
fdi.state = tds;
SInt32 frame_size;
- if (pe == PE_FrameLineEdit) {
- fdi.kind = frame->features & QStyleOptionFrame::Rounded ? kHIThemeFrameTextFieldRound :
- kHIThemeFrameTextFieldSquare;
- GetThemeMetric(kThemeMetricEditTextFrameOutset, &frame_size);
- if ((frame->state & State_ReadOnly) || !(frame->state & State_Enabled))
- fdi.state = kThemeStateInactive;
- } else {
- baseColor = QColor(150, 150, 150); //hardcoded since no query function --Sam
- fdi.kind = kHIThemeFrameListBox;
- GetThemeMetric(kThemeMetricListBoxFrameOutset, &frame_size);
- }
+ fdi.kind = frame->features & QStyleOptionFrame::Rounded ? kHIThemeFrameTextFieldRound :
+ kHIThemeFrameTextFieldSquare;
+ GetThemeMetric(kThemeMetricEditTextFrameOutset, &frame_size);
+ if ((frame->state & State_ReadOnly) || !(frame->state & State_Enabled))
+ fdi.state = kThemeStateInactive;
+ else if (fdi.state == kThemeStatePressed)
+ // This pressed state doesn't make sense for a line edit frame.
+ // And Yosemite agrees with us. Otherwise it starts showing yellow pixels.
+ fdi.state = kThemeStateActive;
fdi.isFocused = (frame->state & State_HasFocus);
int lw = frame->lineWidth;
if (lw <= 0)
@@ -5134,7 +5132,7 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
[scroller initWithFrame:NSMakeRect(0, 0, slider->rect.width(), slider->rect.height())];
// mac os behaviour: as soon as one color channel is >= 128,
// the bg is considered bright, scroller is dark
- const QColor bgColor = opt->palette.color(QPalette::Base);
+ const QColor bgColor = QStyleHelper::backgroundColor(opt->palette, widget);
const bool isDarkBg = bgColor.red() < 128 && bgColor.green() < 128 &&
bgColor.blue() < 128;
if (isDarkBg)
diff --git a/src/widgets/styles/qstylehelper.cpp b/src/widgets/styles/qstylehelper.cpp
index fc73488154..6be07a3f45 100644
--- a/src/widgets/styles/qstylehelper.cpp
+++ b/src/widgets/styles/qstylehelper.cpp
@@ -45,6 +45,8 @@
#include <private/qmath_p.h>
#include <private/qstyle_p.h>
#include <qmath.h>
+#include <qscrollbar.h>
+#include <qabstractscrollarea.h>
#include "qstylehelper_p.h"
#include <qstringbuilder.h>
@@ -387,5 +389,13 @@ void drawBorderPixmap(const QPixmap &pixmap, QPainter *painter, const QRect &rec
}
}
+
+QColor backgroundColor(const QPalette &pal, const QWidget* widget)
+{
+ if (qobject_cast<const QScrollBar *>(widget) && widget->parent() &&
+ qobject_cast<const QAbstractScrollArea *>(widget->parent()->parent()))
+ return widget->parentWidget()->parentWidget()->palette().color(QPalette::Base);
+ return pal.color(QPalette::Base);
+}
}
QT_END_NAMESPACE
diff --git a/src/widgets/styles/qstylehelper_p.h b/src/widgets/styles/qstylehelper_p.h
index 6355cbc985..73e5c94dcd 100644
--- a/src/widgets/styles/qstylehelper_p.h
+++ b/src/widgets/styles/qstylehelper_p.h
@@ -86,6 +86,7 @@ namespace QStyleHelper
bool isInstanceOf(QObject *obj, QAccessible::Role role);
bool hasAncestor(QObject *obj, QAccessible::Role role);
#endif
+ QColor backgroundColor(const QPalette &pal, const QWidget* widget = 0);
}
diff --git a/src/widgets/styles/qstylesheetstyle.cpp b/src/widgets/styles/qstylesheetstyle.cpp
index a22d0a3dca..b82aa1b5a0 100644
--- a/src/widgets/styles/qstylesheetstyle.cpp
+++ b/src/widgets/styles/qstylesheetstyle.cpp
@@ -2698,6 +2698,7 @@ void QStyleSheetStyle::polish(QWidget *w)
styleSheetCaches->styleRulesCache.remove(w);
styleSheetCaches->hasStyleRuleCache.remove(w);
styleSheetCaches->renderRulesCache.remove(w);
+ styleSheetCaches->styleSheetCache.remove(w);
}
setGeometry(w);
setProperties(w);
diff --git a/src/widgets/util/qsystemtrayicon_x11.cpp b/src/widgets/util/qsystemtrayicon_x11.cpp
index 27d0418dff..06eaf86004 100644
--- a/src/widgets/util/qsystemtrayicon_x11.cpp
+++ b/src/widgets/util/qsystemtrayicon_x11.cpp
@@ -86,6 +86,7 @@ protected:
virtual void mouseDoubleClickEvent(QMouseEvent *ev);
virtual bool event(QEvent *);
virtual void paintEvent(QPaintEvent *);
+ virtual void resizeEvent(QResizeEvent *);
private slots:
void systemTrayWindowChanged(QScreen *screen);
@@ -208,6 +209,11 @@ void QSystemTrayIconSys::paintEvent(QPaintEvent *)
q->icon().paint(&painter, rect);
}
+void QSystemTrayIconSys::resizeEvent(QResizeEvent *)
+{
+ update();
+}
+
////////////////////////////////////////////////////////////////////////////
QSystemTrayIconPrivate::QSystemTrayIconPrivate()
diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp
index f857f4eac0..eae0cbbd06 100644
--- a/src/widgets/widgets/qcombobox.cpp
+++ b/src/widgets/widgets/qcombobox.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QtWidgets module of the Qt Toolkit.
@@ -1085,6 +1085,19 @@ void QComboBoxPrivate::updateViewContainerPaletteAndOpacity()
lineEdit->setPalette(q->palette());
}
+void QComboBoxPrivate::updateFocusPolicy()
+{
+#ifdef Q_OS_OSX
+ Q_Q(QComboBox);
+
+ // See comment in QComboBoxPrivate::init()
+ if (q->isEditable())
+ q->setFocusPolicy(Qt::WheelFocus);
+ else
+ q->setFocusPolicy(Qt::TabFocus);
+#endif
+}
+
/*!
Initialize \a option with the values from this QComboBox. This method
is useful for subclasses when they need a QStyleOptionComboBox, but don't want
@@ -1691,10 +1704,6 @@ void QComboBox::setEditable(bool editable)
}
QLineEdit *le = new QLineEdit(this);
setLineEdit(le);
-#ifdef Q_OS_MAC
- // See comment in QComboBoxPrivate::init()
- setFocusPolicy(Qt::WheelFocus);
-#endif
} else {
if (style()->styleHint(QStyle::SH_ComboBox_Popup, &opt, this)) {
d->viewContainer()->updateScrollers();
@@ -1704,12 +1713,10 @@ void QComboBox::setEditable(bool editable)
d->lineEdit->hide();
d->lineEdit->deleteLater();
d->lineEdit = 0;
-#ifdef Q_OS_MAC
- // See comment in QComboBoxPrivate::init()
- setFocusPolicy(Qt::TabFocus);
-#endif
}
+ d->updateFocusPolicy();
+
d->viewContainer()->updateTopBottomMargin();
if (!testAttribute(Qt::WA_Resized))
adjustSize();
@@ -1743,6 +1750,7 @@ void QComboBox::setLineEdit(QLineEdit *edit)
connect(d->lineEdit, SIGNAL(textChanged(QString)), this, SIGNAL(currentTextChanged(QString)));
d->lineEdit->setFrame(false);
d->lineEdit->setContextMenuPolicy(Qt::NoContextMenu);
+ d->updateFocusPolicy();
d->lineEdit->setFocusProxy(this);
d->lineEdit->setAttribute(Qt::WA_MacShowFocusRect, false);
#ifndef QT_NO_COMPLETER
@@ -2055,7 +2063,7 @@ void QComboBoxPrivate::setCurrentIndex(const QModelIndex &mi)
if (indexChanged)
currentIndex = QPersistentModelIndex(normalized);
if (lineEdit) {
- QString newText = q->itemText(normalized.row());
+ const QString newText = itemText(normalized);
if (lineEdit->text() != newText)
lineEdit->setText(newText);
updateLineEditGeometry();
@@ -2377,6 +2385,16 @@ QSize QComboBox::sizeHint() const
}
#ifdef Q_OS_OSX
+
+namespace {
+struct IndexSetter {
+ int index;
+ QComboBox *cb;
+
+ void operator()(void) { cb->setCurrentIndex(index); }
+};
+}
+
/*!
* \internal
*
@@ -2391,13 +2409,6 @@ bool QComboBoxPrivate::showNativePopup()
if (QPlatformMenu *menu = theme->createPlatformMenu()) {
int itemsCount = q->count();
- struct IndexSetter {
- int index;
- QComboBox *cb;
-
- void operator()(void) { cb->setCurrentIndex(index); }
- };
-
QList<QPlatformMenuItem *> items;
items.reserve(itemsCount);
QPlatformMenuItem *currentItem = 0;
diff --git a/src/widgets/widgets/qcombobox_p.h b/src/widgets/widgets/qcombobox_p.h
index dceffe8d35..fb1ed71ee6 100644
--- a/src/widgets/widgets/qcombobox_p.h
+++ b/src/widgets/widgets/qcombobox_p.h
@@ -376,6 +376,7 @@ public:
void keyboardSearchString(const QString &text);
void modelChanged();
void updateViewContainerPaletteAndOpacity();
+ void updateFocusPolicy();
#ifdef Q_OS_OSX
bool showNativePopup();
diff --git a/src/widgets/widgets/qfontcombobox.cpp b/src/widgets/widgets/qfontcombobox.cpp
index 40ca73904c..db01543629 100644
--- a/src/widgets/widgets/qfontcombobox.cpp
+++ b/src/widgets/widgets/qfontcombobox.cpp
@@ -548,7 +548,7 @@ bool QFontComboBox::event(QEvent *e)
if (e->type() == QEvent::Resize) {
QListView *lview = qobject_cast<QListView*>(view());
if (lview) {
- setFixedWidth(qMin(width() * 5 / 3,
+ lview->window()->setFixedWidth(qMin(width() * 5 / 3,
QApplication::desktop()->availableGeometry(lview).width()));
}
}
diff --git a/src/widgets/widgets/qmainwindow.cpp b/src/widgets/widgets/qmainwindow.cpp
index 358569a5e4..36ca90ba00 100644
--- a/src/widgets/widgets/qmainwindow.cpp
+++ b/src/widgets/widgets/qmainwindow.cpp
@@ -1226,7 +1226,9 @@ Qt::DockWidgetArea QMainWindow::dockWidgetArea(QDockWidget *dockwidget) const
/*!
Saves the current state of this mainwindow's toolbars and
- dockwidgets. The \a version number is stored as part of the data.
+ dockwidgets. This includes the corner settings which can
+ be set with setCorner(). The \a version number is stored
+ as part of the data.
The \l{QObject::objectName}{objectName} property is used
to identify each QToolBar and QDockWidget. You should make sure
@@ -1255,8 +1257,9 @@ QByteArray QMainWindow::saveState(int version) const
/*!
Restores the \a state of this mainwindow's toolbars and
- dockwidgets. The \a version number is compared with that stored
- in \a state. If they do not match, the mainwindow's state is left
+ dockwidgets. Also restores the corner settings too. The
+ \a version number is compared with that stored in \a state.
+ If they do not match, the mainwindow's state is left
unchanged, and this function returns \c false; otherwise, the state
is restored, and this function returns \c true.
diff --git a/src/widgets/widgets/qstackedwidget.cpp b/src/widgets/widgets/qstackedwidget.cpp
index 4b7170a596..6dbc7c8fad 100644
--- a/src/widgets/widgets/qstackedwidget.cpp
+++ b/src/widgets/widgets/qstackedwidget.cpp
@@ -91,7 +91,7 @@ public:
the list using the addWidget() function, or inserted at a given
index using the insertWidget() function. The removeWidget()
function removes a widget from the stacked widget. The number of
- widgets contained in the stacked widget, can
+ widgets contained in the stacked widget can
be obtained using the count() function.
The widget() function returns the widget at a given index
diff --git a/src/widgets/widgets/qtoolbar.cpp b/src/widgets/widgets/qtoolbar.cpp
index 3fd615c3c7..1c05529cd6 100644
--- a/src/widgets/widgets/qtoolbar.cpp
+++ b/src/widgets/widgets/qtoolbar.cpp
@@ -59,6 +59,10 @@
#include <private/qwidgetaction_p.h>
#include <private/qmainwindowlayout_p.h>
+#ifdef Q_OS_OSX
+#include <qpa/qplatformnativeinterface.h>
+#endif
+
#include "qtoolbar_p.h"
#include "qtoolbarseparator_p.h"
#include "qtoolbarlayout_p.h"
diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp
index da348e4edc..a6b1aceb66 100644
--- a/src/widgets/widgets/qwidgettextcontrol.cpp
+++ b/src/widgets/widgets/qwidgettextcontrol.cpp
@@ -1694,9 +1694,6 @@ void QWidgetTextControlPrivate::mouseMoveEvent(QEvent *e, Qt::MouseButton button
return;
}
- if (!mousePressed)
- return;
-
const qreal mouseX = qreal(mousePos.x());
int newCursorPos = q->hitTest(mousePos, Qt::FuzzyHit);
@@ -1717,7 +1714,7 @@ void QWidgetTextControlPrivate::mouseMoveEvent(QEvent *e, Qt::MouseButton button
if (newCursorPos == -1)
return;
- if (wordSelectionEnabled && !selectedWordOnDoubleClick.hasSelection()) {
+ if (mousePressed && wordSelectionEnabled && !selectedWordOnDoubleClick.hasSelection()) {
selectedWordOnDoubleClick = cursor;
selectedWordOnDoubleClick.select(QTextCursor::WordUnderCursor);
}
@@ -1726,7 +1723,7 @@ void QWidgetTextControlPrivate::mouseMoveEvent(QEvent *e, Qt::MouseButton button
extendBlockwiseSelection(newCursorPos);
else if (selectedWordOnDoubleClick.hasSelection())
extendWordwiseSelection(newCursorPos, mouseX);
- else if (!isPreediting())
+ else if (mousePressed && !isPreediting())
setCursorPosition(newCursorPos, QTextCursor::KeepAnchor);
if (interactionFlags & Qt::TextEditable) {
diff --git a/tests/auto/corelib/io/qdebug/qdebug.pro b/tests/auto/corelib/io/qdebug/qdebug.pro
index 820c17fc69..5e902bb105 100644
--- a/tests/auto/corelib/io/qdebug/qdebug.pro
+++ b/tests/auto/corelib/io/qdebug/qdebug.pro
@@ -1,5 +1,5 @@
CONFIG += testcase parallel_test
TARGET = tst_qdebug
-QT = core testlib
+QT = core testlib concurrent
SOURCES = tst_qdebug.cpp
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
diff --git a/tests/auto/corelib/io/qdebug/tst_qdebug.cpp b/tests/auto/corelib/io/qdebug/tst_qdebug.cpp
index 07e011f449..3f53ab5f0a 100644
--- a/tests/auto/corelib/io/qdebug/tst_qdebug.cpp
+++ b/tests/auto/corelib/io/qdebug/tst_qdebug.cpp
@@ -44,6 +44,9 @@
#include <QtCore/QtDebug>
#include <QtTest/QtTest>
+#include <QtConcurrentRun>
+#include <QFutureSynchronizer>
+
class tst_QDebug: public QObject
{
Q_OBJECT
@@ -59,6 +62,7 @@ private slots:
void qDebugQLatin1String() const;
void textStreamModifiers() const;
void defaultMessagehandler() const;
+ void threadSafety() const;
};
void tst_QDebug::assignment() const
@@ -315,5 +319,41 @@ void tst_QDebug::defaultMessagehandler() const
QVERIFY(same);
}
+QMutex s_mutex;
+QStringList s_messages;
+QSemaphore s_sema;
+
+static void threadSafeMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
+{
+ QMutexLocker lock(&s_mutex);
+ s_messages.append(msg);
+ Q_UNUSED(type);
+ Q_UNUSED(context);
+}
+
+static void doDebug() // called in each thread
+{
+ s_sema.acquire();
+ qDebug() << "doDebug";
+}
+
+void tst_QDebug::threadSafety() const
+{
+ MessageHandlerSetter mhs(threadSafeMessageHandler);
+ const int numThreads = 10;
+ QThreadPool::globalInstance()->setMaxThreadCount(numThreads);
+ QFutureSynchronizer<void> sync;
+ for (int i = 0; i < numThreads; ++i) {
+ sync.addFuture(QtConcurrent::run(&doDebug));
+ }
+ s_sema.release(numThreads);
+ sync.waitForFinished();
+ QMutexLocker lock(&s_mutex);
+ QCOMPARE(s_messages.count(), numThreads);
+ for (int i = 0; i < numThreads; ++i) {
+ QCOMPARE(s_messages.at(i), QStringLiteral("doDebug"));
+ }
+}
+
QTEST_MAIN(tst_QDebug);
#include "tst_qdebug.moc"
diff --git a/tests/auto/corelib/io/qprocess/test/test.pro b/tests/auto/corelib/io/qprocess/test/test.pro
index 79ea53cc6b..90afeddaa0 100644
--- a/tests/auto/corelib/io/qprocess/test/test.pro
+++ b/tests/auto/corelib/io/qprocess/test/test.pro
@@ -2,7 +2,6 @@ CONFIG += testcase
CONFIG += parallel_test
CONFIG -= app_bundle debug_and_release_target
QT = core testlib network
-embedded: QT += gui
SOURCES = ../tst_qprocess.cpp
TARGET = ../tst_qprocess
diff --git a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
index 67cf954f98..1d6418cbc0 100644
--- a/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
+++ b/tests/auto/corelib/io/qprocess/tst_qprocess.cpp
@@ -1953,7 +1953,7 @@ void tst_QProcess::setStandardOutputFile2()
process.start("testProcessEcho2/testProcessEcho2");
process.write(testdata, sizeof testdata);
QPROCESS_VERIFY(process,waitForFinished());
- QVERIFY(!process.bytesAvailable());
+ QCOMPARE(process.bytesAvailable(), Q_INT64_C(0));
QVERIFY(!QFileInfo(QProcess::nullDevice()).isFile());
}
diff --git a/tests/auto/corelib/plugin/qpluginloader/qpluginloader.pro b/tests/auto/corelib/plugin/qpluginloader/qpluginloader.pro
index 8d117793bf..f5d06b3de9 100644
--- a/tests/auto/corelib/plugin/qpluginloader/qpluginloader.pro
+++ b/tests/auto/corelib/plugin/qpluginloader/qpluginloader.pro
@@ -4,7 +4,7 @@ CONFIG += ordered
SUBDIRS = lib \
theplugin \
tst
-!win32: !mac: SUBDIRS += almostplugin
+!android: !win32: !mac: SUBDIRS += almostplugin
macx-*: SUBDIRS += machtest
TARGET = tst_qpluginloader
diff --git a/tests/auto/corelib/tools/qcollator/tst_qcollator.cpp b/tests/auto/corelib/tools/qcollator/tst_qcollator.cpp
index 3df8422a34..3a00ebd505 100644
--- a/tests/auto/corelib/tools/qcollator/tst_qcollator.cpp
+++ b/tests/auto/corelib/tools/qcollator/tst_qcollator.cpp
@@ -52,6 +52,9 @@ class tst_QCollator : public QObject
private Q_SLOTS:
void moveSemantics();
+
+ void compare_data();
+ void compare();
};
#ifdef Q_COMPILER_RVALUE_REFS
@@ -87,6 +90,96 @@ void tst_QCollator::moveSemantics()
#endif
}
+
+void tst_QCollator::compare_data()
+{
+ QTest::addColumn<QString>("locale");
+ QTest::addColumn<QString>("s1");
+ QTest::addColumn<QString>("s2");
+ QTest::addColumn<int>("result");
+ QTest::addColumn<int>("caseInsensitiveResult");
+
+ /*
+ A few tests below are commented out on the mac. It's unclear why they fail,
+ as it looks like the collator for the locale is created correctly.
+ */
+
+ /*
+ It's hard to test English, because it's treated differently
+ on different platforms. For example, on Linux, it uses the
+ iso14651_t1 template file, which happens to provide good
+ defaults for Swedish. Mac OS X seems to do a pure bytewise
+ comparison of Latin-1 values, although I'm not sure. So I
+ just test digits to make sure that it's not totally broken.
+ */
+ QTest::newRow("english1") << QString("en_US") << QString("5") << QString("4") << 1 << 1;
+ QTest::newRow("english2") << QString("en_US") << QString("4") << QString("6") << -1 << -1;
+ QTest::newRow("english3") << QString("en_US") << QString("5") << QString("6") << -1 << -1;
+ QTest::newRow("english4") << QString("en_US") << QString("a") << QString("b") << -1 << -1;
+ /*
+ In Swedish, a with ring above (E5) comes before a with
+ diaresis (E4), which comes before o diaresis (F6), which
+ all come after z.
+ */
+#if !defined(Q_OS_WIN) || defined(QT_USE_ICU)
+ QTest::newRow("swedish1") << QString("sv_SE") << QString::fromLatin1("\xe5") << QString::fromLatin1("\xe4") << -1 << -1;
+#endif
+ QTest::newRow("swedish2") << QString("sv_SE") << QString::fromLatin1("\xe4") << QString::fromLatin1("\xf6") << -1 << -1;
+ QTest::newRow("swedish3") << QString("sv_SE") << QString::fromLatin1("\xe5") << QString::fromLatin1("\xf6") << -1 << -1;
+#if !defined(Q_OS_OSX) && (!defined(Q_OS_WIN) || defined(QT_USE_ICU))
+ QTest::newRow("swedish4") << QString("sv_SE") << QString::fromLatin1("z") << QString::fromLatin1("\xe5") << -1 << -1;
+#endif
+
+ /*
+ In Norwegian, ae (E6) comes before o with stroke (D8), which
+ comes before a with ring above (E5).
+ */
+ QTest::newRow("norwegian1") << QString("no_NO") << QString::fromLatin1("\xe6") << QString::fromLatin1("\xd8") << -1 << -1;
+#if !defined(Q_OS_WIN) || defined(QT_USE_ICU)
+# ifndef Q_OS_OSX
+ QTest::newRow("norwegian2") << QString("no_NO") << QString::fromLatin1("\xd8") << QString::fromLatin1("\xe5") << -1 << -1;
+# endif
+ QTest::newRow("norwegian3") << QString("no_NO") << QString::fromLatin1("\xe6") << QString::fromLatin1("\xe5") << -1 << -1;
+#endif // !Q_OS_WIN || QT_USE_ICU
+ /*
+ In German, z comes *after* a with diaresis (E4),
+ which comes before o diaresis (F6).
+ */
+ QTest::newRow("german1") << QString("de_DE") << QString::fromLatin1("a") << QString::fromLatin1("\xe4") << -1 << -1;
+ QTest::newRow("german2") << QString("de_DE") << QString::fromLatin1("b") << QString::fromLatin1("\xe4") << 1 << 1;
+ QTest::newRow("german3") << QString("de_DE") << QString::fromLatin1("z") << QString::fromLatin1("\xe4") << 1 << 1;
+ QTest::newRow("german4") << QString("de_DE") << QString::fromLatin1("\xe4") << QString::fromLatin1("\xf6") << -1 << -1;
+ QTest::newRow("german5") << QString("de_DE") << QString::fromLatin1("z") << QString::fromLatin1("\xf6") << 1 << 1;
+ QTest::newRow("german6") << QString("de_DE") << QString::fromLatin1("\xc0") << QString::fromLatin1("\xe0") << 1 << 0;
+ QTest::newRow("german7") << QString("de_DE") << QString::fromLatin1("\xd6") << QString::fromLatin1("\xf6") << 1 << 0;
+ QTest::newRow("german8") << QString("de_DE") << QString::fromLatin1("oe") << QString::fromLatin1("\xf6") << 1 << 1;
+ QTest::newRow("german9") << QString("de_DE") << QString("A") << QString("a") << 1 << 0;
+
+ /*
+ French sorting of e and e with accent
+ */
+ QTest::newRow("french1") << QString("fr_FR") << QString::fromLatin1("\xe9") << QString::fromLatin1("e") << 1 << 1;
+ QTest::newRow("french2") << QString("fr_FR") << QString::fromLatin1("\xe9t") << QString::fromLatin1("et") << 1 << 1;
+ QTest::newRow("french3") << QString("fr_FR") << QString::fromLatin1("\xe9") << QString::fromLatin1("d") << 1 << 1;
+ QTest::newRow("french4") << QString("fr_FR") << QString::fromLatin1("\xe9") << QString::fromLatin1("f") << -1 << -1;
+
+}
+
+
+void tst_QCollator::compare()
+{
+ QFETCH(QString, locale);
+ QFETCH(QString, s1);
+ QFETCH(QString, s2);
+ QFETCH(int, result);
+ QFETCH(int, caseInsensitiveResult);
+
+ QCollator collator(locale);
+ QCOMPARE(collator.compare(s1, s2), result);
+ collator.setCaseSensitivity(Qt::CaseInsensitive);
+ QCOMPARE(collator.compare(s1, s2), caseInsensitiveResult);
+}
+
QTEST_APPLESS_MAIN(tst_QCollator)
#include "tst_qcollator.moc"
diff --git a/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp b/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp
index 6780493206..285cc3042a 100644
--- a/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp
+++ b/tests/auto/corelib/tools/qringbuffer/tst_qringbuffer.cpp
@@ -111,6 +111,13 @@ void tst_QRingBuffer::readPointerAtPositionWithHead()
buf2 = ringBuffer.readPointerAtPosition(0, length);
QCOMPARE(length, qint64(0));
QVERIFY(buf2 == 0);
+
+ // check buffer with 2 blocks
+ memcpy(ringBuffer.reserve(4), "0123", 4);
+ ringBuffer.append(QByteArray("45678", 5));
+ ringBuffer.free(3);
+ buf2 = ringBuffer.readPointerAtPosition(1, length);
+ QCOMPARE(length, qint64(5));
}
void tst_QRingBuffer::readPointerAtPositionEmptyRead()
diff --git a/tests/auto/gui/image/qicon/tst_qicon.cpp b/tests/auto/gui/image/qicon/tst_qicon.cpp
index 0f642bcc10..524f0a30ed 100644
--- a/tests/auto/gui/image/qicon/tst_qicon.cpp
+++ b/tests/auto/gui/image/qicon/tst_qicon.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the test suite of the Qt Toolkit.
@@ -55,6 +55,7 @@ public:
tst_QIcon();
private slots:
+ void initTestCase();
void actualSize_data(); // test with 1 pixmap
void actualSize();
void actualSize2_data(); // test with 2 pixmaps with different aspect ratio
@@ -79,6 +80,10 @@ private slots:
private:
bool haveImageFormat(QByteArray const&);
+ const QString m_pngImageFileName;
+ const QString m_pngRectFileName;
+ const QString m_sourceFileName;
+
const static QIcon staticIcon;
};
@@ -92,9 +97,19 @@ bool tst_QIcon::haveImageFormat(QByteArray const& desiredFormat)
}
tst_QIcon::tst_QIcon()
+ : m_pngImageFileName(QFINDTESTDATA("image.png"))
+ , m_pngRectFileName(QFINDTESTDATA("rect.png"))
+ , m_sourceFileName(QFINDTESTDATA(__FILE__))
{
}
+void tst_QIcon::initTestCase()
+{
+ QVERIFY(!m_pngImageFileName.isEmpty());
+ QVERIFY(!m_pngRectFileName.isEmpty());
+ QVERIFY(!m_sourceFileName.isEmpty());
+}
+
void tst_QIcon::actualSize_data()
{
QTest::addColumn<QString>("source");
@@ -115,14 +130,13 @@ void tst_QIcon::actualSize_data()
QTest::newRow("resource9") << ":/rect.png" << QSize( 15, 50) << QSize( 15, 30);
QTest::newRow("resource10") << ":/rect.png" << QSize( 25, 50) << QSize( 20, 40);
- const QString prefix = QFileInfo(QFINDTESTDATA("icons")).absolutePath() + "/";
- QTest::newRow("external0") << prefix + "image.png" << QSize(128, 128) << QSize(128, 128);
- QTest::newRow("external1") << prefix + "image.png" << QSize( 64, 64) << QSize( 64, 64);
- QTest::newRow("external2") << prefix + "image.png" << QSize( 32, 64) << QSize( 32, 32);
- QTest::newRow("external3") << prefix + "image.png" << QSize( 16, 64) << QSize( 16, 16);
- QTest::newRow("external4") << prefix + "image.png" << QSize( 16, 128) << QSize( 16, 16);
- QTest::newRow("external5") << prefix + "image.png" << QSize( 128, 16) << QSize( 16, 16);
- QTest::newRow("external6") << prefix + "image.png" << QSize( 150, 150) << QSize( 128, 128);
+ QTest::newRow("external0") << m_pngImageFileName << QSize(128, 128) << QSize(128, 128);
+ QTest::newRow("external1") << m_pngImageFileName << QSize( 64, 64) << QSize( 64, 64);
+ QTest::newRow("external2") << m_pngImageFileName << QSize( 32, 64) << QSize( 32, 32);
+ QTest::newRow("external3") << m_pngImageFileName << QSize( 16, 64) << QSize( 16, 16);
+ QTest::newRow("external4") << m_pngImageFileName << QSize( 16, 128) << QSize( 16, 16);
+ QTest::newRow("external5") << m_pngImageFileName << QSize(128, 16) << QSize( 16, 16);
+ QTest::newRow("external6") << m_pngImageFileName << QSize(150, 150) << QSize(128, 128);
// rect image
QTest::newRow("external7") << ":/rect.png" << QSize( 20, 40) << QSize( 20, 40);
QTest::newRow("external8") << ":/rect.png" << QSize( 10, 20) << QSize( 10, 20);
@@ -170,10 +184,8 @@ void tst_QIcon::actualSize2_data()
void tst_QIcon::actualSize2()
{
QIcon icon;
- const QString prefix = QFileInfo(QFINDTESTDATA("icons")).absolutePath() + "/";
-
- icon.addPixmap(QPixmap(prefix + "image.png"));
- icon.addPixmap(QPixmap(prefix + "rect.png"));
+ icon.addPixmap(m_pngImageFileName);
+ icon.addPixmap(m_pngRectFileName);
QFETCH(QSize, argument);
QFETCH(QSize, result);
@@ -209,14 +221,13 @@ void tst_QIcon::isNull() {
QVERIFY(!iconNoFileSuffix.isNull());
QVERIFY(!iconNoFileSuffix.actualSize(QSize(32, 32)).isValid());
- const QString prefix = QFileInfo(QFINDTESTDATA("icons")).absolutePath() + "/";
// test string constructor with existing file but unsupported format
- QIcon iconUnsupportedFormat = QIcon(prefix + "tst_qicon.cpp");
+ QIcon iconUnsupportedFormat = QIcon(m_sourceFileName);
QVERIFY(!iconUnsupportedFormat.isNull());
QVERIFY(!iconUnsupportedFormat.actualSize(QSize(32, 32)).isValid());
// test string constructor with existing file and supported format
- QIcon iconSupportedFormat = QIcon(prefix + "image.png");
+ QIcon iconSupportedFormat = QIcon(m_pngImageFileName);
QVERIFY(!iconSupportedFormat.isNull());
QVERIFY(iconSupportedFormat.actualSize(QSize(32, 32)).isValid());
}
@@ -347,7 +358,7 @@ void tst_QIcon::bestMatch()
void tst_QIcon::cacheKey()
{
- QIcon icon1("image.png");
+ QIcon icon1(m_pngImageFileName);
qint64 icon1_key = icon1.cacheKey();
QIcon icon2 = icon1;
@@ -363,7 +374,7 @@ void tst_QIcon::detach()
img.fill(0xffff0000);
QIcon icon1(QPixmap::fromImage(img));
QIcon icon2 = icon1;
- icon2.addFile(QFINDTESTDATA("image.png"), QSize(64, 64));
+ icon2.addFile(m_pngImageFileName, QSize(64, 64));
QImage img1 = icon1.pixmap(64, 64).toImage();
QImage img2 = icon2.pixmap(64, 64).toImage();
@@ -415,11 +426,11 @@ void tst_QIcon::availableSizes()
{
{
QIcon icon;
- icon.addFile("image.png", QSize(32,32));
- icon.addFile("image.png", QSize(64,64));
- icon.addFile("image.png", QSize(128,128));
- icon.addFile("image.png", QSize(256,256), QIcon::Disabled);
- icon.addFile("image.png", QSize(16,16), QIcon::Normal, QIcon::On);
+ icon.addFile(m_pngImageFileName, QSize(32,32));
+ icon.addFile(m_pngImageFileName, QSize(64,64));
+ icon.addFile(m_pngImageFileName, QSize(128,128));
+ icon.addFile(m_pngImageFileName, QSize(256,256), QIcon::Disabled);
+ icon.addFile(m_pngImageFileName, QSize(16,16), QIcon::Normal, QIcon::On);
QList<QSize> availableSizes = icon.availableSizes();
QCOMPARE(availableSizes.size(), 3);
@@ -542,7 +553,7 @@ static inline bool operator<(const QSize &lhs, const QSize &rhs)
#ifndef QT_NO_WIDGETS
void tst_QIcon::task184901_badCache()
{
- QPixmap pm(QFINDTESTDATA("image.png"));
+ QPixmap pm(m_pngImageFileName);
QIcon icon(pm);
//the disabled icon must have an effect (grayed)
diff --git a/tests/auto/gui/image/qimage/tst_qimage.cpp b/tests/auto/gui/image/qimage/tst_qimage.cpp
index d2072e0e56..0a4456e22a 100644
--- a/tests/auto/gui/image/qimage/tst_qimage.cpp
+++ b/tests/auto/gui/image/qimage/tst_qimage.cpp
@@ -146,6 +146,9 @@ private slots:
void fillRGB888();
+ void fillPixel_data();
+ void fillPixel();
+
void rgbSwapped_data();
void rgbSwapped();
@@ -2058,6 +2061,42 @@ void tst_QImage::fillRGB888()
}
}
+void tst_QImage::fillPixel_data()
+{
+ QTest::addColumn<QImage::Format>("format");
+ QTest::addColumn<uint>("color");
+ QTest::addColumn<uint>("pixelValue");
+
+ QTest::newRow("RGB16, transparent") << QImage::Format_RGB16 << 0x0u << 0xff000000u;
+ QTest::newRow("RGB32, transparent") << QImage::Format_RGB32 << 0x0u << 0xff000000u;
+ QTest::newRow("RGBx8888, transparent") << QImage::Format_RGBX8888 << 0x0u << 0xff000000u;
+ QTest::newRow("ARGB32, transparent") << QImage::Format_ARGB32 << 0x0u << 0x00000000u;
+ QTest::newRow("ARGB32pm, transparent") << QImage::Format_ARGB32_Premultiplied << 0x0u << 0x00000000u;
+ QTest::newRow("RGBA8888pm, transparent") << QImage::Format_RGBA8888_Premultiplied << 0x0u << 0x00000000u;
+
+ QTest::newRow("RGB16, red") << QImage::Format_RGB16 << (uint)qConvertRgb32To16(0xffff0000) << 0xffff0000u;
+ QTest::newRow("RGB32, red") << QImage::Format_RGB32 << 0xffff0000u << 0xffff0000u;
+ QTest::newRow("ARGB32, red") << QImage::Format_ARGB32 << 0xffff0000u << 0xffff0000u;
+ QTest::newRow("RGBA8888, red") << QImage::Format_RGBA8888 << 0xff0000ffu << 0xffff0000u;
+
+ QTest::newRow("RGB32, semi-red") << QImage::Format_RGB32 << 0x80ff0000u << 0xffff0000u;
+ QTest::newRow("ARGB32, semi-red") << QImage::Format_ARGB32 << 0x80ff0000u << 0x80ff0000u;
+ QTest::newRow("ARGB32pm, semi-red") << QImage::Format_ARGB32 << 0x80800000u << 0x80800000u;
+ QTest::newRow("RGBA8888pm, semi-red") << QImage::Format_RGBA8888_Premultiplied << 0x80000080u << 0x80800000u;
+}
+
+void tst_QImage::fillPixel()
+{
+ QFETCH(QImage::Format, format);
+ QFETCH(uint, color);
+ QFETCH(uint, pixelValue);
+
+ QImage image(1, 1, format);
+
+ image.fill(color);
+ QCOMPARE(image.pixel(0, 0), pixelValue);
+}
+
void tst_QImage::rgbSwapped_data()
{
QTest::addColumn<QImage::Format>("format");
@@ -2128,35 +2167,56 @@ void tst_QImage::mirrored_data()
QTest::addColumn<QImage::Format>("format");
QTest::addColumn<bool>("swap_vertical");
QTest::addColumn<bool>("swap_horizontal");
-
- QTest::newRow("Format_RGB32, vertical") << QImage::Format_RGB32 << true << false;
- QTest::newRow("Format_ARGB32, vertical") << QImage::Format_ARGB32 << true << false;
- QTest::newRow("Format_ARGB32_Premultiplied, vertical") << QImage::Format_ARGB32_Premultiplied << true << false;
- QTest::newRow("Format_RGB16, vertical") << QImage::Format_RGB16 << true << false;
- QTest::newRow("Format_ARGB8565_Premultiplied, vertical") << QImage::Format_ARGB8565_Premultiplied << true << false;
- QTest::newRow("Format_ARGB6666_Premultiplied, vertical") << QImage::Format_ARGB6666_Premultiplied << true << false;
- QTest::newRow("Format_ARGB4444_Premultiplied, vertical") << QImage::Format_ARGB4444_Premultiplied << true << false;
- QTest::newRow("Format_RGB666, vertical") << QImage::Format_RGB666 << true << false;
- QTest::newRow("Format_RGB555, vertical") << QImage::Format_RGB555 << true << false;
- QTest::newRow("Format_ARGB8555_Premultiplied, vertical") << QImage::Format_ARGB8555_Premultiplied << true << false;
- QTest::newRow("Format_RGB888, vertical") << QImage::Format_RGB888 << true << false;
- QTest::newRow("Format_RGB444, vertical") << QImage::Format_RGB444 << true << false;
- QTest::newRow("Format_RGBX8888, vertical") << QImage::Format_RGBX8888 << true << false;
- QTest::newRow("Format_RGBA8888_Premultiplied, vertical") << QImage::Format_RGBA8888_Premultiplied << true << false;
- QTest::newRow("Format_Indexed8, vertical") << QImage::Format_Indexed8 << true << false;
- QTest::newRow("Format_Mono, vertical") << QImage::Format_Mono << true << false;
-
- QTest::newRow("Format_ARGB32_Premultiplied, horizontal") << QImage::Format_ARGB32_Premultiplied << false << true;
- QTest::newRow("Format_RGB888, horizontal") << QImage::Format_RGB888 << false << true;
- QTest::newRow("Format_RGB16, horizontal") << QImage::Format_RGB16 << false << true;
- QTest::newRow("Format_Indexed8, horizontal") << QImage::Format_Indexed8 << false << true;
- QTest::newRow("Format_Mono, horizontal") << QImage::Format_Mono << false << true;
-
- QTest::newRow("Format_ARGB32_Premultiplied, horizontal+vertical") << QImage::Format_ARGB32_Premultiplied << true << true;
- QTest::newRow("Format_RGB888, horizontal+vertical") << QImage::Format_RGB888 << true << true;
- QTest::newRow("Format_RGB16, horizontal+vertical") << QImage::Format_RGB16 << true << true;
- QTest::newRow("Format_Indexed8, horizontal+vertical") << QImage::Format_Indexed8 << true << true;
- QTest::newRow("Format_Mono, horizontal+vertical") << QImage::Format_Mono << true << true;
+ QTest::addColumn<int>("width");
+ QTest::addColumn<int>("height");
+
+ QTest::newRow("Format_RGB32, vertical") << QImage::Format_RGB32 << true << false << 16 << 16;
+ QTest::newRow("Format_ARGB32, vertical") << QImage::Format_ARGB32 << true << false << 16 << 16;
+ QTest::newRow("Format_ARGB32_Premultiplied, vertical") << QImage::Format_ARGB32_Premultiplied << true << false << 16 << 16;
+ QTest::newRow("Format_RGB16, vertical") << QImage::Format_RGB16 << true << false << 16 << 16;
+ QTest::newRow("Format_ARGB8565_Premultiplied, vertical") << QImage::Format_ARGB8565_Premultiplied << true << false << 16 << 16;
+ QTest::newRow("Format_ARGB6666_Premultiplied, vertical") << QImage::Format_ARGB6666_Premultiplied << true << false << 16 << 16;
+ QTest::newRow("Format_ARGB4444_Premultiplied, vertical") << QImage::Format_ARGB4444_Premultiplied << true << false << 16 << 16;
+ QTest::newRow("Format_RGB666, vertical") << QImage::Format_RGB666 << true << false << 16 << 16;
+ QTest::newRow("Format_RGB555, vertical") << QImage::Format_RGB555 << true << false << 16 << 16;
+ QTest::newRow("Format_ARGB8555_Premultiplied, vertical") << QImage::Format_ARGB8555_Premultiplied << true << false << 16 << 16;
+ QTest::newRow("Format_RGB888, vertical") << QImage::Format_RGB888 << true << false << 16 << 16;
+ QTest::newRow("Format_RGB444, vertical") << QImage::Format_RGB444 << true << false << 16 << 16;
+ QTest::newRow("Format_RGBX8888, vertical") << QImage::Format_RGBX8888 << true << false << 16 << 16;
+ QTest::newRow("Format_RGBA8888_Premultiplied, vertical") << QImage::Format_RGBA8888_Premultiplied << true << false << 16 << 16;
+ QTest::newRow("Format_Indexed8, vertical") << QImage::Format_Indexed8 << true << false << 16 << 16;
+ QTest::newRow("Format_Mono, vertical") << QImage::Format_Mono << true << false << 16 << 16;
+ QTest::newRow("Format_MonoLSB, vertical") << QImage::Format_MonoLSB << true << false << 16 << 16;
+
+ QTest::newRow("Format_ARGB32_Premultiplied, horizontal") << QImage::Format_ARGB32_Premultiplied << false << true << 16 << 16;
+ QTest::newRow("Format_RGB888, horizontal") << QImage::Format_RGB888 << false << true << 16 << 16;
+ QTest::newRow("Format_RGB16, horizontal") << QImage::Format_RGB16 << false << true << 16 << 16;
+ QTest::newRow("Format_Indexed8, horizontal") << QImage::Format_Indexed8 << false << true << 16 << 16;
+ QTest::newRow("Format_Mono, horizontal") << QImage::Format_Mono << false << true << 16 << 16;
+ QTest::newRow("Format_MonoLSB, horizontal") << QImage::Format_MonoLSB << false << true << 16 << 16;
+
+ QTest::newRow("Format_ARGB32_Premultiplied, horizontal+vertical") << QImage::Format_ARGB32_Premultiplied << true << true << 16 << 16;
+ QTest::newRow("Format_RGB888, horizontal+vertical") << QImage::Format_RGB888 << true << true << 16 << 16;
+ QTest::newRow("Format_RGB16, horizontal+vertical") << QImage::Format_RGB16 << true << true << 16 << 16;
+ QTest::newRow("Format_Indexed8, horizontal+vertical") << QImage::Format_Indexed8 << true << true << 16 << 16;
+ QTest::newRow("Format_Mono, horizontal+vertical") << QImage::Format_Mono << true << true << 16 << 16;
+ QTest::newRow("Format_MonoLSB, horizontal+vertical") << QImage::Format_MonoLSB << true << true << 16 << 16;
+
+ QTest::newRow("Format_RGB32, vertical") << QImage::Format_RGB32 << true << false << 8 << 16;
+ QTest::newRow("Format_ARGB32, vertical") << QImage::Format_ARGB32 << true << false << 16 << 8;
+ QTest::newRow("Format_Mono, vertical, non-aligned") << QImage::Format_Mono << true << false << 19 << 25;
+ QTest::newRow("Format_MonoLSB, vertical, non-aligned") << QImage::Format_MonoLSB << true << false << 19 << 25;
+
+ // Non-aligned horizontal 1-bit needs special handling so test this.
+ QTest::newRow("Format_Mono, horizontal, non-aligned") << QImage::Format_Mono << false << true << 13 << 17;
+ QTest::newRow("Format_Mono, horizontal, non-aligned") << QImage::Format_Mono << false << true << 19 << 25;
+ QTest::newRow("Format_Mono, horizontal+vertical, non-aligned") << QImage::Format_Mono << true << true << 25 << 47;
+ QTest::newRow("Format_Mono, horizontal+vertical, non-aligned") << QImage::Format_Mono << true << true << 21 << 16;
+
+ QTest::newRow("Format_MonoLSB, horizontal, non-aligned") << QImage::Format_MonoLSB << false << true << 13 << 17;
+ QTest::newRow("Format_MonoLSB, horizontal, non-aligned") << QImage::Format_MonoLSB << false << true << 19 << 25;
+ QTest::newRow("Format_MonoLSB, horizontal+vertical, non-aligned") << QImage::Format_MonoLSB << true << true << 25 << 47;
+ QTest::newRow("Format_MonoLSB, horizontal+vertical, non-aligned") << QImage::Format_MonoLSB << true << true << 21 << 16;
}
void tst_QImage::mirrored()
@@ -2164,11 +2224,14 @@ void tst_QImage::mirrored()
QFETCH(QImage::Format, format);
QFETCH(bool, swap_vertical);
QFETCH(bool, swap_horizontal);
+ QFETCH(int, width);
+ QFETCH(int, height);
- QImage image(16, 16, format);
+ QImage image(width, height, format);
switch (format) {
case QImage::Format_Mono:
+ case QImage::Format_MonoLSB:
for (int i = 0; i < image.height(); ++i) {
ushort* scanLine = (ushort*)image.scanLine(i);
*scanLine = (i % 2) ? 0x5555U : 0xCCCCU;
@@ -2205,7 +2268,7 @@ void tst_QImage::mirrored()
QCOMPARE(image, imageMirroredTwice);
- if (format != QImage::Format_Mono)
+ if (format != QImage::Format_Mono && format != QImage::Format_MonoLSB)
QCOMPARE(memcmp(image.constBits(), imageMirroredTwice.constBits(), image.byteCount()), 0);
else {
for (int i = 0; i < image.height(); ++i)
diff --git a/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp b/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp
index 79dc3f311a..b9d0adcd21 100644
--- a/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp
+++ b/tests/auto/gui/image/qpixmap/tst_qpixmap.cpp
@@ -91,6 +91,7 @@ private slots:
void convertFromImage_data();
void convertFromImage();
+ void convertFromImageShouldDetach();
void testMetrics();
@@ -343,6 +344,20 @@ void tst_QPixmap::convertFromImage()
QCOMPARE(pix, res);
}
+void tst_QPixmap::convertFromImageShouldDetach()
+{
+ const QString prefix = QFINDTESTDATA("convertFromImage");
+ QImage img1;
+ QImage img2;
+ QVERIFY(img1.load(prefix + "/task31722_0/img1.png"));
+ QVERIFY(img2.load(prefix + "/task31722_0/img2.png"));
+ QPixmap pix = QPixmap::fromImage(img1);
+ QPixmap pix1 = pix;
+ pix.convertFromImage(img2);
+ QCOMPARE(pix, QPixmap::fromImage(img2));
+ QCOMPARE(pix1, QPixmap::fromImage(img1)); // unchanged
+}
+
void tst_QPixmap::scroll_data()
{
QTest::addColumn<QImage>("input");
diff --git a/tests/auto/network/access/qnetworkdiskcache/tst_qnetworkdiskcache.cpp b/tests/auto/network/access/qnetworkdiskcache/tst_qnetworkdiskcache.cpp
index 44edcc66c0..4740b92b84 100644
--- a/tests/auto/network/access/qnetworkdiskcache/tst_qnetworkdiskcache.cpp
+++ b/tests/auto/network/access/qnetworkdiskcache/tst_qnetworkdiskcache.cpp
@@ -62,6 +62,7 @@ public slots:
void cleanupTestCase();
void init();
void cleanup();
+ void accessAfterRemoveReadyReadSlot();
private slots:
void qnetworkdiskcache_data();
@@ -74,6 +75,7 @@ private slots:
void data();
void metaData();
void remove();
+ void accessAfterRemove(); // QTBUG-17400
void setCacheDirectory_data();
void setCacheDirectory();
void updateMetaData();
@@ -89,6 +91,8 @@ private slots:
private:
QTemporaryDir tempDir;
+ QUrl url; // used by accessAfterRemove()
+ QNetworkDiskCache *diskCache; // used by accessAfterRemove()
};
// FIXME same as in tst_qnetworkreply.cpp .. could be unified
@@ -370,6 +374,40 @@ void tst_QNetworkDiskCache::remove()
QCOMPARE(countFiles(cacheDirectory).count(), NUM_SUBDIRECTORIES + 2);
}
+void tst_QNetworkDiskCache::accessAfterRemove() // QTBUG-17400
+{
+ QByteArray data("HTTP/1.1 200 OK\r\n"
+ "Content-Length: 1\r\n"
+ "\r\n"
+ "a");
+
+ MiniHttpServer server(data);
+
+ QNetworkAccessManager *manager = new QNetworkAccessManager();
+ SubQNetworkDiskCache subCache;
+ subCache.setCacheDirectory(QLatin1String("cacheDir"));
+ diskCache = &subCache;
+ manager->setCache(&subCache);
+
+ url = QUrl("http://127.0.0.1:" + QString::number(server.serverPort()));
+ QNetworkRequest request(url);
+
+ QNetworkReply *reply = manager->get(request);
+ connect(reply, SIGNAL(readyRead()), this, SLOT(accessAfterRemoveReadyReadSlot()));
+ connect(reply, SIGNAL(finished()), &QTestEventLoop::instance(), SLOT(exitLoop()));
+
+ QTestEventLoop::instance().enterLoop(5);
+ QVERIFY(!QTestEventLoop::instance().timeout());
+
+ reply->deleteLater();
+ manager->deleteLater();
+}
+
+void tst_QNetworkDiskCache::accessAfterRemoveReadyReadSlot()
+{
+ diskCache->remove(url); // this used to cause a crash later on
+}
+
void tst_QNetworkDiskCache::setCacheDirectory_data()
{
QTest::addColumn<QString>("cacheDir");
diff --git a/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp b/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp
index c4d42206fe..99f677643c 100644
--- a/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp
+++ b/tests/auto/network/kernel/qhostaddress/tst_qhostaddress.cpp
@@ -55,6 +55,10 @@
# endif
#endif
+#ifdef Q_OS_ANDROID
+# include <netinet/in.h>
+#endif
+
class tst_QHostAddress : public QObject
{
Q_OBJECT
diff --git a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp
index 122ac63034..8e69d827a6 100644
--- a/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp
+++ b/tests/auto/network/socket/qtcpsocket/tst_qtcpsocket.cpp
@@ -1976,9 +1976,9 @@ public slots:
attemptedToConnect = true;
sock->connectToHost(QtNetworkSettings::serverName(), 80);
-#ifdef Q_OS_MAC
+#if defined(Q_OS_MAC)
pthread_yield_np();
-#elif defined Q_OS_LINUX
+#elif defined Q_OS_LINUX && !defined Q_OS_ANDROID
pthread_yield();
#endif
if (!sock->waitForConnected()) {
@@ -2485,7 +2485,7 @@ void tst_QTcpSocket::increaseReadBufferSizeFromSlot() // like KIO's socketconnec
QVERIFY2(passive->waitForBytesWritten(5000), "Network timeout");
// set the read buffer size to less than what was written,
- // and increase it from the slot, first to 384 then to 1024.
+ // and increase it from the slot, first to 384 then to 512.
active->setReadBufferSize(256);
enterLoop(10);
QVERIFY2(!timeout(), "Network timeout");
diff --git a/tests/auto/other/macgui/tst_macgui.cpp b/tests/auto/other/macgui/tst_macgui.cpp
index 14993145b4..4314842c50 100644
--- a/tests/auto/other/macgui/tst_macgui.cpp
+++ b/tests/auto/other/macgui/tst_macgui.cpp
@@ -203,6 +203,7 @@ void tst_MacGui::nonModalOrder()
primary.resize(400, 400);
primary.move(100, 100);
primary.exec();
+ QEXPECT_FAIL("", "Non-modal child windows show behind the modal dialig", Abort);
QCOMPARE(primary.frontWidget, primary.secondaryWindow);
}
diff --git a/tests/auto/other/other.pro b/tests/auto/other/other.pro
index 0ae94fe415..745c8f2499 100644
--- a/tests/auto/other/other.pro
+++ b/tests/auto/other/other.pro
@@ -22,6 +22,7 @@ SUBDIRS=\
qobjectperformance \
qobjectrace \
qsharedpointer_and_qwidget \
+ qprocess_and_guieventloop \
qtokenautomaton \
windowsmobile \
@@ -70,3 +71,5 @@ wince*|!contains(QT_CONFIG, accessibility): SUBDIRS -= qaccessibility
!embedded|wince*: SUBDIRS -= \
qdirectpainter
+winrt: SUBDIRS -= \
+ qprocess_and_guieventloop
diff --git a/tests/auto/other/qprocess_and_guieventloop/qprocess_and_guieventloop.pro b/tests/auto/other/qprocess_and_guieventloop/qprocess_and_guieventloop.pro
new file mode 100644
index 0000000000..e349fe5b11
--- /dev/null
+++ b/tests/auto/other/qprocess_and_guieventloop/qprocess_and_guieventloop.pro
@@ -0,0 +1,4 @@
+TEMPLATE = subdirs
+SUBDIRS = \
+ write-read-write
+SUBDIRS += test.pro
diff --git a/tests/auto/other/qprocess_and_guieventloop/test.pro b/tests/auto/other/qprocess_and_guieventloop/test.pro
new file mode 100644
index 0000000000..54d6f194b0
--- /dev/null
+++ b/tests/auto/other/qprocess_and_guieventloop/test.pro
@@ -0,0 +1,5 @@
+CONFIG += testcase
+CONFIG += parallel_test
+QT = core gui testlib
+SOURCES = tst_qprocess_and_guieventloop.cpp
+TARGET = tst_qprocess_and_guieventloop
diff --git a/tests/auto/other/qprocess_and_guieventloop/tst_qprocess_and_guieventloop.cpp b/tests/auto/other/qprocess_and_guieventloop/tst_qprocess_and_guieventloop.cpp
new file mode 100644
index 0000000000..42153c6c80
--- /dev/null
+++ b/tests/auto/other/qprocess_and_guieventloop/tst_qprocess_and_guieventloop.cpp
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Intel Corporation
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtGui/QGuiApplication>
+#include <QtTest/QtTest>
+#include <QtCore/QProcess>
+
+class tst_QProcess_and_GuiEventLoop : public QObject
+{
+ Q_OBJECT
+private slots:
+ void waitForAndEventLoop();
+};
+
+
+void tst_QProcess_and_GuiEventLoop::waitForAndEventLoop()
+{
+ // based on testcase provided in QTBUG-39488
+ QByteArray msg = "Hello World";
+
+ QProcess process;
+ process.start("write-read-write/write-read-write", QStringList() << msg);
+ QVERIFY(process.waitForStarted(5000));
+ QVERIFY(process.waitForReadyRead(5000));
+ QCOMPARE(process.readAll().trimmed(), msg);
+
+ // run the GUI event dispatcher once
+ QSignalSpy spy(&process, SIGNAL(readyRead()));
+ qApp->processEvents(QEventLoop::AllEvents, 100);
+
+ // we mustn't have read anything in the event loop
+ QCOMPARE(spy.count(), 0);
+
+ // ensure the process hasn't died
+ QVERIFY(!process.waitForFinished(250));
+
+ // we mustn't have read anything during waitForFinished either
+ QCOMPARE(spy.count(), 0);
+
+ // release the child for the second write
+ process.write("\n");
+ QVERIFY(process.waitForFinished(5000));
+ QCOMPARE(int(process.exitStatus()), int(QProcess::NormalExit));
+ QCOMPARE(process.exitCode(), 0);
+ QCOMPARE(spy.count(), 1);
+ QCOMPARE(process.readAll().trimmed(), msg);
+}
+
+QTEST_MAIN(tst_QProcess_and_GuiEventLoop)
+
+#include "tst_qprocess_and_guieventloop.moc"
diff --git a/tests/auto/other/qprocess_and_guieventloop/write-read-write/main.cpp b/tests/auto/other/qprocess_and_guieventloop/write-read-write/main.cpp
new file mode 100644
index 0000000000..e8fc3b5cff
--- /dev/null
+++ b/tests/auto/other/qprocess_and_guieventloop/write-read-write/main.cpp
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Intel Corporation
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** 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 Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/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 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 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 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <stdio.h>
+
+int main(int argc, char **argv)
+{
+ const char *msg = argv[1];
+ char buf[2];
+
+ puts(msg);
+ fflush(stdout);
+
+ // wait for a newline
+ fgets(buf, sizeof buf, stdin);
+
+ puts(msg);
+ fflush(stdout);
+ return 0;
+}
diff --git a/tests/auto/other/qprocess_and_guieventloop/write-read-write/write-read-write.pro b/tests/auto/other/qprocess_and_guieventloop/write-read-write/write-read-write.pro
new file mode 100644
index 0000000000..e236e05c7d
--- /dev/null
+++ b/tests/auto/other/qprocess_and_guieventloop/write-read-write/write-read-write.pro
@@ -0,0 +1,4 @@
+SOURCES = main.cpp
+CONFIG -= qt app_bundle
+CONFIG += console
+DESTDIR = ./
diff --git a/tests/auto/tools/moc/tst_moc.cpp b/tests/auto/tools/moc/tst_moc.cpp
index c5469bd33a..9a737ef96b 100644
--- a/tests/auto/tools/moc/tst_moc.cpp
+++ b/tests/auto/tools/moc/tst_moc.cpp
@@ -1839,6 +1839,12 @@ void tst_Moc::warnings_data()
<< QString("IGNORE_ALL_STDOUT")
<< QString(":3: Warning: Macro argument mismatch.\n:4: Warning: Macro argument mismatch.");
+ QTest::newRow("Class declaration lacks Q_OBJECT macro.")
+ << QByteArray("class X : public QObject \n { \n public slots: \n void foo() {} \n };")
+ << QStringList()
+ << 1
+ << QString()
+ << QString("standard input:5: Error: Class declaration lacks Q_OBJECT macro.");
}
void tst_Moc::warnings()
diff --git a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
index 34936fa5b8..eac8ab2236 100644
--- a/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
+++ b/tests/auto/widgets/kernel/qwidget/tst_qwidget.cpp
@@ -1210,6 +1210,12 @@ void tst_QWidget::isEnabledTo()
QVERIFY( !childWidget->isEnabledTo( testWidget ) );
QVERIFY( grandChildWidget->isEnabledTo( childWidget ) );
QVERIFY( !grandChildWidget->isEnabledTo( testWidget ) );
+
+ QMainWindow* childDialog = new QMainWindow(testWidget);
+ testWidget->setEnabled(false);
+ QVERIFY(!childDialog->isEnabled());
+ QVERIFY(childDialog->isEnabledTo(0));
+ testWidget->setEnabled(true);
}
void tst_QWidget::visible()
diff --git a/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp b/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp
index 14d59d3630..b1e43b69ad 100644
--- a/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp
+++ b/tests/auto/widgets/styles/qstylesheetstyle/tst_qstylesheetstyle.cpp
@@ -106,7 +106,7 @@ private slots:
void changeStyleInChangeEvent();
void QTBUG15910_crashNullWidget();
void QTBUG36933_brokenPseudoClassLookup();
-
+ void styleSheetChangeBeforePolish();
//at the end because it mess with the style.
void widgetStyle();
void appStyle();
@@ -147,7 +147,7 @@ tst_QStyleSheetStyle::~tst_QStyleSheetStyle()
void tst_QStyleSheetStyle::numinstances()
{
- QWidget w;
+ /*QWidget w;
w.resize(200, 200);
centerOnScreen(&w);
QCommonStyle *style = new QCommonStyle;
@@ -180,7 +180,7 @@ void tst_QStyleSheetStyle::numinstances()
c.setStyle(style);
QCOMPARE(QStyleSheetStyle::numinstances, 2);
w.setStyleSheet("");
- QCOMPARE(QStyleSheetStyle::numinstances, 0);
+ QCOMPARE(QStyleSheetStyle::numinstances, 0);*/
}
void tst_QStyleSheetStyle::widgetsBeforeAppStyleSheet()
@@ -351,7 +351,7 @@ void tst_QStyleSheetStyle::repolish()
void tst_QStyleSheetStyle::widgetStyle()
{
- qApp->setStyleSheet("");
+ /*qApp->setStyleSheet("");
QWidget *window1 = new QWidget;
window1->setObjectName("window1");
@@ -488,12 +488,12 @@ void tst_QStyleSheetStyle::widgetStyle()
delete widget2;
delete window2;
delete style1;
- delete style2;
+ delete style2;*/
}
void tst_QStyleSheetStyle::appStyle()
{
- qApp->setStyleSheet("");
+ /* qApp->setStyleSheet("");
// qApp style can never be 0
QVERIFY(QApplication::style() != 0);
QPointer<QStyle> style1 = QStyleFactory::create("Windows");
@@ -531,7 +531,7 @@ void tst_QStyleSheetStyle::appStyle()
QVERIFY(qApp->style() == style1);
qApp->setStyleSheet("");
- QVERIFY(qApp->style() == style1);
+ QVERIFY(qApp->style() == style1);*/
}
void tst_QStyleSheetStyle::dynamicProperty()
@@ -1754,6 +1754,29 @@ void tst_QStyleSheetStyle::QTBUG36933_brokenPseudoClassLookup()
QVERIFY(testForColors(image, QColor(0xFF, 0x00, 0x00)));
}
+void tst_QStyleSheetStyle::styleSheetChangeBeforePolish()
+{
+ QWidget widget;
+ QVBoxLayout *vbox = new QVBoxLayout(&widget);
+ QFrame *frame = new QFrame(&widget);
+ frame->setFixedSize(200, 200);
+ frame->setStyleSheet("background-color: #FF0000;");
+ frame->setStyleSheet("background-color: #00FF00;");
+ vbox->addWidget(frame);
+ QFrame *frame2 = new QFrame(&widget);
+ frame2->setFixedSize(200, 200);
+ frame2->setStyleSheet("background-color: #FF0000;");
+ frame2->setStyleSheet("background-color: #00FF00;");
+ vbox->addWidget(frame);
+ widget.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&widget));
+ QImage image(frame->size(), QImage::Format_ARGB32);
+ frame->render(&image);
+ QVERIFY(testForColors(image, QColor(0x00, 0xFF, 0x00)));
+ QImage image2(frame2->size(), QImage::Format_ARGB32);
+ frame2->render(&image2);
+ QVERIFY(testForColors(image2, QColor(0x00, 0xFF, 0x00)));
+}
QTEST_MAIN(tst_QStyleSheetStyle)
#include "tst_qstylesheetstyle.moc"
diff --git a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
index abc0129f8b..c38c254b9a 100644
--- a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
+++ b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the test suite of the Qt Toolkit.
@@ -72,6 +72,7 @@
#include <qstylefactory.h>
#include <qabstractitemview.h>
#include <qstyleditemdelegate.h>
+#include <qstandarditemmodel.h>
#include <qproxystyle.h>
static inline void setFrameless(QWidget *w)
@@ -163,6 +164,7 @@ private slots:
void itemData();
void task_QTBUG_31146_popupCompletion();
void keyboardSelection();
+ void setCustomModelAndView();
};
class MyAbstractItemDelegate : public QAbstractItemDelegate
@@ -1580,6 +1582,45 @@ void tst_QComboBox::setModel()
QVERIFY(box.model() != oldModel);
}
+void tst_QComboBox::setCustomModelAndView()
+{
+ // QTBUG-27597, ensure the correct text is returned when using custom view and a tree model.
+ QComboBox combo;
+ combo.setWindowTitle("QTBUG-27597, setCustomModelAndView");
+ combo.setEditable(true);
+ combo.setMinimumWidth(400);
+ const QRect availableGeometry = QGuiApplication::primaryScreen()->availableGeometry();
+ combo.move(availableGeometry.center() - QPoint(200, 20));
+
+ QStandardItemModel *model = new QStandardItemModel(0, 1, &combo);
+
+ QStandardItem *item = new QStandardItem(QStringLiteral("Item1"));
+ item->appendRow(new QStandardItem(QStringLiteral("Item11")));
+ model->appendRow(item);
+
+ item = new QStandardItem(QStringLiteral("Item2"));
+ model->appendRow(item);
+ const QString subItem21Text = QStringLiteral("Item21");
+ QStandardItem *subItem = new QStandardItem(subItem21Text);
+ item->appendRow(subItem);
+
+ QTreeView* view = new QTreeView(&combo);
+ view->setHeaderHidden(true);
+ view->setSelectionMode(QAbstractItemView::SingleSelection);
+ view->setModel(model);
+ view->expandAll();
+ combo.setModel(model);
+ combo.setView(view);
+ combo.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&combo));
+ combo.showPopup();
+ QTRY_VERIFY(combo.view()->isVisible());
+ const QRect subItemRect = view->visualRect(model->indexFromItem(subItem));
+ QWidget *window = view->window();
+ QTest::mouseClick(window->windowHandle(), Qt::LeftButton, 0, view->mapTo(window, subItemRect.center()));
+ QTRY_COMPARE(combo.currentText(), subItem21Text);
+}
+
void tst_QComboBox::modelDeleted()
{
QComboBox box;