summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/angle/src/libEGL/main.cpp4
-rw-r--r--src/3rdparty/angle/src/libGLESv2/main.cpp4
-rw-r--r--src/3rdparty/sqlite/sqlite3.c7
-rw-r--r--src/3rdparty/sqlite/sqlite3.h4
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java22
-rw-r--r--src/android/jar/src/org/qtproject/qt5/android/QtInputConnection.java45
-rw-r--r--src/android/java/AndroidManifest.xml3
-rw-r--r--src/android/java/res/values/libs.xml2
-rw-r--r--src/angle/patches/0015-ANGLE-Don-t-export-DLLMain-functions-for-static-buil.patch63
-rw-r--r--src/angle/src/d3dcompiler/d3dcompiler.pro5
-rw-r--r--src/angle/src/d3dcompiler/main.cpp71
-rw-r--r--src/corelib/doc/qtcore.qdocconf1
-rw-r--r--src/corelib/io/qfilesystemwatcher_fsevents.mm134
-rw-r--r--src/corelib/io/qfilesystemwatcher_fsevents_p.h13
-rw-r--r--src/corelib/io/qsettings.cpp6
-rw-r--r--src/corelib/io/qsettings_mac.cpp40
-rw-r--r--src/corelib/io/qstandardpaths_win.cpp25
-rw-r--r--src/corelib/kernel/qcoreevent.cpp3
-rw-r--r--src/corelib/kernel/qeventdispatcher_winrt.cpp6
-rw-r--r--src/corelib/kernel/qmetatype.h42
-rw-r--r--src/corelib/kernel/qmimedata.cpp2
-rw-r--r--src/corelib/kernel/qobject.cpp6
-rw-r--r--src/corelib/tools/qmargins.cpp20
-rw-r--r--src/corelib/tools/qpoint.cpp2
-rw-r--r--src/corelib/tools/qrect.cpp2
-rw-r--r--src/corelib/tools/qsimd_p.h2
-rw-r--r--src/corelib/tools/qstring.cpp24
-rw-r--r--src/corelib/tools/qstring.h2
-rw-r--r--src/corelib/xml/qxmlstream.cpp4
-rw-r--r--src/dbus/qdbusreply.cpp7
-rw-r--r--src/gui/image/qimage.cpp2
-rw-r--r--src/gui/image/qnativeimage.cpp2
-rw-r--r--src/gui/kernel/qdrag.cpp2
-rw-r--r--src/gui/kernel/qevent.cpp4
-rw-r--r--src/gui/kernel/qoffscreensurface.cpp8
-rw-r--r--src/gui/kernel/qopenglcontext.cpp4
-rw-r--r--src/gui/kernel/qopenglcontext_p.h1
-rw-r--r--src/gui/kernel/qsessionmanager.cpp8
-rw-r--r--src/gui/kernel/qsurfaceformat.cpp2
-rw-r--r--src/gui/kernel/qwindow.cpp11
-rw-r--r--src/gui/opengl/qopenglpaintdevice.cpp2
-rw-r--r--src/gui/opengl/qopengltexture.cpp14
-rw-r--r--src/gui/opengl/qopenglvertexarrayobject.cpp8
-rw-r--r--src/gui/painting/qblendfunctions.cpp24
-rw-r--r--src/gui/painting/qblendfunctions_p.h24
-rw-r--r--src/gui/painting/qdrawhelper.cpp2
-rw-r--r--src/gui/painting/qdrawhelper_neon.cpp12
-rw-r--r--src/gui/painting/qdrawhelper_p.h2
-rw-r--r--src/gui/painting/qdrawhelper_sse2.cpp14
-rw-r--r--src/gui/painting/qpaintengine_raster.cpp2
-rw-r--r--src/gui/painting/qpdf.cpp2
-rw-r--r--src/gui/text/qfont.cpp8
-rw-r--r--src/gui/text/qfont.h6
-rw-r--r--src/gui/text/qfont_p.h2
-rw-r--r--src/gui/text/qfontdatabase.cpp2
-rw-r--r--src/gui/text/qharfbuzzng.cpp59
-rw-r--r--src/gui/text/qrawfont.cpp5
-rw-r--r--src/opengl/doc/src/qtopengl-index.qdoc2
-rw-r--r--src/opengl/qgl.cpp47
-rw-r--r--src/opengl/qglfunctions.cpp4
-rw-r--r--src/platformsupport/eglconvenience/qeglconvenience.cpp15
-rw-r--r--src/platformsupport/eglconvenience/qeglplatformcontext.cpp39
-rw-r--r--src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp6
-rw-r--r--src/platformsupport/fontdatabases/basic/qbasicfontdatabase_p.h2
-rw-r--r--src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp220
-rw-r--r--src/plugins/generic/evdevtouch/README13
-rw-r--r--src/plugins/platforms/android/androidjnimain.cpp3
-rw-r--r--src/plugins/platforms/android/qandroidinputcontext.cpp108
-rw-r--r--src/plugins/platforms/android/qandroidinputcontext.h3
-rw-r--r--src/plugins/platforms/android/qandroidplatformdialoghelpers.cpp19
-rw-r--r--src/plugins/platforms/android/qandroidplatformfontdatabase.cpp18
-rw-r--r--src/plugins/platforms/android/qandroidplatformfontdatabase.h3
-rw-r--r--src/plugins/platforms/android/qandroidplatformintegration.cpp43
-rw-r--r--src/plugins/platforms/android/qandroidplatformintegration.h2
-rw-r--r--src/plugins/platforms/android/qandroidplatformopenglcontext.cpp18
-rw-r--r--src/plugins/platforms/android/qandroidplatformopenglcontext.h2
-rw-r--r--src/plugins/platforms/android/qandroidplatformrasterwindow.cpp4
-rw-r--r--src/plugins/platforms/android/qandroidplatformscreen.cpp13
-rw-r--r--src/plugins/platforms/android/qandroidplatformscreen.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibility.mm7
-rw-r--r--src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm18
-rw-r--r--src/plugins/platforms/cocoa/qcocoaeventdispatcher.h1
-rw-r--r--src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm16
-rw-r--r--src/plugins/platforms/cocoa/qcocoaintegration.mm10
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.h2
-rw-r--r--src/plugins/platforms/cocoa/qcocoawindow.mm34
-rw-r--r--src/plugins/platforms/cocoa/qnsview.mm8
-rw-r--r--src/plugins/platforms/cocoa/qnsviewaccessibility.mm53
-rw-r--r--src/plugins/platforms/cocoa/qnswindowdelegate.mm8
-rw-r--r--src/plugins/platforms/eglfs/qeglfscontext.cpp4
-rw-r--r--src/plugins/platforms/eglfs/qeglfshooks_stub.cpp11
-rw-r--r--src/plugins/platforms/ios/qioscontext.h2
-rw-r--r--src/plugins/platforms/ios/qioscontext.mm69
-rw-r--r--src/plugins/platforms/ios/qiosinputcontext.mm64
-rw-r--r--src/plugins/platforms/ios/qiosintegration.h1
-rw-r--r--src/plugins/platforms/ios/qiosintegration.mm7
-rw-r--r--src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp16
-rw-r--r--src/plugins/platforms/qnx/qqnxfilepicker.cpp8
-rw-r--r--src/plugins/platforms/qnx/qqnxscreen.cpp5
-rw-r--r--src/plugins/platforms/qnx/qqnxscreen.h3
-rw-r--r--src/plugins/platforms/qnx/qqnxwindow.cpp8
-rw-r--r--src/plugins/platforms/windows/qwindowsfontdatabase.cpp3
-rw-r--r--src/plugins/platforms/windows/qwindowsfontengine.cpp29
-rw-r--r--src/plugins/platforms/windows/qwindowsfontengine.h10
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp10
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.h3
-rw-r--r--src/plugins/platforms/winrt/qwinrtfontdatabase.cpp331
-rw-r--r--src/plugins/platforms/winrt/qwinrtfontdatabase.h3
-rw-r--r--src/plugins/platforms/winrt/qwinrtintegration.cpp2
-rw-r--r--src/plugins/platforms/winrt/winrt.pro9
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.cpp69
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection.h2
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.cpp285
-rw-r--r--src/plugins/platforms/xcb/qxcbkeyboard.h36
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp10
-rw-r--r--src/plugins/platforms/xcb/xcb-plugin.pro8
-rw-r--r--src/sql/drivers/ibase/qsql_ibase.cpp14
-rw-r--r--src/sql/kernel/qsqlquery.cpp2
-rw-r--r--src/testlib/qtestcase.cpp4
-rw-r--r--src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp4
-rw-r--r--src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp4
-rw-r--r--src/tools/qdoc/doc/qdoc-manual-markupcmds.qdoc2
-rw-r--r--src/tools/qdoc/doc/qdoc-manual-qdocconf.qdoc2
-rw-r--r--src/tools/qdoc/doc/qdoc-manual-topiccmds.qdoc21
-rw-r--r--src/tools/qlalr/cppgenerator.cpp4
-rw-r--r--src/widgets/accessible/simplewidgets.cpp2
-rw-r--r--src/widgets/dialogs/qfontdialog.cpp18
-rw-r--r--src/widgets/itemviews/qabstractitemview.cpp15
-rw-r--r--src/widgets/itemviews/qitemdelegate.cpp5
-rw-r--r--src/widgets/itemviews/qstyleditemdelegate.cpp5
-rw-r--r--src/widgets/kernel/qapplication.cpp27
-rw-r--r--src/widgets/kernel/qgesturemanager.cpp6
-rw-r--r--src/widgets/kernel/qgesturemanager_p.h1
-rw-r--r--src/widgets/kernel/qstandardgestures.cpp35
-rw-r--r--src/widgets/kernel/qwidget.cpp29
-rw-r--r--src/widgets/kernel/qwidget_p.h4
-rw-r--r--src/widgets/util/qcolormap.cpp7
-rw-r--r--src/widgets/widgets/qscrollbar.cpp23
-rw-r--r--src/widgets/widgets/qscrollbar_p.h1
-rw-r--r--src/widgets/widgets/qwidgettextcontrol.cpp3
-rw-r--r--src/xml/doc/src/qtxml-index.qdoc2
141 files changed, 1673 insertions, 1121 deletions
diff --git a/src/3rdparty/angle/src/libEGL/main.cpp b/src/3rdparty/angle/src/libEGL/main.cpp
index e972691a4f..4cdf5f0362 100644
--- a/src/3rdparty/angle/src/libEGL/main.cpp
+++ b/src/3rdparty/angle/src/libEGL/main.cpp
@@ -69,6 +69,8 @@ void DeallocateCurrent()
}
+#ifndef QT_OPENGL_ES_2_ANGLE_STATIC
+
extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
{
switch (reason)
@@ -124,6 +126,8 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
return TRUE;
}
+#endif // !QT_OPENGL_ES_2_ANGLE_STATIC
+
namespace egl
{
diff --git a/src/3rdparty/angle/src/libGLESv2/main.cpp b/src/3rdparty/angle/src/libGLESv2/main.cpp
index 95f4b8de1c..e52799438d 100644
--- a/src/3rdparty/angle/src/libGLESv2/main.cpp
+++ b/src/3rdparty/angle/src/libGLESv2/main.cpp
@@ -66,6 +66,8 @@ void DeallocateCurrent()
}
+#ifndef QT_OPENGL_ES_2_ANGLE_STATIC
+
extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
{
switch (reason)
@@ -107,6 +109,8 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
return TRUE;
}
+#endif // !QT_OPENGL_ES_2_ANGLE_STATIC
+
namespace gl
{
diff --git a/src/3rdparty/sqlite/sqlite3.c b/src/3rdparty/sqlite/sqlite3.c
index a2e37dd48e..f8a10149bc 100644
--- a/src/3rdparty/sqlite/sqlite3.c
+++ b/src/3rdparty/sqlite/sqlite3.c
@@ -1,6 +1,6 @@
/******************************************************************************
** This file is an amalgamation of many separate C source files from SQLite
-** version 3.8.4.1. By combining all the individual C code files into this
+** version 3.8.4.2. By combining all the individual C code files into this
** single large file, the entire code can be compiled as a single translation
** unit. This allows many compilers to do optimizations that would not be
** possible if the files were compiled separately. Performance improvements
@@ -222,9 +222,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
-#define SQLITE_VERSION "3.8.4.1"
+#define SQLITE_VERSION "3.8.4.2"
#define SQLITE_VERSION_NUMBER 3008004
-#define SQLITE_SOURCE_ID "2014-03-11 15:27:36 018d317b1257ce68a92908b05c9c7cf1494050d0"
+#define SQLITE_SOURCE_ID "2014-03-26 18:51:19 02ea166372bdb2ef9d8dfbb05e78a97609673a8e"
/*
** CAPI3REF: Run-Time Library Version Numbers
@@ -64786,6 +64786,7 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompare(
}else{
idx1 = getVarint32(aKey1, szHdr1);
d1 = szHdr1;
+ if( d1>(unsigned)nKey1 ) return 1; /* Corruption */
i = 0;
}
diff --git a/src/3rdparty/sqlite/sqlite3.h b/src/3rdparty/sqlite/sqlite3.h
index 1f19ada4cb..d0d676afae 100644
--- a/src/3rdparty/sqlite/sqlite3.h
+++ b/src/3rdparty/sqlite/sqlite3.h
@@ -107,9 +107,9 @@ extern "C" {
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
-#define SQLITE_VERSION "3.8.4.1"
+#define SQLITE_VERSION "3.8.4.2"
#define SQLITE_VERSION_NUMBER 3008004
-#define SQLITE_SOURCE_ID "2014-03-11 15:27:36 018d317b1257ce68a92908b05c9c7cf1494050d0"
+#define SQLITE_SOURCE_ID "2014-03-26 18:51:19 02ea166372bdb2ef9d8dfbb05e78a97609673a8e"
/*
** CAPI3REF: Run-Time Library Version Numbers
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 ea8e5cd44c..e62b5dab82 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtActivityDelegate.java
@@ -120,7 +120,7 @@ public class QtActivityDelegate
private boolean m_keyboardIsVisible = false;
public boolean m_backKeyPressedSent = false;
-
+ private long m_showHideTimeStamp = System.nanoTime();
public void setFullScreen(boolean enterFullScreen)
{
@@ -201,12 +201,18 @@ public class QtActivityDelegate
private final int ApplicationInactive = 0x2;
private final int ApplicationActive = 0x4;
- public void setKeyboardVisibility(boolean visibility)
+
+ public boolean setKeyboardVisibility(boolean visibility, long timeStamp)
{
+ if (m_showHideTimeStamp > timeStamp)
+ return false;
+ m_showHideTimeStamp = timeStamp;
+
if (m_keyboardIsVisible == visibility)
- return;
+ return false;
m_keyboardIsVisible = visibility;
QtNative.keyboardVisibilityChanged(m_keyboardIsVisible);
+ return true;
}
public void resetSoftwareKeyboard()
{
@@ -304,11 +310,11 @@ public class QtActivityDelegate
QtNativeInputConnection.updateCursorPosition();
//FALLTHROUGH
case InputMethodManager.RESULT_UNCHANGED_SHOWN:
- setKeyboardVisibility(true);
+ setKeyboardVisibility(true, System.nanoTime());
break;
case InputMethodManager.RESULT_HIDDEN:
case InputMethodManager.RESULT_UNCHANGED_HIDDEN:
- setKeyboardVisibility(false);
+ setKeyboardVisibility(false, System.nanoTime());
break;
}
}
@@ -331,11 +337,11 @@ public class QtActivityDelegate
switch (resultCode) {
case InputMethodManager.RESULT_SHOWN:
case InputMethodManager.RESULT_UNCHANGED_SHOWN:
- setKeyboardVisibility(true);
+ setKeyboardVisibility(true, System.nanoTime());
break;
case InputMethodManager.RESULT_HIDDEN:
case InputMethodManager.RESULT_UNCHANGED_HIDDEN:
- setKeyboardVisibility(false);
+ setKeyboardVisibility(false, System.nanoTime());
break;
}
}
@@ -827,7 +833,7 @@ public class QtActivityDelegate
if (keyCode == KeyEvent.KEYCODE_BACK && !m_backKeyPressedSent) {
hideSoftwareKeyboard();
- setKeyboardVisibility(false);
+ setKeyboardVisibility(false, System.nanoTime());
return true;
}
diff --git a/src/android/jar/src/org/qtproject/qt5/android/QtInputConnection.java b/src/android/jar/src/org/qtproject/qt5/android/QtInputConnection.java
index 5e6e227c2b..6de66fe512 100644
--- a/src/android/jar/src/org/qtproject/qt5/android/QtInputConnection.java
+++ b/src/android/jar/src/org/qtproject/qt5/android/QtInputConnection.java
@@ -61,6 +61,8 @@ class QtExtractedText
class QtNativeInputConnection
{
+ static native boolean beginBatchEdit();
+ static native boolean endBatchEdit();
static native boolean commitText(String text, int newCursorPosition);
static native boolean commitCompletion(String text, int position);
static native boolean deleteSurroundingText(int leftLength, int rightLength);
@@ -82,18 +84,11 @@ class QtNativeInputConnection
}
class HideKeyboardRunnable implements Runnable {
- private QtInputConnection m_connection;
- HideKeyboardRunnable(QtInputConnection connection)
- {
- m_connection = connection;
- }
+ private long m_hideTimeStamp = System.nanoTime();
@Override
public void run() {
- if (m_connection.getInputState() == QtInputConnection.InputStates.Hiding) {
- QtNative.activityDelegate().setKeyboardVisibility(false);
- m_connection.reset();
- }
+ QtNative.activityDelegate().setKeyboardVisibility(false, m_hideTimeStamp);
}
}
@@ -107,34 +102,14 @@ public class QtInputConnection extends BaseInputConnection
private static final int ID_SWITCH_INPUT_METHOD = android.R.id.switchInputMethod;
private static final int ID_ADD_TO_DICTIONARY = android.R.id.addToDictionary;
-
- enum InputStates { Visible, FinishComposing, Hiding };
-
private QtEditText m_view = null;
- private InputStates m_inputState = InputStates.Visible;
-
- public void reset()
- {
- m_inputState = InputStates.Visible;
- }
-
- public InputStates getInputState()
- {
- return m_inputState;
- }
private void setClosing(boolean closing)
{
- if (closing && m_inputState == InputStates.Hiding)
- return;
-
- if (closing && m_view.getActivityDelegate().isSoftwareKeyboardVisible()) {
- m_view.postDelayed(new HideKeyboardRunnable(this), 100);
- m_inputState = InputStates.Hiding;
+ if (closing) {
+ m_view.postDelayed(new HideKeyboardRunnable(), 100);
} else {
- if (m_inputState == InputStates.Hiding)
- QtNative.activityDelegate().setKeyboardVisibility(true);
- m_inputState = closing ? InputStates.FinishComposing : InputStates.Visible;
+ QtNative.activityDelegate().setKeyboardVisibility(true, System.nanoTime());
}
}
@@ -148,14 +123,14 @@ public class QtInputConnection extends BaseInputConnection
public boolean beginBatchEdit()
{
setClosing(false);
- return true;
+ return QtNativeInputConnection.beginBatchEdit();
}
@Override
public boolean endBatchEdit()
{
-// setClosing(false);
- return true;
+ setClosing(false);
+ return QtNativeInputConnection.endBatchEdit();
}
@Override
diff --git a/src/android/java/AndroidManifest.xml b/src/android/java/AndroidManifest.xml
index 3209ab58ac..8e551ba7ac 100644
--- a/src/android/java/AndroidManifest.xml
+++ b/src/android/java/AndroidManifest.xml
@@ -4,7 +4,8 @@
<activity android:configChanges="orientation|uiMode|screenLayout|screenSize|smallestScreenSize|locale|fontScale|keyboard|keyboardHidden|navigation"
android:name="org.qtproject.qt5.android.bindings.QtActivity"
android:label="@string/app_name"
- android:screenOrientation="unspecified">
+ android:screenOrientation="unspecified"
+ android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
diff --git a/src/android/java/res/values/libs.xml b/src/android/java/res/values/libs.xml
index 797e6bb8c4..664ab0abec 100644
--- a/src/android/java/res/values/libs.xml
+++ b/src/android/java/res/values/libs.xml
@@ -1,7 +1,7 @@
<?xml version='1.0' encoding='utf-8'?>
<resources>
<array name="qt_sources">
- <item>https://download.qt-project.org/ministro/android/qt5/qt-5.2</item>
+ <item>https://download.qt-project.org/ministro/android/qt5/qt-5.3</item>
</array>
<!-- The following is handled automatically by the deployment tool. It should
diff --git a/src/angle/patches/0015-ANGLE-Don-t-export-DLLMain-functions-for-static-buil.patch b/src/angle/patches/0015-ANGLE-Don-t-export-DLLMain-functions-for-static-buil.patch
new file mode 100644
index 0000000000..0341da289a
--- /dev/null
+++ b/src/angle/patches/0015-ANGLE-Don-t-export-DLLMain-functions-for-static-buil.patch
@@ -0,0 +1,63 @@
+From 6545677945d24854007d39fed86d4e44900b5c1a Mon Sep 17 00:00:00 2001
+From: Andrew Knight <andrew.knight@digia.com>
+Date: Thu, 27 Mar 2014 15:36:52 +0200
+Subject: [PATCH] ANGLE: Don't export DLLMain functions for static builds
+
+These ifdef guards were originally a part of
+"0004-Make-it-possible-to-link-ANGLE-statically-for-single.patch",
+but were lost during the last ANGLE upgrade.
+
+Task-number: QTBUG-37842
+Change-Id: I4340c1641675dd310c14454a851eb4bc0ae2ec0d
+---
+ src/3rdparty/angle/src/libEGL/main.cpp | 4 ++++
+ src/3rdparty/angle/src/libGLESv2/main.cpp | 4 ++++
+ 2 files changed, 8 insertions(+)
+
+diff --git a/src/3rdparty/angle/src/libEGL/main.cpp b/src/3rdparty/angle/src/libEGL/main.cpp
+index e972691..4cdf5f0 100644
+--- a/src/3rdparty/angle/src/libEGL/main.cpp
++++ b/src/3rdparty/angle/src/libEGL/main.cpp
+@@ -69,6 +69,8 @@ void DeallocateCurrent()
+
+ }
+
++#ifndef QT_OPENGL_ES_2_ANGLE_STATIC
++
+ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
+ {
+ switch (reason)
+@@ -124,6 +126,8 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
+ return TRUE;
+ }
+
++#endif // !QT_OPENGL_ES_2_ANGLE_STATIC
++
+ namespace egl
+ {
+
+diff --git a/src/3rdparty/angle/src/libGLESv2/main.cpp b/src/3rdparty/angle/src/libGLESv2/main.cpp
+index 95f4b8d..e527994 100644
+--- a/src/3rdparty/angle/src/libGLESv2/main.cpp
++++ b/src/3rdparty/angle/src/libGLESv2/main.cpp
+@@ -66,6 +66,8 @@ void DeallocateCurrent()
+
+ }
+
++#ifndef QT_OPENGL_ES_2_ANGLE_STATIC
++
+ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved)
+ {
+ switch (reason)
+@@ -107,6 +109,8 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved
+ return TRUE;
+ }
+
++#endif // !QT_OPENGL_ES_2_ANGLE_STATIC
++
+ namespace gl
+ {
+
+--
+1.8.4.msysgit.0
+
diff --git a/src/angle/src/d3dcompiler/d3dcompiler.pro b/src/angle/src/d3dcompiler/d3dcompiler.pro
index 5a10187279..4d22080185 100644
--- a/src/angle/src/d3dcompiler/d3dcompiler.pro
+++ b/src/angle/src/d3dcompiler/d3dcompiler.pro
@@ -9,6 +9,11 @@ DEFINES += QT_NO_CAST_FROM_ASCII QT_NO_CAST_TO_ASCII
SOURCES += main.cpp
win32:!winrt: LIBS += -lole32
+winrt:equals(WINSDK_VER, 8.1) {
+ DEFINES += D3DCOMPILER_LINKED
+ LIBS += -ld3dcompiler
+}
+
# __stdcall exports get mangled, so use a def file
DEF_FILE += $${TARGET}.def
diff --git a/src/angle/src/d3dcompiler/main.cpp b/src/angle/src/d3dcompiler/main.cpp
index 7742596226..63ee1cf976 100644
--- a/src/angle/src/d3dcompiler/main.cpp
+++ b/src/angle/src/d3dcompiler/main.cpp
@@ -52,6 +52,12 @@
#include <qt_windows.h>
#include <d3dcommon.h>
+#ifdef D3DCOMPILER_LINKED
+namespace D3D {
+# include <d3dcompiler.h>
+}
+#endif // D3DCOMPILER_LINKED
+
Q_LOGGING_CATEGORY(QT_D3DCOMPILER, "qt.angle.d3dcompiler")
namespace D3DCompiler {
@@ -127,6 +133,7 @@ private:
static bool loadCompiler()
{
+#ifndef D3DCOMPILER_LINKED
static HMODULE d3dcompiler = 0;
if (!d3dcompiler) {
const wchar_t *dllNames[] = {
@@ -157,7 +164,9 @@ static bool loadCompiler()
if (!d3dcompiler)
qCDebug(QT_D3DCOMPILER) << "Unable to load D3D shader compiler.";
}
-
+#else // !D3DCOMPILER_LINKED
+ compile = &D3D::D3DCompile;
+#endif // D3DCOMPILER_LINKED
return bool(compile);
}
@@ -190,9 +199,19 @@ HRESULT WINAPI D3DCompile(
}
static bool initialized = false;
- static QString binaryPath;
+ static QStringList binaryPaths;
static QString sourcePath;
if (!initialized) {
+ // Precompiled directory
+ QString precompiledPath;
+ if (qEnvironmentVariableIsSet("QT_D3DCOMPILER_BINARY_DIR"))
+ precompiledPath = QString::fromLocal8Bit(qgetenv("QT_D3DCOMPILER_BINARY_DIR"));
+ else
+ precompiledPath = QStringLiteral(":/qt.d3dcompiler"); // Default QRC path
+ if (QDir(precompiledPath).exists())
+ binaryPaths.append(precompiledPath);
+
+ // Service directory
QString base;
if (qEnvironmentVariableIsSet("QT_D3DCOMPILER_DIR"))
base = QString::fromLocal8Bit(qgetenv("QT_D3DCOMPILER_DIR"));
@@ -203,28 +222,33 @@ HRESULT WINAPI D3DCompile(
base = location + QStringLiteral("/d3dcompiler");
}
- // Unless the service has run, this directory won't exist.
+ // Create the directory structure
QDir baseDir(base);
- if (baseDir.exists()) {
- // Check if we have can read/write blobs
- if (baseDir.exists(QStringLiteral("binary"))) {
- binaryPath = baseDir.absoluteFilePath(QStringLiteral("binary/"));
- } else {
- qCWarning(QT_D3DCOMPILER) << "D3D compiler base directory exists, but the binary directory does not.\n"
- "Check the compiler service.";
+ if (!baseDir.exists()) {
+ baseDir.cdUp();
+ if (!baseDir.mkdir(QStringLiteral("d3dcompiler"))) {
+ qCWarning(QT_D3DCOMPILER) << "Unable to create shader base directory:"
+ << QDir::toNativeSeparators(baseDir.absolutePath());
+ if (binaryPaths.isEmpty()) // No possibility to get a shader, abort
+ return E_FAIL;
}
+ baseDir.cd(QStringLiteral("d3dcompiler"));
+ }
- // Check if we can write shader source
- if (baseDir.exists(QStringLiteral("source"))) {
- sourcePath = baseDir.absoluteFilePath(QStringLiteral("source/"));
- } else {
- qCWarning(QT_D3DCOMPILER) << "D3D compiler base directory exists, but the source directory does not.\n"
- "Check the compiler service.";
- }
+ if (!baseDir.exists(QStringLiteral("binary")) && !baseDir.mkdir(QStringLiteral("binary"))) {
+ qCWarning(QT_D3DCOMPILER) << "Unable to create shader binary directory:"
+ << QDir::toNativeSeparators(baseDir.absoluteFilePath(QStringLiteral("binary")));
+ if (binaryPaths.isEmpty()) // No possibility to get a shader, abort
+ return E_FAIL;
+ } else {
+ binaryPaths.append(baseDir.absoluteFilePath(QStringLiteral("binary/")));
+ }
+
+ if (!baseDir.exists(QStringLiteral("source")) && !baseDir.mkdir(QStringLiteral("source"))) {
+ qCWarning(QT_D3DCOMPILER) << "Unable to create shader source directory:"
+ << QDir::toNativeSeparators(baseDir.absoluteFilePath(QStringLiteral("source")));
} else {
- qCWarning(QT_D3DCOMPILER) << "D3D compiler base directory does not exist:"
- << QDir::toNativeSeparators(base)
- << "\nCheck that the compiler service is running.";
+ sourcePath = baseDir.absoluteFilePath(QStringLiteral("source/"));
}
initialized = true;
@@ -245,8 +269,8 @@ HRESULT WINAPI D3DCompile(
+ QLatin1Char('!') + QString::number(sflags);
// Check if pre-compiled shader blob is available
- if (!binaryPath.isEmpty()) {
- QString blobName = binaryPath + fileName;
+ foreach (const QString &path, binaryPaths) {
+ QString blobName = path + fileName;
QFile blob(blobName);
while (!blob.exists()) {
// Progressively drop optional parts
@@ -262,6 +286,7 @@ HRESULT WINAPI D3DCompile(
return S_FALSE;
}
qCDebug(QT_D3DCOMPILER) << "Found, but unable to open, precompiled shader blob at" << blob.fileName();
+ break;
}
}
@@ -284,7 +309,7 @@ HRESULT WINAPI D3DCompile(
QElapsedTimer timer;
timer.start();
- QFile blob(binaryPath + fileName);
+ QFile blob(binaryPaths.last() + fileName);
while (!(blob.exists() && blob.open(QFile::ReadOnly)) && timer.elapsed() < timeout)
QThread::msleep(100);
diff --git a/src/corelib/doc/qtcore.qdocconf b/src/corelib/doc/qtcore.qdocconf
index 2ad24d33b1..18342d0138 100644
--- a/src/corelib/doc/qtcore.qdocconf
+++ b/src/corelib/doc/qtcore.qdocconf
@@ -37,6 +37,7 @@ exampledirs += \
snippets \
../../../examples/threads/ \
../../../examples/tools/ \
+ ../../../examples/ipc/ \
../../../examples/json/ \
../../../examples/network/dnslookup
diff --git a/src/corelib/io/qfilesystemwatcher_fsevents.mm b/src/corelib/io/qfilesystemwatcher_fsevents.mm
index cb6ddd913e..bfcae2a3a2 100644
--- a/src/corelib/io/qfilesystemwatcher_fsevents.mm
+++ b/src/corelib/io/qfilesystemwatcher_fsevents.mm
@@ -55,7 +55,7 @@
#include <qfileinfo.h>
#include <qvarlengtharray.h>
-//#define FSEVENT_DEBUG
+#undef FSEVENT_DEBUG
#ifdef FSEVENT_DEBUG
# define DEBUG if (true) qDebug
#else
@@ -76,14 +76,16 @@ static void callBackFunction(ConstFSEventStreamRef streamRef,
engine->processEvent(streamRef, numEvents, paths, eventFlags, eventIds);
}
-void QFseventsFileSystemWatcherEngine::checkDir(DirsByName::iterator &it)
+bool QFseventsFileSystemWatcherEngine::checkDir(DirsByName::iterator &it)
{
+ bool needsRestart = false;
+
QT_STATBUF st;
const QString &name = it.key();
Info &info = it->dirInfo;
const int res = QT_STAT(QFile::encodeName(name), &st);
if (res == -1) {
- derefPath(info.watchedPath);
+ needsRestart |= derefPath(info.watchedPath);
emit emitDirectoryChanged(info.origPath, true);
it = watchedDirectories.erase(it);
} else if (st.st_ctimespec != info.ctime || st.st_mode != info.mode) {
@@ -127,26 +129,34 @@ void QFseventsFileSystemWatcherEngine::checkDir(DirsByName::iterator &it)
if (dirChanged)
emit emitDirectoryChanged(info.origPath, false);
}
+
+ return needsRestart;
}
-void QFseventsFileSystemWatcherEngine::rescanDirs(const QString &path)
+bool QFseventsFileSystemWatcherEngine::rescanDirs(const QString &path)
{
+ bool needsRestart = false;
+
for (DirsByName::iterator it = watchedDirectories.begin(); it != watchedDirectories.end(); ) {
if (it.key().startsWith(path))
- checkDir(it);
+ needsRestart |= checkDir(it);
else
++it;
}
+
+ return needsRestart;
}
-void QFseventsFileSystemWatcherEngine::rescanFiles(InfoByName &filesInPath)
+bool QFseventsFileSystemWatcherEngine::rescanFiles(InfoByName &filesInPath)
{
+ bool needsRestart = false;
+
for (InfoByName::iterator it = filesInPath.begin(); it != filesInPath.end(); ) {
QT_STATBUF st;
QString name = it.key();
const int res = QT_STAT(QFile::encodeName(name), &st);
if (res == -1) {
- derefPath(it->watchedPath);
+ needsRestart |= derefPath(it->watchedPath);
emit emitFileChanged(it.value().origPath, true);
it = filesInPath.erase(it);
continue;
@@ -158,13 +168,17 @@ void QFseventsFileSystemWatcherEngine::rescanFiles(InfoByName &filesInPath)
++it;
}
+
+ return needsRestart;
}
-void QFseventsFileSystemWatcherEngine::rescanFiles(const QString &path)
+bool QFseventsFileSystemWatcherEngine::rescanFiles(const QString &path)
{
+ bool needsRestart = false;
+
for (FilesByPath::iterator i = watchedFiles.begin(); i != watchedFiles.end(); ) {
if (i.key().startsWith(path)) {
- rescanFiles(i.value());
+ needsRestart |= rescanFiles(i.value());
if (i.value().isEmpty()) {
i = watchedFiles.erase(i);
continue;
@@ -173,6 +187,8 @@ void QFseventsFileSystemWatcherEngine::rescanFiles(const QString &path)
++i;
}
+
+ return needsRestart;
}
void QFseventsFileSystemWatcherEngine::processEvent(ConstFSEventStreamRef streamRef,
@@ -184,11 +200,20 @@ void QFseventsFileSystemWatcherEngine::processEvent(ConstFSEventStreamRef stream
#if defined(Q_OS_OSX) && MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_6
Q_UNUSED(streamRef);
+ bool needsRestart = false;
+
QMutexLocker locker(&lock);
for (size_t i = 0; i < numEvents; ++i) {
FSEventStreamEventFlags eFlags = eventFlags[i];
DEBUG("Change %llu in %s, flags %x", eventIds[i], eventPaths[i], (unsigned int)eFlags);
+
+ if (eFlags & kFSEventStreamEventFlagEventIdsWrapped) {
+ DEBUG("\tthe event ids wrapped");
+ lastReceivedEvent = 0;
+ }
+ lastReceivedEvent = qMax(lastReceivedEvent, eventIds[i]);
+
QString path = QFile::decodeName(eventPaths[i]);
if (path.endsWith(QDir::separator()))
path = path.mid(0, path.size() - 1);
@@ -199,38 +224,36 @@ void QFseventsFileSystemWatcherEngine::processEvent(ConstFSEventStreamRef stream
DEBUG("\t\t... user dropped.");
if (eFlags & kFSEventStreamEventFlagKernelDropped)
DEBUG("\t\t... kernel dropped.");
- rescanDirs(path);
- rescanFiles(path);
+ needsRestart |= rescanDirs(path);
+ needsRestart |= rescanFiles(path);
continue;
}
- if (eFlags & kFSEventStreamEventFlagEventIdsWrapped) {
- DEBUG("\tthe event ids wrapped");
- // TODO: verify if we need to do something
- }
-
if (eFlags & kFSEventStreamEventFlagRootChanged) {
// re-check everything:
DirsByName::iterator dirIt = watchedDirectories.find(path);
if (dirIt != watchedDirectories.end())
- checkDir(dirIt);
- rescanFiles(path);
+ needsRestart |= checkDir(dirIt);
+ needsRestart |= rescanFiles(path);
continue;
}
if ((eFlags & kFSEventStreamEventFlagItemIsDir) && (eFlags & kFSEventStreamEventFlagItemRemoved))
- rescanDirs(path);
+ needsRestart |= rescanDirs(path);
// check watched directories:
DirsByName::iterator dirIt = watchedDirectories.find(path);
if (dirIt != watchedDirectories.end())
- checkDir(dirIt);
+ needsRestart |= checkDir(dirIt);
// check watched files:
FilesByPath::iterator pIt = watchedFiles.find(path);
if (pIt != watchedFiles.end())
- rescanFiles(pIt.value());
+ needsRestart |= rescanFiles(pIt.value());
}
+
+ if (needsRestart)
+ emit scheduleStreamRestart();
#else
// This is a work-around for moc: when we put the version check at the top of the header file,
// moc will still see the Q_OBJECT macro and generate a meta-object when compiling for 10.6,
@@ -248,14 +271,23 @@ void QFseventsFileSystemWatcherEngine::processEvent(ConstFSEventStreamRef stream
void QFseventsFileSystemWatcherEngine::doEmitFileChanged(const QString path, bool removed)
{
+ DEBUG() << "emitting fileChanged for" << path << "with removed =" << removed;
emit fileChanged(path, removed);
}
void QFseventsFileSystemWatcherEngine::doEmitDirectoryChanged(const QString path, bool removed)
{
+ DEBUG() << "emitting directoryChanged for" << path << "with removed =" << removed;
emit directoryChanged(path, removed);
}
+void QFseventsFileSystemWatcherEngine::restartStream()
+{
+ QMutexLocker locker(&lock);
+ stopStream();
+ startStream();
+}
+
QFseventsFileSystemWatcherEngine *QFseventsFileSystemWatcherEngine::create(QObject *parent)
{
return new QFseventsFileSystemWatcherEngine(parent);
@@ -264,6 +296,7 @@ QFseventsFileSystemWatcherEngine *QFseventsFileSystemWatcherEngine::create(QObje
QFseventsFileSystemWatcherEngine::QFseventsFileSystemWatcherEngine(QObject *parent)
: QFileSystemWatcherEngine(parent)
, stream(0)
+ , lastReceivedEvent(kFSEventStreamEventIdSinceNow)
{
// We cannot use signal-to-signal queued connections, because the
@@ -272,6 +305,8 @@ QFseventsFileSystemWatcherEngine::QFseventsFileSystemWatcherEngine(QObject *pare
this, SLOT(doEmitDirectoryChanged(const QString, bool)), Qt::QueuedConnection);
connect(this, SIGNAL(emitFileChanged(const QString, bool)),
this, SLOT(doEmitFileChanged(const QString, bool)), Qt::QueuedConnection);
+ connect(this, SIGNAL(scheduleStreamRestart()),
+ this, SLOT(restartStream()), Qt::QueuedConnection);
queue = dispatch_queue_create("org.qt-project.QFseventsFileSystemWatcherEngine", NULL);
}
@@ -284,7 +319,7 @@ QFseventsFileSystemWatcherEngine::~QFseventsFileSystemWatcherEngine()
// The assumption with the locking strategy is that this class cannot and will not be subclassed!
QMutexLocker locker(&lock);
- stopStream();
+ stopStream(true);
dispatch_release(queue);
}
@@ -292,12 +327,14 @@ QStringList QFseventsFileSystemWatcherEngine::addPaths(const QStringList &paths,
QStringList *files,
QStringList *directories)
{
- if (stream)
+ if (stream) {
+ DEBUG("Flushing, last id is %llu", FSEventStreamGetLatestEventId(stream));
FSEventStreamFlushSync(stream);
+ }
QMutexLocker locker(&lock);
- bool newWatchPathsFound = false;
+ bool needsRestart = false;
QStringList p = paths;
QMutableListIterator<QString> it(p);
@@ -343,8 +380,9 @@ QStringList QFseventsFileSystemWatcherEngine::addPaths(const QStringList &paths,
PathRefCounts::iterator it = watchedPaths.find(watchedPath);
if (it == watchedPaths.end()) {
- newWatchPathsFound = true;
+ needsRestart = true;
watchedPaths.insert(watchedPath, 1);
+ DEBUG("Adding '%s' to watchedPaths", qPrintable(watchedPath));
} else {
++it.value();
}
@@ -355,12 +393,14 @@ QStringList QFseventsFileSystemWatcherEngine::addPaths(const QStringList &paths,
dirInfo.dirInfo = info;
dirInfo.entries = scanForDirEntries(realPath);
watchedDirectories.insert(realPath, dirInfo);
+ DEBUG("-- Also adding '%s' to watchedDirectories", qPrintable(realPath));
} else {
watchedFiles[parentPath].insert(realPath, info);
+ DEBUG("-- Also adding '%s' to watchedFiles", qPrintable(realPath));
}
}
- if (newWatchPathsFound) {
+ if (needsRestart) {
stopStream();
if (!startStream())
p = paths;
@@ -375,6 +415,8 @@ QStringList QFseventsFileSystemWatcherEngine::removePaths(const QStringList &pat
{
QMutexLocker locker(&lock);
+ bool needsRestart = false;
+
QStringList p = paths;
QMutableListIterator<QString> it(p);
while (it.hasNext()) {
@@ -389,10 +431,11 @@ QStringList QFseventsFileSystemWatcherEngine::removePaths(const QStringList &pat
if (fi.isDir()) {
DirsByName::iterator dirIt = watchedDirectories.find(realPath);
if (dirIt != watchedDirectories.end()) {
- derefPath(dirIt->dirInfo.watchedPath);
+ needsRestart |= derefPath(dirIt->dirInfo.watchedPath);
watchedDirectories.erase(dirIt);
directories->removeAll(origPath);
it.remove();
+ DEBUG("Removed directory '%s'", qPrintable(realPath));
}
} else {
QFileInfo fi(realPath);
@@ -402,22 +445,32 @@ QStringList QFseventsFileSystemWatcherEngine::removePaths(const QStringList &pat
InfoByName &filesInDir = pIt.value();
InfoByName::iterator fIt = filesInDir.find(realPath);
if (fIt != filesInDir.end()) {
- derefPath(fIt->watchedPath);
+ needsRestart |= derefPath(fIt->watchedPath);
filesInDir.erase(fIt);
if (filesInDir.isEmpty())
watchedFiles.erase(pIt);
files->removeAll(origPath);
it.remove();
+ DEBUG("Removed file '%s'", qPrintable(realPath));
}
}
}
}
+ locker.unlock();
+
+ if (needsRestart)
+ restartStream();
+
return p;
}
bool QFseventsFileSystemWatcherEngine::startStream()
{
+ Q_ASSERT(stream == 0);
+ if (stream) // This shouldn't happen, but let's be nice and handle it.
+ stopStream();
+
if (watchedPaths.isEmpty())
return false;
@@ -437,11 +490,15 @@ bool QFseventsFileSystemWatcherEngine::startStream()
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.
+ if (lastReceivedEvent == kFSEventStreamEventIdSinceNow)
+ lastReceivedEvent = FSEventsGetCurrentEventId();
stream = FSEventStreamCreate(NULL,
&callBackFunction,
&callBackInfo,
reinterpret_cast<CFArrayRef>(pathsToWatch),
- kFSEventStreamEventIdSinceNow,
+ lastReceivedEvent,
latency,
flags);
@@ -453,10 +510,13 @@ bool QFseventsFileSystemWatcherEngine::startStream()
FSEventStreamSetDispatchQueue(stream, queue);
if (FSEventStreamStart(stream)) {
- DEBUG() << "Stream started successfully.";
+ DEBUG() << "Stream started successfully with sinceWhen =" << lastReceivedEvent;
return true;
} else {
DEBUG() << "Stream failed to start!";
+ FSEventStreamInvalidate(stream);
+ FSEventStreamRelease(stream);
+ stream = 0;
return false;
}
}
@@ -469,7 +529,7 @@ void QFseventsFileSystemWatcherEngine::stopStream(bool isStopped)
FSEventStreamInvalidate(stream);
FSEventStreamRelease(stream);
stream = 0;
- DEBUG() << "Stream stopped.";
+ DEBUG() << "Stream stopped. Last event ID:" << lastReceivedEvent;
}
}
@@ -490,16 +550,16 @@ QFseventsFileSystemWatcherEngine::InfoByName QFseventsFileSystemWatcherEngine::s
return entries;
}
-void QFseventsFileSystemWatcherEngine::derefPath(const QString &watchedPath)
+bool QFseventsFileSystemWatcherEngine::derefPath(const QString &watchedPath)
{
PathRefCounts::iterator it = watchedPaths.find(watchedPath);
- if (it == watchedPaths.end())
- return;
- if (--it.value() < 1) {
+ if (it != watchedPaths.end() && --it.value() < 1) {
watchedPaths.erase(it);
- stopStream();
- startStream();
+ DEBUG("Removing '%s' from watchedPaths.", qPrintable(watchedPath));
+ return true;
}
+
+ return false;
}
#endif //QT_NO_FILESYSTEMWATCHER
diff --git a/src/corelib/io/qfilesystemwatcher_fsevents_p.h b/src/corelib/io/qfilesystemwatcher_fsevents_p.h
index c899c556c8..2de2bf4f18 100644
--- a/src/corelib/io/qfilesystemwatcher_fsevents_p.h
+++ b/src/corelib/io/qfilesystemwatcher_fsevents_p.h
@@ -84,10 +84,12 @@ public:
Q_SIGNALS:
void emitFileChanged(const QString path, bool removed);
void emitDirectoryChanged(const QString path, bool removed);
+ void scheduleStreamRestart();
private slots:
void doEmitFileChanged(const QString path, bool removed);
void doEmitDirectoryChanged(const QString path, bool removed);
+ void restartStream();
private:
struct Info {
@@ -122,11 +124,11 @@ private:
bool startStream();
void stopStream(bool isStopped = false);
InfoByName scanForDirEntries(const QString &path);
- void derefPath(const QString &watchedPath);
- void checkDir(DirsByName::iterator &it);
- void rescanDirs(const QString &path);
- void rescanFiles(InfoByName &filesInPath);
- void rescanFiles(const QString &path);
+ bool derefPath(const QString &watchedPath);
+ bool checkDir(DirsByName::iterator &it);
+ bool rescanDirs(const QString &path);
+ bool rescanFiles(InfoByName &filesInPath);
+ bool rescanFiles(const QString &path);
QMutex lock;
dispatch_queue_t queue;
@@ -134,6 +136,7 @@ private:
FilesByPath watchedFiles;
DirsByName watchedDirectories;
PathRefCounts watchedPaths;
+ FSEventStreamEventId lastReceivedEvent;
};
QT_END_NAMESPACE
diff --git a/src/corelib/io/qsettings.cpp b/src/corelib/io/qsettings.cpp
index 0406aeb501..321525ca18 100644
--- a/src/corelib/io/qsettings.cpp
+++ b/src/corelib/io/qsettings.cpp
@@ -2496,6 +2496,12 @@ void QConfFileSettingsPrivate::ensureSectionParsed(QConfFile *confFile,
\snippet code/src_corelib_io_qsettings.cpp 7
+ \li On Mac OS X, permissions to access settings not belonging to the
+ current user (i.e. SystemScope) have changed with 10.7 (Lion). Prior to
+ that version, users having admin rights could access these. For 10.7 and
+ 10.8 (Mountain Lion), only root can. However, 10.9 (Mavericks) changes
+ that rule again but only for the native format (plist files).
+
\li On Unix and Mac OS X systems, the advisory file locking is disabled
if NFS (or AutoFS or CacheFS) is detected to work around a bug in the
NFS fcntl() implementation, which hangs forever if statd or lockd aren't
diff --git a/src/corelib/io/qsettings_mac.cpp b/src/corelib/io/qsettings_mac.cpp
index 23cff6af27..7d1fb1a7c5 100644
--- a/src/corelib/io/qsettings_mac.cpp
+++ b/src/corelib/io/qsettings_mac.cpp
@@ -405,7 +405,6 @@ QMacSettingsPrivate::QMacSettingsPrivate(QSettings::Scope scope, const QString &
}
// if no bundle identifier yet. use a hard coded string.
if (domainName.isEmpty()) {
- setStatus(QSettings::AccessError);
domainName = QLatin1String("unknown-organization.trolltech.com");
}
@@ -540,27 +539,30 @@ void QMacSettingsPrivate::sync()
// only report failures for the primary file (the one we write to)
if (!ok && i == 0 && hostNames[j] == hostName && status == QSettings::NoError) {
#if 1
- // work around what seems to be a bug in CFPreferences:
- // don't report an error if there are no preferences for the application
- QCFType<CFArrayRef> appIds = CFPreferencesCopyApplicationList(domains[i].userName,
- hostNames[j]);
-
- // iterate through all the applications and see if we're there
- CFIndex size = CFArrayGetCount(appIds);
- for (CFIndex k = 0; k < size; ++k) {
- const void *cfvalue = CFArrayGetValueAtIndex(appIds, k);
- if (CFGetTypeID(cfvalue) == CFStringGetTypeID()) {
- if (CFStringCompare(static_cast<CFStringRef>(cfvalue),
- domains[i].applicationOrSuiteId,
- kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
- setStatus(QSettings::AccessError);
- break;
+ if (QSysInfo::macVersion() < QSysInfo::MV_10_7) {
+ // work around what seems to be a bug in CFPreferences:
+ // don't report an error if there are no preferences for the application
+ QCFType<CFArrayRef> appIds = CFPreferencesCopyApplicationList(domains[i].userName,
+ hostNames[j]);
+
+ // iterate through all the applications and see if we're there
+ CFIndex size = CFArrayGetCount(appIds);
+ for (CFIndex k = 0; k < size; ++k) {
+ const void *cfvalue = CFArrayGetValueAtIndex(appIds, k);
+ if (CFGetTypeID(cfvalue) == CFStringGetTypeID()) {
+ if (CFStringCompare(static_cast<CFStringRef>(cfvalue),
+ domains[i].applicationOrSuiteId,
+ kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
+ setStatus(QSettings::AccessError);
+ break;
+ }
}
}
- }
-#else
- setStatus(QSettings::AccessError);
+ } else
#endif
+ {
+ setStatus(QSettings::AccessError);
+ }
}
}
}
diff --git a/src/corelib/io/qstandardpaths_win.cpp b/src/corelib/io/qstandardpaths_win.cpp
index a0344a0206..062ab49207 100644
--- a/src/corelib/io/qstandardpaths_win.cpp
+++ b/src/corelib/io/qstandardpaths_win.cpp
@@ -49,6 +49,10 @@
#include <qcoreapplication.h>
#endif
+#if !defined(Q_OS_WINCE)
+const GUID qCLSID_FOLDERID_Downloads = { 0x374de290, 0x123f, 0x4565, { 0x91, 0x64, 0x39, 0xc4, 0x92, 0x5e, 0x46, 0x7b } };
+#endif
+
#include <qt_windows.h>
#include <shlobj.h>
#if !defined(Q_OS_WINCE)
@@ -68,6 +72,10 @@
QT_BEGIN_NAMESPACE
+#if !defined(Q_OS_WINCE)
+typedef HRESULT (WINAPI *GetKnownFolderPath)(const GUID&, DWORD, HANDLE, LPWSTR*);
+#endif
+
static QString convertCharArray(const wchar_t *path)
{
return QDir::fromNativeSeparators(QString::fromWCharArray(path));
@@ -77,6 +85,10 @@ QString QStandardPaths::writableLocation(StandardLocation type)
{
QString result;
+#if !defined(Q_OS_WINCE)
+ static GetKnownFolderPath SHGetKnownFolderPath = (GetKnownFolderPath)QSystemLibrary::resolve(QLatin1String("shell32"), "SHGetKnownFolderPath");
+#endif
+
wchar_t path[MAX_PATH];
switch (type) {
@@ -107,7 +119,18 @@ QString QStandardPaths::writableLocation(StandardLocation type)
result = convertCharArray(path);
break;
- case DownloadLocation: // TODO implement with SHGetKnownFolderPath(FOLDERID_Downloads) (starting from Vista)
+ case DownloadLocation:
+#if !defined(Q_OS_WINCE)
+ if (SHGetKnownFolderPath) {
+ LPWSTR path;
+ if (SHGetKnownFolderPath(qCLSID_FOLDERID_Downloads, 0, 0, &path) == S_OK) {
+ result = convertCharArray(path);
+ CoTaskMemFree(path);
+ }
+ break;
+ }
+#endif
+ // fall through
case DocumentsLocation:
if (SHGetSpecialFolderPath(0, path, CSIDL_PERSONAL, FALSE))
result = convertCharArray(path);
diff --git a/src/corelib/kernel/qcoreevent.cpp b/src/corelib/kernel/qcoreevent.cpp
index ae2666f19b..5e588a9f1a 100644
--- a/src/corelib/kernel/qcoreevent.cpp
+++ b/src/corelib/kernel/qcoreevent.cpp
@@ -407,6 +407,9 @@ Q_GLOBAL_STATIC(QEventUserEventRegistration, userEventRegistrationHelper)
between QEvent::User and QEvent::MaxUser that has not yet been
registered. The \a hint is ignored if its value is not between
QEvent::User and QEvent::MaxUser.
+
+ Returns -1 if all available values are already taken or the
+ program is shutting down.
*/
int QEvent::registerEventType(int hint)
{
diff --git a/src/corelib/kernel/qeventdispatcher_winrt.cpp b/src/corelib/kernel/qeventdispatcher_winrt.cpp
index 56f4ac40de..1d4b57642c 100644
--- a/src/corelib/kernel/qeventdispatcher_winrt.cpp
+++ b/src/corelib/kernel/qeventdispatcher_winrt.cpp
@@ -45,6 +45,7 @@
#include <QtCore/QThread>
#include <QtCore/QHash>
#include <private/qabstracteventdispatcher_p.h>
+#include <private/qcoreapplication_p.h>
#include <wrl.h>
#include <windows.foundation.h>
@@ -109,6 +110,11 @@ QEventDispatcherWinRT::QEventDispatcherWinRT(QObject *parent)
: QAbstractEventDispatcher(*new QEventDispatcherWinRTPrivate, parent)
{
Q_D(QEventDispatcherWinRT);
+
+ // Only look up the event dispatcher in the main thread
+ if (QThread::currentThread() != QCoreApplicationPrivate::theMainThread)
+ return;
+
ComPtr<ICoreApplication> application;
HRESULT hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_ApplicationModel_Core_CoreApplication).Get(),
IID_PPV_ARGS(&application));
diff --git a/src/corelib/kernel/qmetatype.h b/src/corelib/kernel/qmetatype.h
index 7679258a98..0a52aaf680 100644
--- a/src/corelib/kernel/qmetatype.h
+++ b/src/corelib/kernel/qmetatype.h
@@ -939,10 +939,6 @@ public:
}
template<class T>
- static void advanceImpl(void **p, int step)
- { IteratorOwner<typename T::const_iterator>::advance(p, step); }
-
- template<class T>
static void moveToBeginImpl(const void *container, void **iterator)
{ IteratorOwner<typename T::const_iterator>::assign(iterator, static_cast<const T*>(container)->begin()); }
@@ -951,21 +947,9 @@ public:
{ IteratorOwner<typename T::const_iterator>::assign(iterator, static_cast<const T*>(container)->end()); }
template<class T>
- static void destroyIterImpl(void **iterator)
- { IteratorOwner<typename T::const_iterator>::destroy(iterator); }
-
- template<class T>
- static bool equalIterImpl(void * const *iterator, void * const *other)
- { return IteratorOwner<typename T::const_iterator>::equal(iterator, other); }
-
- template<class T>
static VariantData getImpl(void * const *iterator, int metaTypeId, uint flags)
{ return VariantData(metaTypeId, IteratorOwner<typename T::const_iterator>::getData(iterator), flags); }
- template<class T>
- static void copyIterImpl(void **dest, void * const * src)
- { IteratorOwner<typename T::const_iterator>::assign(dest, src); }
-
public:
template<class T> QSequentialIterableImpl(const T*p)
: _iterable(p)
@@ -977,11 +961,11 @@ public:
, _at(atImpl<T>)
, _moveToBegin(moveToBeginImpl<T>)
, _moveToEnd(moveToEndImpl<T>)
- , _advance(advanceImpl<T>)
+ , _advance(IteratorOwner<typename T::const_iterator>::advance)
, _get(getImpl<T>)
- , _destroyIter(destroyIterImpl<T>)
- , _equalIter(equalIterImpl<T>)
- , _copyIter(copyIterImpl<T>)
+ , _destroyIter(IteratorOwner<typename T::const_iterator>::destroy)
+ , _equalIter(IteratorOwner<typename T::const_iterator>::equal)
+ , _copyIter(IteratorOwner<typename T::const_iterator>::assign)
{
}
@@ -1134,18 +1118,6 @@ public:
static VariantData getValueImpl(void * const *iterator, int metaTypeId, uint flags)
{ return VariantData(metaTypeId, &AssociativeContainerAccessor<T>::getValue(*static_cast<typename T::const_iterator*>(*iterator)), flags); }
- template<class T>
- static void destroyIterImpl(void **iterator)
- { IteratorOwner<typename T::const_iterator>::destroy(iterator); }
-
- template<class T>
- static bool equalIterImpl(void * const *iterator, void * const *other)
- { return IteratorOwner<typename T::const_iterator>::equal(iterator, other); }
-
- template<class T>
- static void copyIterImpl(void **dest, void * const * src)
- { IteratorOwner<typename T::const_iterator>::assign(dest, src); }
-
public:
template<class T> QAssociativeIterableImpl(const T*p)
: _iterable(p)
@@ -1160,9 +1132,9 @@ public:
, _advance(advanceImpl<T>)
, _getKey(getKeyImpl<T>)
, _getValue(getValueImpl<T>)
- , _destroyIter(destroyIterImpl<T>)
- , _equalIter(equalIterImpl<T>)
- , _copyIter(copyIterImpl<T>)
+ , _destroyIter(IteratorOwner<typename T::const_iterator>::destroy)
+ , _equalIter(IteratorOwner<typename T::const_iterator>::equal)
+ , _copyIter(IteratorOwner<typename T::const_iterator>::assign)
{
}
diff --git a/src/corelib/kernel/qmimedata.cpp b/src/corelib/kernel/qmimedata.cpp
index 483692cdf8..5d2adb0561 100644
--- a/src/corelib/kernel/qmimedata.cpp
+++ b/src/corelib/kernel/qmimedata.cpp
@@ -299,7 +299,7 @@ QVariant QMimeDataPrivate::retrieveTypedData(const QString &format, QVariant::Ty
QMacPasteboardMime maps MIME to Mac flavors.
\sa QClipboard, QDragEnterEvent, QDragMoveEvent, QDropEvent, QDrag,
- QWindowsMime, QMacPasteboardMime, {Drag and Drop}
+ QMacPasteboardMime, {Drag and Drop}
*/
/*!
diff --git a/src/corelib/kernel/qobject.cpp b/src/corelib/kernel/qobject.cpp
index 262d259136..01bedb4a3a 100644
--- a/src/corelib/kernel/qobject.cpp
+++ b/src/corelib/kernel/qobject.cpp
@@ -551,7 +551,7 @@ void QMetaCallEvent::placeMetaCall(QObject *object)
QObject::signalsBlocked() state is transferred to this object.
The object's signals this signal blocker was blocking prior to
- being moved to, if any, are unblocked \em except in the case where
+ being moved to, if any, are unblocked \e except in the case where
both instances block the same object's signals and \c *this is
unblocked while \a other is not, at the time of the move.
*/
@@ -2731,9 +2731,7 @@ QMetaObject::Connection QObject::connect(const QObject *sender, const char *sign
Qt::ConnectionType type)
but it uses QMetaMethod to specify signal and method.
- \sa connect(const QObject *sender, const char *signal,
- const QObject *receiver, const char *method,
- Qt::ConnectionType type)
+ \sa connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
*/
QMetaObject::Connection QObject::connect(const QObject *sender, const QMetaMethod &signal,
const QObject *receiver, const QMetaMethod &method,
diff --git a/src/corelib/tools/qmargins.cpp b/src/corelib/tools/qmargins.cpp
index 03993f05a9..6f2c6c2c7c 100644
--- a/src/corelib/tools/qmargins.cpp
+++ b/src/corelib/tools/qmargins.cpp
@@ -334,6 +334,26 @@ QT_BEGIN_NAMESPACE
*/
/*!
+ \fn QMargins &QMargins::operator+=(int addend)
+ \overload
+
+ Adds the \a addend to each component of this object
+ and returns a reference to it.
+
+ \sa operator-=()
+*/
+
+/*!
+ \fn QMargins &QMargins::operator-=(int subtrahend)
+ \overload
+
+ Subtracts the \a subtrahend from each component of this object
+ and returns a reference to it.
+
+ \sa operator+=()
+*/
+
+/*!
\fn QMargins &QMargins::operator*=(int factor)
Multiplies each component of this object by \a factor
diff --git a/src/corelib/tools/qpoint.cpp b/src/corelib/tools/qpoint.cpp
index f154e4c612..090e8d0ff2 100644
--- a/src/corelib/tools/qpoint.cpp
+++ b/src/corelib/tools/qpoint.cpp
@@ -49,6 +49,7 @@ QT_BEGIN_NAMESPACE
\class QPoint
\inmodule QtCore
\ingroup painting
+ \reentrant
\brief The QPoint class defines a point in the plane using integer
precision.
@@ -470,6 +471,7 @@ QDebug operator<<(QDebug dbg, const QPointF &p)
\class QPointF
\inmodule QtCore
\ingroup painting
+ \reentrant
\brief The QPointF class defines a point in the plane using
floating point precision.
diff --git a/src/corelib/tools/qrect.cpp b/src/corelib/tools/qrect.cpp
index 35c7d1cd3c..04269e485b 100644
--- a/src/corelib/tools/qrect.cpp
+++ b/src/corelib/tools/qrect.cpp
@@ -52,6 +52,7 @@ QT_BEGIN_NAMESPACE
\class QRect
\inmodule QtCore
\ingroup painting
+ \reentrant
\brief The QRect class defines a rectangle in the plane using
integer precision.
@@ -1298,6 +1299,7 @@ QDebug operator<<(QDebug dbg, const QRect &r)
\class QRectF
\inmodule QtCore
\ingroup painting
+ \reentrant
\brief The QRectF class defines a rectangle in the plane using floating
point precision.
diff --git a/src/corelib/tools/qsimd_p.h b/src/corelib/tools/qsimd_p.h
index d293532f1d..f4ca971567 100644
--- a/src/corelib/tools/qsimd_p.h
+++ b/src/corelib/tools/qsimd_p.h
@@ -79,7 +79,7 @@
// SSE intrinsics
#if defined(__SSE2__) || (defined(QT_COMPILER_SUPPORTS_SSE2) && defined(Q_CC_MSVC))
-#if defined(QT_LINUXBASE)
+#if defined(QT_LINUXBASE) || defined(Q_OS_ANDROID_NO_SDK)
/// this is an evil hack - the posix_memalign declaration in LSB
/// is wrong - see http://bugs.linuxbase.org/show_bug.cgi?id=2431
# define posix_memalign _lsb_hack_posix_memalign
diff --git a/src/corelib/tools/qstring.cpp b/src/corelib/tools/qstring.cpp
index 7547ba8c19..01faad6f2d 100644
--- a/src/corelib/tools/qstring.cpp
+++ b/src/corelib/tools/qstring.cpp
@@ -78,6 +78,7 @@
#include "qchar.cpp"
#include "qstringmatcher.cpp"
#include "qstringiterator_p.h"
+#include "qthreadstorage.h"
#ifdef Q_OS_WIN
# include <qt_windows.h>
@@ -5319,6 +5320,10 @@ int QString::localeAwareCompare(const QString &other) const
return localeAwareCompare_helper(constData(), length(), other.constData(), other.length());
}
+#if defined(QT_USE_ICU)
+Q_GLOBAL_STATIC(QThreadStorage<QCollator>, defaultCollator)
+#endif
+
/*!
\internal
\since 4.5
@@ -5362,8 +5367,9 @@ int QString::localeAwareCompare_helper(const QChar *data1, int length1,
CFRelease(otherString);
return result;
#elif defined(QT_USE_ICU)
- QCollator collator;
- return collator.compare(data1, length1, data2, length2);
+ if (!defaultCollator()->hasLocalData())
+ defaultCollator()->setLocalData(QCollator());
+ return defaultCollator()->localData().compare(data1, length1, data2, length2);
#elif defined(Q_OS_UNIX)
// declared in <string.h>
int delta = strcoll(toLocal8Bit_helper(data1, length1).constData(), toLocal8Bit_helper(data2, length2).constData());
@@ -6168,7 +6174,7 @@ qulonglong QString::toIntegral_helper(const QChar *data, uint len, bool *ok, int
\snippet qstring/main.cpp 73
- \sa number(), toULong(), toInt(), QLocale::toLong()
+ \sa number(), toULong(), toInt(), QLocale::toInt()
*/
long QString::toLong(bool *ok, int base) const
@@ -6197,7 +6203,7 @@ long QString::toLong(bool *ok, int base) const
\snippet qstring/main.cpp 78
- \sa number(), QLocale::toULong()
+ \sa number(), QLocale::toUInt()
*/
ulong QString::toULong(bool *ok, int base) const
@@ -7562,6 +7568,8 @@ QString QString::multiArg(int numArgs, const QString **args) const
\since 5.2
Constructs a new QString containing a copy of the \a string CFString.
+
+ \note this function is only available on Mac OS X and iOS.
*/
/*! \fn CFStringRef QString::toCFString() const
@@ -7569,18 +7577,24 @@ QString QString::multiArg(int numArgs, const QString **args) const
Creates a CFString from a QString. The caller owns the CFString and is
responsible for releasing it.
+
+ \note this function is only available on Mac OS X and iOS.
*/
/*! \fn QString QString::fromNSString(const NSString *string)
\since 5.2
Constructs a new QString containing a copy of the \a string NSString.
+
+ \note this function is only available on Mac OS X and iOS.
*/
/*! \fn NSString QString::toNSString() const
\since 5.2
- Creates a NSString from a QString.g. The NSString is autoreleased.
+ Creates a NSString from a QString. The NSString is autoreleased.
+
+ \note this function is only available on Mac OS X and iOS.
*/
/*! \fn bool QString::isSimpleText() const
diff --git a/src/corelib/tools/qstring.h b/src/corelib/tools/qstring.h
index cf0726d831..2d9a42957e 100644
--- a/src/corelib/tools/qstring.h
+++ b/src/corelib/tools/qstring.h
@@ -711,7 +711,7 @@ public:
Q_DECL_CONSTEXPR inline QString(QStringDataPtr dd) : d(dd.ptr) {}
private:
-#if defined(QT_NO_CAST_FROM_ASCII) && !defined(Q_NO_DECLARED_NOT_DEFINED)
+#if defined(QT_NO_CAST_FROM_ASCII)
QString &operator+=(const char *s);
QString &operator+=(const QByteArray &s);
QString(const char *ch);
diff --git a/src/corelib/xml/qxmlstream.cpp b/src/corelib/xml/qxmlstream.cpp
index 5461139582..83d0c73ae1 100644
--- a/src/corelib/xml/qxmlstream.cpp
+++ b/src/corelib/xml/qxmlstream.cpp
@@ -349,11 +349,11 @@ QXmlStreamEntityResolver *QXmlStreamReader::entityResolver() const
\l{QNetworkAccessManager} {network access manager}, you would issue
a \l{QNetworkRequest} {network request} to the manager and receive a
\l{QNetworkReply} {network reply} in return. Since a QNetworkReply
- is a QIODevice, you connect its \l{QNetworkReply::readyRead()}
+ is a QIODevice, you connect its \l{QIODevice::readyRead()}
{readyRead()} signal to a custom slot, e.g. \c{slotReadyRead()} in
the code snippet shown in the discussion for QNetworkAccessManager.
In this slot, you read all available data with
- \l{QNetworkReply::readAll()} {readAll()} and pass it to the XML
+ \l{QIODevice::readAll()} {readAll()} and pass it to the XML
stream reader using addData(). Then you call your custom parsing
function that reads the XML events from the reader.
diff --git a/src/dbus/qdbusreply.cpp b/src/dbus/qdbusreply.cpp
index b1326c11f1..551891fdf2 100644
--- a/src/dbus/qdbusreply.cpp
+++ b/src/dbus/qdbusreply.cpp
@@ -155,7 +155,7 @@ QT_BEGIN_NAMESPACE
*/
/*!
- \fn QDBusReply::error()
+ \fn const QDBusError& QDBusReply::error() const
Returns the error code that was returned from the remote function call. If the remote call did
not return an error (i.e., if it succeeded), then the QDBusError object that is returned will
@@ -165,6 +165,11 @@ QT_BEGIN_NAMESPACE
*/
/*!
+ \fn const QDBusError& QDBusReply::error()
+ \overload
+*/
+
+/*!
\fn QDBusReply::value() const
Returns the remote function's calls return value. If the remote call returned with an error,
the return value of this function is undefined and may be undistinguishable from a valid return
diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp
index 48c262ae7a..3998bbf3ff 100644
--- a/src/gui/image/qimage.cpp
+++ b/src/gui/image/qimage.cpp
@@ -611,7 +611,7 @@ bool QImageData::checkForAlphaPixels() const
*/
/*!
- \fn QImage &operator=(QImage &&other)
+ \fn QImage &QImage::operator=(QImage &&other)
Move-assigns \a other to this QImage instance.
diff --git a/src/gui/image/qnativeimage.cpp b/src/gui/image/qnativeimage.cpp
index 09cdf41399..356bdc09e4 100644
--- a/src/gui/image/qnativeimage.cpp
+++ b/src/gui/image/qnativeimage.cpp
@@ -64,6 +64,8 @@ QNativeImage::~QNativeImage()
QImage::Format QNativeImage::systemFormat()
{
+ if (!QGuiApplication::primaryScreen())
+ return QImage::Format_Invalid;
return QGuiApplication::primaryScreen()->handle()->format();
}
diff --git a/src/gui/kernel/qdrag.cpp b/src/gui/kernel/qdrag.cpp
index 465c04cdc8..d7fd4d5bc0 100644
--- a/src/gui/kernel/qdrag.cpp
+++ b/src/gui/kernel/qdrag.cpp
@@ -101,7 +101,7 @@ QT_BEGIN_NAMESPACE
\l{QWidget::mouseMoveEvent()}{mouseMoveEvent()} to check whether a QDrag is
required.
- \sa {Drag and Drop}, QClipboard, QMimeData, QWindowsMime, QMacPasteboardMime,
+ \sa {Drag and Drop}, QClipboard, QMimeData, QMacPasteboardMime,
{Draggable Icons Example}, {Draggable Text Example}, {Drop Site Example},
{Fridge Magnets Example}
*/
diff --git a/src/gui/kernel/qevent.cpp b/src/gui/kernel/qevent.cpp
index 92d9871dc5..bb7000a266 100644
--- a/src/gui/kernel/qevent.cpp
+++ b/src/gui/kernel/qevent.cpp
@@ -628,7 +628,7 @@ QHoverEvent::~QHoverEvent()
\a modifiers holds the keyboard modifier flags at the time of the
event, and \a orient holds the wheel's orientation.
- \sa pos(), pixelDelta(), angleDelta(), state()
+ \sa pos(), pixelDelta(), angleDelta()
*/
#ifndef QT_NO_WHEELEVENT
QWheelEvent::QWheelEvent(const QPointF &pos, int delta,
@@ -659,7 +659,7 @@ QWheelEvent::~QWheelEvent()
\a orient holds the wheel's orientation.
- \sa pos(), pixelDelta(), angleDelta(), state()
+ \sa pos(), pixelDelta(), angleDelta()
*/
QWheelEvent::QWheelEvent(const QPointF &pos, const QPointF& globalPos, int delta,
Qt::MouseButtons buttons, Qt::KeyboardModifiers modifiers,
diff --git a/src/gui/kernel/qoffscreensurface.cpp b/src/gui/kernel/qoffscreensurface.cpp
index ce913a98af..1625909843 100644
--- a/src/gui/kernel/qoffscreensurface.cpp
+++ b/src/gui/kernel/qoffscreensurface.cpp
@@ -71,6 +71,14 @@ QT_BEGIN_NAMESPACE
How the offscreen surface is implemented depends on the underlying platform, but it will
typically use a pixel buffer (pbuffer). If the platform doesn't implement or support
offscreen surfaces, QOffscreenSurface will use an invisible QWindow internally.
+
+ \note In order to create an offscreen surface that is guaranteed to be compatible with
+ a given context and window, make sure to set the format to the context's or the
+ window's actual format, that is, the QSurfaceFormat returned from
+ QOpenGLContext::format() or QWindow::format() \e{after the context or window has been
+ created}. Passing the format returned from QWindow::requestedFormat() to setFormat()
+ may result in an incompatible offscreen surface since the underlying windowing system
+ interface may offer a different set of configurations for window and pbuffer surfaces.
*/
class Q_GUI_EXPORT QOffscreenSurfacePrivate : public QObjectPrivate
{
diff --git a/src/gui/kernel/qopenglcontext.cpp b/src/gui/kernel/qopenglcontext.cpp
index 5087e33b47..e258218e85 100644
--- a/src/gui/kernel/qopenglcontext.cpp
+++ b/src/gui/kernel/qopenglcontext.cpp
@@ -165,7 +165,7 @@ void QOpenGLVersionProfile::setVersion(int majorVersion, int minorVersion)
/*!
Returns the OpenGL profile. Only makes sense if profiles are supported by this version.
- \sa setProfile(), supportsProfiles()
+ \sa setProfile()
*/
QSurfaceFormat::OpenGLContextProfile QOpenGLVersionProfile::profile() const
{
@@ -176,7 +176,7 @@ QSurfaceFormat::OpenGLContextProfile QOpenGLVersionProfile::profile() const
Sets the OpenGL profile \a profile. Only makes sense if profiles are supported by
this version.
- \sa profile(), supportsProfiles()
+ \sa profile()
*/
void QOpenGLVersionProfile::setProfile(QSurfaceFormat::OpenGLContextProfile profile)
{
diff --git a/src/gui/kernel/qopenglcontext_p.h b/src/gui/kernel/qopenglcontext_p.h
index 07729e0e73..23c13b2e24 100644
--- a/src/gui/kernel/qopenglcontext_p.h
+++ b/src/gui/kernel/qopenglcontext_p.h
@@ -171,6 +171,7 @@ public:
template <typename T>
T *value(QOpenGLContext *context) {
QOpenGLContextGroup *group = context->shareGroup();
+ QMutexLocker locker(&group->d_func()->m_mutex);
T *resource = static_cast<T *>(group->d_func()->m_resources.value(this, 0));
if (!resource) {
resource = new T(context);
diff --git a/src/gui/kernel/qsessionmanager.cpp b/src/gui/kernel/qsessionmanager.cpp
index b9ef35854c..a428840ca8 100644
--- a/src/gui/kernel/qsessionmanager.cpp
+++ b/src/gui/kernel/qsessionmanager.cpp
@@ -201,7 +201,7 @@ QString QSessionManager::sessionKey() const
Here's an example of how an application's QGuiApplication::commitDataRequest()
might be implemented:
- \snippet code/src_gui_kernel_qguiapplication.cpp 8
+ \snippet code/src_gui_kernel_qguiapplication.cpp 1
If an error occurred within the application while saving its data, you may
want to try allowsErrorInteraction() instead.
@@ -293,7 +293,7 @@ QSessionManager::RestartHint QSessionManager::restartHint() const
If the session manager is capable of restoring sessions it will execute
\a command in order to restore the application. The command defaults to
- \snippet code/src_gui_kernel_qguiapplication.cpp 9
+ \snippet code/src_gui_kernel_qguiapplication.cpp 2
The \c -session option is mandatory; otherwise QGuiApplication cannot
tell whether it has been restored or what the current session identifier
@@ -321,7 +321,7 @@ void QSessionManager::setRestartCommand(const QStringList &command)
To iterate over the list, you can use the \l foreach pseudo-keyword:
- \snippet code/src_gui_kernel_qguiapplication.cpp 10
+ \snippet code/src_gui_kernel_qguiapplication.cpp 3
\sa setRestartCommand(), restartHint()
*/
@@ -347,7 +347,7 @@ void QSessionManager::setDiscardCommand(const QStringList &command)
To iterate over the list, you can use the \l foreach pseudo-keyword:
- \snippet code/src_gui_kernel_qguiapplication.cpp 11
+ \snippet code/src_gui_kernel_qguiapplication.cpp 4
\sa setDiscardCommand(), restartCommand(), setRestartCommand()
*/
diff --git a/src/gui/kernel/qsurfaceformat.cpp b/src/gui/kernel/qsurfaceformat.cpp
index 23c0e59779..2b8e611dff 100644
--- a/src/gui/kernel/qsurfaceformat.cpp
+++ b/src/gui/kernel/qsurfaceformat.cpp
@@ -387,7 +387,7 @@ void QSurfaceFormat::setOption(QSurfaceFormat::FormatOption option, bool on)
Returns true if the format option \a option is set; otherwise returns false.
- \sa options(), testOption()
+ \sa options()
*/
bool QSurfaceFormat::testOption(QSurfaceFormat::FormatOption option) const
{
diff --git a/src/gui/kernel/qwindow.cpp b/src/gui/kernel/qwindow.cpp
index fd9e0ad61b..13da58e391 100644
--- a/src/gui/kernel/qwindow.cpp
+++ b/src/gui/kernel/qwindow.cpp
@@ -159,10 +159,6 @@ QWindow::QWindow(QScreen *targetScreen)
d->screen = targetScreen;
if (!d->screen)
d->screen = QGuiApplication::primaryScreen();
-
- //if your applications aborts here, then chances are your creating a QWindow before the
- //screen list is populated.
- Q_ASSERT(d->screen);
d->init();
}
@@ -232,6 +228,13 @@ QWindow::~QWindow()
void QWindowPrivate::init()
{
Q_Q(QWindow);
+
+ // If your application aborts here, you are probably creating a QWindow
+ // before the screen list is populated.
+ if (!screen) {
+ qFatal("Cannot create window: no screens available");
+ exit(1);
+ }
QObject::connect(screen, SIGNAL(destroyed(QObject*)), q, SLOT(screenDestroyed(QObject*)));
QGuiApplicationPrivate::window_list.prepend(q);
}
diff --git a/src/gui/opengl/qopenglpaintdevice.cpp b/src/gui/opengl/qopenglpaintdevice.cpp
index fa392d16aa..6750458f83 100644
--- a/src/gui/opengl/qopenglpaintdevice.cpp
+++ b/src/gui/opengl/qopenglpaintdevice.cpp
@@ -81,7 +81,7 @@ QT_BEGIN_NAMESPACE
multisampling. Most hardware require significantly more memory to
do multisampling and the resulting quality is not on par with the
quality of the software paint engine. The OpenGL paint engine's
- strenght lies in its performance, not its visual rendering
+ strength lies in its performance, not its visual rendering
quality.
\section1 State Changes
diff --git a/src/gui/opengl/qopengltexture.cpp b/src/gui/opengl/qopengltexture.cpp
index 983496230d..078274eabd 100644
--- a/src/gui/opengl/qopengltexture.cpp
+++ b/src/gui/opengl/qopengltexture.cpp
@@ -2668,12 +2668,12 @@ void QOpenGLTexture::generateMipMaps()
}
/*!
- Generates mipmaps for this texture object from mipmap level \baseLevel. If you are
+ Generates mipmaps for this texture object from mipmap level \a baseLevel. If you are
using a texture target and filtering option that requires mipmaps and you
have disabled automatic mipmap generation then you need to call this function
or the overload to create the mipmap chain.
- The generation of mipmaps to above \baseLevel is achieved by setting the mipmap
+ The generation of mipmaps to above \a baseLevel is achieved by setting the mipmap
base level to \a baseLevel and then generating the mipmap chain. If \a resetBaseLevel
is \c true, then the baseLevel of the texture will be reset to its previous value.
@@ -3000,7 +3000,7 @@ void QOpenGLTexture::setBorderColor(QColor color)
}
/*!
- Sets the color red to \a {r}, green to \a {g}, blue to \{b}, and \a {a} to the
+ Sets the color red to \a {r}, green to \a {g}, blue to \a {b}, and \a {a} to the
alpha value.
\overload
*/
@@ -3033,8 +3033,8 @@ void QOpenGLTexture::setBorderColor(float r, float g, float b, float a)
}
/*!
- Sets the color red to \a {r}, green to \a {g}, blue to \a {b}, and \a the alpha
- value to {a}.
+ Sets the color red to \a {r}, green to \a {g}, blue to \a {b}, and the alpha
+ value to \a {a}.
\overload
*/
void QOpenGLTexture::setBorderColor(int r, int g, int b, int a)
@@ -3068,8 +3068,8 @@ void QOpenGLTexture::setBorderColor(int r, int g, int b, int a)
}
/*!
- Sets the color red to \a {r}, green to \a {g}, blue to \a {b}, and \a the alpha
- value to {a}.
+ Sets the color red to \a {r}, green to \a {g}, blue to \a {b}, and the alpha
+ value to \a {a}.
\overload
*/
void QOpenGLTexture::setBorderColor(uint r, uint g, uint b, uint a)
diff --git a/src/gui/opengl/qopenglvertexarrayobject.cpp b/src/gui/opengl/qopenglvertexarrayobject.cpp
index b1fd4ffdfe..22ca35a8c3 100644
--- a/src/gui/opengl/qopenglvertexarrayobject.cpp
+++ b/src/gui/opengl/qopenglvertexarrayobject.cpp
@@ -149,8 +149,6 @@ bool QOpenGLVertexArrayObjectPrivate::create()
}
Q_Q(QOpenGLVertexArrayObject);
- if (context)
- QObject::disconnect(context, SIGNAL(aboutToBeDestroyed()), q, SLOT(_q_contextAboutToBeDestroyed()));
QOpenGLContext *ctx = QOpenGLContext::currentContext();
if (!ctx) {
@@ -202,6 +200,8 @@ void QOpenGLVertexArrayObjectPrivate::destroy()
if (!vao)
return;
+ Q_Q(QOpenGLVertexArrayObject);
+
switch (vaoFuncsType) {
#ifndef QT_OPENGL_ES_2
case Core_3_2:
@@ -220,6 +220,10 @@ void QOpenGLVertexArrayObjectPrivate::destroy()
break;
}
+ Q_ASSERT(context);
+ QObject::disconnect(context, SIGNAL(aboutToBeDestroyed()), q, SLOT(_q_contextAboutToBeDestroyed()));
+ context = 0;
+
vao = 0;
}
diff --git a/src/gui/painting/qblendfunctions.cpp b/src/gui/painting/qblendfunctions.cpp
index 23eaa9a3e7..f22c37aecc 100644
--- a/src/gui/painting/qblendfunctions.cpp
+++ b/src/gui/painting/qblendfunctions.cpp
@@ -129,7 +129,7 @@ struct Blend_ARGB32_on_RGB16_SourceAndConstAlpha {
};
void qt_scale_image_rgb16_on_rgb16(uchar *destPixels, int dbpl,
- const uchar *srcPixels, int sbpl,
+ const uchar *srcPixels, int sbpl, int srch,
const QRectF &targetRect,
const QRectF &sourceRect,
const QRect &clip,
@@ -144,17 +144,17 @@ void qt_scale_image_rgb16_on_rgb16(uchar *destPixels, int dbpl,
#endif
if (const_alpha == 256) {
Blend_RGB16_on_RGB16_NoAlpha noAlpha;
- qt_scale_image_16bit<quint16>(destPixels, dbpl, srcPixels, sbpl,
+ qt_scale_image_16bit<quint16>(destPixels, dbpl, srcPixels, sbpl, srch,
targetRect, sourceRect, clip, noAlpha);
} else {
Blend_RGB16_on_RGB16_ConstAlpha constAlpha(const_alpha);
- qt_scale_image_16bit<quint16>(destPixels, dbpl, srcPixels, sbpl,
+ qt_scale_image_16bit<quint16>(destPixels, dbpl, srcPixels, sbpl, srch,
targetRect, sourceRect, clip, constAlpha);
}
}
void qt_scale_image_argb32_on_rgb16(uchar *destPixels, int dbpl,
- const uchar *srcPixels, int sbpl,
+ const uchar *srcPixels, int sbpl, int srch,
const QRectF &targetRect,
const QRectF &sourceRect,
const QRect &clip,
@@ -169,11 +169,11 @@ void qt_scale_image_argb32_on_rgb16(uchar *destPixels, int dbpl,
#endif
if (const_alpha == 256) {
Blend_ARGB32_on_RGB16_SourceAlpha noAlpha;
- qt_scale_image_16bit<quint32>(destPixels, dbpl, srcPixels, sbpl,
+ qt_scale_image_16bit<quint32>(destPixels, dbpl, srcPixels, sbpl, srch,
targetRect, sourceRect, clip, noAlpha);
} else {
Blend_ARGB32_on_RGB16_SourceAndConstAlpha constAlpha(const_alpha);
- qt_scale_image_16bit<quint32>(destPixels, dbpl, srcPixels, sbpl,
+ qt_scale_image_16bit<quint32>(destPixels, dbpl, srcPixels, sbpl, srch,
targetRect, sourceRect, clip, constAlpha);
}
}
@@ -453,7 +453,7 @@ struct Blend_ARGB32_on_ARGB32_SourceAndConstAlpha {
};
void qt_scale_image_rgb32_on_rgb32(uchar *destPixels, int dbpl,
- const uchar *srcPixels, int sbpl,
+ const uchar *srcPixels, int sbpl, int srch,
const QRectF &targetRect,
const QRectF &sourceRect,
const QRect &clip,
@@ -468,17 +468,17 @@ void qt_scale_image_rgb32_on_rgb32(uchar *destPixels, int dbpl,
#endif
if (const_alpha == 256) {
Blend_RGB32_on_RGB32_NoAlpha noAlpha;
- qt_scale_image_32bit(destPixels, dbpl, srcPixels, sbpl,
+ qt_scale_image_32bit(destPixels, dbpl, srcPixels, sbpl, srch,
targetRect, sourceRect, clip, noAlpha);
} else {
Blend_RGB32_on_RGB32_ConstAlpha constAlpha(const_alpha);
- qt_scale_image_32bit(destPixels, dbpl, srcPixels, sbpl,
+ qt_scale_image_32bit(destPixels, dbpl, srcPixels, sbpl, srch,
targetRect, sourceRect, clip, constAlpha);
}
}
void qt_scale_image_argb32_on_argb32(uchar *destPixels, int dbpl,
- const uchar *srcPixels, int sbpl,
+ const uchar *srcPixels, int sbpl, int srch,
const QRectF &targetRect,
const QRectF &sourceRect,
const QRect &clip,
@@ -493,11 +493,11 @@ void qt_scale_image_argb32_on_argb32(uchar *destPixels, int dbpl,
#endif
if (const_alpha == 256) {
Blend_ARGB32_on_ARGB32_SourceAlpha sourceAlpha;
- qt_scale_image_32bit(destPixels, dbpl, srcPixels, sbpl,
+ qt_scale_image_32bit(destPixels, dbpl, srcPixels, sbpl, srch,
targetRect, sourceRect, clip, sourceAlpha);
} else {
Blend_ARGB32_on_ARGB32_SourceAndConstAlpha constAlpha(const_alpha);
- qt_scale_image_32bit(destPixels, dbpl, srcPixels, sbpl,
+ qt_scale_image_32bit(destPixels, dbpl, srcPixels, sbpl, srch,
targetRect, sourceRect, clip, constAlpha);
}
}
diff --git a/src/gui/painting/qblendfunctions_p.h b/src/gui/painting/qblendfunctions_p.h
index 97b89c8313..98e9e10bd8 100644
--- a/src/gui/painting/qblendfunctions_p.h
+++ b/src/gui/painting/qblendfunctions_p.h
@@ -60,7 +60,7 @@ QT_BEGIN_NAMESPACE
template <typename SRC, typename T>
void qt_scale_image_16bit(uchar *destPixels, int dbpl,
- const uchar *srcPixels, int sbpl,
+ const uchar *srcPixels, int sbpl, int srch,
const QRectF &targetRect,
const QRectF &srcRect,
const QRect &clip,
@@ -136,6 +136,15 @@ void qt_scale_image_16bit(uchar *destPixels, int dbpl,
quint16 *dst = ((quint16 *) (destPixels + ty1 * dbpl)) + tx1;
+ // this bounds check here is required as floating point rounding above might in some cases lead to
+ // w/h values that are one pixel too large, falling outside of the valid image area.
+ int yend = (srcy + iy * (h - 1)) >> 16;
+ if (yend < 0 || yend >= srch)
+ --h;
+ int xend = (basex + ix * (w - 1)) >> 16;
+ if (xend < 0 || xend >= (int)(sbpl/sizeof(quint32)))
+ --w;
+
while (h--) {
const SRC *src = (const SRC *) (srcPixels + (srcy >> 16) * sbpl);
int srcx = basex;
@@ -161,7 +170,7 @@ void qt_scale_image_16bit(uchar *destPixels, int dbpl,
}
template <typename T> void qt_scale_image_32bit(uchar *destPixels, int dbpl,
- const uchar *srcPixels, int sbpl,
+ const uchar *srcPixels, int sbpl, int srch,
const QRectF &targetRect,
const QRectF &srcRect,
const QRect &clip,
@@ -215,6 +224,8 @@ template <typename T> void qt_scale_image_32bit(uchar *destPixels, int dbpl,
int h = ty2 - ty1;
int w = tx2 - tx1;
+ if (!w || !h)
+ return;
quint32 basex;
quint32 srcy;
@@ -236,6 +247,15 @@ template <typename T> void qt_scale_image_32bit(uchar *destPixels, int dbpl,
quint32 *dst = ((quint32 *) (destPixels + ty1 * dbpl)) + tx1;
+ // this bounds check here is required as floating point rounding above might in some cases lead to
+ // w/h values that are one pixel too large, falling outside of the valid image area.
+ int yend = (srcy + iy * (h - 1)) >> 16;
+ if (yend < 0 || yend >= srch)
+ --h;
+ int xend = (basex + ix * (w - 1)) >> 16;
+ if (xend < 0 || xend >= (int)(sbpl/sizeof(quint32)))
+ --w;
+
while (h--) {
const uint *src = (const quint32 *) (srcPixels + (srcy >> 16) * sbpl);
int srcx = basex;
diff --git a/src/gui/painting/qdrawhelper.cpp b/src/gui/painting/qdrawhelper.cpp
index c7472cca29..7a5c5dc660 100644
--- a/src/gui/painting/qdrawhelper.cpp
+++ b/src/gui/painting/qdrawhelper.cpp
@@ -6522,7 +6522,7 @@ void qInitDrawhelperAsm()
qDrawHelper[QImage::Format_RGBA8888_Premultiplied].bitmapBlit = qt_bitmapblit8888_sse2;
extern void qt_scale_image_argb32_on_argb32_sse2(uchar *destPixels, int dbpl,
- const uchar *srcPixels, int sbpl,
+ const uchar *srcPixels, int sbpl, int srch,
const QRectF &targetRect,
const QRectF &sourceRect,
const QRect &clip,
diff --git a/src/gui/painting/qdrawhelper_neon.cpp b/src/gui/painting/qdrawhelper_neon.cpp
index a40166d5be..3ac92122bb 100644
--- a/src/gui/painting/qdrawhelper_neon.cpp
+++ b/src/gui/painting/qdrawhelper_neon.cpp
@@ -539,7 +539,7 @@ Blend_on_RGB16_SourceAndConstAlpha_Neon_create(BlendFunc blender, int const_alph
}
void qt_scale_image_argb32_on_rgb16_neon(uchar *destPixels, int dbpl,
- const uchar *srcPixels, int sbpl,
+ const uchar *srcPixels, int sbpl, int srch,
const QRectF &targetRect,
const QRectF &sourceRect,
const QRect &clip,
@@ -548,19 +548,19 @@ void qt_scale_image_argb32_on_rgb16_neon(uchar *destPixels, int dbpl,
if (const_alpha == 0)
return;
- qt_scale_image_16bit<quint32>(destPixels, dbpl, srcPixels, sbpl, targetRect, sourceRect, clip,
+ qt_scale_image_16bit<quint32>(destPixels, dbpl, srcPixels, sbpl, srch, targetRect, sourceRect, clip,
Blend_on_RGB16_SourceAndConstAlpha_Neon_create<quint32>(blend_8_pixels_argb32_on_rgb16_neon, const_alpha));
}
void qt_scale_image_rgb16_on_rgb16(uchar *destPixels, int dbpl,
- const uchar *srcPixels, int sbpl,
+ const uchar *srcPixels, int sbpl, int srch,
const QRectF &targetRect,
const QRectF &sourceRect,
const QRect &clip,
int const_alpha);
void qt_scale_image_rgb16_on_rgb16_neon(uchar *destPixels, int dbpl,
- const uchar *srcPixels, int sbpl,
+ const uchar *srcPixels, int sbpl, int srch,
const QRectF &targetRect,
const QRectF &sourceRect,
const QRect &clip,
@@ -570,11 +570,11 @@ void qt_scale_image_rgb16_on_rgb16_neon(uchar *destPixels, int dbpl,
return;
if (const_alpha == 256) {
- qt_scale_image_rgb16_on_rgb16(destPixels, dbpl, srcPixels, sbpl, targetRect, sourceRect, clip, const_alpha);
+ qt_scale_image_rgb16_on_rgb16(destPixels, dbpl, srcPixels, sbpl, srch, targetRect, sourceRect, clip, const_alpha);
return;
}
- qt_scale_image_16bit<quint16>(destPixels, dbpl, srcPixels, sbpl, targetRect, sourceRect, clip,
+ qt_scale_image_16bit<quint16>(destPixels, dbpl, srcPixels, sbpl, srch, targetRect, sourceRect, clip,
Blend_on_RGB16_SourceAndConstAlpha_Neon_create<quint16>(blend_8_pixels_rgb16_on_rgb16_neon, const_alpha));
}
diff --git a/src/gui/painting/qdrawhelper_p.h b/src/gui/painting/qdrawhelper_p.h
index bbeb73f0af..1c05fc305a 100644
--- a/src/gui/painting/qdrawhelper_p.h
+++ b/src/gui/painting/qdrawhelper_p.h
@@ -138,7 +138,7 @@ typedef void (*SrcOverBlendFunc)(uchar *destPixels, int dbpl,
int const_alpha);
typedef void (*SrcOverScaleFunc)(uchar *destPixels, int dbpl,
- const uchar *src, int spbl,
+ const uchar *src, int spbl, int srch,
const QRectF &targetRect,
const QRectF &sourceRect,
const QRect &clipRect,
diff --git a/src/gui/painting/qdrawhelper_sse2.cpp b/src/gui/painting/qdrawhelper_sse2.cpp
index c37858d679..d02871c86d 100644
--- a/src/gui/painting/qdrawhelper_sse2.cpp
+++ b/src/gui/painting/qdrawhelper_sse2.cpp
@@ -568,7 +568,7 @@ const uint * QT_FASTCALL qt_fetch_radial_gradient_sse2(uint *buffer, const Opera
}
void qt_scale_image_argb32_on_argb32_sse2(uchar *destPixels, int dbpl,
- const uchar *srcPixels, int sbpl,
+ const uchar *srcPixels, int sbpl, int srch,
const QRectF &targetRect,
const QRectF &sourceRect,
const QRect &clip,
@@ -577,12 +577,12 @@ void qt_scale_image_argb32_on_argb32_sse2(uchar *destPixels, int dbpl,
if (const_alpha != 256) {
// from qblendfunctions.cpp
extern void qt_scale_image_argb32_on_argb32(uchar *destPixels, int dbpl,
- const uchar *srcPixels, int sbpl,
+ const uchar *srcPixels, int sbpl, int srch,
const QRectF &targetRect,
const QRectF &sourceRect,
const QRect &clip,
int const_alpha);
- return qt_scale_image_argb32_on_argb32(destPixels, dbpl, srcPixels, sbpl, targetRect, sourceRect, clip, const_alpha);
+ return qt_scale_image_argb32_on_argb32(destPixels, dbpl, srcPixels, sbpl, srch, targetRect, sourceRect, clip, const_alpha);
}
qreal sx = targetRect.width() / (qreal) sourceRect.width();
@@ -651,6 +651,14 @@ void qt_scale_image_argb32_on_argb32_sse2(uchar *destPixels, int dbpl,
const __m128i alphaMask = _mm_set1_epi32(0xff000000);
const __m128i ixVector = _mm_set1_epi32(4*ix);
+ // this bounds check here is required as floating point rounding above might in some cases lead to
+ // w/h values that are one pixel too large, falling outside of the valid image area.
+ int yend = (srcy + iy * (h - 1)) >> 16;
+ if (yend < 0 || yend >= srch)
+ --h;
+ int xend = (basex + ix * (w - 1)) >> 16;
+ if (xend < 0 || xend >= (int)(sbpl/sizeof(quint32)))
+ --w;
while (h--) {
const uint *src = (const quint32 *) (srcPixels + (srcy >> 16) * sbpl);
diff --git a/src/gui/painting/qpaintengine_raster.cpp b/src/gui/painting/qpaintengine_raster.cpp
index 67896f786d..bfcb24ae3a 100644
--- a/src/gui/painting/qpaintengine_raster.cpp
+++ b/src/gui/painting/qpaintengine_raster.cpp
@@ -2377,7 +2377,7 @@ void QRasterPaintEngine::drawImage(const QRectF &r, const QImage &img, const QRe
SrcOverScaleFunc func = qScaleFunctions[d->rasterBuffer->format][img.format()];
if (func && (!clip || clip->hasRectClip)) {
func(d->rasterBuffer->buffer(), d->rasterBuffer->bytesPerLine(),
- img.bits(), img.bytesPerLine(),
+ img.bits(), img.bytesPerLine(), img.height(),
qt_mapRect_non_normalizing(r, s->matrix), sr,
!clip ? d->deviceRect : clip->clipRect,
s->intOpacity);
diff --git a/src/gui/painting/qpdf.cpp b/src/gui/painting/qpdf.cpp
index 56cfc0f707..bda5df3d13 100644
--- a/src/gui/painting/qpdf.cpp
+++ b/src/gui/painting/qpdf.cpp
@@ -1059,7 +1059,7 @@ void QPdfEngine::drawPath (const QPainterPath &p)
if (!d->hasPen && !d->hasBrush)
return;
- if (d->simplePen) {
+ if (d->simplePen && d->opacity == 1.0) {
// draw strokes natively in this case for better output
*d->currentPage << QPdf::generatePath(p, QTransform(), d->hasBrush ? QPdf::FillAndStrokePath : QPdf::StrokePath);
} else {
diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp
index 0fffa608a4..1797905e93 100644
--- a/src/gui/text/qfont.cpp
+++ b/src/gui/text/qfont.cpp
@@ -546,6 +546,7 @@ QFontEngineData::~QFontEngineData()
/*!
\fn QString QFont::rawName() const
+ \deprecated
Returns the name of the font within the underlying window system.
@@ -559,6 +560,7 @@ QFontEngineData::~QFontEngineData()
/*!
\fn void QFont::setRawName(const QString &name)
+ \deprecated
Sets a font by its system specific name.
@@ -1106,7 +1108,7 @@ int QFont::weight() const
Qt uses a weighting scale from 0 to 99 similar to, but not the
same as, the scales used in Windows or CSS. A weight of 0 is
- ultralight, whilst 99 will be an extremely black.
+ ultralight, whilst 99 will be extremely black.
This enum contains the predefined font weights:
@@ -1282,7 +1284,7 @@ bool QFont::kerning() const
When kerning is enabled, glyph metrics do not add up anymore,
even for Latin text. In other words, the assumption that
width('a') + width('b') is equal to width("ab") is not
- neccesairly true.
+ necessarily true.
\sa kerning(), QFontMetrics
*/
@@ -2420,7 +2422,7 @@ QString QFontInfo::family() const
\since 4.8
Returns the style name of the matched window system font on
- system that supports it.
+ systems that support it.
\sa QFont::styleName()
*/
diff --git a/src/gui/text/qfont.h b/src/gui/text/qfont.h
index a207a1d60e..7fbaf24861 100644
--- a/src/gui/text/qfont.h
+++ b/src/gui/text/qfont.h
@@ -242,9 +242,11 @@ public:
{ qSwap(d, other.d); qSwap(resolve_mask, other.resolve_mask); return *this; }
#endif
+#if QT_DEPRECATED_SINCE(5, 3)
// needed for X11
- void setRawName(const QString &);
- QString rawName() const;
+ QT_DEPRECATED void setRawName(const QString &);
+ QT_DEPRECATED QString rawName() const;
+#endif
QString key() const;
diff --git a/src/gui/text/qfont_p.h b/src/gui/text/qfont_p.h
index da24c6cb67..be0402b95a 100644
--- a/src/gui/text/qfont_p.h
+++ b/src/gui/text/qfont_p.h
@@ -251,7 +251,7 @@ public:
return script == other.script
&& screen == other.screen
&& multi == other.multi
- && (!multi || def.fallBackFamilies.size() == other.def.fallBackFamilies.size())
+ && (!multi || def.fallBackFamilies == other.def.fallBackFamilies)
&& def == other.def;
}
};
diff --git a/src/gui/text/qfontdatabase.cpp b/src/gui/text/qfontdatabase.cpp
index ae7b6c1c0d..558258c30e 100644
--- a/src/gui/text/qfontdatabase.cpp
+++ b/src/gui/text/qfontdatabase.cpp
@@ -531,7 +531,7 @@ static const int scriptForWritingSystem[] = {
Q_STATIC_ASSERT(sizeof(scriptForWritingSystem) / sizeof(scriptForWritingSystem[0]) == QFontDatabase::WritingSystemsCount);
-int qt_script_for_writing_system(QFontDatabase::WritingSystem writingSystem)
+Q_GUI_EXPORT int qt_script_for_writing_system(QFontDatabase::WritingSystem writingSystem)
{
return scriptForWritingSystem[writingSystem];
}
diff --git a/src/gui/text/qharfbuzzng.cpp b/src/gui/text/qharfbuzzng.cpp
index 1258ea9a78..b0bade83ee 100644
--- a/src/gui/text/qharfbuzzng.cpp
+++ b/src/gui/text/qharfbuzzng.cpp
@@ -264,16 +264,12 @@ _hb_qt_unicode_compose(hb_unicode_funcs_t * /*ufuncs*/,
// ### optimize
QString s = QString::fromUcs4(&a, 1) + QString::fromUcs4(&b, 1);
QString normalized = s.normalized(QString::NormalizationForm_C);
- if (normalized.isEmpty())
- return false;
- QVector<uint> ucs4str = normalized.toUcs4();
- if (ucs4str.size() == 1) {
- *ab = ucs4str.at(0);
- return true;
- }
+ QStringIterator it(normalized);
+ Q_ASSERT(it.hasNext()); // size>0
+ *ab = it.next();
- return false;
+ return !it.hasNext(); // size==1
}
static hb_bool_t
@@ -287,29 +283,28 @@ _hb_qt_unicode_decompose(hb_unicode_funcs_t * /*ufuncs*/,
return false;
QString normalized = QChar::decomposition(ab);
- Q_ASSERT(!normalized.isEmpty());
+ if (normalized.isEmpty())
+ return false;
- const QVector<uint> ucs4str = normalized.toUcs4();
- Q_ASSERT(ucs4str.size() <= HB_UNICODE_MAX_DECOMPOSITION_LEN);
+ QStringIterator it(normalized);
+ Q_ASSERT(it.hasNext()); // size>0
+ *a = it.next();
- if (ucs4str.size() == 1) {
- *a = ucs4str.at(0);
+ if (!it.hasNext()) { // size==1
*b = 0;
return *a != ab;
}
- if (ucs4str.size() == 2) {
- *a = ucs4str.at(0);
- *b = ucs4str.at(1);
-
+ // size>1
+ *b = it.next();
+ if (!it.hasNext()) { // size==2
// Here's the ugly part: if ab decomposes to a single character and
// that character decomposes again, we have to detect that and undo
// the second part :-(
- QString recomposed = normalized.normalized(QString::NormalizationForm_C);
- if (recomposed.isEmpty() || recomposed == normalized)
- return false;
-
- hb_codepoint_t c = recomposed.toUcs4().at(0);
+ const QString recomposed = normalized.normalized(QString::NormalizationForm_C);
+ QStringIterator jt(recomposed);
+ Q_ASSERT(jt.hasNext()); // size>0
+ const hb_codepoint_t c = jt.next();
if (c != *a && c != ab) {
*a = c;
*b = 0;
@@ -317,17 +312,18 @@ _hb_qt_unicode_decompose(hb_unicode_funcs_t * /*ufuncs*/,
return true;
}
+ // size>2
// If decomposed to more than two characters, take the last one,
// and recompose the rest to get the first component
- *b = ucs4str.last();
- normalized.chop(1);
- QString recomposed = normalized.normalized(QString::NormalizationForm_C);
- if (recomposed.isEmpty() || recomposed == normalized)
- return false;
-
+ do {
+ *b = it.next();
+ } while (it.hasNext());
+ normalized.chop(QChar::requiresSurrogates(*b) ? 2 : 1);
+ const QString recomposed = normalized.normalized(QString::NormalizationForm_C);
+ QStringIterator jt(recomposed);
+ Q_ASSERT(jt.hasNext()); // size>0
// We expect that recomposed has exactly one character now
- *a = recomposed.toUcs4().at(0);
-
+ *a = jt.next();
return true;
}
@@ -337,9 +333,6 @@ _hb_qt_unicode_decompose_compatibility(hb_unicode_funcs_t * /*ufuncs*/,
hb_codepoint_t *decomposed,
void * /*user_data*/)
{
- if (QChar::decompositionTag(u) == QChar::NoDecomposition) // !NFKD
- return 0;
-
const QString normalized = QChar::decomposition(u);
uint outlen = 0;
diff --git a/src/gui/text/qrawfont.cpp b/src/gui/text/qrawfont.cpp
index 2ba350fb67..f789ec596b 100644
--- a/src/gui/text/qrawfont.cpp
+++ b/src/gui/text/qrawfont.cpp
@@ -700,10 +700,7 @@ QRawFont QRawFont::fromFont(const QFont &font, QFontDatabase::WritingSystem writ
if (fe != 0 && fe->type() == QFontEngine::Multi) {
QFontEngineMulti *multiEngine = static_cast<QFontEngineMulti *>(fe);
fe = multiEngine->engine(0);
- if (fe == 0) {
- multiEngine->loadEngine(0);
- fe = multiEngine->engine(0);
- }
+ Q_ASSERT(fe);
}
if (fe != 0) {
diff --git a/src/opengl/doc/src/qtopengl-index.qdoc b/src/opengl/doc/src/qtopengl-index.qdoc
index fc131c4b17..ff946c6e4e 100644
--- a/src/opengl/doc/src/qtopengl-index.qdoc
+++ b/src/opengl/doc/src/qtopengl-index.qdoc
@@ -68,5 +68,5 @@
non-OpenGL-specific GUI functionality.
The \l{Qt OpenGL C++ Classes} page gives an overview over the available classes
- int this module.
+ in this module.
*/
diff --git a/src/opengl/qgl.cpp b/src/opengl/qgl.cpp
index de1de476b8..e602a05af9 100644
--- a/src/opengl/qgl.cpp
+++ b/src/opengl/qgl.cpp
@@ -3227,43 +3227,6 @@ void QGLContext::moveToThread(QThread *thread)
visual. On other platforms it may work differently.
*/
-/*! \fn int QGLContext::choosePixelFormat(void* dummyPfd, HDC pdc)
-
- \b{Win32 only:} This virtual function chooses a pixel format
- that matches the OpenGL \l{setFormat()}{format}.
- Reimplement this function in a subclass if you need a custom
- context.
-
- \warning The \a dummyPfd pointer and \a pdc are used as a \c
- PIXELFORMATDESCRIPTOR*. We use \c void to avoid using
- Windows-specific types in our header files.
-
- \sa chooseContext()
-*/
-
-/*! \fn void *QGLContext::chooseVisual()
-
- \b{X11 only:} This virtual function tries to find a visual that
- matches the format, reducing the demands if the original request
- cannot be met.
-
- The algorithm for reducing the demands of the format is quite
- simple-minded, so override this method in your subclass if your
- application has spcific requirements on visual selection.
-
- \sa chooseContext()
-*/
-
-/*! \fn void *QGLContext::tryVisual(const QGLFormat& f, int bufDepth)
- \internal
-
- \b{X11 only:} This virtual function chooses a visual that matches
- the OpenGL \l{format()}{format}. Reimplement this function
- in a subclass if you need a custom visual.
-
- \sa chooseContext()
-*/
-
/*!
\fn void QGLContext::reset()
@@ -3706,7 +3669,7 @@ QGLWidget::~QGLWidget()
*/
/*!
- \fn QFunctionPointer QGLContext::getProcAddress() const
+ \fn QFunctionPointer QGLContext::getProcAddress(const QString &proc) const
Returns a function pointer to the GL extension function passed in
\a proc. 0 is returned if a pointer to the function could not be
@@ -4046,14 +4009,6 @@ void QGLWidget::paintEvent(QPaintEvent *)
/*!
- \fn void QGLWidget::setMouseTracking(bool enable)
-
- If \a enable is true then mouse tracking is enabled; otherwise it
- is disabled.
-*/
-
-
-/*!
Renders the current scene on a pixmap and returns the pixmap.
You can use this method on both visible and invisible QGLWidget objects.
diff --git a/src/opengl/qglfunctions.cpp b/src/opengl/qglfunctions.cpp
index 450f17b171..d6d77d0568 100644
--- a/src/opengl/qglfunctions.cpp
+++ b/src/opengl/qglfunctions.cpp
@@ -466,7 +466,7 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
*/
/*!
- \fn void QGLFunctions::glBufferData(GLenum target, qgl_GLsizeiptr size, const void* data, GLenum usage)
+ \fn void QGLFunctions::glBufferData(GLenum target, qopengl_GLsizeiptr size, const void* data, GLenum usage)
Convenience function that calls glBufferData(\a target, \a size, \a data, \a usage).
@@ -475,7 +475,7 @@ void QGLFunctions::initializeGLFunctions(const QGLContext *context)
*/
/*!
- \fn void QGLFunctions::glBufferSubData(GLenum target, qgl_GLintptr offset, qgl_GLsizeiptr size, const void* data)
+ \fn void QGLFunctions::glBufferSubData(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr size, const void* data)
Convenience function that calls glBufferSubData(\a target, \a offset, \a size, \a data).
diff --git a/src/platformsupport/eglconvenience/qeglconvenience.cpp b/src/platformsupport/eglconvenience/qeglconvenience.cpp
index 7cf1f88b02..e6624fb9ff 100644
--- a/src/platformsupport/eglconvenience/qeglconvenience.cpp
+++ b/src/platformsupport/eglconvenience/qeglconvenience.cpp
@@ -82,16 +82,7 @@ QVector<EGLint> q_createConfigAttributesFromFormat(const QSurfaceFormat &format)
// put in the list before 32-bit configs. So, to make sure 16-bit is preffered over 32-bit,
// we must set the red/green/blue sizes to zero. This has an unfortunate consequence that
// if the application sets the red/green/blue size to 5/6/5 on the QSurfaceFormat,
- // they will probably get a 32-bit config, even when there's an RGB565 config available.
-
-// // Now normalize the values so -1 becomes 0
-// redSize = redSize > 0 ? redSize : 0;
-// greenSize = greenSize > 0 ? greenSize : 0;
-// blueSize = blueSize > 0 ? blueSize : 0;
-// alphaSize = alphaSize > 0 ? alphaSize : 0;
-// depthSize = depthSize > 0 ? depthSize : 0;
-// stencilSize = stencilSize > 0 ? stencilSize : 0;
-// sampleCount = sampleCount > 0 ? sampleCount : 0;
+ // they might still get a 32-bit config, even when there's an RGB565 config available.
QVector<EGLint> configAttributes;
@@ -446,11 +437,9 @@ void q_printEglConfig(EGLDisplay display, EGLConfig config)
for (index = 0; attrs[index].attr != -1; ++index) {
EGLint value;
if (eglGetConfigAttrib(display, config, attrs[index].attr, &value)) {
- qWarning("\t%s: %d\n", attrs[index].name, (int)value);
+ qDebug("\t%s: %d", attrs[index].name, (int)value);
}
}
-
- qWarning("\n");
}
#ifdef Q_OS_LINUX
diff --git a/src/platformsupport/eglconvenience/qeglplatformcontext.cpp b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp
index 9c3b9b539c..eec6463c21 100644
--- a/src/platformsupport/eglconvenience/qeglplatformcontext.cpp
+++ b/src/platformsupport/eglconvenience/qeglplatformcontext.cpp
@@ -44,6 +44,7 @@
#include "qeglpbuffer_p.h"
#include <qpa/qplatformwindow.h>
#include <QOpenGLContext>
+#include <QDebug>
QT_BEGIN_NAMESPACE
@@ -191,6 +192,12 @@ void QEGLPlatformContext::init(const QSurfaceFormat &format, QPlatformOpenGLCont
return;
}
+ static const bool printConfig = qgetenv("QT_QPA_EGLFS_DEBUG").toInt();
+ if (printConfig) {
+ qDebug() << "Created context for format" << format << "with config:";
+ q_printEglConfig(m_eglDisplay, m_eglConfig);
+ }
+
#ifndef QT_NO_OPENGL
// Make the context current to ensure the GL version query works. This needs a surface too.
const EGLint pbufferAttributes[] = {
@@ -261,37 +268,15 @@ bool QEGLPlatformContext::makeCurrent(QPlatformSurface *surface)
return true;
}
- bool ok = eglMakeCurrent(m_eglDisplay, eglSurface, eglSurface, m_eglContext);
- if (!ok)
- qWarning("QEGLPlatformContext::makeCurrent: eglError: %x, this: %p \n", eglGetError(), this);
-#ifdef QEGL_EXTRA_DEBUG
- static bool showDebug = true;
- if (showDebug) {
- showDebug = false;
- const char *str = (const char*)glGetString(GL_VENDOR);
- qWarning("Vendor %s\n", str);
- str = (const char*)glGetString(GL_RENDERER);
- qWarning("Renderer %s\n", str);
- str = (const char*)glGetString(GL_VERSION);
- qWarning("Version %s\n", str);
-
- str = (const char*)glGetString(GL_SHADING_LANGUAGE_VERSION);
- qWarning("Extensions %s\n",str);
-
- str = (const char*)glGetString(GL_EXTENSIONS);
- qWarning("Extensions %s\n", str);
-
- }
-#endif
-
+ const bool ok = eglMakeCurrent(m_eglDisplay, eglSurface, eglSurface, m_eglContext);
if (ok) {
if (!m_swapIntervalEnvChecked) {
m_swapIntervalEnvChecked = true;
if (qEnvironmentVariableIsSet("QT_QPA_EGLFS_SWAPINTERVAL")) {
QByteArray swapIntervalString = qgetenv("QT_QPA_EGLFS_SWAPINTERVAL");
- bool ok;
- const int swapInterval = swapIntervalString.toInt(&ok);
- if (ok)
+ bool intervalOk;
+ const int swapInterval = swapIntervalString.toInt(&intervalOk);
+ if (intervalOk)
m_swapIntervalFromEnv = swapInterval;
}
}
@@ -302,6 +287,8 @@ bool QEGLPlatformContext::makeCurrent(QPlatformSurface *surface)
m_swapInterval = requestedSwapInterval;
eglSwapInterval(eglDisplay(), m_swapInterval);
}
+ } else {
+ qWarning("QEGLPlatformContext::makeCurrent: eglError: %x, this: %p \n", eglGetError(), this);
}
return ok;
diff --git a/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp b/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp
index 88814151b6..26ae0eb724 100644
--- a/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp
+++ b/src/platformsupport/fontdatabases/basic/qbasicfontdatabase.cpp
@@ -220,7 +220,7 @@ void QBasicFontDatabase::releaseHandle(void *handle)
extern FT_Library qt_getFreetype();
-QStringList QBasicFontDatabase::addTTFile(const QByteArray &fontData, const QByteArray &file)
+QStringList QBasicFontDatabase::addTTFile(const QByteArray &fontData, const QByteArray &file, QSupportedWritingSystems *supportedWritingSystems)
{
FT_Library library = qt_getFreetype();
@@ -259,6 +259,8 @@ QStringList QBasicFontDatabase::addTTFile(const QByteArray &fontData, const QByt
if (cm->encoding == FT_ENCODING_ADOBE_CUSTOM
|| cm->encoding == FT_ENCODING_MS_SYMBOL) {
writingSystems.setSupported(QFontDatabase::Symbol);
+ if (supportedWritingSystems)
+ supportedWritingSystems->setSupported(QFontDatabase::Symbol);
break;
}
}
@@ -277,6 +279,8 @@ QStringList QBasicFontDatabase::addTTFile(const QByteArray &fontData, const QByt
};
writingSystems = QPlatformFontDatabase::writingSystemsFromTrueTypeBits(unicodeRange, codePageRange);
+ if (supportedWritingSystems)
+ *supportedWritingSystems = writingSystems;
if (os2->usWeightClass == 0)
;
diff --git a/src/platformsupport/fontdatabases/basic/qbasicfontdatabase_p.h b/src/platformsupport/fontdatabases/basic/qbasicfontdatabase_p.h
index 45d7218ece..247a2855e2 100644
--- a/src/platformsupport/fontdatabases/basic/qbasicfontdatabase_p.h
+++ b/src/platformsupport/fontdatabases/basic/qbasicfontdatabase_p.h
@@ -64,7 +64,7 @@ public:
QStringList addApplicationFont(const QByteArray &fontData, const QString &fileName);
void releaseHandle(void *handle);
- static QStringList addTTFile(const QByteArray &fontData, const QByteArray &file);
+ static QStringList addTTFile(const QByteArray &fontData, const QByteArray &file, QSupportedWritingSystems *supportedWritingSystems = 0);
static QString fontNameFromTTFile(const QString &filename);
};
diff --git a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
index 1a31400ea5..17717dd53c 100644
--- a/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
+++ b/src/platformsupport/fontdatabases/fontconfig/qfontconfigdatabase.cpp
@@ -331,10 +331,8 @@ static const char *getFcFamilyForStyleHint(const QFont::StyleHint style)
return stylehint;
}
-void QFontconfigDatabase::populateFontDatabase()
+static void populateFromPattern(FcPattern *pattern)
{
- FcFontSet *fonts;
-
QString familyName;
FcChar8 *value = 0;
int weight_value;
@@ -348,6 +346,110 @@ void QFontconfigDatabase::populateFontDatabase()
FcBool scalable;
FcBool antialias;
+ if (FcPatternGetString(pattern, FC_FAMILY, 0, &value) != FcResultMatch)
+ return;
+
+ familyName = QString::fromUtf8((const char *)value);
+
+ slant_value = FC_SLANT_ROMAN;
+ weight_value = FC_WEIGHT_REGULAR;
+ spacing_value = FC_PROPORTIONAL;
+ file_value = 0;
+ indexValue = 0;
+ scalable = FcTrue;
+
+
+ if (FcPatternGetInteger(pattern, FC_SLANT, 0, &slant_value) != FcResultMatch)
+ slant_value = FC_SLANT_ROMAN;
+ if (FcPatternGetInteger(pattern, FC_WEIGHT, 0, &weight_value) != FcResultMatch)
+ weight_value = FC_WEIGHT_REGULAR;
+ if (FcPatternGetInteger(pattern, FC_WIDTH, 0, &width_value) != FcResultMatch)
+ width_value = FC_WIDTH_NORMAL;
+ if (FcPatternGetInteger(pattern, FC_SPACING, 0, &spacing_value) != FcResultMatch)
+ spacing_value = FC_PROPORTIONAL;
+ if (FcPatternGetString(pattern, FC_FILE, 0, &file_value) != FcResultMatch)
+ file_value = 0;
+ if (FcPatternGetInteger(pattern, FC_INDEX, 0, &indexValue) != FcResultMatch)
+ indexValue = 0;
+ if (FcPatternGetBool(pattern, FC_SCALABLE, 0, &scalable) != FcResultMatch)
+ scalable = FcTrue;
+ if (FcPatternGetString(pattern, FC_FOUNDRY, 0, &foundry_value) != FcResultMatch)
+ foundry_value = 0;
+ if (FcPatternGetString(pattern, FC_STYLE, 0, &style_value) != FcResultMatch)
+ style_value = 0;
+ if (FcPatternGetBool(pattern,FC_ANTIALIAS,0,&antialias) != FcResultMatch)
+ antialias = true;
+
+ QSupportedWritingSystems writingSystems;
+ FcLangSet *langset = 0;
+ FcResult res = FcPatternGetLangSet(pattern, FC_LANG, 0, &langset);
+ if (res == FcResultMatch) {
+ bool hasLang = false;
+ for (int j = 1; j < QFontDatabase::WritingSystemsCount; ++j) {
+ const FcChar8 *lang = (const FcChar8*) languageForWritingSystem[j];
+ if (lang) {
+ FcLangResult langRes = FcLangSetHasLang(langset, lang);
+ if (langRes != FcLangDifferentLang) {
+ writingSystems.setSupported(QFontDatabase::WritingSystem(j));
+ hasLang = true;
+ }
+ }
+ }
+ if (!hasLang)
+ // none of our known languages, add it to the other set
+ writingSystems.setSupported(QFontDatabase::Other);
+ } else {
+ // we set Other to supported for symbol fonts. It makes no
+ // sense to merge these with other ones, as they are
+ // special in a way.
+ writingSystems.setSupported(QFontDatabase::Other);
+ }
+
+#if FC_VERSION >= 20297
+ for (int j = 1; j < QFontDatabase::WritingSystemsCount; ++j) {
+ if (writingSystems.supported(QFontDatabase::WritingSystem(j))
+ && requiresOpenType(j) && openType[j]) {
+ FcChar8 *cap;
+ res = FcPatternGetString (pattern, FC_CAPABILITY, 0, &cap);
+ if (res != FcResultMatch || !strstr((const char *)cap, openType[j]))
+ writingSystems.setSupported(QFontDatabase::WritingSystem(j),false);
+ }
+ }
+#endif
+
+ FontFile *fontFile = new FontFile;
+ fontFile->fileName = QLatin1String((const char *)file_value);
+ fontFile->indexValue = indexValue;
+
+ QFont::Style style = (slant_value == FC_SLANT_ITALIC)
+ ? QFont::StyleItalic
+ : ((slant_value == FC_SLANT_OBLIQUE)
+ ? QFont::StyleOblique
+ : QFont::StyleNormal);
+ // Note: weight should really be an int but registerFont incorrectly uses an enum
+ QFont::Weight weight = QFont::Weight(weightFromFcWeight(weight_value));
+
+ double pixel_size = 0;
+ if (!scalable)
+ FcPatternGetDouble (pattern, FC_PIXEL_SIZE, 0, &pixel_size);
+
+ bool fixedPitch = spacing_value >= FC_MONO;
+ // Note: stretch should really be an int but registerFont incorrectly uses an enum
+ QFont::Stretch stretch = QFont::Stretch(stretchFromFcWidth(width_value));
+ QString styleName = style_value ? QString::fromUtf8((const char *) style_value) : QString();
+ QPlatformFontDatabase::registerFont(familyName,styleName,QLatin1String((const char *)foundry_value),weight,style,stretch,antialias,scalable,pixel_size,fixedPitch,writingSystems,fontFile);
+// qDebug() << familyName << (const char *)foundry_value << weight << style << &writingSystems << scalable << true << pixel_size;
+
+ for (int k = 1; FcPatternGetString(pattern, FC_FAMILY, k, &value) == FcResultMatch; ++k)
+ QPlatformFontDatabase::registerAliasToFontFamily(familyName, QString::fromUtf8((const char *)value));
+
+}
+
+void QFontconfigDatabase::populateFontDatabase()
+{
+ FcInitReinitialize();
+ FcFontSet *fonts;
+
{
FcObjectSet *os = FcObjectSetCreate();
FcPattern *pattern = FcPatternCreate();
@@ -371,103 +473,8 @@ void QFontconfigDatabase::populateFontDatabase()
FcPatternDestroy(pattern);
}
- for (int i = 0; i < fonts->nfont; i++) {
- if (FcPatternGetString(fonts->fonts[i], FC_FAMILY, 0, &value) != FcResultMatch)
- continue;
- // capitalize(value);
- familyName = QString::fromUtf8((const char *)value);
- slant_value = FC_SLANT_ROMAN;
- weight_value = FC_WEIGHT_REGULAR;
- spacing_value = FC_PROPORTIONAL;
- file_value = 0;
- indexValue = 0;
- scalable = FcTrue;
-
-
- if (FcPatternGetInteger (fonts->fonts[i], FC_SLANT, 0, &slant_value) != FcResultMatch)
- slant_value = FC_SLANT_ROMAN;
- if (FcPatternGetInteger (fonts->fonts[i], FC_WEIGHT, 0, &weight_value) != FcResultMatch)
- weight_value = FC_WEIGHT_REGULAR;
- if (FcPatternGetInteger (fonts->fonts[i], FC_WIDTH, 0, &width_value) != FcResultMatch)
- width_value = FC_WIDTH_NORMAL;
- if (FcPatternGetInteger (fonts->fonts[i], FC_SPACING, 0, &spacing_value) != FcResultMatch)
- spacing_value = FC_PROPORTIONAL;
- if (FcPatternGetString (fonts->fonts[i], FC_FILE, 0, &file_value) != FcResultMatch)
- file_value = 0;
- if (FcPatternGetInteger (fonts->fonts[i], FC_INDEX, 0, &indexValue) != FcResultMatch)
- indexValue = 0;
- if (FcPatternGetBool(fonts->fonts[i], FC_SCALABLE, 0, &scalable) != FcResultMatch)
- scalable = FcTrue;
- if (FcPatternGetString(fonts->fonts[i], FC_FOUNDRY, 0, &foundry_value) != FcResultMatch)
- foundry_value = 0;
- if (FcPatternGetString(fonts->fonts[i], FC_STYLE, 0, &style_value) != FcResultMatch)
- style_value = 0;
- if(FcPatternGetBool(fonts->fonts[i],FC_ANTIALIAS,0,&antialias) != FcResultMatch)
- antialias = true;
-
- QSupportedWritingSystems writingSystems;
- FcLangSet *langset = 0;
- FcResult res = FcPatternGetLangSet(fonts->fonts[i], FC_LANG, 0, &langset);
- if (res == FcResultMatch) {
- bool hasLang = false;
- for (int j = 1; j < QFontDatabase::WritingSystemsCount; ++j) {
- const FcChar8 *lang = (const FcChar8*) languageForWritingSystem[j];
- if (lang) {
- FcLangResult langRes = FcLangSetHasLang(langset, lang);
- if (langRes != FcLangDifferentLang) {
- writingSystems.setSupported(QFontDatabase::WritingSystem(j));
- hasLang = true;
- }
- }
- }
- if (!hasLang)
- // none of our known languages, add it to the other set
- writingSystems.setSupported(QFontDatabase::Other);
- } else {
- // we set Other to supported for symbol fonts. It makes no
- // sense to merge these with other ones, as they are
- // special in a way.
- writingSystems.setSupported(QFontDatabase::Other);
- }
-
-#if FC_VERSION >= 20297
- for (int j = 1; j < QFontDatabase::WritingSystemsCount; ++j) {
- if (writingSystems.supported(QFontDatabase::WritingSystem(j))
- && requiresOpenType(j) && openType[j]) {
- FcChar8 *cap;
- res = FcPatternGetString (fonts->fonts[i], FC_CAPABILITY, 0, &cap);
- if (res != FcResultMatch || !strstr((const char *)cap, openType[j]))
- writingSystems.setSupported(QFontDatabase::WritingSystem(j),false);
- }
- }
-#endif
-
- FontFile *fontFile = new FontFile;
- fontFile->fileName = QLatin1String((const char *)file_value);
- fontFile->indexValue = indexValue;
-
- QFont::Style style = (slant_value == FC_SLANT_ITALIC)
- ? QFont::StyleItalic
- : ((slant_value == FC_SLANT_OBLIQUE)
- ? QFont::StyleOblique
- : QFont::StyleNormal);
- // Note: weight should really be an int but registerFont incorrectly uses an enum
- QFont::Weight weight = QFont::Weight(weightFromFcWeight(weight_value));
-
- double pixel_size = 0;
- if (!scalable)
- FcPatternGetDouble (fonts->fonts[i], FC_PIXEL_SIZE, 0, &pixel_size);
-
- bool fixedPitch = spacing_value >= FC_MONO;
- // Note: stretch should really be an int but registerFont incorrectly uses an enum
- QFont::Stretch stretch = QFont::Stretch(stretchFromFcWidth(width_value));
- QString styleName = style_value ? QString::fromUtf8((const char *) style_value) : QString();
- QPlatformFontDatabase::registerFont(familyName,styleName,QLatin1String((const char *)foundry_value),weight,style,stretch,antialias,scalable,pixel_size,fixedPitch,writingSystems,fontFile);
-// qDebug() << familyName << (const char *)foundry_value << weight << style << &writingSystems << scalable << true << pixel_size;
-
- for (int k = 1; FcPatternGetString(fonts->fonts[i], FC_FAMILY, k, &value) == FcResultMatch; ++k)
- QPlatformFontDatabase::registerAliasToFontFamily(familyName, QString::fromUtf8((const char *)value));
- }
+ for (int i = 0; i < fonts->nfont; i++)
+ populateFromPattern(fonts->fonts[i]);
FcFontSetDestroy (fonts);
@@ -802,6 +809,7 @@ static FcPattern *queryFont(const FcChar8 *file, const QByteArray &data, int id,
QStringList QFontconfigDatabase::addApplicationFont(const QByteArray &fontData, const QString &fileName)
{
QStringList families;
+
FcFontSet *set = FcConfigGetFonts(0, FcSetApplication);
if (!set) {
FcConfigAppFontAddFile(0, (const FcChar8 *)":/non-existent");
@@ -814,28 +822,24 @@ QStringList QFontconfigDatabase::addApplicationFont(const QByteArray &fontData,
FcBlanks *blanks = FcConfigGetBlanks(0);
int count = 0;
- FcPattern *pattern = 0;
+ FcPattern *pattern;
do {
pattern = queryFont((const FcChar8 *)QFile::encodeName(fileName).constData(),
fontData, id, blanks, &count);
if (!pattern)
return families;
- FcPatternDel(pattern, FC_FILE);
- QByteArray cs = fileName.toUtf8();
- FcPatternAddString(pattern, FC_FILE, (const FcChar8 *) cs.constData());
-
FcChar8 *fam = 0;
if (FcPatternGetString(pattern, FC_FAMILY, 0, &fam) == FcResultMatch) {
QString family = QString::fromUtf8(reinterpret_cast<const char *>(fam));
families << family;
}
+ populateFromPattern(pattern);
- if (!FcFontSetAdd(set, pattern))
- return families;
+ FcFontSetAdd(set, pattern);
++id;
- } while (pattern && id < count);
+ } while (id < count);
return families;
}
diff --git a/src/plugins/generic/evdevtouch/README b/src/plugins/generic/evdevtouch/README
index 833b511fd8..e5c9aff0af 100644
--- a/src/plugins/generic/evdevtouch/README
+++ b/src/plugins/generic/evdevtouch/README
@@ -1,20 +1,17 @@
Generic plug-in for evdev multiple touch (ABS_MT) events.
Supports protocol type A & B.
Type B is supported both directly and via libmtdev.
-Single-touch devices reporting ABS_X and Y only are not supported
-by this plugin. Use tslib or evdevmouse instead.
-
The protocol type will be detected automatically.
libmtdev is automatically detected based on library availability. To disable it,
pass -no-mtdev to configure.
-Tested with the following kernel drivers:
- bcm5974 (type A)
- hid_magicmouse (type A with ABS_MT_TRACKING_ID) (type B over libmtdev)
- wacom (type B)
+Single-touch devices reporting ABS_X and Y are supported too. Keep in
+mind however that the libudev-based device discovery may not be able
+to recognize such devices. If mouse events are sufficient, it may be
+better to use evdevmouse or tslib with such devices.
-To use this "driver", pass -plugin EvdevTouch on the command line.
+To use this plugin, pass -plugin EvdevTouch on the command line.
If automatic detection does not work, use -plugin
EvdevTouch:/dev/input/eventN to explicitly set the device file
diff --git a/src/plugins/platforms/android/androidjnimain.cpp b/src/plugins/platforms/android/androidjnimain.cpp
index 784cc2e38b..ff1a40bfc5 100644
--- a/src/plugins/platforms/android/androidjnimain.cpp
+++ b/src/plugins/platforms/android/androidjnimain.cpp
@@ -576,7 +576,8 @@ static void updateWindow(JNIEnv */*env*/, jobject /*thiz*/)
}
QAndroidPlatformScreen *screen = static_cast<QAndroidPlatformScreen *>(m_androidPlatformIntegration->screen());
- QMetaObject::invokeMethod(screen, "setDirty", Qt::QueuedConnection, Q_ARG(QRect,screen->geometry()));
+ if (screen->rasterSurfaces())
+ QMetaObject::invokeMethod(screen, "setDirty", Qt::QueuedConnection, Q_ARG(QRect,screen->geometry()));
}
static void updateApplicationState(JNIEnv */*env*/, jobject /*thiz*/, jint state)
diff --git a/src/plugins/platforms/android/qandroidinputcontext.cpp b/src/plugins/platforms/android/qandroidinputcontext.cpp
index bfb13811e3..3324d9ba49 100644
--- a/src/plugins/platforms/android/qandroidinputcontext.cpp
+++ b/src/plugins/platforms/android/qandroidinputcontext.cpp
@@ -70,6 +70,35 @@ static jfieldID m_selectionStartFieldID = 0;
static jfieldID m_startOffsetFieldID = 0;
static jfieldID m_textFieldID = 0;
+static jboolean beginBatchEdit(JNIEnv */*env*/, jobject /*thiz*/)
+{
+ if (!m_androidInputContext)
+ return JNI_FALSE;
+
+#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
+ qDebug() << "@@@ BEGINBATCH";
+#endif
+
+ return m_androidInputContext->beginBatchEdit();
+
+ return JNI_TRUE;
+}
+
+static jboolean endBatchEdit(JNIEnv */*env*/, jobject /*thiz*/)
+{
+ if (!m_androidInputContext)
+ return JNI_FALSE;
+
+#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
+ qDebug() << "@@@ ENDBATCH";
+#endif
+
+ return m_androidInputContext->endBatchEdit();
+
+ return JNI_TRUE;
+}
+
+
static jboolean commitText(JNIEnv *env, jobject /*thiz*/, jstring text, jint newCursorPosition)
{
if (!m_androidInputContext)
@@ -121,12 +150,13 @@ static jobject getExtractedText(JNIEnv *env, jobject /*thiz*/, int hintMaxChars,
if (!m_androidInputContext)
return 0;
-#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
- qDebug() << "@@@ GETEX";
-#endif
const QAndroidInputContext::ExtractedText &extractedText =
m_androidInputContext->getExtractedText(hintMaxChars, hintMaxLines, flags);
+#ifdef QT_DEBUG_ANDROID_IM_PROTOCOL
+ qDebug() << "@@@ GETEX" << hintMaxChars << hintMaxLines << QString::fromLatin1("0x") + QString::number(flags,16) << extractedText.text << "partOff:" << extractedText.partialStartOffset << extractedText.partialEndOffset << "sel:" << extractedText.selectionStart << extractedText.selectionEnd << "offset:" << extractedText.startOffset;
+#endif
+
jobject object = env->NewObject(m_extractedTextClass, m_classConstructorMethodID);
env->SetIntField(object, m_partialStartOffsetFieldID, extractedText.partialStartOffset);
env->SetIntField(object, m_partialEndOffsetFieldID, extractedText.partialEndOffset);
@@ -285,6 +315,8 @@ static jboolean updateCursorPosition(JNIEnv */*env*/, jobject /*thiz*/)
static JNINativeMethod methods[] = {
+ {"beginBatchEdit", "()Z", (void *)beginBatchEdit},
+ {"endBatchEdit", "()Z", (void *)endBatchEdit},
{"commitText", "(Ljava/lang/String;I)Z", (void *)commitText},
{"deleteSurroundingText", "(II)Z", (void *)deleteSurroundingText},
{"finishComposingText", "()Z", (void *)finishComposingText},
@@ -306,7 +338,7 @@ static JNINativeMethod methods[] = {
QAndroidInputContext::QAndroidInputContext()
- : QPlatformInputContext(), m_blockUpdateSelection(false)
+ : QPlatformInputContext(), m_blockUpdateSelection(false), m_batchEditNestingLevel(0)
{
QtAndroid::AttachedJNIEnv env;
if (!env.jniEnv)
@@ -416,11 +448,14 @@ void QAndroidInputContext::commit()
void QAndroidInputContext::updateCursorPosition()
{
QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
- if (!query.isNull() && !m_blockUpdateSelection) {
+ if (!query.isNull() && !m_blockUpdateSelection && !m_batchEditNestingLevel) {
// make sure it also works with editors that have not been updated to the new API
QVariant absolutePos = query->value(Qt::ImAbsolutePosition);
const int cursorPos = absolutePos.isValid() ? absolutePos.toInt() : query->value(Qt::ImCursorPosition).toInt();
- QtAndroidInput::updateSelection(cursorPos, cursorPos, -1, -1); //selection empty and no pre-edit text
+ const int composeLength = m_composingText.length();
+ const int composeStart = composeLength ? cursorPos : -1;
+ QtAndroidInput::updateSelection(cursorPos + composeLength, cursorPos + composeLength, //empty selection
+ composeStart, composeStart + composeLength); // pre-edit text
}
}
@@ -507,6 +542,19 @@ void QAndroidInputContext::sendEvent(QObject *receiver, QInputMethodQueryEvent *
QCoreApplication::sendEvent(receiver, event);
}
+jboolean QAndroidInputContext::beginBatchEdit()
+{
+ ++m_batchEditNestingLevel;
+ return JNI_TRUE;
+}
+
+jboolean QAndroidInputContext::endBatchEdit()
+{
+ if (--m_batchEditNestingLevel == 0 && !m_blockUpdateSelection) //ending batch edit mode
+ updateCursorPosition();
+ return JNI_TRUE;
+}
+
jboolean QAndroidInputContext::commitText(const QString &text, jint /*newCursorPosition*/)
{
m_composingText = text;
@@ -559,19 +607,39 @@ jint QAndroidInputContext::getCursorCapsMode(jint /*reqModes*/)
const QAndroidInputContext::ExtractedText &QAndroidInputContext::getExtractedText(jint hintMaxChars, jint /*hintMaxLines*/, jint /*flags*/)
{
+ // Note to self: "if the GET_EXTRACTED_TEXT_MONITOR flag is set, you should be calling
+ // updateExtractedText(View, int, ExtractedText) whenever you call
+ // updateSelection(View, int, int, int, int)." QTBUG-37980
+
QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
if (query.isNull())
return m_extractedText;
- if (hintMaxChars)
- m_extractedText.text = query->value(Qt::ImSurroundingText).toString().right(hintMaxChars);
+ int localPos = query->value(Qt::ImCursorPosition).toInt(); //position before pre-edit text relative to the current block
+ QVariant absolutePos = query->value(Qt::ImAbsolutePosition);
+ int blockPos = absolutePos.isValid() ? absolutePos.toInt() - localPos : 0; // position of the start of the current block
+ QString blockText = query->value(Qt::ImSurroundingText).toString() + m_composingText;
+ int composeLength = m_composingText.length();
+
+ int cpos = localPos + composeLength; //actual cursor pos relative to the current block
+
+ int localOffset = 0; // start of extracted text relative to the current block
+ if (hintMaxChars) {
+ if (cpos > hintMaxChars)
+ localOffset = cpos - hintMaxChars;
+ m_extractedText.text = blockText.mid(localOffset, hintMaxChars);
+ }
+
+ m_extractedText.startOffset = blockPos + localOffset; // "The offset in the overall text at which the extracted text starts."
- m_extractedText.startOffset = query->value(Qt::ImCursorPosition).toInt();
const QString &selection = query->value(Qt::ImCurrentSelection).toString();
const int selLen = selection.length();
if (selLen) {
- m_extractedText.selectionStart = query->value(Qt::ImAnchorPosition).toInt();
- m_extractedText.selectionEnd = m_extractedText.startOffset;
+ m_extractedText.selectionStart = query->value(Qt::ImAnchorPosition).toInt() - localOffset;
+ m_extractedText.selectionEnd = m_extractedText.selectionStart + selLen;
+ } else {
+ m_extractedText.selectionStart = cpos - localOffset;
+ m_extractedText.selectionEnd = cpos - localOffset;
}
return m_extractedText;
@@ -610,7 +678,7 @@ QString QAndroidInputContext::getTextBeforeCursor(jint length, jint /*flags*/)
{
QVariant textBefore = queryFocusObjectThreadSafe(Qt::ImTextBeforeCursor, QVariant(length));
if (textBefore.isValid()) {
- return textBefore.toString().left(length);
+ return textBefore.toString().left(length) + m_composingText;
}
//compatibility code for old controls that do not implement the new API
@@ -624,7 +692,7 @@ QString QAndroidInputContext::getTextBeforeCursor(jint length, jint /*flags*/)
return text;
const int wordLeftPos = cursorPos - length;
- return text.mid(wordLeftPos > 0 ? wordLeftPos : 0, cursorPos);
+ return text.mid(wordLeftPos > 0 ? wordLeftPos : 0, cursorPos) + m_composingText;
}
jboolean QAndroidInputContext::setComposingText(const QString &text, jint newCursorPosition)
@@ -647,11 +715,11 @@ jboolean QAndroidInputContext::setComposingText(const QString &text, jint newCur
sendInputMethodEvent(&event);
QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
- if (!query.isNull() && !m_blockUpdateSelection) {
+ if (!query.isNull() && !m_blockUpdateSelection && !m_batchEditNestingLevel) {
QVariant absolutePos = query->value(Qt::ImAbsolutePosition);
const int cursorPos = absolutePos.isValid() ? absolutePos.toInt() : query->value(Qt::ImCursorPosition).toInt();
const int preeditLength = text.length();
- QtAndroidInput::updateSelection(cursorPos+preeditLength, cursorPos+preeditLength, cursorPos, cursorPos+preeditLength);
+ QtAndroidInput::updateSelection(cursorPos+preeditLength, cursorPos+preeditLength, -1, -1);
}
return JNI_TRUE;
@@ -713,9 +781,17 @@ jboolean QAndroidInputContext::setComposingRegion(jint start, jint end)
jboolean QAndroidInputContext::setSelection(jint start, jint end)
{
+ QSharedPointer<QInputMethodQueryEvent> query = focusObjectInputMethodQuery();
+ if (query.isNull())
+ return JNI_FALSE;
+
+ int localPos = query->value(Qt::ImCursorPosition).toInt();
+ QVariant absolutePos = query->value(Qt::ImAbsolutePosition);
+ int blockPosition = absolutePos.isValid() ? absolutePos.toInt() - localPos : 0;
+
QList<QInputMethodEvent::Attribute> attributes;
attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::Selection,
- start,
+ start - blockPosition,
end - start,
QVariant()));
diff --git a/src/plugins/platforms/android/qandroidinputcontext.h b/src/plugins/platforms/android/qandroidinputcontext.h
index 2fb54a97c4..f7b29a855f 100644
--- a/src/plugins/platforms/android/qandroidinputcontext.h
+++ b/src/plugins/platforms/android/qandroidinputcontext.h
@@ -97,6 +97,8 @@ public:
void clear();
//---------------//
+ jboolean beginBatchEdit();
+ jboolean endBatchEdit();
jboolean commitText(const QString &text, jint newCursorPosition);
jboolean deleteSurroundingText(jint leftLength, jint rightLength);
jboolean finishComposingText();
@@ -133,6 +135,7 @@ private:
QString m_composingText;
QMetaObject::Connection m_updateCursorPosConnection;
bool m_blockUpdateSelection;
+ int m_batchEditNestingLevel;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidplatformdialoghelpers.cpp b/src/plugins/platforms/android/qandroidplatformdialoghelpers.cpp
index e76eedbfd9..897feb5802 100644
--- a/src/plugins/platforms/android/qandroidplatformdialoghelpers.cpp
+++ b/src/plugins/platforms/android/qandroidplatformdialoghelpers.cpp
@@ -41,6 +41,9 @@
#include "qandroidplatformdialoghelpers.h"
#include "androidjnimain.h"
+
+#include <QTextDocument>
+
#include <private/qguiapplication_p.h>
#include <qpa/qplatformtheme.h>
@@ -61,6 +64,14 @@ void QAndroidPlatformMessageDialogHelper::exec()
m_loop.exec();
}
+static QString htmlText(QString text)
+{
+ if (Qt::mightBeRichText(text))
+ return text;
+ text.remove(QLatin1Char('\r'));
+ return text.toHtmlEscaped().replace(QLatin1Char('\n'), QLatin1String("<br />"));
+}
+
bool QAndroidPlatformMessageDialogHelper::show(Qt::WindowFlags windowFlags
, Qt::WindowModality windowModality
, QWindow *parent)
@@ -74,19 +85,19 @@ bool QAndroidPlatformMessageDialogHelper::show(Qt::WindowFlags windowFlags
m_javaMessageDialog.callMethod<void>("setIcon", "(I)V", opt->icon());
- QString str = opt->windowTitle();
+ QString str = htmlText(opt->windowTitle());
if (!str.isEmpty())
m_javaMessageDialog.callMethod<void>("setTile", "(Ljava/lang/String;)V", QJNIObjectPrivate::fromString(str).object());
- str = opt->text();
+ str = htmlText(opt->text());
if (!str.isEmpty())
m_javaMessageDialog.callMethod<void>("setText", "(Ljava/lang/String;)V", QJNIObjectPrivate::fromString(str).object());
- str = opt->informativeText();
+ str = htmlText(opt->informativeText());
if (!str.isEmpty())
m_javaMessageDialog.callMethod<void>("setInformativeText", "(Ljava/lang/String;)V", QJNIObjectPrivate::fromString(str).object());
- str = opt->detailedText();
+ str = htmlText(opt->detailedText());
if (!str.isEmpty())
m_javaMessageDialog.callMethod<void>("setDetailedText", "(Ljava/lang/String;)V", QJNIObjectPrivate::fromString(str).object());
diff --git a/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp b/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp
index 7f68b44ed8..7423e6c55a 100644
--- a/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp
+++ b/src/plugins/platforms/android/qandroidplatformfontdatabase.cpp
@@ -60,7 +60,17 @@ void QAndroidPlatformFontDatabase::populateFontDatabase()
QDir dir(fontpath, QLatin1String("*.ttf"));
for (int i = 0; i < int(dir.count()); ++i) {
const QByteArray file = QFile::encodeName(dir.absoluteFilePath(dir[i]));
- addTTFile(QByteArray(), file);
+
+ QSupportedWritingSystems supportedWritingSystems;
+ QStringList families = addTTFile(QByteArray(), file, &supportedWritingSystems);
+
+ extern int qt_script_for_writing_system(QFontDatabase::WritingSystem writingSystem);
+ for (int i = 0; i < QFontDatabase::WritingSystemsCount; ++i) {
+ if (i == QFontDatabase::Any || supportedWritingSystems.supported(QFontDatabase::WritingSystem(i))) {
+ QChar::Script script = QChar::Script(qt_script_for_writing_system(QFontDatabase::WritingSystem(i)));
+ m_fallbacks[script] += families;
+ }
+ }
}
}
@@ -71,9 +81,9 @@ QStringList QAndroidPlatformFontDatabase::fallbacksForFamily(const QString &fami
{
Q_UNUSED(family);
Q_UNUSED(style);
- Q_UNUSED(script);
+
if (styleHint == QFont::Monospace)
- return QString(qgetenv("QT_ANDROID_FONTS_MONOSPACE")).split(";");
+ return QString(qgetenv("QT_ANDROID_FONTS_MONOSPACE")).split(";") + m_fallbacks[script];
- return QString(qgetenv("QT_ANDROID_FONTS")).split(";");
+ return QString(qgetenv("QT_ANDROID_FONTS")).split(";") + m_fallbacks[script];
}
diff --git a/src/plugins/platforms/android/qandroidplatformfontdatabase.h b/src/plugins/platforms/android/qandroidplatformfontdatabase.h
index 3cbfe95d36..cdd3cf1674 100644
--- a/src/plugins/platforms/android/qandroidplatformfontdatabase.h
+++ b/src/plugins/platforms/android/qandroidplatformfontdatabase.h
@@ -53,6 +53,9 @@ public:
QFont::Style style,
QFont::StyleHint styleHint,
QChar::Script script) const;
+
+private:
+ QHash<QChar::Script, QStringList> m_fallbacks;
};
#endif // QANDROIDPLATFORMFONTDATABASE_H
diff --git a/src/plugins/platforms/android/qandroidplatformintegration.cpp b/src/plugins/platforms/android/qandroidplatformintegration.cpp
index 9adefd5b2c..7f0f40be0f 100644
--- a/src/plugins/platforms/android/qandroidplatformintegration.cpp
+++ b/src/plugins/platforms/android/qandroidplatformintegration.cpp
@@ -41,6 +41,7 @@
#include "qandroidplatformintegration.h"
+#include <QtCore/private/qjni_p.h>
#include <QGuiApplication>
#include <QOpenGLContext>
#include <QThread>
@@ -103,9 +104,6 @@ QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList &para
m_androidPlatformNativeInterface = new QAndroidPlatformNativeInterface();
- if (!eglBindAPI(EGL_OPENGL_ES_API))
- qFatal("Could not bind GL_ES API");
-
m_eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
if (m_eglDisplay == EGL_NO_DISPLAY)
qFatal("Could not open egl display");
@@ -114,6 +112,9 @@ QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList &para
if (!eglInitialize(m_eglDisplay, &major, &minor))
qFatal("Could not initialize egl display");
+ if (!eglBindAPI(EGL_OPENGL_ES_API))
+ qFatal("Could not bind GL_ES API");
+
m_primaryScreen = new QAndroidPlatformScreen();
screenAdded(m_primaryScreen);
m_primaryScreen->setPhysicalSize(QSize(m_defaultPhysicalSizeWidth, m_defaultPhysicalSizeHeight));
@@ -130,9 +131,41 @@ QAndroidPlatformIntegration::QAndroidPlatformIntegration(const QStringList &para
#endif
m_androidSystemLocale = new QAndroidSystemLocale;
+
+ QJNIObjectPrivate javaActivity(QtAndroid::activity());
+ if (javaActivity.isValid()) {
+ QJNIObjectPrivate resources = javaActivity.callObjectMethod("getResources", "()Landroid/content/res/Resources;");
+ QJNIObjectPrivate configuration = resources.callObjectMethod("getConfiguration", "()Landroid/content/res/Configuration;");
+
+ int touchScreen = configuration.getField<jint>("touchscreen");
+ if (touchScreen == QJNIObjectPrivate::getStaticField<jint>("android/content/res/Configuration", "TOUCHSCREEN_FINGER")
+ || touchScreen == QJNIObjectPrivate::getStaticField<jint>("android/content/res/Configuration", "TOUCHSCREEN_STYLUS"))
+ {
+ m_touchDevice = new QTouchDevice;
+ m_touchDevice->setType(QTouchDevice::TouchScreen);
+ m_touchDevice->setCapabilities(QTouchDevice::Position
+ | QTouchDevice::Area
+ | QTouchDevice::Pressure
+ | QTouchDevice::NormalizedPosition);
+
+ QJNIObjectPrivate pm = javaActivity.callObjectMethod("getPackageManager", "()Landroid/content/pm/PackageManager;");
+ Q_ASSERT(pm.isValid());
+ if (pm.callMethod<jboolean>("hasSystemFeature","(Ljava/lang/String;)Z",
+ QJNIObjectPrivate::getStaticObjectField("android/content/pm/PackageManager", "FEATURE_TOUCHSCREEN_MULTITOUCH_JAZZHAND", "Ljava/lang/String;").object())) {
+ m_touchDevice->setMaximumTouchPoints(10);
+ } else if (pm.callMethod<jboolean>("hasSystemFeature","(Ljava/lang/String;)Z",
+ QJNIObjectPrivate::getStaticObjectField("android/content/pm/PackageManager", "FEATURE_TOUCHSCREEN_MULTITOUCH_DISTINCT", "Ljava/lang/String;").object())) {
+ m_touchDevice->setMaximumTouchPoints(4);
+ } else if (pm.callMethod<jboolean>("hasSystemFeature","(Ljava/lang/String;)Z",
+ QJNIObjectPrivate::getStaticObjectField("android/content/pm/PackageManager", "FEATURE_TOUCHSCREEN_MULTITOUCH", "Ljava/lang/String;").object())) {
+ m_touchDevice->setMaximumTouchPoints(2);
+ }
+ QWindowSystemInterface::registerTouchDevice(m_touchDevice);
+ }
+ }
}
-bool QAndroidPlatformIntegration::needsWorkaround()
+bool QAndroidPlatformIntegration::needsBasicRenderloopWorkaround()
{
static bool needsWorkaround =
QtAndroid::deviceName().compare(QStringLiteral("samsung SM-T211"), Qt::CaseInsensitive) == 0
@@ -150,7 +183,7 @@ bool QAndroidPlatformIntegration::hasCapability(Capability cap) const
case OpenGL: return true;
case ForeignWindows: return true;
case ThreadedOpenGL:
- if (needsWorkaround())
+ if (needsBasicRenderloopWorkaround())
return false;
else
return true;
diff --git a/src/plugins/platforms/android/qandroidplatformintegration.h b/src/plugins/platforms/android/qandroidplatformintegration.h
index 2d685bc567..4a3fe6c766 100644
--- a/src/plugins/platforms/android/qandroidplatformintegration.h
+++ b/src/plugins/platforms/android/qandroidplatformintegration.h
@@ -120,9 +120,9 @@ public:
QTouchDevice *touchDevice() const { return m_touchDevice; }
void setTouchDevice(QTouchDevice *touchDevice) { m_touchDevice = touchDevice; }
- static bool needsWorkaround();
EGLDisplay m_eglDisplay;
private:
+ static bool needsBasicRenderloopWorkaround();
QTouchDevice *m_touchDevice;
diff --git a/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp b/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp
index a0b3ae066c..289480c625 100644
--- a/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp
+++ b/src/plugins/platforms/android/qandroidplatformopenglcontext.cpp
@@ -62,6 +62,22 @@ void QAndroidPlatformOpenGLContext::swapBuffers(QPlatformSurface *surface)
static_cast<QAndroidPlatformOpenGLWindow *>(surface)->checkNativeSurface(eglConfig());
}
+bool QAndroidPlatformOpenGLContext::needsFBOReadBackWorkaroud()
+{
+ static bool set = false;
+ static bool needsWorkaround = false;
+
+ if (!set) {
+ const char *rendererString = reinterpret_cast<const char *>(glGetString(GL_RENDERER));
+ needsWorkaround =
+ qstrcmp(rendererString, "Mali-400 MP") == 0
+ || qstrcmp(rendererString, "Adreno (TM) 200") == 0;
+ set = true;
+ }
+
+ return needsWorkaround;
+}
+
bool QAndroidPlatformOpenGLContext::makeCurrent(QPlatformSurface *surface)
{
bool ret = QEGLPlatformContext::makeCurrent(surface);
@@ -71,7 +87,7 @@ bool QAndroidPlatformOpenGLContext::makeCurrent(QPlatformSurface *surface)
if (rendererString != 0 && qstrncmp(rendererString, "Android Emulator", 16) == 0)
ctx_d->workaround_missingPrecisionQualifiers = true;
- if (!ctx_d->workaround_brokenFBOReadBack && QAndroidPlatformIntegration::needsWorkaround())
+ if (!ctx_d->workaround_brokenFBOReadBack && needsFBOReadBackWorkaroud())
ctx_d->workaround_brokenFBOReadBack = true;
return ret;
diff --git a/src/plugins/platforms/android/qandroidplatformopenglcontext.h b/src/plugins/platforms/android/qandroidplatformopenglcontext.h
index 29e5f596d5..10a89d541b 100644
--- a/src/plugins/platforms/android/qandroidplatformopenglcontext.h
+++ b/src/plugins/platforms/android/qandroidplatformopenglcontext.h
@@ -56,6 +56,8 @@ public:
private:
virtual EGLSurface eglSurfaceForPlatformSurface(QPlatformSurface *surface);
+
+ static bool needsFBOReadBackWorkaroud();
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/android/qandroidplatformrasterwindow.cpp b/src/plugins/platforms/android/qandroidplatformrasterwindow.cpp
index 334b9cdd23..eb5a73c4a3 100644
--- a/src/plugins/platforms/android/qandroidplatformrasterwindow.cpp
+++ b/src/plugins/platforms/android/qandroidplatformrasterwindow.cpp
@@ -57,7 +57,7 @@ void QAndroidPlatformRasterWindow::repaint(const QRegion &region)
if (QAndroidPlatformWindow::parent())
return;
- QRect currentGeometry = geometry().translated(mapToGlobal(QPoint(0,0)));
+ QRect currentGeometry = geometry();
QRect dirtyClient = region.boundingRect();
QRect dirtyRegion(currentGeometry.left() + dirtyClient.left(),
@@ -74,7 +74,7 @@ void QAndroidPlatformRasterWindow::repaint(const QRegion &region)
void QAndroidPlatformRasterWindow::setGeometry(const QRect &rect)
{
- m_oldGeometry = geometry().translated(mapToGlobal(QPoint(0,0)));;
+ m_oldGeometry = geometry();
QAndroidPlatformWindow::setGeometry(rect);
}
diff --git a/src/plugins/platforms/android/qandroidplatformscreen.cpp b/src/plugins/platforms/android/qandroidplatformscreen.cpp
index dbf317696f..678f4e6b5a 100644
--- a/src/plugins/platforms/android/qandroidplatformscreen.cpp
+++ b/src/plugins/platforms/android/qandroidplatformscreen.cpp
@@ -133,8 +133,10 @@ void QAndroidPlatformScreen::addWindow(QAndroidPlatformWindow *window)
return;
m_windowStack.prepend(window);
- if (window->isRaster())
+ if (window->isRaster()) {
+ m_rasterSurfaces.ref();
setDirty(window->geometry());
+ }
QWindow *w = topWindow();
QWindowSystemInterface::handleWindowActivated(w);
@@ -148,8 +150,10 @@ void QAndroidPlatformScreen::removeWindow(QAndroidPlatformWindow *window)
m_windowStack.removeOne(window);
if (window->isRaster()) {
+ m_rasterSurfaces.deref();
setDirty(window->geometry());
}
+
QWindow *w = topWindow();
QWindowSystemInterface::handleWindowActivated(w);
topWindowChanged(w);
@@ -238,6 +242,11 @@ void QAndroidPlatformScreen::topWindowChanged(QWindow *w)
}
}
+int QAndroidPlatformScreen::rasterSurfaces()
+{
+ return m_rasterSurfaces;
+}
+
void QAndroidPlatformScreen::doRedraw()
{
PROFILE_SCOPE;
@@ -246,7 +255,7 @@ void QAndroidPlatformScreen::doRedraw()
return;
QMutexLocker lock(&m_surfaceMutex);
- if (m_id == -1) {
+ if (m_id == -1 && m_rasterSurfaces) {
m_id = QtAndroid::createSurface(this, m_geometry, true, m_depth);
m_surfaceWaitCondition.wait(&m_surfaceMutex);
}
diff --git a/src/plugins/platforms/android/qandroidplatformscreen.h b/src/plugins/platforms/android/qandroidplatformscreen.h
index 625e77840e..96a91fbf06 100644
--- a/src/plugins/platforms/android/qandroidplatformscreen.h
+++ b/src/plugins/platforms/android/qandroidplatformscreen.h
@@ -82,6 +82,7 @@ public:
void scheduleUpdate();
void topWindowChanged(QWindow *w);
+ int rasterSurfaces();
public slots:
void setDirty(const QRect &rect);
@@ -110,6 +111,7 @@ private slots:
private:
int m_id = -1;
+ QAtomicInt m_rasterSurfaces = 0;
ANativeWindow* m_nativeSurface = nullptr;
QWaitCondition m_surfaceWaitCondition;
};
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm
index 0f99a414a0..990acd5301 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibility.mm
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibility.mm
@@ -298,7 +298,8 @@ bool hasValueAttribute(QAccessibleInterface *interface)
Q_ASSERT(interface);
const QAccessible::Role qtrole = interface->role();
if (qtrole == QAccessible::EditableText
- || interface->valueInterface()) {
+ || interface->valueInterface()
+ || interface->state().checkable) {
return true;
}
@@ -330,6 +331,10 @@ id getValueAttribute(QAccessibleInterface *interface)
return QCFString::toNSString(QString::number(valueInterface->currentValue().toDouble()));
}
+ if (interface->state().checkable) {
+ return [NSNumber numberWithInt: (interface->state().checked ? 1 : 0)];
+ }
+
return nil;
}
diff --git a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
index bc98d002f0..0b674b8d2f 100644
--- a/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
+++ b/src/plugins/platforms/cocoa/qcocoaaccessibilityelement.mm
@@ -417,7 +417,23 @@
}
- (id)accessibilityFocusedUIElement {
- return NSAccessibilityUnignoredAncestor(self);
+ QAccessibleInterface *iface = QAccessible::accessibleInterface(axid);
+
+ if (!iface || !iface->isValid()) {
+ qWarning() << "FocusedUIElement for INVALID";
+ return nil;
+ }
+ QAccessibleInterface *childInterface = iface->focusChild();
+ if (childInterface) {
+ QAccessible::Id childAxid = QAccessible::uniqueId(childInterface);
+ // FIXME: parent could be wrong
+ QCocoaAccessibleElement *accessibleElement = [QCocoaAccessibleElement createElementWithId:childAxid parent:self];
+ [accessibleElement autorelease];
+ return accessibleElement;
+ }
+
+ // no focus found
+ return nil;
}
@end
diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h
index 33d7dcbcf4..0274ed8201 100644
--- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h
+++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.h
@@ -163,6 +163,7 @@ public:
// The following variables help organizing modal sessions:
QStack<QCocoaModalSessionInfo> cocoaModalSessionStack;
bool currentExecIsNSAppRun;
+ bool modalSessionOnNSAppRun;
bool nsAppRunCalledByQt;
bool cleanupModalSessionsNeeded;
uint processEventsCalled;
diff --git a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
index 91b631bff9..495a54cac4 100644
--- a/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
+++ b/src/plugins/platforms/cocoa/qcocoaeventdispatcher.mm
@@ -721,7 +721,6 @@ void QCocoaEventDispatcherPrivate::beginModalSession(QWindow *window)
// setting currentModalSessionCached to zero, so that interrupt() calls
// [NSApp abortModal] if another modal session is currently running
Q_Q(QCocoaEventDispatcher);
- q->interrupt();
// Add a new, empty (null), NSModalSession to the stack.
// It will become active the next time QEventDispatcher::processEvents is called.
@@ -734,6 +733,12 @@ void QCocoaEventDispatcherPrivate::beginModalSession(QWindow *window)
cocoaModalSessionStack.push(info);
updateChildrenWorksWhenModal();
currentModalSessionCached = 0;
+ if (currentExecIsNSAppRun) {
+ modalSessionOnNSAppRun = true;
+ q->wakeUp();
+ } else {
+ q->interrupt();
+ }
}
void QCocoaEventDispatcherPrivate::endModalSession(QWindow *window)
@@ -772,6 +777,7 @@ QCocoaEventDispatcherPrivate::QCocoaEventDispatcherPrivate()
runLoopTimerRef(0),
blockSendPostedEvents(false),
currentExecIsNSAppRun(false),
+ modalSessionOnNSAppRun(false),
nsAppRunCalledByQt(false),
cleanupModalSessionsNeeded(false),
processEventsCalled(0),
@@ -902,6 +908,14 @@ void QCocoaEventDispatcherPrivate::postedEventsSourceCallback(void *info)
// processEvents() was called "manually," ignore this source for now
d->maybeCancelWaitForMoreEvents();
return;
+ } else if (d->modalSessionOnNSAppRun) {
+ // We're about to spawn the 1st modal session on top of the main runloop.
+ // Instead of calling processPostedEvents(), which would need us stop
+ // NSApp, we just re-enter processEvents(). This is equivalent to calling
+ // QDialog::exec() except that it's done in a non-blocking way.
+ d->modalSessionOnNSAppRun = false;
+ d->q_func()->processEvents(QEventLoop::DialogExec | QEventLoop::EventLoopExec | QEventLoop::WaitForMoreEvents);
+ return;
}
d->processPostedEvents();
d->maybeCancelWaitForMoreEvents();
diff --git a/src/plugins/platforms/cocoa/qcocoaintegration.mm b/src/plugins/platforms/cocoa/qcocoaintegration.mm
index 65a9f87e2d..412818ae47 100644
--- a/src/plugins/platforms/cocoa/qcocoaintegration.mm
+++ b/src/plugins/platforms/cocoa/qcocoaintegration.mm
@@ -316,11 +316,17 @@ QCocoaIntegration *QCocoaIntegration::instance()
*/
void QCocoaIntegration::updateScreens()
{
- NSArray *screens = [NSScreen screens];
+ NSArray *scrs = [NSScreen screens];
+ NSMutableArray *screens = [NSMutableArray arrayWithArray:scrs];
+ if ([screens count] == 0)
+ if ([NSScreen mainScreen])
+ [screens addObject:[NSScreen mainScreen]];
+ if ([screens count] == 0)
+ return;
QSet<QCocoaScreen*> remainingScreens = QSet<QCocoaScreen*>::fromList(mScreens);
QList<QPlatformScreen *> siblings;
for (uint i = 0; i < [screens count]; i++) {
- NSScreen* scr = [[NSScreen screens] objectAtIndex:i];
+ NSScreen* scr = [screens objectAtIndex:i];
CGDirectDisplayID dpy = [[[scr deviceDescription] objectForKey:@"NSScreenNumber"] unsignedIntValue];
// If this screen is a mirror and is not the primary one of the mirror set, ignore it.
if (CGDisplayIsInMirrorSet(dpy)) {
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.h b/src/plugins/platforms/cocoa/qcocoawindow.h
index 6e1f00eebe..b7a6a14d4a 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.h
+++ b/src/plugins/platforms/cocoa/qcocoawindow.h
@@ -183,6 +183,7 @@ public:
void windowWillMove();
void windowDidMove();
void windowDidResize();
+ void windowDidEndLiveResize();
bool windowShouldClose();
bool windowIsPopupType(Qt::WindowType type = Qt::Widget) const;
@@ -252,6 +253,7 @@ public: // for QNSView
QList<QCocoaWindow *> m_childWindows;
Qt::WindowFlags m_windowFlags;
+ bool m_effectivelyMaximized;
Qt::WindowState m_synchedWindowState;
Qt::WindowModality m_windowModality;
QPointer<QWindow> m_activePopupWindow;
diff --git a/src/plugins/platforms/cocoa/qcocoawindow.mm b/src/plugins/platforms/cocoa/qcocoawindow.mm
index c7fba4eef0..b27e1b03db 100644
--- a/src/plugins/platforms/cocoa/qcocoawindow.mm
+++ b/src/plugins/platforms/cocoa/qcocoawindow.mm
@@ -352,6 +352,7 @@ QCocoaWindow::QCocoaWindow(QWindow *tlw)
, m_contentViewIsToBeEmbedded(false)
, m_parentCocoaWindow(0)
, m_isNSWindowChild(false)
+ , m_effectivelyMaximized(false)
, m_synchedWindowState(Qt::WindowActive)
, m_windowModality(Qt::NonModal)
, m_windowUnderMouse(false)
@@ -1164,6 +1165,14 @@ void QCocoaWindow::windowDidResize()
[m_qtView updateGeometry];
}
+void QCocoaWindow::windowDidEndLiveResize()
+{
+ if (m_synchedWindowState == Qt::WindowMaximized && ![m_nsWindow isZoomed]) {
+ m_effectivelyMaximized = false;
+ [m_qtView notifyWindowStateChanged:Qt::WindowNoState];
+ }
+}
+
bool QCocoaWindow::windowShouldClose()
{
bool accepted = false;
@@ -1436,7 +1445,6 @@ void QCocoaWindow::syncWindowState(Qt::WindowState newState)
{
if (!m_nsWindow)
return;
-
// if content view width or height is 0 then the window animations will crash so
// do nothing except set the new state
NSRect contentRect = [contentView() frame];
@@ -1446,9 +1454,7 @@ void QCocoaWindow::syncWindowState(Qt::WindowState newState)
return;
}
- if ((m_synchedWindowState & Qt::WindowMaximized) != (newState & Qt::WindowMaximized)) {
- [m_nsWindow performZoom : m_nsWindow]; // toggles
- }
+ Qt::WindowState predictedState = newState;
if ((m_synchedWindowState & Qt::WindowMinimized) != (newState & Qt::WindowMinimized)) {
if (newState & Qt::WindowMinimized) {
@@ -1458,12 +1464,26 @@ void QCocoaWindow::syncWindowState(Qt::WindowState newState)
}
}
+ if ((m_synchedWindowState & Qt::WindowMaximized) != (newState & Qt::WindowMaximized) || (m_effectivelyMaximized && newState == Qt::WindowNoState)) {
+ if ((m_synchedWindowState & Qt::WindowFullScreen) == (newState & Qt::WindowFullScreen)) {
+ [m_nsWindow performZoom : m_nsWindow]; // toggles
+ m_effectivelyMaximized = !m_effectivelyMaximized;
+ } else if (!(newState & Qt::WindowMaximized)) {
+ // it would be nice to change the target geometry that toggleFullScreen will animate toward
+ // but there is no known way, so the maximized state is not possible at this time
+ predictedState = static_cast<Qt::WindowState>(static_cast<int>(newState) | Qt::WindowMaximized);
+ m_effectivelyMaximized = true;
+ }
+ }
+
if ((m_synchedWindowState & Qt::WindowFullScreen) != (newState & Qt::WindowFullScreen)) {
bool fakeFullScreen = true;
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
if (QSysInfo::QSysInfo::MacintoshVersion >= QSysInfo::MV_10_7) {
if (window()->flags() & Qt::WindowFullscreenButtonHint) {
fakeFullScreen = false;
+ if (m_effectivelyMaximized && m_synchedWindowState == Qt::WindowFullScreen)
+ predictedState = Qt::WindowMaximized;
[m_nsWindow toggleFullScreen : m_nsWindow];
}
}
@@ -1490,8 +1510,12 @@ void QCocoaWindow::syncWindowState(Qt::WindowState newState)
}
}
+#ifdef QT_COCOA_ENABLE_WINDOW_DEBUG
+ qDebug() << "QCocoaWindow::syncWindowState" << newState << "actual" << predictedState << "was" << m_synchedWindowState << "effectively maximized" << m_effectivelyMaximized;
+#endif
+
// New state is now the current synched state
- m_synchedWindowState = newState;
+ m_synchedWindowState = predictedState;
}
bool QCocoaWindow::setWindowModified(bool modified)
diff --git a/src/plugins/platforms/cocoa/qnsview.mm b/src/plugins/platforms/cocoa/qnsview.mm
index 47081ab890..1197aa9148 100644
--- a/src/plugins/platforms/cocoa/qnsview.mm
+++ b/src/plugins/platforms/cocoa/qnsview.mm
@@ -281,6 +281,12 @@ static QTouchDevice *touchDevice = 0;
- (void)notifyWindowStateChanged:(Qt::WindowState)newState
{
+ // If the window was maximized, then fullscreen, then tried to go directly to "normal" state,
+ // this notification will say that it is "normal", but it will still look maximized, and
+ // if you called performZoom it would actually take it back to "normal".
+ // So we should say that it is maximized because it actually is.
+ if (newState == Qt::WindowNoState && m_platformWindow->m_effectivelyMaximized)
+ newState = Qt::WindowMaximized;
QWindowSystemInterface::handleWindowStateChanged(m_window, newState);
// We want to read the window state back from the window,
// but the event we just sent may be asynchronous.
@@ -346,6 +352,8 @@ static QTouchDevice *touchDevice = 0;
- (void)notifyWindowWillZoom:(BOOL)willZoom
{
Qt::WindowState newState = willZoom ? Qt::WindowMaximized : Qt::WindowNoState;
+ if (!willZoom)
+ m_platformWindow->m_effectivelyMaximized = false;
[self notifyWindowStateChanged:newState];
}
diff --git a/src/plugins/platforms/cocoa/qnsviewaccessibility.mm b/src/plugins/platforms/cocoa/qnsviewaccessibility.mm
index a438950a55..31e3e343b9 100644
--- a/src/plugins/platforms/cocoa/qnsviewaccessibility.mm
+++ b/src/plugins/platforms/cocoa/qnsviewaccessibility.mm
@@ -54,6 +54,15 @@
@implementation QNSView (QNSViewAccessibility)
+- (id)childAccessibleElement {
+ if (!m_window->accessibleRoot())
+ return nil;
+
+ QAccessible::Id childId = QAccessible::uniqueId(m_window->accessibleRoot());
+ QCocoaAccessibleElement *child = [QCocoaAccessibleElement createElementWithId: childId parent: self];
+ return [child autorelease];
+}
+
// The QNSView is a container that the user does not interact directly with:
// Remove it from the user-visible accessibility tree.
- (BOOL)accessibilityIsIgnored {
@@ -61,58 +70,22 @@
}
- (id)accessibilityAttributeValue:(NSString *)attribute {
-
// activate accessibility updates
QCocoaIntegration::instance()->accessibility()->setActive(true);
- if ([attribute isEqualToString:NSAccessibilityRoleAttribute]) {
- if (m_window->accessibleRoot())
- return QCocoaAccessible::macRole(m_window->accessibleRoot());
- return NSAccessibilityUnknownRole;
- } else if ([attribute isEqualToString:NSAccessibilityRoleDescriptionAttribute]) {
- return NSAccessibilityRoleDescriptionForUIElement(self);
- } else if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
- if (!m_window->accessibleRoot())
- return [super accessibilityAttributeValue:attribute];
- return QCocoaAccessible::unignoredChildren(self, m_window->accessibleRoot());
+ if ([attribute isEqualToString:NSAccessibilityChildrenAttribute]) {
+ return NSAccessibilityUnignoredChildrenForOnlyChild([self childAccessibleElement]);
} else {
return [super accessibilityAttributeValue:attribute];
}
}
- (id)accessibilityHitTest:(NSPoint)point {
- if (!m_window->accessibleRoot())
- return [super accessibilityHitTest:point];
-
- QAccessibleInterface *childInterface = m_window->accessibleRoot()->childAt(point.x, qt_mac_flipYCoordinate(point.y));
- // No child found, meaning we hit the NSView
- if (!childInterface) {
- return [super accessibilityHitTest:point];
- }
-
- // Hit a child, forward to child accessible interface.
- QAccessible::Id childAxid = QAccessible::uniqueId(childInterface);
- // FIXME: parent could be wrong
- QCocoaAccessibleElement *accessibleElement = [QCocoaAccessibleElement createElementWithId:childAxid parent:self ];
- [accessibleElement autorelease];
- return [accessibleElement accessibilityHitTest:point];
+ return [[self childAccessibleElement] accessibilityHitTest: point];
}
- (id)accessibilityFocusedUIElement {
- if (!m_window->accessibleRoot())
- return [super accessibilityFocusedUIElement];
-
- QAccessibleInterface *childInterface = m_window->accessibleRoot()->focusChild();
- if (childInterface) {
- QAccessible::Id childAxid = QAccessible::uniqueId(childInterface);
- // FIXME: parent could be wrong
- QCocoaAccessibleElement *accessibleElement = [QCocoaAccessibleElement createElementWithId:childAxid parent:self];
- [accessibleElement autorelease];
- return accessibleElement;
- }
-
- // should not happen
- return nil;
+ return [[self childAccessibleElement] accessibilityFocusedUIElement];
}
@end
diff --git a/src/plugins/platforms/cocoa/qnswindowdelegate.mm b/src/plugins/platforms/cocoa/qnswindowdelegate.mm
index c9b3d69381..d9509098c6 100644
--- a/src/plugins/platforms/cocoa/qnswindowdelegate.mm
+++ b/src/plugins/platforms/cocoa/qnswindowdelegate.mm
@@ -75,6 +75,14 @@
}
}
+- (void)windowDidEndLiveResize:(NSNotification *)notification
+{
+ Q_UNUSED(notification);
+ if (m_cocoaWindow) {
+ m_cocoaWindow->windowDidEndLiveResize();
+ }
+}
+
- (void)windowWillMove:(NSNotification *)notification
{
Q_UNUSED(notification);
diff --git a/src/plugins/platforms/eglfs/qeglfscontext.cpp b/src/plugins/platforms/eglfs/qeglfscontext.cpp
index 9083abc562..4d443b91e3 100644
--- a/src/plugins/platforms/eglfs/qeglfscontext.cpp
+++ b/src/plugins/platforms/eglfs/qeglfscontext.cpp
@@ -53,8 +53,8 @@
QT_BEGIN_NAMESPACE
QEglFSContext::QEglFSContext(const QSurfaceFormat &format, QPlatformOpenGLContext *share, EGLDisplay display)
- : QEGLPlatformContext(QEglFSHooks::hooks()->surfaceFormatFor(format), share, display,
- QEglFSIntegration::chooseConfig(display, QEglFSHooks::hooks()->surfaceFormatFor(format)))
+ : QEGLPlatformContext(format, share, display,
+ QEglFSIntegration::chooseConfig(display, format))
{
}
diff --git a/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp b/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp
index dfb766db32..4aa3f29260 100644
--- a/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp
+++ b/src/plugins/platforms/eglfs/qeglfshooks_stub.cpp
@@ -141,7 +141,16 @@ QImage::Format QEglFSHooks::screenFormat() const
QSurfaceFormat QEglFSHooks::surfaceFormatFor(const QSurfaceFormat &inputFormat) const
{
- return inputFormat;
+ QSurfaceFormat format = inputFormat;
+
+ static const bool force888 = qgetenv("QT_QPA_EGLFS_FORCE888").toInt();
+ if (force888) {
+ format.setRedBufferSize(8);
+ format.setGreenBufferSize(8);
+ format.setBlueBufferSize(8);
+ }
+
+ return format;
}
bool QEglFSHooks::filterConfig(EGLDisplay, EGLConfig) const
diff --git a/src/plugins/platforms/ios/qioscontext.h b/src/plugins/platforms/ios/qioscontext.h
index c48a0251a9..52357a5d58 100644
--- a/src/plugins/platforms/ios/qioscontext.h
+++ b/src/plugins/platforms/ios/qioscontext.h
@@ -85,10 +85,12 @@ private:
GLuint depthRenderbuffer;
GLint renderbufferWidth;
GLint renderbufferHeight;
+ bool isComplete;
};
static void deleteBuffers(const FramebufferObject &framebufferObject);
+ FramebufferObject &backingFramebufferObjectFor(QPlatformSurface *) const;
mutable QHash<QIOSWindow *, FramebufferObject> m_framebufferObjects;
};
diff --git a/src/plugins/platforms/ios/qioscontext.mm b/src/plugins/platforms/ios/qioscontext.mm
index 7310d2904f..ddee52196a 100644
--- a/src/plugins/platforms/ios/qioscontext.mm
+++ b/src/plugins/platforms/ios/qioscontext.mm
@@ -94,14 +94,38 @@ QSurfaceFormat QIOSContext::format() const
return m_format;
}
+#define QT_IOS_GL_STATUS_CASE(val) case val: return QLatin1Literal(#val)
+
+static QString fboStatusString(GLenum status)
+{
+ switch (status) {
+ QT_IOS_GL_STATUS_CASE(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT);
+ QT_IOS_GL_STATUS_CASE(GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS);
+ QT_IOS_GL_STATUS_CASE(GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT);
+ QT_IOS_GL_STATUS_CASE(GL_FRAMEBUFFER_UNSUPPORTED);
+ default:
+ return QString(QStringLiteral("unknown status: %x")).arg(status);
+ }
+}
+
bool QIOSContext::makeCurrent(QPlatformSurface *surface)
{
Q_ASSERT(surface && surface->surface()->surfaceType() == QSurface::OpenGLSurface);
[EAGLContext setCurrentContext:m_eaglContext];
- glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebufferObject(surface));
- return true;
+ // For offscreen surfaces we don't prepare a default FBO
+ if (surface->surface()->surfaceClass() == QSurface::Offscreen)
+ return true;
+
+ FramebufferObject &framebufferObject = backingFramebufferObjectFor(surface);
+
+ // We bind the default FBO even if it's incomplete, so that clients who
+ // call glCheckFramebufferStatus as a result of this function returning
+ // false will get a matching error code.
+ glBindFramebuffer(GL_FRAMEBUFFER, framebufferObject.handle);
+
+ return framebufferObject.isComplete;
}
void QIOSContext::doneCurrent()
@@ -112,17 +136,26 @@ void QIOSContext::doneCurrent()
void QIOSContext::swapBuffers(QPlatformSurface *surface)
{
Q_ASSERT(surface && surface->surface()->surfaceType() == QSurface::OpenGLSurface);
- Q_ASSERT(surface->surface()->surfaceClass() == QSurface::Window);
- QIOSWindow *window = static_cast<QIOSWindow *>(surface);
- Q_ASSERT(m_framebufferObjects.contains(window));
+
+ if (surface->surface()->surfaceClass() == QSurface::Offscreen)
+ return; // Nothing to do
+
+ FramebufferObject &framebufferObject = backingFramebufferObjectFor(surface);
[EAGLContext setCurrentContext:m_eaglContext];
- glBindRenderbuffer(GL_RENDERBUFFER, m_framebufferObjects[window].colorRenderbuffer);
+ glBindRenderbuffer(GL_RENDERBUFFER, framebufferObject.colorRenderbuffer);
[m_eaglContext presentRenderbuffer:GL_RENDERBUFFER];
}
-GLuint QIOSContext::defaultFramebufferObject(QPlatformSurface *surface) const
+QIOSContext::FramebufferObject &QIOSContext::backingFramebufferObjectFor(QPlatformSurface *surface) const
{
+ // We keep track of default-FBOs in the root context of a share-group. This assumes
+ // that the contexts form a tree, where leaf nodes are always destroyed before their
+ // parents. If that assumption (based on the current implementation) doesn't hold we
+ // should probably use QOpenGLMultiGroupSharedResource to track the shared default-FBOs.
+ if (m_sharedContext)
+ return m_sharedContext->backingFramebufferObjectFor(surface);
+
Q_ASSERT(surface && surface->surface()->surfaceClass() == QSurface::Window);
QIOSWindow *window = static_cast<QIOSWindow *>(surface);
@@ -181,11 +214,27 @@ GLuint QIOSContext::defaultFramebufferObject(QPlatformSurface *surface) const
framebufferObject.renderbufferWidth, framebufferObject.renderbufferHeight);
}
- if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
- NSLog(@"Failed to make complete framebuffer object %x", glCheckFramebufferStatus(GL_FRAMEBUFFER));
+ framebufferObject.isComplete = glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE;
+
+ if (!framebufferObject.isComplete) {
+ qWarning("QIOSContext failed to make complete framebuffer object (%s)",
+ qPrintable(fboStatusString(glCheckFramebufferStatus(GL_FRAMEBUFFER))));
+ }
+ }
+
+ return framebufferObject;
+}
+
+GLuint QIOSContext::defaultFramebufferObject(QPlatformSurface *surface) const
+{
+ if (surface->surface()->surfaceClass() == QSurface::Offscreen) {
+ // Binding and rendering to the zero-FBO on iOS seems to be
+ // no-ops, so we can safely return 0 here, even if it's not
+ // really a valid FBO on iOS.
+ return 0;
}
- return framebufferObject.handle;
+ return backingFramebufferObjectFor(surface).handle;
}
void QIOSContext::windowDestroyed(QObject *object)
diff --git a/src/plugins/platforms/ios/qiosinputcontext.mm b/src/plugins/platforms/ios/qiosinputcontext.mm
index 13a0b46745..9a2c55f7f2 100644
--- a/src/plugins/platforms/ios/qiosinputcontext.mm
+++ b/src/plugins/platforms/ios/qiosinputcontext.mm
@@ -47,6 +47,7 @@
#include "qioswindow.h"
#include "quiview.h"
#include <QGuiApplication>
+#include <QtGui/private/qwindow_p.h>
@interface QIOSKeyboardListener : UIGestureRecognizer {
@public
@@ -54,6 +55,8 @@
BOOL m_keyboardVisible;
BOOL m_keyboardVisibleAndDocked;
BOOL m_ignoreKeyboardChanges;
+ BOOL m_touchPressWhileKeyboardVisible;
+ BOOL m_keyboardHiddenByGesture;
QRectF m_keyboardRect;
QRectF m_keyboardEndRect;
NSTimeInterval m_duration;
@@ -72,6 +75,8 @@
m_keyboardVisible = NO;
m_keyboardVisibleAndDocked = NO;
m_ignoreKeyboardChanges = NO;
+ m_touchPressWhileKeyboardVisible = NO;
+ m_keyboardHiddenByGesture = NO;
m_duration = 0;
m_curve = UIViewAnimationCurveEaseOut;
m_viewController = 0;
@@ -145,9 +150,6 @@
- (void) keyboardDidChangeFrame:(NSNotification *)notification
{
Q_UNUSED(notification);
- if (m_ignoreKeyboardChanges)
- return;
-
[self handleKeyboardRectChanged];
// If the keyboard was visible and docked from before, this is just a geometry
@@ -178,7 +180,11 @@
// Note that UIKeyboardWillHideNotification is also sendt when the keyboard is undocked.
m_keyboardVisibleAndDocked = NO;
m_keyboardEndRect = [self getKeyboardRect:notification];
- self.enabled = NO;
+ if (!m_keyboardHiddenByGesture) {
+ // 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.
+ self.enabled = NO;
+ }
m_context->scroll(0);
}
@@ -201,12 +207,45 @@
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
QPointF p = fromCGPoint([[touches anyObject] locationInView:m_viewController.view]);
- if (m_keyboardRect.contains(p))
+ if (m_keyboardRect.contains(p)) {
+ m_keyboardHiddenByGesture = YES;
m_context->hideInputPanel();
+ }
[super touchesMoved:touches withEvent:event];
}
+- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
+{
+ Q_ASSERT(m_keyboardVisibleAndDocked);
+ m_touchPressWhileKeyboardVisible = YES;
+ [super touchesBegan:touches withEvent:event];
+}
+
+- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
+{
+ m_touchPressWhileKeyboardVisible = NO;
+ [self performSelectorOnMainThread:@selector(touchesEndedPostDelivery) withObject:nil waitUntilDone:NO];
+ [super touchesEnded:touches withEvent:event];
+}
+
+- (void)touchesEndedPostDelivery
+{
+ // Do some clean-up _after_ touchEnd has been delivered to QUIView
+ m_keyboardHiddenByGesture = NO;
+ if (!m_keyboardVisibleAndDocked) {
+ self.enabled = NO;
+ if (qApp->focusObject()) {
+ // UI Controls are told to gain focus on touch release. So when the 'hide keyboard' gesture
+ // finishes, the final touch end can trigger a control to gain focus. This is in conflict with
+ // the gesture, so we clear focus once more as a work-around.
+ static_cast<QWindowPrivate *>(QObjectPrivate::get(qApp->focusWindow()))->clearFocusObject();
+ }
+ } else {
+ m_context->scrollToCursor();
+ }
+}
+
@end
QIOSInputContext::QIOSInputContext()
@@ -233,6 +272,12 @@ QRectF QIOSInputContext::keyboardRect() const
void QIOSInputContext::showInputPanel()
{
+ if (m_keyboardListener->m_keyboardHiddenByGesture) {
+ // We refuse to re-show the keyboard until the touch
+ // sequence that triggered the gesture has ended.
+ return;
+ }
+
// Documentation tells that one should call (and recall, if necessary) becomeFirstResponder/resignFirstResponder
// to show/hide the keyboard. This is slightly inconvenient, since there exist no API to get the current first
// responder. Rather than searching for it from the top, we let the active QIOSWindow tell us which view to use.
@@ -306,6 +351,13 @@ void QIOSInputContext::scrollToCursor()
if (!isQtApplication() || !m_focusView)
return;
+ if (m_keyboardListener->m_touchPressWhileKeyboardVisible) {
+ // Don't scroll to the cursor if the user is touching the screen. This
+ // interferes with selection and the 'hide keyboard' gesture. Instead
+ // we update scrolling upon touchEnd.
+ return;
+ }
+
UIView *view = m_keyboardListener->m_viewController.view;
if (view.window != m_focusView.window)
return;
@@ -332,7 +384,7 @@ void QIOSInputContext::scroll(int y)
newBounds.origin.y = y;
QPointer<QIOSInputContext> self = this;
[UIView animateWithDuration:m_keyboardListener->m_duration delay:0
- options:m_keyboardListener->m_curve
+ options:m_keyboardListener->m_curve | UIViewAnimationOptionBeginFromCurrentState
animations:^{ view.bounds = newBounds; }
completion:^(BOOL){
if (self)
diff --git a/src/plugins/platforms/ios/qiosintegration.h b/src/plugins/platforms/ios/qiosintegration.h
index a28926ff99..956c112399 100644
--- a/src/plugins/platforms/ios/qiosintegration.h
+++ b/src/plugins/platforms/ios/qiosintegration.h
@@ -64,6 +64,7 @@ public:
QPlatformBackingStore *createPlatformBackingStore(QWindow *window) const;
QPlatformOpenGLContext *createPlatformOpenGLContext(QOpenGLContext *context) const;
+ QPlatformOffscreenSurface *createPlatformOffscreenSurface(QOffscreenSurface *surface) const Q_DECL_OVERRIDE;
QPlatformFontDatabase *fontDatabase() const;
QPlatformClipboard *clipboard() const;
diff --git a/src/plugins/platforms/ios/qiosintegration.mm b/src/plugins/platforms/ios/qiosintegration.mm
index 7a40e349c9..0fe7adff9f 100644
--- a/src/plugins/platforms/ios/qiosintegration.mm
+++ b/src/plugins/platforms/ios/qiosintegration.mm
@@ -51,6 +51,8 @@
#include "qiostheme.h"
#include "qiosservices.h"
+#include <qpa/qplatformoffscreensurface.h>
+
#include <QtPlatformSupport/private/qcoretextfontdatabase_p.h>
#include <QtPlatformSupport/private/qmacmime_p.h>
#include <QDir>
@@ -144,6 +146,11 @@ QPlatformOpenGLContext *QIOSIntegration::createPlatformOpenGLContext(QOpenGLCont
return new QIOSContext(context);
}
+QPlatformOffscreenSurface *QIOSIntegration::createPlatformOffscreenSurface(QOffscreenSurface *surface) const
+{
+ return new QPlatformOffscreenSurface(surface);
+}
+
QAbstractEventDispatcher *QIOSIntegration::createEventDispatcher() const
{
if (isQtApplication())
diff --git a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
index aca8d76041..72d5833e73 100644
--- a/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
+++ b/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp
@@ -360,7 +360,7 @@ bool QLinuxFbScreen::initialize()
// Open the device
mFbFd = openFramebufferDevice(fbDevice);
if (mFbFd == -1) {
- qWarning("Failed to open framebuffer %s : %s", qPrintable(fbDevice), strerror(errno));
+ qErrnoWarning(errno, "Failed to open framebuffer %s", qPrintable(fbDevice));
return false;
}
@@ -371,12 +371,12 @@ bool QLinuxFbScreen::initialize()
memset(&finfo, 0, sizeof(finfo));
if (ioctl(mFbFd, FBIOGET_FSCREENINFO, &finfo) != 0) {
- qWarning("Error reading fixed information: %s", strerror(errno));
+ qErrnoWarning(errno, "Error reading fixed information");
return false;
}
if (ioctl(mFbFd, FBIOGET_VSCREENINFO, &vinfo)) {
- qWarning("Error reading variable information: %s", strerror(errno));
+ qErrnoWarning(errno, "Error reading variable information");
return false;
}
@@ -391,7 +391,7 @@ bool QLinuxFbScreen::initialize()
mMmap.size = finfo.smem_len;
uchar *data = (unsigned char *)mmap(0, mMmap.size, PROT_READ | PROT_WRITE, MAP_SHARED, mFbFd, 0);
if ((long)data == -1) {
- qWarning("Failed to mmap framebuffer: %s", strerror(errno));
+ qErrnoWarning(errno, "Failed to mmap framebuffer");
return false;
}
@@ -420,10 +420,12 @@ bool QLinuxFbScreen::initialize()
mTtyFd = openTtyDevice(ttyDevice);
if (mTtyFd == -1)
- qWarning() << "Failed to open tty" << strerror(errno);
+ qErrnoWarning(errno, "Failed to open tty");
- if (doSwitchToGraphicsMode && !switchToGraphicsMode(mTtyFd, &mOldTtyMode))
- qWarning() << "Failed to set graphics mode" << strerror(errno);
+ if (doSwitchToGraphicsMode)
+ switchToGraphicsMode(mTtyFd, &mOldTtyMode);
+ // Do not warn if the switch fails: the ioctl fails when launching from
+ // a remote console and there is nothing we can do about it.
blankScreen(mFbFd, false);
diff --git a/src/plugins/platforms/qnx/qqnxfilepicker.cpp b/src/plugins/platforms/qnx/qqnxfilepicker.cpp
index 830b110f2a..08119ce0ae 100644
--- a/src/plugins/platforms/qnx/qqnxfilepicker.cpp
+++ b/src/plugins/platforms/qnx/qqnxfilepicker.cpp
@@ -130,9 +130,9 @@ void QQnxFilePicker::open()
map[QStringLiteral("AllowOverwrite")] = false;
if (!m_defaultSaveFileNames.isEmpty())
- map[QStringLiteral("DefaultFileNames")] = m_defaultSaveFileNames.join(",");
+ map[QStringLiteral("DefaultFileNames")] = m_defaultSaveFileNames.join(QLatin1Char(','));
if (!m_filters.isEmpty())
- map[QStringLiteral("Filter")] = m_filters.join(";");
+ map[QStringLiteral("Filter")] = m_filters.join(QLatin1Char(';'));
QByteArray ppsData;
#if defined(Q_OS_BLACKBERRY_TABLET)
@@ -288,8 +288,8 @@ QString QQnxFilePicker::filePickerType() const
bool video = false;
bool music = false;
QMimeDatabase mimeDb;
- for (int i = 0; i < filters().count(); i++) {
- QList<QMimeType> mimeTypes = mimeDb.mimeTypesForFileName(filters().at(i));
+ for (int i = 0; i < m_filters.count(); i++) {
+ QList<QMimeType> mimeTypes = mimeDb.mimeTypesForFileName(m_filters.at(i));
if (mimeTypes.isEmpty())
return QStringLiteral("Other");
diff --git a/src/plugins/platforms/qnx/qqnxscreen.cpp b/src/plugins/platforms/qnx/qqnxscreen.cpp
index a6c69164c7..2707f14db2 100644
--- a/src/plugins/platforms/qnx/qqnxscreen.cpp
+++ b/src/plugins/platforms/qnx/qqnxscreen.cpp
@@ -177,6 +177,11 @@ QQnxScreen::QQnxScreen(screen_context_t screenContext, screen_display_t display,
m_currentGeometry = m_initialGeometry = QRect(0, 0, val[0], val[1]);
+ char name[100];
+ Q_SCREEN_CHECKERROR(screen_get_display_property_cv(m_display, SCREEN_PROPERTY_ID_STRING, 100,
+ name), "Failed to query display name");
+ m_name = QString::fromUtf8(name);
+
// Cache size of this display in millimeters. We have to take care of the orientation.
// libscreen always reports the physical size dimensions as width and height in the
// native orientation. Contrary to this, QPlatformScreen::physicalSize() expects the
diff --git a/src/plugins/platforms/qnx/qqnxscreen.h b/src/plugins/platforms/qnx/qqnxscreen.h
index d39a210d4b..a0b760135f 100644
--- a/src/plugins/platforms/qnx/qqnxscreen.h
+++ b/src/plugins/platforms/qnx/qqnxscreen.h
@@ -77,6 +77,8 @@ public:
int rotation() const { return m_currentRotation; }
+ QString name() const { return m_name; }
+
int nativeFormat() const { return (depth() == 32) ? SCREEN_FORMAT_RGBA8888 : SCREEN_FORMAT_RGB565; }
screen_display_t nativeDisplay() const { return m_display; }
screen_context_t nativeContext() const { return m_screenContext; }
@@ -132,6 +134,7 @@ private:
int m_initialRotation;
int m_currentRotation;
int m_keyboardHeight;
+ QString m_name;
QSize m_initialPhysicalSize;
QSize m_currentPhysicalSize;
Qt::ScreenOrientation m_nativeOrientation;
diff --git a/src/plugins/platforms/qnx/qqnxwindow.cpp b/src/plugins/platforms/qnx/qqnxwindow.cpp
index f11a009bca..42318729b1 100644
--- a/src/plugins/platforms/qnx/qqnxwindow.cpp
+++ b/src/plugins/platforms/qnx/qqnxwindow.cpp
@@ -709,12 +709,12 @@ void QQnxWindow::initWindow()
if (window()->parent() && window()->parent()->handle())
setParent(window()->parent()->handle());
- if (shouldMakeFullScreen()) {
+ if (shouldMakeFullScreen())
setGeometryHelper(screen()->geometry());
- QWindowSystemInterface::handleGeometryChange(window(), screen()->geometry());
- } else {
+ else
setGeometryHelper(window()->geometry());
- }
+
+ QWindowSystemInterface::handleGeometryChange(window(), screen()->geometry());
}
void QQnxWindow::createWindowGroup()
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
index 8f9ddc2168..1432dfdcd9 100644
--- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp
@@ -1040,8 +1040,7 @@ QWindowsFontDatabase::~QWindowsFontDatabase()
QFontEngineMulti *QWindowsFontDatabase::fontEngineMulti(QFontEngine *fontEngine, QChar::Script script)
{
- Q_UNUSED(script)
- return new QWindowsMultiFontEngine(fontEngine, QStringList());
+ return new QWindowsMultiFontEngine(fontEngine, script);
}
QFontEngine * QWindowsFontDatabase::fontEngine(const QFontDef &fontDef, void *handle)
diff --git a/src/plugins/platforms/windows/qwindowsfontengine.cpp b/src/plugins/platforms/windows/qwindowsfontengine.cpp
index c3774064e3..4f3a007bd7 100644
--- a/src/plugins/platforms/windows/qwindowsfontengine.cpp
+++ b/src/plugins/platforms/windows/qwindowsfontengine.cpp
@@ -1278,35 +1278,14 @@ void QWindowsFontEngine::initFontInfo(const QFontDef &request,
Will probably be superseded by a common Free Type font engine in Qt 5.X.
*/
-
-QWindowsMultiFontEngine::QWindowsMultiFontEngine(QFontEngine *first, const QStringList &fallbacks)
- : QFontEngineMulti(fallbacks.size() + 1),
- fallbackFamilies(fallbacks)
-{
- engines[0] = first;
- first->ref.ref();
- fontDef = engines[0]->fontDef;
- cache_cost = first->cache_cost;
-}
-
-void QWindowsMultiFontEngine::setFallbackFamiliesList(const QStringList &fallbacks)
+QWindowsMultiFontEngine::QWindowsMultiFontEngine(QFontEngine *fe, int script)
+ : QFontEngineMultiQPA(fe, script)
{
- // Original FontEngine to restore after the fill.
- QFontEngine *fe = engines[0];
- fallbackFamilies = fallbacks;
- if (!fallbackFamilies.isEmpty()) {
- engines.fill(0, fallbackFamilies.size() + 1);
- engines[0] = fe;
- } else {
- // Turns out we lied about having any fallback at all.
- fallbackFamilies << fe->fontDef.family;
- engines[1] = fe;
- fe->ref.ref();
- }
}
void QWindowsMultiFontEngine::loadEngine(int at)
{
+ ensureFallbackFamiliesQueried();
Q_ASSERT(at < engines.size());
Q_ASSERT(engines.at(at) == 0);
@@ -1329,7 +1308,7 @@ void QWindowsMultiFontEngine::loadEngine(int at)
data = fe->fontEngineData();
}
- const QString fam = fallbackFamilies.at(at-1);
+ const QString fam = fallbackFamilyAt(at - 1);
memcpy(lf.lfFaceName, fam.utf16(), sizeof(wchar_t) * qMin(fam.length() + 1, 32)); // 32 = Windows hard-coded
#ifndef QT_NO_DIRECTWRITE
diff --git a/src/plugins/platforms/windows/qwindowsfontengine.h b/src/plugins/platforms/windows/qwindowsfontengine.h
index 7d93484220..7a0803830c 100644
--- a/src/plugins/platforms/windows/qwindowsfontengine.h
+++ b/src/plugins/platforms/windows/qwindowsfontengine.h
@@ -53,7 +53,7 @@
// We mean it.
//
-#include <QtGui/private/qfontengine_p.h>
+#include <QtGui/private/qfontengine_qpa_p.h>
#include <QtGui/QImage>
#include <QtCore/QSharedPointer>
@@ -166,15 +166,13 @@ private:
mutable int designAdvancesSize;
};
-class QWindowsMultiFontEngine : public QFontEngineMulti
+
+class QWindowsMultiFontEngine : public QFontEngineMultiQPA
{
public:
- QWindowsMultiFontEngine(QFontEngine *first, const QStringList &fallbacks);
+ explicit QWindowsMultiFontEngine(QFontEngine *fe, int script);
- void setFallbackFamiliesList(const QStringList &fallbacks);
void loadEngine(int at);
-
- QStringList fallbackFamilies;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index 274366d4fe..00229a7540 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -1365,9 +1365,10 @@ void QWindowsWindow::handleResized(int wParam)
handleGeometryChange();
break;
case SIZE_RESTORED:
- bool fullScreen = isFullScreen_sys();
- if ((m_windowState != Qt::WindowNoState) || fullScreen)
- handleWindowStateChange(fullScreen ? Qt::WindowFullScreen : Qt::WindowNoState);
+ if (isFullScreen_sys())
+ handleWindowStateChange(Qt::WindowFullScreen);
+ else if (m_windowState != Qt::WindowNoState && !testFlag(MaximizeToFullScreen))
+ handleWindowStateChange(Qt::WindowNoState);
handleGeometryChange();
break;
}
@@ -1623,8 +1624,11 @@ void QWindowsWindow::setWindowState_sys(Qt::WindowState newState)
if ((oldState == Qt::WindowMaximized) != (newState == Qt::WindowMaximized)) {
if (visible && !(newState == Qt::WindowMinimized)) {
setFlag(WithinMaximize);
+ if (newState == Qt::WindowFullScreen)
+ setFlag(MaximizeToFullScreen);
ShowWindow(m_data.hwnd, (newState == Qt::WindowMaximized) ? SW_MAXIMIZE : SW_SHOWNOACTIVATE);
clearFlag(WithinMaximize);
+ clearFlag(MaximizeToFullScreen);
}
}
diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h
index ba0f22bb0a..cb437b76d0 100644
--- a/src/plugins/platforms/windows/qwindowswindow.h
+++ b/src/plugins/platforms/windows/qwindowswindow.h
@@ -153,7 +153,8 @@ public:
AlertState = 0x8000,
Exposed = 0x10000,
WithinCreate = 0x20000,
- WithinMaximize = 0x40000
+ WithinMaximize = 0x40000,
+ MaximizeToFullScreen = 0x80000
};
QWindowsWindow(QWindow *window, const QWindowsWindowData &data);
diff --git a/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp b/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp
index 3da87de708..70bb9469db 100644
--- a/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp
+++ b/src/plugins/platforms/winrt/qwinrtfontdatabase.cpp
@@ -63,7 +63,7 @@ QString QWinRTFontDatabase::fontDir() const
fontDirectory = applicationDirPath + QLatin1String("/fonts");
if (!QFile::exists(fontDirectory)) {
#ifndef Q_OS_WINPHONE
- if (m_fonts.isEmpty())
+ if (m_fontFamilies.isEmpty())
#endif
qWarning("No fonts directory found in application package.");
fontDirectory = applicationDirPath;
@@ -78,6 +78,9 @@ QWinRTFontDatabase::~QWinRTFontDatabase()
{
foreach (IDWriteFontFile *fontFile, m_fonts.keys())
fontFile->Release();
+
+ foreach (IDWriteFontFamily *fontFamily, m_fontFamilies)
+ fontFamily->Release();
}
QFont QWinRTFontDatabase::defaultFont() const
@@ -132,175 +135,196 @@ void QWinRTFontDatabase::populateFontDatabase()
}
QString familyName = QString::fromWCharArray(familyBuffer.data(), familyNameLength);
- int fontCount = fontFamily->GetFontCount();
- for (int j = 0; j < fontCount; ++j) {
- ComPtr<IDWriteFont> font;
- hr = fontFamily->GetFont(j, &font);
- if (FAILED(hr)) {
- qWarning("Unable to get base font: %s", qPrintable(qt_error_string(hr)));
- continue;
- }
+ m_fontFamilies.insert(familyName, fontFamily.Detach());
- ComPtr<IDWriteFontFace> baseFontFace;
- hr = font->CreateFontFace(&baseFontFace);
- if (FAILED(hr)) {
- qWarning("Unable to create base font face: %s", qPrintable(qt_error_string(hr)));
- continue;
- }
- ComPtr<IDWriteFontFace1> fontFace;
- hr = baseFontFace.As(&fontFace);
- if (FAILED(hr)) {
- qWarning("Unable to create font face: %s", qPrintable(qt_error_string(hr)));
- continue;
- }
+ registerFontFamily(familyName);
+ }
- // Only try to load true-type fonts
- DWRITE_FONT_FACE_TYPE type = fontFace->GetType();
- if (!(type == DWRITE_FONT_FACE_TYPE_TRUETYPE
- || type == DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION)) {
- continue;
- }
+ QBasicFontDatabase::populateFontDatabase();
+}
- // We can't deal with multi-file fonts
- quint32 fileCount;
- hr = fontFace->GetFiles(&fileCount, NULL);
- if (FAILED(hr)) {
- qWarning("Unable to get font file count: %s", qPrintable(qt_error_string(hr)));
- continue;
- }
- if (fileCount != 1) // Should not happen as we only look at TT fonts
- continue;
-
- ComPtr<IDWriteLocalizedStrings> informationalStrings;
- BOOL exists;
- hr = font->GetInformationalStrings(DWRITE_INFORMATIONAL_STRING_MANUFACTURER,
- &informationalStrings, &exists);
- if (FAILED(hr)) {
- qWarning("Unable to get font foundry: %s", qPrintable(qt_error_string(hr)));
- continue;
- }
- QString foundryName;
- if (exists) {
- quint32 length;
- hr = informationalStrings->GetStringLength(0, &length);
+void QWinRTFontDatabase::populateFamily(const QString &familyName)
+{
+ IDWriteFontFamily *fontFamily = m_fontFamilies.value(familyName);
+ if (!fontFamily) {
+ qWarning("The font family %s was not found.", qPrintable(familyName));
+ return;
+ }
+
+ bool fontRegistered = false;
+ const int fontCount = fontFamily->GetFontCount();
+ for (int j = 0; j < fontCount; ++j) {
+ ComPtr<IDWriteFont> font;
+ HRESULT hr = fontFamily->GetFont(j, &font);
+ if (FAILED(hr)) {
+ qWarning("Unable to get font: %s", qPrintable(qt_error_string(hr)));
+ continue;
+ }
+
+ // Skip simulated faces
+ if (font->GetSimulations() != DWRITE_FONT_SIMULATIONS_NONE)
+ continue;
+
+ ComPtr<IDWriteFontFace> baseFontFace;
+ hr = font->CreateFontFace(&baseFontFace);
+ if (FAILED(hr)) {
+ qWarning("Unable to create base font face: %s", qPrintable(qt_error_string(hr)));
+ continue;
+ }
+ ComPtr<IDWriteFontFace1> fontFace;
+ hr = baseFontFace.As(&fontFace);
+ if (FAILED(hr)) {
+ qWarning("Unable to create font face: %s", qPrintable(qt_error_string(hr)));
+ continue;
+ }
+
+ // We can't deal with multi-file fonts
+ quint32 fileCount;
+ hr = fontFace->GetFiles(&fileCount, NULL);
+ if (FAILED(hr)) {
+ qWarning("Unable to get font file count: %s", qPrintable(qt_error_string(hr)));
+ continue;
+ }
+ if (fileCount != 1)
+ continue;
+
+ ComPtr<IDWriteLocalizedStrings> informationalStrings;
+ BOOL exists;
+ hr = font->GetInformationalStrings(DWRITE_INFORMATIONAL_STRING_MANUFACTURER,
+ &informationalStrings, &exists);
+ if (FAILED(hr)) {
+ qWarning("Unable to get font foundry: %s", qPrintable(qt_error_string(hr)));
+ continue;
+ }
+ QString foundryName;
+ if (exists) {
+ quint32 length;
+ hr = informationalStrings->GetStringLength(0, &length);
+ if (FAILED(hr))
+ qWarning("Unable to get foundry name length: %s", qPrintable(qt_error_string(hr)));
+ if (SUCCEEDED(hr)) {
+ QVector<wchar_t> buffer(length + 1);
+ hr = informationalStrings->GetString(0, buffer.data(), buffer.size());
if (FAILED(hr))
- qWarning("Unable to get foundry name length: %s", qPrintable(qt_error_string(hr)));
- if (SUCCEEDED(hr)) {
- QVector<wchar_t> buffer(length + 1);
- hr = informationalStrings->GetString(0, buffer.data(), buffer.size());
- if (FAILED(hr))
- qWarning("Unable to get foundry name: %s", qPrintable(qt_error_string(hr)));
- if (SUCCEEDED(hr))
- foundryName = QString::fromWCharArray(buffer.data(), length);
- }
+ qWarning("Unable to get foundry name: %s", qPrintable(qt_error_string(hr)));
+ if (SUCCEEDED(hr))
+ foundryName = QString::fromWCharArray(buffer.data(), length);
}
+ }
- QFont::Weight weight;
- switch (font->GetWeight()) {
- case DWRITE_FONT_WEIGHT_THIN:
- case DWRITE_FONT_WEIGHT_EXTRA_LIGHT:
- case DWRITE_FONT_WEIGHT_LIGHT:
- case DWRITE_FONT_WEIGHT_SEMI_LIGHT:
- weight = QFont::Light;
- break;
- default:
- case DWRITE_FONT_WEIGHT_NORMAL:
- case DWRITE_FONT_WEIGHT_MEDIUM:
- weight = QFont::Normal;
- break;
- case DWRITE_FONT_WEIGHT_DEMI_BOLD:
- weight = QFont::DemiBold;
- break;
- case DWRITE_FONT_WEIGHT_BOLD:
- case DWRITE_FONT_WEIGHT_EXTRA_BOLD:
- weight = QFont::Bold;
- break;
- case DWRITE_FONT_WEIGHT_BLACK:
- case DWRITE_FONT_WEIGHT_EXTRA_BLACK:
- weight = QFont::Black;
- break;
- }
+ QFont::Weight weight;
+ switch (font->GetWeight()) {
+ case DWRITE_FONT_WEIGHT_THIN:
+ case DWRITE_FONT_WEIGHT_EXTRA_LIGHT:
+ case DWRITE_FONT_WEIGHT_LIGHT:
+ case DWRITE_FONT_WEIGHT_SEMI_LIGHT:
+ weight = QFont::Light;
+ break;
+ default:
+ case DWRITE_FONT_WEIGHT_NORMAL:
+ case DWRITE_FONT_WEIGHT_MEDIUM:
+ weight = QFont::Normal;
+ break;
+ case DWRITE_FONT_WEIGHT_DEMI_BOLD:
+ weight = QFont::DemiBold;
+ break;
+ case DWRITE_FONT_WEIGHT_BOLD:
+ case DWRITE_FONT_WEIGHT_EXTRA_BOLD:
+ weight = QFont::Bold;
+ break;
+ case DWRITE_FONT_WEIGHT_BLACK:
+ case DWRITE_FONT_WEIGHT_EXTRA_BLACK:
+ weight = QFont::Black;
+ break;
+ }
- QFont::Style style;
- switch (font->GetStyle()) {
- default:
- case DWRITE_FONT_STYLE_NORMAL:
- style = QFont::StyleNormal;
- break;
- case DWRITE_FONT_STYLE_OBLIQUE:
- style = QFont::StyleOblique;
- break;
- case DWRITE_FONT_STYLE_ITALIC:
- style = QFont::StyleItalic;
- break;
- }
+ QFont::Style style;
+ switch (font->GetStyle()) {
+ default:
+ case DWRITE_FONT_STYLE_NORMAL:
+ style = QFont::StyleNormal;
+ break;
+ case DWRITE_FONT_STYLE_OBLIQUE:
+ style = QFont::StyleOblique;
+ break;
+ case DWRITE_FONT_STYLE_ITALIC:
+ style = QFont::StyleItalic;
+ break;
+ }
- QFont::Stretch stretch;
- switch (font->GetStretch()) {
- default:
- case DWRITE_FONT_STRETCH_UNDEFINED:
- case DWRITE_FONT_STRETCH_NORMAL:
- stretch = QFont::Unstretched;
- break;
- case DWRITE_FONT_STRETCH_ULTRA_CONDENSED:
- stretch = QFont::UltraCondensed;
- break;
- case DWRITE_FONT_STRETCH_EXTRA_CONDENSED:
- stretch = QFont::ExtraCondensed;
- break;
- case DWRITE_FONT_STRETCH_CONDENSED:
- stretch = QFont::Condensed;
- break;
- case DWRITE_FONT_STRETCH_SEMI_CONDENSED:
- stretch = QFont::SemiCondensed;
- break;
- case DWRITE_FONT_STRETCH_SEMI_EXPANDED:
- stretch = QFont::SemiExpanded;
- break;
- case DWRITE_FONT_STRETCH_EXPANDED:
- stretch = QFont::Expanded;
- break;
- case DWRITE_FONT_STRETCH_EXTRA_EXPANDED:
- stretch = QFont::ExtraExpanded;
- break;
- case DWRITE_FONT_STRETCH_ULTRA_EXPANDED:
- stretch = QFont::UltraExpanded;
- break;
- }
+ QFont::Stretch stretch;
+ switch (font->GetStretch()) {
+ default:
+ case DWRITE_FONT_STRETCH_UNDEFINED:
+ case DWRITE_FONT_STRETCH_NORMAL:
+ stretch = QFont::Unstretched;
+ break;
+ case DWRITE_FONT_STRETCH_ULTRA_CONDENSED:
+ stretch = QFont::UltraCondensed;
+ break;
+ case DWRITE_FONT_STRETCH_EXTRA_CONDENSED:
+ stretch = QFont::ExtraCondensed;
+ break;
+ case DWRITE_FONT_STRETCH_CONDENSED:
+ stretch = QFont::Condensed;
+ break;
+ case DWRITE_FONT_STRETCH_SEMI_CONDENSED:
+ stretch = QFont::SemiCondensed;
+ break;
+ case DWRITE_FONT_STRETCH_SEMI_EXPANDED:
+ stretch = QFont::SemiExpanded;
+ break;
+ case DWRITE_FONT_STRETCH_EXPANDED:
+ stretch = QFont::Expanded;
+ break;
+ case DWRITE_FONT_STRETCH_EXTRA_EXPANDED:
+ stretch = QFont::ExtraExpanded;
+ break;
+ case DWRITE_FONT_STRETCH_ULTRA_EXPANDED:
+ stretch = QFont::UltraExpanded;
+ break;
+ }
- const bool fixedPitch = fontFace->IsMonospacedFont();
+ const bool fixedPitch = fontFace->IsMonospacedFont();
- quint32 unicodeRange[4];
- quint32 actualRangeCount;
- hr = fontFace->GetUnicodeRanges(
- 2, reinterpret_cast<DWRITE_UNICODE_RANGE *>(unicodeRange), &actualRangeCount);
- if (FAILED(hr) && hr != E_NOT_SUFFICIENT_BUFFER) { // Ignore insufficient buffer; we only need 4 indices
- qWarning("Unable to get font unicode range: %s", qPrintable(qt_error_string(hr)));
- continue;
- }
- quint32 codePageRange[2] = { 0, 0 };
- QSupportedWritingSystems writingSystems =
- QPlatformFontDatabase::writingSystemsFromTrueTypeBits(unicodeRange, codePageRange);
-
- IDWriteFontFile *fontFile;
- hr = fontFace->GetFiles(&fileCount, &fontFile);
- if (FAILED(hr)) {
- qWarning("Unable to get font file: %s", qPrintable(qt_error_string(hr)));
- continue;
- }
+ quint32 unicodeRange[4];
+ quint32 actualRangeCount;
+ hr = fontFace->GetUnicodeRanges(
+ 2, reinterpret_cast<DWRITE_UNICODE_RANGE *>(unicodeRange), &actualRangeCount);
+ if (FAILED(hr) && hr != E_NOT_SUFFICIENT_BUFFER) { // Ignore insufficient buffer; we only need 4 indices
+ qWarning("Unable to get font unicode range: %s", qPrintable(qt_error_string(hr)));
+ continue;
+ }
+ quint32 codePageRange[2] = { 0, 0 };
+ QSupportedWritingSystems writingSystems =
+ QPlatformFontDatabase::writingSystemsFromTrueTypeBits(unicodeRange, codePageRange);
- FontDescription description = { fontFace->GetIndex(), QUuid::createUuid().toByteArray() };
- m_fonts.insert(fontFile, description);
- registerFont(familyName, QString(), foundryName, weight, style, stretch,
- true, true, 0, fixedPitch, writingSystems, fontFile);
+ IDWriteFontFile *fontFile;
+ hr = fontFace->GetFiles(&fileCount, &fontFile);
+ if (FAILED(hr)) {
+ qWarning("Unable to get font file: %s", qPrintable(qt_error_string(hr)));
+ continue;
}
+
+ FontDescription description = { fontFace->GetIndex(), QUuid::createUuid().toByteArray() };
+ m_fonts.insert(fontFile, description);
+ registerFont(familyName, QString(), foundryName, weight, style, stretch,
+ true, true, 0, fixedPitch, writingSystems, fontFile);
+ fontRegistered = true;
}
- QBasicFontDatabase::populateFontDatabase();
+ // Always populate something to avoid an assert
+ if (!fontRegistered) {
+ registerFont(familyName, QString(), QString(), QFont::Normal, QFont::StyleNormal,
+ QFont::Unstretched, false, false, 0, false, QSupportedWritingSystems(), 0);
+ }
}
QFontEngine *QWinRTFontDatabase::fontEngine(const QFontDef &fontDef, void *handle)
{
+ if (!handle) // Happens if a font family population failed
+ return 0;
+
IDWriteFontFile *fontFile = reinterpret_cast<IDWriteFontFile *>(handle);
if (!m_fonts.contains(fontFile))
return QBasicFontDatabase::fontEngine(fontDef, handle);
@@ -361,6 +385,9 @@ QFontEngine *QWinRTFontDatabase::fontEngine(const QFontDef &fontDef, void *handl
void QWinRTFontDatabase::releaseHandle(void *handle)
{
+ if (!handle)
+ return;
+
IDWriteFontFile *fontFile = reinterpret_cast<IDWriteFontFile *>(handle);
if (m_fonts.contains(fontFile)) {
m_fonts.remove(fontFile);
diff --git a/src/plugins/platforms/winrt/qwinrtfontdatabase.h b/src/plugins/platforms/winrt/qwinrtfontdatabase.h
index 6f194a10cc..b318a95502 100644
--- a/src/plugins/platforms/winrt/qwinrtfontdatabase.h
+++ b/src/plugins/platforms/winrt/qwinrtfontdatabase.h
@@ -48,6 +48,7 @@ QT_BEGIN_NAMESPACE
#ifndef Q_OS_WINPHONE
struct IDWriteFontFile;
+struct IDWriteFontFamily;
struct FontDescription
{
@@ -64,10 +65,12 @@ public:
~QWinRTFontDatabase();
QFont defaultFont() const Q_DECL_OVERRIDE;
void populateFontDatabase() Q_DECL_OVERRIDE;
+ void populateFamily(const QString &familyName) Q_DECL_OVERRIDE;
QFontEngine *fontEngine(const QFontDef &fontDef, void *handle) Q_DECL_OVERRIDE;
void releaseHandle(void *handle) Q_DECL_OVERRIDE;
private:
QHash<IDWriteFontFile *, FontDescription> m_fonts;
+ QHash<QString, IDWriteFontFamily *> m_fontFamilies;
#endif // !Q_OS_WINPHONE
};
diff --git a/src/plugins/platforms/winrt/qwinrtintegration.cpp b/src/plugins/platforms/winrt/qwinrtintegration.cpp
index be82390723..b3a2cafa2e 100644
--- a/src/plugins/platforms/winrt/qwinrtintegration.cpp
+++ b/src/plugins/platforms/winrt/qwinrtintegration.cpp
@@ -124,6 +124,8 @@ bool QWinRTIntegration::hasCapability(QPlatformIntegration::Capability cap) cons
case OpenGL:
case ApplicationState:
return true;
+ case NonFullScreenWindows:
+ return false;
default:
return QPlatformIntegration::hasCapability(cap);
}
diff --git a/src/plugins/platforms/winrt/winrt.pro b/src/plugins/platforms/winrt/winrt.pro
index 306bbc8174..60c87bb61a 100644
--- a/src/plugins/platforms/winrt/winrt.pro
+++ b/src/plugins/platforms/winrt/winrt.pro
@@ -1,6 +1,15 @@
TARGET = qwinrt
CONFIG -= precompile_header
+# For Windows Phone 8 we have to deploy fonts together with the application as DirectWrite
+# is not supported here.
+# TODO: Add a condition/remove this block if Windows Phone 8.1 supports DirectWrite
+winphone {
+ fonts.path = $$[QT_INSTALL_LIBS]/fonts
+ fonts.files = $$QT_SOURCE_TREE/lib/fonts/DejaVu*.ttf
+ INSTALLS += fonts
+}
+
PLUGIN_TYPE = platforms
PLUGIN_CLASS_NAME = QWinRTIntegrationPlugin
load(qt_plugin)
diff --git a/src/plugins/platforms/xcb/qxcbconnection.cpp b/src/plugins/platforms/xcb/qxcbconnection.cpp
index a68ae8cf71..66b8401ea2 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection.cpp
@@ -185,8 +185,12 @@ void QXcbConnection::updateScreens()
siblings << screen;
activeScreens << screen;
++screenNumber;
- if (!primaryScreen && primary) {
- if (m_primaryScreen == xcbScreenNumber && (primary->output == XCB_NONE || outputs[i] == primary->output)) {
+ // There can be multiple outputs per screen, use either
+ // the first or an exact match. An exact match isn't
+ // always available if primary->output is XCB_NONE
+ // or currently disconnected output.
+ if (m_primaryScreen == xcbScreenNumber) {
+ if (!primaryScreen || (primary && outputs[i] == primary->output)) {
primaryScreen = screen;
siblings.prepend(siblings.takeLast());
#ifdef Q_XCB_DEBUG
@@ -766,6 +770,7 @@ namespace {
xcb_timestamp_t time;
uint8_t deviceID;
} any;
+ xcb_xkb_new_keyboard_notify_event_t new_keyboard_notify;
xcb_xkb_map_notify_event_t map_notify;
xcb_xkb_state_notify_event_t state_notify;
} _xkb_event;
@@ -796,15 +801,11 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
case XCB_EXPOSE:
HANDLE_PLATFORM_WINDOW_EVENT(xcb_expose_event_t, window, handleExposeEvent);
case XCB_BUTTON_PRESS:
-#ifdef QT_NO_XKB
m_keyboard->updateXKBStateFromCore(((xcb_button_press_event_t *)event)->state);
-#endif
handleButtonPress(event);
HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_press_event_t, event, handleButtonPressEvent);
case XCB_BUTTON_RELEASE:
-#ifdef QT_NO_XKB
m_keyboard->updateXKBStateFromCore(((xcb_button_release_event_t *)event)->state);
-#endif
handleButtonRelease(event);
HANDLE_PLATFORM_WINDOW_EVENT(xcb_button_release_event_t, event, handleButtonReleaseEvent);
case XCB_MOTION_NOTIFY:
@@ -812,9 +813,7 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
xcb_motion_notify_event_t *mev = (xcb_motion_notify_event_t *)event;
qDebug("xcb: moved mouse to %4d, %4d; button state %X", mev->event_x, mev->event_y, static_cast<unsigned int>(m_buttons));
}
-#ifdef QT_NO_XKB
m_keyboard->updateXKBStateFromCore(((xcb_motion_notify_event_t *)event)->state);
-#endif
HANDLE_PLATFORM_WINDOW_EVENT(xcb_motion_notify_event_t, event, handleMotionNotifyEvent);
case XCB_CONFIGURE_NOTIFY:
HANDLE_PLATFORM_WINDOW_EVENT(xcb_configure_notify_event_t, event, handleConfigureNotifyEvent);
@@ -830,29 +829,21 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
case XCB_ENTER_NOTIFY:
HANDLE_PLATFORM_WINDOW_EVENT(xcb_enter_notify_event_t, event, handleEnterNotifyEvent);
case XCB_LEAVE_NOTIFY:
-#ifdef QT_NO_XKB
m_keyboard->updateXKBStateFromCore(((xcb_leave_notify_event_t *)event)->state);
-#endif
HANDLE_PLATFORM_WINDOW_EVENT(xcb_leave_notify_event_t, event, handleLeaveNotifyEvent);
case XCB_FOCUS_IN:
HANDLE_PLATFORM_WINDOW_EVENT(xcb_focus_in_event_t, event, handleFocusInEvent);
case XCB_FOCUS_OUT:
HANDLE_PLATFORM_WINDOW_EVENT(xcb_focus_out_event_t, event, handleFocusOutEvent);
case XCB_KEY_PRESS:
-#ifdef QT_NO_XKB
m_keyboard->updateXKBStateFromCore(((xcb_key_press_event_t *)event)->state);
-#endif
HANDLE_KEYBOARD_EVENT(xcb_key_press_event_t, handleKeyPressEvent);
case XCB_KEY_RELEASE:
-#ifdef QT_NO_XKB
m_keyboard->updateXKBStateFromCore(((xcb_key_release_event_t *)event)->state);
-#endif
HANDLE_KEYBOARD_EVENT(xcb_key_release_event_t, handleKeyReleaseEvent);
-#ifdef QT_NO_XKB
case XCB_MAPPING_NOTIFY:
m_keyboard->handleMappingNotifyEvent((xcb_mapping_notify_event_t *)event);
break;
-#endif
case XCB_SELECTION_REQUEST:
{
xcb_selection_request_event_t *sr = (xcb_selection_request_event_t *)event;
@@ -920,6 +911,8 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
_xkb_event *xkb_event = reinterpret_cast<_xkb_event *>(event);
if (xkb_event->any.deviceID == m_keyboard->coreDeviceId()) {
switch (xkb_event->any.xkbType) {
+ // XkbNewKkdNotify and XkbMapNotify together capture all sorts of keymap
+ // updates (e.g. xmodmap, xkbcomp, setxkbmap), with minimal redundent recompilations.
case XCB_XKB_STATE_NOTIFY:
m_keyboard->updateXKBState(&xkb_event->state_notify);
handled = true;
@@ -928,6 +921,12 @@ void QXcbConnection::handleXcbEvent(xcb_generic_event_t *event)
m_keyboard->handleMappingNotifyEvent(&xkb_event->map_notify);
handled = true;
break;
+ case XCB_XKB_NEW_KEYBOARD_NOTIFY: {
+ xcb_xkb_new_keyboard_notify_event_t *ev = &xkb_event->new_keyboard_notify;
+ if (ev->changed & XCB_XKB_NKN_DETAIL_KEYCODES)
+ m_keyboard->updateKeymap();
+ break;
+ }
default:
break;
}
@@ -1661,6 +1660,7 @@ void QXcbConnection::initializeXKB()
#ifndef QT_NO_XKB
const xcb_query_extension_reply_t *reply = xcb_get_extension_data(m_connection, &xcb_xkb_id);
if (!reply || !reply->present) {
+ qWarning() << "Qt: XKEYBOARD extension not present on the X server.";
xkb_first_event = 0;
return;
}
@@ -1670,14 +1670,14 @@ void QXcbConnection::initializeXKB()
xcb_xkb_use_extension_cookie_t xkb_query_cookie;
xcb_xkb_use_extension_reply_t *xkb_query;
- xkb_query_cookie = xcb_xkb_use_extension(c, XCB_XKB_MAJOR_VERSION, XCB_XKB_MINOR_VERSION);
+ xkb_query_cookie = xcb_xkb_use_extension(c, XKB_X11_MIN_MAJOR_XKB_VERSION, XKB_X11_MIN_MINOR_XKB_VERSION);
xkb_query = xcb_xkb_use_extension_reply(c, xkb_query_cookie, 0);
if (!xkb_query) {
qWarning("Qt: Failed to initialize XKB extension");
return;
} else if (!xkb_query->supported) {
- qWarning("Qt: Unsupported XKB version (want %d %d, has %d %d)",
+ qWarning("Qt: Unsupported XKB version (We want %d %d, but X server has %d %d)",
XCB_XKB_MAJOR_VERSION, XCB_XKB_MINOR_VERSION,
xkb_query->serverMajor, xkb_query->serverMinor);
free(xkb_query);
@@ -1687,25 +1687,28 @@ void QXcbConnection::initializeXKB()
has_xkb = true;
free(xkb_query);
- uint affectMap, map;
- affectMap = map = XCB_XKB_MAP_PART_KEY_TYPES |
- XCB_XKB_MAP_PART_KEY_SYMS |
- XCB_XKB_MAP_PART_MODIFIER_MAP |
- XCB_XKB_MAP_PART_EXPLICIT_COMPONENTS |
- XCB_XKB_MAP_PART_KEY_ACTIONS |
- XCB_XKB_MAP_PART_KEY_BEHAVIORS |
- XCB_XKB_MAP_PART_VIRTUAL_MODS |
- XCB_XKB_MAP_PART_VIRTUAL_MOD_MAP;
-
- // Xkb events are reported to all interested clients without regard
+ const uint16_t required_map_parts = (XCB_XKB_MAP_PART_KEY_TYPES |
+ XCB_XKB_MAP_PART_KEY_SYMS |
+ XCB_XKB_MAP_PART_MODIFIER_MAP |
+ XCB_XKB_MAP_PART_EXPLICIT_COMPONENTS |
+ XCB_XKB_MAP_PART_KEY_ACTIONS |
+ XCB_XKB_MAP_PART_KEY_BEHAVIORS |
+ XCB_XKB_MAP_PART_VIRTUAL_MODS |
+ XCB_XKB_MAP_PART_VIRTUAL_MOD_MAP);
+
+ const uint16_t required_events = (XCB_XKB_EVENT_TYPE_NEW_KEYBOARD_NOTIFY |
+ XCB_XKB_EVENT_TYPE_MAP_NOTIFY |
+ XCB_XKB_EVENT_TYPE_STATE_NOTIFY);
+
+ // XKB events are reported to all interested clients without regard
// to the current keyboard input focus or grab state
xcb_void_cookie_t select = xcb_xkb_select_events_checked(c,
XCB_XKB_ID_USE_CORE_KBD,
- XCB_XKB_EVENT_TYPE_STATE_NOTIFY | XCB_XKB_EVENT_TYPE_MAP_NOTIFY,
+ required_events,
0,
- XCB_XKB_EVENT_TYPE_STATE_NOTIFY | XCB_XKB_EVENT_TYPE_MAP_NOTIFY,
- affectMap,
- map,
+ required_events,
+ required_map_parts,
+ required_map_parts,
0);
xcb_generic_error_t *error = xcb_request_check(c, select);
diff --git a/src/plugins/platforms/xcb/qxcbconnection.h b/src/plugins/platforms/xcb/qxcbconnection.h
index 71f5ce13fb..a994c51c7d 100644
--- a/src/plugins/platforms/xcb/qxcbconnection.h
+++ b/src/plugins/platforms/xcb/qxcbconnection.h
@@ -54,7 +54,7 @@
#include <qpa/qwindowsysteminterface.h>
// This is needed to make Qt compile together with XKB. xkb.h is using a variable
-// which is called 'explicit', this is a reserved keyword in c++ */
+// which is called 'explicit', this is a reserved keyword in c++
#ifndef QT_NO_XKB
#define explicit dont_use_cxx_explicit
#include <xcb/xkb.h>
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.cpp b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
index 0a52640c9a..92b24f4722 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.cpp
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.cpp
@@ -38,20 +38,22 @@
** $QT_END_LICENSE$
**
****************************************************************************/
-
#include "qxcbkeyboard.h"
#include "qxcbwindow.h"
#include "qxcbscreen.h"
-#include <X11/keysym.h>
+
#include <qpa/qwindowsysteminterface.h>
+#include <qpa/qplatforminputcontext.h>
+#include <qpa/qplatformintegration.h>
+#include <qpa/qplatformcursor.h>
+
#include <QtCore/QTextCodec>
#include <QtCore/QMetaMethod>
+#include <QtCore/QDir>
#include <private/qguiapplication_p.h>
-#include <stdio.h>
-#include <qpa/qplatforminputcontext.h>
-#include <qpa/qplatformintegration.h>
-#include <qpa/qplatformcursor.h>
+#include <stdio.h>
+#include <X11/keysym.h>
#ifndef XK_ISO_Left_Tab
#define XK_ISO_Left_Tab 0xFE20
@@ -619,6 +621,12 @@ void QXcbKeyboard::readXKBConfig()
char *xkb_config = (char *)xcb_get_property_value(config_reply);
int length = xcb_get_property_value_length(config_reply);
+ // on old X servers xkb_config can be 0 even if config_reply indicates a succesfull read
+ if (!xkb_config || length == 0)
+ return;
+ // ### TODO some X servers don't set _XKB_RULES_NAMES at all, in these cases it is filled
+ // with gibberish, we would need to do some kind of sanity check
+
char *names[5] = { 0, 0, 0, 0, 0 };
char *p = xkb_config, *end = p + length;
int i = 0;
@@ -655,78 +663,97 @@ void QXcbKeyboard::clearXKBConfig()
memset(&xkb_names, 0, sizeof(xkb_names));
}
+void QXcbKeyboard::printKeymapError(const QString &error) const
+{
+ qWarning() << "Qt: " << error;
+ // check if XKB config root is a valid path
+ const QDir xkbRoot = qEnvironmentVariableIsSet("QT_XKB_CONFIG_ROOT")
+ ? QString::fromLocal8Bit(qgetenv("QT_XKB_CONFIG_ROOT"))
+ : DFLT_XKB_CONFIG_ROOT;
+ if (!xkbRoot.exists() || xkbRoot.dirName() != "xkb") {
+ qWarning() << "Set QT_XKB_CONFIG_ROOT to provide a valid XKB configuration data path, current search paths: "
+ << xkbRoot.path() << ". Use ':' as separator to provide several search paths.";
+ return;
+ }
+ qWarning() << "_XKB_RULES_NAMES property contains:" << "\nrules : " << xkb_names.rules <<
+ "\nmodel : " << xkb_names.model << "\nlayout : " << xkb_names.layout <<
+ "\nvariant : " << xkb_names.variant << "\noptions : " << xkb_names.options <<
+ "\nIf this looks like a valid keyboard layout information then you might need to "
+ "update XKB configuration data on the system (http://cgit.freedesktop.org/xkeyboard-config/).";
+}
+
void QXcbKeyboard::updateKeymap()
{
m_config = true;
+ // set xkb context object
if (!xkb_context) {
- xkb_context = xkb_context_new((xkb_context_flags)0);
+ if (qEnvironmentVariableIsSet("QT_XKB_CONFIG_ROOT")) {
+ xkb_context = xkb_context_new((xkb_context_flags)XKB_CONTEXT_NO_DEFAULT_INCLUDES);
+ QList<QByteArray> xkbRootList = QByteArray(qgetenv("QT_XKB_CONFIG_ROOT")).split(':');
+ foreach (QByteArray xkbRoot, xkbRootList)
+ xkb_context_include_path_append(xkb_context, xkbRoot.constData());
+ } else {
+ xkb_context = xkb_context_new((xkb_context_flags)0);
+ }
if (!xkb_context) {
- qWarning("Qt: Failed to create XKB context");
+ printKeymapError("Failed to create XKB context!");
m_config = false;
return;
}
+ // log only critical errors, we do our own error logging from printKeymapError()
+ xkb_context_set_log_level(xkb_context, (xkb_log_level)XKB_LOG_LEVEL_CRITICAL);
}
- readXKBConfig();
- // Compile a keymap from RMLVO (rules, models, layouts, variants and options) names
- if (xkb_keymap)
- xkb_keymap_unref(xkb_keymap);
-
- xkb_keymap = xkb_keymap_new_from_names(xkb_context, &xkb_names, (xkb_keymap_compile_flags)0);
+ // update xkb keymap object
+ xkb_keymap_unref(xkb_keymap);
+ xkb_keymap = 0;
+ struct xkb_state *new_state = 0;
+#ifndef QT_NO_XKB
+ if (connection()->hasXKB()) {
+ xkb_keymap = xkb_x11_keymap_new_from_device(xkb_context, xcb_connection(), core_device_id, (xkb_keymap_compile_flags)0);
+ if (xkb_keymap) {
+ // Create a new keyboard state object for a keymap
+ new_state = xkb_x11_state_new_from_device(xkb_keymap, xcb_connection(), core_device_id);
+ }
+ }
+#endif
if (!xkb_keymap) {
- qWarning("Qt: Failed to compile a keymap");
- m_config = false;
- return;
+ // Compile a keymap from RMLVO (rules, models, layouts, variants and options) names
+ readXKBConfig();
+ xkb_keymap = xkb_keymap_new_from_names(xkb_context, &xkb_names, (xkb_keymap_compile_flags)0);
+ if (!xkb_keymap) {
+ // last fallback is to used hard-coded keymap name, see DEFAULT_XKB_* in xkbcommon.pri
+ qWarning() << "Qt: Could not determine keyboard configuration data"
+ " from X server, will use hard-coded keymap configuration.";
+ clearXKBConfig();
+ xkb_keymap = xkb_keymap_new_from_names(xkb_context, &xkb_names, (xkb_keymap_compile_flags)0);
+ }
+ if (xkb_keymap) {
+ new_state = xkb_state_new(xkb_keymap);
+ } else {
+ // failed to compile from RMLVO, give a verbose error message
+ printKeymapError("Qt: Failed to compile a keymap!");
+ m_config = false;
+ return;
+ }
+
}
- // Create a new keyboard state object for a keymap
- struct xkb_state *new_state = xkb_state_new(xkb_keymap);
if (!new_state) {
- qWarning("Qt: Failed to create a new keyboard state");
+ qWarning("Qt: Failed to create xkb state!");
m_config = false;
return;
}
-
- if (xkb_state) {
- xkb_state_unref(xkb_state);
- xkb_state = new_state;
- } else {
- xkb_state = new_state;
-#ifndef QT_NO_XKB
- // get initial state from the X server (and keep it up-to-date at all times)
- xcb_xkb_get_state_cookie_t state;
- xcb_xkb_get_state_reply_t *init_state;
-
- xcb_connection_t *c = xcb_connection();
- state = xcb_xkb_get_state(c, XCB_XKB_ID_USE_CORE_KBD);
- init_state = xcb_xkb_get_state_reply(c, state, 0);
- if (!init_state) {
- qWarning("Qt: couldn't retrieve an initial keyboard state");
- return;
- }
- /* The xkb keyboard state is comprised of the state of all keyboard modifiers,
- the keyboard group, and the state of the pointer buttons */
- xkb_state_update_mask(xkb_state,
- init_state->baseMods,
- init_state->latchedMods,
- init_state->lockedMods,
- init_state->baseGroup,
- init_state->latchedGroup,
- init_state->lockedGroup);
- free(init_state);
-#else
+ // update xkb state object
+ xkb_state_unref(xkb_state);
+ xkb_state = new_state;
+ if (!connection()->hasXKB())
updateXKBMods();
-#endif
- }
}
#ifndef QT_NO_XKB
void QXcbKeyboard::updateXKBState(xcb_xkb_state_notify_event_t *state)
{
- if (!m_config)
- return;
-
- if (connection()->hasXKB()) {
-
+ if (m_config && connection()->hasXKB()) {
const xkb_state_component newState
= xkb_state_update_mask(xkb_state,
state->baseMods,
@@ -741,35 +768,34 @@ void QXcbKeyboard::updateXKBState(xcb_xkb_state_notify_event_t *state)
}
}
}
+#endif
-#else
void QXcbKeyboard::updateXKBStateFromCore(quint16 state)
{
- if (!m_config)
- return;
+ if (m_config && !connection()->hasXKB()) {
+ const quint32 modsDepressed = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_DEPRESSED);
+ const quint32 modsLatched = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LATCHED);
+ const quint32 modsLocked = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LOCKED);
+ const quint32 xkbMask = xkbModMask(state);
+
+ const quint32 latched = modsLatched & xkbMask;
+ const quint32 locked = modsLocked & xkbMask;
+ quint32 depressed = modsDepressed & xkbMask;
+ // set modifiers in depressed if they don't appear in any of the final masks
+ depressed |= ~(depressed | latched | locked) & xkbMask;
- const quint32 modsDepressed = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_DEPRESSED);
- const quint32 modsLatched = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LATCHED);
- const quint32 modsLocked = xkb_state_serialize_mods(xkb_state, XKB_STATE_MODS_LOCKED);
- const quint32 xkbMask = xkbModMask(state);
-
- const quint32 latched = modsLatched & xkbMask;
- const quint32 locked = modsLocked & xkbMask;
- quint32 depressed = modsDepressed & xkbMask;
- // set modifiers in depressed if they don't appear in any of the final masks
- depressed |= ~(depressed | latched | locked) & xkbMask;
-
- const xkb_state_component newState
- = xkb_state_update_mask(xkb_state,
- depressed,
- latched,
- locked,
- 0,
- 0,
- (state >> 13) & 3); // bits 13 and 14 report the state keyboard group
-
- if ((newState & XKB_STATE_LAYOUT_EFFECTIVE) == XKB_STATE_LAYOUT_EFFECTIVE) {
- //qWarning("TODO: Support KeyboardLayoutChange on QPA (QTBUG-27681)");
+ const xkb_state_component newState
+ = xkb_state_update_mask(xkb_state,
+ depressed,
+ latched,
+ locked,
+ 0,
+ 0,
+ (state >> 13) & 3); // bits 13 and 14 report the state keyboard group
+
+ if ((newState & XKB_STATE_LAYOUT_EFFECTIVE) == XKB_STATE_LAYOUT_EFFECTIVE) {
+ //qWarning("TODO: Support KeyboardLayoutChange on QPA (QTBUG-27681)");
+ }
}
}
@@ -799,16 +825,15 @@ quint32 QXcbKeyboard::xkbModMask(quint16 state)
void QXcbKeyboard::updateXKBMods()
{
- xkb_mods.shift = xkb_map_mod_get_index(xkb_keymap, XKB_MOD_NAME_SHIFT);
- xkb_mods.lock = xkb_map_mod_get_index(xkb_keymap, XKB_MOD_NAME_CAPS);
- xkb_mods.control = xkb_map_mod_get_index(xkb_keymap, XKB_MOD_NAME_CTRL);
- xkb_mods.mod1 = xkb_map_mod_get_index(xkb_keymap, "Mod1");
- xkb_mods.mod2 = xkb_map_mod_get_index(xkb_keymap, "Mod2");
- xkb_mods.mod3 = xkb_map_mod_get_index(xkb_keymap, "Mod3");
- xkb_mods.mod4 = xkb_map_mod_get_index(xkb_keymap, "Mod4");
- xkb_mods.mod5 = xkb_map_mod_get_index(xkb_keymap, "Mod5");
+ xkb_mods.shift = xkb_keymap_mod_get_index(xkb_keymap, XKB_MOD_NAME_SHIFT);
+ xkb_mods.lock = xkb_keymap_mod_get_index(xkb_keymap, XKB_MOD_NAME_CAPS);
+ xkb_mods.control = xkb_keymap_mod_get_index(xkb_keymap, XKB_MOD_NAME_CTRL);
+ xkb_mods.mod1 = xkb_keymap_mod_get_index(xkb_keymap, "Mod1");
+ xkb_mods.mod2 = xkb_keymap_mod_get_index(xkb_keymap, "Mod2");
+ xkb_mods.mod3 = xkb_keymap_mod_get_index(xkb_keymap, "Mod3");
+ xkb_mods.mod4 = xkb_keymap_mod_get_index(xkb_keymap, "Mod4");
+ xkb_mods.mod5 = xkb_keymap_mod_get_index(xkb_keymap, "Mod5");
}
-#endif
QList<int> QXcbKeyboard::possibleKeys(const QKeyEvent *event) const
{
@@ -893,10 +918,8 @@ QList<int> QXcbKeyboard::possibleKeys(const QKeyEvent *event) const
result += (qtKey + mods);
}
}
- if (kb_state)
- xkb_state_unref(kb_state);
- if (fallback_keymap)
- xkb_keymap_unref(fallback_keymap);
+ xkb_state_unref(kb_state);
+ xkb_keymap_unref(fallback_keymap);
return result;
}
@@ -963,58 +986,41 @@ QXcbKeyboard::QXcbKeyboard(QXcbConnection *connection)
, xkb_context(0)
, xkb_keymap(0)
, xkb_state(0)
-#ifndef QT_NO_XKB
, core_device_id(0)
-#endif
{
memset(&xkb_names, 0, sizeof(xkb_names));
- updateKeymap();
#ifndef QT_NO_XKB
if (connection->hasXKB()) {
-
updateVModMapping();
updateVModToRModMapping();
-
- // get the core keyboard id
- xcb_xkb_get_device_info_cookie_t device_id_cookie;
- xcb_xkb_get_device_info_reply_t *device_id;
-
- device_id_cookie = xcb_xkb_get_device_info(xcb_connection(),
- XCB_XKB_ID_USE_CORE_KBD,
- 0, 0, 0, 0, 0, 0);
-
- device_id = xcb_xkb_get_device_info_reply(xcb_connection(), device_id_cookie, 0);
- if (!device_id) {
+ core_device_id = xkb_x11_get_core_keyboard_device_id(xcb_connection());
+ if (core_device_id == -1) {
qWarning("Qt: couldn't get core keyboard device info");
return;
}
-
- core_device_id = device_id->deviceID;
- free(device_id);
+ } else {
+#endif
+ m_key_symbols = xcb_key_symbols_alloc(xcb_connection());
+ updateModifiers();
+#ifndef QT_NO_XKB
}
-#else
- m_key_symbols = xcb_key_symbols_alloc(xcb_connection());
- updateModifiers();
#endif
+ updateKeymap();
}
QXcbKeyboard::~QXcbKeyboard()
{
- if (xkb_state)
- xkb_state_unref(xkb_state);
- if (xkb_keymap)
- xkb_keymap_unref(xkb_keymap);
- if (xkb_context)
- xkb_context_unref(xkb_context);
-#ifdef QT_NO_XKB
- xcb_key_symbols_free(m_key_symbols);
-#endif
+ xkb_state_unref(xkb_state);
+ xkb_keymap_unref(xkb_keymap);
+ xkb_context_unref(xkb_context);
+ if (!connection()->hasXKB())
+ xcb_key_symbols_free(m_key_symbols);
clearXKBConfig();
}
-#ifndef QT_NO_XKB
void QXcbKeyboard::updateVModMapping()
{
+#ifndef QT_NO_XKB
xcb_xkb_get_names_cookie_t names_cookie;
xcb_xkb_get_names_reply_t *name_reply;
xcb_xkb_get_names_value_list_t names_list;
@@ -1078,10 +1084,12 @@ void QXcbKeyboard::updateVModMapping()
}
free(name_reply);
+#endif
}
void QXcbKeyboard::updateVModToRModMapping()
{
+#ifndef QT_NO_XKB
xcb_xkb_get_map_cookie_t map_cookie;
xcb_xkb_get_map_reply_t *map_reply;
xcb_xkb_get_map_map_t map;
@@ -1144,8 +1152,9 @@ void QXcbKeyboard::updateVModToRModMapping()
free(map_reply);
resolveMaskConflicts();
+#endif
}
-#else
+
void QXcbKeyboard::updateModifiers()
{
// The core protocol does not provide a convenient way to determine the mapping
@@ -1209,7 +1218,6 @@ void QXcbKeyboard::updateModifiers()
free(modMapReply);
resolveMaskConflicts();
}
-#endif
void QXcbKeyboard::resolveMaskConflicts()
{
@@ -1292,17 +1300,9 @@ void QXcbKeyboard::handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycod
if (!m_config)
return;
- // It is crucial the order of xkb_state_key_get_one_sym &
- // xkb_state_update_key operations is not reversed!
+
+ // It is crucial the order of xkb_state_key_get_one_sym & xkb_state_update_key operations is not reversed!
xcb_keysym_t sym = xkb_state_key_get_one_sym(xkb_state, code);
-#ifdef QT_NO_XKB
- enum xkb_key_direction direction;
- if (type == QEvent::KeyPress)
- direction = XKB_KEY_DOWN;
- else
- direction = XKB_KEY_UP;
- xkb_state_update_key(xkb_state, code, direction);
-#endif
QPlatformInputContext *inputContext = QGuiApplicationPrivate::platformIntegration()->inputContext();
QMetaMethod method;
@@ -1422,17 +1422,14 @@ void QXcbKeyboard::handleKeyReleaseEvent(QXcbWindowEventListener *eventListener,
void QXcbKeyboard::handleMappingNotifyEvent(const void *event)
{
updateKeymap();
-#ifdef QT_NO_XKB
- void *ev = const_cast<void *>(event);
- xcb_refresh_keyboard_mapping(m_key_symbols, static_cast<xcb_mapping_notify_event_t *>(ev));
- updateModifiers();
-#else
- Q_UNUSED(event)
if (connection()->hasXKB()) {
updateVModMapping();
updateVModToRModMapping();
+ } else {
+ void *ev = const_cast<void *>(event);
+ xcb_refresh_keyboard_mapping(m_key_symbols, static_cast<xcb_mapping_notify_event_t *>(ev));
+ updateModifiers();
}
-#endif
}
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbkeyboard.h b/src/plugins/platforms/xcb/qxcbkeyboard.h
index 0256602782..36ce1ea2f0 100644
--- a/src/plugins/platforms/xcb/qxcbkeyboard.h
+++ b/src/plugins/platforms/xcb/qxcbkeyboard.h
@@ -44,11 +44,15 @@
#include "qxcbobject.h"
-#ifdef QT_NO_XKB
#include <xcb/xcb_keysyms.h>
-#endif
#include <xkbcommon/xkbcommon.h>
+#ifndef QT_NO_XKB
+// note: extern won't be needed from libxkbcommon 0.4.1 and above
+extern "C" {
+#include <xkbcommon/xkbcommon-x11.h>
+}
+#endif
#include <QEvent>
@@ -65,41 +69,38 @@ public:
void handleKeyPressEvent(QXcbWindowEventListener *eventListener, const xcb_key_press_event_t *event);
void handleKeyReleaseEvent(QXcbWindowEventListener *eventListener, const xcb_key_release_event_t *event);
-
void handleMappingNotifyEvent(const void *event);
Qt::KeyboardModifiers translateModifiers(int s) const;
-
void updateKeymap();
QList<int> possibleKeys(const QKeyEvent *e) const;
-#ifdef QT_NO_XKB
- void updateXKBStateFromCore(quint16 state);
+ // when XKEYBOARD not present on the X server
void updateXKBMods();
quint32 xkbModMask(quint16 state);
-#else
- int coreDeviceId() { return core_device_id; }
+ void updateXKBStateFromCore(quint16 state);
+ // when XKEYBOARD is present on the X server
+ int coreDeviceId() const { return core_device_id; }
+#ifndef QT_NO_XKB
void updateXKBState(xcb_xkb_state_notify_event_t *state);
#endif
protected:
void handleKeyEvent(QWindow *window, QEvent::Type type, xcb_keycode_t code, quint16 state, xcb_timestamp_t time);
- void resolveMaskConflicts();
+ void resolveMaskConflicts();
QString keysymToUnicode(xcb_keysym_t sym) const;
-
int keysymToQtKey(xcb_keysym_t keysym) const;
int keysymToQtKey(xcb_keysym_t keysym, Qt::KeyboardModifiers &modifiers, QString text) const;
+ void printKeymapError(const QString &error) const;
void readXKBConfig();
void clearXKBConfig();
-
-#ifdef QT_NO_XKB
+ // when XKEYBOARD not present on the X server
void updateModifiers();
-#else
+ // when XKEYBOARD is present on the X server
void updateVModMapping();
void updateVModToRModMapping();
-#endif
private:
bool m_config;
@@ -120,9 +121,8 @@ private:
_mod_masks rmod_masks;
-#ifdef QT_NO_XKB
+ // when XKEYBOARD not present on the X server
xcb_key_symbols_t *m_key_symbols;
-
struct _xkb_mods {
xkb_mod_index_t shift;
xkb_mod_index_t lock;
@@ -133,12 +133,10 @@ private:
xkb_mod_index_t mod4;
xkb_mod_index_t mod5;
};
-
_xkb_mods xkb_mods;
-#else
+ // when XKEYBOARD is present on the X server
_mod_masks vmod_masks;
int core_device_id;
-#endif
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index d890398416..bed6eb59dc 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -1829,21 +1829,21 @@ void QXcbWindow::handlePropertyNotifyEvent(const xcb_property_notify_event_t *ev
return;
Qt::WindowState newState = Qt::WindowNoState;
- if (event->atom == atom(QXcbAtom::_NET_WM_STATE)) { // WM_STATE: Quick check for 'Minimize'.
+ if (event->atom == atom(QXcbAtom::WM_STATE)) { // WM_STATE: Quick check for 'Minimize'.
const xcb_get_property_cookie_t get_cookie =
- xcb_get_property(xcb_connection(), 0, m_window, atom(QXcbAtom::_NET_WM_STATE),
- XCB_ATOM_ANY, 0, 1024);
+ xcb_get_property(xcb_connection(), 0, m_window, atom(QXcbAtom::WM_STATE),
+ XCB_ATOM_ANY, 0, 1024);
xcb_get_property_reply_t *reply =
xcb_get_property_reply(xcb_connection(), get_cookie, NULL);
- if (reply && reply->format == 32 && reply->type == atom(QXcbAtom::_NET_WM_STATE)) {
+ if (reply && reply->format == 32 && reply->type == atom(QXcbAtom::WM_STATE)) {
const quint32 *data = (const quint32 *)xcb_get_property_value(reply);
if (reply->length != 0 && XCB_WM_STATE_ICONIC == data[0])
newState = Qt::WindowMinimized;
}
free(reply);
- } // WM_STATE: Quick check for 'Minimize'.
+ }
if (newState != Qt::WindowMinimized) { // Something else changed, get _NET_WM_STATE.
const NetWmStates states = netWmStates();
if ((states & NetWmStateMaximizedHorz) && (states & NetWmStateMaximizedVert))
diff --git a/src/plugins/platforms/xcb/xcb-plugin.pro b/src/plugins/platforms/xcb/xcb-plugin.pro
index e19bb921e1..9e4e997f55 100644
--- a/src/plugins/platforms/xcb/xcb-plugin.pro
+++ b/src/plugins/platforms/xcb/xcb-plugin.pro
@@ -121,12 +121,8 @@ contains(QT_CONFIG, xcb-qt) {
INCLUDEPATH += $$XCB_DIR/include $$XCB_DIR/sysinclude
LIBS += -lxcb -L$$OUT_PWD/xcb-static -lxcb-static
} else {
- LIBS += -lxcb -lxcb-image -lxcb-icccm -lxcb-sync -lxcb-xfixes -lxcb-shm -lxcb-randr -lxcb-shape
- contains(DEFINES, QT_NO_XKB) {
- LIBS += -lxcb-keysyms
- } else {
- LIBS += -lxcb-xkb
- }
+ LIBS += -lxcb -lxcb-image -lxcb-icccm -lxcb-sync -lxcb-xfixes -lxcb-shm -lxcb-randr -lxcb-shape -lxcb-keysyms
+ !contains(DEFINES, QT_NO_XKB):LIBS += -lxcb-xkb
}
# libxkbcommon
diff --git a/src/sql/drivers/ibase/qsql_ibase.cpp b/src/sql/drivers/ibase/qsql_ibase.cpp
index d50078b5ff..cc26bfe7e8 100644
--- a/src/sql/drivers/ibase/qsql_ibase.cpp
+++ b/src/sql/drivers/ibase/qsql_ibase.cpp
@@ -1313,6 +1313,7 @@ int QIBaseResult::numRowsAffected()
{
static char acCountInfo[] = {isc_info_sql_records};
char cCountType;
+ bool bIsProcedure = false;
switch (d->queryType) {
case isc_info_sql_stmt_select:
@@ -1327,6 +1328,9 @@ int QIBaseResult::numRowsAffected()
case isc_info_sql_stmt_insert:
cCountType = isc_info_req_insert_count;
break;
+ case isc_info_sql_stmt_exec_procedure:
+ bIsProcedure = true; // will sum all changes
+ break;
default:
qWarning() << "numRowsAffected: Unknown statement type (" << d->queryType << ")";
return -1;
@@ -1344,8 +1348,14 @@ int QIBaseResult::numRowsAffected()
pcBuf += 2;
int iValue = isc_vax_integer (pcBuf, sLength);
pcBuf += sLength;
-
- if (cType == cCountType) {
+ if (bIsProcedure) {
+ if (cType == isc_info_req_insert_count || cType == isc_info_req_update_count
+ || cType == isc_info_req_delete_count) {
+ if (iResult == -1)
+ iResult = 0;
+ iResult += iValue;
+ }
+ } else if (cType == cCountType) {
iResult = iValue;
break;
}
diff --git a/src/sql/kernel/qsqlquery.cpp b/src/sql/kernel/qsqlquery.cpp
index 0cfc37833d..b08f6bc8ef 100644
--- a/src/sql/kernel/qsqlquery.cpp
+++ b/src/sql/kernel/qsqlquery.cpp
@@ -311,7 +311,7 @@ QSqlQuery& QSqlQuery::operator=(const QSqlQuery& other)
/*!
Returns \c true if the query is not \l{isActive()}{active},
the query is not positioned on a valid record,
- there is no such field, or the field is null; otherwise \c false.
+ there is no such \a field, or the \a field is null; otherwise \c false.
Note that for some drivers, isNull() will not return accurate
information until after an attempt is made to retrieve data.
diff --git a/src/testlib/qtestcase.cpp b/src/testlib/qtestcase.cpp
index 7b225ef5b4..3ab3fcc44c 100644
--- a/src/testlib/qtestcase.cpp
+++ b/src/testlib/qtestcase.cpp
@@ -2591,10 +2591,10 @@ void QTest::ignoreMessage(QtMsgType type, const char *message)
/*!
\overload
- Ignores messages created by qDebug() or qWarning(). If the \a message
+ Ignores messages created by qDebug() or qWarning(). If the message
matching \a messagePattern
with the corresponding \a type is outputted, it will be removed from the
- test log. If the test finished and the \a message was not outputted,
+ test log. If the test finished and the message was not outputted,
a test failure is appended to the test log.
\b {Note:} Invoking this function will only ignore one message.
diff --git a/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp b/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp
index 0e1fa59b90..5417cc9b2f 100644
--- a/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp
+++ b/src/tools/qdbuscpp2xml/qdbuscpp2xml.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the tools applications of the Qt Toolkit.
@@ -75,7 +75,7 @@ static const char docTypeHeader[] =
#define PROGRAMNAME "qdbuscpp2xml"
#define PROGRAMVERSION "0.2"
-#define PROGRAMCOPYRIGHT "Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies)."
+#define PROGRAMCOPYRIGHT "Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies)."
static QString outputFile;
static int flags;
diff --git a/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp b/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp
index 560b58817e..b4f9aedd7a 100644
--- a/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp
+++ b/src/tools/qdbusxml2cpp/qdbusxml2cpp.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the tools applications of the Qt Toolkit.
@@ -57,7 +57,7 @@
#define PROGRAMNAME "qdbusxml2cpp"
#define PROGRAMVERSION "0.8"
-#define PROGRAMCOPYRIGHT "Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies)."
+#define PROGRAMCOPYRIGHT "Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies)."
#define ANNOTATION_NO_WAIT "org.freedesktop.DBus.Method.NoReply"
diff --git a/src/tools/qdoc/doc/qdoc-manual-markupcmds.qdoc b/src/tools/qdoc/doc/qdoc-manual-markupcmds.qdoc
index ee0a7b41db..fe43938968 100644
--- a/src/tools/qdoc/doc/qdoc-manual-markupcmds.qdoc
+++ b/src/tools/qdoc/doc/qdoc-manual-markupcmds.qdoc
@@ -3775,7 +3775,7 @@
<author>Qt Development Frameworks</author>
<publisher>Qt Project</publisher>
<copyright>
- <copyryear year="2013"/>
+ <copyryear year="2014"/>
<copyrholder>Qt Project</copyrholder>
</copyright>
<permissions view="all"/>
diff --git a/src/tools/qdoc/doc/qdoc-manual-qdocconf.qdoc b/src/tools/qdoc/doc/qdoc-manual-qdocconf.qdoc
index 3adcf9b213..a28e65e976 100644
--- a/src/tools/qdoc/doc/qdoc-manual-qdocconf.qdoc
+++ b/src/tools/qdoc/doc/qdoc-manual-qdocconf.qdoc
@@ -1569,7 +1569,7 @@
dita.metadata.default.author = Qt Development Frameworks
dita.metadata.default.permissions = all
dita.metadata.default.publisher = Qt Project
- dita.metadata.default.copyryear = 2013
+ dita.metadata.default.copyryear = 2014
dita.metadata.default.copyrholder = Qt Project
dita.metadata.default.audience = programmer
\endcode
diff --git a/src/tools/qdoc/doc/qdoc-manual-topiccmds.qdoc b/src/tools/qdoc/doc/qdoc-manual-topiccmds.qdoc
index 68f3f9652b..b9667b7758 100644
--- a/src/tools/qdoc/doc/qdoc-manual-topiccmds.qdoc
+++ b/src/tools/qdoc/doc/qdoc-manual-topiccmds.qdoc
@@ -1113,27 +1113,24 @@
\section1 \\qmlattachedsignal
The \\qmlattachedsignal command is for documenting an attachable
- \l{http://qt-project.org/doc/qt-4.7/qdeclarativeintroduction.html#signal-handlers}
- {signal handler}. The \\qmlattachedsignal command is used just like
- the \l{qmlsignal-command} {\\qmlsignal} command.
+ \l{Signal and Handler Event System}{signal}. The \\qmlattachedsignal
+ command is used just like the \l{qmlsignal-command} {\\qmlsignal} command.
The argument is the rest of the line. It should be the name of the
- QML type where the signal handler is declared, the \c{::}
- qualifier, and finally the signal handler name. If we have a QML
- attached signal handler named \c onAdd() in the \c GridView
- element, the \\qmlattachedsignal for it would look like this:
+ QML type where the signal is declared, the \c{::}
+ qualifier, and finally the signal name. For example, a QML
+ attached signal named \c add() in the \c GridView
+ element is documented like this:
\code
/ *!
- \qmlattachedsignal GridView::onAdd()
- This attached handler is called immediately after an item is
- added to the view.
+ \qmlattachedsignal GridView::add()
+ This attached signal is emitted immediately after an item is added to the view.
* /
\endcode
QDoc includes this documentation on the QML reference page for the
- \l{http://qt-project.org/doc/qt-4.7/qml-gridview.html#onAdd-signal}
- {GridView} element.
+ \l GridView element.
\target qmlbasictype-command
\section1 \\qmlbasictype
diff --git a/src/tools/qlalr/cppgenerator.cpp b/src/tools/qlalr/cppgenerator.cpp
index d48c059397..9bb699108a 100644
--- a/src/tools/qlalr/cppgenerator.cpp
+++ b/src/tools/qlalr/cppgenerator.cpp
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).
+** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the QLALR module of the Qt Toolkit.
@@ -55,7 +55,7 @@ QString CppGenerator::copyrightHeader() const
return QLatin1String(
"/****************************************************************************\n"
"**\n"
- "** Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies).\n"
+ "** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).\n"
"** Contact: http://www.qt-project.org/legal\n"
"**\n"
"** This file is part of the Qt Toolkit.\n"
diff --git a/src/widgets/accessible/simplewidgets.cpp b/src/widgets/accessible/simplewidgets.cpp
index b729e66d3c..b3170278ee 100644
--- a/src/widgets/accessible/simplewidgets.cpp
+++ b/src/widgets/accessible/simplewidgets.cpp
@@ -137,6 +137,8 @@ QAccessible::State QAccessibleButton::state() const
QAbstractButton *b = button();
QCheckBox *cb = qobject_cast<QCheckBox *>(b);
+ if (b->isCheckable())
+ state.checkable = true;
if (b->isChecked())
state.checked = true;
else if (cb && cb->checkState() == Qt::PartiallyChecked)
diff --git a/src/widgets/dialogs/qfontdialog.cpp b/src/widgets/dialogs/qfontdialog.cpp
index 94e96a52c5..5a68bfbc66 100644
--- a/src/widgets/dialogs/qfontdialog.cpp
+++ b/src/widgets/dialogs/qfontdialog.cpp
@@ -256,8 +256,10 @@ void QFontDialogPrivate::init()
}
updateFamilies();
- if (familyList->count() != 0)
+ if (familyList->count() != 0) {
familyList->setCurrentItem(0);
+ sizeList->setCurrentItem(0);
+ }
// grid layout
QGridLayout *mainGrid = new QGridLayout(q);
@@ -621,16 +623,13 @@ void QFontDialogPrivate::updateSizes()
QStringList str_sizes;
for(QList<int>::const_iterator it = sizes.constBegin(); it != sizes.constEnd(); ++it) {
str_sizes.append(QString::number(*it));
- if (current == -1 && *it >= size)
+ if (current == -1 && *it == size)
current = i;
++i;
}
sizeList->model()->setStringList(str_sizes);
- if (current == -1) {
- // we request a size bigger than the ones in the list, select the biggest one
- current = sizeList->count() - 1;
- }
- sizeList->setCurrentItem(current);
+ if (current != -1)
+ sizeList->setCurrentItem(current);
const QSignalBlocker blocker(sizeEdit);
sizeEdit->setText((smoothScalable ? QString::number(size) : sizeList->currentText()));
@@ -750,7 +749,10 @@ void QFontDialogPrivate::_q_sizeChanged(const QString &s)
break;
}
const QSignalBlocker blocker(sizeList);
- sizeList->setCurrentItem(i);
+ if (sizeList->text(i).toInt() == this->size)
+ sizeList->setCurrentItem(i);
+ else
+ sizeList->clearSelection();
}
_q_updateSample();
}
diff --git a/src/widgets/itemviews/qabstractitemview.cpp b/src/widgets/itemviews/qabstractitemview.cpp
index 771753b7da..b2dc614b2b 100644
--- a/src/widgets/itemviews/qabstractitemview.cpp
+++ b/src/widgets/itemviews/qabstractitemview.cpp
@@ -2753,10 +2753,14 @@ void QAbstractItemView::closeEditor(QWidget *editor, QAbstractItemDelegate::EndE
editor->removeEventFilter(d->delegateForIndex(index));
d->removeEditor(editor);
}
- if (hadFocus)
- setFocus(); // this will send a focusLost event to the editor
- else
+ if (hadFocus) {
+ if (focusPolicy() != Qt::NoFocus)
+ setFocus(); // this will send a focusLost event to the editor
+ else
+ editor->clearFocus();
+ } else {
d->checkPersistentEditorFocus();
+ }
QPointer<QWidget> ed = editor;
QApplication::sendPostedEvents(editor, 0);
@@ -2767,8 +2771,9 @@ void QAbstractItemView::closeEditor(QWidget *editor, QAbstractItemDelegate::EndE
}
// The EndEditHint part
- QItemSelectionModel::SelectionFlags flags = QItemSelectionModel::ClearAndSelect
- | d->selectionBehaviorFlags();
+ QItemSelectionModel::SelectionFlags flags = QItemSelectionModel::NoUpdate;
+ if (d->selectionMode != NoSelection)
+ flags = QItemSelectionModel::ClearAndSelect | d->selectionBehaviorFlags();
switch (hint) {
case QAbstractItemDelegate::EditNextItem: {
QModelIndex index = moveCursor(MoveNext, Qt::NoModifier);
diff --git a/src/widgets/itemviews/qitemdelegate.cpp b/src/widgets/itemviews/qitemdelegate.cpp
index 0b654a7485..6a1fe22395 100644
--- a/src/widgets/itemviews/qitemdelegate.cpp
+++ b/src/widgets/itemviews/qitemdelegate.cpp
@@ -1210,13 +1210,10 @@ bool QItemDelegate::eventFilter(QObject *object, QEvent *event)
case Qt::Key_Escape:
// don't commit data
emit closeEditor(editor, QAbstractItemDelegate::RevertModelCache);
- break;
+ return true;
default:
return false;
}
- if (editor->parentWidget())
- editor->parentWidget()->setFocus();
- return true;
} else if (event->type() == QEvent::FocusOut || (event->type() == QEvent::Hide && editor->isWindow())) {
//the Hide event will take care of he editors that are in fact complete dialogs
if (!editor->isActiveWindow() || (QApplication::focusWidget() != editor)) {
diff --git a/src/widgets/itemviews/qstyleditemdelegate.cpp b/src/widgets/itemviews/qstyleditemdelegate.cpp
index c2aa630918..da5aeb3290 100644
--- a/src/widgets/itemviews/qstyleditemdelegate.cpp
+++ b/src/widgets/itemviews/qstyleditemdelegate.cpp
@@ -678,13 +678,10 @@ bool QStyledItemDelegate::eventFilter(QObject *object, QEvent *event)
case Qt::Key_Escape:
// don't commit data
emit closeEditor(editor, QAbstractItemDelegate::RevertModelCache);
- break;
+ return true;
default:
return false;
}
- if (editor->parentWidget())
- editor->parentWidget()->setFocus();
- return true;
} else if (event->type() == QEvent::FocusOut || (event->type() == QEvent::Hide && editor->isWindow())) {
//the Hide event will take care of he editors that are in fact complete dialogs
if (!editor->isActiveWindow() || (QApplication::focusWidget() != editor)) {
diff --git a/src/widgets/kernel/qapplication.cpp b/src/widgets/kernel/qapplication.cpp
index 92d3359909..8d0a51606e 100644
--- a/src/widgets/kernel/qapplication.cpp
+++ b/src/widgets/kernel/qapplication.cpp
@@ -2867,16 +2867,19 @@ bool QApplication::notify(QObject *receiver, QEvent *e)
case QEvent::NetworkReplyUpdated:
break;
default:
- if (receiver->isWidgetType()) {
- if (d->gestureManager->filterEvent(static_cast<QWidget *>(receiver), e))
- return true;
- } else {
- // a special case for events that go to QGesture objects.
- // We pass the object to the gesture manager and it'll figure
- // out if it's QGesture or not.
- if (d->gestureManager->filterEvent(receiver, e))
- return true;
+ if (d->gestureManager->thread() == QThread::currentThread()) {
+ if (receiver->isWidgetType()) {
+ if (d->gestureManager->filterEvent(static_cast<QWidget *>(receiver), e))
+ return true;
+ } else {
+ // a special case for events that go to QGesture objects.
+ // We pass the object to the gesture manager and it'll figure
+ // out if it's QGesture or not.
+ if (d->gestureManager->filterEvent(receiver, e))
+ return true;
+ }
}
+ break;
}
}
#endif // QT_NO_GESTURES
@@ -3976,7 +3979,11 @@ bool QApplicationPrivate::translateRawTouchEvent(QWidget *window,
break;
}
default:
- if (widget->testAttribute(Qt::WA_WState_AcceptedTouchBeginEvent)) {
+ if (widget->testAttribute(Qt::WA_WState_AcceptedTouchBeginEvent)
+#ifndef QT_NO_GESTURES
+ || QGestureManager::gesturePending(widget)
+#endif
+ ) {
if (touchEvent.type() == QEvent::TouchEnd)
widget->setAttribute(Qt::WA_WState_AcceptedTouchBeginEvent, false);
if (QApplication::sendSpontaneousEvent(widget, &touchEvent) && touchEvent.isAccepted())
diff --git a/src/widgets/kernel/qgesturemanager.cpp b/src/widgets/kernel/qgesturemanager.cpp
index 18abad4b40..929e5e2fcf 100644
--- a/src/widgets/kernel/qgesturemanager.cpp
+++ b/src/widgets/kernel/qgesturemanager.cpp
@@ -718,6 +718,12 @@ void QGestureManager::recycle(QGesture *gesture)
}
}
+bool QGestureManager::gesturePending(QObject *o)
+{
+ const QGestureManager *gm = QGestureManager::instance();
+ return gm && gm->m_gestureOwners.key(o);
+}
+
QT_END_NAMESPACE
#endif // QT_NO_GESTURES
diff --git a/src/widgets/kernel/qgesturemanager_p.h b/src/widgets/kernel/qgesturemanager_p.h
index 4ab631a921..6264b5a25d 100644
--- a/src/widgets/kernel/qgesturemanager_p.h
+++ b/src/widgets/kernel/qgesturemanager_p.h
@@ -81,6 +81,7 @@ public:
#endif //QT_NO_GRAPHICSVIEW
static QGestureManager* instance(); // declared in qapplication.cpp
+ static bool gesturePending(QObject *o);
void cleanupCachedGestures(QObject *target, Qt::GestureType type);
diff --git a/src/widgets/kernel/qstandardgestures.cpp b/src/widgets/kernel/qstandardgestures.cpp
index e3fd6404db..64ab68257a 100644
--- a/src/widgets/kernel/qstandardgestures.cpp
+++ b/src/widgets/kernel/qstandardgestures.cpp
@@ -77,11 +77,10 @@ QGestureRecognizer::Result QPanGestureRecognizer::recognize(QGesture *state,
QPanGesture *q = static_cast<QPanGesture *>(state);
QPanGesturePrivate *d = q->d_func();
- const QTouchEvent *ev = static_cast<const QTouchEvent *>(event);
-
- QGestureRecognizer::Result result;
+ QGestureRecognizer::Result result = QGestureRecognizer::Ignore;
switch (event->type()) {
case QEvent::TouchBegin: {
+ const QTouchEvent *ev = static_cast<const QTouchEvent *>(event);
result = QGestureRecognizer::MayBeGesture;
QTouchEvent::TouchPoint p = ev->touchPoints().at(0);
d->lastOffset = d->offset = QPointF();
@@ -89,6 +88,7 @@ QGestureRecognizer::Result QPanGestureRecognizer::recognize(QGesture *state,
}
case QEvent::TouchEnd: {
if (q->state() != Qt::NoGesture) {
+ const QTouchEvent *ev = static_cast<const QTouchEvent *>(event);
if (ev->touchPoints().size() == 2) {
QTouchEvent::TouchPoint p1 = ev->touchPoints().at(0);
QTouchEvent::TouchPoint p2 = ev->touchPoints().at(1);
@@ -104,6 +104,7 @@ QGestureRecognizer::Result QPanGestureRecognizer::recognize(QGesture *state,
break;
}
case QEvent::TouchUpdate: {
+ const QTouchEvent *ev = static_cast<const QTouchEvent *>(event);
if (ev->touchPoints().size() >= 2) {
QTouchEvent::TouchPoint p1 = ev->touchPoints().at(0);
QTouchEvent::TouchPoint p2 = ev->touchPoints().at(1);
@@ -121,13 +122,7 @@ QGestureRecognizer::Result QPanGestureRecognizer::recognize(QGesture *state,
}
break;
}
- case QEvent::MouseButtonPress:
- case QEvent::MouseMove:
- case QEvent::MouseButtonRelease:
- result = QGestureRecognizer::Ignore;
- break;
default:
- result = QGestureRecognizer::Ignore;
break;
}
return result;
@@ -168,9 +163,7 @@ QGestureRecognizer::Result QPinchGestureRecognizer::recognize(QGesture *state,
QPinchGesture *q = static_cast<QPinchGesture *>(state);
QPinchGesturePrivate *d = q->d_func();
- const QTouchEvent *ev = static_cast<const QTouchEvent *>(event);
-
- QGestureRecognizer::Result result;
+ QGestureRecognizer::Result result = QGestureRecognizer::Ignore;
switch (event->type()) {
case QEvent::TouchBegin: {
@@ -186,6 +179,7 @@ QGestureRecognizer::Result QPinchGestureRecognizer::recognize(QGesture *state,
break;
}
case QEvent::TouchUpdate: {
+ const QTouchEvent *ev = static_cast<const QTouchEvent *>(event);
d->changeFlags = 0;
if (ev->touchPoints().size() == 2) {
QTouchEvent::TouchPoint p1 = ev->touchPoints().at(0);
@@ -245,13 +239,7 @@ QGestureRecognizer::Result QPinchGestureRecognizer::recognize(QGesture *state,
}
break;
}
- case QEvent::MouseButtonPress:
- case QEvent::MouseMove:
- case QEvent::MouseButtonRelease:
- result = QGestureRecognizer::Ignore;
- break;
default:
- result = QGestureRecognizer::Ignore;
break;
}
return result;
@@ -297,9 +285,7 @@ QGestureRecognizer::Result QSwipeGestureRecognizer::recognize(QGesture *state,
QSwipeGesture *q = static_cast<QSwipeGesture *>(state);
QSwipeGesturePrivate *d = q->d_func();
- const QTouchEvent *ev = static_cast<const QTouchEvent *>(event);
-
- QGestureRecognizer::Result result;
+ QGestureRecognizer::Result result = QGestureRecognizer::Ignore;
switch (event->type()) {
case QEvent::TouchBegin: {
@@ -318,6 +304,7 @@ QGestureRecognizer::Result QSwipeGestureRecognizer::recognize(QGesture *state,
break;
}
case QEvent::TouchUpdate: {
+ const QTouchEvent *ev = static_cast<const QTouchEvent *>(event);
if (!d->started)
result = QGestureRecognizer::CancelGesture;
else if (ev->touchPoints().size() == 3) {
@@ -384,13 +371,7 @@ QGestureRecognizer::Result QSwipeGestureRecognizer::recognize(QGesture *state,
}
break;
}
- case QEvent::MouseButtonPress:
- case QEvent::MouseMove:
- case QEvent::MouseButtonRelease:
- result = QGestureRecognizer::Ignore;
- break;
default:
- result = QGestureRecognizer::Ignore;
break;
}
return result;
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index 8db5666d85..569828c44d 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -4681,7 +4681,8 @@ void QWidget::unsetCursor()
void QWidget::render(QPaintDevice *target, const QPoint &targetOffset,
const QRegion &sourceRegion, RenderFlags renderFlags)
{
- d_func()->render(target, targetOffset, sourceRegion, renderFlags, false);
+ QPainter p(target);
+ render(&p, targetOffset, sourceRegion, renderFlags);
}
/*!
@@ -4725,9 +4726,6 @@ void QWidget::render(QPainter *painter, const QPoint &targetOffset,
d->createExtra();
d->extra->inRenderWithPainter = true;
-#ifdef Q_WS_MAC
- d->render_helper(painter, targetOffset, toBePainted, renderFlags);
-#else
QPaintEngine *engine = painter->paintEngine();
Q_ASSERT(engine);
QPaintEnginePrivate *enginePriv = engine->d_func();
@@ -4738,7 +4736,7 @@ void QWidget::render(QPainter *painter, const QPoint &targetOffset,
// Render via a pixmap when dealing with non-opaque painters or printers.
if (!inRenderWithPainter && (opacity < 1.0 || (target->devType() == QInternal::Printer))) {
d->render_helper(painter, targetOffset, toBePainted, renderFlags);
- d->extra->inRenderWithPainter = false;
+ d->extra->inRenderWithPainter = inRenderWithPainter;
return;
}
@@ -4759,7 +4757,7 @@ void QWidget::render(QPainter *painter, const QPoint &targetOffset,
enginePriv->setSystemViewport(oldSystemClip);
}
- render(target, targetOffset, toBePainted, renderFlags);
+ d->render(target, targetOffset, toBePainted, renderFlags);
// Restore system clip, viewport and transform.
enginePriv->systemClip = oldSystemClip;
@@ -4768,9 +4766,8 @@ void QWidget::render(QPainter *painter, const QPoint &targetOffset,
// Restore shared painter.
d->setSharedPainter(oldPainter);
-#endif
- d->extra->inRenderWithPainter = false;
+ d->extra->inRenderWithPainter = inRenderWithPainter;
}
static void sendResizeEvents(QWidget *target)
@@ -5208,8 +5205,7 @@ void QWidgetPrivate::drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QP
}
void QWidgetPrivate::render(QPaintDevice *target, const QPoint &targetOffset,
- const QRegion &sourceRegion, QWidget::RenderFlags renderFlags,
- bool readyToRender)
+ const QRegion &sourceRegion, QWidget::RenderFlags renderFlags)
{
if (!target) {
qWarning("QWidget::render: null pointer to paint device");
@@ -5217,7 +5213,7 @@ void QWidgetPrivate::render(QPaintDevice *target, const QPoint &targetOffset,
}
const bool inRenderWithPainter = extra && extra->inRenderWithPainter;
- QRegion paintRegion = !inRenderWithPainter && !readyToRender
+ QRegion paintRegion = !inRenderWithPainter
? prepareToRender(sourceRegion, renderFlags)
: sourceRegion;
if (paintRegion.isEmpty())
@@ -5276,23 +5272,12 @@ void QWidgetPrivate::render(QPaintDevice *target, const QPoint &targetOffset,
flags |= DontSetCompositionMode;
- if (target->devType() == QInternal::Printer) {
- QPainter p(target);
- render_helper(&p, targetOffset, paintRegion, renderFlags);
- return;
- }
-
-#ifndef Q_WS_MAC
// Render via backingstore.
drawWidget(target, paintRegion, offset, flags, sharedPainter());
// Restore shared painter.
if (oldSharedPainter)
setSharedPainter(oldSharedPainter);
-#else
- // Render via backingstore (no shared painter).
- drawWidget(target, paintRegion, offset, flags, 0);
-#endif
}
void QWidgetPrivate::paintSiblingsRecursive(QPaintDevice *pdev, const QObjectList& siblings, int index, const QRegion &rgn,
diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h
index bdfc57f7c3..99cba0e20f 100644
--- a/src/widgets/kernel/qwidget_p.h
+++ b/src/widgets/kernel/qwidget_p.h
@@ -389,7 +389,7 @@ public:
void render_helper(QPainter *painter, const QPoint &targetOffset, const QRegion &sourceRegion,
QWidget::RenderFlags renderFlags);
void render(QPaintDevice *target, const QPoint &targetOffset, const QRegion &sourceRegion,
- QWidget::RenderFlags renderFlags, bool readyToRender);
+ QWidget::RenderFlags renderFlags);
void drawWidget(QPaintDevice *pdev, const QRegion &rgn, const QPoint &offset, int flags,
QPainter *sharedPainter = 0, QWidgetBackingStore *backingStore = 0);
@@ -628,7 +628,7 @@ public:
#ifndef QT_NO_OPENGL
virtual GLuint textureId() const { return 0; }
- void setRenderToTexture() { renderToTexture = true; textureChildSeen = true; }
+ void setRenderToTexture() { renderToTexture = true; setTextureChildSeen(); }
void setTextureChildSeen()
{
Q_Q(QWidget);
diff --git a/src/widgets/util/qcolormap.cpp b/src/widgets/util/qcolormap.cpp
index 03ee8a395e..decfd7bd2c 100644
--- a/src/widgets/util/qcolormap.cpp
+++ b/src/widgets/util/qcolormap.cpp
@@ -66,7 +66,12 @@ static QColormapPrivate *screenMap = 0;
void QColormap::initialize()
{
screenMap = new QColormapPrivate;
-
+ if (!QGuiApplication::primaryScreen()) {
+ qWarning("no screens available, assuming 24-bit color");
+ screenMap->depth = 24;
+ screenMap->mode = QColormap::Direct;
+ return;
+ }
screenMap->depth = QGuiApplication::primaryScreen()->depth();
if (screenMap->depth < 8) {
screenMap->mode = QColormap::Indexed;
diff --git a/src/widgets/widgets/qscrollbar.cpp b/src/widgets/widgets/qscrollbar.cpp
index 05b8935bb5..5060ca0a70 100644
--- a/src/widgets/widgets/qscrollbar.cpp
+++ b/src/widgets/widgets/qscrollbar.cpp
@@ -248,8 +248,13 @@ void QScrollBarPrivate::flash()
Q_Q(QScrollBar);
if (!flashed && q->style()->styleHint(QStyle::SH_ScrollBar_Transient, 0, q)) {
flashed = true;
- q->show();
+ if (!q->isVisible())
+ q->show();
+ else
+ q->update();
}
+ if (!flashTimer)
+ flashTimer = q->startTimer(0);
}
void QScrollBarPrivate::activateControl(uint control, int threshold)
@@ -386,6 +391,7 @@ void QScrollBarPrivate::init()
pointerOutsidePressedControl = false;
transient = q->style()->styleHint(QStyle::SH_ScrollBar_Transient, 0, q);
flashed = false;
+ flashTimer = 0;
q->setFocusPolicy(Qt::NoFocus);
QSizePolicy sp(QSizePolicy::Minimum, QSizePolicy::Fixed, QSizePolicy::Slider);
if (orientation == Qt::Vertical)
@@ -476,6 +482,7 @@ void QScrollBar::sliderChange(SliderChange change)
*/
bool QScrollBar::event(QEvent *event)
{
+ Q_D(QScrollBar);
switch(event->type()) {
case QEvent::HoverEnter:
case QEvent::HoverLeave:
@@ -486,6 +493,16 @@ bool QScrollBar::event(QEvent *event)
case QEvent::StyleChange:
d_func()->setTransient(style()->styleHint(QStyle::SH_ScrollBar_Transient, 0, this));
break;
+ case QEvent::Timer:
+ if (static_cast<QTimerEvent *>(event)->timerId() == d->flashTimer) {
+ if (d->flashed && style()->styleHint(QStyle::SH_ScrollBar_Transient, 0, this)) {
+ d->flashed = false;
+ update();
+ }
+ killTimer(d->flashTimer);
+ d->flashTimer = 0;
+ }
+ break;
default:
break;
}
@@ -536,10 +553,6 @@ void QScrollBar::paintEvent(QPaintEvent *)
opt.activeSubControls = (QStyle::SubControl)d->hoverControl;
}
style()->drawComplexControl(QStyle::CC_ScrollBar, &opt, &p, this);
- if (d->flashed && style()->styleHint(QStyle::SH_ScrollBar_Transient, 0, this)) {
- d->flashed = false;
- update();
- }
}
/*!
diff --git a/src/widgets/widgets/qscrollbar_p.h b/src/widgets/widgets/qscrollbar_p.h
index c62c337a40..5fc714d530 100644
--- a/src/widgets/widgets/qscrollbar_p.h
+++ b/src/widgets/widgets/qscrollbar_p.h
@@ -81,6 +81,7 @@ public:
void setTransient(bool value);
bool flashed;
+ int flashTimer;
void flash();
};
diff --git a/src/widgets/widgets/qwidgettextcontrol.cpp b/src/widgets/widgets/qwidgettextcontrol.cpp
index 03a65aa8e5..3740f3e698 100644
--- a/src/widgets/widgets/qwidgettextcontrol.cpp
+++ b/src/widgets/widgets/qwidgettextcontrol.cpp
@@ -239,9 +239,6 @@ bool QWidgetTextControlPrivate::cursorMoveKeyEvent(QKeyEvent *e)
else if (e == QKeySequence::MoveToPreviousLine) {
op = QTextCursor::Up;
}
- else if (e == QKeySequence::MoveToPreviousLine) {
- op = QTextCursor::Up;
- }
else if (e == QKeySequence::MoveToStartOfLine) {
op = QTextCursor::StartOfLine;
}
diff --git a/src/xml/doc/src/qtxml-index.qdoc b/src/xml/doc/src/qtxml-index.qdoc
index ded8f3de3c..76866ad66b 100644
--- a/src/xml/doc/src/qtxml-index.qdoc
+++ b/src/xml/doc/src/qtxml-index.qdoc
@@ -44,5 +44,5 @@
\snippet code/doc_src_qtxml.pro 1
The \l{Qt XML C++ Classes} page gives an overview over the available classes
- int this module.
+ in this module.
*/