summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorFrederik Gladhorn <frederik.gladhorn@digia.com>2014-07-01 18:41:14 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-07-01 18:41:14 +0200
commite6a94778d0c26b59e367e9f9fe4f401725fc9c4e (patch)
treec7597213d7eac14863bc3cfd7bccd247c8950710 /src
parent605ba2c2268b2dce3d0b06899101d03a67e7f251 (diff)
parenta09a8d509a69ed16d8afbe15296b8332cacd6c66 (diff)
Merge "Merge remote-tracking branch 'origin/5.3' into dev" into refs/staging/dev
Diffstat (limited to 'src')
-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
161 files changed, 1663 insertions, 1082 deletions
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) {