summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Context.cpp6
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Context.h1
-rw-r--r--src/3rdparty/angle/src/libGLESv2/Shader.cpp9
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.cpp5
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.h2
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp2
-rw-r--r--src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp2
-rw-r--r--src/3rdparty/pcre/patches/pcre-r1513.patch18
-rw-r--r--src/3rdparty/pcre/pcre_exec.c7
-rw-r--r--src/android/accessibility/jar/jar.pri3
-rw-r--r--src/android/accessibility/jar/src/org/qtproject/qt5/android/accessibility/QtAccessibilityDelegate.java74
-rw-r--r--src/android/android.pro1
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java34
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtSurface.java20
-rw-r--r--src/android/java/res/layout/splash.xml4
-rw-r--r--src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java2
-rw-r--r--src/angle/patches/0018-ANGLE-Fix-releasing-textures-after-we-kill-D3D11.patch106
-rw-r--r--src/angle/patches/0019-ANGLE-Fix-handling-of-shader-source-with-fixed-lengt.patch37
-rw-r--r--src/corelib/codecs/qtextcodec.cpp4
-rw-r--r--src/corelib/global/qlogging.cpp18
-rw-r--r--src/corelib/io/qdebug.cpp4
-rw-r--r--src/corelib/io/qfiledevice.cpp6
-rw-r--r--src/corelib/io/qfilesystemwatcher_fsevents.mm3
-rw-r--r--src/corelib/io/qloggingcategory.cpp8
-rw-r--r--src/corelib/io/qprocess.cpp10
-rw-r--r--src/corelib/io/qstandardpaths.cpp8
-rw-r--r--src/corelib/io/qtemporarydir.cpp2
-rw-r--r--src/corelib/io/qtextstream.cpp16
-rw-r--r--src/corelib/io/qurl.cpp13
-rw-r--r--src/corelib/kernel/qfunctions_winrt.cpp4
-rw-r--r--src/corelib/kernel/qfunctions_winrt.h61
-rw-r--r--src/corelib/kernel/qjni.cpp83
-rw-r--r--src/corelib/kernel/qtranslator.cpp20
-rw-r--r--src/corelib/tools/qalgorithms.qdoc88
-rw-r--r--src/dbus/dbus.pro3
-rw-r--r--src/dbus/dbus_minimal_p.h275
-rw-r--r--src/dbus/qdbus_symbols_p.h7
-rw-r--r--src/dbus/qdbusintegrator.cpp2
-rw-r--r--src/dbus/qdbusreply.cpp2
-rw-r--r--src/gui/image/qimage_p.h6
-rw-r--r--src/gui/kernel/qopenglwindow.cpp6
-rw-r--r--src/gui/opengl/qopenglframebufferobject.cpp4
-rw-r--r--src/gui/opengl/qopenglpaintengine.cpp53
-rw-r--r--src/gui/opengl/qopenglpaintengine_p.h2
-rw-r--r--src/gui/painting/qdrawhelper.cpp7
-rw-r--r--src/gui/text/qfontengine_ft.cpp22
-rw-r--r--src/gui/text/qfontengine_ft_p.h2
-rw-r--r--src/network/access/qhttpthreaddelegate.cpp2
-rw-r--r--src/network/access/qnetworkreply.cpp6
-rw-r--r--src/network/socket/qabstractsocket.cpp3
-rw-r--r--src/network/socket/qnativesocketengine_winrt.cpp3
-rw-r--r--src/network/ssl/qsslcertificate.cpp4
-rw-r--r--src/network/ssl/qsslcertificate.h2
-rw-r--r--src/network/ssl/qsslsocket_openssl.cpp2
-rw-r--r--src/network/ssl/qsslsocket_openssl_p.h2
-rw-r--r--src/network/ssl/qsslsocket_winrt.cpp2
-rw-r--r--src/network/ssl/qsslsocket_winrt_p.h2
-rw-r--r--src/plugins/platforms/android/androidjniinput.cpp43
-rw-r--r--src/plugins/platforms/android/qandroidinputcontext.cpp4
-rw-r--r--src/plugins/platforms/android/qandroidplatformscreen.cpp15
-rw-r--r--src/plugins/platforms/android/qandroidplatformtheme.cpp3
-rw-r--r--src/plugins/platforms/cocoa/qcocoamenuloader.mm6
-rw-r--r--src/plugins/platforms/ios/qiosinputcontext.h26
-rw-r--r--src/plugins/platforms/ios/qiosinputcontext.mm300
-rw-r--r--src/plugins/platforms/ios/qiosintegration.mm8
-rw-r--r--src/plugins/platforms/ios/qiosscreen.h1
-rw-r--r--src/plugins/platforms/ios/qiosscreen.mm5
-rw-r--r--src/plugins/platforms/windows/qwindowscontext.cpp3
-rw-r--r--src/plugins/platforms/windows/qwindowscursor.cpp15
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase.cpp6
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp23
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.h2
-rw-r--r--src/plugins/platforms/winrt/qwinrtscreen.cpp23
-rw-r--r--src/sql/kernel/qsqldriver.cpp6
-rw-r--r--src/sql/kernel/qsqldriver.h6
-rw-r--r--src/sql/kernel/qsqldriver_p.h4
-rw-r--r--src/tools/qdoc/doc/examples/componentset/ProgressBar.qml2
-rw-r--r--src/tools/qdoc/doc/examples/componentset/Switch.qml2
-rw-r--r--src/tools/qdoc/doc/examples/componentset/TabWidget.qml2
-rw-r--r--src/tools/qdoc/doc/examples/qml.qdoc.sample2
-rw-r--r--src/tools/qdoc/doc/qdoc-manual-topiccmds.qdoc7
-rw-r--r--src/widgets/itemviews/qabstractitemview.cpp6
-rw-r--r--src/widgets/itemviews/qcolumnview.cpp7
-rw-r--r--src/widgets/itemviews/qheaderview.cpp11
-rw-r--r--src/widgets/kernel/qapplication.cpp33
-rw-r--r--src/widgets/kernel/qapplication_p.h1
-rw-r--r--src/widgets/kernel/qlayout.cpp3
-rw-r--r--src/widgets/kernel/qstandardgestures.cpp23
-rw-r--r--src/widgets/styles/qandroidstyle.cpp32
-rw-r--r--src/widgets/styles/qcommonstyle.cpp7
-rw-r--r--src/widgets/styles/qmacstyle_mac.mm2
-rw-r--r--src/widgets/styles/qstyle.cpp3
-rw-r--r--src/widgets/styles/qwindowsvistastyle.cpp3
-rw-r--r--src/widgets/widgets/qcombobox.cpp4
-rw-r--r--src/widgets/widgets/qdockwidget.cpp2
-rw-r--r--src/widgets/widgets/qmainwindowlayout.cpp2
-rw-r--r--src/widgets/widgets/qmenubar.cpp5
-rw-r--r--src/widgets/widgets/qtoolbar.cpp2
-rw-r--r--src/widgets/widgets/qwidgettextcontrol.cpp11
99 files changed, 1257 insertions, 514 deletions
diff --git a/src/3rdparty/angle/src/libGLESv2/Context.cpp b/src/3rdparty/angle/src/libGLESv2/Context.cpp
index b87689cd3f..3772da6f42 100644
--- a/src/3rdparty/angle/src/libGLESv2/Context.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/Context.cpp
@@ -162,12 +162,6 @@ Context::~Context()
deleteTransformFeedback(mTransformFeedbackMap.begin()->first);
}
- for (TextureMap::iterator i = mIncompleteTextures.begin(); i != mIncompleteTextures.end(); i++)
- {
- i->second.set(NULL);
- }
- mIncompleteTextures.clear();
-
for (TextureMap::iterator i = mZeroTextures.begin(); i != mZeroTextures.end(); i++)
{
i->second.set(NULL);
diff --git a/src/3rdparty/angle/src/libGLESv2/Context.h b/src/3rdparty/angle/src/libGLESv2/Context.h
index 1e890de3ef..0699592d91 100644
--- a/src/3rdparty/angle/src/libGLESv2/Context.h
+++ b/src/3rdparty/angle/src/libGLESv2/Context.h
@@ -247,7 +247,6 @@ class Context
int mClientVersion;
TextureMap mZeroTextures;
- TextureMap mIncompleteTextures;
typedef std::unordered_map<GLuint, Framebuffer*> FramebufferMap;
FramebufferMap mFramebufferMap;
diff --git a/src/3rdparty/angle/src/libGLESv2/Shader.cpp b/src/3rdparty/angle/src/libGLESv2/Shader.cpp
index 1cc17a0501..5bca746094 100644
--- a/src/3rdparty/angle/src/libGLESv2/Shader.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/Shader.cpp
@@ -51,7 +51,14 @@ void Shader::setSource(GLsizei count, const char *const *string, const GLint *le
for (int i = 0; i < count; i++)
{
- stream << string[i];
+ if (length == nullptr || length[i] < 0)
+ {
+ stream.write(string[i], std::strlen(string[i]));
+ }
+ else
+ {
+ stream.write(string[i], length[i]);
+ }
}
mSource = stream.str();
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.cpp
index 97da6da7fd..5cddd8ab5e 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.cpp
@@ -27,6 +27,11 @@ RendererD3D::RendererD3D(egl::Display *display)
RendererD3D::~RendererD3D()
{
+ cleanup();
+}
+
+void RendererD3D::cleanup()
+{
for (gl::TextureMap::iterator i = mIncompleteTextures.begin(); i != mIncompleteTextures.end(); ++i)
{
i->second.set(NULL);
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.h
index 9919207667..a2f778763c 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.h
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.h
@@ -160,6 +160,8 @@ class RendererD3D : public Renderer
const gl::Rectangle *scissor, bool blitRenderTarget,
bool blitDepth, bool blitStencil, GLenum filter) = 0;
+ void cleanup();
+
egl::Display *mDisplay;
private:
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
index e6d7f3025b..777308e6cc 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
@@ -1870,6 +1870,8 @@ bool Renderer11::testDeviceResettable()
void Renderer11::release()
{
+ RendererD3D::cleanup();
+
releaseShaderCompiler();
releaseDeviceResources();
diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
index 601cd24b10..18e6e2d7f0 100644
--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
@@ -151,6 +151,8 @@ Renderer9::~Renderer9()
void Renderer9::release()
{
+ RendererD3D::cleanup();
+
releaseShaderCompiler();
releaseDeviceResources();
diff --git a/src/3rdparty/pcre/patches/pcre-r1513.patch b/src/3rdparty/pcre/patches/pcre-r1513.patch
new file mode 100644
index 0000000000..d84aa0cc61
--- /dev/null
+++ b/src/3rdparty/pcre/patches/pcre-r1513.patch
@@ -0,0 +1,18 @@
+Index: pcre_exec.c
+===================================================================
+--- pcre_exec.c (revisione 1512)
++++ pcre_exec.c (revisione 1513)
+@@ -1404,8 +1404,11 @@
+ condition = TRUE;
+
+ /* Advance ecode past the assertion to the start of the first branch,
+- but adjust it so that the general choosing code below works. */
+-
++ but adjust it so that the general choosing code below works. If the
++ assertion has a quantifier that allows zero repeats we must skip over
++ the BRAZERO. This is a lunatic thing to do, but somebody did! */
++
++ if (*ecode == OP_BRAZERO) ecode++;
+ ecode += GET(ecode, 1);
+ while (*ecode == OP_ALT) ecode += GET(ecode, 1);
+ ecode += 1 + LINK_SIZE - PRIV(OP_lengths)[condcode];
diff --git a/src/3rdparty/pcre/pcre_exec.c b/src/3rdparty/pcre/pcre_exec.c
index b0101da351..7755aaf13a 100644
--- a/src/3rdparty/pcre/pcre_exec.c
+++ b/src/3rdparty/pcre/pcre_exec.c
@@ -1394,8 +1394,11 @@ for (;;)
condition = TRUE;
/* Advance ecode past the assertion to the start of the first branch,
- but adjust it so that the general choosing code below works. */
-
+ but adjust it so that the general choosing code below works. If the
+ assertion has a quantifier that allows zero repeats we must skip over
+ the BRAZERO. This is a lunatic thing to do, but somebody did! */
+
+ if (*ecode == OP_BRAZERO) ecode++;
ecode += GET(ecode, 1);
while (*ecode == OP_ALT) ecode += GET(ecode, 1);
ecode += 1 + LINK_SIZE - PRIV(OP_lengths)[condcode];
diff --git a/src/android/accessibility/jar/jar.pri b/src/android/accessibility/jar/jar.pri
index 23b3ff7087..3ae9fed59d 100644
--- a/src/android/accessibility/jar/jar.pri
+++ b/src/android/accessibility/jar/jar.pri
@@ -4,7 +4,8 @@ API_VERSION = android-16
PATHPREFIX = $$PWD/src/org/qtproject/qt5/android/accessibility
-JAVACLASSPATH += $$PWD/src/
+JAVACLASSPATH += $$PWD/src/ \
+ $$DESTDIR/QtAndroid-bundled.jar
JAVASOURCES += \
$$PATHPREFIX/QtAccessibilityDelegate.java \
$$PATHPREFIX/QtNativeAccessibility.java
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 a4626b9bb1..cc2aba7937 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
@@ -43,6 +43,7 @@
package org.qtproject.qt5.android.accessibility;
import android.accessibilityservice.AccessibilityService;
+import android.app.Activity;
import android.graphics.Rect;
import android.os.Bundle;
import android.util.Log;
@@ -60,6 +61,8 @@ import android.content.Context;
import java.util.LinkedList;
import java.util.List;
+import org.qtproject.qt5.android.QtActivityDelegate;
+
public class QtAccessibilityDelegate extends View.AccessibilityDelegate
{
private static final String TAG = "Qt A11Y";
@@ -72,8 +75,11 @@ public class QtAccessibilityDelegate extends View.AccessibilityDelegate
// Pretend to be an inner class of the QtSurface.
private static final String DEFAULT_CLASS_NAME = "$VirtualChild";
- private final View m_view;
- private final AccessibilityManager m_manager;
+ private View m_view = null;
+ private AccessibilityManager m_manager;
+ private QtActivityDelegate m_activityDelegate;
+ private Activity m_activity;
+ private ViewGroup m_layout;
// The accessible object that currently has the "accessibility focus"
// usually indicated by a yellow rectangle on screen.
@@ -95,17 +101,71 @@ public class QtAccessibilityDelegate extends View.AccessibilityDelegate
}
}
- public QtAccessibilityDelegate(View host)
+ public QtAccessibilityDelegate(Activity activity, ViewGroup layout, QtActivityDelegate activityDelegate)
{
- m_view = host;
- m_view.setOnHoverListener(new HoverEventListener());
- m_manager = (AccessibilityManager) host.getContext()
- .getSystemService(Context.ACCESSIBILITY_SERVICE);
+ m_activity = activity;
+ m_layout = layout;
+ m_activityDelegate = activityDelegate;
+
+ m_manager = (AccessibilityManager) m_activity.getSystemService(Context.ACCESSIBILITY_SERVICE);
+ if (m_manager != null) {
+ AccessibilityManagerListener accServiceListener = new AccessibilityManagerListener();
+ if (!m_manager.addAccessibilityStateChangeListener(accServiceListener))
+ Log.w("Qt A11y", "Could not register a11y state change listener");
+ if (m_manager.isEnabled())
+ accServiceListener.onAccessibilityStateChanged(true);
+ }
+
// Enable Qt Accessibility so that notifications are enabled
QtNativeAccessibility.setActive(true);
}
+ private class AccessibilityManagerListener implements AccessibilityManager.AccessibilityStateChangeListener
+ {
+ @Override
+ public void onAccessibilityStateChanged(boolean enabled)
+ {
+ if (enabled) {
+ // The accessibility code depends on android API level 16, so dynamically resolve it
+ if (android.os.Build.VERSION.SDK_INT >= 16) {
+ try {
+ View view = m_view;
+ if (view == null) {
+ view = new View(m_activity);
+ view.setId(View.NO_ID);
+ }
+
+ // ### Keep this for debugging for a while. It allows us to visually see that our View
+ // ### is on top of the surface(s)
+ // ColorDrawable color = new ColorDrawable(0x80ff8080); //0xAARRGGBB
+ // view.setBackground(color);
+ view.setAccessibilityDelegate(QtAccessibilityDelegate.this);
+
+ // if all is fine, add it to the layout
+ if (m_view == null) {
+ //m_layout.addAccessibilityView(view);
+ m_layout.addView(view, m_activityDelegate.getSurfaceCount(),
+ new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
+ }
+ m_view = view;
+
+ m_view.setOnHoverListener(new HoverEventListener());
+ } catch (Exception e) {
+ // Unknown exception means something went wrong.
+ Log.w("Qt A11y", "Unknown exception: " + e.toString());
+ }
+ }
+ } else {
+ if (m_view != null) {
+ m_layout.removeView(m_view);
+ m_view = null;
+ }
+ }
+ }
+ }
+
+
@Override
public AccessibilityNodeProvider getAccessibilityNodeProvider(View host)
{
diff --git a/src/android/android.pro b/src/android/android.pro
index 55a94a2c06..b17dd15cd4 100644
--- a/src/android/android.pro
+++ b/src/android/android.pro
@@ -1,2 +1,3 @@
TEMPLATE = subdirs
+CONFIG += ordered
SUBDIRS = jar java templates accessibility
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
index f44465b4c5..4d16d7e13f 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
@@ -80,6 +80,7 @@ import java.io.File;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.io.IOException;
+import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
@@ -321,7 +322,6 @@ public class QtActivityDelegate
m_layout.removeView(m_editText);
m_layout.addView(m_editText, new QtLayout.LayoutParams(width, height, x, y));
- m_editText.bringToFront();
m_editText.requestFocus();
m_editText.postDelayed(new Runnable() {
@Override
@@ -803,6 +803,22 @@ public class QtActivityDelegate
m_nativeViews = new HashMap<Integer, View>();
m_activity.registerForContextMenu(m_layout);
+ // Initialize accessibility
+ try {
+ final String a11yDelegateClassName = "org.qtproject.qt5.android.accessibility.QtAccessibilityDelegate";
+ Class<?> qtDelegateClass = Class.forName(a11yDelegateClassName);
+ Constructor constructor = qtDelegateClass.getConstructor(android.app.Activity.class,
+ android.view.ViewGroup.class,
+ this.getClass());
+ Object accessibilityDelegate = constructor.newInstance(m_activity, m_layout, this);
+ } catch (ClassNotFoundException e) {
+ // Class not found is fine since we are compatible with Android API < 16, but the function will
+ // only be available with that API level.
+ } catch (Exception e) {
+ // Unknown exception means something went wrong.
+ Log.w("Qt A11y", "Unknown exception: " + e.toString());
+ }
+
m_activity.setContentView(m_layout,
new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
@@ -1179,8 +1195,8 @@ public class QtActivityDelegate
// Native views are always inserted in the end of the stack (i.e., on top).
// All other views are stacked based on the order they are created.
- final int index = m_layout.getChildCount() - m_nativeViews.size() - 1;
- m_layout.addView(surface, index < 0 ? 0 : index);
+ final int surfaceCount = getSurfaceCount();
+ m_layout.addView(surface, surfaceCount);
m_surfaces.put(id, surface);
}
@@ -1221,12 +1237,18 @@ public class QtActivityDelegate
}
}
+ public int getSurfaceCount()
+ {
+ return m_surfaces.size();
+ }
+
public void bringChildToFront(int id)
{
View view = m_surfaces.get(id);
if (view != null) {
- final int index = m_layout.getChildCount() - m_nativeViews.size() - 1;
- m_layout.moveChild(view, index < 0 ? 0 : index);
+ final int surfaceCount = getSurfaceCount();
+ if (surfaceCount > 0)
+ m_layout.moveChild(view, surfaceCount - 1);
return;
}
@@ -1245,7 +1267,7 @@ public class QtActivityDelegate
view = m_nativeViews.get(id);
if (view != null) {
- final int index = m_layout.getChildCount() - m_nativeViews.size();
+ final int index = getSurfaceCount();
m_layout.moveChild(view, index);
}
}
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 ca3f20f11b..34fc31b222 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtSurface.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtSurface.java
@@ -88,26 +88,6 @@ public class QtSurface extends SurfaceView implements SurfaceHolder.Callback
public void surfaceCreated(SurfaceHolder holder)
{
QtNative.setSurface(getId(), holder.getSurface(), getWidth(), getHeight());
- // Initialize Accessibility
- // The accessibility code depends on android API level 16, so dynamically resolve it
- if (android.os.Build.VERSION.SDK_INT >= 16) {
- try {
- final String a11yDelegateClassName = "org.qtproject.qt5.android.accessibility.QtAccessibilityDelegate";
- Class<?> qtDelegateClass = Class.forName(a11yDelegateClassName);
- Constructor constructor = qtDelegateClass.getConstructor(Class.forName("android.view.View"));
- m_accessibilityDelegate = constructor.newInstance(this);
-
- Class a11yDelegateClass = Class.forName("android.view.View$AccessibilityDelegate");
- Method setDelegateMethod = this.getClass().getMethod("setAccessibilityDelegate", a11yDelegateClass);
- setDelegateMethod.invoke(this, m_accessibilityDelegate);
- } catch (ClassNotFoundException e) {
- // Class not found is fine since we are compatible with Android API < 16, but the function will
- // only be available with that API level.
- } catch (Exception e) {
- // Unknown exception means something went wrong.
- Log.w("Qt A11y", "Unknown exception: " + e.toString());
- }
- }
}
@Override
diff --git a/src/android/java/res/layout/splash.xml b/src/android/java/res/layout/splash.xml
index 6875521a12..476d91a844 100644
--- a/src/android/java/res/layout/splash.xml
+++ b/src/android/java/res/layout/splash.xml
@@ -1,2 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" />
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent" />
diff --git a/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java b/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java
index 0c52bc7530..75f10ad3ba 100644
--- a/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java
+++ b/src/android/java/src/org/qtproject/qt5/android/bindings/QtActivity.java
@@ -187,7 +187,7 @@ public class QtActivity extends Activity
QT_ANDROID_THEMES = new String[] {"Theme_Light"};
QT_ANDROID_DEFAULT_THEME = "Theme_Light";
}
- else if (Build.VERSION.SDK_INT >= 11 && Build.VERSION.SDK_INT <= 13) {
+ else if ((Build.VERSION.SDK_INT >= 11 && Build.VERSION.SDK_INT <= 13) || Build.VERSION.SDK_INT == 21){
QT_ANDROID_THEMES = new String[] {"Theme_Holo_Light"};
QT_ANDROID_DEFAULT_THEME = "Theme_Holo_Light";
} else {
diff --git a/src/angle/patches/0018-ANGLE-Fix-releasing-textures-after-we-kill-D3D11.patch b/src/angle/patches/0018-ANGLE-Fix-releasing-textures-after-we-kill-D3D11.patch
new file mode 100644
index 0000000000..97847ad684
--- /dev/null
+++ b/src/angle/patches/0018-ANGLE-Fix-releasing-textures-after-we-kill-D3D11.patch
@@ -0,0 +1,106 @@
+From 014d3fcf6011109491b0489da9c1abb1fdc6dbdc Mon Sep 17 00:00:00 2001
+From: Kai Koehne <kai.koehne@theqtcompany.com>
+Date: Mon, 24 Nov 2014 10:52:03 +0100
+Subject: [PATCH] ANGLE: Fix releasing textures after we kill D3D11
+
+Cherry-pick upstream commit cc4cd2925b9a4f1142a86df131345a861c9d7cd9
+to fix crashes on exit.
+
+Task-number: QTBUG-42772
+Change-Id: Ib74be17f2b5fdd58f9e0568e1da74ba19e943019
+---
+ src/3rdparty/angle/src/libGLESv2/Context.cpp | 6 ------
+ src/3rdparty/angle/src/libGLESv2/Context.h | 1 -
+ src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.cpp | 5 +++++
+ src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.h | 2 ++
+ src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp | 2 ++
+ src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp | 2 ++
+ 6 files changed, 11 insertions(+), 7 deletions(-)
+
+diff --git a/src/3rdparty/angle/src/libGLESv2/Context.cpp b/src/3rdparty/angle/src/libGLESv2/Context.cpp
+index b87689c..3772da6 100644
+--- a/src/3rdparty/angle/src/libGLESv2/Context.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/Context.cpp
+@@ -162,12 +162,6 @@ Context::~Context()
+ deleteTransformFeedback(mTransformFeedbackMap.begin()->first);
+ }
+
+- for (TextureMap::iterator i = mIncompleteTextures.begin(); i != mIncompleteTextures.end(); i++)
+- {
+- i->second.set(NULL);
+- }
+- mIncompleteTextures.clear();
+-
+ for (TextureMap::iterator i = mZeroTextures.begin(); i != mZeroTextures.end(); i++)
+ {
+ i->second.set(NULL);
+diff --git a/src/3rdparty/angle/src/libGLESv2/Context.h b/src/3rdparty/angle/src/libGLESv2/Context.h
+index 1e890de..0699592 100644
+--- a/src/3rdparty/angle/src/libGLESv2/Context.h
++++ b/src/3rdparty/angle/src/libGLESv2/Context.h
+@@ -247,7 +247,6 @@ class Context
+ int mClientVersion;
+
+ TextureMap mZeroTextures;
+- TextureMap mIncompleteTextures;
+
+ typedef std::unordered_map<GLuint, Framebuffer*> FramebufferMap;
+ FramebufferMap mFramebufferMap;
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.cpp
+index 97da6da..5cddd8a 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.cpp
+@@ -27,6 +27,11 @@ RendererD3D::RendererD3D(egl::Display *display)
+
+ RendererD3D::~RendererD3D()
+ {
++ cleanup();
++}
++
++void RendererD3D::cleanup()
++{
+ for (gl::TextureMap::iterator i = mIncompleteTextures.begin(); i != mIncompleteTextures.end(); ++i)
+ {
+ i->second.set(NULL);
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.h
+index 9919207..a2f7787 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.h
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/RendererD3D.h
+@@ -160,6 +160,8 @@ class RendererD3D : public Renderer
+ const gl::Rectangle *scissor, bool blitRenderTarget,
+ bool blitDepth, bool blitStencil, GLenum filter) = 0;
+
++ void cleanup();
++
+ egl::Display *mDisplay;
+
+ private:
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
+index e6d7f30..777308e 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d11/Renderer11.cpp
+@@ -1870,6 +1870,8 @@ bool Renderer11::testDeviceResettable()
+
+ void Renderer11::release()
+ {
++ RendererD3D::cleanup();
++
+ releaseShaderCompiler();
+ releaseDeviceResources();
+
+diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
+index 601cd24..18e6e2d 100644
+--- a/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d/d3d9/Renderer9.cpp
+@@ -151,6 +151,8 @@ Renderer9::~Renderer9()
+
+ void Renderer9::release()
+ {
++ RendererD3D::cleanup();
++
+ releaseShaderCompiler();
+ releaseDeviceResources();
+
+--
+1.9.4.msysgit.0
+
diff --git a/src/angle/patches/0019-ANGLE-Fix-handling-of-shader-source-with-fixed-lengt.patch b/src/angle/patches/0019-ANGLE-Fix-handling-of-shader-source-with-fixed-lengt.patch
new file mode 100644
index 0000000000..5fa244c1b5
--- /dev/null
+++ b/src/angle/patches/0019-ANGLE-Fix-handling-of-shader-source-with-fixed-lengt.patch
@@ -0,0 +1,37 @@
+From 5e277b05a16e7be24d36c600f158f8119ee583d8 Mon Sep 17 00:00:00 2001
+From: Andrew Knight <andrew.knight@theqtcompany.com>
+Date: Mon, 1 Dec 2014 11:58:08 +0200
+Subject: [PATCH] ANGLE: Fix handling of shader source with fixed length
+
+This is a cherry-pick of upstream f60fab6d154f4c9bf599e92976cd8cee7f8633e0
+(See https://chromium-review.googlesource.com/231612)
+
+Task-number: QTBUG-42882
+Change-Id: I7b4bdc4b68a1b93ff514f09ce35dbf4e9360af9b
+---
+ src/3rdparty/angle/src/libGLESv2/Shader.cpp | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/src/3rdparty/angle/src/libGLESv2/Shader.cpp b/src/3rdparty/angle/src/libGLESv2/Shader.cpp
+index 1cc17a0..5bca746 100644
+--- a/src/3rdparty/angle/src/libGLESv2/Shader.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/Shader.cpp
+@@ -51,7 +51,14 @@ void Shader::setSource(GLsizei count, const char *const *string, const GLint *le
+
+ for (int i = 0; i < count; i++)
+ {
+- stream << string[i];
++ if (length == nullptr || length[i] < 0)
++ {
++ stream.write(string[i], std::strlen(string[i]));
++ }
++ else
++ {
++ stream.write(string[i], length[i]);
++ }
+ }
+
+ mSource = stream.str();
+--
+1.9.4.msysgit.1
+
diff --git a/src/corelib/codecs/qtextcodec.cpp b/src/corelib/codecs/qtextcodec.cpp
index d2857c03b6..6eae9e598d 100644
--- a/src/corelib/codecs/qtextcodec.cpp
+++ b/src/corelib/codecs/qtextcodec.cpp
@@ -380,7 +380,7 @@ QTextCodec::ConverterState::~ConverterState()
If Qt is compiled with ICU support enabled, most codecs supported by
ICU will also be available to the application.
- QTextCodecs can be used as follows to convert some locally encoded
+ \l {QTextCodec}s can be used as follows to convert some locally encoded
string to Unicode. Suppose you have some string encoded in Russian
KOI8-R encoding, and want to convert it to Unicode. The simple way
to do it is like this:
@@ -453,7 +453,7 @@ QTextCodec::ConverterState::~ConverterState()
\li Converts a Unicode string to an 8-bit character string.
\endtable
- \sa QTextStream, QTextDecoder, QTextEncoder, {Codecs Example}
+ \sa QTextStream, QTextDecoder, QTextEncoder, {Text Codecs Example}
*/
/*!
diff --git a/src/corelib/global/qlogging.cpp b/src/corelib/global/qlogging.cpp
index 39c5ac602e..843ec6b0ca 100644
--- a/src/corelib/global/qlogging.cpp
+++ b/src/corelib/global/qlogging.cpp
@@ -1201,11 +1201,14 @@ QString qFormatLogMessage(QtMsgType type, const QMessageLogContext &context, con
}
#endif
} else if (token == timeTokenC) {
- quint64 ms = pattern->timer.elapsed();
- if (pattern->timeFormat.isEmpty())
+ if (pattern->timeFormat == QLatin1String("process")) {
+ quint64 ms = pattern->timer.elapsed();
message.append(QString().sprintf("%6d.%03d", uint(ms / 1000), uint(ms % 1000)));
- else
- message.append(pattern->startTime.addMSecs(ms).toString(pattern->timeFormat));
+ } else if (pattern->timeFormat.isEmpty()) {
+ message.append(QDateTime::currentDateTime().toString(Qt::ISODate));
+ } else {
+ message.append(QDateTime::currentDateTime().toString(pattern->timeFormat));
+ }
#endif
} else if (token == ifCategoryTokenC) {
if (!context.category || (strcmp(context.category, "default") == 0))
@@ -1550,9 +1553,10 @@ void qErrnoWarning(int code, const char *msg, ...)
\row \li \c %{pid} \li QCoreApplication::applicationPid()
\row \li \c %{threadid} \li ID of current thread
\row \li \c %{type} \li "debug", "warning", "critical" or "fatal"
- \row \li \c %{time} \li time of the message, in seconds since the process started
- \row \li \c %{time format} \li system time when the message occurred, formatted by
- passing the \c format to \l QDateTime::toString()
+ \row \li \c %{time process} \li time of the message, in seconds since the process started (the token "process" is literal)
+ \row \li \c %{time [format]} \li system time when the message occurred, formatted by
+ passing the \c format to \l QDateTime::toString(). If the format is
+ not specified, the format of Qt::ISODate is used.
\row \li \c{%{backtrace [depth=N] [separator="..."]}} \li A backtrace with the number of frames
specified by the optional \c depth parameter (defaults to 5), and separated by the optional
\c separator parameter (defaults to "|").
diff --git a/src/corelib/io/qdebug.cpp b/src/corelib/io/qdebug.cpp
index 9eed1f352a..050a48bd65 100644
--- a/src/corelib/io/qdebug.cpp
+++ b/src/corelib/io/qdebug.cpp
@@ -425,8 +425,8 @@ QDebug &QDebug::resetFormat()
\brief Convenience class for custom QDebug operators
Saves the settings used by QDebug, and restores them upon destruction,
- then calls maybeSpace(), to separate arguments with a space if
- autoInsertSpaces() was true at the time of constructing the QDebugStateSaver.
+ then calls \l {QDebug::maybeSpace()}{maybeSpace()}, to separate arguments with a space if
+ \l {QDebug::autoInsertSpaces()}{autoInsertSpaces()} was true at the time of constructing the QDebugStateSaver.
The automatic insertion of spaces between writes is one of the settings
that QDebugStateSaver stores for the duration of the current block.
diff --git a/src/corelib/io/qfiledevice.cpp b/src/corelib/io/qfiledevice.cpp
index 598347a56f..29b59f1dcc 100644
--- a/src/corelib/io/qfiledevice.cpp
+++ b/src/corelib/io/qfiledevice.cpp
@@ -240,7 +240,7 @@ bool QFileDevice::isSequential() const
Returns the file handle of the file.
This is a small positive integer, suitable for use with C library
- functions such as fdopen() and fcntl(). On systems that use file
+ functions such as \c fdopen() and \c fcntl(). On systems that use file
descriptors for sockets (i.e. Unix systems, but not Windows) the handle
can be used with QSocketNotifier as well.
@@ -389,9 +389,9 @@ bool QFileDevice::atEnd() const
return false.
Seeking beyond the end of a file:
- If the position is beyond the end of a file, then seek() shall not
+ If the position is beyond the end of a file, then seek() will not
immediately extend the file. If a write is performed at this position,
- then the file shall be extended. The content of the file between the
+ then the file will be extended. The content of the file between the
previous end of file and the newly written data is UNDEFINED and
varies between platforms and file systems.
*/
diff --git a/src/corelib/io/qfilesystemwatcher_fsevents.mm b/src/corelib/io/qfilesystemwatcher_fsevents.mm
index eebca1cfb0..90ef7a6336 100644
--- a/src/corelib/io/qfilesystemwatcher_fsevents.mm
+++ b/src/corelib/io/qfilesystemwatcher_fsevents.mm
@@ -518,7 +518,6 @@ bool QFseventsFileSystemWatcherEngine::startStream()
NULL
};
const CFAbsoluteTime latency = .5; // in seconds
- FSEventStreamCreateFlags flags = kFSEventStreamCreateFlagWatchRoot;
// Never start with kFSEventStreamEventIdSinceNow, because this will generate an invalid
// soft-assert in FSEventStreamFlushSync in CarbonCore when no event occurred.
@@ -530,7 +529,7 @@ bool QFseventsFileSystemWatcherEngine::startStream()
reinterpret_cast<CFArrayRef>(pathsToWatch),
lastReceivedEvent,
latency,
- flags);
+ FSEventStreamCreateFlags(0));
if (!stream) {
DEBUG() << "Failed to create stream!";
diff --git a/src/corelib/io/qloggingcategory.cpp b/src/corelib/io/qloggingcategory.cpp
index fef48a9040..79d20601a6 100644
--- a/src/corelib/io/qloggingcategory.cpp
+++ b/src/corelib/io/qloggingcategory.cpp
@@ -149,10 +149,10 @@ static void setBoolLane(QBasicAtomicInt *atomic, bool enable, int shift)
Order of evaluation:
\list
- \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
+ \li QtProject/qtlogging.ini
+ \li \l setFilterRules()
+ \li \c QT_LOGGING_CONF
+ \li \c QT_LOGGING_RULES
\endlist
The \c QtProject/qtlogging.ini file is looked up in all directories returned
diff --git a/src/corelib/io/qprocess.cpp b/src/corelib/io/qprocess.cpp
index e76a836954..a234050777 100644
--- a/src/corelib/io/qprocess.cpp
+++ b/src/corelib/io/qprocess.cpp
@@ -1853,8 +1853,8 @@ void QProcess::setProcessState(ProcessState state)
/*!
This function is called in the child process context just before the
- program is executed on Unix or Mac OS X (i.e., after \e fork(), but before
- \e execve()). Reimplement this function to do last minute initialization
+ program is executed on Unix or OS X (i.e., after \c fork(), but before
+ \c execve()). Reimplement this function to do last minute initialization
of the child process. Example:
\snippet code/src_corelib_io_qprocess.cpp 4
@@ -1864,7 +1864,7 @@ void QProcess::setProcessState(ProcessState state)
execution, your workaround is to emit finished() and then call
exit().
- \warning This function is called by QProcess on Unix and Mac OS X
+ \warning This function is called by QProcess on Unix and OS X
only. On Windows and QNX, it is not called.
*/
void QProcess::setupChildProcess()
@@ -2272,7 +2272,7 @@ void QProcess::setArguments(const QStringList &arguments)
On Windows, terminate() posts a WM_CLOSE message to all toplevel windows
of the process and then to the main thread of the process itself. On Unix
- and Mac OS X the SIGTERM signal is sent.
+ and OS X the \c SIGTERM signal is sent.
Console applications on Windows that do not run an event loop, or whose
event loop does not handle the WM_CLOSE message, can only be terminated by
@@ -2289,7 +2289,7 @@ void QProcess::terminate()
/*!
Kills the current process, causing it to exit immediately.
- On Windows, kill() uses TerminateProcess, and on Unix and Mac OS X, the
+ On Windows, kill() uses TerminateProcess, and on Unix and OS X, the
SIGKILL signal is sent to the process.
\sa terminate()
diff --git a/src/corelib/io/qstandardpaths.cpp b/src/corelib/io/qstandardpaths.cpp
index 6950d58fda..b41aee55d2 100644
--- a/src/corelib/io/qstandardpaths.cpp
+++ b/src/corelib/io/qstandardpaths.cpp
@@ -588,11 +588,11 @@ QString QStandardPaths::displayName(StandardLocation type)
GenericCacheLocation, CacheLocation.
Other locations are not affected.
- On Unix, XDG_DATA_HOME is set to ~/.qttest/share, XDG_CONFIG_HOME is
- set to ~/.qttest/config, and XDG_CACHE_HOME is set to ~/.qttest/cache.
+ On Unix, \c XDG_DATA_HOME is set to \e ~/.qttest/share, \c XDG_CONFIG_HOME is
+ set to \e ~/.qttest/config, and \c XDG_CACHE_HOME is set to \e ~/.qttest/cache.
- On Mac, data goes to "~/.qttest/Application Support", cache goes to
- ~/.qttest/Cache, and config goes to ~/.qttest/Preferences.
+ On OS X, data goes to \e ~/.qttest/Application Support, cache goes to
+ \e ~/.qttest/Cache, and config goes to \e ~/.qttest/Preferences.
On Windows, everything goes to a "qttest" directory under Application Data.
*/
diff --git a/src/corelib/io/qtemporarydir.cpp b/src/corelib/io/qtemporarydir.cpp
index 7ce37fd320..5e0def74ee 100644
--- a/src/corelib/io/qtemporarydir.cpp
+++ b/src/corelib/io/qtemporarydir.cpp
@@ -180,7 +180,7 @@ void QTemporaryDirPrivate::create(const QString &templateName)
\snippet code/src_corelib_io_qtemporarydir.cpp 0
It is very important to test that the temporary directory could be
- created, using isValid(). Do not use exists(), since a default-constructed
+ created, using isValid(). Do not use \l {QDir::exists()}{exists()}, since a default-constructed
QDir represents the current directory, which exists.
The path to the temporary dir can be found by calling path().
diff --git a/src/corelib/io/qtextstream.cpp b/src/corelib/io/qtextstream.cpp
index 6cbe91fab2..18cf58d397 100644
--- a/src/corelib/io/qtextstream.cpp
+++ b/src/corelib/io/qtextstream.cpp
@@ -85,8 +85,8 @@ static const int QTEXTSTREAM_BUFFERSIZE = 16384;
\li Chunk by chunk, by calling readLine() or readAll().
- \li Word by word. QTextStream supports streaming into QStrings,
- QByteArrays and char* buffers. Words are delimited by space, and
+ \li Word by word. QTextStream supports streaming into \l {QString}s,
+ \l {QByteArray}s and char* buffers. Words are delimited by space, and
leading white space is automatically skipped.
\li Character by character, by streaming into QChar or char types.
@@ -158,7 +158,7 @@ static const int QTEXTSTREAM_BUFFERSIZE = 16384;
parameter: qSetFieldWidth(), qSetPadChar(), and
qSetRealNumberPrecision().
- \sa QDataStream, QIODevice, QFile, QBuffer, QTcpSocket, {Codecs Example}
+ \sa QDataStream, QIODevice, QFile, QBuffer, QTcpSocket, {Text Codecs Example}
*/
/*! \enum QTextStream::RealNumberNotation
@@ -1557,7 +1557,7 @@ bool QTextStream::atEnd() const
QString. Avoid this function when working on large files, as it
will consume a significant amount of memory.
- Calling readLine() is better if you do not know how much data is
+ Calling \l {QTextStream::readLine()}{readLine()} is better if you do not know how much data is
available.
\sa readLine()
@@ -1582,9 +1582,9 @@ QString QTextStream::readAll()
The returned line has no trailing end-of-line characters ("\\n"
or "\\r\\n"), so calling QString::trimmed() is unnecessary.
- If the stream has read to the end of the file, readLine() will return a
- null QString. For strings, or for devices that support it, you can
- explicitly test for the end of the stream using atEnd().
+ If the stream has read to the end of the file, \l {QTextStream::readLine()}{readLine()}
+ will return a null QString. For strings, or for devices that support it,
+ you can explicitly test for the end of the stream using atEnd().
\sa readAll(), QIODevice::readLine()
*/
@@ -2816,7 +2816,7 @@ QTextStream &endl(QTextStream &stream)
/*!
\relates QTextStream
- Calls QTextStream::flush() on \a stream and returns \a stream.
+ Calls \l{QTextStream::flush()}{flush()} on \a stream and returns \a stream.
\sa endl(), reset(), {QTextStream manipulators}
*/
diff --git a/src/corelib/io/qurl.cpp b/src/corelib/io/qurl.cpp
index b21e9b51e1..eb97eaf6d6 100644
--- a/src/corelib/io/qurl.cpp
+++ b/src/corelib/io/qurl.cpp
@@ -2687,8 +2687,8 @@ void QUrl::setQuery(const QUrlQuery &query)
Sets the query string of the URL to an encoded version of \a
query. The contents of \a query are converted to a string
internally, each pair delimited by the character returned by
- queryPairDelimiter(), and the key and value are delimited by
- queryValueDelimiter().
+ \l {QUrlQuery::queryPairDelimiter()}{queryPairDelimiter()}, and the key and value are delimited by
+ \l {QUrlQuery::queryValueDelimiter()}{queryValueDelimiter()}
\note This method does not encode spaces (ASCII 0x20) as plus (+) signs,
like HTML forms do. If you need that kind of encoding, you must encode
@@ -2707,8 +2707,8 @@ void QUrl::setQuery(const QUrlQuery &query)
Sets the query string of the URL to the encoded version of \a
query. The contents of \a query are converted to a string
internally, each pair delimited by the character returned by
- queryPairDelimiter(), and the key and value are delimited by
- queryValueDelimiter().
+ \l {QUrlQuery::queryPairDelimiter()}{queryPairDelimiter()}, and the key and value are delimited by
+ \l {QUrlQuery::queryValueDelimiter()}{queryValueDelimiter()}.
\obsolete Use QUrlQuery and setQuery().
@@ -2725,8 +2725,9 @@ void QUrl::setQuery(const QUrlQuery &query)
The key-value pair is encoded before it is added to the query. The
pair is converted into separate strings internally. The \a key and
\a value is first encoded into UTF-8 and then delimited by the
- character returned by queryValueDelimiter(). Each key-value pair is
- delimited by the character returned by queryPairDelimiter().
+ character returned by \l {QUrlQuery::queryValueDelimiter()}{queryValueDelimiter()}.
+ Each key-value pair is delimited by the character returned by
+ \l {QUrlQuery::queryPairDelimiter()}{queryPairDelimiter()}
\note This method does not encode spaces (ASCII 0x20) as plus (+) signs,
like HTML forms do. If you need that kind of encoding, you must encode
diff --git a/src/corelib/kernel/qfunctions_winrt.cpp b/src/corelib/kernel/qfunctions_winrt.cpp
index 84e7b5688f..60faead122 100644
--- a/src/corelib/kernel/qfunctions_winrt.cpp
+++ b/src/corelib/kernel/qfunctions_winrt.cpp
@@ -37,7 +37,7 @@
#include "qbytearray.h"
#include "qhash.h"
-QT_USE_NAMESPACE
+QT_BEGIN_NAMESPACE
// Environment ------------------------------------------------------
inline QHash<QByteArray, QByteArray> &qt_app_environment()
@@ -94,4 +94,6 @@ void qt_winrt__tzset()
{
}
+QT_END_NAMESPACE
+
#endif // Q_OS_WINRT
diff --git a/src/corelib/kernel/qfunctions_winrt.h b/src/corelib/kernel/qfunctions_winrt.h
index 04ebda5cfe..2bec1fc2ff 100644
--- a/src/corelib/kernel/qfunctions_winrt.h
+++ b/src/corelib/kernel/qfunctions_winrt.h
@@ -42,21 +42,36 @@
#include <QtCore/QAbstractEventDispatcher>
#include <QtCore/qt_windows.h>
-QT_BEGIN_NAMESPACE
+// Convenience macros for handling HRESULT values
+#define RETURN_IF_FAILED(msg, ret) \
+ if (FAILED(hr)) { \
+ qErrnoWarning(hr, msg); \
+ ret; \
+ }
-#ifdef QT_BUILD_CORE_LIB
-#endif
+#define RETURN_HR_IF_FAILED(msg) RETURN_IF_FAILED(msg, return hr)
+#define RETURN_OK_IF_FAILED(msg) RETURN_IF_FAILED(msg, return S_OK)
+#define RETURN_FALSE_IF_FAILED(msg) RETURN_IF_FAILED(msg, return false)
+#define RETURN_VOID_IF_FAILED(msg) RETURN_IF_FAILED(msg, return)
-QT_END_NAMESPACE
+#define Q_ASSERT_SUCCEEDED(hr) \
+ Q_ASSERT_X(SUCCEEDED(hr), Q_FUNC_INFO, qPrintable(qt_error_string(hr)));
#ifdef Q_OS_WINRT
+QT_BEGIN_NAMESPACE
+
+#ifdef QT_BUILD_CORE_LIB
+#endif
+
// Environment ------------------------------------------------------
errno_t qt_winrt_getenv_s(size_t*, char*, size_t, const char*);
errno_t qt_winrt__putenv_s(const char*, const char*);
void qt_winrt_tzset();
void qt_winrt__tzset();
+QT_END_NAMESPACE
+
// As Windows Runtime lacks some standard functions used in Qt, these got
// reimplemented. Other projects do this as well. Inline functions are used
// that there is a central place to disable functions for newer versions if
@@ -69,42 +84,42 @@ void qt_winrt__tzset();
#define generate_inline_return_func0(funcname, returntype) \
inline returntype funcname() \
{ \
- return qt_winrt_##funcname(); \
+ return QT_PREPEND_NAMESPACE(qt_winrt_##funcname)(); \
}
#define generate_inline_return_func1(funcname, returntype, param1) \
inline returntype funcname(param1 p1) \
{ \
- return qt_winrt_##funcname(p1); \
+ return QT_PREPEND_NAMESPACE(qt_winrt_##funcname)(p1); \
}
#define generate_inline_return_func2(funcname, returntype, param1, param2) \
inline returntype funcname(param1 p1, param2 p2) \
{ \
- return qt_winrt_##funcname(p1, p2); \
+ return QT_PREPEND_NAMESPACE(qt_winrt_##funcname)(p1, p2); \
}
#define generate_inline_return_func3(funcname, returntype, param1, param2, param3) \
inline returntype funcname(param1 p1, param2 p2, param3 p3) \
{ \
- return qt_winrt_##funcname(p1, p2, p3); \
+ return QT_PREPEND_NAMESPACE(qt_winrt_##funcname)(p1, p2, p3); \
}
#define generate_inline_return_func4(funcname, returntype, param1, param2, param3, param4) \
inline returntype funcname(param1 p1, param2 p2, param3 p3, param4 p4) \
{ \
- return qt_winrt_##funcname(p1, p2, p3, p4); \
+ return QT_PREPEND_NAMESPACE(qt_winrt_##funcname)(p1, p2, p3, p4); \
}
#define generate_inline_return_func5(funcname, returntype, param1, param2, param3, param4, param5) \
inline returntype funcname(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5) \
{ \
- return qt_winrt_##funcname(p1, p2, p3, p4, p5); \
+ return QT_PREPEND_NAMESPACE(qt_winrt_##funcname)(p1, p2, p3, p4, p5); \
}
#define generate_inline_return_func6(funcname, returntype, param1, param2, param3, param4, param5, param6) \
inline returntype funcname(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6) \
{ \
- return qt_winrt_##funcname(p1, p2, p3, p4, p5, p6); \
+ return QT_PREPEND_NAMESPACE(qt_winrt_##funcname)(p1, p2, p3, p4, p5, p6); \
}
#define generate_inline_return_func7(funcname, returntype, param1, param2, param3, param4, param5, param6, param7) \
inline returntype funcname(param1 p1, param2 p2, param3 p3, param4 p4, param5 p5, param6 p6, param7 p7) \
{ \
- return qt_winrt_##funcname(p1, p2, p3, p4, p5, p6, p7); \
+ return QT_PREPEND_NAMESPACE(qt_winrt_##funcname)(p1, p2, p3, p4, p5, p6, p7); \
}
typedef unsigned (__stdcall *StartAdressExFunc)(void *);
@@ -116,23 +131,7 @@ generate_inline_return_func2(_putenv_s, errno_t, const char *, const char *)
generate_inline_return_func0(tzset, void)
generate_inline_return_func0(_tzset, void)
-#endif // Q_OS_WINRT
-
-// Convenience macros for handling HRESULT values
-#define RETURN_IF_FAILED(msg, ret) \
- if (FAILED(hr)) { \
- qErrnoWarning(hr, msg); \
- ret; \
- }
-
-#define RETURN_HR_IF_FAILED(msg) RETURN_IF_FAILED(msg, return hr)
-#define RETURN_OK_IF_FAILED(msg) RETURN_IF_FAILED(msg, return S_OK)
-#define RETURN_FALSE_IF_FAILED(msg) RETURN_IF_FAILED(msg, return false)
-#define RETURN_VOID_IF_FAILED(msg) RETURN_IF_FAILED(msg, return)
-
-#define Q_ASSERT_SUCCEEDED(hr) \
- Q_ASSERT_X(SUCCEEDED(hr), Q_FUNC_INFO, qPrintable(qt_error_string(hr)));
-
+QT_BEGIN_NAMESPACE
namespace Microsoft { namespace WRL { template <typename T> class ComPtr; } }
@@ -207,6 +206,10 @@ static inline HRESULT await(const Microsoft::WRL::ComPtr<T> &asyncOp, U *results
} // QWinRTFunctions
+QT_END_NAMESPACE
+
+#endif // Q_OS_WINRT
+
#endif // Q_OS_WIN
#endif // QFUNCTIONS_WINRT_H
diff --git a/src/corelib/kernel/qjni.cpp b/src/corelib/kernel/qjni.cpp
index b179323fdc..9d74fd69de 100644
--- a/src/corelib/kernel/qjni.cpp
+++ b/src/corelib/kernel/qjni.cpp
@@ -37,6 +37,7 @@
#include <QtCore/qhash.h>
#include <QtCore/qstring.h>
#include <QtCore/QThread>
+#include <QtCore/QReadWriteLock>
QT_BEGIN_NAMESPACE
@@ -45,11 +46,6 @@ static inline QString keyBase()
return QStringLiteral("%1%2%3");
}
-static inline QByteArray threadBaseName()
-{
- return QByteArrayLiteral("QtThread-");
-}
-
static QString qt_convertJString(jstring string)
{
QJNIEnvironmentPrivate env;
@@ -74,6 +70,7 @@ static inline bool exceptionCheckAndClear(JNIEnv *env)
typedef QHash<QString, jclass> JClassHash;
Q_GLOBAL_STATIC(JClassHash, cachedClasses)
+Q_GLOBAL_STATIC(QReadWriteLock, cachedClassesLock)
static QString toDotEncodedClassName(const char *className)
{
@@ -82,8 +79,9 @@ static QString toDotEncodedClassName(const char *className)
static jclass getCachedClass(const QString &classDotEnc, bool *isCached = 0)
{
- QHash<QString, jclass>::iterator it = cachedClasses->find(classDotEnc);
- const bool found = (it != cachedClasses->end());
+ QReadLocker locker(cachedClassesLock);
+ const QHash<QString, jclass>::const_iterator &it = cachedClasses->constFind(classDotEnc);
+ const bool found = (it != cachedClasses->constEnd());
if (isCached != 0)
*isCached = found;
@@ -102,6 +100,12 @@ static jclass loadClassDotEnc(const QString &classDotEnc, JNIEnv *env)
if (!classLoader.isValid())
return 0;
+ QWriteLocker locker(cachedClassesLock);
+ // did we lose the race?
+ const QHash<QString, jclass>::const_iterator &it = cachedClasses->constFind(classDotEnc);
+ if (it != cachedClasses->constEnd())
+ return it.value();
+
QJNIObjectPrivate stringName = QJNIObjectPrivate::fromString(classDotEnc);
QJNIObjectPrivate classObject = classLoader.callObjectMethod("loadClass",
"(Ljava/lang/String;)Ljava/lang/Class;",
@@ -121,6 +125,7 @@ inline static jclass loadClass(const char *className, JNIEnv *env)
typedef QHash<QString, jmethodID> JMethodIDHash;
Q_GLOBAL_STATIC(JMethodIDHash, cachedMethodID)
+Q_GLOBAL_STATIC(QReadWriteLock, cachedMethodIDLock)
static jmethodID getCachedMethodID(JNIEnv *env,
jclass clazz,
@@ -128,11 +133,24 @@ static jmethodID getCachedMethodID(JNIEnv *env,
const char *sig,
bool isStatic = false)
{
- jmethodID id = 0;
// TODO: We need to use something else then the ref. from clazz to avoid collisions.
- QString key = keyBase().arg(size_t(clazz)).arg(QLatin1String(name)).arg(QLatin1String(sig));
- QHash<QString, jmethodID>::iterator it = cachedMethodID->find(key);
- if (it == cachedMethodID->end()) {
+ const QString key = keyBase().arg(size_t(clazz)).arg(QLatin1String(name)).arg(QLatin1String(sig));
+ QHash<QString, jmethodID>::const_iterator it;
+
+ {
+ QReadLocker locker(cachedMethodIDLock);
+ it = cachedMethodID->constFind(key);
+ if (it != cachedMethodID->constEnd())
+ return it.value();
+ }
+
+ {
+ QWriteLocker locker(cachedMethodIDLock);
+ it = cachedMethodID->constFind(key);
+ if (it != cachedMethodID->constEnd())
+ return it.value();
+
+ jmethodID id = 0;
if (isStatic)
id = env->GetStaticMethodID(clazz, name, sig);
else
@@ -142,14 +160,13 @@ static jmethodID getCachedMethodID(JNIEnv *env,
id = 0;
cachedMethodID->insert(key, id);
- } else {
- id = it.value();
+ return id;
}
- return id;
}
typedef QHash<QString, jfieldID> JFieldIDHash;
Q_GLOBAL_STATIC(JFieldIDHash, cachedFieldID)
+Q_GLOBAL_STATIC(QReadWriteLock, cachedFieldIDLock)
static jfieldID getCachedFieldID(JNIEnv *env,
jclass clazz,
@@ -157,10 +174,23 @@ static jfieldID getCachedFieldID(JNIEnv *env,
const char *sig,
bool isStatic = false)
{
- jfieldID id = 0;
- QString key = keyBase().arg(size_t(clazz)).arg(QLatin1String(name)).arg(QLatin1String(sig));
- QHash<QString, jfieldID>::iterator it = cachedFieldID->find(key);
- if (it == cachedFieldID->end()) {
+ const QString key = keyBase().arg(size_t(clazz)).arg(QLatin1String(name)).arg(QLatin1String(sig));
+ QHash<QString, jfieldID>::const_iterator it;
+
+ {
+ QReadLocker locker(cachedFieldIDLock);
+ it = cachedFieldID->constFind(key);
+ if (it != cachedFieldID->constEnd())
+ return it.value();
+ }
+
+ {
+ QWriteLocker locker(cachedFieldIDLock);
+ it = cachedFieldID->constFind(key);
+ if (it != cachedFieldID->constEnd())
+ return it.value();
+
+ jfieldID id = 0;
if (isStatic)
id = env->GetStaticFieldID(clazz, name, sig);
else
@@ -170,10 +200,8 @@ static jfieldID getCachedFieldID(JNIEnv *env,
id = 0;
cachedFieldID->insert(key, id);
- } else {
- id = it.value();
+ return id;
}
- return id;
}
class QJNIEnvironmentPrivateTLS
@@ -187,14 +215,14 @@ public:
Q_GLOBAL_STATIC(QThreadStorage<QJNIEnvironmentPrivateTLS *>, jniEnvTLS)
+static const char qJniThreadName[] = "QtThread";
+
QJNIEnvironmentPrivate::QJNIEnvironmentPrivate()
: jniEnv(0)
{
JavaVM *vm = QtAndroidPrivate::javaVM();
if (vm->GetEnv((void**)&jniEnv, JNI_VERSION_1_6) == JNI_EDETACHED) {
- const qulonglong id = reinterpret_cast<qulonglong>(QThread::currentThreadId());
- const QByteArray threadName = threadBaseName() + QByteArray::number(id);
- JavaVMAttachArgs args = { JNI_VERSION_1_6, threadName, Q_NULLPTR };
+ JavaVMAttachArgs args = { JNI_VERSION_1_6, qJniThreadName, Q_NULLPTR };
if (vm->AttachCurrentThread(&jniEnv, &args) != JNI_OK)
return;
}
@@ -223,6 +251,12 @@ jclass QJNIEnvironmentPrivate::findClass(const char *className, JNIEnv *env)
return clazz;
if (env != 0) { // We got an env. pointer (We expect this to be the right env. and call FindClass())
+ QWriteLocker locker(cachedClassesLock);
+ const QHash<QString, jclass>::const_iterator &it = cachedClasses->constFind(classDotEnc);
+ // Did we lose the race?
+ if (it != cachedClasses->constEnd())
+ return it.value();
+
jclass fclazz = env->FindClass(className);
if (!exceptionCheckAndClear(env)) {
clazz = static_cast<jclass>(env->NewGlobalRef(fclazz));
@@ -400,7 +434,6 @@ QJNIObjectPrivate::QJNIObjectPrivate(jobject obj)
d->m_jclass = static_cast<jclass>(env->NewGlobalRef(objectClass));
env->DeleteLocalRef(objectClass);
}
-
template <>
void QJNIObjectPrivate::callMethodV<void>(const char *methodName, const char *sig, va_list args) const
{
diff --git a/src/corelib/kernel/qtranslator.cpp b/src/corelib/kernel/qtranslator.cpp
index a2cf4a7813..a9c608384a 100644
--- a/src/corelib/kernel/qtranslator.cpp
+++ b/src/corelib/kernel/qtranslator.cpp
@@ -86,13 +86,13 @@ static const uchar magic[MagicLength] = {
0xcd, 0x21, 0x1c, 0xbf, 0x60, 0xa1, 0xbd, 0xdd
};
-static bool match(const uchar* found, const char* target, uint len)
+static bool match(const uchar *found, uint foundLen, const char *target, uint targetLen)
{
// catch the case if \a found has a zero-terminating symbol and \a len includes it.
// (normalize it to be without the zero-terminating symbol)
- if (len > 0 && found[len-1] == '\0')
- --len;
- return (memcmp(found, target, len) == 0 && target[len] == '\0');
+ if (foundLen > 0 && found[foundLen-1] == '\0')
+ --foundLen;
+ return ((targetLen == foundLen) && memcmp(found, target, foundLen) == 0);
}
static void elfHash_continue(const char *name, uint &h)
@@ -878,6 +878,9 @@ static QString getMessage(const uchar *m, const uchar *end, const char *context,
{
const uchar *tn = 0;
uint tn_length = 0;
+ const uint sourceTextLen = uint(strlen(sourceText));
+ const uint contextLen = uint(strlen(context));
+ const uint commentLen = uint(strlen(comment));
for (;;) {
uchar tag = 0;
@@ -904,7 +907,7 @@ static QString getMessage(const uchar *m, const uchar *end, const char *context,
case Tag_SourceText: {
quint32 len = read32(m);
m += 4;
- if (!match(m, sourceText, len))
+ if (!match(m, len, sourceText, sourceTextLen))
return QString();
m += len;
}
@@ -912,7 +915,7 @@ static QString getMessage(const uchar *m, const uchar *end, const char *context,
case Tag_Context: {
quint32 len = read32(m);
m += 4;
- if (!match(m, context, len))
+ if (!match(m, len, context, contextLen))
return QString();
m += len;
}
@@ -920,7 +923,7 @@ static QString getMessage(const uchar *m, const uchar *end, const char *context,
case Tag_Comment: {
quint32 len = read32(m);
m += 4;
- if (*m && !match(m, comment, len))
+ if (*m && !match(m, len, comment, commentLen))
return QString();
m += len;
}
@@ -970,11 +973,12 @@ QString QTranslatorPrivate::do_translate(const char *context, const char *source
return QString();
c = contextArray + (2 + (hTableSize << 1) + (off << 1));
+ const uint contextLen = uint(strlen(context));
for (;;) {
quint8 len = read8(c++);
if (len == 0)
return QString();
- if (match(c, context, len))
+ if (match(c, len, context, contextLen))
break;
c += len;
}
diff --git a/src/corelib/tools/qalgorithms.qdoc b/src/corelib/tools/qalgorithms.qdoc
index 5e5a2b42e2..226a63ccae 100644
--- a/src/corelib/tools/qalgorithms.qdoc
+++ b/src/corelib/tools/qalgorithms.qdoc
@@ -168,43 +168,43 @@
\li STL function
\row
\li qBinaryFind
- \li std::binary_search or std::lower_bound
+ \li \c std::binary_search or \c std::lower_bound
\row
\li qCopy
- \li std::copy
+ \li \c std::copy
\row
\li qCopyBackward
- \li std::copy_backward
+ \li \c std::copy_backward
\row
\li qEqual
- \li std::equal
+ \li \c std::equal
\row
\li qFill
- \li std::fill
+ \li \c std::fill
\row
\li qFind
- \li std::find
+ \li \c std::find
\row
\li qCount
- \li std::count
+ \li \c std::count
\row
\li qSort
- \li std::sort
+ \li \c std::sort
\row
\li qStableSort
- \li std::stable_sort
+ \li \c std::stable_sort
\row
\li qLowerBound
- \li std::lower_bound
+ \li \c std::lower_bound
\row
\li qUpperBound
- \li std::upper_bound
+ \li \c std::upper_bound
\row
\li qLess
- \li std::less
+ \li \c std::less
\row
\li qGreater
- \li std::greater
+ \li \c std::greater
\endtable
@@ -223,7 +223,7 @@
Instead, since it's not possible to pass a custom swapper functor to STL
functions, the only workaround for a template specialization for qSwap() is
- providing the same specialization for std::swap().
+ providing the same specialization for \c std::swap().
\sa {container classes}, <QtGlobal>
*/
@@ -232,7 +232,7 @@
\relates <QtAlgorithms>
\deprecated
- Use std::copy instead.
+ Use \c std::copy instead.
Copies the items from range [\a begin1, \a end1) to range [\a
begin2, ...), in the order in which they appear.
@@ -251,7 +251,7 @@
\relates <QtAlgorithms>
\deprecated
- Use std::copy_backward instead.
+ Use \c std::copy_backward instead.
Copies the items from range [\a begin1, \a end1) to range [...,
\a end2).
@@ -270,7 +270,7 @@
\relates <QtAlgorithms>
\deprecated
- Use std::equal instead.
+ Use \c std::equal instead.
Compares the items in the range [\a begin1, \a end1) with the
items in the range [\a begin2, ...). Returns \c true if all the
@@ -289,7 +289,7 @@
\relates <QtAlgorithms>
\deprecated
- Use std::fill instead.
+ Use \c std::fill instead.
Fills the range [\a begin, \a end) with \a value.
@@ -304,7 +304,7 @@
\deprecated
\overload
- Use std::fill instead.
+ Use \c std::fill instead.
This is the same as qFill(\a{container}.begin(), \a{container}.end(), \a value);
*/
@@ -313,7 +313,7 @@
\relates <QtAlgorithms>
\deprecated
- Use std::find instead.
+ Use \c std::find instead.
Returns an iterator to the first occurrence of \a value in a
container in the range [\a begin, \a end). Returns \a end if \a
@@ -337,16 +337,16 @@
\deprecated
\overload
- Use std::find instead.
+ Use \c std::find instead.
- This is the same as qFind(\a{container}.constBegin(), \a{container}.constEnd(), value);
+ This is the same as qFind(\a{container}.constBegin(), \a{container}.constEnd(), \a value);
*/
/*! \fn void qCount(InputIterator begin, InputIterator end, const T &value, Size &n)
\relates <QtAlgorithms>
\deprecated
- Use std::count instead.
+ Use \c std::count instead.
Returns the number of occurrences of \a value in the range [\a begin, \a end),
which is returned in \a n. \a n is never initialized, the count is added to \a n.
@@ -367,7 +367,7 @@
\deprecated
\overload
- Use std::count instead.
+ Use \c std::count instead.
Instead of operating on iterators, as in the other overload, this function
operates on the specified \a container to obtain the number of instances
@@ -378,7 +378,7 @@
\relates <QtAlgorithms>
\deprecated
- Use std::swap instead.
+ Use \c std::swap instead.
Exchanges the values of variables \a var1 and \a var2.
@@ -390,7 +390,7 @@
\relates <QtAlgorithms>
\deprecated
- Use std::sort instead.
+ Use \c std::sort instead.
Sorts the items in range [\a begin, \a end) in ascending order
using the quicksort algorithm.
@@ -416,7 +416,7 @@
\deprecated
\overload
- Use std::sort instead.
+ Use \c std::sort instead.
Uses the \a lessThan function instead of \c operator<() to
compare the items.
@@ -452,7 +452,7 @@
\deprecated
\overload
- Use std::sort instead.
+ Use \c std::sort instead.
This is the same as qSort(\a{container}.begin(), \a{container}.end());
*/
@@ -462,7 +462,7 @@
\relates <QtAlgorithms>
\deprecated
- Use std::stable_sort instead.
+ Use \c std::stable_sort instead.
Sorts the items in range [\a begin, \a end) in ascending order
using a stable sorting algorithm.
@@ -490,7 +490,7 @@
\deprecated
\overload
- Use std::stable_sort instead.
+ Use \c std::stable_sort instead.
Uses the \a lessThan function instead of \c operator<() to
compare the items.
@@ -522,7 +522,7 @@
\deprecated
\overload
- Use std::stable_sort instead.
+ Use \c std::stable_sort instead.
This is the same as qStableSort(\a{container}.begin(), \a{container}.end());
*/
@@ -531,7 +531,7 @@
\relates <QtAlgorithms>
\deprecated
- Use std::lower_bound instead.
+ Use \c std::lower_bound instead.
Performs a binary search of the range [\a begin, \a end) and
returns the position of the first occurrence of \a value. If no
@@ -561,7 +561,7 @@
\deprecated
\overload
- Use std::lower_bound instead.
+ Use \c std::lower_bound instead.
Uses the \a lessThan function instead of \c operator<() to
compare the items.
@@ -576,7 +576,7 @@
\deprecated
\overload
- Use std::lower_bound instead.
+ Use \c std::lower_bound instead.
For read-only iteration over containers, this function is broadly equivalent to
qLowerBound(\a{container}.begin(), \a{container}.end(), value). However, since it
@@ -588,7 +588,7 @@
\relates <QtAlgorithms>
\deprecated
- Use std::upper_bound instead.
+ Use \c std::upper_bound instead.
Performs a binary search of the range [\a begin, \a end) and
returns the position of the one-past-the-last occurrence of \a
@@ -618,7 +618,7 @@
\deprecated
\overload
- Use std::upper_bound instead.
+ Use \c std::upper_bound instead.
Uses the \a lessThan function instead of \c operator<() to
compare the items.
@@ -633,9 +633,9 @@
\deprecated
\overload
- Use std::upper_bound instead.
+ Use \c std::upper_bound instead.
- This is the same as qUpperBound(\a{container}.begin(), \a{container}.end(), value);
+ This is the same as qUpperBound(\a{container}.begin(), \a{container}.end(), \a value);
*/
@@ -643,7 +643,7 @@
\relates <QtAlgorithms>
\deprecated
- Use std::binary_search or std::lower_bound instead.
+ Use \c std::binary_search or \c std::lower_bound instead.
Performs a binary search of the range [\a begin, \a end) and
returns the position of an occurrence of \a value. If there are
@@ -670,7 +670,7 @@
\deprecated
\overload
- Use std::binary_search or std::lower_bound instead.
+ Use \c std::binary_search or \c std::lower_bound instead.
Uses the \a lessThan function instead of \c operator<() to
compare the items.
@@ -685,9 +685,9 @@
\deprecated
\overload
- Use std::binary_search or std::lower_bound instead.
+ Use \c std::binary_search or \c std::lower_bound instead.
- This is the same as qBinaryFind(\a{container}.begin(), \a{container}.end(), value);
+ This is the same as qBinaryFind(\a{container}.begin(), \a{container}.end(), \a value);
*/
@@ -727,7 +727,7 @@
\relates <QtAlgorithms>
\deprecated
- Use std::less instead.
+ Use \c std::less instead.
Returns a functional object, or functor, that can be passed to qSort()
or qStableSort().
@@ -743,7 +743,7 @@
\relates <QtAlgorithms>
\deprecated
- Use std::greater instead.
+ Use \c std::greater instead.
Returns a functional object, or functor, that can be passed to qSort()
or qStableSort().
diff --git a/src/dbus/dbus.pro b/src/dbus/dbus.pro
index c5afe8c4d2..3ef8e6c80c 100644
--- a/src/dbus/dbus.pro
+++ b/src/dbus/dbus.pro
@@ -61,7 +61,8 @@ HEADERS += $$PUB_HEADERS \
qdbusintegrator_p.h \
qdbuspendingcall_p.h \
qdbus_symbols_p.h \
- qdbusintrospection_p.h
+ qdbusintrospection_p.h \
+ dbus_minimal_p.h
SOURCES += qdbusconnection.cpp \
qdbusconnectioninterface.cpp \
qdbuserror.cpp \
diff --git a/src/dbus/dbus_minimal_p.h b/src/dbus/dbus_minimal_p.h
new file mode 100644
index 0000000000..862e8201a1
--- /dev/null
+++ b/src/dbus/dbus_minimal_p.h
@@ -0,0 +1,275 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Intel Corporation
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtDBus module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL21$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 or version 3 as published by the Free
+** Software Foundation and appearing in the file LICENSE.LGPLv21 and
+** LICENSE.LGPLv3 included in the packaging of this file. Please review the
+** following information to ensure the GNU Lesser General Public License
+** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#ifndef DBUS_MINIMAL_P_H
+#define DBUS_MINIMAL_P_H
+
+extern "C" {
+
+// Equivalent to dbus-arch-deps.h
+typedef qint64 dbus_int64_t;
+typedef quint64 dbus_uint64_t;
+typedef qint32 dbus_int32_t;
+typedef quint32 dbus_uint32_t;
+typedef qint16 dbus_int16_t;
+typedef quint16 dbus_uint16_t;
+
+// simulate minimum version we support
+#define DBUS_MAJOR_VERSION 1
+#define DBUS_MINOR_VERSION 2
+#define DBUS_VERSION ((1 << 16) | (2 << 8))
+
+// forward declaration to opaque types we use
+struct DBusConnection;
+struct DBusMessage;
+struct DBusPendingCall;
+struct DBusServer;
+struct DBusTimeout;
+struct DBusWatch;
+
+// This file contains constants and typedefs from libdbus-1 headers,
+// which carry the following copyright:
+/*
+ * Copyright (C) 2002, 2003 CodeFactory AB
+ * Copyright (C) 2004, 2005 Red Hat, Inc.
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+/* dbus-types.h */
+typedef dbus_uint32_t dbus_unichar_t;
+typedef dbus_uint32_t dbus_bool_t;
+
+/* dbus-shared.h */
+#define DBUS_SERVICE_DBUS "org.freedesktop.DBus"
+#define DBUS_PATH_DBUS "/org/freedesktop/DBus"
+#define DBUS_INTERFACE_DBUS "org.freedesktop.DBus"
+#define DBUS_INTERFACE_INTROSPECTABLE "org.freedesktop.DBus.Introspectable"
+#define DBUS_INTERFACE_PROPERTIES "org.freedesktop.DBus.Properties"
+
+#define DBUS_NAME_FLAG_ALLOW_REPLACEMENT 0x1 /**< Allow another service to become the primary owner if requested */
+#define DBUS_NAME_FLAG_REPLACE_EXISTING 0x2 /**< Request to replace the current primary owner */
+#define DBUS_NAME_FLAG_DO_NOT_QUEUE 0x4 /**< If we can not become the primary owner do not place us in the queue */
+
+#define DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER 1 /**< Service has become the primary owner of the requested name */
+#define DBUS_REQUEST_NAME_REPLY_IN_QUEUE 2 /**< Service could not become the primary owner and has been placed in the queue */
+#define DBUS_REQUEST_NAME_REPLY_EXISTS 3 /**< Service is already in the queue */
+#define DBUS_REQUEST_NAME_REPLY_ALREADY_OWNER 4 /**< Service is already the primary owner */
+
+#define DBUS_RELEASE_NAME_REPLY_RELEASED 1 /**< Service was released from the given name */
+#define DBUS_RELEASE_NAME_REPLY_NON_EXISTENT 2 /**< The given name does not exist on the bus */
+#define DBUS_RELEASE_NAME_REPLY_NOT_OWNER 3 /**< Service is not an owner of the given name */
+
+typedef enum
+{
+ DBUS_BUS_SESSION, /**< The login session bus */
+ DBUS_BUS_SYSTEM, /**< The systemwide bus */
+ DBUS_BUS_STARTER /**< The bus that started us, if any */
+} DBusBusType;
+
+typedef enum
+{
+ DBUS_HANDLER_RESULT_HANDLED, /**< Message has had its effect - no need to run more handlers. */
+ DBUS_HANDLER_RESULT_NOT_YET_HANDLED, /**< Message has not had any effect - see if other handlers want it. */
+ DBUS_HANDLER_RESULT_NEED_MEMORY /**< Need more memory in order to return #DBUS_HANDLER_RESULT_HANDLED or #DBUS_HANDLER_RESULT_NOT_YET_HANDLED. Please try again later with more memory. */
+} DBusHandlerResult;
+
+/* dbus-memory.h */
+typedef void (* DBusFreeFunction) (void *memory);
+
+/* dbus-connection.h */
+typedef enum
+{
+ DBUS_WATCH_READABLE = 1 << 0, /**< As in POLLIN */
+ DBUS_WATCH_WRITABLE = 1 << 1, /**< As in POLLOUT */
+ DBUS_WATCH_ERROR = 1 << 2, /**< As in POLLERR (can't watch for
+ * this, but can be present in
+ * current state passed to
+ * dbus_watch_handle()).
+ */
+ DBUS_WATCH_HANGUP = 1 << 3 /**< As in POLLHUP (can't watch for
+ * it, but can be present in current
+ * state passed to
+ * dbus_watch_handle()).
+ */
+ /* Internal to libdbus, there is also _DBUS_WATCH_NVAL in dbus-watch.h */
+} DBusWatchFlags;
+
+typedef enum
+{
+ DBUS_DISPATCH_DATA_REMAINS, /**< There is more data to potentially convert to messages. */
+ DBUS_DISPATCH_COMPLETE, /**< All currently available data has been processed. */
+ DBUS_DISPATCH_NEED_MEMORY /**< More memory is needed to continue. */
+} DBusDispatchStatus;
+
+typedef dbus_bool_t (* DBusAddWatchFunction) (DBusWatch *watch,
+ void *data);
+typedef void (* DBusWatchToggledFunction) (DBusWatch *watch,
+ void *data);
+typedef void (* DBusRemoveWatchFunction) (DBusWatch *watch,
+ void *data);
+typedef dbus_bool_t (* DBusAddTimeoutFunction) (DBusTimeout *timeout,
+ void *data);
+typedef void (* DBusTimeoutToggledFunction) (DBusTimeout *timeout,
+ void *data);
+typedef void (* DBusRemoveTimeoutFunction) (DBusTimeout *timeout,
+ void *data);
+typedef void (* DBusDispatchStatusFunction) (DBusConnection *connection,
+ DBusDispatchStatus new_status,
+ void *data);
+typedef void (* DBusWakeupMainFunction) (void *data);
+typedef void (* DBusPendingCallNotifyFunction) (DBusPendingCall *pending,
+ void *user_data);
+typedef DBusHandlerResult (* DBusHandleMessageFunction) (DBusConnection *connection,
+ DBusMessage *message,
+ void *user_data);
+
+/* dbus-errors.h */
+struct DBusError
+{
+ const char *name; /**< public error name field */
+ const char *message; /**< public error message field */
+
+ unsigned int dummy1 : 1; /**< placeholder */
+ unsigned int dummy2 : 1; /**< placeholder */
+ unsigned int dummy3 : 1; /**< placeholder */
+ unsigned int dummy4 : 1; /**< placeholder */
+ unsigned int dummy5 : 1; /**< placeholder */
+
+ void *padding1; /**< placeholder */
+};
+
+/* dbus-message.h */
+struct DBusMessageIter
+{
+ void *dummy1; /**< Don't use this */
+ void *dummy2; /**< Don't use this */
+ dbus_uint32_t dummy3; /**< Don't use this */
+ int dummy4; /**< Don't use this */
+ int dummy5; /**< Don't use this */
+ int dummy6; /**< Don't use this */
+ int dummy7; /**< Don't use this */
+ int dummy8; /**< Don't use this */
+ int dummy9; /**< Don't use this */
+ int dummy10; /**< Don't use this */
+ int dummy11; /**< Don't use this */
+ int pad1; /**< Don't use this */
+ int pad2; /**< Don't use this */
+ void *pad3; /**< Don't use this */
+};
+
+/* dbus-protocol.h */
+#define DBUS_TYPE_INVALID ((int) '\0')
+#define DBUS_TYPE_INVALID_AS_STRING "\0"
+#define DBUS_TYPE_BYTE ((int) 'y')
+#define DBUS_TYPE_BYTE_AS_STRING "y"
+#define DBUS_TYPE_BOOLEAN ((int) 'b')
+#define DBUS_TYPE_BOOLEAN_AS_STRING "b"
+#define DBUS_TYPE_INT16 ((int) 'n')
+#define DBUS_TYPE_INT16_AS_STRING "n"
+#define DBUS_TYPE_UINT16 ((int) 'q')
+#define DBUS_TYPE_UINT16_AS_STRING "q"
+#define DBUS_TYPE_INT32 ((int) 'i')
+#define DBUS_TYPE_INT32_AS_STRING "i"
+#define DBUS_TYPE_UINT32 ((int) 'u')
+#define DBUS_TYPE_UINT32_AS_STRING "u"
+#define DBUS_TYPE_INT64 ((int) 'x')
+#define DBUS_TYPE_INT64_AS_STRING "x"
+#define DBUS_TYPE_UINT64 ((int) 't')
+#define DBUS_TYPE_UINT64_AS_STRING "t"
+#define DBUS_TYPE_DOUBLE ((int) 'd')
+#define DBUS_TYPE_DOUBLE_AS_STRING "d"
+#define DBUS_TYPE_STRING ((int) 's')
+#define DBUS_TYPE_STRING_AS_STRING "s"
+#define DBUS_TYPE_OBJECT_PATH ((int) 'o')
+#define DBUS_TYPE_OBJECT_PATH_AS_STRING "o"
+#define DBUS_TYPE_SIGNATURE ((int) 'g')
+#define DBUS_TYPE_SIGNATURE_AS_STRING "g"
+#define DBUS_TYPE_UNIX_FD ((int) 'h')
+#define DBUS_TYPE_UNIX_FD_AS_STRING "h"
+#define DBUS_TYPE_ARRAY ((int) 'a')
+#define DBUS_TYPE_ARRAY_AS_STRING "a"
+#define DBUS_TYPE_VARIANT ((int) 'v')
+#define DBUS_TYPE_VARIANT_AS_STRING "v"
+
+#define DBUS_TYPE_STRUCT ((int) 'r')
+#define DBUS_TYPE_STRUCT_AS_STRING "r"
+#define DBUS_TYPE_DICT_ENTRY ((int) 'e')
+#define DBUS_TYPE_DICT_ENTRY_AS_STRING "e"
+
+#define DBUS_STRUCT_BEGIN_CHAR ((int) '(')
+#define DBUS_STRUCT_BEGIN_CHAR_AS_STRING "("
+#define DBUS_STRUCT_END_CHAR ((int) ')')
+#define DBUS_STRUCT_END_CHAR_AS_STRING ")"
+#define DBUS_DICT_ENTRY_BEGIN_CHAR ((int) '{')
+#define DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING "{"
+#define DBUS_DICT_ENTRY_END_CHAR ((int) '}')
+#define DBUS_DICT_ENTRY_END_CHAR_AS_STRING "}"
+
+#define DBUS_MESSAGE_TYPE_INVALID 0
+#define DBUS_MESSAGE_TYPE_METHOD_CALL 1
+#define DBUS_MESSAGE_TYPE_METHOD_RETURN 2
+#define DBUS_MESSAGE_TYPE_ERROR 3
+#define DBUS_MESSAGE_TYPE_SIGNAL 4
+
+#define DBUS_MAXIMUM_NAME_LENGTH 255
+
+#define DBUS_INTROSPECT_1_0_XML_NAMESPACE "http://www.freedesktop.org/standards/dbus"
+#define DBUS_INTROSPECT_1_0_XML_PUBLIC_IDENTIFIER "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
+#define DBUS_INTROSPECT_1_0_XML_SYSTEM_IDENTIFIER "http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd"
+#define DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE "<!DOCTYPE node PUBLIC \"" DBUS_INTROSPECT_1_0_XML_PUBLIC_IDENTIFIER "\"\n\"" DBUS_INTROSPECT_1_0_XML_SYSTEM_IDENTIFIER "\">\n"
+
+/* dbus-server.h */
+typedef void (* DBusNewConnectionFunction) (DBusServer *server,
+ DBusConnection *new_connection,
+ void *data);
+
+} // extern "C"
+
+#endif // DBUS_MINIMAL_P_H
+
diff --git a/src/dbus/qdbus_symbols_p.h b/src/dbus/qdbus_symbols_p.h
index 71658f84c6..88c51947ed 100644
--- a/src/dbus/qdbus_symbols_p.h
+++ b/src/dbus/qdbus_symbols_p.h
@@ -47,10 +47,15 @@
#define QDBUS_SYMBOLS_P_H
#include <QtCore/qglobal.h>
-#include <dbus/dbus.h>
#ifndef QT_NO_DBUS
+#ifdef QT_LINKED_LIBDBUS
+# include <dbus/dbus.h>
+#else
+# include "dbus_minimal_p.h"
+#endif
+
QT_BEGIN_NAMESPACE
#if !defined QT_LINKED_LIBDBUS
diff --git a/src/dbus/qdbusintegrator.cpp b/src/dbus/qdbusintegrator.cpp
index 6fcdd5030a..1978e259fd 100644
--- a/src/dbus/qdbusintegrator.cpp
+++ b/src/dbus/qdbusintegrator.cpp
@@ -1184,6 +1184,7 @@ void QDBusConnectionPrivate::socketRead(int fd)
if (it->watch && it->read && it->read->isEnabled()) {
if (!q_dbus_watch_handle(it.value().watch, DBUS_WATCH_READABLE))
qDebug("OUT OF MEM");
+ break;
}
++it;
}
@@ -1198,6 +1199,7 @@ void QDBusConnectionPrivate::socketWrite(int fd)
if (it->watch && it->write && it->write->isEnabled()) {
if (!q_dbus_watch_handle(it.value().watch, DBUS_WATCH_WRITABLE))
qDebug("OUT OF MEM");
+ break;
}
++it;
}
diff --git a/src/dbus/qdbusreply.cpp b/src/dbus/qdbusreply.cpp
index c141c233a1..624a1bd3ed 100644
--- a/src/dbus/qdbusreply.cpp
+++ b/src/dbus/qdbusreply.cpp
@@ -219,7 +219,7 @@ void qDBusReplyFill(const QDBusMessage &reply, QDBusError &error, QVariant &data
// error
if (receivedSignature.isEmpty())
- receivedSignature = "no signature";
+ receivedSignature = "<empty signature>";
QString errorMsg;
if (receivedType) {
errorMsg = QString::fromLatin1("Unexpected reply signature: got \"%1\" (%4), "
diff --git a/src/gui/image/qimage_p.h b/src/gui/image/qimage_p.h
index 26c42b988e..47e68b14a5 100644
--- a/src/gui/image/qimage_p.h
+++ b/src/gui/image/qimage_p.h
@@ -116,6 +116,9 @@ void qInitImageConversions();
const uchar *qt_get_bitflip_array();
Q_GUI_EXPORT void qGamma_correct_back_to_linear_cs(QImage *image);
+#if defined(Q_OS_WINRT) && defined(_M_ARM) // QTBUG-42038
+#pragma optimize("", off)
+#endif
inline int qt_depthForFormat(QImage::Format format)
{
int depth = 0;
@@ -160,6 +163,9 @@ inline int qt_depthForFormat(QImage::Format format)
}
return depth;
}
+#if defined(Q_OS_WINRT) && defined(_M_ARM)
+#pragma optimize("", on)
+#endif
QT_END_NAMESPACE
diff --git a/src/gui/kernel/qopenglwindow.cpp b/src/gui/kernel/qopenglwindow.cpp
index 158fb248dc..c37974c429 100644
--- a/src/gui/kernel/qopenglwindow.cpp
+++ b/src/gui/kernel/qopenglwindow.cpp
@@ -38,6 +38,7 @@
#include <QtGui/QOpenGLFunctions>
#include <QtGui/private/qopengltextureblitter_p.h>
#include <QtGui/private/qopenglextensions_p.h>
+#include <QtGui/private/qopenglcontext_p.h>
#include <QtGui/QMatrix4x4>
#include <QtGui/QOffscreenSurface>
@@ -101,6 +102,10 @@ QT_BEGIN_NAMESPACE
this way they do not have to redraw the entire window content on each
paintGL() call.
+ Similarly to QOpenGLWidget, QOpenGLWindow supports the Qt::AA_ShareOpenGLContexts
+ attribute. When enabled, the OpenGL contexts of all QOpenGLWindow instances will share
+ with each other. This allows accessing each other's shareable OpenGL resources.
+
For more information on graphics in Qt, see \l {Graphics}.
*/
@@ -196,6 +201,7 @@ public:
if (!context) {
context.reset(new QOpenGLContext);
+ context->setShareContext(qt_gl_global_share_context());
context->setFormat(q->requestedFormat());
if (!context->create())
qWarning("QOpenGLWindow::beginPaint: Failed to create context");
diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp
index 124d9d53f6..6351b8a1e3 100644
--- a/src/gui/opengl/qopenglframebufferobject.cpp
+++ b/src/gui/opengl/qopenglframebufferobject.cpp
@@ -481,11 +481,9 @@ void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *, const QSi
GLenum storageFormat = internal_format;
// ES requires a sized format. The older desktop extension does not. Correct the format on ES.
if (ctx->isOpenGLES() && internal_format == GL_RGBA) {
-#ifdef GL_RGBA8_OES
if (funcs.hasOpenGLExtension(QOpenGLExtensions::Sized8Formats))
- storageFormat = GL_RGBA8_OES;
+ storageFormat = GL_RGBA8;
else
-#endif
storageFormat = GL_RGBA4;
}
diff --git a/src/gui/opengl/qopenglpaintengine.cpp b/src/gui/opengl/qopenglpaintengine.cpp
index 299d3da73d..bfc08a5332 100644
--- a/src/gui/opengl/qopenglpaintengine.cpp
+++ b/src/gui/opengl/qopenglpaintengine.cpp
@@ -107,7 +107,7 @@ QOpenGL2PaintEngineExPrivate::~QOpenGL2PaintEngineExPrivate()
}
}
-void QOpenGL2PaintEngineExPrivate::updateTextureFilter(GLenum target, GLenum wrapMode, bool smoothPixmapTransform, GLuint id)
+void QOpenGL2PaintEngineExPrivate::updateTextureFilter(GLenum wrapMode, bool smoothPixmapTransform, GLuint id)
{
// funcs.glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT); //### Is it always this texture unit?
if (id != GLuint(-1) && id == lastTextureUsed)
@@ -115,6 +115,8 @@ void QOpenGL2PaintEngineExPrivate::updateTextureFilter(GLenum target, GLenum wra
lastTextureUsed = id;
+ static const GLenum target = GL_TEXTURE_2D;
+
if (smoothPixmapTransform) {
funcs.glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
funcs.glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
@@ -122,6 +124,7 @@ void QOpenGL2PaintEngineExPrivate::updateTextureFilter(GLenum target, GLenum wra
funcs.glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
funcs.glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
}
+
funcs.glTexParameteri(target, GL_TEXTURE_WRAP_S, wrapMode);
funcs.glTexParameteri(target, GL_TEXTURE_WRAP_T, wrapMode);
}
@@ -185,7 +188,7 @@ void QOpenGL2PaintEngineExPrivate::updateBrushTexture()
funcs.glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT);
QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, texImage);
- updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, q->state()->renderHints & QPainter::SmoothPixmapTransform);
+ updateTextureFilter(GL_REPEAT, q->state()->renderHints & QPainter::SmoothPixmapTransform);
}
else if (style >= Qt::LinearGradientPattern && style <= Qt::ConicalGradientPattern) {
// Gradiant brush: All the gradiants use the same texture
@@ -196,15 +199,15 @@ void QOpenGL2PaintEngineExPrivate::updateBrushTexture()
// for opacity to the cache.
GLuint texId = QOpenGL2GradientCache::cacheForContext(ctx)->getBuffer(*g, 1.0);
- funcs.glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT);
- funcs.glBindTexture(GL_TEXTURE_2D, texId);
-
+ GLenum wrapMode = GL_CLAMP_TO_EDGE;
if (g->spread() == QGradient::RepeatSpread || g->type() == QGradient::ConicalGradient)
- updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, q->state()->renderHints & QPainter::SmoothPixmapTransform);
+ wrapMode = GL_REPEAT;
else if (g->spread() == QGradient::ReflectSpread)
- updateTextureFilter(GL_TEXTURE_2D, GL_MIRRORED_REPEAT, q->state()->renderHints & QPainter::SmoothPixmapTransform);
- else
- updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE, q->state()->renderHints & QPainter::SmoothPixmapTransform);
+ wrapMode = GL_MIRRORED_REPEAT;
+
+ funcs.glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT);
+ funcs.glBindTexture(GL_TEXTURE_2D, texId);
+ updateTextureFilter(wrapMode, q->state()->renderHints & QPainter::SmoothPixmapTransform);
}
else if (style == Qt::TexturePattern) {
currentBrushImage = currentBrush.textureImage();
@@ -223,7 +226,8 @@ void QOpenGL2PaintEngineExPrivate::updateBrushTexture()
funcs.glActiveTexture(GL_TEXTURE0 + QT_BRUSH_TEXTURE_UNIT);
QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, currentBrushImage);
- updateTextureFilter(GL_TEXTURE_2D, wrapMode, q->state()->renderHints & QPainter::SmoothPixmapTransform);
+ updateTextureFilter(wrapMode, q->state()->renderHints & QPainter::SmoothPixmapTransform);
+
textureInvertedY = false;
}
brushTextureDirty = false;
@@ -1380,16 +1384,14 @@ void QOpenGL2PaintEngineEx::drawPixmap(const QRectF& dest, const QPixmap & pixma
d->funcs.glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
GLuint id = QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, pixmap);
-
- QOpenGLRect srcRect(src.left(), src.top(), src.right(), src.bottom());
+ d->updateTextureFilter(GL_CLAMP_TO_EDGE, state()->renderHints & QPainter::SmoothPixmapTransform, id);
bool isBitmap = pixmap.isQBitmap();
bool isOpaque = !isBitmap && !pixmap.hasAlpha();
- d->updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE,
- state()->renderHints & QPainter::SmoothPixmapTransform, id);
-
d->shaderManager->setSrcPixelType(isBitmap ? QOpenGLEngineShaderManager::PatternSrc : QOpenGLEngineShaderManager::ImageSrc);
+
+ QOpenGLRect srcRect(src.left(), src.top(), src.right(), src.bottom());
d->drawTexture(dest, srcRect, pixmap.size(), isOpaque, isBitmap);
}
@@ -1442,9 +1444,7 @@ void QOpenGL2PaintEngineEx::drawImage(const QRectF& dest, const QImage& image, c
d->funcs.glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
GLuint id = QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, image, bindOption);
-
- d->updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE,
- state()->renderHints & QPainter::SmoothPixmapTransform, id);
+ d->updateTextureFilter(GL_CLAMP_TO_EDGE, state()->renderHints & QPainter::SmoothPixmapTransform, id);
d->drawTexture(dest, src, image.size(), !image.hasAlphaChannel());
}
@@ -1487,13 +1487,13 @@ bool QOpenGL2PaintEngineEx::drawTexture(const QRectF &dest, GLuint textureId, co
d->funcs.glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
d->funcs.glBindTexture(GL_TEXTURE_2D, textureId);
+ d->updateTextureFilter(GL_CLAMP_TO_EDGE, state()->renderHints & QPainter::SmoothPixmapTransform, textureId);
- QOpenGLRect srcRect(src.left(), src.bottom(), src.right(), src.top());
-
- d->updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE,
- state()->renderHints & QPainter::SmoothPixmapTransform, textureId);
d->shaderManager->setSrcPixelType(QOpenGLEngineShaderManager::ImageSrc);
+
+ QOpenGLRect srcRect(src.left(), src.bottom(), src.right(), src.top());
d->drawTexture(dest, srcRect, size, false);
+
return true;
}
@@ -1821,7 +1821,7 @@ void QOpenGL2PaintEngineExPrivate::drawCachedGlyphs(QFontEngine::GlyphFormat gly
funcs.glActiveTexture(GL_TEXTURE0 + QT_MASK_TEXTURE_UNIT);
funcs.glBindTexture(GL_TEXTURE_2D, cache->texture());
- updateTextureFilter(GL_TEXTURE_2D, GL_REPEAT, false);
+ updateTextureFilter(GL_REPEAT, false);
#if defined(QT_OPENGL_DRAWCACHEDGLYPHS_INDEX_ARRAY_VBO)
funcs.glDrawElements(GL_TRIANGLE_STRIP, 6 * numGlyphs, GL_UNSIGNED_SHORT, 0);
@@ -1964,16 +1964,15 @@ void QOpenGL2PaintEngineExPrivate::drawPixmapFragments(const QPainter::PixmapFra
allOpaque &= (opacity >= 0.99f);
}
+ transferMode(ImageOpacityArrayDrawingMode);
+
funcs.glActiveTexture(GL_TEXTURE0 + QT_IMAGE_TEXTURE_UNIT);
GLuint id = QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, pixmap);
- transferMode(ImageOpacityArrayDrawingMode);
+ updateTextureFilter(GL_CLAMP_TO_EDGE, q->state()->renderHints & QPainter::SmoothPixmapTransform, id);
bool isBitmap = pixmap.isQBitmap();
bool isOpaque = !isBitmap && (!pixmap.hasAlpha() || (hints & QPainter::OpaqueHint)) && allOpaque;
- updateTextureFilter(GL_TEXTURE_2D, GL_CLAMP_TO_EDGE,
- q->state()->renderHints & QPainter::SmoothPixmapTransform, id);
-
// Setup for texture drawing
currentBrush = noBrush;
shaderManager->setSrcPixelType(isBitmap ? QOpenGLEngineShaderManager::PatternSrc
diff --git a/src/gui/opengl/qopenglpaintengine_p.h b/src/gui/opengl/qopenglpaintengine_p.h
index 47e915eae5..85ecd82b6f 100644
--- a/src/gui/opengl/qopenglpaintengine_p.h
+++ b/src/gui/opengl/qopenglpaintengine_p.h
@@ -193,7 +193,7 @@ public:
void updateBrushUniforms();
void updateMatrix();
void updateCompositionMode();
- void updateTextureFilter(GLenum target, GLenum wrapMode, bool smoothPixmapTransform, GLuint id = GLuint(-1));
+ void updateTextureFilter(GLenum wrapMode, bool smoothPixmapTransform, GLuint id = GLuint(-1));
void resetGLState();
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index a991b89f48..bd53952d1b 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -6288,6 +6288,8 @@ static inline void rgbBlendPixel(quint32 *dst, int coverage, int sr, int sg, int
}
#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
+Q_GUI_EXPORT bool qt_needs_a8_gamma_correction = false;
+
static inline void grayBlendPixel(quint32 *dst, int coverage, int sr, int sg, int sb, const uint *gamma, const uchar *invgamma)
{
// Do a gammacorrected gray alphablend...
@@ -6335,6 +6337,7 @@ static void qt_alphamapblit_argb32(QRasterBuffer *rasterBuffer,
int sb = gamma[qBlue(color)];
bool opaque_src = (qAlpha(color) == 255);
+ bool doGrayBlendPixel = opaque_src && qt_needs_a8_gamma_correction;
#endif
if (!clip) {
@@ -6349,7 +6352,7 @@ static void qt_alphamapblit_argb32(QRasterBuffer *rasterBuffer,
dest[i] = c;
} else {
#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
- if (QSysInfo::WindowsVersion >= QSysInfo::WV_XP && opaque_src
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_XP && doGrayBlendPixel
&& qAlpha(dest[i]) == 255) {
grayBlendPixel(dest+i, coverage, sr, sg, sb, gamma, invgamma);
} else
@@ -6390,7 +6393,7 @@ static void qt_alphamapblit_argb32(QRasterBuffer *rasterBuffer,
dest[xp] = c;
} else {
#if defined(Q_OS_WIN) && !defined(Q_OS_WINCE)
- if (QSysInfo::WindowsVersion >= QSysInfo::WV_XP && opaque_src
+ if (QSysInfo::WindowsVersion >= QSysInfo::WV_XP && doGrayBlendPixel
&& qAlpha(dest[xp]) == 255) {
grayBlendPixel(dest+xp, coverage, sr, sg, sb, gamma, invgamma);
} else
diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp
index ef397e532c..4d6c04a262 100644
--- a/src/gui/text/qfontengine_ft.cpp
+++ b/src/gui/text/qfontengine_ft.cpp
@@ -762,8 +762,10 @@ bool QFontEngineFT::init(FaceId faceId, bool antialias, GlyphFormat format,
face->face_flags &= ~FT_FACE_FLAG_SCALABLE;
FT_Select_Size(face, i);
- metrics.ascender = face->size->metrics.ascender;
- metrics.descender = face->size->metrics.descender;
+ if (face->size->metrics.ascender + face->size->metrics.descender > 0) {
+ metrics.ascender = face->size->metrics.ascender;
+ metrics.descender = face->size->metrics.descender;
+ }
FT_Set_Char_Size(face, xsize, ysize, 0, 0);
face->face_flags |= FT_FACE_FLAG_SCALABLE;
@@ -889,6 +891,13 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
// this is an error in the bytecode interpreter, just try to run without it
load_flags |= FT_LOAD_FORCE_AUTOHINT;
err = FT_Load_Glyph(face, glyph, load_flags);
+ } else if (err == FT_Err_Execution_Too_Long) {
+ // This is an error in the bytecode, probably a web font made by someone who
+ // didn't test bytecode hinting at all so disable for it for all glyphs.
+ qWarning("load glyph failed due to broken hinting bytecode in font, switching to auto hinting");
+ default_load_flags |= FT_LOAD_FORCE_AUTOHINT;
+ load_flags |= FT_LOAD_FORCE_AUTOHINT;
+ err = FT_Load_Glyph(face, glyph, load_flags);
}
if (err != FT_Err_Ok) {
qWarning("load glyph failed err=%x face=%p, glyph=%d", err, face, glyph);
@@ -1123,7 +1132,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
while (h--) {
uint *dd = (uint *)dst;
*dd++ = 0;
- for (int x = 0; x < slot->bitmap.width; x++) {
+ for (int x = 0; x < static_cast<int>(slot->bitmap.width); x++) {
uint a = ((src[x >> 3] & (0x80 >> (x & 7))) ? 0xffffff : 0x000000);
*dd++ = a;
}
@@ -1134,7 +1143,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
} else if (vfactor != 1) {
while (h--) {
uint *dd = (uint *)dst;
- for (int x = 0; x < slot->bitmap.width; x++) {
+ for (int x = 0; x < static_cast<int>(slot->bitmap.width); x++) {
uint a = ((src[x >> 3] & (0x80 >> (x & 7))) ? 0xffffff : 0x000000);
*dd++ = a;
}
@@ -1143,7 +1152,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
}
} else {
while (h--) {
- for (int x = 0; x < slot->bitmap.width; x++) {
+ for (int x = 0; x < static_cast<int>(slot->bitmap.width); x++) {
unsigned char a = ((src[x >> 3] & (0x80 >> (x & 7))) ? 0xff : 0x00);
dst[x] = a;
}
@@ -1771,8 +1780,7 @@ glyph_metrics_t QFontEngineFT::alphaMapBoundingBox(glyph_t glyph, QFixed subPixe
overall.x = TRUNC(left);
overall.y = -TRUNC(top);
overall.xoff = TRUNC(ROUND(face->glyph->advance.x));
- if (face)
- unlockFace();
+ unlockFace();
}
return overall;
}
diff --git a/src/gui/text/qfontengine_ft_p.h b/src/gui/text/qfontengine_ft_p.h
index 4c29b5a504..02c692cccc 100644
--- a/src/gui/text/qfontengine_ft_p.h
+++ b/src/gui/text/qfontengine_ft_p.h
@@ -293,7 +293,7 @@ private:
protected:
QFreetypeFace *freetype;
- int default_load_flags;
+ mutable int default_load_flags;
HintStyle default_hint_style;
bool antialias;
bool transform;
diff --git a/src/network/access/qhttpthreaddelegate.cpp b/src/network/access/qhttpthreaddelegate.cpp
index 8651efab86..e31f23c18c 100644
--- a/src/network/access/qhttpthreaddelegate.cpp
+++ b/src/network/access/qhttpthreaddelegate.cpp
@@ -558,6 +558,8 @@ void QHttpThreadDelegate::synchronousFinishedWithErrorSlot(QNetworkReply::Networ
incomingErrorCode = errorCode;
incomingErrorDetail = detail;
+ synchronousDownloadData = httpReply->readAll();
+
QMetaObject::invokeMethod(httpReply, "deleteLater", Qt::QueuedConnection);
QMetaObject::invokeMethod(synchronousRequestLoop, "quit", Qt::QueuedConnection);
httpReply = 0;
diff --git a/src/network/access/qnetworkreply.cpp b/src/network/access/qnetworkreply.cpp
index 1ec3fe31ac..d9b3acdd92 100644
--- a/src/network/access/qnetworkreply.cpp
+++ b/src/network/access/qnetworkreply.cpp
@@ -276,7 +276,7 @@ QNetworkReplyPrivate::QNetworkReplyPrivate()
processing. After this signal is emitted, there will be no more
updates to the reply's data or metadata.
- Unless close() has been called, the reply will be still be opened
+ Unless close() or abort() have been called, the reply will be still be opened
for reading, so the data can be retrieved by calls to read() or
readAll(). In particular, if no calls to read() were made as a
result of readyRead(), a call to readAll() will retrieve the full
@@ -365,7 +365,9 @@ QNetworkReplyPrivate::QNetworkReplyPrivate()
connections still open. Uploads still in progress are also
aborted.
- \sa close()
+ The finished() signal will also be emitted.
+
+ \sa close(), finished()
*/
/*!
diff --git a/src/network/socket/qabstractsocket.cpp b/src/network/socket/qabstractsocket.cpp
index e843597a96..604214ce8e 100644
--- a/src/network/socket/qabstractsocket.cpp
+++ b/src/network/socket/qabstractsocket.cpp
@@ -1882,6 +1882,9 @@ bool QAbstractSocket::setSocketDescriptor(qintptr socketDescriptor, SocketState
\since 4.6
Sets the given \a option to the value described by \a value.
+ \note On Windows Runtime, QAbstractSocket::KeepAliveOption must be set
+ before the socket is connected.
+
\sa socketOption()
*/
void QAbstractSocket::setSocketOption(QAbstractSocket::SocketOption option, const QVariant &value)
diff --git a/src/network/socket/qnativesocketengine_winrt.cpp b/src/network/socket/qnativesocketengine_winrt.cpp
index cacfe11fea..e60840d651 100644
--- a/src/network/socket/qnativesocketengine_winrt.cpp
+++ b/src/network/socket/qnativesocketengine_winrt.cpp
@@ -998,7 +998,8 @@ bool QNativeSocketEnginePrivate::setOption(QAbstractSocketEngine::SocketOption o
return true;
}
case QAbstractSocketEngine::KeepAliveOption: {
- if (socketType == QAbstractSocket::UdpSocket)
+ if (socketType == QAbstractSocket::UdpSocket
+ || socketState != QAbstractSocket::UnconnectedState)
return false;
boolean keepAlive = v;
diff --git a/src/network/ssl/qsslcertificate.cpp b/src/network/ssl/qsslcertificate.cpp
index 13bddcb3ea..125a7a0250 100644
--- a/src/network/ssl/qsslcertificate.cpp
+++ b/src/network/ssl/qsslcertificate.cpp
@@ -575,12 +575,12 @@ QList<QSslError> QSslCertificate::verify(QList<QSslCertificate> certificateChain
\note The \a device must be open and ready to be read from.
*/
-bool QSslCertificate::importPKCS12(QIODevice *device,
+bool QSslCertificate::importPkcs12(QIODevice *device,
QSslKey *key, QSslCertificate *certificate,
QList<QSslCertificate> *caCertificates,
const QByteArray &passPhrase)
{
- return QSslSocketBackendPrivate::importPKCS12(device, key, certificate, caCertificates, passPhrase);
+ return QSslSocketBackendPrivate::importPkcs12(device, key, certificate, caCertificates, passPhrase);
}
// These certificates are known to be fraudulent and were created during the comodo
diff --git a/src/network/ssl/qsslcertificate.h b/src/network/ssl/qsslcertificate.h
index e34ea97fc4..6aa7544815 100644
--- a/src/network/ssl/qsslcertificate.h
+++ b/src/network/ssl/qsslcertificate.h
@@ -138,7 +138,7 @@ public:
static QList<QSslError> verify(QList<QSslCertificate> certificateChain, const QString &hostName = QString());
- static bool importPKCS12(QIODevice *device,
+ static bool importPkcs12(QIODevice *device,
QSslKey *key, QSslCertificate *cert,
QList<QSslCertificate> *caCertificates=0,
const QByteArray &passPhrase=QByteArray());
diff --git a/src/network/ssl/qsslsocket_openssl.cpp b/src/network/ssl/qsslsocket_openssl.cpp
index 516d862936..3aa6247a1f 100644
--- a/src/network/ssl/qsslsocket_openssl.cpp
+++ b/src/network/ssl/qsslsocket_openssl.cpp
@@ -1699,7 +1699,7 @@ QList<QSslError> QSslSocketBackendPrivate::verify(QList<QSslCertificate> certifi
return errors;
}
-bool QSslSocketBackendPrivate::importPKCS12(QIODevice *device,
+bool QSslSocketBackendPrivate::importPkcs12(QIODevice *device,
QSslKey *key, QSslCertificate *cert,
QList<QSslCertificate> *caCertificates,
const QByteArray &passPhrase)
diff --git a/src/network/ssl/qsslsocket_openssl_p.h b/src/network/ssl/qsslsocket_openssl_p.h
index 9effc1f4c8..69634ceab5 100644
--- a/src/network/ssl/qsslsocket_openssl_p.h
+++ b/src/network/ssl/qsslsocket_openssl_p.h
@@ -136,7 +136,7 @@ public:
static QList<QSslCertificate> STACKOFX509_to_QSslCertificates(STACK_OF(X509) *x509);
static QList<QSslError> verify(QList<QSslCertificate> certificateChain, const QString &hostName);
static QString getErrorsFromOpenSsl();
- static bool importPKCS12(QIODevice *device,
+ static bool importPkcs12(QIODevice *device,
QSslKey *key, QSslCertificate *cert,
QList<QSslCertificate> *caCertificates,
const QByteArray &passPhrase);
diff --git a/src/network/ssl/qsslsocket_winrt.cpp b/src/network/ssl/qsslsocket_winrt.cpp
index da4c72be01..418a7416e4 100644
--- a/src/network/ssl/qsslsocket_winrt.cpp
+++ b/src/network/ssl/qsslsocket_winrt.cpp
@@ -661,7 +661,7 @@ QList<QSslError> QSslSocketBackendPrivate::verify(QList<QSslCertificate> certifi
return errors;
}
-bool QSslSocketBackendPrivate::importPKCS12(QIODevice *device,
+bool QSslSocketBackendPrivate::importPkcs12(QIODevice *device,
QSslKey *key, QSslCertificate *cert,
QList<QSslCertificate> *caCertificates,
const QByteArray &passPhrase)
diff --git a/src/network/ssl/qsslsocket_winrt_p.h b/src/network/ssl/qsslsocket_winrt_p.h
index aa31c85d6e..f0df7c6ef1 100644
--- a/src/network/ssl/qsslsocket_winrt_p.h
+++ b/src/network/ssl/qsslsocket_winrt_p.h
@@ -92,7 +92,7 @@ public:
static QList<QSslCipher> defaultCiphers();
static QList<QSslError> verify(QList<QSslCertificate> certificateChain, const QString &hostName);
- static bool importPKCS12(QIODevice *device,
+ static bool importPkcs12(QIODevice *device,
QSslKey *key, QSslCertificate *cert,
QList<QSslCertificate> *caCertificates,
const QByteArray &passPhrase);
diff --git a/src/plugins/platforms/android/androidjniinput.cpp b/src/plugins/platforms/android/androidjniinput.cpp
index 62da60ab92..59125ac0d2 100644
--- a/src/plugins/platforms/android/androidjniinput.cpp
+++ b/src/plugins/platforms/android/androidjniinput.cpp
@@ -638,6 +638,25 @@ namespace QtAndroidInput
}
}
+ static Qt::KeyboardModifiers mapAndroidModifiers(jint modifiers)
+ {
+ Qt::KeyboardModifiers qmodifiers;
+
+ if (modifiers & 0x00000001) // META_SHIFT_ON
+ qmodifiers |= Qt::ShiftModifier;
+
+ if (modifiers & 0x00000002) // META_ALT_ON
+ qmodifiers |= Qt::AltModifier;
+
+ if (modifiers & 0x00000004) // META_SYM_ON
+ qmodifiers |= Qt::MetaModifier;
+
+ if (modifiers & 0x00001000) // META_CTRL_ON
+ qmodifiers |= Qt::ControlModifier;
+
+ return qmodifiers;
+ }
+
// maps 0 to the empty string, and anything else to a single-character string
static inline QString toString(jint unicode)
{
@@ -646,40 +665,20 @@ namespace QtAndroidInput
static void keyDown(JNIEnv */*env*/, jobject /*thiz*/, jint key, jint unicode, jint modifier)
{
- Qt::KeyboardModifiers modifiers;
- if (modifier & 1)
- modifiers |= Qt::ShiftModifier;
-
- if (modifier & 2)
- modifiers |= Qt::AltModifier;
-
- if (modifier & 4)
- modifiers |= Qt::MetaModifier;
-
QWindowSystemInterface::handleKeyEvent(0,
QEvent::KeyPress,
mapAndroidKey(key),
- modifiers,
+ mapAndroidModifiers(modifier),
toString(unicode),
false);
}
static void keyUp(JNIEnv */*env*/, jobject /*thiz*/, jint key, jint unicode, jint modifier)
{
- Qt::KeyboardModifiers modifiers;
- if (modifier & 1)
- modifiers |= Qt::ShiftModifier;
-
- if (modifier & 2)
- modifiers |= Qt::AltModifier;
-
- if (modifier & 4)
- modifiers |= Qt::MetaModifier;
-
QWindowSystemInterface::handleKeyEvent(0,
QEvent::KeyRelease,
mapAndroidKey(key),
- modifiers,
+ mapAndroidModifiers(modifier),
toString(unicode),
false);
}
diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp
index a3848c9c2b..7e81735de9 100644
--- a/src/plugins/platforms/android/qandroidinputcontext.cpp
+++ b/src/plugins/platforms/android/qandroidinputcontext.cpp
@@ -611,6 +611,9 @@ jboolean QAndroidInputContext::endBatchEdit()
*/
jboolean QAndroidInputContext::commitText(const QString &text, jint newCursorPosition)
{
+ bool updateSelectionWasBlocked = m_blockUpdateSelection;
+ m_blockUpdateSelection = true;
+
QInputMethodEvent event;
event.setCommitString(text);
sendInputMethodEventThreadSafe(&event);
@@ -630,6 +633,7 @@ jboolean QAndroidInputContext::commitText(const QString &text, jint newCursorPos
newLocalPos, 0, QVariant()));
}
}
+ m_blockUpdateSelection = updateSelectionWasBlocked;
updateCursorPosition();
return JNI_TRUE;
diff --git a/src/plugins/platforms/android/qandroidplatformscreen.cpp b/src/plugins/platforms/android/qandroidplatformscreen.cpp
index 8a07735e5f..940add3a38 100644
--- a/src/plugins/platforms/android/qandroidplatformscreen.cpp
+++ b/src/plugins/platforms/android/qandroidplatformscreen.cpp
@@ -284,9 +284,9 @@ void QAndroidPlatformScreen::doRedraw()
if (m_dirtyRect.isEmpty())
return;
- // Stop if there no visible raster windows. This is important because if we only have
- // RasterGLSurface windows that have renderToTexture children (i.e. they need the
- // OpenGL path) then we must bail out right now.
+ // Stop if there are no visible raster windows. If we only have RasterGLSurface
+ // windows that have renderToTexture children (i.e. they need the OpenGL path) then
+ // we do not need an overlay surface.
bool hasVisibleRasterWindows = false;
foreach (QAndroidPlatformWindow *window, m_windowStack) {
if (window->window()->isVisible() && window->isRaster() && !qt_window_private(window->window())->compositing) {
@@ -294,9 +294,13 @@ void QAndroidPlatformScreen::doRedraw()
break;
}
}
- if (!hasVisibleRasterWindows)
+ if (!hasVisibleRasterWindows) {
+ if (m_id != -1) {
+ QtAndroid::destroySurface(m_id);
+ m_id = -1;
+ }
return;
-
+ }
QMutexLocker lock(&m_surfaceMutex);
if (m_id == -1 && m_rasterSurfaces) {
m_id = QtAndroid::createSurface(this, m_availableGeometry, true, m_depth);
@@ -339,6 +343,7 @@ void QAndroidPlatformScreen::doRedraw()
QRegion visibleRegion(m_dirtyRect);
foreach (QAndroidPlatformWindow *window, m_windowStack) {
if (!window->window()->isVisible()
+ || qt_window_private(window->window())->compositing
|| !window->isRaster())
continue;
diff --git a/src/plugins/platforms/android/qandroidplatformtheme.cpp b/src/plugins/platforms/android/qandroidplatformtheme.cpp
index ef7093942c..e729309ad9 100644
--- a/src/plugins/platforms/android/qandroidplatformtheme.cpp
+++ b/src/plugins/platforms/android/qandroidplatformtheme.cpp
@@ -278,7 +278,8 @@ static std::shared_ptr<AndroidStyle> loadAndroidStyle(QPalette *defaultPalette)
const int pt = paletteType(key);
if (pt > -1 || !qtClassName.isEmpty()) {
// Extract palette information
- QPalette palette;
+ QPalette palette = *defaultPalette;
+
attributeIterator = item.find(QLatin1String("defaultTextColorPrimary"));
if (attributeIterator != item.constEnd())
palette.setColor(QPalette::WindowText, QRgb(int(attributeIterator.value().toDouble())));
diff --git a/src/plugins/platforms/cocoa/qcocoamenuloader.mm b/src/plugins/platforms/cocoa/qcocoamenuloader.mm
index 9340e945fb..0075dea805 100644
--- a/src/plugins/platforms/cocoa/qcocoamenuloader.mm
+++ b/src/plugins/platforms/cocoa/qcocoamenuloader.mm
@@ -87,7 +87,11 @@ void qt_mac_loadMenuNib(QCocoaMenuLoader *qtMenuLoader)
return;
}
foreach (const QFileInfo &file, nibResource.entryInfoList()) {
- QFile::copy(file.absoluteFilePath(), nibDir + QLatin1String("/") + file.fileName());
+ QFileInfo destinationFile(nibDir + QLatin1String("/") + file.fileName());
+ if (destinationFile.exists() && destinationFile.size() != file.size())
+ QFile::remove(destinationFile.absoluteFilePath());
+
+ QFile::copy(file.absoluteFilePath(), destinationFile.absoluteFilePath());
}
// Load and instantiate nib file from temp
diff --git a/src/plugins/platforms/ios/qiosinputcontext.h b/src/plugins/platforms/ios/qiosinputcontext.h
index b4ff695f1a..863e503c3b 100644
--- a/src/plugins/platforms/ios/qiosinputcontext.h
+++ b/src/plugins/platforms/ios/qiosinputcontext.h
@@ -48,6 +48,22 @@ QT_BEGIN_NAMESPACE
@class QIOSKeyboardListener;
@class QIOSTextInputResponder;
+@protocol KeyboardState;
+
+struct KeyboardState
+{
+ KeyboardState() :
+ keyboardVisible(false), keyboardAnimating(false),
+ animationDuration(0), animationCurve(UIViewAnimationCurve(-1))
+ {}
+
+ bool keyboardVisible;
+ bool keyboardAnimating;
+ QRectF keyboardRect;
+ CGRect keyboardEndRect;
+ NSTimeInterval animationDuration;
+ UIViewAnimationCurve animationCurve;
+};
struct ImeState
{
@@ -69,6 +85,7 @@ public:
void hideInputPanel() Q_DECL_OVERRIDE;
bool isInputPanelVisible() const Q_DECL_OVERRIDE;
+ bool isAnimating() const Q_DECL_OVERRIDE;
QRectF keyboardRect() const Q_DECL_OVERRIDE;
void update(Qt::InputMethodQueries) Q_DECL_OVERRIDE;
@@ -84,14 +101,21 @@ public:
void scrollToCursor();
void scroll(int y);
+ void updateKeyboardState(NSNotification *notification = 0);
+
const ImeState &imeState() { return m_imeState; };
+ const KeyboardState &keyboardState() { return m_keyboardState; };
+
bool inputMethodAccepted() const;
static QIOSInputContext *instance();
private:
- QIOSKeyboardListener *m_keyboardListener;
+ UIView* scrollableRootView();
+
+ QIOSKeyboardListener *m_keyboardHideGesture;
QIOSTextInputResponder *m_textResponder;
+ KeyboardState m_keyboardState;
ImeState m_imeState;
};
diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm
index e417e9a1fb..fe9ee18155 100644
--- a/src/plugins/platforms/ios/qiosinputcontext.mm
+++ b/src/plugins/platforms/ios/qiosinputcontext.mm
@@ -45,6 +45,7 @@
#include "qiosglobal.h"
#include "qiosintegration.h"
+#include "qiosscreen.h"
#include "qiostextresponder.h"
#include "qiosviewcontroller.h"
#include "qioswindow.h"
@@ -64,15 +65,8 @@ static QUIView *focusView()
// -------------------------------------------------------------------------
@interface QIOSKeyboardListener : UIGestureRecognizer <UIGestureRecognizerDelegate> {
-@public
+ @private
QIOSInputContext *m_context;
- BOOL m_keyboardVisible;
- BOOL m_keyboardVisibleAndDocked;
- QRectF m_keyboardRect;
- CGRect m_keyboardEndRect;
- NSTimeInterval m_duration;
- UIViewAnimationCurve m_curve;
- UIViewController *m_viewController;
}
@end
@@ -80,87 +74,51 @@ static QUIView *focusView()
- (id)initWithQIOSInputContext:(QIOSInputContext *)context
{
- self = [super initWithTarget:self action:@selector(gestureStateChanged:)];
- if (self) {
+ id originalSelf = self;
+ if (self = [super initWithTarget:self action:@selector(gestureStateChanged:)]) {
+ Q_ASSERT(self == originalSelf);
+
m_context = context;
- m_keyboardVisible = NO;
- m_keyboardVisibleAndDocked = NO;
- m_duration = 0;
- m_curve = UIViewAnimationCurveEaseOut;
- m_viewController = 0;
-
- if (isQtApplication()) {
- // Get the root view controller that is on the same screen as the keyboard:
- for (UIWindow *uiWindow in [[UIApplication sharedApplication] windows]) {
- if (uiWindow.screen == [UIScreen mainScreen]) {
- m_viewController = [uiWindow.rootViewController retain];
- break;
- }
- }
- Q_ASSERT(m_viewController);
-
- // Attach 'hide keyboard' gesture to the window, but keep it disabled when the
- // keyboard is not visible.
- self.enabled = NO;
- self.cancelsTouchesInView = NO;
- self.delaysTouchesEnded = NO;
- [m_viewController.view.window addGestureRecognizer:self];
- }
- [[NSNotificationCenter defaultCenter]
- addObserver:self
+ // UIGestureRecognizer
+ self.enabled = NO;
+ self.cancelsTouchesInView = NO;
+ self.delaysTouchesEnded = NO;
+
+ NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
+
+ [notificationCenter addObserver:self
selector:@selector(keyboardWillShow:)
- name:@"UIKeyboardWillShowNotification" object:nil];
- [[NSNotificationCenter defaultCenter]
- addObserver:self
+ name:UIKeyboardWillShowNotification object:nil];
+ [notificationCenter addObserver:self
+ selector:@selector(keyboardWillOrDidChange:)
+ name:UIKeyboardDidShowNotification object:nil];
+ [notificationCenter addObserver:self
selector:@selector(keyboardWillHide:)
- name:@"UIKeyboardWillHideNotification" object:nil];
- [[NSNotificationCenter defaultCenter]
- addObserver:self
+ name:UIKeyboardWillHideNotification object:nil];
+ [notificationCenter addObserver:self
+ selector:@selector(keyboardWillOrDidChange:)
+ name:UIKeyboardDidHideNotification object:nil];
+ [notificationCenter addObserver:self
selector:@selector(keyboardDidChangeFrame:)
- name:@"UIKeyboardDidChangeFrameNotification" object:nil];
+ name:UIKeyboardDidChangeFrameNotification object:nil];
}
+
return self;
}
-- (void) dealloc
+- (void)dealloc
{
- [m_viewController.view.window removeGestureRecognizer:self];
- [m_viewController release];
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
- [[NSNotificationCenter defaultCenter]
- removeObserver:self
- name:@"UIKeyboardWillShowNotification" object:nil];
- [[NSNotificationCenter defaultCenter]
- removeObserver:self
- name:@"UIKeyboardWillHideNotification" object:nil];
- [[NSNotificationCenter defaultCenter]
- removeObserver:self
- name:@"UIKeyboardDidChangeFrameNotification" object:nil];
[super dealloc];
}
-- (void) keyboardDidChangeFrame:(NSNotification *)notification
-{
- Q_UNUSED(notification);
- [self handleKeyboardRectChanged];
-
- // If the keyboard was visible and docked from before, this is just a geometry
- // change (normally caused by an orientation change). In that case, update scroll:
- if (m_keyboardVisibleAndDocked)
- m_context->scrollToCursor();
-}
+// -------------------------------------------------------------------------
-- (void) keyboardWillShow:(NSNotification *)notification
+- (void)keyboardWillShow:(NSNotification *)notification
{
- // Note that UIKeyboardWillShowNotification is only sendt when the keyboard is docked.
- m_keyboardVisibleAndDocked = YES;
- m_keyboardEndRect = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
-
- if (!m_duration) {
- m_duration = [[notification.userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
- m_curve = UIViewAnimationCurve([[notification.userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue]);
- }
+ [self keyboardWillOrDidChange:notification];
UIResponder *firstResponder = [UIResponder currentFirstResponder];
if (![firstResponder isKindOfClass:[QIOSTextInputResponder class]])
@@ -172,11 +130,10 @@ static QUIView *focusView()
m_context->scrollToCursor();
}
-- (void) keyboardWillHide:(NSNotification *)notification
+- (void)keyboardWillHide:(NSNotification *)notification
{
- // Note that UIKeyboardWillHideNotification is also sendt when the keyboard is undocked.
- m_keyboardVisibleAndDocked = NO;
- m_keyboardEndRect = [[[notification userInfo] objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
+ [self keyboardWillOrDidChange:notification];
+
if (self.state != UIGestureRecognizerStateBegan) {
// Only disable the gesture if the hiding of the keyboard was not caused by it.
// Otherwise we need to await the final touchEnd callback for doing some clean-up.
@@ -185,29 +142,19 @@ static QUIView *focusView()
m_context->scroll(0);
}
-- (void) handleKeyboardRectChanged
+- (void)keyboardDidChangeFrame:(NSNotification *)notification
{
- // QInputmethod::keyboardRectangle() is documented to be in window coordinates.
- // If there is no focus window, we return an empty rectangle
- UIView *view = focusView();
- QRectF convertedRect = fromCGRect([view convertRect:m_keyboardEndRect fromView:nil]);
-
- // Set height to zero if keyboard is hidden. Otherwise the rect will not change
- // when the keyboard hides on a scrolled screen (since the keyboard will already
- // be at the bottom of the 'screen' in that case)
- if (!m_keyboardVisibleAndDocked)
- convertedRect.setHeight(0);
+ [self keyboardWillOrDidChange:notification];
- if (convertedRect != m_keyboardRect) {
- m_keyboardRect = convertedRect;
- m_context->emitKeyboardRectChanged();
- }
+ // If the keyboard was visible and docked from before, this is just a geometry
+ // change (normally caused by an orientation change). In that case, update scroll:
+ if (m_context->isInputPanelVisible())
+ m_context->scrollToCursor();
+}
- BOOL visible = CGRectIntersectsRect(m_keyboardEndRect, [UIScreen mainScreen].bounds);
- if (m_keyboardVisible != visible) {
- m_keyboardVisible = visible;
- m_context->emitInputPanelVisibleChanged();
- }
+- (void)keyboardWillOrDidChange:(NSNotification *)notification
+{
+ m_context->updateKeyboardState(notification);
}
// -------------------------------------------------------------------------
@@ -216,7 +163,7 @@ static QUIView *focusView()
{
[super touchesBegan:touches withEvent:event];
- Q_ASSERT(m_keyboardVisibleAndDocked);
+ Q_ASSERT(m_context->isInputPanelVisible());
if ([touches count] != 1)
self.state = UIGestureRecognizerStateFailed;
@@ -229,8 +176,8 @@ static QUIView *focusView()
if (self.state != UIGestureRecognizerStatePossible)
return;
- CGPoint touchPoint = [[touches anyObject] locationInView:m_viewController.view.window];
- if (CGRectContainsPoint(m_keyboardEndRect, touchPoint))
+ CGPoint touchPoint = [[touches anyObject] locationInView:self.view];
+ if (CGRectContainsPoint(m_context->keyboardState().keyboardEndRect, touchPoint))
self.state = UIGestureRecognizerStateBegan;
}
@@ -280,7 +227,7 @@ static QUIView *focusView()
{
[super reset];
- if (!m_keyboardVisibleAndDocked) {
+ if (!m_context->isInputPanelVisible()) {
qImDebug() << "keyboard was hidden, disabling hide-keyboard gesture";
self.enabled = NO;
} else {
@@ -328,23 +275,25 @@ QIOSInputContext *QIOSInputContext::instance()
QIOSInputContext::QIOSInputContext()
: QPlatformInputContext()
- , m_keyboardListener([[QIOSKeyboardListener alloc] initWithQIOSInputContext:this])
+ , m_keyboardHideGesture([[QIOSKeyboardListener alloc] initWithQIOSInputContext:this])
, m_textResponder(0)
{
- if (isQtApplication())
+ if (isQtApplication()) {
+ QIOSScreen *iosScreen = static_cast<QIOSScreen*>(QGuiApplication::primaryScreen()->handle());
+ [iosScreen->uiWindow() addGestureRecognizer:m_keyboardHideGesture];
+
connect(qGuiApp->inputMethod(), &QInputMethod::cursorRectangleChanged, this, &QIOSInputContext::cursorRectangleChanged);
+ }
+
connect(qGuiApp, &QGuiApplication::focusWindowChanged, this, &QIOSInputContext::focusWindowChanged);
}
QIOSInputContext::~QIOSInputContext()
{
- [m_keyboardListener release];
- [m_textResponder release];
-}
+ [m_keyboardHideGesture.view removeGestureRecognizer:m_keyboardHideGesture];
+ [m_keyboardHideGesture release];
-QRectF QIOSInputContext::keyboardRect() const
-{
- return m_keyboardListener->m_keyboardRect;
+ [m_textResponder release];
}
void QIOSInputContext::showInputPanel()
@@ -375,14 +324,85 @@ void QIOSInputContext::clearCurrentFocusObject()
static_cast<QWindowPrivate *>(QObjectPrivate::get(focusWindow))->clearFocusObject();
}
+// -------------------------------------------------------------------------
+
+void QIOSInputContext::updateKeyboardState(NSNotification *notification)
+{
+ static CGRect currentKeyboardRect = CGRectZero;
+
+ KeyboardState previousState = m_keyboardState;
+
+ if (notification) {
+ NSDictionary *userInfo = [notification userInfo];
+
+ CGRect frameBegin = [[userInfo objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue];
+ CGRect frameEnd = [[userInfo objectForKey:UIKeyboardFrameEndUserInfoKey] CGRectValue];
+
+ bool atEndOfKeyboardTransition = [notification.name rangeOfString:@"Did"].location != NSNotFound;
+
+ currentKeyboardRect = atEndOfKeyboardTransition ? frameEnd : frameBegin;
+
+ // The isInputPanelVisible() property is based on whether or not the virtual keyboard
+ // is visible on screen, and does not follow the logic of the iOS WillShow and WillHide
+ // notifications which are not emitted for undocked keyboards, and are buggy when dealing
+ // with input-accesosory-views. The reason for using frameEnd here (the future state),
+ // instead of the current state reflected in frameBegin, is that QInputMethod::isVisible()
+ // is documented to reflect the future state in the case of animated transitions.
+ m_keyboardState.keyboardVisible = CGRectIntersectsRect(frameEnd, [UIScreen mainScreen].bounds);
+
+ // Used for auto-scroller, and will be used for animation-signal in the future
+ m_keyboardState.keyboardEndRect = frameEnd;
+
+ if (m_keyboardState.animationCurve < 0) {
+ // We only set the animation curve the first time it has a valid value, since iOS will sometimes report
+ // an invalid animation curve even if the keyboard is animating, and we don't want to overwrite the
+ // curve in that case.
+ m_keyboardState.animationCurve = UIViewAnimationCurve([[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] integerValue]);
+ }
+
+ m_keyboardState.animationDuration = [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue];
+ m_keyboardState.keyboardAnimating = m_keyboardState.animationDuration > 0 && !atEndOfKeyboardTransition;
+
+ qImDebug() << qPrintable(QString::fromNSString(notification.name)) << "from" << fromCGRect(frameBegin) << "to" << fromCGRect(frameEnd)
+ << "(curve =" << m_keyboardState.animationCurve << "duration =" << m_keyboardState.animationDuration << "s)";
+ } else {
+ qImDebug() << "No notification to update keyboard state based on, just updating keyboard rect";
+ }
+
+ if (!focusView() || CGRectIsEmpty(currentKeyboardRect))
+ m_keyboardState.keyboardRect = QRectF();
+ else // QInputmethod::keyboardRectangle() is documented to be in window coordinates.
+ m_keyboardState.keyboardRect = fromCGRect([focusView() convertRect:currentKeyboardRect fromView:nil]);
+
+ // Emit for all changed properties
+ if (m_keyboardState.keyboardVisible != previousState.keyboardVisible)
+ emitInputPanelVisibleChanged();
+ if (m_keyboardState.keyboardAnimating != previousState.keyboardAnimating)
+ emitAnimatingChanged();
+ if (m_keyboardState.keyboardRect != previousState.keyboardRect)
+ emitKeyboardRectChanged();
+}
+
bool QIOSInputContext::isInputPanelVisible() const
{
- return m_keyboardListener->m_keyboardVisible;
+ return m_keyboardState.keyboardVisible;
+}
+
+bool QIOSInputContext::isAnimating() const
+{
+ return m_keyboardState.keyboardAnimating;
+}
+
+QRectF QIOSInputContext::keyboardRect() const
+{
+ return m_keyboardState.keyboardRect;
}
+// -------------------------------------------------------------------------
+
void QIOSInputContext::cursorRectangleChanged()
{
- if (!m_keyboardListener->m_keyboardVisibleAndDocked || !qApp->focusObject())
+ if (!isInputPanelVisible() || !qApp->focusObject())
return;
// Check if the cursor has changed position inside the input item. Since
@@ -397,44 +417,67 @@ void QIOSInputContext::cursorRectangleChanged()
prevCursor = cursor;
}
+UIView *QIOSInputContext::scrollableRootView()
+{
+ if (!m_keyboardHideGesture.view)
+ return 0;
+
+ UIWindow *window = static_cast<UIWindow*>(m_keyboardHideGesture.view);
+ if (![window.rootViewController isKindOfClass:[QIOSViewController class]])
+ return 0;
+
+ return window.rootViewController.view;
+}
+
void QIOSInputContext::scrollToCursor()
{
if (!isQtApplication())
return;
- if (m_keyboardListener.state == UIGestureRecognizerStatePossible && m_keyboardListener.numberOfTouches == 1) {
+ if (m_keyboardHideGesture.state == UIGestureRecognizerStatePossible && m_keyboardHideGesture.numberOfTouches == 1) {
// Don't scroll to the cursor if the user is touching the screen and possibly
// trying to trigger the hide-keyboard gesture.
qImDebug() << "preventing scrolling to cursor as we're still waiting for a possible gesture";
return;
}
- UIView *view = m_keyboardListener->m_viewController.view;
- if (view.window != focusView().window)
+ UIView *rootView = scrollableRootView();
+ if (!rootView)
+ return;
+
+ if (rootView.window != focusView().window)
return;
+ // We only support auto-scroll for docked keyboards for now, so make sure that's the case
+ if (CGRectGetMaxY(m_keyboardState.keyboardEndRect) != CGRectGetMaxY([UIScreen mainScreen].bounds)) {
+ qImDebug() << "Keyboard not docked, ignoring request to scroll to reveal cursor";
+ return;
+ }
+
const int margin = 20;
QRectF translatedCursorPos = qApp->inputMethod()->cursorRectangle();
translatedCursorPos.translate(focusView().qwindow->geometry().topLeft());
- qreal keyboardY = [view convertRect:m_keyboardListener->m_keyboardEndRect fromView:nil].origin.y;
+ qreal keyboardY = [rootView convertRect:m_keyboardState.keyboardEndRect fromView:nil].origin.y;
int statusBarY = qGuiApp->primaryScreen()->availableGeometry().y();
scroll((translatedCursorPos.bottomLeft().y() < keyboardY - margin) ? 0
- : qMin(view.bounds.size.height - keyboardY, translatedCursorPos.y() - statusBarY - margin));
+ : qMin(rootView.bounds.size.height - keyboardY, translatedCursorPos.y() - statusBarY - margin));
}
void QIOSInputContext::scroll(int y)
{
- UIView *rootView = m_keyboardListener->m_viewController.view;
+ UIView *rootView = scrollableRootView();
+ if (!rootView)
+ return;
CATransform3D translationTransform = CATransform3DMakeTranslation(0.0, -y, 0.0);
if (CATransform3DEqualToTransform(translationTransform, rootView.layer.sublayerTransform))
return;
QPointer<QIOSInputContext> self = this;
- [UIView animateWithDuration:m_keyboardListener->m_duration delay:0
- options:(m_keyboardListener->m_curve << 16) | UIViewAnimationOptionBeginFromCurrentState
+ [UIView animateWithDuration:m_keyboardState.animationDuration delay:0
+ options:(m_keyboardState.animationCurve << 16) | UIViewAnimationOptionBeginFromCurrentState
animations:^{
// The sublayerTransform property of CALayer is not implicitly animated for a
// layer-backed view, even inside a UIView animation block, so we need to set up
@@ -463,8 +506,12 @@ void QIOSInputContext::scroll(int y)
[rootView.qtViewController updateProperties];
}
completion:^(BOOL){
- if (self)
- [m_keyboardListener handleKeyboardRectChanged];
+ if (self) {
+ // Scrolling the root view results in the keyboard being moved
+ // relative to the focus window, so we need to re-evaluate the
+ // keyboard rectangle.
+ updateKeyboardState();
+ }
}
];
}
@@ -477,7 +524,7 @@ void QIOSInputContext::setFocusObject(QObject *focusObject)
qImDebug() << "new focus object =" << focusObject;
- if (m_keyboardListener.state == UIGestureRecognizerStateChanged) {
+ if (m_keyboardHideGesture.state == UIGestureRecognizerStateChanged) {
// A new focus object may be set as part of delivering touch events to
// application during the hide-keyboard gesture, but we don't want that
// to result in a new object getting focus and bringing the keyboard up
@@ -489,7 +536,7 @@ void QIOSInputContext::setFocusObject(QObject *focusObject)
reset();
- if (m_keyboardListener->m_keyboardVisibleAndDocked)
+ if (isInputPanelVisible())
scrollToCursor();
}
@@ -501,8 +548,11 @@ void QIOSInputContext::focusWindowChanged(QWindow *focusWindow)
reset();
- [m_keyboardListener handleKeyboardRectChanged];
- if (m_keyboardListener->m_keyboardVisibleAndDocked)
+ // The keyboard rectangle depend on the focus window, so
+ // we need to re-evaluate the keyboard state.
+ updateKeyboardState();
+
+ if (isInputPanelVisible())
scrollToCursor();
}
diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm
index 9a722ead37..461f160892 100644
--- a/src/plugins/platforms/ios/qiosintegration.mm
+++ b/src/plugins/platforms/ios/qiosintegration.mm
@@ -88,7 +88,13 @@ QIOSIntegration::QIOSIntegration()
// Set current directory to app bundle folder
QDir::setCurrent(QString::fromUtf8([[[NSBundle mainBundle] bundlePath] UTF8String]));
- for (UIScreen *screen in [UIScreen screens])
+ NSMutableArray *screens = [[[UIScreen screens] mutableCopy] autorelease];
+ if (![screens containsObject:[UIScreen mainScreen]]) {
+ // Fallback for iOS 7.1 (QTBUG-42345)
+ [screens insertObject:[UIScreen mainScreen] atIndex:0];
+ }
+
+ for (UIScreen *screen in screens)
addScreen(new QIOSScreen(screen));
// Depends on a primary screen being present
diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h
index 7987ef82d5..7aa62b9190 100644
--- a/src/plugins/platforms/ios/qiosscreen.h
+++ b/src/plugins/platforms/ios/qiosscreen.h
@@ -63,6 +63,7 @@ public:
void setOrientationUpdateMask(Qt::ScreenOrientations mask);
UIScreen *uiScreen() const;
+ UIWindow *uiWindow() const;
void updateProperties();
diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm
index e70b369b79..4af2a4965f 100644
--- a/src/plugins/platforms/ios/qiosscreen.mm
+++ b/src/plugins/platforms/ios/qiosscreen.mm
@@ -321,6 +321,11 @@ UIScreen *QIOSScreen::uiScreen() const
return m_uiScreen;
}
+UIWindow *QIOSScreen::uiWindow() const
+{
+ return m_uiWindow;
+}
+
#include "moc_qiosscreen.cpp"
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowscontext.cpp b/src/plugins/platforms/windows/qwindowscontext.cpp
index 4f1a1a375f..13a3d044a0 100644
--- a/src/plugins/platforms/windows/qwindowscontext.cpp
+++ b/src/plugins/platforms/windows/qwindowscontext.cpp
@@ -952,6 +952,9 @@ bool QWindowsContext::windowsProc(HWND hwnd, UINT message,
return true;
case QtWindows::CalculateSize:
return QWindowsGeometryHint::handleCalculateSize(d->m_creationContext->customMargins, msg, result);
+ case QtWindows::GeometryChangingEvent:
+ return QWindowsWindow::handleGeometryChangingMessage(&msg, d->m_creationContext->window,
+ d->m_creationContext->margins + d->m_creationContext->customMargins);
default:
break;
}
diff --git a/src/plugins/platforms/windows/qwindowscursor.cpp b/src/plugins/platforms/windows/qwindowscursor.cpp
index f5d6c140bf..d10c7fdb20 100644
--- a/src/plugins/platforms/windows/qwindowscursor.cpp
+++ b/src/plugins/platforms/windows/qwindowscursor.cpp
@@ -570,8 +570,21 @@ QWindowsWindowCursor QWindowsCursor::pixmapWindowCursor(const QCursor &c)
{
const QWindowsCursorCacheKey cacheKey(c);
CursorCache::iterator it = m_cursorCache.find(cacheKey);
- if (it == m_cursorCache.end())
+ if (it == m_cursorCache.end()) {
+ if (m_cursorCache.size() > 50) {
+ // Prevent the cursor cache from growing indefinitely hitting GDI resource
+ // limits if new pixmap cursors are created repetitively by purging out
+ // all-noncurrent pixmap cursors (QTBUG-43515)
+ const HCURSOR currentCursor = GetCursor();
+ for (it = m_cursorCache.begin(); it != m_cursorCache.end() ; ) {
+ if (it.key().bitmapCacheKey && it.value().handle() != currentCursor)
+ it = m_cursorCache.erase(it);
+ else
+ ++it;
+ }
+ }
it = m_cursorCache.insert(cacheKey, QWindowsWindowCursor(c));
+ }
return it.value();
}
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
index 7492423e69..214273e685 100644
--- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
@@ -1062,6 +1062,9 @@ QWindowsFontEngineDataPtr sharedFontData()
}
#endif // QT_NO_THREAD
+#ifndef Q_OS_WINCE
+extern Q_GUI_EXPORT bool qt_needs_a8_gamma_correction;
+#endif
QWindowsFontDatabase::QWindowsFontDatabase()
{
// Properties accessed by QWin32PrintEngine (Qt Print Support)
@@ -1075,6 +1078,9 @@ QWindowsFontDatabase::QWindowsFontDatabase()
qCDebug(lcQpaFonts) << __FUNCTION__ << "Clear type: "
<< data->clearTypeEnabled << "gamma: " << data->fontSmoothingGamma;
}
+#ifndef Q_OS_WINCE
+ qt_needs_a8_gamma_correction = true;
+#endif
}
QWindowsFontDatabase::~QWindowsFontDatabase()
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index 0b4bb9b09d..5768800947 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -801,7 +801,7 @@ QWindowCreationContext::QWindowCreationContext(const QWindow *w,
const QRect &geometry,
const QMargins &cm,
DWORD style_, DWORD exStyle_) :
- geometryHint(w, cm), style(style_), exStyle(exStyle_),
+ geometryHint(w, cm), window(w), style(style_), exStyle(exStyle_),
requestedGeometry(geometry), obtainedGeometry(geometry),
margins(QWindowsGeometryHint::frame(style, exStyle)), customMargins(cm),
frameX(CW_USEDEFAULT), frameY(CW_USEDEFAULT),
@@ -1783,16 +1783,14 @@ void QWindowsWindow::propagateSizeHints()
qCDebug(lcQpaWindows) << __FUNCTION__ << this << window();
}
-bool QWindowsWindow::handleGeometryChanging(MSG *message) const
+bool QWindowsWindow::handleGeometryChangingMessage(MSG *message, const QWindow *qWindow, const QMargins &marginsDp)
{
#ifndef Q_OS_WINCE
- QWindow *qWin = window();
- if (!qWin->isTopLevel())
+ if (!qWindow->isTopLevel()) // Implement hasHeightForWidth().
return false;
WINDOWPOS *windowPos = reinterpret_cast<WINDOWPOS *>(message->lParam);
if ((windowPos->flags & (SWP_NOCOPYBITS | SWP_NOSIZE)))
return false;
- const QMargins marginsDp = frameMarginsDp();
const QRect suggestedFrameGeometryDp(windowPos->x, windowPos->y,
windowPos->cx, windowPos->cy);
const qreal factor = QWindowsScaling::factor();
@@ -1800,7 +1798,7 @@ bool QWindowsWindow::handleGeometryChanging(MSG *message) const
const QRectF suggestedGeometry = QRectF(QPointF(suggestedGeometryDp.topLeft()) / factor,
QSizeF(suggestedGeometryDp.size()) / factor);
const QRectF correctedGeometryF =
- qt_window_private(qWin)->closestAcceptableGeometry(suggestedGeometry);
+ qt_window_private(const_cast<QWindow *>(qWindow))->closestAcceptableGeometry(suggestedGeometry);
if (!correctedGeometryF.isValid())
return false;
const QRect correctedFrameGeometryDp
@@ -1820,6 +1818,12 @@ bool QWindowsWindow::handleGeometryChanging(MSG *message) const
#endif
}
+bool QWindowsWindow::handleGeometryChanging(MSG *message) const
+{
+ const QMargins marginsDp = window()->isTopLevel() ? frameMarginsDp() : QMargins();
+ return QWindowsWindow::handleGeometryChangingMessage(message, window(), marginsDp);
+}
+
QMargins QWindowsWindow::frameMarginsDp() const
{
// Frames are invalidated by style changes (window state, flags).
@@ -1827,7 +1831,12 @@ QMargins QWindowsWindow::frameMarginsDp() const
// event sequences, introduce a dirty flag mechanism to be able
// to cache results.
if (testFlag(FrameDirty)) {
- m_data.frame = QWindowsGeometryHint::frame(style(), exStyle());
+ // Always skip calculating style-dependent margins for windows claimed to be frameless.
+ // This allows users to remove the margins by handling WM_NCCALCSIZE with WS_THICKFRAME set
+ // to ensure Areo snap still works (QTBUG-40578).
+ m_data.frame = window()->flags() & Qt::FramelessWindowHint
+ ? QMargins(0, 0, 0, 0)
+ : QWindowsGeometryHint::frame(style(), exStyle());
clearFlag(FrameDirty);
}
return m_data.frame + m_data.customMargins;
diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h
index a63a9f56e3..9822ebce45 100644
--- a/src/plugins/platforms/windows/qwindowswindow.h
+++ b/src/plugins/platforms/windows/qwindowswindow.h
@@ -84,6 +84,7 @@ struct QWindowCreationContext
#endif
QWindowsGeometryHint geometryHint;
+ const QWindow *window;
DWORD style;
DWORD exStyle;
QRect requestedGeometry;
@@ -183,6 +184,7 @@ public:
void windowEvent(QEvent *event);
void propagateSizeHints() Q_DECL_OVERRIDE;
+ static bool handleGeometryChangingMessage(MSG *message, const QWindow *qWindow, const QMargins &marginsDp);
bool handleGeometryChanging(MSG *message) const;
QMargins frameMarginsDp() const;
QMargins frameMargins() const Q_DECL_OVERRIDE { return frameMarginsDp() / QWindowsScaling::factor(); }
diff --git a/src/plugins/platforms/winrt/qwinrtscreen.cpp b/src/plugins/platforms/winrt/qwinrtscreen.cpp
index fadcd01b06..37a3ff3d63 100644
--- a/src/plugins/platforms/winrt/qwinrtscreen.cpp
+++ b/src/plugins/platforms/winrt/qwinrtscreen.cpp
@@ -37,6 +37,9 @@
#include <EGL/eglext.h>
#include <d3d11.h>
#include <dxgi1_2.h>
+#ifndef Q_OS_WINPHONE
+#include <dxgi1_3.h>
+#endif
#include "qwinrtbackingstore.h"
#include "qwinrtinputcontext.h"
@@ -1078,12 +1081,14 @@ HRESULT QWinRTScreen::onSizeChanged(ICoreWindow *, IWindowSizeChangedEventArgs *
d->logicalSize = logicalSize;
if (d->eglDisplay) {
const QRect newGeometry = geometry();
-#ifdef Q_OS_WINPHONE // Resize the EGL window
- const int width = newGeometry.width() * (d->orientation == Qt::InvertedPortraitOrientation || d->orientation == Qt::LandscapeOrientation ? -1 : 1);
- const int height = newGeometry.height() * (d->orientation == Qt::InvertedPortraitOrientation || d->orientation == Qt::InvertedLandscapeOrientation ? -1 : 1);
+ int width = newGeometry.width();
+ int height = newGeometry.height();
+#ifdef Q_OS_WINPHONE // Windows Phone can pass in a negative size to provide orientation information
+ width *= (d->orientation == Qt::InvertedPortraitOrientation || d->orientation == Qt::LandscapeOrientation) ? -1 : 1;
+ height *= (d->orientation == Qt::InvertedPortraitOrientation || d->orientation == Qt::InvertedLandscapeOrientation) ? -1 : 1;
+#endif
eglSurfaceAttrib(d->eglDisplay, d->eglSurface, EGL_WIDTH, width);
eglSurfaceAttrib(d->eglDisplay, d->eglSurface, EGL_HEIGHT, height);
-#endif
QWindowSystemInterface::handleScreenGeometryChange(screen(), newGeometry, newGeometry);
QPlatformScreen::resizeMaximizedWindows();
handleExpose();
@@ -1113,6 +1118,16 @@ HRESULT QWinRTScreen::onActivated(ICoreWindow *, IWindowActivatedEventArgs *args
HRESULT QWinRTScreen::onSuspended(IInspectable *, ISuspendingEventArgs *)
{
+#ifndef Q_OS_WINPHONE
+ Q_D(QWinRTScreen);
+ ComPtr<ID3D11Device> d3dDevice;
+ const EGLBoolean ok = eglQuerySurfacePointerANGLE(d->eglDisplay, EGL_NO_SURFACE, EGL_DEVICE_EXT, (void **)d3dDevice.GetAddressOf());
+ if (ok && d3dDevice) {
+ ComPtr<IDXGIDevice3> dxgiDevice;
+ if (SUCCEEDED(d3dDevice.As(&dxgiDevice)))
+ dxgiDevice->Trim();
+ }
+#endif
QWindowSystemInterface::handleApplicationStateChanged(Qt::ApplicationSuspended);
QWindowSystemInterface::flushWindowSystemEvents();
return S_OK;
diff --git a/src/sql/kernel/qsqldriver.cpp b/src/sql/kernel/qsqldriver.cpp
index 736fe310e3..f218016876 100644
--- a/src/sql/kernel/qsqldriver.cpp
+++ b/src/sql/kernel/qsqldriver.cpp
@@ -237,11 +237,11 @@ bool QSqlDriver::isOpenError() const
*/
/*!
- \enum QSqlDriver::DBMSType
+ \enum QSqlDriver::DbmsType
This enum contains DBMS types.
- \value UnknownDBMS
+ \value UnknownDbms
\value MSSqlServer
\value MySqlServer
\value PostgreSQL
@@ -787,7 +787,7 @@ QSql::NumericalPrecisionPolicy QSqlDriver::numericalPrecisionPolicy() const
Returns the current DBMS type for the database connection.
*/
-QSqlDriver::DBMSType QSqlDriver::dbmsType() const
+QSqlDriver::DbmsType QSqlDriver::dbmsType() const
{
return d_func()->dbmsType;
}
diff --git a/src/sql/kernel/qsqldriver.h b/src/sql/kernel/qsqldriver.h
index 767c1ac74d..eabda74da5 100644
--- a/src/sql/kernel/qsqldriver.h
+++ b/src/sql/kernel/qsqldriver.h
@@ -71,8 +71,8 @@ public:
enum NotificationSource { UnknownSource, SelfSource, OtherSource };
- enum DBMSType {
- UnknownDBMS,
+ enum DbmsType {
+ UnknownDbms,
MSSqlServer,
MySqlServer,
PostgreSQL,
@@ -123,7 +123,7 @@ public:
void setNumericalPrecisionPolicy(QSql::NumericalPrecisionPolicy precisionPolicy);
QSql::NumericalPrecisionPolicy numericalPrecisionPolicy() const;
- DBMSType dbmsType() const;
+ DbmsType dbmsType() const;
public Q_SLOTS:
virtual bool cancelQuery();
diff --git a/src/sql/kernel/qsqldriver_p.h b/src/sql/kernel/qsqldriver_p.h
index 427e3984fa..c511f8e13b 100644
--- a/src/sql/kernel/qsqldriver_p.h
+++ b/src/sql/kernel/qsqldriver_p.h
@@ -61,14 +61,14 @@ public:
isOpen(false),
isOpenError(false),
precisionPolicy(QSql::LowPrecisionDouble),
- dbmsType(QSqlDriver::UnknownDBMS)
+ dbmsType(QSqlDriver::UnknownDbms)
{ }
uint isOpen;
uint isOpenError;
QSqlError error;
QSql::NumericalPrecisionPolicy precisionPolicy;
- QSqlDriver::DBMSType dbmsType;
+ QSqlDriver::DbmsType dbmsType;
};
QT_END_NAMESPACE
diff --git a/src/tools/qdoc/doc/examples/componentset/ProgressBar.qml b/src/tools/qdoc/doc/examples/componentset/ProgressBar.qml
index 72e0815d19..f7aeb29865 100644
--- a/src/tools/qdoc/doc/examples/componentset/ProgressBar.qml
+++ b/src/tools/qdoc/doc/examples/componentset/ProgressBar.qml
@@ -42,7 +42,7 @@ import QtQuick 1.0
/*!
\qmltype ProgressBar
- \inqmlmodule UIComponents 1.0
+ \inqmlmodule UIComponents
\brief A component that shows the progress of an event
A ProgressBar shows the linear progress of an event as its \l value.
diff --git a/src/tools/qdoc/doc/examples/componentset/Switch.qml b/src/tools/qdoc/doc/examples/componentset/Switch.qml
index ae760e566e..7dee33eb3c 100644
--- a/src/tools/qdoc/doc/examples/componentset/Switch.qml
+++ b/src/tools/qdoc/doc/examples/componentset/Switch.qml
@@ -42,7 +42,7 @@ import QtQuick 1.0
/*!
\qmltype ToggleSwitch
- \inqmlmodule UIComponents 1.0
+ \inqmlmodule UIComponents
\brief A component that can be turned on or off
A toggle switch has two states: an \c on and an \c off state. The \c off
diff --git a/src/tools/qdoc/doc/examples/componentset/TabWidget.qml b/src/tools/qdoc/doc/examples/componentset/TabWidget.qml
index 337f23fdad..0fbac1604e 100644
--- a/src/tools/qdoc/doc/examples/componentset/TabWidget.qml
+++ b/src/tools/qdoc/doc/examples/componentset/TabWidget.qml
@@ -42,7 +42,7 @@ import QtQuick 1.0
/*!
\qmltype TabWidget
- \inqmlmodule UIComponents 1.0
+ \inqmlmodule UIComponents
\brief A widget that places its children as tabs
A TabWidget places its children as tabs in a view. Selecting
diff --git a/src/tools/qdoc/doc/examples/qml.qdoc.sample b/src/tools/qdoc/doc/examples/qml.qdoc.sample
index d913c6f164..11713b4e4d 100644
--- a/src/tools/qdoc/doc/examples/qml.qdoc.sample
+++ b/src/tools/qdoc/doc/examples/qml.qdoc.sample
@@ -28,7 +28,7 @@
//![qmltype]
\qmltype TextEdit
\instantiates QQuickTextEdit
- \inqmlmodule QtQuick 2
+ \inqmlmodule QtQuick
\ingroup qtquick-visual
\ingroup qtquick-input
\inherits Item
diff --git a/src/tools/qdoc/doc/qdoc-manual-topiccmds.qdoc b/src/tools/qdoc/doc/qdoc-manual-topiccmds.qdoc
index b50a343a22..1d78eff386 100644
--- a/src/tools/qdoc/doc/qdoc-manual-topiccmds.qdoc
+++ b/src/tools/qdoc/doc/qdoc-manual-topiccmds.qdoc
@@ -1376,9 +1376,10 @@
\section1 \\inqmlmodule
A QML class may belong to a \l{qmlmodule-command}{QML module} by inserting
- the \l{inqmlmodule-command}{\\inqmlmodule} command as a topic command.
- Every member of a group must be linked to using the module name and two
- colons (\c{::}).
+ the \l{inqmlmodule-command}{\\inqmlmodule} command as a topic command, with
+ the module name (without a version number) as the only argument. Every
+ member of a group must be linked to using the module name and two colons
+ (\c{::}).
\code
\qmltype ClickableButton
diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp
index 9d38a330c8..75979e3986 100644
--- a/src/widgets/itemviews/qabstractitemview.cpp
+++ b/src/widgets/itemviews/qabstractitemview.cpp
@@ -891,6 +891,7 @@ void QAbstractItemView::setItemDelegateForRow(int row, QAbstractItemDelegate *de
disconnect(rowDelegate, SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)),
this, SLOT(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)));
disconnect(rowDelegate, SIGNAL(commitData(QWidget*)), this, SLOT(commitData(QWidget*)));
+ disconnect(rowDelegate, SIGNAL(sizeHintChanged(QModelIndex)), this, SLOT(doItemsLayout()));
}
d->rowDelegates.remove(row);
}
@@ -899,10 +900,12 @@ void QAbstractItemView::setItemDelegateForRow(int row, QAbstractItemDelegate *de
connect(delegate, SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)),
this, SLOT(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)));
connect(delegate, SIGNAL(commitData(QWidget*)), this, SLOT(commitData(QWidget*)));
+ connect(delegate, SIGNAL(sizeHintChanged(QModelIndex)), this, SLOT(doItemsLayout()), Qt::QueuedConnection);
}
d->rowDelegates.insert(row, delegate);
}
viewport()->update();
+ d->doDelayedItemsLayout();
}
/*!
@@ -948,6 +951,7 @@ void QAbstractItemView::setItemDelegateForColumn(int column, QAbstractItemDelega
disconnect(columnDelegate, SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)),
this, SLOT(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)));
disconnect(columnDelegate, SIGNAL(commitData(QWidget*)), this, SLOT(commitData(QWidget*)));
+ disconnect(columnDelegate, SIGNAL(sizeHintChanged(QModelIndex)), this, SLOT(doItemsLayout()));
}
d->columnDelegates.remove(column);
}
@@ -956,10 +960,12 @@ void QAbstractItemView::setItemDelegateForColumn(int column, QAbstractItemDelega
connect(delegate, SIGNAL(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)),
this, SLOT(closeEditor(QWidget*,QAbstractItemDelegate::EndEditHint)));
connect(delegate, SIGNAL(commitData(QWidget*)), this, SLOT(commitData(QWidget*)));
+ connect(delegate, SIGNAL(sizeHintChanged(QModelIndex)), this, SLOT(doItemsLayout()), Qt::QueuedConnection);
}
d->columnDelegates.insert(column, delegate);
}
viewport()->update();
+ d->doDelayedItemsLayout();
}
/*!
diff --git a/src/widgets/itemviews/qcolumnview.cpp b/src/widgets/itemviews/qcolumnview.cpp
index 1c60d50922..3234e1e832 100644
--- a/src/widgets/itemviews/qcolumnview.cpp
+++ b/src/widgets/itemviews/qcolumnview.cpp
@@ -976,8 +976,11 @@ void QColumnViewPrivate::_q_changeCurrentColumn()
QAbstractItemView *view = columns.at(i);
view->setSelectionModel(replacementSelectionModel);
view->setFocusPolicy(Qt::NoFocus);
- if (columns.size() > i + 1)
- view->setCurrentIndex(columns.at(i+1)->rootIndex());
+ if (columns.size() > i + 1) {
+ const QModelIndex newRootIndex = columns.at(i + 1)->rootIndex();
+ if (newRootIndex.isValid())
+ view->setCurrentIndex(newRootIndex);
+ }
break;
}
}
diff --git a/src/widgets/itemviews/qheaderview.cpp b/src/widgets/itemviews/qheaderview.cpp
index df61441800..f1ebc4505e 100644
--- a/src/widgets/itemviews/qheaderview.cpp
+++ b/src/widgets/itemviews/qheaderview.cpp
@@ -1550,7 +1550,7 @@ int QHeaderView::minimumSectionSize() const
Q_D(const QHeaderView);
if (d->minimumSectionSize == -1) {
QSize strut = QApplication::globalStrut();
- int margin = style()->pixelMetric(QStyle::PM_HeaderMargin, 0, this);
+ int margin = 2 * style()->pixelMetric(QStyle::PM_HeaderMargin, 0, this);
if (d->orientation == Qt::Horizontal)
return qMax(strut.width(), (fontMetrics().maxWidth() + margin));
return qMax(strut.height(), (fontMetrics().height() + margin));
@@ -2665,7 +2665,14 @@ void QHeaderView::paintSection(QPainter *painter, const QRect &rect, int logical
opt.iconAlignment = Qt::AlignVCenter;
opt.text = d->model->headerData(logicalIndex, d->orientation,
Qt::DisplayRole).toString();
- const int margin = 2 * style()->pixelMetric(QStyle::PM_HeaderMargin, 0, this);
+
+ int margin = 2 * style()->pixelMetric(QStyle::PM_HeaderMargin, 0, this);
+
+ const Qt::Alignment headerArrowAlignment = static_cast<Qt::Alignment>(style()->styleHint(QStyle::SH_Header_ArrowAlignment, 0, this));
+ const bool isHeaderArrowOnTheSide = headerArrowAlignment & Qt::AlignVCenter;
+ if (isSortIndicatorShown() && sortIndicatorSection() == logicalIndex && isHeaderArrowOnTheSide)
+ margin += style()->pixelMetric(QStyle::PM_HeaderMarkSize, 0, this);
+
if (d->textElideMode != Qt::ElideNone)
opt.text = opt.fontMetrics.elidedText(opt.text, d->textElideMode , rect.width() - margin);
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp
index 500e812e28..943abd1f1a 100644
--- a/src/widgets/kernel/qapplication.cpp
+++ b/src/widgets/kernel/qapplication.cpp
@@ -53,7 +53,6 @@
#include "qtranslator.h"
#include "qvariant.h"
#include "qwidget.h"
-#include "qgraphicssceneevent.h"
#include "private/qdnd_p.h"
#include "private/qguiapplication_p.h"
#include "qcolormap.h"
@@ -2292,31 +2291,6 @@ QWidget *QApplicationPrivate::focusNextPrevChild_helper(QWidget *toplevel, bool
return w;
}
-Qt::MouseEventSource QApplicationPrivate::mouseEventSource(const QEvent *e)
-{
- switch (e->type()) {
- case QEvent::NonClientAreaMouseButtonDblClick:
- case QEvent::NonClientAreaMouseButtonPress:
- case QEvent::NonClientAreaMouseButtonRelease:
- case QEvent::NonClientAreaMouseMove:
- case QEvent::MouseButtonDblClick:
- case QEvent::MouseButtonPress:
- case QEvent::MouseButtonRelease:
- case QEvent::MouseMove:
- return static_cast<const QMouseEvent *>(e)->source();
-#ifndef QT_NO_GRAPHICSVIEW
- case QEvent::GraphicsSceneMouseDoubleClick:
- case QEvent::GraphicsSceneMousePress:
- case QEvent::GraphicsSceneMouseRelease:
- case QEvent::GraphicsSceneMouseMove:
- return static_cast<const QGraphicsSceneMouseEvent *>(e)->source();
-#endif // !QT_NO_GRAPHICSVIEW
- default:
- break;
- }
- return Qt::MouseEventNotSynthesized;
-}
-
/*!
\fn void QApplicationPrivate::dispatchEnterLeave(QWidget* enter, QWidget* leave, const QPointF &globalPosF)
\internal
@@ -4179,11 +4153,13 @@ void QApplicationPrivate::giveFocusAccordingToFocusPolicy(QWidget *widget, QEven
{
const bool setFocusOnRelease = QGuiApplication::styleHints()->setFocusOnTouchRelease();
Qt::FocusPolicy focusPolicy = Qt::ClickFocus;
+ static QPointer<QWidget> focusedWidgetOnTouchBegin = 0;
switch (event->type()) {
case QEvent::MouseButtonPress:
case QEvent::MouseButtonDblClick:
case QEvent::TouchBegin:
+ focusedWidgetOnTouchBegin = QApplication::focusWidget();
if (setFocusOnRelease)
return;
break;
@@ -4191,6 +4167,11 @@ void QApplicationPrivate::giveFocusAccordingToFocusPolicy(QWidget *widget, QEven
case QEvent::TouchEnd:
if (!setFocusOnRelease)
return;
+ if (focusedWidgetOnTouchBegin != QApplication::focusWidget()) {
+ // Focus widget was changed while delivering press/move events.
+ // To not interfere with application logic, we leave focus as-is
+ return;
+ }
break;
case QEvent::Wheel:
focusPolicy = Qt::WheelFocus;
diff --git a/src/widgets/kernel/qapplication_p.h b/src/widgets/kernel/qapplication_p.h
index 809c7ccd66..10f81a403a 100644
--- a/src/widgets/kernel/qapplication_p.h
+++ b/src/widgets/kernel/qapplication_p.h
@@ -168,7 +168,6 @@ public:
static void setFocusWidget(QWidget *focus, Qt::FocusReason reason);
static QWidget *focusNextPrevChild_helper(QWidget *toplevel, bool next,
bool *wrappingOccurred = 0);
- static Qt::MouseEventSource mouseEventSource(const QEvent *e);
#ifndef QT_NO_GRAPHICSVIEW
// Maintain a list of all scenes to ensure font and palette propagation to
diff --git a/src/widgets/kernel/qlayout.cpp b/src/widgets/kernel/qlayout.cpp
index 46cab90ab4..f124f1ed8e 100644
--- a/src/widgets/kernel/qlayout.cpp
+++ b/src/widgets/kernel/qlayout.cpp
@@ -576,11 +576,12 @@ void QLayoutPrivate::doResize(const QSize &r)
int mbh = menuBarHeightForWidth(menubar, r.width());
QWidget *mw = q->parentWidget();
QRect rect = mw->testAttribute(Qt::WA_LayoutOnEntireRect) ? mw->rect() : mw->contentsRect();
+ const int mbTop = rect.top();
rect.setTop(rect.top() + mbh);
q->setGeometry(rect);
#ifndef QT_NO_MENUBAR
if (menubar)
- menubar->setGeometry(0,0,r.width(), mbh);
+ menubar->setGeometry(rect.left(), mbTop, r.width(), mbh);
#endif
}
diff --git a/src/widgets/kernel/qstandardgestures.cpp b/src/widgets/kernel/qstandardgestures.cpp
index 53e5d091fa..6656903e70 100644
--- a/src/widgets/kernel/qstandardgestures.cpp
+++ b/src/widgets/kernel/qstandardgestures.cpp
@@ -38,7 +38,6 @@
#include "qwidget.h"
#include "qabstractscrollarea.h"
#include <qgraphicssceneevent.h>
-#include <QtGui/QTouchDevice>
#include "qdebug.h"
#ifndef QT_NO_GESTURES
@@ -68,26 +67,8 @@ static QPointF panOffset(const QList<QTouchEvent::TouchPoint> &touchPoints, int
return result / qreal(count);
}
-// ### fixme: Remove this
-// Use single finger pan to scroll QPlainTextEdit/QTextEdit
-// by changing the number of pan points to 1 for these classes.
-// This used to be Qt 4's behavior on Windows which was achieved using native
-// Windows gesture recognizers for these classes.
-// The other classes inheriting QScrollArea still use standard 2 finger pan.
-// In the long run, they should also use single finger pan to
-// scroll on touch screens, however, this requires a distinct Tap&Hold-followed-by-pan
-// type gesture to avoid clashes with item view selection and DnD.
-
-static inline int panTouchPoints(const QTouchEvent *event, const QObject *object,
- int defaultTouchPoints)
-{
- return event->device()->type() == QTouchDevice::TouchScreen && object && object->parent()
- && (object->parent()->inherits("QPlainTextEdit") || object->parent()->inherits("QTextEdit"))
- ? 1 : defaultTouchPoints;
-}
-
QGestureRecognizer::Result QPanGestureRecognizer::recognize(QGesture *state,
- QObject *object,
+ QObject *,
QEvent *event)
{
QPanGesture *q = static_cast<QPanGesture *>(state);
@@ -100,7 +81,7 @@ QGestureRecognizer::Result QPanGestureRecognizer::recognize(QGesture *state,
result = QGestureRecognizer::MayBeGesture;
QTouchEvent::TouchPoint p = ev->touchPoints().at(0);
d->lastOffset = d->offset = QPointF();
- d->pointCount = panTouchPoints(ev, object, m_pointCount);
+ d->pointCount = m_pointCount;
break;
}
case QEvent::TouchEnd: {
diff --git a/src/widgets/styles/qandroidstyle.cpp b/src/widgets/styles/qandroidstyle.cpp
index 5b4b346da9..a5a75dae02 100644
--- a/src/widgets/styles/qandroidstyle.cpp
+++ b/src/widgets/styles/qandroidstyle.cpp
@@ -1719,28 +1719,43 @@ void QAndroidStyle::AndroidSeekBarControl::drawControl(const QStyleOption *optio
qstyleoption_cast<const QStyleOptionSlider *>(option)) {
double factor = double(styleOption->sliderPosition - styleOption->minimum)
/ double(styleOption->maximum - styleOption->minimum);
+
+ // Android does not have a vertical slider. To support the vertical orientation, we rotate
+ // the painter and pretend that we are horizontal.
+ if (styleOption->orientation == Qt::Vertical)
+ factor = 1 - factor;
+
if (m_progressDrawable->type() == QAndroidStyle::Layer) {
QAndroidStyle::AndroidDrawable *clipDrawable = static_cast<QAndroidStyle::AndroidLayerDrawable *>(m_progressDrawable)->layer(m_progressId);
if (clipDrawable->type() == QAndroidStyle::Clip)
- static_cast<QAndroidStyle::AndroidClipDrawable *>(clipDrawable)->setFactor(factor, styleOption->orientation);
+ static_cast<QAndroidStyle::AndroidClipDrawable *>(clipDrawable)->setFactor(factor, Qt::Horizontal);
else
- static_cast<QAndroidStyle::AndroidLayerDrawable *>(m_progressDrawable)->setFactor(m_progressId, factor, styleOption->orientation);
+ static_cast<QAndroidStyle::AndroidLayerDrawable *>(m_progressDrawable)->setFactor(m_progressId, factor, Qt::Horizontal);
}
const AndroidDrawable *drawable = m_seekBarThumb;
if (drawable->type() == State)
drawable = static_cast<const QAndroidStyle::AndroidStateDrawable *>(m_seekBarThumb)->bestAndroidStateMatch(option);
QStyleOption copy(*option);
+
+ p->save();
+
+ if (styleOption->orientation == Qt::Vertical) {
+ // rotate the painter, and transform the rectangle to match
+ p->rotate(90);
+ copy.rect = QRect(copy.rect.y(), copy.rect.x() - copy.rect.width(), copy.rect.height(), copy.rect.width());
+ }
+
copy.rect.setHeight(m_progressDrawable->size().height());
copy.rect.setWidth(copy.rect.width() - drawable->size().width());
const int yTranslate = abs(drawable->size().height() - copy.rect.height()) / 2;
copy.rect.translate(drawable->size().width() / 2, yTranslate);
m_progressDrawable->draw(p, &copy);
- if (styleOption->orientation == Qt::Vertical)
- qCritical() << "Vertical slider are not supported";
int pos = copy.rect.width() * factor - drawable->size().width() / 2;
copy.rect.translate(pos, -yTranslate);
copy.rect.setSize(drawable->size());
m_seekBarThumb->draw(p, &copy);
+
+ p->restore();
}
}
@@ -1772,8 +1787,13 @@ QRect QAndroidStyle::AndroidSeekBarControl::subControlRect(const QStyleOptionCom
QRect r(option->rect);
double factor = double(styleOption->sliderPosition - styleOption->minimum)
/ (styleOption->maximum - styleOption->minimum);
- int pos = option->rect.width() * factor - double(drawable->size().width() / 2);
- r.setX(r.x() + pos);
+ if (styleOption->orientation == Qt::Vertical) {
+ int pos = option->rect.height() * (1 - factor) - double(drawable->size().height() / 2);
+ r.setY(r.y() + pos);
+ } else {
+ int pos = option->rect.width() * factor - double(drawable->size().width() / 2);
+ r.setX(r.x() + pos);
+ }
r.setSize(drawable->size());
return r;
}
diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp
index 7e9a631c5e..6b8cba1b18 100644
--- a/src/widgets/styles/qcommonstyle.cpp
+++ b/src/widgets/styles/qcommonstyle.cpp
@@ -4587,7 +4587,7 @@ int QCommonStyle::pixelMetric(PixelMetric m, const QStyleOption *opt, const QWid
ret = int(QStyleHelper::dpiScaled(4.));
break;
case PM_HeaderMarkSize:
- ret = int(QStyleHelper::dpiScaled(32.));
+ ret = int(QStyleHelper::dpiScaled(16.));
break;
case PM_HeaderGripMargin:
ret = int(QStyleHelper::dpiScaled(4.));
@@ -4907,10 +4907,13 @@ int QCommonStyle::styleHint(StyleHint sh, const QStyleOption *opt, const QWidget
case SH_TabBar_Alignment:
- case SH_Header_ArrowAlignment:
ret = Qt::AlignLeft;
break;
+ case SH_Header_ArrowAlignment:
+ ret = Qt::AlignRight | Qt::AlignVCenter;
+ break;
+
case SH_TitleBar_AutoRaise:
ret = false;
break;
diff --git a/src/widgets/styles/qmacstyle_mac.mm b/src/widgets/styles/qmacstyle_mac.mm
index 328378cb8e..3918b874e6 100644
--- a/src/widgets/styles/qmacstyle_mac.mm
+++ b/src/widgets/styles/qmacstyle_mac.mm
@@ -5592,7 +5592,7 @@ void QMacStyle::drawComplexControl(ComplexControl cc, const QStyleOptionComplex
CGContextTranslateCTM(ctx, 0, rect.size.height);
CGContextScaleCTM(ctx, 1, -1);
}
- [sl.cell drawBarInside:tdi.bounds flipped:NO];
+ [sl.cell drawBarInside:NSRectFromCGRect(tdi.bounds) flipped:NO];
// No need to restore the CTM later, the context has been saved
// and will be restored at the end of drawNSViewInRect()
});
diff --git a/src/widgets/styles/qstyle.cpp b/src/widgets/styles/qstyle.cpp
index 109a0ea451..2d5f676b65 100644
--- a/src/widgets/styles/qstyle.cpp
+++ b/src/widgets/styles/qstyle.cpp
@@ -1663,7 +1663,8 @@ void QStyle::drawItemPixmap(QPainter *painter, const QRect &rect, int alignment,
\value SH_Header_ArrowAlignment The placement of the sorting
indicator may appear in list or table headers. Possible values
- are Qt::Left or Qt::Right.
+ are Qt::Alignment values (that is, an OR combination of
+ Qt::AlignmentFlag flags).
\value SH_Slider_SnapToValue Sliders snap to values while moving,
as they do on Windows.
diff --git a/src/widgets/styles/qwindowsvistastyle.cpp b/src/widgets/styles/qwindowsvistastyle.cpp
index 463b120e04..42a85e8f64 100644
--- a/src/widgets/styles/qwindowsvistastyle.cpp
+++ b/src/widgets/styles/qwindowsvistastyle.cpp
@@ -2112,6 +2112,9 @@ int QWindowsVistaStyle::styleHint(StyleHint hint, const QStyleOption *option, co
else
ret = -1;
break;
+ case SH_Header_ArrowAlignment:
+ ret = Qt::AlignTop | Qt::AlignHCenter;
+ break;
default:
ret = QWindowsXPStyle::styleHint(hint, option, widget, returnData);
break;
diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp
index fda37c49de..40cf2f0f95 100644
--- a/src/widgets/widgets/qcombobox.cpp
+++ b/src/widgets/widgets/qcombobox.cpp
@@ -942,8 +942,8 @@ QComboBox::QComboBox(QComboBoxPrivate &dd, QWidget *parent)
void QComboBoxPrivate::init()
{
Q_Q(QComboBox);
-#ifdef Q_OS_MAC
- // On Mac, only line edits and list views always get tab focus. It's only
+#ifdef Q_OS_OSX
+ // On OS X, only line edits and list views always get tab focus. It's only
// when we enable full keyboard access that other controls can get tab focus.
// When it's not editable, a combobox looks like a button, and it behaves as
// such in this respect.
diff --git a/src/widgets/widgets/qdockwidget.cpp b/src/widgets/widgets/qdockwidget.cpp
index 6862daf84e..121fb2da49 100644
--- a/src/widgets/widgets/qdockwidget.cpp
+++ b/src/widgets/widgets/qdockwidget.cpp
@@ -1009,6 +1009,8 @@ void QDockWidgetPrivate::setWindowState(bool floating, bool unplug, const QRect
}
bool wasFloating = q->isFloating();
+ if (wasFloating) // Prevent repetitive unplugging from nested invocations (QTBUG-42818)
+ unplug = false;
bool hidden = q->isHidden();
if (q->isVisible())
diff --git a/src/widgets/widgets/qmainwindowlayout.cpp b/src/widgets/widgets/qmainwindowlayout.cpp
index d14ace1b73..9e8e0aee27 100644
--- a/src/widgets/widgets/qmainwindowlayout.cpp
+++ b/src/widgets/widgets/qmainwindowlayout.cpp
@@ -1440,7 +1440,7 @@ void QMainWindowLayout::setGeometry(const QRect &_r)
QLayout::setGeometry(r);
if (statusbar) {
- QRect sbr(QPoint(0, 0),
+ QRect sbr(QPoint(r.left(), 0),
QSize(r.width(), statusbar->heightForWidth(r.width()))
.expandedTo(statusbar->minimumSize()));
sbr.moveBottom(r.bottom());
diff --git a/src/widgets/widgets/qmenubar.cpp b/src/widgets/widgets/qmenubar.cpp
index 97991d97b5..5f40e4b1d9 100644
--- a/src/widgets/widgets/qmenubar.cpp
+++ b/src/widgets/widgets/qmenubar.cpp
@@ -1631,9 +1631,8 @@ QSize QMenuBar::sizeHint() const
int margin = 2*vmargin + 2*fw + spaceBelowMenuBar;
if(d->leftWidget) {
QSize sz = d->leftWidget->sizeHint();
- ret.setWidth(ret.width() + sz.width());
- if(sz.height() + margin > ret.height())
- ret.setHeight(sz.height() + margin);
+ sz.rheight() += margin;
+ ret.expandedTo(sz);
}
if(d->rightWidget) {
QSize sz = d->rightWidget->sizeHint();
diff --git a/src/widgets/widgets/qtoolbar.cpp b/src/widgets/widgets/qtoolbar.cpp
index 17e64be4f4..77119a0d7d 100644
--- a/src/widgets/widgets/qtoolbar.cpp
+++ b/src/widgets/widgets/qtoolbar.cpp
@@ -220,10 +220,8 @@ void QToolBarPrivate::endDrag()
if (!layout->plug(state->widgetItem)) {
if (q->isFloatable()) {
layout->restore();
-#if defined(Q_WS_X11) || defined(Q_WS_MAC)
setWindowState(true); // gets rid of the X11BypassWindowManager window flag
// and activates the resizer
-#endif
q->activateWindow();
} else {
layout->revert(state->widgetItem);
diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp
index 93835156da..eabaa160a0 100644
--- a/src/widgets/widgets/qwidgettextcontrol.cpp
+++ b/src/widgets/widgets/qwidgettextcontrol.cpp
@@ -110,7 +110,7 @@ QWidgetTextControlPrivate::QWidgetTextControlPrivate()
#ifndef Q_OS_ANDROID
interactionFlags(Qt::TextEditorInteraction),
#else
- interactionFlags(Qt::TextEditable),
+ interactionFlags(Qt::TextEditable | Qt::TextSelectableByKeyboard),
#endif
dragEnabled(true),
#ifndef QT_NO_DRAGANDDROP
@@ -1582,10 +1582,8 @@ void QWidgetTextControlPrivate::mousePressEvent(QEvent *e, Qt::MouseButton butto
cursor.clearSelection();
}
}
- // Do not start selection on a mouse event synthesized from a touch event.
if (!(button & Qt::LeftButton) ||
- !((interactionFlags & Qt::TextSelectableByMouse) || (interactionFlags & Qt::TextEditable))
- || QApplicationPrivate::mouseEventSource(e) != Qt::MouseEventNotSynthesized) {
+ !((interactionFlags & Qt::TextSelectableByMouse) || (interactionFlags & Qt::TextEditable))) {
e->ignore();
return;
}
@@ -1756,11 +1754,6 @@ void QWidgetTextControlPrivate::mouseReleaseEvent(QEvent *e, Qt::MouseButton but
{
Q_Q(QWidgetTextControl);
- if (QApplicationPrivate::mouseEventSource(e) != Qt::MouseEventNotSynthesized) {
- setCursorPosition(pos); // Emulate Tap to set cursor for events synthesized from touch.
- return;
- }
-
const QTextCursor oldSelection = cursor;
if (sendMouseEventToInputContext(
e, QEvent::MouseButtonRelease, button, pos, modifiers, buttons, globalPos)) {