summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@theqtcompany.com>2015-11-23 07:13:00 +0100
committerLiang Qi <liang.qi@theqtcompany.com>2015-11-23 07:13:00 +0100
commit1ed7a67a4cef8350103e4ea33b4bbd084f5d4c2d (patch)
tree03dd7b6f8d9ccc02da6d0d882793ec62c71b00f7
parentdbb7817e13bc7f7ccb8f04b00a65eb3dcf8d25f8 (diff)
parent6a2b17eeec2d171d2afa17bdbc36456346bfd13b (diff)
Merge remote-tracking branch 'origin/5.6' into dev
Conflicts: src/corelib/kernel/qcoreapplication.cpp src/corelib/thread/qthread_unix.cpp Change-Id: Ia08d613c3f0bd08cb6dc3e3a57257207dfd4a099
-rw-r--r--mkspecs/common/winrt_winphone/manifests/10.0/AppxManifest.xml.in5
-rw-r--r--mkspecs/features/qt.prf4
-rw-r--r--mkspecs/features/qt_functions.prf2
-rw-r--r--mkspecs/features/qt_module.prf10
-rw-r--r--mkspecs/features/qt_module_pris.prf2
-rw-r--r--mkspecs/features/testcase.prf2
-rw-r--r--mkspecs/features/winrt/package_manifest.prf4
-rw-r--r--qmake/generators/makefiledeps.cpp252
-rw-r--r--src/3rdparty/freetype/freetype.pro4
-rw-r--r--src/corelib/kernel/qcoreapplication.cpp26
-rw-r--r--src/corelib/kernel/qeventdispatcher_cf.mm3
-rw-r--r--src/corelib/mimetypes/qmimeprovider.cpp7
-rw-r--r--src/corelib/plugin/qfactoryloader.cpp2
-rw-r--r--src/corelib/thread/qthread_unix.cpp22
-rw-r--r--src/corelib/tools/qlocale_win.cpp48
-rw-r--r--src/corelib/xml/qxmlstream.cpp7
-rw-r--r--src/corelib/xml/qxmlstream.h26
-rw-r--r--src/gui/image/qppmhandler.cpp16
-rw-r--r--src/gui/kernel/qguiapplication.cpp13
-rw-r--r--src/gui/kernel/qplatformscreen.cpp2
-rw-r--r--src/gui/painting/qplatformbackingstore.cpp42
-rw-r--r--src/gui/text/qtextlayout.cpp2
-rw-r--r--src/network/access/qhttpnetworkconnectionchannel.cpp4
-rw-r--r--src/network/kernel/qhostinfo_winrt.cpp35
-rw-r--r--src/network/kernel/qnetworkinterface_winrt.cpp3
-rw-r--r--src/platformsupport/eglconvenience/eglconvenience.pri1
-rw-r--r--src/platformsupport/eglconvenience/qeglstreamconvenience_p.h9
-rw-r--r--src/platformsupport/input/evdevmouse/qevdevmousehandler.cpp4
-rw-r--r--src/platformsupport/input/evdevmouse/qevdevmousemanager.cpp4
-rw-r--r--src/platformsupport/input/libinput/qlibinputpointer.cpp8
-rw-r--r--src/plugins/bearer/generic/qgenericengine.cpp3
-rw-r--r--src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp2
-rw-r--r--src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp5
-rw-r--r--src/plugins/platforms/eglfs/qeglfsdeviceintegration.h1
-rw-r--r--src/plugins/platforms/eglfs/qeglfsscreen.cpp5
-rw-r--r--src/plugins/platforms/eglfs/qeglfsscreen.h1
-rw-r--r--src/plugins/platforms/ios/qiosscreen.h2
-rw-r--r--src/plugins/platforms/ios/qiosscreen.mm25
-rw-r--r--src/plugins/platforms/windows/openglblacklists/default.json4
-rw-r--r--src/plugins/platforms/windows/qwindowsbackingstore.cpp3
-rw-r--r--src/plugins/platforms/windows/qwindowscursor.cpp174
-rw-r--r--src/plugins/platforms/windows/qwindowscursor.h65
-rw-r--r--src/plugins/platforms/windows/qwindowsdrag.cpp25
-rw-r--r--src/plugins/platforms/windows/qwindowstheme.cpp2
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.cpp19
-rw-r--r--src/plugins/platforms/windows/qwindowswindow.h6
-rw-r--r--src/plugins/platforms/winrt/qwinrtintegration.cpp6
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.cpp5
-rw-r--r--src/plugins/platforms/xcb/qxcbwindow.h1
-rw-r--r--src/sql/models/qsqlquerymodel.cpp2
-rw-r--r--src/sql/models/qsqlrelationaltablemodel.cpp2
-rw-r--r--src/sql/models/qsqltablemodel.cpp2
-rw-r--r--src/widgets/kernel/qopenglwidget.cpp6
-rw-r--r--src/widgets/kernel/qwidget.cpp3
-rw-r--r--src/widgets/kernel/qwidget_p.h9
-rw-r--r--src/widgets/kernel/qwidgetbackingstore.cpp228
-rw-r--r--src/widgets/kernel/qwidgetbackingstore_p.h5
-rw-r--r--src/widgets/styles/qcommonstyle.cpp81
-rw-r--r--src/widgets/styles/qcommonstyle_p.h2
-rw-r--r--src/widgets/widgets/qmenu.cpp7
-rw-r--r--tests/auto/gui/image/qimagereader/images/longcomment.pgm12
-rw-r--r--tests/auto/gui/image/qimagereader/tst_qimagereader.cpp1
-rw-r--r--tests/auto/other/compiler/tst_compiler.cpp187
-rw-r--r--tests/auto/sql/models/qsqlquerymodel/tst_qsqlquerymodel.cpp13
-rw-r--r--tests/auto/tools/qmake/testdata/findDeps/findDeps.pro2
-rw-r--r--tests/auto/tools/qmake/testdata/findDeps/main.cpp9
-rw-r--r--tests/auto/tools/qmake/testdata/findDeps/needed.cpp1
-rw-r--r--tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp74
-rw-r--r--tests/manual/qopenglwidget/openglwidget/main.cpp175
-rw-r--r--tests/manual/qopenglwidget/openglwidget/openglwidget.cpp23
-rw-r--r--tests/manual/qopenglwidget/openglwidget/openglwidget.h5
71 files changed, 1183 insertions, 589 deletions
diff --git a/mkspecs/common/winrt_winphone/manifests/10.0/AppxManifest.xml.in b/mkspecs/common/winrt_winphone/manifests/10.0/AppxManifest.xml.in
index 9e188084ad..d091ea3b82 100644
--- a/mkspecs/common/winrt_winphone/manifests/10.0/AppxManifest.xml.in
+++ b/mkspecs/common/winrt_winphone/manifests/10.0/AppxManifest.xml.in
@@ -43,8 +43,5 @@
</uap:VisualElements>
</Application>
</Applications>
-
- <Capabilities>
- <Capability Name=\"internetClient\" />
- </Capabilities>
+ $${WINRT_MANIFEST.capabilities}
</Package>
diff --git a/mkspecs/features/qt.prf b/mkspecs/features/qt.prf
index dfff6cc091..c3448718b9 100644
--- a/mkspecs/features/qt.prf
+++ b/mkspecs/features/qt.prf
@@ -89,7 +89,7 @@ for(ever) {
MODULE_LIBS_ADD -= $$QMAKE_DEFAULT_LIBDIRS
LINKAGE =
- mac:contains(MODULE_CONFIG, lib_bundle) {
+ contains(MODULE_CONFIG, lib_bundle) {
FRAMEWORK_INCLUDE = $${MODULE_LIBS}/$${MODULE_NAME}.framework/Headers
!qt_no_framework_direct_includes {
INCLUDEPATH *= $$FRAMEWORK_INCLUDE
@@ -111,7 +111,7 @@ for(ever) {
# Re-insert the major version in the library name (cf qt5LibraryTarget above)
# unless it's a framework build
- !mac|!contains(MODULE_CONFIG, lib_bundle): \
+ !contains(MODULE_CONFIG, lib_bundle): \
MODULE_NAME ~= s,^Qt,Qt$$QT_MAJOR_VERSION,
isEmpty(LINKAGE) {
diff --git a/mkspecs/features/qt_functions.prf b/mkspecs/features/qt_functions.prf
index 6616aa4230..403b847ac1 100644
--- a/mkspecs/features/qt_functions.prf
+++ b/mkspecs/features/qt_functions.prf
@@ -15,7 +15,7 @@ defineReplace(qtPlatformTargetSuffix) {
defineReplace(qtLibraryTarget) {
LIBRARY_NAME = $$1
- mac:CONFIG(shared, static|shared):contains(QT_CONFIG, qt_framework) {
+ CONFIG(shared, static|shared):contains(QT_CONFIG, qt_framework) {
QMAKE_FRAMEWORK_BUNDLE_NAME = $$LIBRARY_NAME
export(QMAKE_FRAMEWORK_BUNDLE_NAME)
}
diff --git a/mkspecs/features/qt_module.prf b/mkspecs/features/qt_module.prf
index 663bddffb0..e2e56c318f 100644
--- a/mkspecs/features/qt_module.prf
+++ b/mkspecs/features/qt_module.prf
@@ -42,8 +42,8 @@ host_build {
}
}
-mac:CONFIG(shared, static|shared):contains(QT_CONFIG, qt_framework): \
- CONFIG += qt_framework
+CONFIG(shared, static|shared):contains(QT_CONFIG, qt_framework): \
+ CONFIG += lib_bundle
CONFIG += relative_qt_rpath # Qt libraries should be relocatable
@@ -106,7 +106,7 @@ else: \
DEFINES += QT_BUILD_$${ucmodule}_LIB
# OS X and iOS frameworks
-qt_framework {
+lib_bundle {
# Set the CFBundleIdentifier prefix for Qt frameworks
QMAKE_TARGET_BUNDLE_PREFIX = org.qt-project
#QMAKE_FRAMEWORK_VERSION = 4.0
@@ -115,8 +115,6 @@ qt_framework {
CONFIG += bundle
QMAKE_BUNDLE_EXTENSION = .framework
QMAKE_INFO_PLIST = $$QMAKESPEC/Info.plist.lib
- } else {
- CONFIG += lib_bundle
}
CONFIG -= qt_install_headers #no need to install these as well
!debug_and_release|!build_all|CONFIG(release, debug|release) {
@@ -239,7 +237,7 @@ load(qt_installs)
load(qt_targets)
# this builds on top of qt_common
-!internal_module:!qt_framework:if(unix|mingw) {
+!internal_module:!lib_bundle:if(unix|mingw) {
CONFIG += create_pc
QMAKE_PKGCONFIG_DESTDIR = pkgconfig
host_build: \
diff --git a/mkspecs/features/qt_module_pris.prf b/mkspecs/features/qt_module_pris.prf
index 8c05b90cd6..3f21a0f7d5 100644
--- a/mkspecs/features/qt_module_pris.prf
+++ b/mkspecs/features/qt_module_pris.prf
@@ -55,7 +55,7 @@ MODULE_FWD_PRI = $$mod_work_pfx/qt_lib_$${MODULE_ID}.pri
module_rundep =
static: \
module_build_type = staticlib
- else: qt_framework: \
+ else: lib_bundle: \
module_build_type = lib_bundle
else: \
module_build_type =
diff --git a/mkspecs/features/testcase.prf b/mkspecs/features/testcase.prf
index a6ef930128..6f6f073f70 100644
--- a/mkspecs/features/testcase.prf
+++ b/mkspecs/features/testcase.prf
@@ -27,7 +27,7 @@ check.commands += $(TESTRUNNER)
unix {
isEmpty(TEST_TARGET_DIR): TEST_TARGET_DIR = .
- mac:app_bundle: \
+ app_bundle: \
check.commands += $${TEST_TARGET_DIR}/$(QMAKE_TARGET).app/Contents/MacOS/$(QMAKE_TARGET)
else: \
check.commands += $${TEST_TARGET_DIR}/$(QMAKE_TARGET)
diff --git a/mkspecs/features/winrt/package_manifest.prf b/mkspecs/features/winrt/package_manifest.prf
index 9b4a6672e5..3520fcdf93 100644
--- a/mkspecs/features/winrt/package_manifest.prf
+++ b/mkspecs/features/winrt/package_manifest.prf
@@ -108,6 +108,10 @@
INDENT = "$$escape_expand(\\r\\n) "
+ # All Windows 10 applications need to have internetClient. It is also not marked as additional
+ # capability anymore and is assumed to be standard.
+ *-msvc2015: WINRT_MANIFEST.capabilities += internetClient
+
# Capabilities are given as a string list and may change with the configuration (network, sensors, etc.)
WINRT_MANIFEST.capabilities = $$unique(WINRT_MANIFEST.capabilities)
WINRT_MANIFEST.capabilities_device = $$unique(WINRT_MANIFEST.capabilities_device)
diff --git a/qmake/generators/makefiledeps.cpp b/qmake/generators/makefiledeps.cpp
index 79e017a560..f4479750c8 100644
--- a/qmake/generators/makefiledeps.cpp
+++ b/qmake/generators/makefiledeps.cpp
@@ -56,6 +56,7 @@
QT_BEGIN_NAMESPACE
+// FIXME: a line ending in CRLF gets counted as two lines.
#if 1
#define qmake_endOfLine(c) (c == '\r' || c == '\n')
#else
@@ -431,104 +432,103 @@ bool QMakeSourceFileInfo::findDeps(SourceFile *file)
char *inc = 0;
if(file->type == QMakeSourceFileInfo::TYPE_UI) {
// skip whitespaces
- while(x < buffer_len && (*(buffer+x) == ' ' || *(buffer+x) == '\t'))
+ while (x < buffer_len && (buffer[x] == ' ' || buffer[x] == '\t'))
++x;
- if(*(buffer + x) == '<') {
+ if (buffer[x] == '<') {
++x;
- if(buffer_len >= x + 12 && !strncmp(buffer + x, "includehint", 11) &&
- (*(buffer + x + 11) == ' ' || *(buffer + x + 11) == '>')) {
- for(x += 11; *(buffer + x) != '>'; ++x) ;
+ if (buffer_len >= x + 12 && !strncmp(buffer + x, "includehint", 11) &&
+ (buffer[x + 11] == ' ' || buffer[x + 11] == '>')) {
+ for (x += 11; buffer[x] != '>'; ++x) {} // skip
int inc_len = 0;
- for(x += 1 ; *(buffer + x + inc_len) != '<'; ++inc_len) ;
- *(buffer + x + inc_len) = '\0';
+ for (x += 1 ; buffer[x + inc_len] != '<'; ++inc_len) {} // skip
+ buffer[x + inc_len] = '\0';
inc = buffer + x;
- } else if(buffer_len >= x + 13 && !strncmp(buffer + x, "customwidget", 12) &&
- (*(buffer + x + 12) == ' ' || *(buffer + x + 12) == '>')) {
- for(x += 13; *(buffer + x) != '>'; ++x) ; //skip up to >
+ } else if (buffer_len >= x + 13 && !strncmp(buffer + x, "customwidget", 12) &&
+ (buffer[x + 12] == ' ' || buffer[x + 12] == '>')) {
+ for (x += 13; buffer[x] != '>'; ++x) {} // skip up to >
while(x < buffer_len) {
- for(x++; *(buffer + x) != '<'; ++x) ; //skip up to <
+ for (x++; buffer[x] != '<'; ++x) {} // skip up to <
x++;
if(buffer_len >= x + 7 && !strncmp(buffer+x, "header", 6) &&
- (*(buffer + x + 6) == ' ' || *(buffer + x + 6) == '>')) {
- for(x += 7; *(buffer + x) != '>'; ++x) ; //skip up to >
+ (buffer[x + 6] == ' ' || buffer[x + 6] == '>')) {
+ for (x += 7; buffer[x] != '>'; ++x) {} // skip up to >
int inc_len = 0;
- for(x += 1 ; *(buffer + x + inc_len) != '<'; ++inc_len) ;
- *(buffer + x + inc_len) = '\0';
+ for (x += 1 ; buffer[x + inc_len] != '<'; ++inc_len) {} // skip
+ buffer[x + inc_len] = '\0';
inc = buffer + x;
break;
} else if(buffer_len >= x + 14 && !strncmp(buffer+x, "/customwidget", 13) &&
- (*(buffer + x + 13) == ' ' || *(buffer + x + 13) == '>')) {
+ (buffer[x + 13] == ' ' || buffer[x + 13] == '>')) {
x += 14;
break;
}
}
} else if(buffer_len >= x + 8 && !strncmp(buffer + x, "include", 7) &&
- (*(buffer + x + 7) == ' ' || *(buffer + x + 7) == '>')) {
- for(x += 8; *(buffer + x) != '>'; ++x) {
- if(buffer_len >= x + 9 && *(buffer + x) == 'i' &&
- !strncmp(buffer + x, "impldecl", 8)) {
- for(x += 8; *(buffer + x) != '='; ++x) ;
- if(*(buffer + x) != '=')
+ (buffer[x + 7] == ' ' || buffer[x + 7] == '>')) {
+ for (x += 8; buffer[x] != '>'; ++x) {
+ if (buffer_len >= x + 9 && buffer[x] == 'i' &&
+ !strncmp(buffer + x, "impldecl", 8)) {
+ for (x += 8; buffer[x] != '='; ++x) {} // skip
+ if (buffer[x] != '=')
continue;
- for(++x; *(buffer+x) == '\t' || *(buffer+x) == ' '; ++x) ;
+ for (++x; buffer[x] == '\t' || buffer[x] == ' '; ++x) {} // skip
char quote = 0;
- if(*(buffer+x) == '\'' || *(buffer+x) == '"') {
- quote = *(buffer + x);
+ if (buffer[x] == '\'' || buffer[x] == '"') {
+ quote = buffer[x];
++x;
}
int val_len;
for(val_len = 0; true; ++val_len) {
if(quote) {
- if(*(buffer+x+val_len) == quote)
+ if (buffer[x + val_len] == quote)
break;
- } else if(*(buffer + x + val_len) == '>' ||
- *(buffer + x + val_len) == ' ') {
+ } else if (buffer[x + val_len] == '>' ||
+ buffer[x + val_len] == ' ') {
break;
}
}
-//? char saved = *(buffer + x + val_len);
- *(buffer + x + val_len) = '\0';
+//? char saved = buffer[x + val_len];
+ buffer[x + val_len] = '\0';
if(!strcmp(buffer+x, "in implementation")) {
//### do this
}
}
}
int inc_len = 0;
- for(x += 1 ; *(buffer + x + inc_len) != '<'; ++inc_len) ;
- *(buffer + x + inc_len) = '\0';
+ for (x += 1 ; buffer[x + inc_len] != '<'; ++inc_len) {} // skip
+ buffer[x + inc_len] = '\0';
inc = buffer + x;
}
}
//read past new line now..
- for(; x < buffer_len && !qmake_endOfLine(*(buffer + x)); ++x) ;
+ for (; x < buffer_len && !qmake_endOfLine(buffer[x]); ++x) {} // skip
++line_count;
} else if(file->type == QMakeSourceFileInfo::TYPE_QRC) {
} else if(file->type == QMakeSourceFileInfo::TYPE_C) {
for(int beginning=1; x < buffer_len; ++x) {
- // whitespace comments and line-endings
+ // Seek code or directive, skipping comments and space:
for(; x < buffer_len; ++x) {
- if(*(buffer+x) == ' ' || *(buffer+x) == '\t') {
+ if (buffer[x] == ' ' || buffer[x] == '\t') {
// keep going
- } else if(*(buffer+x) == '/') {
+ } else if (buffer[x] == '/' && x + 1 < buffer_len &&
+ (buffer[x + 1] == '/' || buffer[x + 1] == '*')) {
++x;
- if(buffer_len >= x) {
- if(*(buffer+x) == '/') { //c++ style comment
- for(; x < buffer_len && !qmake_endOfLine(*(buffer + x)); ++x) ;
- beginning = 1;
- } else if(*(buffer+x) == '*') { //c style comment
- for(++x; x < buffer_len; ++x) {
- if(*(buffer+x) == '*') {
- if(x+1 < buffer_len && *(buffer + (x+1)) == '/') {
- ++x;
- break;
- }
- } else if(qmake_endOfLine(*(buffer+x))) {
- ++line_count;
+ if (buffer[x] == '/') { // C++-style comment
+ for (; x < buffer_len && !qmake_endOfLine(buffer[x]); ++x) {} // skip
+ beginning = 1;
+ } else { // C-style comment
+ while (++x < buffer_len) {
+ if (buffer[x] == '*') {
+ if (x + 1 < buffer_len && buffer[x + 1] == '/') {
+ ++x; // skip '*'; for loop skips '/'.
+ break;
}
+ } else if (qmake_endOfLine(buffer[x])) {
+ ++line_count;
}
}
}
- } else if(qmake_endOfLine(*(buffer+x))) {
+ } else if (qmake_endOfLine(buffer[x])) {
++line_count;
beginning = 1;
} else {
@@ -540,19 +540,29 @@ bool QMakeSourceFileInfo::findDeps(SourceFile *file)
break;
// preprocessor directive
- if(beginning && *(buffer+x) == '#')
+ if (beginning && buffer[x] == '#') {
+ // Advance to start of preprocessing directive
+ while (++x < buffer_len
+ && (buffer[x] == ' ' || buffer[x] == '\t')) {} // skip
+
+ if (qmake_endOfLine(buffer[x])) {
+ ++line_count;
+ beginning = 1;
+ continue;
+ }
break;
+ }
// quoted strings
- if(*(buffer+x) == '\'' || *(buffer+x) == '"') {
- const char term = *(buffer+(x++));
- for(; x < buffer_len; ++x) {
- if(*(buffer+x) == term) {
+ if (buffer[x] == '\'' || buffer[x] == '"') {
+ const char term = buffer[x];
+ while (++x < buffer_len) {
+ if (buffer[x] == term) {
++x;
break;
- } else if(*(buffer+x) == '\\') {
+ } else if (buffer[x] == '\\') {
++x;
- } else if(qmake_endOfLine(*(buffer+x))) {
+ } else if (qmake_endOfLine(buffer[x])) {
++line_count;
}
}
@@ -562,34 +572,23 @@ bool QMakeSourceFileInfo::findDeps(SourceFile *file)
if(x >= buffer_len)
break;
- //got a preprocessor symbol
- ++x;
- while(x < buffer_len) {
- if(*(buffer+x) != ' ' && *(buffer+x) != '\t')
- break;
- ++x;
- }
+ // Got a preprocessor directive
+ const char *const keyword = buffer + x;
+ for (;
+ x < buffer_len && buffer[x] >= 'a' && buffer[x] <= 'z';
+ x++) {} // skip over identifier
+ int keyword_len = buffer + x - keyword;
+ for (;
+ x < buffer_len && (buffer[x] == ' ' || buffer[x] == '\t');
+ x++) {} // skip spaces after keyword
- int keyword_len = 0;
- const char *keyword = buffer+x;
- while(x+keyword_len < buffer_len) {
- if(((*(buffer+x+keyword_len) < 'a' || *(buffer+x+keyword_len) > 'z')) &&
- *(buffer+x+keyword_len) != '_') {
- for(x+=keyword_len; //skip spaces after keyword
- x < buffer_len && (*(buffer+x) == ' ' || *(buffer+x) == '\t');
- x++) ;
- break;
- } else if(qmake_endOfLine(*(buffer+x+keyword_len))) {
- x += keyword_len-1;
- keyword_len = 0;
- break;
- }
- keyword_len++;
- }
+ /* Keyword with nothing after it, e.g. #endif: not interesting. */
+ if (qmake_endOfLine(buffer[x]))
+ keyword_len = 0;
if((keyword_len == 7 && !strncmp(keyword, "include", 7)) // C & Obj-C
|| (keyword_len == 6 && !strncmp(keyword, "import", 6))) { // Obj-C
- char term = *(buffer + x);
+ char term = buffer[x];
if(term == '<') {
try_local = false;
term = '>';
@@ -599,34 +598,21 @@ bool QMakeSourceFileInfo::findDeps(SourceFile *file)
x++;
int inc_len;
- for(inc_len = 0; *(buffer + x + inc_len) != term && !qmake_endOfLine(*(buffer + x + inc_len)); ++inc_len) ;
- *(buffer + x + inc_len) = '\0';
+ for (inc_len = 0;
+ buffer[x + inc_len] != term && !qmake_endOfLine(buffer[x + inc_len]);
+ ++inc_len) {} // skip until end of include name
+ buffer[x + inc_len] = '\0';
inc = buffer + x;
x += inc_len;
- } else if(keyword_len == 13 && !strncmp(keyword, "qmake_warning", keyword_len)) {
- char term = 0;
- if(*(buffer + x) == '"')
- term = '"';
- if(*(buffer + x) == '\'')
- term = '\'';
- if(term)
- x++;
-
- int msg_len;
- for(msg_len = 0; (term && *(buffer + x + msg_len) != term) &&
- !qmake_endOfLine(*(buffer + x + msg_len)); ++msg_len) ;
- *(buffer + x + msg_len) = '\0';
- debug_msg(0, "%s:%d %s -- %s", file->file.local().toLatin1().constData(), line_count, keyword, buffer+x);
- x += msg_len;
- } else if(*(buffer+x) == '\'' || *(buffer+x) == '"') {
- const char term = *(buffer+(x++));
+ } else if (buffer[x] == '\'' || buffer[x] == '"') {
+ const char term = buffer[x++];
while(x < buffer_len) {
- if(*(buffer+x) == term)
+ if (buffer[x] == term)
break;
- if(*(buffer+x) == '\\') {
+ if (buffer[x] == '\\') {
x+=2;
} else {
- if(qmake_endOfLine(*(buffer+x)))
+ if (qmake_endOfLine(buffer[x]))
++line_count;
++x;
}
@@ -702,6 +688,13 @@ bool QMakeSourceFileInfo::findDeps(SourceFile *file)
return true;
}
+static bool isCWordChar(char c) {
+ return c == '_'
+ || (c >= 'a' && c <= 'z')
+ || (c >= 'A' && c <= 'Z')
+ || (c >= '0' && c <= '9');
+}
+
bool QMakeSourceFileInfo::findMocs(SourceFile *file)
{
if(file->moc_checked)
@@ -739,14 +732,14 @@ bool QMakeSourceFileInfo::findMocs(SourceFile *file)
/* qmake ignore Q_GADGET */
/* qmake ignore Q_OBJECT */
for(int x = 0; x < buffer_len; x++) {
- if(*(buffer + x) == '/') {
+ if (buffer[x] == '/') {
++x;
if(buffer_len >= x) {
- if(*(buffer + x) == '/') { //c++ style comment
- for(;x < buffer_len && !qmake_endOfLine(*(buffer + x)); ++x) ;
- } else if(*(buffer + x) == '*') { //c style comment
+ if (buffer[x] == '/') { // C++-style comment
+ for (; x < buffer_len && !qmake_endOfLine(buffer[x]); ++x) {} // skip
+ } else if (buffer[x] == '*') { // C-style comment
for(++x; x < buffer_len; ++x) {
- if(*(buffer + x) == 't' || *(buffer + x) == 'q') { //ignore
+ if (buffer[x] == 't' || buffer[x] == 'q') { // ignore
if(buffer_len >= (x + 20) &&
!strncmp(buffer + x + 1, "make ignore Q_OBJECT", 20)) {
debug_msg(2, "Mocgen: %s:%d Found \"qmake ignore Q_OBJECT\"",
@@ -760,38 +753,35 @@ bool QMakeSourceFileInfo::findMocs(SourceFile *file)
x += 20;
ignore_qgadget = true;
}
- } else if(*(buffer + x) == '*') {
- if(buffer_len >= (x+1) && *(buffer + (x+1)) == '/') {
+ } else if (buffer[x] == '*') {
+ if (buffer_len >= x + 1 && buffer[x + 1] == '/') {
++x;
break;
}
- } else if(Option::debug_level && qmake_endOfLine(*(buffer + x))) {
+ } else if (Option::debug_level && qmake_endOfLine(buffer[x])) {
++line_count;
}
}
}
}
- } else if(*(buffer+x) == '\'' || *(buffer+x) == '"') {
- const char term = *(buffer+(x++));
+ } else if (buffer[x] == '\'' || buffer[x] == '"') {
+ const char term = buffer[x++];
while(x < buffer_len) {
- if(*(buffer+x) == term)
+ if (buffer[x] == term)
break;
- if(*(buffer+x) == '\\') {
+ if (buffer[x] == '\\') {
x+=2;
} else {
- if(qmake_endOfLine(*(buffer+x)))
+ if (qmake_endOfLine(buffer[x]))
++line_count;
++x;
}
}
}
- if(Option::debug_level && qmake_endOfLine(*(buffer+x)))
+ if (Option::debug_level && qmake_endOfLine(buffer[x]))
++line_count;
- if (buffer_len > x + 2 && buffer[x + 1] == 'Q' && buffer[x + 2] == '_' &&
- *(buffer + x) != '_' &&
- (*(buffer + x) < 'a' || *(buffer + x) > 'z') &&
- (*(buffer + x) < 'A' || *(buffer + x) > 'Z') &&
- (*(buffer + x) < '0' || *(buffer + x) > '9')) {
+ if (buffer_len > x + 2 && buffer[x + 1] == 'Q' &&
+ buffer[x + 2] == '_' && !isCWordChar(buffer[x])) {
++x;
int match = 0;
static const char *interesting[] = { "OBJECT", "GADGET" };
@@ -800,8 +790,8 @@ bool QMakeSourceFileInfo::findMocs(SourceFile *file)
continue;
else if(interest == 1 && ignore_qgadget)
continue;
- for(m1 = 0, m2 = 0; *(interesting[interest]+m1); ++m1) {
- if(*(interesting[interest]+m1) != *(buffer+x+2+m1)) {
+ for (m1 = 0, m2 = 0; interesting[interest][m1]; ++m1) {
+ if (interesting[interest][m1] != buffer[x + 2 + m1]) {
m2 = -1;
break;
}
@@ -812,14 +802,12 @@ bool QMakeSourceFileInfo::findMocs(SourceFile *file)
break;
}
}
- if(match && *(buffer+x+match) != '_' &&
- (*(buffer+x+match) < 'a' || *(buffer+x+match) > 'z') &&
- (*(buffer+x+match) < 'A' || *(buffer+x+match) > 'Z') &&
- (*(buffer+x+match) < '0' || *(buffer+x+match) > '9')) {
- if(Option::debug_level) {
- *(buffer+x+match) = '\0';
- debug_msg(2, "Mocgen: %s:%d Found MOC symbol %s", file->file.real().toLatin1().constData(),
- line_count, buffer+x);
+ if (match && !isCWordChar(buffer[x + match])) {
+ if (Option::debug_level) {
+ buffer[x + match] = '\0';
+ debug_msg(2, "Mocgen: %s:%d Found MOC symbol %s",
+ file->file.real().toLatin1().constData(),
+ line_count, buffer + x);
}
file->mocable = true;
return true;
diff --git a/src/3rdparty/freetype/freetype.pro b/src/3rdparty/freetype/freetype.pro
index a32579e0f9..e9436febc6 100644
--- a/src/3rdparty/freetype/freetype.pro
+++ b/src/3rdparty/freetype/freetype.pro
@@ -67,5 +67,9 @@ contains(QT_CONFIG, system-zlib) {
DEFINES += FT_CONFIG_OPTION_SYSTEM_ZLIB
include($$PWD/../zlib_dependency.pri)
}
+contains(QT_CONFIG, system-png) {
+ DEFINES += FT_CONFIG_OPTION_USE_PNG
+ include($$PWD/../png_dependency.pri)
+}
DEFINES += TT_CONFIG_OPTION_SUBPIXEL_HINTING
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index 53206cfb8c..e64ee04134 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -66,8 +66,12 @@
#ifndef QT_NO_QOBJECT
#if defined(Q_OS_UNIX)
-# if !defined(QT_NO_GLIB)
-# include "qeventdispatcher_glib_p.h"
+# if defined(Q_OS_OSX)
+# include "qeventdispatcher_cf_p.h"
+# else
+# if !defined(QT_NO_GLIB)
+# include "qeventdispatcher_glib_p.h"
+# endif
# endif
# include "qeventdispatcher_unix_p.h"
#endif
@@ -469,12 +473,21 @@ void QCoreApplicationPrivate::createEventDispatcher()
{
Q_Q(QCoreApplication);
#if defined(Q_OS_UNIX)
-# if !defined(QT_NO_GLIB)
+# if defined(Q_OS_OSX)
+ bool ok = false;
+ int value = qEnvironmentVariableIntValue("QT_EVENT_DISPATCHER_CORE_FOUNDATION", &ok);
+ if (ok && value > 0)
+ eventDispatcher = new QEventDispatcherCoreFoundation(q);
+ else
+ eventDispatcher = new QEventDispatcherUNIX(q);
+# elif !defined(QT_NO_GLIB)
if (qEnvironmentVariableIsEmpty("QT_NO_GLIB") && QEventDispatcherGlib::versionSupported())
eventDispatcher = new QEventDispatcherGlib(q);
else
-# endif
eventDispatcher = new QEventDispatcherUNIX(q);
+# else
+ eventDispatcher = new QEventDispatcherUNIX(q);
+# endif
#elif defined(Q_OS_WINRT)
eventDispatcher = new QEventDispatcherWinRT(q);
#elif defined(Q_OS_WIN)
@@ -613,8 +626,9 @@ void QCoreApplicationPrivate::initLocale()
The command line arguments which are passed to QCoreApplication's
constructor should be accessed using the arguments() function.
- Note that some arguments supplied by the user may have been
- processed and removed by QCoreApplication.
+
+ \note QCoreApplication removes option \c -qmljsdebugger="...". It parses the
+ argument of \c qmljsdebugger, and then removes this option plus its argument.
For more advanced command line option handling, create a QCommandLineParser.
diff --git a/src/corelib/kernel/qeventdispatcher_cf.mm b/src/corelib/kernel/qeventdispatcher_cf.mm
index 240dfed79f..8422345968 100644
--- a/src/corelib/kernel/qeventdispatcher_cf.mm
+++ b/src/corelib/kernel/qeventdispatcher_cf.mm
@@ -49,6 +49,8 @@
# include <UIKit/UIApplication.h>
#endif
+QT_USE_NAMESPACE
+
@interface RunLoopModeTracker : NSObject {
QStack<CFStringRef> m_runLoopModes;
}
@@ -119,7 +121,6 @@ static CFStringRef runLoopMode(NSDictionary *dictionary)
@end
QT_BEGIN_NAMESPACE
-QT_USE_NAMESPACE
class RunLoopDebugger : public QObject
{
diff --git a/src/corelib/mimetypes/qmimeprovider.cpp b/src/corelib/mimetypes/qmimeprovider.cpp
index ebaa1b069c..e0fe144c26 100644
--- a/src/corelib/mimetypes/qmimeprovider.cpp
+++ b/src/corelib/mimetypes/qmimeprovider.cpp
@@ -578,11 +578,8 @@ void QMimeBinaryProvider::loadMimeTypePrivate(QMimeTypePrivate &data)
QString mainPattern;
const QString preferredLanguage = QLocale::system().name();
- QListIterator<QString> mimeFilesIter(mimeFiles);
- mimeFilesIter.toBack();
- while (mimeFilesIter.hasPrevious()) { // global first, then local.
- const QString fullPath = mimeFilesIter.previous();
- QFile qfile(fullPath);
+ for (QStringList::const_reverse_iterator it = mimeFiles.crbegin(), end = mimeFiles.crend(); it != end; ++it) { // global first, then local.
+ QFile qfile(*it);
if (!qfile.open(QFile::ReadOnly))
continue;
diff --git a/src/corelib/plugin/qfactoryloader.cpp b/src/corelib/plugin/qfactoryloader.cpp
index f7545b5bcb..9924bef8f5 100644
--- a/src/corelib/plugin/qfactoryloader.cpp
+++ b/src/corelib/plugin/qfactoryloader.cpp
@@ -54,7 +54,9 @@ namespace {
// avoid duplicate QStringLiteral data:
inline QString iidKeyLiteral() { return QStringLiteral("IID"); }
+#ifdef QT_SHARED
inline QString versionKeyLiteral() { return QStringLiteral("version"); }
+#endif
inline QString metaDataKeyLiteral() { return QStringLiteral("MetaData"); }
inline QString keysKeyLiteral() { return QStringLiteral("Keys"); }
diff --git a/src/corelib/thread/qthread_unix.cpp b/src/corelib/thread/qthread_unix.cpp
index cc0476461f..9329c515af 100644
--- a/src/corelib/thread/qthread_unix.cpp
+++ b/src/corelib/thread/qthread_unix.cpp
@@ -36,9 +36,14 @@
#include "qplatformdefs.h"
#include <private/qcoreapplication_p.h>
+#include <private/qcore_unix_p.h>
-#if !defined(QT_NO_GLIB)
-# include "../kernel/qeventdispatcher_glib_p.h"
+#if defined(Q_OS_OSX)
+# include <private/qeventdispatcher_cf_p.h>
+#else
+# if !defined(QT_NO_GLIB)
+# include "../kernel/qeventdispatcher_glib_p.h"
+# endif
#endif
#include <private/qeventdispatcher_unix_p.h>
@@ -243,14 +248,23 @@ typedef void*(*QtThreadCallback)(void*);
void QThreadPrivate::createEventDispatcher(QThreadData *data)
{
-#if !defined(QT_NO_GLIB)
+#if defined(Q_OS_OSX)
+ bool ok = false;
+ int value = qEnvironmentVariableIntValue("QT_EVENT_DISPATCHER_CORE_FOUNDATION", &ok);
+ if (ok && value > 0)
+ data->eventDispatcher.storeRelease(new QEventDispatcherCoreFoundation);
+ else
+ data->eventDispatcher.storeRelease(new QEventDispatcherUNIX);
+#elif !defined(QT_NO_GLIB)
if (qEnvironmentVariableIsEmpty("QT_NO_GLIB")
&& qEnvironmentVariableIsEmpty("QT_NO_THREADED_GLIB")
&& QEventDispatcherGlib::versionSupported())
data->eventDispatcher.storeRelease(new QEventDispatcherGlib);
else
-#endif
+ data->eventDispatcher.storeRelease(new QEventDispatcherUNIX);
+#else
data->eventDispatcher.storeRelease(new QEventDispatcherUNIX);
+#endif
data->eventDispatcher.load()->startingUp();
}
diff --git a/src/corelib/tools/qlocale_win.cpp b/src/corelib/tools/qlocale_win.cpp
index 574453f4ca..a5eb7ec058 100644
--- a/src/corelib/tools/qlocale_win.cpp
+++ b/src/corelib/tools/qlocale_win.cpp
@@ -48,6 +48,8 @@
#endif
#ifdef Q_OS_WINRT
+#include <qfunctions_winrt.h>
+
#include <wrl.h>
#include <windows.foundation.h>
#include <windows.foundation.collections.h>
@@ -644,21 +646,53 @@ QVariant QSystemLocalePrivate::uiLanguages()
}
ComPtr<ABI::Windows::Foundation::Collections::IVectorView<HSTRING> > languageList;
- appLanguagesStatics->get_ManifestLanguages(&languageList);
-
- if (!languageList)
- return QStringList();
-
+ // Languages is a ranked list of "long names" (e.g. en-US) of preferred languages, which matches
+ // languages from the manifest with languages from the user's system.
+ HRESULT hr = appLanguagesStatics->get_Languages(&languageList);
+ Q_ASSERT_SUCCEEDED(hr);
unsigned int size;
- languageList->get_Size(&size);
+ hr = languageList->get_Size(&size);
+ Q_ASSERT_SUCCEEDED(hr);
+ result.reserve(size);
for (unsigned int i = 0; i < size; ++i) {
HString language;
- languageList->GetAt(i, language.GetAddressOf());
+ hr = languageList->GetAt(i, language.GetAddressOf());
+ Q_ASSERT_SUCCEEDED(hr);
UINT32 length;
PCWSTR rawString = language.GetRawBuffer(&length);
result << QString::fromWCharArray(rawString, length);
}
+ // ManifestLanguages covers all languages given in the manifest and uses short names (like "en").
+ hr = appLanguagesStatics->get_ManifestLanguages(&languageList);
+ Q_ASSERT_SUCCEEDED(hr);
+ hr = languageList->get_Size(&size);
+ Q_ASSERT_SUCCEEDED(hr);
+ for (unsigned int i = 0; i < size; ++i) {
+ HString language;
+ hr = languageList->GetAt(i, language.GetAddressOf());
+ Q_ASSERT_SUCCEEDED(hr);
+ UINT32 length;
+ PCWSTR rawString = language.GetRawBuffer(&length);
+ const QString qLanguage = QString::fromWCharArray(rawString, length);
+ bool found = false;
+ // Since ApplicationLanguages:::Languages uses long names, we compare the "pre-dash" part of
+ // the language and filter it out, if it is already covered by a more specialized form.
+ foreach (const QString &lang, result) {
+ int dashIndex = lang.indexOf('-');
+ // There will not be any long name after the first short name was found, so we can stop.
+ if (dashIndex == -1)
+ break;
+
+ if (lang.leftRef(dashIndex) == qLanguage) {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ result << qLanguage;
+ }
+
return result;
#endif // Q_OS_WINRT
}
diff --git a/src/corelib/xml/qxmlstream.cpp b/src/corelib/xml/qxmlstream.cpp
index 69e2e5d5c1..64a130e45a 100644
--- a/src/corelib/xml/qxmlstream.cpp
+++ b/src/corelib/xml/qxmlstream.cpp
@@ -2622,6 +2622,13 @@ QXmlStreamEntityDeclaration::~QXmlStreamEntityDeclaration()
{
}
+/*! \fn QXmlStreamStringRef::swap(QXmlStreamStringRef &other)
+ \since 5.6
+
+ Swaps this string reference's contents with \a other.
+ This function is very fast and never fails.
+*/
+
/*! \fn QStringRef QXmlStreamEntityDeclaration::name() const
Returns the entity name.
diff --git a/src/corelib/xml/qxmlstream.h b/src/corelib/xml/qxmlstream.h
index 7b1ea624c5..34f26cb953 100644
--- a/src/corelib/xml/qxmlstream.h
+++ b/src/corelib/xml/qxmlstream.h
@@ -53,13 +53,37 @@ public:
inline QXmlStreamStringRef(const QStringRef &aString)
:m_string(aString.string()?*aString.string():QString()), m_position(aString.position()), m_size(aString.size()){}
inline QXmlStreamStringRef(const QString &aString):m_string(aString), m_position(0), m_size(aString.size()){}
- inline ~QXmlStreamStringRef(){}
+
+#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
+ QXmlStreamStringRef(const QXmlStreamStringRef &other) // = default
+ : m_string(other.m_string), m_position(other.m_position), m_size(other.m_size) {}
+#ifdef Q_COMPILER_RVALUE_REFS
+ QXmlStreamStringRef(QXmlStreamStringRef &&other) Q_DECL_NOTHROW // = default
+ : m_string(std::move(other.m_string)), m_position(other.m_position), m_size(other.m_size) {}
+ QXmlStreamStringRef &operator=(QXmlStreamStringRef &&other) Q_DECL_NOTHROW // = default
+ { swap(other); return *this; }
+#endif
+ QXmlStreamStringRef &operator=(const QXmlStreamStringRef &other) // = default
+ { m_string = other.m_string; m_position = other.m_position; m_size = other.m_size; return *this; }
+ inline ~QXmlStreamStringRef() {} // ### this prevents (or deprecates) all the move/copy special member functions,
+ // ### that's why we need to provide them by hand above. We can't remove it in
+ // ### Qt 5, since that would change the way its passed to functions. In Qt 6, remove all.
+#endif // Qt < 6.0
+
+ void swap(QXmlStreamStringRef &other) Q_DECL_NOTHROW
+ {
+ qSwap(m_string, other.m_string);
+ qSwap(m_position, other.m_position);
+ qSwap(m_size, other.m_size);
+ }
+
inline void clear() { m_string.clear(); m_position = m_size = 0; }
inline operator QStringRef() const { return QStringRef(&m_string, m_position, m_size); }
inline const QString *string() const { return &m_string; }
inline int position() const { return m_position; }
inline int size() const { return m_size; }
};
+Q_DECLARE_SHARED_NOT_MOVABLE_UNTIL_QT6(QXmlStreamStringRef)
class QXmlStreamReaderPrivate;
diff --git a/src/gui/image/qppmhandler.cpp b/src/gui/image/qppmhandler.cpp
index f460431c2b..7f23656c02 100644
--- a/src/gui/image/qppmhandler.cpp
+++ b/src/gui/image/qppmhandler.cpp
@@ -46,13 +46,21 @@ QT_BEGIN_NAMESPACE
PBM/PGM/PPM (ASCII and RAW) image read/write functions
*****************************************************************************/
+static void discard_pbm_line(QIODevice *d)
+{
+ const int buflen = 100;
+ char buf[buflen];
+ int res = 0;
+ do {
+ res = d->readLine(buf, buflen);
+ } while (res > 0 && buf[res-1] != '\n');
+}
+
static int read_pbm_int(QIODevice *d)
{
char c;
int val = -1;
bool digit;
- const int buflen = 100;
- char buf[buflen];
for (;;) {
if (!d->getChar(&c)) // end of file
break;
@@ -63,7 +71,7 @@ static int read_pbm_int(QIODevice *d)
continue;
} else {
if (c == '#') // comment
- d->readLine(buf, buflen);
+ discard_pbm_line(d);
break;
}
}
@@ -72,7 +80,7 @@ static int read_pbm_int(QIODevice *d)
else if (isspace((uchar) c))
continue;
else if (c == '#')
- (void)d->readLine(buf, buflen);
+ discard_pbm_line(d);
else
break;
}
diff --git a/src/gui/kernel/qguiapplication.cpp b/src/gui/kernel/qguiapplication.cpp
index 66f1b1dfce..0b1c49dd60 100644
--- a/src/gui/kernel/qguiapplication.cpp
+++ b/src/gui/kernel/qguiapplication.cpp
@@ -1853,16 +1853,23 @@ void QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::Mo
if (!window)
return;
- QMouseEvent ev(type, localPoint, localPoint, globalPoint, button, buttons, e->modifiers, e->source);
- ev.setTimestamp(e->timestamp);
#ifndef QT_NO_CURSOR
if (!e->synthetic()) {
if (const QScreen *screen = window->screen())
- if (QPlatformCursor *cursor = screen->handle()->cursor())
+ if (QPlatformCursor *cursor = screen->handle()->cursor()) {
+ const QPointF nativeLocalPoint = QHighDpi::toNativePixels(localPoint, screen);
+ const QPointF nativeGlobalPoint = QHighDpi::toNativePixels(globalPoint, screen);
+ QMouseEvent ev(type, nativeLocalPoint, nativeLocalPoint, nativeGlobalPoint,
+ button, buttons, e->modifiers, e->source);
+ ev.setTimestamp(e->timestamp);
cursor->pointerEvent(ev);
+ }
}
#endif
+ QMouseEvent ev(type, localPoint, localPoint, globalPoint, button, buttons, e->modifiers, e->source);
+ ev.setTimestamp(e->timestamp);
+
if (window->d_func()->blockedByModalWindow) {
// a modal window is blocking this window, don't allow mouse events through
return;
diff --git a/src/gui/kernel/qplatformscreen.cpp b/src/gui/kernel/qplatformscreen.cpp
index d1d8eba697..8666d0a04c 100644
--- a/src/gui/kernel/qplatformscreen.cpp
+++ b/src/gui/kernel/qplatformscreen.cpp
@@ -90,7 +90,7 @@ QWindow *QPlatformScreen::topLevelAt(const QPoint & pos) const
QWindowList list = QGuiApplication::topLevelWindows();
for (int i = list.size()-1; i >= 0; --i) {
QWindow *w = list[i];
- if (w->isVisible() && w->geometry().contains(pos))
+ if (w->isVisible() && QHighDpi::toNativePixels(w->geometry(), w).contains(pos))
return w;
}
diff --git a/src/gui/painting/qplatformbackingstore.cpp b/src/gui/painting/qplatformbackingstore.cpp
index dd02e24676..5f873bfe7e 100644
--- a/src/gui/painting/qplatformbackingstore.cpp
+++ b/src/gui/painting/qplatformbackingstore.cpp
@@ -224,16 +224,16 @@ static inline QRect deviceRect(const QRect &rect, QWindow *window)
return deviceRect;
}
-static QRegion deviceRegion(const QRegion &region, QWindow *window)
+static QRegion deviceRegion(const QRegion &region, QWindow *window, const QPoint &offset)
{
- if (!(window->devicePixelRatio() > 1))
+ if (offset.isNull() && window->devicePixelRatio() <= 1)
return region;
QVector<QRect> rects;
const QVector<QRect> regionRects = region.rects();
rects.reserve(regionRects.count());
foreach (const QRect &rect, regionRects)
- rects.append(deviceRect(rect, window));
+ rects.append(deviceRect(rect.translated(offset), window));
QRegion deviceRegion;
deviceRegion.setRects(rects.constData(), rects.count());
@@ -246,10 +246,12 @@ static inline QRect toBottomLeftRect(const QRect &topLeftRect, int windowHeight)
topLeftRect.width(), topLeftRect.height());
}
-static void blit(const QPlatformTextureList *textures, int idx, QWindow *window, const QRect &deviceWindowRect,
- QOpenGLTextureBlitter *blitter)
+static void blitTextureForWidget(const QPlatformTextureList *textures, int idx, QWindow *window, const QRect &deviceWindowRect,
+ QOpenGLTextureBlitter *blitter, const QPoint &offset)
{
- const QRect rectInWindow = textures->geometry(idx);
+ QRect rectInWindow = textures->geometry(idx);
+ // relative to the TLW, not necessarily our window (if the flush is for a native child widget), have to adjust
+ rectInWindow.translate(-offset);
QRect clipRect = textures->clipRect(idx);
if (clipRect.isEmpty())
clipRect = QRect(QPoint(0, 0), rectInWindow.size());
@@ -274,7 +276,9 @@ static void blit(const QPlatformTextureList *textures, int idx, QWindow *window,
and composes using OpenGL. May be reimplemented in subclasses if there
is a more efficient native way to do it.
- Note that the \a offset parameter is currently unused.
+ \note \a region is relative to the window which may not be top-level in case
+ \a window corresponds to a native child widget. \a offset is the position of
+ the native child relative to the top-level window.
*/
void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &region,
@@ -282,7 +286,8 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &regi
QPlatformTextureList *textures, QOpenGLContext *context,
bool translucentBackground)
{
- Q_UNUSED(offset);
+ if (!qt_window_private(window)->receivedExpose)
+ return;
if (!context->makeCurrent(window)) {
qWarning("composeAndFlush: makeCurrent() failed");
@@ -306,7 +311,7 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &regi
// Textures for renderToTexture widgets.
for (int i = 0; i < textures->count(); ++i) {
if (!textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop))
- blit(textures, i, window, deviceWindowRect, d_ptr->blitter);
+ blitTextureForWidget(textures, i, window, deviceWindowRect, d_ptr->blitter, offset);
}
funcs->glEnable(GL_BLEND);
@@ -348,17 +353,26 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &regi
textureId = d_ptr->textureId;
} else {
TextureFlags flags = 0;
- textureId = toTexture(deviceRegion(region, window), &d_ptr->textureSize, &flags);
+ textureId = toTexture(deviceRegion(region, window, offset), &d_ptr->textureSize, &flags);
d_ptr->needsSwizzle = (flags & TextureSwizzle) != 0;
if (flags & TextureFlip)
origin = QOpenGLTextureBlitter::OriginBottomLeft;
}
if (textureId) {
- QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(QRect(QPoint(), d_ptr->textureSize), deviceWindowRect);
if (d_ptr->needsSwizzle)
d_ptr->blitter->setSwizzleRB(true);
- d_ptr->blitter->blit(textureId, target, origin);
+ // offset is usually (0, 0) unless we have native child widgets.
+ if (offset.isNull()) {
+ d_ptr->blitter->blit(textureId, QMatrix4x4(), origin);
+ } else {
+ // The backingstore is for the entire tlw. offset tells the position of the native child in the tlw.
+ const QRect srcRect = toBottomLeftRect(deviceWindowRect.translated(offset), d_ptr->textureSize.height());
+ const QMatrix3x3 source = QOpenGLTextureBlitter::sourceTransform(deviceRect(srcRect, window),
+ d_ptr->textureSize,
+ origin);
+ d_ptr->blitter->blit(textureId, QMatrix4x4(), source);
+ }
if (d_ptr->needsSwizzle)
d_ptr->blitter->setSwizzleRB(false);
}
@@ -366,7 +380,7 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion &regi
// Textures for renderToTexture widgets that have WA_AlwaysStackOnTop set.
for (int i = 0; i < textures->count(); ++i) {
if (textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop))
- blit(textures, i, window, deviceWindowRect, d_ptr->blitter);
+ blitTextureForWidget(textures, i, window, deviceWindowRect, d_ptr->blitter, offset);
}
funcs->glDisable(GL_BLEND);
@@ -413,6 +427,8 @@ QImage QPlatformBackingStore::toImage() const
If the image has to be flipped (e.g. because the texture is attached to an FBO), \a
flags will be set to include \c TextureFlip.
+
+ \note \a dirtyRegion is relative to the backingstore so no adjustment is needed.
*/
GLuint QPlatformBackingStore::toTexture(const QRegion &dirtyRegion, QSize *textureSize, TextureFlags *flags) const
{
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp
index d68a59fae3..9f046af47c 100644
--- a/src/gui/text/qtextlayout.cpp
+++ b/src/gui/text/qtextlayout.cpp
@@ -2617,7 +2617,7 @@ void QTextLine::draw(QPainter *p, const QPointF &pos, const QTextLayout::FormatR
inside the line, taking account of the \a edge.
If \a cursorPos is not a valid cursor position, the nearest valid
- cursor position will be used instead, and cpos will be modified to
+ cursor position will be used instead, and \a cursorPos will be modified to
point to this valid cursor position.
\sa xToCursor()
diff --git a/src/network/access/qhttpnetworkconnectionchannel.cpp b/src/network/access/qhttpnetworkconnectionchannel.cpp
index b4eda3477e..f591abc28b 100644
--- a/src/network/access/qhttpnetworkconnectionchannel.cpp
+++ b/src/network/access/qhttpnetworkconnectionchannel.cpp
@@ -254,6 +254,10 @@ void QHttpNetworkConnectionChannel::handleUnexpectedEOF()
close();
reply->d_func()->errorString = connection->d_func()->errorDetail(QNetworkReply::RemoteHostClosedError, socket);
emit reply->finishedWithError(QNetworkReply::RemoteHostClosedError, reply->d_func()->errorString);
+ reply = 0;
+ if (protocolHandler)
+ protocolHandler->setReply(0);
+ request = QHttpNetworkRequest();
QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection);
} else {
reconnectAttempts--;
diff --git a/src/network/kernel/qhostinfo_winrt.cpp b/src/network/kernel/qhostinfo_winrt.cpp
index 3d2344726b..1840bebd39 100644
--- a/src/network/kernel/qhostinfo_winrt.cpp
+++ b/src/network/kernel/qhostinfo_winrt.cpp
@@ -33,6 +33,7 @@
#include "qhostinfo_p.h"
+#include <qfunctions_winrt.h>
#include <qurl.h>
#include <wrl.h>
@@ -49,6 +50,8 @@ using namespace ABI::Windows::Networking::Sockets;
QT_BEGIN_NAMESPACE
+#define E_NO_SUCH_HOST 0x80072af9
+
//#define QHOSTINFO_DEBUG
QHostInfo QHostInfoAgent::fromName(const QString &hostName)
@@ -74,19 +77,22 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName)
ComPtr<IHostNameFactory> hostnameFactory;
HRESULT hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_HostName).Get(),
IID_PPV_ARGS(&hostnameFactory));
- Q_ASSERT_X(SUCCEEDED(hr), Q_FUNC_INFO, qPrintable(qt_error_string(hr)));
+ Q_ASSERT_SUCCEEDED(hr);
ComPtr<IHostName> host;
HStringReference hostNameRef((const wchar_t*)hostName.utf16());
- hostnameFactory->CreateHostName(hostNameRef.Get(), &host);
+ hr = hostnameFactory->CreateHostName(hostNameRef.Get(), &host);
+ Q_ASSERT_SUCCEEDED(hr);
ComPtr<IDatagramSocketStatics> datagramSocketStatics;
- GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_DatagramSocket).Get(), &datagramSocketStatics);
+ hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_DatagramSocket).Get(), &datagramSocketStatics);
+ Q_ASSERT_SUCCEEDED(hr);
ComPtr<IAsyncOperation<IVectorView<EndpointPair *> *>> op;
- datagramSocketStatics->GetEndpointPairsAsync(host.Get(),
+ hr = datagramSocketStatics->GetEndpointPairsAsync(host.Get(),
HString::MakeReference(L"0").Get(),
&op);
+ Q_ASSERT_SUCCEEDED(hr);
ComPtr<IVectorView<EndpointPair *>> endpointPairs;
hr = op->GetResults(&endpointPairs);
@@ -98,26 +104,35 @@ QHostInfo QHostInfoAgent::fromName(const QString &hostName)
return results;
}
- if (!endpointPairs)
+ if (hr == E_NO_SUCH_HOST || !endpointPairs) {
+ results.setError(QHostInfo::HostNotFound);
+ results.setErrorString(tr("Host %1 could not be found.").arg(hostName));
return results;
+ }
+ Q_ASSERT_SUCCEEDED(hr);
unsigned int size;
- endpointPairs->get_Size(&size);
+ hr = endpointPairs->get_Size(&size);
+ Q_ASSERT_SUCCEEDED(hr);
QList<QHostAddress> addresses;
for (unsigned int i = 0; i < size; ++i) {
ComPtr<IEndpointPair> endpointpair;
- endpointPairs->GetAt(i, &endpointpair);
+ hr = endpointPairs->GetAt(i, &endpointpair);
+ Q_ASSERT_SUCCEEDED(hr);
ComPtr<IHostName> remoteHost;
- endpointpair->get_RemoteHostName(&remoteHost);
+ hr = endpointpair->get_RemoteHostName(&remoteHost);
+ Q_ASSERT_SUCCEEDED(hr);
if (!remoteHost)
continue;
HostNameType type;
- remoteHost->get_Type(&type);
+ hr = remoteHost->get_Type(&type);
+ Q_ASSERT_SUCCEEDED(hr);
if (type == HostNameType_DomainName)
continue;
HString name;
- remoteHost->get_CanonicalName(name.GetAddressOf());
+ hr = remoteHost->get_CanonicalName(name.GetAddressOf());
+ Q_ASSERT_SUCCEEDED(hr);
UINT32 length;
PCWSTR rawString = name.GetRawBuffer(&length);
QHostAddress addr;
diff --git a/src/network/kernel/qnetworkinterface_winrt.cpp b/src/network/kernel/qnetworkinterface_winrt.cpp
index 18bfcaabda..1e22ab15da 100644
--- a/src/network/kernel/qnetworkinterface_winrt.cpp
+++ b/src/network/kernel/qnetworkinterface_winrt.cpp
@@ -89,6 +89,9 @@ static QNetworkInterfacePrivate *interfaceFromProfile(IConnectionProfile *profil
ComPtr<INetworkAdapter> adapter;
hr = profile->get_NetworkAdapter(&adapter);
+ // Indicates that no internet connection is available/the device is in airplane mode
+ if (hr == E_INVALIDARG)
+ return 0;
Q_ASSERT_SUCCEEDED(hr);
UINT32 type;
hr = adapter->get_IanaInterfaceType(&type);
diff --git a/src/platformsupport/eglconvenience/eglconvenience.pri b/src/platformsupport/eglconvenience/eglconvenience.pri
index 1cab1e556f..f1e0d58a6d 100644
--- a/src/platformsupport/eglconvenience/eglconvenience.pri
+++ b/src/platformsupport/eglconvenience/eglconvenience.pri
@@ -23,6 +23,7 @@ contains(QT_CONFIG,egl) {
$$PWD/qxlibeglintegration_p.h
SOURCES += \
$$PWD/qxlibeglintegration.cpp
+ LIBS_PRIVATE += $$QMAKE_LIBS_X11
}
CONFIG += egl
}
diff --git a/src/platformsupport/eglconvenience/qeglstreamconvenience_p.h b/src/platformsupport/eglconvenience/qeglstreamconvenience_p.h
index 12787d03ae..648b129579 100644
--- a/src/platformsupport/eglconvenience/qeglstreamconvenience_p.h
+++ b/src/platformsupport/eglconvenience/qeglstreamconvenience_p.h
@@ -84,6 +84,15 @@ typedef const char *(EGLAPIENTRYP PFNEGLQUERYOUTPUTPORTSTRINGEXTPROC) (EGLDispla
typedef void *EGLStreamKHR;
typedef quint64 EGLuint64KHR;
#define EGL_NO_STREAM_KHR ((EGLStreamKHR)0)
+#define EGL_STREAM_STATE_KHR 0x3214
+#define EGL_STREAM_STATE_CREATED_KHR 0x3215
+#define EGL_STREAM_STATE_CONNECTING_KHR 0x3216
+#define EGL_STREAM_STATE_EMPTY_KHR 0x3217
+#define EGL_STREAM_STATE_NEW_FRAME_AVAILABLE_KHR 0x3218
+#define EGL_STREAM_STATE_OLD_FRAME_AVAILABLE_KHR 0x3219
+#define EGL_STREAM_STATE_DISCONNECTED_KHR 0x321A
+#define EGL_BAD_STREAM_KHR 0x321B
+#define EGL_BAD_STATE_KHR 0x321C
typedef EGLStreamKHR (EGLAPIENTRYP PFNEGLCREATESTREAMKHRPROC) (EGLDisplay dpy, const EGLint *attrib_list);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLDESTROYSTREAMKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream);
typedef EGLBoolean (EGLAPIENTRYP PFNEGLSTREAMATTRIBKHRPROC) (EGLDisplay dpy, EGLStreamKHR stream, EGLenum attribute, EGLint value);
diff --git a/src/platformsupport/input/evdevmouse/qevdevmousehandler.cpp b/src/platformsupport/input/evdevmouse/qevdevmousehandler.cpp
index c4ebc5c51d..76d8aab8f2 100644
--- a/src/platformsupport/input/evdevmouse/qevdevmousehandler.cpp
+++ b/src/platformsupport/input/evdevmouse/qevdevmousehandler.cpp
@@ -43,6 +43,7 @@
#include <qplatformdefs.h>
#include <private/qcore_unix_p.h> // overrides QT_OPEN
+#include <private/qhighdpiscaling_p.h>
#include <errno.h>
@@ -141,7 +142,8 @@ bool QEvdevMouseHandler::getHardwareMaximum()
m_hardwareHeight = absInfo.maximum - absInfo.minimum;
- QRect g = QGuiApplication::primaryScreen()->virtualGeometry();
+ QScreen *primaryScreen = QGuiApplication::primaryScreen();
+ QRect g = QHighDpi::toNativePixels(primaryScreen->virtualGeometry(), primaryScreen);
m_hardwareScalerX = static_cast<qreal>(m_hardwareWidth) / (g.right() - g.left());
m_hardwareScalerY = static_cast<qreal>(m_hardwareHeight) / (g.bottom() - g.top());
diff --git a/src/platformsupport/input/evdevmouse/qevdevmousemanager.cpp b/src/platformsupport/input/evdevmouse/qevdevmousemanager.cpp
index 805397f021..68db0b26ba 100644
--- a/src/platformsupport/input/evdevmouse/qevdevmousemanager.cpp
+++ b/src/platformsupport/input/evdevmouse/qevdevmousemanager.cpp
@@ -41,6 +41,7 @@
#include <QtPlatformSupport/private/qdevicediscovery_p.h>
#include <private/qguiapplication_p.h>
#include <private/qinputdevicemanager_p_p.h>
+#include <private/qhighdpiscaling_p.h>
QT_BEGIN_NAMESPACE
@@ -106,7 +107,8 @@ QEvdevMouseManager::~QEvdevMouseManager()
void QEvdevMouseManager::clampPosition()
{
// clamp to screen geometry
- QRect g = QGuiApplication::primaryScreen()->virtualGeometry();
+ QScreen *primaryScreen = QGuiApplication::primaryScreen();
+ QRect g = QHighDpi::toNativePixels(primaryScreen->virtualGeometry(), primaryScreen);
if (m_x + m_xoffset < g.left())
m_x = g.left() - m_xoffset;
else if (m_x + m_xoffset > g.right())
diff --git a/src/platformsupport/input/libinput/qlibinputpointer.cpp b/src/platformsupport/input/libinput/qlibinputpointer.cpp
index 48e5a6cf1c..55339a841a 100644
--- a/src/platformsupport/input/libinput/qlibinputpointer.cpp
+++ b/src/platformsupport/input/libinput/qlibinputpointer.cpp
@@ -36,6 +36,7 @@
#include <QtGui/QGuiApplication>
#include <QtGui/QScreen>
#include <qpa/qwindowsysteminterface.h>
+#include <private/qhighdpiscaling_p.h>
QT_BEGIN_NAMESPACE
@@ -81,7 +82,8 @@ void QLibInputPointer::processMotion(libinput_event_pointer *e)
{
const double dx = libinput_event_pointer_get_dx(e);
const double dy = libinput_event_pointer_get_dy(e);
- const QRect g = QGuiApplication::primaryScreen()->virtualGeometry();
+ QScreen * const primaryScreen = QGuiApplication::primaryScreen();
+ const QRect g = QHighDpi::toNativePixels(primaryScreen->virtualGeometry(), primaryScreen);
m_pos.setX(qBound(g.left(), qRound(m_pos.x() + dx), g.right()));
m_pos.setY(qBound(g.top(), qRound(m_pos.y() + dy), g.bottom()));
@@ -110,7 +112,9 @@ void QLibInputPointer::processAxis(libinput_event_pointer *e)
void QLibInputPointer::setPos(const QPoint &pos)
{
- const QRect g = QGuiApplication::primaryScreen()->virtualGeometry();
+ QScreen * const primaryScreen = QGuiApplication::primaryScreen();
+ const QRect g = QHighDpi::toNativePixels(primaryScreen->virtualGeometry(), primaryScreen);
+
m_pos.setX(qBound(g.left(), pos.x(), g.right()));
m_pos.setY(qBound(g.top(), pos.y(), g.bottom()));
}
diff --git a/src/plugins/bearer/generic/qgenericengine.cpp b/src/plugins/bearer/generic/qgenericengine.cpp
index 7f56846179..1e424dc223 100644
--- a/src/plugins/bearer/generic/qgenericengine.cpp
+++ b/src/plugins/bearer/generic/qgenericengine.cpp
@@ -201,6 +201,9 @@ static QNetworkConfiguration::BearerType qGetInterfaceType(const QString &interf
ComPtr<INetworkAdapter> adapter;
hr = profile->get_NetworkAdapter(&adapter);
+ // Indicates that no internet connection is available/the device is in airplane mode
+ if (hr == E_INVALIDARG)
+ return QNetworkConfiguration::BearerUnknown;
Q_ASSERT_SUCCEEDED(hr);
GUID id;
hr = adapter->get_NetworkAdapterId(&id);
diff --git a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp
index b86dfa3546..3bd6e76c52 100644
--- a/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp
+++ b/src/plugins/platforms/direct2d/qwindowsdirect2dintegration.cpp
@@ -39,12 +39,12 @@
#include "qwindowsdirect2dwindow.h"
#include "qwindowscontext.h"
-#include "qwindowsguieventdispatcher.h"
#include <qplatformdefs.h>
#include <QtCore/QCoreApplication>
#include <QtGui/private/qpixmap_raster_p.h>
#include <QtGui/qpa/qwindowsysteminterface.h>
+#include <QtPlatformSupport/private/qwindowsguieventdispatcher_p.h>
QT_BEGIN_NAMESPACE
diff --git a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp
index 10c8091815..064b9f6306 100644
--- a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp
+++ b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.cpp
@@ -219,6 +219,11 @@ QDpi QEGLDeviceIntegration::logicalDpi() const
25.4 * s.height() / ps.height());
}
+qreal QEGLDeviceIntegration::pixelDensity() const
+{
+ return logicalDpi().first / qreal(100);
+}
+
Qt::ScreenOrientation QEGLDeviceIntegration::nativeOrientation() const
{
return Qt::PrimaryOrientation;
diff --git a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h
index 97082df7f5..5ec98b37d1 100644
--- a/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h
+++ b/src/plugins/platforms/eglfs/qeglfsdeviceintegration.h
@@ -75,6 +75,7 @@ public:
virtual QSizeF physicalScreenSize() const;
virtual QSize screenSize() const;
virtual QDpi logicalDpi() const;
+ virtual qreal pixelDensity() const;
virtual Qt::ScreenOrientation nativeOrientation() const;
virtual Qt::ScreenOrientation orientation() const;
virtual int screenDepth() const;
diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.cpp b/src/plugins/platforms/eglfs/qeglfsscreen.cpp
index 6f8d0b88dd..a14e68b667 100644
--- a/src/plugins/platforms/eglfs/qeglfsscreen.cpp
+++ b/src/plugins/platforms/eglfs/qeglfsscreen.cpp
@@ -82,6 +82,11 @@ QDpi QEglFSScreen::logicalDpi() const
return qt_egl_device_integration()->logicalDpi();
}
+qreal QEglFSScreen::pixelDensity() const
+{
+ return qt_egl_device_integration()->pixelDensity();
+}
+
Qt::ScreenOrientation QEglFSScreen::nativeOrientation() const
{
return qt_egl_device_integration()->nativeOrientation();
diff --git a/src/plugins/platforms/eglfs/qeglfsscreen.h b/src/plugins/platforms/eglfs/qeglfsscreen.h
index 44e9da4a5a..8f1d87ea25 100644
--- a/src/plugins/platforms/eglfs/qeglfsscreen.h
+++ b/src/plugins/platforms/eglfs/qeglfsscreen.h
@@ -55,6 +55,7 @@ public:
QSizeF physicalSize() const Q_DECL_OVERRIDE;
QDpi logicalDpi() const Q_DECL_OVERRIDE;
+ qreal pixelDensity() const Q_DECL_OVERRIDE;
Qt::ScreenOrientation nativeOrientation() const Q_DECL_OVERRIDE;
Qt::ScreenOrientation orientation() const Q_DECL_OVERRIDE;
diff --git a/src/plugins/platforms/ios/qiosscreen.h b/src/plugins/platforms/ios/qiosscreen.h
index a0aa922a31..f31be9756c 100644
--- a/src/plugins/platforms/ios/qiosscreen.h
+++ b/src/plugins/platforms/ios/qiosscreen.h
@@ -73,7 +73,7 @@ private:
QRect m_geometry;
QRect m_availableGeometry;
int m_depth;
- uint m_unscaledDpi;
+ uint m_pixelDensity;
QSizeF m_physicalSize;
QIOSOrientationListener *m_orientationListener;
};
diff --git a/src/plugins/platforms/ios/qiosscreen.mm b/src/plugins/platforms/ios/qiosscreen.mm
index 3e16efcd22..5cb06d591d 100644
--- a/src/plugins/platforms/ios/qiosscreen.mm
+++ b/src/plugins/platforms/ios/qiosscreen.mm
@@ -170,23 +170,28 @@ QIOSScreen::QIOSScreen(UIScreen *screen)
if (screen == [UIScreen mainScreen]) {
QString deviceIdentifier = deviceModelIdentifier();
- if (deviceIdentifier == QLatin1String("iPhone2,1") /* iPhone 3GS */
- || deviceIdentifier == QLatin1String("iPod3,1") /* iPod touch 3G */) {
+ // Based on https://en.wikipedia.org/wiki/List_of_iOS_devices#Display
+
+ // iPhone (1st gen), 3G, 3GS, and iPod Touch (1st–3rd gen) are 18-bit devices
+ if (deviceIdentifier.contains(QRegularExpression("^(iPhone1,[12]|iPhone2,1|iPod[1-3],1)$")))
m_depth = 18;
- } else {
+ else
m_depth = 24;
- }
- if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad
- && !deviceIdentifier.contains(QRegularExpression("^iPad2,[567]$")) /* excluding iPad Mini */) {
- m_unscaledDpi = 132;
+ if (deviceIdentifier.contains(QRegularExpression("^iPhone(7,1|8,2)$"))) {
+ // iPhone 6 Plus or iPhone 6S Plus
+ m_pixelDensity = 401;
+ } else if (deviceIdentifier.contains(QRegularExpression("^iPad(1,1|2,[1-4]|3,[1-6]|4,[1-3]|5,[3-4]|6,[7-8])$"))) {
+ // All iPads except the iPad Mini series
+ m_pixelDensity = 132 * devicePixelRatio();
} else {
- m_unscaledDpi = 163; // Regular iPhone DPI
+ // All non-Plus iPhones, and iPad Minis
+ m_pixelDensity = 163 * devicePixelRatio();
}
} else {
// External display, hard to say
m_depth = 24;
- m_unscaledDpi = 96;
+ m_pixelDensity = 96;
}
for (UIWindow *existingWindow in [[UIApplication sharedApplication] windows]) {
@@ -249,7 +254,7 @@ void QIOSScreen::updateProperties()
if (m_geometry != previousGeometry) {
const qreal millimetersPerInch = 25.4;
- m_physicalSize = QSizeF(m_geometry.size()) / m_unscaledDpi * millimetersPerInch;
+ m_physicalSize = QSizeF(m_geometry.size() * devicePixelRatio()) / m_pixelDensity * millimetersPerInch;
}
// At construction time, we don't yet have an associated QScreen, but we still want
diff --git a/src/plugins/platforms/windows/openglblacklists/default.json b/src/plugins/platforms/windows/openglblacklists/default.json
index a5d42719a9..1e003e2d15 100644
--- a/src/plugins/platforms/windows/openglblacklists/default.json
+++ b/src/plugins/platforms/windows/openglblacklists/default.json
@@ -57,9 +57,9 @@
},
{
"id": 5,
- "description": "Intel GMA 3150 crashes (QTBUG-43243)",
+ "description": "Intel GMA 3150 (QTBUG-43243), Mobile Intel 945GM (QTBUG-47435) crash",
"vendor_id": "0x8086",
- "device_id": [ "0xA001", "0xA011" ],
+ "device_id": [ "0xA001", "0xA011", "0x27A0" ],
"os": {
"type": "win"
},
diff --git a/src/plugins/platforms/windows/qwindowsbackingstore.cpp b/src/plugins/platforms/windows/qwindowsbackingstore.cpp
index 3f19e4401a..bd5c35037d 100644
--- a/src/plugins/platforms/windows/qwindowsbackingstore.cpp
+++ b/src/plugins/platforms/windows/qwindowsbackingstore.cpp
@@ -84,7 +84,8 @@ void QWindowsBackingStore::flush(QWindow *window, const QRegion &region,
if ((flags & Qt::FramelessWindowHint) && QWindowsWindow::setWindowLayered(rw->handle(), flags, hasAlpha, rw->opacity()) && hasAlpha) {
// Windows with alpha: Use blend function to update.
QRect r = QHighDpi::toNativePixels(window->frameGeometry(), window);
- QPoint frameOffset(QHighDpi::toNativePixels(QPoint(window->frameMargins().left(), window->frameMargins().top()), window));
+ QPoint frameOffset(QHighDpi::toNativePixels(QPoint(window->frameMargins().left(), window->frameMargins().top()),
+ static_cast<const QWindow *>(Q_NULLPTR)));
QRect dirtyRect = br.translated(offset + frameOffset);
SIZE size = {r.width(), r.height()};
diff --git a/src/plugins/platforms/windows/qwindowscursor.cpp b/src/plugins/platforms/windows/qwindowscursor.cpp
index 1fbef61029..800b79347c 100644
--- a/src/plugins/platforms/windows/qwindowscursor.cpp
+++ b/src/plugins/platforms/windows/qwindowscursor.cpp
@@ -67,19 +67,14 @@ Q_GUI_EXPORT HBITMAP qt_createIconMask(const QBitmap &bitmap);
\ingroup qt-lighthouse-win
*/
-QWindowsCursorCacheKey::QWindowsCursorCacheKey(const QCursor &c)
- : shape(c.shape()), bitmapCacheKey(0), maskCacheKey(0)
+QWindowsPixmapCursorCacheKey::QWindowsPixmapCursorCacheKey(const QCursor &c)
+ : bitmapCacheKey(c.pixmap().cacheKey()), maskCacheKey(0)
{
- if (shape == Qt::BitmapCursor) {
- const qint64 pixmapCacheKey = c.pixmap().cacheKey();
- if (pixmapCacheKey) {
- bitmapCacheKey = pixmapCacheKey;
- } else {
- Q_ASSERT(c.bitmap());
- Q_ASSERT(c.mask());
- bitmapCacheKey = c.bitmap()->cacheKey();
- maskCacheKey = c.mask()->cacheKey();
- }
+ if (!bitmapCacheKey) {
+ Q_ASSERT(c.bitmap());
+ Q_ASSERT(c.mask());
+ bitmapCacheKey = c.bitmap()->cacheKey();
+ maskCacheKey = c.mask()->cacheKey();
}
}
@@ -206,6 +201,17 @@ static HCURSOR createBitmapCursor(const QImage &bbits, const QImage &mbits,
#endif
}
+// Create a cursor from image and mask of the format QImage::Format_Mono.
+static HCURSOR createBitmapCursor(const QCursor &cursor)
+{
+ Q_ASSERT(cursor.shape() == Qt::BitmapCursor && cursor.bitmap());
+ const QImage bbits = cursor.bitmap()->toImage().convertToFormat(QImage::Format_Mono);
+ const QImage mbits = cursor.mask()->toImage().convertToFormat(QImage::Format_Mono);
+ const bool invb = bbits.colorCount() > 1 && qGray(bbits.color(0)) < qGray(bbits.color(1));
+ const bool invm = mbits.colorCount() > 1 && qGray(mbits.color(0)) < qGray(mbits.color(1));
+ return createBitmapCursor(bbits, mbits, cursor.hotSpot(), invb, invm);
+}
+
static inline QSize systemCursorSize() { return QSize(GetSystemMetrics(SM_CXCURSOR), GetSystemMetrics(SM_CYCURSOR)); }
static inline QSize standardCursorSize() { return QSize(32, 32); }
@@ -215,7 +221,7 @@ static inline QSize standardCursorSize() { return QSize(32, 32); }
// createBitmapCursor() only work for standard sizes (32,48,64...), which does
// not work when scaling the 16x16 openhand cursor bitmaps to 150% (resulting
// in a non-standard 24x24 size).
-static QCursor createPixmapCursorFromData(const QSize &systemCursorSize,
+static QWindowsCursor::PixmapCursor createPixmapCursorFromData(const QSize &systemCursorSize,
// The cursor size the bitmap is targeted for
const QSize &bitmapTargetCursorSize,
// The actual size of the bitmap data
@@ -233,10 +239,10 @@ static QCursor createPixmapCursorFromData(const QSize &systemCursorSize,
rawImage = rawImage.transformed(transform, Qt::SmoothTransformation);
}
const QPoint hotSpot(rawImage.width() / 2, rawImage.height() / 2);
- return QCursor(rawImage, hotSpot.x(), hotSpot.y());
+ return QWindowsCursor::PixmapCursor(rawImage, hotSpot);
}
-QCursor QWindowsCursor::customCursor(Qt::CursorShape cursorShape)
+QWindowsCursor::PixmapCursor QWindowsCursor::customCursor(Qt::CursorShape cursorShape)
{
// Non-standard Windows cursors are created from bitmaps
static const uchar vsplit_bits[] = {
@@ -412,14 +418,14 @@ QCursor QWindowsCursor::customCursor(Qt::CursorShape cursorShape)
case Qt::ClosedHandCursor:
return createPixmapCursorFromData(systemCursorSize(), standardCursorSize(), 16, closedhand_bits, closedhandm_bits);
case Qt::DragCopyCursor:
- return QCursor(QPixmap(copyDragCursorXpmC), 0, 0);
+ return QWindowsCursor::PixmapCursor(QPixmap(copyDragCursorXpmC), QPoint(0, 0));
case Qt::DragMoveCursor:
- return QCursor(QPixmap(moveDragCursorXpmC), 0, 0);
+ return QWindowsCursor::PixmapCursor(QPixmap(moveDragCursorXpmC), QPoint(0, 0));
case Qt::DragLinkCursor:
- return QCursor(QPixmap(linkDragCursorXpmC), 0, 0);
+ return QWindowsCursor::PixmapCursor(QPixmap(linkDragCursorXpmC), QPoint(0, 0));
}
- return QCursor();
+ return QWindowsCursor::PixmapCursor();
}
#else // Q_OS_WINCE || QT_NO_IMAGEFORMAT_PNG
struct QWindowsCustomPngCursor {
@@ -430,7 +436,7 @@ struct QWindowsCustomPngCursor {
int hotSpotY;
};
-QCursor QWindowsCursor::customCursor(Qt::CursorShape cursorShape)
+QWindowsCursor::PixmapCursor QWindowsCursor::customCursor(Qt::CursorShape cursorShape)
{
static const QWindowsCustomPngCursor pngCursors[] = {
{ Qt::SplitVCursor, 32, "splitvcursor_32.png", 11, 11 },
@@ -473,11 +479,11 @@ QCursor QWindowsCursor::customCursor(Qt::CursorShape cursorShape)
}
if (!bestFit)
- return QCursor();
+ return PixmapCursor();
const QPixmap rawImage(QStringLiteral(":/qt-project.org/windows/cursors/images/") +
QString::fromLatin1(bestFit->fileName));
- return QCursor(rawImage, bestFit->hotSpotX, bestFit->hotSpotY);
+ return PixmapCursor(rawImage, QPoint(bestFit->hotSpotX, bestFit->hotSpotY));
}
#endif // Q_OS_WINCE || QT_NO_IMAGEFORMAT_PNG
@@ -486,8 +492,10 @@ struct QWindowsStandardCursorMapping {
LPCWSTR resource;
};
-HCURSOR QWindowsCursor::createSystemCursor(const QCursor &c)
+HCURSOR QWindowsCursor::createCursorFromShape(Qt::CursorShape cursorShape)
{
+ Q_ASSERT(cursorShape != Qt::BitmapCursor);
+
static const QWindowsStandardCursorMapping standardCursors[] = {
{ Qt::ArrowCursor, IDC_ARROW},
{ Qt::UpArrowCursor, IDC_UPARROW },
@@ -505,18 +513,7 @@ HCURSOR QWindowsCursor::createSystemCursor(const QCursor &c)
{ Qt::PointingHandCursor, IDC_HAND }
};
- const Qt::CursorShape cursorShape = c.shape();
switch (cursorShape) {
- case Qt::BitmapCursor: {
- const QPixmap pixmap = c.pixmap();
- if (!pixmap.isNull())
- return QWindowsCursor::createPixmapCursor(pixmap, c.hotSpot());
- const QImage bbits = c.bitmap()->toImage().convertToFormat(QImage::Format_Mono);
- const QImage mbits = c.mask()->toImage().convertToFormat(QImage::Format_Mono);
- const bool invb = bbits.colorCount() > 1 && qGray(bbits.color(0)) < qGray(bbits.color(1));
- const bool invm = mbits.colorCount() > 1 && qGray(mbits.color(0)) < qGray(mbits.color(1));
- return createBitmapCursor(bbits, mbits, c.hotSpot(), invb, invm);
- }
case Qt::BlankCursor: {
QImage blank = QImage(systemCursorSize(), QImage::Format_Mono);
blank.fill(0); // ignore color table
@@ -529,7 +526,7 @@ HCURSOR QWindowsCursor::createSystemCursor(const QCursor &c)
case Qt::DragCopyCursor:
case Qt::DragMoveCursor:
case Qt::DragLinkCursor:
- return createSystemCursor(customCursor(cursorShape));
+ return QWindowsCursor::createPixmapCursor(customCursor(cursorShape));
default:
break;
}
@@ -554,37 +551,41 @@ HCURSOR QWindowsCursor::createSystemCursor(const QCursor &c)
\brief Return cached standard cursor resources or create new ones.
*/
-QWindowsWindowCursor QWindowsCursor::standardWindowCursor(Qt::CursorShape shape)
+CursorHandlePtr QWindowsCursor::standardWindowCursor(Qt::CursorShape shape)
{
- const QWindowsCursorCacheKey key(shape);
- CursorCache::iterator it = m_cursorCache.find(key);
- if (it == m_cursorCache.end())
- it = m_cursorCache.insert(key, QWindowsWindowCursor(QCursor(shape)));
- return it.value();
+ StandardCursorCache::Iterator it = m_standardCursorCache.find(shape);
+ if (it == m_standardCursorCache.end()) {
+ if (const HCURSOR hc = QWindowsCursor::createCursorFromShape(shape))
+ it = m_standardCursorCache.insert(shape, CursorHandlePtr(new CursorHandle(hc)));
+ }
+ return it != m_standardCursorCache.end() ? it.value() : CursorHandlePtr(new CursorHandle);
}
/*!
\brief Return cached pixmap cursor or create new one.
*/
-QWindowsWindowCursor QWindowsCursor::pixmapWindowCursor(const QCursor &c)
+CursorHandlePtr QWindowsCursor::pixmapWindowCursor(const QCursor &c)
{
- const QWindowsCursorCacheKey cacheKey(c);
- CursorCache::iterator it = m_cursorCache.find(cacheKey);
- if (it == m_cursorCache.end()) {
- if (m_cursorCache.size() > 50) {
+ const QWindowsPixmapCursorCacheKey cacheKey(c);
+ PixmapCursorCache::iterator it = m_pixmapCursorCache.find(cacheKey);
+ if (it == m_pixmapCursorCache.end()) {
+ if (m_pixmapCursorCache.size() > 50) {
// Prevent the cursor cache from growing indefinitely hitting GDI resource
// limits if new pixmap cursors are created repetitively by purging out
// all-noncurrent pixmap cursors (QTBUG-43515)
const HCURSOR currentCursor = GetCursor();
- for (it = m_cursorCache.begin(); it != m_cursorCache.end() ; ) {
- if (it.key().bitmapCacheKey && it.value().handle() != currentCursor)
- it = m_cursorCache.erase(it);
+ for (it = m_pixmapCursorCache.begin(); it != m_pixmapCursorCache.end() ; ) {
+ if (it.value()->handle() != currentCursor)
+ it = m_pixmapCursorCache.erase(it);
else
++it;
}
}
- it = m_cursorCache.insert(cacheKey, QWindowsWindowCursor(c));
+ const QPixmap pixmap = c.pixmap();
+ const HCURSOR hc = pixmap.isNull()
+ ? createBitmapCursor(c) : QWindowsCursor::createPixmapCursor(pixmap, c.hotSpot());
+ it = m_pixmapCursorCache.insert(cacheKey, CursorHandlePtr(new CursorHandle(hc)));
}
return it.value();
}
@@ -606,13 +607,13 @@ void QWindowsCursor::changeCursor(QCursor *cursorIn, QWindow *window)
if (!window)
return;
if (!cursorIn) {
- QWindowsWindow::baseWindowOf(window)->setCursor(QWindowsWindowCursor());
+ QWindowsWindow::baseWindowOf(window)->setCursor(CursorHandlePtr(new CursorHandle));
return;
}
- const QWindowsWindowCursor wcursor =
+ const CursorHandlePtr wcursor =
cursorIn->shape() == Qt::BitmapCursor ?
pixmapWindowCursor(*cursorIn) : standardWindowCursor(cursorIn->shape());
- if (wcursor.handle()) {
+ if (wcursor->handle()) {
QWindowsWindow::baseWindowOf(window)->setCursor(wcursor);
} else {
qWarning("%s: Unable to obtain system cursor for %d",
@@ -658,78 +659,11 @@ void QWindowsCursor::setPos(const QPoint &pos)
\brief Per-Window cursor. Contains a QCursor and manages its associated system
cursor handle resource.
- Based on QSharedDataPointer, so that it can be passed around and
- used as a property of QWindowsBaseWindow.
-
\internal
\ingroup qt-lighthouse-win
\sa QWindowsCursor
*/
-class QWindowsWindowCursorData : public QSharedData
-{
-public:
- QWindowsWindowCursorData() : m_cursor(Qt::ArrowCursor), m_handle(0) {}
- explicit QWindowsWindowCursorData(const QCursor &c);
- ~QWindowsWindowCursorData();
-
- const QCursor m_cursor;
- const HCURSOR m_handle;
-};
-
-QWindowsWindowCursorData::QWindowsWindowCursorData(const QCursor &c) :
- m_cursor(c),
- m_handle(QWindowsCursor::createSystemCursor(c))
-{
-}
-
-QWindowsWindowCursorData::~QWindowsWindowCursorData()
-{
- if (m_handle)
- DestroyCursor(m_handle);
-}
-
-QWindowsWindowCursor::QWindowsWindowCursor() :
- m_data(new QWindowsWindowCursorData)
-{
-}
-
-QWindowsWindowCursor::QWindowsWindowCursor(const QCursor &c) :
- m_data(new QWindowsWindowCursorData(c))
-{
-}
-
-QWindowsWindowCursor::~QWindowsWindowCursor()
-{
-}
-
-QWindowsWindowCursor::QWindowsWindowCursor(const QWindowsWindowCursor &rhs) :
- m_data(rhs.m_data)
-{
-}
-
-QWindowsWindowCursor & QWindowsWindowCursor::operator =(const QWindowsWindowCursor &rhs)
-{
- if (this != &rhs)
- m_data.operator =(rhs.m_data);
- return *this;
-}
-
-bool QWindowsWindowCursor::isNull() const
-{
- return m_data->m_handle == 0;
-}
-
-QCursor QWindowsWindowCursor::cursor() const
-{
- return m_data->m_cursor;
-}
-
-HCURSOR QWindowsWindowCursor::handle() const
-{
- return m_data->m_handle;
-}
-
QT_END_NAMESPACE
#endif // !QT_NO_CURSOR
diff --git a/src/plugins/platforms/windows/qwindowscursor.h b/src/plugins/platforms/windows/qwindowscursor.h
index f1763ddd7d..ac9e87d1fb 100644
--- a/src/plugins/platforms/windows/qwindowscursor.h
+++ b/src/plugins/platforms/windows/qwindowscursor.h
@@ -37,51 +37,49 @@
#include "qtwindows_additional.h"
#include <qpa/qplatformcursor.h>
-#include <QtCore/QSharedDataPointer>
+#include <QtCore/QSharedPointer>
#include <QtCore/QHash>
QT_BEGIN_NAMESPACE
-class QWindowsWindowCursorData;
-
-struct QWindowsCursorCacheKey
+struct QWindowsPixmapCursorCacheKey
{
- explicit QWindowsCursorCacheKey(const QCursor &c);
- explicit QWindowsCursorCacheKey(Qt::CursorShape s) : shape(s), bitmapCacheKey(0), maskCacheKey(0) {}
- QWindowsCursorCacheKey() : shape(Qt::CustomCursor), bitmapCacheKey(0), maskCacheKey(0) {}
+ explicit QWindowsPixmapCursorCacheKey(const QCursor &c);
- Qt::CursorShape shape;
qint64 bitmapCacheKey;
qint64 maskCacheKey;
};
-inline bool operator==(const QWindowsCursorCacheKey &k1, const QWindowsCursorCacheKey &k2)
+inline bool operator==(const QWindowsPixmapCursorCacheKey &k1, const QWindowsPixmapCursorCacheKey &k2)
{
- return k1.shape == k2.shape && k1.bitmapCacheKey == k2.bitmapCacheKey && k1.maskCacheKey == k2.maskCacheKey;
+ return k1.bitmapCacheKey == k2.bitmapCacheKey && k1.maskCacheKey == k2.maskCacheKey;
}
-inline uint qHash(const QWindowsCursorCacheKey &k, uint seed) Q_DECL_NOTHROW
+inline uint qHash(const QWindowsPixmapCursorCacheKey &k, uint seed) Q_DECL_NOTHROW
{
- return (uint(k.shape) + uint(k.bitmapCacheKey) + uint(k.maskCacheKey)) ^ seed;
+ return (uint(k.bitmapCacheKey) + uint(k.maskCacheKey)) ^ seed;
}
-class QWindowsWindowCursor
+class CursorHandle
{
+ Q_DISABLE_COPY(CursorHandle)
public:
- QWindowsWindowCursor();
- explicit QWindowsWindowCursor(const QCursor &c);
- ~QWindowsWindowCursor();
- QWindowsWindowCursor(const QWindowsWindowCursor &c);
- QWindowsWindowCursor &operator=(const QWindowsWindowCursor &c);
+ explicit CursorHandle(HCURSOR hcursor = Q_NULLPTR) : m_hcursor(hcursor) {}
+ ~CursorHandle()
+ {
+ if (m_hcursor)
+ DestroyCursor(m_hcursor);
+ }
- bool isNull() const;
- QCursor cursor() const;
- HCURSOR handle() const;
+ bool isNull() const { return !m_hcursor; }
+ HCURSOR handle() const { return m_hcursor; }
private:
- QSharedDataPointer<QWindowsWindowCursorData> m_data;
+ const HCURSOR m_hcursor;
};
+typedef QSharedPointer<CursorHandle> CursorHandlePtr;
+
class QWindowsCursor : public QPlatformCursor
{
public:
@@ -91,6 +89,13 @@ public:
CursorSuppressed // Cursor suppressed by touch interaction (Windows 8).
};
+ struct PixmapCursor {
+ explicit PixmapCursor(const QPixmap &pix = QPixmap(), const QPoint &h = QPoint()) : pixmap(pix), hotSpot(h) {}
+
+ QPixmap pixmap;
+ QPoint hotSpot;
+ };
+
QWindowsCursor();
void changeCursor(QCursor * widgetCursor, QWindow * widget) Q_DECL_OVERRIDE;
@@ -98,18 +103,22 @@ public:
void setPos(const QPoint &pos) Q_DECL_OVERRIDE;
static HCURSOR createPixmapCursor(const QPixmap &pixmap, const QPoint &hotSpot);
- static HCURSOR createSystemCursor(const QCursor &c);
- static QCursor customCursor(Qt::CursorShape cursorShape);
+ static HCURSOR createPixmapCursor(const PixmapCursor &pc) { return createPixmapCursor(pc.pixmap, pc.hotSpot); }
+ static PixmapCursor customCursor(Qt::CursorShape cursorShape);
+
+ static HCURSOR createCursorFromShape(Qt::CursorShape cursorShape);
static QPoint mousePosition();
static CursorState cursorState();
- QWindowsWindowCursor standardWindowCursor(Qt::CursorShape s = Qt::ArrowCursor);
- QWindowsWindowCursor pixmapWindowCursor(const QCursor &c);
+ CursorHandlePtr standardWindowCursor(Qt::CursorShape s = Qt::ArrowCursor);
+ CursorHandlePtr pixmapWindowCursor(const QCursor &c);
private:
- typedef QHash<QWindowsCursorCacheKey, QWindowsWindowCursor> CursorCache;
+ typedef QHash<Qt::CursorShape, CursorHandlePtr> StandardCursorCache;
+ typedef QHash<QWindowsPixmapCursorCacheKey, CursorHandlePtr> PixmapCursorCache;
- CursorCache m_cursorCache;
+ StandardCursorCache m_standardCursorCache;
+ PixmapCursorCache m_pixmapCursorCache;
};
QT_END_NAMESPACE
diff --git a/src/plugins/platforms/windows/qwindowsdrag.cpp b/src/plugins/platforms/windows/qwindowsdrag.cpp
index fcd9911a56..5435c4820a 100644
--- a/src/plugins/platforms/windows/qwindowsdrag.cpp
+++ b/src/plugins/platforms/windows/qwindowsdrag.cpp
@@ -218,23 +218,14 @@ public:
STDMETHOD(GiveFeedback)(DWORD dwEffect);
private:
- class DragCursorHandle {
- Q_DISABLE_COPY(DragCursorHandle)
- public:
- DragCursorHandle(HCURSOR c) : cursor(c) {}
- ~DragCursorHandle() { DestroyCursor(cursor); }
- const HCURSOR cursor;
- };
- typedef QSharedPointer<DragCursorHandle> DragCursorHandlePtr;
-
struct CursorEntry {
CursorEntry() : cacheKey(0) {}
- CursorEntry(const QPixmap &p, qint64 cK, const DragCursorHandlePtr &c, const QPoint &h) :
+ CursorEntry(const QPixmap &p, qint64 cK, const CursorHandlePtr &c, const QPoint &h) :
pixmap(p), cacheKey(cK), cursor(c), hotSpot(h) {}
QPixmap pixmap;
qint64 cacheKey; // Cache key of cursor
- DragCursorHandlePtr cursor;
+ CursorHandlePtr cursor;
QPoint hotSpot;
};
@@ -273,7 +264,7 @@ QWindowsOleDropSource::~QWindowsOleDropSource()
QDebug operator<<(QDebug d, const QWindowsOleDropSource::CursorEntry &e)
{
d << "CursorEntry:" << e.pixmap.size() << '#' << e.cacheKey
- << "HCURSOR" << e.cursor->cursor << "hotspot:" << e.hotSpot;
+ << "HCURSOR" << e.cursor->handle() << "hotspot:" << e.hotSpot;
return d;
}
#endif // !QT_NO_DEBUG_STREAM
@@ -343,7 +334,7 @@ void QWindowsOleDropSource::createCursors()
}
if (const HCURSOR sysCursor = QWindowsCursor::createPixmapCursor(newPixmap, newHotSpot)) {
- const CursorEntry entry(newPixmap, cacheKey, DragCursorHandlePtr(new DragCursorHandle(sysCursor)), newHotSpot);
+ const CursorEntry entry(newPixmap, cacheKey, CursorHandlePtr(new CursorHandle(sysCursor)), newHotSpot);
if (it == m_cursors.end())
m_cursors.insert(action, entry);
else
@@ -456,7 +447,7 @@ QWindowsOleDropSource::GiveFeedback(DWORD dwEffect)
const CursorEntry &e = it.value();
switch (m_mode) {
case MouseDrag:
- SetCursor(e.cursor->cursor);
+ SetCursor(e.cursor->handle());
break;
case TouchDrag:
if (!m_touchDragWindow)
@@ -718,16 +709,16 @@ QPixmap QWindowsDrag::defaultCursor(Qt::DropAction action) const
switch (action) {
case Qt::CopyAction:
if (m_copyDragCursor.isNull())
- m_copyDragCursor = QWindowsCursor::customCursor(Qt::DragCopyCursor).pixmap();
+ m_copyDragCursor = QWindowsCursor::customCursor(Qt::DragCopyCursor).pixmap;
return m_copyDragCursor;
case Qt::TargetMoveAction:
case Qt::MoveAction:
if (m_moveDragCursor.isNull())
- m_moveDragCursor = QWindowsCursor::customCursor(Qt::DragMoveCursor).pixmap();
+ m_moveDragCursor = QWindowsCursor::customCursor(Qt::DragMoveCursor).pixmap;
return m_moveDragCursor;
case Qt::LinkAction:
if (m_linkDragCursor.isNull())
- m_linkDragCursor = QWindowsCursor::customCursor(Qt::DragLinkCursor).pixmap();
+ m_linkDragCursor = QWindowsCursor::customCursor(Qt::DragLinkCursor).pixmap;
return m_linkDragCursor;
default:
break;
diff --git a/src/plugins/platforms/windows/qwindowstheme.cpp b/src/plugins/platforms/windows/qwindowstheme.cpp
index 33c7ccfdce..877bdfec17 100644
--- a/src/plugins/platforms/windows/qwindowstheme.cpp
+++ b/src/plugins/platforms/windows/qwindowstheme.cpp
@@ -393,6 +393,8 @@ QVariant QWindowsTheme::themeHint(ThemeHint hint) const
return QVariant(booleanSystemParametersInfo(SPI_GETSNAPTODEFBUTTON, false));
case ContextMenuOnMouseRelease:
return QVariant(true);
+ case WheelScrollLines:
+ return dWordSystemParametersInfo(SPI_GETWHEELSCROLLLINES, 3);
default:
break;
}
diff --git a/src/plugins/platforms/windows/qwindowswindow.cpp b/src/plugins/platforms/windows/qwindowswindow.cpp
index 01e2a804bd..c49682cc26 100644
--- a/src/plugins/platforms/windows/qwindowswindow.cpp
+++ b/src/plugins/platforms/windows/qwindowswindow.cpp
@@ -928,6 +928,7 @@ QWindowsWindow::QWindowsWindow(QWindow *aWindow, const QWindowsWindowData &data)
m_hdc(0),
m_windowState(Qt::WindowNoState),
m_opacity(1.0),
+ m_cursor(new CursorHandle),
m_dropTarget(0),
m_savedStyle(0),
m_format(aWindow->requestedFormat()),
@@ -2113,13 +2114,13 @@ bool QWindowsWindow::handleNonClientHitTest(const QPoint &globalPos, LRESULT *re
#ifndef QT_NO_CURSOR
// Return the default cursor (Arrow) from QWindowsCursor's cache.
-static inline QWindowsWindowCursor defaultCursor(const QWindow *w)
+static inline CursorHandlePtr defaultCursor(const QWindow *w)
{
if (QScreen *screen = w->screen())
if (const QPlatformScreen *platformScreen = screen->handle())
if (QPlatformCursor *cursor = platformScreen->cursor())
return static_cast<QWindowsCursor *>(cursor)->standardWindowCursor(Qt::ArrowCursor);
- return QWindowsWindowCursor(Qt::ArrowCursor);
+ return CursorHandlePtr(new CursorHandle(QWindowsCursor::createCursorFromShape(Qt::ArrowCursor)));
}
// Check whether to apply a new cursor. Either the window in question is
@@ -2133,7 +2134,7 @@ static inline bool applyNewCursor(const QWindow *w)
for (const QWindow *p = underMouse; p ; p = p->parent()) {
if (p == w)
return true;
- if (!QWindowsWindow::baseWindowOf(p)->cursor().isNull())
+ if (!QWindowsWindow::baseWindowOf(p)->cursor()->isNull())
return false;
}
return false;
@@ -2149,25 +2150,25 @@ static inline bool applyNewCursor(const QWindow *w)
void QWindowsWindow::applyCursor()
{
#ifndef QT_NO_CURSOR
- if (m_cursor.isNull()) { // Recurse up to parent with non-null cursor. Set default for toplevel.
+ if (m_cursor->isNull()) { // Recurse up to parent with non-null cursor. Set default for toplevel.
if (const QWindow *p = window()->parent()) {
QWindowsWindow::baseWindowOf(p)->applyCursor();
} else {
- SetCursor(defaultCursor(window()).handle());
+ SetCursor(defaultCursor(window())->handle());
}
} else {
- SetCursor(m_cursor.handle());
+ SetCursor(m_cursor->handle());
}
#endif
}
-void QWindowsWindow::setCursor(const QWindowsWindowCursor &c)
+void QWindowsWindow::setCursor(const CursorHandlePtr &c)
{
#ifndef QT_NO_CURSOR
- if (c.handle() != m_cursor.handle()) {
+ if (c->handle() != m_cursor->handle()) {
const bool apply = applyNewCursor(window());
qCDebug(lcQpaWindows) << window() << __FUNCTION__
- << c.cursor().shape() << " doApply=" << apply;
+ << c->handle() << " doApply=" << apply;
m_cursor = c;
if (apply)
applyCursor();
diff --git a/src/plugins/platforms/windows/qwindowswindow.h b/src/plugins/platforms/windows/qwindowswindow.h
index 40d7a3f076..4172a3d850 100644
--- a/src/plugins/platforms/windows/qwindowswindow.h
+++ b/src/plugins/platforms/windows/qwindowswindow.h
@@ -225,9 +225,9 @@ public:
#endif // !Q_OS_WINCE
#ifndef QT_NO_CURSOR
- QWindowsWindowCursor cursor() const { return m_cursor; }
+ CursorHandlePtr cursor() const { return m_cursor; }
#endif
- void setCursor(const QWindowsWindowCursor &c);
+ void setCursor(const CursorHandlePtr &c);
void applyCursor();
inline bool testFlag(unsigned f) const { return (m_flags & f) != 0; }
@@ -278,7 +278,7 @@ private:
Qt::WindowState m_windowState;
qreal m_opacity;
#ifndef QT_NO_CURSOR
- QWindowsWindowCursor m_cursor;
+ CursorHandlePtr m_cursor;
#endif
QWindowsOleDropTarget *m_dropTarget;
unsigned m_savedStyle;
diff --git a/src/plugins/platforms/winrt/qwinrtintegration.cpp b/src/plugins/platforms/winrt/qwinrtintegration.cpp
index 23bb6c16ec..9db5df995a 100644
--- a/src/plugins/platforms/winrt/qwinrtintegration.cpp
+++ b/src/plugins/platforms/winrt/qwinrtintegration.cpp
@@ -260,8 +260,10 @@ HRESULT QWinRTIntegration::onBackButtonPressed(IInspectable *, IBackPressedEvent
Q_D(QWinRTIntegration);
QWindow *window = d->mainScreen->topWindow();
QWindowSystemInterface::setSynchronousWindowSystemEvents(true);
- const bool pressed = QWindowSystemInterface::handleKeyEvent(window, QEvent::KeyPress, Qt::Key_Back, Qt::NoModifier);
- const bool released = QWindowSystemInterface::handleKeyEvent(window, QEvent::KeyRelease, Qt::Key_Back, Qt::NoModifier);
+ const bool pressed = QWindowSystemInterface::handleExtendedKeyEvent(window, QEvent::KeyPress, Qt::Key_Back, Qt::NoModifier,
+ 0, 0, 0, QString(), false, 1, false);
+ const bool released = QWindowSystemInterface::handleExtendedKeyEvent(window, QEvent::KeyRelease, Qt::Key_Back, Qt::NoModifier,
+ 0, 0, 0, QString(), false, 1, false);
QWindowSystemInterface::setSynchronousWindowSystemEvents(false);
args->put_Handled(pressed || released);
return S_OK;
diff --git a/src/plugins/platforms/xcb/qxcbwindow.cpp b/src/plugins/platforms/xcb/qxcbwindow.cpp
index bcc571c3c8..d76f1245e8 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.cpp
+++ b/src/plugins/platforms/xcb/qxcbwindow.cpp
@@ -500,10 +500,7 @@ void QXcbWindow::create()
properties[propertyCount++] = atom(QXcbAtom::WM_TAKE_FOCUS);
properties[propertyCount++] = atom(QXcbAtom::_NET_WM_PING);
- if (platformScreen->syncRequestSupported())
- m_usingSyncProtocol = supportsSyncProtocol();
- else
- m_usingSyncProtocol = false;
+ m_usingSyncProtocol = platformScreen->syncRequestSupported();
if (m_usingSyncProtocol)
properties[propertyCount++] = atom(QXcbAtom::_NET_WM_SYNC_REQUEST);
diff --git a/src/plugins/platforms/xcb/qxcbwindow.h b/src/plugins/platforms/xcb/qxcbwindow.h
index b2c5fa7d4d..41c4b4443d 100644
--- a/src/plugins/platforms/xcb/qxcbwindow.h
+++ b/src/plugins/platforms/xcb/qxcbwindow.h
@@ -176,7 +176,6 @@ public Q_SLOTS:
protected:
virtual void resolveFormat() { m_format = window()->requestedFormat(); }
virtual void *createVisual() { return Q_NULLPTR; }
- virtual bool supportsSyncProtocol() { return !window()->supportsOpenGL(); }
QXcbScreen *parentScreen();
diff --git a/src/sql/models/qsqlquerymodel.cpp b/src/sql/models/qsqlquerymodel.cpp
index 3faea11c70..5a1958708a 100644
--- a/src/sql/models/qsqlquerymodel.cpp
+++ b/src/sql/models/qsqlquerymodel.cpp
@@ -471,6 +471,7 @@ void QSqlQueryModel::setQuery(const QString &query, const QSqlDatabase &db)
void QSqlQueryModel::clear()
{
Q_D(QSqlQueryModel);
+ beginResetModel();
d->error = QSqlError();
d->atEnd = true;
d->query.clear();
@@ -478,6 +479,7 @@ void QSqlQueryModel::clear()
d->colOffsets.clear();
d->bottom = QModelIndex();
d->headers.clear();
+ endResetModel();
}
/*!
diff --git a/src/sql/models/qsqlrelationaltablemodel.cpp b/src/sql/models/qsqlrelationaltablemodel.cpp
index 42acf6a73b..ac2d270fc8 100644
--- a/src/sql/models/qsqlrelationaltablemodel.cpp
+++ b/src/sql/models/qsqlrelationaltablemodel.cpp
@@ -652,9 +652,11 @@ void QSqlRelationalTableModel::revertRow(int row)
void QSqlRelationalTableModel::clear()
{
Q_D(QSqlRelationalTableModel);
+ beginResetModel();
d->clearChanges();
d->relations.clear();
QSqlTableModel::clear();
+ endResetModel();
}
diff --git a/src/sql/models/qsqltablemodel.cpp b/src/sql/models/qsqltablemodel.cpp
index b0d3e6df9d..740c1b9b5d 100644
--- a/src/sql/models/qsqltablemodel.cpp
+++ b/src/sql/models/qsqltablemodel.cpp
@@ -1262,8 +1262,10 @@ void QSqlTableModel::setFilter(const QString &filter)
void QSqlTableModel::clear()
{
Q_D(QSqlTableModel);
+ beginResetModel();
d->clear();
QSqlQueryModel::clear();
+ endResetModel();
}
/*! \reimp
diff --git a/src/widgets/kernel/qopenglwidget.cpp b/src/widgets/kernel/qopenglwidget.cpp
index 389539bb18..3a4a3a0d63 100644
--- a/src/widgets/kernel/qopenglwidget.cpp
+++ b/src/widgets/kernel/qopenglwidget.cpp
@@ -645,12 +645,6 @@ void QOpenGLWidgetPaintDevice::ensureActiveTarget()
GLuint QOpenGLWidgetPrivate::textureId() const
{
- Q_Q(const QOpenGLWidget);
- if (!q->isWindow() && q->internalWinId()) {
- qWarning("QOpenGLWidget cannot be used as a native child widget. Consider setting "
- "Qt::WA_DontCreateNativeAncestors and Qt::AA_DontCreateNativeWidgetSiblings");
- return 0;
- }
return resolvedFbo ? resolvedFbo->texture() : (fbo ? fbo->texture() : 0);
}
diff --git a/src/widgets/kernel/qwidget.cpp b/src/widgets/kernel/qwidget.cpp
index 14eb368973..0f580f7369 100644
--- a/src/widgets/kernel/qwidget.cpp
+++ b/src/widgets/kernel/qwidget.cpp
@@ -60,6 +60,7 @@
# include <private/qmainwindowlayout_p.h>
#endif
#include <qpa/qplatformwindow.h>
+#include <qpa/qplatformbackingstore.h>
#include "private/qwidgetwindow_p.h"
#include "qpainter.h"
#include "qtooltip.h"
@@ -1834,6 +1835,8 @@ void QWidgetPrivate::deleteTLSysExtra()
delete extra->topextra->backingStore;
extra->topextra->backingStore = 0;
#ifndef QT_NO_OPENGL
+ qDeleteAll(extra->topextra->widgetTextures);
+ extra->topextra->widgetTextures.clear();
if (textureChildSeen && extra->topextra->shareContext)
extra->topextra->shareContext->doneCurrent();
delete extra->topextra->shareContext;
diff --git a/src/widgets/kernel/qwidget_p.h b/src/widgets/kernel/qwidget_p.h
index fe65cb19c7..a78cf099ac 100644
--- a/src/widgets/kernel/qwidget_p.h
+++ b/src/widgets/kernel/qwidget_p.h
@@ -75,6 +75,7 @@ class QWidgetBackingStore;
class QGraphicsProxyWidget;
class QWidgetItemV2;
class QOpenGLContext;
+class QPlatformTextureList;
class QStyle;
@@ -153,6 +154,8 @@ struct QTLWExtra {
QWidgetBackingStoreTracker backingStoreTracker;
QBackingStore *backingStore;
QPainter *sharedPainter;
+ QWidgetWindow *window;
+ QOpenGLContext *shareContext;
// Implicit pointers (shared_null).
QString caption; // widget caption
@@ -167,6 +170,9 @@ struct QTLWExtra {
QRect frameStrut;
QRect normalGeometry; // used by showMin/maximized/FullScreen
Qt::WindowFlags savedFlags; // Save widget flags while showing fullscreen
+ int initialScreenIndex; // Screen number when passing a QDesktop[Screen]Widget as parent.
+
+ QVector<QPlatformTextureList *> widgetTextures;
// *************************** Cross-platform bit fields ****************************
uint opacity : 8;
@@ -210,9 +216,6 @@ struct QTLWExtra {
// starting position as 0,0 instead of the normal starting position.
bool wasMaximized;
#endif
- QWidgetWindow *window;
- QOpenGLContext *shareContext;
- int initialScreenIndex; // Screen number when passing a QDesktop[Screen]Widget as parent.
};
struct QWExtra {
diff --git a/src/widgets/kernel/qwidgetbackingstore.cpp b/src/widgets/kernel/qwidgetbackingstore.cpp
index 69958636fd..55b8513072 100644
--- a/src/widgets/kernel/qwidgetbackingstore.cpp
+++ b/src/widgets/kernel/qwidgetbackingstore.cpp
@@ -79,7 +79,6 @@ void QWidgetBackingStore::qt_flush(QWidget *widget, const QRegion &region, QBack
Q_ASSERT(widget);
Q_ASSERT(backingStore);
Q_ASSERT(tlw);
-
#if !defined(QT_NO_PAINT_DEBUG)
static int flushUpdate = qEnvironmentVariableIntValue("QT_FLUSH_UPDATE");
if (flushUpdate > 0)
@@ -105,13 +104,17 @@ void QWidgetBackingStore::qt_flush(QWidget *widget, const QRegion &region, QBack
#ifndef QT_NO_OPENGL
if (widgetTextures) {
+ Q_ASSERT(!widgetTextures->isEmpty());
+ qt_window_private(tlw->windowHandle())->compositing = true;
widget->window()->d_func()->sendComposeStatus(widget->window(), false);
// A window may have alpha even when the app did not request
// WA_TranslucentBackground. Therefore the compositor needs to know whether the app intends
// to rely on translucency, in order to decide if it should clear to transparent or opaque.
const bool translucentBackground = widget->testAttribute(Qt::WA_TranslucentBackground);
+ // Use the tlw's context, not widget's. The difference is important with native child
+ // widgets where tlw != widget.
backingStore->handle()->composeAndFlush(widget->windowHandle(), region, offset, widgetTextures,
- widget->d_func()->shareContext(), translucentBackground);
+ tlw->d_func()->shareContext(), translucentBackground);
widget->window()->d_func()->sendComposeStatus(widget->window(), true);
} else
#endif
@@ -741,7 +744,6 @@ void QWidgetBackingStore::updateLists(QWidget *cur)
QWidgetBackingStore::QWidgetBackingStore(QWidget *topLevel)
: tlw(topLevel),
dirtyOnScreenWidgets(0),
- widgetTextures(0),
fullUpdatePending(0),
updateRequestSent(0),
textureListWatcher(0),
@@ -761,9 +763,6 @@ QWidgetBackingStore::~QWidgetBackingStore()
for (int c = 0; c < dirtyRenderToTextureWidgets.size(); ++c)
resetWidget(dirtyRenderToTextureWidgets.at(c));
-#ifndef QT_NO_OPENGL
- delete widgetTextures;
-#endif
delete dirtyOnScreenWidgets;
}
@@ -792,8 +791,9 @@ void QWidgetPrivate::moveRect(const QRect &rect, int dx, int dy)
destRect = destRect.translated(dx, dy).intersected(clipR);
const QRect sourceRect(destRect.translated(-dx, -dy));
const QRect parentRect(rect & clipR);
+ const bool nativeWithTextureChild = textureChildSeen && q->internalWinId();
- bool accelerateMove = accelEnv && isOpaque
+ bool accelerateMove = accelEnv && isOpaque && !nativeWithTextureChild
#ifndef QT_NO_GRAPHICSVIEW
// No accelerate move for proxy widgets.
&& !tlw->d_func()->extra->proxyWidget
@@ -913,6 +913,95 @@ void QWidgetPrivate::scrollRect(const QRect &rect, int dx, int dy)
}
}
+#ifndef QT_NO_OPENGL
+static void findTextureWidgetsRecursively(QWidget *tlw, QWidget *widget, QPlatformTextureList *widgetTextures, QVector<QWidget *> *nativeChildren)
+{
+ QWidgetPrivate *wd = QWidgetPrivate::get(widget);
+ if (wd->renderToTexture) {
+ QPlatformTextureList::Flags flags = 0;
+ if (widget->testAttribute(Qt::WA_AlwaysStackOnTop))
+ flags |= QPlatformTextureList::StacksOnTop;
+ const QRect rect(widget->mapTo(tlw, QPoint()), widget->size());
+ widgetTextures->appendTexture(widget, wd->textureId(), rect, wd->clipRect(), flags);
+ }
+
+ for (int i = 0; i < wd->children.size(); ++i) {
+ QWidget *w = qobject_cast<QWidget *>(wd->children.at(i));
+ // Stop at native widgets but store them. Stop at hidden widgets too.
+ if (w && !w->isWindow() && w->internalWinId())
+ nativeChildren->append(w);
+ if (w && !w->isWindow() && !w->internalWinId() && !w->isHidden() && QWidgetPrivate::get(w)->textureChildSeen)
+ findTextureWidgetsRecursively(tlw, w, widgetTextures, nativeChildren);
+ }
+}
+
+static void findAllTextureWidgetsRecursively(QWidget *tlw, QWidget *widget)
+{
+ // textureChildSeen does not take native child widgets into account and that's good.
+ if (QWidgetPrivate::get(widget)->textureChildSeen) {
+ QVector<QWidget *> nativeChildren;
+ QScopedPointer<QPlatformTextureList> tl(new QPlatformTextureList);
+ // Look for texture widgets (incl. widget itself) from 'widget' down,
+ // but skip subtrees with a parent of a native child widget.
+ findTextureWidgetsRecursively(tlw, widget, tl.data(), &nativeChildren);
+ // tl may be empty regardless of textureChildSeen if we have native or hidden children.
+ if (!tl->isEmpty())
+ QWidgetPrivate::get(tlw)->topData()->widgetTextures.append(tl.take());
+ // Native child widgets, if there was any, get their own separate QPlatformTextureList.
+ foreach (QWidget *ncw, nativeChildren) {
+ if (QWidgetPrivate::get(ncw)->textureChildSeen)
+ findAllTextureWidgetsRecursively(tlw, ncw);
+ }
+ }
+}
+
+static QPlatformTextureList *widgetTexturesFor(QWidget *tlw, QWidget *widget)
+{
+ foreach (QPlatformTextureList *tl, QWidgetPrivate::get(tlw)->topData()->widgetTextures) {
+ Q_ASSERT(!tl->isEmpty());
+ for (int i = 0; i < tl->count(); ++i) {
+ QWidget *w = static_cast<QWidget *>(tl->source(i));
+ if ((w->internalWinId() && w == widget) || (!w->internalWinId() && w->nativeParentWidget() == widget))
+ return tl;
+ }
+ }
+ return 0;
+}
+
+// Watches one or more QPlatformTextureLists for changes in the lock state and
+// triggers a backingstore sync when all the registered lists turn into
+// unlocked state. This is essential when a custom composeAndFlush()
+// implementation in a platform plugin is not synchronous and keeps
+// holding on to the textures for some time even after returning from there.
+QPlatformTextureListWatcher::QPlatformTextureListWatcher(QWidgetBackingStore *backingStore)
+ : m_backingStore(backingStore)
+{
+}
+
+void QPlatformTextureListWatcher::watch(QPlatformTextureList *textureList)
+{
+ connect(textureList, SIGNAL(locked(bool)), SLOT(onLockStatusChanged(bool)));
+ m_locked[textureList] = textureList->isLocked();
+}
+
+bool QPlatformTextureListWatcher::isLocked() const
+{
+ foreach (bool v, m_locked) {
+ if (v)
+ return true;
+ }
+ return false;
+}
+
+void QPlatformTextureListWatcher::onLockStatusChanged(bool locked)
+{
+ QPlatformTextureList *tl = static_cast<QPlatformTextureList *>(sender());
+ m_locked[tl] = locked;
+ if (!isLocked())
+ m_backingStore->sync();
+}
+#endif // QT_NO_OPENGL
+
static inline bool discardSyncRequest(QWidget *tlw, QTLWExtra *tlwExtra)
{
if (!tlw || !tlwExtra || !tlw->testAttribute(Qt::WA_Mapped) || !tlw->isVisible())
@@ -941,7 +1030,7 @@ void QWidgetBackingStore::sync(QWidget *exposedWidget, const QRegion &exposedReg
// Nothing to repaint.
if (!isDirty() && store->size().isValid()) {
- qt_flush(exposedWidget, exposedRegion, store, tlw, tlwOffset, widgetTextures, this);
+ qt_flush(exposedWidget, exposedRegion, store, tlw, tlwOffset, widgetTexturesFor(tlw, tlw), this);
return;
}
@@ -953,45 +1042,6 @@ void QWidgetBackingStore::sync(QWidget *exposedWidget, const QRegion &exposedReg
doSync();
}
-#ifndef QT_NO_OPENGL
-static void findTextureWidgetsRecursively(QWidget *tlw, QWidget *widget, QPlatformTextureList *widgetTextures)
-{
- QWidgetPrivate *wd = QWidgetPrivate::get(widget);
- if (wd->renderToTexture) {
- QPlatformTextureList::Flags flags = 0;
- if (widget->testAttribute(Qt::WA_AlwaysStackOnTop))
- flags |= QPlatformTextureList::StacksOnTop;
- const QRect rect(widget->mapTo(tlw, QPoint()), widget->size());
- widgetTextures->appendTexture(widget, wd->textureId(), rect, wd->clipRect(), flags);
- }
-
- for (int i = 0; i < wd->children.size(); ++i) {
- QWidget *w = qobject_cast<QWidget *>(wd->children.at(i));
- if (w && !w->isWindow() && !w->isHidden() && QWidgetPrivate::get(w)->textureChildSeen)
- findTextureWidgetsRecursively(tlw, w, widgetTextures);
- }
-}
-
-QPlatformTextureListWatcher::QPlatformTextureListWatcher(QWidgetBackingStore *backingStore)
- : m_locked(false),
- m_backingStore(backingStore)
-{
-}
-
-void QPlatformTextureListWatcher::watch(QPlatformTextureList *textureList)
-{
- connect(textureList, SIGNAL(locked(bool)), SLOT(onLockStatusChanged(bool)));
- m_locked = textureList->isLocked();
-}
-
-void QPlatformTextureListWatcher::onLockStatusChanged(bool locked)
-{
- m_locked = locked;
- if (!locked)
- m_backingStore->sync();
-}
-#endif // QT_NO_OPENGL
-
/*!
Synchronizes the backing store, i.e. dirty areas are repainted and flushed.
*/
@@ -1019,12 +1069,19 @@ void QWidgetBackingStore::sync()
if (textureListWatcher && !textureListWatcher->isLocked()) {
textureListWatcher->deleteLater();
textureListWatcher = 0;
- } else if (widgetTextures && widgetTextures->isLocked()) {
- if (!textureListWatcher)
- textureListWatcher = new QPlatformTextureListWatcher(this);
- if (!textureListWatcher->isLocked())
- textureListWatcher->watch(widgetTextures);
- return;
+ } else if (!tlwExtra->widgetTextures.isEmpty()) {
+ bool skipSync = false;
+ foreach (QPlatformTextureList *tl, tlwExtra->widgetTextures) {
+ if (tl->isLocked()) {
+ if (!textureListWatcher)
+ textureListWatcher = new QPlatformTextureListWatcher(this);
+ if (!textureListWatcher->isLocked())
+ textureListWatcher->watch(tl);
+ skipSync = true;
+ }
+ }
+ if (skipSync) // cannot compose due to widget textures being in use
+ return;
}
#endif
@@ -1117,13 +1174,14 @@ void QWidgetBackingStore::doSync()
dirtyWidgets.clear();
#ifndef QT_NO_OPENGL
- delete widgetTextures;
- widgetTextures = 0;
- if (tlw->d_func()->textureChildSeen) {
- widgetTextures = new QPlatformTextureList;
- findTextureWidgetsRecursively(tlw, tlw, widgetTextures);
- }
- qt_window_private(tlw->windowHandle())->compositing = widgetTextures;
+ // Find all render-to-texture child widgets (including self).
+ // The search is cut at native widget boundaries, meaning that each native child widget
+ // has its own list for the subtree below it.
+ QTLWExtra *tlwExtra = tlw->d_func()->topData();
+ qDeleteAll(tlwExtra->widgetTextures);
+ tlwExtra->widgetTextures.clear();
+ findAllTextureWidgetsRecursively(tlw, tlw);
+ qt_window_private(tlw->windowHandle())->compositing = false; // will get updated in qt_flush()
fullUpdatePending = false;
#endif
@@ -1143,6 +1201,9 @@ void QWidgetBackingStore::doSync()
for (int i = 0; i < paintPending.count(); ++i) {
QWidget *w = paintPending[i];
w->d_func()->sendPaintEvent(w->rect());
+ QWidget *npw = w->nativeParentWidget();
+ if (w->internalWinId() || (npw && npw != tlw))
+ markDirtyOnScreen(w->rect(), w, w->mapTo(tlw, QPoint()));
}
// We might have newly exposed areas on the screen if this function was
@@ -1154,18 +1215,23 @@ void QWidgetBackingStore::doSync()
}
#ifndef QT_NO_OPENGL
- if (widgetTextures && widgetTextures->count()) {
- for (int i = 0; i < widgetTextures->count(); ++i) {
- QWidget *w = static_cast<QWidget *>(widgetTextures->source(i));
+ foreach (QPlatformTextureList *tl, tlwExtra->widgetTextures) {
+ for (int i = 0; i < tl->count(); ++i) {
+ QWidget *w = static_cast<QWidget *>(tl->source(i));
if (dirtyRenderToTextureWidgets.contains(w)) {
- const QRect rect = widgetTextures->geometry(i); // mapped to the tlw already
+ const QRect rect = tl->geometry(i); // mapped to the tlw already
dirty += rect;
toClean += rect;
}
}
}
- for (int i = 0; i < dirtyRenderToTextureWidgets.count(); ++i)
- resetWidget(dirtyRenderToTextureWidgets.at(i));
+ for (int i = 0; i < dirtyRenderToTextureWidgets.count(); ++i) {
+ QWidget *w = dirtyRenderToTextureWidgets.at(i);
+ resetWidget(w);
+ QWidget *npw = w->nativeParentWidget();
+ if (w->internalWinId() || (npw && npw != tlw))
+ markDirtyOnScreen(w->rect(), w, w->mapTo(tlw, QPoint()));
+ }
dirtyRenderToTextureWidgets.clear();
#endif
@@ -1235,31 +1301,39 @@ void QWidgetBackingStore::doSync()
*/
void QWidgetBackingStore::flush(QWidget *widget)
{
+ const bool hasDirtyOnScreenWidgets = dirtyOnScreenWidgets && !dirtyOnScreenWidgets->isEmpty();
+ bool flushed = false;
+
+ // Flush the region in dirtyOnScreen.
if (!dirtyOnScreen.isEmpty()) {
QWidget *target = widget ? widget : tlw;
- qt_flush(target, dirtyOnScreen, store, tlw, tlwOffset, widgetTextures, this);
+ qt_flush(target, dirtyOnScreen, store, tlw, tlwOffset, widgetTexturesFor(tlw, tlw), this);
dirtyOnScreen = QRegion();
-#ifndef QT_NO_OPENGL
- if (widgetTextures && widgetTextures->count())
- return;
-#endif
+ flushed = true;
}
- if (!dirtyOnScreenWidgets || dirtyOnScreenWidgets->isEmpty()) {
+ // Render-to-texture widgets are not in dirtyOnScreen so flush if we have not done it above.
+ if (!flushed && !hasDirtyOnScreenWidgets) {
#ifndef QT_NO_OPENGL
- if (widgetTextures && widgetTextures->count()) {
- QWidget *target = widget ? widget : tlw;
- qt_flush(target, QRegion(), store, tlw, tlwOffset, widgetTextures, this);
+ if (!tlw->d_func()->topData()->widgetTextures.isEmpty()) {
+ QPlatformTextureList *tl = widgetTexturesFor(tlw, tlw);
+ if (tl) {
+ QWidget *target = widget ? widget : tlw;
+ qt_flush(target, QRegion(), store, tlw, tlwOffset, tl, this);
+ }
}
#endif
- return;
}
+ if (!hasDirtyOnScreenWidgets)
+ return;
+
for (int i = 0; i < dirtyOnScreenWidgets->size(); ++i) {
QWidget *w = dirtyOnScreenWidgets->at(i);
QWidgetPrivate *wd = w->d_func();
Q_ASSERT(wd->needsFlush);
- qt_flush(w, *wd->needsFlush, store, tlw, tlwOffset, 0, this);
+ QPlatformTextureList *widgetTexturesForNative = wd->textureChildSeen ? widgetTexturesFor(tlw, w) : 0;
+ qt_flush(w, *wd->needsFlush, store, tlw, tlwOffset, widgetTexturesForNative, this);
*wd->needsFlush = QRegion();
}
dirtyOnScreenWidgets->clear();
diff --git a/src/widgets/kernel/qwidgetbackingstore_p.h b/src/widgets/kernel/qwidgetbackingstore_p.h
index b7ee7e4168..c45e60ef6e 100644
--- a/src/widgets/kernel/qwidgetbackingstore_p.h
+++ b/src/widgets/kernel/qwidgetbackingstore_p.h
@@ -71,13 +71,13 @@ class QPlatformTextureListWatcher : public QObject
public:
QPlatformTextureListWatcher(QWidgetBackingStore *backingStore);
void watch(QPlatformTextureList *textureList);
- bool isLocked() const { return m_locked; }
+ bool isLocked() const;
private slots:
void onLockStatusChanged(bool locked);
private:
- bool m_locked;
+ QHash<QPlatformTextureList *, bool> m_locked;
QWidgetBackingStore *m_backingStore;
};
#endif
@@ -128,7 +128,6 @@ private:
QVector<QWidget *> dirtyRenderToTextureWidgets;
QVector<QWidget *> *dirtyOnScreenWidgets;
QList<QWidget *> staticWidgets;
- QPlatformTextureList *widgetTextures;
QBackingStore *store;
uint fullUpdatePending : 1;
uint updateRequestSent : 1;
diff --git a/src/widgets/styles/qcommonstyle.cpp b/src/widgets/styles/qcommonstyle.cpp
index 5a08801e94..a14ca84388 100644
--- a/src/widgets/styles/qcommonstyle.cpp
+++ b/src/widgets/styles/qcommonstyle.cpp
@@ -265,8 +265,8 @@ void QCommonStyle::drawPrimitive(PrimitiveElement pe, const QStyleOption *opt, Q
case PE_IndicatorProgressChunk:
{
bool vertical = false;
- if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt))
- vertical = (pb2->orientation == Qt::Vertical);
+ if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt))
+ vertical = pb->orientation == Qt::Vertical;
if (!vertical) {
p->fillRect(opt->rect.x(), opt->rect.y() + 3, opt->rect.width() -2, opt->rect.height() - 6,
opt->palette.brush(QPalette::Highlight));
@@ -1085,7 +1085,7 @@ void QCommonStylePrivate::viewItemLayout(const QStyleOptionViewItem *opt, QRect
Uses the same computation than in QTabBar::tabSizeHint
*/
-void QCommonStylePrivate::tabLayout(const QStyleOptionTabV3 *opt, const QWidget *widget, QRect *textRect, QRect *iconRect) const
+void QCommonStylePrivate::tabLayout(const QStyleOptionTab *opt, const QWidget *widget, QRect *textRect, QRect *iconRect) const
{
Q_ASSERT(textRect);
Q_ASSERT(iconRect);
@@ -1391,7 +1391,7 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt,
case CE_ProgressBar:
if (const QStyleOptionProgressBar *pb
= qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
- QStyleOptionProgressBarV2 subopt = *pb;
+ QStyleOptionProgressBar subopt = *pb;
subopt.rect = subElementRect(SE_ProgressBarGroove, pb, widget);
proxy()->drawControl(CE_ProgressBarGroove, &subopt, p, widget);
subopt.rect = subElementRect(SE_ProgressBarContents, pb, widget);
@@ -1409,10 +1409,7 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt,
break;
case CE_ProgressBarLabel:
if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
- bool vertical = false;
- if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt)) {
- vertical = (pb2->orientation == Qt::Vertical);
- }
+ const bool vertical = pb->orientation == Qt::Vertical;
if (!vertical) {
QPalette::ColorRole textRole = QPalette::NoRole;
if ((pb->textAlignment & Qt::AlignCenter) && pb->textVisible
@@ -1437,18 +1434,12 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt,
if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
QRect rect = pb->rect;
- bool vertical = false;
- bool inverted = false;
+ const bool vertical = pb->orientation == Qt::Vertical;
+ const bool inverted = pb->invertedAppearance;
qint64 minimum = qint64(pb->minimum);
qint64 maximum = qint64(pb->maximum);
qint64 progress = qint64(pb->progress);
- // Get extra style options if version 2
- const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt);
- if (pb2) {
- vertical = (pb2->orientation == Qt::Vertical);
- inverted = pb2->invertedAppearance;
- }
QMatrix m;
if (vertical) {
@@ -1508,7 +1499,7 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt,
int x0 = reverse ? rect.right() - ((unit_width > 1) ? unit_width : 0)
: rect.x();
- QStyleOptionProgressBarV2 pbBits = *pb;
+ QStyleOptionProgressBar pbBits = *pb;
pbBits.rect = rect;
pbBits.palette = pal2;
int myY = pbBits.rect.y();
@@ -1864,12 +1855,11 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt,
break;
case CE_TabBarTabLabel:
if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
- QStyleOptionTabV3 tabV2(*tab);
- QRect tr = tabV2.rect;
- bool verticalTabs = tabV2.shape == QTabBar::RoundedEast
- || tabV2.shape == QTabBar::RoundedWest
- || tabV2.shape == QTabBar::TriangularEast
- || tabV2.shape == QTabBar::TriangularWest;
+ QRect tr = tab->rect;
+ bool verticalTabs = tab->shape == QTabBar::RoundedEast
+ || tab->shape == QTabBar::RoundedWest
+ || tab->shape == QTabBar::TriangularEast
+ || tab->shape == QTabBar::TriangularWest;
int alignment = Qt::AlignCenter | Qt::TextShowMnemonic;
if (!proxy()->styleHint(SH_UnderlineShortcut, opt, widget))
@@ -1878,7 +1868,7 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt,
if (verticalTabs) {
p->save();
int newX, newY, newRot;
- if (tabV2.shape == QTabBar::RoundedEast || tabV2.shape == QTabBar::TriangularEast) {
+ if (tab->shape == QTabBar::RoundedEast || tab->shape == QTabBar::TriangularEast) {
newX = tr.width() + tr.x();
newY = tr.y();
newRot = 90;
@@ -1892,15 +1882,15 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt,
p->setTransform(m, true);
}
QRect iconRect;
- d->tabLayout(&tabV2, widget, &tr, &iconRect);
+ d->tabLayout(tab, widget, &tr, &iconRect);
tr = proxy()->subElementRect(SE_TabBarTabText, opt, widget); //we compute tr twice because the style may override subElementRect
- if (!tabV2.icon.isNull()) {
- QPixmap tabIcon = tabV2.icon.pixmap(qt_getWindow(widget), tabV2.iconSize,
- (tabV2.state & State_Enabled) ? QIcon::Normal
- : QIcon::Disabled,
- (tabV2.state & State_Selected) ? QIcon::On
- : QIcon::Off);
+ if (!tab->icon.isNull()) {
+ QPixmap tabIcon = tab->icon.pixmap(qt_getWindow(widget), tab->iconSize,
+ (tab->state & State_Enabled) ? QIcon::Normal
+ : QIcon::Disabled,
+ (tab->state & State_Selected) ? QIcon::On
+ : QIcon::Off);
p->drawPixmap(iconRect.x(), iconRect.y(), tabIcon);
}
@@ -1908,17 +1898,17 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt,
if (verticalTabs)
p->restore();
- if (tabV2.state & State_HasFocus) {
+ if (tab->state & State_HasFocus) {
const int OFFSET = 1 + pixelMetric(PM_DefaultFrameWidth);
int x1, x2;
- x1 = tabV2.rect.left();
- x2 = tabV2.rect.right() - 1;
+ x1 = tab->rect.left();
+ x2 = tab->rect.right() - 1;
QStyleOptionFocusRect fropt;
fropt.QStyleOption::operator=(*tab);
- fropt.rect.setRect(x1 + 1 + OFFSET, tabV2.rect.y() + OFFSET,
- x2 - x1 - 2*OFFSET, tabV2.rect.height() - 2*OFFSET);
+ fropt.rect.setRect(x1 + 1 + OFFSET, tab->rect.y() + OFFSET,
+ x2 - x1 - 2*OFFSET, tab->rect.height() - 2*OFFSET);
drawPrimitive(PE_FrameFocusRect, &fropt, p, widget);
}
}
@@ -2037,9 +2027,7 @@ void QCommonStyle::drawControl(ControlElement element, const QStyleOption *opt,
}
if (!dwOpt->title.isEmpty()) {
- const QStyleOptionDockWidgetV2 *v2
- = qstyleoption_cast<const QStyleOptionDockWidgetV2*>(opt);
- bool verticalTitleBar = v2 == 0 ? false : v2->verticalTitleBar;
+ const bool verticalTitleBar = dwOpt->verticalTitleBar;
if (verticalTitleBar) {
r.setSize(r.size().transposed());
@@ -2475,10 +2463,7 @@ QRect QCommonStyle::subElementRect(SubElement sr, const QStyleOption *opt,
case SE_ProgressBarLabel:
if (const QStyleOptionProgressBar *pb = qstyleoption_cast<const QStyleOptionProgressBar *>(opt)) {
int textw = 0;
- bool vertical = false;
- if (const QStyleOptionProgressBarV2 *pb2 = qstyleoption_cast<const QStyleOptionProgressBarV2 *>(opt)) {
- vertical = (pb2->orientation == Qt::Vertical);
- }
+ const bool vertical = pb->orientation == Qt::Vertical;
if (!vertical) {
if (pb->textVisible)
textw = qMax(pb->fontMetrics.width(pb->text), pb->fontMetrics.width(QLatin1String("100%"))) + 6;
@@ -2731,14 +2716,13 @@ QRect QCommonStyle::subElementRect(SubElement sr, const QStyleOption *opt,
break;
case SE_TabBarTabText:
if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
- QStyleOptionTabV3 tabV3(*tab);
QRect dummyIconRect;
- d->tabLayout(&tabV3, widget, &r, &dummyIconRect);
+ d->tabLayout(tab, widget, &r, &dummyIconRect);
}
break;
case SE_TabBarTabLeftButton:
case SE_TabBarTabRightButton:
- if (const QStyleOptionTabV3 *tab = qstyleoption_cast<const QStyleOptionTabV3 *>(opt)) {
+ if (const QStyleOptionTab *tab = qstyleoption_cast<const QStyleOptionTab *>(opt)) {
bool selected = tab->state & State_Selected;
int verticalShift = proxy()->pixelMetric(QStyle::PM_TabBarTabShiftVertical, tab, widget);
int horizontalShift = proxy()->pixelMetric(QStyle::PM_TabBarTabShiftHorizontal, tab, widget);
@@ -2927,9 +2911,8 @@ QRect QCommonStyle::subElementRect(SubElement sr, const QStyleOption *opt,
= qstyleoption_cast<const QStyleOptionDockWidget*>(opt);
bool canClose = dwOpt == 0 ? true : dwOpt->closable;
bool canFloat = dwOpt == 0 ? false : dwOpt->floatable;
- const QStyleOptionDockWidgetV2 *v2
- = qstyleoption_cast<const QStyleOptionDockWidgetV2*>(opt);
- bool verticalTitleBar = v2 == 0 ? false : v2->verticalTitleBar;
+
+ const bool verticalTitleBar = dwOpt && dwOpt->verticalTitleBar;
// If this is a vertical titlebar, we transpose and work as if it was
// horizontal, then transpose again.
diff --git a/src/widgets/styles/qcommonstyle_p.h b/src/widgets/styles/qcommonstyle_p.h
index 1287528bdb..8f512f7d72 100644
--- a/src/widgets/styles/qcommonstyle_p.h
+++ b/src/widgets/styles/qcommonstyle_p.h
@@ -104,7 +104,7 @@ public:
#endif
mutable QIcon tabBarcloseButtonIcon;
#ifndef QT_NO_TABBAR
- void tabLayout(const QStyleOptionTabV3 *opt, const QWidget *widget, QRect *textRect, QRect *pixmapRect) const;
+ void tabLayout(const QStyleOptionTab *opt, const QWidget *widget, QRect *textRect, QRect *pixmapRect) const;
#endif
int animationFps;
diff --git a/src/widgets/widgets/qmenu.cpp b/src/widgets/widgets/qmenu.cpp
index b29d7de5f5..27e977f027 100644
--- a/src/widgets/widgets/qmenu.cpp
+++ b/src/widgets/widgets/qmenu.cpp
@@ -192,11 +192,10 @@ void QMenuPrivate::syncPlatformMenu()
return;
QPlatformMenuItem *beforeItem = Q_NULLPTR;
- QListIterator<QAction*> it(q->actions());
- it.toBack();
- while (it.hasPrevious()) {
+ const QList<QAction*> actions = q->actions();
+ for (QList<QAction*>::const_reverse_iterator it = actions.rbegin(), end = actions.rend(); it != end; ++it) {
QPlatformMenuItem *menuItem = platformMenu->createMenuItem();
- QAction *action = it.previous();
+ QAction *action = *it;
menuItem->setTag(reinterpret_cast<quintptr>(action));
QObject::connect(menuItem, SIGNAL(activated()), action, SLOT(trigger()), Qt::QueuedConnection);
QObject::connect(menuItem, SIGNAL(hovered()), action, SIGNAL(hovered()), Qt::QueuedConnection);
diff --git a/tests/auto/gui/image/qimagereader/images/longcomment.pgm b/tests/auto/gui/image/qimagereader/images/longcomment.pgm
new file mode 100644
index 0000000000..a5624b6c73
--- /dev/null
+++ b/tests/auto/gui/image/qimagereader/images/longcomment.pgm
@@ -0,0 +1,12 @@
+P2
+# A short comment
+# A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment A very long comment
+24 7
+15
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
+0 3 3 3 3 0 0 7 7 7 7 0 0 11 11 11 11 0 0 15 15 15 15 0
+0 3 0 0 0 0 0 7 0 0 0 0 0 11 0 0 0 0 0 15 0 0 15 0
+0 3 3 3 0 0 0 7 7 7 0 0 0 11 11 11 0 0 0 15 15 15 15 0
+0 3 0 0 0 0 0 7 0 0 0 0 0 11 0 0 0 0 0 15 0 0 0 0
+0 3 0 0 0 0 0 7 7 7 7 0 0 11 11 11 11 0 0 15 0 0 0 0
+0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
diff --git a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp
index 2eb9b4fc2d..1425ce3c2f 100644
--- a/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp
+++ b/tests/auto/gui/image/qimagereader/tst_qimagereader.cpp
@@ -224,6 +224,7 @@ void tst_QImageReader::readImage_data()
QTest::newRow("PPM: runners") << QString("runners.ppm") << true << QByteArray("ppm");
QTest::newRow("PPM: test") << QString("test.ppm") << true << QByteArray("ppm");
QTest::newRow("XBM: gnus") << QString("gnus.xbm") << true << QByteArray("xbm");
+ QTest::newRow("PGM: longcomment") << QString("longcomment.pgm") << true << QByteArray("pgm");
QTest::newRow("JPEG: beavis") << QString("beavis.jpg") << true << QByteArray("jpeg");
QTest::newRow("JPEG: qtbug13653") << QString("qtbug13653-no_eoi.jpg") << true << QByteArray("jpeg");
diff --git a/tests/auto/other/compiler/tst_compiler.cpp b/tests/auto/other/compiler/tst_compiler.cpp
index 2c95002cb2..af0fa4682d 100644
--- a/tests/auto/other/compiler/tst_compiler.cpp
+++ b/tests/auto/other/compiler/tst_compiler.cpp
@@ -979,6 +979,20 @@ void tst_Compiler::cxx11_nullptr()
#endif
}
+namespace SomeNamespace {
+class AdlOnly {
+ QVector<int> v;
+public:
+ AdlOnly() : v(5) { std::fill_n(v.begin(), v.size(), 42); }
+
+private:
+ friend QVector<int>::const_iterator begin(const AdlOnly &x) { return x.v.begin(); }
+ friend QVector<int>::const_iterator end(const AdlOnly &x) { return x.v.end(); }
+ friend QVector<int>::iterator begin(AdlOnly &x) { return x.v.begin(); }
+ friend QVector<int>::iterator end(AdlOnly &x) { return x.v.end(); }
+};
+}
+
void tst_Compiler::cxx11_range_for()
{
#ifndef Q_COMPILER_RANGE_FOR
@@ -998,6 +1012,85 @@ void tst_Compiler::cxx11_range_for()
l << 2;
for (int i : ll)
QCOMPARE(i, 2);
+
+ {
+ const int array[] = { 0, 1, 2, 3, 4 };
+ int i = 0;
+ for (const int &e : array)
+ QCOMPARE(e, array[i++]);
+ i = 0;
+ for (int e : array)
+ QCOMPARE(e, array[i++]);
+ i = 0;
+ for (const int e : array)
+ QCOMPARE(e, array[i++]);
+#ifdef Q_COMPILER_AUTO_TYPE
+ i = 0;
+ for (const auto &e : array)
+ QCOMPARE(e, array[i++]);
+ i = 0;
+ for (auto &e : array) // auto deducing const
+ QCOMPARE(e, array[i++]);
+ i = 0;
+ for (auto e : array)
+ QCOMPARE(e, array[i++]);
+ i = 0;
+ for (const auto e : array)
+ QCOMPARE(e, array[i++]);
+#endif
+ }
+
+ {
+ int array[] = { 0, 1, 2, 3, 4 };
+ const int array2[] = { 10, 11, 12, 13, 14 };
+ int i = 0;
+ for (const int &e : array)
+ QCOMPARE(e, array[i++]);
+ i = 0;
+ for (int &e : array)
+ QCOMPARE(e, array[i++]);
+ i = 0;
+ for (int e : array)
+ QCOMPARE(e, array[i++]);
+ i = 0;
+ for (const int e : array)
+ QCOMPARE(e, array[i++]);
+#ifdef Q_COMPILER_AUTO_TYPE
+ i = 0;
+ for (const auto &e : array)
+ QCOMPARE(e, array[i++]);
+ i = 0;
+ for (auto &e : array)
+ QCOMPARE(e, array[i++]);
+ i = 0;
+ for (auto e : array)
+ QCOMPARE(e, array[i++]);
+ i = 0;
+ for (const auto e : array)
+ QCOMPARE(e, array[i++]);
+#endif
+ for (int &e : array)
+ e += 10;
+ i = 0;
+ for (const int &e : array)
+ QCOMPARE(e, array2[i++]);
+ }
+
+ {
+ const SomeNamespace::AdlOnly x;
+ for (const int &e : x)
+ QCOMPARE(e, 42);
+ }
+
+ {
+ SomeNamespace::AdlOnly x;
+ for (const int &e : x)
+ QCOMPARE(e, 42);
+ for (int &e : x)
+ e += 10;
+ for (const int &e : x)
+ QCOMPARE(e, 52);
+ }
#endif
}
@@ -1035,24 +1128,88 @@ void tst_Compiler::cxx11_ref_qualifiers()
#endif
}
+class MoveDefinedQString {
+ QString s;
+public:
+ MoveDefinedQString() : s() {}
+ explicit MoveDefinedQString(const QString &s) : s(s) {}
+ MoveDefinedQString(const MoveDefinedQString &other) : s(other.s) {}
+#ifdef Q_COMPILER_RVALUE_REFS
+ MoveDefinedQString(MoveDefinedQString &&other) : s(std::move(other.s)) { other.s.clear(); }
+ MoveDefinedQString &operator=(MoveDefinedQString &&other)
+ { s = std::move(other.s); other.s.clear(); return *this; }
+#endif
+ MoveDefinedQString &operator=(const MoveDefinedQString &other) { s = other.s; return *this; }
+
+private:
+ friend bool operator==(const MoveDefinedQString &lhs, const MoveDefinedQString &rhs)
+ { return lhs.s == rhs.s; }
+ friend bool operator!=(const MoveDefinedQString &lhs, const MoveDefinedQString &rhs)
+ { return !operator==(lhs, rhs); }
+ friend char* toString(const MoveDefinedQString &mds)
+ { using namespace QTest; return toString(mds.s); }
+};
+
void tst_Compiler::cxx11_rvalue_refs()
{
#ifndef Q_COMPILER_RVALUE_REFS
QSKIP("Compiler does not support C++11 feature");
#else
- int i = 1;
- i = std::move(i);
-
- QString s = "Hello";
- QString t = std::move(s);
- QCOMPARE(t, QString("Hello"));
+ // we require std::move:
+ {
+ int i = 1;
+ i = std::move(i);
+
+ MoveDefinedQString s("Hello");
+ MoveDefinedQString t = std::move(s);
+ QCOMPARE(t, MoveDefinedQString("Hello"));
+ QCOMPARE(s, MoveDefinedQString());
+
+ s = t;
+ t = std::move(s);
+ QCOMPARE(t, MoveDefinedQString("Hello"));
+ QCOMPARE(s, MoveDefinedQString());
+
+ MoveDefinedQString &&r = std::move(t); // no actual move!
+ QCOMPARE(r, MoveDefinedQString("Hello"));
+ QCOMPARE(t, MoveDefinedQString("Hello")); // so 't' is unchanged
+ }
- s = t;
- t = std::move(s);
- QCOMPARE(t, QString("Hello"));
+ // we require std::forward:
+ {
+ MoveDefinedQString s("Hello");
+ MoveDefinedQString s2 = std::forward<MoveDefinedQString>(s); // forward as rvalue
+ QCOMPARE(s2, MoveDefinedQString("Hello"));
+ QCOMPARE(s, MoveDefinedQString());
+
+ MoveDefinedQString s3 = std::forward<MoveDefinedQString&>(s2); // forward as lvalue
+ QCOMPARE(s2, MoveDefinedQString("Hello"));
+ QCOMPARE(s3, MoveDefinedQString("Hello"));
+ }
- QString &&r = std::move(s);
- QCOMPARE(r, QString("Hello"));
+ // supported by MSVC only from November 2013 CTP, but only check for VC2015:
+# if !defined(Q_CC_MSVC) || defined(Q_CC_INTEL) || _MSC_VER >= 1900 // VS14 == VC2015
+ // we require automatic generation of move special member functions:
+ {
+ struct M { MoveDefinedQString s1, s2; };
+ M m1 = { MoveDefinedQString("Hello"), MoveDefinedQString("World") };
+ QCOMPARE(m1.s1, MoveDefinedQString("Hello"));
+ QCOMPARE(m1.s2, MoveDefinedQString("World"));
+ M m2 = std::move(m1);
+ QCOMPARE(m1.s1, MoveDefinedQString());
+ QCOMPARE(m1.s2, MoveDefinedQString());
+ QCOMPARE(m2.s1, MoveDefinedQString("Hello"));
+ QCOMPARE(m2.s2, MoveDefinedQString("World"));
+ M m3;
+ QCOMPARE(m3.s1, MoveDefinedQString());
+ QCOMPARE(m3.s2, MoveDefinedQString());
+ m3 = std::move(m2);
+ QCOMPARE(m2.s1, MoveDefinedQString());
+ QCOMPARE(m2.s2, MoveDefinedQString());
+ QCOMPARE(m3.s1, MoveDefinedQString("Hello"));
+ QCOMPARE(m3.s2, MoveDefinedQString("World"));
+ }
+# endif // MSVC < 2015
#endif
}
@@ -1265,9 +1422,11 @@ void tst_Compiler::cxx14_decltype_auto()
}
#if __cpp_return_type_deduction >= 201304
-auto returnTypeDeduction()
+auto returnTypeDeduction(bool choice)
{
- return 1U;
+ if (choice)
+ return 1U;
+ return returnTypeDeduction(!choice);
}
#endif
@@ -1276,7 +1435,7 @@ void tst_Compiler::cxx14_return_type_deduction()
#if __cpp_return_type_deduction-0 < 201304
QSKIP("Compiler does not support this C++14 feature");
#else
- QCOMPARE(returnTypeDeduction(), 1U);
+ QCOMPARE(returnTypeDeduction(false), 1U);
#endif
}
diff --git a/tests/auto/sql/models/qsqlquerymodel/tst_qsqlquerymodel.cpp b/tests/auto/sql/models/qsqlquerymodel/tst_qsqlquerymodel.cpp
index ae2f8dde5f..52baa0070b 100644
--- a/tests/auto/sql/models/qsqlquerymodel/tst_qsqlquerymodel.cpp
+++ b/tests/auto/sql/models/qsqlquerymodel/tst_qsqlquerymodel.cpp
@@ -593,7 +593,7 @@ public:
connect(this, SIGNAL(modelReset()), this, SLOT(modelResetSlot()));
}
- void testme()
+ void testNested()
{
// Only the outermost beginResetModel/endResetModel should
// emit signals.
@@ -618,6 +618,14 @@ public:
QCOMPARE(gotReset, true);
}
+ void testClear() // QTBUG-49404: Basic test whether clear() emits signals.
+ {
+ gotAboutToBeReset = gotReset = false;
+ clear();
+ QVERIFY(gotAboutToBeReset);
+ QVERIFY(gotReset);
+ }
+
private slots:
void modelAboutToBeResetSlot() { gotAboutToBeReset = true; }
void modelResetSlot() { gotReset = true; }
@@ -634,7 +642,8 @@ void tst_QSqlQueryModel::nestedResets()
CHECK_DATABASE(db);
NestedResetsTest t;
- t.testme();
+ t.testClear();
+ t.testNested();
}
// For task 180617
diff --git a/tests/auto/tools/qmake/testdata/findDeps/findDeps.pro b/tests/auto/tools/qmake/testdata/findDeps/findDeps.pro
index 442c9c767f..2713296f5b 100644
--- a/tests/auto/tools/qmake/testdata/findDeps/findDeps.pro
+++ b/tests/auto/tools/qmake/testdata/findDeps/findDeps.pro
@@ -9,4 +9,4 @@ HEADERS += object1.h \
object7.h \
object8.h \
object9.h
-SOURCES += main.cpp
+SOURCES += main.cpp needed.cpp
diff --git a/tests/auto/tools/qmake/testdata/findDeps/main.cpp b/tests/auto/tools/qmake/testdata/findDeps/main.cpp
index e4aa5c6251..0df3f9b7c3 100644
--- a/tests/auto/tools/qmake/testdata/findDeps/main.cpp
+++ b/tests/auto/tools/qmake/testdata/findDeps/main.cpp
@@ -31,6 +31,9 @@
**
****************************************************************************/
+#define spurious \
+ / #include "needed.cpp"
+// if not ignored, symbol needed() won't be available ...
#include <moc_object1.cpp>
/**/ #include <moc_object2.cpp>
@@ -49,5 +52,7 @@ static void function2(); /**/
static void function3(); //
#include <moc_object9.cpp>
-int main () {}
-
+int main () {
+ extern int needed(void);
+ return needed();
+}
diff --git a/tests/auto/tools/qmake/testdata/findDeps/needed.cpp b/tests/auto/tools/qmake/testdata/findDeps/needed.cpp
new file mode 100644
index 0000000000..698d0aaa12
--- /dev/null
+++ b/tests/auto/tools/qmake/testdata/findDeps/needed.cpp
@@ -0,0 +1 @@
+extern int needed(void) { return 1; }
diff --git a/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp b/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp
index 638fad6206..a4a0045265 100644
--- a/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp
+++ b/tests/auto/widgets/widgets/qopenglwidget/tst_qopenglwidget.cpp
@@ -57,6 +57,8 @@ private slots:
void asViewport();
void requestUpdate();
void fboRedirect();
+ void showHide();
+ void nativeWindow();
};
void tst_QOpenGLWidget::create()
@@ -81,7 +83,8 @@ public:
: QOpenGLWidget(parent),
m_initCalled(false), m_paintCalled(false), m_resizeCalled(false),
m_resizeOk(false),
- m_w(expectedWidth), m_h(expectedHeight) { }
+ m_w(expectedWidth), m_h(expectedHeight),
+ r(1.0f), g(0.0f), b(0.0f) { }
void initializeGL() Q_DECL_OVERRIDE {
m_initCalled = true;
@@ -89,13 +92,16 @@ public:
}
void paintGL() Q_DECL_OVERRIDE {
m_paintCalled = true;
- glClearColor(1.0f, 0.0f, 0.0f, 1.0f);
+ glClearColor(r, g, b, 1.0f);
glClear(GL_COLOR_BUFFER_BIT);
}
void resizeGL(int w, int h) Q_DECL_OVERRIDE {
m_resizeCalled = true;
m_resizeOk = w == m_w && h == m_h;
}
+ void setClearColor(float r, float g, float b) {
+ this->r = r; this->g = g; this->b = b;
+ }
bool m_initCalled;
bool m_paintCalled;
@@ -103,6 +109,7 @@ public:
bool m_resizeOk;
int m_w;
int m_h;
+ float r, g, b;
};
void tst_QOpenGLWidget::clearAndGrab()
@@ -355,6 +362,69 @@ void tst_QOpenGLWidget::fboRedirect()
QVERIFY(reportedDefaultFbo != widgetFbo);
}
+void tst_QOpenGLWidget::showHide()
+{
+ QScopedPointer<ClearWidget> w(new ClearWidget(0, 800, 600));
+ w->resize(800, 600);
+ w->show();
+ QTest::qWaitForWindowExposed(w.data());
+
+ w->hide();
+
+ QImage image = w->grabFramebuffer();
+ QVERIFY(!image.isNull());
+ QCOMPARE(image.width(), w->width());
+ QCOMPARE(image.height(), w->height());
+ QVERIFY(image.pixel(30, 40) == qRgb(255, 0, 0));
+
+ w->setClearColor(0, 0, 1);
+ w->show();
+ QTest::qWaitForWindowExposed(w.data());
+
+ image = w->grabFramebuffer();
+ QVERIFY(!image.isNull());
+ QCOMPARE(image.width(), w->width());
+ QCOMPARE(image.height(), w->height());
+ QVERIFY(image.pixel(30, 40) == qRgb(0, 0, 255));
+}
+
+void tst_QOpenGLWidget::nativeWindow()
+{
+ QScopedPointer<ClearWidget> w(new ClearWidget(0, 800, 600));
+ w->resize(800, 600);
+ w->show();
+ w->winId();
+ QTest::qWaitForWindowExposed(w.data());
+
+ QImage image = w->grabFramebuffer();
+ QVERIFY(!image.isNull());
+ QCOMPARE(image.width(), w->width());
+ QCOMPARE(image.height(), w->height());
+ QVERIFY(image.pixel(30, 40) == qRgb(255, 0, 0));
+ QVERIFY(w->internalWinId());
+
+ // Now as a native child.
+ QWidget nativeParent;
+ nativeParent.resize(800, 600);
+ nativeParent.setAttribute(Qt::WA_NativeWindow);
+ ClearWidget *child = new ClearWidget(0, 800, 600);
+ child->setClearColor(0, 1, 0);
+ child->setParent(&nativeParent);
+ child->resize(400, 400);
+ child->move(23, 34);
+ nativeParent.show();
+ QTest::qWaitForWindowExposed(&nativeParent);
+
+ QVERIFY(nativeParent.internalWinId());
+ QVERIFY(!child->internalWinId());
+
+ image = child->grabFramebuffer();
+ QVERIFY(!image.isNull());
+ QCOMPARE(image.width(), child->width());
+ QCOMPARE(image.height(), child->height());
+ QVERIFY(image.pixel(30, 40) == qRgb(0, 255, 0));
+}
+
QTEST_MAIN(tst_QOpenGLWidget)
#include "tst_qopenglwidget.moc"
diff --git a/tests/manual/qopenglwidget/openglwidget/main.cpp b/tests/manual/qopenglwidget/openglwidget/main.cpp
index aaa48ea60a..a56cea1dfe 100644
--- a/tests/manual/qopenglwidget/openglwidget/main.cpp
+++ b/tests/manual/qopenglwidget/openglwidget/main.cpp
@@ -35,13 +35,108 @@
#include <QApplication>
#include <QPushButton>
#include <QMdiArea>
+#include <QMdiSubWindow>
+#include <QMenu>
+#include <QMenuBar>
+#include <QMainWindow>
#include <QLCDNumber>
+#include <QScrollArea>
+#include <QScrollBar>
+#include <QTabWidget>
+#include <QLabel>
#include <QTimer>
#include <QSurfaceFormat>
#include <QDebug>
+#include <private/qwindow_p.h>
+
+class Tools : public QObject
+{
+ Q_OBJECT
+
+public:
+ Tools(QWidget *root, QWidget *widgetToTurn, const QVector<QWidget *> glwidgets)
+ : m_root(root), m_widgetToTurn(widgetToTurn), m_glWidgets(glwidgets) { }
+ void dump();
+
+private slots:
+ void turnNative();
+ void hideShowAllGL();
+ void dumpCompositingStatus();
+
+signals:
+ void aboutToShowGLWidgets();
+
+private:
+ void dumpWidget(QWidget *w, int indent = 0);
+
+ QWidget *m_root;
+ QWidget *m_widgetToTurn;
+ QVector<QWidget *> m_glWidgets;
+};
+
+void Tools::turnNative()
+{
+ qDebug("Turning into native");
+ m_widgetToTurn->winId();
+ dump();
+}
+
+void Tools::hideShowAllGL()
+{
+ if (m_glWidgets[0]->isVisible()) {
+ qDebug("Hiding all render-to-texture widgets");
+ foreach (QWidget *w, m_glWidgets)
+ w->hide();
+ } else {
+ qDebug("Showing all render-to-texture widgets");
+ emit aboutToShowGLWidgets();
+ foreach (QWidget *w, m_glWidgets)
+ w->show();
+ }
+}
+
+void Tools::dump()
+{
+ qDebug() << "Widget hierarchy";
+ dumpWidget(m_root);
+ qDebug() << "========";
+}
+
+void Tools::dumpWidget(QWidget *w, int indent)
+{
+ QString indentStr;
+ indentStr.fill(' ', indent);
+ qDebug().noquote() << indentStr << w << "winId =" << w->internalWinId();
+ foreach (QObject *obj, w->children()) {
+ if (QWidget *cw = qobject_cast<QWidget *>(obj))
+ dumpWidget(cw, indent + 4);
+ }
+}
+
+void Tools::dumpCompositingStatus()
+{
+ QWindow *w = m_root->window()->windowHandle();
+ qDebug() << "Compositing status for" << w << m_root->window() << "is" << QWindowPrivate::get(w)->compositing;
+}
+
+class TabWidgetResetter : public QObject
+{
+ Q_OBJECT
+public:
+ TabWidgetResetter(QTabWidget *tw) : m_tw(tw) { }
+public slots:
+ void reset() { m_tw->setCurrentIndex(0); }
+private:
+ QTabWidget *m_tw;
+};
int main(int argc, char *argv[])
{
+ if (argc > 1 && !strcmp(argv[1], "--sharecontext")) {
+ qDebug("Requesting all contexts to share");
+ QCoreApplication::setAttribute(Qt::AA_ShareOpenGLContexts);
+ }
+
QApplication a(argc, argv);
QSurfaceFormat format;
@@ -53,28 +148,86 @@ int main(int argc, char *argv[])
}
qDebug() << "Requesting" << format;
- QMdiArea w;
- w.resize(400,400);
+ QMainWindow wnd;
+ wnd.setObjectName("Main Window");
+ wnd.resize(1024, 768);
+
+ QMdiArea *w = new QMdiArea;
+ w->setObjectName("MDI area");
+ w->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+ wnd.setCentralWidget(w);
- OpenGLWidget *glw = new OpenGLWidget;
+ OpenGLWidget *glw = new OpenGLWidget(33, QVector3D(0, 0, 1));
+ glw->setObjectName("First GL Widget with 33 ms timer");
glw->setFormat(format);
- w.addSubWindow(glw);
- glw->setMinimumSize(100,100);
+ glw->setMinimumSize(100, 100);
+ QMdiSubWindow *sw = w->addSubWindow(glw);
+ sw->setObjectName("First MDI Sub-Window");
+ sw->setWindowTitle("33 ms timer");
- OpenGLWidget *glw2 = new OpenGLWidget;
+ OpenGLWidget *glw2 = new OpenGLWidget(16);
+ glw2->setObjectName("Second GL Widget with 16 ms timer");
glw2->setFormat(format);
- glw2->setMinimumSize(100,100);
- w.addSubWindow(glw2);
+ glw2->setMinimumSize(100, 100);
+ QOpenGLWidget *glw22 = new OpenGLWidget(16);
+ glw22->setObjectName("Second #2 GLWidget");
+ glw22->setParent(glw2);
+ glw22->resize(40, 40);
+ sw = w->addSubWindow(glw2);
+ sw->setObjectName("Second MDI Sub-Window");
+ sw->setWindowTitle("16 ms timer");
+
+ OpenGLWidget *glw3 = new OpenGLWidget(0); // trigger updates continuously, no timer
+ glw3->setObjectName("GL widget in scroll area (possibly native)");
+ glw3->setFormat(format);
+ glw3->setFixedSize(600, 600);
+ QScrollArea *sa = new QScrollArea;
+ sa->setWidget(glw3);
+ sa->setMinimumSize(100, 100);
+ sa->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
+ sw = w->addSubWindow(sa);
+ sw->setObjectName("MDI Sub-Window for scroll area");
+ sw->setWindowTitle("Cont. update");
+ sw->resize(300, 300);
+ sa->verticalScrollBar()->setValue(300);
QLCDNumber *lcd = new QLCDNumber;
lcd->display(1337);
- lcd->setMinimumSize(300,100);
- w.addSubWindow(lcd);
+ lcd->setMinimumSize(300, 100);
+ sw = w->addSubWindow(lcd);
+ sw->setObjectName("MDI Sub-Window for LCD widget");
+ sw->setWindowTitle("Ordinary widget");
+
+ QTabWidget *tw = new QTabWidget;
+ QOpenGLWidget *glw4 = new OpenGLWidget(16, QVector3D(1, 0, 0));
+ glw4->setObjectName("GL widget in tab widget");
+ tw->addTab(glw4, "OpenGL");
+ QLabel *label = new QLabel("Another tab");
+ tw->addTab(label, "Not OpenGL");
+ tw->setMinimumSize(100, 100);
+ sw = w->addSubWindow(tw);
+ sw->setObjectName("MDI Sub-Window for tab widget");
+ sw->setWindowTitle("Tabs");
- w.show();
+ TabWidgetResetter twr(tw);
+ Tools t(&wnd, glw3, QVector<QWidget *>() << glw << glw2 << glw3 << glw4);
+ QObject::connect(&t, SIGNAL(aboutToShowGLWidgets()), &twr, SLOT(reset()));
+ QMenu *toolsMenu = wnd.menuBar()->addMenu("&Tools");
+ toolsMenu->addAction("&Turn widgets (or some parent) into native", &t, SLOT(turnNative()));
+ toolsMenu->addAction("&Hide/show all OpenGL widgets", &t, SLOT(hideShowAllGL()));
+
+ QTimer compStatusDumpTimer;
+ QObject::connect(&compStatusDumpTimer, SIGNAL(timeout()), &t, SLOT(dumpCompositingStatus()));
+ compStatusDumpTimer.start(5000);
+
+ wnd.show();
if (glw->isValid())
qDebug() << "Got" << glw->format();
+ t.dump();
+
return a.exec();
}
+
+#include "main.moc"
diff --git a/tests/manual/qopenglwidget/openglwidget/openglwidget.cpp b/tests/manual/qopenglwidget/openglwidget/openglwidget.cpp
index d47e12edc8..4d2463b84d 100644
--- a/tests/manual/qopenglwidget/openglwidget/openglwidget.cpp
+++ b/tests/manual/qopenglwidget/openglwidget/openglwidget.cpp
@@ -75,16 +75,23 @@ public:
int w,h;
QWidget *q;
+
+ int m_interval;
+ QVector3D m_rotAxis;
};
-OpenGLWidget::OpenGLWidget(QWidget *parent)
+OpenGLWidget::OpenGLWidget(int interval, const QVector3D &rotAxis, QWidget *parent)
: QOpenGLWidget(parent)
{
- d = new OpenGLWidgetPrivate(this);
- QTimer *timer = new QTimer(this);
- connect(timer, SIGNAL(timeout()), this, SLOT(update()));
- timer->start(30);
+ d.reset(new OpenGLWidgetPrivate(this));
+ d->m_interval = interval;
+ d->m_rotAxis = rotAxis;
+ if (interval > 0) {
+ QTimer *timer = new QTimer(this);
+ connect(timer, SIGNAL(timeout()), this, SLOT(update()));
+ timer->start(interval);
+ }
}
OpenGLWidget::~OpenGLWidget()
@@ -152,7 +159,8 @@ void OpenGLWidgetPrivate::render()
QMatrix4x4 matrix;
matrix.perspective(60.0f, 4.0f/3.0f, 0.1f, 100.0f);
matrix.translate(0, 0, -2);
- matrix.rotate(100.0f * m_frame / 30/*screen()->refreshRate()*/, 0, 1, 0);
+ const qreal angle = 100.0f * m_frame / 30;
+ matrix.rotate(angle, m_rotAxis);
m_program->setUniformValue(m_matrixUniform, matrix);
@@ -182,4 +190,7 @@ void OpenGLWidgetPrivate::render()
m_program->release();
++m_frame;
+
+ if (m_interval <= 0)
+ q->update();
}
diff --git a/tests/manual/qopenglwidget/openglwidget/openglwidget.h b/tests/manual/qopenglwidget/openglwidget/openglwidget.h
index 4dc5fde067..a1d5490845 100644
--- a/tests/manual/qopenglwidget/openglwidget/openglwidget.h
+++ b/tests/manual/qopenglwidget/openglwidget/openglwidget.h
@@ -35,13 +35,14 @@
#define OPENGLWIDGET_H
#include <QtWidgets/QOpenGLWidget>
+#include <QtGui/QVector3D>
class OpenGLWidgetPrivate;
class OpenGLWidget : public QOpenGLWidget
{
Q_OBJECT
public:
- OpenGLWidget(QWidget *parent = 0);
+ OpenGLWidget(int interval = 30, const QVector3D &rotAxis = QVector3D(0, 1, 0), QWidget *parent = 0);
~OpenGLWidget();
void initializeGL();
@@ -49,7 +50,7 @@ public:
void paintGL();
private:
- OpenGLWidgetPrivate *d;
+ QScopedPointer<OpenGLWidgetPrivate> d;
};
#endif // OPENGLWIDGET_H