Merge "Merge remote-tracking branch 'origin/5.6' into dev" into refs/staging/dev
This commit is contained in:
commit
746f54c6df
@ -43,8 +43,5 @@
|
||||
</uap:VisualElements>
|
||||
</Application>
|
||||
</Applications>
|
||||
|
||||
<Capabilities>
|
||||
<Capability Name=\"internetClient\" />
|
||||
</Capabilities>
|
||||
$${WINRT_MANIFEST.capabilities}
|
||||
</Package>
|
||||
|
@ -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) {
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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: \
|
||||
|
@ -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 =
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
4
src/3rdparty/freetype/freetype.pro
vendored
4
src/3rdparty/freetype/freetype.pro
vendored
@ -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
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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"); }
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -224,16 +224,16 @@ static inline QRect deviceRect(const QRect &rect, QWindow *window)
|
||||
return deviceRect;
|
||||
}
|
||||
|
||||
static QRegion deviceRegion(const QRegion ®ion, QWindow *window)
|
||||
static QRegion deviceRegion(const QRegion ®ion, 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 ®ion,
|
||||
@ -282,7 +286,8 @@ void QPlatformBackingStore::composeAndFlush(QWindow *window, const QRegion ®i
|
||||
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 ®i
|
||||
// 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 ®i
|
||||
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 ®i
|
||||
// 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
|
||||
{
|
||||
|
@ -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()
|
||||
|
@ -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--;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -23,6 +23,7 @@ contains(QT_CONFIG,egl) {
|
||||
$$PWD/qxlibeglintegration_p.h
|
||||
SOURCES += \
|
||||
$$PWD/qxlibeglintegration.cpp
|
||||
LIBS_PRIVATE += $$QMAKE_LIBS_X11
|
||||
}
|
||||
CONFIG += egl
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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());
|
||||
|
||||
|
@ -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())
|
||||
|
@ -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()));
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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 */) {
|
||||
m_depth = 18;
|
||||
} else {
|
||||
m_depth = 24;
|
||||
}
|
||||
// Based on https://en.wikipedia.org/wiki/List_of_iOS_devices#Display
|
||||
|
||||
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad
|
||||
&& !deviceIdentifier.contains(QRegularExpression("^iPad2,[567]$")) /* excluding iPad Mini */) {
|
||||
m_unscaledDpi = 132;
|
||||
// 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
|
||||
m_depth = 24;
|
||||
|
||||
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
|
||||
|
@ -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"
|
||||
},
|
||||
|
@ -84,7 +84,8 @@ void QWindowsBackingStore::flush(QWindow *window, const QRegion ®ion,
|
||||
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()};
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -652,9 +652,11 @@ void QSqlRelationalTableModel::revertRow(int row)
|
||||
void QSqlRelationalTableModel::clear()
|
||||
{
|
||||
Q_D(QSqlRelationalTableModel);
|
||||
beginResetModel();
|
||||
d->clearChanges();
|
||||
d->relations.clear();
|
||||
QSqlTableModel::clear();
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1262,8 +1262,10 @@ void QSqlTableModel::setFilter(const QString &filter)
|
||||
void QSqlTableModel::clear()
|
||||
{
|
||||
Q_D(QSqlTableModel);
|
||||
beginResetModel();
|
||||
d->clear();
|
||||
QSqlQueryModel::clear();
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
/*! \reimp
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -79,7 +79,6 @@ void QWidgetBackingStore::qt_flush(QWidget *widget, const QRegion ®ion, 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 ®ion, 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();
|
||||
flushed = true;
|
||||
}
|
||||
|
||||
// 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())
|
||||
return;
|
||||
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
|
||||
}
|
||||
|
||||
if (!dirtyOnScreenWidgets || dirtyOnScreenWidgets->isEmpty()) {
|
||||
#ifndef QT_NO_OPENGL
|
||||
if (widgetTextures && widgetTextures->count()) {
|
||||
QWidget *target = widget ? widget : tlw;
|
||||
qt_flush(target, QRegion(), store, tlw, tlwOffset, widgetTextures, this);
|
||||
}
|
||||
#endif
|
||||
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();
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
12
tests/auto/gui/image/qimagereader/images/longcomment.pgm
Normal file
12
tests/auto/gui/image/qimagereader/images/longcomment.pgm
Normal file
@ -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
|
@ -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");
|
||||
|
@ -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);
|
||||
// we require std::move:
|
||||
{
|
||||
int i = 1;
|
||||
i = std::move(i);
|
||||
|
||||
QString s = "Hello";
|
||||
QString t = std::move(s);
|
||||
QCOMPARE(t, QString("Hello"));
|
||||
MoveDefinedQString s("Hello");
|
||||
MoveDefinedQString t = std::move(s);
|
||||
QCOMPARE(t, MoveDefinedQString("Hello"));
|
||||
QCOMPARE(s, MoveDefinedQString());
|
||||
|
||||
s = t;
|
||||
t = std::move(s);
|
||||
QCOMPARE(t, QString("Hello"));
|
||||
s = t;
|
||||
t = std::move(s);
|
||||
QCOMPARE(t, MoveDefinedQString("Hello"));
|
||||
QCOMPARE(s, MoveDefinedQString());
|
||||
|
||||
QString &&r = std::move(s);
|
||||
QCOMPARE(r, QString("Hello"));
|
||||
MoveDefinedQString &&r = std::move(t); // no actual move!
|
||||
QCOMPARE(r, MoveDefinedQString("Hello"));
|
||||
QCOMPARE(t, MoveDefinedQString("Hello")); // so 't' is unchanged
|
||||
}
|
||||
|
||||
// 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"));
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -9,4 +9,4 @@ HEADERS += object1.h \
|
||||
object7.h \
|
||||
object8.h \
|
||||
object9.h
|
||||
SOURCES += main.cpp
|
||||
SOURCES += main.cpp needed.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();
|
||||
}
|
||||
|
1
tests/auto/tools/qmake/testdata/findDeps/needed.cpp
vendored
Normal file
1
tests/auto/tools/qmake/testdata/findDeps/needed.cpp
vendored
Normal file
@ -0,0 +1 @@
|
||||
extern int needed(void) { return 1; }
|
@ -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"
|
||||
|
@ -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);
|
||||
|
||||
OpenGLWidget *glw = new OpenGLWidget;
|
||||
QMdiArea *w = new QMdiArea;
|
||||
w->setObjectName("MDI area");
|
||||
w->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
|
||||
wnd.setCentralWidget(w);
|
||||
|
||||
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");
|
||||
|
||||
w.show();
|
||||
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");
|
||||
|
||||
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"
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user